2019-05-17 18:33:47 -05:00
|
|
|
// Copyright 2019 Jeremy Wall
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
2019-05-21 20:34:42 -05:00
|
|
|
use std::collections::BTreeMap;
|
2019-05-17 18:33:47 -05:00
|
|
|
|
|
|
|
use crate::ast::printer::*;
|
|
|
|
use crate::iter::OffsetStrIter;
|
|
|
|
use crate::parse::*;
|
|
|
|
|
2019-05-20 21:02:51 -05:00
|
|
|
fn assert_parse(input: &str, comment_map: Option<&mut CommentMap>) -> Vec<Statement> {
|
|
|
|
parse(OffsetStrIter::new(input), comment_map).unwrap()
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
2019-05-23 19:52:03 -05:00
|
|
|
fn print_to_buffer(input: &str) -> String {
|
|
|
|
let mut comment_map = BTreeMap::new();
|
|
|
|
let stmts = assert_parse(input, Some(&mut comment_map));
|
|
|
|
let mut buffer: Vec<u8> = Vec::new();
|
|
|
|
let mut printer = AstPrinter::new(2, &mut buffer).with_comment_map(&comment_map);
|
|
|
|
assert!(printer.render(&stmts).is_ok());
|
|
|
|
String::from_utf8(buffer).unwrap()
|
|
|
|
}
|
|
|
|
|
2019-05-17 18:33:47 -05:00
|
|
|
#[test]
|
|
|
|
fn test_simple_value_printing() {
|
|
|
|
let input = "1;";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:31:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_simple_selector_printing() {
|
|
|
|
let input = "foo.bar.quux;";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_simple_quoted_printing() {
|
|
|
|
let input = "\"foo\";";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_escaped_quoted_printing() {
|
|
|
|
let input = "\"f\\\\o\\\"o\";";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_empty_tuple_printing() {
|
|
|
|
let input = "{};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_empty_list_printing() {
|
|
|
|
let input = "[];";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_non_empty_tuple_printing() {
|
|
|
|
let input = "{\n foo = 1,\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_nested_empty_tuple_printing() {
|
|
|
|
let input = "{\n foo = {},\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_list_nested_empty_tuple_printing() {
|
|
|
|
let input = "[\n {},\n];";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_nested_non_empty_tuple_printing() {
|
|
|
|
let input = "{\n foo = {\n bar = 1,\n },\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_nested_non_empty_list_printing() {
|
|
|
|
let input = "[\n [\n 1,\n ],\n];";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_simple_quoted_field_tuple_printing() {
|
|
|
|
let input = "{\n \"foo\" = {\n bar = 1,\n },\n};";
|
|
|
|
assert_eq!(
|
2019-05-23 19:52:03 -05:00
|
|
|
print_to_buffer(input),
|
2019-05-17 18:33:47 -05:00
|
|
|
format!("{}\n", "{\n foo = {\n bar = 1,\n },\n};")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_special_quoted_field_tuple_printing() {
|
|
|
|
let input = "{\n \"foo bar\" = {\n bar = 1,\n },\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_let_statement_printing() {
|
|
|
|
let input = "let tpl = {\n \"foo bar\" = {\n bar = 1,\n },\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 18:33:47 -05:00
|
|
|
}
|
2019-05-17 19:31:29 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_call_expr_printing() {
|
|
|
|
let input = "call(\n foo,\n bar,\n);";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:31:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_call_expr_one_arg_printing() {
|
|
|
|
let input = "call(foo);";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:31:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_copy_expr_printing() {
|
|
|
|
let input = "copy{\n foo = 1,\n bar = 2,\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:31:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_copy_expr_one_arg_printing() {
|
|
|
|
let input = "copy{\n foo = 1,\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:31:29 -05:00
|
|
|
}
|
2019-05-17 19:58:48 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_out_expr_printing() {
|
|
|
|
let input = "out json {\n foo = 1,\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:58:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_select_expr_no_default_printing() {
|
|
|
|
let input = "select true, {\n true = 1,\n false = 2,\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:58:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_select_expr_with_default_printing() {
|
|
|
|
let input = "select true, 3, {\n true = 1,\n false = 2,\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:58:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_not_expr_printing() {
|
|
|
|
let input = "not true;";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:58:48 -05:00
|
|
|
}
|
|
|
|
|
2019-05-17 21:21:20 -05:00
|
|
|
#[test]
|
|
|
|
fn test_fail_expr_printing() {
|
|
|
|
let input = "fail \"AHHh\";";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 21:21:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_trace_expr_printing() {
|
|
|
|
let input = "TRACE \"AHHh\";";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 21:21:20 -05:00
|
|
|
}
|
|
|
|
|
2019-05-17 19:58:48 -05:00
|
|
|
#[test]
|
|
|
|
fn test_module_no_out_expr_printing() {
|
|
|
|
let input = "let m = module {
|
|
|
|
hostname = \"\",
|
|
|
|
mem = 2048,
|
|
|
|
cpu = 2,
|
|
|
|
} => {
|
|
|
|
let config = {
|
|
|
|
hostname = mod.hostname,
|
|
|
|
\"memory_size\" = mod.mem,
|
|
|
|
\"cpu_count\" = mod.cpu,
|
|
|
|
};
|
|
|
|
};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:58:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_module_with_out_expr_printing() {
|
|
|
|
let input = "let m = module {
|
|
|
|
hostname = \"\",
|
|
|
|
mem = 2048,
|
|
|
|
cpu = 2,
|
|
|
|
} => (config) {
|
|
|
|
let config = {
|
|
|
|
hostname = mod.hostname,
|
|
|
|
\"memory_size\" = mod.mem,
|
|
|
|
\"cpu_count\" = mod.cpu,
|
|
|
|
};
|
|
|
|
};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 19:58:48 -05:00
|
|
|
}
|
2019-05-17 20:06:06 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_func_expr_printing() {
|
|
|
|
let input = "let f = func (foo, bar) => {
|
|
|
|
foo = foo,
|
|
|
|
bar = bar,
|
|
|
|
};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 20:06:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_func_expr_single_arg_printing() {
|
|
|
|
let input = "let f = func (foo) => {
|
|
|
|
foo = foo,
|
|
|
|
};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 20:06:06 -05:00
|
|
|
}
|
2019-05-17 21:19:01 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_format_expr_single_arg_printing() {
|
|
|
|
let input = "\"what? @{item.foo}\" % {
|
|
|
|
foo = 1,
|
|
|
|
};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 21:19:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_format_expr_list_arg_printing() {
|
|
|
|
let input = "\"what? @ @\" % (
|
|
|
|
1,
|
|
|
|
2);";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-17 21:19:01 -05:00
|
|
|
}
|
2019-05-21 20:34:42 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_statement_with_comment_printing() {
|
|
|
|
let input = "// add 1 + 1\n1 + 1;";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-21 20:34:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_statement_with_comment_printing_groups() {
|
|
|
|
let input = "// add 1\n// and 1\n1 + 1;";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-21 20:34:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_statement_with_comment_printing_multiple_groups() {
|
|
|
|
let input = "\n// group 1\n// more group 1\n\n// group 2\n// more group 2\n1 + 1;";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input.trim()));
|
2019-05-21 20:34:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_statement_with_comment_printing_comments_at_end() {
|
|
|
|
let input = "// group 1\n1 + 1;\n// group 2\n\n";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input.trim()));
|
2019-05-21 20:34:42 -05:00
|
|
|
}
|
2019-05-22 18:29:25 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_tuple_expression_with_embedded_comment() {
|
|
|
|
let input = "{\n foo = bar,\n // a comment\n bar = foo,\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-22 18:29:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_tuple_expression_with_embedded_comment_mid_field_expr() {
|
|
|
|
let input = "{\n foo = bar,\n bar =\n// a comment\n foo\n};";
|
|
|
|
assert_eq!(
|
2019-05-23 19:52:03 -05:00
|
|
|
print_to_buffer(input),
|
|
|
|
"{\n foo = bar,\n // a comment\n bar = foo,\n};\n"
|
2019-05-22 18:29:25 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_tuple_expression_with_embedded_comment_and_mid_field_expr() {
|
|
|
|
let input = "{\n foo = bar,\n// a comment\n bar =\n// another comment\n foo\n};";
|
|
|
|
assert_eq!(
|
2019-05-23 19:52:03 -05:00
|
|
|
print_to_buffer(input),
|
|
|
|
"{\n foo = bar,\n // a comment\n // another comment\n bar = foo,\n};\n"
|
2019-05-22 18:29:25 -05:00
|
|
|
);
|
|
|
|
}
|
2019-05-22 18:34:42 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_list_expression_with_embedded_comment() {
|
|
|
|
let input = "[\n bar,\n // a comment\n foo,\n];";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-22 18:34:42 -05:00
|
|
|
}
|
2019-05-22 18:52:10 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_binary_expression_with_embedded_comment() {
|
|
|
|
let input = "true == \n// false is not true\nfalse;";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-22 18:52:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_empty_call_expression_with_comment() {
|
|
|
|
let input = "// a comment\nmyfunc();";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-22 18:52:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_call_expression_with_embedded_comment_in_args() {
|
|
|
|
let input = "// a comment\nmyfunc(\n arg1,\n // another comment\n arg2,\n);";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-22 18:52:10 -05:00
|
|
|
}
|
2019-05-22 19:05:48 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_copy_expression_with_embedded_comment_in_args() {
|
|
|
|
let input = "// a comment\nmyfunc{\n foo = arg1,\n // another comment\n bar = arg2,\n};";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-22 19:05:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_trace_expression_with_embedded_comment() {
|
|
|
|
let input = "// a comment\nTRACE \n// another comment\nfoo;";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-22 19:05:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_fail_expression_with_embedded_comment() {
|
|
|
|
let input = "// a comment\nfail \n// another comment\nfoo;";
|
2019-05-23 19:52:03 -05:00
|
|
|
assert_eq!(print_to_buffer(input), format!("{}\n", input));
|
2019-05-22 19:05:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_format_expression_with_embedded_comment() {
|
|
|
|
let input = "// a comment\n\"@(item.bar)\" % \n// another comment\nfoo;";
|
2019-05-23 19:52:03 -05:00
|
|
|
let output = print_to_buffer(input);
|
|
|
|
assert_eq!(output, format!("{}\n", input.trim()));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_filter_func_operator_expression_with_embedded_comment() {
|
|
|
|
//let input = "// a comment\nfilter(foo, bar);";
|
|
|
|
let input = "// a comment\nfilter(\n // another comment\n foo,\n // one more\n bar);";
|
|
|
|
let output = print_to_buffer(input);
|
|
|
|
assert_eq!(output, format!("{}\n", input.trim()));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_reduce_func_operator_expression_with_embedded_comment() {
|
|
|
|
//let input = "// a comment\nfilter(foo, bar);";
|
|
|
|
let input = "// a comment\nreduce(
|
|
|
|
// another comment
|
|
|
|
myfunc,
|
|
|
|
// one more
|
|
|
|
acc,
|
|
|
|
// and the last
|
|
|
|
target);";
|
|
|
|
let output = print_to_buffer(input);
|
|
|
|
assert_eq!(output, format!("{}\n", input.trim()));
|
2019-05-22 19:05:48 -05:00
|
|
|
}
|
2019-05-23 19:57:51 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_map_func_operator_expression_with_embedded_comment() {
|
|
|
|
//let input = "// a comment\nfilter(foo, bar);";
|
|
|
|
let input = "// a comment\nmap(\n // another comment\n foo,\n // one more\n bar);";
|
|
|
|
let output = print_to_buffer(input);
|
|
|
|
assert_eq!(output, format!("{}\n", input.trim()));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_grouped_expression_with_embedded_comment() {
|
|
|
|
//let input = "// a comment\nfilter(foo, bar);";
|
|
|
|
let input = "// a comment\n(\n // a comment\n foo\n);";
|
|
|
|
let output = print_to_buffer(input);
|
|
|
|
assert_eq!(output, format!("{}\n", input.trim()));
|
|
|
|
}
|