xeipuuv/gojsonschema — pull request #38 by xogeny (2014-11-01 14:41:08+00:00)
Title: Inconsistent handling of integers vs. numbers

I came across a very odd "bug" using `gojsonschema` that is demonstrated nicely by this code:

```
package main

import "log"
import "github.com/xeipuuv/gojsonschema"

func main() {
s1 := map[string]interface{}{"type": "array", "minItems": 1}
_, err := gojsonschema.NewJsonSchemaDocument(s1)
if err != nil {
log.Printf("Error when minItems is an int: %v", err)
}

s2 := map[string]interface{}{"type": "array", "minItems": float64(1)}
_, err = gojsonschema.NewJsonSchemaDocument(s2)
if err != nil {
log.Printf("Error in s2: %v", err)
} else {
log.Printf("When minItems is a float, error saying it must be an int goes away!?!")
}
}
```

When you run it, it prints:

```
2014/11/01 09:02:26 Error when minItems is an int: minItems must be an integer
2014/11/01 09:02:26 When minItems is a float, error saying it must be an int goes away!?!
```

The issue here is that you can pass a native Go `map[string]interface{}` for your schema and it seems very natural to provide integer values for things that must be integers (see example). But this results in an error because in the case of `minItems`, it only considers the case where `minItems` is a `float64` and then checks to make sure that it is an integral value.

Now, there are some cases in the code where it does the correct handling of checking whether something is an integer or a float and then handling each case appropriately. But in looking at the code, it was inconsistent. Furthermore, the code that handles numbers tends to have some boilerplate code in there.

I recognized that across all cases where a `float64` is used, there are really just two cases to handle. The first is that you want an integer and the other case is that you want a number. So I made two utility routines (`mustBeInteger` and `mustBeNumber`, respectively) that encapsulate all the `isKind` handling and simply return a pointer to the appropriate type **if** the data can be represented in that form.

So, this pull request includes all the changes to address this inconsistency. **All the tests still pass** and I see no reason it should not be 100% backward compatible. Finally, the handling of `minItems` now works with native types.