diff --git a/README.md b/README.md
index f4be6e0..e98cc2d 100644
--- a/README.md
+++ b/README.md
@@ -142,6 +142,7 @@ jobs:
# java-junit
# jest-junit
# mocha-json
+ # rspec-json
reporter: ''
# Allows you to generate only the summary.
diff --git a/__tests__/__outputs__/rspec-json.md b/__tests__/__outputs__/rspec-json.md
new file mode 100644
index 0000000..04bae8a
--- /dev/null
+++ b/__tests__/__outputs__/rspec-json.md
@@ -0,0 +1,16 @@
+
+## ❌ fixtures/rspec-json.json
+**3** tests were completed in **0ms** with **1** passed, **1** failed and **1** skipped.
+|Test suite|Passed|Failed|Skipped|Time|
+|:---|---:|---:|---:|---:|
+|[./spec/config/check_env_vars_spec.rb](#r0s0)|1✅|1❌|1⚪|0ms|
+### ❌ ./spec/config/check_env_vars_spec.rb
+```
+CheckEnvVars#call when all env vars are defined behaves like success load
+ ❌ CheckEnvVars#call when all env vars are defined behaves like success load fails in assertion
+ (#ActiveSupport::BroadcastLogger:0x00007f1007fedf58).debug("All config env vars exist")
+ expected: 0 times with arguments: ("All config env vars exist")
+ received: 1 time with arguments: ("All config env vars exist")
+ ✅ CheckEnvVars#call when all env vars are defined behaves like success load logs success message
+ ⚪ CheckEnvVars#call when all env vars are defined behaves like success load skips the test
+```
\ No newline at end of file
diff --git a/__tests__/__snapshots__/rspec-json.test.ts.snap b/__tests__/__snapshots__/rspec-json.test.ts.snap
new file mode 100644
index 0000000..cc14bfb
--- /dev/null
+++ b/__tests__/__snapshots__/rspec-json.test.ts.snap
@@ -0,0 +1,49 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`rspec-json tests report from ./reports/rspec-json test results matches snapshot 1`] = `
+TestRunResult {
+ "path": "fixtures/rspec-json.json",
+ "suites": [
+ TestSuiteResult {
+ "groups": [
+ TestGroupResult {
+ "name": "CheckEnvVars#call when all env vars are defined behaves like success load",
+ "tests": [
+ TestCaseResult {
+ "error": {
+ "details": "/usr/local/bundle/ruby/3.3.0/gems/net-http-0.4.1/lib/net/http.rb:1603:in \`initialize'
+./config/check_env_vars.rb:11:in \`call'
+./spec/config/check_env_vars_spec.rb:7:in \`block (3 levels) in '
+./spec/config/check_env_vars_spec.rb:19:in \`block (4 levels) in '",
+ "line": 11,
+ "message": "(#ActiveSupport::BroadcastLogger:0x00007f1007fedf58).debug("All config env vars exist")
+ expected: 0 times with arguments: ("All config env vars exist")
+ received: 1 time with arguments: ("All config env vars exist")",
+ "path": "./config/check_env_vars.rb",
+ },
+ "name": "CheckEnvVars#call when all env vars are defined behaves like success load fails in assertion",
+ "result": "failed",
+ "time": 0.004411051,
+ },
+ TestCaseResult {
+ "error": undefined,
+ "name": "CheckEnvVars#call when all env vars are defined behaves like success load logs success message",
+ "result": "success",
+ "time": 0.079159625,
+ },
+ TestCaseResult {
+ "error": undefined,
+ "name": "CheckEnvVars#call when all env vars are defined behaves like success load skips the test",
+ "result": "skipped",
+ "time": 0.000023007,
+ },
+ ],
+ },
+ ],
+ "name": "./spec/config/check_env_vars_spec.rb",
+ "totalTime": undefined,
+ },
+ ],
+ "totalTime": 0.19118387,
+}
+`;
diff --git a/__tests__/fixtures/empty/rspec-json.json b/__tests__/fixtures/empty/rspec-json.json
new file mode 100644
index 0000000..3629097
--- /dev/null
+++ b/__tests__/fixtures/empty/rspec-json.json
@@ -0,0 +1,17 @@
+{
+ "version": "3.13.0",
+ "messages": [
+ "No examples found."
+ ],
+ "examples": [
+
+ ],
+ "summary": {
+ "duration": 0.002514266,
+ "example_count": 0,
+ "failure_count": 0,
+ "pending_count": 0,
+ "errors_outside_of_examples_count": 0
+ },
+ "summary_line": "0 examples, 0 failures"
+}
diff --git a/__tests__/fixtures/rspec-json.json b/__tests__/fixtures/rspec-json.json
new file mode 100644
index 0000000..34d4e49
--- /dev/null
+++ b/__tests__/fixtures/rspec-json.json
@@ -0,0 +1,53 @@
+{
+ "version": "3.13.0",
+ "examples": [
+ {
+ "id": "./spec/config/check_env_vars_spec.rb[1:1:1:1:1]",
+ "description": "logs success message",
+ "full_description": "CheckEnvVars#call when all env vars are defined behaves like success load logs success message",
+ "status": "passed",
+ "file_path": "./spec/config/check_env_vars_spec.rb",
+ "line_number": 12,
+ "run_time": 0.079159625,
+ "pending_message": null
+ },
+ {
+ "id": "./spec/config/check_env_vars_spec.rb[1:1:1:1:2]",
+ "description": "fails in assertion",
+ "full_description": "CheckEnvVars#call when all env vars are defined behaves like success load fails in assertion",
+ "status": "failed",
+ "file_path": "./spec/config/check_env_vars_spec.rb",
+ "line_number": 17,
+ "run_time": 0.004411051,
+ "pending_message": null,
+ "exception": {
+ "class": "RSpec::Mocks::MockExpectationError",
+ "message": "(#ActiveSupport::BroadcastLogger:0x00007f1007fedf58).debug(\"All config env vars exist\")\n expected: 0 times with arguments: (\"All config env vars exist\")\n received: 1 time with arguments: (\"All config env vars exist\")",
+ "backtrace": [
+ "/usr/local/bundle/ruby/3.3.0/gems/net-http-0.4.1/lib/net/http.rb:1603:in `initialize'",
+ "./config/check_env_vars.rb:11:in `call'",
+ "./spec/config/check_env_vars_spec.rb:7:in `block (3 levels) in \u003ctop (required)\u003e'",
+ "./spec/config/check_env_vars_spec.rb:19:in `block (4 levels) in \u003ctop (required)\u003e'"
+ ]
+ }
+ },
+ {
+ "id": "./spec/config/check_env_vars_spec.rb[1:1:1:1:4]",
+ "description": "skips the test",
+ "full_description": "CheckEnvVars#call when all env vars are defined behaves like success load skips the test",
+ "status": "pending",
+ "file_path": "./spec/config/check_env_vars_spec.rb",
+ "line_number": 27,
+ "run_time": 2.3007e-05,
+ "pending_message": "Temporarily skipped with xit"
+ }
+ ],
+ "summary": {
+ "duration": 0.19118387,
+ "example_count": 3,
+ "failure_count": 1,
+ "pending_count": 1,
+ "errors_outside_of_examples_count": 0
+ },
+ "summary_line": "3 examples, 1 failures, 1 pending"
+}
diff --git a/__tests__/rspec-json.test.ts b/__tests__/rspec-json.test.ts
new file mode 100644
index 0000000..f77475a
--- /dev/null
+++ b/__tests__/rspec-json.test.ts
@@ -0,0 +1,45 @@
+import * as fs from 'fs'
+import * as path from 'path'
+
+import {RspecJsonParser} from '../src/parsers/rspec-json/rspec-json-parser'
+import {ParseOptions} from '../src/test-parser'
+import {getReport} from '../src/report/get-report'
+import {normalizeFilePath} from '../src/utils/path-utils'
+
+describe('rspec-json tests', () => {
+ it('produces empty test run result when there are no test cases', async () => {
+ const fixturePath = path.join(__dirname, 'fixtures', 'empty', 'rspec-json.json')
+ const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
+ const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
+
+ const opts: ParseOptions = {
+ parseErrors: true,
+ trackedFiles: []
+ }
+
+ const parser = new RspecJsonParser(opts)
+ const result = await parser.parse(filePath, fileContent)
+ expect(result.tests).toBe(0)
+ expect(result.result).toBe('success')
+ })
+
+ it('report from ./reports/rspec-json test results matches snapshot', async () => {
+ const fixturePath = path.join(__dirname, 'fixtures', 'rspec-json.json')
+ const outputPath = path.join(__dirname, '__outputs__', 'rspec-json.md')
+ const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
+ const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
+
+ const opts: ParseOptions = {
+ parseErrors: true,
+ trackedFiles: ['test/main.test.js', 'test/second.test.js', 'lib/main.js']
+ }
+
+ const parser = new RspecJsonParser(opts)
+ const result = await parser.parse(filePath, fileContent)
+ expect(result).toMatchSnapshot()
+
+ const report = getReport([result])
+ fs.mkdirSync(path.dirname(outputPath), {recursive: true})
+ fs.writeFileSync(outputPath, report)
+ })
+})
diff --git a/action.yml b/action.yml
index 6f35ebf..8d9d728 100644
--- a/action.yml
+++ b/action.yml
@@ -31,6 +31,7 @@ inputs:
- java-junit
- jest-junit
- mocha-json
+ - rspec-json
- swift-xunit
required: true
list-suites:
diff --git a/dist/index.js b/dist/index.js
index 47a1b8d..dee4468 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -265,6 +265,7 @@ const dotnet_trx_parser_1 = __nccwpck_require__(2664);
const java_junit_parser_1 = __nccwpck_require__(676);
const jest_junit_parser_1 = __nccwpck_require__(1113);
const mocha_json_parser_1 = __nccwpck_require__(6043);
+const rspec_json_parser_1 = __nccwpck_require__(406);
const swift_xunit_parser_1 = __nccwpck_require__(5366);
const path_utils_1 = __nccwpck_require__(4070);
const github_utils_1 = __nccwpck_require__(3522);
@@ -434,6 +435,8 @@ class TestReporter {
return new jest_junit_parser_1.JestJunitParser(options);
case 'mocha-json':
return new mocha_json_parser_1.MochaJsonParser(options);
+ case 'rspec-json':
+ return new rspec_json_parser_1.RspecJsonParser(options);
case 'swift-xunit':
return new swift_xunit_parser_1.SwiftXunitParser(options);
default:
@@ -1403,6 +1406,121 @@ class MochaJsonParser {
exports.MochaJsonParser = MochaJsonParser;
+/***/ }),
+
+/***/ 406:
+/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
+
+"use strict";
+
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.RspecJsonParser = void 0;
+const test_results_1 = __nccwpck_require__(2768);
+class RspecJsonParser {
+ constructor(options) {
+ this.options = options;
+ }
+ parse(path, content) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const mocha = this.getRspecJson(path, content);
+ const result = this.getTestRunResult(path, mocha);
+ result.sort(true);
+ return Promise.resolve(result);
+ });
+ }
+ getRspecJson(path, content) {
+ try {
+ return JSON.parse(content);
+ }
+ catch (e) {
+ throw new Error(`Invalid JSON at ${path}\n\n${e}`);
+ }
+ }
+ getTestRunResult(resultsPath, rspec) {
+ const suitesMap = {};
+ const getSuite = (test) => {
+ var _a;
+ const path = test.file_path;
+ return (_a = suitesMap[path]) !== null && _a !== void 0 ? _a : (suitesMap[path] = new test_results_1.TestSuiteResult(path, []));
+ };
+ for (const test of rspec.examples) {
+ const suite = getSuite(test);
+ if (test.status === 'failed') {
+ this.processTest(suite, test, 'failed');
+ }
+ else if (test.status === 'passed') {
+ this.processTest(suite, test, 'success');
+ }
+ else if (test.status === 'pending') {
+ this.processTest(suite, test, 'skipped');
+ }
+ }
+ const suites = Object.values(suitesMap);
+ return new test_results_1.TestRunResult(resultsPath, suites, rspec.summary.duration);
+ }
+ processTest(suite, test, result) {
+ var _a;
+ const groupName = test.full_description !== test.description
+ ? test.full_description.substr(0, test.full_description.length - test.description.length).trimEnd()
+ : null;
+ let group = suite.groups.find(grp => grp.name === groupName);
+ if (group === undefined) {
+ group = new test_results_1.TestGroupResult(groupName, []);
+ suite.groups.push(group);
+ }
+ const error = this.getTestCaseError(test);
+ const testCase = new test_results_1.TestCaseResult(test.full_description, result, (_a = test.run_time) !== null && _a !== void 0 ? _a : 0, error);
+ group.tests.push(testCase);
+ }
+ getTestCaseError(test) {
+ var _a, _b;
+ const backtrace = (_a = test.exception) === null || _a === void 0 ? void 0 : _a.backtrace;
+ const message = (_b = test.exception) === null || _b === void 0 ? void 0 : _b.message;
+ if (backtrace === undefined) {
+ return undefined;
+ }
+ let path;
+ let line;
+ const details = backtrace.join('\n');
+ const src = this.getExceptionSource(backtrace);
+ if (src) {
+ path = src.path;
+ line = src.line;
+ }
+ return {
+ path,
+ line,
+ message,
+ details
+ };
+ }
+ getExceptionSource(backtrace) {
+ const re = /^(.*?):(\d+):/;
+ for (const str of backtrace) {
+ const match = str.match(re);
+ if (match !== null) {
+ const [_, path, lineStr] = match;
+ if (path.startsWith('./')) {
+ const line = parseInt(lineStr);
+ return { path, line };
+ }
+ }
+ }
+ return undefined;
+ }
+}
+exports.RspecJsonParser = RspecJsonParser;
+
+
/***/ }),
/***/ 5366:
@@ -11219,7 +11337,8 @@ module.exports = function (/**String*/ input, /** object */ options) {
*
* @return Array
*/
- getEntries: function () {
+ getEntries: function (/**String*/ password) {
+ _zip.password=password;
return _zip ? _zip.entries : [];
},
@@ -11296,7 +11415,7 @@ module.exports = function (/**String*/ input, /** object */ options) {
return true;
}
- var content = item.getData();
+ var content = item.getData(_zip.password);
if (!content) throw new Error(Utils.Errors.CANT_EXTRACT_FILE);
if (filetools.fs.existsSync(target) && !overwrite) {
@@ -11458,9 +11577,9 @@ module.exports = function (/**String*/ input, /** object */ options) {
callback(getError("Unable to set times", filePath));
return;
}
- fileEntries.delete(entry);
// call the callback if it was last entry
done();
+ fileEntries.delete(entry);
});
});
}
@@ -11624,7 +11743,9 @@ module.exports = function () {
set time(val) {
setTime(val);
},
-
+ get timeHighByte() {
+ return (_time >>> 8) & 0xff;
+ },
get crc() {
return _crc;
},
@@ -12238,8 +12359,12 @@ function decrypt(/*Buffer*/ data, /*Object*/ header, /*String, Buffer*/ pwd) {
// 2. decrypt salt what is always 12 bytes and is a part of file content
const salt = decrypter(data.slice(0, 12));
- // 3. does password meet expectations
- if (salt[11] !== header.crc >>> 24) {
+ // if bit 3 (0x08) of the general-purpose flags field is set, check salt[11] with the high byte of the header time
+ // 2 byte data block (as per Info-Zip spec), otherwise check with the high byte of the header entry
+ const verifyByte = ((header.flags & 0x8) === 0x8) ? header.timeHighByte : header.crc >>> 24;
+
+ //3. does password meet expectations
+ if (salt[11] !== verifyByte) {
throw "ADM-ZIP: Wrong Password";
}
@@ -13205,6 +13330,7 @@ module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) {
_comment = Buffer.alloc(0),
mainHeader = new Headers.MainHeader(),
loadedEntries = false;
+ var password = null;
// assign options
const opts = Object.assign(Object.create(null), options);
@@ -13456,7 +13582,7 @@ module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) {
// 1.2. postheader - data after data header
const postHeader = Buffer.alloc(entryNameLen + entry.extra.length);
entry.rawEntryName.copy(postHeader, 0);
- postHeader.copy(entry.extra, entryNameLen);
+ entry.extra.copy(postHeader, entryNameLen);
// 2. offsets
const dataLength = dataHeader.length + postHeader.length + compressedData.length;
@@ -26637,31 +26763,21 @@ module.exports.CancelError = CancelError;
"use strict";
-const os = __nccwpck_require__(2037);
const pico = __nccwpck_require__(3322);
-
-const isWindows = os.platform() === 'win32';
+const utils = __nccwpck_require__(479);
function picomatch(glob, options, returnState = false) {
// default to os.platform()
if (options && (options.windows === null || options.windows === undefined)) {
// don't mutate the original options object
- options = { ...options, windows: isWindows };
+ options = { ...options, windows: utils.isWindows() };
}
+
return pico(glob, options, returnState);
}
+Object.assign(picomatch, pico);
module.exports = picomatch;
-// public api
-module.exports.test = pico.test;
-module.exports.matchBase = pico.matchBase;
-module.exports.isMatch = pico.isMatch;
-module.exports.parse = pico.parse;
-module.exports.scan = pico.scan;
-module.exports.compileRe = pico.compileRe;
-module.exports.toRegex = pico.toRegex;
-// for tests
-module.exports.makeRe = pico.makeRe;
/***/ }),
@@ -27068,8 +27184,8 @@ const parse = (input, options) => {
if (tok.value || tok.output) append(tok);
if (prev && prev.type === 'text' && tok.type === 'text') {
+ prev.output = (prev.output || prev.value) + tok.value;
prev.value += tok.value;
- prev.output = (prev.output || '') + tok.value;
return;
}
@@ -27557,10 +27673,6 @@ const parse = (input, options) => {
const next = peek();
let output = value;
- if (next === '<' && !utils.supportsLookbehinds()) {
- throw new Error('Node.js v10 or higher is required for regex lookbehinds');
- }
-
if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {
output = `\\${value}`;
}
@@ -28702,6 +28814,7 @@ module.exports = scan;
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
+/*global navigator*/
const {
@@ -28717,22 +28830,25 @@ exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
+exports.isWindows = () => {
+ if (typeof navigator !== 'undefined' && navigator.platform) {
+ const platform = navigator.platform.toLowerCase();
+ return platform === 'win32' || platform === 'windows';
+ }
+
+ if (typeof process !== 'undefined' && process.platform) {
+ return process.platform === 'win32';
+ }
+
+ return false;
+};
+
exports.removeBackslashes = str => {
return str.replace(REGEX_REMOVE_BACKSLASH, match => {
return match === '\\' ? '' : match;
});
};
-exports.supportsLookbehinds = () => {
- if (typeof process !== 'undefined') {
- const segs = process.version.slice(1).split('.').map(Number);
- if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
- return true;
- }
- }
- return false;
-};
-
exports.escapeLast = (input, char, lastIdx) => {
const idx = input.lastIndexOf(char, lastIdx);
if (idx === -1) return input;
diff --git a/package-lock.json b/package-lock.json
index b728053..d630191 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,21 +1,21 @@
{
- "name": "test-check",
- "version": "1.8.0",
+ "name": "test-reporter",
+ "version": "1.9.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "test-check",
- "version": "1.8.0",
+ "name": "test-reporter",
+ "version": "1.9.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.1",
"@actions/exec": "^1.1.1",
"@actions/github": "^6.0.0",
- "adm-zip": "^0.5.10",
+ "adm-zip": "^0.5.12",
"fast-glob": "^3.3.2",
- "got": "^11.8.2",
- "picomatch": "^3.0.1",
+ "got": "^11.8.6",
+ "picomatch": "^4.0.2",
"xml2js": "^0.6.2"
},
"devDependencies": {
@@ -24,27 +24,27 @@
"@octokit/webhooks-types": "^7.3.1",
"@types/adm-zip": "^0.5.5",
"@types/github-slugger": "^1.3.0",
- "@types/jest": "^29.5.11",
- "@types/node": "^20.11.9",
+ "@types/jest": "^29.5.12",
+ "@types/node": "^18.19.28",
"@types/picomatch": "^2.3.3",
"@types/xml2js": "^0.4.14",
- "@typescript-eslint/eslint-plugin": "^6.19.1",
- "@typescript-eslint/parser": "^6.19.1",
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
+ "@typescript-eslint/parser": "^6.21.0",
"@vercel/ncc": "^0.38.1",
"eol-converter-cli": "^1.0.8",
- "eslint": "^8.56.0",
+ "eslint": "^8.57.0",
"eslint-import-resolver-typescript": "^3.6.1",
- "eslint-plugin-github": "^4.10.1",
+ "eslint-plugin-github": "^4.10.2",
"eslint-plugin-import": "^2.29.1",
- "eslint-plugin-jest": "^27.6.3",
+ "eslint-plugin-jest": "^27.9.0",
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
"jest-circus": "^29.7.0",
"jest-junit": "^16.0.0",
"js-yaml": "^4.1.0",
- "prettier": "^3.2.4",
+ "prettier": "^3.2.5",
"ts-jest": "^29.1.2",
- "typescript": "^5.3.3"
+ "typescript": "^5.4.3"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -820,9 +820,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
- "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+ "version": "8.57.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+ "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -843,13 +843,13 @@
"dev": true
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.11.13",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
- "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
+ "version": "0.11.14",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+ "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
"dev": true,
"dependencies": {
- "@humanwhocodes/object-schema": "^2.0.1",
- "debug": "^4.1.1",
+ "@humanwhocodes/object-schema": "^2.0.2",
+ "debug": "^4.3.1",
"minimatch": "^3.0.5"
},
"engines": {
@@ -870,9 +870,9 @@
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
- "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
"dev": true
},
"node_modules/@istanbuljs/load-nyc-config": {
@@ -1659,9 +1659,9 @@
}
},
"node_modules/@types/jest": {
- "version": "29.5.11",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz",
- "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==",
+ "version": "29.5.12",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz",
+ "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==",
"dev": true,
"dependencies": {
"expect": "^29.0.0",
@@ -1689,9 +1689,9 @@
}
},
"node_modules/@types/node": {
- "version": "20.11.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.9.tgz",
- "integrity": "sha512-CQXNuMoS/VcoAMISe5pm4JnEd1Br5jildbQEToEMQvutmv+EaQr90ry9raiudgpyDuqFiV9e4rnjSfLNq12M5w==",
+ "version": "18.19.28",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.28.tgz",
+ "integrity": "sha512-J5cOGD9n4x3YGgVuaND6khm5x07MMdAKkRyXnjVR6KFhLMNh2yONGiP7Z+4+tBOt5mK+GvDTiacTOVGGpqiecw==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -1747,16 +1747,16 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.1.tgz",
- "integrity": "sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
+ "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.5.1",
- "@typescript-eslint/scope-manager": "6.19.1",
- "@typescript-eslint/type-utils": "6.19.1",
- "@typescript-eslint/utils": "6.19.1",
- "@typescript-eslint/visitor-keys": "6.19.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/type-utils": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
@@ -1782,13 +1782,13 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz",
- "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.19.1",
- "@typescript-eslint/visitor-keys": "6.19.1"
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -1799,9 +1799,9 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz",
- "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -1812,13 +1812,13 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz",
- "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.19.1",
- "@typescript-eslint/visitor-keys": "6.19.1",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -1840,17 +1840,17 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz",
- "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
+ "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "6.19.1",
- "@typescript-eslint/types": "6.19.1",
- "@typescript-eslint/typescript-estree": "6.19.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
"semver": "^7.5.4"
},
"engines": {
@@ -1865,12 +1865,12 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz",
- "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.19.1",
+ "@typescript-eslint/types": "6.21.0",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
@@ -1906,15 +1906,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.1.tgz",
- "integrity": "sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "6.19.1",
- "@typescript-eslint/types": "6.19.1",
- "@typescript-eslint/typescript-estree": "6.19.1",
- "@typescript-eslint/visitor-keys": "6.19.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1934,13 +1934,13 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz",
- "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.19.1",
- "@typescript-eslint/visitor-keys": "6.19.1"
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -1951,9 +1951,9 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz",
- "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -1964,13 +1964,13 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz",
- "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.19.1",
- "@typescript-eslint/visitor-keys": "6.19.1",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -1992,12 +1992,12 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz",
- "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.19.1",
+ "@typescript-eslint/types": "6.21.0",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
@@ -2050,13 +2050,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.1.tgz",
- "integrity": "sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
+ "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "6.19.1",
- "@typescript-eslint/utils": "6.19.1",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
},
@@ -2077,13 +2077,13 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz",
- "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.19.1",
- "@typescript-eslint/visitor-keys": "6.19.1"
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -2094,9 +2094,9 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz",
- "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -2107,13 +2107,13 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz",
- "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.19.1",
- "@typescript-eslint/visitor-keys": "6.19.1",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -2135,17 +2135,17 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz",
- "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
+ "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "6.19.1",
- "@typescript-eslint/types": "6.19.1",
- "@typescript-eslint/typescript-estree": "6.19.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
"semver": "^7.5.4"
},
"engines": {
@@ -2160,12 +2160,12 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
- "version": "6.19.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz",
- "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.19.1",
+ "@typescript-eslint/types": "6.21.0",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
@@ -2320,9 +2320,9 @@
}
},
"node_modules/adm-zip": {
- "version": "0.5.10",
- "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz",
- "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==",
+ "version": "0.5.12",
+ "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.12.tgz",
+ "integrity": "sha512-6TVU49mK6KZb4qG6xWaaM4C7sA/sgUMLy/JYMOzkcp3BvVLpW0fXDFQiIzAuxFCt/2+xD7fNIiPFAoLZPhVNLQ==",
"engines": {
"node": ">=6.0"
}
@@ -3418,16 +3418,16 @@
}
},
"node_modules/eslint": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
- "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+ "version": "8.57.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+ "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.56.0",
- "@humanwhocodes/config-array": "^0.11.13",
+ "@eslint/js": "8.57.0",
+ "@humanwhocodes/config-array": "^0.11.14",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0",
@@ -3611,14 +3611,14 @@
}
},
"node_modules/eslint-plugin-github": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-github/-/eslint-plugin-github-4.10.1.tgz",
- "integrity": "sha512-1AqQBockOM+m0ZUpwfjWtX0lWdX5cRi/hwJnSNvXoOmz/Hh+ULH6QFz6ENWueTWjoWpgPv0af3bj+snps6o4og==",
+ "version": "4.10.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-github/-/eslint-plugin-github-4.10.2.tgz",
+ "integrity": "sha512-F1F5aAFgi1Y5hYoTFzGQACBkw5W1hu2Fu5FSTrMlXqrojJnKl1S2pWO/rprlowRQpt+hzHhqSpsfnodJEVd5QA==",
"dev": true,
"dependencies": {
"@github/browserslist-config": "^1.0.0",
- "@typescript-eslint/eslint-plugin": "^6.0.0",
- "@typescript-eslint/parser": "^6.0.0",
+ "@typescript-eslint/eslint-plugin": "^7.0.1",
+ "@typescript-eslint/parser": "^7.0.1",
"aria-query": "^5.3.0",
"eslint-config-prettier": ">=8.0.0",
"eslint-plugin-escompat": "^3.3.3",
@@ -3641,6 +3641,220 @@
"eslint": "^8.0.1"
}
},
+ "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz",
+ "integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "7.5.0",
+ "@typescript-eslint/type-utils": "7.5.0",
+ "@typescript-eslint/utils": "7.5.0",
+ "@typescript-eslint/visitor-keys": "7.5.0",
+ "debug": "^4.3.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^7.0.0",
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/parser": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.5.0.tgz",
+ "integrity": "sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "7.5.0",
+ "@typescript-eslint/types": "7.5.0",
+ "@typescript-eslint/typescript-estree": "7.5.0",
+ "@typescript-eslint/visitor-keys": "7.5.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/scope-manager": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz",
+ "integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "7.5.0",
+ "@typescript-eslint/visitor-keys": "7.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/type-utils": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz",
+ "integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "7.5.0",
+ "@typescript-eslint/utils": "7.5.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/types": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz",
+ "integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/typescript-estree": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz",
+ "integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "7.5.0",
+ "@typescript-eslint/visitor-keys": "7.5.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "9.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/utils": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz",
+ "integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "7.5.0",
+ "@typescript-eslint/types": "7.5.0",
+ "@typescript-eslint/typescript-estree": "7.5.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ }
+ },
+ "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/visitor-keys": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz",
+ "integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "7.5.0",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/eslint-plugin-github/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-github/node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/eslint-plugin-i18n-text": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-i18n-text/-/eslint-plugin-i18n-text-1.0.1.tgz",
@@ -3712,9 +3926,9 @@
}
},
"node_modules/eslint-plugin-jest": {
- "version": "27.6.3",
- "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.6.3.tgz",
- "integrity": "sha512-+YsJFVH6R+tOiO3gCJon5oqn4KWc+mDq2leudk8mrp8RFubLOo9CVyi3cib4L7XMpxExmkmBZQTPDYVBzgpgOA==",
+ "version": "27.9.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz",
+ "integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==",
"dev": true,
"dependencies": {
"@typescript-eslint/utils": "^5.10.0"
@@ -3723,7 +3937,7 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
},
"peerDependencies": {
- "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0",
+ "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0",
"eslint": "^7.0.0 || ^8.0.0",
"jest": "*"
},
@@ -6199,11 +6413,11 @@
"dev": true
},
"node_modules/picomatch": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz",
- "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"engines": {
- "node": ">=10"
+ "node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
@@ -6292,9 +6506,9 @@
}
},
"node_modules/prettier": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
- "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+ "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@@ -7219,9 +7433,9 @@
}
},
"node_modules/typescript": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
- "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+ "version": "5.4.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
+ "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
diff --git a/package.json b/package.json
index 9742e5d..87251d1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
- "name": "test-check",
- "version": "1.8.0",
+ "name": "test-reporter",
+ "version": "1.9.0",
"private": true,
"description": "Presents test results from popular testing frameworks as Github check run",
"main": "lib/main.js",
@@ -21,7 +21,7 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/dorny/test-check.git"
+ "url": "git+https://github.com/dorny/test-reporter.git"
},
"keywords": [
"actions",
@@ -35,10 +35,10 @@
"@actions/core": "^1.10.1",
"@actions/exec": "^1.1.1",
"@actions/github": "^6.0.0",
- "adm-zip": "^0.5.10",
+ "adm-zip": "^0.5.12",
"fast-glob": "^3.3.2",
- "got": "^11.8.2",
- "picomatch": "^3.0.1",
+ "got": "^11.8.6",
+ "picomatch": "^4.0.2",
"xml2js": "^0.6.2"
},
"devDependencies": {
@@ -47,27 +47,27 @@
"@octokit/webhooks-types": "^7.3.1",
"@types/adm-zip": "^0.5.5",
"@types/github-slugger": "^1.3.0",
- "@types/jest": "^29.5.11",
- "@types/node": "^20.11.9",
+ "@types/jest": "^29.5.12",
+ "@types/node": "^18.19.28",
"@types/picomatch": "^2.3.3",
"@types/xml2js": "^0.4.14",
- "@typescript-eslint/eslint-plugin": "^6.19.1",
- "@typescript-eslint/parser": "^6.19.1",
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
+ "@typescript-eslint/parser": "^6.21.0",
"@vercel/ncc": "^0.38.1",
"eol-converter-cli": "^1.0.8",
- "eslint": "^8.56.0",
+ "eslint": "^8.57.0",
"eslint-import-resolver-typescript": "^3.6.1",
- "eslint-plugin-github": "^4.10.1",
+ "eslint-plugin-github": "^4.10.2",
"eslint-plugin-import": "^2.29.1",
- "eslint-plugin-jest": "^27.6.3",
+ "eslint-plugin-jest": "^27.9.0",
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
"jest-circus": "^29.7.0",
"jest-junit": "^16.0.0",
"js-yaml": "^4.1.0",
- "prettier": "^3.2.4",
+ "prettier": "^3.2.5",
"ts-jest": "^29.1.2",
- "typescript": "^5.3.3"
+ "typescript": "^5.4.3"
},
"jest-junit": {
"suiteName": "jest tests",
diff --git a/src/main.ts b/src/main.ts
index c3c89ef..8f481af 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -15,6 +15,7 @@ import {DotnetTrxParser} from './parsers/dotnet-trx/dotnet-trx-parser'
import {JavaJunitParser} from './parsers/java-junit/java-junit-parser'
import {JestJunitParser} from './parsers/jest-junit/jest-junit-parser'
import {MochaJsonParser} from './parsers/mocha-json/mocha-json-parser'
+import {RspecJsonParser} from './parsers/rspec-json/rspec-json-parser'
import {SwiftXunitParser} from './parsers/swift-xunit/swift-xunit-parser'
import {normalizeDirPath, normalizeFilePath} from './utils/path-utils'
@@ -223,6 +224,8 @@ class TestReporter {
return new JestJunitParser(options)
case 'mocha-json':
return new MochaJsonParser(options)
+ case 'rspec-json':
+ return new RspecJsonParser(options)
case 'swift-xunit':
return new SwiftXunitParser(options)
default:
diff --git a/src/parsers/rspec-json/rspec-json-parser.ts b/src/parsers/rspec-json/rspec-json-parser.ts
new file mode 100644
index 0000000..bf404a1
--- /dev/null
+++ b/src/parsers/rspec-json/rspec-json-parser.ts
@@ -0,0 +1,113 @@
+import { Console } from 'console'
+import {ParseOptions, TestParser} from '../../test-parser'
+import {
+ TestCaseError,
+ TestCaseResult,
+ TestExecutionResult,
+ TestGroupResult,
+ TestRunResult,
+ TestSuiteResult
+} from '../../test-results'
+import {RspecJson, RspecExample} from './rspec-json-types'
+
+export class RspecJsonParser implements TestParser {
+ assumedWorkDir: string | undefined
+
+ constructor(readonly options: ParseOptions) {}
+
+ async parse(path: string, content: string): Promise {
+ const mocha = this.getRspecJson(path, content)
+ const result = this.getTestRunResult(path, mocha)
+ result.sort(true)
+ return Promise.resolve(result)
+ }
+
+ private getRspecJson(path: string, content: string): RspecJson {
+ try {
+ return JSON.parse(content)
+ } catch (e) {
+ throw new Error(`Invalid JSON at ${path}\n\n${e}`)
+ }
+ }
+
+ private getTestRunResult(resultsPath: string, rspec: RspecJson): TestRunResult {
+ const suitesMap: {[path: string]: TestSuiteResult} = {}
+
+ const getSuite = (test: RspecExample): TestSuiteResult => {
+ const path = test.file_path
+ return suitesMap[path] ?? (suitesMap[path] = new TestSuiteResult(path, []))
+ }
+
+ for (const test of rspec.examples) {
+ const suite = getSuite(test)
+ if (test.status === 'failed') {
+ this.processTest(suite, test, 'failed')
+ } else if (test.status === 'passed') {
+ this.processTest(suite, test, 'success')
+ } else if (test.status === 'pending') {
+ this.processTest(suite, test, 'skipped')
+ }
+ }
+
+ const suites = Object.values(suitesMap)
+ return new TestRunResult(resultsPath, suites, rspec.summary.duration)
+ }
+
+ private processTest(suite: TestSuiteResult, test: RspecExample, result: TestExecutionResult): void {
+ const groupName =
+ test.full_description !== test.description
+ ? test.full_description.substr(0, test.full_description.length - test.description.length).trimEnd()
+ : null
+
+ let group = suite.groups.find(grp => grp.name === groupName)
+ if (group === undefined) {
+ group = new TestGroupResult(groupName, [])
+ suite.groups.push(group)
+ }
+
+ const error = this.getTestCaseError(test)
+ const testCase = new TestCaseResult(test.full_description, result, test.run_time ?? 0, error)
+ group.tests.push(testCase)
+ }
+
+ private getTestCaseError(test: RspecExample): TestCaseError | undefined {
+ const backtrace = test.exception?.backtrace
+ const message = test.exception?.message
+ if (backtrace === undefined) {
+ return undefined
+ }
+
+ let path
+ let line
+ const details = backtrace.join('\n')
+
+ const src = this.getExceptionSource(backtrace)
+ if (src) {
+ path = src.path
+ line = src.line
+ }
+
+ return {
+ path,
+ line,
+ message,
+ details
+ }
+ }
+
+ private getExceptionSource(backtrace: string[]): {path: string; line: number} | undefined {
+ const re = /^(.*?):(\d+):/
+
+ for (const str of backtrace) {
+ const match = str.match(re)
+ if (match !== null) {
+ const [_, path, lineStr] = match
+ if (path.startsWith('./')) {
+ const line = parseInt(lineStr)
+ return {path, line}
+ }
+ }
+ }
+ return undefined
+ }
+}
diff --git a/src/parsers/rspec-json/rspec-json-types.ts b/src/parsers/rspec-json/rspec-json-types.ts
new file mode 100644
index 0000000..495af89
--- /dev/null
+++ b/src/parsers/rspec-json/rspec-json-types.ts
@@ -0,0 +1,34 @@
+export interface RspecJson {
+ version: number
+ examples: RspecExample[]
+ summary: RspecSummary
+ summary_line: string
+}
+
+export interface RspecExample {
+ id: string
+ description: string
+ full_description: string
+ status: TestStatus
+ file_path: string
+ line_number: number
+ run_time: number
+ pending_message: string | null
+ exception?: RspecException
+}
+
+type TestStatus = 'passed' | 'failed' | 'pending';
+
+export interface RspecException {
+ class: string
+ message: string
+ backtrace: string[]
+}
+
+export interface RspecSummary {
+ duration: number
+ example_count: number
+ failure_count: number
+ pending_count: number
+ errors_outside_of_examples_count: number
+}