json-schema-validator icon indicating copy to clipboard operation
json-schema-validator copied to clipboard

Property Keyword Walk Listeners Invoked Too Often Since 1.0.59

Open tomdeering-wf opened this issue 4 years ago • 4 comments

Consider the following schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "title": "default_schema",
  "description": "Default Description",
  "properties": {
    "tags": {
      "type": "array",
      "items": [
        {
          "type": "string"
        }
      ]
    }
  }
}

A walk listener configured with config.addKeywordWalkListener(ValidatorTypeCode.PROPERTIES.getValue(), jsonSchemaWalkListener); is only expected to be invoked when "tags" is walked since that is the only property defined in the schema, but in 1.0.61 it is invoked for: tags $.properties.tags.items $.properties.tags.items[0] The latter two invocations are unexpected, since those are not properties.

tomdeering-wf avatar Oct 12 '21 18:10 tomdeering-wf

@prashanthjos Would you be able to comment on it?

stevehu avatar Oct 13 '21 19:10 stevehu

@tomdeering-wf I tried this in my local with the latest code and the walker behaves correctly and is getting called only once. Can you please add a test case for me to verify this.

prashanthjos avatar Oct 26 '21 15:10 prashanthjos

@prashanthjos sorry to take so long to respond. This reproduces it for me:

  @Test
  public void testPropertyWalk() throws JsonProcessingException {

    final var someSchema = "{\n" +
        "  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n" +
        "  \"type\": \"object\",\n" +
        "  \"title\": \"default_schema\",\n" +
        "  \"description\": \"Default Description\",\n" +
        "  \"properties\": {\n" +
        "    \"tags\": {\n" +
        "      \"type\": \"array\",\n" +
        "      \"items\": [\n" +
        "        {\n" +
        "          \"type\": \"string\"\n" +
        "        }\n" +
        "      ]\n" +
        "    }\n" +
        "  }\n" +
        "}";

    final var factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
    final var properties = new HashSet<String>();

    final var config = new SchemaValidatorsConfig();
    config.addKeywordWalkListener(ValidatorTypeCode.PROPERTIES.getValue(), new JsonSchemaWalkListener() {
      @Override
      public WalkFlow onWalkStart(WalkEvent walkEvent) {
        properties.add(walkEvent.getAt());
        return WalkFlow.CONTINUE;
      }

      @Override
      public void onWalkEnd(WalkEvent walkEvent, Set<ValidationMessage> set) {
      }
    });

    final var schema = factory.getSchema(JsonSchemaUtil.class.getResourceAsStream("/metaschemas/draft-07.json"), config);

    final var node = JacksonUtil.get().readTree(someSchema);
    schema.walk(node, true);

    Assertions.assertEquals(Set.of("$.properties.tags"), properties);
  }

and yields:

org.opentest4j.AssertionFailedError: 
Expected :[$.properties.tags]
Actual   :[$.properties.tags.items, $, $.properties.tags.items[0], $.properties.tags]

Version 1.0.59 of json-schema-validator collected only [$, $.properties.tags], so the behavior changed between 1.0.59 and 1.0.61 (and remains with the latest version).

tomdeering-wf avatar Jan 10 '22 22:01 tomdeering-wf

Likewise, adding a listener with config.addPropertyWalkListener collects even more unexpected things:

org.opentest4j.AssertionFailedError: 
Expected :[$.properties.tags]
Actual   :[$.properties.tags.type, $.properties.tags.items, $.properties.tags.items[0].type, $.type, $.$schema, $.description, $.title, $.properties]

tomdeering-wf avatar Jan 10 '22 22:01 tomdeering-wf