repl: execute REPL tests ~1.5x to 2x faster

pull/3522/head
Delyan Angelov 2020-01-21 00:04:26 +02:00 committed by Alexander Medvednikov
parent 64a9f43405
commit d92291dd76
30 changed files with 183 additions and 198 deletions

View File

@ -0,0 +1,5 @@
fn test_array_to_string_conversion() {
expected := '["1", "2", "3", "4"] '
arr := ['1', '2', '3', '4']
assert '$arr' == expected
}

View File

@ -1,4 +0,0 @@
arr := ['1', '2', '3', '4']
println(arr)
===output===
["1", "2", "3", "4"]

View File

@ -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

View File

@ -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 <<)

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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 <<)

View File

@ -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

View File

@ -0,0 +1,8 @@
for i := 0; i < 4; i++ {
println(i)
}
===output===
0
1
2
3

View File

@ -0,0 +1,5 @@
if true {
println('foo')
}
===output===
foo

View File

@ -0,0 +1,7 @@
if false {
println('foo')
} else {
println('bar')
}
===output===
bar

View File

@ -1,5 +1,4 @@
num := 1
string := 'Hello'
num := 1 string := 'Hello'
num
string
===output===

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,5 +0,0 @@
a := 'Hello'
b := 'World'
println('$a $b')
===output===
Hello World

View File

@ -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)

View File

@ -1,9 +1,5 @@
'abc'
'abc'+'xyz'
'{'
'}'
===output===
abc
abcxyz
{
}

View File

@ -1,5 +1,3 @@
===output===

View File

@ -0,0 +1,5 @@
'{'
'}'
===output===
{
}

View File

@ -1,7 +1,4 @@
fn foo() ?bool {
return true
}
fn foo() ?bool {return true}
fn main() {
foo()? // only works in main()
println('done')

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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}'
}