Test all errors and error messages (#145)

This commit is contained in:
Casey Rodarmor 2017-01-08 19:01:48 -08:00 committed by GitHub
parent 64e4905e49
commit 1befc8674e
2 changed files with 269 additions and 14 deletions

View file

@ -344,7 +344,7 @@ recipe:
}
#[test]
fn error() {
fn unknown_dependency() {
integration_test(
&[],
"bar:\nhello:\nfoo: bar baaaaaaaz hello",
@ -740,6 +740,31 @@ wut:
);
}
#[test]
fn outer_shebang() {
integration_test(
&[],
r#"#!/lol/wut
export foo = "a"
baz = "c"
export bar = "b"
export abc = foo + bar + baz
wut:
#!/bin/sh
echo $foo $bar $abc
"#,
255,
"",
"error: `#!` is reserved syntax outside of recipes
|
1 | #!/lol/wut
| ^
",
);
}
#[test]
fn export_shebang() {
integration_test(
@ -1100,6 +1125,53 @@ recipe a b +d:
);
}
#[test]
fn mixed_whitespace() {
integration_test(
&[],
"bar:\n\t echo hello",
255,
"",
"error: Found a mix of tabs and spaces in leading whitespace: `␉␠`
Leading whitespace may consist of tabs or spaces, but not both
|
2 | echo hello
| ^
",
);
}
#[test]
fn extra_leading_whitespace() {
integration_test(
&[],
"bar:\n\t\techo hello\n\t\t\techo goodbye",
255,
"",
"error: Recipe line has extra leading whitespace
|
3 | echo goodbye
| ^^^^^^^^^^^^^^^^
",
);
}
#[test]
fn inconsistent_leading_whitespace() {
integration_test(
&[],
"bar:\n\t\techo hello\n\t echo goodbye",
255,
"",
"error: Recipe line has inconsistent leading whitespace. Recipe started with `␉␉` but found line with `␉␠`
|
3 | echo goodbye
| ^
",
);
}
#[test]
fn required_after_default() {
integration_test(
@ -1115,6 +1187,21 @@ fn required_after_default() {
);
}
#[test]
fn required_after_variadic() {
integration_test(
&[],
"bar:\nhello baz +arg bar:",
255,
"",
"error: Parameter `bar` follows variadic parameter
|
2 | hello baz +arg bar:
| ^^^
",
);
}
#[test]
fn use_string_default() {
integration_test(
@ -1374,6 +1461,128 @@ c: b a
);
}
#[test]
fn parameter_shadows_variable() {
integration_test(
&["a"],
"FOO = 'hello'\na FOO:",
255,
"",
"error: Parameter `FOO` shadows variable of the same name
|
2 | a FOO:
| ^^^
",
);
}
#[test]
fn dependency_takes_arguments() {
integration_test(
&["b"],
"b: a\na FOO:",
255,
"",
"error: Recipe `b` depends on `a` which requires arguments. Dependencies may not require arguments
|
1 | b: a
| ^
",
);
}
#[test]
fn duplicate_parameter() {
integration_test(
&["a"],
"a foo foo:",
255,
"",
"error: Recipe `a` has duplicate parameter `foo`
|
1 | a foo foo:
| ^^^
",
);
}
#[test]
fn duplicate_dependency() {
integration_test(
&["a"],
"b:\na: b b",
255,
"",
"error: Recipe `a` has duplicate dependency `b`
|
2 | a: b b
| ^
",
);
}
#[test]
fn duplicate_recipe() {
integration_test(
&["b"],
"b:\nb:",
255,
"",
"error: Recipe `b` first defined on line 1 is redefined on line 2
|
2 | b:
| ^
",
);
}
#[test]
fn duplicate_variable() {
integration_test(
&["foo"],
"a = 'hello'\na = 'hello'\nfoo:",
255,
"",
"error: Variable `a` has multiple definitions
|
2 | a = 'hello'
| ^
",
);
}
#[test]
fn unexpected_token() {
integration_test(
&["foo"],
"foo: 'bar'",
255,
"",
"error: Expected name, end of line, or end of file, but found raw string
|
1 | foo: 'bar'
| ^^^^^
",
);
}
#[test]
fn self_dependency() {
integration_test(
&["a"],
"a: a",
255,
"",
"error: Recipe `a` depends on itself
|
1 | a: a
| ^
",
);
}
#[test]
fn long_circular_recipe_dependency() {
integration_test(
@ -1389,6 +1598,53 @@ fn long_circular_recipe_dependency() {
);
}
#[test]
fn variable_self_dependency() {
integration_test(
&["a"],
"z = z\na:",
255,
"",
"error: Variable `z` is defined in terms of itself
|
1 | z = z
| ^
",
);
}
#[test]
fn variable_circular_dependency() {
integration_test(
&["a"],
"x = y\ny = z\nz = x\na:",
255,
"",
"error: Variable `x` depends on its own value: `x -> y -> z -> x`
|
1 | x = y
| ^
",
);
}
#[test]
fn invalid_escape_sequence() {
integration_test(
&["a"],
r#"x = "\q"
a:"#,
255,
"",
"error: `\\q` is not a valid escape sequence
|
1 | x = \"\\q\"
| ^^^^
",
);
}
#[test]
fn multiline_raw_string() {
integration_test(

View file

@ -828,7 +828,7 @@ fn internal_error(message: String) -> CompileError<'static> {
}
fn show_whitespace(text: &str) -> String {
text.chars().map(|c| match c { '\t' => 't', ' ' => 's', _ => c }).collect()
text.chars().map(|c| match c { '\t' => '␉', ' ' => '␠', _ => c }).collect()
}
fn mixed_whitespace(text: &str) -> bool {
@ -1052,7 +1052,7 @@ impl<'a> Display for CompileError<'a> {
match self.kind {
CircularRecipeDependency{recipe, ref circle} => {
if circle.len() == 2 {
write!(f, "Recipe `{}` depends on itself", recipe)?;
writeln!(f, "Recipe `{}` depends on itself", recipe)?;
} else {
writeln!(f, "Recipe `{}` has circular dependency `{}`",
recipe, circle.join(" -> "))?;
@ -1060,8 +1060,7 @@ impl<'a> Display for CompileError<'a> {
}
CircularVariableDependency{variable, ref circle} => {
if circle.len() == 2 {
writeln!(f, "Variable `{}` depends on its own value: `{}`",
variable, circle.join(" -> "))?;
writeln!(f, "Variable `{}` is defined in terms of itself", variable)?;
} else {
writeln!(f, "Variable `{}` depends on its own value: `{}`",
variable, circle.join(" -> "))?;
@ -1075,21 +1074,21 @@ impl<'a> Display for CompileError<'a> {
writeln!(f, "Recipe `{}` has duplicate parameter `{}`", recipe, parameter)?;
}
DuplicateVariable{variable} => {
writeln!(f, "Variable `{}` is has multiple definitions", variable)?;
writeln!(f, "Variable `{}` has multiple definitions", variable)?;
}
UnexpectedToken{ref expected, found} => {
writeln!(f, "Expected {} but found {}", Or(expected), found)?;
writeln!(f, "Expected {}, but found {}", Or(expected), found)?;
}
DuplicateDependency{recipe, dependency} => {
writeln!(f, "Recipe `{}` has duplicate dependency `{}`", recipe, dependency)?;
}
DuplicateRecipe{recipe, first} => {
writeln!(f, "Recipe `{}` first defined on line {} is redefined on line {}",
recipe, first, self.line)?;
recipe, first + 1, self.line + 1)?;
}
DependencyHasParameters{recipe, dependency} => {
writeln!(f, "Recipe `{}` depends on `{}` which requires arguments. \
dependencies may not require arguments", recipe, dependency)?;
Dependencies may not require arguments", recipe, dependency)?;
}
ParameterShadowsVariable{parameter} => {
writeln!(f, "Parameter `{}` shadows variable of the same name", parameter)?;
@ -1098,12 +1097,12 @@ impl<'a> Display for CompileError<'a> {
writeln!(f, "Non-default parameter `{}` follows default parameter", parameter)?;
}
ParameterFollowsVariadicParameter{parameter} => {
writeln!(f, "Parameter `{}` follows a varidic parameter", parameter)?;
writeln!(f, "Parameter `{}` follows variadic parameter", parameter)?;
}
MixedLeadingWhitespace{whitespace} => {
writeln!(f,
"Found a mix of tabs and spaces in leading whitespace: `{}`\n\
leading whitespace may consist of tabs or spaces, but not both",
Leading whitespace may consist of tabs or spaces, but not both",
show_whitespace(whitespace)
)?;
}
@ -1112,12 +1111,12 @@ impl<'a> Display for CompileError<'a> {
}
InconsistentLeadingWhitespace{expected, found} => {
writeln!(f,
"Inconsistant leading whitespace: recipe started with `{}` but found line with `{}`:",
"Recipe line has inconsistent leading whitespace. Recipe started with `{}` but found line with `{}`",
show_whitespace(expected), show_whitespace(found)
)?;
}
OuterShebang => {
writeln!(f, "Shebang `#!` is reserved syntax outside of recipes")?;
writeln!(f, "`#!` is reserved syntax outside of recipes")?;
}
UnknownDependency{recipe, unknown} => {
writeln!(f, "Recipe `{}` has unknown dependency `{}`", recipe, unknown)?;
@ -1405,7 +1404,7 @@ impl<'a> Display for RunError<'a> {
error_token = Some(token);
}
BacktickUnknownFailure{ref token} => {
write!(f, "Backtick failed for an uknown reason")?;
write!(f, "Backtick failed for an unknown reason")?;
error_token = Some(token);
}
BacktickIoError{ref token, ref io_error} => {