EmitEachSelectorValidator extends AbstractValidator { @Override public List<ValidationEvent> validate(Model model) { if (config.bindToTrait != null && !model.getAppliedTraits().contains(config.getBindToTrait())) { return Collections.emptyList(); } else if (config.messageTemplate == null) { return validateWithSimpleMessages(model); } else { return validateWithTemplate(model); } } EmitEachSelectorValidator(Config config); @Override List<ValidationEvent> validate(Model model);  }
@Test public void expandsMessageTemplates() { EmitEachSelectorValidator.Config config = new EmitEachSelectorValidator.Config(); Model model = Model.builder() .addShape(StringShape.builder() .id(ShapeId.from("foo.bar#Baz")) .addTrait(new DocumentationTrait("hello")) .build()) .build(); config.setSelector(Selector.parse("$foo(*)")); config.setMessageTemplate("before `@{trait|documentation}` after. ID: @{id}. Var: @{var|foo|id}."); EmitEachSelectorValidator validator = new EmitEachSelectorValidator(config); List<ValidationEvent> events = validator.validate(model); assertThat(events.get(0).getMessage(), equalTo("before `\"hello\"` after. ID: foo.bar#Baz. Var: [foo.bar#Baz].")); }
@Test public void onlyEmitsEventsWhenShapeHasBoundTraitAndNoTemplate() { EmitEachSelectorValidator.Config config = new EmitEachSelectorValidator.Config(); Model model = Model.builder() .addShape(StringShape.builder() .id(ShapeId.from("foo.bar#A")) .addTrait(new DocumentationTrait("hello")) .build()) .addShape(StringShape.builder().id(ShapeId.from("foo.bar#B")).build()) .build(); config.setSelector(Selector.parse("*")); config.setBindToTrait(DocumentationTrait.ID); EmitEachSelectorValidator validator = new EmitEachSelectorValidator(config); List<ValidationEvent> events = validator.validate(model); assertThat(events, hasSize(1)); assertThat(events.get(0).getShapeId(), equalTo(Optional.of(ShapeId.from("foo.bar#A")))); }
@Test public void onlyEmitsEventsWhenShapeHasBoundTraitAndHasTemplate() { EmitEachSelectorValidator.Config config = new EmitEachSelectorValidator.Config(); Model model = Model.builder() .addShape(StringShape.builder() .id(ShapeId.from("foo.bar#A")) .addTrait(new DocumentationTrait("hello")) .build()) .addShape(StringShape.builder().id(ShapeId.from("foo.bar#B")).build()) .build(); config.setSelector(Selector.parse("*")); config.setMessageTemplate("This is only set to test the necessary code path of using templates..."); config.setBindToTrait(DocumentationTrait.ID); EmitEachSelectorValidator validator = new EmitEachSelectorValidator(config); List<ValidationEvent> events = validator.validate(model); assertThat(events, hasSize(1)); assertThat(events.get(0).getShapeId(), equalTo(Optional.of(ShapeId.from("foo.bar#A")))); }
@Test public void skipsUsingTheActualValidatorIfNoTraitsUseTheBoundTrait() { EmitEachSelectorValidator.Config config = new EmitEachSelectorValidator.Config(); Model model = Model.builder() .addShape(StringShape.builder().id(ShapeId.from("foo.bar#A")).build()) .build(); config.setSelector(Selector.parse("*")); config.setBindToTrait(DocumentationTrait.ID); EmitEachSelectorValidator validator = new EmitEachSelectorValidator(config); assertThat(validator.validate(model), empty()); }
@Test public void handlesEscapesAtSymbols() { EmitEachSelectorValidator.Config config = new EmitEachSelectorValidator.Config(); config.setSelector(Selector.parse("string")); config.setMessageTemplate("A@@@@B"); EmitEachSelectorValidator validator = new EmitEachSelectorValidator(config); Model model = Model.builder() .addShape(StringShape.builder().id(ShapeId.from("foo.bar#Baz")).build()) .build(); List<ValidationEvent> events = validator.validate(model); assertThat(events, hasSize(1)); assertThat(events.get(0).getMessage(), equalTo("A@@B")); }