git.delta.rocks / jrsonnet / refs/commits / f314b37b4c17

difftreelog

source

crates/jrsonnet-rowan-parser/src/tests.rs4.6 KiBsourcehistory
1// `never`2#![cfg(any())]34use miette::{5	Diagnostic, GraphicalReportHandler, GraphicalTheme, LabeledSpan, ThemeCharacters, ThemeStyles,6};7use thiserror::Error;89use crate::{parse, AstNode};1011#[derive(Debug, Error)]12#[error("syntax error")]13struct MyDiagnostic {14	code: String,15	spans: Vec<LabeledSpan>,16}17impl Diagnostic for MyDiagnostic {18	fn code<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {19		None20	}2122	fn severity(&self) -> Option<miette::Severity> {23		None24	}2526	fn help<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {27		None28	}2930	fn url<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {31		None32	}3334	fn source_code(&self) -> Option<&dyn miette::SourceCode> {35		Some(&self.code)36	}3738	fn labels(&self) -> Option<Box<dyn Iterator<Item = miette::LabeledSpan> + '_>> {39		Some(Box::new(self.spans.clone().into_iter()))40	}4142	fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {43		None44	}45}4647fn process(text: &str) -> String {48	use std::fmt::Write;49	let mut out = String::new();50	let (node, errors) = parse(text);51	write!(out, "{:#?}", node.syntax()).unwrap();52	if !errors.is_empty() && !text.is_empty() {53		writeln!(out, "===").unwrap();54		for err in &errors {55			writeln!(out, "{:?}", err).unwrap();56		}57		let mut code = text.to_string();5859		// Prettier errors at EOF position60		if code.ends_with('\n') {61			code.truncate(code.len() - 1);62			code += " ";63		}64		code += " ";6566		let diag = MyDiagnostic {67			code,68			spans: errors.into_iter().map(|e| e.into()).collect(),69		};7071		let handler = GraphicalReportHandler::new_themed(GraphicalTheme {72			characters: ThemeCharacters::ascii(),73			styles: ThemeStyles::none(),74		});7576		writeln!(out, "===").unwrap();77		handler78			.render_report(&mut out, &diag)79			.expect("fmt error?..");80	}81	out.split('\n')82		.map(|s| s.trim_end().to_string())83		.collect::<Vec<String>>()84		.join("\n")85		.trim_end()86		.to_string()87}88macro_rules! mk_test {89		($($name:ident => $test:expr)+) => {$(90			#[test]91			fn $name() {92				let src = indoc::indoc!($test);93				let result = process(&src);94				insta::assert_snapshot!(stringify!($name), result, src);9596			}97		)+};98	}99mk_test!(100	empty => r#" "#101	function => r#"102		function(a, b = 1) a + b103	"#104	function_error_no_value => r#"105		function(a, b = ) a + b106	"#107	function_error_rparen => r#"108		function(a, b109	"#110	function_error_body => r#"111		function(a, b)112	"#113	local_novalue => r#"114		local a =115	"#116	local_no_value_recovery => r#"117		local a =118		local b = 3;119		1120	"#121122123	no_rhs => r#"124		a +125	"#126	no_lhs => r#"127		+ 2128	"#129	no_operator => "130		2 2131	"132133	named_before_positional => "134		a(1, 2, b=4, 3, 5, k = 12, 6)135	"136137	wrong_field_end => "138		{139			a: 1;140			b: 2;141		}142	"143144145	plain_call => "146		std.substr(a, 0, std.length(b)) == b147	"148149	destruct => "150		local [a, b, c] = arr;151		local [a, ...] = arr_rest;152		local [..., a] = rest_arr;153		local [...] = rest_in_arr;154		local [a, ...n] = arr_rest_n;155		local [...n, a] = rest_arr_n;156		local [...n] = rest_in_arr_n;157158		local {a, b, c} = obj;159		local {a, b, c, ...} = obj_rest;160		local {a, b, c, ...n} = obj_rest_n;161162		null163	"164165	str_block_missing_indent => "166		|||167	"168	str_block_missing_termination => "169		|||170			hello171	"172	str_block_missing_newline => "173		|||hello174	"175	str_block_missing_indent_text => "176		|||177		hello178	"179180	unexpected_destruct => "181		local * = 1;182		a183	"184	arr_compspec => r#"185		[a for a in [1, 2, 3]]186	"#187	arr_compspec_comma => "188		[a, for a in [1, 2, 3]]189	"190	arr_compspec_no_elems => "191		[for a in [1, 2, 3]]192	"193	arr_compspec_incompatible_with_multiple_elems => r#"194		[a for a in [1, 2, 3], b]195	"#196	arr_compspec_incompatible_with_multiple_elems_w => r#"197		[a, b, for a in [1, 2, 3], c]198	"#199200	obj_compspec => r#"201		{a:1 for a in [1, 2, 3]}202	"#203	obj_compspec_comma => "204		{a:1, for a in [1, 2, 3]}205	"206	obj_compspec_no_elems => "207		{for a in [1, 2, 3]}208	"209	obj_compspec_incompatible_with_multiple_elems => r#"210		{a:1 for a in [1, 2, 3], b:1}211	"#212	obj_compspec_incompatible_with_multiple_elems_w => r#"213		{a:1, b:1, for a in [1, 2, 3], c:1}214	"#215216	obj_compspec_incompatible_with_asserts => r#"217		{assert 1, a: 1 for a in [1,2,3]}218	"#219220	local_method => r#"221		local222			a(x) = x,223			a = function(x) x,224		; c225	"#226	obj_method => r#"227		{228			a(x): x,229			a: function(x) x,230		}231	"#232233	continue_after_total_failure => r#"234		local intr = $intrinsic(test);235236		local a = 1, b = 2, c = a + b;237238		[c]239	"#240);241242#[test]243fn stdlib() {244	let src = include_str!("../../jrsonnet-stdlib/src/std.jsonnet");245	let result = process(src);246	insta::assert_snapshot!("stdlib", result, src);247}248#[test]249fn eval_simple() {250	let src = "local a = 1, b = 2; a + local c = 1; c";251	let (node, _errors) = parse(src);252253	dbg!(node);254}