1
+ const fs = require ( 'fs' )
2
+ const dir = require ( 'node-dir' )
3
+ const path = require ( 'path' )
4
+
5
+ const falsePredicate = ( ) => false
6
+ // package.json -> always take the package root, remove filename, go to submodule
7
+ const defaultTestsPath = path . join ( path . dirname ( require . resolve ( "ethereumjs-testing/package.json" ) ) , 'tests' )
8
+
9
+ /**
10
+ * Returns the list of test files matching the given parameters
11
+ * @param {string } testType the test type (path segment)
12
+ * @param {Function } onFile a callback for each file
13
+ * @param {RegExp|Array<string> } fileFilter a {@code RegExp} or array to specify filenames to operate on
14
+ * @param {Function<boolean> } skipPredicate a filtering function for test names
15
+ * @param {string } testDir the directory inside the {@code tests/} directory to use
16
+ * @param {RegExp|Array<string> } excludeDir a {@code RegExp} or array to specify directories to ignore
17
+ * @param {string } testsPath the path to the {@code tests/} directory
18
+ * @return {Promise<Array<string>> } the list of test files
19
+ */
20
+ const getTests = exports . getTests = (
21
+ testType ,
22
+ onFile ,
23
+ fileFilter = / .j s o n $ / ,
24
+ skipPredicate = falsePredicate ,
25
+ testDir = '' ,
26
+ excludeDir = '' ,
27
+ testsPath = defaultTestsPath
28
+ ) => {
29
+ const directory = path . join ( testsPath , testType , testDir )
30
+ const options = {
31
+ match : fileFilter ,
32
+ excludeDir : excludeDir
33
+ }
34
+
35
+ return new Promise ( ( resolve , reject ) => {
36
+ const finishedCallback = ( err , files ) => {
37
+ if ( err ) {
38
+ reject ( err )
39
+ return
40
+ }
41
+
42
+ resolve ( files )
43
+ }
44
+
45
+ const fileCallback = async ( err , content , fileName , next ) => {
46
+ if ( err ) {
47
+ reject ( err )
48
+ return
49
+ }
50
+
51
+ const parsedFileName = path . parse ( fileName ) . name
52
+ const testsByName = JSON . parse ( content )
53
+ const testNames = Object . keys ( testsByName )
54
+ for ( const testName of testNames ) {
55
+ if ( ! skipPredicate ( testName ) ) {
56
+ await onFile ( parsedFileName , testName , testsByName [ testName ] )
57
+ }
58
+ }
59
+
60
+ next ( )
61
+ }
62
+
63
+ dir . readFiles ( directory , options , fileCallback , finishedCallback )
64
+ } )
65
+ }
66
+
67
+ function skipTest ( testName , skipList = [ ] ) {
68
+ return skipList . map ( ( skipName ) => ( new RegExp ( `^${ skipName } ` ) ) . test ( testName ) ) . some ( isMatch => isMatch )
69
+ }
70
+
71
+ /**
72
+ * Loads a single test specified in a file
73
+ * @method getTestFromSource
74
+ * @param {String } file or path to load a single test from
75
+ * @param {Function } Callback function which is invoked, and passed the contents of the specified file (or an error message)
76
+ */
77
+ const getTestFromSource = exports . getTestFromSource = function ( file , onFile ) {
78
+ let stream = fs . createReadStream ( file )
79
+ let contents = ''
80
+ let test = null
81
+
82
+ stream . on ( 'data' , function ( data ) {
83
+ contents += data
84
+ } ) . on ( 'error' , function ( err ) {
85
+ onFile ( err )
86
+ } ) . on ( 'end' , function ( ) {
87
+ try {
88
+ test = JSON . parse ( contents )
89
+ } catch ( e ) {
90
+ onFile ( e )
91
+ }
92
+
93
+ let testName = Object . keys ( test ) [ 0 ]
94
+ let testData = test [ testName ]
95
+ testData . testName = testName
96
+
97
+ onFile ( null , testData )
98
+ } )
99
+ }
100
+
101
+ exports . getTestsFromArgs = function ( testType , onFile , args = { } ) {
102
+ let testsPath , testDir , fileFilter , excludeDir , skipFn
103
+
104
+ skipFn = ( name ) => {
105
+ return skipTest ( name , args . skipTests )
106
+ }
107
+
108
+ if ( testType === 'BlockchainTests' ) {
109
+ const forkFilter = new RegExp ( `${ args . forkConfig } $` )
110
+ skipFn = ( name ) => {
111
+ return ( ( forkFilter . test ( name ) === false ) || skipTest ( name , args . skipTests ) )
112
+ }
113
+ }
114
+
115
+ if ( testType === 'VMTests' ) {
116
+ skipFn = ( name ) => {
117
+ return skipTest ( name , args . skipVM )
118
+ }
119
+ }
120
+
121
+ if ( args . singleSource ) {
122
+ return getTestFromSource ( args . singleSource , onFile )
123
+ }
124
+
125
+ if ( args . dir ) {
126
+ testDir = args . dir
127
+ }
128
+
129
+ if ( args . file ) {
130
+ fileFilter = new RegExp ( args . file )
131
+ }
132
+
133
+ if ( args . excludeDir ) {
134
+ excludeDir = new RegExp ( args . excludeDir )
135
+ }
136
+
137
+ if ( args . test ) {
138
+ skipFn = ( testName ) => {
139
+ return testName !== args . test
140
+ }
141
+ }
142
+
143
+ if ( args . testsPath ) {
144
+ testsPath = args . testsPath
145
+ }
146
+
147
+ return getTests ( testType , onFile , fileFilter , skipFn , testDir , excludeDir , testsPath )
148
+ }
149
+
150
+ exports . getSingleFile = ( file ) => {
151
+ return require ( path . join ( defaultTestsPath , file ) )
152
+ }
0 commit comments