Skip to content

Commit

Permalink
add enable to inject custom logger
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroki0525 committed Nov 6, 2023
1 parent 62a8e2f commit 8a7ffe0
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 117 deletions.
15 changes: 13 additions & 2 deletions packages/cli/src/core/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import generateDandoriTasks, {
DandoriTask,
OptionalTaskPropsOption,
} from "@dandori/core";
import { logger } from "@dandori/libs";

const tasks: DandoriTask[] = [
{
Expand All @@ -31,9 +30,21 @@ vi.mock("@dandori/core", () => ({
default: vi.fn(() => tasks),
}));

const mockLogError = vi.fn();

vi.mock("@dandori/libs", async () => {
const actualModule =
await vi.importActual<typeof import("@dandori/libs")>("@dandori/libs");
return {
...actualModule,
getLogger: vi.fn(() => ({
error: mockLogError,
})),
};
});

describe("DandoriCoreCli", () => {
const mockConsole = vi.spyOn(console, "log").mockImplementation(() => {});
const mockLogError = vi.spyOn(logger, "error").mockImplementation(() => {});
const inputFileName = "DandoriCoreCli.txt";
const inputFileText = "DandoriCoreCli";
const loadProcessArgv = (options: string[]) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import generateDandoriTasks, {
OptionalTaskPropsOption,
} from "@dandori/core";
import { readFile } from "fs/promises";
import { loadFile, logger } from "@dandori/libs";
import { getLogger, loadFile } from "@dandori/libs";

const supportedChatGPTModels: ChatGPTFunctionCallModel[] = [
"gpt-3.5-turbo-0613",
Expand Down Expand Up @@ -77,6 +77,7 @@ export default class DandoriCoreCli {
optionalTaskProps?: string;
model?: string;
}>();
const logger = getLogger();
if (!isSupportedChatGPTModels(model)) {
const logMessage = `Unsupported model: ${model}. Supported models are ${supportedChatGPTModels.join(
", ",
Expand Down
12 changes: 7 additions & 5 deletions packages/core/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import generateDandoriTasks, {
} from "../index";
import { describe, beforeEach, afterEach, it, vi, expect, Mock } from "vitest";
import OpenAI from "openai";
import { loadEnvFile, logger, runPromisesSequentially } from "@dandori/libs";
import { loadEnvFile, runPromisesSequentially } from "@dandori/libs";

const openAiResArguments = { tasks: [] } as const;
vi.mock("openai", () => {
Expand All @@ -30,16 +30,18 @@ vi.mock("openai", () => {
return { default: OpenAI };
});

const mockLogDebug = vi.fn();

vi.mock("@dandori/libs", async () => {
const actualModule =
await vi.importActual<typeof import("@dandori/libs")>("@dandori/libs");
return {
...actualModule,
logger: {
getLogger: vi.fn(() => ({
error: vi.fn(),
debug: vi.fn(),
debug: mockLogDebug,
info: vi.fn(),
},
})),
runPromisesSequentially: vi.fn((runPromises, _runningLogPrefix) =>
Promise.all(runPromises.map((runPromise: () => any) => runPromise())),
),
Expand Down Expand Up @@ -252,7 +254,7 @@ describe("generateDandoriTasks", () => {
});

it("called logger.debug with valid arguments", () => {
expect(logger.debug).toBeCalledWith(openAiResArguments.tasks);
expect(mockLogDebug).toBeCalledWith(openAiResArguments.tasks);
});

it("return tasks", () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import OpenAI from "openai";
import { loadEnvFile, logger, runPromisesSequentially } from "@dandori/libs";
import { getLogger, loadEnvFile, runPromisesSequentially } from "@dandori/libs";
import { ChatCompletionMessage } from "openai/resources";

export type ChatGPTFunctionCallModel = "gpt-3.5-turbo-0613" | "gpt-4-0613";
Expand Down Expand Up @@ -179,6 +179,6 @@ export default async function generateDandoriTasks(
const resFunctionCall = completion.choices[0].message
.function_call as ChatCompletionMessage.FunctionCall;
const { tasks } = JSON.parse(resFunctionCall.arguments);
logger.debug(tasks);
getLogger().debug(tasks);
return tasks as DandoriTask[];
}
112 changes: 34 additions & 78 deletions packages/libs/src/__tests__/loadEnvFile.test.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,44 @@
import { loadEnvFile, logger } from "../index";
import {
describe,
it,
expect,
beforeAll,
afterAll,
beforeEach,
vi,
afterEach,
} from "vitest";
import { mkdir, rm, rmdir, writeFile } from "fs/promises";

describe("loadEnvFile", () => {
describe("with valid .env file", () => {
const openApiKeyPropName = "OPENAI_API_KEY";

afterEach(() => {
delete process.env[openApiKeyPropName];
});

describe("no filePath argument", () => {
const apiKey = "123";
const envFileName = ".env";

beforeAll(async () => {
await writeFile(envFileName, `${openApiKeyPropName}=${apiKey}`);
});

afterAll(async () => {
await rm(envFileName);
});

beforeEach(() => {
loadEnvFile();
});

it(`loaded ${openApiKeyPropName}`, () => {
expect(process.env[openApiKeyPropName]).toBe(apiKey);
});
});

describe("filePath argument", () => {
const apiKey = "456";
const envFileDir = "./dir";
const envFilePath = `./${envFileDir}/.env`;

beforeAll(async () => {
await mkdir(envFileDir);
await writeFile(envFilePath, `${openApiKeyPropName}=${apiKey}`);
});

afterAll(async () => {
await rm(envFilePath);
await rmdir(envFileDir);
});
import { describe, expect, vi, it, beforeEach } from "vitest";
import { getLogger, setLogger } from "../logger";
import pino from "pino";

const defaultLogger = pino({
name: "dandori",
level: "debug",
transport: {
target: "pino-pretty",
options: {
colorize: true,
},
},
});

beforeEach(() => {
loadEnvFile(envFilePath);
});
vi.mock("pino", () => ({
default: vi.fn(),
}));

it(`loaded ${openApiKeyPropName}`, () => {
expect(process.env[openApiKeyPropName]).toBe(apiKey);
});
describe("logger", () => {
describe("use default logger", () => {
it("get default logger", () => {
expect(getLogger()).toEqual(defaultLogger);
});
});

describe("without valid .env file", () => {
const mockErrorLog = vi.spyOn(logger, "error").mockImplementation(() => {});
const runErrorLoadEnvFile = () => loadEnvFile("./nodir/.env");

afterEach(() => {
vi.clearAllMocks();
});

it("throw Error", async () => {
expect(runErrorLoadEnvFile).toThrowError();
describe("use custom logger", () => {
const customLogger = {
debug: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
customProp: vi.fn(),
};

beforeEach(() => {
setLogger(customLogger);
});

it("called error log", async () => {
try {
runErrorLoadEnvFile();
} catch (e) {
expect(mockErrorLog).toBeCalled();
}
it("get custom logger", () => {
expect(getLogger()).toEqual(customLogger);
});
});
});
95 changes: 95 additions & 0 deletions packages/libs/src/__tests__/logger.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { loadEnvFile } from "../index";
import {
describe,
it,
expect,
beforeAll,
afterAll,
beforeEach,
vi,
afterEach,
} from "vitest";
import { mkdir, rm, rmdir, writeFile } from "fs/promises";

const mockErrorLog = vi.fn();

vi.mock("../logger", () => ({
getLogger: vi.fn(() => ({
error: mockErrorLog,
})),
}));

describe("loadEnvFile", () => {
describe("with valid .env file", () => {
const openApiKeyPropName = "OPENAI_API_KEY";

afterEach(() => {
delete process.env[openApiKeyPropName];
});

describe("no filePath argument", () => {
const apiKey = "123";
const envFileName = ".env";

beforeAll(async () => {
await writeFile(envFileName, `${openApiKeyPropName}=${apiKey}`);
});

afterAll(async () => {
await rm(envFileName);
});

beforeEach(() => {
loadEnvFile();
});

it(`loaded ${openApiKeyPropName}`, () => {
expect(process.env[openApiKeyPropName]).toBe(apiKey);
});
});

describe("filePath argument", () => {
const apiKey = "456";
const envFileDir = "./dir";
const envFilePath = `./${envFileDir}/.env`;

beforeAll(async () => {
await mkdir(envFileDir);
await writeFile(envFilePath, `${openApiKeyPropName}=${apiKey}`);
});

afterAll(async () => {
await rm(envFilePath);
await rmdir(envFileDir);
});

beforeEach(() => {
loadEnvFile(envFilePath);
});

it(`loaded ${openApiKeyPropName}`, () => {
expect(process.env[openApiKeyPropName]).toBe(apiKey);
});
});
});

describe("without valid .env file", () => {
const runErrorLoadEnvFile = () => loadEnvFile("./nodir/.env");

afterEach(() => {
vi.clearAllMocks();
});

it("throw Error", async () => {
expect(runErrorLoadEnvFile).toThrowError();
});

it("called error log", async () => {
try {
runErrorLoadEnvFile();
} catch (e) {
expect(mockErrorLog).toBeCalled();
}
});
});
});
19 changes: 9 additions & 10 deletions packages/libs/src/__tests__/runPromisesSequentially.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { describe, it, expect, vi, afterEach, beforeEach, Mock } from "vitest";
import { logger } from "../logger";
import { describe, it, expect, vi, afterEach, beforeEach } from "vitest";
import { runPromisesSequentially } from "../runPromisesSequentially";

vi.mock("../logger", async () => ({
logger: {
error: vi.fn(),
info: vi.fn(),
},
}));
const logErrorMock = vi.fn();
const logInfoMock = vi.fn();

const logErrorMock = logger.error as Mock;
const logInfoMock = logger.info as Mock;
vi.mock("../logger", () => ({
getLogger: vi.fn(() => ({
error: logErrorMock,
info: logInfoMock,
})),
}));

describe("runPromisesSequentially", () => {
const msPerLog = 5000;
Expand Down
4 changes: 2 additions & 2 deletions packages/libs/src/loadEnvFile.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { configDotenv } from "dotenv";
import { loadFile } from "./loadFile";
import { logger } from "./logger";
import { getLogger } from "./logger";

export function loadEnvFile(filePath: string = ".env"): void {
const loadEnvResult = configDotenv({
path: loadFile(filePath),
});
if (loadEnvResult.error) {
logger.error(loadEnvResult.error);
getLogger().error(loadEnvResult.error);
throw loadEnvResult.error;
}
}
Loading

0 comments on commit 8a7ffe0

Please sign in to comment.