xunit.ts 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -2
- package/cli.ts +9 -4
- package/dist/cli.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/eslint.config.d.ts +3 -0
- package/dist/eslint.config.d.ts.map +1 -0
- package/dist/eslint.config.js +46 -0
- package/dist/eslint.config.js.map +1 -0
- package/dist/src/Assertions/Contains.d.ts +1 -1
- package/dist/src/Assertions/Contains.d.ts.map +1 -1
- package/dist/src/Assertions/Contains.js +2 -2
- package/dist/src/Assertions/Contains.js.map +1 -1
- package/dist/src/Assertions/Count.d.ts +1 -1
- package/dist/src/Assertions/Count.d.ts.map +1 -1
- package/dist/src/Assertions/Count.js +2 -2
- package/dist/src/Assertions/Count.js.map +1 -1
- package/dist/src/Assertions/Defined.d.ts +1 -1
- package/dist/src/Assertions/Defined.d.ts.map +1 -1
- package/dist/src/Assertions/Defined.js +2 -2
- package/dist/src/Assertions/Defined.js.map +1 -1
- package/dist/src/Assertions/DoesNotContain.d.ts +1 -1
- package/dist/src/Assertions/DoesNotContain.d.ts.map +1 -1
- package/dist/src/Assertions/DoesNotContain.js +2 -2
- package/dist/src/Assertions/DoesNotContain.js.map +1 -1
- package/dist/src/Assertions/DoesNotThrow.d.ts +1 -1
- package/dist/src/Assertions/DoesNotThrow.d.ts.map +1 -1
- package/dist/src/Assertions/DoesNotThrow.js +2 -2
- package/dist/src/Assertions/DoesNotThrow.js.map +1 -1
- package/dist/src/Assertions/Empty.d.ts +1 -1
- package/dist/src/Assertions/Empty.d.ts.map +1 -1
- package/dist/src/Assertions/Empty.js +2 -2
- package/dist/src/Assertions/Empty.js.map +1 -1
- package/dist/src/Assertions/Equal.d.ts +1 -1
- package/dist/src/Assertions/Equal.d.ts.map +1 -1
- package/dist/src/Assertions/Equal.js +2 -2
- package/dist/src/Assertions/Equal.js.map +1 -1
- package/dist/src/Assertions/False.d.ts +1 -1
- package/dist/src/Assertions/False.d.ts.map +1 -1
- package/dist/src/Assertions/False.js +2 -2
- package/dist/src/Assertions/False.js.map +1 -1
- package/dist/src/Assertions/InstanceOf.d.ts +1 -1
- package/dist/src/Assertions/InstanceOf.d.ts.map +1 -1
- package/dist/src/Assertions/InstanceOf.js +2 -2
- package/dist/src/Assertions/InstanceOf.js.map +1 -1
- package/dist/src/Assertions/NotEmpty.d.ts +1 -1
- package/dist/src/Assertions/NotEmpty.d.ts.map +1 -1
- package/dist/src/Assertions/NotEmpty.js +2 -2
- package/dist/src/Assertions/NotEmpty.js.map +1 -1
- package/dist/src/Assertions/NotEqual.d.ts +1 -1
- package/dist/src/Assertions/NotEqual.d.ts.map +1 -1
- package/dist/src/Assertions/NotEqual.js +2 -2
- package/dist/src/Assertions/NotEqual.js.map +1 -1
- package/dist/src/Assertions/NotNull.d.ts +1 -1
- package/dist/src/Assertions/NotNull.d.ts.map +1 -1
- package/dist/src/Assertions/NotNull.js +2 -2
- package/dist/src/Assertions/NotNull.js.map +1 -1
- package/dist/src/Assertions/Null.d.ts +1 -1
- package/dist/src/Assertions/Null.d.ts.map +1 -1
- package/dist/src/Assertions/Null.js +2 -2
- package/dist/src/Assertions/Null.js.map +1 -1
- package/dist/src/Assertions/StringContains.js +3 -3
- package/dist/src/Assertions/StringContains.js.map +1 -1
- package/dist/src/Assertions/StringDoesNotContain.js +3 -3
- package/dist/src/Assertions/StringDoesNotContain.js.map +1 -1
- package/dist/src/Assertions/StringDoesNotEndWith.d.ts.map +1 -1
- package/dist/src/Assertions/StringDoesNotEndWith.js +3 -5
- package/dist/src/Assertions/StringDoesNotEndWith.js.map +1 -1
- package/dist/src/Assertions/StringDoesNotMatch.d.ts +1 -1
- package/dist/src/Assertions/StringDoesNotMatch.d.ts.map +1 -1
- package/dist/src/Assertions/StringDoesNotMatch.js +2 -2
- package/dist/src/Assertions/StringDoesNotMatch.js.map +1 -1
- package/dist/src/Assertions/StringDoesNotStartWith.js +2 -2
- package/dist/src/Assertions/StringDoesNotStartWith.js.map +1 -1
- package/dist/src/Assertions/StringEndsWith.d.ts.map +1 -1
- package/dist/src/Assertions/StringEndsWith.js +3 -5
- package/dist/src/Assertions/StringEndsWith.js.map +1 -1
- package/dist/src/Assertions/StringMatches.d.ts +1 -1
- package/dist/src/Assertions/StringMatches.d.ts.map +1 -1
- package/dist/src/Assertions/StringMatches.js +2 -2
- package/dist/src/Assertions/StringMatches.js.map +1 -1
- package/dist/src/Assertions/StringStartsWith.js +2 -2
- package/dist/src/Assertions/StringStartsWith.js.map +1 -1
- package/dist/src/Assertions/Throws.d.ts +1 -1
- package/dist/src/Assertions/Throws.d.ts.map +1 -1
- package/dist/src/Assertions/Throws.js +3 -3
- package/dist/src/Assertions/Throws.js.map +1 -1
- package/dist/src/Assertions/True.d.ts +1 -1
- package/dist/src/Assertions/True.d.ts.map +1 -1
- package/dist/src/Assertions/True.js +2 -2
- package/dist/src/Assertions/True.js.map +1 -1
- package/dist/src/Assertions/Undefined.d.ts +1 -1
- package/dist/src/Assertions/Undefined.d.ts.map +1 -1
- package/dist/src/Assertions/Undefined.js +2 -2
- package/dist/src/Assertions/Undefined.js.map +1 -1
- package/dist/src/Assertions/index.d.ts +15 -15
- package/dist/src/Assertions/index.d.ts.map +1 -1
- package/dist/src/Assertions/index.js +15 -15
- package/dist/src/Assertions/index.js.map +1 -1
- package/dist/src/CLI.d.ts +1 -1
- package/dist/src/CLI.d.ts.map +1 -1
- package/dist/src/CLI.js +7 -6
- package/dist/src/CLI.js.map +1 -1
- package/dist/src/Factory.d.ts +1 -1
- package/dist/src/Factory.d.ts.map +1 -1
- package/dist/src/Factory.js +7 -7
- package/dist/src/Factory.js.map +1 -1
- package/dist/src/Framework/Test.d.ts +1 -1
- package/dist/src/Framework/Test.d.ts.map +1 -1
- package/dist/src/Framework/Test.js.map +1 -1
- package/dist/src/Framework/TestInfo.d.ts +5 -1
- package/dist/src/Framework/TestInfo.d.ts.map +1 -1
- package/dist/src/Framework/TestName.js +2 -2
- package/dist/src/Framework/TestName.js.map +1 -1
- package/dist/src/Framework/TestSuite.d.ts +2 -2
- package/dist/src/Framework/TestSuite.d.ts.map +1 -1
- package/dist/src/Framework/TestSuite.js +7 -6
- package/dist/src/Framework/TestSuite.js.map +1 -1
- package/dist/src/IO/FileSystem.d.ts +1 -1
- package/dist/src/IO/FileSystem.d.ts.map +1 -1
- package/dist/src/IO/FileSystem.js +4 -4
- package/dist/src/IO/FileSystem.js.map +1 -1
- package/dist/src/IO/Output.d.ts +1 -1
- package/dist/src/IO/Output.d.ts.map +1 -1
- package/dist/src/Reporters/ConsoleReporter.d.ts +4 -4
- package/dist/src/Reporters/ConsoleReporter.d.ts.map +1 -1
- package/dist/src/Reporters/ConsoleReporter.js +39 -28
- package/dist/src/Reporters/ConsoleReporter.js.map +1 -1
- package/dist/src/Reporters/FileReporter.d.ts +4 -4
- package/dist/src/Reporters/FileReporter.d.ts.map +1 -1
- package/dist/src/Reporters/FileReporter.js +0 -1
- package/dist/src/Reporters/FileReporter.js.map +1 -1
- package/dist/src/Reporters/JUnitReporter.d.ts.map +1 -1
- package/dist/src/Reporters/JUnitReporter.js +1 -1
- package/dist/src/Reporters/JUnitReporter.js.map +1 -1
- package/dist/src/Reporters/ResultReporter.d.ts +2 -2
- package/dist/src/Reporters/ResultReporter.d.ts.map +1 -1
- package/dist/src/Reporters/ResultReporter.js +1 -0
- package/dist/src/Reporters/ResultReporter.js.map +1 -1
- package/dist/src/Reporters/SonarReporter.d.ts.map +1 -1
- package/dist/src/Reporters/SonarReporter.js +2 -2
- package/dist/src/Reporters/SonarReporter.js.map +1 -1
- package/dist/src/Reporters/XMLReporter.d.ts +1 -1
- package/dist/src/Reporters/XMLReporter.d.ts.map +1 -1
- package/dist/src/Reporters/XMLReporter.js.map +1 -1
- package/dist/src/Runners/Runner.d.ts +3 -3
- package/dist/src/Runners/Runner.d.ts.map +1 -1
- package/dist/src/Runners/Runner.js +1 -1
- package/dist/src/Runners/Runner.js.map +1 -1
- package/dist/src/Runners/TestRunner.d.ts +4 -2
- package/dist/src/Runners/TestRunner.d.ts.map +1 -1
- package/dist/src/Runners/TestRunner.js +13 -8
- package/dist/src/Runners/TestRunner.js.map +1 -1
- package/dist/src/Runners/TestSuiteLoader.d.ts.map +1 -1
- package/dist/src/Runners/TestSuiteLoader.js +15 -11
- package/dist/src/Runners/TestSuiteLoader.js.map +1 -1
- package/dist/src/Runners/TestSuiteRunner.d.ts +4 -4
- package/dist/src/Runners/TestSuiteRunner.d.ts.map +1 -1
- package/dist/src/Runners/TestSuiteRunner.js +3 -3
- package/dist/src/Runners/TestSuiteRunner.js.map +1 -1
- package/dist/xunit.d.ts +2 -2
- package/dist/xunit.d.ts.map +1 -1
- package/dist/xunit.js +3 -3
- package/dist/xunit.js.map +1 -1
- package/eslint.config.ts +44 -0
- package/package.json +13 -9
- package/src/Assertions/Contains.ts +2 -2
- package/src/Assertions/Count.ts +2 -2
- package/src/Assertions/Defined.ts +2 -2
- package/src/Assertions/DoesNotContain.ts +2 -2
- package/src/Assertions/DoesNotThrow.ts +2 -2
- package/src/Assertions/Empty.ts +2 -2
- package/src/Assertions/Equal.ts +3 -2
- package/src/Assertions/False.ts +2 -2
- package/src/Assertions/InstanceOf.ts +2 -2
- package/src/Assertions/NotEmpty.ts +2 -2
- package/src/Assertions/NotEqual.ts +3 -2
- package/src/Assertions/NotNull.ts +2 -2
- package/src/Assertions/Null.ts +2 -2
- package/src/Assertions/StringContains.ts +2 -2
- package/src/Assertions/StringDoesNotContain.ts +2 -2
- package/src/Assertions/StringDoesNotEndWith.ts +2 -4
- package/src/Assertions/StringDoesNotMatch.ts +2 -2
- package/src/Assertions/StringDoesNotStartWith.ts +1 -1
- package/src/Assertions/StringEndsWith.ts +2 -4
- package/src/Assertions/StringMatches.ts +2 -2
- package/src/Assertions/StringStartsWith.ts +1 -1
- package/src/Assertions/Throws.ts +3 -3
- package/src/Assertions/True.ts +2 -2
- package/src/Assertions/Undefined.ts +2 -2
- package/src/Assertions/index.ts +15 -27
- package/src/CLI.ts +9 -6
- package/src/Factory.ts +11 -9
- package/src/Framework/Test.ts +1 -1
- package/src/Framework/TestInfo.ts +7 -1
- package/src/Framework/TestName.ts +2 -2
- package/src/Framework/TestSuite.ts +10 -8
- package/src/IO/FileSystem.ts +4 -4
- package/src/IO/Output.ts +1 -1
- package/src/Reporters/ConsoleReporter.ts +13 -11
- package/src/Reporters/FileReporter.ts +7 -5
- package/src/Reporters/JUnitReporter.ts +3 -2
- package/src/Reporters/ResultReporter.ts +4 -3
- package/src/Reporters/SonarReporter.ts +4 -2
- package/src/Reporters/XMLReporter.ts +2 -2
- package/src/Runners/Runner.ts +5 -5
- package/src/Runners/TestRunner.ts +19 -11
- package/src/Runners/TestSuiteLoader.ts +14 -7
- package/src/Runners/TestSuiteRunner.ts +7 -7
- package/tsconfig.json +3 -0
- package/xunit.ts +3 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssertionError } from "assert";
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Asserts that a string contains a given substring
|
|
@@ -16,7 +16,7 @@ import { AssertionError } from "assert";
|
|
|
16
16
|
* this.assert.stringContains(needle, haystack);
|
|
17
17
|
*/
|
|
18
18
|
export default function StringContains(needle: string, haystack: string | null, message?: string) {
|
|
19
|
-
if (haystack
|
|
19
|
+
if (haystack?.includes(needle)) {
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssertionError } from "assert";
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Asserts that a string does not contain a given substring
|
|
@@ -16,7 +16,7 @@ import { AssertionError } from "assert";
|
|
|
16
16
|
* this.assert.stringDoesNotContain(needle, haystack);
|
|
17
17
|
*/
|
|
18
18
|
export default function StringDoesNotContain(needle: string, haystack: string | null, message?: string) {
|
|
19
|
-
if (haystack
|
|
19
|
+
if (!haystack?.includes(needle)) {
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssertionError } from "assert";
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Asserts that a string does not end with a given substring
|
|
@@ -16,9 +16,7 @@ import { AssertionError } from "assert";
|
|
|
16
16
|
* this.assert.stringDoesNotEndWith(needle, haystack);
|
|
17
17
|
*/
|
|
18
18
|
export default function StringDoesNotEndWith(needle: string, haystack: string | null, message?: string) {
|
|
19
|
-
if (haystack
|
|
20
|
-
|| haystack.indexOf(needle) === -1
|
|
21
|
-
|| haystack.indexOf(needle) !== haystack.length - needle.length) {
|
|
19
|
+
if (!haystack?.endsWith(needle)) {
|
|
22
20
|
return;
|
|
23
21
|
}
|
|
24
22
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssertionError } from "assert";
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Asserts that a string does not match a given regular expression
|
|
@@ -15,7 +15,7 @@ import { AssertionError } from "assert";
|
|
|
15
15
|
* @example
|
|
16
16
|
* this.assert.stringDoesNotMatch(regex, haystack);
|
|
17
17
|
*/
|
|
18
|
-
export default function StringDoesNotMatch(regex: RegExp, haystack
|
|
18
|
+
export default function StringDoesNotMatch(regex: RegExp, haystack?: string | null, message?: string) {
|
|
19
19
|
if (haystack === undefined || haystack === null || !regex.test(haystack)) {
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssertionError } from "assert";
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Asserts that a string ends with a given substring
|
|
@@ -16,9 +16,7 @@ import { AssertionError } from "assert";
|
|
|
16
16
|
* this.assert.stringEndsWith(needle, haystack);
|
|
17
17
|
*/
|
|
18
18
|
export default function StringEndsWith(needle: string, haystack: string | null, message?: string) {
|
|
19
|
-
if (haystack
|
|
20
|
-
&& haystack.indexOf(needle) > -1
|
|
21
|
-
&& haystack.indexOf(needle) === haystack.length - needle.length) {
|
|
19
|
+
if (haystack?.endsWith(needle)) {
|
|
22
20
|
return;
|
|
23
21
|
}
|
|
24
22
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssertionError } from "assert";
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Asserts that a string matches a given regular expression
|
|
@@ -15,7 +15,7 @@ import { AssertionError } from "assert";
|
|
|
15
15
|
* @example
|
|
16
16
|
* this.assert.stringMatches(regex, haystack);
|
|
17
17
|
*/
|
|
18
|
-
export default function StringMatches(regex: RegExp, haystack
|
|
18
|
+
export default function StringMatches(regex: RegExp, haystack?: string | null, message?: string) {
|
|
19
19
|
if (haystack !== undefined && haystack !== null && regex.test(haystack)) {
|
|
20
20
|
return;
|
|
21
21
|
}
|
package/src/Assertions/Throws.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssertionError } from "assert";
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Asserts that an expression throws an error/exception
|
|
@@ -14,10 +14,10 @@ import { AssertionError } from "assert";
|
|
|
14
14
|
* @example
|
|
15
15
|
* this.assert.throws(() => expression);
|
|
16
16
|
*/
|
|
17
|
-
export default function Throws(expression: () =>
|
|
17
|
+
export default function Throws(expression: () => unknown, message?: string) {
|
|
18
18
|
try {
|
|
19
19
|
expression();
|
|
20
|
-
} catch
|
|
20
|
+
} catch {
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
|
package/src/Assertions/True.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssertionError } from "assert";
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Asserts that a given expression evaluates to `true`
|
|
@@ -14,7 +14,7 @@ import { AssertionError } from "assert";
|
|
|
14
14
|
* @example
|
|
15
15
|
* this.assert.true(expression);
|
|
16
16
|
*/
|
|
17
|
-
export default function True(expression:
|
|
17
|
+
export default function True(expression: unknown, message?: string) {
|
|
18
18
|
if (expression === true) {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AssertionError } from "assert";
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Asserts that a given value is equal to `undefined`
|
|
@@ -14,7 +14,7 @@ import { AssertionError } from "assert";
|
|
|
14
14
|
* @example
|
|
15
15
|
* this.assert.undefined(expression);
|
|
16
16
|
*/
|
|
17
|
-
export default function Undefined(expression:
|
|
17
|
+
export default function Undefined(expression: unknown, message?: string) {
|
|
18
18
|
if (expression === undefined) {
|
|
19
19
|
return;
|
|
20
20
|
}
|
package/src/Assertions/index.ts
CHANGED
|
@@ -1,39 +1,27 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import is_undefined from "./Undefined";
|
|
1
|
+
import contains from "./Contains";
|
|
2
|
+
import count from "./Count";
|
|
5
3
|
import is_defined from "./Defined";
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import not_null from "./NotNull";
|
|
9
|
-
|
|
10
|
-
import equal from "./Equal";
|
|
11
|
-
import not_equal from "./NotEqual";
|
|
12
|
-
|
|
4
|
+
import not_contains from "./DoesNotContain";
|
|
5
|
+
import does_not_throw from "./DoesNotThrow";
|
|
13
6
|
import empty from "./Empty";
|
|
7
|
+
import equal from "./Equal";
|
|
8
|
+
import is_false from "./False";
|
|
9
|
+
import instance_of from "./InstanceOf";
|
|
14
10
|
import not_empty from "./NotEmpty";
|
|
15
|
-
|
|
16
|
-
import
|
|
17
|
-
|
|
18
|
-
import contains from "./Contains";
|
|
19
|
-
import not_contains from "./DoesNotContain";
|
|
20
|
-
|
|
11
|
+
import not_equal from "./NotEqual";
|
|
12
|
+
import not_null from "./NotNull";
|
|
13
|
+
import is_null from "./Null";
|
|
21
14
|
import string_contains from "./StringContains";
|
|
22
15
|
import string_not_contains from "./StringDoesNotContain";
|
|
23
|
-
|
|
24
|
-
import
|
|
16
|
+
import string_not_ends from "./StringDoesNotEndWith";
|
|
17
|
+
import string_not_matches from "./StringDoesNotMatch";
|
|
25
18
|
import string_not_starts from "./StringDoesNotStartWith";
|
|
26
|
-
|
|
27
19
|
import string_ends from "./StringEndsWith";
|
|
28
|
-
import string_not_ends from "./StringDoesNotEndWith";
|
|
29
|
-
|
|
30
20
|
import string_matches from "./StringMatches";
|
|
31
|
-
import
|
|
32
|
-
|
|
33
|
-
import instance_of from "./InstanceOf";
|
|
34
|
-
|
|
21
|
+
import string_starts from "./StringStartsWith";
|
|
35
22
|
import throws from "./Throws";
|
|
36
|
-
import
|
|
23
|
+
import is_true from "./True";
|
|
24
|
+
import is_undefined from "./Undefined";
|
|
37
25
|
|
|
38
26
|
export default new class AssertionLibrary {
|
|
39
27
|
true = is_true;
|
package/src/CLI.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import Process from "process";
|
|
1
|
+
import Process from "node:process";
|
|
2
|
+
|
|
4
3
|
import Args from "command-line-args";
|
|
4
|
+
import Usage from "command-line-usage";
|
|
5
5
|
import SafeRegex from "lodash.escaperegexp";
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
import JUnitReporter from "./Reporters/JUnitReporter";
|
|
7
8
|
import SonarReporter from "./Reporters/SonarReporter";
|
|
9
|
+
import Runner from "./Runners/Runner";
|
|
8
10
|
|
|
9
11
|
export default class CLI {
|
|
10
12
|
private static readonly options: Usage.OptionDefinition[] = [
|
|
@@ -97,9 +99,10 @@ export default class CLI {
|
|
|
97
99
|
const runner = this.runnerFactory(args);
|
|
98
100
|
|
|
99
101
|
try {
|
|
100
|
-
const
|
|
102
|
+
const argFilter = args.filter as string[] | undefined;
|
|
103
|
+
const filters: string[] = argFilter ?? [];
|
|
101
104
|
const regexFilters = filters.map((f: string) => new RegExp(SafeRegex(f)));
|
|
102
|
-
const results = await runner.runAll(args.dir, regexFilters);
|
|
105
|
+
const results = await runner.runAll(args.dir as string, regexFilters);
|
|
103
106
|
return Runner.allTestsPassed(results);
|
|
104
107
|
} catch (error) {
|
|
105
108
|
if (error instanceof Error) {
|
package/src/Factory.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
|
|
1
3
|
import Args from "command-line-args";
|
|
2
|
-
|
|
4
|
+
|
|
3
5
|
import FileSystem from "./IO/FileSystem";
|
|
4
|
-
import JUnitReporter from "./Reporters/JUnitReporter";
|
|
5
6
|
import Output from "./IO/Output";
|
|
7
|
+
import ConsoleReporter from "./Reporters/ConsoleReporter";
|
|
8
|
+
import JUnitReporter from "./Reporters/JUnitReporter";
|
|
6
9
|
import ResultReporter from "./Reporters/ResultReporter";
|
|
10
|
+
import SonarReporter from "./Reporters/SonarReporter";
|
|
7
11
|
import Runner from "./Runners/Runner";
|
|
8
12
|
import TestRunner from "./Runners/TestRunner";
|
|
9
13
|
import TestSuiteLoader from "./Runners/TestSuiteLoader";
|
|
10
14
|
import TestSuiteRunner from "./Runners/TestSuiteRunner";
|
|
11
|
-
import fs from "fs/promises";
|
|
12
|
-
import SonarReporter from "./Reporters/SonarReporter";
|
|
13
15
|
|
|
14
16
|
export default class Factory {
|
|
15
17
|
static readonly file_system = new FileSystem(fs);
|
|
@@ -23,11 +25,11 @@ export default class Factory {
|
|
|
23
25
|
return new Runner(loader, test_suite_runner, reporters);
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
static Reporters(args: Args.CommandLineOptions):
|
|
28
|
+
static Reporters(args: Args.CommandLineOptions): readonly ResultReporter[] {
|
|
27
29
|
return [
|
|
28
|
-
|
|
29
|
-
args.junit
|
|
30
|
-
args.sonar
|
|
31
|
-
].filter(r => r !== null)
|
|
30
|
+
args.quiet ? null : new ConsoleReporter(new Output(process.stdout)),
|
|
31
|
+
args.junit === undefined ? null : new JUnitReporter(Factory.file_system, args.junit as string | undefined ?? JUnitReporter.defaultFileName),
|
|
32
|
+
args.sonar === undefined ? null : new SonarReporter(Factory.file_system, args.sonar as string | undefined ?? SonarReporter.defaultFileName)
|
|
33
|
+
].filter(r => r !== null);
|
|
32
34
|
}
|
|
33
35
|
}
|
package/src/Framework/Test.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
type
|
|
1
|
+
type AsyncTest = () => Promise<void>;
|
|
2
|
+
type SyncTest = () => void;
|
|
3
|
+
|
|
4
|
+
export type AsyncTestInfo = TypedPropertyDescriptor<AsyncTest>;
|
|
5
|
+
export type SyncTestInfo = TypedPropertyDescriptor<SyncTest>;
|
|
6
|
+
|
|
7
|
+
type TestInfo = AsyncTestInfo | SyncTestInfo;
|
|
2
8
|
export default TestInfo;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export default class TestName {
|
|
2
2
|
static toSentenceCase(test_name: string) {
|
|
3
3
|
const result = test_name
|
|
4
|
-
.
|
|
5
|
-
.
|
|
4
|
+
.replaceAll(/_([A-Z])/gi, (substring: string, match: string) => match.toUpperCase())
|
|
5
|
+
.replaceAll(/([A-Z])/g, " $1")
|
|
6
6
|
.trim();
|
|
7
7
|
return result.charAt(0).toUpperCase() + result.slice(1);
|
|
8
8
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import TestInfo from "./TestInfo";
|
|
2
1
|
import AssertionLibrary from "../Assertions";
|
|
2
|
+
import TestInfo from "./TestInfo";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Defines a container of tests
|
|
@@ -13,12 +13,10 @@ import AssertionLibrary from "../Assertions";
|
|
|
13
13
|
export default abstract class TestSuite {
|
|
14
14
|
assert = AssertionLibrary;
|
|
15
15
|
|
|
16
|
-
private tests
|
|
16
|
+
private tests?: Record<string, TestInfo> = {};
|
|
17
17
|
|
|
18
18
|
addTest(name: string, info: TestInfo) {
|
|
19
|
-
|
|
20
|
-
this.tests = {};
|
|
21
|
-
}
|
|
19
|
+
this.tests ??= {};
|
|
22
20
|
this.tests[name] = info;
|
|
23
21
|
}
|
|
24
22
|
|
|
@@ -33,14 +31,18 @@ export default abstract class TestSuite {
|
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
filteredTests(filters: RegExp[]) {
|
|
36
|
-
|
|
34
|
+
const tests = this.tests;
|
|
35
|
+
if (tests === undefined)
|
|
37
36
|
return {};
|
|
38
37
|
|
|
38
|
+
const keys = Object.keys(tests)
|
|
39
|
+
.filter(k => filters.map(f => f.test(`${this.constructor.name}.${tests[k].value?.name}`)).some(Boolean));
|
|
40
|
+
|
|
39
41
|
const filtered: Record<string, TestInfo> = {};
|
|
40
|
-
const keys = Object.keys(this.tests).filter(k => filters.map(f => f.test(`${this.constructor.name}.${this.tests[k].value?.name}`)).filter(m => m).length > 0);
|
|
41
42
|
keys.forEach(k => {
|
|
42
|
-
filtered[k] =
|
|
43
|
+
filtered[k] = tests[k];
|
|
43
44
|
});
|
|
45
|
+
|
|
44
46
|
return filtered;
|
|
45
47
|
}
|
|
46
48
|
}
|
package/src/IO/FileSystem.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import fs_promises from "fs/promises";
|
|
2
|
-
import path from "path";
|
|
1
|
+
import fs_promises from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
export default class FileSystem {
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ export default class FileSystem {
|
|
|
10
10
|
|
|
11
11
|
static extension(file: string) {
|
|
12
12
|
const match = this.matchExtension.exec(file);
|
|
13
|
-
return match
|
|
13
|
+
return match && match.length > 1
|
|
14
14
|
? match[1]
|
|
15
15
|
: "";
|
|
16
16
|
}
|
|
@@ -27,7 +27,7 @@ export default class FileSystem {
|
|
|
27
27
|
: [ item_path ]);
|
|
28
28
|
}
|
|
29
29
|
return files;
|
|
30
|
-
} catch
|
|
30
|
+
} catch {
|
|
31
31
|
return [];
|
|
32
32
|
}
|
|
33
33
|
}
|
package/src/IO/Output.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import TestName from "../Framework/TestName";
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import { AssertionError } from "node:assert";
|
|
3
|
+
|
|
5
4
|
import colors from "colors";
|
|
6
|
-
|
|
7
|
-
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
5
|
+
|
|
8
6
|
import { ResultType } from "../Framework/ResultType";
|
|
7
|
+
import TestName from "../Framework/TestName";
|
|
8
|
+
import TestSuite from "../Framework/TestSuite";
|
|
9
|
+
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
10
|
+
import Output from "../IO/Output";
|
|
11
|
+
import ResultReporter from "./ResultReporter";
|
|
9
12
|
|
|
10
13
|
export default class ConsoleReporter implements ResultReporter {
|
|
11
14
|
|
|
@@ -42,11 +45,10 @@ export default class ConsoleReporter implements ResultReporter {
|
|
|
42
45
|
testErrored(suite: TestSuite, test_name: string, error: Error, duration: number): void {
|
|
43
46
|
this.out.write(` (${Math.round(duration)} ms)`);
|
|
44
47
|
this.out.overwrite(` ${colors.red("✘")}\n`);
|
|
45
|
-
this.out.writeLine(` ${error.stack}`);
|
|
48
|
+
this.out.writeLine(` ${error.stack ?? ""}`);
|
|
46
49
|
this.out.writeLine();
|
|
47
50
|
}
|
|
48
51
|
|
|
49
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
50
52
|
testIncomplete(suite: TestSuite, test_name: string): void {
|
|
51
53
|
this.out.overwrite(` ${colors.yellow("?")}\n`);
|
|
52
54
|
}
|
|
@@ -61,15 +63,15 @@ export default class ConsoleReporter implements ResultReporter {
|
|
|
61
63
|
this.out.writeLine();
|
|
62
64
|
}
|
|
63
65
|
|
|
64
|
-
runCompleted(suites: Record<string, TestSuiteResults>): void {
|
|
66
|
+
async runCompleted(suites: Record<string, TestSuiteResults>): Promise<void> {
|
|
65
67
|
const results = Object.values(suites);
|
|
66
68
|
if (!results.length) {
|
|
67
69
|
this.out.writeLine("No tests found!");
|
|
68
|
-
return;
|
|
70
|
+
return Promise.resolve();
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
const sum = (result_type?: ResultType) => results
|
|
72
|
-
.map((suite_result) => result_type
|
|
74
|
+
.map((suite_result) => result_type === undefined ? suite_result.total() : suite_result.count(result_type))
|
|
73
75
|
.reduce((acc, current) => acc + current, 0);
|
|
74
76
|
|
|
75
77
|
const result = (result_type?: ResultType, color: (string: string) => string = colors.white) => {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import { AssertionError } from "node:assert";
|
|
3
|
+
|
|
3
4
|
import TestSuite from "../Framework/TestSuite";
|
|
4
|
-
import
|
|
5
|
+
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
5
6
|
import FileSystem from "../IO/FileSystem";
|
|
7
|
+
import ResultReporter from "./ResultReporter";
|
|
6
8
|
|
|
7
9
|
export default abstract class FileReporter implements ResultReporter {
|
|
8
|
-
|
|
10
|
+
|
|
9
11
|
constructor(protected readonly file_system: FileSystem, protected readonly path: string) {
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -41,5 +43,5 @@ export default abstract class FileReporter implements ResultReporter {
|
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
abstract runCompleted(results: Record<string, TestSuiteResults>): void
|
|
46
|
+
abstract runCompleted(results: Record<string, TestSuiteResults>): Promise<void>;
|
|
45
47
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
2
1
|
import xml from "xml";
|
|
3
|
-
|
|
2
|
+
|
|
4
3
|
import { ResultType } from "../Framework/ResultType";
|
|
4
|
+
import TestName from "../Framework/TestName";
|
|
5
5
|
import TestResult from "../Framework/TestResult";
|
|
6
|
+
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
6
7
|
import XMLReporter from "./XMLReporter";
|
|
7
8
|
|
|
8
9
|
export default class JUnitReporter extends XMLReporter {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
|
+
|
|
1
3
|
import TestSuite from "../Framework/TestSuite";
|
|
2
|
-
import { AssertionError } from "assert";
|
|
3
4
|
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
4
5
|
|
|
5
6
|
export default interface ResultReporter {
|
|
@@ -19,5 +20,5 @@ export default interface ResultReporter {
|
|
|
19
20
|
|
|
20
21
|
suiteCompleted(suite: TestSuite, results: TestSuiteResults): void;
|
|
21
22
|
|
|
22
|
-
runCompleted(results: Record<string, TestSuiteResults>): void
|
|
23
|
-
}
|
|
23
|
+
runCompleted(results: Record<string, TestSuiteResults>): Promise<void>;
|
|
24
|
+
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
2
3
|
import xml from "xml";
|
|
4
|
+
|
|
3
5
|
import { ResultType } from "../Framework/ResultType";
|
|
4
6
|
import TestResult from "../Framework/TestResult";
|
|
7
|
+
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
5
8
|
import XMLReporter from "./XMLReporter";
|
|
6
|
-
import path from "path";
|
|
7
9
|
|
|
8
10
|
export default class SonarReporter extends XMLReporter {
|
|
9
11
|
static readonly defaultFileName: string = "sonar.xml";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
2
|
+
import FileReporter from "./FileReporter";
|
|
3
3
|
|
|
4
4
|
export default abstract class XMLReporter extends FileReporter {
|
|
5
5
|
async runCompleted(results: Record<string, TestSuiteResults>): Promise<void> {
|
package/src/Runners/Runner.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { ResultType } from "../Framework/ResultType";
|
|
2
|
+
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
3
|
+
import ResultReporter from "../Reporters/ResultReporter";
|
|
1
4
|
import TestSuiteLoader from "./TestSuiteLoader";
|
|
2
5
|
import TestSuiteRunner from "./TestSuiteRunner";
|
|
3
|
-
import ResultReporter from "../Reporters/ResultReporter";
|
|
4
|
-
import TestSuiteResults from "../Framework/TestSuiteResults";
|
|
5
|
-
import { ResultType } from "../Framework/ResultType";
|
|
6
6
|
|
|
7
7
|
export default class Runner {
|
|
8
8
|
|
|
9
|
-
constructor(private readonly loader: TestSuiteLoader, private readonly runner: TestSuiteRunner, private readonly reporters:
|
|
9
|
+
constructor(private readonly loader: TestSuiteLoader, private readonly runner: TestSuiteRunner, private readonly reporters: readonly ResultReporter[]) {
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
static allTestsPassed(results: Record<string, TestSuiteResults>): boolean {
|
|
@@ -16,7 +16,7 @@ export default class Runner {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
async runAll(dir: string, filters: RegExp[]): Promise<Record<string, TestSuiteResults>> {
|
|
19
|
-
|
|
19
|
+
this.reporters.map(r => r.runStarted());
|
|
20
20
|
const results: Record<string, TestSuiteResults> = {};
|
|
21
21
|
const suites = await this.loader.loadTestSuites(dir, filters);
|
|
22
22
|
for (const file of Object.keys(suites)) {
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { AssertionError } from "node:assert";
|
|
2
|
+
|
|
3
3
|
import { ResultType } from "../Framework/ResultType";
|
|
4
|
-
import
|
|
4
|
+
import TestInfo, { AsyncTestInfo, SyncTestInfo } from "../Framework/TestInfo";
|
|
5
5
|
import TestResult from "../Framework/TestResult";
|
|
6
|
-
import
|
|
6
|
+
import TestSuite from "../Framework/TestSuite";
|
|
7
|
+
import ResultReporter from "../Reporters/ResultReporter";
|
|
7
8
|
|
|
8
9
|
export default class TestRunner {
|
|
9
10
|
|
|
10
|
-
constructor(private readonly reporters:
|
|
11
|
+
constructor(private readonly reporters: readonly ResultReporter[]) {
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
private static msSince(start: [ number, number ]) {
|
|
@@ -15,29 +16,36 @@ export default class TestRunner {
|
|
|
15
16
|
return duration[0] * 1_000 + duration[1] / 1_000_000;
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
private static isSyncTest = (test?: TestInfo): test is SyncTestInfo|undefined => test !== undefined;
|
|
20
|
+
private static isAsyncTest = (test?: TestInfo): test is AsyncTestInfo|undefined => test !== undefined;
|
|
21
|
+
|
|
18
22
|
async runTest(name: string, info: TestInfo, suite: TestSuite): Promise<TestResult> {
|
|
19
|
-
|
|
23
|
+
this.reporters.map(r => r.testStarted(suite, name));
|
|
20
24
|
if (info.value === undefined) {
|
|
21
|
-
|
|
25
|
+
this.reporters.map(r => r.testIncomplete(suite, name));
|
|
22
26
|
return new TestResult(ResultType.Incomplete, 0);
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
const start = process.hrtime();
|
|
26
30
|
try {
|
|
27
|
-
|
|
31
|
+
if (TestRunner.isAsyncTest(info))
|
|
32
|
+
await info.value.call(suite);
|
|
33
|
+
else if (TestRunner.isSyncTest(info))
|
|
34
|
+
info.value.call(suite);
|
|
35
|
+
|
|
28
36
|
const duration = TestRunner.msSince(start);
|
|
29
|
-
|
|
37
|
+
this.reporters.map(r => r.testPassed(suite, name, duration));
|
|
30
38
|
return new TestResult(ResultType.Passed, duration);
|
|
31
39
|
|
|
32
40
|
} catch (error) {
|
|
33
41
|
const duration = TestRunner.msSince(start);
|
|
34
42
|
const typedError = error as Error;
|
|
35
43
|
if (typedError instanceof AssertionError) {
|
|
36
|
-
|
|
44
|
+
this.reporters.map(r => r.testFailed(suite, name, typedError, duration));
|
|
37
45
|
return new TestResult(ResultType.Failed, duration, typedError);
|
|
38
46
|
}
|
|
39
47
|
|
|
40
|
-
|
|
48
|
+
this.reporters.map(r => r.testErrored(suite, name, typedError, duration));
|
|
41
49
|
return new TestResult(ResultType.Error, duration, typedError);
|
|
42
50
|
}
|
|
43
51
|
}
|