diff --git a/vlib/compiler/tests/prod/.gitignore b/vlib/compiler/tests/prod/.gitignore new file mode 100644 index 0000000000..74cb147f53 --- /dev/null +++ b/vlib/compiler/tests/prod/.gitignore @@ -0,0 +1,2 @@ +/*.prod +/*.result.txt diff --git a/vlib/compiler/tests/prod/assoc.prod.v b/vlib/compiler/tests/prod/assoc.prod.v new file mode 100644 index 0000000000..2abf7f32aa --- /dev/null +++ b/vlib/compiler/tests/prod/assoc.prod.v @@ -0,0 +1,14 @@ +struct MyStruct { + s string +} +fn new_st() MyStruct { + return MyStruct{} +} +fn get_st() MyStruct { + r := new_st() + return {r|s:'6'} +} +fn main() { + s := get_st() + println(s) +} \ No newline at end of file diff --git a/vlib/compiler/tests/prod/assoc.prod.v.expected.txt b/vlib/compiler/tests/prod/assoc.prod.v.expected.txt new file mode 100644 index 0000000000..0d8e50ab55 --- /dev/null +++ b/vlib/compiler/tests/prod/assoc.prod.v.expected.txt @@ -0,0 +1,3 @@ +{ + s: 6 +} \ No newline at end of file diff --git a/vlib/compiler/tests/prod_test.v b/vlib/compiler/tests/prod_test.v new file mode 100644 index 0000000000..21da8c3020 --- /dev/null +++ b/vlib/compiler/tests/prod_test.v @@ -0,0 +1,29 @@ +// Build and run files in ./prod/ folder, comparing their output to *.expected.txt files. +// (Similar to REPL tests, but in -prod mode.) + +// import os +import compiler.tests.repl.runner +import benchmark + +fn test_all_v_prod_files() { + // TODO: Fix running this test on Windows: + $if !windows { + options := runner.new_prod_options() + mut bmark := benchmark.new_benchmark() + for file in options.files { + // println('file:$file') + bmark.step() + fres := runner.run_prod_file(options.wd, options.vexec, file) or { + bmark.fail() + eprintln( bmark.step_message(err) ) + assert false + continue + } + bmark.ok() + println( bmark.step_message(fres) ) + assert true + } + bmark.stop() + println( bmark.total_message('total time spent running PROD files') ) + } +} \ No newline at end of file diff --git a/vlib/compiler/tests/repl/repl_test.v b/vlib/compiler/tests/repl/repl_test.v index c2160b26b7..21160c3159 100644 --- a/vlib/compiler/tests/repl/repl_test.v +++ b/vlib/compiler/tests/repl/repl_test.v @@ -3,7 +3,7 @@ import compiler.tests.repl.runner import benchmark fn test_the_v_compiler_can_be_invoked() { - vexec := runner.full_path_to_v() + vexec := runner.full_path_to_v(5) println('vexecutable: $vexec') assert vexec != '' diff --git a/vlib/compiler/tests/repl/runner/runner.v b/vlib/compiler/tests/repl/runner/runner.v index 3f454d305d..bb52ad6b23 100644 --- a/vlib/compiler/tests/repl/runner/runner.v +++ b/vlib/compiler/tests/repl/runner/runner.v @@ -9,9 +9,13 @@ pub: files []string } -pub fn full_path_to_v() string { - vname := if os.user_os() == 'windows' { 'v.exe' } else { 'v' } - vexec := os.dir(os.dir(os.dir(os.dir(os.dir( os.executable() ))))) + os.path_separator + vname +pub fn full_path_to_v(dirs_in int) string { + vname := if os.user_os() == 'windows' { 'v.exe' } else { 'v' } + mut path := os.executable() + for i := 0; i < dirs_in; i++ { + path = os.dir(path) + } + vexec := path + os.path_separator + vname /* args := os.args vreal := os.realpath('v') @@ -75,9 +79,42 @@ $diff } } +pub fn run_prod_file(wd string, vexec string, file string) ?string { + file_expected := '${file}.expected.txt' + f_expected_content := os.read_file(file_expected) or { return error('Could not read file $file') } + expected_content := f_expected_content.replace('\r', '') + + cmd := '"$vexec" -prod run "$file"' + r := os.exec(cmd) or { + return error('Could not execute: $cmd') + } + + if r.exit_code != 0 { + return error('$cmd return exit code: $r.exit_code') + } + + result := r.output.replace('\r','') + + if result != expected_content { + file_result := '${file}.result.txt' + os.write_file( file_result, result ) + diff := diff_files( file_result, file_expected ) + return error('Difference found in test: $file +====> Got : +|$result| +====> Expected : +|$expected_content| +====> Diff : +$diff + ') + } else { + return 'Prod file $file is OK' + } +} + pub fn new_options() RunnerOptions { wd := os.getwd() + os.path_separator - vexec := full_path_to_v() + vexec := full_path_to_v(5) mut files := []string if os.args.len > 1 { files = os.args[1..] @@ -91,3 +128,19 @@ pub fn new_options() RunnerOptions { } } +pub fn new_prod_options() RunnerOptions { + wd := os.getwd() + os.path_separator + vexec := full_path_to_v(4) + mut files := []string + if os.args.len > 1 { + files = os.args[1..] + } else { + files = os.walk_ext(wd, '.prod.v') + } + return RunnerOptions { + wd: wd + vexec: vexec + files: files + } +} + diff --git a/vlib/os/os.v b/vlib/os/os.v index d56868c7bc..84778806d5 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -856,11 +856,12 @@ pub fn walk_ext(path, ext string) []string { } mut files := os.ls(path) or { panic(err) } mut res := []string + separator := if path.ends_with(path_separator) { '' } else { path_separator} for i, file in files { if file.starts_with('.') { continue } - p := path + path_separator + file + p := path + separator + file if os.is_dir(p) { res << walk_ext(p, ext) }