Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mlakewood committed Dec 27, 2016
1 parent e91be59 commit 0f10402
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.hypothesis
*.egg-info
venv
*.pyc
build
dist
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

venv:
pip install --upgrade virtualenv
virtualenv --python=python3 venv

install: venv
. venv/bin/activate; \
pip install -e .

unit-test:
. venv/bin/activate; \
python -m unittest discover tests/
Empty file added README.rst
Empty file.
Empty file added hypo_schema/__init__.py
Empty file.
77 changes: 77 additions & 0 deletions hypo_schema/hypo_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from copy import deepcopy
from random import randint

from hypothesis import strategies as hs



def gen_int(prop):
min_value = prop.get("minimum", None)
max_value = prop.get("maximum", None)
return hs.integers(min_value=min_value, max_value=max_value)

def gen_string(prop):
return hs.text()

def should_include(key, required_list):
if key in required_list:
return True
else:
return bool(randint(0, 1))

def gen_array(prop):
min_value = prop.get("minimum", None)
max_value = prop.get("maximum", None)

if prop.get("items", {}).get("type", False) is not False:
generator = get_generator(prop.get("items"))
return hs.lists(elements=generator, min_size=min_value, max_size=max_value)
return hs.lists(elements=gen_anything(), min_size=min_value, max_size=max_value)

def gen_anything():
return hs.one_of(hs.text(), hs.booleans(), hs.integers(), hs.none())

def gen_object(prop):

required = prop["required"]
output = {}

for k in prop["properties"].keys():
json_prop = prop["properties"][k]

if should_include(k, required):
output[k] = get_generator(prop["properties"][k])

return hs.fixed_dictionaries(output)

def gen_enum(prop):
enum = prop["enum"]
return hs.sampled_from(enum)

def get_generator(prop):
disp = { "string": gen_string,
"integer": gen_int,
"number": gen_int,
"object": gen_object,
"array": gen_array,
"enum": gen_enum,
}

enum = prop.get("enum", None)
if enum is not None:
return gen_enum(prop)


json_type = prop.get("type", None)
if json_type is None:
raise JsonTypeError("Couldnt find type in prop {0}".format(prop))

return disp[json_type](prop)

def generate_from_schema(json_schema):
example_data = get_generator(json_schema)
return example_data


class JsonTypeError(Exception):
pass
18 changes: 18 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from setuptools import setup

setup(
name = 'hypo_schema',
packages = ['hypo_schema'], # this must be the same as the name above
version = '0.1',
description = 'Generate Hypothesis generators from a json schema definition',
author = 'Mark Lakewood',
author_email = '[email protected]',
url = 'https://github.com/mlakewood/hypo_schema', # use the URL to the github repo
download_url = 'https://github.com/mlakewood/hypo_schema/tarball/0.1', # I'll explain this in a second
keywords = ['testing', 'hypothesis', 'json_schema', 'generative'], # arbitrary keywords
classifiers = [],
install_requires=[
'jsonschema',
'hypothesis',
],
)
68 changes: 68 additions & 0 deletions tests/test_json_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import unittest
from pprint import pprint

from jsonschema import validate

from hypothesis import given, settings
from hypo_schema.hypo_schema import generate_from_schema


EXAMPLE_JSON_SCHEMA= {
"title": "Example Schema",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 0
},
"listOfElements": {
"type": "array",
"items": {
"type": "number"
}
},
"listOfRandom": {
"min": 4,
"max": 10,
"type": "array"
},
"type": {
"type": "string",
"enum": ["string", "int", "bool"]
},
"nestedMap": {
"type": "object",
"properties": {
"firstProp": {
"type": "string"
}
},
"required": ["firstProp"]
}
},
"required": ["firstName", "lastName", "nestedMap", "listOfElements"]
}


class TestJsonSchema(unittest.TestCase):

def setUp(self):
self.maxDiff = None


@given(generate_from_schema(EXAMPLE_JSON_SCHEMA))
@settings(max_examples=500)
def test_basic_map(self, example_data):


# example_data = generate_from_schema(example_json_schema).example()
# pprint(example_data)

validate(example_data, EXAMPLE_JSON_SCHEMA)

0 comments on commit 0f10402

Please sign in to comment.