santhosh-tekuri/jsonschema

compiling twice gives different validation result

Closed this issue · 2 comments

i have a validation function. I give here json which should not be valid. I have not valid if commented line is commented. If i uncommont it, i have valid. Seems like it influnces on result

`func ForTest(textToCheck string) (v bool, err error) {
var m interface{}
err = yaml.Unmarshal([]byte(textToCheck), &m)
if err != nil {
return false, err
}
m, err = toStringKeys(m)
if err != nil {
return false, err
}

compiler := jsonschema.NewCompiler()

if err := compiler.AddResource(SchemaResourceV2, strings.NewReader(schemaBodyResourceV2)); err != nil {
	return false, err
}

//schema, err := compiler.Compile(SchemaResourceV2) //if uncomment this line -> validation will be true/if leave it -> it's folse

if err := compiler.AddResource(SchemaNamedV1, strings.NewReader(schemaBodyNamedV1)); err != nil {
	return false, err
}

if err := compiler.AddResource(SchemaMultilingualV1, strings.NewReader(schemaBodyMultilingualV1)); err != nil {
	return false, err
}

schema, err := compiler.Compile(SchemaResourceV2)
if err != nil {
	return false, err
}

if err := schema.Validate(m); err != nil {
	return false, err
}

return true, err

}`

ideally you should add all resources first and then call compile (as many times)

also note that:
the implementation compiles a schema only once, if you compile same schema second time, it returns the schema value from first compilation.

i can give following example which has similar behaviour as yours, and why it is happening ?

say you have b.json in your working directory with following content

{ "type": "string" }
compiler := jsonschema.NewCompiler()
if err := compiler.AddResource("a.json", strings.NewReader(`{"ref":"b.json"}`)); err != nil {
	return false, error
}
schema, err := compiler.Compile("a.json") // XXX
if err := compiler.AddResource("b.json", strings.NewReader(`{"type":"number"}`)); err != nil {
	return false, error
}
schema, err := compiler.Compile("a.json")
if err != nil {
	return false, err
}
value := 1
if err := schema.Validate(1); err != nil {
	return false, err
}

when line XXX is commented:

  • a.json and b.json resources are added
  • note that resource b.json added says type must be number
  • now you compile a.json, the schema returned will has check for type number
  • so the validating 1 against schema passes

when line XXX is uncommented:

  • after a.json is added you are compiling
  • the compilation internally adds resource b.json from your working directory, which says type must be string
  • now you override b.json by adding resource, which says type must be number
  • now you compile a.json again, but internally it simply returns previously compiled schema, which says type must be string
  • so now validating 1 against schema fails

i hope you understand why you get such behaviour. and the behaviour is as expected by the implementation.

i guess the same thing is happening in your case. you can confirm it yourself or send the complete code with all json strings if you want me to analyze.

Yes, it's what i have as well, thank you.

That's first time i'm using your lib, so still try to get used to.

What i'was doing: i try to compile a schema which contains diff ref. So i simply added main schema, try to compile, got as result "ref 1 is not found", get the name of ref1 and add it as resource, then recompile. Now i'm simply recreate compiler and reAdd all resources which works fine. Thank you.