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

difftreelog

source

crates/jrsonnet-rowan-parser/src/tests.rs3.2 KiBsourcehistory
1#![cfg(test)]23use miette::{4	Diagnostic, GraphicalReportHandler, GraphicalTheme, LabeledSpan, ThemeCharacters, ThemeStyles,5};6use thiserror::Error;78use crate::{parse, AstNode};910#[derive(Debug, Error)]11#[error("syntax error")]12struct MyDiagnostic {13	code: String,14	spans: Vec<LabeledSpan>,15}16impl Diagnostic for MyDiagnostic {17	fn code<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {18		None19	}2021	fn severity(&self) -> Option<miette::Severity> {22		None23	}2425	fn help<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {26		None27	}2829	fn url<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {30		None31	}3233	fn source_code(&self) -> Option<&dyn miette::SourceCode> {34		Some(&self.code)35	}3637	fn labels(&self) -> Option<Box<dyn Iterator<Item = miette::LabeledSpan> + '_>> {38		Some(Box::new(self.spans.clone().into_iter()))39	}4041	fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {42		None43	}44}4546fn process(text: &str) -> String {47	use std::fmt::Write;48	let mut out = String::new();49	let (node, errors) = parse(text);50	write!(out, "{:#?}", node.syntax()).unwrap();51	if !errors.is_empty() && !text.is_empty() {52		writeln!(out, "===").unwrap();53		for err in &errors {54			writeln!(out, "{:?}", err).unwrap();55		}56		let diag = MyDiagnostic {57			code: text.to_string(),58			spans: errors.into_iter().map(|e| e.into()).collect(),59		};6061		let handler = GraphicalReportHandler::new_themed(GraphicalTheme {62			characters: ThemeCharacters::ascii(),63			styles: ThemeStyles::none(),64		});6566		write!(out, "===").unwrap();67		handler.render_report(&mut out, &diag).unwrap();68	}69	out70}71macro_rules! mk_test {72		($($name:ident => $test:expr)+) => {$(73			#[test]74			fn $name() {75				let src = indoc::indoc!($test);76				let result = process(&src);77				insta::assert_snapshot!(stringify!($name), result, src);7879			}80		)+};81	}82mk_test!(83	empty => r#" "#84	function => r#"85		function(a, b = 1) a + b86	"#87	function_error_no_value => r#"88		function(a, b = ) a + b89	"#90	function_error_rparen => r#"91		function(a, b92	"#93	function_error_body => r#"94		function(a, b)95	"#96	local_novalue => r#"97		local a =98	"#99	local_no_value_recovery => r#"100		local a =101		local b = 3;102		1103	"#104105	array_comp => r#"106		[a for a in [1, 2, 3]]107	"#108	array_comp_incompatible_with_multiple_elems => r#"109		[a for a in [1, 2, 3], b]110	"#111112	no_rhs => r#"113		a +114	"#115	no_lhs => r#"116		+ 2117	"#118	no_operator => "119		2 2120	"121122	named_before_positional => "123		a(1, 2, b=4, 3, 5, k = 12, 6)124	"125126	wrong_field_end => "127		{128			a: 1;129			b: 2;130		}131	"132133134	plain_call => "135		std.substr(a, 0, std.length(b)) == b136	"137138	destruct => "139		local [a, b, c] = arr;140		local [a, ...] = arr_rest;141		local [..., a] = rest_arr;142		local [...] = rest_in_arr;143		local [a, ...n] = arr_rest_n;144		local [...n, a] = rest_arr_n;145		local [...n] = rest_in_arr_n;146147		local {a, b, c} = obj;148		local {a, b, c, ...} = obj_rest;149		local {a, b, c, ...n} = obj_rest_n;150151		null152	"153154	str_block_missing_indent => "155		|||156	"157	str_block_missing_termination => "158		|||159			hello160	"161	str_block_missing_newline => "162		|||hello163	"164	str_block_missing_indent_text => "165		|||166		hello167	"168);169170#[test]171fn stdlib() {172	let src = jrsonnet_stdlib::STDLIB_STR;173	let result = process(src);174	insta::assert_snapshot!("stdlib", result, src);175}