From 211e0102e4ed27c0845b009960646198911f84b8 Mon Sep 17 00:00:00 2001 From: jauco noordzij Date: Mon, 20 Apr 2015 21:53:08 +0200 Subject: [PATCH 01/11] Updated readme to mention next release --- README.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6f5c03b6..c354ed1d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ +**NOTE: you probably want the @next version of jester tester!** + +You can install it using `npm install jester-tester@next`. I've been working on it for a while now and it has a bunch of needed improvements such as being able to configure webpack and eslint directly. However I'm currently beta testing it and I have yet to add a migration script. Eslint is doing a lot of breaking changes at the moment while they're ramping up for their 1.0 release so I won't make the @next version the default until after the 1.0 eslint release. I also might replace karma with testem before that. + +But me and my team are using the @next version full time, so it probably won't delete your entire file system. I encourage new jester users to start with the @next version. Just be aware that you might have a non-automatic upgrades (usually changing some settings, renaming some properties) for new releases. + +If you encounter anything: let me know at https://github.com/jauco/jester/issues ! + + #Jester >Get your project tested and out there with minimal fuss. @@ -15,7 +24,7 @@ The goal of Jester is to give you a bootstrap for integrating these tools so you 1. Install [node.js](http://nodejs.org/download/) 2. Create a directory for your app `mkdir myApp; cd myApp` 3. Add a basic machine readable description of your app `npm init` - 4. Install jester from npm and save it into the development dependencies. Under windows you'll have to run this as administrator (required by jsdoc for creating symlinks): + 4. Install jester from npm and save it into the development dependencies. Under windows you'll have to run this as administrator (required by jsdoc for creating symlinks): `npm install --save-dev jester-tester` ## Creating a project @@ -127,7 +136,7 @@ describe("Greetings", function() { ``` This test asserts that the function hello will return the string `hello tested world`. -The test will run upon saving it if jester-watch is running, or else when you +The test will run upon saving it if jester-watch is running, or else when you execute jester-batch. Jester will now run your tests in the browsers as specified in `jester.js`. Of @@ -144,7 +153,7 @@ module.exports = hello; ##Dependency injection Jester makes it easy to replace a 'require'd module in the source file with a -test-stub. +test-stub. Let's say we have a file called src/lib/db.js ```javascript @@ -196,7 +205,7 @@ what happens under the hood. It's not really magical. ## Generating documentation from source -Documentation will be generated from appropriately annotated sources by jsdoc and includes the syntax highlighted source code. See [usejsdoc](http://usejsdoc.org/) for how to annotate your code, especially relevant is [Document CommonJS Modules](http://usejsdoc.org/howto-commonjs-modules.html). +Documentation will be generated from appropriately annotated sources by jsdoc and includes the syntax highlighted source code. See [usejsdoc](http://usejsdoc.org/) for how to annotate your code, especially relevant is [Document CommonJS Modules](http://usejsdoc.org/howto-commonjs-modules.html). There are many ways to export and document code. The recommended way to export functions is: @@ -204,7 +213,7 @@ There are many ways to export and document code. The recommended way to export f * Deep clone an object * * @param {Object} obj - the object to clone - * @returns {Object} a deep clone of the original object + * @returns {Object} a deep clone of the original object * @see {@link http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object} */ function clone(obj) { @@ -215,8 +224,8 @@ There are many ways to export and document code. The recommended way to export f This enables jsdoc to recognize that clone is a (static) function, the clone symbol will show up in stack traces and is fully supported by IE8. -The api documentation will be written to a directory specified by the `apiDocPath` setting in `jester.json`, which defaults to `./doc/api/`. You can set the configuration option `readme` to point to a file that is a markdown formatted readme which will be included in the generated documentation on the homepage. +The api documentation will be written to a directory specified by the `apiDocPath` setting in `jester.json`, which defaults to `./doc/api/`. You can set the configuration option `readme` to point to a file that is a markdown formatted readme which will be included in the generated documentation on the homepage. -The api documentation will be generated when you run `jester-batch` or `jester-doc`. The latter is a bit faster because it *only* runs jsdoc. The documentation is *not* automatically updated when running `jester-watch`. +The api documentation will be generated when you run `jester-batch` or `jester-doc`. The latter is a bit faster because it *only* runs jsdoc. The documentation is *not* automatically updated when running `jester-watch`. -An additional benefit of annotating your code with jsdoc style comments is that there are a number of tools such as ide's and compilers which can take advantages of the additional information contained in those comments. \ No newline at end of file +An additional benefit of annotating your code with jsdoc style comments is that there are a number of tools such as ide's and compilers which can take advantages of the additional information contained in those comments. From f4ba91ffd82fae08eb15ea738ae94be990a00cbd Mon Sep 17 00:00:00 2001 From: jauco noordzij Date: Mon, 20 Apr 2015 21:55:32 +0200 Subject: [PATCH 02/11] Update i dependency because the author accidentally removed the 0.3.2 version from npm --- npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 37e9c03c..ad138445 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -353,8 +353,8 @@ "from": "deep-equal@0.2.1" }, "i": { - "version": "0.3.2", - "from": "i@0.3.2" + "version": "0.3.3", + "from": "i@0.3.3" }, "ncp": { "version": "0.4.2", diff --git a/package.json b/package.json index edc478d3..845a7869 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "jester-tester", "description": "Get your project tested and out there with minimal fuss.", "repository": "https://github.com/jauco/jester", - "version": "2.0.0", + "version": "2.0.1", "author": "Jauco Noordzij ", "bin": { "jester-watch": "./src/bin/jester-watch.js", From 30c7331267bb26ba1fab7e873ad60cd1b12c5980 Mon Sep 17 00:00:00 2001 From: Oscar de Groot Date: Wed, 13 May 2015 11:15:41 +0200 Subject: [PATCH 03/11] The debug instructions didn't work (anymore). Changed them to something that works. --- HACKING.md | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/HACKING.md b/HACKING.md index 5b0c53af..d75c2681 100644 --- a/HACKING.md +++ b/HACKING.md @@ -1,25 +1,17 @@ # How to debug Jester -You attach a graphical debugger ([node-inspector]) to jester. +You attach a graphical debugger ([Node Inspector]) to jester. -- Install [node-inspector] somewhere. Doesn't matter where. +- Install [Node Inspector] somewhere. Doesn't matter where. $ npm install node-inspector -- Start node-inspector. - - $ node_modules/.bin/node-inspector - Node Inspector v0.7.4 - Visit http://127.0.0.1:8080/debug?port=5858 to start debugging. - - *node-inspector* now waits for the process-to-debug on port 5858, and for you on port 8080. - - Start jester in debug mode. - $ node --debug-brk node_modules/jester-tester/src/bin/jester-watch.js + $ node-debug node_modules/jester-tester/src/bin/jester-watch.js debugger listening on port 5858 -- Browse to http://127.0.0.1:8080/debug?port=5858. +- Node Inspector opens http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 in a browser. - Place your breakpoints and press the play button to start running jester. -[node-inspector]: https://npmjs.org/package/node-inspector +[Node Inspector]: https://npmjs.org/package/node-inspector From 8c925f76a3d405379418d65a4f2ed4c932e2f6c0 Mon Sep 17 00:00:00 2001 From: Oscar de Groot Date: Wed, 13 May 2015 13:17:19 +0200 Subject: [PATCH 04/11] Removing 'string' suffix on each error line. This was introduced by commit 93f78302b06c4a8eb0a3e94cf183eddc137a714b and that was presumably unintentional. --- src/lib/handleWebpackResult.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/handleWebpackResult.js b/src/lib/handleWebpackResult.js index 3f2de0a8..dd10488d 100644 --- a/src/lib/handleWebpackResult.js +++ b/src/lib/handleWebpackResult.js @@ -17,7 +17,7 @@ module.exports = function handleWebpackResult(stats, webpackWarningFilters) { var logErrorsByLine = function (errors) { byLine(errors, function (err) { - console.log(" ", err, typeof err); + console.log(" ", err); }); }; From fd80c53bd5f2c270d9f8e5a75af98eb34f2261f1 Mon Sep 17 00:00:00 2001 From: Oscar de Groot Date: Wed, 13 May 2015 16:37:29 +0200 Subject: [PATCH 05/11] WIP --- src/lib/handleWebpackResult.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/lib/handleWebpackResult.js b/src/lib/handleWebpackResult.js index 8bbcdf2d..f1057433 100644 --- a/src/lib/handleWebpackResult.js +++ b/src/lib/handleWebpackResult.js @@ -2,7 +2,8 @@ module.exports = function handleWebpackResult(stats, webpackWarningFilters) { if (stats) { if (filterConfigIsValid(webpackWarningFilters)) { - stats.compilation.warnings = filterWebpackWarnings(stats.compilation.warnings, webpackWarningFilters); + // stats.compilation.errors = filterWebpackSoftErrors(stats.compilation.errors, webpackWarningFilters.softErrors); + stats.compilation.warnings = filterWebpackWarnings(stats.compilation.warnings, webpackWarningFilters.warnings); } stats = stats.toJson(); } @@ -57,6 +58,8 @@ function filterConfigIsSupported(webpackWarningFilter) { * @return {bool} whether it is sane */ function filterConfigIsValid(webpackWarningFilters) { + return true; + // TODO adjust this var result = true; if (webpackWarningFilters) { if (Array.isArray(webpackWarningFilters)) { @@ -84,8 +87,8 @@ function filterConfigIsValid(webpackWarningFilters) { return result; } -function filterWebpackWarnings(unfilteredWarnings, webpackWarningFilters) { - if (!webpackWarningFilters) { +function filterWebpackWarnings(unfilteredWarnings, warningFilters) { + if (!warningFilters) { // No filters are configured. Use the complete, unfiltered list of warnings. return unfilteredWarnings; } @@ -98,8 +101,8 @@ function filterWebpackWarnings(unfilteredWarnings, webpackWarningFilters) { return true; } - for (var i = 0; i < webpackWarningFilters.length; i++) { - var webpackWarningFilter = webpackWarningFilters[i]; + for (var i = 0; i < warningFilters.length; i++) { + var webpackWarningFilter = warningFilters[i]; if ( warning.origin.rawRequest === webpackWarningFilter["origin/rawRequest"] && warning.dependencies.length > 0 From f9f2b31bdec4b46c739079b3e0b534f3b84ba5d4 Mon Sep 17 00:00:00 2001 From: Oscar de Groot Date: Wed, 20 May 2015 10:59:47 +0200 Subject: [PATCH 06/11] Renaming webpack 'warnings' to 'alerts', so that they can cover both warnings and soft errors. --- src/bin/jester-batch.js | 2 +- src/bin/jester-watch.js | 4 +- src/lib/createTestFile.js | 4 +- src/lib/handleWebpackResult.js | 70 +++++++++++++++++----------------- src/lib/rebuildProject.js | 4 +- src/lib/runAllTests.js | 2 +- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/bin/jester-batch.js b/src/bin/jester-batch.js index a45be401..cc65fe1f 100755 --- a/src/bin/jester-batch.js +++ b/src/bin/jester-batch.js @@ -11,7 +11,7 @@ var loadConfig = require("../lib/loadConfig"), var config = loadConfig(); -rebuildProject(config.webpackOptions, config.fullEntryGlob, config.webpackWarningFilters) +rebuildProject(config.webpackOptions, config.fullEntryGlob, config.webpackAlertFilters) .then(function() { if(config.srcPath && config.apiDocPath) { return rebuildDocumentation(config.srcPath, config.apiDocPath, config.jsdocConf, config.readme); diff --git a/src/bin/jester-watch.js b/src/bin/jester-watch.js index 5867ccf0..3ebea8d8 100755 --- a/src/bin/jester-watch.js +++ b/src/bin/jester-watch.js @@ -33,7 +33,7 @@ function runTests(path) { console.log("No tests found for '" + path + "'"); return false; } - return createTestFile(testFiles, config.srcPath, config.webpackOptions, config.karmaPath, config.webpackWarningFilters).then(function () { + return createTestFile(testFiles, config.srcPath, config.webpackOptions, config.karmaPath, config.webpackAlertFilters).then(function () { return server.run(); }); }); @@ -65,7 +65,7 @@ function startWatching() { } if (filePath.length > 3 && filePath.substr(-3) === ".js") { - var build = rebuildProject(config.webpackOptions, config.fullEntryGlob, config.webpackWarningFilters); + var build = rebuildProject(config.webpackOptions, config.fullEntryGlob, config.webpackAlertFilters); if (isReallyFileChangeEvent(changeType, fileCurrentStat, filePreviousStat)) { when.join(build, runTests(filePath)).done(function(){}); } else { diff --git a/src/lib/createTestFile.js b/src/lib/createTestFile.js index d8bc449c..ed1bc695 100644 --- a/src/lib/createTestFile.js +++ b/src/lib/createTestFile.js @@ -19,7 +19,7 @@ function createEntryModules(srcPath, filenames) { return entryModules; } -module.exports = function createTestFile(filenames, srcPath, webpackConfig, karmaPath, webpackWarningFilters) { +module.exports = function createTestFile(filenames, srcPath, webpackConfig, karmaPath, webpackAlertFilters) { var config = Object.create(webpackConfig); config.output = Object.create(webpackConfig.output); config.output.path = karmaPath; @@ -27,6 +27,6 @@ module.exports = function createTestFile(filenames, srcPath, webpackConfig, karm config.output = Object.create(config.output || {}); config.output.filename = "[name].karmatest.js"; return webpack(config).then(function(stats) { - return handleWebpackResult(stats, webpackWarningFilters); + return handleWebpackResult(stats, webpackAlertFilters); }); }; diff --git a/src/lib/handleWebpackResult.js b/src/lib/handleWebpackResult.js index f1057433..f28537ee 100644 --- a/src/lib/handleWebpackResult.js +++ b/src/lib/handleWebpackResult.js @@ -1,9 +1,9 @@ "use strict"; -module.exports = function handleWebpackResult(stats, webpackWarningFilters) { +module.exports = function handleWebpackResult(stats, webpackAlertFilters) { if (stats) { - if (filterConfigIsValid(webpackWarningFilters)) { - // stats.compilation.errors = filterWebpackSoftErrors(stats.compilation.errors, webpackWarningFilters.softErrors); - stats.compilation.warnings = filterWebpackWarnings(stats.compilation.warnings, webpackWarningFilters.warnings); + if (filterConfigIsValid(webpackAlertFilters)) { + stats.compilation.errors = filterWebpackAlerts(stats.compilation.errors, webpackAlertFilters); + stats.compilation.warnings = filterWebpackAlerts(stats.compilation.warnings, webpackAlertFilters); } stats = stats.toJson(); } @@ -44,30 +44,30 @@ module.exports = function handleWebpackResult(stats, webpackWarningFilters) { }; -function filterConfigIsSupported(webpackWarningFilter) { - return "name" in webpackWarningFilter - && "origin/rawRequest" in webpackWarningFilter - && "dependencies/0/request" in webpackWarningFilter - && Object.keys(webpackWarningFilter).length === 3 // That is, webpackWarningFilter contains no keys other than these three. - && webpackWarningFilter.name === "ModuleNotFoundError"; +function filterConfigIsSupported(webpackAlertFilter) { + return "name" in webpackAlertFilter + && "origin/rawRequest" in webpackAlertFilter + && "dependencies/0/request" in webpackAlertFilter + && Object.keys(webpackAlertFilter).length === 3 // That is, webpackAlertFilter contains no keys other than these three. + && webpackAlertFilter.name === "ModuleNotFoundError"; } /** - * Checks the sanity of the webpackWarningFilters-configuration. - * @param {Array} webpackWarningFilters - the filter configuration. + * Checks the sanity of the webpackAlertFilters-configuration. + * @param {Array} webpackAlertFilters - the filter configuration. * @return {bool} whether it is sane */ -function filterConfigIsValid(webpackWarningFilters) { +function filterConfigIsValid(webpackAlertFilters) { return true; // TODO adjust this var result = true; - if (webpackWarningFilters) { - if (Array.isArray(webpackWarningFilters)) { - for (var i = 0; i < webpackWarningFilters.length; i++) { - if (!filterConfigIsSupported(webpackWarningFilters[i])) { + if (webpackAlertFilters) { + if (Array.isArray(webpackAlertFilters)) { + for (var i = 0; i < webpackAlertFilters.length; i++) { + if (!filterConfigIsSupported(webpackAlertFilters[i])) { // This filter config isn't supported. Abort. console.warn( - "config.webpackWarningFilters[" + i + "] must be an object similar to {\n" + + "config.webpackAlertFilters[" + i + "] must be an object similar to {\n" + " 'name': 'ModuleNotFoundError',\n" + " 'origin/rawRequest': 'imports?process=>undefined!when',\n" + " 'dependencies/0/request': 'vertx'\n" + @@ -77,7 +77,7 @@ function filterConfigIsValid(webpackWarningFilters) { } } } else { - console.warn("config.webpackWarningFilters must be an array."); + console.warn("config.webpackAlertFilters must be an array."); result = false; } } else { @@ -87,37 +87,37 @@ function filterConfigIsValid(webpackWarningFilters) { return result; } -function filterWebpackWarnings(unfilteredWarnings, warningFilters) { - if (!warningFilters) { - // No filters are configured. Use the complete, unfiltered list of warnings. - return unfilteredWarnings; +function filterWebpackAlerts(unfilteredAlerts, alertFilters) { + if (!alertFilters) { + // No filters are configured. Use the complete, unfiltered list of alerts. + return unfilteredAlerts; } // There's at least one filter and all filter configs are supported. Do the actual filtering. - var filteredWarnings = unfilteredWarnings.filter(function filterWarning(warning, index) { - if (warning.name !== "ModuleNotFoundError") { - // filterWebpackWarnings only supports filtering of ModuleNotFoundError-warnings. - // This is some other kind of warning. Leave it in the list, so that it IS shown in Jester's output. + var filteredAlerts = unfilteredAlerts.filter(function filterAlert(alert, index) { + if (alert.name !== "ModuleNotFoundError") { + // filterWebpackAlerts only supports filtering of ModuleNotFoundError-alerts. + // This is some other kind of alert. Leave it in the list, so that it IS shown in Jester's output. return true; } - for (var i = 0; i < warningFilters.length; i++) { - var webpackWarningFilter = warningFilters[i]; + for (var i = 0; i < alertFilters.length; i++) { + var webpackAlertFilter = alertFilters[i]; if ( - warning.origin.rawRequest === webpackWarningFilter["origin/rawRequest"] - && warning.dependencies.length > 0 - && warning.dependencies[0].request === webpackWarningFilter["dependencies/0/request"] + alert.origin.rawRequest === webpackAlertFilter["origin/rawRequest"] + && alert.dependencies.length > 0 + && alert.dependencies[0].request === webpackAlertFilter["dependencies/0/request"] ) { - // This warning matches one of the filters. + // This alert matches one of the filters. // Remove it from the list, so that it is NOT shown in Jester's output. return false; } } - // This warning matches none of the filters. + // This alert matches none of the filters. // Leave it in the list, so that it IS shown in Jester's output. return true; }); - return filteredWarnings; + return filteredAlerts; } diff --git a/src/lib/rebuildProject.js b/src/lib/rebuildProject.js index 705286b6..29260b5c 100644 --- a/src/lib/rebuildProject.js +++ b/src/lib/rebuildProject.js @@ -18,7 +18,7 @@ function createEntryModules(featureFiles) { return entryModules; } -module.exports = function rebuildProject(webpackConfig, entryGlob, webpackWarningFilters) { +module.exports = function rebuildProject(webpackConfig, entryGlob, webpackAlertFilters) { return glob(entryGlob) .then(function (featureFiles) { var config = Object.create(webpackConfig); @@ -26,6 +26,6 @@ module.exports = function rebuildProject(webpackConfig, entryGlob, webpackWarnin return webpack(config); }) .then(function (stats){ - return handleWebpackResult(stats, webpackWarningFilters); + return handleWebpackResult(stats, webpackAlertFilters); }); }; diff --git a/src/lib/runAllTests.js b/src/lib/runAllTests.js index 121f5aee..6765d776 100644 --- a/src/lib/runAllTests.js +++ b/src/lib/runAllTests.js @@ -17,7 +17,7 @@ module.exports = function runAllTests(config) { return getTestFiles(config.srcPath); }) .then(function (testInputFiles) { - return createTestFile(testInputFiles, config.srcPath, config.webpackOptions, config.karmaPath, config.webpackWarningFilters); + return createTestFile(testInputFiles, config.srcPath, config.webpackOptions, config.karmaPath, config.webpackAlertFilters); }) .catch(function(err) { console.error("failed creating test files ", err); From 5ec75b8d4974e5496241a8ab2ccf71554777c108 Mon Sep 17 00:00:00 2001 From: Oscar de Groot Date: Wed, 20 May 2015 11:33:58 +0200 Subject: [PATCH 07/11] Now separating filters for soft errors/warnings. --- src/lib/handleWebpackResult.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/lib/handleWebpackResult.js b/src/lib/handleWebpackResult.js index f28537ee..8cdf727a 100644 --- a/src/lib/handleWebpackResult.js +++ b/src/lib/handleWebpackResult.js @@ -2,8 +2,14 @@ module.exports = function handleWebpackResult(stats, webpackAlertFilters) { if (stats) { if (filterConfigIsValid(webpackAlertFilters)) { - stats.compilation.errors = filterWebpackAlerts(stats.compilation.errors, webpackAlertFilters); - stats.compilation.warnings = filterWebpackAlerts(stats.compilation.warnings, webpackAlertFilters); + var softErrorFilters = webpackAlertFilters.filter(function isSoftErrorFilter(filter) { + return filter.severity === "softError"; + }); + var warningFilters = webpackAlertFilters.filter(function isWarningFilter(filter) { + return filter.severity === "warning"; + }); + stats.compilation.errors = filterWebpackAlerts(stats.compilation.errors, softErrorFilters); + stats.compilation.warnings = filterWebpackAlerts(stats.compilation.warnings, warningFilters); } stats = stats.toJson(); } @@ -94,7 +100,7 @@ function filterWebpackAlerts(unfilteredAlerts, alertFilters) { } // There's at least one filter and all filter configs are supported. Do the actual filtering. - var filteredAlerts = unfilteredAlerts.filter(function filterAlert(alert, index) { + var filteredAlerts = unfilteredAlerts.filter(function isShown(alert) { if (alert.name !== "ModuleNotFoundError") { // filterWebpackAlerts only supports filtering of ModuleNotFoundError-alerts. // This is some other kind of alert. Leave it in the list, so that it IS shown in Jester's output. From 5fdfec78e1c1fa43d103c3d4a140c7790e02d99d Mon Sep 17 00:00:00 2001 From: Oscar de Groot Date: Wed, 20 May 2015 13:30:27 +0200 Subject: [PATCH 08/11] handleWebpackResult now doesn't error out when you don't specify any webpackAlertFilters. --- src/lib/handleWebpackResult.js | 38 +++++++++++++++------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/lib/handleWebpackResult.js b/src/lib/handleWebpackResult.js index 8cdf727a..95074dd0 100644 --- a/src/lib/handleWebpackResult.js +++ b/src/lib/handleWebpackResult.js @@ -1,7 +1,7 @@ "use strict"; module.exports = function handleWebpackResult(stats, webpackAlertFilters) { if (stats) { - if (filterConfigIsValid(webpackAlertFilters)) { + if (webpackAlertFilters && filterConfigIsValid(webpackAlertFilters)) { var softErrorFilters = webpackAlertFilters.filter(function isSoftErrorFilter(filter) { return filter.severity === "softError"; }); @@ -66,29 +66,25 @@ function filterConfigIsSupported(webpackAlertFilter) { function filterConfigIsValid(webpackAlertFilters) { return true; // TODO adjust this - var result = true; - if (webpackAlertFilters) { - if (Array.isArray(webpackAlertFilters)) { - for (var i = 0; i < webpackAlertFilters.length; i++) { - if (!filterConfigIsSupported(webpackAlertFilters[i])) { - // This filter config isn't supported. Abort. - console.warn( - "config.webpackAlertFilters[" + i + "] must be an object similar to {\n" + - " 'name': 'ModuleNotFoundError',\n" + - " 'origin/rawRequest': 'imports?process=>undefined!when',\n" + - " 'dependencies/0/request': 'vertx'\n" + - "}." - ); - result = false; - } + var result; + if (Array.isArray(webpackAlertFilters)) { + result = true; + for (var i = 0; i < webpackAlertFilters.length; i++) { + if (!filterConfigIsSupported(webpackAlertFilters[i])) { + // This filter config isn't supported. Abort. + console.warn( + "config.webpackAlertFilters[" + i + "] must be an object similar to {\n" + + " 'name': 'ModuleNotFoundError',\n" + + " 'origin/rawRequest': 'imports?process=>undefined!when',\n" + + " 'dependencies/0/request': 'vertx'\n" + + "}." + ); + result = false; } - } else { - console.warn("config.webpackAlertFilters must be an array."); - result = false; } } else { - // No filters are configured. That's okay. - result = true; + console.warn("config.webpackAlertFilters must be an array."); + result = false; } return result; } From 079f534b67d8f799a65d8b8cb35eab92cd2fc5de Mon Sep 17 00:00:00 2001 From: Oscar de Groot Date: Wed, 20 May 2015 13:31:27 +0200 Subject: [PATCH 09/11] filterWebpackAlerts now supports multiple kinds of filters. --- src/lib/handleWebpackResult.js | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/lib/handleWebpackResult.js b/src/lib/handleWebpackResult.js index 95074dd0..c79c1fa7 100644 --- a/src/lib/handleWebpackResult.js +++ b/src/lib/handleWebpackResult.js @@ -97,19 +97,10 @@ function filterWebpackAlerts(unfilteredAlerts, alertFilters) { // There's at least one filter and all filter configs are supported. Do the actual filtering. var filteredAlerts = unfilteredAlerts.filter(function isShown(alert) { - if (alert.name !== "ModuleNotFoundError") { - // filterWebpackAlerts only supports filtering of ModuleNotFoundError-alerts. - // This is some other kind of alert. Leave it in the list, so that it IS shown in Jester's output. - return true; - } - for (var i = 0; i < alertFilters.length; i++) { var webpackAlertFilter = alertFilters[i]; - if ( - alert.origin.rawRequest === webpackAlertFilter["origin/rawRequest"] - && alert.dependencies.length > 0 - && alert.dependencies[0].request === webpackAlertFilter["dependencies/0/request"] - ) { + var matches = matchers[webpackAlertFilter.name]; + if (matches(alert, webpackAlertFilter)) { // This alert matches one of the filters. // Remove it from the list, so that it is NOT shown in Jester's output. return false; @@ -123,3 +114,17 @@ function filterWebpackAlerts(unfilteredAlerts, alertFilters) { return filteredAlerts; } + +var matchers = { + ModuleNotFoundError: function matches(alert, webpackAlertFilter) { + return alert.name === "ModuleNotFoundError" + && alert.origin.rawRequest === webpackAlertFilter["origin/rawRequest"] + && alert.dependencies.length > 0 + && alert.dependencies[0].request === webpackAlertFilter["dependencies/0/request"]; + }, + CriticalDependenciesWarning: function matches(alert, webpackAlertFilter) { + return alert.name === "CriticalDependenciesWarning" + && alert.origin.rawRequest === webpackAlertFilter["origin/rawRequest"] + && alert.origin.blocks[0].expr.type === webpackAlertFilter["origin/blocks/0/expr/type"]; + }, +}; From 59d59bbcb65687f90d61e051f08e79eb69c2440c Mon Sep 17 00:00:00 2001 From: Oscar de Groot Date: Wed, 20 May 2015 14:12:00 +0200 Subject: [PATCH 10/11] Updating filterConfigIsValid() --- src/lib/handleWebpackResult.js | 41 ++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/lib/handleWebpackResult.js b/src/lib/handleWebpackResult.js index c79c1fa7..535b5a0f 100644 --- a/src/lib/handleWebpackResult.js +++ b/src/lib/handleWebpackResult.js @@ -51,11 +51,19 @@ module.exports = function handleWebpackResult(stats, webpackAlertFilters) { }; function filterConfigIsSupported(webpackAlertFilter) { - return "name" in webpackAlertFilter - && "origin/rawRequest" in webpackAlertFilter - && "dependencies/0/request" in webpackAlertFilter - && Object.keys(webpackAlertFilter).length === 3 // That is, webpackAlertFilter contains no keys other than these three. - && webpackAlertFilter.name === "ModuleNotFoundError"; + if (webpackAlertFilter && webpackAlertFilter.name && webpackAlertFilter.justification) { + if (webpackAlertFilter.name === "ModuleNotFoundError") { + return "origin/rawRequest" in webpackAlertFilter + && "dependencies/0/request" in webpackAlertFilter; + } else if (webpackAlertFilter.name === "CriticalDependenciesWarning") { + return "origin/rawRequest" in webpackAlertFilter + && "origin/blocks/0/expr/type" in webpackAlertFilter; + } else { + return false; + } + } else { + return false; + } } /** @@ -64,8 +72,6 @@ function filterConfigIsSupported(webpackAlertFilter) { * @return {bool} whether it is sane */ function filterConfigIsValid(webpackAlertFilters) { - return true; - // TODO adjust this var result; if (Array.isArray(webpackAlertFilters)) { result = true; @@ -73,11 +79,22 @@ function filterConfigIsValid(webpackAlertFilters) { if (!filterConfigIsSupported(webpackAlertFilters[i])) { // This filter config isn't supported. Abort. console.warn( - "config.webpackAlertFilters[" + i + "] must be an object similar to {\n" + - " 'name': 'ModuleNotFoundError',\n" + - " 'origin/rawRequest': 'imports?process=>undefined!when',\n" + - " 'dependencies/0/request': 'vertx'\n" + - "}." + 'config.webpackAlertFilters[' + i + '] must be an object similar to either\n' + + '{\n' + + ' "severity": "softError" or "warning",\n' + + ' "name": "ModuleNotFoundError",\n' + + ' "justification": "Suppressing this alert is a good idea because ...",\n' + + ' "origin/rawRequest": "imports?process=>undefined!when",\n' + + ' "dependencies/0/request": "vertx"\n' + + '}\n' + + 'or\n' + + '{\n' + + ' "severity": "softError" or "warning",\n' + + ' "name": "CriticalDependenciesWarning",\n' + + ' "justification": "Suppressing this alert is a good idea because ...",\n' + + ' "origin/rawRequest": "localforage",\n' + + ' "origin/blocks/0/expr/type": "CallExpression"\n' + + '}\n' ); result = false; } From d2adde27cb5ecb3323c2b0b9b2bf169796fc03f2 Mon Sep 17 00:00:00 2001 From: Oscar de Groot Date: Wed, 20 May 2015 14:48:38 +0200 Subject: [PATCH 11/11] Adding some documentation to webpackAlertFilters. --- HACKING.md | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/HACKING.md b/HACKING.md index d75c2681..8caf1709 100644 --- a/HACKING.md +++ b/HACKING.md @@ -1,4 +1,4 @@ -# How to debug Jester +# How to debug jester You attach a graphical debugger ([Node Inspector]) to jester. @@ -15,3 +15,46 @@ You attach a graphical debugger ([Node Inspector]) to jester. - Place your breakpoints and press the play button to start running jester. [Node Inspector]: https://npmjs.org/package/node-inspector + +# Suppressing webpack errors/warnings + +Webpack can return three kinds of alerts (http://webpack.github.io/docs/node.js-api.html#error-handling): + +- Fatal errors - webpack was not able to build. +- Soft errors - webpack was able to build, but it'll probably break if you try to run it. +- Warnings - webpack was able to build and it'll probably work, but there are some code paths that break. + +Some soft errors / warnings are false positives, +in the sense that the scenario in which these cause a failure is guaranteed never to occur in practice. + +You can tell jester to suppress these false positives by adding the following to your `jester.json`. + +```json +{ + ... + "webpackAlertFilters": [ + { + "severity": "softError" or "warning", + "name": "ModuleNotFoundError", + "justification": "Suppressing this alert is a good idea because ...", + "origin/rawRequest": "imports?process=>undefined!when", + "dependencies/0/request": "vertx" + }, + { + "severity": "softError" or "warning", + "name": "CriticalDependenciesWarning", + "justification": "Suppressing this alert is a good idea because ...", + "origin/rawRequest": "localforage", + "origin/blocks/0/expr/type": "CallExpression" + } + ] +} +``` + +Sadly, figuring out exactly which values to configure is not easy: +they're not visible in jester's console output. +To get a hold of them, [debug jester](#how-to-debug-jester) and place a breakpoint in `src/lib/handleWebpackResult.js`. +Then build some code that triggers the alert that you wish to suppress. +This will hit the breakpoint. +Inspect the contents of `stats.compilation.errors` and/or `stats.compilation.warnings` +to see which values you should add to your configuration.