From 9c4ea85041963fec9d15a2502afc6428e2756486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Astori?= Date: Tue, 21 Nov 2017 20:21:51 -0500 Subject: [PATCH] Instrument client code before running tests Despite being a bit gross to look at, this brings a few advantages: - Tests are now closer to what actually runs, so more likely to find broken stuff. - We can start using things that were so far Webpack-only or browser-only, like ES6 imports, loading Handlebars templates, etc. - We open ourselves to browser testing (there is some work to do, but that would be a necessary step). - We improve the client/server separation, by making it possible to run them independently I do some extra steps around coverage: now we have 2 reports (client + server), so I have an extra step to combine them (the `nyc report` part). This is strictly to keep feature parity (the coverage report of this code is effectively the same as before), but in the near future, we might want to keep both reports separate, for example to continue separating client/server. Another reason would be to use something like Codecov, which I believe has the ability to have multiple reports. This is down the road though, our coverage is not good enough to make hosting them somewhere be useful (I think). A few extras with this commit: - Coverage summary is displayed when tests are run (this is not slowing down tests) - Tests check for leaks (see https://mochajs.org/#--check-leaks) - Tests now output with the `dot` reporter. This is nice as `npm test` runs in parallel, the whole output holds in a few lines instead of spanning over multiple screens. --- .nycrc | 15 ----- appveyor.yml | 3 +- package.json | 7 ++- test/.nycrc-mocha | 16 ++++++ test/.nycrc-mocha-webpack | 11 ++++ test/.nycrc-report | 6 ++ test/mocha-webpack.opts | 6 ++ test/mocha.opts | 5 +- webpack.config-test.js | 26 +++++++++ yarn.lock | 118 ++++++++++++++++++++++++++++++++++++-- 10 files changed, 188 insertions(+), 25 deletions(-) delete mode 100644 .nycrc create mode 100644 test/.nycrc-mocha create mode 100644 test/.nycrc-mocha-webpack create mode 100644 test/.nycrc-report create mode 100644 test/mocha-webpack.opts create mode 100644 webpack.config-test.js diff --git a/.nycrc b/.nycrc deleted file mode 100644 index 4f049f0c..00000000 --- a/.nycrc +++ /dev/null @@ -1,15 +0,0 @@ -{ - "all": true, - "exclude": [ - "coverage", - "public/", - "scripts/", - "test/", - "webpack.config.js" - ], - "reporter": [ - "lcov", - "text", - "text-summary" - ] -} diff --git a/appveyor.yml b/appveyor.yml index f835a8a9..9a401ad0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,7 +18,8 @@ install: - yarn --frozen-lockfile - yarn build - yarn add mocha-appveyor-reporter - - echo --reporter mocha-appveyor-reporter >> test/mocha.opts + - ps: (gc test/mocha.opts) -replace 'dot', 'mocha-appveyor-reporter' | sc test/mocha.opts + - ps: (gc test/mocha-webpack.opts) -replace 'dot', 'mocha-appveyor-reporter' | sc test/mocha-webpack.opts test_script: - node --version diff --git a/package.json b/package.json index 29d832ae..235865f7 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,14 @@ }, "homepage": "https://thelounge.chat/", "scripts": { - "coverage": "nyc mocha", + "coverage": "rm -rf .nyc_output/ && npm-run-all test:* && nyc --nycrc-path=test/.nycrc-report report", "start": "node index start", "start-dev": "npm-run-all --parallel watch start", "build": "webpack", "watch": "webpack --watch", "test": "npm-run-all --aggregate-output --parallel --continue-on-error test:* lint:*", - "test:mocha": "mocha --colors", + "test:mocha": "nyc --nycrc-path=test/.nycrc-mocha mocha --colors", + "test:mocha-webpack": "nyc --nycrc-path=test/.nycrc-mocha-webpack mocha-webpack --colors --opts=test/mocha-webpack.opts", "lint:js": "eslint . --report-unused-disable-directives --color", "lint:css": "stylelint --color \"client/**/*.css\"" }, @@ -75,9 +76,11 @@ "handlebars": "4.0.11", "handlebars-loader": "1.6.0", "intersection-observer": "0.5.0", + "istanbul-instrumenter-loader": "3.0.0", "jquery": "3.3.1", "jquery-ui": "1.12.1", "mocha": "5.0.1", + "mocha-webpack": "1.0.1", "mousetrap": "1.6.1", "npm-run-all": "4.1.2", "nyc": "11.4.1", diff --git a/test/.nycrc-mocha b/test/.nycrc-mocha new file mode 100644 index 00000000..fdd6c982 --- /dev/null +++ b/test/.nycrc-mocha @@ -0,0 +1,16 @@ +{ + "all": true, + "exclude": [ + "webpack.config*.js" + ], + "include": [ + "defaults", + "src", + "*.js" + ], + "reporter": [ + "json", + "text-summary" + ], + "clean": false +} diff --git a/test/.nycrc-mocha-webpack b/test/.nycrc-mocha-webpack new file mode 100644 index 00000000..1712592a --- /dev/null +++ b/test/.nycrc-mocha-webpack @@ -0,0 +1,11 @@ +{ + "all": true, + "include": [ + "client/" + ], + "reporter": [ + "json", + "text-summary" + ], + "clean": false +} diff --git a/test/.nycrc-report b/test/.nycrc-report new file mode 100644 index 00000000..33a96e55 --- /dev/null +++ b/test/.nycrc-report @@ -0,0 +1,6 @@ +{ + "reporter": [ + "lcov", + "text-summary" + ] +} diff --git a/test/mocha-webpack.opts b/test/mocha-webpack.opts new file mode 100644 index 00000000..dc1a0ec9 --- /dev/null +++ b/test/mocha-webpack.opts @@ -0,0 +1,6 @@ +--check-leaks +--interactive false +--recursive +--reporter dot +--webpack-config webpack.config-test.js +test/client/**/*.js diff --git a/test/mocha.opts b/test/mocha.opts index 09f51914..82fe802e 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1,2 +1,5 @@ ---require test/fixtures/env +--check-leaks --recursive +--reporter dot +--require test/fixtures/env +test/{,!(client)/**/}*.js diff --git a/webpack.config-test.js b/webpack.config-test.js new file mode 100644 index 00000000..1bb50859 --- /dev/null +++ b/webpack.config-test.js @@ -0,0 +1,26 @@ +"use strict"; + +const path = require("path"); +const webpack = require("webpack"); +const config = require("./webpack.config.js"); + +config.target = "node"; + +// Instrumentation for coverage with Istanbul +config.module.rules.push({ + test: /\.js$/, + include: path.resolve(__dirname, "client"), + use: { + loader: "istanbul-instrumenter-loader", + options: {esModules: true}, + }, + enforce: "post", +}); + +// `CommonsChunkPlugin` is incompatible with a `target` of `node`. +// See https://github.com/zinserjan/mocha-webpack/issues/84 +config.plugins = config.plugins.filter((a) => + !(a instanceof webpack.optimize.CommonsChunkPlugin) +); + +module.exports = config; diff --git a/yarn.lock b/yarn.lock index 7f13b2f6..60552292 100644 --- a/yarn.lock +++ b/yarn.lock @@ -60,7 +60,7 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: +ajv@^5.0.0, ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: @@ -1044,6 +1044,10 @@ camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -1145,7 +1149,7 @@ cheerio@0.22.0: lodash.reject "^4.4.0" lodash.some "^4.4.0" -chokidar@^1.7.0: +chokidar@^1.6.1, chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" dependencies: @@ -2404,6 +2408,16 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + globby@^7.0.0, globby@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" @@ -2758,7 +2772,7 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -interpret@^1.0.0: +interpret@^1.0.0, interpret@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" @@ -3019,6 +3033,15 @@ isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" +istanbul-instrumenter-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.0.tgz#9f553923b22360bac95e617aaba01add1f7db0b2" + dependencies: + convert-source-map "^1.5.0" + istanbul-lib-instrument "^1.7.3" + loader-utils "^1.1.0" + schema-utils "^0.3.0" + istanbul-lib-coverage@^1.1.1, istanbul-lib-coverage@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.2.tgz#4113c8ff6b7a40a1ef7350b01016331f63afde14" @@ -3029,7 +3052,7 @@ istanbul-lib-hook@^1.1.0: dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.9.1: +istanbul-lib-instrument@^1.7.3, istanbul-lib-instrument@^1.9.1: version "1.9.2" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.2.tgz#84905bf47f7e0b401d6b840da7bad67086b4aab6" dependencies: @@ -3274,6 +3297,10 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +lodash.assign@^4.0.3, lodash.assign@^4.0.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + lodash.assignin@^4.0.9: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" @@ -3432,7 +3459,7 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" -memory-fs@^0.4.0, memory-fs@~0.4.1: +memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" dependencies: @@ -3576,6 +3603,27 @@ mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: dependencies: minimist "0.0.8" +mocha-webpack@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mocha-webpack/-/mocha-webpack-1.0.1.tgz#96d80f711b82a9b5ee307883ce2a1b1794404f3c" + dependencies: + babel-runtime "^6.18.0" + chalk "^1.1.3" + chokidar "^1.6.1" + glob-parent "^2.0.0" + globby "^6.1.0" + interpret "^1.0.1" + is-glob "^2.0.1" + loader-utils "^1.1.0" + lodash "^4.3.0" + memory-fs "^0.4.1" + nodent-runtime "^3.0.3" + normalize-path "^2.0.1" + progress "^1.1.8" + source-map-support "^0.4.6" + toposort "^1.0.0" + yargs "^4.8.0" + mocha@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.1.tgz#759b62c836b0732382a62b6b1fb245ec1bc943ac" @@ -3688,6 +3736,10 @@ node-pre-gyp@^0.6.39: tar "^2.2.1" tar-pack "^3.4.0" +nodent-runtime@^3.0.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nodent-runtime/-/nodent-runtime-3.2.0.tgz#8b79500a1274176d732b60284c7a7d10d9e44180" + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -3882,6 +3934,12 @@ os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" @@ -4234,6 +4292,10 @@ process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" @@ -4704,6 +4766,12 @@ safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, s version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +schema-utils@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" + dependencies: + ajv "^5.0.0" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -4870,7 +4938,7 @@ source-list-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" -source-map-support@^0.4.15: +source-map-support@^0.4.15, source-map-support@^0.4.6: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" dependencies: @@ -5306,6 +5374,10 @@ to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" +toposort@^1.0.0: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" + tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" @@ -5644,6 +5716,10 @@ whatwg-fetch@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -5664,6 +5740,10 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -5737,6 +5817,13 @@ yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" +yargs-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + yargs-parser@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" @@ -5766,6 +5853,25 @@ yargs@^10.0.3: y18n "^3.2.1" yargs-parser "^8.1.0" +yargs@^4.8.0: + version "4.8.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + yargs@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360"