voxpupuli / json-schema

Ruby JSON Schema Validator
MIT License
1.52k stars 241 forks source link

I cannot use format date options. #427

Open muuuuuuura opened 5 years ago

muuuuuuura commented 5 years ago

I cannot use date format options. But I can use date-time format options.

Why JSON::Validator.fully_validate return empty Array? Please help me.

schema = {
  "type" => "object",
  "required" => ["a"],
  "properties" => {
    "a" => {
      "type" => "string",
      "format" => "date",
    }
   }
}
Rails5.1.6Ruby2.5.1 pry(main)> JSON::Validator.fully_validate(schema, {"a" => "abcdefg"})
=> []
tannakartikey commented 5 years ago

The date property is removed from draft-04 which is default version with this library.

You can achieve similar result by using regex as shown below:

schema = {
  "type" => "object",
  "required" => ["a"],
  "properties" => {
    "a" => {
      "type" => "string",
      "pattern" => "^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$"
    }
   }
}

Regex reference: https://www.regextester.com/99555

Reference: Tests for "Format" for darft-04 (Notice the absence of date format) Tests for "Format" for darft-03

muuuuuuura commented 5 years ago

Oh, I didn't know that. Thanks.

aaronbartell commented 5 years ago

Another approach is to create a custom format validator.

require 'json-schema'

iso_8601_date = -> value {
  begin
    Date.iso8601(value)
  rescue ArgumentError
    raise JSON::Schema::CustomFormatError.new('must be in ISO-8601 format: CCYY-MM-DD')
  end
}
JSON::Validator.register_format_validator(:iso_8601_date, iso_8601_date)

schema = {
  type: :object,
  required: [
    :first_name,
    :last_name,
    :birthdate
  ],
  properties: {
    birthdate: {
      type: :string,
      format: :iso_8601_date
    }
  }
}

input = <<-JSON
{
    "first_name": "Thomas",
    "last_name": "Paine",
    "birthdate": "1737-13-45"
}
JSON

JSON::Validator.fully_validate(schema, input)
JSON::Validator.validate(schema, input)

That will produce the following error. Note I called both fully_validate and validate to show the level of errors returned.

=> ["The property '#/birthdate' must be in ISO-8601 format: CCYY-MM-DD in schema 21b02321-c18e-53c4-b7f7-9c0adeeb6325"]

invalid: 1737-13-45
=> false
phil-workato commented 2 weeks ago

I tried with a pattern-based validation:

"birthday": {
  "type": "string",
  "format": "date",
  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
}

and it works. But a plain format does not validate incorrect values:

"birthday": {
  "type": "string",
  "format": "date"
}

even though the :

"birthday": {
  "type": "string",
  "format": "date-time"
}

does!

The 2020-12 version defines both "date-time" and "date" formats.

Does this look like a bug, or is just because the Draft 04 doesn't support those formats? It seems that the "date" was introduced in Draft 07, but I can't find about "date-time".