From eff4daaddb44295895b5debca511d25b3c7fe6b0 Mon Sep 17 00:00:00 2001 From: juergba Date: Tue, 17 Aug 2021 20:14:31 +0200 Subject: [PATCH] try/catch plus test --- example/config/.mocharc.js | 2 +- example/config/.mocharc.yml | 2 +- lib/reporters/base.js | 2 +- lib/reporters/json.js | 25 ++++++++----- test/reporters/json.spec.js | 73 ++++++++++++++++++++++++++----------- 5 files changed, 70 insertions(+), 34 deletions(-) diff --git a/example/config/.mocharc.js b/example/config/.mocharc.js index b730b4d399..e40bea1b71 100644 --- a/example/config/.mocharc.js +++ b/example/config/.mocharc.js @@ -33,7 +33,7 @@ module.exports = { parallel: false, recursive: false, reporter: 'spec', - 'reporter-option': ['foo=bar', 'baz=quux'], + 'reporter-option': ['foo=bar', 'baz=quux'], // array, not object require: '@babel/register', retries: 1, slow: '75', diff --git a/example/config/.mocharc.yml b/example/config/.mocharc.yml index 456b351332..e132b7a99d 100644 --- a/example/config/.mocharc.yml +++ b/example/config/.mocharc.yml @@ -35,7 +35,7 @@ package: './package.json' parallel: false recursive: false reporter: 'spec' -reporter-option: +reporter-option: # array, not object - 'foo=bar' - 'baz=quux' require: '@babel/register' diff --git a/lib/reporters/base.js b/lib/reporters/base.js index 20d1ccec11..f2f2bc65fc 100644 --- a/lib/reporters/base.js +++ b/lib/reporters/base.js @@ -90,7 +90,7 @@ exports.colors = { exports.symbols = { ok: symbols.success, - err: symbols.err, + err: symbols.error, dot: '.', comma: ',', bang: '!' diff --git a/lib/reporters/json.js b/lib/reporters/json.js index ead181b4e8..05e6269361 100644 --- a/lib/reporters/json.js +++ b/lib/reporters/json.js @@ -9,14 +9,14 @@ var Base = require('./base'); var fs = require('fs'); var path = require('path'); -var errors = require('../errors'); -var createUnsupportedError = errors.createUnsupportedError; +const createUnsupportedError = require('../errors').createUnsupportedError; +const utils = require('../utils'); var constants = require('../runner').constants; var EVENT_TEST_PASS = constants.EVENT_TEST_PASS; +var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING; var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL; var EVENT_TEST_END = constants.EVENT_TEST_END; var EVENT_RUN_END = constants.EVENT_RUN_END; -var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING; /** * Expose `JSON`. @@ -34,7 +34,7 @@ exports = module.exports = JSONReporter; * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function JSONReporter(runner, options) { +function JSONReporter(runner, options = {}) { Base.call(this, runner, options); var self = this; @@ -44,11 +44,11 @@ function JSONReporter(runner, options) { var passes = []; var output; - if (options && options.reporterOptions && options.reporterOptions.output) { - if (!fs || !fs.writeFileSync) { + if (options.reporterOption && options.reporterOption.output) { + if (utils.isBrowser()) { throw createUnsupportedError('file output not supported in browser'); } - output = options.reporterOptions.output; + output = options.reporterOption.output; } runner.on(EVENT_TEST_END, function(test) { @@ -80,8 +80,15 @@ function JSONReporter(runner, options) { var json = JSON.stringify(obj, null, 2); if (output) { - fs.mkdirSync(path.dirname(output), {recursive: true}); - fs.writeFileSync(output, json); + try { + fs.mkdirSync(path.dirname(output), {recursive: true}); + fs.writeFileSync(output, json); + } catch (err) { + console.error( + `${Base.symbols.err} [mocha] writing output to "${output}" failed: ${err.message}\n` + ); + process.stdout.write(json); + } } else { process.stdout.write(json); } diff --git a/test/reporters/json.spec.js b/test/reporters/json.spec.js index 97f9019732..8a44bc4e2a 100644 --- a/test/reporters/json.spec.js +++ b/test/reporters/json.spec.js @@ -3,6 +3,7 @@ var fs = require('fs'); var sinon = require('sinon'); var JSONReporter = require('../../lib/reporters/json'); +var utils = require('../../lib/utils'); var Mocha = require('../../'); var Suite = Mocha.Suite; var Runner = Mocha.Runner; @@ -98,6 +99,7 @@ describe('JSON reporter', function() { suite.addTest(test); runner.run(function(failureCount) { + sinon.restore(); expect(runner, 'to satisfy', { testResults: { passes: [ @@ -150,11 +152,11 @@ describe('JSON reporter', function() { }); }); - describe("when 'reporterOptions.output' is provided", function() { + describe('when "reporterOption.output" is provided', function() { var expectedDirName = 'reports'; var expectedFileName = 'reports/test-results.json'; var options = { - reporterOptions: { + reporterOption: { output: expectedFileName } }; @@ -171,34 +173,61 @@ describe('JSON reporter', function() { suite.addTest(test); }); - describe('when file can be created', function() { - it('should write test results to file', function(done) { - var fsMkdirSync = sinon.stub(fs, 'mkdirSync'); - var fsWriteFileSync = sinon.stub(fs, 'writeFileSync'); + it('should write test results to file', function(done) { + const fsMkdirSync = sinon.stub(fs, 'mkdirSync'); + const fsWriteFileSync = sinon.stub(fs, 'writeFileSync'); - fsWriteFileSync.callsFake(function(filename, content) { - var expectedJson = JSON.stringify(runner.testResults, null, 2); - expect(expectedFileName, 'to be', filename); - expect(content, 'to be', expectedJson); - }); + fsWriteFileSync.callsFake(function(filename, content) { + const expectedJson = JSON.stringify(runner.testResults, null, 2); + expect(expectedFileName, 'to be', filename); + expect(content, 'to be', expectedJson); + }); - runner.run(function() { - fsMkdirSync.calledWith(expectedDirName, {recursive: true}); - expect(fsWriteFileSync.calledOnce, 'to be true'); - done(); - }); + runner.run(function() { + expect( + fsMkdirSync.calledWith(expectedDirName, {recursive: true}), + 'to be true' + ); + expect(fsWriteFileSync.calledOnce, 'to be true'); + done(); }); }); - describe('when run in browser', function() { - it('should throw unsupported error', function() { - sinon.stub(fs, 'writeFileSync').value(false); + it('should warn and write test results to console', function(done) { + const fsMkdirSync = sinon.stub(fs, 'mkdirSync'); + const fsWriteFileSync = sinon.stub(fs, 'writeFileSync'); + + fsWriteFileSync.throws('unable to write file'); + + const outLog = []; + const fake = chunk => outLog.push(chunk); + sinon.stub(process.stderr, 'write').callsFake(fake); + sinon.stub(process.stdout, 'write').callsFake(fake); + + runner.run(function() { + sinon.restore(); + expect( + fsMkdirSync.calledWith(expectedDirName, {recursive: true}), + 'to be true' + ); + expect(fsWriteFileSync.calledOnce, 'to be true'); expect( - () => new JSONReporter(runner, options), - 'to throw', - 'file output not supported in browser' + outLog[0], + 'to contain', + `[mocha] writing output to "${expectedFileName}" failed:` ); + expect(outLog[1], 'to match', /"fullTitle": "JSON suite json test 1"/); + done(); }); }); + + it('should throw "unsupported error" in browser', function() { + sinon.stub(utils, 'isBrowser').callsFake(() => true); + expect( + () => new JSONReporter(runner, options), + 'to throw', + 'file output not supported in browser' + ); + }); }); });