mirror of
https://github.com/vlang/v.git
synced 2025-08-04 02:07:28 -04:00
162 lines
5.5 KiB
V
162 lines
5.5 KiB
V
import os
|
|
import rand
|
|
import term
|
|
import v.util.vtest
|
|
import v.util.diff
|
|
|
|
const vexe_path = @VEXE
|
|
const vexe = os.quoted_path(vexe_path)
|
|
const vroot = os.dir(vexe_path)
|
|
const should_autofix = os.getenv('VAUTOFIX') != ''
|
|
|
|
fn test_output() {
|
|
os.setenv('VCOLORS', 'never', true)
|
|
os.chdir(vroot)!
|
|
mut total_fails := 0
|
|
test_files := vtest.filter_vtest_only(os.walk_ext('cmd/tools/vdoc/testdata', '.v'),
|
|
basepath: vroot
|
|
)
|
|
for path in test_files {
|
|
mut fails := 0
|
|
qpath := os.quoted_path(path)
|
|
path_no_ext := path.all_before_last('.')
|
|
print(path + ' ')
|
|
fails += check_output('${vexe} doc ${qpath}', path_no_ext + '.out')
|
|
fails += check_output('${vexe} doc -comments ${qpath}', '${path_no_ext}.unsorted.out',
|
|
should_sort: false
|
|
)
|
|
fails += check_output('${vexe} doc -comments ${qpath}', '${path_no_ext}.comments.out')
|
|
fails += check_output('${vexe} doc -readme -comments ${qpath}', '${path_no_ext}.readme.comments.out')
|
|
// test the main 3 different formats:
|
|
program_dir := os.quoted_path(if os.is_dir(path) { path } else { os.dir(path) })
|
|
for fmt in ['html', 'ansi', 'text'] {
|
|
fails += check_output('${vexe} doc -f ${fmt} -o - -html-only-contents -readme -comments ${program_dir}',
|
|
'${path_no_ext}.${fmt}')
|
|
}
|
|
if fails == 0 {
|
|
println(term.green('OK'))
|
|
} else {
|
|
total_fails += fails
|
|
}
|
|
flush_stdout()
|
|
}
|
|
assert total_fails == 0
|
|
}
|
|
|
|
fn test_run_examples_good() {
|
|
os.setenv('VCOLORS', 'never', true)
|
|
os.chdir(vroot)!
|
|
res := os.execute('${vexe} doc -comments -run-examples cmd/tools/vdoc/testdata/run_examples_good/main.v')
|
|
assert res.exit_code == 0
|
|
assert res.output.contains('module main'), res.output
|
|
assert res.output.contains('fn abc()'), res.output
|
|
assert res.output.contains("abc just prints 'xyz'"), res.output
|
|
assert res.output.contains('and should succeed'), res.output
|
|
assert res.output.contains('Example: assert 5 * 5 == 25'), res.output
|
|
}
|
|
|
|
fn test_run_examples_bad() {
|
|
os.setenv('VCOLORS', 'never', true)
|
|
os.chdir(vroot)!
|
|
res := os.execute('${vexe} doc -comments -run-examples cmd/tools/vdoc/testdata/run_examples_bad/main.v')
|
|
assert res.exit_code != 0
|
|
assert res.output.contains('error in documentation example'), res.output
|
|
assert res.output.contains(' left value: 5 * 5 = 25'), res.output
|
|
assert res.output.contains('right value: 77'), res.output
|
|
assert res.output.contains('V panic: Assertion failed...'), res.output
|
|
assert res.output.contains('module main'), res.output
|
|
assert res.output.contains('Example: assert 5 * 5 == 77'), res.output
|
|
}
|
|
|
|
const small_pure_v_vlib_module = 'bitfield'
|
|
|
|
fn test_out_path() {
|
|
// Work around CI issues covering v doc generation for relative input paths in tmp dir.
|
|
// Instead just generate documentation in the v source dir.
|
|
if os.getenv('CI') == 'true' {
|
|
default_output_path := os.join_path(vroot, 'vlib', small_pure_v_vlib_module, '_docs')
|
|
os.execute_opt('${vexe} doc -f html -m vlib/${small_pure_v_vlib_module}')!
|
|
final_html_path := os.join_path(default_output_path, '${small_pure_v_vlib_module}.html')
|
|
assert os.exists(final_html_path), final_html_path
|
|
|
|
// Custom out path (no `_docs` subdir).
|
|
out_dir := os.join_path(vroot, 'vlib', small_pure_v_vlib_module, 'docs')
|
|
os.execute_opt('${vexe} doc -f html -m -o ${out_dir} ${small_pure_v_vlib_module}')!
|
|
out_html_path := os.join_path(out_dir, '${small_pure_v_vlib_module}.html')
|
|
assert os.exists(out_html_path), out_html_path
|
|
os.rmdir_all(out_dir) or {}
|
|
os.rmdir_all(default_output_path) or {}
|
|
return
|
|
}
|
|
|
|
// Copy a *small* vlib module, that is written in pure V, for the test:
|
|
test_path := os.join_path(os.vtmp_dir(), 'vdoc_test_${rand.ulid()}')
|
|
test_mod_path := os.join_path(test_path, small_pure_v_vlib_module)
|
|
os.mkdir_all(test_path)!
|
|
defer {
|
|
os.chdir(vroot) or {}
|
|
os.rmdir_all(test_path) or {}
|
|
}
|
|
os.chdir(test_path)!
|
|
mod_path := os.join_path(vroot, 'vlib', small_pure_v_vlib_module)
|
|
os.cp_all(mod_path, test_mod_path, true) or {}
|
|
|
|
// Relative input with default output path.
|
|
os.execute_opt('${vexe} doc -f html -m ${small_pure_v_vlib_module}')!
|
|
output_path := os.join_path(mod_path, '_docs', '${small_pure_v_vlib_module}.html')
|
|
assert os.exists(output_path), output_path
|
|
|
|
// Custom out path (no `_docs` subdir).
|
|
out_dir := os.join_path(os.vtmp_dir(), 'docs_test')
|
|
defer {
|
|
os.rmdir_all(out_dir) or {}
|
|
}
|
|
os.execute_opt('${vexe} doc -f html -m -o ${out_dir} ${small_pure_v_vlib_module}')!
|
|
html_path := os.join_path(out_dir, '${small_pure_v_vlib_module}.html')
|
|
assert os.exists(html_path), html_path
|
|
}
|
|
|
|
fn print_compare(expected string, found string) {
|
|
println(term.red('FAIL'))
|
|
println('============')
|
|
if diff_ := diff.compare_text(expected, found) {
|
|
println('diff:')
|
|
println(diff_)
|
|
println('============\n')
|
|
} else {
|
|
println('expected:')
|
|
println(expected)
|
|
println('============')
|
|
println('found:')
|
|
println(found)
|
|
println('============\n')
|
|
}
|
|
}
|
|
|
|
@[params]
|
|
struct CheckOutputParams {
|
|
should_sort bool = true
|
|
}
|
|
|
|
fn check_output(cmd string, out_path string, opts CheckOutputParams) int {
|
|
if !os.exists(out_path) {
|
|
return 0
|
|
}
|
|
mut fails := 0
|
|
os.setenv('VDOC_SORT', opts.should_sort.str(), true)
|
|
expected := os.read_file(out_path) or { panic(err) }.replace('\r\n', '\n').trim_space()
|
|
res := os.execute_opt(cmd) or { panic(err) }
|
|
found := res.output.replace('\r\n', '\n').trim_space()
|
|
if expected != found {
|
|
print_compare(expected, found)
|
|
eprintln('>>> cmd: VDOC_SORT=${opts.should_sort} ${cmd}')
|
|
eprintln('>>> out_file_path: `${out_path}`')
|
|
eprintln('>>> fix: VDOC_SORT=${opts.should_sort} ${cmd} > ${out_path}')
|
|
fails++
|
|
}
|
|
if should_autofix {
|
|
os.write_file(out_path, res.output) or {}
|
|
}
|
|
return fails
|
|
}
|