2020-08-10 20:10:39 -07:00
/ * *
* Copyright ( c ) Microsoft Corporation .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
const fs = require ( 'fs' ) ;
const path = require ( 'path' ) ;
2020-08-11 10:57:30 -07:00
const program = require ( 'commander' ) ;
const { Runner } = require ( './runner' ) ;
2020-08-11 19:44:13 -07:00
const Mocha = require ( 'mocha' ) ;
2020-08-12 13:47:44 -07:00
const constants = require ( 'mocha/lib/runner' ) . constants ;
2020-08-11 19:44:13 -07:00
const { fixturesUI } = require ( './fixturesUI' ) ;
2020-08-12 13:47:44 -07:00
const colors = require ( 'colors/safe' ) ;
2020-08-10 20:10:39 -07:00
2020-08-11 19:44:13 -07:00
class NullReporter { }
2020-08-10 20:10:39 -07:00
2020-08-11 10:57:30 -07:00
program
. version ( 'Version ' + require ( '../../package.json' ) . version )
2020-08-12 14:57:37 -07:00
. option ( '--forbid-only' , 'Fail if exclusive test(s) encountered' , false )
. option ( '-g, --grep <grep>' , 'Only run tests matching this string or regexp' , '.*' )
. option ( '-j, --jobs <jobs>' , 'Number of concurrent jobs for --parallel; use 1 to run in serial, default: (number of CPU cores / 2)' , Math . ceil ( require ( 'os' ) . cpus ( ) . length / 2 ) )
. option ( '--reporter <reporter>' , 'Specify reporter to use' , '' )
. option ( '--timeout <timeout>' , 'Specify test timeout threshold (in milliseconds), default: 10000' , 10000 )
2020-08-11 19:44:13 -07:00
. action ( async ( command ) => {
// Collect files
2020-08-12 11:48:30 -07:00
const files = [ ] ;
collectFiles ( path . join ( process . cwd ( ) , 'test' ) , command . args , files ) ;
2020-08-11 19:44:13 -07:00
const rootSuite = new Mocha . Suite ( '' , new Mocha . Context ( ) , true ) ;
2020-08-12 14:57:37 -07:00
console . log ( ` Parsing ${ files . length } test files ` ) ;
let total = 0 ;
2020-08-11 19:44:13 -07:00
// Build the test model, suite per file.
for ( const file of files ) {
const mocha = new Mocha ( {
2020-08-12 14:57:37 -07:00
forbidOnly : command . forbidOnly || undefined ,
reporter : NullReporter ,
2020-08-11 19:44:13 -07:00
retries : command . retries ,
timeout : command . timeout ,
2020-08-12 14:57:37 -07:00
ui : fixturesUI . bind ( null , true ) ,
2020-08-11 19:44:13 -07:00
} ) ;
2020-08-12 14:57:37 -07:00
if ( command . grep )
mocha . grep ( command . grep ) ;
2020-08-11 19:44:13 -07:00
mocha . addFile ( file ) ;
2020-08-12 14:57:37 -07:00
let runner ;
2020-08-12 13:47:44 -07:00
await new Promise ( f => {
2020-08-12 14:57:37 -07:00
runner = mocha . run ( f ) ;
2020-08-12 13:47:44 -07:00
runner . on ( constants . EVENT _RUN _BEGIN , ( ) => {
process . stdout . write ( colors . yellow ( '\u00B7' ) ) ;
} ) ;
} ) ;
2020-08-12 14:57:37 -07:00
total += runner . grepTotal ( mocha . suite ) ;
rootSuite . addSuite ( mocha . suite ) ;
mocha . suite . title = path . basename ( file ) ;
2020-08-11 10:57:30 -07:00
}
2020-08-12 14:57:37 -07:00
if ( rootSuite . hasOnly ( ) )
rootSuite . filterOnly ( ) ;
2020-08-12 13:47:44 -07:00
console . log ( ) ;
2020-08-12 14:57:37 -07:00
total = Math . min ( total , rootSuite . total ( ) ) ; // First accounts for grep, second for only.
console . log ( ` Running ${ total } tests using ${ Math . min ( command . jobs , total ) } workers ` ) ;
2020-08-10 20:10:39 -07:00
2020-08-11 19:44:13 -07:00
const runner = new Runner ( rootSuite , {
2020-08-12 14:57:37 -07:00
grep : command . grep ,
jobs : command . jobs ,
2020-08-11 19:44:13 -07:00
reporter : command . reporter ,
retries : command . retries ,
timeout : command . timeout ,
2020-08-11 10:57:30 -07:00
} ) ;
await runner . run ( files ) ;
await runner . stop ( ) ;
} ) ;
2020-08-10 20:10:39 -07:00
2020-08-11 10:57:30 -07:00
program . parse ( process . argv ) ;
2020-08-11 19:44:13 -07:00
2020-08-12 11:48:30 -07:00
function collectFiles ( dir , filters , files ) {
for ( const name of fs . readdirSync ( dir ) ) {
if ( fs . lstatSync ( path . join ( dir , name ) ) . isDirectory ( ) ) {
collectFiles ( path . join ( dir , name ) , filters , files ) ;
continue ;
}
if ( ! name . includes ( 'spec' ) )
2020-08-11 19:44:13 -07:00
continue ;
2020-08-12 11:48:30 -07:00
if ( ! filters . length ) {
files . push ( path . join ( dir , name ) ) ;
2020-08-11 19:44:13 -07:00
continue ;
}
2020-08-12 11:48:30 -07:00
for ( const filter of filters ) {
2020-08-11 19:44:13 -07:00
if ( name . includes ( filter ) ) {
2020-08-12 11:48:30 -07:00
files . push ( path . join ( dir , name ) ) ;
2020-08-11 19:44:13 -07:00
break ;
}
}
}
}