├── .github
└── workflows
│ └── node.js.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── config.json
├── index.js
├── lib
├── file-path-parser.js
└── xunit-file.js
├── package-lock.json
├── package.json
└── test
├── file-path-parser.spec.js
├── fixture
└── success
│ └── success.spec.js
├── lib
└── util.js
└── output.spec.js
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Node.js CI
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [12.x, 14.x, 16.x, 18.x]
20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21 |
22 | steps:
23 | - uses: actions/checkout@v2
24 | - name: Use Node.js ${{ matrix.node-version }}
25 | uses: actions/setup-node@v2
26 | with:
27 | node-version: ${{ matrix.node-version }}
28 | cache: 'npm'
29 | - run: npm ci
30 | - run: npm test
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | lib-cov
2 | *.seed
3 | *.log
4 | *.csv
5 | *.dat
6 | *.out
7 | *.pid
8 | *.gz
9 |
10 | pids
11 | logs
12 | results
13 |
14 | node_modules
15 | npm-debug.log
16 |
17 | _tmp
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | All notable changes to this project will be documented in this file.
3 |
4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6 |
7 | ## [2.0.0] - 2021-11-24
8 |
9 | BREAKING CHANGE: This is the first version which has a node engines specifier. Hence we are releasing this as a major version.
10 |
11 | ### Added
12 |
13 | - [#36](https://github.com/peerigon/xunit-file/pull/36) chore: CI Action to run tests
14 |
15 | ### Changed
16 |
17 | - [#27](https://github.com/peerigon/xunit-file/pull/27) fix: Dont count xunit failures as errors (thanks @mlucool)
18 | - [#25](https://github.com/peerigon/xunit-file/pull/25) fix: Remove escaping character in CDATA (thanks @jugend)
19 | - [#38](https://github.com/peerigon/xunit-file/pull/38) feat!: Specified supported node engine versions `> 12 < 16`
20 |
21 | ### Fixed
22 |
23 | - [#38](https://github.com/peerigon/xunit-file/pull/38) fix: Update packages to resolve CVE issues #38 (thanks @gagyibenedek)
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 peerigon UG (haftungsbeschränkt)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | xunit-file
2 | ==========
3 |
4 | Basically the same reporter as mocha's xunit reporter, but writes the output to a file.
5 |
6 | [](https://www.npmjs.com/package/xunit-file)
7 | [](https://www.npmjs.com/package/xunit-file)
8 |
9 | # Usage
10 |
11 | ```
12 | npm install xunit-file --save-dev
13 | ```
14 |
15 | Run mocha with `-R xunit-file` or `--reporter xunit-file`
16 |
17 | The xunit.xml output is saved in `process.cwd()/xunit.xml` by default.
18 |
19 | ### Options
20 |
21 | To change the output and activate terminal output, you can create a `config.json`, or use environment variables.
22 |
23 | **config.json**
24 | ```
25 | {
26 | "file" : "${cwd}/xunit.xml",
27 | "consoleOutput" : {
28 | "suite" : true,
29 | "test" : true,
30 | "fail" : false
31 | }
32 | }
33 | ```
34 |
35 | **environment variables**
36 | ```
37 | $ XUNIT_FILE=output/xunit.xml mocha -R xunit-file // writes result to output/xunit.xml
38 | $ LOG_XUNIT=true mocha -R xunit-file // activates terminal output
39 | $ XUNIT_SILENT=true mocha -R xunit-file // disable all terminal output
40 | ```
41 |
42 | Set XUNIT_LOG_ENV environment variable, if you want the output process and environment variables in the properties section of the xml file.
43 |
44 | ```
45 | $ XUNIT_LOG_ENV=true mocha -R xunit-file
46 | ```
47 |
48 | Add the following to the xml report.
49 |
50 | ```xml
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | ...
61 |
62 |
63 |
64 |
65 |
66 |
67 | ```
68 |
69 | **File Path Options**
70 |
71 | The file path accepts a few custom tokens to allow creation of dynamic file names. This can be useful for multithreaded testing (such as using a Selenium Grid) or to keep multiple files by timestamp. Tokens are in the following format:
72 |
73 | ```
74 | ${tokenName: 'Token Data'}
75 | ```
76 |
77 | The available tokens are `pid` to inject the process id, `cwd` to inject the current working directory, and `ts` or `timestamp` to inject a timestamp.
78 |
79 | By default `ts` and `timestamp` use the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format, ex: `2016-03-31T07:27:48+00:00`. However, if you specify a custom format in the Token Data, the timestamp uses the [node dateformat](https://github.com/felixge/node-dateformat) library to output a string in that format.
80 |
81 | A full example `config.json` is as follows:
82 |
83 | ```
84 | {
85 | "file": "${cwd}/${timestamp: 'MMDD-hhmm'}/xunit-${pid}.xml"
86 | }
87 | ```
88 |
89 | This would output something like `~/myProject/1217-1507/xunit-1234.xml`. This example would keep copies good for a year without collision, and group multithreaded results by test run.
90 |
91 | Tokens can be used in either environment variables or a config.json. The default filepath is always `${cwd}/xunit.xml`.
92 |
93 | # Credits
94 | This reporter is just the original [xunit reporter](https://github.com/visionmedia/mocha/blob/master/lib/reporters/xunit.js) from mocha only writing the result in an xml file.
95 |
96 | # LICENSE
97 |
98 | MIT
99 |
100 | # Sponsors
101 |
102 | [
](https://peerigon.com)
103 |
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "file" : "xunit.xml",
3 | "consoleOutput" : {
4 | "suite" : true,
5 | "test" : true,
6 | "fail" : false
7 | }
8 | }
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // @see https://raw.github.com/visionmedia/mocha/master/lib/reporters/xunit.js
4 |
5 | var XUnitFile = require("./lib/xunit-file");
6 |
7 | module.exports = XUnitFile;
--------------------------------------------------------------------------------
/lib/file-path-parser.js:
--------------------------------------------------------------------------------
1 | // Exports a factory for testing purposes.
2 | // Otherwise process will be the real deal.
3 | // Also, testing with time/timezones is rather difficult, so that's all mocked.
4 | module.exports = function(myProcess, myDate, myFormatter) {
5 | return function(pathTemplate) {
6 | var now = myDate.now();
7 | var pidRE = regexTokenCreator('pid');
8 | var cwdRE = regexTokenCreator('cwd');
9 | var simpleTSRE = regexTokenCreator('(?:ts|timestamp)');
10 | var customTSRE = regexTokenCreator('(?:ts|timestamp):\\s*["\']([^"\']*)["\']');
11 | var matches = [];
12 | var match;
13 |
14 | //process the template to get the final path
15 | path = pathTemplate;
16 | path = path.replace(pidRE, myProcess.pid);
17 | path = path.replace(cwdRE, myProcess.cwd());
18 | path = path.replace(simpleTSRE, myFormatter(now, 'isoDateTime'));
19 |
20 | // collect all of our regex matches
21 | while ((match = customTSRE.exec(path)) !== null) {
22 | matches.push(match);
23 | }
24 |
25 | // Use each match to replace the whole with the date in the format of the
26 | // first matching group (the contents of the quotes).
27 | matches.forEach(function(match) {
28 | path = path.replace(match[0], myFormatter(now, match[1]));
29 | });
30 |
31 | return path;
32 | }
33 | }
34 |
35 | function regexTokenCreator(s) {
36 | return new RegExp('\\${\\s*' + s + '\\s*}', 'ig');
37 | }
38 |
--------------------------------------------------------------------------------
/lib/xunit-file.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module dependencies.
3 | */
4 |
5 | var mocha = require("mocha")
6 | , Base = mocha.reporters.Base
7 | , utils = mocha.utils
8 | , escape = utils.escape
9 | , config = require("../config.json")
10 | , fs = require("fs")
11 | , path = require("path")
12 | , mkdirp = require("mkdirp")
13 | , dateFormat = require('dateformat')
14 | , filePathParser = require('./file-path-parser')(process, global.Date, dateFormat)
15 | , filePath = filePathParser(process.env.XUNIT_FILE || config.file || "${cwd}/xunit.xml")
16 | , consoleOutput = process.env.XUNIT_SILENT ? {} : config.consoleOutput || {};
17 |
18 | /**
19 | * Save timer references to avoid Sinon interfering (see GH-237).
20 | */
21 |
22 | var Date = global.Date
23 | , setTimeout = global.setTimeout
24 | , setInterval = global.setInterval
25 | , clearTimeout = global.clearTimeout
26 | , clearInterval = global.clearInterval;
27 |
28 | /**
29 | * Expose `XUnitFile`.
30 | */
31 |
32 | exports = module.exports = XUnitFile;
33 |
34 | /**
35 | * Initialize a new `XUnitFile` reporter.
36 | *
37 | * @param {Runner} runner
38 | * @api public
39 | */
40 |
41 | function XUnitFile(runner) {
42 | Base.call(this, runner);
43 | var stats = this.stats
44 | , tests = []
45 | , fd;
46 |
47 | mkdirp.sync(path.dirname(filePath));
48 | fd = fs.openSync(filePath, 'w', 0755);
49 |
50 | runner.on('suite', function(suite){
51 | if(consoleOutput.suite){
52 | console.log(' ' + suite.title);
53 | }
54 | });
55 |
56 | runner.on('test', function(test){
57 | if(consoleOutput.test){
58 | console.log(' ◦ ' + test.title);
59 | }
60 | });
61 |
62 | runner.on('pass', function(test){
63 | tests.push(test);
64 | });
65 |
66 | runner.on('fail', function(test){
67 | if(consoleOutput.fail){
68 | console.log(' - ' + test.title);
69 | }
70 | tests.push(test);
71 | });
72 |
73 | runner.on('pending', function(test) {
74 | tests.push(test);
75 | });
76 |
77 | runner.on('end', function(){
78 | var timestampStr = (new Date).toISOString().split('.', 1)[0];
79 | appendLine(fd, tag('testsuite', {
80 | name: process.env.SUITE_NAME || 'Mocha Tests'
81 | , tests: stats.tests
82 | , failures: stats.failures
83 | , errors: 0
84 | , skipped: stats.tests - stats.failures - stats.passes
85 | , timestamp: timestampStr
86 | , time: stats.duration / 1000
87 | }, false));
88 |
89 | if( process.env.XUNIT_LOG_ENV) {
90 | logProperties(fd);
91 | }
92 |
93 | tests.forEach(function(test){
94 | writeTest(fd, test);
95 | });
96 |
97 | appendLine(fd, '');
98 | fs.closeSync(fd);
99 | });
100 | }
101 |
102 | /**
103 | * Inherit from `Base.prototype`.
104 | */
105 |
106 | XUnitFile.prototype.__proto__ = Base.prototype;
107 |
108 | /**
109 | * Writes a list of process and environment variables to the section in the XML.
110 | */
111 | function logProperties(fd) {
112 | var attrs = new Object();
113 | var properties = "\n";
114 |
115 | properties += logProperty('process.arch', process.arch);
116 | properties += logProperty('process.platform', process.platform);
117 | properties += logProperty('process.memoryUsage', objectToString(process.memoryUsage()));
118 | properties += logProperty('process.cwd', process.cwd());
119 | properties += logProperty('process.execPath', process.execPath)
120 | properties += logProperty('process.execArgv', process.execArgv.join( ' '));
121 | properties += logProperty('process.argv', process.argv.join( ' '));
122 | properties += logProperty('process.version', process.version.replace('"',''));
123 | properties += logProperty('process.versions', objectToString(process.versions));
124 | properties += logProperty('process.env.PATH', process.env.PATH);
125 | properties += logProperty('process.env.NODE_PATH', process.env.NODE_PATH);
126 | properties += logProperty('process.env.SUITE_NAME', process.env.SUITE_NAME);
127 | properties += logProperty('process.env.XUNIT_FILE', process.env.XUNIT_FILE);
128 | properties += logProperty('process.env.LOG_XUNIT', process.env.LOG_XUNIT);
129 |
130 | appendLine(fd, tag('properties', {}, false, properties));
131 | }
132 |
133 | /**
134 | * Formats a single property value.
135 | */
136 |
137 | function logProperty( name, value) {
138 | return ' ' + tag('property', { name: name, value: value }, true) + '\n';
139 | }
140 |
141 | /**
142 | * Simple utility to convert a flat Object to a readable string.
143 | */
144 |
145 | function objectToString( obj) {
146 | var arrayString = '';
147 |
148 | if( obj) {
149 | for (var prop in obj) {
150 | var propValue = '' + obj[prop];
151 | if( arrayString.length > 0) {
152 | arrayString += ', ';
153 | }
154 | arrayString += prop + ": '" + propValue.replace( "'", "\\'") + "'";
155 | }
156 | }
157 | return '[ ' + arrayString + ']';
158 | }
159 |
160 |
161 | /**
162 | * Output tag for the given `test.`
163 | */
164 |
165 | function writeTest(fd, test) {
166 | var attrs = {
167 | classname: test.parent.fullTitle()
168 | , name: test.title
169 | // , time: test.duration / 1000 //old
170 | ,time: test.duration ? test.duration / 1000 : 0 //new
171 | };
172 |
173 | if ('failed' == test.state) {
174 | var err = test.err;
175 | appendLine(fd, tag('testcase', attrs, false, tag('failure', { message: escape(err.message) }, false, cdata(err.stack))));
176 | } else if (test.pending) {
177 | delete attrs.time;
178 | appendLine(fd, tag('testcase', attrs, false, tag('skipped', {}, true)));
179 | } else {
180 | appendLine(fd, tag('testcase', attrs, true) );
181 | }
182 | }
183 |
184 | /**
185 | * HTML tag helper.
186 | */
187 |
188 | function tag(name, attrs, close, content) {
189 | var end = close ? '/>' : '>'
190 | , pairs = []
191 | , result;
192 |
193 | for (var key in attrs) {
194 | pairs.push(key + '="' + escape(attrs[key]) + '"');
195 | }
196 |
197 | result = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
198 | if (content) result += content + '' + name + end;
199 | return result;
200 | }
201 |
202 | /**
203 | * Return CDATA `str`.
204 | */
205 |
206 | function cdata(str) {
207 | return '';
208 | }
209 |
210 | function appendLine(fd, line) {
211 | if (process.env.LOG_XUNIT) {
212 | console.log(line);
213 | }
214 | fs.writeSync(fd, line + "\n", null, 'utf8');
215 | }
216 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "xunit-file",
3 | "version": "2.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@sinonjs/commons": {
8 | "version": "1.8.3",
9 | "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
10 | "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
11 | "dev": true,
12 | "requires": {
13 | "type-detect": "4.0.8"
14 | }
15 | },
16 | "@sinonjs/fake-timers": {
17 | "version": "8.1.0",
18 | "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
19 | "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
20 | "dev": true,
21 | "requires": {
22 | "@sinonjs/commons": "^1.7.0"
23 | }
24 | },
25 | "@sinonjs/samsam": {
26 | "version": "6.0.2",
27 | "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz",
28 | "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==",
29 | "dev": true,
30 | "requires": {
31 | "@sinonjs/commons": "^1.6.0",
32 | "lodash.get": "^4.4.2",
33 | "type-detect": "^4.0.8"
34 | }
35 | },
36 | "@sinonjs/text-encoding": {
37 | "version": "0.7.1",
38 | "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
39 | "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
40 | "dev": true
41 | },
42 | "@ungap/promise-all-settled": {
43 | "version": "1.1.2",
44 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
45 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
46 | "dev": true
47 | },
48 | "ansi-colors": {
49 | "version": "4.1.1",
50 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
51 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
52 | "dev": true
53 | },
54 | "ansi-regex": {
55 | "version": "5.0.1",
56 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
57 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
58 | "dev": true
59 | },
60 | "ansi-styles": {
61 | "version": "4.3.0",
62 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
63 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
64 | "dev": true,
65 | "requires": {
66 | "color-convert": "^2.0.1"
67 | }
68 | },
69 | "anymatch": {
70 | "version": "3.1.2",
71 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
72 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
73 | "dev": true,
74 | "requires": {
75 | "normalize-path": "^3.0.0",
76 | "picomatch": "^2.0.4"
77 | }
78 | },
79 | "argparse": {
80 | "version": "2.0.1",
81 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
82 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
83 | "dev": true
84 | },
85 | "assertion-error": {
86 | "version": "1.1.0",
87 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
88 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
89 | "dev": true
90 | },
91 | "balanced-match": {
92 | "version": "1.0.2",
93 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
94 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
95 | "dev": true
96 | },
97 | "binary-extensions": {
98 | "version": "2.2.0",
99 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
100 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
101 | "dev": true
102 | },
103 | "brace-expansion": {
104 | "version": "1.1.11",
105 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
106 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
107 | "dev": true,
108 | "requires": {
109 | "balanced-match": "^1.0.0",
110 | "concat-map": "0.0.1"
111 | }
112 | },
113 | "braces": {
114 | "version": "3.0.2",
115 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
116 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
117 | "dev": true,
118 | "requires": {
119 | "fill-range": "^7.0.1"
120 | }
121 | },
122 | "browser-stdout": {
123 | "version": "1.3.1",
124 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
125 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
126 | "dev": true
127 | },
128 | "camelcase": {
129 | "version": "6.2.1",
130 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz",
131 | "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==",
132 | "dev": true
133 | },
134 | "chai": {
135 | "version": "4.3.4",
136 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz",
137 | "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==",
138 | "dev": true,
139 | "requires": {
140 | "assertion-error": "^1.1.0",
141 | "check-error": "^1.0.2",
142 | "deep-eql": "^3.0.1",
143 | "get-func-name": "^2.0.0",
144 | "pathval": "^1.1.1",
145 | "type-detect": "^4.0.5"
146 | }
147 | },
148 | "chalk": {
149 | "version": "4.1.2",
150 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
151 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
152 | "dev": true,
153 | "requires": {
154 | "ansi-styles": "^4.1.0",
155 | "supports-color": "^7.1.0"
156 | },
157 | "dependencies": {
158 | "supports-color": {
159 | "version": "7.2.0",
160 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
161 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
162 | "dev": true,
163 | "requires": {
164 | "has-flag": "^4.0.0"
165 | }
166 | }
167 | }
168 | },
169 | "check-error": {
170 | "version": "1.0.2",
171 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
172 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
173 | "dev": true
174 | },
175 | "chokidar": {
176 | "version": "3.5.2",
177 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
178 | "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
179 | "dev": true,
180 | "requires": {
181 | "anymatch": "~3.1.2",
182 | "braces": "~3.0.2",
183 | "fsevents": "~2.3.2",
184 | "glob-parent": "~5.1.2",
185 | "is-binary-path": "~2.1.0",
186 | "is-glob": "~4.0.1",
187 | "normalize-path": "~3.0.0",
188 | "readdirp": "~3.6.0"
189 | }
190 | },
191 | "cliui": {
192 | "version": "7.0.4",
193 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
194 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
195 | "dev": true,
196 | "requires": {
197 | "string-width": "^4.2.0",
198 | "strip-ansi": "^6.0.0",
199 | "wrap-ansi": "^7.0.0"
200 | }
201 | },
202 | "color-convert": {
203 | "version": "2.0.1",
204 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
205 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
206 | "dev": true,
207 | "requires": {
208 | "color-name": "~1.1.4"
209 | }
210 | },
211 | "color-name": {
212 | "version": "1.1.4",
213 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
214 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
215 | "dev": true
216 | },
217 | "concat-map": {
218 | "version": "0.0.1",
219 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
220 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
221 | "dev": true
222 | },
223 | "dateformat": {
224 | "version": "4.6.3",
225 | "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz",
226 | "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA=="
227 | },
228 | "debug": {
229 | "version": "4.3.2",
230 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
231 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
232 | "dev": true,
233 | "requires": {
234 | "ms": "2.1.2"
235 | },
236 | "dependencies": {
237 | "ms": {
238 | "version": "2.1.2",
239 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
240 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
241 | "dev": true
242 | }
243 | }
244 | },
245 | "decamelize": {
246 | "version": "4.0.0",
247 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
248 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
249 | "dev": true
250 | },
251 | "deep-eql": {
252 | "version": "3.0.1",
253 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
254 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
255 | "dev": true,
256 | "requires": {
257 | "type-detect": "^4.0.0"
258 | }
259 | },
260 | "diff": {
261 | "version": "5.0.0",
262 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
263 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
264 | "dev": true
265 | },
266 | "emoji-regex": {
267 | "version": "8.0.0",
268 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
269 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
270 | "dev": true
271 | },
272 | "escalade": {
273 | "version": "3.1.1",
274 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
275 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
276 | "dev": true
277 | },
278 | "escape-string-regexp": {
279 | "version": "4.0.0",
280 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
281 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
282 | "dev": true
283 | },
284 | "fill-range": {
285 | "version": "7.0.1",
286 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
287 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
288 | "dev": true,
289 | "requires": {
290 | "to-regex-range": "^5.0.1"
291 | }
292 | },
293 | "find-up": {
294 | "version": "5.0.0",
295 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
296 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
297 | "dev": true,
298 | "requires": {
299 | "locate-path": "^6.0.0",
300 | "path-exists": "^4.0.0"
301 | }
302 | },
303 | "flat": {
304 | "version": "5.0.2",
305 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
306 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
307 | "dev": true
308 | },
309 | "fs.realpath": {
310 | "version": "1.0.0",
311 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
312 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
313 | "dev": true
314 | },
315 | "fsevents": {
316 | "version": "2.3.2",
317 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
318 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
319 | "dev": true,
320 | "optional": true
321 | },
322 | "get-caller-file": {
323 | "version": "2.0.5",
324 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
325 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
326 | "dev": true
327 | },
328 | "get-func-name": {
329 | "version": "2.0.0",
330 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
331 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
332 | "dev": true
333 | },
334 | "glob": {
335 | "version": "7.1.7",
336 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
337 | "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
338 | "dev": true,
339 | "requires": {
340 | "fs.realpath": "^1.0.0",
341 | "inflight": "^1.0.4",
342 | "inherits": "2",
343 | "minimatch": "^3.0.4",
344 | "once": "^1.3.0",
345 | "path-is-absolute": "^1.0.0"
346 | }
347 | },
348 | "glob-parent": {
349 | "version": "5.1.2",
350 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
351 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
352 | "dev": true,
353 | "requires": {
354 | "is-glob": "^4.0.1"
355 | }
356 | },
357 | "growl": {
358 | "version": "1.10.5",
359 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
360 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
361 | "dev": true
362 | },
363 | "has-flag": {
364 | "version": "4.0.0",
365 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
366 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
367 | "dev": true
368 | },
369 | "he": {
370 | "version": "1.2.0",
371 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
372 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
373 | "dev": true
374 | },
375 | "inflight": {
376 | "version": "1.0.6",
377 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
378 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
379 | "dev": true,
380 | "requires": {
381 | "once": "^1.3.0",
382 | "wrappy": "1"
383 | }
384 | },
385 | "inherits": {
386 | "version": "2.0.4",
387 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
388 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
389 | "dev": true
390 | },
391 | "is-binary-path": {
392 | "version": "2.1.0",
393 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
394 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
395 | "dev": true,
396 | "requires": {
397 | "binary-extensions": "^2.0.0"
398 | }
399 | },
400 | "is-extglob": {
401 | "version": "2.1.1",
402 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
403 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
404 | "dev": true
405 | },
406 | "is-fullwidth-code-point": {
407 | "version": "3.0.0",
408 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
409 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
410 | "dev": true
411 | },
412 | "is-glob": {
413 | "version": "4.0.3",
414 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
415 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
416 | "dev": true,
417 | "requires": {
418 | "is-extglob": "^2.1.1"
419 | }
420 | },
421 | "is-number": {
422 | "version": "7.0.0",
423 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
424 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
425 | "dev": true
426 | },
427 | "is-plain-obj": {
428 | "version": "2.1.0",
429 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
430 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
431 | "dev": true
432 | },
433 | "is-unicode-supported": {
434 | "version": "0.1.0",
435 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
436 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
437 | "dev": true
438 | },
439 | "isarray": {
440 | "version": "0.0.1",
441 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
442 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
443 | "dev": true
444 | },
445 | "isexe": {
446 | "version": "2.0.0",
447 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
448 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
449 | "dev": true
450 | },
451 | "js-yaml": {
452 | "version": "4.1.0",
453 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
454 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
455 | "dev": true,
456 | "requires": {
457 | "argparse": "^2.0.1"
458 | }
459 | },
460 | "just-extend": {
461 | "version": "4.2.1",
462 | "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
463 | "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
464 | "dev": true
465 | },
466 | "locate-path": {
467 | "version": "6.0.0",
468 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
469 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
470 | "dev": true,
471 | "requires": {
472 | "p-locate": "^5.0.0"
473 | }
474 | },
475 | "lodash.get": {
476 | "version": "4.4.2",
477 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
478 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
479 | "dev": true
480 | },
481 | "log-symbols": {
482 | "version": "4.1.0",
483 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
484 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
485 | "dev": true,
486 | "requires": {
487 | "chalk": "^4.1.0",
488 | "is-unicode-supported": "^0.1.0"
489 | }
490 | },
491 | "minimatch": {
492 | "version": "3.0.4",
493 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
494 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
495 | "dev": true,
496 | "requires": {
497 | "brace-expansion": "^1.1.7"
498 | }
499 | },
500 | "mkdirp": {
501 | "version": "1.0.4",
502 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
503 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
504 | },
505 | "mocha": {
506 | "version": "9.1.3",
507 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz",
508 | "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==",
509 | "dev": true,
510 | "requires": {
511 | "@ungap/promise-all-settled": "1.1.2",
512 | "ansi-colors": "4.1.1",
513 | "browser-stdout": "1.3.1",
514 | "chokidar": "3.5.2",
515 | "debug": "4.3.2",
516 | "diff": "5.0.0",
517 | "escape-string-regexp": "4.0.0",
518 | "find-up": "5.0.0",
519 | "glob": "7.1.7",
520 | "growl": "1.10.5",
521 | "he": "1.2.0",
522 | "js-yaml": "4.1.0",
523 | "log-symbols": "4.1.0",
524 | "minimatch": "3.0.4",
525 | "ms": "2.1.3",
526 | "nanoid": "3.1.25",
527 | "serialize-javascript": "6.0.0",
528 | "strip-json-comments": "3.1.1",
529 | "supports-color": "8.1.1",
530 | "which": "2.0.2",
531 | "workerpool": "6.1.5",
532 | "yargs": "16.2.0",
533 | "yargs-parser": "20.2.4",
534 | "yargs-unparser": "2.0.0"
535 | }
536 | },
537 | "ms": {
538 | "version": "2.1.3",
539 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
540 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
541 | "dev": true
542 | },
543 | "nanoid": {
544 | "version": "3.1.25",
545 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz",
546 | "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==",
547 | "dev": true
548 | },
549 | "nise": {
550 | "version": "5.1.0",
551 | "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz",
552 | "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==",
553 | "dev": true,
554 | "requires": {
555 | "@sinonjs/commons": "^1.7.0",
556 | "@sinonjs/fake-timers": "^7.0.4",
557 | "@sinonjs/text-encoding": "^0.7.1",
558 | "just-extend": "^4.0.2",
559 | "path-to-regexp": "^1.7.0"
560 | },
561 | "dependencies": {
562 | "@sinonjs/fake-timers": {
563 | "version": "7.1.2",
564 | "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz",
565 | "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==",
566 | "dev": true,
567 | "requires": {
568 | "@sinonjs/commons": "^1.7.0"
569 | }
570 | }
571 | }
572 | },
573 | "normalize-path": {
574 | "version": "3.0.0",
575 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
576 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
577 | "dev": true
578 | },
579 | "once": {
580 | "version": "1.4.0",
581 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
582 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
583 | "dev": true,
584 | "requires": {
585 | "wrappy": "1"
586 | }
587 | },
588 | "p-limit": {
589 | "version": "3.1.0",
590 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
591 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
592 | "dev": true,
593 | "requires": {
594 | "yocto-queue": "^0.1.0"
595 | }
596 | },
597 | "p-locate": {
598 | "version": "5.0.0",
599 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
600 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
601 | "dev": true,
602 | "requires": {
603 | "p-limit": "^3.0.2"
604 | }
605 | },
606 | "path-exists": {
607 | "version": "4.0.0",
608 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
609 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
610 | "dev": true
611 | },
612 | "path-is-absolute": {
613 | "version": "1.0.1",
614 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
615 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
616 | "dev": true
617 | },
618 | "path-to-regexp": {
619 | "version": "1.8.0",
620 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
621 | "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
622 | "dev": true,
623 | "requires": {
624 | "isarray": "0.0.1"
625 | }
626 | },
627 | "pathval": {
628 | "version": "1.1.1",
629 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
630 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
631 | "dev": true
632 | },
633 | "picomatch": {
634 | "version": "2.3.0",
635 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
636 | "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
637 | "dev": true
638 | },
639 | "randombytes": {
640 | "version": "2.1.0",
641 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
642 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
643 | "dev": true,
644 | "requires": {
645 | "safe-buffer": "^5.1.0"
646 | }
647 | },
648 | "readdirp": {
649 | "version": "3.6.0",
650 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
651 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
652 | "dev": true,
653 | "requires": {
654 | "picomatch": "^2.2.1"
655 | }
656 | },
657 | "require-directory": {
658 | "version": "2.1.1",
659 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
660 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
661 | "dev": true
662 | },
663 | "safe-buffer": {
664 | "version": "5.2.1",
665 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
666 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
667 | "dev": true
668 | },
669 | "serialize-javascript": {
670 | "version": "6.0.0",
671 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
672 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
673 | "dev": true,
674 | "requires": {
675 | "randombytes": "^2.1.0"
676 | }
677 | },
678 | "sinon": {
679 | "version": "12.0.1",
680 | "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz",
681 | "integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==",
682 | "dev": true,
683 | "requires": {
684 | "@sinonjs/commons": "^1.8.3",
685 | "@sinonjs/fake-timers": "^8.1.0",
686 | "@sinonjs/samsam": "^6.0.2",
687 | "diff": "^5.0.0",
688 | "nise": "^5.1.0",
689 | "supports-color": "^7.2.0"
690 | },
691 | "dependencies": {
692 | "supports-color": {
693 | "version": "7.2.0",
694 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
695 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
696 | "dev": true,
697 | "requires": {
698 | "has-flag": "^4.0.0"
699 | }
700 | }
701 | }
702 | },
703 | "string-width": {
704 | "version": "4.2.3",
705 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
706 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
707 | "dev": true,
708 | "requires": {
709 | "emoji-regex": "^8.0.0",
710 | "is-fullwidth-code-point": "^3.0.0",
711 | "strip-ansi": "^6.0.1"
712 | }
713 | },
714 | "strip-ansi": {
715 | "version": "6.0.1",
716 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
717 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
718 | "dev": true,
719 | "requires": {
720 | "ansi-regex": "^5.0.1"
721 | }
722 | },
723 | "strip-json-comments": {
724 | "version": "3.1.1",
725 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
726 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
727 | "dev": true
728 | },
729 | "supports-color": {
730 | "version": "8.1.1",
731 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
732 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
733 | "dev": true,
734 | "requires": {
735 | "has-flag": "^4.0.0"
736 | }
737 | },
738 | "to-regex-range": {
739 | "version": "5.0.1",
740 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
741 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
742 | "dev": true,
743 | "requires": {
744 | "is-number": "^7.0.0"
745 | }
746 | },
747 | "type-detect": {
748 | "version": "4.0.8",
749 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
750 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
751 | "dev": true
752 | },
753 | "which": {
754 | "version": "2.0.2",
755 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
756 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
757 | "dev": true,
758 | "requires": {
759 | "isexe": "^2.0.0"
760 | }
761 | },
762 | "workerpool": {
763 | "version": "6.1.5",
764 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz",
765 | "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==",
766 | "dev": true
767 | },
768 | "wrap-ansi": {
769 | "version": "7.0.0",
770 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
771 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
772 | "dev": true,
773 | "requires": {
774 | "ansi-styles": "^4.0.0",
775 | "string-width": "^4.1.0",
776 | "strip-ansi": "^6.0.0"
777 | }
778 | },
779 | "wrappy": {
780 | "version": "1.0.2",
781 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
782 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
783 | "dev": true
784 | },
785 | "y18n": {
786 | "version": "5.0.8",
787 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
788 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
789 | "dev": true
790 | },
791 | "yargs": {
792 | "version": "16.2.0",
793 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
794 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
795 | "dev": true,
796 | "requires": {
797 | "cliui": "^7.0.2",
798 | "escalade": "^3.1.1",
799 | "get-caller-file": "^2.0.5",
800 | "require-directory": "^2.1.1",
801 | "string-width": "^4.2.0",
802 | "y18n": "^5.0.5",
803 | "yargs-parser": "^20.2.2"
804 | }
805 | },
806 | "yargs-parser": {
807 | "version": "20.2.4",
808 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
809 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
810 | "dev": true
811 | },
812 | "yargs-unparser": {
813 | "version": "2.0.0",
814 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
815 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
816 | "dev": true,
817 | "requires": {
818 | "camelcase": "^6.0.0",
819 | "decamelize": "^4.0.0",
820 | "flat": "^5.0.2",
821 | "is-plain-obj": "^2.1.0"
822 | }
823 | },
824 | "yocto-queue": {
825 | "version": "0.1.0",
826 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
827 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
828 | "dev": true
829 | }
830 | }
831 | }
832 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "xunit-file",
3 | "description": "Basically the same reporter as mocha's xunit reporter, but writes the output in a file.",
4 | "version": "2.0.0",
5 | "author": {
6 | "name": "Matthias Jahn",
7 | "email": "matthias.jahn@peerigon.com"
8 | },
9 | "contributors": [
10 | {
11 | "name": "Matthias Jahn",
12 | "email": "matthias.jahn@peerigon.com"
13 | },
14 | {
15 | "name": "Paul Torka",
16 | "email": "paul.torka@yahoo.de"
17 | },
18 | {
19 | "name": "Peter Janes",
20 | "email": "peter.janes@ek3.com"
21 | },
22 | {
23 | "name": "Nathan Fairhurst",
24 | "email": "nathan.p3pictures@gmail.com"
25 | }
26 | ],
27 | "keywords": [
28 | "mocha",
29 | "xunit",
30 | "file",
31 | "reporter"
32 | ],
33 | "main": "lib/xunit-file.js",
34 | "repository": "git://github.com/peerigon/xunit-file.git",
35 | "license": "MIT",
36 | "dependencies": {
37 | "dateformat": "^4.6.2",
38 | "mkdirp": "^1.0.4"
39 | },
40 | "devDependencies": {
41 | "chai": "^4.3.4",
42 | "mocha": "^9.1.3",
43 | "sinon": "^12.0.1"
44 | },
45 | "scripts": {
46 | "test": "rm -rf _tmp && mocha test/*.spec.js"
47 | },
48 | "engines": {
49 | "node": ">= 12.0.0"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/test/file-path-parser.spec.js:
--------------------------------------------------------------------------------
1 | var parserFactory = require('../lib/file-path-parser.js');
2 | var sinon = require('sinon');
3 | var expect = require('chai').expect;
4 |
5 | describe('file-path-parser', function() {
6 | var testTime;
7 | var parser;
8 | var mockProcess;
9 | var mockDate;
10 | var mockFormatter;
11 |
12 | beforeEach(function() {
13 | testTime = 1459546726107;
14 | mockProcess = {};
15 | mockProcess.pid = 'mockpid123';
16 | mockProcess.cwd = function() { return '/my/mock/cwd'; };
17 |
18 | mockDate = {};
19 | mockDate.now = function() { return testTime; };
20 |
21 | mockFormatter = sinon.stub();
22 | mockFormatter.returnsArg(1);
23 | mockFormatter.withArgs(testTime, 'isoDateTime').returns('defaultTS');
24 |
25 | parser = parserFactory(mockProcess, mockDate, mockFormatter);
26 | });
27 |
28 | it('should add in the current working directory', function() {
29 | var input = '${cwd}/xunit.xml';
30 | var output = parser(input);
31 | expect(output).to.equal('/my/mock/cwd/xunit.xml');
32 | });
33 |
34 | it('should be able to add in the process id', function() {
35 | var input = '~/myProject/xunit-${pid}.xml';
36 | var output = parser(input);
37 | expect(output).to.equal('~/myProject/xunit-mockpid123.xml');
38 | });
39 |
40 | it('should be able to add in multiple process ids', function() {
41 | var input = '~/myProject/xunit/${pid}/report-${pid}.xml';
42 | var output = parser(input);
43 | expect(output).to.equal('~/myProject/xunit/mockpid123/report-mockpid123.xml');
44 | });
45 |
46 | it('should be able to add a default timestamp with shorthand', function() {
47 | var input = '~/myProject/xunit-${ts}.xml';
48 | var output = parser(input);
49 | expect(output).to.equal('~/myProject/xunit-defaultTS.xml');
50 | });
51 |
52 | it('should be able to add a default timestamp with longform', function() {
53 | var input = '~/myProject/xunit-${timestamp}.xml';
54 | var output = parser(input);
55 | expect(output).to.equal('~/myProject/xunit-defaultTS.xml');
56 | });
57 |
58 | it('should be able to add in multiple default timestamps', function() {
59 | var input = '~/myProject/xunit/${ts}/report-${timestamp}.xml';
60 | var output = parser(input);
61 | expect(output).to.equal('~/myProject/xunit/defaultTS/report-defaultTS.xml');
62 | });
63 |
64 | it('should be able to add in custom timestamps using double quotes and short form', function() {
65 | var input = '~/myProject/xunit-${ts: "M"}.xml';
66 | var output = parser(input);
67 | expect(output).to.equal('~/myProject/xunit-M.xml');
68 | expect(mockFormatter.calledWith(testTime, 'M')).to.be.true;
69 | });
70 |
71 | it('should be able to add in custom timestamps using single quotes and long form', function() {
72 | var input = '~/myProject/xunit-${timestamp: \'yyss\'}.xml';
73 | var output = parser(input);
74 | expect(output).to.equal('~/myProject/xunit-yyss.xml');
75 | expect(mockFormatter.calledWith(testTime, 'yyss')).to.be.true;
76 | });
77 |
78 | it('should be able to add in multiple custom timestamps', function() {
79 | var input = '~/myProject/xunit/${ts: \'yyyy\'}/report-${timestamp:"ddmmss"}.xml';
80 | var output = parser(input);
81 | expect(output).to.equal('~/myProject/xunit/yyyy/report-ddmmss.xml');
82 | expect(mockFormatter.calledWith(testTime, 'yyyy')).to.be.true;
83 | expect(mockFormatter.calledWith(testTime, 'ddmmss')).to.be.true;
84 | });
85 |
86 | it('should put it all together', function() {
87 | var input = '${cwd}/${pid}/p-${pid}/time-${ts}/xunit-${timestamp: "mmdd" }.xml';
88 | var output = parser(input);
89 | expect(output).to.equal('/my/mock/cwd/mockpid123/p-mockpid123/time-defaultTS/xunit-mmdd.xml');
90 | expect(mockFormatter.calledWith(testTime, 'mmdd')).to.be.true;
91 | });
92 | });
93 |
--------------------------------------------------------------------------------
/test/fixture/success/success.spec.js:
--------------------------------------------------------------------------------
1 | describe("Success Suite", function () {
2 | it("should pass", function (done) {
3 | done();
4 | });
5 | });
--------------------------------------------------------------------------------
/test/lib/util.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var spawn = require('child_process').spawn;
3 | var mochaBin = require.resolve('mocha/bin/_mocha');
4 |
5 | exports.runFixture = function(name, cb) {
6 | var suitePath = 'test/fixture/' + name
7 | , result = { code: 0, stdout: '', stderr: '' }
8 | , mocha;
9 |
10 | mocha = spawn(mochaBin, [ '--reporter', path.resolve(__dirname, '../../index.js'), suitePath ]);
11 |
12 | mocha.stdout.on('data', function (data) {
13 | result.stdout += data.toString();
14 | });
15 |
16 | mocha.stderr.on('data', function (data) {
17 | result.stderr += data.toString();
18 | });
19 |
20 | mocha.on('close', function (code) {
21 | result.code = code;
22 | cb(result);
23 | });
24 | };
--------------------------------------------------------------------------------
/test/output.spec.js:
--------------------------------------------------------------------------------
1 | var runFixture = require('./lib/util').runFixture
2 | , fs = require('fs');
3 |
4 | describe('output', function () {
5 | afterEach(function () {
6 | delete process.env.XUNIT_FILE;
7 | });
8 |
9 | it('should write the report to the path specified by the XUNIT_FILE environment variable', function (done) {
10 | process.env.XUNIT_FILE = '_tmp/out/target.xml';
11 | runFixture('success', function (result) {
12 | if (result.stderr) {
13 | return done(new Error (result.stderr))
14 | }
15 | var reportExists = fs.existsSync('_tmp/out/target.xml');
16 | (reportExists) ? done() : done(new Error('Report not found'));
17 | })
18 | });
19 | });
--------------------------------------------------------------------------------