sigu-399/gojsonschema — pull request #8 by tolsen (2013-09-06 19:09:59+00:00)
Title: Better anyOf and oneOf error messages

This pull request adds better error messages for anyOf and oneOf failures. This new code scores subschema matches for how closely they match (by a very rough heuristic we'll probably have to tweak over time). In the case where anyOf fails or oneOf fails (with zero matches), the error messages for the closest matching subschema are copied over. The result is often what the user is looking for.

For example, before I was getting error messages like this on my json:

```
actions ROOT.steps.FinishDownload.actions.0 : items failed to validate any of the schema
actions ROOT.steps.FinishStart.actions.0 : items failed to validate any of the schema
```

Now I am getting:

```
actions ROOT.steps.FinishDownload.actions.0.name : name must match one of the enum values ["download"]
actions ROOT.steps.FinishDownload.actions.0.args : url property is required
actions ROOT.steps.FinishDownload.actions.0.args.dest : dest must be of type string
actions ROOT.steps.FinishDownload.actions.0 : items failed to validate any of the schema
actions ROOT.steps.FinishStart.actions.0.args : No additional property ( processType ) is allowed on args
actions ROOT.steps.FinishStart.actions.0.args.bin : bin must be of type string
actions ROOT.steps.FinishStart.actions.0 : items failed to validate any of the schema
```

gojsonschema now guesses the sub-schema the user was trying to match and tells the user how the json is failing against that subschema.

In order to do the scoring, I made several changes to ValidationResult:

1. I first simplified ValidationResult by removing the valid field. It can be determined by the number of error messages. This reduces the amount of state that needs to be maintained.

2. I added a score field

3. I renamed CopyErrorMessages() and CopyErrorMessagesWithAnnotation to Merge() and MergeWithAnnotation(), respectively. When either are called the error messages are copied over and the scores are summed.

4. I removed the `if !result.IsValid()` guard around calls to CopyErrorMessages*() . Strictly speaking this wasn't necessary before as copying 0 messages has no effect (other than the function call overhead). Now it has to be removed anyway so that the scores can be summed.

I realize this is a new feature. Let me know what you think!