@webex/xunit-with-logs 2.59.1 → 2.59.3-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.js CHANGED
@@ -1,6 +1,6 @@
1
- const config = {
2
- root: true,
3
- extends: ['@webex/eslint-config-legacy'],
4
- };
5
-
6
- module.exports = config;
1
+ const config = {
2
+ root: true,
3
+ extends: ['@webex/eslint-config-legacy'],
4
+ };
5
+
6
+ module.exports = config;
package/README.md CHANGED
@@ -1,35 +1,35 @@
1
- # @webex/xunit-with-logs
2
-
3
- [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
4
-
5
- > Mocha reporter based on the core XUnit reporter; captures console output and includes it under the related test node.
6
-
7
- - [Install](#install)
8
- - [Usage](#usage)
9
- - [Contribute](#contribute)
10
- - [Maintainers](#maintainers)
11
- - [License](#license)
12
-
13
- ## Install
14
-
15
- ```bash
16
- npm install --save @webex/xunit-with-logs
17
- ```
18
-
19
- ## Usage
20
-
21
- ```bash
22
- mocha --reporter @webex/xunit-with-logs ./tests
23
- ```
24
-
25
- ## Maintainers
26
-
27
- This package is maintained by [Cisco Webex for Developers](https://developer.webex.com/).
28
-
29
- ## Contribute
30
-
31
- Pull requests welcome. Please see [CONTRIBUTING.md](https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md) for more details.
32
-
33
- ## License
34
-
35
- © 2016-2020 Cisco and/or its affiliates. All Rights Reserved.
1
+ # @webex/xunit-with-logs
2
+
3
+ [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
4
+
5
+ > Mocha reporter based on the core XUnit reporter; captures console output and includes it under the related test node.
6
+
7
+ - [Install](#install)
8
+ - [Usage](#usage)
9
+ - [Contribute](#contribute)
10
+ - [Maintainers](#maintainers)
11
+ - [License](#license)
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install --save @webex/xunit-with-logs
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```bash
22
+ mocha --reporter @webex/xunit-with-logs ./tests
23
+ ```
24
+
25
+ ## Maintainers
26
+
27
+ This package is maintained by [Cisco Webex for Developers](https://developer.webex.com/).
28
+
29
+ ## Contribute
30
+
31
+ Pull requests welcome. Please see [CONTRIBUTING.md](https://github.com/webex/webex-js-sdk/blob/master/CONTRIBUTING.md) for more details.
32
+
33
+ ## License
34
+
35
+ © 2016-2020 Cisco and/or its affiliates. All Rights Reserved.
package/babel.config.js CHANGED
@@ -1,3 +1,3 @@
1
- const babelConfigLegacy = require('@webex/babel-config-legacy');
2
-
3
- module.exports = babelConfigLegacy;
1
+ const babelConfigLegacy = require('@webex/babel-config-legacy');
2
+
3
+ module.exports = babelConfigLegacy;
package/dist/index.js CHANGED
@@ -4,8 +4,8 @@ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequ
4
4
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
5
5
  var _apply = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/apply"));
6
6
  var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
7
- /*!
8
- * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
7
+ /*!
8
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
9
9
  */
10
10
 
11
11
  // These'll get cleaned up in the xunit PR; for now, they're just here because
@@ -13,8 +13,8 @@ var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/ob
13
13
  /* eslint-disable no-console */
14
14
  /* eslint-disable no-multi-assign */
15
15
 
16
- /**
17
- * Module dependencies.
16
+ /**
17
+ * Module dependencies.
18
18
  */
19
19
 
20
20
  var util = require('util');
@@ -27,19 +27,19 @@ var path = require('path');
27
27
  var _require = require('lodash'),
28
28
  pick = _require.pick;
29
29
 
30
- /**
31
- * Expose `XUnit`.
30
+ /**
31
+ * Expose `XUnit`.
32
32
  */
33
33
 
34
34
  exports = module.exports = XUnit;
35
35
 
36
- /**
37
- * Initialize a new `XUnit` reporter.
38
- *
39
- * @param {Runner} runner
40
- * @param {Object} options
41
- * @returns {undefined}
42
- * @api public
36
+ /**
37
+ * Initialize a new `XUnit` reporter.
38
+ *
39
+ * @param {Runner} runner
40
+ * @param {Object} options
41
+ * @returns {undefined}
42
+ * @api public
43
43
  */
44
44
  function XUnit(runner, options) {
45
45
  (0, _apply.default)(Base, this, [runner]);
@@ -115,17 +115,17 @@ function XUnit(runner, options) {
115
115
  });
116
116
  }
117
117
 
118
- /**
119
- * Inherit from `Base.prototype`.
118
+ /**
119
+ * Inherit from `Base.prototype`.
120
120
  */
121
121
  util.inherits(XUnit, Base);
122
122
 
123
- /**
124
- * Override done to close the stream (if it's a file).
125
- *
126
- * @param {Array} failures
127
- * @param {Function} fn
128
- * @returns {undefined}
123
+ /**
124
+ * Override done to close the stream (if it's a file).
125
+ *
126
+ * @param {Array} failures
127
+ * @param {Function} fn
128
+ * @returns {undefined}
129
129
  */
130
130
  XUnit.prototype.done = function done(failures, fn) {
131
131
  if (this.fileStream) {
@@ -137,11 +137,11 @@ XUnit.prototype.done = function done(failures, fn) {
137
137
  }
138
138
  };
139
139
 
140
- /**
141
- * Write out the given line.
142
- *
143
- * @param {string} line
144
- * @returns {undefined}
140
+ /**
141
+ * Write out the given line.
142
+ *
143
+ * @param {string} line
144
+ * @returns {undefined}
145
145
  */
146
146
  XUnit.prototype.write = function write(line) {
147
147
  if (this.fileStream) {
@@ -151,11 +151,11 @@ XUnit.prototype.write = function write(line) {
151
151
  }
152
152
  };
153
153
 
154
- /**
155
- * Output tag for the given `test.`
156
- *
157
- * @param {Test} test
158
- * @returns {undefined}
154
+ /**
155
+ * Output tag for the given `test.`
156
+ *
157
+ * @param {Test} test
158
+ * @returns {undefined}
159
159
  */
160
160
  XUnit.prototype.test = function testFn(test) {
161
161
  var attrs = {
@@ -185,12 +185,12 @@ XUnit.prototype.test = function testFn(test) {
185
185
  this.write(tag('testcase', attrs, true));
186
186
  }
187
187
 
188
- /**
189
- * reducer
190
- * @param {string} out
191
- * @param {Array<mixed>} args
192
- * @returns {string}
193
- * @private
188
+ /**
189
+ * reducer
190
+ * @param {string} out
191
+ * @param {Array<mixed>} args
192
+ * @returns {string}
193
+ * @private
194
194
  */
195
195
  function reducer(out, args) {
196
196
  return "".concat(out + args.reduce(function (innerOut, arg) {
@@ -199,14 +199,14 @@ XUnit.prototype.test = function testFn(test) {
199
199
  }
200
200
  };
201
201
 
202
- /**
203
- * HTML tag helper.
204
- *
205
- * @param {string} name
206
- * @param {Object} attrs
207
- * @param {boolean} close
208
- * @param {string} content
209
- * @returns {string}
202
+ /**
203
+ * HTML tag helper.
204
+ *
205
+ * @param {string} name
206
+ * @param {Object} attrs
207
+ * @param {boolean} close
208
+ * @param {string} content
209
+ * @returns {string}
210
210
  */
211
211
  function tag(name, attrs, close, content) {
212
212
  var end = close ? '/>' : '>';
@@ -225,10 +225,10 @@ function tag(name, attrs, close, content) {
225
225
  return innerTag;
226
226
  }
227
227
 
228
- /**
229
- * Return cdata escaped CDATA `str`.
230
- * @param {string} str
231
- * @returns {string}
228
+ /**
229
+ * Return cdata escaped CDATA `str`.
230
+ * @param {string} str
231
+ * @returns {string}
232
232
  */
233
233
  function cdata(str) {
234
234
  return "<![CDATA[".concat(escape(str), "]]>");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"names":["util","require","fs","Base","utils","escape","mkdirp","path","_require","pick","exports","module","XUnit","runner","options","_apply","default","stats","tests","self","reporterOptions","output","createWriteStream","Error","sync","dirname","fileStream","on","test","push","logMethodNames","originalMethods","console","systemErr","systemOut","forEach","methodName","_len","arguments","length","args","Array","_key","callerInfo","stack","split","match","callerFile","relative","__dirname","unshift","concat","toUpperCase","write","tag","name","failures","errors","skipped","passes","timestamp","Date","toUTCString","time","duration","t","inherits","prototype","done","fn","end","line","log","testFn","attrs","classname","parent","fullTitle","title","cdata","reduce","reducer","state","err","failureMessage","message","pending","out","innerOut","arg","close","content","pairs","innerTag","_i","_Object$entries","_entries","_Object$entries$_i","_slicedToArray2","key","value","join","str"],"sources":["index.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n// These'll get cleaned up in the xunit PR; for now, they're just here because\n// this file attempted to follow the format of the mocha core xunit reporter\n/* eslint-disable no-console */\n/* eslint-disable no-multi-assign */\n\n/**\n * Module dependencies.\n */\n\nconst util = require('util');\nconst fs = require('fs');\n\nconst Base = require('mocha/lib/reporters/base');\nconst utils = require('mocha/lib/utils');\n\nconst {escape} = utils;\nconst mkdirp = require('mkdirp');\n\nconst path = require('path');\n\nconst {pick} = require('lodash');\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @param {Runner} runner\n * @param {Object} options\n * @returns {undefined}\n * @api public\n */\nfunction XUnit(runner, options) {\n Reflect.apply(Base, this, [runner]);\n const {stats} = this;\n const tests = [];\n const self = this;\n\n if (options.reporterOptions && options.reporterOptions.output) {\n if (!fs.createWriteStream) {\n throw new Error('file output not supported in browser');\n }\n mkdirp.sync(path.dirname(options.reporterOptions.output));\n self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n }\n\n runner.on('pending', (test) => {\n tests.push(test);\n });\n\n runner.on('pass', (test) => {\n tests.push(test);\n });\n\n runner.on('fail', (test) => {\n tests.push(test);\n });\n\n const logMethodNames = ['error', 'warn', 'log', 'info', 'debug', 'trace'];\n const originalMethods = pick(console, logMethodNames);\n\n runner.on('test', (test) => {\n test.systemErr = [];\n test.systemOut = [];\n\n logMethodNames.forEach((methodName) => {\n if (!console[methodName]) {\n methodName = 'log';\n }\n\n console[methodName] = (...args) => {\n Reflect.apply(originalMethods[methodName], console, args);\n\n const callerInfo = new Error().stack.split('\\n')[2].match(/\\((.+?):(\\d+):\\d+/);\n\n if (callerInfo && callerInfo.length >= 2) {\n const callerFile = path.relative(__dirname, '..', callerInfo[1]);\n\n args.unshift(`(FILE:${callerFile || 'UNKNOWN'})`);\n args.unshift(`(LINE:${callerInfo[2] || 'UNKNOWN'})`);\n }\n\n if (methodName === 'error') {\n test.systemErr.push(args);\n } else {\n args.unshift(`${methodName.toUpperCase()}:`);\n\n test.systemOut.push(args);\n }\n };\n });\n });\n\n runner.on('test end', () => {\n logMethodNames.forEach((methodName) => {\n console[methodName] = originalMethods[methodName];\n });\n });\n\n runner.on('end', () => {\n self.write('<testsuites>');\n self.write(\n tag(\n 'testsuite',\n {\n name: 'Mocha Tests',\n tests: stats.tests,\n failures: stats.failures,\n errors: stats.failures,\n skipped: stats.tests - stats.failures - stats.passes,\n timestamp: new Date().toUTCString(),\n time: stats.duration / 1000 || 0,\n },\n false\n )\n );\n\n tests.forEach((t) => {\n self.test(t);\n });\n\n self.write('</testsuite>');\n self.write('</testsuites>');\n });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\nutil.inherits(XUnit, Base);\n\n/**\n * Override done to close the stream (if it's a file).\n *\n * @param {Array} failures\n * @param {Function} fn\n * @returns {undefined}\n */\nXUnit.prototype.done = function done(failures, fn) {\n if (this.fileStream) {\n this.fileStream.end(() => {\n fn(failures);\n });\n } else {\n fn(failures);\n }\n};\n\n/**\n * Write out the given line.\n *\n * @param {string} line\n * @returns {undefined}\n */\nXUnit.prototype.write = function write(line) {\n if (this.fileStream) {\n this.fileStream.write(`${line}\\n`);\n } else {\n console.log(line);\n }\n};\n\n/**\n * Output tag for the given `test.`\n *\n * @param {Test} test\n * @returns {undefined}\n */\nXUnit.prototype.test = function testFn(test) {\n const attrs = {\n classname: test.parent.fullTitle(),\n name: test.title,\n time: test.duration / 1000 || 0,\n };\n\n let systemErr;\n\n if (test.systemErr && test.systemErr.length > 0) {\n systemErr = tag('system-err', {}, false, cdata(test.systemErr.reduce(reducer, '\\n')));\n } else {\n systemErr = '';\n }\n\n let systemOut;\n\n if (test.systemOut && test.systemOut.length > 0) {\n systemOut = tag('system-out', {}, false, cdata(test.systemOut.reduce(reducer, '\\n')));\n } else {\n systemOut = '';\n }\n\n if (test.state === 'failed') {\n const {err} = test;\n const failureMessage = tag('failure', {}, false, cdata(`${escape(err.message)}\\n${err.stack}`));\n\n this.write(tag('testcase', attrs, false, failureMessage + systemOut + systemErr));\n } else if (test.pending) {\n this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\n } else {\n this.write(tag('testcase', attrs, true));\n }\n\n /**\n * reducer\n * @param {string} out\n * @param {Array<mixed>} args\n * @returns {string}\n * @private\n */\n function reducer(out, args) {\n return `${out + args.reduce((innerOut, arg) => `${innerOut + arg} `, '')}\\n`;\n }\n};\n\n/**\n * HTML tag helper.\n *\n * @param {string} name\n * @param {Object} attrs\n * @param {boolean} close\n * @param {string} content\n * @returns {string}\n */\nfunction tag(name, attrs, close, content) {\n const end = close ? '/>' : '>';\n const pairs = [];\n let innerTag;\n\n for (const [key, value] of Object.entries(attrs)) {\n pairs.push(`${key}=\"${escape(value)}\"`);\n }\n\n innerTag = `<${name}${pairs.length ? ` ${pairs.join(' ')}` : ''}${end}`;\n if (content) {\n innerTag += `${content}</${name}${end}`;\n }\n\n return innerTag;\n}\n\n/**\n * Return cdata escaped CDATA `str`.\n * @param {string} str\n * @returns {string}\n */\nfunction cdata(str) {\n return `<![CDATA[${escape(str)}]]>`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["util","require","fs","Base","utils","escape","mkdirp","path","_require","pick","exports","module","XUnit","runner","options","_apply","default","stats","tests","self","reporterOptions","output","createWriteStream","Error","sync","dirname","fileStream","on","test","push","logMethodNames","originalMethods","console","systemErr","systemOut","forEach","methodName","_len","arguments","length","args","Array","_key","callerInfo","stack","split","match","callerFile","relative","__dirname","unshift","concat","toUpperCase","write","tag","name","failures","errors","skipped","passes","timestamp","Date","toUTCString","time","duration","t","inherits","prototype","done","fn","end","line","log","testFn","attrs","classname","parent","fullTitle","title","cdata","reduce","reducer","state","err","failureMessage","message","pending","out","innerOut","arg","close","content","pairs","innerTag","_i","_Object$entries","_entries","_Object$entries$_i","_slicedToArray2","key","value","join","str"],"sources":["index.js"],"sourcesContent":["/*!\r\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\r\n */\r\n\r\n// These'll get cleaned up in the xunit PR; for now, they're just here because\r\n// this file attempted to follow the format of the mocha core xunit reporter\r\n/* eslint-disable no-console */\r\n/* eslint-disable no-multi-assign */\r\n\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nconst util = require('util');\r\nconst fs = require('fs');\r\n\r\nconst Base = require('mocha/lib/reporters/base');\r\nconst utils = require('mocha/lib/utils');\r\n\r\nconst {escape} = utils;\r\nconst mkdirp = require('mkdirp');\r\n\r\nconst path = require('path');\r\n\r\nconst {pick} = require('lodash');\r\n\r\n/**\r\n * Expose `XUnit`.\r\n */\r\n\r\nexports = module.exports = XUnit;\r\n\r\n/**\r\n * Initialize a new `XUnit` reporter.\r\n *\r\n * @param {Runner} runner\r\n * @param {Object} options\r\n * @returns {undefined}\r\n * @api public\r\n */\r\nfunction XUnit(runner, options) {\r\n Reflect.apply(Base, this, [runner]);\r\n const {stats} = this;\r\n const tests = [];\r\n const self = this;\r\n\r\n if (options.reporterOptions && options.reporterOptions.output) {\r\n if (!fs.createWriteStream) {\r\n throw new Error('file output not supported in browser');\r\n }\r\n mkdirp.sync(path.dirname(options.reporterOptions.output));\r\n self.fileStream = fs.createWriteStream(options.reporterOptions.output);\r\n }\r\n\r\n runner.on('pending', (test) => {\r\n tests.push(test);\r\n });\r\n\r\n runner.on('pass', (test) => {\r\n tests.push(test);\r\n });\r\n\r\n runner.on('fail', (test) => {\r\n tests.push(test);\r\n });\r\n\r\n const logMethodNames = ['error', 'warn', 'log', 'info', 'debug', 'trace'];\r\n const originalMethods = pick(console, logMethodNames);\r\n\r\n runner.on('test', (test) => {\r\n test.systemErr = [];\r\n test.systemOut = [];\r\n\r\n logMethodNames.forEach((methodName) => {\r\n if (!console[methodName]) {\r\n methodName = 'log';\r\n }\r\n\r\n console[methodName] = (...args) => {\r\n Reflect.apply(originalMethods[methodName], console, args);\r\n\r\n const callerInfo = new Error().stack.split('\\n')[2].match(/\\((.+?):(\\d+):\\d+/);\r\n\r\n if (callerInfo && callerInfo.length >= 2) {\r\n const callerFile = path.relative(__dirname, '..', callerInfo[1]);\r\n\r\n args.unshift(`(FILE:${callerFile || 'UNKNOWN'})`);\r\n args.unshift(`(LINE:${callerInfo[2] || 'UNKNOWN'})`);\r\n }\r\n\r\n if (methodName === 'error') {\r\n test.systemErr.push(args);\r\n } else {\r\n args.unshift(`${methodName.toUpperCase()}:`);\r\n\r\n test.systemOut.push(args);\r\n }\r\n };\r\n });\r\n });\r\n\r\n runner.on('test end', () => {\r\n logMethodNames.forEach((methodName) => {\r\n console[methodName] = originalMethods[methodName];\r\n });\r\n });\r\n\r\n runner.on('end', () => {\r\n self.write('<testsuites>');\r\n self.write(\r\n tag(\r\n 'testsuite',\r\n {\r\n name: 'Mocha Tests',\r\n tests: stats.tests,\r\n failures: stats.failures,\r\n errors: stats.failures,\r\n skipped: stats.tests - stats.failures - stats.passes,\r\n timestamp: new Date().toUTCString(),\r\n time: stats.duration / 1000 || 0,\r\n },\r\n false\r\n )\r\n );\r\n\r\n tests.forEach((t) => {\r\n self.test(t);\r\n });\r\n\r\n self.write('</testsuite>');\r\n self.write('</testsuites>');\r\n });\r\n}\r\n\r\n/**\r\n * Inherit from `Base.prototype`.\r\n */\r\nutil.inherits(XUnit, Base);\r\n\r\n/**\r\n * Override done to close the stream (if it's a file).\r\n *\r\n * @param {Array} failures\r\n * @param {Function} fn\r\n * @returns {undefined}\r\n */\r\nXUnit.prototype.done = function done(failures, fn) {\r\n if (this.fileStream) {\r\n this.fileStream.end(() => {\r\n fn(failures);\r\n });\r\n } else {\r\n fn(failures);\r\n }\r\n};\r\n\r\n/**\r\n * Write out the given line.\r\n *\r\n * @param {string} line\r\n * @returns {undefined}\r\n */\r\nXUnit.prototype.write = function write(line) {\r\n if (this.fileStream) {\r\n this.fileStream.write(`${line}\\n`);\r\n } else {\r\n console.log(line);\r\n }\r\n};\r\n\r\n/**\r\n * Output tag for the given `test.`\r\n *\r\n * @param {Test} test\r\n * @returns {undefined}\r\n */\r\nXUnit.prototype.test = function testFn(test) {\r\n const attrs = {\r\n classname: test.parent.fullTitle(),\r\n name: test.title,\r\n time: test.duration / 1000 || 0,\r\n };\r\n\r\n let systemErr;\r\n\r\n if (test.systemErr && test.systemErr.length > 0) {\r\n systemErr = tag('system-err', {}, false, cdata(test.systemErr.reduce(reducer, '\\n')));\r\n } else {\r\n systemErr = '';\r\n }\r\n\r\n let systemOut;\r\n\r\n if (test.systemOut && test.systemOut.length > 0) {\r\n systemOut = tag('system-out', {}, false, cdata(test.systemOut.reduce(reducer, '\\n')));\r\n } else {\r\n systemOut = '';\r\n }\r\n\r\n if (test.state === 'failed') {\r\n const {err} = test;\r\n const failureMessage = tag('failure', {}, false, cdata(`${escape(err.message)}\\n${err.stack}`));\r\n\r\n this.write(tag('testcase', attrs, false, failureMessage + systemOut + systemErr));\r\n } else if (test.pending) {\r\n this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\r\n } else {\r\n this.write(tag('testcase', attrs, true));\r\n }\r\n\r\n /**\r\n * reducer\r\n * @param {string} out\r\n * @param {Array<mixed>} args\r\n * @returns {string}\r\n * @private\r\n */\r\n function reducer(out, args) {\r\n return `${out + args.reduce((innerOut, arg) => `${innerOut + arg} `, '')}\\n`;\r\n }\r\n};\r\n\r\n/**\r\n * HTML tag helper.\r\n *\r\n * @param {string} name\r\n * @param {Object} attrs\r\n * @param {boolean} close\r\n * @param {string} content\r\n * @returns {string}\r\n */\r\nfunction tag(name, attrs, close, content) {\r\n const end = close ? '/>' : '>';\r\n const pairs = [];\r\n let innerTag;\r\n\r\n for (const [key, value] of Object.entries(attrs)) {\r\n pairs.push(`${key}=\"${escape(value)}\"`);\r\n }\r\n\r\n innerTag = `<${name}${pairs.length ? ` ${pairs.join(' ')}` : ''}${end}`;\r\n if (content) {\r\n innerTag += `${content}</${name}${end}`;\r\n }\r\n\r\n return innerTag;\r\n}\r\n\r\n/**\r\n * Return cdata escaped CDATA `str`.\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nfunction cdata(str) {\r\n return `<![CDATA[${escape(str)}]]>`;\r\n}\r\n"],"mappings":"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"}
package/jest.config.js CHANGED
@@ -1,3 +1,3 @@
1
- const config = require('@webex/jest-config-legacy');
2
-
3
- module.exports = config;
1
+ const config = require('@webex/jest-config-legacy');
2
+
3
+ module.exports = config;
package/package.json CHANGED
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "name": "@webex/xunit-with-logs",
3
- "version": "2.59.1",
4
3
  "description": "",
5
4
  "license": "MIT",
6
5
  "main": "dist/index.js",
@@ -14,14 +13,14 @@
14
13
  },
15
14
  "devDependencies": {
16
15
  "@babel/core": "^7.17.10",
17
- "@webex/babel-config-legacy": "2.59.1",
18
- "@webex/eslint-config-legacy": "2.59.1",
19
- "@webex/jest-config-legacy": "2.59.1",
20
- "@webex/legacy-tools": "2.59.1",
21
- "@webex/test-helper-chai": "2.59.1",
22
- "@webex/test-helper-mocha": "2.59.1",
23
- "@webex/test-helper-mock-webex": "2.59.1",
24
- "@webex/test-helper-test-users": "2.59.1",
16
+ "@webex/babel-config-legacy": "^0.0.0",
17
+ "@webex/eslint-config-legacy": "^0.0.0",
18
+ "@webex/jest-config-legacy": "^0.0.0",
19
+ "@webex/legacy-tools": "^0.0.0",
20
+ "@webex/test-helper-chai": "^2.59.3-next.1",
21
+ "@webex/test-helper-mocha": "^2.59.3-next.1",
22
+ "@webex/test-helper-mock-webex": "^2.59.3-next.1",
23
+ "@webex/test-helper-test-users": "^2.59.3-next.1",
25
24
  "eslint": "^8.24.0",
26
25
  "mocha": "10.0",
27
26
  "prettier": "^2.7.1"
@@ -33,10 +32,12 @@
33
32
  "scripts": {
34
33
  "build": "yarn build:src",
35
34
  "build:src": "webex-legacy-tools build -dest \"./dist\" -src \"./src\" -js -ts -maps",
35
+ "deploy:npm": "yarn npm publish",
36
36
  "test": "yarn test:style && yarn test:unit && yarn test:integration && yarn test:browser",
37
37
  "test:browser": "webex-legacy-tools test --integration --unit --runner karma",
38
38
  "test:integration": "webex-legacy-tools test --integration --runner mocha",
39
39
  "test:style": "eslint ./src/**/*.*",
40
40
  "test:unit": "webex-legacy-tools test --unit --runner jest"
41
- }
42
- }
41
+ },
42
+ "version": "2.59.3-next.1"
43
+ }
package/process CHANGED
@@ -1 +1 @@
1
- module.exports = {browser: true};
1
+ module.exports = {browser: true};
package/src/index.js CHANGED
@@ -1,256 +1,256 @@
1
- /*!
2
- * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
- */
4
-
5
- // These'll get cleaned up in the xunit PR; for now, they're just here because
6
- // this file attempted to follow the format of the mocha core xunit reporter
7
- /* eslint-disable no-console */
8
- /* eslint-disable no-multi-assign */
9
-
10
- /**
11
- * Module dependencies.
12
- */
13
-
14
- const util = require('util');
15
- const fs = require('fs');
16
-
17
- const Base = require('mocha/lib/reporters/base');
18
- const utils = require('mocha/lib/utils');
19
-
20
- const {escape} = utils;
21
- const mkdirp = require('mkdirp');
22
-
23
- const path = require('path');
24
-
25
- const {pick} = require('lodash');
26
-
27
- /**
28
- * Expose `XUnit`.
29
- */
30
-
31
- exports = module.exports = XUnit;
32
-
33
- /**
34
- * Initialize a new `XUnit` reporter.
35
- *
36
- * @param {Runner} runner
37
- * @param {Object} options
38
- * @returns {undefined}
39
- * @api public
40
- */
41
- function XUnit(runner, options) {
42
- Reflect.apply(Base, this, [runner]);
43
- const {stats} = this;
44
- const tests = [];
45
- const self = this;
46
-
47
- if (options.reporterOptions && options.reporterOptions.output) {
48
- if (!fs.createWriteStream) {
49
- throw new Error('file output not supported in browser');
50
- }
51
- mkdirp.sync(path.dirname(options.reporterOptions.output));
52
- self.fileStream = fs.createWriteStream(options.reporterOptions.output);
53
- }
54
-
55
- runner.on('pending', (test) => {
56
- tests.push(test);
57
- });
58
-
59
- runner.on('pass', (test) => {
60
- tests.push(test);
61
- });
62
-
63
- runner.on('fail', (test) => {
64
- tests.push(test);
65
- });
66
-
67
- const logMethodNames = ['error', 'warn', 'log', 'info', 'debug', 'trace'];
68
- const originalMethods = pick(console, logMethodNames);
69
-
70
- runner.on('test', (test) => {
71
- test.systemErr = [];
72
- test.systemOut = [];
73
-
74
- logMethodNames.forEach((methodName) => {
75
- if (!console[methodName]) {
76
- methodName = 'log';
77
- }
78
-
79
- console[methodName] = (...args) => {
80
- Reflect.apply(originalMethods[methodName], console, args);
81
-
82
- const callerInfo = new Error().stack.split('\n')[2].match(/\((.+?):(\d+):\d+/);
83
-
84
- if (callerInfo && callerInfo.length >= 2) {
85
- const callerFile = path.relative(__dirname, '..', callerInfo[1]);
86
-
87
- args.unshift(`(FILE:${callerFile || 'UNKNOWN'})`);
88
- args.unshift(`(LINE:${callerInfo[2] || 'UNKNOWN'})`);
89
- }
90
-
91
- if (methodName === 'error') {
92
- test.systemErr.push(args);
93
- } else {
94
- args.unshift(`${methodName.toUpperCase()}:`);
95
-
96
- test.systemOut.push(args);
97
- }
98
- };
99
- });
100
- });
101
-
102
- runner.on('test end', () => {
103
- logMethodNames.forEach((methodName) => {
104
- console[methodName] = originalMethods[methodName];
105
- });
106
- });
107
-
108
- runner.on('end', () => {
109
- self.write('<testsuites>');
110
- self.write(
111
- tag(
112
- 'testsuite',
113
- {
114
- name: 'Mocha Tests',
115
- tests: stats.tests,
116
- failures: stats.failures,
117
- errors: stats.failures,
118
- skipped: stats.tests - stats.failures - stats.passes,
119
- timestamp: new Date().toUTCString(),
120
- time: stats.duration / 1000 || 0,
121
- },
122
- false
123
- )
124
- );
125
-
126
- tests.forEach((t) => {
127
- self.test(t);
128
- });
129
-
130
- self.write('</testsuite>');
131
- self.write('</testsuites>');
132
- });
133
- }
134
-
135
- /**
136
- * Inherit from `Base.prototype`.
137
- */
138
- util.inherits(XUnit, Base);
139
-
140
- /**
141
- * Override done to close the stream (if it's a file).
142
- *
143
- * @param {Array} failures
144
- * @param {Function} fn
145
- * @returns {undefined}
146
- */
147
- XUnit.prototype.done = function done(failures, fn) {
148
- if (this.fileStream) {
149
- this.fileStream.end(() => {
150
- fn(failures);
151
- });
152
- } else {
153
- fn(failures);
154
- }
155
- };
156
-
157
- /**
158
- * Write out the given line.
159
- *
160
- * @param {string} line
161
- * @returns {undefined}
162
- */
163
- XUnit.prototype.write = function write(line) {
164
- if (this.fileStream) {
165
- this.fileStream.write(`${line}\n`);
166
- } else {
167
- console.log(line);
168
- }
169
- };
170
-
171
- /**
172
- * Output tag for the given `test.`
173
- *
174
- * @param {Test} test
175
- * @returns {undefined}
176
- */
177
- XUnit.prototype.test = function testFn(test) {
178
- const attrs = {
179
- classname: test.parent.fullTitle(),
180
- name: test.title,
181
- time: test.duration / 1000 || 0,
182
- };
183
-
184
- let systemErr;
185
-
186
- if (test.systemErr && test.systemErr.length > 0) {
187
- systemErr = tag('system-err', {}, false, cdata(test.systemErr.reduce(reducer, '\n')));
188
- } else {
189
- systemErr = '';
190
- }
191
-
192
- let systemOut;
193
-
194
- if (test.systemOut && test.systemOut.length > 0) {
195
- systemOut = tag('system-out', {}, false, cdata(test.systemOut.reduce(reducer, '\n')));
196
- } else {
197
- systemOut = '';
198
- }
199
-
200
- if (test.state === 'failed') {
201
- const {err} = test;
202
- const failureMessage = tag('failure', {}, false, cdata(`${escape(err.message)}\n${err.stack}`));
203
-
204
- this.write(tag('testcase', attrs, false, failureMessage + systemOut + systemErr));
205
- } else if (test.pending) {
206
- this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
207
- } else {
208
- this.write(tag('testcase', attrs, true));
209
- }
210
-
211
- /**
212
- * reducer
213
- * @param {string} out
214
- * @param {Array<mixed>} args
215
- * @returns {string}
216
- * @private
217
- */
218
- function reducer(out, args) {
219
- return `${out + args.reduce((innerOut, arg) => `${innerOut + arg} `, '')}\n`;
220
- }
221
- };
222
-
223
- /**
224
- * HTML tag helper.
225
- *
226
- * @param {string} name
227
- * @param {Object} attrs
228
- * @param {boolean} close
229
- * @param {string} content
230
- * @returns {string}
231
- */
232
- function tag(name, attrs, close, content) {
233
- const end = close ? '/>' : '>';
234
- const pairs = [];
235
- let innerTag;
236
-
237
- for (const [key, value] of Object.entries(attrs)) {
238
- pairs.push(`${key}="${escape(value)}"`);
239
- }
240
-
241
- innerTag = `<${name}${pairs.length ? ` ${pairs.join(' ')}` : ''}${end}`;
242
- if (content) {
243
- innerTag += `${content}</${name}${end}`;
244
- }
245
-
246
- return innerTag;
247
- }
248
-
249
- /**
250
- * Return cdata escaped CDATA `str`.
251
- * @param {string} str
252
- * @returns {string}
253
- */
254
- function cdata(str) {
255
- return `<![CDATA[${escape(str)}]]>`;
256
- }
1
+ /*!
2
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ // These'll get cleaned up in the xunit PR; for now, they're just here because
6
+ // this file attempted to follow the format of the mocha core xunit reporter
7
+ /* eslint-disable no-console */
8
+ /* eslint-disable no-multi-assign */
9
+
10
+ /**
11
+ * Module dependencies.
12
+ */
13
+
14
+ const util = require('util');
15
+ const fs = require('fs');
16
+
17
+ const Base = require('mocha/lib/reporters/base');
18
+ const utils = require('mocha/lib/utils');
19
+
20
+ const {escape} = utils;
21
+ const mkdirp = require('mkdirp');
22
+
23
+ const path = require('path');
24
+
25
+ const {pick} = require('lodash');
26
+
27
+ /**
28
+ * Expose `XUnit`.
29
+ */
30
+
31
+ exports = module.exports = XUnit;
32
+
33
+ /**
34
+ * Initialize a new `XUnit` reporter.
35
+ *
36
+ * @param {Runner} runner
37
+ * @param {Object} options
38
+ * @returns {undefined}
39
+ * @api public
40
+ */
41
+ function XUnit(runner, options) {
42
+ Reflect.apply(Base, this, [runner]);
43
+ const {stats} = this;
44
+ const tests = [];
45
+ const self = this;
46
+
47
+ if (options.reporterOptions && options.reporterOptions.output) {
48
+ if (!fs.createWriteStream) {
49
+ throw new Error('file output not supported in browser');
50
+ }
51
+ mkdirp.sync(path.dirname(options.reporterOptions.output));
52
+ self.fileStream = fs.createWriteStream(options.reporterOptions.output);
53
+ }
54
+
55
+ runner.on('pending', (test) => {
56
+ tests.push(test);
57
+ });
58
+
59
+ runner.on('pass', (test) => {
60
+ tests.push(test);
61
+ });
62
+
63
+ runner.on('fail', (test) => {
64
+ tests.push(test);
65
+ });
66
+
67
+ const logMethodNames = ['error', 'warn', 'log', 'info', 'debug', 'trace'];
68
+ const originalMethods = pick(console, logMethodNames);
69
+
70
+ runner.on('test', (test) => {
71
+ test.systemErr = [];
72
+ test.systemOut = [];
73
+
74
+ logMethodNames.forEach((methodName) => {
75
+ if (!console[methodName]) {
76
+ methodName = 'log';
77
+ }
78
+
79
+ console[methodName] = (...args) => {
80
+ Reflect.apply(originalMethods[methodName], console, args);
81
+
82
+ const callerInfo = new Error().stack.split('\n')[2].match(/\((.+?):(\d+):\d+/);
83
+
84
+ if (callerInfo && callerInfo.length >= 2) {
85
+ const callerFile = path.relative(__dirname, '..', callerInfo[1]);
86
+
87
+ args.unshift(`(FILE:${callerFile || 'UNKNOWN'})`);
88
+ args.unshift(`(LINE:${callerInfo[2] || 'UNKNOWN'})`);
89
+ }
90
+
91
+ if (methodName === 'error') {
92
+ test.systemErr.push(args);
93
+ } else {
94
+ args.unshift(`${methodName.toUpperCase()}:`);
95
+
96
+ test.systemOut.push(args);
97
+ }
98
+ };
99
+ });
100
+ });
101
+
102
+ runner.on('test end', () => {
103
+ logMethodNames.forEach((methodName) => {
104
+ console[methodName] = originalMethods[methodName];
105
+ });
106
+ });
107
+
108
+ runner.on('end', () => {
109
+ self.write('<testsuites>');
110
+ self.write(
111
+ tag(
112
+ 'testsuite',
113
+ {
114
+ name: 'Mocha Tests',
115
+ tests: stats.tests,
116
+ failures: stats.failures,
117
+ errors: stats.failures,
118
+ skipped: stats.tests - stats.failures - stats.passes,
119
+ timestamp: new Date().toUTCString(),
120
+ time: stats.duration / 1000 || 0,
121
+ },
122
+ false
123
+ )
124
+ );
125
+
126
+ tests.forEach((t) => {
127
+ self.test(t);
128
+ });
129
+
130
+ self.write('</testsuite>');
131
+ self.write('</testsuites>');
132
+ });
133
+ }
134
+
135
+ /**
136
+ * Inherit from `Base.prototype`.
137
+ */
138
+ util.inherits(XUnit, Base);
139
+
140
+ /**
141
+ * Override done to close the stream (if it's a file).
142
+ *
143
+ * @param {Array} failures
144
+ * @param {Function} fn
145
+ * @returns {undefined}
146
+ */
147
+ XUnit.prototype.done = function done(failures, fn) {
148
+ if (this.fileStream) {
149
+ this.fileStream.end(() => {
150
+ fn(failures);
151
+ });
152
+ } else {
153
+ fn(failures);
154
+ }
155
+ };
156
+
157
+ /**
158
+ * Write out the given line.
159
+ *
160
+ * @param {string} line
161
+ * @returns {undefined}
162
+ */
163
+ XUnit.prototype.write = function write(line) {
164
+ if (this.fileStream) {
165
+ this.fileStream.write(`${line}\n`);
166
+ } else {
167
+ console.log(line);
168
+ }
169
+ };
170
+
171
+ /**
172
+ * Output tag for the given `test.`
173
+ *
174
+ * @param {Test} test
175
+ * @returns {undefined}
176
+ */
177
+ XUnit.prototype.test = function testFn(test) {
178
+ const attrs = {
179
+ classname: test.parent.fullTitle(),
180
+ name: test.title,
181
+ time: test.duration / 1000 || 0,
182
+ };
183
+
184
+ let systemErr;
185
+
186
+ if (test.systemErr && test.systemErr.length > 0) {
187
+ systemErr = tag('system-err', {}, false, cdata(test.systemErr.reduce(reducer, '\n')));
188
+ } else {
189
+ systemErr = '';
190
+ }
191
+
192
+ let systemOut;
193
+
194
+ if (test.systemOut && test.systemOut.length > 0) {
195
+ systemOut = tag('system-out', {}, false, cdata(test.systemOut.reduce(reducer, '\n')));
196
+ } else {
197
+ systemOut = '';
198
+ }
199
+
200
+ if (test.state === 'failed') {
201
+ const {err} = test;
202
+ const failureMessage = tag('failure', {}, false, cdata(`${escape(err.message)}\n${err.stack}`));
203
+
204
+ this.write(tag('testcase', attrs, false, failureMessage + systemOut + systemErr));
205
+ } else if (test.pending) {
206
+ this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
207
+ } else {
208
+ this.write(tag('testcase', attrs, true));
209
+ }
210
+
211
+ /**
212
+ * reducer
213
+ * @param {string} out
214
+ * @param {Array<mixed>} args
215
+ * @returns {string}
216
+ * @private
217
+ */
218
+ function reducer(out, args) {
219
+ return `${out + args.reduce((innerOut, arg) => `${innerOut + arg} `, '')}\n`;
220
+ }
221
+ };
222
+
223
+ /**
224
+ * HTML tag helper.
225
+ *
226
+ * @param {string} name
227
+ * @param {Object} attrs
228
+ * @param {boolean} close
229
+ * @param {string} content
230
+ * @returns {string}
231
+ */
232
+ function tag(name, attrs, close, content) {
233
+ const end = close ? '/>' : '>';
234
+ const pairs = [];
235
+ let innerTag;
236
+
237
+ for (const [key, value] of Object.entries(attrs)) {
238
+ pairs.push(`${key}="${escape(value)}"`);
239
+ }
240
+
241
+ innerTag = `<${name}${pairs.length ? ` ${pairs.join(' ')}` : ''}${end}`;
242
+ if (content) {
243
+ innerTag += `${content}</${name}${end}`;
244
+ }
245
+
246
+ return innerTag;
247
+ }
248
+
249
+ /**
250
+ * Return cdata escaped CDATA `str`.
251
+ * @param {string} str
252
+ * @returns {string}
253
+ */
254
+ function cdata(str) {
255
+ return `<![CDATA[${escape(str)}]]>`;
256
+ }