1
1
import type { HardhatConfig } from "@ignored/hardhat-vnext/types/config" ;
2
2
import type { NewTaskActionFunction } from "@ignored/hardhat-vnext/types/tasks" ;
3
3
4
+ import { finished } from "node:stream/promises" ;
4
5
import { run } from "node:test" ;
5
6
import { fileURLToPath } from "node:url" ;
6
7
@@ -20,6 +21,15 @@ function isJavascriptFile(path: string): boolean {
20
21
return / \. ( j s | c j s | m j s ) $ / i. test ( path ) ;
21
22
}
22
23
24
+ function isSubtestFailedError ( error : Error ) : boolean {
25
+ return (
26
+ "code" in error &&
27
+ "failureType" in error &&
28
+ error . code === "ERR_TEST_FAILURE" &&
29
+ error . failureType === "subtestsFailed"
30
+ ) ;
31
+ }
32
+
23
33
async function getTestFiles (
24
34
testFiles : string [ ] ,
25
35
config : HardhatConfig ,
@@ -34,6 +44,9 @@ async function getTestFiles(
34
44
) ;
35
45
}
36
46
47
+ /**
48
+ * Note that we are testing this manually for now as you can't run a node:test within a node:test
49
+ */
37
50
const testWithHardhat : NewTaskActionFunction < TestActionArguments > = async (
38
51
{ testFiles, only } ,
39
52
hre ,
@@ -43,7 +56,37 @@ const testWithHardhat: NewTaskActionFunction<TestActionArguments> = async (
43
56
const tsx = fileURLToPath ( import . meta. resolve ( "tsx/esm" ) ) ;
44
57
process . env . NODE_OPTIONS = `--import ${ tsx } ` ;
45
58
46
- run ( { files, only } ) . compose ( hardhatTestReporter ) . pipe ( process . stdout ) ;
59
+ async function runTests ( ) : Promise < number > {
60
+ let failures = 0 ;
61
+ const reporterStream = run ( { files, only } )
62
+ . on ( "test:fail" , ( event ) => {
63
+ if ( event . details . type === "suite" ) {
64
+ // If a suite failed only because a subtest failed, we don't want to
65
+ // count it as a failure since the subtest failure will be reported as well
66
+ if ( isSubtestFailedError ( event . details . error ) ) {
67
+ return ;
68
+ }
69
+ }
70
+
71
+ failures ++ ;
72
+ } )
73
+ . compose ( hardhatTestReporter ) ;
74
+
75
+ reporterStream . pipe ( process . stdout ) ;
76
+
77
+ await finished ( reporterStream ) ;
78
+
79
+ return failures ;
80
+ }
81
+
82
+ const testFailures = await runTests ( ) ;
83
+ console . log ( "Failures: " , testFailures ) ;
84
+
85
+ if ( testFailures > 0 ) {
86
+ process . exitCode = testFailures ;
87
+ }
88
+
89
+ return testFailures ;
47
90
} ;
48
91
49
92
export default testWithHardhat ;
0 commit comments