diff --git a/lib/json_schemer/result.rb b/lib/json_schemer/result.rb index 1c021e1..c00bc99 100644 --- a/lib/json_schemer/result.rb +++ b/lib/json_schemer/result.rb @@ -191,6 +191,7 @@ def classic def insert_property_defaults(context) instance_locations = {} + instance_locations.compare_by_identity results = [[self, true]] while (result, valid = results.pop) diff --git a/test/hooks_test.rb b/test/hooks_test.rb index 8a79ec0..7a23081 100644 --- a/test/hooks_test.rb +++ b/test/hooks_test.rb @@ -668,4 +668,52 @@ def test_insert_property_defaults_ref_depth_first assert(JSONSchemer.schema(schema, insert_property_defaults: true).valid?(data)) assert_equal('ref', data.fetch('x')) end + + def test_insert_property_defaults_compare_by_identity + data = JSON.parse(%q({ + "fieldname": [ + { "aaaa": "item0", "bbbb": "val1", "cccc": true }, + { "aaaa": "item1", "cccc": true, "buggy": true, "dddd": 0 }, + { "aaaa": "item2", "cccc": true, "buggy": true, "dddd": 0 }, + { "aaaa": "item3", "buggy": true }, + { "aaaa": "item4", "cccc": true }, + { "aaaa": "item5", "cccc": true } + ] + })) + schema = %q({ + "type": "object", + "properties": { + "fieldname": { + "type": "array", + "items": { + "$ref": "#/$defs/Record" + } + } + }, + "$defs": { + "Enumerated": { + "enum": [ "val1", "val2" ] + }, + "Record": { + "type": "object", + "properties": { + "aaaa": { "type": "string" }, + "cccc": { "type": "boolean", "default": false }, + "buggy": { "type": "boolean", "default": false }, + "bbbb": { "$ref": "#/$defs/Enumerated", "default": "val2" }, + "dddd": { "type": "number", "default": 0 }, + "eeee": { "type": "boolean", "default": false }, + "ffff": { "type": "boolean", "default": false } + } + } + } + }) + assert(JSONSchemer.schema(schema, insert_property_defaults: true).valid?(data)) + assert_equal('val2', data.dig('fieldname', 2, 'bbbb')) + assert_equal(false, data.dig('fieldname', 3, 'cccc')) + assert_equal(false, data.dig('fieldname', 4, 'buggy')) + assert_equal(0, data.dig('fieldname', 0, 'dddd')) + assert_equal(false, data.dig('fieldname', 1, 'eeee')) + assert_equal(false, data.dig('fieldname', 5, 'ffff')) + end end