class GovukSchemas::RandomSchemaGenerator
def generate_value(props)
def generate_value(props) # TODO: #/definitions/nested_headers are recursively nested and can cause # infinite loops. We need to add something that detects and prevents the # loop. In the meantime return a valid value. if props["$ref"] == "#/definitions/nested_headers" return [{ "text" => "1", "level" => 1, "id" => "ABC" }] end # JSON schemas can have "pointers". We use this to extract defintions and # reduce duplication. To make the schema easily parsable we inline the # reference here. if props["$ref"] props.merge!(lookup_json_pointer(props["$ref"])) end # Attributes with `enum` specified often omit the `type` from # their definition. It's most likely a string. type = props["type"] || "string" # Except when it has properties, because it's defintely an object then. if props["properties"] type = "object" end # Make sure that we choose a type when there are more than one specified. type = Array(type).sample(random: @random) if props["anyOf"] generate_value(props["anyOf"].sample(random: @random)) elsif props["oneOf"] && type != "object" # FIXME: Generating valid data for a `oneOf` schema is quite interesting. # According to the JSON Schema spec a `oneOf` schema is only valid if # the data is valid against *only one* of the clauses. To do this # properly, we'd have to verify that the data generated below doesn't # validate against the other schemas in `props['oneOf']`. generate_value(props["oneOf"].sample(random: @random)) elsif props["allOf"] props["allOf"].each_with_object({}) do |subschema, hash| val = generate_value(subschema) hash.merge(val) end elsif props["enum"] props["enum"].sample(random: @random) elsif type == "null" nil elsif type == "object" generate_random_object(props) elsif type == "array" generate_random_array(props) elsif type == "boolean" @generator.bool elsif type == "integer" min = props["minimum"] || 0 max = props["maximum"] || 10 @random.rand(min..max) elsif type == "string" generate_random_string(props) else raise "Unknown attribute type: #{props}" end end