difftreelog
refactor use rstest for non-snapshot suites
in: master
5 files changed
Cargo.lockdiffbeforeafterboth884source = "registry+https://github.com/rust-lang/crates.io-index"884source = "registry+https://github.com/rust-lang/crates.io-index"885checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a"885checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a"886887[[package]]888name = "futures-macro"889version = "0.3.33"890source = "registry+https://github.com/rust-lang/crates.io-index"891checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b"892dependencies = [893 "proc-macro2",894 "quote",895 "syn 2.0.119",896]886897887[[package]]898[[package]]888name = "futures-sink"899name = "futures-sink"896source = "registry+https://github.com/rust-lang/crates.io-index"907source = "registry+https://github.com/rust-lang/crates.io-index"897checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"908checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"909910[[package]]911name = "futures-timer"912version = "3.0.4"913source = "registry+https://github.com/rust-lang/crates.io-index"914checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968"898915899[[package]]916[[package]]900name = "futures-util"917name = "futures-util"904dependencies = [921dependencies = [905 "futures-core",922 "futures-core",906 "futures-io",923 "futures-io",924 "futures-macro",907 "futures-sink",925 "futures-sink",908 "futures-task",926 "futures-task",909 "memchr",927 "memchr",1883 "zlib-rs",1901 "zlib-rs",1884]1902]19031904[[package]]1905name = "glob"1906version = "0.3.4"1907source = "registry+https://github.com/rust-lang/crates.io-index"1908checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b"188519091886[[package]]1910[[package]]1887name = "globset"1911name = "globset"2657name = "jrsonnet-pkg"2681name = "jrsonnet-pkg"2658version = "0.5.0-pre99"2682version = "0.5.0-pre99"2659dependencies = [2683dependencies = [2684 "base64 0.23.0",2660 "camino",2685 "camino",2661 "directories",2686 "directories",2662 "gix",2687 "gix",2663 "peg",2688 "peg",2664 "reqwest",2689 "reqwest",2665 "serde",2690 "serde",2666 "serde_json",2691 "serde_json",2692 "sha2",2667 "thiserror",2693 "thiserror",2668 "tracing",2694 "tracing",2669 "url",2695 "url",3189 "zerocopy",3215 "zerocopy",3190]3216]32173218[[package]]3219name = "proc-macro-crate"3220version = "3.5.0"3221source = "registry+https://github.com/rust-lang/crates.io-index"3222checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"3223dependencies = [3224 "toml_edit",3225]319132263192[[package]]3227[[package]]3193name = "proc-macro2"3228name = "proc-macro2"3369source = "registry+https://github.com/rust-lang/crates.io-index"3404source = "registry+https://github.com/rust-lang/crates.io-index"3370checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"3405checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"34063407[[package]]3408name = "relative-path"3409version = "1.9.3"3410source = "registry+https://github.com/rust-lang/crates.io-index"3411checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2"337134123372[[package]]3413[[package]]3373name = "reqwest"3414name = "reqwest"3434 "text-size",3475 "text-size",3435]3476]34773478[[package]]3479name = "rstest"3480version = "0.26.1"3481source = "registry+https://github.com/rust-lang/crates.io-index"3482checksum = "f5a3193c063baaa2a95a33f03035c8a72b83d97a54916055ba22d35ed3839d49"3483dependencies = [3484 "futures-timer",3485 "futures-util",3486 "rstest_macros",3487]34883489[[package]]3490name = "rstest_macros"3491version = "0.26.1"3492source = "registry+https://github.com/rust-lang/crates.io-index"3493checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0"3494dependencies = [3495 "cfg-if",3496 "glob",3497 "proc-macro-crate",3498 "proc-macro2",3499 "quote",3500 "regex",3501 "relative-path",3502 "rustc_version",3503 "syn 2.0.119",3504 "unicode-ident",3505]343635063437[[package]]3507[[package]]3438name = "rustc-hash"3508name = "rustc-hash"3938 "jrsonnet-gcmodule",4008 "jrsonnet-gcmodule",3939 "jrsonnet-stdlib",4009 "jrsonnet-stdlib",3940 "mimallocator",4010 "mimallocator",4011 "rstest",3941 "serde",4012 "serde",3942 "serde_json",4013 "serde_json",3943]4014]4050 "tokio",4121 "tokio",4051]4122]41234124[[package]]4125name = "toml_datetime"4126version = "1.1.1+spec-1.1.0"4127source = "registry+https://github.com/rust-lang/crates.io-index"4128checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"4129dependencies = [4130 "serde_core",4131]41324133[[package]]4134name = "toml_edit"4135version = "0.25.13+spec-1.1.0"4136source = "registry+https://github.com/rust-lang/crates.io-index"4137checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b"4138dependencies = [4139 "indexmap",4140 "toml_datetime",4141 "toml_parser",4142 "winnow",4143]41444145[[package]]4146name = "toml_parser"4147version = "1.1.3+spec-1.1.0"4148source = "registry+https://github.com/rust-lang/crates.io-index"4149checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56"4150dependencies = [4151 "winnow",4152]405241534053[[package]]4154[[package]]4054name = "tower"4155name = "tower"4504source = "registry+https://github.com/rust-lang/crates.io-index"4605source = "registry+https://github.com/rust-lang/crates.io-index"4505checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"4606checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"46074608[[package]]4609name = "winnow"4610version = "1.0.4"4611source = "registry+https://github.com/rust-lang/crates.io-index"4612checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"4613dependencies = [4614 "memchr",4615]450646164507[[package]]4617[[package]]4508name = "wit-bindgen"4618name = "wit-bindgen"flake.lockdiffbeforeafterboth18 },18 },19 "crane": {19 "crane": {20 "locked": {20 "locked": {21 "lastModified": 1785284101,21 "lastModified": 1787326676,22 "owner": "ipetkov",22 "owner": "ipetkov",23 "repo": "crane",23 "repo": "crane",24 "rev": "756d6d07c3818ea95d1e2cdac63fa7d02fe3e61b",24 "rev": "692f7e9ef2ece8125b466f66f2af532b3edaed0d",25 "type": "github"25 "type": "github"26 },26 },27 "original": {27 "original": {58 ]58 ]59 },59 },60 "locked": {60 "locked": {61 "lastModified": 1782949081,61 "lastModified": 1787559586,62 "owner": "hercules-ci",62 "owner": "hercules-ci",63 "repo": "flake-parts",63 "repo": "flake-parts",64 "rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",64 "rev": "9d0d87172c374f89da73c1cfe6d81ae62feac1f1",65 "type": "github"65 "type": "github"66 },66 },67 "original": {67 "original": {96 ]96 ]97 },97 },98 "locked": {98 "locked": {99 "lastModified": 1784091696,99 "lastModified": 1786770286,100 "owner": "hercules-ci",100 "owner": "hercules-ci",101 "repo": "hercules-ci-effects",101 "repo": "hercules-ci-effects",102 "rev": "41134a44913c4a32cdb03e5e82ac331af0ff3efc",102 "rev": "f5df0b4ad1aea4a435dfdd65b616c64cadcd2725",103 "type": "github"103 "type": "github"104 },104 },105 "original": {105 "original": {110 },110 },111 "nixpkgs": {111 "nixpkgs": {112 "locked": {112 "locked": {113 "lastModified": 1785288896,113 "lastModified": 1788181121,114 "owner": "nixos",114 "owner": "nixos",115 "repo": "nixpkgs",115 "repo": "nixpkgs",116 "rev": "18fb21044ebd6570f88f0b60893d85a48bb06395",116 "rev": "68777210cd7f124b02e334e03cd366117355ab0b",117 "type": "github"117 "type": "github"118 },118 },119 "original": {119 "original": {174 ]174 ]175 },175 },176 "locked": {176 "locked": {177 "lastModified": 1784369104,177 "lastModified": 1786901030,178 "owner": "numtide",178 "owner": "numtide",179 "repo": "treefmt-nix",179 "repo": "treefmt-nix",180 "rev": "df3c0640565d04a0261253cdd89fce78ec50168a",180 "rev": "27b3b12a8e6375f28ebe122f07d230ca5459bbfa",181 "type": "github"181 "type": "github"182 },182 },183 "original": {183 "original": {tests/Cargo.tomldiffbeforeafterboth29jrsonnet-gcmodule.workspace = true29jrsonnet-gcmodule.workspace = true30jrsonnet-stdlib.workspace = true30jrsonnet-stdlib.workspace = true31mimallocator.workspace = true31mimallocator.workspace = true32rstest = "0.26.1"32serde.workspace = true33serde.workspace = true33serde_json.workspace = true34serde_json.workspace = true3435tests/tests/cpp_test_suite.rsdiffbeforeafterboth14 tla::TlaArg,14 tla::TlaArg,15 trace::{CompactFormat, PathResolver, TraceFormat},15 trace::{CompactFormat, PathResolver, TraceFormat},16};16};17use jrsonnet_gcmodule::ObjectSpace;18use jrsonnet_stdlib::ContextInitializer;17use jrsonnet_stdlib::ContextInitializer;19mod common;18mod common;20use common::ContextInitializer as TestContextInitializer;19use common::ContextInitializer as TestContextInitializer;20use rstest::rstest;212122#[builtin]22#[builtin]23fn json_to_string(x: Val) -> Result<String> {23fn json_to_string(x: Val) -> Result<String> {122 }122 }123}123}124124125const SKIPPED: &[&str] = &[125fn check(file: &Path, root: &Path, override_root: &Path) {126 // C++ tests:127128 // Parser fails with stack overflow. While is a bug, this is a too unusual129 // thing to run untrusted jsonnet code? Will be fixed with nom/rowan.130 "error.parse.deep_array_nesting.jsonnet",131 // Too slow to throw due to how lazyness is implemented in jrsonnet132 "error.recursive_object_non_term.jsonnet",133 // In jrsonnet returns the one passed argument, works as Rust's dbg!()134 "error.trace_one_param.jsonnet",135 // In jrsonnet can display any value136 "error.trace_two_param.jsonnet",137 // Depends on unsafe handling of strings as arrays in jsonnet stdlib138 "invariant_manifest.jsonnet",139 // Little bit hard to capture trace logs in this test suite at this moment140 "trace.jsonnet",141 // Go tests:142143 // Something is wrong, go-jsonnet skips safe integer range check here144 "bitwise_or9.jsonnet",145 // Bad check: https://github.com/databricks/sjsonnet/issues/793#issuecomment-4323153709146 "builtinBase64_string_high_codepoint.jsonnet",147 // Split by empty string is string characters, same as everywhere else148 "builtinSplitLimitR6.jsonnet",149 // escapeStringJson only accepts string in jrsonnet150 "builtin_escapeStringJson.jsonnet",151 // golang float formatting is inefficient and not portable152 "builtin_manifestTomlEx.jsonnet",153 // golang escapes "e" yaml key, does it think it is float?154 "builtin_manifestYamlDoc.jsonnet",155 // multi output is a CLI part, not an interpreter.156 "multi.jsonnet",157 "multi_no_newline.jsonnet",158 "multi_no_newline_string_output.jsonnet",159 "multi_string_output.jsonnet",160 // Golang fails with max stack frames exceeded error161 "std.makeArray_recursive_evalutation_order_matters.jsonnet",162 // Tailstrict semantics is partially unspecified163 "tailstrict3.jsonnet",164 // Jrsonnet has this overload165 "number_times_string.jsonnet",166 // Jrsonnet has this overload167 "string_times_number.jsonnet",168];169170fn run_test_suite(root: PathBuf, root_override: PathBuf) -> io::Result<()> {171 dbg!(&root);172 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}")))? {173 let entry = entry?;174 if entry.path().extension().is_none_or(|e| e != "jsonnet") {175 continue;176 }177178 let _stack = if entry.path().file_stem().is_some_and(|e| e == "recursive_function" || e == "tailstrict"|| e == "tailstrict5") {126 let _stack = if file127 .file_stem()128 .is_some_and(|e| e == "recursive_function" || e == "tailstrict" || e == "tailstrict5")129 {179 Some(limit_stack_depth(100_000))130 Some(limit_stack_depth(100_000))180 } else {131 } else {181 None132 None182 };133 };183184 if entry185 .path()186 .file_name()187 .and_then(|v| v.to_str())188 .is_some_and(|v| SKIPPED.contains(&v))189 {190 continue;191 }192193 eprintln!("test: {}", entry.path().display());194134195 let result = run(&entry.path(), &root);135 let result = run(file, root);196136197 let mut golden_path = entry.path();137 let mut golden_path = file.to_path_buf();198 golden_path.set_extension("jsonnet.golden");138 golden_path.set_extension("jsonnet.golden");199139200 let mut golden_path2 = entry.path();140 let mut golden_path2 = file.to_path_buf();201 golden_path2.set_extension("golden");141 golden_path2.set_extension("golden");202142203 let golden_override =143 let golden_override = override_root.join(golden_path.file_name().expect("file has basename"));204 root_override.join(golden_path.file_name().expect("file has basename"));205144206 // .jsonnet.golden for C++ tests145 // .jsonnet.golden for C++ tests207 let mut golden = read_file(&golden_path)?;146 let mut golden = read_file(&golden_path).expect("read golden");208 // .golden for Go tests147 // .golden for Go tests209 if golden.is_none() && let Some(golden_path) = read_file(&golden_path2)? {148 if golden.is_none()149 && let Some(v) = read_file(&golden_path2).expect("read golden")150 {210 golden = Some(golden_path);151 golden = Some(v);211 }152 }212153213 // Any of them can be overriden by overrides154 // Any of them can be overriden by overrides214 if let Some(golden_path) = read_file(&golden_override)? {155 if let Some(v) = read_file(&golden_override).expect("read golden override") {215 golden = Some(golden_path);156 golden = Some(v);216 }157 }217158218 // Otherwise assume test should just not fail and return true.159 // Otherwise assume test should just not fail and return true.219 let golden = golden.unwrap_or_else(|| "true".to_owned());160 let golden = golden.unwrap_or_else(|| "true".to_owned());220161221 let update_golden_path = &golden_override;162 let update_golden_path = &golden_override;222163223 match (serde_json::from_str::<serde_json::Value>(&result), serde_json::from_str::<serde_json::Value>(&golden)) {164 match (165 serde_json::from_str::<serde_json::Value>(&result),166 serde_json::from_str::<serde_json::Value>(&golden),167 ) {224 (Err(_), Ok(_)) => panic!(168 (Err(_), Ok(_)) => panic!(225 "unexpected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",169 "unexpected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",226 entry.path().display()170 file.display()227 ),171 ),228 (Ok(_), Err(_)) => panic!(172 (Ok(_), Err(_)) => panic!(229 "expected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",173 "expected error for golden {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",230 entry.path().display()174 file.display()231 ),175 ),232 (Ok(result_v), Ok(golden_v)) => {176 (Ok(result_v), Ok(golden_v)) => {233 if result_v != golden_v {177 if result_v != golden_v {234 if env::var_os("UPDATE_GOLDEN").is_some() {178 if env::var_os("UPDATE_GOLDEN").is_some() {235 fs::write(update_golden_path, result)?;179 fs::write(update_golden_path, result).expect("write golden override");236 } else {180 } else {237 panic!(181 panic!(238 "Result \n{result_v:#}\n\182 "Result \n{result_v:#}\n\239 and golden \n{golden_v:#}\n\183 and golden \n{golden_v:#}\n\240 did not match structurally\n\184 did not match structurally\n\241 for golden {}",185 for golden {}",242 entry.path().display()186 file.display()243 );187 );244 }188 }245 }189 }246 }190 }247 (Err(_), Err(_)) => {191 (Err(_), Err(_)) => {248 if result != golden.trim_end() {192 if result != golden.trim_end() {249 if env::var_os("UPDATE_GOLDEN").is_some() {193 if env::var_os("UPDATE_GOLDEN").is_some() {250 fs::write(update_golden_path, result)?;194 fs::write(update_golden_path, result).expect("write golden override");251 } else {195 } else {252 panic!(196 panic!(253 "golden didn't match for {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",197 "golden didn't match for {}:\n<got>\n{result}\n</got>\n<golden>\n{golden}\n</golden>",254 entry.path().display()198 file.display()255 )199 )256 }200 }257 }201 }258 }202 }259 }203 }260 println!("done!");261 }204}205206#[rstest]262 Ok(())207fn cpp_test_suite(263}208 #[base_dir = "$CPP_JSONNET_FOR_TESTS/test_suite"]209 #[files("*.jsonnet")]210 // Parser fails with stack overflow. While is a bug, this is a too unusual211 // thing to run untrusted jsonnet code? Will be fixed with nom/rowan.212 #[exclude("^error\\.parse\\.deep_array_nesting\\.jsonnet$")]213 // Too slow to throw due to how lazyness is implemented in jrsonnet214 #[exclude("^error\\.recursive_object_non_term\\.jsonnet$")]215 // In jrsonnet returns the one passed argument, works as Rust's dbg!()216 #[exclude("^error\\.trace_one_param\\.jsonnet$")]217 // In jrsonnet can display any value218 #[exclude("^error\\.trace_two_param\\.jsonnet$")]219 // Depends on unsafe handling of strings as arrays in jsonnet stdlib220 #[exclude("^invariant_manifest\\.jsonnet$")]221 // Little bit hard to capture trace logs in this test suite at this moment222 #[exclude("^trace\\.jsonnet$")]223 file: PathBuf,224) {225 let root = PathBuf::from(env!("CPP_JSONNET_FOR_TESTS")).join("test_suite");226 let override_root =227 PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("cpp_test_suite_golden_override");228 check(&file, &root, &override_root);229}264230265#[test]231#[rstest]266fn upstream_test_suite() -> io::Result<()> {232fn go_test_suite(233 #[base_dir = "$GO_JSONNET_FOR_TESTS/testdata"]234 #[files("*.jsonnet")]235 // Something is wrong, go-jsonnet skips safe integer range check here236 #[exclude("^bitwise_or9\\.jsonnet$")]237 // Bad check: https://github.com/databricks/sjsonnet/issues/793#issuecomment-4323153709238 #[exclude("^builtinBase64_string_high_codepoint\\.jsonnet$")]239 // Split by empty string is string characters, same as everywhere else240 #[exclude("^builtinSplitLimitR6\\.jsonnet$")]241 // escapeStringJson only accepts string in jrsonnet242 #[exclude("^builtin_escapeStringJson\\.jsonnet$")]243 // golang float formatting is inefficient and not portable244 #[exclude("^builtin_manifestTomlEx\\.jsonnet$")]245 // golang escapes "e" yaml key, does it think it is float?267 let manifest = PathBuf::from(env!("CARGO_MANIFEST_DIR"));246 #[exclude("^builtin_manifestYamlDoc\\.jsonnet$")]247 // multi output is a CLI part, not an interpreter.248 #[exclude("^multi\\.jsonnet$")]268 if let Some(cpp_jsonnet) = std::env::var_os("CPP_JSONNET_FOR_TESTS") {249 #[exclude("^multi_no_newline\\.jsonnet$")]250 #[exclude("^multi_no_newline_string_output\\.jsonnet$")]269 let path = PathBuf::from(cpp_jsonnet).join("test_suite");251 #[exclude("^multi_string_output\\.jsonnet$")]252 // Golang fails with max stack frames exceeded error270 let path_override = manifest.join("cpp_test_suite_golden_override");253 #[exclude("^std\\.makeArray_recursive_evalutation_order_matters\\.jsonnet$")]254 // Tailstrict semantics is partially unspecified271 run_test_suite(path, path_override)?;255 #[exclude("^tailstrict3\\.jsonnet$")]272 } else {256 // Jrsonnet has this overload273 eprintln!("no cpp jsonnet available for tests");257 #[exclude("^number_times_string\\.jsonnet$")]274 }258 // Jrsonnet has this overload275 if let Some(go_jsonnet) = std::env::var_os("GO_JSONNET_FOR_TESTS") {259 #[exclude("^string_times_number\\.jsonnet$")]260 file: PathBuf,261) {276 let path = PathBuf::from(go_jsonnet).join("testdata");262 let root = PathBuf::from(env!("GO_JSONNET_FOR_TESTS")).join("testdata");277 let path_override = manifest.join("go_testdata_golden_override");263 let override_root =264 PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("go_testdata_golden_override");278 run_test_suite(path, path_override)?;265 check(&file, &root, &override_root);279 } else {266}280 eprintln!("no go jsonnet available for tests");281 }282283 jrsonnet_gcmodule::with_thread_object_space(ObjectSpace::leak);284285 Ok(())286}287267tests/tests/suite.rsdiffbeforeafterboth1use std::{1use std::path::{Path, PathBuf};2 fs, io,3 path::{Path, PathBuf},4};526use jrsonnet_evaluator::{3use jrsonnet_evaluator::{7 FileImportResolver, State, Val,4 FileImportResolver, State, Val,11812mod common;9mod common;13use common::ContextInitializer as TestContextInitializer;10use common::ContextInitializer as TestContextInitializer;11use rstest::rstest;141215fn run(file: &Path) {13fn run(file: &Path) {16 let mut s = State::builder();14 let mut s = State::builder();35 }33 }36}34}373538#[test]36#[rstest]39fn suite() -> io::Result<()> {37fn test_suite(40 let mut root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));38 #[base_dir = "suite"]41 root.push("suite");39 #[files("*.jsonnet")]4243 for entry in fs::read_dir(&root)? {44 let entry = entry?;45 if entry.path().extension().is_some_and(|e| e == "jsonnet") {40 path: PathBuf,41) {46 run(&entry.path());42 run(&path);47 }43}48 }4950 Ok(())51}5244