More straightforward pretty printing tests 🧹

This commit is contained in:
Laurenz 2021-01-26 21:57:56 +01:00
parent f006636dd2
commit 010ddc4795
3 changed files with 93 additions and 92 deletions

View File

@ -64,6 +64,8 @@ impl Pretty for Expr {
Self::Angle(v, u) => write!(p, "{}{}", v, u).unwrap(),
Self::Percent(v) => write!(p, "{}%", v).unwrap(),
Self::Color(v) => write!(p, "{}", v).unwrap(),
// TODO: Debug escapes a bit more than we want (e.g. apostrophes).
// We probably need to do the escaping ourselves.
Self::Str(v) => write!(p, "{:?}", &v).unwrap(),
Self::Array(v) => v.pretty(p),
Self::Dict(v) => v.pretty(p),
@ -543,61 +545,3 @@ impl Pretty for ExprFor {
self.body.v.pretty(p);
}
}
#[cfg(test)]
mod tests {
use super::super::tests::test_pretty;
#[test]
fn test_pretty_print_chaining() {
// All equivalent.
test_pretty("[v [[f]]]", "[v | f]");
test_pretty("[v][[f]]", "[v | f]");
test_pretty("[v | f]", "[v | f]");
}
#[test]
fn test_pretty_print_expressions() {
// Unary and binary operations.
test_pretty("{}", "{}");
test_pretty("{1 +}", "{1}");
test_pretty("{1++1}", "{1 + +1}");
test_pretty("{+-1}", "{+-1}");
test_pretty("{1 + func(-2)}", "{1 + func(-2)}");
test_pretty("{1+2*3}", "{1 + 2 * 3}");
test_pretty("{(1+2)*3}", "{(1 + 2) * 3}");
// Array.
test_pretty("(-5,)", "(-5,)");
test_pretty("(1, 2, 3)", "(1, 2, 3)");
// Dictionary.
test_pretty("{(:)}", "{(:)}");
test_pretty("{(percent: 5%)}", "{(percent: 5%)}");
// Content expression.
test_pretty("[v [[f]], 1]", "[v [[f]], 1]");
// Parens and blocks.
test_pretty("{(1)}", "{(1)}");
test_pretty("{{1}}", "{{1}}");
// Control flow.
test_pretty("#let x = 1+2", "#let x = 1 + 2");
test_pretty("#if x [y] #else [z]", "#if x [y] #else [z]");
test_pretty("#for x #in y {z}", "#for x #in y {z}");
}
#[test]
fn test_pretty_print_literals() {
test_pretty("{none}", "{none}");
test_pretty("{true}", "{true}");
test_pretty("{25}", "{25}");
test_pretty("{2.50}", "{2.5}");
test_pretty("{1e2}", "{100.0}");
test_pretty("{12pt}", "{12pt}");
test_pretty("{90.0deg}", "{90deg}");
test_pretty("{50%}", "{50%}");
test_pretty("{#fff}", "{#ffffff}");
test_pretty(r#"{"hi\n"}"#, r#"{"hi\n"}"#);
}
}

View File

@ -31,7 +31,7 @@ mod tests {
use crate::pretty::pretty;
#[track_caller]
pub fn test_pretty(src: &str, exp: &str) {
fn test(src: &str, exp: &str) {
let tree = parse(src).output;
let found = pretty(&tree);
if exp != found {
@ -41,4 +41,91 @@ mod tests {
panic!("test failed");
}
}
#[track_caller]
fn roundtrip(src: &str) {
test(src, src);
}
#[test]
fn test_pretty_print_node() {
// Basic text and markup.
roundtrip("*");
roundtrip("_");
roundtrip(" ");
roundtrip("\\ ");
roundtrip("\n\n");
roundtrip("hi");
// Heading.
roundtrip("# *Ok*");
// Raw.
roundtrip("`lang 1`");
test("`` hi``", "`hi`");
test("`` ` ``", "```");
}
#[test]
fn test_pretty_print_expr() {
// Basic expressions.
roundtrip("{none}");
roundtrip("{hi}");
roundtrip("{true}");
roundtrip("{10}");
roundtrip("{3.14}");
roundtrip("{10pt}");
roundtrip("{14.1deg}");
roundtrip("{20%}");
roundtrip("{#abcdef}");
roundtrip(r#"{"hi"}"#);
test(r#"{"let's go"}"#, r#"{"let\'s go"}"#);
// Arrays.
roundtrip("{()}");
roundtrip("{(1)}");
roundtrip("{(1, 2, 3)}");
// Dictionaries.
roundtrip("{(:)}");
roundtrip("{(key: value)}");
roundtrip("{(a: 1, b: 2)}");
// Templates.
roundtrip("{[]}");
roundtrip("{[*Ok*]}");
roundtrip("{[[f]]}");
// Groups.
roundtrip("{(1)}");
// Blocks.
roundtrip("{}");
roundtrip("{1}");
roundtrip("{ #let x = 1; x += 2; x + 1 }");
// Operators.
roundtrip("{-x}");
roundtrip("{not true}");
roundtrip("{1 + 3}");
// Parenthesized calls.
roundtrip("{v()}");
roundtrip("{v(1)}");
roundtrip("{v(a: 1, b)}");
// Bracket calls.
roundtrip("[v]");
roundtrip("[v 1]");
roundtrip("[v 1, 2][*Ok*]");
roundtrip("[v 1 | f 2]");
roundtrip("{[[v]]}");
test("[v 1, [[f 2]]]", "[v 1 | f 2]");
test("[v 1, 2][[f 3]]", "[v 1, 2 | f 3]");
// Keywords.
roundtrip("#let x = 1 + 2");
roundtrip("#if x [y] #else [z]");
roundtrip("#for x #in y {z}");
}
}

View File

@ -150,40 +150,10 @@ impl Pretty for NodeRaw {
p.push_str(&lang);
p.push_str(" ");
}
// TODO: Technically, we should handle backticks in the lines
// by wrapping with more backticks and possibly adding space
// before the first or after the last line.
// TODO: Technically, we should handle backticks in the lines by
// wrapping with more backticks, and we should add space before the
// first and/or after the last line if necessary.
p.join(&self.lines, "\n", |line, p| p.push_str(line));
p.push_str("`");
}
}
#[cfg(test)]
mod tests {
use super::super::tests::test_pretty;
#[test]
fn test_pretty_print_bracket_calls() {
// Top-level call expression formatted as bracket call.
test_pretty("[v]", "[v]");
// Blocks are preserved.
test_pretty("{v()}", "{v()}");
test_pretty("{[[v]]}", "{[[v]]}");
}
#[test]
fn test_pretty_print_nodes() {
// Basic text and markup.
test_pretty(r"*Hi_\", r"*Hi_\");
// Whitespace.
test_pretty(" ", " ");
test_pretty("\n\n\n", "\n\n");
// Heading and raw.
test_pretty("# Ok", "# Ok");
test_pretty("``\none\ntwo\n``", "`one\ntwo`");
test_pretty("`lang one\ntwo`", "`lang one\ntwo`");
}
}