git.delta.rocks / jrsonnet / refs/commits / 5f11fd70bef6

difftreelog

test reenable more upstream tests

nmyzzlrlYaroslav Bolyukin2026-05-06parent: #6fbe7c6.patch.diff
in: master

6 files changed

addedtests/cpp_test_suite_golden_override/error.function_duplicate_param.jsonnet.goldendiffbeforeafterboth
--- /dev/null
+++ b/tests/cpp_test_suite_golden_override/error.function_duplicate_param.jsonnet.golden
@@ -0,0 +1 @@
+static analysis errors: local is already defined in the current frame: x; do not define identity functions manually, use std.id instead
\ No newline at end of file
addedtests/cpp_test_suite_golden_override/error.parse.object_local_clash.jsonnet.goldendiffbeforeafterboth
--- /dev/null
+++ b/tests/cpp_test_suite_golden_override/error.parse.object_local_clash.jsonnet.golden
@@ -0,0 +1 @@
+static analysis errors: local is already defined in the current frame: x; unused local: x
\ No newline at end of file
addedtests/go_testdata_golden_override/div3.jsonnet.goldendiffbeforeafterboth
--- /dev/null
+++ b/tests/go_testdata_golden_override/div3.jsonnet.golden
@@ -0,0 +1 @@
+0.0000000000000000000000000000009999999999999999
\ No newline at end of file
addedtests/go_testdata_golden_override/number_leading_zero.jsonnet.goldendiffbeforeafterboth
--- /dev/null
+++ b/tests/go_testdata_golden_override/number_leading_zero.jsonnet.golden
@@ -0,0 +1,3 @@
+syntax error: expected end of file, got number "42"
+    number_leading_zero.jsonnet:1:2
+    number_leading_zero.jsonnet:1:2-3: parse imported
\ No newline at end of file
addedtests/go_testdata_golden_override/pow6.jsonnet.goldendiffbeforeafterboth
--- /dev/null
+++ b/tests/go_testdata_golden_override/pow6.jsonnet.golden
@@ -0,0 +1 @@
+179754255558440960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
\ No newline at end of file
modifiedtests/tests/cpp_test_suite.rsdiffbeforeafterboth
before · tests/tests/cpp_test_suite.rs
1use std::{2	env, fs,3	io::{self, ErrorKind},4	path::{Path, PathBuf},5};67use jrsonnet_evaluator::{8	FileImportResolver, IStr, ObjValueBuilder, State, Val, apply_tla,9	gc::WithCapacityExt as _,10	manifest::JsonFormat,11	rustc_hash::FxHashMap,12	stack::limit_stack_depth,13	tla::TlaArg,14	trace::{CompactFormat, PathResolver, TraceFormat},15};16use jrsonnet_gcmodule::ObjectSpace;17use jrsonnet_stdlib::ContextInitializer;18mod common;19use common::ContextInitializer as TestContextInitializer;2021fn run(file: &Path, root: &Path) -> String {22	let mut s = State::builder();2324	let resolver = PathResolver::Relative(root.to_owned());25	let std_context = ContextInitializer::new(resolver.clone());26	// C++ test suite27	std_context.add_ext_str("var1".into(), "test".into());28	std_context29		.add_ext_code("var2", "{x:1,y:2}")30		.expect("code is valid");3132	// Golang test suite33	std_context34		.add_ext_code("codeVar", "3+3")35		.expect("code is valid");36	std_context.add_ext_str("stringVar".into(), "2 + 2".into());37	std_context38		.add_ext_code(39			"selfRecursiveVar",40			r#"[42, std.extVar("selfRecursiveVar")[0] + 1]"#,41		)42		.expect("code is valid");43	std_context44		.add_ext_code(45			"mutuallyRecursiveVar1",46			r#"[42, std.extVar("mutuallyRecursiveVar2")[0] + 1]"#,47		)48		.expect("code is valid");49	std_context50		.add_ext_code(51			"mutuallyRecursiveVar2",52			r#"[42, std.extVar("mutuallyRecursiveVar1")[0] + 1]"#,53		)54		.expect("code is valid");5556	s.context_initializer((std_context, TestContextInitializer))57		.import_resolver(FileImportResolver::default());58	let s = s.build();5960	let _entered = s.enter();6162	let trace_format = CompactFormat {63		resolver: resolver.clone(),64		max_trace: 20,65		padding: 4,66	};6768	let mut v = match s.import(file) {69		Ok(v) => v,70		Err(e) => return trace_format.format(&e).unwrap(),71	};7273	if file74		.file_name()75		.expect("file has basename")76		.to_str()77		.expect("jsonnet testsuite has ascii names")78		.starts_with("tla.")79	{80		let mut args = FxHashMap::new();81		args.insert(IStr::from("var1"), TlaArg::String("test".into()));82		args.insert(83			IStr::from("var2"),84			TlaArg::Val({85				let mut o = ObjValueBuilder::new();8687				o.field("x").value(Val::num(1));88				o.field("y").value(Val::num(2));8990				Val::Obj(o.build())91			}),92		);93		v = apply_tla(&args, v).expect("failed to apply tla");94	} else {95		v = match apply_tla(&FxHashMap::new(), v) {96			Ok(v) => v,97			Err(e) => return trace_format.format(&e).unwrap(),98		};99	}100101	match v.manifest(JsonFormat::default()) {102		Ok(v) => v,103		Err(e) => trace_format.format(&e).unwrap(),104	}105}106107fn read_file(path: &Path) -> io::Result<Option<String>> {108	match fs::read_to_string(path) {109		Ok(v) => Ok(Some(v)),110		Err(e) if e.kind() == ErrorKind::NotFound => Ok(None),111		Err(e) => Err(e),112	}113}114115const SKIPPED: &[&str] = &[116	// C++ tests:117118	// Parser fails with stack overflow. While is a bug, this is a too unusual119	// thing to run untrusted jsonnet code? Will be fixed with nom/rowan.120	"error.parse.deep_array_nesting.jsonnet",121	// Runtime, not static error in jrsonnet122	"error.parse.object_local_clash.jsonnet",123	"error.function_duplicate_param.jsonnet",124	// Too slow to throw due to how lazyness is implemented in jrsonnet125	"error.recursive_object_non_term.jsonnet",126	// In jrsonnet returns the one passed argument, works as Rust's dbg!()127	"error.trace_one_param.jsonnet",128	// In jrsonnet can display any value129	"error.trace_two_param.jsonnet",130	// Depends on unsafe handling of strings as arrays in jsonnet stdlib131	"invariant_manifest.jsonnet",132	// Little bit hard to capture trace logs in this test suite at this moment133	"trace.jsonnet",134	// Go tests:135136	// Something is wrong, go-jsonnet skips safe integer range check here137	"bitwise_or9.jsonnet",138	// Jrsonnet does not use byte strings, all utf8 is converted to bytes first139	"builtinBase64_string_high_codepoint.jsonnet",140	// Split by empty string is string characters, same as everywhere else141	"builtinSplitLimitR6.jsonnet",142	// escapeStringJson only accepts string in jrsonnet143	"builtin_escapeStringJson.jsonnet",144	// golang float formatting is inefficient and not portable145	"builtin_manifestTomlEx.jsonnet",146	"div3.jsonnet",147	"pow6.jsonnet",148	// golang escapes "e" yaml key, does it think it is float?149	"builtin_manifestYamlDoc.jsonnet",150	// multi output is a CLI part, not an interpreter.151	"multi.jsonnet",152	"multi_no_newline.jsonnet",153	"multi_no_newline_string_output.jsonnet",154	"multi_string_output.jsonnet",155	// Tested otherwise156	"native1.jsonnet",157	"native2.jsonnet",158	"native3.jsonnet",159	"native6.jsonnet",160	// Since when parser should throw an error for that?..161	"number_leading_zero.jsonnet",162	// Golang fails with max stack frames exceeded error163	"std.makeArray_recursive_evalutation_order_matters.jsonnet",164	// Tailstrict semantics is partially unspecified165	"tailstrict3.jsonnet",166	// Jrsonnet has this overload167	"number_times_string.jsonnet",168	// Jrsonnet has this overload169	"string_times_number.jsonnet",170];171172fn run_test_suite(root: PathBuf, root_override: PathBuf) -> io::Result<()> {173	dbg!(&root);174	for entry in fs::read_dir(&root).map_err(|e| io::Error::other(format!("failed to enumerate test suite dir (Note: it needs to be cloned from upstream jsonnet repo for this test): {e}")))? {175		let entry = entry?;176		if entry.path().extension().is_none_or(|e| e != "jsonnet") {177			continue;178		}179180		let _stack = if entry.path().file_stem().is_some_and(|e| e == "recursive_function" || e == "tailstrict"|| e == "tailstrict5") {181			Some(limit_stack_depth(100_000))182		} else {183			None184		};185186		if entry187			.path()188			.file_name()189			.and_then(|v| v.to_str())190			.is_some_and(|v| SKIPPED.contains(&v))191		{192			continue;193		}194195		eprintln!("test: {}", entry.path().display());196197		let result = run(&entry.path(), &root);198199		let mut golden_path = entry.path();200		golden_path.set_extension("jsonnet.golden");201202		let mut golden_path2 = entry.path();203		golden_path2.set_extension("golden");204205		let golden_override =206			root_override.join(golden_path.file_name().expect("file has basename"));207208		// .jsonnet.golden for C++ tests209		let mut golden = read_file(&golden_path)?;210		// .golden for Go tests211		if golden.is_none() && let Some(golden_path) = read_file(&golden_path2)? {212			golden = Some(golden_path);213		}214215		// Any of them can be overriden by overrides216		if let Some(golden_path) = read_file(&golden_override)? {217			golden = Some(golden_path);218		}219220		// Otherwise assume test should just not fail and return true.221		let golden = golden.unwrap_or_else(|| "true".to_owned());222223		let update_golden_path = &golden_override;224225		match (serde_json::from_str::<serde_json::Value>(&result), serde_json::from_str::<serde_json::Value>(&golden)) {226			(Err(_), Ok(_)) => panic!(227				"unexpected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",228				entry.path().display()229			),230			(Ok(_), Err(_)) => panic!(231				"expected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",232				entry.path().display()233			),234			(Ok(result_v), Ok(golden_v)) => {235				if result_v != golden_v {236					if env::var_os("UPDATE_GOLDEN").is_some() {237						fs::write(update_golden_path, result)?;238					} else {239						panic!(240							"Result \n{result_v:#}\n\241								and golden \n{golden_v:#}\n\242								did not match structurally\n\243								for golden {}",244							entry.path().display()245						);246					}247				}248			}249			(Err(_), Err(_)) => {250				if result != golden.trim_end() {251					if env::var_os("UPDATE_GOLDEN").is_some() {252						fs::write(update_golden_path, result)?;253					} else {254						panic!(255						"golden didn't match for {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",256						entry.path().display()257					)258					}259				}260			}261		}262		println!("done!");263	}264	Ok(())265}266267#[test]268fn upstream_test_suite() -> io::Result<()> {269	let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR"));270	if let Some(cpp_jsonnet) = std::env::var_os("CPP_JSONNET_FOR_TESTS") {271		let path = PathBuf::from(cpp_jsonnet).join("test_suite");272		let path_override = manifest.join("cpp_test_suite_golden_override");273		run_test_suite(path, path_override)?;274	} else {275		eprintln!("no cpp jsonnet available for tests");276	}277	if let Some(go_jsonnet) = std::env::var_os("GO_JSONNET_FOR_TESTS") {278		let path = PathBuf::from(go_jsonnet).join("testdata");279		let path_override = manifest.join("go_testdata_golden_override");280		run_test_suite(path, path_override)?;281	} else {282		eprintln!("no go jsonnet available for tests");283	}284285	jrsonnet_gcmodule::with_thread_object_space(ObjectSpace::leak);286287	Ok(())288}
after · tests/tests/cpp_test_suite.rs
1use std::{2	env, fs,3	io::{self, ErrorKind},4	path::{Path, PathBuf},5};67use jrsonnet_evaluator::{8	FileImportResolver, IStr, ObjValueBuilder, State, Val, apply_tla,9	gc::WithCapacityExt as _,10	manifest::JsonFormat,11	rustc_hash::FxHashMap,12	stack::limit_stack_depth,13	tla::TlaArg,14	trace::{CompactFormat, PathResolver, TraceFormat},15};16use jrsonnet_gcmodule::ObjectSpace;17use jrsonnet_stdlib::ContextInitializer;18mod common;19use common::ContextInitializer as TestContextInitializer;2021fn run(file: &Path, root: &Path) -> String {22	let mut s = State::builder();2324	let resolver = PathResolver::Relative(root.to_owned());25	let std_context = ContextInitializer::new(resolver.clone());26	// C++ test suite27	std_context.add_ext_str("var1".into(), "test".into());28	std_context29		.add_ext_code("var2", "{x:1,y:2}")30		.expect("code is valid");3132	// Golang test suite33	std_context34		.add_ext_code("codeVar", "3+3")35		.expect("code is valid");36	std_context.add_ext_str("stringVar".into(), "2 + 2".into());37	std_context38		.add_ext_code(39			"selfRecursiveVar",40			r#"[42, std.extVar("selfRecursiveVar")[0] + 1]"#,41		)42		.expect("code is valid");43	std_context44		.add_ext_code(45			"mutuallyRecursiveVar1",46			r#"[42, std.extVar("mutuallyRecursiveVar2")[0] + 1]"#,47		)48		.expect("code is valid");49	std_context50		.add_ext_code(51			"mutuallyRecursiveVar2",52			r#"[42, std.extVar("mutuallyRecursiveVar1")[0] + 1]"#,53		)54		.expect("code is valid");5556	s.context_initializer((std_context, TestContextInitializer))57		.import_resolver(FileImportResolver::default());58	let s = s.build();5960	let _entered = s.enter();6162	let trace_format = CompactFormat {63		resolver: resolver.clone(),64		max_trace: 20,65		padding: 4,66	};6768	let mut v = match s.import(file) {69		Ok(v) => v,70		Err(e) => return trace_format.format(&e).unwrap(),71	};7273	if file74		.file_name()75		.expect("file has basename")76		.to_str()77		.expect("jsonnet testsuite has ascii names")78		.starts_with("tla.")79	{80		let mut args = FxHashMap::new();81		args.insert(IStr::from("var1"), TlaArg::String("test".into()));82		args.insert(83			IStr::from("var2"),84			TlaArg::Val({85				let mut o = ObjValueBuilder::new();8687				o.field("x").value(Val::num(1));88				o.field("y").value(Val::num(2));8990				Val::Obj(o.build())91			}),92		);93		v = apply_tla(&args, v).expect("failed to apply tla");94	} else {95		v = match apply_tla(&FxHashMap::new(), v) {96			Ok(v) => v,97			Err(e) => return trace_format.format(&e).unwrap(),98		};99	}100101	match v.manifest(JsonFormat::default()) {102		Ok(v) => v,103		Err(e) => trace_format.format(&e).unwrap(),104	}105}106107fn read_file(path: &Path) -> io::Result<Option<String>> {108	match fs::read_to_string(path) {109		Ok(v) => Ok(Some(v)),110		Err(e) if e.kind() == ErrorKind::NotFound => Ok(None),111		Err(e) => Err(e),112	}113}114115const SKIPPED: &[&str] = &[116	// C++ tests:117118	// Parser fails with stack overflow. While is a bug, this is a too unusual119	// thing to run untrusted jsonnet code? Will be fixed with nom/rowan.120	"error.parse.deep_array_nesting.jsonnet",121	// Too slow to throw due to how lazyness is implemented in jrsonnet122	"error.recursive_object_non_term.jsonnet",123	// In jrsonnet returns the one passed argument, works as Rust's dbg!()124	"error.trace_one_param.jsonnet",125	// In jrsonnet can display any value126	"error.trace_two_param.jsonnet",127	// Depends on unsafe handling of strings as arrays in jsonnet stdlib128	"invariant_manifest.jsonnet",129	// Little bit hard to capture trace logs in this test suite at this moment130	"trace.jsonnet",131	// Go tests:132133	// Something is wrong, go-jsonnet skips safe integer range check here134	"bitwise_or9.jsonnet",135	// Bad check: https://github.com/databricks/sjsonnet/issues/793#issuecomment-4323153709136	"builtinBase64_string_high_codepoint.jsonnet",137	// Split by empty string is string characters, same as everywhere else138	"builtinSplitLimitR6.jsonnet",139	// escapeStringJson only accepts string in jrsonnet140	"builtin_escapeStringJson.jsonnet",141	// golang float formatting is inefficient and not portable142	"builtin_manifestTomlEx.jsonnet",143	// golang escapes "e" yaml key, does it think it is float?144	"builtin_manifestYamlDoc.jsonnet",145	// multi output is a CLI part, not an interpreter.146	"multi.jsonnet",147	"multi_no_newline.jsonnet",148	"multi_no_newline_string_output.jsonnet",149	"multi_string_output.jsonnet",150	// Tested otherwise151	"native1.jsonnet",152	"native2.jsonnet",153	"native3.jsonnet",154	"native6.jsonnet",155	// Golang fails with max stack frames exceeded error156	"std.makeArray_recursive_evalutation_order_matters.jsonnet",157	// Tailstrict semantics is partially unspecified158	"tailstrict3.jsonnet",159	// Jrsonnet has this overload160	"number_times_string.jsonnet",161	// Jrsonnet has this overload162	"string_times_number.jsonnet",163];164165fn run_test_suite(root: PathBuf, root_override: PathBuf) -> io::Result<()> {166	dbg!(&root);167	for entry in fs::read_dir(&root).map_err(|e| io::Error::other(format!("failed to enumerate test suite dir (Note: it needs to be cloned from upstream jsonnet repo for this test): {e}")))? {168		let entry = entry?;169		if entry.path().extension().is_none_or(|e| e != "jsonnet") {170			continue;171		}172173		let _stack = if entry.path().file_stem().is_some_and(|e| e == "recursive_function" || e == "tailstrict"|| e == "tailstrict5") {174			Some(limit_stack_depth(100_000))175		} else {176			None177		};178179		if entry180			.path()181			.file_name()182			.and_then(|v| v.to_str())183			.is_some_and(|v| SKIPPED.contains(&v))184		{185			continue;186		}187188		eprintln!("test: {}", entry.path().display());189190		let result = run(&entry.path(), &root);191192		let mut golden_path = entry.path();193		golden_path.set_extension("jsonnet.golden");194195		let mut golden_path2 = entry.path();196		golden_path2.set_extension("golden");197198		let golden_override =199			root_override.join(golden_path.file_name().expect("file has basename"));200201		// .jsonnet.golden for C++ tests202		let mut golden = read_file(&golden_path)?;203		// .golden for Go tests204		if golden.is_none() && let Some(golden_path) = read_file(&golden_path2)? {205			golden = Some(golden_path);206		}207208		// Any of them can be overriden by overrides209		if let Some(golden_path) = read_file(&golden_override)? {210			golden = Some(golden_path);211		}212213		// Otherwise assume test should just not fail and return true.214		let golden = golden.unwrap_or_else(|| "true".to_owned());215216		let update_golden_path = &golden_override;217218		match (serde_json::from_str::<serde_json::Value>(&result), serde_json::from_str::<serde_json::Value>(&golden)) {219			(Err(_), Ok(_)) => panic!(220				"unexpected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",221				entry.path().display()222			),223			(Ok(_), Err(_)) => panic!(224				"expected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",225				entry.path().display()226			),227			(Ok(result_v), Ok(golden_v)) => {228				if result_v != golden_v {229					if env::var_os("UPDATE_GOLDEN").is_some() {230						fs::write(update_golden_path, result)?;231					} else {232						panic!(233							"Result \n{result_v:#}\n\234								and golden \n{golden_v:#}\n\235								did not match structurally\n\236								for golden {}",237							entry.path().display()238						);239					}240				}241			}242			(Err(_), Err(_)) => {243				if result != golden.trim_end() {244					if env::var_os("UPDATE_GOLDEN").is_some() {245						fs::write(update_golden_path, result)?;246					} else {247						panic!(248						"golden didn't match for {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",249						entry.path().display()250					)251					}252				}253			}254		}255		println!("done!");256	}257	Ok(())258}259260#[test]261fn upstream_test_suite() -> io::Result<()> {262	let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR"));263	if let Some(cpp_jsonnet) = std::env::var_os("CPP_JSONNET_FOR_TESTS") {264		let path = PathBuf::from(cpp_jsonnet).join("test_suite");265		let path_override = manifest.join("cpp_test_suite_golden_override");266		run_test_suite(path, path_override)?;267	} else {268		eprintln!("no cpp jsonnet available for tests");269	}270	if let Some(go_jsonnet) = std::env::var_os("GO_JSONNET_FOR_TESTS") {271		let path = PathBuf::from(go_jsonnet).join("testdata");272		let path_override = manifest.join("go_testdata_golden_override");273		run_test_suite(path, path_override)?;274	} else {275		eprintln!("no go jsonnet available for tests");276	}277278	jrsonnet_gcmodule::with_thread_object_space(ObjectSpace::leak);279280	Ok(())281}