| 1 | import os |
| 2 | import encoding.txtar |
| 3 | |
| 4 | const vexe = @VEXE |
| 5 | const vroot = os.dir(vexe) |
| 6 | const tpath = os.join_path(os.vtmp_dir(), 'vtest_folder') |
| 7 | const tpath_passing = os.join_path(tpath, 'passing') |
| 8 | const tpath_impure = os.join_path(tpath, 'impure') |
| 9 | const tpath_js_runtime_error = os.join_path(tpath, 'js_runtime_error') |
| 10 | const tpath_partial = os.join_path(tpath, 'partial') |
| 11 | const mytest_exe = os.join_path(tpath, 'mytest.exe') |
| 12 | |
| 13 | fn testsuite_end() { |
| 14 | os.rmdir_all(tpath) or {} |
| 15 | } |
| 16 | |
| 17 | fn testsuite_begin() { |
| 18 | os.setenv('VFLAGS', '', true) |
| 19 | os.setenv('VCOLORS', 'never', true) |
| 20 | os.setenv('VJOBS', '2', true) |
| 21 | os.setenv('VTEST_HIDE_OK', '0', true) |
| 22 | os.rmdir_all(tpath) or {} |
| 23 | os.mkdir_all(tpath)! |
| 24 | |
| 25 | txtar.parse('Some known test files to make sure `v test` and `v -stats test` work: |
| 26 | -- passing/1_test.v -- |
| 27 | fn test_abc() { assert true; assert true; assert true } |
| 28 | fn test_def() { assert 2 * 2 == 4 } |
| 29 | -- passing/2_test.v -- |
| 30 | fn test_xyz() { assert 1 == 2 - 1 } |
| 31 | fn test_abc() { assert 10 == 2 * 5 } |
| 32 | -- impure/warning_test.v -- |
| 33 | fn test_warning() { |
| 34 | C.printf(c"") |
| 35 | } |
| 36 | -- js_runtime_error/runtime_error_test.js.v -- |
| 37 | fn test_runtime_error() { |
| 38 | JS.eval("(()=>{ throw new TypeError(`boom`) })()".str) |
| 39 | } |
| 40 | -- partial/passing_test.v -- |
| 41 | fn test_xyz() { assert 3 == 10 - 7 } |
| 42 | fn test_def() { assert 10 == 100 / 10 } |
| 43 | -- partial/failing_test.v -- |
| 44 | fn test_xyz() { assert 5 == 7, "oh no" } |
| 45 | ').unpack_to(tpath)! |
| 46 | assert os.exists(os.join_path(tpath, 'passing/1_test.v')) |
| 47 | assert os.exists(os.join_path(tpath, 'passing/2_test.v')) |
| 48 | assert os.exists(os.join_path(tpath, 'impure/warning_test.v')) |
| 49 | assert os.exists(os.join_path(tpath, 'js_runtime_error/runtime_error_test.js.v')) |
| 50 | assert os.exists(os.join_path(tpath, 'partial/passing_test.v')) |
| 51 | assert os.exists(os.join_path(tpath, 'partial/failing_test.v')) |
| 52 | } |
| 53 | |
| 54 | fn test_vtest_executable_compiles() { |
| 55 | os.chdir(vroot)! |
| 56 | os.execute_or_exit('${os.quoted_path(vexe)} -o ${tpath}/mytest.exe cmd/tools/vtest.v') |
| 57 | assert os.exists(mytest_exe), 'executable file: `${mytest_exe}` should exist' |
| 58 | } |
| 59 | |
| 60 | fn test_with_several_test_files() { |
| 61 | res := os.execute_or_exit('${os.quoted_path(mytest_exe)} test ${os.quoted_path(tpath_passing)}') |
| 62 | assert !res.output.contains('1 assert'), res.output |
| 63 | assert !res.output.contains('3 asserts'), res.output |
| 64 | assert res.output.contains('2 passed, 2 total'), res.output |
| 65 | assert res.output.count('OK') == 2, res.output |
| 66 | assert res.output.contains('on 2 parallel jobs'), res.output |
| 67 | } |
| 68 | |
| 69 | fn test_with_stats_and_several_test_files() { |
| 70 | // There should be more OKs here, since the output will have the inner OKs for each individual test fn: |
| 71 | res := |
| 72 | os.execute_or_exit('${os.quoted_path(mytest_exe)} -stats test ${os.quoted_path(tpath_passing)}') |
| 73 | assert res.output.contains('1 assert'), res.output |
| 74 | assert res.output.contains('3 asserts'), res.output |
| 75 | assert res.output.contains('2 passed, 2 total'), res.output |
| 76 | assert res.output.count('OK') == 6, res.output |
| 77 | run_1 := '1_test.v\n OK' |
| 78 | run_2 := '2_test.v\n OK' |
| 79 | summary_1 := 'Summary for running V tests in "1_test.v"' |
| 80 | summary_2 := 'Summary for running V tests in "2_test.v"' |
| 81 | run_1_idx := res.output.index(run_1) or { -1 } |
| 82 | run_2_idx := res.output.index(run_2) or { -1 } |
| 83 | summary_1_idx := res.output.index(summary_1) or { -1 } |
| 84 | summary_2_idx := res.output.index(summary_2) or { -1 } |
| 85 | assert run_1_idx != -1, res.output |
| 86 | assert run_2_idx != -1, res.output |
| 87 | assert summary_1_idx != -1, res.output |
| 88 | assert summary_2_idx != -1, res.output |
| 89 | assert run_1_idx < summary_1_idx, res.output |
| 90 | assert run_2_idx < summary_2_idx, res.output |
| 91 | assert summary_1_idx < run_2_idx || summary_2_idx < run_1_idx, res.output |
| 92 | } |
| 93 | |
| 94 | fn test_partial_failure() { |
| 95 | res := os.execute('${os.quoted_path(mytest_exe)} test ${os.quoted_path(tpath_partial)}') |
| 96 | assert res.exit_code == 1 |
| 97 | assert res.output.contains('assert 5 == 7'), res.output |
| 98 | assert res.output.contains(' 1 failed, 1 passed, 2 total'), res.output |
| 99 | assert res.output.contains('To reproduce just failure'), res.output |
| 100 | } |
| 101 | |
| 102 | fn test_run_only_reports_filtered_failures() { |
| 103 | failing_test_path := os.join_path(tpath_partial, 'failing_test.v') |
| 104 | res := |
| 105 | os.execute('${os.quoted_path(mytest_exe)} test -run-only test_xyz ${os.quoted_path(failing_test_path)}') |
| 106 | assert res.exit_code == 1 |
| 107 | assert res.output.contains('assert 5 == 7'), res.output |
| 108 | assert res.output.contains(' 1 failed, 1 total'), res.output |
| 109 | } |
| 110 | |
| 111 | fn test_wimpure_v_warnings_are_shown_for_test_files() { |
| 112 | res := |
| 113 | os.execute_or_exit('${os.quoted_path(mytest_exe)} -Wimpure-v test ${os.quoted_path(tpath_impure)}') |
| 114 | assert res.output.contains('warning_test.v'), res.output |
| 115 | assert res.output.contains('warning: C code will not be allowed in pure .v files'), res.output |
| 116 | } |
| 117 | |
| 118 | fn test_js_runtime_errors_are_shown_for_js_tests() { |
| 119 | if @CCOMPILER.contains('musl') || os.getenv('VFLAGS').contains('musl') |
| 120 | || os.getenv('V_CI_MUSL') == '1' { |
| 121 | return |
| 122 | } |
| 123 | if os.execute('node --version').exit_code != 0 { |
| 124 | return |
| 125 | } |
| 126 | res := |
| 127 | os.execute('${os.quoted_path(mytest_exe)} test ${os.quoted_path(tpath_js_runtime_error)}') |
| 128 | assert res.exit_code == 1, res.output |
| 129 | assert res.output.contains('runtime_error_test.js.v'), res.output |
| 130 | assert res.output.contains('TypeError: boom'), res.output |
| 131 | } |
| 132 | |
| 133 | fn test_with_stats_and_partial_failure() { |
| 134 | res := os.execute('${os.quoted_path(mytest_exe)} -stats test ${os.quoted_path(tpath_partial)}') |
| 135 | assert res.exit_code == 1 |
| 136 | assert res.output.contains('assert 5 == 7'), res.output |
| 137 | assert res.output.contains(' 1 failed, 1 passed, 2 total'), res.output |
| 138 | assert res.output.contains('To reproduce just failure'), res.output |
| 139 | } |
| 140 | |