module main import ( os term benchmark ) struct TestSession { mut: files []string vexe string vargs string failed bool benchmark benchmark.Benchmark } pub fn new_test_sesion(vargs string) TestSession { return TestSession{ vexe: vexe_path() vargs: vargs } } fn vexe_path() string { // NB: tools extracted from v require that the first // argument to them to be the v executable location. // They are usually launched by vlib/compiler/vtools.v, // launch_tool/1 , which provides it. return os.args[1] } pub fn main() { args := os.args if args.last() == 'test' { println('Usage:') println(' A)') println(' v test v : run all v tests and build all the examples') println(' B)') println(' v test folder/ : run all v tests in the given folder.') println(' v -stats test folder/ : the same, but print more stats.') println(' C)') println(' v test file_test.v : run test functions in a given test file.') println(' v -stats test file_test.v : as above, but with more stats.') println(' NB: you can also give many and mixed folder/ file_test.v arguments after test.') println('') return } args_string := args[1..].join(' ') args_before := args_string.all_before('test ') args_after := args_string.all_after('test ') if args_after == 'v' { v_test_v(args_before) return } mut ts := new_test_sesion(args_before) for targ in args_after.split(' ') { if os.file_exists(targ) && targ.ends_with('_test.v') { ts.files << targ continue } if os.dir_exists(targ) { // Fetch all tests from the directory ts.files << os.walk_ext( targ.trim_right(os.path_separator), '_test.v') continue } println('Unrecognized test file $targ .') } println('Testing...') ts.test() println('----------------------------------------------------------------------------') println( ts.benchmark.total_message('running V _test.v files') ) if ts.failed { exit(1) } } pub fn (ts mut TestSession) test() { ok := term.ok_message('OK') fail := term.fail_message('FAIL') show_stats := '-stats' in ts.vargs.split(' ') ts.benchmark = benchmark.new_benchmark() for dot_relative_file in ts.files { relative_file := dot_relative_file.replace('./', '') file := os.realpath( relative_file ) $if windows { if file.contains('sqlite') { continue } } $if msvc { if file.contains('asm') { continue } } $if tinyc { if file.contains('asm') { continue } } tmpc_filepath := file.replace('.v', '.tmp.c') cmd := '"$ts.vexe" $ts.vargs "$file"' ts.benchmark.step() if show_stats { println('-------------------------------------------------') status := os.system(cmd) if status == 0 { ts.benchmark.ok() }else{ ts.benchmark.fail() ts.failed = true continue } }else{ r := os.exec(cmd) or { ts.benchmark.fail() ts.failed = true println(ts.benchmark.step_message('$relative_file $fail')) continue } if r.exit_code != 0 { ts.benchmark.fail() ts.failed = true println(ts.benchmark.step_message('$relative_file $fail\n`$file`\n (\n$r.output\n)')) } else { ts.benchmark.ok() println(ts.benchmark.step_message('$relative_file $ok')) } } os.rm( tmpc_filepath ) } ts.benchmark.stop() } pub fn v_test_v(args_before_test string){ vexe := vexe_path() parent_dir := os.dir(vexe) // Changing the current directory is needed for some of the compiler tests, // compiler/tests/local_test.v and compiler/tests/repl/repl_test.v os.chdir( parent_dir ) if !os.dir_exists(parent_dir + '/vlib') { println('vlib/ is missing, it must be next to the V executable') exit(1) } /* if !os.file_exists(parent_dir + '/v.v') { println('v.v is missing, it must be next to the V executable') exit(1) } */ // Make sure v.c can be compiled without warnings $if mac { if os.file_exists('/v.v') { os.system('$vexe -o v.c v.v') if os.system('cc -Werror v.c') != 0 { println('cc failed to build v.c without warnings') exit(1) } println('v.c can be compiled without warnings. This is good :)') } } // println('Testing...') mut ts := new_test_sesion( args_before_test ) ts.files << os.walk_ext(parent_dir, '_test.v') ts.test() println( ts.benchmark.total_message('running V tests') ) // println('\nBuilding examples...') mut es := new_test_sesion( args_before_test ) files := os.walk_ext(parent_dir+'/examples','.v') stable := files.filter(!it.contains('automaton.v') && !it.contains('some_module.v')) es.files << stable es.test() println( es.benchmark.total_message('building examples') ) // test_vget() if ts.failed || es.failed { exit(1) } } pub fn test_vget() { /* vexe := vexe_path() ret := os.system('$vexe install nedpals.args') if ret != 0 { println('failed to run v install') exit(1) } if !os.file_exists(v_modules_path + '/nedpals/args') { println('v failed to install a test module') exit(1) } println('vget is OK') */ }