vfmt2: more convenient way to test multiple files for correct formatting

pull/3772/head
Delyan Angelov 2020-02-18 18:54:14 +02:00 committed by GitHub
parent 4e9bfa95ec
commit b991ca4ebc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 29 deletions

3
.gitattributes vendored
View File

@ -1 +1,2 @@
*.v linguist-language=V *.v linguist-language=V text=auto eol=lf
*.vv linguist-language=V text=auto eol=lf

View File

@ -22,15 +22,14 @@ mut:
empty_line bool empty_line bool
} }
pub fn fmt(file ast.File, table &table.Table) { pub fn fmt(file ast.File, table &table.Table) string {
mut f := Fmt{ mut f := Fmt{
out: strings.new_builder(1000) out: strings.new_builder(1000)
table: table table: table
indent: -1 indent: -1
} }
f.stmts(file.stmts) f.stmts(file.stmts)
println('vfmt output:') return f.out.str()
println(f.out.str())
} }
pub fn (f mut Fmt) write(s string) { pub fn (f mut Fmt) write(s string) {
@ -98,7 +97,13 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
f.writeln('') f.writeln('')
} }
ast.FnDecl { ast.FnDecl {
f.writeln('fn ${it.name}() {') return_type_sym := f.table.get_type_symbol(it.typ)
rtype_name := if return_type_sym.name == 'void' {
''
} else {
'${return_type_sym.name} '
}
f.writeln('fn ${it.name}() ${rtype_name}{')
f.stmts(it.stmts) f.stmts(it.stmts)
f.writeln('}\n') f.writeln('}\n')
} }

View File

@ -1,35 +1,83 @@
import ( import (
os os
v.fmt
filepath
term term
v.table benchmark
filepath
v.fmt
v.parser v.parser
v.table
) )
const ( const (
nr_tests = 1 error_missing_vexe = 1
error_missing_diff = 2
error_failed_tests = 3
) )
fn test_fmt() { fn test_fmt() {
println('Running vfmt tests') fmt_message := 'vfmt tests'
eprintln(term.header(fmt_message,'-'))
vexe := os.getenv('VEXE') vexe := os.getenv('VEXE')
if vexe.len == 0 || !os.exists(vexe) {
eprintln('VEXE must be set')
exit(error_missing_vexe)
}
vroot := filepath.dir(vexe) vroot := filepath.dir(vexe)
term_ok := term.ok_message('OK') tmpfolder := os.tmpdir()
term_fail := term.fail_message('FAIL') diff_cmd := find_working_diff_command() or { '' }
// for i in 1 .. nr_tests + 1 { mut fmt_bench := benchmark.new_benchmark()
// path := '$vroot/vlib/v/fmt/tests/${i}.vv' // Lookup the existing test _input.vv files:
path := '$vroot/vlib/compiler/aparser.v' input_files := os.walk_ext('$vroot/vlib/v/fmt/tests', '_input.vv')
println(path) fmt_bench.set_total_expected_steps( input_files.len )
/* for istep, ipath in input_files {
mut ctext := os.read_file('$vroot/vlib/v/fmt/tests/${i}_out.vv') or { fmt_bench.cstep = istep
panic(err) fmt_bench.step()
ifilename := filepath.filename(ipath)
opath := ipath.replace('_input.vv', '_expected.vv')
if !os.exists(opath) {
fmt_bench.fail()
eprintln(fmt_bench.step_message_fail('missing file ${opath}'))
continue
}
expected_ocontent := os.read_file(opath) or {
fmt_bench.fail()
eprintln(fmt_bench.step_message_fail('cannot read from ${opath}'))
continue
} }
ctext = ctext // unused warn
*/
table := table.new_table() table := table.new_table()
file := parser.parse_file(path, table) file_ast := parser.parse_file(ipath, table)
fmt.fmt(file, table) result_ocontent := fmt.fmt(file_ast, table)
// } if expected_ocontent != result_ocontent {
fmt_bench.fail()
eprintln(fmt_bench.step_message_fail('file ${ipath} after formatting, does not look as expected.'))
if diff_cmd == '' {
eprintln('>> sorry, but no working "diff" CLI command can be found')
continue
}
vfmt_result_file := filepath.join(tmpfolder,'vfmt_run_over_${ifilename}')
os.write_file(vfmt_result_file, result_ocontent)
os.system('$diff_cmd --minimal --text --unified=2 --show-function-line="fn " "$opath" "$vfmt_result_file"')
continue
}
fmt_bench.ok()
eprintln(fmt_bench.step_message_ok('${ipath}'))
}
fmt_bench.stop()
eprintln(term.h_divider('-'))
eprintln(fmt_bench.total_message(fmt_message))
if fmt_bench.nfail > 0 {
exit(error_failed_tests)
}
}
fn find_working_diff_command() ?string {
for diffcmd in ['colordiff', 'diff', 'colordiff.exe', 'diff.exe'] {
p := os.exec('$diffcmd --version') or {
continue
}
if p.exit_code == 0 {
return diffcmd
}
}
return error('no working diff command found')
} }

View File

@ -0,0 +1,47 @@
fn hello() {
mut a := 3 + 3
a = 10
a++
-23
b := 42
println('hello')
abc()
if true {
a = 10
a++
} else {
println('false')
}
}
const (
pi = 3.14
)
struct User {
name string
age int
very_long_field bool
}
fn abc() int {
mut u := User{
name: 'Bob'
}
u.age = 20
nums := [1, 2, 3]
number := nums[0]
return 0
}
fn new_user() User {
return User{
name: 'Serious Sam'
age: 19
}
}
fn voidfn() {
println('this is a function that does not return anything')
}

View File

@ -35,3 +35,16 @@ fn abc() int {
number := nums[0] number := nums[0]
return 0 return 0
} }
fn new_user()
User
{
return User{
name: 'Serious Sam'
age: 19
}
}
fn voidfn(){
println('this is a function that does not return anything')
}

View File

@ -459,7 +459,7 @@ pub fn (p mut Parser) parse_ident(is_c bool) ast.Ident {
fn (p mut Parser) struct_init() ast.StructInit { fn (p mut Parser) struct_init() ast.StructInit {
typ := p.parse_type() typ := p.parse_type()
sym := p.table.get_type_symbol(typ) sym := p.table.get_type_symbol(typ)
p.warn('struct init typ=$sym.name') //p.warn('struct init typ=$sym.name')
p.check(.lcbr) p.check(.lcbr)
mut field_names := []string mut field_names := []string
mut exprs := []ast.Expr mut exprs := []ast.Expr