repl: execute REPL tests ~1.5x to 2x faster
							parent
							
								
									64a9f43405
								
							
						
					
					
						commit
						d92291dd76
					
				|  | @ -0,0 +1,5 @@ | ||||||
|  | fn test_array_to_string_conversion() { | ||||||
|  |   expected := '["1", "2", "3", "4"] ' | ||||||
|  |   arr := ['1', '2', '3', '4'] | ||||||
|  |   assert '$arr' == expected | ||||||
|  | } | ||||||
|  | @ -1,4 +0,0 @@ | ||||||
| arr := ['1', '2', '3', '4'] |  | ||||||
| println(arr) |  | ||||||
| ===output=== |  | ||||||
| ["1", "2", "3", "4"] |  | ||||||
|  | @ -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 |  | ||||||
|  | @ -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 <<) |  | ||||||
|  | @ -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 | ||||||
|  | } | ||||||
|  | @ -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 | ||||||
|  | } | ||||||
|  | @ -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 | ||||||
|  | @ -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 | ||||||
|  | @ -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 <<) | ||||||
|  | @ -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 |  | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | for i := 0; i < 4; i++ { | ||||||
|  |   println(i) | ||||||
|  | } | ||||||
|  | ===output=== | ||||||
|  | 0 | ||||||
|  | 1 | ||||||
|  | 2 | ||||||
|  | 3 | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | if true { | ||||||
|  |   println('foo') | ||||||
|  | } | ||||||
|  | ===output=== | ||||||
|  | foo | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | if false { | ||||||
|  |   println('foo') | ||||||
|  | } else { | ||||||
|  |   println('bar') | ||||||
|  | } | ||||||
|  | ===output=== | ||||||
|  | bar | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| num := 1 | num := 1 string := 'Hello' | ||||||
| string := 'Hello' |  | ||||||
| num | num | ||||||
| string | string | ||||||
| ===output=== | ===output=== | ||||||
|  |  | ||||||
|  | @ -1,11 +1,4 @@ | ||||||
| fn test() { | fn test() { println('foo') } test() fn test2(a int) {  println(a) } test2(42) | ||||||
|   println('foo') |  | ||||||
| } |  | ||||||
| test() |  | ||||||
| fn test2(a int) { |  | ||||||
|   println(a) |  | ||||||
| } |  | ||||||
| test2(42) |  | ||||||
| ===output=== | ===output=== | ||||||
| foo | foo | ||||||
| 42 | 42 | ||||||
|  |  | ||||||
|  | @ -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 |  | ||||||
|  | @ -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 | ||||||
|  | @ -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 | ||||||
|  | @ -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 | ||||||
|  | @ -1,5 +0,0 @@ | ||||||
| a := 'Hello' |  | ||||||
| b := 'World' |  | ||||||
| println('$a $b') |  | ||||||
| ===output=== |  | ||||||
| Hello World |  | ||||||
|  | @ -1,6 +1,4 @@ | ||||||
| name := 'Bob'  | name := 'Bob' age := 20 large_number := i64(9999999999) | ||||||
| age := 20 |  | ||||||
| large_number := i64(9999999999) |  | ||||||
| println(name) | println(name) | ||||||
| println(age) | println(age) | ||||||
| println(large_number) | println(large_number) | ||||||
|  |  | ||||||
|  | @ -1,9 +1,5 @@ | ||||||
| 'abc' | 'abc' | ||||||
| 'abc'+'xyz' | 'abc'+'xyz' | ||||||
| '{' |  | ||||||
| '}' |  | ||||||
| ===output=== | ===output=== | ||||||
| abc | abc | ||||||
| abcxyz | abcxyz | ||||||
| { |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -1,5 +1,3 @@ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| ===output=== | ===output=== | ||||||
|  |  | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | '{' | ||||||
|  | '}' | ||||||
|  | ===output=== | ||||||
|  | { | ||||||
|  | } | ||||||
|  | @ -1,7 +1,4 @@ | ||||||
| fn foo() ?bool { | fn foo() ?bool {return true}	 | ||||||
| 	return true |  | ||||||
| }	 |  | ||||||
| 
 |  | ||||||
| fn main() { | fn main() { | ||||||
| 	foo()? // only works in main() | 	foo()? // only works in main() | ||||||
| 	println('done') | 	println('done') | ||||||
|  |  | ||||||
|  | @ -1,11 +1,4 @@ | ||||||
| mut a := 2 | mut a := 10 a++ a++ a++ a-- | ||||||
| a++ |  | ||||||
| a |  | ||||||
| println(a) |  | ||||||
| println(a++) |  | ||||||
| a | a | ||||||
| ===output=== | ===output=== | ||||||
| 3 | 12 | ||||||
| 3 |  | ||||||
| 3 |  | ||||||
| 3 |  | ||||||
|  |  | ||||||
|  | @ -43,28 +43,28 @@ fn test_all_v_repl_files() { | ||||||
| 		ntask_mtx: sync.new_mutex() | 		ntask_mtx: sync.new_mutex() | ||||||
| 		waitgroup: sync.new_waitgroup() | 		waitgroup: sync.new_waitgroup() | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	// warmup, and ensure that the vrepl is compiled in single threaded mode if it does not exist
 | 	// 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 { | 	runner.run_repl_file(os.cachedir(), session.options.vexec, 'vlib/compiler/tests/repl/nothing.repl') or { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	session.bmark.set_total_expected_steps( session.options.files.len ) | 	session.bmark.set_total_expected_steps( session.options.files.len ) | ||||||
| 	mut ncpus := runtime.nr_cpus() | 	mut ncpus := 0 | ||||||
|  | 	ncpus = runtime.nr_cpus() | ||||||
| 	$if windows { | 	$if windows { | ||||||
| 	// See: https://docs.microsoft.com/en-us/cpp/build/reference/fs-force-synchronous-pdb-writes?view=vs-2019
 | 	// See: https://docs.microsoft.com/en-us/cpp/build/reference/fs-force-synchronous-pdb-writes?view=vs-2019
 | ||||||
| 		ncpus = 1 | 		ncpus = 1 | ||||||
| 	} | 	} | ||||||
| 	session.waitgroup.add( ncpus ) | 	session.waitgroup.add( ncpus ) | ||||||
| 	for i:=0; i < ncpus; i++ { | 	for i:=0; i < ncpus; i++ { | ||||||
| 		go process_in_thread(session) | 		go process_in_thread(session,i) | ||||||
| 	} | 	} | ||||||
| 	session.waitgroup.wait() | 	session.waitgroup.wait() | ||||||
| 	session.bmark.stop() | 	session.bmark.stop() | ||||||
| 	println(session.bmark.total_message('total time spent running REPL files')) | 	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() | 	cdir := os.cachedir() | ||||||
| 	mut tls_bench := benchmark.new_benchmark() | 	mut tls_bench := benchmark.new_benchmark() | ||||||
| 	tls_bench.set_total_expected_steps( session.bmark.nexpected_steps ) | 	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) } | 		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() | 		session.bmark.step() | ||||||
| 		tls_bench.step() | 		tls_bench.step() | ||||||
| 		fres := runner.run_repl_file(tfolder, session.options.vexec, file) or { | 		fres := runner.run_repl_file(tfolder, session.options.vexec, file) or { | ||||||
|  |  | ||||||
|  | @ -46,17 +46,18 @@ fn find_working_diff_command() ?string { | ||||||
| 
 | 
 | ||||||
| fn diff_files( file_result, file_expected string ) string { | fn diff_files( file_result, file_expected string ) string { | ||||||
| 	diffcmd := find_working_diff_command() or { return err } | 	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 | 	return diff.output | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn run_repl_file(wd string, vexec string, file string) ?string { | 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', '')		 | 	content := fcontent.replace('\r', '')		 | ||||||
| 	input := content.all_before('===output===\n') | 	input := content.all_before('===output===\n') | ||||||
| 	output := content.all_after('===output===\n') | 	output := content.all_after('===output===\n') | ||||||
| 
 | 
 | ||||||
| 	fname := filepath.filename( file ) | 	fname := filepath.filename( file ) | ||||||
|  | 
 | ||||||
| 	input_temporary_filename := os.realpath(filepath.join( wd, 'input_temporary_filename.txt')) | 	input_temporary_filename := os.realpath(filepath.join( wd, 'input_temporary_filename.txt')) | ||||||
| 	os.write_file(input_temporary_filename, input) | 	os.write_file(input_temporary_filename, input) | ||||||
| 	os.write_file(  os.realpath(filepath.join( wd, 'original.txt' ) ), fcontent ) | 	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_result, result ) | ||||||
| 		os.write_file( file_expected, output ) | 		os.write_file( file_expected, output ) | ||||||
| 		diff := diff_files( file_result, file_expected ) | 		diff := diff_files( file_result, file_expected ) | ||||||
| 		return error('Difference found in REPL file: $file | 		return error('Difference found in REPL file: ${file} | ||||||
| ====> Got      : | ====> Got      : | ||||||
| |$result| | |$result| | ||||||
| ====> Expected : | ====> Expected : | ||||||
|  | @ -89,16 +90,16 @@ pub fn run_repl_file(wd string, vexec string, file string) ?string { | ||||||
| $diff | $diff | ||||||
| 		') | 		') | ||||||
| 	} else { | 	} 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 { | pub fn run_prod_file(wd string, vexec string, file string) ?string { | ||||||
| 	file_expected := '${file}.expected.txt' | 	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', '')		 | 	expected_content := f_expected_content.replace('\r', '')		 | ||||||
| 
 | 
 | ||||||
| 	cmd := '"$vexec" -prod run "$file"' | 	cmd := '"$vexec" -prod run "${file}"' | ||||||
| 	r := os.exec(cmd) or { | 	r := os.exec(cmd) or { | ||||||
| 		return error('Could not execute: $cmd') | 		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' | 		file_result   := '${file}.result.txt' | ||||||
| 		os.write_file( file_result, result ) | 		os.write_file( file_result, result ) | ||||||
| 		diff := diff_files( file_result, file_expected ) | 		diff := diff_files( file_result, file_expected ) | ||||||
| 		return error('Difference found in test: $file | 		return error('Difference found in test: ${file} | ||||||
| ====> Got      : | ====> Got      : | ||||||
| |$result| | |$result| | ||||||
| ====> Expected : | ====> Expected : | ||||||
|  | @ -122,17 +123,19 @@ pub fn run_prod_file(wd string, vexec string, file string) ?string { | ||||||
| $diff | $diff | ||||||
| 		') | 		') | ||||||
| 	} else { | 	} else { | ||||||
| 		return 'Prod file $file is OK' | 		return 'Prod file ${file} is OK' | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn new_options() RunnerOptions { | pub fn new_options() RunnerOptions { | ||||||
| 	wd := os.getwd() |  | ||||||
| 	vexec := full_path_to_v(5) | 	vexec := full_path_to_v(5) | ||||||
|  | 	mut wd := os.getwd() | ||||||
| 	mut files := []string | 	mut files := []string | ||||||
| 	if os.args.len > 1 { | 	if os.args.len > 1 { | ||||||
| 		files = os.args[1..] | 		files = os.args[1..] | ||||||
| 	} else { | 	} else { | ||||||
|  | 		os.chdir( filepath.dir(vexec) ) | ||||||
|  | 		wd = os.getwd() | ||||||
| 		files = os.walk_ext('.', '.repl') | 		files = os.walk_ext('.', '.repl') | ||||||
| 	} | 	} | ||||||
| 	return RunnerOptions { | 	return RunnerOptions { | ||||||
|  |  | ||||||
|  | @ -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() { | fn test_excape_dollar_in_string() { | ||||||
|   i := 42 |   i := 42 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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}' | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue