Add dedicated pretty-printer tests with new pp-exact directive

Add a new src/test/pretty directory to hold just source files for testing the
pretty-printer.

Add a new pp-exact directive. When this directive is followed by a file name
it specifies a file containing the output that the pretty-printer should
generate. When pp-exact is not followed by a filename it says that the file
should pretty-print as written.
This commit is contained in:
Brian Anderson 2011-08-01 14:10:59 -07:00
parent eea888af25
commit 0fbb6782bb
7 changed files with 86 additions and 12 deletions

View file

@ -1,6 +1,7 @@
import std::option;
import std::str;
import std::io;
import std::fs;
import common::config;
@ -8,24 +9,40 @@ export test_props;
export load_props;
export is_test_ignored;
type test_props = {error_patterns: str[], compile_flags: option::t[str]};
type test_props = {
// Lines that should be expected, in order, on standard out
error_patterns: str[],
// Extra flags to pass to the compiler
compile_flags: option::t[str],
// If present, the name of a file that this test should match when
// pretty-printed
pp_exact: option::t[str]
};
// Load any test directives embedded in the file
fn load_props(testfile: &str) -> test_props {
let error_patterns = ~[];
let compile_flags = option::none;
let pp_exact = option::none;
for each ln: str in iter_header(testfile) {
alt parse_error_pattern(ln) {
option::some(ep) { error_patterns += ~[ep]; }
option::none. { }
}
if option::is_none(compile_flags) {
compile_flags = parse_compile_flags(ln);
}
if option::is_none(pp_exact) {
pp_exact = parse_pp_exact(ln, testfile);
}
}
ret {error_patterns: error_patterns, compile_flags: compile_flags};
ret {
error_patterns: error_patterns,
compile_flags: compile_flags,
pp_exact: pp_exact
};
}
fn is_test_ignored(config: &config, testfile: &str) -> bool {
@ -64,6 +81,19 @@ fn parse_compile_flags(line: &str) -> option::t[str] {
parse_name_value_directive(line, "compile-flags")
}
fn parse_pp_exact(line: &str, testfile: &str) -> option::t[str] {
alt parse_name_value_directive(line, "pp-exact") {
option::some(s) { option::some(s) }
option::none. {
if parse_name_directive(line, "pp-exact") {
option::some(fs::basename(testfile))
} else {
option::none
}
}
}
}
fn parse_name_directive(line: &str, directive: &str) -> bool {
str::find(line, directive) >= 0
}

View file

@ -75,7 +75,16 @@ fn run_rpass_test(cx: &cx, props: &test_props, testfile: &str) {
}
fn run_pretty_test(cx: &cx, props: &test_props, testfile: &str) {
const rounds: int = 2;
if option::is_some(props.pp_exact) {
logv(cx.config, "testing for exact pretty-printing");
} else {
logv(cx.config, "testing for converging pretty-printing");
}
let rounds = alt props.pp_exact {
option::some(_) { 1 }
option::none. { 2 }
};
let srcs = ~[str::unsafe_from_bytes(
io::file_reader(testfile).read_whole_stream())];
@ -94,7 +103,16 @@ fn run_pretty_test(cx: &cx, props: &test_props, testfile: &str) {
round += 1;
}
let expected = srcs.(ivec::len(srcs) - 2u);
let expected = alt props.pp_exact {
option::some(file) {
let filepath = fs::connect(fs::dirname(testfile), file);
str::unsafe_from_bytes(
io::file_reader(filepath).read_whole_stream())
}
option::none. {
srcs.(ivec::len(srcs) - 2u)
}
};
let actual = srcs.(ivec::len(srcs) - 1u);
compare_source(expected, actual);
@ -122,7 +140,7 @@ fn run_pretty_test(cx: &cx, props: &test_props, testfile: &str) {
fn compare_source(expected: &str, actual: &str) {
if expected != actual {
error("pretty-printed source does not converge");
error("pretty-printed source does match expected source");
let msg = #fmt("\n\
expected:\n\
------------------------------------------\n\

View file

@ -0,0 +1,3 @@
// pp-exact
fn main() { }

View file

@ -0,0 +1,3 @@
// pp-exact:example2.pp
fn main() { }

View file

@ -0,0 +1,7 @@
// pp-exact:example2.pp
fn
main
()
{
}