diff --git a/vlib/compiler/tests/array_to_string_test.v b/vlib/compiler/tests/array_to_string_test.v new file mode 100644 index 0000000000..08e1001d18 --- /dev/null +++ b/vlib/compiler/tests/array_to_string_test.v @@ -0,0 +1,5 @@ +fn test_array_to_string_conversion() { + expected := '["1", "2", "3", "4"] ' + arr := ['1', '2', '3', '4'] + assert '$arr' == expected +} diff --git a/vlib/compiler/tests/repl/arr_decl.repl b/vlib/compiler/tests/repl/arr_decl.repl deleted file mode 100644 index 1e7472a04a..0000000000 --- a/vlib/compiler/tests/repl/arr_decl.repl +++ /dev/null @@ -1,4 +0,0 @@ -arr := ['1', '2', '3', '4'] -println(arr) -===output=== -["1", "2", "3", "4"] diff --git a/vlib/compiler/tests/repl/chained_fields.correct.repl b/vlib/compiler/tests/repl/chained_fields.correct.repl deleted file mode 100644 index 81597218c6..0000000000 --- a/vlib/compiler/tests/repl/chained_fields.correct.repl +++ /dev/null @@ -1,16 +0,0 @@ -struct A { mut: v int } struct B { a A } struct C { mut: b B } struct D { mut: c C } struct E { mut: v []int } struct F { e []E } - -mut b := B{} b = B{A{2}} -println('b is: ' + b.a.v.str()) - -mut c := C{} c.b = B{} - -mut d := D{} d.c.b = B{} - -f := F{[E{[10,20,30]},E{[100,200,300,400]}]} -println('f.e[0].v.len: ${f.e[0].v.len}') -println('f.e[1].v.len: ${f.e[1].v.len}') -===output=== -b is: 2 -f.e[0].v.len: 3 -f.e[1].v.len: 4 diff --git a/vlib/compiler/tests/repl/chained_fields.repl b/vlib/compiler/tests/repl/chained_fields.repl deleted file mode 100644 index e62ead43e2..0000000000 --- a/vlib/compiler/tests/repl/chained_fields.repl +++ /dev/null @@ -1,78 +0,0 @@ -/* 1 */ struct A { mut: v int } -/* 2 */ struct B { a A } -/* 3 */ struct C { mut: b B } -/* 4 */ struct D { mut: c C } - -/* 5 */ struct E { mut: v []int } -/* 6 */ struct F { e []E } - -/* 7 */ mut s := 'hello world' -/*( 8)*/ s.len = 0 // Error (field len immutable) - -/* 8 */ mut b := B{} -/*( 9)*/ b.a.v = 1 // Error (field a immutable) -/*( 9)*/ b.a = A{} // Error (field a immutable) -/* 9 */ b = B{A{2}} // Correct - -/* 10 */ mut c := C{} -/* 11 */ c.b = B{} // Correct -/*(12)*/ c.b.a = A{} // Error (field a immutable) -/*(12)*/ c.b.a.v = 1 // Error (field a immutable) - -/* 12 */ c2 := C{} -/*(13)*/ c2.b = B{} // Error (c2 immutable) -/* 13 */ mut d := D{} -/* 14 */ d.c.b = B{} // Correct - -/* 15 */ mut f := F{} -/*(16)*/ f.e << E{} // Error (field e immutable) -/*(16)*/ f.e[0].v << 1 // Error (field e immutable) - -/* 16 */ e := E{} -/*(17)*/ e.v << 1 // Error (e immutable) - -===output=== -cannot modify immutable field `len` (type `string`) -declare the field with `mut:` -struct string { -mut: - len int -} -cannot modify immutable field `a` (type `B`) -declare the field with `mut:` -struct B { -mut: - a A -} -cannot modify immutable field `a` (type `B`) -declare the field with `mut:` -struct B { -mut: - a A -} -cannot modify immutable field `a` (type `B`) -declare the field with `mut:` -struct B { -mut: - a A -} -cannot modify immutable field `a` (type `B`) -declare the field with `mut:` -struct B { -mut: - a A -} -`c2` is immutable -cannot modify immutable field `e` (type `F`) -declare the field with `mut:` -struct F { -mut: - e []E -} -cannot modify immutable field `e` (type `F`) -declare the field with `mut:` -struct F { -mut: - e []E -} -`e` is immutable (can't <<) diff --git a/vlib/compiler/tests/repl/chained_fields/bd.repl b/vlib/compiler/tests/repl/chained_fields/bd.repl new file mode 100644 index 0000000000..75cc56b917 --- /dev/null +++ b/vlib/compiler/tests/repl/chained_fields/bd.repl @@ -0,0 +1,17 @@ +struct A { mut: v int } struct B { a A } struct C { mut: b B } struct D { mut: c C } +mut b := B{} b = B{A{2}} +b.a.v = 1 // Error (field a immutable) +b.a = A{} // Error (field a immutable) +===output=== +cannot modify immutable field `a` (type `B`) +declare the field with `mut:` +struct B { +mut: + a A +} +cannot modify immutable field `a` (type `B`) +declare the field with `mut:` +struct B { +mut: + a A +} diff --git a/vlib/compiler/tests/repl/chained_fields/c.repl b/vlib/compiler/tests/repl/chained_fields/c.repl new file mode 100644 index 0000000000..1919ff6f58 --- /dev/null +++ b/vlib/compiler/tests/repl/chained_fields/c.repl @@ -0,0 +1,17 @@ +struct A { mut: v int } struct B { a A } struct C { mut: b B } struct D { mut: c C } +mut c := C{} c.b = B{} +c.b.a = A{} // Error (field a immutable) +c.b.a.v = 1 // Error (field a immutable) +===output=== +cannot modify immutable field `a` (type `B`) +declare the field with `mut:` +struct B { +mut: + a A +} +cannot modify immutable field `a` (type `B`) +declare the field with `mut:` +struct B { +mut: + a A +} diff --git a/vlib/compiler/tests/repl/chained_fields/c2.repl b/vlib/compiler/tests/repl/chained_fields/c2.repl new file mode 100644 index 0000000000..1c477a589b --- /dev/null +++ b/vlib/compiler/tests/repl/chained_fields/c2.repl @@ -0,0 +1,5 @@ +struct A { mut: v int } struct B { a A } struct C { mut: b B } struct D { mut: c C } +c2 := C{} +c2.b = B{} // Error (c2 immutable) +===output=== +`c2` is immutable diff --git a/vlib/compiler/tests/repl/chained_fields/d.repl b/vlib/compiler/tests/repl/chained_fields/d.repl new file mode 100644 index 0000000000..af7986ae18 --- /dev/null +++ b/vlib/compiler/tests/repl/chained_fields/d.repl @@ -0,0 +1,5 @@ +struct A { mut: v int } struct B { a A } struct C { mut: b B } struct D { mut: c C } +mut d := D{} d.c.b = B{} +'OK' +===output=== +OK diff --git a/vlib/compiler/tests/repl/chained_fields/ef.repl b/vlib/compiler/tests/repl/chained_fields/ef.repl new file mode 100644 index 0000000000..509218bf90 --- /dev/null +++ b/vlib/compiler/tests/repl/chained_fields/ef.repl @@ -0,0 +1,19 @@ +struct E { mut: v []int } struct F { e []E } mut f := F{} +f.e << E{} // Error (field e immutable) +f.e[0].v << 1 // Error (field e immutable) +e := E{} +e.v << 1 // Error (e immutable) +===output=== +cannot modify immutable field `e` (type `F`) +declare the field with `mut:` +struct F { +mut: + e []E +} +cannot modify immutable field `e` (type `F`) +declare the field with `mut:` +struct F { +mut: + e []E +} +`e` is immutable (can't <<) diff --git a/vlib/compiler/tests/repl/conditional_blocks.repl b/vlib/compiler/tests/repl/conditional_blocks.repl deleted file mode 100644 index ca10025c37..0000000000 --- a/vlib/compiler/tests/repl/conditional_blocks.repl +++ /dev/null @@ -1,18 +0,0 @@ -if true { - println('foo') -} -for i := 0; i < 4; i++ { - println(i) -} -if false { - println('foo') -} else { - println('bar') -} -===output=== -foo -0 -1 -2 -3 -bar diff --git a/vlib/compiler/tests/repl/conditional_blocks/for.repl b/vlib/compiler/tests/repl/conditional_blocks/for.repl new file mode 100644 index 0000000000..2f3f50cba6 --- /dev/null +++ b/vlib/compiler/tests/repl/conditional_blocks/for.repl @@ -0,0 +1,8 @@ +for i := 0; i < 4; i++ { + println(i) +} +===output=== +0 +1 +2 +3 diff --git a/vlib/compiler/tests/repl/conditional_blocks/if.repl b/vlib/compiler/tests/repl/conditional_blocks/if.repl new file mode 100644 index 0000000000..9b3b2d6c5e --- /dev/null +++ b/vlib/compiler/tests/repl/conditional_blocks/if.repl @@ -0,0 +1,5 @@ +if true { + println('foo') +} +===output=== +foo diff --git a/vlib/compiler/tests/repl/conditional_blocks/if_else.repl b/vlib/compiler/tests/repl/conditional_blocks/if_else.repl new file mode 100644 index 0000000000..b44b66eed3 --- /dev/null +++ b/vlib/compiler/tests/repl/conditional_blocks/if_else.repl @@ -0,0 +1,7 @@ +if false { + println('foo') +} else { + println('bar') +} +===output=== +bar diff --git a/vlib/compiler/tests/repl/default_printing.repl b/vlib/compiler/tests/repl/default_printing.repl index b1de4b4f5b..5b03a57b99 100644 --- a/vlib/compiler/tests/repl/default_printing.repl +++ b/vlib/compiler/tests/repl/default_printing.repl @@ -1,5 +1,4 @@ -num := 1 -string := 'Hello' +num := 1 string := 'Hello' num string ===output=== diff --git a/vlib/compiler/tests/repl/function.repl b/vlib/compiler/tests/repl/function.repl index 0b20fa1a4e..25c0b9d887 100644 --- a/vlib/compiler/tests/repl/function.repl +++ b/vlib/compiler/tests/repl/function.repl @@ -1,11 +1,4 @@ -fn test() { - println('foo') -} -test() -fn test2(a int) { - println(a) -} -test2(42) +fn test() { println('foo') } test() fn test2(a int) { println(a) } test2(42) ===output=== foo 42 diff --git a/vlib/compiler/tests/repl/immutable_len_fields.repl b/vlib/compiler/tests/repl/immutable_len_fields.repl deleted file mode 100644 index 120eb7edcd..0000000000 --- a/vlib/compiler/tests/repl/immutable_len_fields.repl +++ /dev/null @@ -1,30 +0,0 @@ -mut s := 'hello world' -s.len = 0 // Error (field len immutable) - -mut a := []string -a.len = 0 // Error (field len immutable) - -mut ints := []int -ints.len = 0 // Error (field len immutable) - -println('BYE') -===output=== -cannot modify immutable field `len` (type `string`) -declare the field with `mut:` -struct string { -mut: - len int -} -cannot modify immutable field `len` (type `array`) -declare the field with `mut:` -struct array { -mut: - len int -} -cannot modify immutable field `len` (type `array`) -declare the field with `mut:` -struct array { -mut: - len int -} -BYE diff --git a/vlib/compiler/tests/repl/immutable_len_fields/fields.1.repl b/vlib/compiler/tests/repl/immutable_len_fields/fields.1.repl new file mode 100644 index 0000000000..6186c4c826 --- /dev/null +++ b/vlib/compiler/tests/repl/immutable_len_fields/fields.1.repl @@ -0,0 +1,11 @@ +mut s := 'hello world' +s.len = 0 // Error (field len immutable) +'BYE' +===output=== +cannot modify immutable field `len` (type `string`) +declare the field with `mut:` +struct string { +mut: + len int +} +BYE diff --git a/vlib/compiler/tests/repl/immutable_len_fields/fields.2.repl b/vlib/compiler/tests/repl/immutable_len_fields/fields.2.repl new file mode 100644 index 0000000000..60e3929703 --- /dev/null +++ b/vlib/compiler/tests/repl/immutable_len_fields/fields.2.repl @@ -0,0 +1,11 @@ +mut a := []string +a.len = 0 // Error (field len immutable) +'BYE' +===output=== +cannot modify immutable field `len` (type `array`) +declare the field with `mut:` +struct array { +mut: + len int +} +BYE diff --git a/vlib/compiler/tests/repl/immutable_len_fields/fields.3.repl b/vlib/compiler/tests/repl/immutable_len_fields/fields.3.repl new file mode 100644 index 0000000000..41061ed354 --- /dev/null +++ b/vlib/compiler/tests/repl/immutable_len_fields/fields.3.repl @@ -0,0 +1,11 @@ +mut ints := []int +ints.len = 0 // Error (field len immutable) +println('BYE') +===output=== +cannot modify immutable field `len` (type `array`) +declare the field with `mut:` +struct array { +mut: + len int +} +BYE diff --git a/vlib/compiler/tests/repl/interpolation.repl b/vlib/compiler/tests/repl/interpolation.repl deleted file mode 100644 index c699b4d866..0000000000 --- a/vlib/compiler/tests/repl/interpolation.repl +++ /dev/null @@ -1,5 +0,0 @@ -a := 'Hello' -b := 'World' -println('$a $b') -===output=== -Hello World diff --git a/vlib/compiler/tests/repl/multiple_decl.repl b/vlib/compiler/tests/repl/multiple_decl.repl index b7702fde71..e7b2ba8ebd 100644 --- a/vlib/compiler/tests/repl/multiple_decl.repl +++ b/vlib/compiler/tests/repl/multiple_decl.repl @@ -1,6 +1,4 @@ -name := 'Bob' -age := 20 -large_number := i64(9999999999) +name := 'Bob' age := 20 large_number := i64(9999999999) println(name) println(age) println(large_number) diff --git a/vlib/compiler/tests/repl/naked_strings.repl b/vlib/compiler/tests/repl/naked_strings.repl index ba6fc474c7..3769ccc964 100644 --- a/vlib/compiler/tests/repl/naked_strings.repl +++ b/vlib/compiler/tests/repl/naked_strings.repl @@ -1,9 +1,5 @@ 'abc' 'abc'+'xyz' -'{' -'}' ===output=== abc abcxyz -{ -} diff --git a/vlib/compiler/tests/repl/newlines.repl b/vlib/compiler/tests/repl/newlines.repl index 9f00e0b5e3..23304fa161 100644 --- a/vlib/compiler/tests/repl/newlines.repl +++ b/vlib/compiler/tests/repl/newlines.repl @@ -1,5 +1,3 @@ - - ===output=== diff --git a/vlib/compiler/tests/repl/open_close_string_check.repl b/vlib/compiler/tests/repl/open_close_string_check.repl new file mode 100644 index 0000000000..00aabe3009 --- /dev/null +++ b/vlib/compiler/tests/repl/open_close_string_check.repl @@ -0,0 +1,5 @@ +'{' +'}' +===output=== +{ +} diff --git a/vlib/compiler/tests/repl/option.repl b/vlib/compiler/tests/repl/option.repl index 84ed92976d..dbd223f449 100644 --- a/vlib/compiler/tests/repl/option.repl +++ b/vlib/compiler/tests/repl/option.repl @@ -1,7 +1,4 @@ -fn foo() ?bool { - return true -} - +fn foo() ?bool {return true} fn main() { foo()? // only works in main() println('done') diff --git a/vlib/compiler/tests/repl/postfix_operators.repl b/vlib/compiler/tests/repl/postfix_operators.repl index 92b4db9fd6..68066f5594 100644 --- a/vlib/compiler/tests/repl/postfix_operators.repl +++ b/vlib/compiler/tests/repl/postfix_operators.repl @@ -1,11 +1,4 @@ -mut a := 2 -a++ -a -println(a) -println(a++) +mut a := 10 a++ a++ a++ a-- a ===output=== -3 -3 -3 -3 +12 diff --git a/vlib/compiler/tests/repl/repl_test.v b/vlib/compiler/tests/repl/repl_test.v index 107f7ff83c..78f5ec2d9d 100644 --- a/vlib/compiler/tests/repl/repl_test.v +++ b/vlib/compiler/tests/repl/repl_test.v @@ -8,7 +8,7 @@ import sync import filepath fn test_the_v_compiler_can_be_invoked() { - vexec := runner.full_path_to_v(5) + vexec := runner.full_path_to_v(5) println('vexecutable: $vexec') assert vexec != '' vcmd := '"$vexec" --version' @@ -43,28 +43,28 @@ fn test_all_v_repl_files() { ntask_mtx: sync.new_mutex() waitgroup: sync.new_waitgroup() } - // warmup, and ensure that the vrepl is compiled in single threaded mode if it does not exist runner.run_repl_file(os.cachedir(), session.options.vexec, 'vlib/compiler/tests/repl/nothing.repl') or { panic(err) } session.bmark.set_total_expected_steps( session.options.files.len ) - mut ncpus := runtime.nr_cpus() + mut ncpus := 0 + ncpus = runtime.nr_cpus() $if windows { // See: https://docs.microsoft.com/en-us/cpp/build/reference/fs-force-synchronous-pdb-writes?view=vs-2019 ncpus = 1 } session.waitgroup.add( ncpus ) for i:=0; i < ncpus; i++ { - go process_in_thread(session) + go process_in_thread(session,i) } session.waitgroup.wait() session.bmark.stop() println(session.bmark.total_message('total time spent running REPL files')) } -fn process_in_thread( session mut Session ){ +fn process_in_thread( session mut Session, thread_id int ){ cdir := os.cachedir() mut tls_bench := benchmark.new_benchmark() tls_bench.set_total_expected_steps( session.bmark.nexpected_steps ) @@ -83,7 +83,7 @@ fn process_in_thread( session mut Session ){ } os.mkdir( tfolder ) or { panic(err) } - file := os.realpath( filepath.join( session.options.wd, session.options.files[ idx ] ) ) + file := session.options.files[ idx ] session.bmark.step() tls_bench.step() fres := runner.run_repl_file(tfolder, session.options.vexec, file) or { diff --git a/vlib/compiler/tests/repl/runner/runner.v b/vlib/compiler/tests/repl/runner/runner.v index 7962a7d9c4..0818105c97 100644 --- a/vlib/compiler/tests/repl/runner/runner.v +++ b/vlib/compiler/tests/repl/runner/runner.v @@ -46,17 +46,18 @@ fn find_working_diff_command() ?string { fn diff_files( file_result, file_expected string ) string { diffcmd := find_working_diff_command() or { return err } - diff := os.exec('$diffcmd --minimal --text --unified=2 $file_result $file_expected') or { return 'found diff command "$diffcmd" does not work' } + diff := os.exec('$diffcmd --minimal --text --unified=2 ${file_result} ${file_expected}') or { return 'found diff command "$diffcmd" does not work' } return diff.output } pub fn run_repl_file(wd string, vexec string, file string) ?string { - fcontent := os.read_file(file) or { return error('Could not read file $file') } + fcontent := os.read_file(file) or { return error('Could not read file ${file}') } content := fcontent.replace('\r', '') input := content.all_before('===output===\n') output := content.all_after('===output===\n') fname := filepath.filename( file ) + input_temporary_filename := os.realpath(filepath.join( wd, 'input_temporary_filename.txt')) os.write_file(input_temporary_filename, input) os.write_file( os.realpath(filepath.join( wd, 'original.txt' ) ), fcontent ) @@ -80,7 +81,7 @@ pub fn run_repl_file(wd string, vexec string, file string) ?string { os.write_file( file_result, result ) os.write_file( file_expected, output ) diff := diff_files( file_result, file_expected ) - return error('Difference found in REPL file: $file + return error('Difference found in REPL file: ${file} ====> Got : |$result| ====> Expected : @@ -89,16 +90,16 @@ pub fn run_repl_file(wd string, vexec string, file string) ?string { $diff ') } else { - return 'Repl file $file is OK' + return 'Repl file ${file} is OK' } } 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') } + 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"' + cmd := '"$vexec" -prod run "${file}"' r := os.exec(cmd) or { return error('Could not execute: $cmd') } @@ -113,7 +114,7 @@ pub fn run_prod_file(wd string, vexec string, file string) ?string { 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 + return error('Difference found in test: ${file} ====> Got : |$result| ====> Expected : @@ -122,17 +123,19 @@ pub fn run_prod_file(wd string, vexec string, file string) ?string { $diff ') } else { - return 'Prod file $file is OK' + return 'Prod file ${file} is OK' } } pub fn new_options() RunnerOptions { - wd := os.getwd() vexec := full_path_to_v(5) + mut wd := os.getwd() mut files := []string if os.args.len > 1 { files = os.args[1..] } else { + os.chdir( filepath.dir(vexec) ) + wd = os.getwd() files = os.walk_ext('.', '.repl') } return RunnerOptions { diff --git a/vlib/compiler/tests/string_interpolation_test.v b/vlib/compiler/tests/string_interpolation_test.v index d939d244dd..280c5d0045 100644 --- a/vlib/compiler/tests/string_interpolation_test.v +++ b/vlib/compiler/tests/string_interpolation_test.v @@ -1,4 +1,11 @@ +fn test_simple_string_interpolation(){ + a := 'Hello' + b := 'World' + res := '$a $b' + assert res == 'Hello World' +} + fn test_excape_dollar_in_string() { i := 42 diff --git a/vlib/compiler/tests/struct_chained_fields_correct_test.v b/vlib/compiler/tests/struct_chained_fields_correct_test.v new file mode 100644 index 0000000000..3a5581dbc9 --- /dev/null +++ b/vlib/compiler/tests/struct_chained_fields_correct_test.v @@ -0,0 +1,26 @@ + +struct Axx { mut: v int } +struct Bxx { a Axx } +struct Cxx { mut: b Bxx } +struct Dxx { mut: c Cxx } +struct Exx { mut: v []int } +struct Fxx { e []Exx } + +fn test_chained_string(){ + mut b := Bxx{} b = Bxx{Axx{2}} + assert 'b is: ' + b.a.v.str() == 'b is: 2' +} + +fn test_chained_assignments(){ + mut c := Cxx{} + c.b = Bxx{} + mut d := Dxx{} + d.c.b = Bxx{} + assert true +} + +fn test_chained_array_access(){ + f := Fxx{[Exx{[10,20,30]},Exx{[100,200,300,400]}]} + assert 'f.e[0].v.len: 3' == 'f.e[0].v.len: ${f.e[0].v.len}' + assert 'f.e[1].v.len: 4' == 'f.e[1].v.len: ${f.e[1].v.len}' +}