| 1 | module main |
| 2 | |
| 3 | import os |
| 4 | |
| 5 | // VAssertMetaInfo is used during assertions. An instance of it |
| 6 | // is filled in by compile time generated code, when an assertion fails. |
| 7 | pub struct VAssertMetaInfo { |
| 8 | pub: |
| 9 | fpath string // the source file path of the assertion |
| 10 | line_nr int // the line number of the assertion |
| 11 | fn_name string // the function name in which the assertion is |
| 12 | src string // the actual source line of the assertion |
| 13 | op string // the operation of the assertion, i.e. '==', '<', 'call', etc ... |
| 14 | llabel string // the left side of the infix expressions as source |
| 15 | rlabel string // the right side of the infix expressions as source |
| 16 | lvalue string // the stringified *actual value* of the left side of a failed assertion |
| 17 | rvalue string // the stringified *actual value* of the right side of a failed assertion |
| 18 | } |
| 19 | |
| 20 | const use_relative_paths = can_use_relative_paths() |
| 21 | |
| 22 | fn can_use_relative_paths() bool { |
| 23 | return match os.getenv('VERROR_PATHS') { |
| 24 | 'absolute' { false } |
| 25 | else { true } |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | fn myeprintln(s string) { |
| 30 | println(s) |
| 31 | } |
| 32 | |
| 33 | // ////////////////////////////////////////////////////////////////// |
| 34 | // / This file will get compiled as part of the main program, |
| 35 | // / for a _test.v file. |
| 36 | // / The methods defined here are called back by the test program's |
| 37 | // / assert statements, on each success/fail. The goal is to make |
| 38 | // / customizing the look & feel of the assertions results easier, |
| 39 | // / since it is done in normal V code, instead of in embedded C ... |
| 40 | // ////////////////////////////////////////////////////////////////// |
| 41 | // TODO: copy pasta builtin.v fn ___print_assert_failure |
| 42 | fn cb_assertion_failed(i VAssertMetaInfo) { |
| 43 | filepath := if use_relative_paths { i.fpath } else { os.real_path(i.fpath) } |
| 44 | mut final_filepath := filepath + ':${i.line_nr + 1}:' |
| 45 | mut final_funcname := 'fn ' + i.fn_name |
| 46 | final_src := 'assert ' + i.src |
| 47 | |
| 48 | myeprintln('${final_filepath} ${final_funcname}') |
| 49 | |
| 50 | if i.op.len > 0 && i.op != 'call' { |
| 51 | mut lvtitle := ' Left value:' |
| 52 | mut rvtitle := ' Right value:' |
| 53 | mut slvalue := '${i.lvalue}' |
| 54 | mut srvalue := '${i.rvalue}' |
| 55 | cutoff_limit := 30 |
| 56 | if slvalue.len > cutoff_limit || srvalue.len > cutoff_limit { |
| 57 | myeprintln(' > ${final_src}') |
| 58 | myeprintln(lvtitle) |
| 59 | myeprintln(' ${slvalue}') |
| 60 | myeprintln(rvtitle) |
| 61 | myeprintln(' ${srvalue}') |
| 62 | } else { |
| 63 | myeprintln(' > ${final_src}') |
| 64 | myeprintln(' ${lvtitle} ${slvalue}') |
| 65 | myeprintln('${rvtitle} ${srvalue}') |
| 66 | } |
| 67 | } else { |
| 68 | myeprintln(' ${final_src}') |
| 69 | } |
| 70 | myeprintln('') |
| 71 | } |
| 72 | |
| 73 | fn cb_assertion_ok(_ &VAssertMetaInfo) { |
| 74 | } |
| 75 | |
| 76 | fn cb_propagate_test_error(line_nr int, file string, _ string, fn_name string, errmsg string) { |
| 77 | filepath := if use_relative_paths { file } else { os.real_path(file) } |
| 78 | mut final_filepath := filepath + ':${line_nr}:' |
| 79 | mut final_funcname := 'fn ' + fn_name.replace('main.', '').replace('__', '.') |
| 80 | final_msg := errmsg |
| 81 | myeprintln('${final_filepath} ${final_funcname} failed propagation with error: ${final_msg}') |
| 82 | // TODO: implement os.is_file and os.read_lines: |
| 83 | /* |
| 84 | if os.is_file(file) { |
| 85 | source_lines := os.read_lines(file) or { []string{len: line_nr + 1} } |
| 86 | myeprintln('${line_nr:5} | ${source_lines[line_nr - 1]}') |
| 87 | } |
| 88 | */ |
| 89 | } |
| 90 | |