git.delta.rocks / jrsonnet / refs/commits / 078724755e3c

difftreelog

source

crates/jsonnet-evaluator/src/lib.rs4.2 KiBsourcehistory
1#![feature(box_syntax, box_patterns)]2#![feature(type_alias_impl_trait)]3#![feature(debug_non_exhaustive)]45mod binding;6mod ctx;7mod dynamic;8mod evaluate;9mod obj;10mod val;1112pub use binding::*;13pub use ctx::*;14pub use dynamic::*;15pub use evaluate::*;16use jsonnet_parser::*;17pub use obj::*;18use std::fmt::Debug;19use std::rc::Rc;20pub use val::*;2122pub trait FunctionRhs: Debug {23	fn evaluate(&self, ctx: Context) -> Val;24}25dynamic_wrapper!(FunctionRhs, BoxedFunctionRhs);2627pub trait FunctionDefault: Debug {28	fn default(&self, ctx: Context, expr: Expr) -> Val;29}30dynamic_wrapper!(FunctionDefault, BoxedFunctionDefault);3132#[cfg(test)]33pub mod tests {34	use super::{evaluate, Context, Val};35	use jsonnet_parser::*;3637	// macro_rules! eval {38	// 	($str: expr) => {39	// 		evaluate(Context::new(), &parse($str).unwrap())40	// 	};41	// }42	macro_rules! assert_eval {43		($str: expr) => {44			assert_eq!(45				evaluate(Context::new(), &parse($str).unwrap()),46				Val::Literal(LiteralType::True)47				)48		};49	}50	macro_rules! assert_json {51		($str: expr, $out: expr) => {52			assert_eq!(53				format!("{}", evaluate(Context::new(), &parse($str).unwrap())),54				$out55				)56		};57	}58	macro_rules! assert_eval_neg {59		($str: expr) => {60			assert_eq!(61				evaluate(Context::new(), &parse($str).unwrap()),62				Val::Literal(LiteralType::False)63				)64		};65	}6667	/// Sanity checking, before trusting to another tests68	#[test]69	fn equality_operator() {70		assert_eval!("2 == 2");71		assert_eval_neg!("2 != 2");72		assert_eval!("2 != 3");73		assert_eval_neg!("2 == 3");74		assert_eval!("'Hello' == 'Hello'");75		assert_eval_neg!("'Hello' != 'Hello'");76		assert_eval!("'Hello' != 'World'");77		assert_eval_neg!("'Hello' == 'World'");78	}7980	#[test]81	fn math_evaluation() {82		assert_eval!("2 + 2 * 2 == 6");83		assert_eval!("3 + (2 + 2 * 2) == 9");84	}8586	#[test]87	fn string_concat() {88		assert_eval!("'Hello' + 'World' == 'HelloWorld'");89		assert_eval!("'Hello' * 3 == 'HelloHelloHello'");90		assert_eval!("'Hello' + 'World' * 3 == 'HelloWorldWorldWorld'");91	}9293	#[test]94	fn local() {95		assert_eval!("local a = 2; local b = 3; a + b == 5");96		assert_eval!("local a = 1, b = a + 1; a + b == 3");97		assert_eval!("local a = 1; local a = 2; a == 2");98	}99100	#[test]101	fn object_lazyness() {102		assert_json!("local a = {a:error 'test'}; {}", r#"{}"#);103	}104105	#[test]106	fn object_inheritance() {107		assert_json!("{a:self.b} + {b:3}", r#"{"a":3,"b":3}"#);108	}109110	#[test]111	fn test_object() {112		assert_json!("{a:2}", r#"{"a":2}"#);113		assert_json!("{a:2+2}", r#"{"a":4}"#);114		assert_json!("{a:2}+{b:2}", r#"{"a":2,"b":2}"#);115		assert_json!("{b:3}+{b:2}", r#"{"b":2}"#);116		assert_json!("{b:3}+{b+:2}", r#"{"b":5}"#);117		assert_json!("local test='a'; {[test]:2}", r#"{"a":2}"#);118		assert_json!(119			r#"120				{121					name: "Alice",122					welcome: "Hello " + self.name + "!",123				}124			"#,125			r#"{"name":"Alice","welcome":"Hello Alice!"}"#126		);127		assert_json!(128			r#"129				{130					name: "Alice",131					welcome: "Hello " + self.name + "!",132				} + {133					name: "Bob"134				}135			"#,136			r#"{"name":"Bob","welcome":"Hello Bob!"}"#137		);138	}139140	#[test]141	fn functions() {142		assert_json!(r#"local a = function(b, c = 2) b + c; a(2)"#, "4");143		assert_json!(144			r#"local a = function(b, c = "Dear") b + c + d, d = "World"; a("Hello")"#,145			r#""HelloDearWorld""#146		);147	}148149	#[test]150	fn local_methods() {151		assert_json!(r#"local a(b, c = 2) = b + c; a(2)"#, "4");152		assert_json!(153			r#"local a(b, c = "Dear") = b + c + d, d = "World"; a("Hello")"#,154			r#""HelloDearWorld""#155		);156	}157158	#[test]159	fn object_locals() {160		assert_json!(r#"{local a = 3, b: a}"#, r#"{"b":3}"#);161		assert_json!(r#"{local a = 3, local c = a, b: c}"#, r#"{"b":3}"#);162		assert_json!(163			r#"{local a = function (b) {[b]:4}, test: a("test")}"#,164			r#"{"test":{"test":4}}"#165		);166	}167168	// We can't trust other tests (And official jsonnet testsuite), if assert is not working correctly169	#[test]170	fn std_assert_ok() {171		let std = "local std = ".to_owned() + jsonnet_stdlib::STDLIB_STR + ";";172		evaluate(173			Context::new(),174			&parse(&(std + "std.assertEqual(4.5 << 2, 16,)")).unwrap(),175		);176	}177178	#[test]179	#[should_panic]180	fn std_assert_failure() {181		let std = "local std = ".to_owned() + jsonnet_stdlib::STDLIB_STR + ";";182		evaluate(183			Context::new(),184			&parse(&(std + "std.assertEqual(4.5 << 2, 15,)")).unwrap(),185		);186	}187}