12#![cfg(test)]34use hi_doc::{Formatting, SnippetBuilder, Text};5use thiserror::Error;67use crate::{parse, AstNode};89fn process(text: &str) -> String {10 use std::fmt::Write;11 let mut out = String::new();12 let (node, errors) = parse(text);13 write!(out, "{:#?}", node.syntax()).unwrap();14 if !errors.is_empty() && !text.is_empty() {15 writeln!(out, "===").unwrap();16 for err in &errors {17 writeln!(out, "{:?}", err).unwrap();18 }19 let mut code = text.to_string();2021 22 if code.ends_with('\n') {23 code.truncate(code.len() - 1);24 code += " ";25 }26 code += " ";2728 let mut s = SnippetBuilder::new(code);2930 for error in errors {31 s.error(Text::fragment(32 format!("{}", error.error),33 Formatting::default(),34 ))35 .range(error.range.start().into()..=error.range.end().into())36 .build();37 }3839 writeln!(out, "===").unwrap();40 let ansi = hi_doc::source_to_ansi(&s.build());41 let text = strip_ansi_escapes::strip_str(&ansi);42 out.push_str(&text);43 }44 out.split('\n')45 .map(|s| s.trim_end().to_string())46 .collect::<Vec<String>>()47 .join("\n")48 .trim_end()49 .to_string()50}51macro_rules! mk_test {52 ($($name:ident => $test:expr)+) => {$(53 #[test]54 fn $name() {55 let src = indoc::indoc!($test);56 let result = process(&src);57 insta::assert_snapshot!(stringify!($name), result, src);5859 }60 )+};61 }62mk_test!(63 empty => r#" "#64 function => r#"65 function(a, b = 1) a + b66 "#67 function_error_no_value => r#"68 function(a, b = ) a + b69 "#70 function_error_rparen => r#"71 function(a, b72 "#73 function_error_body => r#"74 function(a, b)75 "#76 local_novalue => r#"77 local a =78 "#79 local_no_value_recovery => r#"80 local a =81 local b = 3;82 183 "#848586 no_rhs => r#"87 a +88 "#89 no_lhs => r#"90 + 291 "#92 no_operator => "93 2 294 "9596 named_before_positional => "97 a(1, 2, b=4, 3, 5, k = 12, 6)98 "99100 wrong_field_end => "101 {102 a: 1;103 b: 2;104 }105 "106107108 plain_call => "109 std.substr(a, 0, std.length(b)) == b110 "111112 destruct => "113 local [a, b, c] = arr;114 local [a, ...] = arr_rest;115 local [..., a] = rest_arr;116 local [...] = rest_in_arr;117 local [a, ...n] = arr_rest_n;118 local [...n, a] = rest_arr_n;119 local [...n] = rest_in_arr_n;120121 local {a, b, c} = obj;122 local {a, b, c, ...} = obj_rest;123 local {a, b, c, ...n} = obj_rest_n;124125 null126 "127128 str_block_missing_indent => "129 |||130 "131 str_block_missing_termination => "132 |||133 hello134 "135 str_block_missing_newline => "136 |||hello137 "138 str_block_missing_indent_text => "139 |||140 hello141 "142143 unexpected_destruct => "144 local * = 1;145 a146 "147 arr_compspec => r#"148 [a for a in [1, 2, 3]]149 "#150 arr_compspec_comma => "151 [a, for a in [1, 2, 3]]152 "153 arr_compspec_no_elems => "154 [for a in [1, 2, 3]]155 "156 arr_compspec_incompatible_with_multiple_elems => r#"157 [a for a in [1, 2, 3], b]158 "#159 arr_compspec_incompatible_with_multiple_elems_w => r#"160 [a, b, for a in [1, 2, 3], c]161 "#162163 obj_compspec => r#"164 {a:1 for a in [1, 2, 3]}165 "#166 obj_compspec_comma => "167 {a:1, for a in [1, 2, 3]}168 "169 obj_compspec_no_elems => "170 {for a in [1, 2, 3]}171 "172 obj_compspec_incompatible_with_multiple_elems => r#"173 {a:1 for a in [1, 2, 3], b:1}174 "#175 obj_compspec_incompatible_with_multiple_elems_w => r#"176 {a:1, b:1, for a in [1, 2, 3], c:1}177 "#178179 obj_compspec_incompatible_with_asserts => r#"180 {assert 1, a: 1 for a in [1,2,3]}181 "#182183 local_method => r#"184 local185 a(x) = x,186 a = function(x) x,187 ; c188 "#189 obj_method => r#"190 {191 a(x): x,192 a: function(x) x,193 }194 "#195196 continue_after_total_failure => r#"197 local intr = $intrinsic(test);198199 local a = 1, b = 2, c = a + b;200201 [c]202 "#203204 super_nesting => r#"205 super.a + super.b206 "#207);208209#[test]210fn eval_simple() {211 let src = "local a = 1, b = 2; a + local c = 1; c";212 let (node, _errors) = parse(src);213214 dbg!(node);215}