def generate_from_schema(schema, no_empty=True, retry=5): test_data = [] settings = Settings() if (schema.get('type') == 'string' and not schema.get('minLength') and not schema.get('maxLength') and not schema.get('format')): schema['minLength'] = settings.test_data_str_min_length # schema['pattern'] = '^\w+$' generate_func = from_schema(schema) generate_func = generate_func.filter(FILTERS[str]) elif schema.get('type') == 'integer' and not schema.get('minimum'): schema['minimum'] = settings.test_data_int_min generate_func = from_schema(schema) generate_func = generate_func.filter(FILTERS[int]) else: generate_func = from_schema(schema) @given(generate_func) def f(x): if x or not no_empty: test_data.append(x) passed = False while retry > 0 or not passed: try: f() passed = True retry = 0 except (hypothesis.errors.Unsatisfiable, hypothesis.errors.FailedHealthCheck): retry -= 1 if not passed: raise hypothesis.errors.Unsatisfiable("Max retries hit") yield test_data
def test_can_generate_for_test_suite_schema(data, name): note(suite[name]) value = data.draw(from_schema(suite[name])) try: jsonschema.validate(value, suite[name]) except jsonschema.exceptions.SchemaError: jsonschema.Draft4Validator(suite[name]).validate(value)
def test_draft03_not_supported(): # Also checks that errors are deferred from importtime to runtime @given(from_schema({"$schema": "http://json-schema.org/draft-03/schema#"})) def f(_): raise AssertionError with pytest.raises(InvalidArgument): f()
def test_custom_formats_validation(data, kw): s = from_schema({ "type": "string", "format": "card-test" }, custom_formats=kw) with pytest.raises(InvalidArgument): data.draw(s)
def test_impossible_multiplier(type_): # Covering test for a failsafe branch, which explicitly returns nothing() # if scaling the bounds and taking their ceil/floor also inverts them. schema = {"maximum": -1, "minimum": -1, "multipleOf": 0.0009765625000000002} schema["type"] = type_ strategy = from_schema(schema) strategy.validate() assert strategy.is_empty
def test_unsatisfiable_array_returns_nothing(): schema = { "type": "array", "items": [], "additionalItems": INVALID_REGEX_SCHEMA, "minItems": 1, } with pytest.warns(UserWarning): strategy = from_schema(schema) strategy.validate() assert strategy.is_empty
def test_generated_data_matches_schema(schema_strategy, data): """Check that an object drawn from an arbitrary schema is valid.""" schema = data.draw(schema_strategy) note(schema) try: value = data.draw(from_schema(schema), "value from schema") except InvalidArgument: reject() jsonschema.validate(value, schema) # This checks that our canonicalisation is semantically equivalent. jsonschema.validate(value, canonicalish(schema))
def gen_object(draw: Any) -> Schema: """Draw an object schema.""" out: Schema = {"type": "object"} names = draw(st.sampled_from([None, None, None, draw(gen_string())])) name_strat = st.text() if names is None else from_schema(names) required = draw( st.just(False) | st.lists(name_strat, min_size=1, max_size=5, unique=True)) # Trying to generate schemata that are consistent would mean dealing with # overlapping regex and names, and that would suck. So instead we ensure that # there *are* no overlapping requirements, which is much easier. properties = draw(st.dictionaries(name_strat, _json_schemata(recur=False))) disjoint = REGEX_PATTERNS.filter(lambda r: all( re.search(r, string=name) is None for name in properties)) patterns = draw( st.dictionaries(disjoint, _json_schemata(recur=False), max_size=1)) additional = draw(st.none() | _json_schemata(recur=False)) min_size = draw(st.none() | st.integers(0, 5)) max_size = draw(st.none() | st.integers(2, 5)) if min_size is not None and max_size is not None and min_size > max_size: min_size, max_size = max_size, min_size if names is not None: out["propertyNames"] = names if required: out["required"] = required if min_size is not None: min_size += len(required) if max_size is not None: max_size += len(required) if min_size is not None: out["minProperties"] = min_size if max_size is not None: out["maxProperties"] = max_size if properties: out["properties"] = properties props = st.sampled_from(sorted(properties)) if draw(st.integers(0, 3)) == 3: out["dependencies"] = draw( st.dictionaries(props, st.lists(props, unique=True))) elif draw(st.integers(0, 3)) == 3: out["dependencies"] = draw(st.dictionaries(props, json_schemata())) if patterns: out["patternProperties"] = patterns if additional is not None: out["additionalProperties"] = additional return out
def test_generated_data_matches_schema(schema_strategy, data): """Check that an object drawn from an arbitrary schema is valid.""" schema = data.draw(schema_strategy) note(schema) try: value = data.draw(from_schema(schema), "value from schema") except InvalidArgument: reject() try: jsonschema.validate(value, schema) # This checks that our canonicalisation is semantically equivalent. jsonschema.validate(value, canonicalish(schema)) except jsonschema.ValidationError as err: if "'uniqueItems': True" in str(err): pytest.xfail("https://github.com/Julian/jsonschema/issues/686") raise
def test_invalid_schemas_raise(schema): """Trigger all the validation exceptions for full coverage.""" with pytest.raises(Exception): from_schema(schema).example()
note(schema) try: value = data.draw(from_schema(schema), "value from schema") except InvalidArgument: reject() try: jsonschema.validate(value, schema) # This checks that our canonicalisation is semantically equivalent. jsonschema.validate(value, canonicalish(schema)) except jsonschema.ValidationError as err: if "'uniqueItems': True" in str(err): pytest.xfail("https://github.com/Julian/jsonschema/issues/686") raise @given(from_schema(True)) def test_boolean_true_is_valid_schema_and_resolvable(_): """...even though it's currently broken in jsonschema.""" @pytest.mark.parametrize( "schema", [ None, False, { "type": "an unknown type" }, { "allOf": [{ "type": "boolean"
def test_cannot_generate_for_empty_test_suite_schema(name): strat = from_schema(invalid_suite[name]) with pytest.raises(Exception): strat.example()
def test_invalid_regex_emit_warning(schema): with pytest.warns(UserWarning): from_schema(schema).validate()
def test_can_generate_for_real_large_schema(data, name): note(name) value = data.draw(from_schema(catalog[name])) jsonschema.validate(value, catalog[name])
@given(data=st.data()) @schema_strategy_params def test_generated_data_matches_schema(schema_strategy, data): """Check that an object drawn from an arbitrary schema is valid.""" schema = data.draw(schema_strategy) note(schema) try: value = data.draw(from_schema(schema), "value from schema") except InvalidArgument: reject() jsonschema.validate(value, schema) # This checks that our canonicalisation is semantically equivalent. jsonschema.validate(value, canonicalish(schema)) @given(from_schema(True)) def test_boolean_true_is_valid_schema_and_resolvable(_): """...even though it's currently broken in jsonschema.""" @pytest.mark.parametrize( "schema", [ None, False, { "type": "an unknown type" }, { "allOf": [{ "type": "boolean"
def test_draft03_not_supported(): with pytest.raises(InvalidArgument): from_schema({"$schema": "http://json-schema.org/draft-03/schema#"})