Compare commits

...

36 Commits

Author SHA1 Message Date
Michal Dorner
0c4e1654a1 Merge pull request #99 from dorny/dev
Version 1.4.0
2021-04-20 00:09:45 +02:00
Michal Dorner
c74b76e916 Update CHANGELOG for v1.4.0 2021-04-20 00:05:12 +02:00
Michal Dorner
d39bdea68c Update screenshots for README 2021-04-19 23:58:58 +02:00
Michal Dorner
e81e3750bc Merge pull request #90 from dorny/mocha-json
Add support for mocha-json
2021-04-19 23:22:04 +02:00
Michal Dorner
368fd2475a Fix grammar issues in README 2021-04-19 23:19:35 +02:00
Michal Dorner
78b798ea79 Add mocha-json external test fixtures 2021-04-19 23:19:19 +02:00
Michal Dorner
0e5d21a75b Document potential issue with mocha JSON reporter 2021-04-01 00:05:59 +02:00
Michal Dorner
ee126813a2 Merge branch 'dev' into mocha-json 2021-04-01 00:05:41 +02:00
Michal Dorner
39f7ac7868 Merge pull request #89 from dorny/fix-suite-links
Use full URL to link test suites
2021-03-31 23:33:25 +02:00
Michal Dorner
4c2f9f34f7 Use full URL in suites table
Adds full URL in place previous commit missed
2021-03-31 23:30:19 +02:00
Michal Dorner
fab342311c Use full URL to link test suites
GitHub UI for some unknown reason navigates user to check run with `check_suite_focus=true` query argument. With this argument unfortunately navigation to document ID with `#something` doesn't work
2021-03-31 23:22:02 +02:00
Michal Dorner
f48646179b Merge pull request #88 from dorny/improve-report
Improve report
2021-03-31 22:57:20 +02:00
Michal Dorner
cfaaaf1a47 Use non-breaking space between icon and suite name 2021-03-31 22:34:58 +02:00
Michal Dorner
690ec77880 New report rendering with code blocks instead of tables
Previously we listed tests using markdown tables. Each test group had it's own table and textual preface saying how many tests were executed in what time.
This was completely reworked - now tests are listed inside code block. Grouping is achieved using simple indentation. Duration of individual tests is no longer shown - it produced too much "noise" in the report. Pass/Fail check-mark was also moved before name of test suite.
Behavior of "listTests" option was also changed - now if set to failed, it will list all tests, but only if suite is failed. Otherwise test listing is completely omitted.
Last change affects report trimming - if report is still too big after "listTests" is set to "failed" - it will trim report to fit max size and add informational message at the end.
2021-03-31 21:49:53 +02:00
Michal Dorner
96df6db61e Round test duration to whole seconds if it's more then 1s
Report will contain less accurate information but it will be easier to read.
2021-03-31 21:33:21 +02:00
Michal Dorner
3c4d3b3836 Merge pull request #87 from dorny/dart-error-message
Improve test error messages from flutter
2021-03-31 21:28:46 +02:00
Michal Dorner
ea36be4653 Improve test error messages from flutter
For some reason the error message from flutter SDK might contain no useful information. Basically it just says that test failed and you should see the logs. Logs itself are provided as content of `print` event. This commit adds special processing for this behavior - it parses actual error message out of print event.
2021-03-31 21:25:54 +02:00
Michal Dorner
2c87efac07 Moving README,CHANGELOG and LICENSE back to root folder
It turns out it's not possible to publish action when README is in docs folder
2021-03-24 18:22:55 +01:00
Michal Dorner
383ae3ef8c Fix path to assets in README 2021-03-24 18:17:10 +01:00
Michal Dorner
8a00817999 Update CHANGELOG for v1.3.1 2021-03-24 18:15:49 +01:00
Michal Dorner
bab8ddc2ca Move README, CHANGELOG and LICENSE to docs folder 2021-03-24 18:10:44 +01:00
Michal Dorner
10268d2d6d Merge pull request #86 from dorny/issue-82-net-trx-no-duration
Fixes #82: net-trx parser handles missing duration attribute
2021-03-24 18:08:55 +01:00
Michal Dorner
d29a37e78a Fixes #82 - net-trx parser handles missing duration attribute 2021-03-24 18:02:31 +01:00
Michal Dorner
faaff05398 Merge pull request #85 from dorny/dart-json-fix-duplicated-group-name
dart-json: remove group name from test case names
2021-03-23 22:03:16 +01:00
Michal Dorner
d5e42b8d57 dart-json: remove group name from test case names 2021-03-23 21:58:20 +01:00
Michal Dorner
40df4133f9 Merge pull request #84 from Shazwazza/patch-1
Fixes #83 - parsing .NET duration without milliseconds throws error
2021-03-23 21:45:24 +01:00
Michal Dorner
3a0bb833dc #83 - Use non-capturing optional group, add tests and update dist 2021-03-23 21:39:47 +01:00
Shannon Deminick
c0e7f7f7dc Fixes #83
This regex change should match the dotnet format with or without milliseconds
2021-03-23 11:09:02 +11:00
Michal Dorner
b9af250554 Document mocha-json usage 2021-03-08 21:27:44 +01:00
Michal Dorner
9db99178aa Add mocha-json test case for empty test results 2021-03-08 21:04:14 +01:00
Michal Dorner
3768e4e756 Merge branch 'main' into mocha-json 2021-03-08 21:00:14 +01:00
Michal Dorner
63dddc9ecc Update dist/index.js 2021-02-24 21:35:06 +01:00
Michal Dorner
2d842d6ac6 Upload test results on success() || failure() 2021-02-24 21:33:54 +01:00
Michal Dorner
fbb83bff74 Include group name in error annotations 2021-02-24 21:33:29 +01:00
Michal Dorner
8dba8714d0 Fix mocha report fixture + test duration handling 2021-02-24 21:32:51 +01:00
Michal Dorner
9b675bd55f Add support for mocha-json 2021-02-23 22:39:35 +01:00
46 changed files with 28379 additions and 1358 deletions

View File

@@ -21,6 +21,7 @@ jobs:
- run: npm test - run: npm test
- name: Upload test results - name: Upload test results
if: success() || failure()
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: test-results name: test-results

View File

@@ -1,5 +1,16 @@
# Changelog # Changelog
## v1.4.0
- [Add support for mocha-json](https://github.com/dorny/test-reporter/pull/90)
- [Use full URL to fix navigation from summary to suite details](https://github.com/dorny/test-reporter/pull/89)
- [New report rendering with code blocks instead of tables](https://github.com/dorny/test-reporter/pull/88)
- [Improve test error messages from flutter](https://github.com/dorny/test-reporter/pull/87)
## v1.3.1
- [Fix: parsing of .NET duration string without milliseconds](https://github.com/dorny/test-reporter/pull/84)
- [Fix: dart-json - remove group name from test case names](https://github.com/dorny/test-reporter/pull/85)
- [Fix: net-trx parser crashing on missing duration attribute](https://github.com/dorny/test-reporter/pull/86)
## v1.3.0 ## v1.3.0
- [Add support for java-junit](https://github.com/dorny/test-reporter/pull/80) - [Add support for java-junit](https://github.com/dorny/test-reporter/pull/80)
- [Fix: Handle test reports with no test cases](https://github.com/dorny/test-reporter/pull/70) - [Fix: Handle test reports with no test cases](https://github.com/dorny/test-reporter/pull/70)

View File

@@ -9,15 +9,15 @@ This [Github Action](https://github.com/features/actions) displays test results
✔️ Provides final `conclusion` and counts of `passed`, `failed` and `skipped` tests as output parameters ✔️ Provides final `conclusion` and counts of `passed`, `failed` and `skipped` tests as output parameters
**How it looks:** **How it looks:**
|![](assets/fluent-validation-report.png)|![](assets/provider-error-summary.png)|![](assets/provider-error-details.png)|![](assets/provider-groups.png)| |![](assets/fluent-validation-report.png)|![](assets/provider-error-summary.png)|![](assets/provider-error-details.png)|![](assets/mocha-groups.png)|
|:--:|:--:|:--:|:--:| |:--:|:--:|:--:|:--:|
**Supported languages / frameworks:** **Supported languages / frameworks:**
- .NET / [xUnit](https://xunit.net/) / [NUnit](https://nunit.org/) / [MSTest](https://github.com/Microsoft/testfx-docs) - .NET / [xUnit](https://xunit.net/) / [NUnit](https://nunit.org/) / [MSTest](https://github.com/Microsoft/testfx-docs)
- Dart / [test](https://pub.dev/packages/test) - Dart / [test](https://pub.dev/packages/test)
- Flutter / [test](https://pub.dev/packages/test) - Flutter / [test](https://pub.dev/packages/test)
- JavaScript / [JEST](https://jestjs.io/)
- Java / [JUnit](https://junit.org/) - Java / [JUnit](https://junit.org/)
- JavaScript / [JEST](https://jestjs.io/) / [Mocha](https://mochajs.org/)
For more information see [Supported formats](#supported-formats) section. For more information see [Supported formats](#supported-formats) section.
@@ -54,9 +54,9 @@ jobs:
## Recommended setup for public repositories ## Recommended setup for public repositories
Workflows triggered by pull requests from forked repositories are executed with read-only token and therefore can't create check runs. Workflows triggered by pull requests from forked repositories are executed with read-only token and therefore can't create check runs.
To workaround this security restriction it's required to use two separate workflows: To workaround this security restriction, it's required to use two separate workflows:
1. `CI` runs in the context of PR head branch with read-only token. It executes the tests and uploads test results as build artifact 1. `CI` runs in the context of the PR head branch with the read-only token. It executes the tests and uploads test results as a build artifact
2. `Test Report` runs in the context of repository main branch with read/write token. It will download test results and create reports 2. `Test Report` runs in the context of the repository main branch with read/write token. It will download test results and create reports
**PR head branch:** *.github/workflows/ci.yml* **PR head branch:** *.github/workflows/ci.yml*
```yaml ```yaml
@@ -116,7 +116,7 @@ jobs:
# Coma separated list of paths to test results # Coma separated list of paths to test results
# Supports wildcards via [fast-glob](https://github.com/mrmlnc/fast-glob) # Supports wildcards via [fast-glob](https://github.com/mrmlnc/fast-glob)
# All matched result files must be of same format # All matched result files must be of the same format
path: '' path: ''
# Format of test results. Supported options: # Format of test results. Supported options:
@@ -125,6 +125,7 @@ jobs:
# flutter-json # flutter-json
# java-junit # java-junit
# jest-junit # jest-junit
# mocha-json
reporter: '' reporter: ''
# Limits which test suites are listed: # Limits which test suites are listed:
@@ -142,7 +143,7 @@ jobs:
# Must be less or equal to 50. # Must be less or equal to 50.
max-annotations: '10' max-annotations: '10'
# Set action as failed if test report contain any failed test # Set action as failed if test report contains any failed test
fail-on-error: 'true' fail-on-error: 'true'
# Relative path under $GITHUB_WORKSPACE where the repository was checked out. # Relative path under $GITHUB_WORKSPACE where the repository was checked out.
@@ -224,8 +225,8 @@ Or with (undocumented) CLI argument:
According to documentation `dart_test.yaml` should be at the root of the package, next to the package's pubspec. According to documentation `dart_test.yaml` should be at the root of the package, next to the package's pubspec.
On current `stable` and `beta` channels it doesn't work and you have to put `dart_test.yaml` inside your `test` folder. On current `stable` and `beta` channels it doesn't work, and you have to put `dart_test.yaml` inside your `test` folder.
On `dev` channel it's already fixed. On `dev` channel, it's already fixed.
For more information see: For more information see:
- [test package](https://pub.dev/packages/test) - [test package](https://pub.dev/packages/test)
@@ -239,17 +240,17 @@ For more information see:
<summary>java-junit (Experimental)</summary> <summary>java-junit (Experimental)</summary>
Support for [JUnit](https://Junit.org/) XML is experimental - should work but it was not extensively tested. Support for [JUnit](https://Junit.org/) XML is experimental - should work but it was not extensively tested.
To have code annotations working properly it's required your directory structure matches package name. To have code annotations working properly, it's required your directory structure matches the package name.
This is due to the fact Java stacktraces doesn't contains full path to the source file. This is due to the fact Java stack traces don't contain a full path to the source file.
Some heuristic was necessary to figure out mapping between line in stack trace and actual source file. Some heuristic was necessary to figure out the mapping between the line in the stack trace and an actual source file.
</details> </details>
<details> <details>
<summary>jest-Junit</summary> <summary>jest-Junit</summary>
[JEST](https://jestjs.io/) testing framework support requires usage of [jest-Junit](https://github.com/jest-community/jest-Junit) reporter. [JEST](https://jestjs.io/) testing framework support requires the usage of [jest-Junit](https://github.com/jest-community/jest-Junit) reporter.
It will create test results in Junit XML format which can be then processed by this action. It will create test results in Junit XML format which can be then processed by this action.
You can use following example configuration in `package.json`: You can use the following example configuration in `package.json`:
```json ```json
"scripts": { "scripts": {
"test": "jest --ci --reporters=default --reporters=jest-Junit" "test": "jest --ci --reporters=default --reporters=jest-Junit"
@@ -272,20 +273,39 @@ You can use following example configuration in `package.json`:
Configuration of `uniqueOutputName`, `suiteNameTemplate`, `classNameTemplate`, `titleTemplate` is important for proper visualization of test results. Configuration of `uniqueOutputName`, `suiteNameTemplate`, `classNameTemplate`, `titleTemplate` is important for proper visualization of test results.
</details> </details>
<details>
<summary>mocha-json</summary>
[Mocha](https://mochajs.org/) testing framework support requires:
- Mocha version [v7.2.0](https://github.com/mochajs/mocha/releases/tag/v7.2.0) or higher
- Usage of [json](https://mochajs.org/#json) reporter.
You can use the following example configuration in `package.json`:
```json
"scripts": {
"test": "mocha --reporter json > test-results.json"
}
```
Test processing might fail if any of your tests write anything on standard output.
Mocha, unfortunately, doesn't have the option to store `json` output directly to the file, and we have to rely on redirecting its standard output.
There is a work in progress to fix it: [mocha#4607](https://github.com/mochajs/mocha/pull/4607)
</details>
## GitHub limitations ## GitHub limitations
Unfortunately there are some known issues and limitations caused by GitHub API: Unfortunately, there are some known issues and limitations caused by GitHub API:
- Test report (i.e. Check Run summary) is markdown text. No custom styling or HTML is possible. - Test report (i.e. Check Run summary) is markdown text. No custom styling or HTML is possible.
- Maximum report size is 65535 bytes. Input parameters `list-suites` and `list-tests` will be automatically adjusted if max size is exceeded. - Maximum report size is 65535 bytes. Input parameters `list-suites` and `list-tests` will be automatically adjusted if max size is exceeded.
- Test report can't reference any additional files (e.g. screenshots). You can use `actions/upload-artifact@v2` to upload them and inspect manually. - Test report can't reference any additional files (e.g. screenshots). You can use `actions/upload-artifact@v2` to upload them and inspect them manually.
- Check Runs are created for specific commit SHA. it's not possible to specify under which workflow test report should belong if there are more - Check Runs are created for specific commit SHA. It's not possible to specify under which workflow test report should belong if more
workflows running for same SHA. Thanks to this GitHub "feature" it's possible your test report will appear in unexpected place in GitHub UI. workflows are running for the same SHA. Thanks to this GitHub "feature" it's possible your test report will appear in an unexpected place in GitHub UI.
For more information see [#67](https://github.com/dorny/test-reporter/issues/67). For more information, see [#67](https://github.com/dorny/test-reporter/issues/67).
## See also ## See also
- [paths-filter](https://github.com/dorny/paths-filter) - Conditionally run actions based on files modified by PR, feature branch or pushed commits - [paths-filter](https://github.com/dorny/paths-filter) - Conditionally run actions based on files modified by PR, feature branch, or pushed commits
## License ## License
The scripts and documentation in this project are released under the [MIT License](https://github.com/dorny/test-reporter/blob/master/LICENSE) The scripts and documentation in this project are released under the [MIT License](https://github.com/dorny/test-reporter/blob/main/LICENSE)

View File

@@ -1,32 +1,28 @@
![Tests failed](https://img.shields.io/badge/tests-1%20passed%2C%204%20failed%2C%201%20skipped-critical) ![Tests failed](https://img.shields.io/badge/tests-1%20passed%2C%204%20failed%2C%201%20skipped-critical)
## <a id="user-content-r0" href="#r0">fixtures/dart-json.json</a> ## ❌ <a id="user-content-r0" href="#r0">fixtures/dart-json.json</a>
**6** tests were completed in **3.760s** with **1** passed, **4** failed and **1** skipped. **6** tests were completed in **4s** with **1** passed, **4** failed and **1** skipped.
|Test suite|Passed|Failed|Skipped|Time| |Test suite|Passed|Failed|Skipped|Time|
|:---|---:|---:|---:|---:| |:---|---:|---:|---:|---:|
|[test/main_test.dart](#r0s0)|1✔|3❌||74ms| |[test/main_test.dart](#r0s0)|1✔|3❌||74ms|
|[test/second_test.dart](#r0s1)||1❌|1✖|51ms| |[test/second_test.dart](#r0s1)||1❌|1✖|51ms|
### <a id="user-content-r0s0" href="#r0s0">test/main_test.dart</a> ### ❌ <a id="user-content-r0s0" href="#r0s0">test/main_test.dart</a>
**4** tests were completed in **74ms** with **1** passed, **3** failed and **0** skipped. ```
Test 1
**Test 1** ✔️ Passing test
|Result|Test|Time| Test 1 Test 1.1
|:---:|:---|---:| ❌ Failing test
|✔️|Test 1 Passing test|36ms| Expected: <2>
Actual: <1>
**Test 1 Test 1.1**
|Result|Test|Time| ❌ Exception in target unit
|:---:|:---|---:| Exception: Some error
|❌|Test 1 Test 1.1 Failing test|20ms| Test 2
|❌|Test 1 Test 1.1 Exception in target unit|6ms| ❌ Exception in test
Exception: Some error
**Test 2** ```
|Result|Test|Time| ### ❌ <a id="user-content-r0s1" href="#r0s1">test/second_test.dart</a>
|:---:|:---|---:| ```
|❌|Test 2 Exception in test|12ms| ❌ Timeout test
### <a id="user-content-r0s1" href="#r0s1">test/second_test.dart</a> ❌ TimeoutException after 0:00:00.000001: Test timed out after 0 seconds.
**2** tests were completed in **51ms** with **0** passed, **1** failed and **1** skipped. ✖️ Skipped test
```
|Result|Test|Time|
|:---:|:---|---:|
|❌|Timeout test|37ms|
|✖️|Skipped test|14ms|

View File

@@ -1,18 +1,21 @@
![Tests failed](https://img.shields.io/badge/tests-3%20passed%2C%203%20failed%2C%201%20skipped-critical) ![Tests failed](https://img.shields.io/badge/tests-3%20passed%2C%203%20failed%2C%201%20skipped-critical)
## <a id="user-content-r0" href="#r0">fixtures/dotnet-trx.trx</a> ## ❌ <a id="user-content-r0" href="#r0">fixtures/dotnet-trx.trx</a>
**7** tests were completed in **1.061s** with **3** passed, **3** failed and **1** skipped. **7** tests were completed in **1s** with **3** passed, **3** failed and **1** skipped.
|Test suite|Passed|Failed|Skipped|Time| |Test suite|Passed|Failed|Skipped|Time|
|:---|---:|---:|---:|---:| |:---|---:|---:|---:|---:|
|[DotnetTests.XUnitTests.CalculatorTests](#r0s0)|3✔|3❌|1✖|110ms| |[DotnetTests.XUnitTests.CalculatorTests](#r0s0)|3✔|3❌|1✖|110ms|
### <a id="user-content-r0s0" href="#r0s0">DotnetTests.XUnitTests.CalculatorTests</a> ### ❌ <a id="user-content-r0s0" href="#r0s0">DotnetTests.XUnitTests.CalculatorTests</a>
**7** tests were completed in **110ms** with **3** passed, **3** failed and **1** skipped. ```
❌ Exception_In_TargetTest
|Result|Test|Time| System.DivideByZeroException : Attempted to divide by zero.
|:---:|:---|---:| ❌ Exception_In_Test
|❌|Exception_In_TargetTest|0ms| System.Exception : Test
|❌|Exception_In_Test|2ms| ❌ Failing_Test
|❌|Failing_Test|3ms| Assert.Equal() Failure
|✔️|Passing_Test|0ms| Expected: 3
|✔️|Passing_Test_With_Name|0ms| Actual: 2
|✖️|Skipped_Test|1ms| ✔️ Passing_Test
|✔️|Timeout_Test|102ms| ✔️ Passing_Test_With_Name
✖️ Skipped_Test
✔️ Timeout_Test
```

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +1,26 @@
![Tests failed](https://img.shields.io/badge/tests-1%20passed%2C%204%20failed%2C%201%20skipped-critical) ![Tests failed](https://img.shields.io/badge/tests-1%20passed%2C%204%20failed%2C%201%20skipped-critical)
## <a id="user-content-r0" href="#r0">fixtures/jest-junit.xml</a> ## ❌ <a id="user-content-r0" href="#r0">fixtures/jest-junit.xml</a>
**6** tests were completed in **1.360s** with **1** passed, **4** failed and **1** skipped. **6** tests were completed in **1s** with **1** passed, **4** failed and **1** skipped.
|Test suite|Passed|Failed|Skipped|Time| |Test suite|Passed|Failed|Skipped|Time|
|:---|---:|---:|---:|---:| |:---|---:|---:|---:|---:|
|[__tests__\main.test.js](#r0s0)|1✔|3❌||486ms| |[__tests__\main.test.js](#r0s0)|1✔|3❌||486ms|
|[__tests__\second.test.js](#r0s1)||1❌|1✖|82ms| |[__tests__\second.test.js](#r0s1)||1❌|1✖|82ms|
### <a id="user-content-r0s0" href="#r0s0">__tests__\main.test.js</a> ### ❌ <a id="user-content-r0s0" href="#r0s0">__tests__\main.test.js</a>
**4** tests were completed in **486ms** with **1** passed, **3** failed and **0** skipped. ```
Test 1
**Test 1** ✔️ Passing test
|Result|Test|Time| Test 1 Test 1.1
|:---:|:---|---:| ❌ Failing test
|✔️|Passing test|1ms| Error: expect(received).toBeTruthy()
❌ Exception in target unit
**Test 1 Test 1.1** Error: Some error
|Result|Test|Time| Test 2
|:---:|:---|---:| ❌ Exception in test
|❌|Failing test|2ms| Error: Some error
|❌|Exception in target unit|0ms| ```
### ❌ <a id="user-content-r0s1" href="#r0s1">__tests__\second.test.js</a>
**Test 2** ```
|Result|Test|Time| ❌ Timeout test
|:---:|:---|---:| : Timeout - Async callback was not invoked within the 1 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 1 ms timeout specified by jest.setTimeout.Error:
|❌|Exception in test|0ms| ✖️ Skipped test
### <a id="user-content-r0s1" href="#r0s1">__tests__\second.test.js</a> ❌ ```
**2** tests were completed in **82ms** with **0** passed, **1** failed and **1** skipped.
|Result|Test|Time|
|:---:|:---|---:|
|❌|Timeout test|4ms|
|✖️|Skipped test|0ms|

View File

@@ -1,182 +1,182 @@
![Tests failed](https://img.shields.io/badge/tests-4207%20passed%2C%202%20failed%2C%2030%20skipped-critical) ![Tests failed](https://img.shields.io/badge/tests-4207%20passed%2C%202%20failed%2C%2030%20skipped-critical)
## <a id="user-content-r0" href="#r0">fixtures/external/jest/jest-test-results.xml</a> ## ❌ <a id="user-content-r0" href="#r0">fixtures/external/jest/jest-test-results.xml</a>
**4239** tests were completed in **165.872s** with **4207** passed, **2** failed and **30** skipped. **4239** tests were completed in **166s** with **4207** passed, **2** failed and **30** skipped.
|Test suite|Passed|Failed|Skipped|Time| |Test suite|Passed|Failed|Skipped|Time|
|:---|---:|---:|---:|---:| |:---|---:|---:|---:|---:|
|e2e/__tests__/asyncAndCallback.test.ts|1✔|||746ms| |e2e/__tests__/asyncAndCallback.test.ts|1✔|||746ms|
|e2e/__tests__/asyncRegenerator.test.ts|1✔|||4.127s| |e2e/__tests__/asyncRegenerator.test.ts|1✔|||4s|
|e2e/__tests__/autoClearMocks.test.ts|2✔|||1.681s| |e2e/__tests__/autoClearMocks.test.ts|2✔|||2s|
|e2e/__tests__/autoResetMocks.test.ts|2✔|||1.666s| |e2e/__tests__/autoResetMocks.test.ts|2✔|||2s|
|e2e/__tests__/autoRestoreMocks.test.ts|2✔|||1.797s| |e2e/__tests__/autoRestoreMocks.test.ts|2✔|||2s|
|e2e/__tests__/babelPluginJestHoist.test.ts|1✔|||6.249s| |e2e/__tests__/babelPluginJestHoist.test.ts|1✔|||6s|
|e2e/__tests__/badSourceMap.test.ts|1✔|||858ms| |e2e/__tests__/badSourceMap.test.ts|1✔|||858ms|
|e2e/__tests__/beforeAllFiltered.ts|1✔|||958ms| |e2e/__tests__/beforeAllFiltered.ts|1✔|||958ms|
|e2e/__tests__/beforeEachQueue.ts|1✔||1✖|55ms| |e2e/__tests__/beforeEachQueue.ts|1✔||1✖|55ms|
|e2e/__tests__/callDoneTwice.test.ts|1✔|||882ms| |e2e/__tests__/callDoneTwice.test.ts|1✔|||882ms|
|e2e/__tests__/chaiAssertionLibrary.ts|1✔|||1.902s| |e2e/__tests__/chaiAssertionLibrary.ts|1✔|||2s|
|e2e/__tests__/circularInequality.test.ts|1✔|||1.451s| |e2e/__tests__/circularInequality.test.ts|1✔|||1s|
|e2e/__tests__/circusConcurrentEach.test.ts|2✔|||1.591s| |e2e/__tests__/circusConcurrentEach.test.ts|2✔|||2s|
|e2e/__tests__/circusDeclarationErrors.test.ts|1✔|||869ms| |e2e/__tests__/circusDeclarationErrors.test.ts|1✔|||869ms|
|e2e/__tests__/clearCache.test.ts|2✔|||1.004s| |e2e/__tests__/clearCache.test.ts|2✔|||1s|
|e2e/__tests__/cliHandlesExactFilenames.test.ts|2✔|||1.230s| |e2e/__tests__/cliHandlesExactFilenames.test.ts|2✔|||1s|
|e2e/__tests__/compareDomNodes.test.ts|1✔|||1.407s| |e2e/__tests__/compareDomNodes.test.ts|1✔|||1s|
|e2e/__tests__/config.test.ts|6✔|||3.945s| |e2e/__tests__/config.test.ts|6✔|||4s|
|e2e/__tests__/console.test.ts|7✔|||8.072s| |e2e/__tests__/console.test.ts|7✔|||8s|
|e2e/__tests__/consoleAfterTeardown.test.ts|1✔|||1.341s| |e2e/__tests__/consoleAfterTeardown.test.ts|1✔|||1s|
|e2e/__tests__/consoleLogOutputWhenRunInBand.test.ts|1✔|||793ms| |e2e/__tests__/consoleLogOutputWhenRunInBand.test.ts|1✔|||793ms|
|e2e/__tests__/coverageHandlebars.test.ts|1✔|||1.873s| |e2e/__tests__/coverageHandlebars.test.ts|1✔|||2s|
|e2e/__tests__/coverageRemapping.test.ts|1✔|||12.701s| |e2e/__tests__/coverageRemapping.test.ts|1✔|||13s|
|e2e/__tests__/coverageReport.test.ts|12✔|||22.264s| |e2e/__tests__/coverageReport.test.ts|12✔|||22s|
|e2e/__tests__/coverageThreshold.test.ts|5✔|||4.868s| |e2e/__tests__/coverageThreshold.test.ts|5✔|||5s|
|e2e/__tests__/coverageTransformInstrumented.test.ts|1✔|||5.029s| |e2e/__tests__/coverageTransformInstrumented.test.ts|1✔|||5s|
|e2e/__tests__/coverageWithoutTransform.test.ts|1✔|||1.075s| |e2e/__tests__/coverageWithoutTransform.test.ts|1✔|||1s|
|e2e/__tests__/createProcessObject.test.ts|1✔|||908ms| |e2e/__tests__/createProcessObject.test.ts|1✔|||908ms|
|e2e/__tests__/customInlineSnapshotMatchers.test.ts|1✔|||2.206s| |e2e/__tests__/customInlineSnapshotMatchers.test.ts|1✔|||2s|
|e2e/__tests__/customMatcherStackTrace.test.ts|2✔|||1.539s| |e2e/__tests__/customMatcherStackTrace.test.ts|2✔|||2s|
|e2e/__tests__/customReporters.test.ts|9✔|||6.553s| |e2e/__tests__/customReporters.test.ts|9✔|||7s|
|e2e/__tests__/customResolver.test.ts|1✔|||826ms| |e2e/__tests__/customResolver.test.ts|1✔|||826ms|
|e2e/__tests__/customTestSequencers.test.ts|3✔|||2.757s| |e2e/__tests__/customTestSequencers.test.ts|3✔|||3s|
|e2e/__tests__/debug.test.ts|1✔|||899ms| |e2e/__tests__/debug.test.ts|1✔|||899ms|
|e2e/__tests__/declarationErrors.test.ts|3✔|||2.389s| |e2e/__tests__/declarationErrors.test.ts|3✔|||2s|
|e2e/__tests__/dependencyClash.test.ts|1✔|||833ms| |e2e/__tests__/dependencyClash.test.ts|1✔|||833ms|
|e2e/__tests__/detectOpenHandles.ts|8✔|||7.528s| |e2e/__tests__/detectOpenHandles.ts|8✔|||8s|
|e2e/__tests__/domDiffing.test.ts|1✔|||1.361s| |e2e/__tests__/domDiffing.test.ts|1✔|||1s|
|e2e/__tests__/doneInHooks.test.ts|1✔|||855ms| |e2e/__tests__/doneInHooks.test.ts|1✔|||855ms|
|e2e/__tests__/dynamicRequireDependencies.ts|1✔|||847ms| |e2e/__tests__/dynamicRequireDependencies.ts|1✔|||847ms|
|e2e/__tests__/each.test.ts|7✔|||4.721s| |e2e/__tests__/each.test.ts|7✔|||5s|
|e2e/__tests__/emptyDescribeWithHooks.test.ts|4✔|||2.886s| |e2e/__tests__/emptyDescribeWithHooks.test.ts|4✔|||3s|
|e2e/__tests__/emptySuiteError.test.ts|1✔|||885ms| |e2e/__tests__/emptySuiteError.test.ts|1✔|||885ms|
|e2e/__tests__/env.test.ts|6✔|||5.221s| |e2e/__tests__/env.test.ts|6✔|||5s|
|e2e/__tests__/environmentAfterTeardown.test.ts|1✔|||892ms| |e2e/__tests__/environmentAfterTeardown.test.ts|1✔|||892ms|
|e2e/__tests__/errorOnDeprecated.test.ts|1✔||24✖|56ms| |e2e/__tests__/errorOnDeprecated.test.ts|1✔||24✖|56ms|
|e2e/__tests__/esmConfigFile.test.ts|3✔|||526ms| |e2e/__tests__/esmConfigFile.test.ts|3✔|||526ms|
|e2e/__tests__/executeTestsOnceInMpr.ts|1✔|||976ms| |e2e/__tests__/executeTestsOnceInMpr.ts|1✔|||976ms|
|e2e/__tests__/existentRoots.test.ts|4✔|||627ms| |e2e/__tests__/existentRoots.test.ts|4✔|||627ms|
|e2e/__tests__/expectAsyncMatcher.test.ts|2✔|||2.732s| |e2e/__tests__/expectAsyncMatcher.test.ts|2✔|||3s|
|e2e/__tests__/expectInVm.test.ts|1✔|||1.527s| |e2e/__tests__/expectInVm.test.ts|1✔|||2s|
|e2e/__tests__/extraGlobals.test.ts|1✔|||1.011s| |e2e/__tests__/extraGlobals.test.ts|1✔|||1s|
|e2e/__tests__/failureDetailsProperty.test.ts|1✔|||907ms| |e2e/__tests__/failureDetailsProperty.test.ts|1✔|||907ms|
|e2e/__tests__/failures.test.ts|7✔|||10.353s| |e2e/__tests__/failures.test.ts|7✔|||10s|
|e2e/__tests__/fakePromises.test.ts|2✔|||1.716s| |e2e/__tests__/fakePromises.test.ts|2✔|||2s|
|e2e/__tests__/fatalWorkerError.test.ts|1✔|||3.167s| |e2e/__tests__/fatalWorkerError.test.ts|1✔|||3s|
|e2e/__tests__/filter.test.ts|7✔|||5.422s| |e2e/__tests__/filter.test.ts|7✔|||5s|
|e2e/__tests__/findRelatedFiles.test.ts|5✔|||6.230s| |e2e/__tests__/findRelatedFiles.test.ts|5✔|||6s|
|e2e/__tests__/focusedTests.test.ts|1✔|||888ms| |e2e/__tests__/focusedTests.test.ts|1✔|||888ms|
|e2e/__tests__/forceExit.test.ts|1✔|||2.208s| |e2e/__tests__/forceExit.test.ts|1✔|||2s|
|e2e/__tests__/generatorMock.test.ts|1✔|||1.027s| |e2e/__tests__/generatorMock.test.ts|1✔|||1s|
|e2e/__tests__/global-mutation.test.ts|1✔|||40ms| |e2e/__tests__/global-mutation.test.ts|1✔|||40ms|
|e2e/__tests__/global.test.ts|1✔|||31ms| |e2e/__tests__/global.test.ts|1✔|||31ms|
|e2e/__tests__/globals.test.ts|10✔|||7.505s| |e2e/__tests__/globals.test.ts|10✔|||8s|
|e2e/__tests__/globalSetup.test.ts|10✔|||13.926s| |e2e/__tests__/globalSetup.test.ts|10✔|||14s|
|e2e/__tests__/globalTeardown.test.ts|7✔|||11.886s| |e2e/__tests__/globalTeardown.test.ts|7✔|||12s|
|e2e/__tests__/hasteMapMockChanged.test.ts|1✔|||379ms| |e2e/__tests__/hasteMapMockChanged.test.ts|1✔|||379ms|
|e2e/__tests__/hasteMapSha1.test.ts|1✔|||298ms| |e2e/__tests__/hasteMapSha1.test.ts|1✔|||298ms|
|e2e/__tests__/hasteMapSize.test.ts|2✔|||397ms| |e2e/__tests__/hasteMapSize.test.ts|2✔|||397ms|
|e2e/__tests__/importedGlobals.test.ts|1✔|||1.043s| |e2e/__tests__/importedGlobals.test.ts|1✔|||1s|
|e2e/__tests__/injectGlobals.test.ts|2✔|||1.860s| |e2e/__tests__/injectGlobals.test.ts|2✔|||2s|
|e2e/__tests__/jasmineAsync.test.ts|15✔|||28.291s| |e2e/__tests__/jasmineAsync.test.ts|15✔|||28s|
|e2e/__tests__/jasmineAsyncWithPendingDuringTest.ts|1✔||1✖|72ms| |e2e/__tests__/jasmineAsyncWithPendingDuringTest.ts|1✔||1✖|72ms|
|e2e/__tests__/jest.config.js.test.ts|3✔|||2.134s| |e2e/__tests__/jest.config.js.test.ts|3✔|||2s|
|e2e/__tests__/jest.config.ts.test.ts|5✔|||14.322s| |e2e/__tests__/jest.config.ts.test.ts|5✔|||14s|
|[e2e/__tests__/jestChangedFiles.test.ts](#r0s75)|9✔|1❌||9.045s| |[e2e/__tests__/jestChangedFiles.test.ts](#r0s75)|9✔|1❌||9s|
|e2e/__tests__/jestEnvironmentJsdom.test.ts|1✔|||1.744s| |e2e/__tests__/jestEnvironmentJsdom.test.ts|1✔|||2s|
|e2e/__tests__/jestRequireActual.test.ts|1✔|||1.665s| |e2e/__tests__/jestRequireActual.test.ts|1✔|||2s|
|e2e/__tests__/jestRequireMock.test.ts|1✔|||2.119s| |e2e/__tests__/jestRequireMock.test.ts|1✔|||2s|
|e2e/__tests__/json.test.ts|2✔|||29ms| |e2e/__tests__/json.test.ts|2✔|||29ms|
|e2e/__tests__/jsonReporter.test.ts|2✔|||1.514s| |e2e/__tests__/jsonReporter.test.ts|2✔|||2s|
|e2e/__tests__/lifecycles.ts|1✔|||861ms| |e2e/__tests__/lifecycles.ts|1✔|||861ms|
|e2e/__tests__/listTests.test.ts|2✔|||945ms| |e2e/__tests__/listTests.test.ts|2✔|||945ms|
|e2e/__tests__/locationInResults.test.ts|2✔|||1.764s| |e2e/__tests__/locationInResults.test.ts|2✔|||2s|
|e2e/__tests__/logHeapUsage.test.ts|1✔|||884ms| |e2e/__tests__/logHeapUsage.test.ts|1✔|||884ms|
|e2e/__tests__/mockNames.test.ts|8✔|||6.771s| |e2e/__tests__/mockNames.test.ts|8✔|||7s|
|e2e/__tests__/modernFakeTimers.test.ts|2✔|||1.680s| |e2e/__tests__/modernFakeTimers.test.ts|2✔|||2s|
|e2e/__tests__/moduleNameMapper.test.ts|5✔|||5.395s| |e2e/__tests__/moduleNameMapper.test.ts|5✔|||5s|
|e2e/__tests__/moduleParentNullInTest.ts|1✔|||886ms| |e2e/__tests__/moduleParentNullInTest.ts|1✔|||886ms|
|e2e/__tests__/multiProjectRunner.test.ts|14✔|||16.360s| |e2e/__tests__/multiProjectRunner.test.ts|14✔|||16s|
|e2e/__tests__/nativeAsyncMock.test.ts|1✔|||55ms| |e2e/__tests__/nativeAsyncMock.test.ts|1✔|||55ms|
|e2e/__tests__/nativeEsm.test.ts|2✔||1✖|905ms| |e2e/__tests__/nativeEsm.test.ts|2✔||1✖|905ms|
|e2e/__tests__/nativeEsmTypescript.test.ts|1✔|||956ms| |e2e/__tests__/nativeEsmTypescript.test.ts|1✔|||956ms|
|e2e/__tests__/nestedEventLoop.test.ts|1✔|||1.422s| |e2e/__tests__/nestedEventLoop.test.ts|1✔|||1s|
|e2e/__tests__/nestedTestDefinitions.test.ts|4✔|||4.641s| |e2e/__tests__/nestedTestDefinitions.test.ts|4✔|||5s|
|e2e/__tests__/nodePath.test.ts|1✔|||866ms| |e2e/__tests__/nodePath.test.ts|1✔|||866ms|
|e2e/__tests__/noTestFound.test.ts|2✔|||1.063s| |e2e/__tests__/noTestFound.test.ts|2✔|||1s|
|e2e/__tests__/noTestsFound.test.ts|5✔|||2.739s| |e2e/__tests__/noTestsFound.test.ts|5✔|||3s|
|[e2e/__tests__/onlyChanged.test.ts](#r0s98)|8✔|1❌||22.281s| |[e2e/__tests__/onlyChanged.test.ts](#r0s98)|8✔|1❌||22s|
|e2e/__tests__/onlyFailuresNonWatch.test.ts|1✔|||2.893s| |e2e/__tests__/onlyFailuresNonWatch.test.ts|1✔|||3s|
|e2e/__tests__/overrideGlobals.test.ts|2✔|||2.046s| |e2e/__tests__/overrideGlobals.test.ts|2✔|||2s|
|e2e/__tests__/pnp.test.ts|1✔|||2.715s| |e2e/__tests__/pnp.test.ts|1✔|||3s|
|e2e/__tests__/presets.test.ts|2✔|||1.966s| |e2e/__tests__/presets.test.ts|2✔|||2s|
|e2e/__tests__/processExit.test.ts|1✔|||1.070s| |e2e/__tests__/processExit.test.ts|1✔|||1s|
|e2e/__tests__/promiseReject.test.ts|1✔|||967ms| |e2e/__tests__/promiseReject.test.ts|1✔|||967ms|
|e2e/__tests__/regexCharInPath.test.ts|1✔|||962ms| |e2e/__tests__/regexCharInPath.test.ts|1✔|||962ms|
|e2e/__tests__/requireAfterTeardown.test.ts|1✔|||921ms| |e2e/__tests__/requireAfterTeardown.test.ts|1✔|||921ms|
|e2e/__tests__/requireMain.test.ts|1✔|||1.137s| |e2e/__tests__/requireMain.test.ts|1✔|||1s|
|e2e/__tests__/requireMainAfterCreateRequire.test.ts|1✔|||966ms| |e2e/__tests__/requireMainAfterCreateRequire.test.ts|1✔|||966ms|
|e2e/__tests__/requireMainIsolateModules.test.ts|1✔|||976ms| |e2e/__tests__/requireMainIsolateModules.test.ts|1✔|||976ms|
|e2e/__tests__/requireMainResetModules.test.ts|2✔|||1.961s| |e2e/__tests__/requireMainResetModules.test.ts|2✔|||2s|
|e2e/__tests__/requireV8Module.test.ts|1✔|||30ms| |e2e/__tests__/requireV8Module.test.ts|1✔|||30ms|
|e2e/__tests__/resetModules.test.ts|1✔|||926ms| |e2e/__tests__/resetModules.test.ts|1✔|||926ms|
|e2e/__tests__/resolve.test.ts|1✔|||1.863s| |e2e/__tests__/resolve.test.ts|1✔|||2s|
|e2e/__tests__/resolveGetPaths.test.ts|1✔|||1.155s| |e2e/__tests__/resolveGetPaths.test.ts|1✔|||1s|
|e2e/__tests__/resolveNodeModule.test.ts|1✔|||943ms| |e2e/__tests__/resolveNodeModule.test.ts|1✔|||943ms|
|e2e/__tests__/resolveNoFileExtensions.test.ts|2✔|||1.263s| |e2e/__tests__/resolveNoFileExtensions.test.ts|2✔|||1s|
|e2e/__tests__/resolveWithPaths.test.ts|1✔|||1.170s| |e2e/__tests__/resolveWithPaths.test.ts|1✔|||1s|
|e2e/__tests__/runProgrammatically.test.ts|2✔|||575ms| |e2e/__tests__/runProgrammatically.test.ts|2✔|||575ms|
|e2e/__tests__/runTestsByPath.test.ts|1✔|||1.999s| |e2e/__tests__/runTestsByPath.test.ts|1✔|||2s|
|e2e/__tests__/runtimeInternalModuleRegistry.test.ts|1✔|||1.202s| |e2e/__tests__/runtimeInternalModuleRegistry.test.ts|1✔|||1s|
|e2e/__tests__/selectProjects.test.ts|18✔|||5.236s| |e2e/__tests__/selectProjects.test.ts|18✔|||5s|
|e2e/__tests__/setImmediate.test.ts|1✔|||904ms| |e2e/__tests__/setImmediate.test.ts|1✔|||904ms|
|e2e/__tests__/setupFilesAfterEnvConfig.test.ts|2✔|||1.967s| |e2e/__tests__/setupFilesAfterEnvConfig.test.ts|2✔|||2s|
|e2e/__tests__/showConfig.test.ts|1✔|||195ms| |e2e/__tests__/showConfig.test.ts|1✔|||195ms|
|e2e/__tests__/skipBeforeAfterAll.test.ts|1✔|||1.061s| |e2e/__tests__/skipBeforeAfterAll.test.ts|1✔|||1s|
|e2e/__tests__/snapshot-unknown.test.ts|1✔|||838ms| |e2e/__tests__/snapshot-unknown.test.ts|1✔|||838ms|
|e2e/__tests__/snapshot.test.ts|9✔|||13.899s| |e2e/__tests__/snapshot.test.ts|9✔|||14s|
|e2e/__tests__/snapshotMockFs.test.ts|1✔|||883ms| |e2e/__tests__/snapshotMockFs.test.ts|1✔|||883ms|
|e2e/__tests__/snapshotResolver.test.ts|1✔|||823ms| |e2e/__tests__/snapshotResolver.test.ts|1✔|||823ms|
|e2e/__tests__/snapshotSerializers.test.ts|2✔|||2.065s| |e2e/__tests__/snapshotSerializers.test.ts|2✔|||2s|
|e2e/__tests__/stackTrace.test.ts|7✔|||4.725s| |e2e/__tests__/stackTrace.test.ts|7✔|||5s|
|e2e/__tests__/stackTraceNoCaptureStackTrace.test.ts|1✔|||899ms| |e2e/__tests__/stackTraceNoCaptureStackTrace.test.ts|1✔|||899ms|
|e2e/__tests__/stackTraceSourceMaps.test.ts|1✔|||2.185s| |e2e/__tests__/stackTraceSourceMaps.test.ts|1✔|||2s|
|e2e/__tests__/stackTraceSourceMapsWithCoverage.test.ts|1✔|||2.444s| |e2e/__tests__/stackTraceSourceMapsWithCoverage.test.ts|1✔|||2s|
|e2e/__tests__/supportsDashedArgs.ts|2✔|||968ms| |e2e/__tests__/supportsDashedArgs.ts|2✔|||968ms|
|e2e/__tests__/symbol.test.ts|1✔|||49ms| |e2e/__tests__/symbol.test.ts|1✔|||49ms|
|e2e/__tests__/testEnvironment.test.ts|1✔|||1.628s| |e2e/__tests__/testEnvironment.test.ts|1✔|||2s|
|e2e/__tests__/testEnvironmentAsync.test.ts|1✔|||1.493s| |e2e/__tests__/testEnvironmentAsync.test.ts|1✔|||1s|
|e2e/__tests__/testEnvironmentCircus.test.ts|1✔|||1.501s| |e2e/__tests__/testEnvironmentCircus.test.ts|1✔|||2s|
|e2e/__tests__/testEnvironmentCircusAsync.test.ts|1✔|||1.507s| |e2e/__tests__/testEnvironmentCircusAsync.test.ts|1✔|||2s|
|e2e/__tests__/testFailureExitCode.test.ts|2✔|||4.476s| |e2e/__tests__/testFailureExitCode.test.ts|2✔|||4s|
|e2e/__tests__/testInRoot.test.ts|1✔|||1.009s| |e2e/__tests__/testInRoot.test.ts|1✔|||1s|
|e2e/__tests__/testNamePattern.test.ts|1✔|||859ms| |e2e/__tests__/testNamePattern.test.ts|1✔|||859ms|
|e2e/__tests__/testNamePatternSkipped.test.ts|1✔|||991ms| |e2e/__tests__/testNamePatternSkipped.test.ts|1✔|||991ms|
|e2e/__tests__/testPathPatternReporterMessage.test.ts|1✔|||3.076s| |e2e/__tests__/testPathPatternReporterMessage.test.ts|1✔|||3s|
|e2e/__tests__/testResultsProcessor.test.ts|1✔|||910ms| |e2e/__tests__/testResultsProcessor.test.ts|1✔|||910ms|
|e2e/__tests__/testRetries.test.ts|4✔|||3.277s| |e2e/__tests__/testRetries.test.ts|4✔|||3s|
|e2e/__tests__/testTodo.test.ts|5✔|||3.573s| |e2e/__tests__/testTodo.test.ts|5✔|||4s|
|e2e/__tests__/timeouts.test.ts|4✔|||4.029s| |e2e/__tests__/timeouts.test.ts|4✔|||4s|
|e2e/__tests__/timeoutsLegacy.test.ts|1✔||3✖|71ms| |e2e/__tests__/timeoutsLegacy.test.ts|1✔||3✖|71ms|
|e2e/__tests__/timerResetMocks.test.ts|2✔|||1.878s| |e2e/__tests__/timerResetMocks.test.ts|2✔|||2s|
|e2e/__tests__/timerUseRealTimers.test.ts|1✔|||1.018s| |e2e/__tests__/timerUseRealTimers.test.ts|1✔|||1s|
|e2e/__tests__/toMatchInlineSnapshot.test.ts|12✔|||23.917s| |e2e/__tests__/toMatchInlineSnapshot.test.ts|12✔|||24s|
|e2e/__tests__/toMatchInlineSnapshotWithRetries.test.ts|3✔|||4.670s| |e2e/__tests__/toMatchInlineSnapshotWithRetries.test.ts|3✔|||5s|
|e2e/__tests__/toMatchSnapshot.test.ts|9✔|||17.025s| |e2e/__tests__/toMatchSnapshot.test.ts|9✔|||17s|
|e2e/__tests__/toMatchSnapshotWithRetries.test.ts|2✔|||4.435s| |e2e/__tests__/toMatchSnapshotWithRetries.test.ts|2✔|||4s|
|e2e/__tests__/toMatchSnapshotWithStringSerializer.test.ts|3✔|||3.544s| |e2e/__tests__/toMatchSnapshotWithStringSerializer.test.ts|3✔|||4s|
|e2e/__tests__/toThrowErrorMatchingInlineSnapshot.test.ts|4✔|||3.562s| |e2e/__tests__/toThrowErrorMatchingInlineSnapshot.test.ts|4✔|||4s|
|e2e/__tests__/toThrowErrorMatchingSnapshot.test.ts|5✔|||3.524s| |e2e/__tests__/toThrowErrorMatchingSnapshot.test.ts|5✔|||4s|
|e2e/__tests__/transform.test.ts|16✔|||26.740s| |e2e/__tests__/transform.test.ts|16✔|||27s|
|e2e/__tests__/transformLinkedModules.test.ts|1✔|||783ms| |e2e/__tests__/transformLinkedModules.test.ts|1✔|||783ms|
|e2e/__tests__/typescriptCoverage.test.ts|1✔|||2.893s| |e2e/__tests__/typescriptCoverage.test.ts|1✔|||3s|
|e2e/__tests__/unexpectedToken.test.ts|3✔|||3.411s| |e2e/__tests__/unexpectedToken.test.ts|3✔|||3s|
|e2e/__tests__/useStderr.test.ts|1✔|||1.352s| |e2e/__tests__/useStderr.test.ts|1✔|||1s|
|e2e/__tests__/v8Coverage.test.ts|2✔|||2.412s| |e2e/__tests__/v8Coverage.test.ts|2✔|||2s|
|e2e/__tests__/verbose.test.ts|1✔|||683ms| |e2e/__tests__/verbose.test.ts|1✔|||683ms|
|e2e/__tests__/version.test.ts|1✔|||138ms| |e2e/__tests__/version.test.ts|1✔|||138ms|
|e2e/__tests__/watchModeNoAccess.test.ts|1✔|||4.370s| |e2e/__tests__/watchModeNoAccess.test.ts|1✔|||4s|
|e2e/__tests__/watchModeOnlyFailed.test.ts|1✔|||1.394s| |e2e/__tests__/watchModeOnlyFailed.test.ts|1✔|||1s|
|e2e/__tests__/watchModePatterns.test.ts|2✔|||3.503s| |e2e/__tests__/watchModePatterns.test.ts|2✔|||4s|
|e2e/__tests__/watchModeUpdateSnapshot.test.ts|1✔|||1.075s| |e2e/__tests__/watchModeUpdateSnapshot.test.ts|1✔|||1s|
|e2e/__tests__/workerForceExit.test.ts|2✔|||4.751s| |e2e/__tests__/workerForceExit.test.ts|2✔|||5s|
|e2e/__tests__/wrongEnv.test.ts|5✔|||3.877s| |e2e/__tests__/wrongEnv.test.ts|5✔|||4s|
|e2e/custom-test-sequencer/a.test.js|1✔|||29ms| |e2e/custom-test-sequencer/a.test.js|1✔|||29ms|
|e2e/custom-test-sequencer/b.test.js|1✔|||21ms| |e2e/custom-test-sequencer/b.test.js|1✔|||21ms|
|e2e/custom-test-sequencer/c.test.js|1✔|||42ms| |e2e/custom-test-sequencer/c.test.js|1✔|||42ms|
@@ -206,7 +206,7 @@
|examples/module-mock/__tests__/mock_per_test.js|2✔|||116ms| |examples/module-mock/__tests__/mock_per_test.js|2✔|||116ms|
|examples/module-mock/__tests__/partial_mock.js|1✔|||215ms| |examples/module-mock/__tests__/partial_mock.js|1✔|||215ms|
|examples/mongodb/__test__/db.test.js|1✔|||236ms| |examples/mongodb/__test__/db.test.js|1✔|||236ms|
|examples/react-native/__tests__/intro.test.js|4✔|||8.559s| |examples/react-native/__tests__/intro.test.js|4✔|||9s|
|examples/react-testing-library/__tests__/CheckboxWithLabel-test.js|1✔|||469ms| |examples/react-testing-library/__tests__/CheckboxWithLabel-test.js|1✔|||469ms|
|examples/react/__tests__/CheckboxWithLabel-test.js|1✔|||256ms| |examples/react/__tests__/CheckboxWithLabel-test.js|1✔|||256ms|
|examples/snapshot/__tests__/clock.react.test.js|1✔|||62ms| |examples/snapshot/__tests__/clock.react.test.js|1✔|||62ms|
@@ -228,7 +228,7 @@
|packages/expect/src/__tests__/isError.test.ts|4✔|||43ms| |packages/expect/src/__tests__/isError.test.ts|4✔|||43ms|
|packages/expect/src/__tests__/matchers-toContain.property.test.ts|2✔|||236ms| |packages/expect/src/__tests__/matchers-toContain.property.test.ts|2✔|||236ms|
|packages/expect/src/__tests__/matchers-toContainEqual.property.test.ts|2✔|||287ms| |packages/expect/src/__tests__/matchers-toContainEqual.property.test.ts|2✔|||287ms|
|packages/expect/src/__tests__/matchers-toEqual.property.test.ts|2✔|||1.062s| |packages/expect/src/__tests__/matchers-toEqual.property.test.ts|2✔|||1s|
|packages/expect/src/__tests__/matchers-toStrictEqual.property.test.ts|3✔|||394ms| |packages/expect/src/__tests__/matchers-toStrictEqual.property.test.ts|3✔|||394ms|
|packages/expect/src/__tests__/matchers.test.js|592✔|||862ms| |packages/expect/src/__tests__/matchers.test.js|592✔|||862ms|
|packages/expect/src/__tests__/spyMatchers.test.ts|248✔|||395ms| |packages/expect/src/__tests__/spyMatchers.test.ts|248✔|||395ms|
@@ -237,11 +237,11 @@
|packages/expect/src/__tests__/toEqual-dom.test.ts|12✔|||99ms| |packages/expect/src/__tests__/toEqual-dom.test.ts|12✔|||99ms|
|packages/expect/src/__tests__/toThrowMatchers.test.ts|98✔|||257ms| |packages/expect/src/__tests__/toThrowMatchers.test.ts|98✔|||257ms|
|packages/expect/src/__tests__/utils.test.ts|41✔|||147ms| |packages/expect/src/__tests__/utils.test.ts|41✔|||147ms|
|packages/jest-circus/src/__tests__/afterAll.test.ts|6✔|||5.755s| |packages/jest-circus/src/__tests__/afterAll.test.ts|6✔|||6s|
|packages/jest-circus/src/__tests__/baseTest.test.ts|2✔|||2.902s| |packages/jest-circus/src/__tests__/baseTest.test.ts|2✔|||3s|
|packages/jest-circus/src/__tests__/circusItTestError.test.ts|8✔|||300ms| |packages/jest-circus/src/__tests__/circusItTestError.test.ts|8✔|||300ms|
|packages/jest-circus/src/__tests__/circusItTodoTestError.test.ts|3✔|||81ms| |packages/jest-circus/src/__tests__/circusItTodoTestError.test.ts|3✔|||81ms|
|packages/jest-circus/src/__tests__/hooks.test.ts|3✔|||3.762s| |packages/jest-circus/src/__tests__/hooks.test.ts|3✔|||4s|
|packages/jest-circus/src/__tests__/hooksError.test.ts|32✔|||127ms| |packages/jest-circus/src/__tests__/hooksError.test.ts|32✔|||127ms|
|packages/jest-cli/src/__tests__/cli/args.test.ts|17✔|||345ms| |packages/jest-cli/src/__tests__/cli/args.test.ts|17✔|||345ms|
|packages/jest-cli/src/init/__tests__/init.test.js|24✔|||119ms| |packages/jest-cli/src/init/__tests__/init.test.js|24✔|||119ms|
@@ -261,12 +261,12 @@
|packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.js|5✔|||61ms| |packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.js|5✔|||61ms|
|packages/jest-core/src/__tests__/globals.test.ts|1✔|||22ms| |packages/jest-core/src/__tests__/globals.test.ts|1✔|||22ms|
|packages/jest-core/src/__tests__/runJest.test.js|2✔|||261ms| |packages/jest-core/src/__tests__/runJest.test.js|2✔|||261ms|
|packages/jest-core/src/__tests__/SearchSource.test.ts|27✔|||2.596s| |packages/jest-core/src/__tests__/SearchSource.test.ts|27✔|||3s|
|packages/jest-core/src/__tests__/SnapshotInteractiveMode.test.js|13✔|||89ms| |packages/jest-core/src/__tests__/SnapshotInteractiveMode.test.js|13✔|||89ms|
|packages/jest-core/src/__tests__/TestScheduler.test.js|8✔|||520ms| |packages/jest-core/src/__tests__/TestScheduler.test.js|8✔|||520ms|
|packages/jest-core/src/__tests__/testSchedulerHelper.test.js|12✔|||48ms| |packages/jest-core/src/__tests__/testSchedulerHelper.test.js|12✔|||48ms|
|packages/jest-core/src/__tests__/watch.test.js|80✔|||6.755s| |packages/jest-core/src/__tests__/watch.test.js|80✔|||7s|
|packages/jest-core/src/__tests__/watchFileChanges.test.ts|1✔|||1.514s| |packages/jest-core/src/__tests__/watchFileChanges.test.ts|1✔|||2s|
|packages/jest-core/src/__tests__/watchFilenamePatternMode.test.js|2✔|||165ms| |packages/jest-core/src/__tests__/watchFilenamePatternMode.test.js|2✔|||165ms|
|packages/jest-core/src/__tests__/watchTestNamePatternMode.test.js|1✔|||246ms| |packages/jest-core/src/__tests__/watchTestNamePatternMode.test.js|1✔|||246ms|
|packages/jest-core/src/lib/__tests__/isValidPath.test.ts|3✔|||166ms| |packages/jest-core/src/lib/__tests__/isValidPath.test.ts|3✔|||166ms|
@@ -289,7 +289,7 @@
|packages/jest-globals/src/__tests__/index.ts|1✔|||533ms| |packages/jest-globals/src/__tests__/index.ts|1✔|||533ms|
|packages/jest-haste-map/src/__tests__/get_mock_name.test.js|1✔|||22ms| |packages/jest-haste-map/src/__tests__/get_mock_name.test.js|1✔|||22ms|
|packages/jest-haste-map/src/__tests__/includes_dotfiles.test.ts|1✔|||337ms| |packages/jest-haste-map/src/__tests__/includes_dotfiles.test.ts|1✔|||337ms|
|packages/jest-haste-map/src/__tests__/index.test.js|44✔|||1.145s| |packages/jest-haste-map/src/__tests__/index.test.js|44✔|||1s|
|packages/jest-haste-map/src/__tests__/worker.test.js|7✔|||100ms| |packages/jest-haste-map/src/__tests__/worker.test.js|7✔|||100ms|
|packages/jest-haste-map/src/crawlers/__tests__/node.test.js|10✔|||170ms| |packages/jest-haste-map/src/crawlers/__tests__/node.test.js|10✔|||170ms|
|packages/jest-haste-map/src/crawlers/__tests__/watchman.test.js|8✔|||153ms| |packages/jest-haste-map/src/crawlers/__tests__/watchman.test.js|8✔|||153ms|
@@ -318,12 +318,12 @@
|packages/jest-message-util/src/__tests__/messages.test.ts|11✔|||205ms| |packages/jest-message-util/src/__tests__/messages.test.ts|11✔|||205ms|
|packages/jest-mock/src/__tests__/index.test.ts|84✔|||509ms| |packages/jest-mock/src/__tests__/index.test.ts|84✔|||509ms|
|packages/jest-regex-util/src/__tests__/index.test.ts|8✔|||56ms| |packages/jest-regex-util/src/__tests__/index.test.ts|8✔|||56ms|
|packages/jest-repl/src/__tests__/jest_repl.test.js|1✔|||1.172s| |packages/jest-repl/src/__tests__/jest_repl.test.js|1✔|||1s|
|packages/jest-repl/src/__tests__/runtime_cli.test.js|4✔|||4.094s| |packages/jest-repl/src/__tests__/runtime_cli.test.js|4✔|||4s|
|packages/jest-reporters/src/__tests__/CoverageReporter.test.js|12✔|||397ms| |packages/jest-reporters/src/__tests__/CoverageReporter.test.js|12✔|||397ms|
|packages/jest-reporters/src/__tests__/CoverageWorker.test.js|2✔|||199ms| |packages/jest-reporters/src/__tests__/CoverageWorker.test.js|2✔|||199ms|
|packages/jest-reporters/src/__tests__/DefaultReporter.test.js|2✔|||148ms| |packages/jest-reporters/src/__tests__/DefaultReporter.test.js|2✔|||148ms|
|packages/jest-reporters/src/__tests__/generateEmptyCoverage.test.js|3✔|||1.129s| |packages/jest-reporters/src/__tests__/generateEmptyCoverage.test.js|3✔|||1s|
|packages/jest-reporters/src/__tests__/getResultHeader.test.js|4✔|||30ms| |packages/jest-reporters/src/__tests__/getResultHeader.test.js|4✔|||30ms|
|packages/jest-reporters/src/__tests__/getSnapshotStatus.test.js|3✔|||28ms| |packages/jest-reporters/src/__tests__/getSnapshotStatus.test.js|3✔|||28ms|
|packages/jest-reporters/src/__tests__/getSnapshotSummary.test.js|4✔|||49ms| |packages/jest-reporters/src/__tests__/getSnapshotSummary.test.js|4✔|||49ms|
@@ -334,7 +334,7 @@
|packages/jest-reporters/src/__tests__/VerboseReporter.test.js|11✔|||425ms| |packages/jest-reporters/src/__tests__/VerboseReporter.test.js|11✔|||425ms|
|packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.ts|11✔|||666ms| |packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.ts|11✔|||666ms|
|packages/jest-resolve/src/__tests__/isBuiltinModule.test.ts|4✔|||36ms| |packages/jest-resolve/src/__tests__/isBuiltinModule.test.ts|4✔|||36ms|
|packages/jest-resolve/src/__tests__/resolve.test.ts|16✔|||1.308s| |packages/jest-resolve/src/__tests__/resolve.test.ts|16✔|||1s|
|packages/jest-runner/src/__tests__/testRunner.test.ts|2✔|||905ms| |packages/jest-runner/src/__tests__/testRunner.test.ts|2✔|||905ms|
|packages/jest-runtime/src/__tests__/instrumentation.test.ts|1✔|||275ms| |packages/jest-runtime/src/__tests__/instrumentation.test.ts|1✔|||275ms|
|packages/jest-runtime/src/__tests__/runtime_create_mock_from_module.test.js|3✔|||606ms| |packages/jest-runtime/src/__tests__/runtime_create_mock_from_module.test.js|3✔|||606ms|
@@ -344,31 +344,31 @@
|packages/jest-runtime/src/__tests__/runtime_jest_spy_on.test.js|2✔|||521ms| |packages/jest-runtime/src/__tests__/runtime_jest_spy_on.test.js|2✔|||521ms|
|packages/jest-runtime/src/__tests__/runtime_mock.test.js|4✔|||743ms| |packages/jest-runtime/src/__tests__/runtime_mock.test.js|4✔|||743ms|
|packages/jest-runtime/src/__tests__/runtime_module_directories.test.js|4✔|||525ms| |packages/jest-runtime/src/__tests__/runtime_module_directories.test.js|4✔|||525ms|
|packages/jest-runtime/src/__tests__/runtime_node_path.test.js|4✔|||1.088s| |packages/jest-runtime/src/__tests__/runtime_node_path.test.js|4✔|||1s|
|packages/jest-runtime/src/__tests__/runtime_require_actual.test.js|2✔|||478ms| |packages/jest-runtime/src/__tests__/runtime_require_actual.test.js|2✔|||478ms|
|packages/jest-runtime/src/__tests__/runtime_require_cache.test.js|2✔|||454ms| |packages/jest-runtime/src/__tests__/runtime_require_cache.test.js|2✔|||454ms|
|packages/jest-runtime/src/__tests__/runtime_require_mock.test.js|13✔|||962ms| |packages/jest-runtime/src/__tests__/runtime_require_mock.test.js|13✔|||962ms|
|packages/jest-runtime/src/__tests__/runtime_require_module_no_ext.test.js|1✔|||261ms| |packages/jest-runtime/src/__tests__/runtime_require_module_no_ext.test.js|1✔|||261ms|
|packages/jest-runtime/src/__tests__/runtime_require_module_or_mock_transitive_deps.test.js|6✔|||2.366s| |packages/jest-runtime/src/__tests__/runtime_require_module_or_mock_transitive_deps.test.js|6✔|||2s|
|packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js|17✔|||1.223s| |packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js|17✔|||1s|
|packages/jest-runtime/src/__tests__/runtime_require_module.test.js|27✔|||2.439s| |packages/jest-runtime/src/__tests__/runtime_require_module.test.js|27✔|||2s|
|packages/jest-runtime/src/__tests__/runtime_require_resolve.test.ts|5✔|||707ms| |packages/jest-runtime/src/__tests__/runtime_require_resolve.test.ts|5✔|||707ms|
|packages/jest-runtime/src/__tests__/runtime_wrap.js|2✔|||263ms| |packages/jest-runtime/src/__tests__/runtime_wrap.js|2✔|||263ms|
|packages/jest-runtime/src/__tests__/Runtime-sourceMaps.test.js|1✔|||584ms| |packages/jest-runtime/src/__tests__/Runtime-sourceMaps.test.js|1✔|||584ms|
|packages/jest-runtime/src/__tests__/Runtime-statics.test.js|2✔|||162ms| |packages/jest-runtime/src/__tests__/Runtime-statics.test.js|2✔|||162ms|
|packages/jest-serializer/src/__tests__/index.test.ts|17✔|||158ms| |packages/jest-serializer/src/__tests__/index.test.ts|17✔|||158ms|
|packages/jest-snapshot/src/__tests__/dedentLines.test.ts|17✔|||94ms| |packages/jest-snapshot/src/__tests__/dedentLines.test.ts|17✔|||94ms|
|packages/jest-snapshot/src/__tests__/InlineSnapshots.test.ts|22✔|||1.149s| |packages/jest-snapshot/src/__tests__/InlineSnapshots.test.ts|22✔|||1s|
|packages/jest-snapshot/src/__tests__/matcher.test.ts|1✔|||131ms| |packages/jest-snapshot/src/__tests__/matcher.test.ts|1✔|||131ms|
|packages/jest-snapshot/src/__tests__/mockSerializer.test.ts|10✔|||45ms| |packages/jest-snapshot/src/__tests__/mockSerializer.test.ts|10✔|||45ms|
|packages/jest-snapshot/src/__tests__/printSnapshot.test.ts|71✔|||1.188s| |packages/jest-snapshot/src/__tests__/printSnapshot.test.ts|71✔|||1s|
|packages/jest-snapshot/src/__tests__/SnapshotResolver.test.ts|10✔|||98ms| |packages/jest-snapshot/src/__tests__/SnapshotResolver.test.ts|10✔|||98ms|
|packages/jest-snapshot/src/__tests__/throwMatcher.test.ts|3✔|||481ms| |packages/jest-snapshot/src/__tests__/throwMatcher.test.ts|3✔|||481ms|
|packages/jest-snapshot/src/__tests__/utils.test.ts|26✔|||214ms| |packages/jest-snapshot/src/__tests__/utils.test.ts|26✔|||214ms|
|packages/jest-source-map/src/__tests__/getCallsite.test.ts|3✔|||86ms| |packages/jest-source-map/src/__tests__/getCallsite.test.ts|3✔|||86ms|
|packages/jest-test-result/src/__tests__/formatTestResults.test.ts|1✔|||53ms| |packages/jest-test-result/src/__tests__/formatTestResults.test.ts|1✔|||53ms|
|packages/jest-test-sequencer/src/__tests__/test_sequencer.test.js|8✔|||251ms| |packages/jest-test-sequencer/src/__tests__/test_sequencer.test.js|8✔|||251ms|
|packages/jest-transform/src/__tests__/ScriptTransformer.test.ts|22✔|||1.660s| |packages/jest-transform/src/__tests__/ScriptTransformer.test.ts|22✔|||2s|
|packages/jest-transform/src/__tests__/shouldInstrument.test.ts|25✔|||155ms| |packages/jest-transform/src/__tests__/shouldInstrument.test.ts|25✔|||155ms|
|packages/jest-util/src/__tests__/createProcessObject.test.ts|4✔|||81ms| |packages/jest-util/src/__tests__/createProcessObject.test.ts|4✔|||81ms|
|packages/jest-util/src/__tests__/deepCyclicCopy.test.ts|12✔|||86ms| |packages/jest-util/src/__tests__/deepCyclicCopy.test.ts|12✔|||86ms|
@@ -403,32 +403,30 @@
|packages/pretty-format/src/__tests__/prettyFormat.test.ts|86✔|||219ms| |packages/pretty-format/src/__tests__/prettyFormat.test.ts|86✔|||219ms|
|packages/pretty-format/src/__tests__/react.test.tsx|55✔|||325ms| |packages/pretty-format/src/__tests__/react.test.tsx|55✔|||325ms|
|packages/pretty-format/src/__tests__/ReactElement.test.ts|3✔|||64ms| |packages/pretty-format/src/__tests__/ReactElement.test.ts|3✔|||64ms|
### <a id="user-content-r0s75" href="#r0s75">e2e/__tests__/jestChangedFiles.test.ts</a> ### ❌ <a id="user-content-r0s75" href="#r0s75">e2e/__tests__/jestChangedFiles.test.ts</a>
**10** tests were completed in **9.045s** with **9** passed, **1** failed and **0** skipped. ```
✔️ gets hg SCM roots and dedupes them
|Result|Test|Time| ✔️ gets git SCM roots and dedupes them
|:---:|:---|---:| ✔️ gets mixed git and hg SCM roots and dedupes them
|✔️|gets hg SCM roots and dedupes them|559ms| ✔️ gets changed files for git
|✔️|gets git SCM roots and dedupes them|416ms| ✔️ monitors only root paths for git
|✔️|gets mixed git and hg SCM roots and dedupes them|467ms| ✔️ does not find changes in files with no diff, for git
|✔️|gets changed files for git|2.298s| ✔️ handles a bad revision for "changedSince", for git
|✔️|monitors only root paths for git|151ms| ❌ gets changed files for hg
|✔️|does not find changes in files with no diff, for git|628ms| Error: abort: empty revision range
|✔️|handles a bad revision for "changedSince", for git|878ms| ✔️ monitors only root paths for hg
|❌|gets changed files for hg|2.219s| ✔️ handles a bad revision for "changedSince", for hg
|✔️|monitors only root paths for hg|281ms| ```
|✔️|handles a bad revision for "changedSince", for hg|949ms| ### ❌ <a id="user-content-r0s98" href="#r0s98">e2e/__tests__/onlyChanged.test.ts</a>
### <a id="user-content-r0s98" href="#r0s98">e2e/__tests__/onlyChanged.test.ts</a> ❌ ```
**9** tests were completed in **22.281s** with **8** passed, **1** failed and **0** skipped. ✔️ run for "onlyChanged" and "changedSince"
✔️ run only changed files
|Result|Test|Time| ✔️ report test coverage for only changed files
|:---:|:---|---:| ✔️ report test coverage of source on test file change under only changed files
|✔️|run for "onlyChanged" and "changedSince"|1.464s| ✔️ do not pickup non-tested files when reporting coverage on only changed files
|✔️|run only changed files|5.196s| ✔️ collect test coverage when using onlyChanged
|✔️|report test coverage for only changed files|1.889s| ✔️ onlyChanged in config is overwritten by --all or testPathPattern
|✔️|report test coverage of source on test file change under only changed files|822ms| ❌ gets changed files for hg
|✔️|do not pickup non-tested files when reporting coverage on only changed files|861ms| Error: expect(received).toMatch(expected)
|✔️|collect test coverage when using onlyChanged|1.058s| ✔️ path on Windows is case-insensitive
|✔️|onlyChanged in config is overwritten by --all or testPathPattern|7.023s| ```
|❌|gets changed files for hg|3.765s|
|✔️|path on Windows is case-insensitive|0ms|

View File

@@ -0,0 +1,29 @@
![Tests failed](https://img.shields.io/badge/tests-1%20passed%2C%204%20failed%2C%201%20skipped-critical)
## ❌ <a id="user-content-r0" href="#r0">fixtures/mocha-json.json</a>
**6** tests were completed in **12ms** with **1** passed, **4** failed and **1** skipped.
|Test suite|Passed|Failed|Skipped|Time|
|:---|---:|---:|---:|---:|
|[test/main.test.js](#r0s0)|1✔|3❌||1ms|
|[test/second.test.js](#r0s1)||1❌|1✖|8ms|
### ❌ <a id="user-content-r0s0" href="#r0s0">test/main.test.js</a>
```
Test 1
✔️ Passing test
Test 1 Test 1.1
❌ Exception in target unit
Some error
❌ Failing test
Expected values to be strictly equal:
false !== true
Test 2
❌ Exception in test
Some error
```
### ❌ <a id="user-content-r0s1" href="#r0s1">test/second.test.js</a>
```
✖️ Skipped test
❌ Timeout test
Timeout of 1ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (C:\Users\Michal\Workspace\dorny\test-reporter\reports\mocha\test\second.test.js)
```

View File

@@ -0,0 +1,41 @@
![Tests passed successfully](https://img.shields.io/badge/tests-833%20passed%2C%206%20skipped-success)
## ✔️ <a id="user-content-r0" href="#r0">fixtures/external/mocha/mocha-test-results.json</a>
**839** tests were completed in **6s** with **833** passed, **0** failed and **6** skipped.
|Test suite|Passed|Failed|Skipped|Time|
|:---|---:|---:|---:|---:|
|test/node-unit/buffered-worker-pool.spec.js|14✔|||8ms|
|test/node-unit/cli/config.spec.js|10✔|||8ms|
|test/node-unit/cli/node-flags.spec.js|105✔|||9ms|
|test/node-unit/cli/options.spec.js|36✔|||250ms|
|test/node-unit/cli/run-helpers.spec.js|9✔|||8ms|
|test/node-unit/cli/run.spec.js|40✔|||4ms|
|test/node-unit/mocha.spec.js|24✔|||33ms|
|test/node-unit/parallel-buffered-runner.spec.js|19✔|||23ms|
|test/node-unit/reporters/parallel-buffered.spec.js|6✔|||16ms|
|test/node-unit/serializer.spec.js|40✔|||31ms|
|test/node-unit/stack-trace-filter.spec.js|2✔||4✖|1ms|
|test/node-unit/utils.spec.js|5✔|||1ms|
|test/node-unit/worker.spec.js|15✔|||92ms|
|test/unit/context.spec.js|8✔|||5ms|
|test/unit/duration.spec.js|3✔|||166ms|
|test/unit/errors.spec.js|13✔|||5ms|
|test/unit/globals.spec.js|4✔|||0ms|
|test/unit/grep.spec.js|8✔|||2ms|
|test/unit/hook-async.spec.js|3✔|||1ms|
|test/unit/hook-sync-nested.spec.js|4✔|||1ms|
|test/unit/hook-sync.spec.js|3✔|||0ms|
|test/unit/hook-timeout.spec.js|1✔|||0ms|
|test/unit/hook.spec.js|4✔|||0ms|
|test/unit/mocha.spec.js|115✔||1✖|128ms|
|test/unit/overspecified-async.spec.js|1✔|||3ms|
|test/unit/parse-query.spec.js|2✔|||1ms|
|test/unit/plugin-loader.spec.js|41✔||1✖|16ms|
|test/unit/required-tokens.spec.js|1✔|||0ms|
|test/unit/root.spec.js|1✔|||0ms|
|test/unit/runnable.spec.js|55✔|||122ms|
|test/unit/runner.spec.js|77✔|||43ms|
|test/unit/suite.spec.js|57✔|||14ms|
|test/unit/test.spec.js|15✔|||0ms|
|test/unit/throw.spec.js|9✔|||9ms|
|test/unit/timeout.spec.js|8✔|||109ms|
|test/unit/utils.spec.js|75✔|||24ms|

View File

@@ -1,5 +1,5 @@
![Tests failed](https://img.shields.io/badge/tests-268%20passed%2C%201%20failed-critical) ![Tests failed](https://img.shields.io/badge/tests-268%20passed%2C%201%20failed-critical)
## <a id="user-content-r0" href="#r0">fixtures/external/flutter/provider-test-results.json</a> ## ❌ <a id="user-content-r0" href="#r0">fixtures/external/flutter/provider-test-results.json</a>
**269** tests were completed in **0ms** with **268** passed, **1** failed and **0** skipped. **269** tests were completed in **0ms** with **268** passed, **1** failed and **0** skipped.
|Test suite|Passed|Failed|Skipped|Time| |Test suite|Passed|Failed|Skipped|Time|
|:---|---:|---:|---:|---:| |:---|---:|---:|---:|---:|
@@ -8,7 +8,7 @@
|[test/consumer_test.dart](#r0s2)|18✔|||340ms| |[test/consumer_test.dart](#r0s2)|18✔|||340ms|
|[test/context_test.dart](#r0s3)|31✔|||698ms| |[test/context_test.dart](#r0s3)|31✔|||698ms|
|[test/future_provider_test.dart](#r0s4)|10✔|||305ms| |[test/future_provider_test.dart](#r0s4)|10✔|||305ms|
|[test/inherited_provider_test.dart](#r0s5)|81✔|||1.117s| |[test/inherited_provider_test.dart](#r0s5)|81✔|||1s|
|[test/listenable_provider_test.dart](#r0s6)|16✔|||353ms| |[test/listenable_provider_test.dart](#r0s6)|16✔|||353ms|
|[test/listenable_proxy_provider_test.dart](#r0s7)|12✔|||373ms| |[test/listenable_proxy_provider_test.dart](#r0s7)|12✔|||373ms|
|[test/multi_provider_test.dart](#r0s8)|3✔|||198ms| |[test/multi_provider_test.dart](#r0s8)|3✔|||198ms|
@@ -19,455 +19,356 @@
|[test/stateful_provider_test.dart](#r0s13)|4✔|||254ms| |[test/stateful_provider_test.dart](#r0s13)|4✔|||254ms|
|[test/stream_provider_test.dart](#r0s14)|8✔|||282ms| |[test/stream_provider_test.dart](#r0s14)|8✔|||282ms|
|[test/value_listenable_provider_test.dart](#r0s15)|4✔|1❌||327ms| |[test/value_listenable_provider_test.dart](#r0s15)|4✔|1❌||327ms|
### <a id="user-content-r0s0" href="#r0s0">test/builder_test.dart</a> ✔️ ### ✔️ <a id="user-content-r0s0" href="#r0s0">test/builder_test.dart</a>
**24** tests were completed in **402ms** with **24** passed, **0** failed and **0** skipped. ```
ChangeNotifierProvider
**ChangeNotifierProvider** ✔️ default
|Result|Test|Time| ✔️ .value
|:---:|:---|---:| ListenableProvider
|✔️|ChangeNotifierProvider default|189ms| ✔️ default
|✔️|ChangeNotifierProvider .value|10ms| ✔️ .value
Provider
**ListenableProvider** ✔️ default
|Result|Test|Time| ✔️ .value
|:---:|:---|---:| ProxyProvider
|✔️|ListenableProvider default|9ms| ✔️ 0
|✔️|ListenableProvider .value|16ms| ✔️ 1
✔️ 2
**Provider** ✔️ 3
|Result|Test|Time| ✔️ 4
|:---:|:---|---:| ✔️ 5
|✔️|Provider default|11ms| ✔️ 6
|✔️|Provider .value|8ms| MultiProvider
✔️ with 1 ChangeNotifierProvider default
**ProxyProvider** ✔️ with 2 ChangeNotifierProvider default
|Result|Test|Time| ✔️ with ListenableProvider default
|:---:|:---|---:| ✔️ with Provider default
|✔️|ProxyProvider 0|11ms| ✔️ with ProxyProvider0
|✔️|ProxyProvider 1|10ms| ✔️ with ProxyProvider1
|✔️|ProxyProvider 2|8ms| ✔️ with ProxyProvider2
|✔️|ProxyProvider 3|10ms| ✔️ with ProxyProvider3
|✔️|ProxyProvider 4|9ms| ✔️ with ProxyProvider4
|✔️|ProxyProvider 5|9ms| ✔️ with ProxyProvider5
|✔️|ProxyProvider 6|9ms| ✔️ with ProxyProvider6
```
**MultiProvider** ### ✔️ <a id="user-content-r0s1" href="#r0s1">test/change_notifier_provider_test.dart</a>
|Result|Test|Time| ```
|:---:|:---|---:| ✔️ Use builder property, not child
|✔️|MultiProvider with 1 ChangeNotifierProvider default|9ms| ChangeNotifierProvider
|✔️|MultiProvider with 2 ChangeNotifierProvider default|9ms| ✔️ value
|✔️|MultiProvider with ListenableProvider default|12ms| ✔️ builder
|✔️|MultiProvider with Provider default|8ms| ✔️ builder1
|✔️|MultiProvider with ProxyProvider0|7ms| ✔️ builder2
|✔️|MultiProvider with ProxyProvider1|9ms| ✔️ builder3
|✔️|MultiProvider with ProxyProvider2|7ms| ✔️ builder4
|✔️|MultiProvider with ProxyProvider3|9ms| ✔️ builder5
|✔️|MultiProvider with ProxyProvider4|9ms| ✔️ builder6
|✔️|MultiProvider with ProxyProvider5|7ms| ✔️ builder0
|✔️|MultiProvider with ProxyProvider6|7ms| ```
### <a id="user-content-r0s1" href="#r0s1">test/change_notifier_provider_test.dart</a> ✔️ ### ✔️ <a id="user-content-r0s2" href="#r0s2">test/consumer_test.dart</a>
**10** tests were completed in **306ms** with **10** passed, **0** failed and **0** skipped. ```
consumer
|Result|Test|Time| ✔️ obtains value from Provider<T>
|:---:|:---|---:| ✔️ crashed with no builder
|✔️|Use builder property, not child|10ms| ✔️ can be used inside MultiProvider
consumer2
**ChangeNotifierProvider** ✔️ obtains value from Provider<T>
|Result|Test|Time| ✔️ crashed with no builder
|:---:|:---|---:| ✔️ can be used inside MultiProvider
|✔️|ChangeNotifierProvider value|185ms| consumer3
|✔️|ChangeNotifierProvider builder|18ms| ✔️ obtains value from Provider<T>
|✔️|ChangeNotifierProvider builder1|12ms| ✔️ crashed with no builder
|✔️|ChangeNotifierProvider builder2|12ms| ✔️ can be used inside MultiProvider
|✔️|ChangeNotifierProvider builder3|19ms| consumer4
|✔️|ChangeNotifierProvider builder4|14ms| ✔️ obtains value from Provider<T>
|✔️|ChangeNotifierProvider builder5|15ms| ✔️ crashed with no builder
|✔️|ChangeNotifierProvider builder6|11ms| ✔️ can be used inside MultiProvider
|✔️|ChangeNotifierProvider builder0|10ms| consumer5
### <a id="user-content-r0s2" href="#r0s2">test/consumer_test.dart</a> ✔️ ✔️ obtains value from Provider<T>
**18** tests were completed in **340ms** with **18** passed, **0** failed and **0** skipped. ✔️ crashed with no builder
✔️ can be used inside MultiProvider
**consumer** consumer6
|Result|Test|Time| ✔️ obtains value from Provider<T>
|:---:|:---|---:| ✔️ crashed with no builder
|✔️|consumer obtains value from Provider<T>|181ms| ✔️ can be used inside MultiProvider
|✔️|consumer crashed with no builder|11ms| ```
|✔️|consumer can be used inside MultiProvider|16ms| ### ✔️ <a id="user-content-r0s3" href="#r0s3">test/context_test.dart</a>
```
**consumer2** ✔️ watch in layoutbuilder
|Result|Test|Time| ✔️ select in layoutbuilder
|:---:|:---|---:| ✔️ cannot select in listView
|✔️|consumer2 obtains value from Provider<T>|22ms| ✔️ watch in listView
|✔️|consumer2 crashed with no builder|8ms| ✔️ watch in gridView
|✔️|consumer2 can be used inside MultiProvider|9ms| ✔️ clears select dependencies for all dependents
BuildContext
**consumer3** ✔️ internal selected value is updated
|Result|Test|Time| ✔️ create can use read without being lazy
|:---:|:---|---:| ✔️ watch can be used inside InheritedProvider.update
|✔️|consumer3 obtains value from Provider<T>|9ms| ✔️ select doesn't fail if it loads a provider that depends on other providers
|✔️|consumer3 crashed with no builder|7ms| ✔️ don't call old selectors if the child rebuilds individually
|✔️|consumer3 can be used inside MultiProvider|8ms| ✔️ selects throws inside click handlers
✔️ select throws if try to read dynamic
**consumer4** ✔️ select throws ProviderNotFoundException
|Result|Test|Time| ✔️ select throws if watch called inside the callback from build
|:---:|:---|---:| ✔️ select throws if read called inside the callback from build
|✔️|consumer4 obtains value from Provider<T>|8ms| ✔️ select throws if select called inside the callback from build
|✔️|consumer4 crashed with no builder|6ms| ✔️ select throws if read called inside the callback on dependency change
|✔️|consumer4 can be used inside MultiProvider|8ms| ✔️ select throws if watch called inside the callback on dependency change
✔️ select throws if select called inside the callback on dependency change
**consumer5** ✔️ can call read inside didChangeDependencies
|Result|Test|Time| ✔️ select cannot be called inside didChangeDependencies
|:---:|:---|---:| ✔️ select in initState throws
|✔️|consumer5 obtains value from Provider<T>|8ms| ✔️ watch in initState throws
|✔️|consumer5 crashed with no builder|6ms| ✔️ read in initState works
|✔️|consumer5 can be used inside MultiProvider|9ms| ✔️ consumer can be removed and selector stops to be called
✔️ context.select deeply compares maps
**consumer6** ✔️ context.select deeply compares lists
|Result|Test|Time| ✔️ context.select deeply compares iterables
|:---:|:---|---:| ✔️ context.select deeply compares sets
|✔️|consumer6 obtains value from Provider<T>|8ms| ✔️ context.watch listens to value changes
|✔️|consumer6 crashed with no builder|8ms| ```
|✔️|consumer6 can be used inside MultiProvider|8ms| ### ✔️ <a id="user-content-r0s4" href="#r0s4">test/future_provider_test.dart</a>
### <a id="user-content-r0s3" href="#r0s3">test/context_test.dart</a> ✔️ ```
**31** tests were completed in **698ms** with **31** passed, **0** failed and **0** skipped. ✔️ works with MultiProvider
✔️ (catchError) previous future completes after transition is no-op
|Result|Test|Time| ✔️ previous future completes after transition is no-op
|:---:|:---|---:| ✔️ transition from future to future preserve state
|✔️|watch in layoutbuilder|179ms| ✔️ throws if future has error and catchError is missing
|✔️|select in layoutbuilder|12ms| ✔️ calls catchError if present and future has error
|✔️|cannot select in listView|138ms| ✔️ works with null
|✔️|watch in listView|33ms| ✔️ create and dispose future with builder
|✔️|watch in gridView|21ms| ✔️ FutureProvider() crashes if builder is null
|✔️|clears select dependencies for all dependents|19ms| FutureProvider()
✔️ crashes if builder is null
**BuildContext** ```
|Result|Test|Time| ### ✔️ <a id="user-content-r0s5" href="#r0s5">test/inherited_provider_test.dart</a>
|:---:|:---|---:| ```
|✔️|BuildContext internal selected value is updated|32ms| ✔️ regression test #377
|✔️|BuildContext create can use read without being lazy|11ms| ✔️ rebuild on dependency flags update
|✔️|BuildContext watch can be used inside InheritedProvider.update|10ms| ✔️ properly update debug flags if a create triggers another deferred create
|✔️|BuildContext select doesn't fail if it loads a provider that depends on other providers|9ms| ✔️ properly update debug flags if a create triggers another deferred create
|✔️|BuildContext don't call old selectors if the child rebuilds individually|21ms| ✔️ properly update debug flags if an update triggers another create/update
|✔️|BuildContext selects throws inside click handlers|40ms| ✔️ properly update debug flags if a create triggers another create/update
|✔️|BuildContext select throws if try to read dynamic|9ms| ✔️ Provider.of(listen: false) outside of build works when it loads a provider
|✔️|BuildContext select throws ProviderNotFoundException|9ms| ✔️ new value is available in didChangeDependencies
|✔️|BuildContext select throws if watch called inside the callback from build|6ms| ✔️ builder receives the current value and updates independently from `update`
|✔️|BuildContext select throws if read called inside the callback from build|9ms| ✔️ builder can _not_ rebuild when provider updates
|✔️|BuildContext select throws if select called inside the callback from build|8ms| ✔️ builder rebuilds if provider is recreated
|✔️|BuildContext select throws if read called inside the callback on dependency change|10ms| ✔️ provider.of throws if listen:true outside of the widget tree
|✔️|BuildContext select throws if watch called inside the callback on dependency change|17ms| ✔️ InheritedProvider throws if no child is provided with default constructor
|✔️|BuildContext select throws if select called inside the callback on dependency change|9ms| ✔️ InheritedProvider throws if no child is provided with value constructor
|✔️|BuildContext can call read inside didChangeDependencies|9ms| ✔️ DeferredInheritedProvider throws if no child is provided with default constructor
|✔️|BuildContext select cannot be called inside didChangeDependencies|6ms| ✔️ DeferredInheritedProvider throws if no child is provided with value constructor
|✔️|BuildContext select in initState throws|6ms| ✔️ startListening markNeedsNotifyDependents
|✔️|BuildContext watch in initState throws|10ms| ✔️ InheritedProvider can be subclassed
|✔️|BuildContext read in initState works|6ms| ✔️ DeferredInheritedProvider can be subclassed
|✔️|BuildContext consumer can be removed and selector stops to be called|7ms| ✔️ can be used with MultiProvider
|✔️|BuildContext context.select deeply compares maps|15ms| ✔️ throw if the widget ctor changes
|✔️|BuildContext context.select deeply compares lists|8ms| ✔️ InheritedProvider lazy loading can be disabled
|✔️|BuildContext context.select deeply compares iterables|8ms| ✔️ InheritedProvider.value lazy loading can be disabled
|✔️|BuildContext context.select deeply compares sets|11ms| ✔️ InheritedProvider subclass don't have to specify default lazy value
|✔️|BuildContext context.watch listens to value changes|10ms| ✔️ DeferredInheritedProvider lazy loading can be disabled
### <a id="user-content-r0s4" href="#r0s4">test/future_provider_test.dart</a> ✔️ ✔️ DeferredInheritedProvider.value lazy loading can be disabled
**10** tests were completed in **305ms** with **10** passed, **0** failed and **0** skipped. ✔️ selector
✔️ can select multiple types from same provider
|Result|Test|Time| ✔️ can select same type on two different providers
|:---:|:---|---:| ✔️ can select same type twice on same provider
|✔️|works with MultiProvider|184ms| ✔️ Provider.of has a proper error message if context is null
|✔️|(catchError) previous future completes after transition is no-op|16ms| diagnostics
|✔️|previous future completes after transition is no-op|15ms| ✔️ InheritedProvider.value
|✔️|transition from future to future preserve state|12ms| ✔️ InheritedProvider doesn't break lazy loading
|✔️|throws if future has error and catchError is missing|24ms| ✔️ InheritedProvider show if listening
|✔️|calls catchError if present and future has error|21ms| ✔️ DeferredInheritedProvider.value
|✔️|works with null|14ms| ✔️ DeferredInheritedProvider
|✔️|create and dispose future with builder|12ms| InheritedProvider.value()
|✔️|FutureProvider() crashes if builder is null|4ms| ✔️ markNeedsNotifyDependents during startListening is noop
✔️ startListening called again when create returns new value
**FutureProvider()** ✔️ startListening
|Result|Test|Time| ✔️ stopListening not called twice if rebuild doesn't have listeners
|:---:|:---|---:| ✔️ removeListener cannot be null
|✔️|FutureProvider() crashes if builder is null|3ms| ✔️ pass down current value
### <a id="user-content-r0s5" href="#r0s5">test/inherited_provider_test.dart</a> ✔️ ✔️ default updateShouldNotify
**81** tests were completed in **1.117s** with **81** passed, **0** failed and **0** skipped. ✔️ custom updateShouldNotify
InheritedProvider()
|Result|Test|Time| ✔️ hasValue
|:---:|:---|---:| ✔️ provider calls update if rebuilding only due to didChangeDependencies
|✔️|regression test #377|167ms| ✔️ provider notifying dependents doesn't call update
|✔️|rebuild on dependency flags update|15ms| ✔️ update can call Provider.of with listen:true
|✔️|properly update debug flags if a create triggers another deferred create|9ms| ✔️ update lazy loaded can call Provider.of with listen:true
|✔️|properly update debug flags if a create triggers another deferred create|8ms| ✔️ markNeedsNotifyDependents during startListening is noop
|✔️|properly update debug flags if an update triggers another create/update|7ms| ✔️ update can obtain parent of the same type than self
|✔️|properly update debug flags if a create triggers another create/update|8ms| ✔️ _debugCheckInvalidValueType
|✔️|Provider.of(listen: false) outside of build works when it loads a provider|22ms| ✔️ startListening
|✔️|new value is available in didChangeDependencies|26ms| ✔️ startListening called again when create returns new value
|✔️|builder receives the current value and updates independently from `update`|16ms| ✔️ stopListening not called twice if rebuild doesn't have listeners
|✔️|builder can _not_ rebuild when provider updates|8ms| ✔️ removeListener cannot be null
|✔️|builder rebuilds if provider is recreated|9ms| ✔️ fails if initialValueBuilder calls inheritFromElement/inheritFromWiggetOfExactType
|✔️|provider.of throws if listen:true outside of the widget tree|23ms| ✔️ builder is called on every rebuild and after a dependency change
|✔️|InheritedProvider throws if no child is provided with default constructor|14ms| ✔️ builder with no updateShouldNotify use ==
|✔️|InheritedProvider throws if no child is provided with value constructor|8ms| ✔️ builder calls updateShouldNotify callback
|✔️|DeferredInheritedProvider throws if no child is provided with default constructor|15ms| ✔️ initialValue is transmitted to valueBuilder
|✔️|DeferredInheritedProvider throws if no child is provided with value constructor|7ms| ✔️ calls builder again if dependencies change
|✔️|startListening markNeedsNotifyDependents|7ms| ✔️ exposes initialValue if valueBuilder is null
|✔️|InheritedProvider can be subclassed|8ms| ✔️ call dispose on unmount
|✔️|DeferredInheritedProvider can be subclassed|7ms| ✔️ builder unmount, dispose not called if value never read
|✔️|can be used with MultiProvider|8ms| ✔️ call dispose after new value
|✔️|throw if the widget ctor changes|8ms| ✔️ valueBuilder works without initialBuilder
|✔️|InheritedProvider lazy loading can be disabled|6ms| ✔️ calls initialValueBuilder lazily once
|✔️|InheritedProvider.value lazy loading can be disabled|9ms| ✔️ throws if both builder and initialBuilder are missing
|✔️|InheritedProvider subclass don't have to specify default lazy value|7ms| DeferredInheritedProvider.value()
|✔️|DeferredInheritedProvider lazy loading can be disabled|7ms| ✔️ hasValue
|✔️|DeferredInheritedProvider.value lazy loading can be disabled|7ms| ✔️ startListening
|✔️|selector|14ms| ✔️ stopListening cannot be null
|✔️|can select multiple types from same provider|9ms| ✔️ startListening doesn't need setState if already initialized
|✔️|can select same type on two different providers|8ms| ✔️ setState without updateShouldNotify
|✔️|can select same type twice on same provider|10ms| ✔️ setState with updateShouldNotify
|✔️|Provider.of has a proper error message if context is null|6ms| ✔️ startListening never leave the widget uninitialized
✔️ startListening called again on controller change
**diagnostics** DeferredInheritedProvider()
|Result|Test|Time| ✔️ create can't call inherited widgets
|:---:|:---|---:| ✔️ creates the value lazily
|✔️|diagnostics InheritedProvider.value|11ms| ✔️ dispose
|✔️|diagnostics InheritedProvider doesn't break lazy loading|7ms| ✔️ dispose no-op if never built
|✔️|diagnostics InheritedProvider show if listening|7ms| ```
|✔️|diagnostics DeferredInheritedProvider.value|6ms| ### ✔️ <a id="user-content-r0s6" href="#r0s6">test/listenable_provider_test.dart</a>
|✔️|diagnostics DeferredInheritedProvider|16ms| ```
ListenableProvider
**InheritedProvider.value()** ✔️ works with MultiProvider
|Result|Test|Time| ✔️ asserts that the created notifier can have listeners
|:---:|:---|---:| ✔️ don't listen again if listenable instance doesn't change
|✔️|InheritedProvider.value() markNeedsNotifyDependents during startListening is noop|8ms| ✔️ works with null (default)
|✔️|InheritedProvider.value() startListening called again when create returns new value|27ms| ✔️ works with null (create)
|✔️|InheritedProvider.value() startListening|19ms| ✔️ stateful create called once
|✔️|InheritedProvider.value() stopListening not called twice if rebuild doesn't have listeners|16ms| ✔️ dispose called on unmount
|✔️|InheritedProvider.value() removeListener cannot be null|22ms| ✔️ dispose can be null
|✔️|InheritedProvider.value() pass down current value|17ms| ✔️ changing listenable rebuilds descendants
|✔️|InheritedProvider.value() default updateShouldNotify|8ms| ✔️ rebuilding with the same provider don't rebuilds descendants
|✔️|InheritedProvider.value() custom updateShouldNotify|32ms| ✔️ notifylistener rebuilds descendants
ListenableProvider value constructor
**InheritedProvider()** ✔️ pass down key
|Result|Test|Time| ✔️ changing the Listenable instance rebuilds dependents
|:---:|:---|---:| ListenableProvider stateful constructor
|✔️|InheritedProvider() hasValue|16ms| ✔️ called with context
|✔️|InheritedProvider() provider calls update if rebuilding only due to didChangeDependencies|9ms| ✔️ pass down key
|✔️|InheritedProvider() provider notifying dependents doesn't call update|11ms| ✔️ throws if create is null
|✔️|InheritedProvider() update can call Provider.of with listen:true|7ms| ```
|✔️|InheritedProvider() update lazy loaded can call Provider.of with listen:true|10ms| ### ✔️ <a id="user-content-r0s7" href="#r0s7">test/listenable_proxy_provider_test.dart</a>
|✔️|InheritedProvider() markNeedsNotifyDependents during startListening is noop|22ms| ```
|✔️|InheritedProvider() update can obtain parent of the same type than self|15ms| ListenableProxyProvider
|✔️|InheritedProvider() _debugCheckInvalidValueType|22ms| ✔️ throws if update is missing
|✔️|InheritedProvider() startListening|18ms| ✔️ asserts that the created notifier has no listener
|✔️|InheritedProvider() startListening called again when create returns new value|20ms| ✔️ asserts that the created notifier has no listener after rebuild
|✔️|InheritedProvider() stopListening not called twice if rebuild doesn't have listeners|18ms| ✔️ rebuilds dependendents when listeners are called
|✔️|InheritedProvider() removeListener cannot be null|16ms| ✔️ update returning a new Listenable disposes the previously created value and update dependents
|✔️|InheritedProvider() fails if initialValueBuilder calls inheritFromElement/inheritFromWiggetOfExactType|17ms| ✔️ disposes of created value
|✔️|InheritedProvider() builder is called on every rebuild and after a dependency change|11ms| ListenableProxyProvider variants
|✔️|InheritedProvider() builder with no updateShouldNotify use ==|8ms| ✔️ ListenableProxyProvider
|✔️|InheritedProvider() builder calls updateShouldNotify callback|8ms| ✔️ ListenableProxyProvider2
|✔️|InheritedProvider() initialValue is transmitted to valueBuilder|8ms| ✔️ ListenableProxyProvider3
|✔️|InheritedProvider() calls builder again if dependencies change|22ms| ✔️ ListenableProxyProvider4
|✔️|InheritedProvider() exposes initialValue if valueBuilder is null|20ms| ✔️ ListenableProxyProvider5
|✔️|InheritedProvider() call dispose on unmount|22ms| ✔️ ListenableProxyProvider6
|✔️|InheritedProvider() builder unmount, dispose not called if value never read|11ms| ```
|✔️|InheritedProvider() call dispose after new value|9ms| ### ✔️ <a id="user-content-r0s8" href="#r0s8">test/multi_provider_test.dart</a>
|✔️|InheritedProvider() valueBuilder works without initialBuilder|11ms| ```
|✔️|InheritedProvider() calls initialValueBuilder lazily once|7ms| MultiProvider
|✔️|InheritedProvider() throws if both builder and initialBuilder are missing|5ms| ✔️ throw if providers is null
✔️ MultiProvider children can only access parent providers
**DeferredInheritedProvider.value()** ✔️ MultiProvider.providers with ignored child
|Result|Test|Time| ```
|:---:|:---|---:| ### ✔️ <a id="user-content-r0s9" href="#r0s9">test/provider_test.dart</a>
|✔️|DeferredInheritedProvider.value() hasValue|6ms| ```
|✔️|DeferredInheritedProvider.value() startListening|9ms| ✔️ works with MultiProvider
|✔️|DeferredInheritedProvider.value() stopListening cannot be null|9ms| Provider.of
|✔️|DeferredInheritedProvider.value() startListening doesn't need setState if already initialized|8ms| ✔️ throws if T is dynamic
|✔️|DeferredInheritedProvider.value() setState without updateShouldNotify|8ms| ✔️ listen defaults to true when building widgets
|✔️|DeferredInheritedProvider.value() setState with updateShouldNotify|9ms| ✔️ listen defaults to false outside of the widget tree
|✔️|DeferredInheritedProvider.value() startListening never leave the widget uninitialized|8ms| ✔️ listen:false doesn't trigger rebuild
|✔️|DeferredInheritedProvider.value() startListening called again on controller change|10ms| ✔️ listen:true outside of the widget tree throws
Provider
**DeferredInheritedProvider()** ✔️ throws if the provided value is a Listenable/Stream
|Result|Test|Time| ✔️ debugCheckInvalidValueType can be disabled
|:---:|:---|---:| ✔️ simple usage
|✔️|DeferredInheritedProvider() create can't call inherited widgets|7ms| ✔️ throws an error if no provider found
|✔️|DeferredInheritedProvider() creates the value lazily|7ms| ✔️ update should notify
|✔️|DeferredInheritedProvider() dispose|7ms| ```
|✔️|DeferredInheritedProvider() dispose no-op if never built|7ms| ### ✔️ <a id="user-content-r0s10" href="#r0s10">test/proxy_provider_test.dart</a>
### <a id="user-content-r0s6" href="#r0s6">test/listenable_provider_test.dart</a> ✔️ ```
**16** tests were completed in **353ms** with **16** passed, **0** failed and **0** skipped. ProxyProvider
✔️ throws if the provided value is a Listenable/Stream
**ListenableProvider** ✔️ debugCheckInvalidValueType can be disabled
|Result|Test|Time| ✔️ create creates initial value
|:---:|:---|---:| ✔️ consume another providers
|✔️|ListenableProvider works with MultiProvider|173ms| ✔️ rebuild descendants if value change
|✔️|ListenableProvider asserts that the created notifier can have listeners|12ms| ✔️ call dispose when unmounted with the latest result
|✔️|ListenableProvider don't listen again if listenable instance doesn't change|12ms| ✔️ don't rebuild descendants if value doesn't change
|✔️|ListenableProvider works with null (default)|7ms| ✔️ pass down updateShouldNotify
|✔️|ListenableProvider works with null (create)|7ms| ✔️ works with MultiProvider
|✔️|ListenableProvider stateful create called once|11ms| ✔️ update callback can trigger descendants setState synchronously
|✔️|ListenableProvider dispose called on unmount|13ms| ✔️ throws if update is null
|✔️|ListenableProvider dispose can be null|8ms| ProxyProvider variants
|✔️|ListenableProvider changing listenable rebuilds descendants|12ms| ✔️ ProxyProvider2
|✔️|ListenableProvider rebuilding with the same provider don't rebuilds descendants|11ms| ✔️ ProxyProvider3
|✔️|ListenableProvider notifylistener rebuilds descendants|9ms| ✔️ ProxyProvider4
✔️ ProxyProvider5
**ListenableProvider value constructor** ✔️ ProxyProvider6
|Result|Test|Time| ```
|:---:|:---|---:| ### ✔️ <a id="user-content-r0s11" href="#r0s11">test/reassemble_test.dart</a>
|✔️|ListenableProvider value constructor pass down key|17ms| ```
|✔️|ListenableProvider value constructor changing the Listenable instance rebuilds dependents|29ms| ✔️ ReassembleHandler
✔️ unevaluated create
**ListenableProvider stateful constructor** ✔️ unevaluated create
|Result|Test|Time| ```
|:---:|:---|---:| ### ✔️ <a id="user-content-r0s12" href="#r0s12">test/selector_test.dart</a>
|✔️|ListenableProvider stateful constructor called with context|8ms| ```
|✔️|ListenableProvider stateful constructor pass down key|20ms| ✔️ asserts that builder/selector are not null
|✔️|ListenableProvider stateful constructor throws if create is null|4ms| ✔️ Deep compare maps by default
### <a id="user-content-r0s7" href="#r0s7">test/listenable_proxy_provider_test.dart</a> ✔️ ✔️ Deep compare iterables by default
**12** tests were completed in **373ms** with **12** passed, **0** failed and **0** skipped. ✔️ Deep compare sets by default
✔️ Deep compare lists by default
**ListenableProxyProvider** ✔️ custom shouldRebuid
|Result|Test|Time| ✔️ passes `child` and `key`
|:---:|:---|---:| ✔️ calls builder if the callback changes
|✔️|ListenableProxyProvider throws if update is missing|43ms| ✔️ works with MultiProvider
|✔️|ListenableProxyProvider asserts that the created notifier has no listener|177ms| ✔️ don't call builder again if it rebuilds but selector returns the same thing
|✔️|ListenableProxyProvider asserts that the created notifier has no listener after rebuild|18ms| ✔️ call builder again if it rebuilds abd selector returns the a different variable
|✔️|ListenableProxyProvider rebuilds dependendents when listeners are called|20ms| ✔️ Selector
|✔️|ListenableProxyProvider update returning a new Listenable disposes the previously created value and update dependents|25ms| ✔️ Selector2
|✔️|ListenableProxyProvider disposes of created value|13ms| ✔️ Selector3
✔️ Selector4
**ListenableProxyProvider variants** ✔️ Selector5
|Result|Test|Time| ✔️ Selector6
|:---:|:---|---:| ```
|✔️|ListenableProxyProvider variants ListenableProxyProvider|13ms| ### ✔️ <a id="user-content-r0s13" href="#r0s13">test/stateful_provider_test.dart</a>
|✔️|ListenableProxyProvider variants ListenableProxyProvider2|9ms| ```
|✔️|ListenableProxyProvider variants ListenableProxyProvider3|9ms| ✔️ asserts
|✔️|ListenableProxyProvider variants ListenableProxyProvider4|17ms| ✔️ works with MultiProvider
|✔️|ListenableProxyProvider variants ListenableProxyProvider5|12ms| ✔️ calls create only once
|✔️|ListenableProxyProvider variants ListenableProxyProvider6|17ms| ✔️ dispose
### <a id="user-content-r0s8" href="#r0s8">test/multi_provider_test.dart</a> ✔️ ```
**3** tests were completed in **198ms** with **3** passed, **0** failed and **0** skipped. ### ✔️ <a id="user-content-r0s14" href="#r0s14">test/stream_provider_test.dart</a>
```
**MultiProvider** ✔️ works with MultiProvider
|Result|Test|Time| ✔️ transition from stream to stream preserve state
|:---:|:---|---:| ✔️ throws if stream has error and catchError is missing
|✔️|MultiProvider throw if providers is null|30ms| ✔️ calls catchError if present and stream has error
|✔️|MultiProvider MultiProvider children can only access parent providers|160ms| ✔️ works with null
|✔️|MultiProvider MultiProvider.providers with ignored child|8ms| ✔️ StreamProvider() crashes if builder is null
### <a id="user-content-r0s9" href="#r0s9">test/provider_test.dart</a> ✔️ StreamProvider()
**11** tests were completed in **306ms** with **11** passed, **0** failed and **0** skipped. ✔️ create and dispose stream with builder
✔️ crashes if builder is null
|Result|Test|Time| ```
|:---:|:---|---:| ### ❌ <a id="user-content-r0s15" href="#r0s15">test/value_listenable_provider_test.dart</a>
|✔️|works with MultiProvider|172ms| ```
valueListenableProvider
**Provider.of** ✔️ rebuilds when value change
|Result|Test|Time| ✔️ don't rebuild dependents by default
|:---:|:---|---:| ✔️ pass keys
|✔️|Provider.of throws if T is dynamic|26ms| ✔️ don't listen again if stream instance doesn't change
|✔️|Provider.of listen defaults to true when building widgets|13ms| ❌ pass updateShouldNotify
|✔️|Provider.of listen defaults to false outside of the widget tree|9ms| The following TestFailure object was thrown running a test:
|✔️|Provider.of listen:false doesn't trigger rebuild|10ms| Expected: <2>
|✔️|Provider.of listen:true outside of the widget tree throws|11ms| Actual: <1>
Unexpected number of calls
**Provider**
|Result|Test|Time| ```
|:---:|:---|---:|
|✔️|Provider throws if the provided value is a Listenable/Stream|28ms|
|✔️|Provider debugCheckInvalidValueType can be disabled|9ms|
|✔️|Provider simple usage|9ms|
|✔️|Provider throws an error if no provider found|11ms|
|✔️|Provider update should notify|8ms|
### <a id="user-content-r0s10" href="#r0s10">test/proxy_provider_test.dart</a> ✔️
**16** tests were completed in **438ms** with **16** passed, **0** failed and **0** skipped.
**ProxyProvider**
|Result|Test|Time|
|:---:|:---|---:|
|✔️|ProxyProvider throws if the provided value is a Listenable/Stream|209ms|
|✔️|ProxyProvider debugCheckInvalidValueType can be disabled|13ms|
|✔️|ProxyProvider create creates initial value|23ms|
|✔️|ProxyProvider consume another providers|18ms|
|✔️|ProxyProvider rebuild descendants if value change|13ms|
|✔️|ProxyProvider call dispose when unmounted with the latest result|11ms|
|✔️|ProxyProvider don't rebuild descendants if value doesn't change|12ms|
|✔️|ProxyProvider pass down updateShouldNotify|19ms|
|✔️|ProxyProvider works with MultiProvider|16ms|
|✔️|ProxyProvider update callback can trigger descendants setState synchronously|24ms|
|✔️|ProxyProvider throws if update is null|7ms|
**ProxyProvider variants**
|Result|Test|Time|
|:---:|:---|---:|
|✔️|ProxyProvider variants ProxyProvider2|18ms|
|✔️|ProxyProvider variants ProxyProvider3|16ms|
|✔️|ProxyProvider variants ProxyProvider4|9ms|
|✔️|ProxyProvider variants ProxyProvider5|20ms|
|✔️|ProxyProvider variants ProxyProvider6|10ms|
### <a id="user-content-r0s11" href="#r0s11">test/reassemble_test.dart</a> ✔️
**3** tests were completed in **221ms** with **3** passed, **0** failed and **0** skipped.
|Result|Test|Time|
|:---:|:---|---:|
|✔️|ReassembleHandler|194ms|
|✔️|unevaluated create|11ms|
|✔️|unevaluated create|16ms|
### <a id="user-content-r0s12" href="#r0s12">test/selector_test.dart</a> ✔️
**17** tests were completed in **364ms** with **17** passed, **0** failed and **0** skipped.
|Result|Test|Time|
|:---:|:---|---:|
|✔️|asserts that builder/selector are not null|32ms|
|✔️|Deep compare maps by default|158ms|
|✔️|Deep compare iterables by default|9ms|
|✔️|Deep compare sets by default|12ms|
|✔️|Deep compare lists by default|14ms|
|✔️|custom shouldRebuid|11ms|
|✔️|passes `child` and `key`|13ms|
|✔️|calls builder if the callback changes|14ms|
|✔️|works with MultiProvider|12ms|
|✔️|don't call builder again if it rebuilds but selector returns the same thing|9ms|
|✔️|call builder again if it rebuilds abd selector returns the a different variable|9ms|
|✔️|Selector|15ms|
|✔️|Selector2|9ms|
|✔️|Selector3|8ms|
|✔️|Selector4|9ms|
|✔️|Selector5|19ms|
|✔️|Selector6|11ms|
### <a id="user-content-r0s13" href="#r0s13">test/stateful_provider_test.dart</a> ✔️
**4** tests were completed in **254ms** with **4** passed, **0** failed and **0** skipped.
|Result|Test|Time|
|:---:|:---|---:|
|✔️|asserts|6ms|
|✔️|works with MultiProvider|203ms|
|✔️|calls create only once|27ms|
|✔️|dispose|18ms|
### <a id="user-content-r0s14" href="#r0s14">test/stream_provider_test.dart</a> ✔️
**8** tests were completed in **282ms** with **8** passed, **0** failed and **0** skipped.
|Result|Test|Time|
|:---:|:---|---:|
|✔️|works with MultiProvider|191ms|
|✔️|transition from stream to stream preserve state|16ms|
|✔️|throws if stream has error and catchError is missing|22ms|
|✔️|calls catchError if present and stream has error|20ms|
|✔️|works with null|13ms|
|✔️|StreamProvider() crashes if builder is null|5ms|
**StreamProvider()**
|Result|Test|Time|
|:---:|:---|---:|
|✔️|StreamProvider() create and dispose stream with builder|11ms|
|✔️|StreamProvider() crashes if builder is null|4ms|
### <a id="user-content-r0s15" href="#r0s15">test/value_listenable_provider_test.dart</a> ❌
**5** tests were completed in **327ms** with **4** passed, **1** failed and **0** skipped.
**valueListenableProvider**
|Result|Test|Time|
|:---:|:---|---:|
|✔️|valueListenableProvider rebuilds when value change|200ms|
|✔️|valueListenableProvider don't rebuild dependents by default|26ms|
|✔️|valueListenableProvider pass keys|10ms|
|✔️|valueListenableProvider don't listen again if stream instance doesn't change|22ms|
|❌|valueListenableProvider pass updateShouldNotify|69ms|

View File

@@ -1,13 +1,12 @@
![Tests failed](https://img.shields.io/badge/tests-1%20failed%2C%201%20skipped-critical) ![Tests failed](https://img.shields.io/badge/tests-1%20failed%2C%201%20skipped-critical)
## <a id="user-content-r0" href="#r0">fixtures/external/java/TEST-org.apache.pulsar.AddMissingPatchVersionTest.xml</a> ## ❌ <a id="user-content-r0" href="#r0">fixtures/external/java/TEST-org.apache.pulsar.AddMissingPatchVersionTest.xml</a>
**2** tests were completed in **116ms** with **0** passed, **1** failed and **1** skipped. **2** tests were completed in **116ms** with **0** passed, **1** failed and **1** skipped.
|Test suite|Passed|Failed|Skipped|Time| |Test suite|Passed|Failed|Skipped|Time|
|:---|---:|---:|---:|---:| |:---|---:|---:|---:|---:|
|[org.apache.pulsar.AddMissingPatchVersionTest](#r0s0)||1❌|1✖|116ms| |[org.apache.pulsar.AddMissingPatchVersionTest](#r0s0)||1❌|1✖|116ms|
### <a id="user-content-r0s0" href="#r0s0">org.apache.pulsar.AddMissingPatchVersionTest</a> ### ❌ <a id="user-content-r0s0" href="#r0s0">org.apache.pulsar.AddMissingPatchVersionTest</a>
**2** tests were completed in **116ms** with **0** passed, **1** failed and **1** skipped. ```
✖️ testVersionStrings
|Result|Test|Time| ❌ testVersionStrings
|:---:|:---|---:| java.lang.AssertionError: expected [1.2.1] but found [1.2.0]
|✖️|testVersionStrings|99ms| ```
|❌|testVersionStrings|17ms|

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
{
"stats": {
"suites": 0,
"tests": 0,
"passes": 0,
"pending": 0,
"failures": 0,
"start": "2021-03-08T20:01:44.391Z",
"end": "2021-03-08T20:01:44.391Z",
"duration": 0
},
"tests": [],
"pending": [],
"failures": [],
"passes": []
}

View File

@@ -0,0 +1,516 @@
.browserslistrc
.editorconfig
.eleventy.js
.eslintignore
.eslintrc.yml
.fossaignore
.gitattributes
.github/CODE_OF_CONDUCT.md
.github/CONTRIBUTING.md
.github/FUNDING.yml
.github/ISSUE_TEMPLATE/bug_report.md
.github/ISSUE_TEMPLATE/feature_request.md
.github/ISSUE_TEMPLATE/support-question.md
.github/PULL_REQUEST_TEMPLATE.md
.github/stale.yml
.github/workflows/mocha.yml
.github/workflows/nightly-site-deploy.yml
.github/workflows/purge-expired-artifacts.yml
.gitignore
.lintstagedrc.json
.mailmap
.markdownlint.json
.mocharc.yml
.npmrc
.nycrc
.wallaby.js
AUTHORS
CHANGELOG.md
LICENSE
MAINTAINERS.md
PROJECT_CHARTER.md
README.md
assets/growl/error.png
assets/growl/ok.png
assets/mocha-banner-192.png
assets/mocha-banner.svg
assets/mocha-fixture-wizard.sketch
assets/mocha-logo-128.png
assets/mocha-logo-192.png
assets/mocha-logo-64.png
assets/mocha-logo-96.png
assets/mocha-logo.svg
assets/opencollective-header.png
bin/_mocha
bin/mocha
browser-entry.js
docs/.browserslistrc
docs/.eleventyignore
docs/API.md
docs/CNAME
docs/LICENSE-CC-BY-4.0
docs/README.md
docs/_data/blocklist.json
docs/_data/files.js
docs/_data/supporters.js
docs/_data/toc.js
docs/_data/usage.js
docs/_headers
docs/_includes/default.liquid
docs/_includes/fixture-wizard.html
docs/_includes/supporters.md
docs/api-tutorials/custom-reporter.md
docs/api-tutorials/jsdoc.tutorials.json
docs/changelogs/CHANGELOG_V3_older.md
docs/changelogs/CHANGELOG_V4.md
docs/changelogs/README.md
docs/css/normalize.css
docs/css/prism.css
docs/css/style.css
docs/css/supporters.css
docs/example/Array.js
docs/example/async-dump.js
docs/example/debug-hanging-mocha.js
docs/example/tests.html
docs/favicon.ico
docs/images/emacs.png
docs/images/jetbrains-plugin.png
docs/images/join-chat.svg
docs/images/link-icon.svg
docs/images/matomo-logo.png
docs/images/mocha-logo.svg
docs/images/mocha_side_bar.png
docs/images/openjsf-logo.svg
docs/images/reporter-doc.png
docs/images/reporter-dot.png
docs/images/reporter-html.png
docs/images/reporter-json-stream.png
docs/images/reporter-json.png
docs/images/reporter-landing-fail.png
docs/images/reporter-landing.png
docs/images/reporter-list.png
docs/images/reporter-min.png
docs/images/reporter-nyan.png
docs/images/reporter-progress.png
docs/images/reporter-spec-duration.png
docs/images/reporter-spec-fail.png
docs/images/reporter-spec.png
docs/images/reporter-string-diffs.png
docs/images/reporter-tap.png
docs/images/test-duration-range.png
docs/images/wallaby-logo.png
docs/images/wallaby.png
docs/index.md
docs/js/html5shiv.min.js
example/config/.mocharc.js
example/config/.mocharc.json
example/config/.mocharc.jsonc
example/config/.mocharc.yml
example/config/README.md
index.js
jsdoc.conf.json
karma.conf.js
lib/browser/growl.js
lib/browser/highlight-tags.js
lib/browser/parse-query.js
lib/browser/progress.js
lib/browser/template.html
lib/cli/cli.js
lib/cli/collect-files.js
lib/cli/commands.js
lib/cli/config.js
lib/cli/index.js
lib/cli/init.js
lib/cli/lookup-files.js
lib/cli/node-flags.js
lib/cli/one-and-dones.js
lib/cli/options.js
lib/cli/run-helpers.js
lib/cli/run-option-metadata.js
lib/cli/run.js
lib/cli/watch-run.js
lib/context.js
lib/errors.js
lib/esm-utils.js
lib/hook.js
lib/interfaces/bdd.js
lib/interfaces/common.js
lib/interfaces/exports.js
lib/interfaces/index.js
lib/interfaces/qunit.js
lib/interfaces/tdd.js
lib/mocha.js
lib/mocharc.json
lib/nodejs/buffered-worker-pool.js
lib/nodejs/file-unloader.js
lib/nodejs/growl.js
lib/nodejs/parallel-buffered-runner.js
lib/nodejs/reporters/parallel-buffered.js
lib/nodejs/serializer.js
lib/nodejs/worker.js
lib/pending.js
lib/plugin-loader.js
lib/reporters/base.js
lib/reporters/doc.js
lib/reporters/dot.js
lib/reporters/html.js
lib/reporters/index.js
lib/reporters/json-stream.js
lib/reporters/json.js
lib/reporters/landing.js
lib/reporters/list.js
lib/reporters/markdown.js
lib/reporters/min.js
lib/reporters/nyan.js
lib/reporters/progress.js
lib/reporters/spec.js
lib/reporters/tap.js
lib/reporters/xunit.js
lib/runnable.js
lib/runner.js
lib/stats-collector.js
lib/suite.js
lib/test.js
lib/utils.js
mocha.css
netlify.toml
package-lock.json
package-scripts.js
package.json
rollup.config.js
scripts/karma-rollup-plugin.js
scripts/linkify-changelog.js
scripts/netlify-headers.js
scripts/pick-from-package-json.js
scripts/update-authors.js
test/README.md
test/assertions.js
test/browser-specific/esm.spec.mjs
test/browser-specific/fixtures/esm.fixture.mjs
test/browser-specific/fixtures/requirejs/lib.fixture.js
test/browser-specific/fixtures/requirejs/main.fixture.js
test/browser-specific/fixtures/webpack/webpack.config.js
test/browser-specific/fixtures/webpack/webpack.fixture.mjs
test/browser-specific/requirejs-setup.js
test/browser-specific/setup.js
test/compiler-fixtures/foo.fixture.js
test/compiler/test.coffee
test/compiler/test.foo
test/integration/README.md
test/integration/color.spec.js
test/integration/common-js-require.spec.js
test/integration/compiler-globbing.spec.js
test/integration/config.spec.js
test/integration/deprecate.spec.js
test/integration/diffs.spec.js
test/integration/duplicate-arguments.spec.js
test/integration/esm.spec.js
test/integration/events.spec.js
test/integration/file-utils.spec.js
test/integration/fixtures/__default__.fixture.js
test/integration/fixtures/cascade.fixture.js
test/integration/fixtures/common-js-require.fixture.js
test/integration/fixtures/config/mocha-config/index.js
test/integration/fixtures/config/mocha-config/package.json
test/integration/fixtures/config/mocharc.cjs
test/integration/fixtures/config/mocharc.js
test/integration/fixtures/config/mocharc.json
test/integration/fixtures/config/mocharc.yaml
test/integration/fixtures/current-test-title.fixture.js
test/integration/fixtures/deprecate.fixture.js
test/integration/fixtures/diffs/diffs.css.in
test/integration/fixtures/diffs/diffs.css.out
test/integration/fixtures/diffs/diffs.fixture.js
test/integration/fixtures/diffs/output
test/integration/fixtures/esm/add.mjs
test/integration/fixtures/esm/esm-failure.fixture.mjs
test/integration/fixtures/esm/esm-success.fixture.mjs
test/integration/fixtures/esm/js-folder/add.js
test/integration/fixtures/esm/js-folder/esm-in-js.fixture.js
test/integration/fixtures/esm/js-folder/package.json
test/integration/fixtures/esm/syntax-error/esm-syntax-error.fixture.mjs
test/integration/fixtures/exit.fixture.js
test/integration/fixtures/glob/glob.spec.js
test/integration/fixtures/glob/nested/glob.spec.js
test/integration/fixtures/hooks/after-each-hook-async-error.fixture.js
test/integration/fixtures/hooks/after-each-hook-error.fixture.js
test/integration/fixtures/hooks/after-each-this-test-error.fixture.js
test/integration/fixtures/hooks/after-hook-async-error.fixture.js
test/integration/fixtures/hooks/after-hook-deepnested-error.fixture.js
test/integration/fixtures/hooks/after-hook-error.fixture.js
test/integration/fixtures/hooks/after-hook-nested-error.fixture.js
test/integration/fixtures/hooks/before-each-hook-async-error.fixture.js
test/integration/fixtures/hooks/before-each-hook-error.fixture.js
test/integration/fixtures/hooks/before-hook-async-error-tip.fixture.js
test/integration/fixtures/hooks/before-hook-async-error.fixture.js
test/integration/fixtures/hooks/before-hook-deepnested-error.fixture.js
test/integration/fixtures/hooks/before-hook-error-tip.fixture.js
test/integration/fixtures/hooks/before-hook-error.fixture.js
test/integration/fixtures/hooks/before-hook-nested-error.fixture.js
test/integration/fixtures/hooks/before-hook-root-error.fixture.js
test/integration/fixtures/hooks/multiple-hook-async-error.fixture.js
test/integration/fixtures/hooks/multiple-hook-error.fixture.js
test/integration/fixtures/multiple-done-async.fixture.js
test/integration/fixtures/multiple-done-before-each.fixture.js
test/integration/fixtures/multiple-done-before.fixture.js
test/integration/fixtures/multiple-done-specs.fixture.js
test/integration/fixtures/multiple-done-with-error.fixture.js
test/integration/fixtures/multiple-done.fixture.js
test/integration/fixtures/multiple-runs/clean-references.fixture.js
test/integration/fixtures/multiple-runs/dispose.fixture.js
test/integration/fixtures/multiple-runs/multiple-runs-with-different-output-suite.fixture.js
test/integration/fixtures/multiple-runs/multiple-runs-with-flaky-before-each-suite.fixture.js
test/integration/fixtures/multiple-runs/multiple-runs-with-flaky-before-each.fixture.js
test/integration/fixtures/multiple-runs/run-thrice-helper.js
test/integration/fixtures/multiple-runs/run-thrice.fixture.js
test/integration/fixtures/multiple-runs/start-second-run-if-previous-is-still-running-suite.fixture.js
test/integration/fixtures/multiple-runs/start-second-run-if-previous-is-still-running.fixture.js
test/integration/fixtures/no-diff.fixture.js
test/integration/fixtures/options/allow-uncaught/propagate.fixture.js
test/integration/fixtures/options/allow-uncaught/this-skip-it.fixture.js
test/integration/fixtures/options/async-only-async.fixture.js
test/integration/fixtures/options/async-only-sync.fixture.js
test/integration/fixtures/options/bail-async.fixture.js
test/integration/fixtures/options/bail-with-after.fixture.js
test/integration/fixtures/options/bail-with-afterEach.fixture.js
test/integration/fixtures/options/bail-with-before.fixture.js
test/integration/fixtures/options/bail-with-beforeEach.fixture.js
test/integration/fixtures/options/bail-with-test.fixture.js
test/integration/fixtures/options/bail.fixture.js
test/integration/fixtures/options/delay-fail.fixture.js
test/integration/fixtures/options/delay-only.fixture.js
test/integration/fixtures/options/delay.fixture.js
test/integration/fixtures/options/extension/test1.fixture.js
test/integration/fixtures/options/extension/test2.fixture.coffee
test/integration/fixtures/options/file-alpha.fixture.js
test/integration/fixtures/options/file-beta.fixture.js
test/integration/fixtures/options/file-theta.fixture.js
test/integration/fixtures/options/forbid-only/only-before-each.fixture.js
test/integration/fixtures/options/forbid-only/only-before.fixture.js
test/integration/fixtures/options/forbid-only/only-empty-suite.fixture.js
test/integration/fixtures/options/forbid-only/only-suite.fixture.js
test/integration/fixtures/options/forbid-only/only.fixture.js
test/integration/fixtures/options/forbid-only/passed.fixture.js
test/integration/fixtures/options/forbid-pending/before-this-skip.fixture.js
test/integration/fixtures/options/forbid-pending/beforeEach-this-skip.fixture.js
test/integration/fixtures/options/forbid-pending/passed.fixture.js
test/integration/fixtures/options/forbid-pending/pending.fixture.js
test/integration/fixtures/options/forbid-pending/skip-empty-suite.fixture.js
test/integration/fixtures/options/forbid-pending/skip-suite.fixture.js
test/integration/fixtures/options/forbid-pending/skip.fixture.js
test/integration/fixtures/options/forbid-pending/this-skip.fixture.js
test/integration/fixtures/options/grep.fixture.js
test/integration/fixtures/options/ignore/fail.fixture.js
test/integration/fixtures/options/ignore/nested/fail.fixture.js
test/integration/fixtures/options/ignore/nested/pass.fixture.js
test/integration/fixtures/options/ignore/pass.fixture.js
test/integration/fixtures/options/jobs/fail-in-parallel.fixture.js
test/integration/fixtures/options/only/bdd.fixture.js
test/integration/fixtures/options/only/qunit.fixture.js
test/integration/fixtures/options/only/tdd.fixture.js
test/integration/fixtures/options/parallel/bail.fixture.js
test/integration/fixtures/options/parallel/exclusive-test-a.fixture.js
test/integration/fixtures/options/parallel/exclusive-test-b.fixture.js
test/integration/fixtures/options/parallel/retries-a.fixture.js
test/integration/fixtures/options/parallel/retries-b.fixture.js
test/integration/fixtures/options/parallel/syntax-err.fixture.js
test/integration/fixtures/options/parallel/test-a.fixture.js
test/integration/fixtures/options/parallel/test-b.fixture.js
test/integration/fixtures/options/parallel/test-c.fixture.js
test/integration/fixtures/options/parallel/test-d.fixture.js
test/integration/fixtures/options/parallel/uncaught.fixture.js
test/integration/fixtures/options/reporter-with-options.fixture.js
test/integration/fixtures/options/retries.fixture.js
test/integration/fixtures/options/slow-test.fixture.js
test/integration/fixtures/options/sort-alpha.fixture.js
test/integration/fixtures/options/sort-beta.fixture.js
test/integration/fixtures/options/watch/dependency.fixture.js
test/integration/fixtures/options/watch/hook.fixture.js
test/integration/fixtures/options/watch/test-file-change.fixture.js
test/integration/fixtures/options/watch/test-with-dependency.fixture.js
test/integration/fixtures/parallel/test1.mjs
test/integration/fixtures/parallel/test2.mjs
test/integration/fixtures/parallel/test3.mjs
test/integration/fixtures/passing-async.fixture.js
test/integration/fixtures/passing-sync.fixture.js
test/integration/fixtures/passing.fixture.js
test/integration/fixtures/pending/programmatic.fixture.js
test/integration/fixtures/pending/skip-async-before-hooks.fixture.js
test/integration/fixtures/pending/skip-async-before-nested.fixture.js
test/integration/fixtures/pending/skip-async-before.fixture.js
test/integration/fixtures/pending/skip-async-beforeEach.fixture.js
test/integration/fixtures/pending/skip-async-spec.fixture.js
test/integration/fixtures/pending/skip-hierarchy.fixture.js
test/integration/fixtures/pending/skip-shorthand.fixture.js
test/integration/fixtures/pending/skip-sync-after.fixture.js
test/integration/fixtures/pending/skip-sync-before-hooks.fixture.js
test/integration/fixtures/pending/skip-sync-before-inner.fixture.js
test/integration/fixtures/pending/skip-sync-before-nested.fixture.js
test/integration/fixtures/pending/skip-sync-before.fixture.js
test/integration/fixtures/pending/skip-sync-beforeEach-cond.fixture.js
test/integration/fixtures/pending/skip-sync-beforeEach.fixture.js
test/integration/fixtures/pending/skip-sync-spec.fixture.js
test/integration/fixtures/pending/spec.fixture.js
test/integration/fixtures/plugins/global-fixtures/global-setup-teardown-multiple.fixture.js
test/integration/fixtures/plugins/global-fixtures/global-setup-teardown.fixture.js
test/integration/fixtures/plugins/global-fixtures/global-setup.fixture.js
test/integration/fixtures/plugins/global-fixtures/global-teardown.fixture.js
test/integration/fixtures/plugins/root-hooks/esm/package.json
test/integration/fixtures/plugins/root-hooks/esm/root-hook-defs-esm.fixture.js
test/integration/fixtures/plugins/root-hooks/root-hook-defs-a.fixture.js
test/integration/fixtures/plugins/root-hooks/root-hook-defs-b.fixture.js
test/integration/fixtures/plugins/root-hooks/root-hook-defs-c.fixture.js
test/integration/fixtures/plugins/root-hooks/root-hook-defs-d.fixture.js
test/integration/fixtures/plugins/root-hooks/root-hook-defs-esm-broken.fixture.js
test/integration/fixtures/plugins/root-hooks/root-hook-defs-esm.fixture.mjs
test/integration/fixtures/plugins/root-hooks/root-hook-test-2.fixture.js
test/integration/fixtures/plugins/root-hooks/root-hook-test.fixture.js
test/integration/fixtures/regression/issue-1991.fixture.js
test/integration/fixtures/regression/issue-2315.fixture.js
test/integration/fixtures/regression/issue-2406.fixture.js
test/integration/fixtures/regression/issue-2417.fixture.js
test/integration/fixtures/reporters.fixture.js
test/integration/fixtures/retries/async.fixture.js
test/integration/fixtures/retries/early-pass.fixture.js
test/integration/fixtures/retries/hooks.fixture.js
test/integration/fixtures/retries/nested.fixture.js
test/integration/fixtures/runner/events-bail-retries.fixture.js
test/integration/fixtures/runner/events-bail.fixture.js
test/integration/fixtures/runner/events-basic.fixture.js
test/integration/fixtures/runner/events-delay.fixture.js
test/integration/fixtures/runner/events-retries.fixture.js
test/integration/fixtures/simple-reporter.js
test/integration/fixtures/simple-ui.fixture.js
test/integration/fixtures/suite/suite-no-callback.fixture.js
test/integration/fixtures/suite/suite-returning-value.fixture.js
test/integration/fixtures/suite/suite-skipped-callback.fixture.js
test/integration/fixtures/suite/suite-skipped-no-callback.fixture.js
test/integration/fixtures/test-for-simple-ui.fixture.js
test/integration/fixtures/timeout-override.fixture.js
test/integration/fixtures/timeout.fixture.js
test/integration/fixtures/uncaught/after-runner.fixture.js
test/integration/fixtures/uncaught/double.fixture.js
test/integration/fixtures/uncaught/fatal.fixture.js
test/integration/fixtures/uncaught/hook.fixture.js
test/integration/fixtures/uncaught/issue-1327.fixture.js
test/integration/fixtures/uncaught/issue-1417.fixture.js
test/integration/fixtures/uncaught/listeners.fixture.js
test/integration/fixtures/uncaught/pending.fixture.js
test/integration/fixtures/uncaught/recover.fixture.js
test/integration/fixtures/uncaught/unhandled.fixture.js
test/integration/glob.spec.js
test/integration/helpers.js
test/integration/hook-err.spec.js
test/integration/hooks.spec.js
test/integration/init.spec.js
test/integration/invalid-arguments.spec.js
test/integration/multiple-done.spec.js
test/integration/multiple-runs.spec.js
test/integration/no-diff.spec.js
test/integration/only.spec.js
test/integration/options/allowUncaught.spec.js
test/integration/options/asyncOnly.spec.js
test/integration/options/bail.spec.js
test/integration/options/compilers.spec.js
test/integration/options/delay.spec.js
test/integration/options/exit.spec.js
test/integration/options/extension.spec.js
test/integration/options/file.spec.js
test/integration/options/forbidOnly.spec.js
test/integration/options/forbidPending.spec.js
test/integration/options/grep.spec.js
test/integration/options/ignore.spec.js
test/integration/options/invert.spec.js
test/integration/options/jobs.spec.js
test/integration/options/listInterfaces.spec.js
test/integration/options/listReporters.spec.js
test/integration/options/node-flags.spec.js
test/integration/options/opts.spec.js
test/integration/options/parallel.spec.js
test/integration/options/reporter-option.spec.js
test/integration/options/retries.spec.js
test/integration/options/sort.spec.js
test/integration/options/timeout.spec.js
test/integration/options/ui.spec.js
test/integration/options/watch.spec.js
test/integration/parallel.spec.js
test/integration/pending.spec.js
test/integration/plugins/global-fixtures.spec.js
test/integration/plugins/root-hooks.spec.js
test/integration/regression.spec.js
test/integration/reporters.spec.js
test/integration/retries.spec.js
test/integration/suite.spec.js
test/integration/timeout.spec.js
test/integration/uncaught.spec.js
test/interfaces/bdd.spec.js
test/interfaces/exports.spec.js
test/interfaces/qunit.spec.js
test/interfaces/tdd.spec.js
test/jsapi/index.js
test/node-unit/buffered-worker-pool.spec.js
test/node-unit/cli/config.spec.js
test/node-unit/cli/fixtures/bad-module.fixture.js
test/node-unit/cli/node-flags.spec.js
test/node-unit/cli/options.spec.js
test/node-unit/cli/run-helpers.spec.js
test/node-unit/cli/run.spec.js
test/node-unit/fixtures/dumb-module.fixture.js
test/node-unit/fixtures/dumber-module.fixture.js
test/node-unit/fixtures/wonky-reporter.fixture.js
test/node-unit/mocha.spec.js
test/node-unit/parallel-buffered-runner.spec.js
test/node-unit/reporters/parallel-buffered.spec.js
test/node-unit/serializer.spec.js
test/node-unit/stack-trace-filter.spec.js
test/node-unit/utils.spec.js
test/node-unit/worker.spec.js
test/only/bdd-require.spec.js
test/only/global/bdd.spec.js
test/only/global/qunit.spec.js
test/only/global/tdd.spec.js
test/reporters/base.spec.js
test/reporters/doc.spec.js
test/reporters/dot.spec.js
test/reporters/helpers.js
test/reporters/json-stream.spec.js
test/reporters/json.spec.js
test/reporters/landing.spec.js
test/reporters/list.spec.js
test/reporters/markdown.spec.js
test/reporters/min.spec.js
test/reporters/nyan.spec.js
test/reporters/progress.spec.js
test/reporters/spec.spec.js
test/reporters/tap.spec.js
test/reporters/xunit.spec.js
test/require/a.js
test/require/b.coffee
test/require/c.js
test/require/d.coffee
test/require/require.spec.js
test/setup.js
test/smoke/smoke.spec.js
test/unit/context.spec.js
test/unit/duration.spec.js
test/unit/errors.spec.js
test/unit/globals.spec.js
test/unit/grep.spec.js
test/unit/hook-async.spec.js
test/unit/hook-sync-nested.spec.js
test/unit/hook-sync.spec.js
test/unit/hook-timeout.spec.js
test/unit/hook.spec.js
test/unit/mocha.spec.js
test/unit/overspecified-async.spec.js
test/unit/parse-query.spec.js
test/unit/plugin-loader.spec.js
test/unit/required-tokens.spec.js
test/unit/root.spec.js
test/unit/runnable.spec.js
test/unit/runner.spec.js
test/unit/suite.spec.js
test/unit/test.spec.js
test/unit/throw.spec.js
test/unit/timeout.spec.js
test/unit/utils.spec.js

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,158 @@
{
"stats": {
"suites": 3,
"tests": 6,
"passes": 1,
"pending": 1,
"failures": 4,
"start": "2021-02-24T20:26:09.297Z",
"end": "2021-02-24T20:26:09.309Z",
"duration": 12
},
"tests": [
{
"title": "Timeout test",
"fullTitle": "Timeout test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js",
"duration": 8,
"currentRetry": 0,
"err": {
"stack": "Error: Timeout of 1ms exceeded. For async tests and hooks, ensure \"done()\" is called; if returning a Promise, ensure it resolves. (C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js)\n at listOnTimeout (internal/timers.js:554:17)\n at processTimers (internal/timers.js:497:7)",
"message": "Timeout of 1ms exceeded. For async tests and hooks, ensure \"done()\" is called; if returning a Promise, ensure it resolves. (C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js)",
"code": "ERR_MOCHA_TIMEOUT",
"timeout": 1,
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js"
}
},
{
"title": "Skipped test",
"fullTitle": "Skipped test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js",
"currentRetry": 0,
"err": {}
},
{
"title": "Passing test",
"fullTitle": "Test 1 Passing test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\main.test.js",
"duration": 0,
"currentRetry": 0,
"speed": "fast",
"err": {}
},
{
"title": "Failing test",
"fullTitle": "Test 1 Test 1.1 Failing test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\main.test.js",
"duration": 1,
"currentRetry": 0,
"err": {
"stack": "AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:\n\nfalse !== true\n\n at Context.<anonymous> (test\\main.test.js:11:14)\n at processImmediate (internal/timers.js:461:21)",
"message": "Expected values to be strictly equal:\n\nfalse !== true\n",
"generatedMessage": true,
"name": "AssertionError",
"code": "ERR_ASSERTION",
"actual": "false",
"expected": "true",
"operator": "strictEqual"
}
},
{
"title": "Exception in target unit",
"fullTitle": "Test 1 Test 1.1 Exception in target unit",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\main.test.js",
"duration": 0,
"currentRetry": 0,
"err": {
"stack": "Error: Some error\n at Object.throwError (lib\\main.js:2:9)\n at Context.<anonymous> (test\\main.test.js:15:11)\n at processImmediate (internal/timers.js:461:21)",
"message": "Some error"
}
},
{
"title": "Exception in test",
"fullTitle": "Test 2 Exception in test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\main.test.js",
"duration": 0,
"currentRetry": 0,
"err": {
"stack": "Error: Some error\n at Context.<anonymous> (test\\main.test.js:22:11)\n at processImmediate (internal/timers.js:461:21)",
"message": "Some error"
}
}
],
"pending": [
{
"title": "Skipped test",
"fullTitle": "Skipped test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js",
"currentRetry": 0,
"err": {}
}
],
"failures": [
{
"title": "Timeout test",
"fullTitle": "Timeout test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js",
"duration": 8,
"currentRetry": 0,
"err": {
"stack": "Error: Timeout of 1ms exceeded. For async tests and hooks, ensure \"done()\" is called; if returning a Promise, ensure it resolves. (C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js)\n at listOnTimeout (internal/timers.js:554:17)\n at processTimers (internal/timers.js:497:7)",
"message": "Timeout of 1ms exceeded. For async tests and hooks, ensure \"done()\" is called; if returning a Promise, ensure it resolves. (C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js)",
"code": "ERR_MOCHA_TIMEOUT",
"timeout": 1,
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\second.test.js"
}
},
{
"title": "Failing test",
"fullTitle": "Test 1 Test 1.1 Failing test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\main.test.js",
"duration": 1,
"currentRetry": 0,
"err": {
"stack": "AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:\n\nfalse !== true\n\n at Context.<anonymous> (test\\main.test.js:11:14)\n at processImmediate (internal/timers.js:461:21)",
"message": "Expected values to be strictly equal:\n\nfalse !== true\n",
"generatedMessage": true,
"name": "AssertionError",
"code": "ERR_ASSERTION",
"actual": "false",
"expected": "true",
"operator": "strictEqual"
}
},
{
"title": "Exception in target unit",
"fullTitle": "Test 1 Test 1.1 Exception in target unit",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\main.test.js",
"duration": 0,
"currentRetry": 0,
"err": {
"stack": "Error: Some error\n at Object.throwError (lib\\main.js:2:9)\n at Context.<anonymous> (test\\main.test.js:15:11)\n at processImmediate (internal/timers.js:461:21)",
"message": "Some error"
}
},
{
"title": "Exception in test",
"fullTitle": "Test 2 Exception in test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\main.test.js",
"duration": 0,
"currentRetry": 0,
"err": {
"stack": "Error: Some error\n at Context.<anonymous> (test\\main.test.js:22:11)\n at processImmediate (internal/timers.js:461:21)",
"message": "Some error"
}
}
],
"passes": [
{
"title": "Passing test",
"fullTitle": "Test 1 Passing test",
"file": "C:\\Users\\Michal\\Workspace\\dorny\\test-reporter\\reports\\mocha\\test\\main.test.js",
"duration": 0,
"currentRetry": 0,
"speed": "fast",
"err": {}
}
]
}

View File

@@ -0,0 +1,67 @@
import * as fs from 'fs'
import * as path from 'path'
import {MochaJsonParser} from '../src/parsers/mocha-json/mocha-json-parser'
import {ParseOptions} from '../src/test-parser'
import {getReport} from '../src/report/get-report'
import {normalizeFilePath} from '../src/utils/path-utils'
describe('mocha-json tests', () => {
it('produces empty test run result when there are no test cases', async () => {
const fixturePath = path.join(__dirname, 'fixtures', 'empty', 'mocha-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 MochaJsonParser(opts)
const result = await parser.parse(filePath, fileContent)
expect(result.tests).toBe(0)
expect(result.result).toBe('success')
})
it('report from ./reports/mocha-json test results matches snapshot', async () => {
const fixturePath = path.join(__dirname, 'fixtures', 'mocha-json.json')
const outputPath = path.join(__dirname, '__outputs__', 'mocha-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 MochaJsonParser(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)
})
it('report from mochajs/mocha test results matches snapshot', async () => {
const fixturePath = path.join(__dirname, 'fixtures', 'external', 'mocha', 'mocha-test-results.json')
const trackedFilesPath = path.join(__dirname, 'fixtures', 'external', 'mocha', 'files.txt')
const outputPath = path.join(__dirname, '__outputs__', 'mocha-test-results.md')
const filePath = normalizeFilePath(path.relative(__dirname, fixturePath))
const fileContent = fs.readFileSync(fixturePath, {encoding: 'utf8'})
const trackedFiles = fs.readFileSync(trackedFilesPath, {encoding: 'utf8'}).split(/\n\r?/g)
const opts: ParseOptions = {
parseErrors: true,
trackedFiles
}
const parser = new MochaJsonParser(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)
})
})

View File

@@ -0,0 +1,37 @@
import {parseNetDuration} from '../../src/utils/parse-utils'
describe('parseNetDuration', () => {
it('returns 0 for 00:00:00', () => {
const ms = parseNetDuration('00:00:00')
expect(ms).toBe(0)
})
it('returns 0 for 00:00:00.0000000', () => {
const ms = parseNetDuration('00:00:00.0000000')
expect(ms).toBe(0)
})
it('returns 123 for 00:00:00.123', () => {
const ms = parseNetDuration('00:00:00.123')
expect(ms).toBe(123)
})
it('returns 12 * 1000 for 00:00:12', () => {
const ms = parseNetDuration('00:00:12')
expect(ms).toBe(12 * 1000)
})
it('returns 12 * 60 * 1000 for 00:12:00', () => {
const ms = parseNetDuration('00:12:00')
expect(ms).toBe(12 * 60 * 1000)
})
it('returns 12 * 60 * 60 * 1000 for 12:00:00', () => {
const ms = parseNetDuration('12:00:00')
expect(ms).toBe(12 * 60 * 60 * 1000)
})
it('throws when string has invalid format', () => {
expect(() => parseNetDuration('12:34:56 not a duration')).toThrowError(/^Invalid format/)
})
})

View File

@@ -1,6 +1,6 @@
name: Test Reporter name: Test Reporter
description: | description: |
Displays test results directly in GitHub. Supports .NET (xUnit, NUnit, MSTest), Dart, Flutter and JavaScript (JEST). Shows test results in GitHub UI: .NET (xUnit, NUnit, MSTest), Dart, Flutter, Java (JUnit), JavaScript (JEST, Mocha)
author: Michal Dorner <dorner.michal@gmail.com> author: Michal Dorner <dorner.michal@gmail.com>
inputs: inputs:
artifact: artifact:
@@ -23,6 +23,7 @@ inputs:
- flutter-json - flutter-json
- java-junit - java-junit
- jest-junit - jest-junit
- mocha-json
required: true required: true
list-suites: list-suites:
description: | description: |

BIN
assets/mocha-groups.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

373
dist/index.js generated vendored
View File

@@ -221,6 +221,7 @@ const dart_json_parser_1 = __nccwpck_require__(4528);
const dotnet_trx_parser_1 = __nccwpck_require__(2664); const dotnet_trx_parser_1 = __nccwpck_require__(2664);
const java_junit_parser_1 = __nccwpck_require__(676); const java_junit_parser_1 = __nccwpck_require__(676);
const jest_junit_parser_1 = __nccwpck_require__(1113); const jest_junit_parser_1 = __nccwpck_require__(1113);
const mocha_json_parser_1 = __nccwpck_require__(6043);
const path_utils_1 = __nccwpck_require__(4070); const path_utils_1 = __nccwpck_require__(4070);
const github_utils_1 = __nccwpck_require__(3522); const github_utils_1 = __nccwpck_require__(3522);
const markdown_utils_1 = __nccwpck_require__(6482); const markdown_utils_1 = __nccwpck_require__(6482);
@@ -324,18 +325,29 @@ class TestReporter {
const tr = await parser.parse(file, content); const tr = await parser.parse(file, content);
results.push(tr); results.push(tr);
} }
core.info(`Creating check run ${name}`);
const createResp = await this.octokit.checks.create({
head_sha: this.context.sha,
name,
status: 'in_progress',
output: {
title: name,
summary: ''
},
...github.context.repo
});
core.info('Creating report summary'); core.info('Creating report summary');
const { listSuites, listTests } = this; const { listSuites, listTests } = this;
const summary = get_report_1.getReport(results, { listSuites, listTests }); const baseUrl = createResp.data.html_url;
const summary = get_report_1.getReport(results, { listSuites, listTests, baseUrl });
core.info('Creating annotations'); core.info('Creating annotations');
const annotations = get_annotations_1.getAnnotations(results, this.maxAnnotations); const annotations = get_annotations_1.getAnnotations(results, this.maxAnnotations);
const isFailed = results.some(tr => tr.result === 'failed'); const isFailed = results.some(tr => tr.result === 'failed');
const conclusion = isFailed ? 'failure' : 'success'; const conclusion = isFailed ? 'failure' : 'success';
const icon = isFailed ? markdown_utils_1.Icon.fail : markdown_utils_1.Icon.success; const icon = isFailed ? markdown_utils_1.Icon.fail : markdown_utils_1.Icon.success;
core.info(`Creating check run with conclusion ${conclusion}`); core.info(`Updating check run conclusion (${conclusion}) and output`);
const resp = await this.octokit.checks.create({ const resp = await this.octokit.checks.update({
head_sha: this.context.sha, check_run_id: createResp.data.id,
name,
conclusion, conclusion,
status: 'completed', status: 'completed',
output: { output: {
@@ -362,6 +374,8 @@ class TestReporter {
return new java_junit_parser_1.JavaJunitParser(options); return new java_junit_parser_1.JavaJunitParser(options);
case 'jest-junit': case 'jest-junit':
return new jest_junit_parser_1.JestJunitParser(options); return new jest_junit_parser_1.JestJunitParser(options);
case 'mocha-json':
return new mocha_json_parser_1.MochaJsonParser(options);
default: default:
throw new Error(`Input variable 'reporter' is set to invalid value '${reporter}'`); throw new Error(`Input variable 'reporter' is set to invalid value '${reporter}'`);
} }
@@ -498,7 +512,10 @@ class DartJsonParser {
group.tests.sort((a, b) => { var _a, _b; return ((_a = a.testStart.test.line) !== null && _a !== void 0 ? _a : 0) - ((_b = b.testStart.test.line) !== null && _b !== void 0 ? _b : 0); }); group.tests.sort((a, b) => { var _a, _b; return ((_a = a.testStart.test.line) !== null && _a !== void 0 ? _a : 0) - ((_b = b.testStart.test.line) !== null && _b !== void 0 ? _b : 0); });
const tests = group.tests.map(tc => { const tests = group.tests.map(tc => {
const error = this.getError(suite, tc); const error = this.getError(suite, tc);
return new test_results_1.TestCaseResult(tc.testStart.test.name, tc.result, tc.time, error); const testName = group.group.name !== undefined && tc.testStart.test.name.startsWith(group.group.name)
? tc.testStart.test.name.slice(group.group.name.length).trim()
: tc.testStart.test.name.trim();
return new test_results_1.TestCaseResult(testName, tc.result, tc.time, error);
}); });
return new test_results_1.TestGroupResult(group.group.name, tests); return new test_results_1.TestGroupResult(group.group.name, tests);
}); });
@@ -509,14 +526,14 @@ class DartJsonParser {
return undefined; return undefined;
} }
const { trackedFiles } = this.options; const { trackedFiles } = this.options;
const message = (_b = (_a = test.error) === null || _a === void 0 ? void 0 : _a.error) !== null && _b !== void 0 ? _b : ''; const stackTrace = (_b = (_a = test.error) === null || _a === void 0 ? void 0 : _a.stackTrace) !== null && _b !== void 0 ? _b : '';
const stackTrace = (_d = (_c = test.error) === null || _c === void 0 ? void 0 : _c.stackTrace) !== null && _d !== void 0 ? _d : '';
const print = test.print const print = test.print
.filter(p => p.messageType === 'print') .filter(p => p.messageType === 'print')
.map(p => p.message) .map(p => p.message)
.join('\n'); .join('\n');
const details = [print, stackTrace].filter(str => str !== '').join('\n'); const details = [print, stackTrace].filter(str => str !== '').join('\n');
const src = this.exceptionThrowSource(details, trackedFiles); const src = this.exceptionThrowSource(details, trackedFiles);
const message = this.getErrorMessage((_d = (_c = test.error) === null || _c === void 0 ? void 0 : _c.error) !== null && _d !== void 0 ? _d : '', print);
let path; let path;
let line; let line;
if (src !== undefined) { if (src !== undefined) {
@@ -537,6 +554,19 @@ class DartJsonParser {
details details
}; };
} }
getErrorMessage(message, print) {
if (this.sdk === 'flutter') {
const uselessMessageRe = /^Test failed\. See exception logs above\.\nThe test description was:/m;
const flutterPrintRe = /^ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK +\s+(.*)\s+When the exception was thrown, this was the stack:/ms;
if (uselessMessageRe.test(message)) {
const match = print.match(flutterPrintRe);
if (match !== null) {
return match[1];
}
}
}
return message || print;
}
exceptionThrowSource(ex, trackedFiles) { exceptionThrowSource(ex, trackedFiles) {
const lines = ex.split(/\r?\n/g); const lines = ex.split(/\r?\n/g);
// regexp to extract file path and line number from stack trace // regexp to extract file path and line number from stack trace
@@ -660,6 +690,7 @@ class DotnetTrxParser {
const trx = await this.getTrxReport(path, content); const trx = await this.getTrxReport(path, content);
const tc = this.getTestClasses(trx); const tc = this.getTestClasses(trx);
const tr = this.getTestRunResult(path, trx, tc); const tr = this.getTestRunResult(path, trx, tc);
tr.sort(true);
return tr; return tr;
} }
async getTrxReport(path, content) { async getTrxReport(path, content) {
@@ -694,15 +725,12 @@ class DotnetTrxParser {
} }
const output = r.unitTestResult.Output; const output = r.unitTestResult.Output;
const error = (output === null || output === void 0 ? void 0 : output.length) > 0 && ((_a = output[0].ErrorInfo) === null || _a === void 0 ? void 0 : _a.length) > 0 ? output[0].ErrorInfo[0] : undefined; const error = (output === null || output === void 0 ? void 0 : output.length) > 0 && ((_a = output[0].ErrorInfo) === null || _a === void 0 ? void 0 : _a.length) > 0 ? output[0].ErrorInfo[0] : undefined;
const duration = parse_utils_1.parseNetDuration(r.unitTestResult.$.duration); const durationAttr = r.unitTestResult.$.duration;
const duration = durationAttr ? parse_utils_1.parseNetDuration(durationAttr) : 0;
const test = new Test(r.testMethod.$.name, r.unitTestResult.$.outcome, duration, error); const test = new Test(r.testMethod.$.name, r.unitTestResult.$.outcome, duration, error);
tc.tests.push(test); tc.tests.push(test);
} }
const result = Object.values(testClasses); const result = Object.values(testClasses);
result.sort((a, b) => a.name.localeCompare(b.name));
for (const tc of result) {
tc.tests.sort((a, b) => a.name.localeCompare(b.name));
}
return result; return result;
} }
getTestRunResult(path, trx, testClasses) { getTestRunResult(path, trx, testClasses) {
@@ -976,6 +1004,7 @@ exports.JavaJunitParser = JavaJunitParser;
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.JestJunitParser = void 0; exports.JestJunitParser = void 0;
const xml2js_1 = __nccwpck_require__(6189); const xml2js_1 = __nccwpck_require__(6189);
const node_utils_1 = __nccwpck_require__(5824);
const path_utils_1 = __nccwpck_require__(4070); const path_utils_1 = __nccwpck_require__(4070);
const test_results_1 = __nccwpck_require__(2768); const test_results_1 = __nccwpck_require__(2768);
class JestJunitParser { class JestJunitParser {
@@ -1041,7 +1070,7 @@ class JestJunitParser {
const details = tc.failure[0]; const details = tc.failure[0];
let path; let path;
let line; let line;
const src = this.exceptionThrowSource(details); const src = node_utils_1.getExceptionSource(details, this.options.trackedFiles, file => this.getRelativePath(file));
if (src) { if (src) {
path = src.path; path = src.path;
line = src.line; line = src.line;
@@ -1052,29 +1081,13 @@ class JestJunitParser {
details details
}; };
} }
exceptionThrowSource(stackTrace) { getRelativePath(path) {
const lines = stackTrace.split(/\r?\n/); path = path_utils_1.normalizeFilePath(path);
const re = /\((.*):(\d+):\d+\)$/; const workDir = this.getWorkDir(path);
const { trackedFiles } = this.options; if (workDir !== undefined && path.startsWith(workDir)) {
for (const str of lines) { path = path.substr(workDir.length);
const match = str.match(re);
if (match !== null) {
const [_, fileStr, lineStr] = match;
const filePath = path_utils_1.normalizeFilePath(fileStr);
if (filePath.startsWith('internal/') || filePath.includes('/node_modules/')) {
continue;
}
const workDir = this.getWorkDir(filePath);
if (!workDir) {
continue;
}
const path = filePath.substr(workDir.length);
if (trackedFiles.includes(path)) {
const line = parseInt(lineStr);
return { path, line };
}
}
} }
return path;
} }
getWorkDir(path) { getWorkDir(path) {
var _a, _b; var _a, _b;
@@ -1084,6 +1097,108 @@ class JestJunitParser {
exports.JestJunitParser = JestJunitParser; exports.JestJunitParser = JestJunitParser;
/***/ }),
/***/ 6043:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MochaJsonParser = void 0;
const test_results_1 = __nccwpck_require__(2768);
const node_utils_1 = __nccwpck_require__(5824);
const path_utils_1 = __nccwpck_require__(4070);
class MochaJsonParser {
constructor(options) {
this.options = options;
}
async parse(path, content) {
const mocha = this.getMochaJson(path, content);
const result = this.getTestRunResult(path, mocha);
result.sort(true);
return Promise.resolve(result);
}
getMochaJson(path, content) {
try {
return JSON.parse(content);
}
catch (e) {
throw new Error(`Invalid JSON at ${path}\n\n${e}`);
}
}
getTestRunResult(resultsPath, mocha) {
const suitesMap = {};
const getSuite = (test) => {
var _a;
const path = this.getRelativePath(test.file);
return (_a = suitesMap[path]) !== null && _a !== void 0 ? _a : (suitesMap[path] = new test_results_1.TestSuiteResult(path, []));
};
for (const test of mocha.passes) {
const suite = getSuite(test);
this.processTest(suite, test, 'success');
}
for (const test of mocha.failures) {
const suite = getSuite(test);
this.processTest(suite, test, 'failed');
}
for (const test of mocha.pending) {
const suite = getSuite(test);
this.processTest(suite, test, 'skipped');
}
const suites = Object.values(suitesMap);
return new test_results_1.TestRunResult(resultsPath, suites, mocha.stats.duration);
}
processTest(suite, test, result) {
var _a;
const groupName = test.fullTitle !== test.title
? test.fullTitle.substr(0, test.fullTitle.length - test.title.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.title, result, (_a = test.duration) !== null && _a !== void 0 ? _a : 0, error);
group.tests.push(testCase);
}
getTestCaseError(test) {
const details = test.err.stack;
const message = test.err.message;
if (details === undefined) {
return undefined;
}
let path;
let line;
const src = node_utils_1.getExceptionSource(details, this.options.trackedFiles, file => this.getRelativePath(file));
if (src) {
path = src.path;
line = src.line;
}
return {
path,
line,
message,
details
};
}
getRelativePath(path) {
path = path_utils_1.normalizeFilePath(path);
const workDir = this.getWorkDir(path);
if (workDir !== undefined && path.startsWith(workDir)) {
path = path.substr(workDir.length);
}
return path;
}
getWorkDir(path) {
var _a, _b;
return ((_b = (_a = this.options.workDir) !== null && _a !== void 0 ? _a : this.assumedWorkDir) !== null && _b !== void 0 ? _b : (this.assumedWorkDir = path_utils_1.getBasePath(path, this.options.trackedFiles)));
}
}
exports.MochaJsonParser = MochaJsonParser;
/***/ }), /***/ }),
/***/ 5867: /***/ 5867:
@@ -1094,6 +1209,7 @@ exports.JestJunitParser = JestJunitParser;
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getAnnotations = void 0; exports.getAnnotations = void 0;
const markdown_utils_1 = __nccwpck_require__(6482); const markdown_utils_1 = __nccwpck_require__(6482);
const parse_utils_1 = __nccwpck_require__(7811);
function getAnnotations(results, maxCount) { function getAnnotations(results, maxCount) {
var _a, _b, _c, _d; var _a, _b, _c, _d;
if (maxCount === 0) { if (maxCount === 0) {
@@ -1123,9 +1239,9 @@ function getAnnotations(results, maxCount) {
errors.push({ errors.push({
testRunPaths: [tr.path], testRunPaths: [tr.path],
suiteName: ts.name, suiteName: ts.name,
testName: tc.name, testName: tg.name ? `${tg.name}${tc.name}` : tc.name,
details: err.details, details: err.details,
message: (_d = (_c = err.message) !== null && _c !== void 0 ? _c : getFirstNonEmptyLine(err.details)) !== null && _d !== void 0 ? _d : 'Test failed', message: (_d = (_c = err.message) !== null && _c !== void 0 ? _c : parse_utils_1.getFirstNonEmptyLine(err.details)) !== null && _d !== void 0 ? _d : 'Test failed',
path, path,
line line
}); });
@@ -1163,10 +1279,6 @@ function enforceCheckRunLimits(err) {
} }
return err; return err;
} }
function getFirstNonEmptyLine(stackTrace) {
const lines = stackTrace.split(/\r?\n/g);
return lines.find(str => !/^\s*$/.test(str));
}
function ident(text, prefix) { function ident(text, prefix) {
return text return text
.split(/\n/g) .split(/\n/g)
@@ -1205,50 +1317,62 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getReport = void 0; exports.getReport = void 0;
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const markdown_utils_1 = __nccwpck_require__(6482); const markdown_utils_1 = __nccwpck_require__(6482);
const parse_utils_1 = __nccwpck_require__(7811);
const slugger_1 = __nccwpck_require__(3328); const slugger_1 = __nccwpck_require__(3328);
const MAX_REPORT_LENGTH = 65535;
const defaultOptions = { const defaultOptions = {
listSuites: 'all', listSuites: 'all',
listTests: 'all' listTests: 'all',
baseUrl: ''
}; };
function getReport(results, options = defaultOptions) { function getReport(results, options = defaultOptions) {
core.info('Generating check run summary'); core.info('Generating check run summary');
const maxReportLength = 65535;
applySort(results); applySort(results);
const opts = { ...options }; const opts = { ...options };
let report = renderReport(results, opts); let lines = renderReport(results, opts);
if (getByteLength(report) <= maxReportLength) { let report = lines.join('\n');
if (getByteLength(report) <= MAX_REPORT_LENGTH) {
return report; return report;
} }
if (opts.listTests === 'all') { if (opts.listTests === 'all') {
core.info("Test report summary is too big - setting 'listTests' to 'failed'"); core.info("Test report summary is too big - setting 'listTests' to 'failed'");
opts.listTests = 'failed'; opts.listTests = 'failed';
report = renderReport(results, opts); lines = renderReport(results, opts);
if (getByteLength(report) <= maxReportLength) { report = lines.join('\n');
if (getByteLength(report) <= MAX_REPORT_LENGTH) {
return report; return report;
} }
} }
if (opts.listSuites === 'all') { core.warning(`Test report summary exceeded limit of ${MAX_REPORT_LENGTH} bytes and will be trimmed`);
core.info("Test report summary is too big - setting 'listSuites' to 'failed'"); return trimReport(lines);
opts.listSuites = 'failed';
report = renderReport(results, opts);
if (getByteLength(report) <= maxReportLength) {
return report;
}
}
if (opts.listTests !== 'none') {
core.info("Test report summary is too big - setting 'listTests' to 'none'");
opts.listTests = 'none';
report = renderReport(results, opts);
if (getByteLength(report) <= maxReportLength) {
return report;
}
}
core.warning(`Test report summary exceeded limit of ${maxReportLength} bytes`);
const badge = getReportBadge(results);
const msg = `**Test report summary exceeded limit of ${maxReportLength} bytes and was removed**`;
return `${badge}\n${msg}`;
} }
exports.getReport = getReport; exports.getReport = getReport;
function trimReport(lines) {
const closingBlock = '```';
const errorMsg = `**Report exceeded GitHub limit of ${MAX_REPORT_LENGTH} bytes and has been trimmed**`;
const maxErrorMsgLength = closingBlock.length + errorMsg.length + 2;
const maxReportLength = MAX_REPORT_LENGTH - maxErrorMsgLength;
let reportLength = 0;
let codeBlock = false;
let endLineIndex = 0;
for (endLineIndex = 0; endLineIndex < lines.length; endLineIndex++) {
const line = lines[endLineIndex];
const lineLength = getByteLength(line);
reportLength += lineLength + 1;
if (reportLength > maxReportLength) {
break;
}
if (line === '```') {
codeBlock = !codeBlock;
}
}
const reportLines = lines.slice(0, endLineIndex);
if (codeBlock) {
reportLines.push('```');
}
reportLines.push(errorMsg);
return reportLines.join('\n');
}
function applySort(results) { function applySort(results) {
results.sort((a, b) => a.path.localeCompare(b.path)); results.sort((a, b) => a.path.localeCompare(b.path));
for (const res of results) { for (const res of results) {
@@ -1264,7 +1388,7 @@ function renderReport(results, options) {
sections.push(badge); sections.push(badge);
const runs = getTestRunsReport(results, options); const runs = getTestRunsReport(results, options);
sections.push(...runs); sections.push(...runs);
return sections.join('\n'); return sections;
} }
function getReportBadge(results) { function getReportBadge(results) {
const passed = results.reduce((sum, tr) => sum + tr.passed, 0); const passed = results.reduce((sum, tr) => sum + tr.passed, 0);
@@ -1301,7 +1425,7 @@ function getTestRunsReport(testRuns, options) {
const tableData = testRuns.map((tr, runIndex) => { const tableData = testRuns.map((tr, runIndex) => {
const time = markdown_utils_1.formatTime(tr.time); const time = markdown_utils_1.formatTime(tr.time);
const name = tr.path; const name = tr.path;
const addr = makeRunSlug(runIndex).link; const addr = options.baseUrl + makeRunSlug(runIndex).link;
const nameLink = markdown_utils_1.link(name, addr); const nameLink = markdown_utils_1.link(name, addr);
const passed = tr.passed > 0 ? `${tr.passed}${markdown_utils_1.Icon.success}` : ''; const passed = tr.passed > 0 ? `${tr.passed}${markdown_utils_1.Icon.success}` : '';
const failed = tr.failed > 0 ? `${tr.failed}${markdown_utils_1.Icon.fail}` : ''; const failed = tr.failed > 0 ? `${tr.failed}${markdown_utils_1.Icon.fail}` : '';
@@ -1318,9 +1442,9 @@ function getTestRunsReport(testRuns, options) {
function getSuitesReport(tr, runIndex, options) { function getSuitesReport(tr, runIndex, options) {
const sections = []; const sections = [];
const trSlug = makeRunSlug(runIndex); const trSlug = makeRunSlug(runIndex);
const nameLink = `<a id="${trSlug.id}" href="${trSlug.link}">${tr.path}</a>`; const nameLink = `<a id="${trSlug.id}" href="${options.baseUrl + trSlug.link}">${tr.path}</a>`;
const icon = getResultIcon(tr.result); const icon = getResultIcon(tr.result);
sections.push(`## ${nameLink} ${icon}`); sections.push(`## ${icon}\xa0${nameLink}`);
const time = markdown_utils_1.formatTime(tr.time); const time = markdown_utils_1.formatTime(tr.time);
const headingLine2 = tr.tests > 0 const headingLine2 = tr.tests > 0
? `**${tr.tests}** tests were completed in **${time}** with **${tr.passed}** passed, **${tr.failed}** failed and **${tr.skipped}** skipped.` ? `**${tr.tests}** tests were completed in **${time}** with **${tr.passed}** passed, **${tr.failed}** failed and **${tr.skipped}** skipped.`
@@ -1332,7 +1456,7 @@ function getSuitesReport(tr, runIndex, options) {
const tsTime = markdown_utils_1.formatTime(s.time); const tsTime = markdown_utils_1.formatTime(s.time);
const tsName = s.name; const tsName = s.name;
const skipLink = options.listTests === 'none' || (options.listTests === 'failed' && s.result !== 'failed'); const skipLink = options.listTests === 'none' || (options.listTests === 'failed' && s.result !== 'failed');
const tsAddr = makeSuiteSlug(runIndex, suiteIndex).link; const tsAddr = options.baseUrl + makeSuiteSlug(runIndex, suiteIndex).link;
const tsNameLink = skipLink ? tsName : markdown_utils_1.link(tsName, tsAddr); const tsNameLink = skipLink ? tsName : markdown_utils_1.link(tsName, tsAddr);
const passed = s.passed > 0 ? `${s.passed}${markdown_utils_1.Icon.success}` : ''; const passed = s.passed > 0 ? `${s.passed}${markdown_utils_1.Icon.success}` : '';
const failed = s.failed > 0 ? `${s.failed}${markdown_utils_1.Icon.fail}` : ''; const failed = s.failed > 0 ? `${s.failed}${markdown_utils_1.Icon.fail}` : '';
@@ -1350,33 +1474,38 @@ function getSuitesReport(tr, runIndex, options) {
return sections; return sections;
} }
function getTestsReport(ts, runIndex, suiteIndex, options) { function getTestsReport(ts, runIndex, suiteIndex, options) {
const groups = options.listTests === 'failed' ? ts.failedGroups : ts.groups; var _a, _b, _c;
if (options.listTests === 'failed' && ts.result !== 'failed') {
return [];
}
const groups = ts.groups;
if (groups.length === 0) { if (groups.length === 0) {
return []; return [];
} }
const sections = []; const sections = [];
const tsName = ts.name; const tsName = ts.name;
const tsSlug = makeSuiteSlug(runIndex, suiteIndex); const tsSlug = makeSuiteSlug(runIndex, suiteIndex);
const tsNameLink = `<a id="${tsSlug.id}" href="${tsSlug.link}">${tsName}</a>`; const tsNameLink = `<a id="${tsSlug.id}" href="${options.baseUrl + tsSlug.link}">${tsName}</a>`;
const icon = getResultIcon(ts.result); const icon = getResultIcon(ts.result);
sections.push(`### ${tsNameLink} ${icon}`); sections.push(`### ${icon}\xa0${tsNameLink}`);
const tsTime = markdown_utils_1.formatTime(ts.time); sections.push('```');
const headingLine2 = `**${ts.tests}** tests were completed in **${tsTime}** with **${ts.passed}** passed, **${ts.failed}** failed and **${ts.skipped}** skipped.`;
sections.push(headingLine2);
for (const grp of groups) { for (const grp of groups) {
const tests = options.listTests === 'failed' ? grp.failedTests : grp.tests; if (grp.name) {
if (tests.length === 0) { sections.push(grp.name);
continue;
} }
const grpHeader = grp.name ? `\n**${grp.name}**` : ''; const space = grp.name ? ' ' : '';
const testsTable = markdown_utils_1.table(['Result', 'Test', 'Time'], [markdown_utils_1.Align.Center, markdown_utils_1.Align.Left, markdown_utils_1.Align.Right], ...grp.tests.map(tc => { for (const tc of grp.tests) {
const name = tc.name;
const time = markdown_utils_1.formatTime(tc.time);
const result = getResultIcon(tc.result); const result = getResultIcon(tc.result);
return [result, name, time]; sections.push(`${space}${result} ${tc.name}`);
})); if (tc.error) {
sections.push(grpHeader, testsTable); const lines = (_c = ((_a = tc.error.message) !== null && _a !== void 0 ? _a : (_b = parse_utils_1.getFirstNonEmptyLine(tc.error.details)) === null || _b === void 0 ? void 0 : _b.trim())) === null || _c === void 0 ? void 0 : _c.split(/\r?\n/g).map(l => '\t' + l);
if (lines) {
sections.push(...lines);
}
}
}
} }
sections.push('```');
return sections; return sections;
} }
function makeRunSlug(runIndex) { function makeRunSlug(runIndex) {
@@ -1438,6 +1567,14 @@ class TestRunResult {
get failedSuites() { get failedSuites() {
return this.suites.filter(s => s.result === 'failed'); return this.suites.filter(s => s.result === 'failed');
} }
sort(deep) {
this.suites.sort((a, b) => a.name.localeCompare(b.name));
if (deep) {
for (const suite of this.suites) {
suite.sort(deep);
}
}
}
} }
exports.TestRunResult = TestRunResult; exports.TestRunResult = TestRunResult;
class TestSuiteResult { class TestSuiteResult {
@@ -1468,6 +1605,14 @@ class TestSuiteResult {
get failedGroups() { get failedGroups() {
return this.groups.filter(grp => grp.result === 'failed'); return this.groups.filter(grp => grp.result === 'failed');
} }
sort(deep) {
this.groups.sort((a, b) => { var _a, _b; return ((_a = a.name) !== null && _a !== void 0 ? _a : '').localeCompare((_b = b.name) !== null && _b !== void 0 ? _b : ''); });
if (deep) {
for (const grp of this.groups) {
grp.sort();
}
}
}
} }
exports.TestSuiteResult = TestSuiteResult; exports.TestSuiteResult = TestSuiteResult;
class TestGroupResult { class TestGroupResult {
@@ -1493,6 +1638,9 @@ class TestGroupResult {
get failedTests() { get failedTests() {
return this.tests.filter(tc => tc.result === 'failed'); return this.tests.filter(tc => tc.result === 'failed');
} }
sort() {
this.tests.sort((a, b) => a.name.localeCompare(b.name));
}
} }
exports.TestGroupResult = TestGroupResult; exports.TestGroupResult = TestGroupResult;
class TestCaseResult { class TestCaseResult {
@@ -1782,13 +1930,48 @@ function ellipsis(text, maxLength) {
exports.ellipsis = ellipsis; exports.ellipsis = ellipsis;
function formatTime(ms) { function formatTime(ms) {
if (ms > 1000) { if (ms > 1000) {
return `${(ms / 1000).toFixed(3)}s`; return `${Math.round(ms / 1000)}s`;
} }
return `${Math.round(ms)}ms`; return `${Math.round(ms)}ms`;
} }
exports.formatTime = formatTime; exports.formatTime = formatTime;
/***/ }),
/***/ 5824:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getExceptionSource = void 0;
const path_utils_1 = __nccwpck_require__(4070);
function getExceptionSource(stackTrace, trackedFiles, getRelativePath) {
const lines = stackTrace.split(/\r?\n/);
const re = /\((.*):(\d+):\d+\)$/;
for (const str of lines) {
const match = str.match(re);
if (match !== null) {
const [_, fileStr, lineStr] = match;
const filePath = path_utils_1.normalizeFilePath(fileStr);
if (filePath.startsWith('internal/') || filePath.includes('/node_modules/')) {
continue;
}
const path = getRelativePath(filePath);
if (!path) {
continue;
}
if (trackedFiles.includes(path)) {
const line = parseInt(lineStr);
return { path, line };
}
}
}
}
exports.getExceptionSource = getExceptionSource;
/***/ }), /***/ }),
/***/ 7811: /***/ 7811:
@@ -1797,10 +1980,9 @@ exports.formatTime = formatTime;
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseIsoDate = exports.parseNetDuration = void 0; exports.getFirstNonEmptyLine = exports.parseIsoDate = exports.parseNetDuration = void 0;
function parseNetDuration(str) { function parseNetDuration(str) {
// matches dotnet duration: 00:00:00.0010000 const durationRe = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)$/;
const durationRe = /^(\d\d):(\d\d):(\d\d\.\d+)$/;
const durationMatch = str.match(durationRe); const durationMatch = str.match(durationRe);
if (durationMatch === null) { if (durationMatch === null) {
throw new Error(`Invalid format: "${str}" is not NET duration`); throw new Error(`Invalid format: "${str}" is not NET duration`);
@@ -1817,6 +1999,11 @@ function parseIsoDate(str) {
return new Date(str); return new Date(str);
} }
exports.parseIsoDate = parseIsoDate; exports.parseIsoDate = parseIsoDate;
function getFirstNonEmptyLine(stackTrace) {
const lines = stackTrace.split(/\r?\n/g);
return lines.find(str => !/^\s*$/.test(str));
}
exports.getFirstNonEmptyLine = getFirstNonEmptyLine;
/***/ }), /***/ }),

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -14,7 +14,8 @@
"all": "npm run build && npm run format && npm run lint && npm run package && npm test", "all": "npm run build && npm run format && npm run lint && npm run package && npm test",
"dart-fixture": "cd \"reports/dart\" && dart test --file-reporter=\"json:../../__tests__/fixtures/dart-json.json\"", "dart-fixture": "cd \"reports/dart\" && dart test --file-reporter=\"json:../../__tests__/fixtures/dart-json.json\"",
"dotnet-fixture": "dotnet test reports/dotnet/DotnetTests.XUnitTests --logger \"trx;LogFileName=../../../../__tests__/fixtures/dotnet-trx.trx\"", "dotnet-fixture": "dotnet test reports/dotnet/DotnetTests.XUnitTests --logger \"trx;LogFileName=../../../../__tests__/fixtures/dotnet-trx.trx\"",
"jest-fixture": "cd \"reports/jest\" && npm test" "jest-fixture": "cd \"reports/jest\" && npm test",
"mocha-fixture": "cd \"reports/mocha\" && npm test"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -0,0 +1,5 @@
function throwError() {
throw new Error('Some error')
}
exports.throwError = throwError

761
reports/mocha/package-lock.json generated Normal file
View File

@@ -0,0 +1,761 @@
{
"name": "mocha-fixture",
"version": "0.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@ungap/promise-all-settled": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
"integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
"dev": true
},
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true
},
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"anymatch": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
"dev": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
}
},
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"browser-stdout": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
"camelcase": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
"integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
"dev": true
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"dependencies": {
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"chokidar": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
"dev": true,
"requires": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.3.1",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.5.0"
}
},
"cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dev": true,
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^7.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"string-width": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
}
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
}
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
},
"dependencies": {
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
},
"decamelize": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
"integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
"dev": true
},
"diff": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
"dev": true
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"dev": true
},
"escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
"requires": {
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
}
},
"flat": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
"dev": true
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"optional": true
},
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"glob-parent": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
},
"growl": {
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"requires": {
"binary-extensions": "^2.0.0"
}
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
"is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
"dev": true
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"js-yaml": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
"dev": true,
"requires": {
"argparse": "^2.0.1"
}
},
"locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"requires": {
"p-locate": "^5.0.0"
}
},
"log-symbols": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
"integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
"dev": true,
"requires": {
"chalk": "^4.0.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"mocha": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.0.tgz",
"integrity": "sha512-TQqyC89V1J/Vxx0DhJIXlq9gbbL9XFNdeLQ1+JsnZsVaSOV1z3tWfw0qZmQJGQRIfkvZcs7snQnZnOCKoldq1Q==",
"dev": true,
"requires": {
"@ungap/promise-all-settled": "1.1.2",
"ansi-colors": "4.1.1",
"browser-stdout": "1.3.1",
"chokidar": "3.5.1",
"debug": "4.3.1",
"diff": "5.0.0",
"escape-string-regexp": "4.0.0",
"find-up": "5.0.0",
"glob": "7.1.6",
"growl": "1.10.5",
"he": "1.2.0",
"js-yaml": "4.0.0",
"log-symbols": "4.0.0",
"minimatch": "3.0.4",
"ms": "2.1.3",
"nanoid": "3.1.20",
"serialize-javascript": "5.0.1",
"strip-json-comments": "3.1.1",
"supports-color": "8.1.1",
"which": "2.0.2",
"wide-align": "1.1.3",
"workerpool": "6.1.0",
"yargs": "16.2.0",
"yargs-parser": "20.2.4",
"yargs-unparser": "2.0.0"
}
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
"nanoid": {
"version": "3.1.20",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
"dev": true
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"requires": {
"yocto-queue": "^0.1.0"
}
},
"p-locate": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"requires": {
"p-limit": "^3.0.2"
}
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
"dev": true
},
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
"requires": {
"safe-buffer": "^5.1.0"
}
},
"readdirp": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
"dev": true,
"requires": {
"picomatch": "^2.2.1"
}
},
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
"dev": true
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
},
"serialize-javascript": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
"integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
}
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"requires": {
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0"
}
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
}
},
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
},
"wide-align": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"dev": true,
"requires": {
"string-width": "^1.0.2 || 2"
}
},
"workerpool": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
"integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==",
"dev": true
},
"wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"string-width": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
}
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
}
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"y18n": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
"dev": true
},
"yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true,
"requires": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^20.2.2"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"string-width": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
}
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
}
}
},
"yargs-parser": {
"version": "20.2.4",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
"dev": true
},
"yargs-unparser": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
"integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
"dev": true,
"requires": {
"camelcase": "^6.0.0",
"decamelize": "^4.0.0",
"flat": "^5.0.2",
"is-plain-obj": "^2.1.0"
}
},
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
}
}
}

View File

@@ -0,0 +1,14 @@
{
"name": "mocha-fixture",
"version": "0.0.0",
"private": true,
"description": "Generates test fixtures for test-reporter action",
"scripts": {
"test": "mocha --reporter json > ../../__tests__/fixtures/mocha-json.json"
},
"author": "Michal Dorner <dorner.michal@gmail.com>",
"license": "MIT",
"devDependencies": {
"mocha": "^8.3.0"
}
}

View File

@@ -0,0 +1,24 @@
const assert = require('assert').strict;
const lib = require('../lib/main')
describe('Test 1', () => {
it('Passing test', () => {
assert.equal(true, true)
});
describe('Test 1.1', () => {
it('Failing test', () => {
assert.equal(false, true)
});
it('Exception in target unit', () => {
lib.throwError();
});
});
});
describe('Test 2', () => {
it('Exception in test', () => {
throw new Error('Some error');
});
});

View File

@@ -0,0 +1,8 @@
it('Timeout test', async function(done) {
this.timeout(1);
setTimeout(done, 1000);
});
it.skip('Skipped test', () => {
// do nothing
});

View File

@@ -14,6 +14,7 @@ import {DartJsonParser} from './parsers/dart-json/dart-json-parser'
import {DotnetTrxParser} from './parsers/dotnet-trx/dotnet-trx-parser' import {DotnetTrxParser} from './parsers/dotnet-trx/dotnet-trx-parser'
import {JavaJunitParser} from './parsers/java-junit/java-junit-parser' import {JavaJunitParser} from './parsers/java-junit/java-junit-parser'
import {JestJunitParser} from './parsers/jest-junit/jest-junit-parser' import {JestJunitParser} from './parsers/jest-junit/jest-junit-parser'
import {MochaJsonParser} from './parsers/mocha-json/mocha-json-parser'
import {normalizeDirPath} from './utils/path-utils' import {normalizeDirPath} from './utils/path-utils'
import {getCheckRunContext} from './utils/github-utils' import {getCheckRunContext} from './utils/github-utils'
@@ -146,9 +147,22 @@ class TestReporter {
results.push(tr) results.push(tr)
} }
core.info(`Creating check run ${name}`)
const createResp = await this.octokit.checks.create({
head_sha: this.context.sha,
name,
status: 'in_progress',
output: {
title: name,
summary: ''
},
...github.context.repo
})
core.info('Creating report summary') core.info('Creating report summary')
const {listSuites, listTests} = this const {listSuites, listTests} = this
const summary = getReport(results, {listSuites, listTests}) const baseUrl = createResp.data.html_url
const summary = getReport(results, {listSuites, listTests, baseUrl})
core.info('Creating annotations') core.info('Creating annotations')
const annotations = getAnnotations(results, this.maxAnnotations) const annotations = getAnnotations(results, this.maxAnnotations)
@@ -157,10 +171,9 @@ class TestReporter {
const conclusion = isFailed ? 'failure' : 'success' const conclusion = isFailed ? 'failure' : 'success'
const icon = isFailed ? Icon.fail : Icon.success const icon = isFailed ? Icon.fail : Icon.success
core.info(`Creating check run with conclusion ${conclusion}`) core.info(`Updating check run conclusion (${conclusion}) and output`)
const resp = await this.octokit.checks.create({ const resp = await this.octokit.checks.update({
head_sha: this.context.sha, check_run_id: createResp.data.id,
name,
conclusion, conclusion,
status: 'completed', status: 'completed',
output: { output: {
@@ -189,6 +202,8 @@ class TestReporter {
return new JavaJunitParser(options) return new JavaJunitParser(options)
case 'jest-junit': case 'jest-junit':
return new JestJunitParser(options) return new JestJunitParser(options)
case 'mocha-json':
return new MochaJsonParser(options)
default: default:
throw new Error(`Input variable 'reporter' is set to invalid value '${reporter}'`) throw new Error(`Input variable 'reporter' is set to invalid value '${reporter}'`)
} }

View File

@@ -145,7 +145,11 @@ export class DartJsonParser implements TestParser {
group.tests.sort((a, b) => (a.testStart.test.line ?? 0) - (b.testStart.test.line ?? 0)) group.tests.sort((a, b) => (a.testStart.test.line ?? 0) - (b.testStart.test.line ?? 0))
const tests = group.tests.map(tc => { const tests = group.tests.map(tc => {
const error = this.getError(suite, tc) const error = this.getError(suite, tc)
return new TestCaseResult(tc.testStart.test.name, tc.result, tc.time, error) const testName =
group.group.name !== undefined && tc.testStart.test.name.startsWith(group.group.name)
? tc.testStart.test.name.slice(group.group.name.length).trim()
: tc.testStart.test.name.trim()
return new TestCaseResult(testName, tc.result, tc.time, error)
}) })
return new TestGroupResult(group.group.name, tests) return new TestGroupResult(group.group.name, tests)
}) })
@@ -157,7 +161,6 @@ export class DartJsonParser implements TestParser {
} }
const {trackedFiles} = this.options const {trackedFiles} = this.options
const message = test.error?.error ?? ''
const stackTrace = test.error?.stackTrace ?? '' const stackTrace = test.error?.stackTrace ?? ''
const print = test.print const print = test.print
.filter(p => p.messageType === 'print') .filter(p => p.messageType === 'print')
@@ -165,6 +168,7 @@ export class DartJsonParser implements TestParser {
.join('\n') .join('\n')
const details = [print, stackTrace].filter(str => str !== '').join('\n') const details = [print, stackTrace].filter(str => str !== '').join('\n')
const src = this.exceptionThrowSource(details, trackedFiles) const src = this.exceptionThrowSource(details, trackedFiles)
const message = this.getErrorMessage(test.error?.error ?? '', print)
let path let path
let line let line
@@ -187,6 +191,21 @@ export class DartJsonParser implements TestParser {
} }
} }
private getErrorMessage(message: string, print: string): string {
if (this.sdk === 'flutter') {
const uselessMessageRe = /^Test failed\. See exception logs above\.\nThe test description was:/m
const flutterPrintRe = /^ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK +\s+(.*)\s+When the exception was thrown, this was the stack:/ms
if (uselessMessageRe.test(message)) {
const match = print.match(flutterPrintRe)
if (match !== null) {
return match[1]
}
}
}
return message || print
}
private exceptionThrowSource(ex: string, trackedFiles: string[]): {path: string; line: number} | undefined { private exceptionThrowSource(ex: string, trackedFiles: string[]): {path: string; line: number} | undefined {
const lines = ex.split(/\r?\n/g) const lines = ex.split(/\r?\n/g)

View File

@@ -49,6 +49,7 @@ export class DotnetTrxParser implements TestParser {
const trx = await this.getTrxReport(path, content) const trx = await this.getTrxReport(path, content)
const tc = this.getTestClasses(trx) const tc = this.getTestClasses(trx)
const tr = this.getTestRunResult(path, trx, tc) const tr = this.getTestRunResult(path, trx, tc)
tr.sort(true)
return tr return tr
} }
@@ -86,17 +87,14 @@ export class DotnetTrxParser implements TestParser {
} }
const output = r.unitTestResult.Output const output = r.unitTestResult.Output
const error = output?.length > 0 && output[0].ErrorInfo?.length > 0 ? output[0].ErrorInfo[0] : undefined const error = output?.length > 0 && output[0].ErrorInfo?.length > 0 ? output[0].ErrorInfo[0] : undefined
const duration = parseNetDuration(r.unitTestResult.$.duration) const durationAttr = r.unitTestResult.$.duration
const duration = durationAttr ? parseNetDuration(durationAttr) : 0
const test = new Test(r.testMethod.$.name, r.unitTestResult.$.outcome, duration, error) const test = new Test(r.testMethod.$.name, r.unitTestResult.$.outcome, duration, error)
tc.tests.push(test) tc.tests.push(test)
} }
const result = Object.values(testClasses) const result = Object.values(testClasses)
result.sort((a, b) => a.name.localeCompare(b.name))
for (const tc of result) {
tc.tests.sort((a, b) => a.name.localeCompare(b.name))
}
return result return result
} }

View File

@@ -43,7 +43,7 @@ export interface UnitTestResult {
$: { $: {
testId: string testId: string
testName: string testName: string
duration: string duration?: string
outcome: Outcome outcome: Outcome
} }
Output: Output[] Output: Output[]

View File

@@ -2,6 +2,7 @@ import {ParseOptions, TestParser} from '../../test-parser'
import {parseStringPromise} from 'xml2js' import {parseStringPromise} from 'xml2js'
import {JunitReport, TestCase, TestSuite} from './jest-junit-types' import {JunitReport, TestCase, TestSuite} from './jest-junit-types'
import {getExceptionSource} from '../../utils/node-utils'
import {getBasePath, normalizeFilePath} from '../../utils/path-utils' import {getBasePath, normalizeFilePath} from '../../utils/path-utils'
import { import {
@@ -84,7 +85,7 @@ export class JestJunitParser implements TestParser {
let path let path
let line let line
const src = this.exceptionThrowSource(details) const src = getExceptionSource(details, this.options.trackedFiles, file => this.getRelativePath(file))
if (src) { if (src) {
path = src.path path = src.path
line = src.line line = src.line
@@ -97,31 +98,13 @@ export class JestJunitParser implements TestParser {
} }
} }
private exceptionThrowSource(stackTrace: string): {path: string; line: number} | undefined { private getRelativePath(path: string): string {
const lines = stackTrace.split(/\r?\n/) path = normalizeFilePath(path)
const re = /\((.*):(\d+):\d+\)$/ const workDir = this.getWorkDir(path)
if (workDir !== undefined && path.startsWith(workDir)) {
const {trackedFiles} = this.options path = path.substr(workDir.length)
for (const str of lines) {
const match = str.match(re)
if (match !== null) {
const [_, fileStr, lineStr] = match
const filePath = normalizeFilePath(fileStr)
if (filePath.startsWith('internal/') || filePath.includes('/node_modules/')) {
continue
}
const workDir = this.getWorkDir(filePath)
if (!workDir) {
continue
}
const path = filePath.substr(workDir.length)
if (trackedFiles.includes(path)) {
const line = parseInt(lineStr)
return {path, line}
}
}
} }
return path
} }
private getWorkDir(path: string): string | undefined { private getWorkDir(path: string): string | undefined {

View File

@@ -0,0 +1,118 @@
import {ParseOptions, TestParser} from '../../test-parser'
import {
TestCaseError,
TestCaseResult,
TestExecutionResult,
TestGroupResult,
TestRunResult,
TestSuiteResult
} from '../../test-results'
import {getExceptionSource} from '../../utils/node-utils'
import {getBasePath, normalizeFilePath} from '../../utils/path-utils'
import {MochaJson, MochaJsonTest} from './mocha-json-types'
export class MochaJsonParser implements TestParser {
assumedWorkDir: string | undefined
constructor(readonly options: ParseOptions) {}
async parse(path: string, content: string): Promise<TestRunResult> {
const mocha = this.getMochaJson(path, content)
const result = this.getTestRunResult(path, mocha)
result.sort(true)
return Promise.resolve(result)
}
private getMochaJson(path: string, content: string): MochaJson {
try {
return JSON.parse(content)
} catch (e) {
throw new Error(`Invalid JSON at ${path}\n\n${e}`)
}
}
private getTestRunResult(resultsPath: string, mocha: MochaJson): TestRunResult {
const suitesMap: {[path: string]: TestSuiteResult} = {}
const getSuite = (test: MochaJsonTest): TestSuiteResult => {
const path = this.getRelativePath(test.file)
return suitesMap[path] ?? (suitesMap[path] = new TestSuiteResult(path, []))
}
for (const test of mocha.passes) {
const suite = getSuite(test)
this.processTest(suite, test, 'success')
}
for (const test of mocha.failures) {
const suite = getSuite(test)
this.processTest(suite, test, 'failed')
}
for (const test of mocha.pending) {
const suite = getSuite(test)
this.processTest(suite, test, 'skipped')
}
const suites = Object.values(suitesMap)
return new TestRunResult(resultsPath, suites, mocha.stats.duration)
}
private processTest(suite: TestSuiteResult, test: MochaJsonTest, result: TestExecutionResult): void {
const groupName =
test.fullTitle !== test.title
? test.fullTitle.substr(0, test.fullTitle.length - test.title.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.title, result, test.duration ?? 0, error)
group.tests.push(testCase)
}
private getTestCaseError(test: MochaJsonTest): TestCaseError | undefined {
const details = test.err.stack
const message = test.err.message
if (details === undefined) {
return undefined
}
let path
let line
const src = getExceptionSource(details, this.options.trackedFiles, file => this.getRelativePath(file))
if (src) {
path = src.path
line = src.line
}
return {
path,
line,
message,
details
}
}
private getRelativePath(path: string): string {
path = normalizeFilePath(path)
const workDir = this.getWorkDir(path)
if (workDir !== undefined && path.startsWith(workDir)) {
path = path.substr(workDir.length)
}
return path
}
private getWorkDir(path: string): string | undefined {
return (
this.options.workDir ??
this.assumedWorkDir ??
(this.assumedWorkDir = getBasePath(path, this.options.trackedFiles))
)
}
}

View File

@@ -0,0 +1,23 @@
export interface MochaJson {
stats: MochaJsonStats
passes: MochaJsonTest[]
pending: MochaJsonTest[]
failures: MochaJsonTest[]
}
export interface MochaJsonStats {
duration: number
}
export interface MochaJsonTest {
title: string
fullTitle: string
file: string
duration?: number
err: MochaJsonTestError
}
export interface MochaJsonTestError {
stack?: string
message?: string
}

View File

@@ -1,5 +1,6 @@
import {ellipsis, fixEol} from '../utils/markdown-utils' import {ellipsis, fixEol} from '../utils/markdown-utils'
import {TestRunResult} from '../test-results' import {TestRunResult} from '../test-results'
import {getFirstNonEmptyLine} from '../utils/parse-utils'
type Annotation = { type Annotation = {
path: string path: string
@@ -53,7 +54,7 @@ export function getAnnotations(results: TestRunResult[], maxCount: number): Anno
errors.push({ errors.push({
testRunPaths: [tr.path], testRunPaths: [tr.path],
suiteName: ts.name, suiteName: ts.name,
testName: tc.name, testName: tg.name ? `${tg.name}${tc.name}` : tc.name,
details: err.details, details: err.details,
message: err.message ?? getFirstNonEmptyLine(err.details) ?? 'Test failed', message: err.message ?? getFirstNonEmptyLine(err.details) ?? 'Test failed',
path, path,
@@ -98,11 +99,6 @@ function enforceCheckRunLimits(err: Annotation): Annotation {
return err return err
} }
function getFirstNonEmptyLine(stackTrace: string): string | undefined {
const lines = stackTrace.split(/\r?\n/g)
return lines.find(str => !/^\s*$/.test(str))
}
function ident(text: string, prefix: string): string { function ident(text: string, prefix: string): string {
return text return text
.split(/\n/g) .split(/\n/g)

View File

@@ -1,61 +1,79 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import {TestExecutionResult, TestRunResult, TestSuiteResult} from '../test-results' import {TestExecutionResult, TestRunResult, TestSuiteResult} from '../test-results'
import {Align, formatTime, Icon, link, table} from '../utils/markdown-utils' import {Align, formatTime, Icon, link, table} from '../utils/markdown-utils'
import {getFirstNonEmptyLine} from '../utils/parse-utils'
import {slug} from '../utils/slugger' import {slug} from '../utils/slugger'
const MAX_REPORT_LENGTH = 65535
export interface ReportOptions { export interface ReportOptions {
listSuites: 'all' | 'failed' listSuites: 'all' | 'failed'
listTests: 'all' | 'failed' | 'none' listTests: 'all' | 'failed' | 'none'
baseUrl: string
} }
const defaultOptions: ReportOptions = { const defaultOptions: ReportOptions = {
listSuites: 'all', listSuites: 'all',
listTests: 'all' listTests: 'all',
baseUrl: ''
} }
export function getReport(results: TestRunResult[], options: ReportOptions = defaultOptions): string { export function getReport(results: TestRunResult[], options: ReportOptions = defaultOptions): string {
core.info('Generating check run summary') core.info('Generating check run summary')
const maxReportLength = 65535
applySort(results) applySort(results)
const opts = {...options} const opts = {...options}
let report = renderReport(results, opts) let lines = renderReport(results, opts)
if (getByteLength(report) <= maxReportLength) { let report = lines.join('\n')
if (getByteLength(report) <= MAX_REPORT_LENGTH) {
return report return report
} }
if (opts.listTests === 'all') { if (opts.listTests === 'all') {
core.info("Test report summary is too big - setting 'listTests' to 'failed'") core.info("Test report summary is too big - setting 'listTests' to 'failed'")
opts.listTests = 'failed' opts.listTests = 'failed'
report = renderReport(results, opts) lines = renderReport(results, opts)
if (getByteLength(report) <= maxReportLength) { report = lines.join('\n')
if (getByteLength(report) <= MAX_REPORT_LENGTH) {
return report return report
} }
} }
if (opts.listSuites === 'all') { core.warning(`Test report summary exceeded limit of ${MAX_REPORT_LENGTH} bytes and will be trimmed`)
core.info("Test report summary is too big - setting 'listSuites' to 'failed'") return trimReport(lines)
opts.listSuites = 'failed' }
report = renderReport(results, opts)
if (getByteLength(report) <= maxReportLength) { function trimReport(lines: string[]): string {
return report const closingBlock = '```'
const errorMsg = `**Report exceeded GitHub limit of ${MAX_REPORT_LENGTH} bytes and has been trimmed**`
const maxErrorMsgLength = closingBlock.length + errorMsg.length + 2
const maxReportLength = MAX_REPORT_LENGTH - maxErrorMsgLength
let reportLength = 0
let codeBlock = false
let endLineIndex = 0
for (endLineIndex = 0; endLineIndex < lines.length; endLineIndex++) {
const line = lines[endLineIndex]
const lineLength = getByteLength(line)
reportLength += lineLength + 1
if (reportLength > maxReportLength) {
break
}
if (line === '```') {
codeBlock = !codeBlock
} }
} }
if (opts.listTests !== 'none') { const reportLines = lines.slice(0, endLineIndex)
core.info("Test report summary is too big - setting 'listTests' to 'none'") if (codeBlock) {
opts.listTests = 'none' reportLines.push('```')
report = renderReport(results, opts)
if (getByteLength(report) <= maxReportLength) {
return report
}
} }
reportLines.push(errorMsg)
core.warning(`Test report summary exceeded limit of ${maxReportLength} bytes`) return reportLines.join('\n')
const badge = getReportBadge(results)
const msg = `**Test report summary exceeded limit of ${maxReportLength} bytes and was removed**`
return `${badge}\n${msg}`
} }
function applySort(results: TestRunResult[]): void { function applySort(results: TestRunResult[]): void {
@@ -69,7 +87,7 @@ function getByteLength(text: string): number {
return Buffer.byteLength(text, 'utf8') return Buffer.byteLength(text, 'utf8')
} }
function renderReport(results: TestRunResult[], options: ReportOptions): string { function renderReport(results: TestRunResult[], options: ReportOptions): string[] {
const sections: string[] = [] const sections: string[] = []
const badge = getReportBadge(results) const badge = getReportBadge(results)
sections.push(badge) sections.push(badge)
@@ -77,7 +95,7 @@ function renderReport(results: TestRunResult[], options: ReportOptions): string
const runs = getTestRunsReport(results, options) const runs = getTestRunsReport(results, options)
sections.push(...runs) sections.push(...runs)
return sections.join('\n') return sections
} }
function getReportBadge(results: TestRunResult[]): string { function getReportBadge(results: TestRunResult[]): string {
@@ -118,7 +136,7 @@ function getTestRunsReport(testRuns: TestRunResult[], options: ReportOptions): s
const tableData = testRuns.map((tr, runIndex) => { const tableData = testRuns.map((tr, runIndex) => {
const time = formatTime(tr.time) const time = formatTime(tr.time)
const name = tr.path const name = tr.path
const addr = makeRunSlug(runIndex).link const addr = options.baseUrl + makeRunSlug(runIndex).link
const nameLink = link(name, addr) const nameLink = link(name, addr)
const passed = tr.passed > 0 ? `${tr.passed}${Icon.success}` : '' const passed = tr.passed > 0 ? `${tr.passed}${Icon.success}` : ''
const failed = tr.failed > 0 ? `${tr.failed}${Icon.fail}` : '' const failed = tr.failed > 0 ? `${tr.failed}${Icon.fail}` : ''
@@ -143,9 +161,9 @@ function getSuitesReport(tr: TestRunResult, runIndex: number, options: ReportOpt
const sections: string[] = [] const sections: string[] = []
const trSlug = makeRunSlug(runIndex) const trSlug = makeRunSlug(runIndex)
const nameLink = `<a id="${trSlug.id}" href="${trSlug.link}">${tr.path}</a>` const nameLink = `<a id="${trSlug.id}" href="${options.baseUrl + trSlug.link}">${tr.path}</a>`
const icon = getResultIcon(tr.result) const icon = getResultIcon(tr.result)
sections.push(`## ${nameLink} ${icon}`) sections.push(`## ${icon}\xa0${nameLink}`)
const time = formatTime(tr.time) const time = formatTime(tr.time)
const headingLine2 = const headingLine2 =
@@ -163,7 +181,7 @@ function getSuitesReport(tr: TestRunResult, runIndex: number, options: ReportOpt
const tsTime = formatTime(s.time) const tsTime = formatTime(s.time)
const tsName = s.name const tsName = s.name
const skipLink = options.listTests === 'none' || (options.listTests === 'failed' && s.result !== 'failed') const skipLink = options.listTests === 'none' || (options.listTests === 'failed' && s.result !== 'failed')
const tsAddr = makeSuiteSlug(runIndex, suiteIndex).link const tsAddr = options.baseUrl + makeSuiteSlug(runIndex, suiteIndex).link
const tsNameLink = skipLink ? tsName : link(tsName, tsAddr) const tsNameLink = skipLink ? tsName : link(tsName, tsAddr)
const passed = s.passed > 0 ? `${s.passed}${Icon.success}` : '' const passed = s.passed > 0 ? `${s.passed}${Icon.success}` : ''
const failed = s.failed > 0 ? `${s.failed}${Icon.fail}` : '' const failed = s.failed > 0 ? `${s.failed}${Icon.fail}` : ''
@@ -186,7 +204,10 @@ function getSuitesReport(tr: TestRunResult, runIndex: number, options: ReportOpt
} }
function getTestsReport(ts: TestSuiteResult, runIndex: number, suiteIndex: number, options: ReportOptions): string[] { function getTestsReport(ts: TestSuiteResult, runIndex: number, suiteIndex: number, options: ReportOptions): string[] {
const groups = options.listTests === 'failed' ? ts.failedGroups : ts.groups if (options.listTests === 'failed' && ts.result !== 'failed') {
return []
}
const groups = ts.groups
if (groups.length === 0) { if (groups.length === 0) {
return [] return []
} }
@@ -195,33 +216,30 @@ function getTestsReport(ts: TestSuiteResult, runIndex: number, suiteIndex: numbe
const tsName = ts.name const tsName = ts.name
const tsSlug = makeSuiteSlug(runIndex, suiteIndex) const tsSlug = makeSuiteSlug(runIndex, suiteIndex)
const tsNameLink = `<a id="${tsSlug.id}" href="${tsSlug.link}">${tsName}</a>` const tsNameLink = `<a id="${tsSlug.id}" href="${options.baseUrl + tsSlug.link}">${tsName}</a>`
const icon = getResultIcon(ts.result) const icon = getResultIcon(ts.result)
sections.push(`### ${tsNameLink} ${icon}`) sections.push(`### ${icon}\xa0${tsNameLink}`)
const tsTime = formatTime(ts.time)
const headingLine2 = `**${ts.tests}** tests were completed in **${tsTime}** with **${ts.passed}** passed, **${ts.failed}** failed and **${ts.skipped}** skipped.`
sections.push(headingLine2)
sections.push('```')
for (const grp of groups) { for (const grp of groups) {
const tests = options.listTests === 'failed' ? grp.failedTests : grp.tests if (grp.name) {
if (tests.length === 0) { sections.push(grp.name)
continue }
const space = grp.name ? ' ' : ''
for (const tc of grp.tests) {
const result = getResultIcon(tc.result)
sections.push(`${space}${result} ${tc.name}`)
if (tc.error) {
const lines = (tc.error.message ?? getFirstNonEmptyLine(tc.error.details)?.trim())
?.split(/\r?\n/g)
.map(l => '\t' + l)
if (lines) {
sections.push(...lines)
}
}
} }
const grpHeader = grp.name ? `\n**${grp.name}**` : ''
const testsTable = table(
['Result', 'Test', 'Time'],
[Align.Center, Align.Left, Align.Right],
...grp.tests.map(tc => {
const name = tc.name
const time = formatTime(tc.time)
const result = getResultIcon(tc.result)
return [result, name, time]
})
)
sections.push(grpHeader, testsTable)
} }
sections.push('```')
return sections return sections
} }

View File

@@ -26,6 +26,15 @@ export class TestRunResult {
get failedSuites(): TestSuiteResult[] { get failedSuites(): TestSuiteResult[] {
return this.suites.filter(s => s.result === 'failed') return this.suites.filter(s => s.result === 'failed')
} }
sort(deep: boolean): void {
this.suites.sort((a, b) => a.name.localeCompare(b.name))
if (deep) {
for (const suite of this.suites) {
suite.sort(deep)
}
}
}
} }
export class TestSuiteResult { export class TestSuiteResult {
@@ -55,6 +64,15 @@ export class TestSuiteResult {
get failedGroups(): TestGroupResult[] { get failedGroups(): TestGroupResult[] {
return this.groups.filter(grp => grp.result === 'failed') return this.groups.filter(grp => grp.result === 'failed')
} }
sort(deep: boolean): void {
this.groups.sort((a, b) => (a.name ?? '').localeCompare(b.name ?? ''))
if (deep) {
for (const grp of this.groups) {
grp.sort()
}
}
}
} }
export class TestGroupResult { export class TestGroupResult {
@@ -80,6 +98,10 @@ export class TestGroupResult {
get failedTests(): TestCaseResult[] { get failedTests(): TestCaseResult[] {
return this.tests.filter(tc => tc.result === 'failed') return this.tests.filter(tc => tc.result === 'failed')
} }
sort(): void {
this.tests.sort((a, b) => a.name.localeCompare(b.name))
}
} }
export class TestCaseResult { export class TestCaseResult {

View File

@@ -41,7 +41,7 @@ export function ellipsis(text: string, maxLength: number): string {
export function formatTime(ms: number): string { export function formatTime(ms: number): string {
if (ms > 1000) { if (ms > 1000) {
return `${(ms / 1000).toFixed(3)}s` return `${Math.round(ms / 1000)}s`
} }
return `${Math.round(ms)}ms` return `${Math.round(ms)}ms`

30
src/utils/node-utils.ts Normal file
View File

@@ -0,0 +1,30 @@
import {normalizeFilePath} from './path-utils'
export function getExceptionSource(
stackTrace: string,
trackedFiles: string[],
getRelativePath: (str: string) => string
): {path: string; line: number} | undefined {
const lines = stackTrace.split(/\r?\n/)
const re = /\((.*):(\d+):\d+\)$/
for (const str of lines) {
const match = str.match(re)
if (match !== null) {
const [_, fileStr, lineStr] = match
const filePath = normalizeFilePath(fileStr)
if (filePath.startsWith('internal/') || filePath.includes('/node_modules/')) {
continue
}
const path = getRelativePath(filePath)
if (!path) {
continue
}
if (trackedFiles.includes(path)) {
const line = parseInt(lineStr)
return {path, line}
}
}
}
}

View File

@@ -1,6 +1,5 @@
export function parseNetDuration(str: string): number { export function parseNetDuration(str: string): number {
// matches dotnet duration: 00:00:00.0010000 const durationRe = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)$/
const durationRe = /^(\d\d):(\d\d):(\d\d\.\d+)$/
const durationMatch = str.match(durationRe) const durationMatch = str.match(durationRe)
if (durationMatch === null) { if (durationMatch === null) {
throw new Error(`Invalid format: "${str}" is not NET duration`) throw new Error(`Invalid format: "${str}" is not NET duration`)
@@ -18,3 +17,8 @@ export function parseIsoDate(str: string): Date {
return new Date(str) return new Date(str)
} }
export function getFirstNonEmptyLine(stackTrace: string): string | undefined {
const lines = stackTrace.split(/\r?\n/g)
return lines.find(str => !/^\s*$/.test(str))
}