Skip to content

Commit

Permalink
Examples with fastify added and working. Fixed the nyc issue (all: tr…
Browse files Browse the repository at this point in the history
…ue does not work..)
  • Loading branch information
Flowkap committed Nov 13, 2020
1 parent 4fd4419 commit 1bd093c
Show file tree
Hide file tree
Showing 15 changed files with 129 additions and 79 deletions.
6 changes: 6 additions & 0 deletions .mocharc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ require:
recursive: true
color: true
exit: true
extension:
- ts
- test.ts
ignore:
# this is so that mocha doesn'T auto execute app.ts before the tests does load it.
- "**/src/app.ts"
3 changes: 1 addition & 2 deletions .nycrc.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# according to https://github.com/istanbuljs/istanbuljs/tree/master/packages/nyc-config-typescript
extends: "@istanbuljs/nyc-config-typescript"
all: true

reporter:
- html
Expand All @@ -13,7 +12,7 @@ report-dir: coverage

# Coverage gates
check-coverage: true
functions: 90
functions: 80
lines: 80
statements: 80
branches: 70
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"--no-timeouts",
"${workspaceFolder}/src/**/*.test.ts",
"${workspaceFolder}/test/**/*.ts"
"${workspaceFolder}/src",
"${workspaceFolder}/test"
],
"internalConsoleOptions": "openOnSessionStart"
},
Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ Whilst working with typescript for a while now I found that most examples on the
* Out of the box VsCode config for debugging app + tests no matter where with proper sourcemaps
* Multi stage docker build
* All type infos needed as well

I will probably extend to show off:

* Fastify with native async await in Typescript
* Fastify with native async await in Typescript, including mocked / stubbed and spy tests as well as using inject to test the calls
* Sinon for mocking / stubbing

The biggest challenge was trying to make code coverage work without ts-node which unfortunately wasn't really possible. It kindof worked but did not track any files that were not called in any test counteracting the purpose of finding uncovered code. So this template uses ts-node for all test execution and a transpiled build (no ts-node hence for "prod") to run the app.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"lint": "eslint src",
"build": "npm run clean && npm run lint && tsc -p .",
"start": "npm run build && node build/app.js",
"test": "npm run lint && nyc mocha src/**/*.test.ts test/**/*.ts" ,
"test": "npm run lint && nyc mocha src test",
"docker": "docker build -t typescript-node-template ."
},
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ export async function stop(): Promise<void> {
await app.server.close();
}

// start();
start();
11 changes: 0 additions & 11 deletions src/handler/Persons.test.ts

This file was deleted.

18 changes: 18 additions & 0 deletions src/handler/hello.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

import { expect } from "chai";
import { hello } from "./hello";
import { fastify} from "fastify";

describe("Hello", () => {
it("handler", async () => {
const app = fastify();
app.get("/", hello);
const response = await app.inject({
method: "GET",
url: "/",
});
expect(response.statusCode).to.equal(200);
expect(response.headers["content-type"]).to.equal("text/html; charset=utf-8");
expect(response.body).to.contain("Hallo!");
});
});
6 changes: 6 additions & 0 deletions src/handler/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { FastifyRequest, FastifyReply } from "fastify";

export async function hello(req: FastifyRequest, reply: FastifyReply): Promise<string> {
reply.type("text/html; charset=utf-8").code(200);
return "<h1>Hallo!</h1><a href='/persons'>Fetch persons here</a>";
}
21 changes: 21 additions & 0 deletions src/handler/persons.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

import { expect } from "chai";
import { getAll } from "./persons";
import { fastify} from "fastify";

describe("Persons", () => {
it("handler", async () => {
const app = fastify();
app.get("/", getAll);
const response = await app.inject({
method: "GET",
url: "/",
});
expect(response.statusCode).to.equal(200);
expect(response.headers["content-type"]).to.equal("application/json; charset=utf-8");
const persons = JSON.parse(response.body);
expect(persons.length).to.equal(1);
expect(persons[0].firstName).to.equal("Rick");
expect(persons[0].lastName).to.equal("Sanchez");
});
});
6 changes: 3 additions & 3 deletions src/handler/persons.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// import { FastifyRequest, FastifyReply } from "fastify";
import { FastifyRequest, FastifyReply } from "fastify";
import { Person } from "../types/Person";

export async function getAll(/* req: FastifyRequest, reply: FastifyReply */): Promise<Person[]> {
// reply.type("application/json").code(200);
export async function getAll(req: FastifyRequest, reply: FastifyReply): Promise<Person[]> {
reply.type("application/json; charset=utf-8").code(200);
return [new Person({
firstName: "Rick",
lastName: "Sanchez",
Expand Down
6 changes: 4 additions & 2 deletions src/routes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { FastifyInstance } from "fastify";
import * as persons from "./handler/persons";
import { getAll } from "./handler/persons";
import { hello } from "./handler/hello";

export function register(app: FastifyInstance): void {
app.get("/persons", persons.getAll);
app.get("/", hello);
app.get("/persons", getAll);
}
4 changes: 4 additions & 0 deletions src/unused.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// intentionally uncovered to show nyc corectly finds unused files as well.
export function unused(): void {
console.log("This should be uncovered code");
}
61 changes: 61 additions & 0 deletions test/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { expect, use } from "chai";
import * as chaiAsPromised from "chai-as-promised";
import * as sinon from "sinon";
import * as routes from "../src/routes";
import * as fastify from "fastify";

use(chaiAsPromised);
describe("Integration", () => {

let sandbox: sinon.SinonSandbox;
beforeEach(() => {
sandbox = sinon.createSandbox();
});

afterEach(() => {
sandbox.restore();
});

const fakeFastify: any = {
listen: sinon.spy(),
get: sinon.spy(),
log: {
error: sinon.spy(),
},
server: {
close: sinon.spy(),
},
};

before(() => {
const fastifyStub = sinon.stub(fastify, "fastify");
fastifyStub.returns(fakeFastify);
});

let app: any;
it("Successful app startup", async () => {
const mock = sandbox.mock(routes);

// conditional loading as we can only test this when module loads FIRST time as its auto executing!
// This is just as app auto executes itself on start
app = await import("../src/app");

mock.expects("register").calledOnce;
expect(fakeFastify.listen.calledOnce, "listen called once").to.be.true;
expect(fakeFastify.get.calledTwice, "get called twice").to.be.true;
});

it("Failed app startup", async () => {
const exitStub = sandbox.stub(process, "exit");
fakeFastify.listen = () => { throw new Error(); };
await app.start();
expect(fakeFastify.log.error.calledOnce, "log.error called once").to.be.true;
expect(exitStub.calledOnce, "process.exit called once").to.be.true;
});

it("Close the server", async () => {
await app.stop();
expect(fakeFastify.server.close.calledOnce, "server close called once").to.be.true;
});
});
53 changes: 0 additions & 53 deletions test/integration.ts

This file was deleted.

0 comments on commit 1bd093c

Please sign in to comment.