Improve test coverage
This commit is contained in:
parent
6bdf7a32a9
commit
b2a0cafe6e
|
@ -17,6 +17,7 @@
|
|||
"rules": {
|
||||
"@typescript-eslint/no-inferrable-types": 0,
|
||||
"@typescript-eslint/no-unused-vars": 2,
|
||||
"@typescript-eslint/no-var-requires": 0
|
||||
"@typescript-eslint/no-var-requires": 0,
|
||||
"@typescript-eslint/no-explicit-any": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
|
||||
describe("Environment Configuration", () => {
|
||||
const originalEnv = process.env;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
process.env = { ...originalEnv };
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env = originalEnv;
|
||||
});
|
||||
|
||||
it("should set NODE_ENV to development by default", async () => {
|
||||
delete process.env.NODE_ENV;
|
||||
const { envs, isProduction } = await import("./index");
|
||||
expect(envs.NODE_ENV).toBe("development");
|
||||
expect(isProduction).toBe(false);
|
||||
});
|
||||
|
||||
it("should use existing NODE_ENV if set", async () => {
|
||||
process.env.NODE_ENV = "production";
|
||||
const { envs, isProduction } = await import("./index");
|
||||
expect(envs.NODE_ENV).toBe("production");
|
||||
expect(isProduction).toBe(true);
|
||||
});
|
||||
|
||||
it("should export config from dotenv-flow", async () => {
|
||||
const { config } = await import("./index");
|
||||
expect(config).toBeDefined();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,68 @@
|
|||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { $log } from "@tsed/common";
|
||||
|
||||
vi.mock("@tsed/common", () => ({
|
||||
$log: {
|
||||
appenders: {
|
||||
set: vi.fn()
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
describe("Logger Configuration", () => {
|
||||
const originalEnv = process.env;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
process.env = { ...originalEnv };
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env = originalEnv;
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("should not set appenders in non-production environment", async () => {
|
||||
process.env.NODE_ENV = "development";
|
||||
await import("./index");
|
||||
expect($log.appenders.set).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should set appenders in production environment", async () => {
|
||||
process.env.NODE_ENV = "production";
|
||||
await import("./index");
|
||||
|
||||
expect($log.appenders.set).toHaveBeenCalledTimes(2);
|
||||
expect($log.appenders.set).toHaveBeenCalledWith("stdout", {
|
||||
type: "stdout",
|
||||
levels: ["info", "debug"],
|
||||
layout: {
|
||||
type: "json"
|
||||
}
|
||||
});
|
||||
expect($log.appenders.set).toHaveBeenCalledWith("stderr", {
|
||||
levels: ["trace", "fatal", "error", "warn"],
|
||||
type: "stderr",
|
||||
layout: {
|
||||
type: "json"
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("should export correct DILoggerOptions in non-production", async () => {
|
||||
process.env.NODE_ENV = "development";
|
||||
const { default: loggerOptions } = await import("./index");
|
||||
expect(loggerOptions).toEqual({
|
||||
disableRoutesSummary: false
|
||||
});
|
||||
});
|
||||
|
||||
it("should export correct DILoggerOptions in production", async () => {
|
||||
process.env.NODE_ENV = "production";
|
||||
const { default: loggerOptions } = await import("./index");
|
||||
expect(loggerOptions).toEqual({
|
||||
disableRoutesSummary: true
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
import { IndexController } from "./IndexController";
|
||||
import { describe, it, expect, beforeEach } from "vitest";
|
||||
|
||||
describe("IndexController", () => {
|
||||
let controller: IndexController;
|
||||
|
||||
beforeEach(() => {
|
||||
controller = new IndexController();
|
||||
// @ts-expect-error - swagger is private
|
||||
controller.swagger = [
|
||||
{ path: "/api-docs", specVersion: "3.0.1" },
|
||||
{ path: "/api-docs-2", specVersion: "3.0.2" }
|
||||
];
|
||||
});
|
||||
|
||||
it("should return correct view data", () => {
|
||||
const protocol = "https";
|
||||
const host = "example.com";
|
||||
|
||||
const result = controller.get(protocol, host);
|
||||
|
||||
expect(result).toEqual({
|
||||
BASE_URL: "https://example.com",
|
||||
docs: [
|
||||
{ url: "https://example.com/api-docs", path: "/api-docs", specVersion: "3.0.1" },
|
||||
{ url: "https://example.com/api-docs-2", path: "/api-docs-2", specVersion: "3.0.2" }
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it("should use http when protocol is not provided", () => {
|
||||
const host = "example.com";
|
||||
|
||||
const result = controller.get("", host);
|
||||
|
||||
expect(result.BASE_URL).toBe("http://example.com");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,79 @@
|
|||
import { describe, it, expect, vi, beforeEach, afterEach, Mock } from "vitest";
|
||||
import { Server } from "./Server";
|
||||
|
||||
vi.mock("@tsed/common", () => ({
|
||||
$log: {
|
||||
error: vi.fn()
|
||||
},
|
||||
PlatformApplication: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock("@tsed/platform-express", () => ({
|
||||
PlatformExpress: {
|
||||
bootstrap: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
describe("bootstrap function", () => {
|
||||
let bootstrap: () => Promise<void>;
|
||||
let mockPlatform: {
|
||||
listen: Mock;
|
||||
stop: Mock;
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
mockPlatform = {
|
||||
listen: vi.fn().mockResolvedValue(undefined),
|
||||
stop: vi.fn().mockResolvedValue(undefined)
|
||||
};
|
||||
|
||||
const { PlatformExpress } = await import("@tsed/platform-express");
|
||||
(PlatformExpress.bootstrap as Mock).mockResolvedValue(mockPlatform);
|
||||
|
||||
const module = await import("./index");
|
||||
bootstrap = module.bootstrap;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("should bootstrap the server successfully", async () => {
|
||||
await bootstrap();
|
||||
const { PlatformExpress } = await import("@tsed/platform-express");
|
||||
expect(PlatformExpress.bootstrap).toHaveBeenCalledWith(Server);
|
||||
expect(mockPlatform.listen).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should handle errors during bootstrap", async () => {
|
||||
const error = new Error("Bootstrap error");
|
||||
const { PlatformExpress } = await import("@tsed/platform-express");
|
||||
(PlatformExpress.bootstrap as Mock).mockRejectedValueOnce(error);
|
||||
|
||||
await bootstrap();
|
||||
|
||||
const { $log } = await import("@tsed/common");
|
||||
expect($log.error).toHaveBeenCalledWith({
|
||||
event: "SERVER_BOOTSTRAP_ERROR",
|
||||
message: error.message,
|
||||
stack: error.stack
|
||||
});
|
||||
});
|
||||
|
||||
it("should set up SIGINT handler", async () => {
|
||||
const processOnSpy = vi.spyOn(process, "on");
|
||||
await bootstrap();
|
||||
expect(processOnSpy).toHaveBeenCalledWith("SIGINT", expect.any(Function));
|
||||
|
||||
// Simulate SIGINT
|
||||
const sigintHandler = processOnSpy.mock.calls.find((call) => call[0] === "SIGINT")?.[1];
|
||||
if (sigintHandler && typeof sigintHandler === "function") {
|
||||
sigintHandler();
|
||||
expect(mockPlatform.stop).toHaveBeenCalled();
|
||||
} else {
|
||||
throw new Error("SIGINT handler not found or not a function");
|
||||
}
|
||||
});
|
||||
});
|
|
@ -2,11 +2,10 @@ import { $log } from "@tsed/common";
|
|||
import { PlatformExpress } from "@tsed/platform-express";
|
||||
import { Server } from "./Server";
|
||||
|
||||
async function bootstrap() {
|
||||
export async function bootstrap() {
|
||||
try {
|
||||
const platform = await PlatformExpress.bootstrap(Server);
|
||||
await platform.listen();
|
||||
|
||||
process.on("SIGINT", () => {
|
||||
platform.stop();
|
||||
});
|
||||
|
@ -15,4 +14,7 @@ async function bootstrap() {
|
|||
}
|
||||
}
|
||||
|
||||
// Only call bootstrap if this file is being run directly
|
||||
if (require.main === module) {
|
||||
bootstrap();
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
"resolveJsonModule": true,
|
||||
"useDefineForClassFields": false,
|
||||
"lib": ["es7", "dom", "ESNext.AsyncIterable"],
|
||||
"typeRoots": ["./node_modules/@types"]
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"noEmitHelpers": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"linterOptions": {
|
||||
|
|
|
@ -4,7 +4,10 @@ import { defineConfig } from "vitest/config";
|
|||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
root: "./"
|
||||
root: "./",
|
||||
coverage: {
|
||||
exclude: ["./processes.config.js", "vitest.config.mts"]
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
// This is required to build the test files with SWC
|
||||
|
|
Loading…
Reference in New Issue