From fa976cac9a2584b3c327a5a73f76ee4567b75c8a Mon Sep 17 00:00:00 2001 From: Xymorot Date: Thu, 10 Oct 2019 23:07:33 +0200 Subject: [PATCH] test: add simple unit test with sinon and nock, also refactor 'test' directory to 'tests', split tests into integration and unit --- .eslintignore | 2 +- .gitignore | 4 +- .mocharc.yml | 2 +- forge.config.js | 2 +- package-lock.json | 158 ++++++++++++++++++- package.json | 9 +- {test => tests}/integration/main.spec.ts | 0 tests/unit/main/services/web-crawler.spec.ts | 42 +++++ 8 files changed, 209 insertions(+), 10 deletions(-) rename {test => tests}/integration/main.spec.ts (100%) create mode 100644 tests/unit/main/services/web-crawler.spec.ts diff --git a/.eslintignore b/.eslintignore index 96a5ee8..5858b0d 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,5 @@ node_modules src/**/*.js -test/**/*.js +tests/**/*.js frontend out diff --git a/.gitignore b/.gitignore index 201e536..fd1211e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,8 @@ node_modules # generated code /src/**/*.js /src/**/*.js.map -/test/**/*.js -/test/**/*.js.map +/tests/**/*.js +/tests/**/*.js.map /frontend /index.html diff --git a/.mocharc.yml b/.mocharc.yml index 31a966c..1f601b1 100644 --- a/.mocharc.yml +++ b/.mocharc.yml @@ -1 +1 @@ -spec: 'test/**/*spec.js' +# https://github.com/mochajs/mocha/blob/master/example/config diff --git a/forge.config.js b/forge.config.js index 099c254..96516c6 100644 --- a/forge.config.js +++ b/forge.config.js @@ -6,7 +6,7 @@ const ignoreList = [ /^\/node_modules\/\.cache($|\/)/, /^\/src\/.*\.(ts|js\.map)/, /^\/store($|\/)/, - /^\/test($|\/)/, + /^\/tests($|\/)/, /^\/\.editorconfig/, /^\/\.eslintignore/, /^\/\.eslintrc\.json/, diff --git a/package-lock.json b/package-lock.json index 1dc7cff..f01f4fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -388,6 +388,50 @@ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "dev": true }, + "@sinonjs/commons": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.6.0.tgz", + "integrity": "sha512-w4/WHG7C4WWFyE5geCieFJF6MZkbW4VAriol5KlmQXpAQdxvV0p26sqNZOW6Qyw6Y0l9K4g+cHvvczR2sEEpqg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", + "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "@sinonjs/samsam": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "array-from": "^2.1.1", + "lodash": "^4.17.15" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + } + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -497,9 +541,9 @@ "dev": true }, "@types/node": { - "version": "12.7.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.11.tgz", - "integrity": "sha512-Otxmr2rrZLKRYIybtdG/sgeO+tHY20GxeDjcGmUnmmlCWyEnv2a2x1ZXBo3BTec4OiTXMQCiazB8NMBf0iRlFw==", + "version": "12.7.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.12.tgz", + "integrity": "sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ==", "dev": true }, "@types/node-fetch": { @@ -517,6 +561,12 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, + "@types/sinon": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.5.0.tgz", + "integrity": "sha512-NyzhuSBy97B/zE58cDw4NyGvByQbAHNP9069KVSgnXt/sc0T6MFRh0InKAeBVHJWdSXG1S3+PxgVIgKo9mTHbw==", + "dev": true + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -1045,6 +1095,12 @@ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, "array-initial": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", @@ -6115,6 +6171,12 @@ "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", "dev": true }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", @@ -6310,6 +6372,12 @@ "chalk": "^2.4.2" } }, + "lolex": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", + "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", + "dev": true + }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -6960,6 +7028,44 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "nise": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.2.tgz", + "integrity": "sha512-/6RhOUlicRCbE9s+94qCUsyE+pKlVJ5AhIv+jEE7ESKwnbXqulKZ1FYU+XAtHHWE9TinYvAxDUJAb912PwPoWA==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^4.1.0", + "path-to-regexp": "^1.7.0" + } + }, + "nock": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/nock/-/nock-11.4.0.tgz", + "integrity": "sha512-UrVEbEAvhyDoUttrS0fv3znhZ5nEJvlxqgmrC6Gb2Mf9cFci65RMK17e6EjDDQB57g5iwZw1TFnVvyeL0eUlhQ==", + "dev": true, + "requires": { + "chai": "^4.1.2", + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.13", + "mkdirp": "^0.5.0", + "propagate": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "node-abi": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.11.0.tgz", @@ -7704,6 +7810,23 @@ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", "dev": true }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -7897,6 +8020,12 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, + "propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "dev": true + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -8648,6 +8777,29 @@ "string-width": "^1.0.1" } }, + "sinon": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.5.0.tgz", + "integrity": "sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.4.0", + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/samsam": "^3.3.3", + "diff": "^3.5.0", + "lolex": "^4.2.0", + "nise": "^1.5.2", + "supports-color": "^5.5.0" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + } + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", diff --git a/package.json b/package.json index f0e3617..dd6481a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "typeorm:migrate:library": "typeorm migration:run -c library", "watch": "gulp build --watch --dev", "build": "gulp build", - "test": "mocha", + "test:integration": "mocha --spec tests/integration/**/*.spec.js", + "test:unit": "mocha --spec tests/unit/**/*.spec.js", + "test": "mocha --spec tests/**/*.spec.js", "lint": "npm run eslint && npm run tslint", "eslint-check": "eslint --print-config gulpfile.js | eslint-config-prettier-check", "eslint": "eslint .", @@ -24,7 +26,7 @@ "forge:start": "electron-forge start", "forge:make": "electron-forge --platform win32 --arch x64 make", "forge": "npm run build && npm run forge:make", - "precommit": "npm run prettier:write && npm run eslint-check && npm run tslint-check", + "precommit": "npm run test:unit && npm run prettier:write && npm run eslint-check && npm run tslint-check", "prepush": "npm run lint && npm run test" }, "dependencies": { @@ -44,6 +46,7 @@ "@types/mocha": "latest", "@types/node": "latest", "@types/node-fetch": "latest", + "@types/sinon": "^7.5.0", "@types/webdriverio": "^4.13.3", "@types/webpack": "latest", "chai": "^4.2.0", @@ -58,7 +61,9 @@ "husky": "^3.0.8", "minimist": "^1.2.0", "mocha": "^6.2.1", + "nock": "^11.4.0", "prettier": "latest", + "sinon": "^7.5.0", "spectron": "^8.0.0", "svelte": "^3.12.1", "svelte-loader": "^2.13.6", diff --git a/test/integration/main.spec.ts b/tests/integration/main.spec.ts similarity index 100% rename from test/integration/main.spec.ts rename to tests/integration/main.spec.ts diff --git a/tests/unit/main/services/web-crawler.spec.ts b/tests/unit/main/services/web-crawler.spec.ts new file mode 100644 index 0000000..308965a --- /dev/null +++ b/tests/unit/main/services/web-crawler.spec.ts @@ -0,0 +1,42 @@ +import { expect } from 'chai'; +import { afterEach, beforeEach, describe, it } from 'mocha'; +import nock from 'nock'; +import { Response } from 'node-fetch'; +import sinon from 'sinon'; +import { fetch } from '../../../../src/main/services/web-crawler'; + +describe('Web Crawler', function(): void { + this.timeout('2s'); + + beforeEach(() => { + if (!nock.isActive()) { + nock.activate(); + } + }); + + afterEach(() => { + nock.cleanAll(); + }); + + it('fetches websites', async () => { + const callback = sinon.spy(); + + const testUrl = 'https://example.com'; + nock(testUrl) + .get(/.*/) + .reply( + HttpCode.OK, + () => { + callback(); + return JSON.stringify([{ id: 12, comment: 'Hey there' }]); + }, + { 'Content-Type': 'application/json' } + ) + .persist(); + + const res: Response = await fetch(testUrl); + expect(callback.callCount).to.equal(1, 'multiple requests (or none) are sent when only one should be'); + const json = await res.json(); + expect(json).to.deep.equal([{ id: 12, comment: 'Hey there' }], 'response body is incorrect'); + }); +});