Skip to content

Commit

Permalink
feat: use jest (#1)
Browse files Browse the repository at this point in the history
* jest support

* add support for jest and mocha

* cleanup tests
  • Loading branch information
menduz authored May 22, 2021
1 parent b5aea9f commit baeb0c3
Show file tree
Hide file tree
Showing 13 changed files with 4,351 additions and 167 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
dist
node_modules
temp
tsdoc-metadata.json
tsdoc-metadata.json
coverage
4 changes: 1 addition & 3 deletions .mocharc.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
require:
- 'ts-node/register'
# - './test/setup.ts'
reporter:
- 'spec'
- list
reporter: spec
watch-files:
- 'dist/**/*.js'
- 'test/**/*.ts'
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ LOCAL_ARG = --local --verbose --diagnostics
endif

test:
./node_modules/.bin/jest --forceExit --detectOpenHandles --coverage --verbose
./node_modules/.bin/mocha

build:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# test-helpers
# test-helpers
13 changes: 13 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
globals: {
'ts-jest': {
tsconfig: 'tsconfig.json'
}
},
moduleFileExtensions: ['ts', 'js'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest'
},
testMatch: ['**/*.spec.(ts)'],
testEnvironment: 'node'
}
4,256 changes: 4,104 additions & 152 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@
"devDependencies": {
"@microsoft/api-extractor": "^7.12.1",
"@well-known-components/interfaces": "^1.1.0",
"typescript": "^4.2.4"
"typescript": "^4.2.4",
"mocha": "^8.4.0",
"@types/mocha": "^8.2.2",
"ts-node": "^9.1.1"
},
"dependencies": {
"@types/mocha": "^8.2.2",
"@types/jest": "^26.0.23",
"@types/sinon": "^10.0.0",
"expect": "^26.6.2",
"mocha": "^8.3.2",
"jest": "^26.6.3",
"sinon": "^10.0.0",
"ts-node": "^9.1.1"
"ts-jest": "^26.5.6"
},
"peerDependencies": {
"@well-known-components/interfaces": "^1.1.0"
Expand Down
16 changes: 14 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ export type TestArguments<TestComponents extends Record<string, any>> = {
}
}

declare var before: typeof beforeAll
declare var after: typeof afterAll

const _beforeAll: typeof beforeAll =
typeof beforeAll != "undefined" ? beforeAll : typeof before != "undefined" ? before : undefined!
const _afterAll: typeof beforeAll =
typeof afterAll != "undefined" ? afterAll : typeof after != "undefined" ? after : undefined!

if (!_beforeAll || !_afterAll) {
throw new Error("Neither before or beforeAll are defined in the globalThis")
}

/**
* Creates a test runner. Receives the same arguments as Lifecycle.run
* @public
Expand Down Expand Up @@ -60,7 +72,7 @@ export function createRunner<TestComponents extends Record<string, any>>(
}

describe(name, () => {
before(async () => {
_beforeAll(async () => {
program = await Lifecycle.run<TestComponents>(options)
})

Expand All @@ -78,7 +90,7 @@ export function createRunner<TestComponents extends Record<string, any>>(

suite(testArgs)

after(async () => {
_afterAll(async () => {
if (program) {
await program.stop()
}
Expand Down
86 changes: 86 additions & 0 deletions test/simple-smoke-test/jest.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import expect from "expect"
import { createRunner } from "../../src"

type Components = {
componentA: {
functionThatThrows(): void
}
componentB: {
sum(a: number, b: number): number
counter(): number
}
}

const test = createRunner<Components>({
async main(program) {
await program.startComponents()
},
async initComponents() {
let counter = 0

const componentA = {
functionThatThrows() {
throw new Error("ABC")
},
}
const componentB = {
sum(a: number, b: number) {
counter++
return a + b
},
counter() {
return counter
},
}

return { componentA, componentB }
},
})

if (typeof jest != "undefined") {
test("mocking component A", ({ components }) => {
it("tests without mock", async () => {
const { componentA } = components
expect(() => componentA.functionThatThrows()).toThrow("ABC")
})
it("tests with mock", async () => {
const { componentA } = components
const spy1 = jest.spyOn(componentA, "functionThatThrows")
spy1.mockImplementation(() => {
throw new Error("XYZ")
})
expect(() => componentA.functionThatThrows()).toThrow("XYZ")
expect(spy1).toHaveBeenCalledTimes(1)
})
})
}

test("mocking component B", ({ components }) => {
// this should throw because we are at "test declaration stage" and components don't exist yet
expect(() => components.componentB.sum(1, 2)).toThrow(
"Cannot get the components before the test program is initialized"
)

it("tests without mock", async () => {
const { componentB } = components
expect(componentB.counter()).toEqual(0)
expect(componentB.sum(1, 2)).toEqual(3)
expect(componentB.counter()).toEqual(1)
})

it("same components instances should be used inside tests of the same run", async () => {
const { componentB } = components
expect(componentB.counter()).toEqual(1)
})
if (typeof jest != "undefined") {
it("tests with mock", async () => {
const { componentB } = components
const spy1 = jest.spyOn(componentB, "sum")
spy1.mockImplementation((a, b) => {
return 4
})
expect(componentB.sum(1, 2)).toEqual(4)
expect(spy1).toHaveBeenCalledTimes(1)
})
}
})
120 changes: 120 additions & 0 deletions test/simple-smoke-test/mocha.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import expect from "expect"
import sinon from "sinon"
import { createRunner } from "../../src"

type Components = {
componentA: {
functionThatThrows(): void
}
componentB: {
sum(a: number, b: number): number
counter(): number
}
}

const test = createRunner<Components>({
async main(program) {
await program.startComponents()
},
async initComponents() {
let counter = 0

const componentA = {
functionThatThrows() {
throw new Error("ABC")
},
}
const componentB = {
sum(a: number, b: number) {
counter++
return a + b
},
counter() {
return counter
},
}

return { componentA, componentB }
},
})

test("mocking component A", ({ components, stubComponents }) => {
it("tests without mock", async () => {
const { componentA } = components
expect(() => componentA.functionThatThrows()).toThrow("ABC")
})
it("tests with mock", async () => {
const { componentA } = stubComponents
componentA.functionThatThrows.withArgs().throwsException(new Error("XYZ"))
expect(() => componentA.functionThatThrows()).toThrow("XYZ")
expect(componentA.functionThatThrows.calledOnce).toEqual(true)
})
})

test("mocking component B", ({ components, stubComponents }) => {
// this should throw because we are at "test declaration stage" and components don't exist yet
expect(() => components.componentB.sum(1, 2)).toThrow(
"Cannot get the components before the test program is initialized"
)

it("tests without mock", async () => {
const { componentB } = components
expect(componentB.counter()).toEqual(0)
expect(componentB.sum(1, 2)).toEqual(3)
expect(componentB.counter()).toEqual(1)
})

it("same components instances should be used inside tests of the same run", async () => {
const { componentB } = components
expect(componentB.counter()).toEqual(1)
})

it("tests with mock", async () => {
const { componentB } = stubComponents
componentB.sum.withArgs(1, 2).returns(4)
expect(componentB.sum(1, 2)).toEqual(4)
expect(componentB.sum.calledOnce).toEqual(true)
})
})

test("logic tests", ({ components, stubComponents }) => {
it("new components should be created for each test run", async () => {
const { componentB } = components
// the previous tests incremented the counter
expect(componentB.counter()).toEqual(0)
})
it("stubs could be used many times inside the same 'it'", async () => {
const { componentB } = stubComponents
componentB.counter.returns(12)
expect(componentB.counter()).toEqual(12)
componentB.counter.returns(15)
expect(componentB.counter()).toEqual(15)
// even without deconstructor
stubComponents.componentB.counter.returns(19)
expect(componentB.counter()).toEqual(19)
})
it("stubs should reset between test cases", async () => {
expect(components.componentB.counter()).toEqual(undefined)
})

it("accessing stub and real components should yield the same results", async () => {
stubComponents.componentB.counter.returns(33)
expect(components.componentB.counter()).toEqual(33)

expect(components.componentB).toEqual(stubComponents.componentB)
})

it("stub methods should be restorable", async () => {
stubComponents.componentB.counter.restore()
expect(stubComponents.componentB.counter()).toEqual(0)
})
it("restored stubs should remain that way between test cases", async () => {
expect(stubComponents.componentB.counter()).toEqual(0)
})
it("restored stubs should be re-stubabble", async () => {
sinon.stub(stubComponents.componentB, "counter")

stubComponents.componentB.counter.returns(33)
expect(components.componentB.counter()).toEqual(33)
})
})
1 change: 0 additions & 1 deletion test/simple-smoke-test/suite-with-lifecycle.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import expect from "expect"
import sinon from "sinon"
import { createRunner } from "../../src"

type Components = {
Expand Down
2 changes: 1 addition & 1 deletion test/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"sourceMap": true, /* Generates corresponding '.map' file. */
"types": [
"node",
"mocha"
"jest"
],
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"skipLibCheck": true, /* Skip type checking of declaration files. */
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"sourceMap": true, /* Generates corresponding '.map' file. */
"types": [
"node",
"mocha"
"jest"
],
"strict": true,
"outDir": "./dist", /* Redirect output structure to the directory. */
Expand Down

0 comments on commit baeb0c3

Please sign in to comment.