From 007fab803c3d8eacb8c3027262442cbd11283a31 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Mon, 11 May 2020 23:56:45 +0800 Subject: [PATCH] Cmr output (#65) * - Testing: Get to 100% coverage * - Apply some common rules; simplify * - Docs: Use `const` in README * - Enhancement: Add `cmrOutput` reporter option for dynamic output Co-authored-by: Yousaf Nabi --- README.md | 31 +++++++++++- lib/MultiReporters.js | 15 +++++- ...custom-internal-dynamic-output-config.json | 17 +++++++ tests/lib/MultiReporters.test.js | 50 +++++++++++++++++++ 4 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 tests/custom-internal-dynamic-output-config.json diff --git a/README.md b/README.md index 2278beb..c92fda1 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ $ ./node_modules/.bin/mocha --reporter cypress-multi-reporters ``` -### Advanced +### Configuring reporters * Generate `spec` and `json` reports. @@ -215,7 +215,34 @@ $ cat xunit-custom.xml ``` -* When calling Mocha programmatically +### `cmrOutput` option + +This option lets you dynamically replace the output files of reporter options. + +In your Mocha `--reporterOptions`, specify `cmrOutput` with a plug-sign-separated +list of the reporter name, the property on that reporter's options to have replaced, and the dynamic ID you would like substituted. If you need multiple reporters +to have dynamic output, add additional plus-sign-separated lists separated by colons. + +```sh +mocha --reporter cypress-multi-reporters --reporterOptions configFile=cypress-multi-reporters.json,cmrOutput=@mochajs/json-file-reporter+output+specialID tests +``` + +```js +// cypress-multi-reporters.json +{ + "mochajsJsonFileReporterReporterOptions": { + "output": "tests/results/file-{id}.json" + }, + "reporterEnabled": "spec, @mochajs/json-file-reporter" +} +``` + +This will produce an `output` for `@mochajs/json-file-reporter` +`reporterOptions` with the value: + +> tests/results/file-specialID.json + +### Programmatic Note that when Mocha is called programmatically, it is passed an options object when created. This object is usually derived from a config file that your mocha test runner reads prior to instantiation. This is the object that must contain a key `reporter` with a value of `cypress-multi-reporters` for this plugin to be used. You can also pass the key `reporterOptions` with a value of any of the above listed config files (including the `reporterEnabled` subkey and any other plugin configuration information.) This removes the requirement to have an intermediate configuration file specifically for the multireporter configuration. diff --git a/lib/MultiReporters.js b/lib/MultiReporters.js index e788a60..a080a88 100644 --- a/lib/MultiReporters.js +++ b/lib/MultiReporters.js @@ -134,7 +134,10 @@ MultiReporters.prototype.done = function (failures, fn) { MultiReporters.prototype.getOptions = function (options) { debug('options', options); - const resultantOptions = _.merge({}, this.getDefaultOptions(), this.getCustomOptions(options)); + + const cmrOutput = _.get(options, 'reporterOptions.cmrOutput'); + const resultantOptions = _.merge({}, this.getDefaultOptions(), this.getCustomOptions(options), cmrOutput ? {cmrOutput} : null); + debug('options file (resultant)', resultantOptions); return resultantOptions; }; @@ -200,6 +203,16 @@ MultiReporters.prototype.getReporterOptions = function (options, name) { const resultantReporterOptions = _.merge({}, commonReporterOptions, customReporterOptions); debug('reporter options (resultant)', _name, resultantReporterOptions); + const cmrOutput = _.get(options, 'cmrOutput'); + if (cmrOutput) { + cmrOutput.split(':').forEach((cmrOutputReporter) => { + const [targetName, prop, output] = cmrOutputReporter.split('+'); + if (resultantReporterOptions[prop] && _name === targetName) { + resultantReporterOptions[prop] = resultantReporterOptions[prop].replace(/\{id\}/gu, output); + } + }); + } + return resultantReporterOptions; }; diff --git a/tests/custom-internal-dynamic-output-config.json b/tests/custom-internal-dynamic-output-config.json new file mode 100644 index 0000000..80d1f8f --- /dev/null +++ b/tests/custom-internal-dynamic-output-config.json @@ -0,0 +1,17 @@ +{ + "reporterEnabled": "dot, tests/custom-internal-reporter", + + "testsCustomInternalReporterReporterOptions": { + "id": "customID", + "output": "artifacts/test/custom-internal-{id}.xml" + }, + + "xunitReporterOptions": { + "output": "artifacts/test/custom-xunit.xml" + }, + + "mochaJunitReporterReporterOptions": { + "id": "mocha-junit-reporter", + "mochaFile": "junit.xml" + } +} diff --git a/tests/lib/MultiReporters.test.js b/tests/lib/MultiReporters.test.js index 03207fc..c1300c1 100644 --- a/tests/lib/MultiReporters.test.js +++ b/tests/lib/MultiReporters.test.js @@ -198,6 +198,56 @@ describe('lib/MultiReporters', function () { }); }); + describe('#internal (with dynamic output)', function () { + beforeEach(function () { + mocha = new Mocha({ + reporter: MultiReporters + }); + suite = new Suite('#internal-multi-reporter', 'root'); + runner = new Runner(suite); + options = { + execute: false, + reporterOptions: { + configFile: 'tests/custom-internal-config.json' + } + }; + reporter = new mocha._reporter(runner, options); + }); + it('return reporter options: "customID" (dynamic output)', function () { + expect(reporter.getReporterOptions(reporter.getOptions({ + reporterOptions: { + cmrOutput: 'tests/custom-internal-reporter+output+customName', + configFile: 'tests/custom-internal-dynamic-output-config.json' + } + }), 'tests/custom-internal-reporter')).to.be.deep.equal({ + id: 'customID', + output: 'artifacts/test/custom-internal-customName.xml' + }); + }); + + it('ignores non-matching reporter options with dynamic output', function () { + expect(reporter.getReporterOptions(reporter.getOptions({ + reporterOptions: { + cmrOutput: 'tests/custom-internal-reporter+output+customName', + configFile: 'tests/custom-internal-dynamic-output-config.json' + } + }), 'xunit')).to.be.deep.equal({ + id: 'xunit', + output: 'artifacts/test/custom-xunit.xml' + }); + + expect(reporter.getReporterOptions(reporter.getOptions({ + reporterOptions: { + cmrOutput: 'tests/custom-internal-reporter+output+customName', + configFile: 'tests/custom-internal-dynamic-output-config.json' + } + }), 'mocha-junit-reporter')).to.be.deep.equal({ + id: 'mocha-junit-reporter', + mochaFile: 'junit.xml' + }); + }); + }); + describe('#external', function () { const checkReporterOptions = function (options) { expect(reporter.getReporterOptions(reporter.getOptions(options), 'mocha-junit-reporter')).to.be.deep.equal({