diff --git a/jsonpath-compliance-test-suite b/jsonpath-compliance-test-suite index 446336c..c6261e1 160000 --- a/jsonpath-compliance-test-suite +++ b/jsonpath-compliance-test-suite @@ -1 +1 @@ -Subproject commit 446336cd6651586f416a3b546c70bdd0fa2022c0 +Subproject commit c6261e15635321c728b2b7ba4a822f73b2698b7a diff --git a/serde_json_path/CHANGELOG.md b/serde_json_path/CHANGELOG.md index 05d8818..cdabe28 100644 --- a/serde_json_path/CHANGELOG.md +++ b/serde_json_path/CHANGELOG.md @@ -7,8 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Unreleased +- **testing**: support tests for non-determinism in compliance test suite ([#85]) - **fixed**: bug preventing registered functions from being used as arguments to other functions ([#84]) +[#85]: https://github.com/hiltontj/serde_json_path/pull/85 [#84]: https://github.com/hiltontj/serde_json_path/pull/84 # 0.6.6 (23 February 2024) diff --git a/serde_json_path/tests/compliance.rs b/serde_json_path/tests/compliance.rs index 531562f..b2ee3fe 100644 --- a/serde_json_path/tests/compliance.rs +++ b/serde_json_path/tests/compliance.rs @@ -16,11 +16,39 @@ struct TestCase { name: String, selector: String, #[serde(default)] - invalid_selector: bool, - #[serde(default)] document: Value, - #[serde(default)] - result: Vec, + #[serde(flatten)] + result: TestResult, +} + +#[derive(Deserialize)] +#[serde(untagged)] +enum TestResult { + Deterministic { result: Vec }, + NonDeterministic { results: Vec> }, + InvalidSelector { invalid_selector: bool }, +} + +impl TestResult { + fn verify(&self, name: &str, actual: Vec<&Value>) { + match self { + TestResult::Deterministic { result } => assert_eq!( + result.iter().collect::>(), + actual, + "{name}: incorrect result, expected {result:?}, got {actual:?}" + ), + TestResult::NonDeterministic { results } => { + assert!(results + .iter() + .any(|r| r.iter().collect::>().eq(&actual))) + } + TestResult::InvalidSelector { .. } => unreachable!(), + } + } + + fn is_invalid_selector(&self) -> bool { + matches!(self, Self::InvalidSelector { invalid_selector } if *invalid_selector) + } } #[test] @@ -36,7 +64,6 @@ fn compliance_test_suite() { TestCase { name, selector, - invalid_selector, document, result, }, @@ -44,36 +71,29 @@ fn compliance_test_suite() { { println!("Test ({i}): {name}"); let path = JsonPath::parse(selector); - if *invalid_selector { + if result.is_invalid_selector() { assert!( path.is_err(), "{name}: parsing {selector:?} should have failed", ); } else { let path = path.expect("valid JSON Path string"); - let expected = result.iter().collect::>(); { // Query using JsonPath::query let actual = path.query(document).all(); - assert_eq!( - expected, actual, - "{name}: incorrect result, expected {expected:?}, got {actual:?}" - ); + result.verify(name, actual); } { // Query using JsonPath::query_located let q = path.query_located(document); let actual = q.nodes().collect::>(); - assert_eq!( - expected, actual, - "(located) {name}: incorrect result, expected {expected:?}, got {actual:?}" - ); + result.verify(name, actual); } } } } -const TEST_CASE_N: usize = 388; +const TEST_CASE_N: usize = 10; #[test] #[ignore = "this is only for testing individual CTS test cases as needed"] @@ -87,24 +107,29 @@ fn compliance_single() { let TestCase { name, selector, - invalid_selector, document, result, } = &test_cases.tests[TEST_CASE_N]; println!("Test Case: {name}"); let path = JsonPath::parse(selector); - if *invalid_selector { + if result.is_invalid_selector() { println!("...this test should fail"); assert!( path.is_err(), "{name}: parsing {selector:?} should have failed", ); } else { - let actual = path.expect("valid JSON Path string").query(document).all(); - let expected = result.iter().collect::>(); - assert_eq!( - expected, actual, - "{name}: incorrect result, expected {expected:?}, got {actual:?}" - ); + let path = path.expect("valid JSON Path string"); + { + // Query using JsonPath::query + let actual = path.query(document).all(); + result.verify(name, actual); + } + { + // Query using JsonPath::query_located + let q = path.query_located(document); + let actual = q.nodes().collect::>(); + result.verify(name, actual); + } } } diff --git a/serde_json_path_core/CHANGELOG.md b/serde_json_path_core/CHANGELOG.md index 59ce670..2c5188b 100644 --- a/serde_json_path_core/CHANGELOG.md +++ b/serde_json_path_core/CHANGELOG.md @@ -7,8 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Unreleased +- **testing**: support tests for non-determinism in compliance test suite ([#85]) - **fixed**: bug preventing registered functions from being used as arguments to other functions ([#84]) +[#85]: https://github.com/hiltontj/serde_json_path/pull/85 [#84]: https://github.com/hiltontj/serde_json_path/pull/84 # 0.1.5 (23 February 2024) diff --git a/serde_json_path_macros/CHANGELOG.md b/serde_json_path_macros/CHANGELOG.md index 27e8930..f383553 100644 --- a/serde_json_path_macros/CHANGELOG.md +++ b/serde_json_path_macros/CHANGELOG.md @@ -7,8 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Unreleased +- **testing**: support tests for non-determinism in compliance test suite ([#85]) - **fixed**: bug preventing registered functions from being used as arguments to other functions ([#84]) +[#85]: https://github.com/hiltontj/serde_json_path/pull/85 [#84]: https://github.com/hiltontj/serde_json_path/pull/84 # 0.1.3 (23 February 2024)