From e55977c11b0c16907eaa9644d87f9aaf35d411c0 Mon Sep 17 00:00:00 2001 From: Alex Groleau Date: Tue, 17 Feb 2026 22:41:08 -0500 Subject: [PATCH] jspg cleanup --- debug.log | 813 ----------------------------- debug_2.log | 44 -- debug_3.log | 815 ----------------------------- log_root.txt | 106 ---- old_code/lib.rs | 243 --------- old_code/registry.rs | 217 -------- old_code/suite.rs | 236 --------- old_code/tests.rs | 482 ------------------ old_code/util.rs | 53 -- old_code/validator.rs | 621 ----------------------- old_tests/helpers.rs | 88 ---- old_tests/schemas.rs | 1128 ----------------------------------------- old_tests/tests.rs | 1089 --------------------------------------- puncs_6_fix.txt | 106 ---- puncs_6_full.txt | 103 ---- puncs_6_output.txt | 57 --- puncs_6_resolved.txt | 106 ---- 17 files changed, 6307 deletions(-) delete mode 100644 debug.log delete mode 100644 debug_2.log delete mode 100644 debug_3.log delete mode 100644 log_root.txt delete mode 100644 old_code/lib.rs delete mode 100644 old_code/registry.rs delete mode 100644 old_code/suite.rs delete mode 100644 old_code/tests.rs delete mode 100644 old_code/util.rs delete mode 100644 old_code/validator.rs delete mode 100755 old_tests/helpers.rs delete mode 100755 old_tests/schemas.rs delete mode 100755 old_tests/tests.rs delete mode 100644 puncs_6_fix.txt delete mode 100644 puncs_6_full.txt delete mode 100644 puncs_6_output.txt delete mode 100644 puncs_6_resolved.txt diff --git a/debug.log b/debug.log deleted file mode 100644 index 66ad3d4..0000000 --- a/debug.log +++ /dev/null @@ -1,813 +0,0 @@ -warning: function `test_uniqueItems_0` should have a snake case name - --> tests/tests.rs:52:4 - | -52 | fn test_uniqueItems_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_0` - | - = note: `#[warn(non_snake_case)]` (part of `#[warn(nonstandard_style)]`) on by default - -warning: function `test_uniqueItems_1` should have a snake case name - --> tests/tests.rs:58:4 - | -58 | fn test_uniqueItems_1() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_1` - -warning: function `test_uniqueItems_2` should have a snake case name - --> tests/tests.rs:64:4 - | -64 | fn test_uniqueItems_2() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_2` - -warning: function `test_uniqueItems_3` should have a snake case name - --> tests/tests.rs:70:4 - | -70 | fn test_uniqueItems_3() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_3` - -warning: function `test_uniqueItems_4` should have a snake case name - --> tests/tests.rs:76:4 - | -76 | fn test_uniqueItems_4() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_4` - -warning: function `test_uniqueItems_5` should have a snake case name - --> tests/tests.rs:82:4 - | -82 | fn test_uniqueItems_5() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_5` - -warning: function `test_uniqueItems_6` should have a snake case name - --> tests/tests.rs:88:4 - | -88 | fn test_uniqueItems_6() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_6` - -warning: function `test_minItems_0` should have a snake case name - --> tests/tests.rs:94:4 - | -94 | fn test_minItems_0() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_items_0` - -warning: function `test_minItems_1` should have a snake case name - --> tests/tests.rs:100:4 - | -100 | fn test_minItems_1() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_items_1` - -warning: function `test_minItems_2` should have a snake case name - --> tests/tests.rs:106:4 - | -106 | fn test_minItems_2() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_items_2` - -warning: function `test_exclusiveMinimum_0` should have a snake case name - --> tests/tests.rs:160:4 - | -160 | fn test_exclusiveMinimum_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_exclusive_minimum_0` - -warning: function `test_anyOf_0` should have a snake case name - --> tests/tests.rs:274:4 - | -274 | fn test_anyOf_0() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_0` - -warning: function `test_anyOf_1` should have a snake case name - --> tests/tests.rs:280:4 - | -280 | fn test_anyOf_1() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_1` - -warning: function `test_anyOf_2` should have a snake case name - --> tests/tests.rs:286:4 - | -286 | fn test_anyOf_2() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_2` - -warning: function `test_anyOf_3` should have a snake case name - --> tests/tests.rs:292:4 - | -292 | fn test_anyOf_3() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_3` - -warning: function `test_anyOf_4` should have a snake case name - --> tests/tests.rs:298:4 - | -298 | fn test_anyOf_4() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_4` - -warning: function `test_anyOf_5` should have a snake case name - --> tests/tests.rs:304:4 - | -304 | fn test_anyOf_5() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_5` - -warning: function `test_anyOf_6` should have a snake case name - --> tests/tests.rs:310:4 - | -310 | fn test_anyOf_6() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_6` - -warning: function `test_anyOf_7` should have a snake case name - --> tests/tests.rs:316:4 - | -316 | fn test_anyOf_7() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_7` - -warning: function `test_anyOf_8` should have a snake case name - --> tests/tests.rs:322:4 - | -322 | fn test_anyOf_8() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_8` - -warning: function `test_anyOf_9` should have a snake case name - --> tests/tests.rs:328:4 - | -328 | fn test_anyOf_9() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_9` - -warning: function `test_propertyNames_0` should have a snake case name - --> tests/tests.rs:334:4 - | -334 | fn test_propertyNames_0() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_0` - -warning: function `test_propertyNames_1` should have a snake case name - --> tests/tests.rs:340:4 - | -340 | fn test_propertyNames_1() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_1` - -warning: function `test_propertyNames_2` should have a snake case name - --> tests/tests.rs:346:4 - | -346 | fn test_propertyNames_2() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_2` - -warning: function `test_propertyNames_3` should have a snake case name - --> tests/tests.rs:352:4 - | -352 | fn test_propertyNames_3() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_3` - -warning: function `test_propertyNames_4` should have a snake case name - --> tests/tests.rs:358:4 - | -358 | fn test_propertyNames_4() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_4` - -warning: function `test_propertyNames_5` should have a snake case name - --> tests/tests.rs:364:4 - | -364 | fn test_propertyNames_5() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_5` - -warning: function `test_propertyNames_6` should have a snake case name - --> tests/tests.rs:370:4 - | -370 | fn test_propertyNames_6() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_6` - -warning: function `test_minProperties_0` should have a snake case name - --> tests/tests.rs:646:4 - | -646 | fn test_minProperties_0() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_properties_0` - -warning: function `test_minProperties_1` should have a snake case name - --> tests/tests.rs:652:4 - | -652 | fn test_minProperties_1() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_properties_1` - -warning: function `test_minProperties_2` should have a snake case name - --> tests/tests.rs:658:4 - | -658 | fn test_minProperties_2() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_properties_2` - -warning: function `test_minContains_0` should have a snake case name - --> tests/tests.rs:664:4 - | -664 | fn test_minContains_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_0` - -warning: function `test_minContains_1` should have a snake case name - --> tests/tests.rs:670:4 - | -670 | fn test_minContains_1() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_1` - -warning: function `test_minContains_2` should have a snake case name - --> tests/tests.rs:676:4 - | -676 | fn test_minContains_2() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_2` - -warning: function `test_minContains_3` should have a snake case name - --> tests/tests.rs:682:4 - | -682 | fn test_minContains_3() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_3` - -warning: function `test_minContains_4` should have a snake case name - --> tests/tests.rs:688:4 - | -688 | fn test_minContains_4() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_4` - -warning: function `test_minContains_5` should have a snake case name - --> tests/tests.rs:694:4 - | -694 | fn test_minContains_5() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_5` - -warning: function `test_minContains_6` should have a snake case name - --> tests/tests.rs:700:4 - | -700 | fn test_minContains_6() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_6` - -warning: function `test_minContains_7` should have a snake case name - --> tests/tests.rs:706:4 - | -706 | fn test_minContains_7() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_7` - -warning: function `test_minContains_8` should have a snake case name - --> tests/tests.rs:712:4 - | -712 | fn test_minContains_8() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_8` - -warning: function `test_maxContains_0` should have a snake case name - --> tests/tests.rs:796:4 - | -796 | fn test_maxContains_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_0` - -warning: function `test_maxContains_1` should have a snake case name - --> tests/tests.rs:802:4 - | -802 | fn test_maxContains_1() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_1` - -warning: function `test_maxContains_2` should have a snake case name - --> tests/tests.rs:808:4 - | -808 | fn test_maxContains_2() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_2` - -warning: function `test_maxContains_3` should have a snake case name - --> tests/tests.rs:814:4 - | -814 | fn test_maxContains_3() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_3` - -warning: function `test_maxContains_4` should have a snake case name - --> tests/tests.rs:820:4 - | -820 | fn test_maxContains_4() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_4` - -warning: function `test_maxLength_0` should have a snake case name - --> tests/tests.rs:826:4 - | -826 | fn test_maxLength_0() { - | ^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_length_0` - -warning: function `test_maxLength_1` should have a snake case name - --> tests/tests.rs:832:4 - | -832 | fn test_maxLength_1() { - | ^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_length_1` - -warning: function `test_dependentSchemas_0` should have a snake case name - --> tests/tests.rs:838:4 - | -838 | fn test_dependentSchemas_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_schemas_0` - -warning: function `test_dependentSchemas_1` should have a snake case name - --> tests/tests.rs:844:4 - | -844 | fn test_dependentSchemas_1() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_schemas_1` - -warning: function `test_dependentSchemas_2` should have a snake case name - --> tests/tests.rs:850:4 - | -850 | fn test_dependentSchemas_2() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_schemas_2` - -warning: function `test_dependentSchemas_3` should have a snake case name - --> tests/tests.rs:856:4 - | -856 | fn test_dependentSchemas_3() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_schemas_3` - -warning: function `test_exclusiveMaximum_0` should have a snake case name - --> tests/tests.rs:862:4 - | -862 | fn test_exclusiveMaximum_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_exclusive_maximum_0` - -warning: function `test_prefixItems_0` should have a snake case name - --> tests/tests.rs:868:4 - | -868 | fn test_prefixItems_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_0` - -warning: function `test_prefixItems_1` should have a snake case name - --> tests/tests.rs:874:4 - | -874 | fn test_prefixItems_1() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_1` - -warning: function `test_prefixItems_2` should have a snake case name - --> tests/tests.rs:880:4 - | -880 | fn test_prefixItems_2() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_2` - -warning: function `test_prefixItems_3` should have a snake case name - --> tests/tests.rs:886:4 - | -886 | fn test_prefixItems_3() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_3` - -warning: function `test_prefixItems_4` should have a snake case name - --> tests/tests.rs:892:4 - | -892 | fn test_prefixItems_4() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_4` - -warning: function `test_oneOf_0` should have a snake case name - --> tests/tests.rs:910:4 - | -910 | fn test_oneOf_0() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_0` - -warning: function `test_oneOf_1` should have a snake case name - --> tests/tests.rs:916:4 - | -916 | fn test_oneOf_1() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_1` - -warning: function `test_oneOf_2` should have a snake case name - --> tests/tests.rs:922:4 - | -922 | fn test_oneOf_2() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_2` - -warning: function `test_oneOf_3` should have a snake case name - --> tests/tests.rs:928:4 - | -928 | fn test_oneOf_3() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_3` - -warning: function `test_oneOf_4` should have a snake case name - --> tests/tests.rs:934:4 - | -934 | fn test_oneOf_4() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_4` - -warning: function `test_oneOf_5` should have a snake case name - --> tests/tests.rs:940:4 - | -940 | fn test_oneOf_5() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_5` - -warning: function `test_oneOf_6` should have a snake case name - --> tests/tests.rs:946:4 - | -946 | fn test_oneOf_6() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_6` - -warning: function `test_oneOf_7` should have a snake case name - --> tests/tests.rs:952:4 - | -952 | fn test_oneOf_7() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_7` - -warning: function `test_oneOf_8` should have a snake case name - --> tests/tests.rs:958:4 - | -958 | fn test_oneOf_8() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_8` - -warning: function `test_oneOf_9` should have a snake case name - --> tests/tests.rs:964:4 - | -964 | fn test_oneOf_9() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_9` - -warning: function `test_oneOf_10` should have a snake case name - --> tests/tests.rs:970:4 - | -970 | fn test_oneOf_10() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_10` - -warning: function `test_oneOf_11` should have a snake case name - --> tests/tests.rs:976:4 - | -976 | fn test_oneOf_11() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_11` - -warning: function `test_oneOf_12` should have a snake case name - --> tests/tests.rs:982:4 - | -982 | fn test_oneOf_12() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_12` - -warning: function `test_emptyString_0` should have a snake case name - --> tests/tests.rs:1072:4 - | -1072 | fn test_emptyString_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_empty_string_0` - -warning: function `test_maxProperties_0` should have a snake case name - --> tests/tests.rs:1090:4 - | -1090 | fn test_maxProperties_0() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_properties_0` - -warning: function `test_maxProperties_1` should have a snake case name - --> tests/tests.rs:1096:4 - | -1096 | fn test_maxProperties_1() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_properties_1` - -warning: function `test_maxProperties_2` should have a snake case name - --> tests/tests.rs:1102:4 - | -1102 | fn test_maxProperties_2() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_properties_2` - -warning: function `test_maxProperties_3` should have a snake case name - --> tests/tests.rs:1108:4 - | -1108 | fn test_maxProperties_3() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_properties_3` - -warning: function `test_dependentRequired_0` should have a snake case name - --> tests/tests.rs:1114:4 - | -1114 | fn test_dependentRequired_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_0` - -warning: function `test_dependentRequired_1` should have a snake case name - --> tests/tests.rs:1120:4 - | -1120 | fn test_dependentRequired_1() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_1` - -warning: function `test_dependentRequired_2` should have a snake case name - --> tests/tests.rs:1126:4 - | -1126 | fn test_dependentRequired_2() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_2` - -warning: function `test_dependentRequired_3` should have a snake case name - --> tests/tests.rs:1132:4 - | -1132 | fn test_dependentRequired_3() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_3` - -warning: function `test_dependentRequired_4` should have a snake case name - --> tests/tests.rs:1138:4 - | -1138 | fn test_dependentRequired_4() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_4` - -warning: function `test_multipleOf_0` should have a snake case name - --> tests/tests.rs:1252:4 - | -1252 | fn test_multipleOf_0() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_multiple_of_0` - -warning: function `test_multipleOf_1` should have a snake case name - --> tests/tests.rs:1258:4 - | -1258 | fn test_multipleOf_1() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_multiple_of_1` - -warning: function `test_multipleOf_2` should have a snake case name - --> tests/tests.rs:1264:4 - | -1264 | fn test_multipleOf_2() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_multiple_of_2` - -warning: function `test_multipleOf_3` should have a snake case name - --> tests/tests.rs:1270:4 - | -1270 | fn test_multipleOf_3() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_multiple_of_3` - -warning: function `test_patternProperties_0` should have a snake case name - --> tests/tests.rs:1276:4 - | -1276 | fn test_patternProperties_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_0` - -warning: function `test_patternProperties_1` should have a snake case name - --> tests/tests.rs:1282:4 - | -1282 | fn test_patternProperties_1() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_1` - -warning: function `test_patternProperties_2` should have a snake case name - --> tests/tests.rs:1288:4 - | -1288 | fn test_patternProperties_2() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_2` - -warning: function `test_patternProperties_3` should have a snake case name - --> tests/tests.rs:1294:4 - | -1294 | fn test_patternProperties_3() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_3` - -warning: function `test_patternProperties_4` should have a snake case name - --> tests/tests.rs:1300:4 - | -1300 | fn test_patternProperties_4() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_4` - -warning: function `test_patternProperties_5` should have a snake case name - --> tests/tests.rs:1306:4 - | -1306 | fn test_patternProperties_5() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_5` - -warning: function `test_allOf_0` should have a snake case name - --> tests/tests.rs:1336:4 - | -1336 | fn test_allOf_0() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_0` - -warning: function `test_allOf_1` should have a snake case name - --> tests/tests.rs:1342:4 - | -1342 | fn test_allOf_1() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_1` - -warning: function `test_allOf_2` should have a snake case name - --> tests/tests.rs:1348:4 - | -1348 | fn test_allOf_2() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_2` - -warning: function `test_allOf_3` should have a snake case name - --> tests/tests.rs:1354:4 - | -1354 | fn test_allOf_3() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_3` - -warning: function `test_allOf_4` should have a snake case name - --> tests/tests.rs:1360:4 - | -1360 | fn test_allOf_4() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_4` - -warning: function `test_allOf_5` should have a snake case name - --> tests/tests.rs:1366:4 - | -1366 | fn test_allOf_5() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_5` - -warning: function `test_allOf_6` should have a snake case name - --> tests/tests.rs:1372:4 - | -1372 | fn test_allOf_6() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_6` - -warning: function `test_allOf_7` should have a snake case name - --> tests/tests.rs:1378:4 - | -1378 | fn test_allOf_7() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_7` - -warning: function `test_allOf_8` should have a snake case name - --> tests/tests.rs:1384:4 - | -1384 | fn test_allOf_8() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_8` - -warning: function `test_allOf_9` should have a snake case name - --> tests/tests.rs:1390:4 - | -1390 | fn test_allOf_9() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_9` - -warning: function `test_allOf_10` should have a snake case name - --> tests/tests.rs:1396:4 - | -1396 | fn test_allOf_10() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_10` - -warning: function `test_allOf_11` should have a snake case name - --> tests/tests.rs:1402:4 - | -1402 | fn test_allOf_11() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_11` - -warning: function `test_allOf_12` should have a snake case name - --> tests/tests.rs:1408:4 - | -1408 | fn test_allOf_12() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_12` - -warning: function `test_allOf_13` should have a snake case name - --> tests/tests.rs:1414:4 - | -1414 | fn test_allOf_13() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_13` - -warning: function `test_allOf_14` should have a snake case name - --> tests/tests.rs:1420:4 - | -1420 | fn test_allOf_14() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_14` - -warning: function `test_allOf_15` should have a snake case name - --> tests/tests.rs:1426:4 - | -1426 | fn test_allOf_15() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_15` - -warning: function `test_minLength_0` should have a snake case name - --> tests/tests.rs:1828:4 - | -1828 | fn test_minLength_0() { - | ^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_length_0` - -warning: function `test_minLength_1` should have a snake case name - --> tests/tests.rs:1834:4 - | -1834 | fn test_minLength_1() { - | ^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_length_1` - -warning: function `test_maxItems_0` should have a snake case name - --> tests/tests.rs:1840:4 - | -1840 | fn test_maxItems_0() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_items_0` - -warning: function `test_maxItems_1` should have a snake case name - --> tests/tests.rs:1846:4 - | -1846 | fn test_maxItems_1() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_items_1` - -warning: function `test_maxItems_2` should have a snake case name - --> tests/tests.rs:1852:4 - | -1852 | fn test_maxItems_2() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_items_2` - -warning: function `test_dynamicRef_0` should have a snake case name - --> tests/tests.rs:1912:4 - | -1912 | fn test_dynamicRef_0() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_0` - -warning: function `test_dynamicRef_1` should have a snake case name - --> tests/tests.rs:1918:4 - | -1918 | fn test_dynamicRef_1() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_1` - -warning: function `test_dynamicRef_2` should have a snake case name - --> tests/tests.rs:1924:4 - | -1924 | fn test_dynamicRef_2() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_2` - -warning: function `test_dynamicRef_3` should have a snake case name - --> tests/tests.rs:1930:4 - | -1930 | fn test_dynamicRef_3() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_3` - -warning: function `test_dynamicRef_4` should have a snake case name - --> tests/tests.rs:1936:4 - | -1936 | fn test_dynamicRef_4() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_4` - -warning: function `test_dynamicRef_5` should have a snake case name - --> tests/tests.rs:1942:4 - | -1942 | fn test_dynamicRef_5() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_5` - -warning: function `test_dynamicRef_6` should have a snake case name - --> tests/tests.rs:1948:4 - | -1948 | fn test_dynamicRef_6() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_6` - -warning: function `test_dynamicRef_7` should have a snake case name - --> tests/tests.rs:1954:4 - | -1954 | fn test_dynamicRef_7() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_7` - -warning: function `test_dynamicRef_8` should have a snake case name - --> tests/tests.rs:1960:4 - | -1960 | fn test_dynamicRef_8() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_8` - -warning: function `test_dynamicRef_9` should have a snake case name - --> tests/tests.rs:1966:4 - | -1966 | fn test_dynamicRef_9() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_9` - -warning: function `test_dynamicRef_10` should have a snake case name - --> tests/tests.rs:1972:4 - | -1972 | fn test_dynamicRef_10() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_10` - -warning: function `test_dynamicRef_11` should have a snake case name - --> tests/tests.rs:1978:4 - | -1978 | fn test_dynamicRef_11() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_11` - -warning: function `test_dynamicRef_12` should have a snake case name - --> tests/tests.rs:1984:4 - | -1984 | fn test_dynamicRef_12() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_12` - -warning: function `test_dynamicRef_13` should have a snake case name - --> tests/tests.rs:1990:4 - | -1990 | fn test_dynamicRef_13() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_13` - -warning: function `test_dynamicRef_14` should have a snake case name - --> tests/tests.rs:1996:4 - | -1996 | fn test_dynamicRef_14() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_14` - -warning: function `test_dynamicRef_15` should have a snake case name - --> tests/tests.rs:2002:4 - | -2002 | fn test_dynamicRef_15() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_15` - -warning: function `test_dynamicRef_16` should have a snake case name - --> tests/tests.rs:2008:4 - | -2008 | fn test_dynamicRef_16() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_16` - -warning: function `test_dynamicRef_17` should have a snake case name - --> tests/tests.rs:2014:4 - | -2014 | fn test_dynamicRef_17() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_17` - -warning: function `test_dynamicRef_18` should have a snake case name - --> tests/tests.rs:2020:4 - | -2020 | fn test_dynamicRef_18() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_18` - -warning: function `test_dynamicRef_19` should have a snake case name - --> tests/tests.rs:2026:4 - | -2026 | fn test_dynamicRef_19() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_19` - -warning: function `test_dynamicRef_20` should have a snake case name - --> tests/tests.rs:2032:4 - | -2032 | fn test_dynamicRef_20() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_20` - -warning: `jspg` (test "tests") generated 132 warnings - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.42s - Running tests/tests.rs (target/debug/deps/tests-0f6b1e496850f0af) - -running 1 test - -thread 'test_ref_39' (14864151) panicked at tests/tests.rs:1812:45: -called `Result::unwrap()` on an `Err` value: "[implicit keyword shadowing] Test 'child type overrides parent type' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'age'\", details: ErrorDetails { path: \"/age\" } }]\n[implicit keyword shadowing] Test 'parent max age (20) is shadowed (replaced) by child definition' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'age'\", details: ErrorDetails { path: \"/age\" } }]" -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -test test_ref_39 ... FAILED - -failures: - -failures: - test_ref_39 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 338 filtered out; finished in 0.01s - -error: test failed, to rerun pass `--test tests` diff --git a/debug_2.log b/debug_2.log deleted file mode 100644 index 3e577be..0000000 --- a/debug_2.log +++ /dev/null @@ -1,44 +0,0 @@ - Blocking waiting for file lock on artifact directory - Compiling jspg v0.1.0 (/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg) -error[E0424]: expected value, found module `self` - --> src/util.rs:162:33 - | - 40 | pub fn run_test_file_at_index(path: &str, index: usi... - | ---------------------- this function can't have a `self` parameter -... -162 | let mut new_overrides = self.overrides.clone(); - | ^^^^ `self` value is a keyword only available in methods with a `self` parameter - -error[E0424]: expected value, found module `self` - --> src/util.rs:164:31 - | - 40 | pub fn run_test_file_at_index(path: &str, index: usi... - | ---------------------- this function can't have a `self` parameter -... -164 | if let Some(props) = &self.schema.properties { - | ^^^^ `self` value is a keyword only available in methods with a `self` parameter - -error[E0282]: type annotations needed - --> src/util.rs:166:32 - | -166 | new_overrides.extend(props.keys().cloned()); - | ^^^^^ cannot infer type - -error[E0599]: no method named `is_valid` found for struct `drop::Drop` in the current scope - --> src/util.rs:204:18 - | -204 | ...ult.is_valid(), // Use is_valid() for clear "Got"... - | ^^^^^^^^ method not found in `drop::Drop` - | - ::: src/drop.rs:5:1 - | - 5 | pub struct Drop { - | --------------- method `is_valid` not found for this struct - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `is_valid`, perhaps you need to implement it: - candidate #1: `NullLayout` - -Some errors have detailed explanations: E0282, E0424, E0599. -For more information about an error, try `rustc --explain E0282`. -error: could not compile `jspg` (lib) due to 4 previous errors diff --git a/debug_3.log b/debug_3.log deleted file mode 100644 index d25ffb3..0000000 --- a/debug_3.log +++ /dev/null @@ -1,815 +0,0 @@ - Blocking waiting for file lock on artifact directory - Compiling jspg v0.1.0 (/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg) -warning: function `test_uniqueItems_0` should have a snake case name - --> tests/tests.rs:52:4 - | -52 | fn test_uniqueItems_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_0` - | - = note: `#[warn(non_snake_case)]` (part of `#[warn(nonstandard_style)]`) on by default - -warning: function `test_uniqueItems_1` should have a snake case name - --> tests/tests.rs:58:4 - | -58 | fn test_uniqueItems_1() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_1` - -warning: function `test_uniqueItems_2` should have a snake case name - --> tests/tests.rs:64:4 - | -64 | fn test_uniqueItems_2() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_2` - -warning: function `test_uniqueItems_3` should have a snake case name - --> tests/tests.rs:70:4 - | -70 | fn test_uniqueItems_3() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_3` - -warning: function `test_uniqueItems_4` should have a snake case name - --> tests/tests.rs:76:4 - | -76 | fn test_uniqueItems_4() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_4` - -warning: function `test_uniqueItems_5` should have a snake case name - --> tests/tests.rs:82:4 - | -82 | fn test_uniqueItems_5() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_5` - -warning: function `test_uniqueItems_6` should have a snake case name - --> tests/tests.rs:88:4 - | -88 | fn test_uniqueItems_6() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_unique_items_6` - -warning: function `test_minItems_0` should have a snake case name - --> tests/tests.rs:94:4 - | -94 | fn test_minItems_0() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_items_0` - -warning: function `test_minItems_1` should have a snake case name - --> tests/tests.rs:100:4 - | -100 | fn test_minItems_1() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_items_1` - -warning: function `test_minItems_2` should have a snake case name - --> tests/tests.rs:106:4 - | -106 | fn test_minItems_2() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_items_2` - -warning: function `test_exclusiveMinimum_0` should have a snake case name - --> tests/tests.rs:160:4 - | -160 | fn test_exclusiveMinimum_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_exclusive_minimum_0` - -warning: function `test_anyOf_0` should have a snake case name - --> tests/tests.rs:274:4 - | -274 | fn test_anyOf_0() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_0` - -warning: function `test_anyOf_1` should have a snake case name - --> tests/tests.rs:280:4 - | -280 | fn test_anyOf_1() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_1` - -warning: function `test_anyOf_2` should have a snake case name - --> tests/tests.rs:286:4 - | -286 | fn test_anyOf_2() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_2` - -warning: function `test_anyOf_3` should have a snake case name - --> tests/tests.rs:292:4 - | -292 | fn test_anyOf_3() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_3` - -warning: function `test_anyOf_4` should have a snake case name - --> tests/tests.rs:298:4 - | -298 | fn test_anyOf_4() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_4` - -warning: function `test_anyOf_5` should have a snake case name - --> tests/tests.rs:304:4 - | -304 | fn test_anyOf_5() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_5` - -warning: function `test_anyOf_6` should have a snake case name - --> tests/tests.rs:310:4 - | -310 | fn test_anyOf_6() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_6` - -warning: function `test_anyOf_7` should have a snake case name - --> tests/tests.rs:316:4 - | -316 | fn test_anyOf_7() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_7` - -warning: function `test_anyOf_8` should have a snake case name - --> tests/tests.rs:322:4 - | -322 | fn test_anyOf_8() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_8` - -warning: function `test_anyOf_9` should have a snake case name - --> tests/tests.rs:328:4 - | -328 | fn test_anyOf_9() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_any_of_9` - -warning: function `test_propertyNames_0` should have a snake case name - --> tests/tests.rs:334:4 - | -334 | fn test_propertyNames_0() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_0` - -warning: function `test_propertyNames_1` should have a snake case name - --> tests/tests.rs:340:4 - | -340 | fn test_propertyNames_1() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_1` - -warning: function `test_propertyNames_2` should have a snake case name - --> tests/tests.rs:346:4 - | -346 | fn test_propertyNames_2() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_2` - -warning: function `test_propertyNames_3` should have a snake case name - --> tests/tests.rs:352:4 - | -352 | fn test_propertyNames_3() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_3` - -warning: function `test_propertyNames_4` should have a snake case name - --> tests/tests.rs:358:4 - | -358 | fn test_propertyNames_4() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_4` - -warning: function `test_propertyNames_5` should have a snake case name - --> tests/tests.rs:364:4 - | -364 | fn test_propertyNames_5() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_5` - -warning: function `test_propertyNames_6` should have a snake case name - --> tests/tests.rs:370:4 - | -370 | fn test_propertyNames_6() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_property_names_6` - -warning: function `test_minProperties_0` should have a snake case name - --> tests/tests.rs:646:4 - | -646 | fn test_minProperties_0() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_properties_0` - -warning: function `test_minProperties_1` should have a snake case name - --> tests/tests.rs:652:4 - | -652 | fn test_minProperties_1() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_properties_1` - -warning: function `test_minProperties_2` should have a snake case name - --> tests/tests.rs:658:4 - | -658 | fn test_minProperties_2() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_properties_2` - -warning: function `test_minContains_0` should have a snake case name - --> tests/tests.rs:664:4 - | -664 | fn test_minContains_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_0` - -warning: function `test_minContains_1` should have a snake case name - --> tests/tests.rs:670:4 - | -670 | fn test_minContains_1() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_1` - -warning: function `test_minContains_2` should have a snake case name - --> tests/tests.rs:676:4 - | -676 | fn test_minContains_2() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_2` - -warning: function `test_minContains_3` should have a snake case name - --> tests/tests.rs:682:4 - | -682 | fn test_minContains_3() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_3` - -warning: function `test_minContains_4` should have a snake case name - --> tests/tests.rs:688:4 - | -688 | fn test_minContains_4() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_4` - -warning: function `test_minContains_5` should have a snake case name - --> tests/tests.rs:694:4 - | -694 | fn test_minContains_5() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_5` - -warning: function `test_minContains_6` should have a snake case name - --> tests/tests.rs:700:4 - | -700 | fn test_minContains_6() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_6` - -warning: function `test_minContains_7` should have a snake case name - --> tests/tests.rs:706:4 - | -706 | fn test_minContains_7() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_7` - -warning: function `test_minContains_8` should have a snake case name - --> tests/tests.rs:712:4 - | -712 | fn test_minContains_8() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_contains_8` - -warning: function `test_maxContains_0` should have a snake case name - --> tests/tests.rs:796:4 - | -796 | fn test_maxContains_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_0` - -warning: function `test_maxContains_1` should have a snake case name - --> tests/tests.rs:802:4 - | -802 | fn test_maxContains_1() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_1` - -warning: function `test_maxContains_2` should have a snake case name - --> tests/tests.rs:808:4 - | -808 | fn test_maxContains_2() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_2` - -warning: function `test_maxContains_3` should have a snake case name - --> tests/tests.rs:814:4 - | -814 | fn test_maxContains_3() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_3` - -warning: function `test_maxContains_4` should have a snake case name - --> tests/tests.rs:820:4 - | -820 | fn test_maxContains_4() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_contains_4` - -warning: function `test_maxLength_0` should have a snake case name - --> tests/tests.rs:826:4 - | -826 | fn test_maxLength_0() { - | ^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_length_0` - -warning: function `test_maxLength_1` should have a snake case name - --> tests/tests.rs:832:4 - | -832 | fn test_maxLength_1() { - | ^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_length_1` - -warning: function `test_dependentSchemas_0` should have a snake case name - --> tests/tests.rs:838:4 - | -838 | fn test_dependentSchemas_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_schemas_0` - -warning: function `test_dependentSchemas_1` should have a snake case name - --> tests/tests.rs:844:4 - | -844 | fn test_dependentSchemas_1() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_schemas_1` - -warning: function `test_dependentSchemas_2` should have a snake case name - --> tests/tests.rs:850:4 - | -850 | fn test_dependentSchemas_2() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_schemas_2` - -warning: function `test_dependentSchemas_3` should have a snake case name - --> tests/tests.rs:856:4 - | -856 | fn test_dependentSchemas_3() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_schemas_3` - -warning: function `test_exclusiveMaximum_0` should have a snake case name - --> tests/tests.rs:862:4 - | -862 | fn test_exclusiveMaximum_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_exclusive_maximum_0` - -warning: function `test_prefixItems_0` should have a snake case name - --> tests/tests.rs:868:4 - | -868 | fn test_prefixItems_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_0` - -warning: function `test_prefixItems_1` should have a snake case name - --> tests/tests.rs:874:4 - | -874 | fn test_prefixItems_1() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_1` - -warning: function `test_prefixItems_2` should have a snake case name - --> tests/tests.rs:880:4 - | -880 | fn test_prefixItems_2() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_2` - -warning: function `test_prefixItems_3` should have a snake case name - --> tests/tests.rs:886:4 - | -886 | fn test_prefixItems_3() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_3` - -warning: function `test_prefixItems_4` should have a snake case name - --> tests/tests.rs:892:4 - | -892 | fn test_prefixItems_4() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_prefix_items_4` - -warning: function `test_oneOf_0` should have a snake case name - --> tests/tests.rs:910:4 - | -910 | fn test_oneOf_0() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_0` - -warning: function `test_oneOf_1` should have a snake case name - --> tests/tests.rs:916:4 - | -916 | fn test_oneOf_1() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_1` - -warning: function `test_oneOf_2` should have a snake case name - --> tests/tests.rs:922:4 - | -922 | fn test_oneOf_2() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_2` - -warning: function `test_oneOf_3` should have a snake case name - --> tests/tests.rs:928:4 - | -928 | fn test_oneOf_3() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_3` - -warning: function `test_oneOf_4` should have a snake case name - --> tests/tests.rs:934:4 - | -934 | fn test_oneOf_4() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_4` - -warning: function `test_oneOf_5` should have a snake case name - --> tests/tests.rs:940:4 - | -940 | fn test_oneOf_5() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_5` - -warning: function `test_oneOf_6` should have a snake case name - --> tests/tests.rs:946:4 - | -946 | fn test_oneOf_6() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_6` - -warning: function `test_oneOf_7` should have a snake case name - --> tests/tests.rs:952:4 - | -952 | fn test_oneOf_7() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_7` - -warning: function `test_oneOf_8` should have a snake case name - --> tests/tests.rs:958:4 - | -958 | fn test_oneOf_8() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_8` - -warning: function `test_oneOf_9` should have a snake case name - --> tests/tests.rs:964:4 - | -964 | fn test_oneOf_9() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_9` - -warning: function `test_oneOf_10` should have a snake case name - --> tests/tests.rs:970:4 - | -970 | fn test_oneOf_10() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_10` - -warning: function `test_oneOf_11` should have a snake case name - --> tests/tests.rs:976:4 - | -976 | fn test_oneOf_11() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_11` - -warning: function `test_oneOf_12` should have a snake case name - --> tests/tests.rs:982:4 - | -982 | fn test_oneOf_12() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_one_of_12` - -warning: function `test_emptyString_0` should have a snake case name - --> tests/tests.rs:1072:4 - | -1072 | fn test_emptyString_0() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_empty_string_0` - -warning: function `test_maxProperties_0` should have a snake case name - --> tests/tests.rs:1090:4 - | -1090 | fn test_maxProperties_0() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_properties_0` - -warning: function `test_maxProperties_1` should have a snake case name - --> tests/tests.rs:1096:4 - | -1096 | fn test_maxProperties_1() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_properties_1` - -warning: function `test_maxProperties_2` should have a snake case name - --> tests/tests.rs:1102:4 - | -1102 | fn test_maxProperties_2() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_properties_2` - -warning: function `test_maxProperties_3` should have a snake case name - --> tests/tests.rs:1108:4 - | -1108 | fn test_maxProperties_3() { - | ^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_properties_3` - -warning: function `test_dependentRequired_0` should have a snake case name - --> tests/tests.rs:1114:4 - | -1114 | fn test_dependentRequired_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_0` - -warning: function `test_dependentRequired_1` should have a snake case name - --> tests/tests.rs:1120:4 - | -1120 | fn test_dependentRequired_1() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_1` - -warning: function `test_dependentRequired_2` should have a snake case name - --> tests/tests.rs:1126:4 - | -1126 | fn test_dependentRequired_2() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_2` - -warning: function `test_dependentRequired_3` should have a snake case name - --> tests/tests.rs:1132:4 - | -1132 | fn test_dependentRequired_3() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_3` - -warning: function `test_dependentRequired_4` should have a snake case name - --> tests/tests.rs:1138:4 - | -1138 | fn test_dependentRequired_4() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dependent_required_4` - -warning: function `test_multipleOf_0` should have a snake case name - --> tests/tests.rs:1252:4 - | -1252 | fn test_multipleOf_0() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_multiple_of_0` - -warning: function `test_multipleOf_1` should have a snake case name - --> tests/tests.rs:1258:4 - | -1258 | fn test_multipleOf_1() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_multiple_of_1` - -warning: function `test_multipleOf_2` should have a snake case name - --> tests/tests.rs:1264:4 - | -1264 | fn test_multipleOf_2() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_multiple_of_2` - -warning: function `test_multipleOf_3` should have a snake case name - --> tests/tests.rs:1270:4 - | -1270 | fn test_multipleOf_3() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_multiple_of_3` - -warning: function `test_patternProperties_0` should have a snake case name - --> tests/tests.rs:1276:4 - | -1276 | fn test_patternProperties_0() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_0` - -warning: function `test_patternProperties_1` should have a snake case name - --> tests/tests.rs:1282:4 - | -1282 | fn test_patternProperties_1() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_1` - -warning: function `test_patternProperties_2` should have a snake case name - --> tests/tests.rs:1288:4 - | -1288 | fn test_patternProperties_2() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_2` - -warning: function `test_patternProperties_3` should have a snake case name - --> tests/tests.rs:1294:4 - | -1294 | fn test_patternProperties_3() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_3` - -warning: function `test_patternProperties_4` should have a snake case name - --> tests/tests.rs:1300:4 - | -1300 | fn test_patternProperties_4() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_4` - -warning: function `test_patternProperties_5` should have a snake case name - --> tests/tests.rs:1306:4 - | -1306 | fn test_patternProperties_5() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_pattern_properties_5` - -warning: function `test_allOf_0` should have a snake case name - --> tests/tests.rs:1336:4 - | -1336 | fn test_allOf_0() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_0` - -warning: function `test_allOf_1` should have a snake case name - --> tests/tests.rs:1342:4 - | -1342 | fn test_allOf_1() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_1` - -warning: function `test_allOf_2` should have a snake case name - --> tests/tests.rs:1348:4 - | -1348 | fn test_allOf_2() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_2` - -warning: function `test_allOf_3` should have a snake case name - --> tests/tests.rs:1354:4 - | -1354 | fn test_allOf_3() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_3` - -warning: function `test_allOf_4` should have a snake case name - --> tests/tests.rs:1360:4 - | -1360 | fn test_allOf_4() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_4` - -warning: function `test_allOf_5` should have a snake case name - --> tests/tests.rs:1366:4 - | -1366 | fn test_allOf_5() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_5` - -warning: function `test_allOf_6` should have a snake case name - --> tests/tests.rs:1372:4 - | -1372 | fn test_allOf_6() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_6` - -warning: function `test_allOf_7` should have a snake case name - --> tests/tests.rs:1378:4 - | -1378 | fn test_allOf_7() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_7` - -warning: function `test_allOf_8` should have a snake case name - --> tests/tests.rs:1384:4 - | -1384 | fn test_allOf_8() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_8` - -warning: function `test_allOf_9` should have a snake case name - --> tests/tests.rs:1390:4 - | -1390 | fn test_allOf_9() { - | ^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_9` - -warning: function `test_allOf_10` should have a snake case name - --> tests/tests.rs:1396:4 - | -1396 | fn test_allOf_10() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_10` - -warning: function `test_allOf_11` should have a snake case name - --> tests/tests.rs:1402:4 - | -1402 | fn test_allOf_11() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_11` - -warning: function `test_allOf_12` should have a snake case name - --> tests/tests.rs:1408:4 - | -1408 | fn test_allOf_12() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_12` - -warning: function `test_allOf_13` should have a snake case name - --> tests/tests.rs:1414:4 - | -1414 | fn test_allOf_13() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_13` - -warning: function `test_allOf_14` should have a snake case name - --> tests/tests.rs:1420:4 - | -1420 | fn test_allOf_14() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_14` - -warning: function `test_allOf_15` should have a snake case name - --> tests/tests.rs:1426:4 - | -1426 | fn test_allOf_15() { - | ^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_all_of_15` - -warning: function `test_minLength_0` should have a snake case name - --> tests/tests.rs:1828:4 - | -1828 | fn test_minLength_0() { - | ^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_length_0` - -warning: function `test_minLength_1` should have a snake case name - --> tests/tests.rs:1834:4 - | -1834 | fn test_minLength_1() { - | ^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_min_length_1` - -warning: function `test_maxItems_0` should have a snake case name - --> tests/tests.rs:1840:4 - | -1840 | fn test_maxItems_0() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_items_0` - -warning: function `test_maxItems_1` should have a snake case name - --> tests/tests.rs:1846:4 - | -1846 | fn test_maxItems_1() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_items_1` - -warning: function `test_maxItems_2` should have a snake case name - --> tests/tests.rs:1852:4 - | -1852 | fn test_maxItems_2() { - | ^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_max_items_2` - -warning: function `test_dynamicRef_0` should have a snake case name - --> tests/tests.rs:1912:4 - | -1912 | fn test_dynamicRef_0() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_0` - -warning: function `test_dynamicRef_1` should have a snake case name - --> tests/tests.rs:1918:4 - | -1918 | fn test_dynamicRef_1() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_1` - -warning: function `test_dynamicRef_2` should have a snake case name - --> tests/tests.rs:1924:4 - | -1924 | fn test_dynamicRef_2() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_2` - -warning: function `test_dynamicRef_3` should have a snake case name - --> tests/tests.rs:1930:4 - | -1930 | fn test_dynamicRef_3() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_3` - -warning: function `test_dynamicRef_4` should have a snake case name - --> tests/tests.rs:1936:4 - | -1936 | fn test_dynamicRef_4() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_4` - -warning: function `test_dynamicRef_5` should have a snake case name - --> tests/tests.rs:1942:4 - | -1942 | fn test_dynamicRef_5() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_5` - -warning: function `test_dynamicRef_6` should have a snake case name - --> tests/tests.rs:1948:4 - | -1948 | fn test_dynamicRef_6() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_6` - -warning: function `test_dynamicRef_7` should have a snake case name - --> tests/tests.rs:1954:4 - | -1954 | fn test_dynamicRef_7() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_7` - -warning: function `test_dynamicRef_8` should have a snake case name - --> tests/tests.rs:1960:4 - | -1960 | fn test_dynamicRef_8() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_8` - -warning: function `test_dynamicRef_9` should have a snake case name - --> tests/tests.rs:1966:4 - | -1966 | fn test_dynamicRef_9() { - | ^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_9` - -warning: function `test_dynamicRef_10` should have a snake case name - --> tests/tests.rs:1972:4 - | -1972 | fn test_dynamicRef_10() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_10` - -warning: function `test_dynamicRef_11` should have a snake case name - --> tests/tests.rs:1978:4 - | -1978 | fn test_dynamicRef_11() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_11` - -warning: function `test_dynamicRef_12` should have a snake case name - --> tests/tests.rs:1984:4 - | -1984 | fn test_dynamicRef_12() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_12` - -warning: function `test_dynamicRef_13` should have a snake case name - --> tests/tests.rs:1990:4 - | -1990 | fn test_dynamicRef_13() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_13` - -warning: function `test_dynamicRef_14` should have a snake case name - --> tests/tests.rs:1996:4 - | -1996 | fn test_dynamicRef_14() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_14` - -warning: function `test_dynamicRef_15` should have a snake case name - --> tests/tests.rs:2002:4 - | -2002 | fn test_dynamicRef_15() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_15` - -warning: function `test_dynamicRef_16` should have a snake case name - --> tests/tests.rs:2008:4 - | -2008 | fn test_dynamicRef_16() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_16` - -warning: function `test_dynamicRef_17` should have a snake case name - --> tests/tests.rs:2014:4 - | -2014 | fn test_dynamicRef_17() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_17` - -warning: function `test_dynamicRef_18` should have a snake case name - --> tests/tests.rs:2020:4 - | -2020 | fn test_dynamicRef_18() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_18` - -warning: function `test_dynamicRef_19` should have a snake case name - --> tests/tests.rs:2026:4 - | -2026 | fn test_dynamicRef_19() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_19` - -warning: function `test_dynamicRef_20` should have a snake case name - --> tests/tests.rs:2032:4 - | -2032 | fn test_dynamicRef_20() { - | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `test_dynamic_ref_20` - -warning: `jspg` (test "tests") generated 132 warnings - Finished `test` profile [unoptimized + debuginfo] target(s) in 6.12s - Running tests/tests.rs (target/debug/deps/tests-0f6b1e496850f0af) - -running 1 test - -thread 'test_ref_39' (14867888) panicked at tests/tests.rs:1812:45: -called `Result::unwrap()` on an `Err` value: "[implicit keyword shadowing] Test 'child type overrides parent type' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'age'\", details: ErrorDetails { path: \"/age\" } }]\n[implicit keyword shadowing] Test 'parent max age (20) is shadowed (replaced) by child definition' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'age'\", details: ErrorDetails { path: \"/age\" } }]" -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -test test_ref_39 ... FAILED - -failures: - -failures: - test_ref_39 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 338 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--test tests` diff --git a/log_root.txt b/log_root.txt deleted file mode 100644 index 0077179..0000000 --- a/log_root.txt +++ /dev/null @@ -1,106 +0,0 @@ - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.34s - Running tests/tests.rs (target/debug/deps/tests-0f6b1e496850f0af) - -running 1 test -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"job_id", "manager_id", "name"} -DEBUG: validate_refs merging res from super_job. Keys: {"job_id", "manager_id", "type", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"manager_id", "type", "job_id", "name"} -DEBUG: validate_object inserted 'nested_or_super_job' at /nested_or_super_job. Keys: {"name", "job_id", "manager_id", "type"} -DEBUG: check_strictness at /root_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /root_job/name. Keys: {} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /root_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /root_job/job_id. Keys: {"name"} -DEBUG: check_strictness at /root_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /root_job/type. Keys: {"job_id", "name"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"job_id", "name", "type"} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "name", "type"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"job_id", "type", "name"} -DEBUG: validate_object inserted 'root_job' at /root_job. Keys: {"name", "job_id", "manager_id", "nested_or_super_job", "type"} -DEBUG: check_strictness at . Extensible: false. Keys: {"root_job", "name", "job_id", "manager_id", "nested_or_super_job", "type"} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"name", "manager_id", "job_id"} -DEBUG: validate_refs merging res from super_job. Keys: {"manager_id", "name", "type", "job_id"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"manager_id", "type", "job_id", "name"} -DEBUG: validate_object inserted 'nested_or_super_job' at /nested_or_super_job. Keys: {"manager_id", "type", "name", "job_id"} -DEBUG: check_strictness at /root_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /root_job/name. Keys: {} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /root_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /root_job/job_id. Keys: {"name"} -DEBUG: check_strictness at /root_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /root_job/type. Keys: {"name", "job_id"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name", "job_id", "type"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id", "type"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"job_id", "type", "name"} -DEBUG: validate_object inserted 'root_job' at /root_job. Keys: {"manager_id", "type", "nested_or_super_job", "name", "job_id"} -DEBUG: check_strictness at . Extensible: false. Keys: {"manager_id", "root_job", "type", "nested_or_super_job", "name", "job_id"} -DEBUG: validate_refs merging res from entity. Keys: {} -DEBUG: validate_refs merging res from job. Keys: {} -DEBUG: validate_refs merging res from super_job. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/my_job/name. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/my_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/my_job/type. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"type", "name"} -DEBUG: validate_refs merging res from job. Keys: {"type", "name"} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name", "type"} -DEBUG: validate_object inserted 'my_job' at /nested_or_super_job/my_job. Keys: {"type", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"job_id", "manager_id", "name"} -DEBUG: validate_refs merging res from super_job. Keys: {"job_id", "type", "manager_id", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("polymorphic_org_punc.request") ref=Some("organization.family") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("polymorphic_org_punc.request") ref=Some("organization.family") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("polymorphic_org_punc.request") ref=Some("organization.family") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("strict_org_punc.request") ref=Some("organization") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("strict_org_punc.request") ref=Some("organization") -DEBUG: check_strictness at . Extensible: false. Keys: {} - -thread 'test_puncs_6' (15117383) panicked at tests/tests.rs:150:44: -called `Result::unwrap()` on an `Err` value: "[complex punc type matching with oneOf and nested refs] Test 'valid person against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'first_name'\", details: ErrorDetails { path: \"/first_name\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against strict punc' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]" -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -test test_puncs_6 ... FAILED - -failures: - -failures: - test_puncs_6 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 338 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--test tests` diff --git a/old_code/lib.rs b/old_code/lib.rs deleted file mode 100644 index 845769a..0000000 --- a/old_code/lib.rs +++ /dev/null @@ -1,243 +0,0 @@ -use pgrx::*; - -pg_module_magic!(); - -// mod schema; -mod registry; -mod validator; -mod util; - -use crate::registry::REGISTRY; -// use crate::schema::Schema; -use crate::validator::{Validator, ValidationOptions}; -use lazy_static::lazy_static; -use serde_json::{json, Value}; -use std::collections::{HashMap, HashSet}; - -#[derive(Clone, Copy, Debug, PartialEq)] -enum SchemaType { - Enum, - Type, - Family, - PublicPunc, - PrivatePunc, -} - -struct CachedSchema { - t: SchemaType, -} - -lazy_static! { - static ref SCHEMA_META: std::sync::RwLock> = std::sync::RwLock::new(HashMap::new()); -} - -#[pg_extern(strict)] -fn cache_json_schemas(enums: JsonB, types: JsonB, puncs: JsonB) -> JsonB { - let mut meta = SCHEMA_META.write().unwrap(); - let enums_value: Value = enums.0; - let types_value: Value = types.0; - let puncs_value: Value = puncs.0; - - let mut schemas_to_register = Vec::new(); - - // Phase 1: Enums - if let Some(enums_array) = enums_value.as_array() { - for enum_row in enums_array { - if let Some(schemas_raw) = enum_row.get("schemas") { - if let Some(schemas_array) = schemas_raw.as_array() { - for schema_def in schemas_array { - if let Some(schema_id) = schema_def.get("$id").and_then(|v| v.as_str()) { - schemas_to_register.push((schema_id.to_string(), schema_def.clone(), SchemaType::Enum)); - } - } - } - } - } - } - - // Phase 2: Types & Hierarchy - let mut hierarchy_map: HashMap> = HashMap::new(); - if let Some(types_array) = types_value.as_array() { - for type_row in types_array { - if let Some(schemas_raw) = type_row.get("schemas") { - if let Some(schemas_array) = schemas_raw.as_array() { - for schema_def in schemas_array { - if let Some(schema_id) = schema_def.get("$id").and_then(|v| v.as_str()) { - schemas_to_register.push((schema_id.to_string(), schema_def.clone(), SchemaType::Type)); - } - } - } - } - if let Some(type_name) = type_row.get("name").and_then(|v| v.as_str()) { - if let Some(hierarchy_raw) = type_row.get("hierarchy") { - if let Some(hierarchy_array) = hierarchy_raw.as_array() { - for ancestor_val in hierarchy_array { - if let Some(ancestor_name) = ancestor_val.as_str() { - hierarchy_map.entry(ancestor_name.to_string()).or_default().insert(type_name.to_string()); - } - } - } - } - } - } - } - - for (base_type, descendant_types) in hierarchy_map { - let family_id = format!("{}.family", base_type); - let values: Vec = descendant_types.into_iter().collect(); - let family_schema = json!({ "$id": family_id, "type": "string", "enum": values }); - schemas_to_register.push((family_id, family_schema, SchemaType::Family)); - } - - // Phase 3: Puncs - if let Some(puncs_array) = puncs_value.as_array() { - for punc_row in puncs_array { - if let Some(punc_obj) = punc_row.as_object() { - if let Some(punc_name) = punc_obj.get("name").and_then(|v| v.as_str()) { - let is_public = punc_obj.get("public").and_then(|v| v.as_bool()).unwrap_or(false); - let punc_type = if is_public { SchemaType::PublicPunc } else { SchemaType::PrivatePunc }; - if let Some(schemas_raw) = punc_obj.get("schemas") { - if let Some(schemas_array) = schemas_raw.as_array() { - for schema_def in schemas_array { - if let Some(schema_id) = schema_def.get("$id").and_then(|v| v.as_str()) { - let req_id = format!("{}.request", punc_name); - let resp_id = format!("{}.response", punc_name); - let st = if schema_id == req_id || schema_id == resp_id { punc_type } else { SchemaType::Type }; - schemas_to_register.push((schema_id.to_string(), schema_def.clone(), st)); - } - } - } - } - } - } - } - } - - let mut all_errors = Vec::new(); - for (id, value, st) in schemas_to_register { - // Meta-validation: Check 'type' enum if present - if let Some(type_val) = value.get("type") { - let types = match type_val { - Value::String(s) => vec![s.as_str()], - Value::Array(a) => a.iter().filter_map(|v| v.as_str()).collect(), - _ => vec![], - }; - let valid_primitives = ["string", "number", "integer", "boolean", "array", "object", "null"]; - for t in types { - if !valid_primitives.contains(&t) { - all_errors.push(json!({ "code": "ENUM_VIOLATED", "message": format!("Invalid type: {}", t) })); - } - } - } - - // Clone value for insertion since it might be consumed/moved if we were doing other things - let value_for_registry = value.clone(); - - // Validation: just ensure it is an object or boolean - if value.is_object() || value.is_boolean() { - REGISTRY.insert(id.clone(), value_for_registry); - meta.insert(id, CachedSchema { t: st }); - } else { - all_errors.push(json!({ "code": "INVALID_SCHEMA_TYPE", "message": format!("Schema {} must be an object or boolean", id) })); - } - } - - if !all_errors.is_empty() { - return JsonB(json!({ "errors": all_errors })); - } - - JsonB(json!({ "response": "success" })) -} - -#[pg_extern(strict, parallel_safe)] -fn validate_json_schema(schema_id: &str, instance: JsonB) -> JsonB { - let schema = match REGISTRY.get(schema_id) { - Some(s) => s, - None => return JsonB(json!({ - "errors": [{ - "code": "SCHEMA_NOT_FOUND", - "message": format!("Schema '{}' not found", schema_id), - "details": { "schema": schema_id } - }] - })), - }; - - let meta = SCHEMA_META.read().unwrap(); - let st = meta.get(schema_id).map(|m| m.t).unwrap_or(SchemaType::Type); - - let be_strict = match st { - SchemaType::PublicPunc => true, - _ => false, - }; - - let options = ValidationOptions { - be_strict, - }; - - let mut validator = Validator::new(options, schema_id); - match validator.validate(&schema, &instance.0) { - Ok(_) => JsonB(json!({ "response": "success" })), - Err(errors) => { - let drop_errors: Vec = errors.into_iter().map(|e| json!({ - "code": e.code, - "message": e.message, - "details": { - "path": e.path, - "context": e.context, - "cause": e.cause, - "schema": e.schema_id - } - })).collect(); - - if let Ok(mut f) = std::fs::OpenOptions::new().create(true).append(true).open("/tmp/debug_jspg_errors.log") { - use std::io::Write; - let _ = writeln!(f, "VALIDATION FAILED for {}: {:?}", schema_id, drop_errors); - } - - JsonB(json!({ "errors": drop_errors })) - } - } -} - - -#[pg_extern(strict, parallel_safe)] -fn json_schema_cached(schema_id: &str) -> bool { - REGISTRY.get(schema_id).is_some() -} - -#[pg_extern(strict)] -fn clear_json_schemas() -> JsonB { - REGISTRY.reset(); - let mut meta = SCHEMA_META.write().unwrap(); - meta.clear(); - JsonB(json!({ "response": "success" })) -} - -#[pg_extern(strict, parallel_safe)] -fn show_json_schemas() -> JsonB { - let meta = SCHEMA_META.read().unwrap(); - let ids: Vec = meta.keys().cloned().collect(); - JsonB(json!({ "response": ids })) -} - -/// This module is required by `cargo pgrx test` invocations. -/// It must be visible at the root of your extension crate. -#[cfg(test)] -pub mod pg_test { - pub fn setup(_options: Vec<&str>) { - // perform one-off initialization when the pg_test framework starts - } - - #[must_use] - pub fn postgresql_conf_options() -> Vec<&'static str> { - // return any postgresql.conf settings that are required for your tests - vec![] - } -} - -#[cfg(any(test, feature = "pg_test"))] -#[pg_schema] -mod tests { - use pgrx::pg_test; - include!("suite.rs"); -} \ No newline at end of file diff --git a/old_code/registry.rs b/old_code/registry.rs deleted file mode 100644 index 55f47d8..0000000 --- a/old_code/registry.rs +++ /dev/null @@ -1,217 +0,0 @@ -use serde_json::Value; -use std::collections::HashMap; -use std::sync::RwLock; -use lazy_static::lazy_static; - -lazy_static! { - pub static ref REGISTRY: Registry = Registry::new(); -} - -pub struct Registry { - schemas: RwLock>, -} - -impl Registry { - pub fn new() -> Self { - Self { - schemas: RwLock::new(HashMap::new()), - } - } - - pub fn reset(&self) { - let mut schemas = self.schemas.write().unwrap(); - schemas.clear(); - } - - pub fn insert(&self, id: String, schema: Value) { - let mut schemas = self.schemas.write().unwrap(); - - // Index the schema and its sub-resources (IDs and anchors) - self.index_schema(&schema, &mut schemas, Some(&id)); - - // Ensure the root ID is inserted (index_schema handles it, but let's be explicit) - schemas.insert(id, schema); - } - - fn index_schema(&self, schema: &Value, registry: &mut HashMap, current_scope: Option<&str>) { - if let Value::Object(map) = schema { - // Only strictly index $id for scope resolution - let mut my_scope = current_scope.map(|s| s.to_string()); - - if let Some(Value::String(id)) = map.get("$id") { - if id.contains("://") { - my_scope = Some(id.clone()); - } else if let Some(scope) = current_scope { - if let Some(pos) = scope.rfind('/') { - my_scope = Some(format!("{}{}", &scope[..pos + 1], id)); - } else { - my_scope = Some(id.clone()); - } - } else { - my_scope = Some(id.clone()); - } - - if let Some(final_id) = &my_scope { - registry.insert(final_id.clone(), schema.clone()); - } - } - - // Minimal recursion only for definitions where sub-IDs often live - // This is a tradeoff: we don't index EVERYWHERE, but we catch the 90% common case of - // bundled definitions without full tree traversal. - if let Some(Value::Object(defs)) = map.get("$defs").or_else(|| map.get("definitions")) { - for (_, def_schema) in defs { - self.index_schema(def_schema, registry, my_scope.as_deref()); - } - } - } - } - - pub fn get(&self, id: &str) -> Option { - let schemas = self.schemas.read().unwrap(); - schemas.get(id).cloned() - } - - pub fn resolve(&self, ref_str: &str, current_id: Option<&str>) -> Option<(Value, String)> { - // 1. Try full lookup (Absolute or explicit ID) - if let Some(s) = self.get(ref_str) { - return Some((s, ref_str.to_string())); - } - - // 2. Try Relative lookup against current scope - if let Some(curr) = current_id { - if let Some(pos) = curr.rfind('/') { - let joined = format!("{}{}", &curr[..pos + 1], ref_str); - if let Some(s) = self.get(&joined) { - return Some((s, joined)); - } - } - } - - // 3. Pointer Resolution - // Split into Base URI + Fragment - let (base, fragment) = match ref_str.split_once('#') { - Some((b, f)) => (b, Some(f)), - None => (ref_str, None), - }; - - // If base is empty, we stay in current schema. - // If base is present, we resolve it first. - let (root_schema, scope) = if base.is_empty() { - if let Some(curr) = current_id { - // If we are looking up internally, we rely on the caller having passed the correct current ID - // But typically internal refs are just fragments. - if let Some(s) = self.get(curr) { - (s, curr.to_string()) - } else { - return None; - } - } else { - return None; - } - } else { - // Resolve external base - if let Some(s) = self.get(base) { - (s, base.to_string()) - } else if let Some(curr) = current_id { - // Try relative base - if let Some(pos) = curr.rfind('/') { - let joined = format!("{}{}", &curr[..pos + 1], base); - if let Some(s) = self.get(&joined) { - (s, joined) - } else { - return None; - } - } else { - return None; - } - } else { - return None; - } - }; - - if let Some(frag_raw) = fragment { - if frag_raw.is_empty() { - return Some((root_schema, scope)); - } - // Decode fragment (it is URI encoded) - let frag_cow = percent_encoding::percent_decode_str(frag_raw).decode_utf8().unwrap_or(std::borrow::Cow::Borrowed(frag_raw)); - let frag = frag_cow.as_ref(); - - if frag.starts_with('/') { - if let Some(sub) = root_schema.pointer(frag) { - return Some((sub.clone(), scope)); - } - } else { - // It is an anchor. We scan for it at runtime to avoid complex indexing at insertion. - if let Some(sub) = self.find_anchor(&root_schema, frag) { - return Some((sub, scope)); - } - } - None - } else { - Some((root_schema, scope)) - } - } - - fn find_anchor(&self, schema: &Value, anchor: &str) -> Option { - match schema { - Value::Object(map) => { - // Check if this schema itself has the anchor - if let Some(Value::String(a)) = map.get("$anchor") { - if a == anchor { - return Some(schema.clone()); - } - } - - // Recurse into $defs / definitions (Map of Schemas) - if let Some(Value::Object(defs)) = map.get("$defs").or_else(|| map.get("definitions")) { - for val in defs.values() { - if let Some(found) = self.find_anchor(val, anchor) { return Some(found); } - } - } - - // Recurse into properties / patternProperties / dependentSchemas (Map of Schemas) - for key in ["properties", "patternProperties", "dependentSchemas"] { - if let Some(Value::Object(props)) = map.get(key) { - for val in props.values() { - if let Some(found) = self.find_anchor(val, anchor) { return Some(found); } - } - } - } - - // Recurse into arrays of schemas - for key in ["allOf", "anyOf", "oneOf", "prefixItems"] { - if let Some(Value::Array(arr)) = map.get(key) { - for item in arr { - if let Some(found) = self.find_anchor(item, anchor) { return Some(found); } - } - } - } - - // Recurse into single sub-schemas - for key in ["items", "contains", "additionalProperties", "unevaluatedProperties", "not", "if", "then", "else"] { - if let Some(val) = map.get(key) { - if val.is_object() || val.is_boolean() { - if let Some(found) = self.find_anchor(val, anchor) { return Some(found); } - } - } - } - None - } - Value::Array(arr) => { - // Should not happen for a schema object, but if we are passed an array of schemas? - // Standard schema is object or bool. - // But let's be safe. - for item in arr { - if let Some(found) = self.find_anchor(item, anchor) { - return Some(found); - } - } - None - } - _ => None, - } - } -} - diff --git a/old_code/suite.rs b/old_code/suite.rs deleted file mode 100644 index 6754e5b..0000000 --- a/old_code/suite.rs +++ /dev/null @@ -1,236 +0,0 @@ -// use crate::schema::Schema; -use crate::registry::REGISTRY; -use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; -use pgrx::JsonB; -use std::{fs, path::Path}; - -#[derive(Debug, Serialize, Deserialize)] -struct ExpectedError { - code: String, - path: String, - message_contains: Option, - cause: Option, - context: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -struct Group { - description: String, - schema: Option, - enums: Option, - types: Option, - puncs: Option, - tests: Vec, -} - -#[derive(Debug, Serialize, Deserialize)] -struct TestCase { - description: String, - data: Value, - valid: bool, - action: Option, - schema_id: Option, - expect_errors: Option>, -} - -include!("tests.rs"); - -fn load_remotes(dir: &Path, base_url: &str) { - if !dir.exists() { return; } - - for entry in fs::read_dir(dir).expect("Failed to read remotes directory") { - let entry = entry.unwrap(); - let path = entry.path(); - let file_name = path.file_name().unwrap().to_str().unwrap(); - - if path.is_file() && file_name.ends_with(".json") { - let content = fs::read_to_string(&path).expect("Failed to read remote file"); - if let Ok(schema_value) = serde_json::from_str::(&content) { - // Just check if it's a valid JSON value for a schema (object or bool) - if schema_value.is_object() || schema_value.is_boolean() { - let schema_id = format!("{}{}", base_url, file_name); - REGISTRY.insert(schema_id, schema_value); - } - } - } else if path.is_dir() { - load_remotes(&path, &format!("{}{}/", base_url, file_name)); - } - } - - // Mock the meta-schema for testing recursive refs - let meta_id = "https://json-schema.org/draft/2020-12/schema"; - if REGISTRY.get(meta_id).is_none() { - // Just mock it as a permissive schema for now so refs resolve - REGISTRY.insert(meta_id.to_string(), json!({ "$id": meta_id })); - } -} - -#[allow(dead_code)] -fn run_dir(dir: &Path, base_url: Option<&str>) -> (usize, usize) { - let mut file_count = 0; - let mut test_count = 0; - - for entry in fs::read_dir(dir).expect("Failed to read directory") { - let entry = entry.unwrap(); - let path = entry.path(); - let file_name = path.file_name().unwrap().to_str().unwrap(); - - if path.is_file() && file_name.ends_with(".json") { - let count = run_file(&path, base_url); - test_count += count; - file_count += 1; - } else if path.is_dir() { - if !file_name.starts_with('.') && file_name != "optional" { - let (f, t) = run_dir(&path, base_url); - file_count += f; - test_count += t; - } - } - } - (file_count, test_count) -} - -fn run_file(path: &Path, base_url: Option<&str>) -> usize { - let content = fs::read_to_string(path).expect("Failed to read file"); - let groups: Vec = serde_json::from_str(&content).expect("Failed to parse JSON"); - let filename = path.file_name().unwrap().to_str().unwrap(); - - let mut test_count = 0; - - for group in groups { - // Handle JSPG setup if any JSPG fields are present - if group.enums.is_some() || group.types.is_some() || group.puncs.is_some() { - let enums = group.enums.clone().unwrap_or(json!([])); - let types = group.types.clone().unwrap_or(json!([])); - let puncs = group.puncs.clone().unwrap_or(json!([])); - // Use internal helper to register without clearing - let result = crate::cache_json_schemas(JsonB(enums), JsonB(types), JsonB(puncs)); - if let Some(errors) = result.0.get("errors") { - // If the group has a test specifically for caching failures, don't panic here - let has_cache_test = group.tests.iter().any(|t| t.action.as_deref() == Some("cache")); - if !has_cache_test { - panic!("FAILED: File: {}, Group: {}\nCache failed: {:?}", filename, group.description, errors); - } - } - } - - let mut temp_id = "test_root".to_string(); - if let Some(schema_value) = &group.schema { - temp_id = base_url.map(|b| format!("{}schema.json", b)).unwrap_or_else(|| "test_root".to_string()); - - if schema_value.is_object() || schema_value.is_boolean() { - REGISTRY.insert(temp_id.clone(), schema_value.clone()); - } - } else { - // Fallback for JSPG style tests where the schema is in the puncs/types - let get_first_id = |items: &Option| { - items.as_ref() - .and_then(|v| v.as_array()) - .and_then(|arr| arr.first()) - .and_then(|item| item.get("schemas")) - .and_then(|v| v.as_array()) - .and_then(|arr| arr.first()) - .and_then(|sch| sch.get("$id")) - .and_then(|id| id.as_str()) - .map(|s| s.to_string()) - }; - - if let Some(id) = get_first_id(&group.puncs).or_else(|| get_first_id(&group.types)) { - temp_id = id; - } - } - - for test in &group.tests { - test_count += 1; - let sid = test.schema_id.clone().unwrap_or_else(|| temp_id.clone()); - let action = test.action.as_deref().unwrap_or("validate"); - pgrx::notice!("Starting Test: {}", test.description); - - let result = if action == "cache" { - let enums = group.enums.clone().unwrap_or(json!([])); - let types = group.types.clone().unwrap_or(json!([])); - let puncs = group.puncs.clone().unwrap_or(json!([])); - crate::cache_json_schemas(JsonB(enums), JsonB(types), JsonB(puncs)) - } else { - crate::validate_json_schema(&sid, JsonB(test.data.clone())) - }; - let is_success = result.0.get("response").is_some(); - pgrx::notice!("TEST: file={}, group={}, test={}, valid={}, outcome={}", - filename, - &group.description, - &test.description, - test.valid, - if is_success { "SUCCESS" } else { "ERRORS" } - ); - - if is_success != test.valid { - if let Some(errs) = result.0.get("errors") { - panic!( - "FAILED: File: {}, Group: {}, Test: {}\nExpected valid: {}, got ERRORS: {:?}", - filename, - group.description, - test.description, - test.valid, - errs - ); - } else { - panic!( - "FAILED: File: {}, Group: {}, Test: {}\nExpected invalid, got SUCCESS", - filename, - group.description, - test.description - ); - } - } - - // Perform detailed assertions if present - if let Some(expectations) = &test.expect_errors { - let actual_errors = result.0.get("errors").and_then(|e| e.as_array()).expect("Expected errors array in failure response"); - - for expected in expectations { - let found = actual_errors.iter().any(|e| { - let code = e["code"].as_str().unwrap_or(""); - let path = e["details"]["path"].as_str().unwrap_or(""); - let message = e["message"].as_str().unwrap_or(""); - - let code_match = code == expected.code; - let path_match = path == expected.path; - let msg_match = if let Some(sub) = &expected.message_contains { - message.contains(sub) - } else { - true - }; - - let matches_cause = if let Some(expected_cause) = &expected.cause { - e["details"]["cause"] == *expected_cause - } else { - true - }; - - let matches_context = if let Some(expected_context) = &expected.context { - e["details"]["context"] == *expected_context - } else { - true - }; - - code_match && path_match && msg_match && matches_cause && matches_context - }); - - if !found { - panic!( - "FAILED: File: {}, Group: {}, Test: {}\nMissing expected error: code='{}', path='{}'\nActual errors: {:?}", - filename, - group.description, - test.description, - expected.code, - expected.path, - actual_errors - ); - } - } - } - } // end of test loop - } // end of group loop - test_count -} \ No newline at end of file diff --git a/old_code/tests.rs b/old_code/tests.rs deleted file mode 100644 index 05a714b..0000000 --- a/old_code/tests.rs +++ /dev/null @@ -1,482 +0,0 @@ - -#[pg_test] -fn test_jspg_additional_properties() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/additionalProperties.json"), None); -} - -#[pg_test] -fn test_jspg_cache() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/cache.json"), None); -} - -#[pg_test] -fn test_jspg_const() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/const.json"), None); -} - -#[pg_test] -fn test_jspg_dependencies() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/dependencies.json"), None); -} - -#[pg_test] -fn test_jspg_enum() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/enum.json"), None); -} - -#[pg_test] -fn test_jspg_errors() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/errors.json"), None); -} - -#[pg_test] -fn test_jspg_format() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/format.json"), None); -} - -#[pg_test] -fn test_jspg_infinite_loop_detection() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/infinite-loop-detection.json"), None); -} - -#[pg_test] -fn test_jspg_one_of() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/oneOf.json"), None); -} - -#[pg_test] -fn test_jspg_properties() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/properties.json"), None); -} - -#[pg_test] -fn test_jspg_punc() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/punc.json"), None); -} - -#[pg_test] -fn test_jspg_ref() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/ref.json"), None); -} - -#[pg_test] -fn test_jspg_required() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/required.json"), None); -} - -#[pg_test] -fn test_jspg_simple() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/simple.json"), None); -} - -#[pg_test] -fn test_jspg_strict() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/strict.json"), None); -} - -#[pg_test] -fn test_jspg_title() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/title.json"), None); -} - -#[pg_test] -fn test_jspg_type() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/type.json"), None); -} - -#[pg_test] -fn test_jspg_unevaluated_properties() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/unevaluatedProperties.json"), None); -} - -#[pg_test] -fn test_jspg_unique_items() { - REGISTRY.reset(); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSPG-Test-Suite/uniqueItems.json"), None); -} - -#[pg_test] -fn test_json_schema_additional_properties() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/additionalProperties.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_all_of() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/allOf.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_anchor() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/anchor.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_any_of() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/anyOf.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_boolean_schema() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/boolean_schema.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_const() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/const.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_contains() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/contains.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_content() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/content.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_default() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/default.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_defs() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/defs.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_dependent_required() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/dependentRequired.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_dependent_schemas() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/dependentSchemas.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_dynamic_ref() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/dynamicRef.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_enum() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/enum.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_exclusive_maximum() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/exclusiveMaximum.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_exclusive_minimum() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/exclusiveMinimum.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_format() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/format.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_if_then_else() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/if-then-else.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_infinite_loop_detection() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/infinite-loop-detection.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_items() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/items.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_max_contains() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/maxContains.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_max_items() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/maxItems.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_max_length() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/maxLength.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_max_properties() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/maxProperties.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_maximum() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/maximum.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_min_contains() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/minContains.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_min_items() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/minItems.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_min_length() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/minLength.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_min_properties() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/minProperties.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_minimum() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/minimum.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_multiple_of() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/multipleOf.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_not() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/not.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_one_of() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/oneOf.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_pattern() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/pattern.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_pattern_properties() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/patternProperties.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_prefix_items() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/prefixItems.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_properties() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/properties.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_property_names() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/propertyNames.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_ref() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/ref.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_ref_remote() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/refRemote.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_required() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/required.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_type() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/type.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_unevaluated_items() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/unevaluatedItems.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_unevaluated_properties() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/unevaluatedProperties.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_unique_items() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/uniqueItems.json"), Some("http://localhost:1234/")); -} - -#[pg_test] -fn test_json_schema_vocabulary() { - REGISTRY.reset(); - let remotes_dir = Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/remotes"); - load_remotes(remotes_dir, "http://localhost:1234/"); - run_file(Path::new("/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg/tests/fixtures/JSON-Schema-Test-Suite/tests/draft2020-12/vocabulary.json"), Some("http://localhost:1234/")); -} diff --git a/old_code/util.rs b/old_code/util.rs deleted file mode 100644 index e8dc69c..0000000 --- a/old_code/util.rs +++ /dev/null @@ -1,53 +0,0 @@ -use serde_json::Value; - -/// serde_json treats 0 and 0.0 not equal. so we cannot simply use v1==v2 -pub fn equals(v1: &Value, v2: &Value) -> bool { - match (v1, v2) { - (Value::Null, Value::Null) => true, - (Value::Bool(b1), Value::Bool(b2)) => b1 == b2, - (Value::Number(n1), Value::Number(n2)) => { - if let (Some(n1), Some(n2)) = (n1.as_u64(), n2.as_u64()) { - return n1 == n2; - } - if let (Some(n1), Some(n2)) = (n1.as_i64(), n2.as_i64()) { - return n1 == n2; - } - if let (Some(n1), Some(n2)) = (n1.as_f64(), n2.as_f64()) { - return (n1 - n2).abs() < f64::EPSILON; - } - false - } - (Value::String(s1), Value::String(s2)) => s1 == s2, - (Value::Array(arr1), Value::Array(arr2)) => { - if arr1.len() != arr2.len() { - return false; - } - arr1.iter().zip(arr2).all(|(e1, e2)| equals(e1, e2)) - } - (Value::Object(obj1), Value::Object(obj2)) => { - if obj1.len() != obj2.len() { - return false; - } - for (k1, v1) in obj1 { - if let Some(v2) = obj2.get(k1) { - if !equals(v1, v2) { - return false; - } - } else { - return false; - } - } - true - } - _ => false, - } -} - -pub fn is_integer(v: &Value) -> bool { - match v { - Value::Number(n) => { - n.is_i64() || n.is_u64() || n.as_f64().filter(|n| n.fract() == 0.0).is_some() - } - _ => false, - } -} diff --git a/old_code/validator.rs b/old_code/validator.rs deleted file mode 100644 index fbaa934..0000000 --- a/old_code/validator.rs +++ /dev/null @@ -1,621 +0,0 @@ -use crate::registry::REGISTRY; -use crate::util::{equals, is_integer}; -use serde_json::{Value, json, Map}; -use std::collections::HashSet; - -#[derive(Debug, Clone, serde::Serialize)] -pub struct ValidationError { - pub code: String, - pub message: String, - pub path: String, - pub context: Value, - pub cause: Value, - pub schema_id: String, -} - -#[derive(Default, Clone, Copy)] -pub struct ValidationOptions { - pub be_strict: bool, -} - -pub struct Validator<'a> { - options: ValidationOptions, - // The top-level root schema ID we started with - root_schema_id: String, - // Accumulated errors - errors: Vec, - // Max depth to prevent stack overflow - max_depth: usize, - _phantom: std::marker::PhantomData<&'a ()>, -} - -/// Context passed down through the recursion -#[derive(Clone)] -struct ValidationContext { - // Current JSON pointer path in the instance (e.g. "/users/0/name") - current_path: String, - // The properties overridden by parent schemas (for JSPG inheritance) - overrides: HashSet, - // Current resolution scope for $ref (changes when following refs) - resolution_scope: String, - // Current recursion depth - depth: usize, -} - -impl ValidationContext { - fn append_path(&self, extra: &str) -> ValidationContext { - let mut new_ctx = self.clone(); - if new_ctx.current_path.ends_with('/') { - new_ctx.current_path.push_str(extra); - } else if new_ctx.current_path.is_empty() { - new_ctx.current_path.push('/'); - new_ctx.current_path.push_str(extra); - } else { - new_ctx.current_path.push('/'); - new_ctx.current_path.push_str(extra); - } - new_ctx - } - - fn append_path_new_scope(&self, extra: &str) -> ValidationContext { - let mut new_ctx = self.append_path(extra); - // Structural recursion clears overrides - new_ctx.overrides.clear(); - new_ctx - } -} - -impl<'a> Validator<'a> { - pub fn new(options: ValidationOptions, root_schema_id: &str) -> Self { - Self { - options, - root_schema_id: root_schema_id.to_string(), - errors: Vec::new(), - max_depth: 100, - _phantom: std::marker::PhantomData, - } - } - - pub fn validate(&mut self, schema: &Value, instance: &Value) -> Result<(), Vec> { - let ctx = ValidationContext { - current_path: String::new(), - overrides: HashSet::new(), - resolution_scope: self.root_schema_id.clone(), - depth: 0, - }; - - // We treat the top-level validate as "not lax" by default, unless specific schema logic says otherwise. - let is_lax = !self.options.be_strict; - - self.validate_node(schema, instance, ctx, is_lax, false, false); - - if self.errors.is_empty() { - Ok(()) - } else { - Err(self.errors.clone()) - } - } - - fn validate_node( - &mut self, - schema: &Value, - instance: &Value, - mut ctx: ValidationContext, - is_lax: bool, - skip_strict: bool, - skip_id: bool, - ) -> HashSet { - let mut evaluated = HashSet::new(); - - // Recursion limit - if ctx.depth > self.max_depth { - self.add_error("MAX_DEPTH_REACHED", "Maximum recursion depth exceeded".to_string(), instance, json!({ "depth": ctx.depth }), &ctx); - return evaluated; - } - - ctx.depth += 1; - - // Handle Boolean Schemas - if let Value::Bool(b) = schema { - if !b { - self.add_error("FALSE_SCHEMA", "Schema is always false".to_string(), instance, Value::Null, &ctx); - } - return evaluated; - } - - let schema_obj = match schema.as_object() { - Some(o) => o, - None => return evaluated, // Should be object or bool - }; - - // 1. Update Resolution Scope ($id) - if !skip_id { - if let Some(Value::String(id)) = schema_obj.get("$id") { - if id.contains("://") { - ctx.resolution_scope = id.clone(); - } else { - if let Some(pos) = ctx.resolution_scope.rfind('/') { - let base = &ctx.resolution_scope[..pos + 1]; - ctx.resolution_scope = format!("{}{}", base, id); - } else { - ctx.resolution_scope = id.clone(); - } - } - } - } - - // 2. Identify Overrides (JSPG Custom Logic) - let mut inheritance_ctx = ctx.clone(); - if let Some(Value::Object(props)) = schema_obj.get("properties") { - for (pname, pval) in props { - if let Some(Value::Bool(true)) = pval.get("override") { - inheritance_ctx.overrides.insert(pname.clone()); - } - } - } - - // 3. Determine Laxness - let mut current_lax = is_lax; - if let Some(Value::Bool(true)) = schema_obj.get("unevaluatedProperties") { current_lax = true; } - if let Some(Value::Bool(true)) = schema_obj.get("additionalProperties") { current_lax = true; } - - // ======== VALIDATION KEYWORDS ======== - - // Type - if let Some(type_val) = schema_obj.get("type") { - if !self.check_type(type_val, instance) { - let got = value_type_name(instance); - let want_json = serde_json::to_value(type_val).unwrap_or(json!("unknown")); - self.add_error("TYPE_MISMATCH", format!("Expected type {:?} but got {}", type_val, got), instance, json!({ "want": type_val, "got": got }), &ctx); - } - } - - // Enum - if let Some(Value::Array(vals)) = schema_obj.get("enum") { - if !vals.iter().any(|v| equals(v, instance)) { - self.add_error("ENUM_VIOLATED", "Value not in enum".to_string(), instance, json!({ "want": vals }), &ctx); - } - } - - // Const - if let Some(c) = schema_obj.get("const") { - if !equals(c, instance) { - self.add_error("CONST_VIOLATED", "Value does not match constant".to_string(), instance, json!({ "want": c }), &ctx); - } - } - - // Object Validation - if let Value::Object(obj) = instance { - let obj_eval = self.validate_object(schema_obj, obj, instance, &ctx, current_lax); - evaluated.extend(obj_eval); - } - - // Array Validation - if let Value::Array(arr) = instance { - self.validate_array(schema_obj, arr, &ctx, current_lax); - } - - // Primitive Validation - self.validate_primitives(schema_obj, instance, &ctx); - - // Combinators - evaluated.extend(self.validate_combinators(schema_obj, instance, &inheritance_ctx, current_lax)); - - // Conditionals - evaluated.extend(self.validate_conditionals(schema_obj, instance, &inheritance_ctx, current_lax)); - - // $ref - if let Some(Value::String(ref_str)) = schema_obj.get("$ref") { - if let Some((ref_schema, scope_uri)) = REGISTRY.resolve(ref_str, Some(&inheritance_ctx.resolution_scope)) { - let mut new_ctx = inheritance_ctx.clone(); - new_ctx.resolution_scope = scope_uri; - let ref_evaluated = self.validate_node(&ref_schema, instance, new_ctx, is_lax, true, true); - evaluated.extend(ref_evaluated); - } else { - self.add_error("SCHEMA_NOT_FOUND", format!("Ref '{}' not found", ref_str), instance, json!({ "ref": ref_str }), &ctx); - } - } - - // Unevaluated / Strictness Check - self.check_unevaluated(schema_obj, instance, &evaluated, &ctx, current_lax, skip_strict); - - evaluated - } - - fn validate_object( - &mut self, - schema: &Map, - obj: &Map, - instance: &Value, - ctx: &ValidationContext, - is_lax: bool, - ) -> HashSet { - let mut evaluated = HashSet::new(); - - // required - if let Some(Value::Array(req)) = schema.get("required") { - for field_val in req { - if let Some(field) = field_val.as_str() { - if !obj.contains_key(field) { - self.add_error("REQUIRED_FIELD_MISSING", format!("Required field '{}' is missing", field), &Value::Null, json!({ "want": [field] }), &ctx.append_path(field)); - } - } - } - } - - // properties - if let Some(Value::Object(props)) = schema.get("properties") { - for (pname, psch) in props { - if obj.contains_key(pname) { - if ctx.overrides.contains(pname) { - evaluated.insert(pname.clone()); - continue; - } - evaluated.insert(pname.clone()); - let sub_ctx = ctx.append_path_new_scope(pname); - self.validate_node(psch, &obj[pname], sub_ctx, is_lax, false, false); - } - } - } - - // patternProperties - if let Some(Value::Object(pprops)) = schema.get("patternProperties") { - for (pattern, psch) in pprops { - if let Ok(re) = regex::Regex::new(pattern) { - for (pname, pval) in obj { - if re.is_match(pname) { - if ctx.overrides.contains(pname) { - evaluated.insert(pname.clone()); - continue; - } - evaluated.insert(pname.clone()); - let sub_ctx = ctx.append_path_new_scope(pname); - self.validate_node(psch, pval, sub_ctx, is_lax, false, false); - } - } - } - } - } - - // additionalProperties - if let Some(apsch) = schema.get("additionalProperties") { - if apsch.is_object() || apsch.is_boolean() { - for (key, val) in obj { - let in_props = schema.get("properties").and_then(|p| p.as_object()).map_or(false, |p| p.contains_key(key)); - let in_patterns = schema.get("patternProperties").and_then(|p| p.as_object()).map_or(false, |pp| { - pp.keys().any(|k| regex::Regex::new(k).map(|re| re.is_match(key)).unwrap_or(false)) - }); - - if !in_props && !in_patterns { - evaluated.insert(key.clone()); - let sub_ctx = ctx.append_path_new_scope(key); - self.validate_node(apsch, val, sub_ctx, is_lax, false, false); - } - } - } - } - - // dependentRequired - if let Some(Value::Object(dep_req)) = schema.get("dependentRequired") { - for (prop, required_fields_val) in dep_req { - if obj.contains_key(prop) { - if let Value::Array(required_fields) = required_fields_val { - for req_field_val in required_fields { - if let Some(req_field) = req_field_val.as_str() { - if !obj.contains_key(req_field) { - self.add_error("DEPENDENCY_FAILED", format!("Field '{}' is required when '{}' is present", req_field, prop), &Value::Null, json!({ "prop": prop, "missing": [req_field] }), &ctx.append_path(req_field)); - } - } - } - } - } - } - } - - // dependentSchemas - if let Some(Value::Object(dep_sch)) = schema.get("dependentSchemas") { - for (prop, psch) in dep_sch { - if obj.contains_key(prop) { - let sub_evaluated = self.validate_node(psch, instance, ctx.clone(), is_lax, false, false); - evaluated.extend(sub_evaluated); - } - } - } - - // legacy dependencies (Draft 4-7 compat) - if let Some(Value::Object(deps)) = schema.get("dependencies") { - for (prop, dep_val) in deps { - if obj.contains_key(prop) { - match dep_val { - Value::Array(arr) => { - for req_val in arr { - if let Some(req_field) = req_val.as_str() { - if !obj.contains_key(req_field) { - self.add_error( - "DEPENDENCY_FAILED", - format!("Field '{}' is required when '{}' is present", req_field, prop), - &Value::Null, - json!({ "prop": prop, "missing": [req_field] }), - &ctx.append_path(req_field), - ); - } - } - } - } - Value::Object(_) => { - // Schema dependency - let sub_evaluated = self.validate_node(dep_val, instance, ctx.clone(), is_lax, false, false); - evaluated.extend(sub_evaluated); - } - _ => {} - } - } - } - } - - // minProperties / maxProperties - if let Some(min) = schema.get("minProperties").and_then(|v| v.as_u64()) { - if (obj.len() as u64) < min { - self.add_error("MIN_PROPERTIES_VIOLATED", format!("Object must have at least {} properties", min), &json!(obj.len()), json!({ "want": min, "got": obj.len() }), ctx); - } - } - if let Some(max) = schema.get("maxProperties").and_then(|v| v.as_u64()) { - if (obj.len() as u64) > max { - self.add_error("MAX_PROPERTIES_VIOLATED", format!("Object must have at most {} properties", max), &json!(obj.len()), json!({ "want": max, "got": obj.len() }), ctx); - } - } - - evaluated - } - - fn validate_array( - &mut self, - schema: &Map, - arr: &Vec, - ctx: &ValidationContext, - is_lax: bool, - ) { - if let Some(min) = schema.get("minItems").and_then(|v| v.as_u64()) { - if (arr.len() as u64) < min { - self.add_error("MIN_ITEMS_VIOLATED", format!("Array must have at least {} items", min), &json!(arr.len()), json!({ "want": min, "got": arr.len() }), ctx); - } - } - if let Some(max) = schema.get("maxItems").and_then(|v| v.as_u64()) { - if (arr.len() as u64) > max { - self.add_error("MAX_ITEMS_VIOLATED", format!("Array must have at most {} items", max), &json!(arr.len()), json!({ "want": max, "got": arr.len() }), ctx); - } - } - - let mut evaluated_index = 0; - if let Some(Value::Array(prefix)) = schema.get("prefixItems") { - for (i, psch) in prefix.iter().enumerate() { - if let Some(item) = arr.get(i) { - let sub_ctx = ctx.append_path_new_scope(&i.to_string()); - self.validate_node(psch, item, sub_ctx, is_lax, false, false); - evaluated_index = i + 1; - } - } - } - - if let Some(items_val) = schema.get("items") { - if let Value::Bool(false) = items_val { - if arr.len() > evaluated_index { - self.add_error("ADDITIONAL_ITEMS_NOT_ALLOWED", "Extra items not allowed".to_string(), &json!(arr.len()), json!({ "got": arr.len() - evaluated_index }), ctx); - } - } else { - // Schema or true - for i in evaluated_index..arr.len() { - let sub_ctx = ctx.append_path_new_scope(&i.to_string()); - self.validate_node(items_val, &arr[i], sub_ctx, is_lax, false, false); - } - } - } - - if let Some(contains_sch) = schema.get("contains") { - let mut matches = 0; - for (i, item) in arr.iter().enumerate() { - let mut sub = self.branch(); - let sub_ctx = ctx.append_path_new_scope(&i.to_string()); - sub.validate_node(contains_sch, item, sub_ctx, is_lax, false, false); - if sub.errors.is_empty() { - matches += 1; - } - } - if matches == 0 { - self.add_error("CONTAINS_FAILED", "No items match 'contains' schema".to_string(), &json!(arr), json!({}), ctx); - } - if let Some(min) = schema.get("minContains").and_then(|v| v.as_u64()) { - if (matches as u64) < min { - self.add_error("MIN_CONTAINS_VIOLATED", format!("Expected at least {} items to match 'contains'", min), &json!(arr), json!({ "want": min, "got": matches }), ctx); - } - } - if let Some(max) = schema.get("maxContains").and_then(|v| v.as_u64()) { - if (matches as u64) > max { - self.add_error("MAX_CONTAINS_VIOLATED", format!("Expected at most {} items to match 'contains'", max), &json!(arr), json!({ "want": max, "got": matches }), ctx); - } - } - } - - // uniqueItems - if let Some(Value::Bool(true)) = schema.get("uniqueItems") { - for i in 0..arr.len() { - for j in (i + 1)..arr.len() { - if equals(&arr[i], &arr[j]) { - self.add_error("UNIQUE_ITEMS_VIOLATED", format!("Array items at indices {} and {} are equal", i, j), &json!(arr), json!({ "got": [i, j] }), ctx); - return; - } - } - } - } - } - - fn validate_primitives(&mut self, schema: &Map, instance: &Value, ctx: &ValidationContext) { - if let Some(s) = instance.as_str() { - if let Some(min) = schema.get("minLength").and_then(|v| v.as_u64()) { - if (s.chars().count() as u64) < min { self.add_error("MIN_LENGTH_VIOLATED", format!("String too short (min {})", min), instance, json!({ "want": min, "got": s.len() }), ctx); } - } - if let Some(max) = schema.get("maxLength").and_then(|v| v.as_u64()) { - if (s.chars().count() as u64) > max { self.add_error("MAX_LENGTH_VIOLATED", format!("String too long (max {})", max), instance, json!({ "want": max, "got": s.len() }), ctx); } - } - if let Some(Value::String(pat)) = schema.get("pattern") { - if let Ok(re) = regex::Regex::new(pat) { - if !re.is_match(s) { self.add_error("PATTERN_VIOLATED", format!("String does not match pattern '{}'", pat), instance, json!({ "want": pat, "got": s }), ctx); } - } - } - if let Some(Value::String(fmt)) = schema.get("format") { - if !s.is_empty() { - match fmt.as_str() { - "uuid" => { if uuid::Uuid::parse_str(s).is_err() { self.add_error("FORMAT_INVALID", format!("Value '{}' is not a valid UUID", s), instance, json!({ "format": "uuid" }), ctx); } } - "date-time" => { if chrono::DateTime::parse_from_rfc3339(s).is_err() { self.add_error("FORMAT_INVALID", format!("Value '{}' is not a valid date-time", s), instance, json!({ "format": "date-time" }), ctx); } } - "email" => { if !s.contains('@') { self.add_error("FORMAT_INVALID", format!("Value '{}' is not a valid email", s), instance, json!({ "format": "email" }), ctx); } } - _ => {} - } - } - } - } - - if let Some(n) = instance.as_f64() { - if let Some(min) = schema.get("minimum").and_then(|v| v.as_f64()) { - if n < min { self.add_error("MINIMUM_VIOLATED", format!("Value {} < minimum {}", n, min), instance, json!({ "want": min, "got": n }), ctx); } - } - if let Some(max) = schema.get("maximum").and_then(|v| v.as_f64()) { - if n > max { self.add_error("MAXIMUM_VIOLATED", format!("Value {} > maximum {}", n, max), instance, json!({ "want": max, "got": n }), ctx); } - } - if let Some(min) = schema.get("exclusiveMinimum").and_then(|v| v.as_f64()) { - if n <= min { self.add_error("EXCLUSIVE_MINIMUM_VIOLATED", format!("Value {} <= exclusive minimum {}", n, min), instance, json!({ "want": min, "got": n }), ctx); } - } - if let Some(max) = schema.get("exclusiveMaximum").and_then(|v| v.as_f64()) { - if n >= max { self.add_error("EXCLUSIVE_MAXIMUM_VIOLATED", format!("Value {} >= exclusive maximum {}", n, max), instance, json!({ "want": max, "got": n }), ctx); } - } - if let Some(mult) = schema.get("multipleOf").and_then(|v| v.as_f64()) { - let rem = (n / mult).fract(); - if rem.abs() > f64::EPSILON && (1.0 - rem).abs() > f64::EPSILON { - self.add_error("MULTIPLE_OF_VIOLATED", format!("Value {} not multiple of {}", n, mult), instance, json!({ "want": mult, "got": n }), ctx); - } - } - } - } - - fn validate_combinators(&mut self, schema: &Map, instance: &Value, ctx: &ValidationContext, is_lax: bool) -> HashSet { - let mut evaluated = HashSet::new(); - if let Some(Value::Array(all_of)) = schema.get("allOf") { - for sch in all_of { evaluated.extend(self.validate_node(sch, instance, ctx.clone(), is_lax, true, false)); } - } - if let Some(Value::Array(any_of)) = schema.get("anyOf") { - let mut matched = false; - let mut errors_acc = Vec::new(); - for sch in any_of { - let mut sub = self.branch(); - let sub_eval = sub.validate_node(sch, instance, ctx.clone(), is_lax, false, false); - if sub.errors.is_empty() { matched = true; evaluated.extend(sub_eval); } else { errors_acc.extend(sub.errors); } - } - if !matched { self.add_error("ANY_OF_VIOLATED", "Value did not match any allowed schema".to_string(), instance, json!({ "causes": errors_acc }), ctx); } - } - if let Some(Value::Array(one_of)) = schema.get("oneOf") { - let mut match_count = 0; - let mut last_eval = HashSet::new(); - let mut error_causes = Vec::new(); - for sch in one_of { - let mut sub = self.branch(); - let sub_eval = sub.validate_node(sch, instance, ctx.clone(), is_lax, false, false); - if sub.errors.is_empty() { match_count += 1; last_eval = sub_eval; } else { error_causes.extend(sub.errors); } - } - if match_count == 1 { evaluated.extend(last_eval); } - else { self.add_error("ONE_OF_VIOLATED", format!("Value matched {} schemas, expected 1", match_count), instance, json!({ "matched": match_count, "causes": error_causes }), ctx); } - } - if let Some(not_sch) = schema.get("not") { - let mut sub = self.branch(); - sub.validate_node(not_sch, instance, ctx.clone(), is_lax, false, false); - if sub.errors.is_empty() { self.add_error("NOT_VIOLATED", "Value matched 'not' schema".to_string(), instance, Value::Null, ctx); } - } - evaluated - } - - fn validate_conditionals(&mut self, schema: &Map, instance: &Value, ctx: &ValidationContext, is_lax: bool) -> HashSet { - let mut evaluated = HashSet::new(); - if let Some(if_sch) = schema.get("if") { - let mut sub = self.branch(); - let sub_eval = sub.validate_node(if_sch, instance, ctx.clone(), is_lax, true, false); - if sub.errors.is_empty() { - evaluated.extend(sub_eval); - if let Some(then_sch) = schema.get("then") { evaluated.extend(self.validate_node(then_sch, instance, ctx.clone(), is_lax, false, false)); } - } else if let Some(else_sch) = schema.get("else") { - evaluated.extend(self.validate_node(else_sch, instance, ctx.clone(), is_lax, false, false)); - } - } - evaluated - } - - fn check_unevaluated(&mut self, schema: &Map, instance: &Value, evaluated: &HashSet, ctx: &ValidationContext, is_lax: bool, skip_strict: bool) { - if let Value::Object(obj) = instance { - if let Some(Value::Bool(false)) = schema.get("additionalProperties") { - for key in obj.keys() { - let in_props = schema.get("properties").and_then(|p| p.as_object()).map_or(false, |p| p.contains_key(key)); - let in_pattern = schema.get("patternProperties").and_then(|p| p.as_object()).map_or(false, |pp| pp.keys().any(|k| regex::Regex::new(k).map(|re| re.is_match(key)).unwrap_or(false))); - if !in_props && !in_pattern { - if ctx.overrides.contains(key) { continue; } - self.add_error("ADDITIONAL_PROPERTIES_NOT_ALLOWED", format!("Property '{}' is not allowed", key), &Value::Null, json!({ "got": [key] }), &ctx.append_path(key)); - } - } - } - - let explicit_opts = schema.contains_key("unevaluatedProperties") || schema.contains_key("additionalProperties"); - let should_check_strict = self.options.be_strict && !is_lax && !explicit_opts && !skip_strict; - let check_unevaluated = matches!(schema.get("unevaluatedProperties"), Some(Value::Bool(false))); - if should_check_strict || check_unevaluated { - for key in obj.keys() { - if !evaluated.contains(key) { - if ctx.overrides.contains(key) { continue; } - self.add_error("ADDITIONAL_PROPERTIES_NOT_ALLOWED", format!("Property '{}' is not allowed (strict/unevaluated)", key), &Value::Null, json!({ "got": [key] }), &ctx.append_path(key)); - } - } - } - } - } - - fn check_type(&self, expected: &Value, instance: &Value) -> bool { - match expected { - Value::String(s) => self.is_primitive_type(s, instance), - Value::Array(arr) => arr.iter().filter_map(|v| v.as_str()).any(|pt| self.is_primitive_type(pt, instance)), - _ => false - } - } - - fn is_primitive_type(&self, pt: &str, instance: &Value) -> bool { - match pt { - "string" => instance.is_string(), - "number" => instance.is_number(), - "integer" => is_integer(instance), - "boolean" => instance.is_boolean(), - "array" => instance.is_array(), - "object" => instance.is_object(), - "null" => instance.is_null(), - _ => false - } - } - - fn branch(&self) -> Self { - Self { options: self.options, root_schema_id: self.root_schema_id.clone(), errors: Vec::new(), max_depth: self.max_depth, _phantom: std::marker::PhantomData } - } - - fn add_error(&mut self, code: &str, message: String, context: &Value, cause: Value, ctx: &ValidationContext) { - let path = ctx.current_path.clone(); - if self.errors.iter().any(|e| e.code == code && e.path == path) { return; } - self.errors.push(ValidationError { code: code.to_string(), message, path, context: context.clone(), cause, schema_id: self.root_schema_id.clone() }); - } - - fn extend_unique(&mut self, errors: Vec) { - for e in errors { if !self.errors.iter().any(|existing| existing.code == e.code && existing.path == e.path) { self.errors.push(e); } } - } -} - -fn value_type_name(v: &Value) -> &'static str { - match v { - Value::Null => "null", - Value::Bool(_) => "boolean", - Value::Number(n) => if n.is_i64() { "integer" } else { "number" }, - Value::String(_) => "string", - Value::Array(_) => "array", - Value::Object(_) => "object", - } -} diff --git a/old_tests/helpers.rs b/old_tests/helpers.rs deleted file mode 100755 index db108ac..0000000 --- a/old_tests/helpers.rs +++ /dev/null @@ -1,88 +0,0 @@ -use serde_json::Value; -use pgrx::JsonB; - -// Simple test helpers for cleaner test code -pub fn assert_success(result: &JsonB) { - let json = &result.0; - if !json.get("response").is_some() || json.get("errors").is_some() { - let pretty = serde_json::to_string_pretty(json).unwrap_or_else(|_| format!("{:?}", json)); - panic!("Expected success but got:\n{}", pretty); - } -} - -pub fn assert_failure(result: &JsonB) { - let json = &result.0; - if json.get("response").is_some() || !json.get("errors").is_some() { - let pretty = serde_json::to_string_pretty(json).unwrap_or_else(|_| format!("{:?}", json)); - panic!("Expected failure but got:\n{}", pretty); - } -} - -pub fn assert_error_count(result: &JsonB, expected_count: usize) { - assert_failure(result); - let errors = get_errors(result); - if errors.len() != expected_count { - let pretty = serde_json::to_string_pretty(&result.0).unwrap_or_else(|_| format!("{:?}", result.0)); - panic!("Expected {} errors, got {}:\n{}", expected_count, errors.len(), pretty); - } -} - -pub fn get_errors(result: &JsonB) -> &Vec { - result.0["errors"].as_array().expect("errors should be an array") -} - -pub fn has_error_with_code(result: &JsonB, code: &str) -> bool { - get_errors(result).iter().any(|e| e["code"] == code) -} - - -pub fn has_error_with_code_and_path(result: &JsonB, code: &str, path: &str) -> bool { - get_errors(result).iter().any(|e| e["code"] == code && e["details"]["path"] == path) -} - -pub fn assert_has_error(result: &JsonB, code: &str, path: &str) { - if !has_error_with_code_and_path(result, code, path) { - let pretty = serde_json::to_string_pretty(&result.0).unwrap_or_else(|_| format!("{:?}", result.0)); - panic!("Expected error with code='{}' and path='{}' but not found:\n{}", code, path, pretty); - } -} - -pub fn find_error_with_code<'a>(result: &'a JsonB, code: &str) -> &'a Value { - get_errors(result).iter().find(|e| e["code"] == code) - .unwrap_or_else(|| panic!("No error found with code '{}'", code)) -} - - -pub fn find_error_with_code_and_path<'a>(result: &'a JsonB, code: &str, path: &str) -> &'a Value { - get_errors(result).iter().find(|e| e["code"] == code && e["details"]["path"] == path) - .unwrap_or_else(|| panic!("No error found with code '{}' and path '{}'", code, path)) -} - -pub fn assert_error_detail(error: &Value, detail_key: &str, expected_value: &str) { - let actual = error["details"][detail_key].as_str() - .unwrap_or_else(|| panic!("Error detail '{}' is not a string", detail_key)); - assert_eq!(actual, expected_value, "Error detail '{}' mismatch", detail_key); -} - - -// Additional convenience helpers for common patterns - -pub fn assert_error_message_contains(error: &Value, substring: &str) { - let message = error["message"].as_str().expect("error should have message"); - assert!(message.contains(substring), "Expected message to contain '{}', got '{}'", substring, message); -} - -pub fn assert_error_cause_json(error: &Value, expected_cause: &Value) { - let cause = &error["details"]["cause"]; - assert!(cause.is_object(), "cause should be JSON object"); - assert_eq!(cause, expected_cause, "cause mismatch"); -} - -pub fn assert_error_context(error: &Value, expected_context: &Value) { - assert_eq!(&error["details"]["context"], expected_context, "context mismatch"); -} - - -pub fn jsonb(val: Value) -> JsonB { - JsonB(val) -} \ No newline at end of file diff --git a/old_tests/schemas.rs b/old_tests/schemas.rs deleted file mode 100755 index 1e20562..0000000 --- a/old_tests/schemas.rs +++ /dev/null @@ -1,1128 +0,0 @@ -use crate::*; -use serde_json::{json, Value}; -use pgrx::JsonB; - -// Helper to convert Value to JsonB -fn jsonb(val: Value) -> JsonB { - JsonB(val) -} - -pub fn simple_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([{ - "name": "simple", - "public": false, - "schemas": [{ - "$id": "simple.request", - "type": "object", - "properties": { - "name": { "type": "string" }, - "age": { "type": "integer", "minimum": 0 } - }, - "required": ["name", "age"] - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn invalid_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([{ - "name": "invalid_punc", - "public": false, - "schemas": [{ - "$id": "invalid_punc.request", - "type": ["invalid_type_value"] - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn errors_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([{ - "name": "detailed_errors_test", - "public": false, - "schemas": [{ - "$id": "detailed_errors_test.request", - "type": "object", - "properties": { - "address": { - "type": "object", - "properties": { - "street": { "type": "string" }, - "city": { "type": "string", "maxLength": 10 } - }, - "required": ["street", "city"] - } - }, - "required": ["address"] - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn oneof_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([{ - "name": "oneof_test", - "public": false, - "schemas": [{ - "$id": "oneof_test.request", - "oneOf": [ - { - "type": "object", - "properties": { - "string_prop": { "type": "string", "maxLength": 5 } - }, - "required": ["string_prop"] - }, - { - "type": "object", - "properties": { - "number_prop": { "type": "number", "minimum": 10 } - }, - "required": ["number_prop"] - } - ] - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn root_types_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([ - { - "name": "object_test", - "public": false, - "schemas": [{ - "$id": "object_test.request", - "type": "object", - "properties": { - "name": { "type": "string" }, - "age": { "type": "integer", "minimum": 0 } - }, - "required": ["name", "age"] - }] - }, - { - "name": "array_test", - "public": false, - "schemas": [{ - "$id": "array_test.request", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string", "format": "uuid" } - } - } - }] - } - ]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn strict_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([ - { - "name": "basic_strict_test", - "public": true, - "schemas": [{ - "$id": "basic_strict_test.request", - "type": "object", - "properties": { - "name": { "type": "string" } - } - }] - }, - { - "name": "non_strict_test", - "public": false, - "schemas": [{ - "$id": "non_strict_test.request", - "type": "object", - "properties": { - "name": { "type": "string" } - } - }] - }, - { - "name": "nested_strict_test", - "public": true, - "schemas": [{ - "$id": "nested_strict_test.request", - "type": "object", - "properties": { - "user": { - "type": "object", - "properties": { - "name": { "type": "string" } - } - }, - "items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" } - } - } - } - } - }] - }, - { - "name": "already_unevaluated_test", - "public": true, - "schemas": [{ - "$id": "already_unevaluated_test.request", - "type": "object", - "properties": { - "name": { "type": "string" } - }, - "unevaluatedProperties": true - }] - }, - { - "name": "already_additional_test", - "public": true, - "schemas": [{ - "$id": "already_additional_test.request", - "type": "object", - "properties": { - "name": { "type": "string" } - }, - "additionalProperties": false - }] - }, - { - "name": "conditional_strict_test", - "public": true, - "schemas": [{ - "$id": "conditional_strict_test.request", - "type": "object", - "properties": { - "creating": { "type": "boolean" } - }, - "if": { - "properties": { - "creating": { "const": true } - } - }, - "then": { - "properties": { - "name": { "type": "string" } - }, - "required": ["name"] - } - }] - } - ]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn required_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([{ - "name": "basic_validation_test", - "public": false, - "schemas": [{ - "$id": "basic_validation_test.request", - "type": "object", - "properties": { - "name": { "type": "string" }, - "age": { "type": "integer", "minimum": 0 } - }, - "required": ["name", "age"] - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn dependencies_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([{ - "name": "dependency_split_test", - "public": false, - "schemas": [{ - "$id": "dependency_split_test.request", - "type": "object", - "properties": { - "creating": { "type": "boolean" }, - "name": { "type": "string" }, - "kind": { "type": "string" }, - "description": { "type": "string" } - }, - "dependencies": { - "creating": ["name", "kind"] - } - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn nested_req_deps_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([{ - "name": "nested_dep_test", - "public": false, - "schemas": [{ - "$id": "nested_dep_test.request", - "type": "object", - "properties": { - "items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { "type": "string" }, - "creating": { "type": "boolean" }, - "name": { "type": "string" }, - "kind": { "type": "string" } - }, - "required": ["id"], - "dependencies": { - "creating": ["name", "kind"] - } - } - } - }, - "required": ["items"] - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn additional_properties_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([ - { - "name": "additional_props_test", - "public": false, - "schemas": [{ - "$id": "additional_props_test.request", - "type": "object", - "properties": { - "name": { "type": "string" }, - "age": { "type": "number" } - }, - "additionalProperties": false - }] - }, - { - "name": "nested_additional_props_test", - "public": false, - "schemas": [{ - "$id": "nested_additional_props_test.request", - "type": "object", - "properties": { - "user": { - "type": "object", - "properties": { - "name": { "type": "string" } - }, - "additionalProperties": false - } - } - }] - } - ]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn unevaluated_properties_schemas() -> JsonB { - let enums = json!([]); - let types = json!([{ - "name": "nested_for_uneval", - "schemas": [{ - "$id": "nested_for_uneval", - "type": "object", - "properties": { - "deep_prop": { "type": "string" } - } - }] - }]); - let puncs = json!([ - { - "name": "simple_unevaluated_test", - "public": false, - "schemas": [{ - "$id": "simple_unevaluated_test.request", - "type": "object", - "properties": { - "name": { "type": "string" }, - "age": { "type": "number" } - }, - "patternProperties": { - "^attr_": { "type": "string" } - }, - "unevaluatedProperties": false - }] - }, - { - "name": "conditional_unevaluated_test", - "public": false, - "schemas": [{ - "$id": "conditional_unevaluated_test.request", - "type": "object", - "allOf": [ - { - "properties": { - "firstName": { "type": "string" } - } - }, - { - "properties": { - "lastName": { "type": "string" } - } - } - ], - "properties": { - "age": { "type": "number" } - }, - "unevaluatedProperties": false - }] - }, - { - "name": "nested_unevaluated_test", - "public": true, // To trigger strict mode - "schemas": [{ - "$id": "nested_unevaluated_test.request", - "type": "object", - "properties": { - "non_strict_branch": { - "type": "object", - "unevaluatedProperties": true, // The magic switch - "properties": { - "some_prop": { "$ref": "nested_for_uneval" } - } - }, - "strict_branch": { - "type": "object", - "properties": { - "another_prop": { "type": "string" } - } - } - } - }] - } - ]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn format_schemas() -> JsonB { - let enums = json!([]); - let types = json!([]); - let puncs = json!([{ - "name": "format_test", - "public": false, - "schemas": [{ - "$id": "format_test.request", - "type": "object", - "properties": { - "uuid": { "type": "string", "format": "uuid" }, - "date_time": { "type": "string", "format": "date-time" }, - "email": { "type": "string", "format": "email" } - } - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn property_merging_schemas() -> JsonB { - let enums = json!([]); - let types = json!([ - { - "name": "entity", - "schemas": [{ - "$id": "entity", - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "type": { "type": "string", "const": "entity" } - }, - "required": ["id"] - }] - }, - { - "name": "user", - "schemas": [{ - "$id": "user", - "$ref": "entity", - "properties": { - "type": { "type": "string", "const": "user", "override": true }, - "password": { "type": "string", "minLength": 8 } - }, - "required": ["password"] - }] - }, - { - "name": "person", - "schemas": [{ - "$id": "person", - "$ref": "user", - "properties": { - "type": { "type": "string", "const": "person", "override": true }, - "first_name": { "type": "string", "minLength": 1 }, - "last_name": { "type": "string", "minLength": 1 } - }, - "required": ["first_name", "last_name"] - }] - } - ]); - - let puncs = json!([]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn required_merging_schemas() -> JsonB { - let enums = json!([]); - - let types = json!([ - { - "name": "entity", - "schemas": [{ - "$id": "entity", - "type": "object", - "properties": { - "id": { "type": "string", "format": "uuid" }, - "type": { "type": "string" }, - "created_by": { "type": "string", "format": "uuid" } - }, - "required": ["id", "type", "created_by"] - }] - }, - { - "name": "user", - "schemas": [{ - "$id": "user", - "$ref": "entity", - "properties": { - "password": { "type": "string", "minLength": 8 } - }, - "if": { - "properties": { "type": { "const": "user" } } - }, - "then": { - "required": ["password"] - } - }] - }, - { - "name": "person", - "schemas": [{ - "$id": "person", - "$ref": "user", - "properties": { - "first_name": { "type": "string", "minLength": 1 }, - "last_name": { "type": "string", "minLength": 1 } - }, - "if": { - "properties": { "type": { "const": "person" } } - }, - "then": { - "required": ["first_name", "last_name"] - } - }] - } - ]); - - let puncs = json!([]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn dependencies_merging_schemas() -> JsonB { - let enums = json!([]); - - let types = json!([ - { - "name": "entity", - "schemas": [{ - "$id": "entity", - "type": "object", - "properties": { - "id": { "type": "string", "format": "uuid" }, - "type": { "type": "string" }, - "created_by": { "type": "string", "format": "uuid" }, - "creating": { "type": "boolean" }, - "name": { "type": "string" } - }, - "required": ["id", "type", "created_by"], - "dependencies": { - "creating": ["name"] - } - }] - }, - { - "name": "user", - "schemas": [{ - "$id": "user", - "$ref": "entity", - "properties": { - "password": { "type": "string", "minLength": 8 } - }, - "dependencies": { - "creating": ["name"] - } - }] - }, - { - "name": "person", - "schemas": [{ - "$id": "person", - "$ref": "user", - "properties": { - "first_name": { "type": "string", "minLength": 1 }, - "last_name": { "type": "string", "minLength": 1 } - }, - "dependencies": { - "creating": ["first_name", "last_name"] - } - }] - } - ]); - - let puncs = json!([]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn punc_with_refs_schemas() -> JsonB { - let enums = json!([]); - - let types = json!([ - { - "name": "entity", - "schemas": [{ - "$id": "entity", - "type": "object", - "properties": { - "id": { "type": "string" }, - "name": { "type": "string" }, - "type": { "type": "string" } - }, - "required": ["id", "type"] - }] - }, - { - "name": "person", - "schemas": [{ - "$id": "person", - "$ref": "entity", - "properties": { - "first_name": { "type": "string", "minLength": 1 }, - "last_name": { "type": "string", "minLength": 1 }, - "address": { - "type": "object", - "properties": { - "street": { "type": "string" }, - "city": { "type": "string" } - }, - "required": ["street", "city"] - } - } - }] - } - ]); - - let puncs = json!([ - { - "name": "public_ref_test", - "public": true, - "schemas": [{ - "$id": "public_ref_test.request", - "$ref": "person" - }] - }, - { - "name": "private_ref_test", - "public": false, - "schemas": [{ - "$id": "private_ref_test.request", - "$ref": "person" - }] - } - ]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn enum_schemas() -> JsonB { - let enums = json!([ - { - "name": "task_priority", - "values": ["low", "medium", "high", "urgent"], - "schemas": [{ - "$id": "task_priority", - "type": "string", - "enum": ["low", "medium", "high", "urgent"] - }] - } - ]); - - let types = json!([]); - - let puncs = json!([{ - "name": "enum_ref_test", - "public": false, - "schemas": [{ - "$id": "enum_ref_test.request", - "type": "object", - "properties": { - "priority": { "$ref": "task_priority" } - }, - "required": ["priority"] - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn punc_local_refs_schemas() -> JsonB { - let enums = json!([]); - - let types = json!([ - { - "name": "global_thing", - "schemas": [{ - "$id": "global_thing", - "type": "object", - "properties": { - "id": { "type": "string", "format": "uuid" }, - "type": { "type": "string" } - }, - "required": ["id", "type"] - }] - } - ]); - - let puncs = json!([ - { - "name": "punc_with_local_ref_test", - "public": false, - "schemas": [ - { - "$id": "local_address", - "type": "object", - "properties": { - "street": { "type": "string" }, - "city": { "type": "string" } - }, - "required": ["street", "city"] - }, - { - "$id": "punc_with_local_ref_test.request", - "$ref": "local_address" - } - ] - }, - { - "name": "punc_with_local_ref_to_global_test", - "public": false, - "schemas": [ - { - "$id": "local_user_with_thing", - "type": "object", - "properties": { - "user_name": { "type": "string" }, - "thing": { "$ref": "global_thing" } - }, - "required": ["user_name", "thing"] - }, - { - "$id": "punc_with_local_ref_to_global_test.request", - "$ref": "local_user_with_thing" - } - ] - } - ]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn title_override_schemas() -> JsonB { - let enums = json!([]); - - let types = json!([ - { - "name": "base_with_title", - "schemas": [{ - "$id": "base_with_title", - "type": "object", - "title": "Base Title", - "properties": { - "name": { "type": "string" }, - "type": { "type": "string" } - }, - "required": ["name"] - }] - }, - { - "name": "override_with_title", - "schemas": [{ - "$id": "override_with_title", - "$ref": "base_with_title", - "title": "Override Title" - }] - } - ]); - - let puncs = json!([]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn format_with_ref_schemas() -> JsonB { - let enums = json!([]); - let types = json!([ - { - "name": "entity", - "schemas": [{ - "$id": "entity", - "type": "object", - "properties": { - "id": { "type": "string", "format": "uuid" }, - "type": { "type": "string" }, - "name": { "type": "string" } - }, - "required": ["id", "type"] - }] - }, - { - "name": "job", - "schemas": [{ - "$id": "job", - "$ref": "entity", - "properties": { - "worker_id": { "type": "string", "format": "uuid" } - } - }] - } - ]); - - let puncs = json!([{ - "name": "save_job", - "public": true, - "schemas": [ - { - "$id": "save_job.request", - "$ref": "job" - }, - { - "$id": "save_job.response", - "$ref": "job" - } - ] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn type_matching_schemas() -> JsonB { - let enums = json!([]); - let types = json!([ - { - "name": "entity", - "schemas": [{ - "$id": "entity", - "type": "object", - "properties": { - "type": { "type": "string", "const": "entity" }, - "name": { "type": "string" } - }, - "required": ["type", "name"] - }] - }, - { - "name": "job", - "schemas": [{ - "$id": "job", - "$ref": "entity", - "properties": { - "type": { "type": "string", "const": "job", "override": true }, - "job_id": { "type": "string" } - }, - "required": ["job_id"] - }] - }, - { - "name": "super_job", - "schemas": [ - { - "$id": "super_job", - "$ref": "job", - "properties": { - "type": { "type": "string", "const": "super_job", "override": true }, - "manager_id": { "type": "string" } - }, - "required": ["manager_id"] - }, - { - "$id": "super_job.short", - "$ref": "super_job", - "properties": { "name": { "maxLength": 10 } } - } - ] - } - ]); - let puncs = json!([{ - "name": "type_test_punc", - "public": false, - "schemas": [{ - "$id": "type_test_punc.request", - "type": "object", - "properties": { - "root_job": { "$ref": "job" }, - "nested_or_super_job": { - "oneOf": [ - { "$ref": "super_job" }, - { - "type": "object", - "properties": { - "my_job": { "$ref": "job" } - }, - "required": ["my_job"] - } - ] - } - }, - "required": ["root_job", "nested_or_super_job"] - }] - }]); - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn union_schemas() -> JsonB { - let enums = json!([]); - let types = json!([ - { - "name": "union_base", - "schemas": [{ - "$id": "union_base", - "type": "object", - "properties": { - "type": { "type": "string", "const": "union_base" }, - "id": { "type": "string" } - }, - "required": ["type", "id"] - }] - }, - { - "name": "union_a", - "schemas": [{ - "$id": "union_a", - "$ref": "union_base", - "properties": { - "type": { "type": "string", "const": "union_a", "override": true }, - "prop_a": { "type": "string" } - }, - "required": ["prop_a"] - }] - }, - { - "name": "union_b", - "schemas": [{ - "$id": "union_b", - "$ref": "union_base", - "properties": { - "type": { "type": "string", "const": "union_b", "override": true }, - "prop_b": { "type": "number" } - }, - "required": ["prop_b"] - }] - }, - { - "name": "union_c", - "schemas": [{ - "$id": "union_c", - "$ref": "union_base", - "properties": { - "type": { "type": "string", "const": "union_c", "override": true }, - "prop_c": { "type": "boolean" } - }, - "required": ["prop_c"] - }] - } - ]); - - let puncs = json!([{ - "name": "union_test", - "public": true, - "schemas": [{ - "$id": "union_test.request", - "type": "object", - "properties": { - "union_prop": { - "oneOf": [ - { "$ref": "union_a" }, - { "$ref": "union_b" }, - { "$ref": "union_c" } - ] - } - }, - "required": ["union_prop"] - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn nullable_union_schemas() -> JsonB { - let enums = json!([]); - let types = json!([ - { - "name": "thing_base", - "schemas": [{ - "$id": "thing_base", - "type": "object", - "properties": { - "type": { "type": "string", "const": "thing_base" }, - "id": { "type": "string" } - }, - "required": ["type", "id"] - }] - }, - { - "name": "thing_a", - "schemas": [{ - "$id": "thing_a", - "$ref": "thing_base", - "properties": { - "type": { "type": "string", "const": "thing_a", "override": true }, - "prop_a": { "type": "string" } - }, - "required": ["prop_a"] - }] - }, - { - "name": "thing_b", - "schemas": [{ - "$id": "thing_b", - "$ref": "thing_base", - "properties": { - "type": { "type": "string", "const": "thing_b", "override": true }, - "prop_b": { "type": "string" } - }, - "required": ["prop_b"] - }] - } - ]); - - let puncs = json!([{ - "name": "nullable_union_test", - "public": true, - "schemas": [{ - "$id": "nullable_union_test.request", - "type": "object", - "properties": { - "nullable_prop": { - "oneOf": [ - { "$ref": "thing_a" }, - { "$ref": "thing_b" }, - { "type": "null" } - ] - } - }, - "required": ["nullable_prop"] - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} - -pub fn hierarchy_schemas() -> JsonB { - let enums = json!([]); - let types = json!([ - { - "name": "entity", - "hierarchy": ["entity"], - "schemas": [{ - "$id": "entity", - "type": "object", - "properties": { - "id": { "type": "string" }, - "type": { "$ref": "entity.family", "override": true } - }, - "required": ["id", "type"] - }] - }, - { - "name": "organization", - "hierarchy": ["entity", "organization"], - "schemas": [{ - "$id": "organization", - "$ref": "entity", - "properties": { - "type": { "$ref": "organization.family", "override": true }, - "name": { "type": "string" } - }, - "required": ["name"] - }] - }, - { - "name": "user", - "hierarchy": ["entity", "organization", "user"], - "schemas": [{ - "$id": "user", - "$ref": "organization", - "properties": { - "type": { "$ref": "user.family", "override": true }, - "password": { "type": "string" } - }, - "required": ["password"] - }] - }, - { - "name": "person", - "hierarchy": ["entity", "organization", "user", "person"], - "schemas": [{ - "$id": "person", - "$ref": "user", - "properties": { - "type": { "$ref": "person.family", "override": true }, - "first_name": { "type": "string" } - }, - "required": ["first_name"] - }] - } - ]); - - let puncs = json!([{ - "name": "test_org_punc", - "public": false, - "schemas": [{ - "$id": "test_org_punc.request", - "$ref": "organization" - }] - }]); - - cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs)) -} diff --git a/old_tests/tests.rs b/old_tests/tests.rs deleted file mode 100755 index 746a4b2..0000000 --- a/old_tests/tests.rs +++ /dev/null @@ -1,1089 +0,0 @@ -use crate::*; -use crate::helpers::*; -use crate::schemas::*; -use serde_json::json; -use pgrx::pg_test; - -#[pg_test] -fn test_validate_not_cached() { - clear_json_schemas(); - let instance = json!({ "foo": "bar" }); - let result = validate_json_schema("non_existent_schema", jsonb(instance)); - assert_error_count(&result, 1); - let error = find_error_with_code(&result, "SCHEMA_NOT_FOUND"); - assert_error_message_contains(error, "Schema 'non_existent_schema' not found"); -} - -#[pg_test] -fn test_validate_simple() { - // Use specific schema setup for this test - let cache_result = simple_schemas(); - assert_success(&cache_result); - - // Test the basic validation schema - let valid_instance = json!({ "name": "Alice", "age": 30 }); - let invalid_instance_type = json!({ "name": "Bob", "age": -5 }); - let invalid_instance_missing = json!({ "name": "Charlie" }); - - let valid_result = validate_json_schema("simple.request", jsonb(valid_instance)); - assert_success(&valid_result); - - // Invalid type - age is negative - let invalid_result_type = validate_json_schema("simple.request", jsonb(invalid_instance_type)); - assert_error_count(&invalid_result_type, 1); - - let error = find_error_with_code_and_path(&invalid_result_type, "MINIMUM_VIOLATED", "/age"); - assert_error_detail(error, "schema", "simple.request"); - assert_error_context(error, &json!(-5)); - assert_error_cause_json(error, &json!({"got": -5, "want": 0})); - assert_error_message_contains(error, "Value must be at least 0, but got -5"); - - // Missing field - let invalid_result_missing = validate_json_schema("simple.request", jsonb(invalid_instance_missing)); - assert_error_count(&invalid_result_missing, 1); - - let missing_error = find_error_with_code_and_path(&invalid_result_missing, "REQUIRED_FIELD_MISSING", "/age"); - assert_error_detail(missing_error, "schema", "simple.request"); - assert_error_cause_json(missing_error, &json!({"want": ["age"]})); - assert_error_message_contains(missing_error, "Required field 'age' is missing"); -} - -#[pg_test] -fn test_cache_invalid() { - let cache_result = invalid_schemas(); - assert_error_count(&cache_result, 2); - assert!(has_error_with_code(&cache_result, "ENUM_VIOLATED"), - "Should have ENUM_VIOLATED errors"); -} - -#[pg_test] -fn test_validate_errors() { - let cache_result = errors_schemas(); - assert_success(&cache_result); - - let invalid_instance = json!({ - "address": { - "street": 123, // Wrong type - "city": "Supercalifragilisticexpialidocious" // Too long (maxLength: 10) - } - }); - - let result = validate_json_schema("detailed_errors_test.request", jsonb(invalid_instance)); - - // Expect 2 errors: one for type mismatch, one for maxLength violation - assert_error_count(&result, 2); - assert_has_error(&result, "TYPE_MISMATCH", "/address/street"); - assert_has_error(&result, "MAX_LENGTH_VIOLATED", "/address/city"); -} - -#[pg_test] -fn test_validate_oneof() { - let cache_result = oneof_schemas(); - assert_success(&cache_result); - - // --- Test case 1: Fails string maxLength (in branch 0) AND missing number_prop (in branch 1) --- - let invalid_string_instance = json!({ "string_prop": "toolongstring" }); - let result_invalid_string = validate_json_schema("oneof_test.request", jsonb(invalid_string_instance)); - assert_error_count(&result_invalid_string, 2); - assert_has_error(&result_invalid_string, "MAX_LENGTH_VIOLATED", "/string_prop"); - assert_has_error(&result_invalid_string, "REQUIRED_FIELD_MISSING", "/number_prop"); - - // --- Test case 2: Fails number minimum (in branch 1) AND missing string_prop (in branch 0) --- - let invalid_number_instance = json!({ "number_prop": 5 }); - let result_invalid_number = validate_json_schema("oneof_test.request", jsonb(invalid_number_instance)); - assert_error_count(&result_invalid_number, 2); - assert_has_error(&result_invalid_number, "MINIMUM_VIOLATED", "/number_prop"); - assert_has_error(&result_invalid_number, "REQUIRED_FIELD_MISSING", "/string_prop"); - - // --- Test case 3: Fails type check (not object) for both branches --- - // Input: boolean, expected object for both branches - let invalid_bool_instance = json!(true); // Not an object - let result_invalid_bool = validate_json_schema("oneof_test.request", jsonb(invalid_bool_instance)); - // Expect only 1 leaf error after filtering, as both original errors have instance_path "" - assert_error_count(&result_invalid_bool, 1); - let error = find_error_with_code_and_path(&result_invalid_bool, "TYPE_MISMATCH", ""); - assert_error_detail(error, "schema", "oneof_test.request"); - - // --- Test case 4: Fails missing required for both branches --- - // Input: empty object, expected string_prop (branch 0) OR number_prop (branch 1) - let invalid_empty_obj = json!({}); - let result_empty_obj = validate_json_schema("oneof_test.request", jsonb(invalid_empty_obj)); - // Now we expect 2 errors because required fields are split into individual errors - assert_error_count(&result_empty_obj, 2); - assert_has_error(&result_empty_obj, "REQUIRED_FIELD_MISSING", "/string_prop"); - assert_has_error(&result_empty_obj, "REQUIRED_FIELD_MISSING", "/number_prop"); -} - -#[pg_test] -fn test_validate_root_types() { - let cache_result = root_types_schemas(); - assert_success(&cache_result); - - // Test 1: Validate null against array schema (using array_test from comprehensive setup) - let null_instance = json!(null); - let null_result = validate_json_schema("array_test.request", jsonb(null_instance)); - assert_error_count(&null_result, 1); - let null_error = find_error_with_code_and_path(&null_result, "TYPE_MISMATCH", ""); - assert_error_detail(null_error, "schema", "array_test.request"); - assert_error_context(null_error, &json!(null)); - assert_error_cause_json(null_error, &json!({"got": "null", "want": ["array"]})); - assert_error_message_contains(null_error, "Expected array but got null"); - - // Test 2: Validate object against array schema - let object_instance = json!({"id": "not-an-array"}); - let object_result = validate_json_schema("array_test.request", jsonb(object_instance.clone())); - assert_error_count(&object_result, 1); - let object_error = find_error_with_code_and_path(&object_result, "TYPE_MISMATCH", ""); - assert_error_detail(object_error, "schema", "array_test.request"); - assert_error_context(object_error, &object_instance); - assert_error_cause_json(object_error, &json!({"got": "object", "want": ["array"]})); - assert_error_message_contains(object_error, "Expected array but got object"); - - // Test 3: Valid empty array - let valid_empty = json!([]); - let valid_result = validate_json_schema("array_test.request", jsonb(valid_empty)); - assert_success(&valid_result); - - // Test 4: String at root when object expected (using object_test) - let string_instance = json!("not an object"); - let string_result = validate_json_schema("object_test.request", jsonb(string_instance)); - assert_error_count(&string_result, 1); - let string_error = find_error_with_code_and_path(&string_result, "TYPE_MISMATCH", ""); - assert_error_detail(string_error, "schema", "object_test.request"); - assert_error_context(string_error, &json!("not an object")); - assert_error_cause_json(string_error, &json!({"got": "string", "want": ["object"]})); - assert_error_message_contains(string_error, "Expected object but got string"); -} - -#[pg_test] -fn test_validate_strict() { - let cache_result = strict_schemas(); - assert_success(&cache_result); - - // Test 1: Basic strict validation - extra properties should fail - let valid_basic = json!({ "name": "John" }); - let invalid_basic = json!({ "name": "John", "extra": "not allowed" }); - - let result_basic_valid = validate_json_schema("basic_strict_test.request", jsonb(valid_basic)); - assert_success(&result_basic_valid); - - let result_basic_invalid = validate_json_schema("basic_strict_test.request", jsonb(invalid_basic.clone())); - assert_error_count(&result_basic_invalid, 1); - assert_has_error(&result_basic_invalid, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra"); - - // Test 2: Non-strict validation - extra properties should pass - let result_non_strict = validate_json_schema("non_strict_test.request", jsonb(invalid_basic.clone())); - assert_success(&result_non_strict); - - // Test 3: Nested objects and arrays - test recursive strict validation - let valid_nested = json!({ - "user": { "name": "Alice" }, - "items": [{ "id": "123" }] - }); - let invalid_nested = json!({ - "user": { "name": "Alice", "extra": "not allowed" }, // Extra in nested object - "items": [{ "id": "123", "extra": "not allowed" }] // Extra in array item - }); - - let result_nested_valid = validate_json_schema("nested_strict_test.request", jsonb(valid_nested)); - assert_success(&result_nested_valid); - - let result_nested_invalid = validate_json_schema("nested_strict_test.request", jsonb(invalid_nested)); - assert_error_count(&result_nested_invalid, 2); - assert_has_error(&result_nested_invalid, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/user/extra"); - assert_has_error(&result_nested_invalid, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/items/0/extra"); - - // Test 4: Schema with unevaluatedProperties already set - should allow extras - let result_already_unevaluated = validate_json_schema("already_unevaluated_test.request", jsonb(invalid_basic.clone())); - assert_success(&result_already_unevaluated); - - // Test 5: Schema with additionalProperties already set - should follow that setting - let result_already_additional = validate_json_schema("already_additional_test.request", jsonb(invalid_basic)); - assert_error_count(&result_already_additional, 1); - assert_has_error(&result_already_additional, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra"); - - // Test 6: Conditional schemas - properties in if/then/else should not be restricted - let valid_conditional = json!({ - "creating": true, - "name": "Test" // Required when creating=true - }); - let invalid_conditional = json!({ - "creating": true, - "name": "Test", - "extra": "not allowed" // Extra property at root level - }); - - let result_conditional_valid = validate_json_schema("conditional_strict_test.request", jsonb(valid_conditional)); - assert_success(&result_conditional_valid); - - let result_conditional_invalid = validate_json_schema("conditional_strict_test.request", jsonb(invalid_conditional)); - assert_error_count(&result_conditional_invalid, 1); - assert_has_error(&result_conditional_invalid, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra"); -} - -#[pg_test] -fn test_validate_required() { - let cache_result = required_schemas(); - assert_success(&cache_result); - - // Test 1: Missing all required fields (using basic_validation_test which requires name and age) - let empty_instance = json!({}); - let result = validate_json_schema("basic_validation_test.request", jsonb(empty_instance)); - - // Should get 2 separate errors, one for each missing field - assert_error_count(&result, 2); - - let name_error = find_error_with_code_and_path(&result, "REQUIRED_FIELD_MISSING", "/name"); - assert_error_message_contains(name_error, "Required field 'name' is missing"); - - let age_error = find_error_with_code_and_path(&result, "REQUIRED_FIELD_MISSING", "/age"); - assert_error_message_contains(age_error, "Required field 'age' is missing"); - - // Test 2: Missing only some required fields - let partial_instance = json!({ - "name": "Alice" - }); - let partial_result = validate_json_schema("basic_validation_test.request", jsonb(partial_instance)); - - // Should get 1 error for the missing field - assert_error_count(&partial_result, 1); - assert_has_error(&partial_result, "REQUIRED_FIELD_MISSING", "/age"); -} - -#[pg_test] -fn test_validate_dependencies() { - let cache_result = dependencies_schemas(); - assert_success(&cache_result); - - // Test 1: Has creating=true but missing both dependent fields - let missing_both = json!({ - "creating": true, - "description": "Some description" - }); - let result = validate_json_schema("dependency_split_test.request", jsonb(missing_both)); - - // Should get 2 separate errors, one for each missing dependent field - assert_error_count(&result, 2); - - let name_dep_error = find_error_with_code_and_path(&result, "DEPENDENCY_FAILED", "/name"); - assert_error_message_contains(name_dep_error, "Field 'name' is required when 'creating' is present"); - - let kind_dep_error = find_error_with_code_and_path(&result, "DEPENDENCY_FAILED", "/kind"); - assert_error_message_contains(kind_dep_error, "Field 'kind' is required when 'creating' is present"); - - // Test 2: Has creating=true with only one dependent field - let missing_one = json!({ - "creating": true, - "name": "My Account" - }); - let result_one = validate_json_schema("dependency_split_test.request", jsonb(missing_one)); - - // Should get 1 error for the missing kind field - assert_error_count(&result_one, 1); - let kind_error = find_error_with_code_and_path(&result_one, "DEPENDENCY_FAILED", "/kind"); - assert_error_message_contains(kind_error, "Field 'kind' is required when 'creating' is present"); - - // Test 3: Has no creating field - no dependency errors - let no_creating = json!({ - "description": "No creating field" - }); - let result_no_creating = validate_json_schema("dependency_split_test.request", jsonb(no_creating)); - assert_success(&result_no_creating); - - // Test 4: Has creating=false - dependencies still apply because field exists! - let creating_false = json!({ - "creating": false, - "description": "Creating is false" - }); - let result_false = validate_json_schema("dependency_split_test.request", jsonb(creating_false)); - // Dependencies are triggered by field existence, not value, so this should fail - assert_error_count(&result_false, 2); - assert_has_error(&result_false, "DEPENDENCY_FAILED", "/name"); - assert_has_error(&result_false, "DEPENDENCY_FAILED", "/kind"); -} - -#[pg_test] -fn test_validate_nested_req_deps() { - let cache_result = nested_req_deps_schemas(); - assert_success(&cache_result); - - // Test with array items that have dependency violations - let instance = json!({ - "items": [ - { - "id": "item1", - "creating": true - // Missing name and kind - }, - { - "id": "item2", - "creating": true, - "name": "Item 2" - // Missing kind - } - ] - }); - - let result = validate_json_schema("nested_dep_test.request", jsonb(instance)); - - // Should get 3 errors total: 2 for first item, 1 for second item - assert_error_count(&result, 3); - - // Check paths are correct for array items - assert_has_error(&result, "DEPENDENCY_FAILED", "/items/0/name"); - assert_has_error(&result, "DEPENDENCY_FAILED", "/items/0/kind"); - assert_has_error(&result, "DEPENDENCY_FAILED", "/items/1/kind"); -} - -#[pg_test] -fn test_validate_additional_properties() { - let cache_result = additional_properties_schemas(); - assert_success(&cache_result); - - // Test 1: Multiple additional properties not allowed - let instance_many_extras = json!({ - "name": "Alice", - "age": 30, - "extra1": "not allowed", - "extra2": 42, - "extra3": true - }); - - let result = validate_json_schema("additional_props_test.request", jsonb(instance_many_extras)); - - // Should get 3 separate errors, one for each additional property - assert_error_count(&result, 3); - - let extra1_error = find_error_with_code_and_path(&result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra1"); - assert_error_message_contains(extra1_error, "Property 'extra1' is not allowed"); - - let extra2_error = find_error_with_code_and_path(&result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra2"); - assert_error_message_contains(extra2_error, "Property 'extra2' is not allowed"); - - let extra3_error = find_error_with_code_and_path(&result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra3"); - assert_error_message_contains(extra3_error, "Property 'extra3' is not allowed"); - - // Test 2: Single additional property - let instance_one_extra = json!({ - "name": "Bob", - "age": 25, - "unauthorized": "field" - }); - - let result_one = validate_json_schema("additional_props_test.request", jsonb(instance_one_extra)); - - // Should get 1 error for the additional property - assert_error_count(&result_one, 1); - let unauthorized_error = find_error_with_code_and_path(&result_one, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/unauthorized"); - assert_error_message_contains(unauthorized_error, "Property 'unauthorized' is not allowed"); - - // Test 3: Nested objects with additional properties (already in comprehensive setup) - - let nested_instance = json!({ - "user": { - "name": "Charlie", - "role": "admin", - "level": 5 - } - }); - - let nested_result = validate_json_schema("nested_additional_props_test.request", jsonb(nested_instance)); - - // Should get 2 errors for the nested additional properties - assert_error_count(&nested_result, 2); - assert_has_error(&nested_result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/user/role"); - assert_has_error(&nested_result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/user/level"); -} - -#[pg_test] -fn test_validate_unevaluated_properties() { - let cache_result = unevaluated_properties_schemas(); - assert_success(&cache_result); - - // Test 1: Multiple unevaluated properties - let instance_uneval = json!({ - "name": "Alice", - "age": 30, - "attr_color": "blue", // This is OK - matches pattern - "extra1": "not evaluated", // These should fail - "extra2": 42, - "extra3": true - }); - - let result = validate_json_schema("simple_unevaluated_test.request", jsonb(instance_uneval)); - - // Should get 3 separate ADDITIONAL_PROPERTIES_NOT_ALLOWED errors, one for each unevaluated property - assert_error_count(&result, 3); - - // Verify all errors are ADDITIONAL_PROPERTIES_NOT_ALLOWED and check paths - assert_has_error(&result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra1"); - assert_has_error(&result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra2"); - assert_has_error(&result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra3"); - - // Verify error messages - let extra1_error = find_error_with_code_and_path(&result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra1"); - assert_error_message_contains(extra1_error, "Property 'extra1' is not allowed"); - - // Test 2: Complex schema with allOf and unevaluatedProperties (already in comprehensive setup) - - // firstName and lastName are evaluated by allOf schemas, age by main schema - let complex_instance = json!({ - "firstName": "John", - "lastName": "Doe", - "age": 25, - "nickname": "JD", // Not evaluated by any schema - "title": "Mr" // Not evaluated by any schema - }); - - let complex_result = validate_json_schema("conditional_unevaluated_test.request", jsonb(complex_instance)); - - // Should get 2 ADDITIONAL_PROPERTIES_NOT_ALLOWED errors for unevaluated properties - assert_error_count(&complex_result, 2); - assert_has_error(&complex_result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/nickname"); - assert_has_error(&complex_result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/title"); - - // Test 3: Valid instance with all properties evaluated - let valid_instance = json!({ - "name": "Bob", - "age": 40, - "attr_style": "modern", - "attr_theme": "dark" - }); - - let valid_result = validate_json_schema("simple_unevaluated_test.request", jsonb(valid_instance)); - assert_success(&valid_result); - - // Test 4: Test that unevaluatedProperties: true cascades down refs - let cascading_instance = json!({ - "strict_branch": { - "another_prop": "is_ok" - }, - "non_strict_branch": { - "extra_at_toplevel": "is_ok", // Extra property at this level - "some_prop": { - "deep_prop": "is_ok", - "extra_in_ref": "is_also_ok" // Extra property in the $ref'd schema - } - } - }); - let cascading_result = validate_json_schema("nested_unevaluated_test.request", jsonb(cascading_instance)); - assert_success(&cascading_result); - - // Test 5: For good measure, test that the strict branch is still strict - let strict_fail_instance = json!({ - "strict_branch": { - "another_prop": "is_ok", - "extra_in_strict": "is_not_ok" - } - }); - let strict_fail_result = validate_json_schema("nested_unevaluated_test.request", jsonb(strict_fail_instance)); - assert_error_count(&strict_fail_result, 1); - assert_has_error(&strict_fail_result, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/strict_branch/extra_in_strict"); -} - -#[pg_test] -fn test_validate_format_normal() { - let cache_result = format_schemas(); - assert_success(&cache_result); - - // A non-empty but invalid string should still fail - let instance = json!({ - "date_time": "not-a-date" - }); - - let result = validate_json_schema("format_test.request", jsonb(instance)); - assert_error_count(&result, 1); - let error = find_error_with_code(&result, "FORMAT_INVALID"); - assert_error_message_contains(error, "not-a-date"); -} - -#[pg_test] -fn test_validate_format_empty_string() { - let cache_result = format_schemas(); - assert_success(&cache_result); - - // Test with empty strings for all formatted fields - let instance = json!({ - "uuid": "", - "date_time": "", - "email": "" - }); - - let result = validate_json_schema("format_test.request", jsonb(instance)); - - // This is the test that should fail before the change and pass after - assert_success(&result); -} - -#[pg_test] -fn test_validate_format_empty_string_with_ref() { - let cache_result = format_with_ref_schemas(); - assert_success(&cache_result); - - // Test that an optional field with a format constraint passes validation - // when the value is an empty string, even when the schema is referenced by a punc. - let instance = json!({ - "id": "123e4567-e89b-12d3-a456-426614174000", - "type": "job", - "worker_id": "" // Optional field with format, but empty string - }); - - let result = validate_json_schema("save_job.request", jsonb(instance)); - - // This should succeed because empty strings are ignored for format validation. - assert_success(&result); -} - -#[pg_test] -fn test_validate_property_merging() { - let cache_result = property_merging_schemas(); - assert_success(&cache_result); - - // Test that person schema has all properties from the inheritance chain: - // entity (id, name) + user (password) + person (first_name, last_name) - - let valid_person_with_all_properties = json!({ - // From entity - "id": "550e8400-e29b-41d4-a716-446655440000", - "name": "John Doe", - "type": "person", - - // From user - "password": "securepass123", - - // From person - "first_name": "John", - "last_name": "Doe" - }); - - let result = validate_json_schema("person", jsonb(valid_person_with_all_properties)); - assert_success(&result); - - // Test that properties validate according to their schema definitions across the chain - let invalid_mixed_properties = json!({ - "id": "550e8400-e29b-41d4-a716-446655440000", - "name": "John Doe", - "type": "person", - "password": "short", // Too short from user schema - "first_name": "", // Empty string violates person schema minLength - "last_name": "Doe" - }); - - let result_invalid = validate_json_schema("person", jsonb(invalid_mixed_properties)); - assert_error_count(&result_invalid, 2); - assert_has_error(&result_invalid, "MIN_LENGTH_VIOLATED", "/password"); - assert_has_error(&result_invalid, "MIN_LENGTH_VIOLATED", "/first_name"); -} - -#[pg_test] -fn test_validate_required_merging() { - let cache_result = required_merging_schemas(); - assert_success(&cache_result); - - // Test that required fields are merged from inheritance chain: - // entity: ["id", "type", "created_by"] - // user: ["password"] (conditional when type=user) - // person: ["first_name", "last_name"] (conditional when type=person) - - let missing_all_required = json!({ "type": "person" }); - - let result = validate_json_schema("person", jsonb(missing_all_required)); - // Should fail for all required fields across inheritance chain - assert_error_count(&result, 4); // id, created_by, first_name, last_name - assert_has_error(&result, "REQUIRED_FIELD_MISSING", "/id"); - assert_has_error(&result, "REQUIRED_FIELD_MISSING", "/created_by"); - assert_has_error(&result, "REQUIRED_FIELD_MISSING", "/first_name"); - assert_has_error(&result, "REQUIRED_FIELD_MISSING", "/last_name"); - - // Test conditional requirements work through inheritance - let with_person_type = json!({ - "id": "550e8400-e29b-41d4-a716-446655440000", - "type": "person", - "created_by": "550e8400-e29b-41d4-a716-446655440001" - // Missing password (required when type=user, which person inherits from) - // Missing first_name, last_name (required when type=person) - }); - - let result_conditional = validate_json_schema("person", jsonb(with_person_type)); - assert_error_count(&result_conditional, 2); // first_name, last_name - assert_has_error(&result_conditional, "REQUIRED_FIELD_MISSING", "/first_name"); - assert_has_error(&result_conditional, "REQUIRED_FIELD_MISSING", "/last_name"); -} - -#[pg_test] -fn test_validate_dependencies_merging() { - let cache_result = dependencies_merging_schemas(); - assert_success(&cache_result); - - // Test dependencies are merged across inheritance: - // user: creating -> ["name"] - // person: creating -> ["first_name", "last_name"] - - let with_creating_missing_deps = json!({ - "id": "550e8400-e29b-41d4-a716-446655440000", - "type": "person", - "created_by": "550e8400-e29b-41d4-a716-446655440001", - "creating": true, - "password": "securepass" - // Missing name (from user dependency) - // Missing first_name, last_name (from person dependency) - }); - - let result = validate_json_schema("person", jsonb(with_creating_missing_deps)); - assert_error_count(&result, 3); // name, first_name, last_name - assert_has_error(&result, "DEPENDENCY_FAILED", "/name"); - assert_has_error(&result, "DEPENDENCY_FAILED", "/first_name"); - assert_has_error(&result, "DEPENDENCY_FAILED", "/last_name"); - - // Test partial dependency satisfaction - let with_some_deps = json!({ - "id": "550e8400-e29b-41d4-a716-446655440000", - "type": "person", - "created_by": "550e8400-e29b-41d4-a716-446655440001", - "creating": true, - "password": "securepass", - "name": "John Doe", - "first_name": "John" - // Missing last_name from person dependency - }); - - let result_partial = validate_json_schema("person", jsonb(with_some_deps)); - assert_error_count(&result_partial, 1); - assert_has_error(&result_partial, "DEPENDENCY_FAILED", "/last_name"); -} - -#[pg_test] -fn test_validate_punc_with_refs() { - let cache_result = punc_with_refs_schemas(); - assert_success(&cache_result); - - // Test 1: Public punc is strict - no extra properties allowed at root level - let public_root_extra = json!({ - "type": "person", - "id": "550e8400-e29b-41d4-a716-446655440000", - "name": "John Doe", - "first_name": "John", - "last_name": "Doe", - "extra_field": "not allowed at root", // Should fail in public punc - "another_extra": 123 // Should also fail in public punc - }); - - let result_public_root = validate_json_schema("public_ref_test.request", jsonb(public_root_extra)); - assert_error_count(&result_public_root, 2); - assert_has_error(&result_public_root, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/extra_field"); - assert_has_error(&result_public_root, "ADDITIONAL_PROPERTIES_NOT_ALLOWED", "/another_extra"); - - // Test 2: Private punc allows extra properties at root level - let private_root_extra = json!({ - "type": "person", - "id": "550e8400-e29b-41d4-a716-446655440000", - "name": "John Doe", - "first_name": "John", - "last_name": "Doe", - "extra_field": "allowed at root in private punc", // Should pass in private punc - "another_extra": 123 // Should also pass in private punc - }); - - let result_private_root = validate_json_schema("private_ref_test.request", jsonb(private_root_extra)); - assert_success(&result_private_root); // Should pass with extra properties at root - - // Test 3: Valid data with address should pass for both - let valid_data_with_address = json!({ - "type": "person", - "id": "550e8400-e29b-41d4-a716-446655440000", - "name": "John Doe", - "first_name": "John", - "last_name": "Doe", - "address": { - "street": "123 Main St", - "city": "Boston" - } - }); - - let result_public_valid = validate_json_schema("public_ref_test.request", jsonb(valid_data_with_address.clone())); - assert_success(&result_public_valid); - - let result_private_valid = validate_json_schema("private_ref_test.request", jsonb(valid_data_with_address)); - assert_success(&result_private_valid); -} - -#[pg_test] -fn test_validate_enum_schema() { - let cache_result = enum_schemas(); - assert_success(&cache_result); - - // Test valid enum value - let valid_priority = json!({ - "priority": "high" - }); - - let result = validate_json_schema("enum_ref_test.request", jsonb(valid_priority)); - assert_success(&result); - - // Test invalid enum value for priority (required field) - let invalid_priority = json!({ - "priority": "critical" // Invalid - not in task_priority enum - }); - - let result_priority = validate_json_schema("enum_ref_test.request", jsonb(invalid_priority)); - assert_error_count(&result_priority, 1); - assert_has_error(&result_priority, "ENUM_VIOLATED", "/priority"); - - // Test missing required enum field - let missing_priority = json!({}); - - let result_missing = validate_json_schema("enum_ref_test.request", jsonb(missing_priority)); - assert_error_count(&result_missing, 1); - assert_has_error(&result_missing, "REQUIRED_FIELD_MISSING", "/priority"); -} - -#[pg_test] -fn test_validate_punc_local_refs() { - let cache_result = punc_local_refs_schemas(); - assert_success(&cache_result); - - // Test 1: Punc request referencing a schema defined locally within the punc - let valid_local_ref = json!({ - "type": "local_address", - "street": "123 Main St", - "city": "Anytown" - }); - let result_valid_local = validate_json_schema("punc_with_local_ref_test.request", jsonb(valid_local_ref)); - assert_success(&result_valid_local); - - let invalid_local_ref = json!({ - "type": "local_address", - "street": "123 Main St" // Missing city - }); - let result_invalid_local = validate_json_schema("punc_with_local_ref_test.request", jsonb(invalid_local_ref)); - assert_error_count(&result_invalid_local, 1); - assert_has_error(&result_invalid_local, "REQUIRED_FIELD_MISSING", "/city"); - - // Test 2: Punc with a local schema that references a global type schema - let valid_global_ref = json!({ - "type": "local_user_with_thing", - "user_name": "Alice", - "thing": { - "type": "global_thing", - "id": "550e8400-e29b-41d4-a716-446655440000" - } - }); - let result_valid_global = validate_json_schema("punc_with_local_ref_to_global_test.request", jsonb(valid_global_ref)); - assert_success(&result_valid_global); - - let invalid_global_ref = json!({ - "type": "local_user_with_thing", - "user_name": "Bob", - "thing": { - "type": "global_thing", - "id": "not-a-uuid" // Invalid format for global_thing's id - } - }); - let result_invalid_global = validate_json_schema("punc_with_local_ref_to_global_test.request", jsonb(invalid_global_ref)); - assert_error_count(&result_invalid_global, 1); - assert_has_error(&result_invalid_global, "FORMAT_INVALID", "/thing/id"); -} - -#[pg_test] -fn test_validate_title_override() { - let cache_result = title_override_schemas(); - assert_success(&cache_result); - - // Test that a schema with an overridden title still inherits validation keywords correctly. - - // This instance is valid because it provides the 'name' required by the base schema. - let valid_instance = json!({ "type": "override_with_title", "name": "Test Name" }); - let result_valid = validate_json_schema("override_with_title", jsonb(valid_instance)); - assert_success(&result_valid); - - // This instance is invalid because it's missing the 'name' required by the base schema. - // This proves that validation keywords are inherited even when metadata keywords are overridden. - let invalid_instance = json!({ "type": "override_with_title" }); - let result_invalid = validate_json_schema("override_with_title", jsonb(invalid_instance)); - assert_error_count(&result_invalid, 1); - assert_has_error(&result_invalid, "REQUIRED_FIELD_MISSING", "/name"); -} - -#[pg_test] -fn test_validate_type_matching() { - let cache_result = type_matching_schemas(); - assert_success(&cache_result); - - // 1. Test 'job' which extends 'entity' - let valid_job = json!({ - "type": "job", - "name": "my job", - "job_id": "job123" - }); - let result_valid_job = validate_json_schema("job", jsonb(valid_job)); - assert_success(&result_valid_job); - - let invalid_job = json!({ - "type": "not_job", - "name": "my job", - "job_id": "job123" - }); - let result_invalid_job = validate_json_schema("job", jsonb(invalid_job)); - assert_failure(&result_invalid_job); - assert_has_error(&result_invalid_job, "CONST_VIOLATED", "/type"); - - // 2. Test 'super_job' which extends 'job' - let valid_super_job = json!({ - "type": "super_job", - "name": "my super job", - "job_id": "job123", - "manager_id": "mgr1" - }); - let result_valid_super_job = validate_json_schema("super_job", jsonb(valid_super_job)); - assert_success(&result_valid_super_job); - - // 3. Test 'super_job.short' which should still expect type 'super_job' - let valid_short_super_job = json!({ - "type": "super_job", - "name": "short", // maxLength: 10 - "job_id": "job123", - "manager_id": "mgr1" - }); - let result_valid_short = validate_json_schema("super_job.short", jsonb(valid_short_super_job)); - assert_success(&result_valid_short); - - let invalid_short_super_job = json!({ - "type": "job", // Should be 'super_job' - "name": "short", - "job_id": "job123", - "manager_id": "mgr1" - }); - let result_invalid_short = validate_json_schema("super_job.short", jsonb(invalid_short_super_job)); - assert_failure(&result_invalid_short); - assert_has_error(&result_invalid_short, "CONST_VIOLATED", "/type"); - - // 4. Test punc with root, nested, and oneOf type refs - let valid_punc_instance = json!({ - "root_job": { - "type": "job", - "name": "root job", - "job_id": "job456" - }, - "nested_or_super_job": { - "type": "super_job", - "name": "nested super job", - "job_id": "job789", - "manager_id": "mgr2" - } - }); - let result_valid_punc = validate_json_schema("type_test_punc.request", jsonb(valid_punc_instance)); - assert_success(&result_valid_punc); - - // 5. Test invalid type at punc root ref - let invalid_punc_root = json!({ - "root_job": { - "type": "entity", // Should be "job" - "name": "root job", - "job_id": "job456" - }, - "nested_or_super_job": { - "type": "super_job", - "name": "nested super job", - "job_id": "job789", - "manager_id": "mgr2" - } - }); - let result_invalid_punc_root = validate_json_schema("type_test_punc.request", jsonb(invalid_punc_root)); - assert_failure(&result_invalid_punc_root); - assert_has_error(&result_invalid_punc_root, "CONST_VIOLATED", "/root_job/type"); - - // 6. Test invalid type at punc nested ref - let invalid_punc_nested = json!({ - "root_job": { - "type": "job", - "name": "root job", - "job_id": "job456" - }, - "nested_or_super_job": { - "my_job": { - "type": "entity", // Should be "job" - "name": "nested job", - "job_id": "job789" - } - } - }); - let result_invalid_punc_nested = validate_json_schema("type_test_punc.request", jsonb(invalid_punc_nested)); - assert_failure(&result_invalid_punc_nested); - assert_has_error(&result_invalid_punc_nested, "CONST_VIOLATED", "/nested_or_super_job/my_job/type"); - - // 7. Test invalid type at punc oneOf ref - let invalid_punc_oneof = json!({ - "root_job": { - "type": "job", - "name": "root job", - "job_id": "job456" - }, - "nested_or_super_job": { - "type": "job", // Should be "super_job" - "name": "nested super job", - "job_id": "job789", - "manager_id": "mgr2" - } - }); - let result_invalid_punc_oneof = validate_json_schema("type_test_punc.request", jsonb(invalid_punc_oneof)); - assert_failure(&result_invalid_punc_oneof); - assert_has_error(&result_invalid_punc_oneof, "CONST_VIOLATED", "/nested_or_super_job/type"); -} - -#[pg_test] -fn test_validate_union_type_matching() { - let cache_result = union_schemas(); - assert_success(&cache_result); - - // 1. Test valid instance with type 'union_a' - let valid_instance_a = json!({ - "union_prop": { - "id": "123", - "type": "union_a", - "prop_a": "hello" - } - }); - let result_a = validate_json_schema("union_test.request", jsonb(valid_instance_a)); - assert_success(&result_a); - - // 2. Test valid instance with type 'union_b' - let valid_instance_b = json!({ - "union_prop": { - "id": "456", - "type": "union_b", - "prop_b": 123 - } - }); - let result_b = validate_json_schema("union_test.request", jsonb(valid_instance_b)); - assert_success(&result_b); - - // 3. Test invalid instance - wrong type const in a valid oneOf branch - let invalid_sub_schema = json!({ - "union_prop": { - "id": "789", - "type": "union_b", // Should be union_a - "prop_a": "hello" - } - }); - let result_invalid_sub = validate_json_schema("union_test.request", jsonb(invalid_sub_schema)); - assert_failure(&result_invalid_sub); - // This should fail because the `type` override in `union_a` is `const: "union_a"` - assert_has_error(&result_invalid_sub, "CONST_VIOLATED", "/union_prop/type"); - - // 4. Test invalid instance - base type, should fail due to override - let invalid_base_type = json!({ - "union_prop": { - "id": "101", - "type": "union_base", // This is the base type, but the override should be enforced - "prop_a": "world" - } - }); - let result_invalid_base = validate_json_schema("union_test.request", jsonb(invalid_base_type)); - assert_failure(&result_invalid_base); - assert_has_error(&result_invalid_base, "CONST_VIOLATED", "/union_prop/type"); -} - -#[pg_test] -fn test_validate_nullable_union() { - let cache_result = nullable_union_schemas(); - assert_success(&cache_result); - - // 1. Test valid instance with object type 'thing_a' - let valid_object_a = json!({ - "nullable_prop": { - "id": "123", - "type": "thing_a", - "prop_a": "hello" - } - }); - let result_obj_a = validate_json_schema("nullable_union_test.request", jsonb(valid_object_a)); - assert_success(&result_obj_a); - - // 2. Test valid instance with object type 'thing_b' - let valid_object_b = json!({ - "nullable_prop": { - "id": "456", - "type": "thing_b", - "prop_b": "goodbye" - } - }); - let result_obj_b = validate_json_schema("nullable_union_test.request", jsonb(valid_object_b)); - assert_success(&result_obj_b); - - // 3. Test valid instance with null - let valid_null = json!({ - "nullable_prop": null - }); - let result_null = validate_json_schema("nullable_union_test.request", jsonb(valid_null)); - assert_success(&result_null); - - // 4. Test invalid instance - base type, should fail due to override - let invalid_base_type = json!({ - "nullable_prop": { - "id": "789", - "type": "thing_base", - "prop_a": "should fail" - } - }); - let result_invalid_base = validate_json_schema("nullable_union_test.request", jsonb(invalid_base_type)); - assert_failure(&result_invalid_base); - assert_has_error(&result_invalid_base, "CONST_VIOLATED", "/nullable_prop/type"); - - // 5. Test invalid instance (e.g., a string) - let invalid_string = json!({ - "nullable_prop": "not_an_object_or_null" - }); - let result_invalid = validate_json_schema("nullable_union_test.request", jsonb(invalid_string)); - assert_failure(&result_invalid); - assert_has_error(&result_invalid, "TYPE_MISMATCH", "/nullable_prop"); -} - -#[pg_test] -fn test_validate_type_hierarchy() { - clear_json_schemas(); - let cache_result = hierarchy_schemas(); - assert_success(&cache_result); - - // 1. Test success case: validating a derived type (person) against a base schema (organization) - let person_instance = json!({ - "id": "person-id", - "type": "person", - "name": "person-name", - "password": "person-password", - "first_name": "person-first-name" - }); - let result_success = validate_json_schema("organization", jsonb(person_instance.clone())); - assert_success(&result_success); - - // 2. Test success case: validating a base type (organization) against its own schema - let org_instance = json!({ - "id": "org-id", - "type": "organization", - "name": "org-name" - }); - let result_org_success = validate_json_schema("organization", jsonb(org_instance)); - assert_success(&result_org_success); - - // 3. Test failure case: validating an ancestor type (entity) against a derived schema (organization) - let entity_instance = json!({ - "id": "entity-id", - "type": "entity" - }); - let result_fail_ancestor = validate_json_schema("organization", jsonb(entity_instance)); - assert_failure(&result_fail_ancestor); - assert_has_error(&result_fail_ancestor, "ENUM_VIOLATED", "/type"); - - // 4. Test failure case: validating a completely unrelated type - let unrelated_instance = json!({ - "id": "job-id", - "type": "job", - "name": "job-name" - }); - let result_fail_unrelated = validate_json_schema("organization", jsonb(unrelated_instance)); - assert_failure(&result_fail_unrelated); - assert_has_error(&result_fail_unrelated, "ENUM_VIOLATED", "/type"); - - // 5. Test that the punc using the schema also works - let punc_success = validate_json_schema("test_org_punc.request", jsonb(person_instance.clone())); - assert_success(&punc_success); -} diff --git a/puncs_6_fix.txt b/puncs_6_fix.txt deleted file mode 100644 index 5e07a61..0000000 --- a/puncs_6_fix.txt +++ /dev/null @@ -1,106 +0,0 @@ - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.39s - Running tests/tests.rs (target/debug/deps/tests-0f6b1e496850f0af) - -running 1 test -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"name", "job_id", "manager_id"} -DEBUG: validate_refs merging res from super_job. Keys: {"job_id", "name", "manager_id", "type"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"name", "manager_id", "job_id", "type"} -DEBUG: validate_object inserted 'nested_or_super_job' at /nested_or_super_job. Keys: {"name", "manager_id", "job_id", "type"} -DEBUG: check_strictness at /root_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /root_job/name. Keys: {} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /root_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /root_job/job_id. Keys: {"name"} -DEBUG: check_strictness at /root_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /root_job/type. Keys: {"job_id", "name"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"job_id", "type", "name"} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "type", "name"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name", "job_id", "type"} -DEBUG: validate_object inserted 'root_job' at /root_job. Keys: {"name", "manager_id", "job_id", "type", "nested_or_super_job"} -DEBUG: check_strictness at . Extensible: false. Keys: {"name", "manager_id", "job_id", "type", "nested_or_super_job", "root_job"} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"job_id", "name", "manager_id"} -DEBUG: validate_refs merging res from super_job. Keys: {"job_id", "name", "type", "manager_id"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"type", "job_id", "manager_id", "name"} -DEBUG: validate_object inserted 'nested_or_super_job' at /nested_or_super_job. Keys: {"job_id", "name", "manager_id", "type"} -DEBUG: check_strictness at /root_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /root_job/name. Keys: {} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /root_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /root_job/job_id. Keys: {"name"} -DEBUG: check_strictness at /root_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /root_job/type. Keys: {"name", "job_id"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name", "type", "job_id"} -DEBUG: validate_refs merging res from job. Keys: {"name", "type", "job_id"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"type", "name", "job_id"} -DEBUG: validate_object inserted 'root_job' at /root_job. Keys: {"job_id", "name", "manager_id", "type", "nested_or_super_job"} -DEBUG: check_strictness at . Extensible: false. Keys: {"root_job", "job_id", "name", "manager_id", "type", "nested_or_super_job"} -DEBUG: validate_refs merging res from entity. Keys: {} -DEBUG: validate_refs merging res from job. Keys: {} -DEBUG: validate_refs merging res from super_job. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/my_job/name. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/my_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/my_job/type. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name", "type"} -DEBUG: validate_refs merging res from job. Keys: {"name", "type"} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name", "type"} -DEBUG: validate_object inserted 'my_job' at /nested_or_super_job/my_job. Keys: {"type", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"job_id", "name", "manager_id"} -DEBUG: validate_refs merging res from super_job. Keys: {"job_id", "manager_id", "type", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("polymorphic_org_punc.request") ref=Some("organization.family") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("polymorphic_org_punc.request") ref=Some("organization.family") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("polymorphic_org_punc.request") ref=Some("organization.family") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("strict_org_punc.request") ref=Some("organization") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("strict_org_punc.request") ref=Some("organization") -DEBUG: check_strictness at . Extensible: false. Keys: {} - -thread 'test_puncs_6' (15118678) panicked at tests/tests.rs:150:44: -called `Result::unwrap()` on an `Err` value: "[complex punc type matching with oneOf and nested refs] Test 'valid person against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'first_name'\", details: ErrorDetails { path: \"/first_name\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against strict punc' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]" -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -test test_puncs_6 ... FAILED - -failures: - -failures: - test_puncs_6 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 338 filtered out; finished in 0.01s - -error: test failed, to rerun pass `--test tests` diff --git a/puncs_6_full.txt b/puncs_6_full.txt deleted file mode 100644 index 69bb707..0000000 --- a/puncs_6_full.txt +++ /dev/null @@ -1,103 +0,0 @@ - Blocking waiting for file lock on artifact directory - Compiling jspg v0.1.0 (/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg) - Finished `test` profile [unoptimized + debuginfo] target(s) in 7.63s - Running tests/tests.rs (target/debug/deps/tests-0f6b1e496850f0af) - -running 1 test -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"name", "job_id", "manager_id"} -DEBUG: validate_refs merging res from super_job. Keys: {"job_id", "manager_id", "type", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"manager_id", "type", "name", "job_id"} -DEBUG: validate_object inserted 'nested_or_super_job' at /nested_or_super_job. Keys: {"name", "job_id", "manager_id", "type"} -DEBUG: check_strictness at /root_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /root_job/name. Keys: {} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /root_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /root_job/job_id. Keys: {"name"} -DEBUG: check_strictness at /root_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /root_job/type. Keys: {"name", "job_id"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name", "job_id", "type"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id", "type"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"job_id", "type", "name"} -DEBUG: validate_object inserted 'root_job' at /root_job. Keys: {"name", "job_id", "nested_or_super_job", "manager_id", "type"} -DEBUG: check_strictness at . Extensible: false. Keys: {"root_job", "name", "job_id", "nested_or_super_job", "manager_id", "type"} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"job_id", "manager_id", "name"} -DEBUG: validate_refs merging res from super_job. Keys: {"type", "job_id", "manager_id", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"job_id", "manager_id", "type", "name"} -DEBUG: validate_object inserted 'nested_or_super_job' at /nested_or_super_job. Keys: {"name", "manager_id", "job_id", "type"} -DEBUG: check_strictness at /root_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /root_job/name. Keys: {} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /root_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /root_job/job_id. Keys: {"name"} -DEBUG: check_strictness at /root_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /root_job/type. Keys: {"name", "job_id"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name", "type", "job_id"} -DEBUG: validate_refs merging res from job. Keys: {"name", "type", "job_id"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"type", "job_id", "name"} -DEBUG: validate_object inserted 'root_job' at /root_job. Keys: {"name", "manager_id", "job_id", "type", "nested_or_super_job"} -DEBUG: check_strictness at . Extensible: false. Keys: {"name", "root_job", "manager_id", "job_id", "type", "nested_or_super_job"} -DEBUG: validate_refs merging res from entity. Keys: {} -DEBUG: validate_refs merging res from job. Keys: {} -DEBUG: validate_refs merging res from super_job. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/my_job/name. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/my_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/my_job/type. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name", "type"} -DEBUG: validate_refs merging res from job. Keys: {"name", "type"} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"type", "name"} -DEBUG: validate_object inserted 'my_job' at /nested_or_super_job/my_job. Keys: {"type", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"name", "job_id", "manager_id"} -DEBUG: validate_refs merging res from super_job. Keys: {"job_id", "manager_id", "name", "type"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: check_strictness at . Extensible: false. Keys: {} - -thread 'test_puncs_6' (15113120) panicked at tests/tests.rs:150:44: -called `Result::unwrap()` on an `Err` value: "[complex punc type matching with oneOf and nested refs] Test 'valid person against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'first_name'\", details: ErrorDetails { path: \"/first_name\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against strict punc' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]" -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -test test_puncs_6 ... FAILED - -failures: - -failures: - test_puncs_6 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 338 filtered out; finished in 0.01s - -error: test failed, to rerun pass `--test tests` diff --git a/puncs_6_output.txt b/puncs_6_output.txt deleted file mode 100644 index c38622e..0000000 --- a/puncs_6_output.txt +++ /dev/null @@ -1,57 +0,0 @@ - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.47s - Running tests/tests.rs (target/debug/deps/tests-0f6b1e496850f0af) - -running 1 test -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_refs merging res from super_job. Keys: {"job_id", "type", "manager_id", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"type", "name", "manager_id", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_refs merging res from super_job. Keys: {"manager_id", "type", "job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"manager_id", "job_id", "type", "name"} -DEBUG: validate_refs merging res from entity. Keys: {} -DEBUG: validate_refs merging res from job. Keys: {} -DEBUG: validate_refs merging res from super_job. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/my_job/name -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/my_job/type. Extensible: false. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"type", "name"} -DEBUG: validate_refs merging res from job. Keys: {"type", "name"} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name", "type"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_refs merging res from job. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_refs merging res from super_job. Keys: {"manager_id", "type", "name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} - -thread 'test_puncs_6' (15109801) panicked at tests/tests.rs:150:44: -called `Result::unwrap()` on an `Err` value: "[complex punc type matching with oneOf and nested refs] Test 'valid person against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'first_name'\", details: ErrorDetails { path: \"/first_name\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against strict punc' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]" -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -test test_puncs_6 ... FAILED - -failures: - -failures: - test_puncs_6 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 338 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--test tests` diff --git a/puncs_6_resolved.txt b/puncs_6_resolved.txt deleted file mode 100644 index d8916a3..0000000 --- a/puncs_6_resolved.txt +++ /dev/null @@ -1,106 +0,0 @@ - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.41s - Running tests/tests.rs (target/debug/deps/tests-0f6b1e496850f0af) - -running 1 test -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"name", "job_id", "manager_id"} -DEBUG: validate_refs merging res from super_job. Keys: {"name", "job_id", "manager_id", "type"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"name", "manager_id", "job_id", "type"} -DEBUG: validate_object inserted 'nested_or_super_job' at /nested_or_super_job. Keys: {"job_id", "manager_id", "type", "name"} -DEBUG: check_strictness at /root_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /root_job/name. Keys: {} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /root_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /root_job/job_id. Keys: {"name"} -DEBUG: check_strictness at /root_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /root_job/type. Keys: {"name", "job_id"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name", "job_id", "type"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id", "type"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"job_id", "type", "name"} -DEBUG: validate_object inserted 'root_job' at /root_job. Keys: {"job_id", "nested_or_super_job", "manager_id", "type", "name"} -DEBUG: check_strictness at . Extensible: false. Keys: {"job_id", "nested_or_super_job", "manager_id", "type", "name", "root_job"} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"manager_id", "name", "job_id"} -DEBUG: validate_refs merging res from super_job. Keys: {"manager_id", "name", "job_id", "type"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {"job_id", "manager_id", "type", "name"} -DEBUG: validate_object inserted 'nested_or_super_job' at /nested_or_super_job. Keys: {"type", "manager_id", "job_id", "name"} -DEBUG: check_strictness at /root_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /root_job/name. Keys: {} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /root_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /root_job/job_id. Keys: {"name"} -DEBUG: check_strictness at /root_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /root_job/type. Keys: {"name", "job_id"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"name", "type", "job_id"} -DEBUG: validate_refs merging res from job. Keys: {"name", "type", "job_id"} -DEBUG: check_strictness at /root_job. Extensible: false. Keys: {"type", "name", "job_id"} -DEBUG: validate_object inserted 'root_job' at /root_job. Keys: {"type", "manager_id", "job_id", "name", "nested_or_super_job"} -DEBUG: check_strictness at . Extensible: false. Keys: {"type", "root_job", "manager_id", "job_id", "name", "nested_or_super_job"} -DEBUG: validate_refs merging res from entity. Keys: {} -DEBUG: validate_refs merging res from job. Keys: {} -DEBUG: validate_refs merging res from super_job. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/my_job/name. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name"} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/my_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/my_job/type. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"type", "name"} -DEBUG: validate_refs merging res from job. Keys: {"type", "name"} -DEBUG: check_strictness at /nested_or_super_job/my_job. Extensible: false. Keys: {"name", "type"} -DEBUG: validate_object inserted 'my_job' at /nested_or_super_job/my_job. Keys: {"name", "type"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} -DEBUG: check_strictness at /nested_or_super_job/name. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'name' at /nested_or_super_job/name. Keys: {} -DEBUG: validate_refs merging res from entity. Keys: {"name"} -DEBUG: check_strictness at /nested_or_super_job/job_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'job_id' at /nested_or_super_job/job_id. Keys: {"name"} -DEBUG: validate_refs merging res from job. Keys: {"name", "job_id"} -DEBUG: check_strictness at /nested_or_super_job/manager_id. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'manager_id' at /nested_or_super_job/manager_id. Keys: {"job_id", "name"} -DEBUG: check_strictness at /nested_or_super_job/type. Extensible: false. Keys: {} -DEBUG: validate_object inserted 'type' at /nested_or_super_job/type. Keys: {"manager_id", "job_id", "name"} -DEBUG: validate_refs merging res from super_job. Keys: {"job_id", "manager_id", "type", "name"} -DEBUG: check_strictness at /nested_or_super_job. Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("polymorphic_org_punc.request") ref=Some("organization.family") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("polymorphic_org_punc.request") ref=Some("organization.family") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("polymorphic_org_punc.request") ref=Some("organization.family") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("strict_org_punc.request") ref=Some("organization") -DEBUG: check_strictness at . Extensible: false. Keys: {} -DEBUG: VALIDATE ROOT: id=Some("strict_org_punc.request") ref=Some("organization") -DEBUG: check_strictness at . Extensible: false. Keys: {} - -thread 'test_puncs_6' (15121282) panicked at tests/tests.rs:150:44: -called `Result::unwrap()` on an `Err` value: "[complex punc type matching with oneOf and nested refs] Test 'valid person against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'first_name'\", details: ErrorDetails { path: \"/first_name\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against organization punc (polymorphic)' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]\n[complex punc type matching with oneOf and nested refs] Test 'valid organization against strict punc' failed. Expected: true, Got: true. Errors: [Error { punc: None, code: \"STRICT_PROPERTY_VIOLATION\", message: \"Unexpected property 'id'\", details: ErrorDetails { path: \"/id\" } }]" -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -test test_puncs_6 ... FAILED - -failures: - -failures: - test_puncs_6 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 338 filtered out; finished in 0.01s - -error: test failed, to rerun pass `--test tests`