Skip to content

Commit

Permalink
Merge pull request #13 from muhtalipdede/5-add-unit-test-and-test-cov…
Browse files Browse the repository at this point in the history
…erage

add unit test
  • Loading branch information
suphero authored Nov 1, 2023
2 parents 19643dd + 8acd1e2 commit 8e2247a
Show file tree
Hide file tree
Showing 16 changed files with 7,243 additions and 1,082 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
dist
dist
coverage
5 changes: 5 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ examples
.github
images
CONTRIBUTING.md
coverage
__tests__
__mocks__
.eslintrc.cjs
CONTRIBUTING.md
6 changes: 6 additions & 0 deletions __mocks__/fs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const fsMock = {
readFileSync: jest.fn(),
createReadStream: jest.fn(),
};

export = fsMock;
22 changes: 22 additions & 0 deletions __mocks__/http.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const mockData = JSON.stringify({ foo: "bar" });

const httpMock = {
createServer: jest.fn(),
IncomingMessage: jest.fn(function () {
this.bodyData = mockData;
return {
once: jest.fn((event, callback) => {
if (event === "data") {
callback(this.bodyData);
}
}),
};
}),
ServerResponse: jest.fn(() => ({
writeHead: jest.fn(),
write: jest.fn(),
end: jest.fn(),
})),
};

export = httpMock;
139 changes: 139 additions & 0 deletions __tests__/context.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import http from "http";
import fs from "fs";
import Context from "../src/context";
import { Socket } from "net";

jest.mock("http");
jest.mock("fs");

const { IncomingMessage, ServerResponse } = http;
const mockIncomingMessage = new IncomingMessage(new Socket());
const mockServerResponse = new ServerResponse(mockIncomingMessage);

describe('Context', () => {
it('should be defined', () => {
mockIncomingMessage.url = '/';
const context = new Context(mockIncomingMessage, mockServerResponse, '/');
expect(context).toBeDefined();
expect(context.req).toBeDefined();
expect(context.res).toBeDefined();
});

it('should be defined with params', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
expect(context).toBeDefined();
expect(context.req).toBeDefined();
expect(context.res).toBeDefined();
expect(context.params).toBeDefined();
expect(context.params.id).toBeDefined();
expect(context.params.id).toBe('1');
})

it('should not be defined with params', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/');
expect(context).toBeDefined();
expect(context.req).toBeDefined();
expect(context.res).toBeDefined();
expect(context.params).toEqual({});
})

it('should not be defined url', () => {
mockIncomingMessage.url = undefined;
const context = new Context(mockIncomingMessage, mockServerResponse, '/');
expect(context).toBeDefined();
expect(context.req).toBeDefined();
expect(context.res).toBeDefined();
expect(context.params).toEqual({});
})

it('should not be defined pathname', () => {
mockIncomingMessage.url = '';
const context = new Context(mockIncomingMessage, mockServerResponse, '/');
expect(context).toBeDefined();
expect(context.req).toBeDefined();
expect(context.res).toBeDefined();
expect(context.params).toEqual({});
})

it('should be defined send method', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
context.send({ id: 1 });
expect(mockServerResponse.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'application/json' });
expect(mockServerResponse.write).toHaveBeenCalledWith(JSON.stringify({ id: 1 }));
expect(mockServerResponse.end).toHaveBeenCalled();
})

it('should be defined redirect method', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
context.redirect('/2');
expect(mockServerResponse.writeHead).toHaveBeenCalledWith(302, { 'Location': '/2' });
expect(mockServerResponse.end).toHaveBeenCalled();
})

it('should be defined json method', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
context.json({ id: 1 });
expect(mockServerResponse.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'application/json' });
expect(mockServerResponse.write).toHaveBeenCalledWith(JSON.stringify({ id: 1 }));
expect(mockServerResponse.end).toHaveBeenCalled();
})

it('should be defined html method', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
context.html('<h1>hello</h1>');
expect(mockServerResponse.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'text/html' });
expect(mockServerResponse.write).toHaveBeenCalledWith('<h1>hello</h1>');
expect(mockServerResponse.end).toHaveBeenCalled();
})

it('should be defined js method', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
context.js('console.log("hello");');
expect(mockServerResponse.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'application/javascript' });
expect(mockServerResponse.write).toHaveBeenCalledWith('console.log("hello");');
expect(mockServerResponse.end).toHaveBeenCalled();
})

it('should be defined text method', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
context.text('hello');
expect(mockServerResponse.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'text/plain' });
expect(mockServerResponse.write).toHaveBeenCalledWith('hello');
expect(mockServerResponse.end).toHaveBeenCalled();
})

it('should be defined css method', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
context.css('body { background-color: red; }');
expect(mockServerResponse.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'text/css' });
expect(mockServerResponse.write).toHaveBeenCalledWith('body { background-color: red; }');
expect(mockServerResponse.end).toHaveBeenCalled();
})

it('should be defined file method', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
context.file('index.html');
expect(mockServerResponse.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'application/octet-stream' });
expect(mockServerResponse.write).toHaveBeenCalledWith(fs.readFileSync('index.html'));
expect(mockServerResponse.end).toHaveBeenCalled();
})

it('should be defined fileStream method', () => {
mockIncomingMessage.url = '/1';
const context = new Context(mockIncomingMessage, mockServerResponse, '/:id');
context.fileStream('index.html');
expect(mockServerResponse.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'application/octet-stream' });
expect(mockServerResponse.write).toHaveBeenCalledWith(fs.createReadStream('index.html'));
expect(mockServerResponse.end).toHaveBeenCalled();
})
})
36 changes: 36 additions & 0 deletions __tests__/middleware-manager.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Context from "../src/context";
import http from "http";
import { Socket } from "net";
import { MiddlewareManager } from "../src/middleware";

jest.mock('http');

const { IncomingMessage, ServerResponse } = http;
const mockIncomingMessage = new IncomingMessage(new Socket());
const mockServerResponse = new ServerResponse(mockIncomingMessage);

describe("Middleware Manager", () => {
it("should be defined", () => {
const manager = new MiddlewareManager();
manager.add((context, next) => {
context.send("1");
next();
})
expect(manager).toBeDefined();
expect(manager.middlewares).toBeDefined();
expect(manager.middlewares.length).toBe(1);
})

it("should be defined run middleware", () => {
const manager = new MiddlewareManager();
manager.add((context, next) => {
context.send("1");
next();
})

const context = new Context(mockIncomingMessage, mockServerResponse, '/');
manager.run(context);

expect(context.res.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'application/json' });
})
})
29 changes: 29 additions & 0 deletions __tests__/middleware-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Context from "../src/context";
import { runMiddleware } from "../src/middleware/utils";
import http from "http";
import { Socket } from "net";

jest.mock("http");

const { IncomingMessage, ServerResponse } = http;
const mockIncomingMessage = new IncomingMessage(new Socket());
const mockServerResponse = new ServerResponse(mockIncomingMessage);

describe("Middleware Utils", () => {
it("should be defined run middleware", () => {

const middlewares = [];
middlewares.push((context: Context, next: () => void) => {
context.send("1");
next();
})

middlewares.push((context: Context, next: () => void) => {
context.send("2");
next();
})
runMiddleware(new Context(mockIncomingMessage, mockServerResponse, "/"), middlewares);

expect(mockServerResponse.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'application/json' });
});
})
42 changes: 42 additions & 0 deletions __tests__/route-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Router from "../src/router";
import { matcher } from "../src/router/route-utils";

describe("Route Utils", () => {
let router: Router;

beforeEach(() => {
router = new Router();
});

describe("matcher", () => {
it("should be defined for existing routes", () => {
router.get("/", (context) => context.send("hello"));
const match = matcher(router, "GET", "/");
expect(match).toBeDefined();
});

it("should not be defined if route is not added", () => {
const match = matcher(router, "GET", "/");
expect(match).toBeNull();
});

it("should not be defined for non-existent methods or urls", () => {
router.get("/", (context) => context.send("hello"));

let match = matcher(router, "", "/");
expect(match).toBeNull();

match = matcher(router, "GET", "");
expect(match).toBeNull();

match = matcher(router, "", "");
expect(match).toBeNull();
});

it("should be defined for routes with params", () => {
router.get("/123", (context) => context.send("hello"));
const match = matcher(router, "GET", "/:id");
expect(match).toBeDefined();
});
});
});
Loading

0 comments on commit 8e2247a

Please sign in to comment.