Skip to content

Commit

Permalink
Merge pull request #28 from jetavator/issue-11-Improve_access_to_json…
Browse files Browse the repository at this point in the history
…schema_validation_for_a_given_schema

Improve access to jsonschema validation and document DOM functions
  • Loading branch information
jtv8 authored May 22, 2020
2 parents 636ef19 + 69c0986 commit ea31416
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 3 deletions.
17 changes: 17 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,23 @@ properties, you may use the `default_function` parameter::
default_function=lambda person: person.first_name
)

DOM functions
=============

While the DOM and schema information can be retrieved from a DOMElement
using the `__json_dom_info__` property and `__json_schema__()` method
respectively, the following convenience functions are provided
for code readability.

.. autofunction:: wysdom.document

.. autofunction:: wysdom.parent

.. autofunction:: wysdom.key

.. autofunction:: wysdom.schema


Mixins
======

Expand Down
83 changes: 83 additions & 0 deletions features/dict.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
Feature: Test JSON DOM objects

Scenario: Test good input string

Given the Python module dict_module.py
When we execute the following python code:
"""
example_dict_input = {
"first_name": "Marge",
"last_name": "Simpson",
"current_address": {
"first_line": "123 Fake Street",
"second_line": "",
"city": "Springfield",
"postal_code": 58008
},
"previous_addresses": [{
"first_line": "742 Evergreen Terrace",
"second_line": "",
"city": "Springfield",
"postal_code": 58008
}],
"vehicles": {
"eabf04": {
"color": "orange",
"description": "Station Wagon"
}
}
}
example = dict_module.Person(example_dict_input)
example_dict_output = example.to_builtin()
"""
Then the following statements are true:
"""
example.first_name == "Marge"
example.last_name == "Simpson"
example.current_address.first_line == "123 Fake Street"
example.current_address.second_line == ""
example.current_address.city == "Springfield"
example.current_address.postal_code == 58008
example["current_address"].first_line == "123 Fake Street"
example["current_address"].second_line == ""
example["current_address"].city == "Springfield"
example["current_address"].postal_code == 58008
example.previous_addresses[0].first_line == "742 Evergreen Terrace"
example.previous_addresses[0].second_line == ""
example.previous_addresses[0].city == "Springfield"
example.previous_addresses[0].postal_code == 58008
example.vehicles["eabf04"].color == "orange"
example.vehicles["eabf04"].description == "Station Wagon"
example.vehicles["eabf04"].license == "eabf04"
len(example) == 5
len(example.current_address) == 4
len(example.previous_addresses) == 1
len(example.vehicles) == 1
parent(example.current_address) is example
document(example.current_address) is example
key(example.current_address) == "current_address"
parent(example.vehicles["eabf04"]) is example.vehicles
document(example.vehicles["eabf04"]) is example
key(example.vehicles["eabf04"]) == "eabf04"
parent(example["vehicles"]["eabf04"]) is example.vehicles
document(example["vehicles"]["eabf04"]) is example
key(example["vehicles"]["eabf04"]) == "eabf04"
schema(example).is_valid(example_dict_input)
example_dict_output == example_dict_input
"""

Scenario: Test bad input string

Given the Python module dict_module.py
When we execute the following python code:
"""
example_dict_input = {"foo": "bar"}
"""
Then the following statements are true:
"""
not(schema(example).is_valid(example_dict_input))
"""
And the following statement raises ValidationError
"""
dict_module.Person(example_dict_input)
"""
27 changes: 27 additions & 0 deletions features/examples/modules/dict_module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from typing import Dict, List

from wysdom import UserObject, UserProperty, SchemaArray, SchemaDict, key


class Vehicle(UserObject):
color: str = UserProperty(str)
description: str = UserProperty(str)

@property
def license(self):
return key(self)


class Address(UserObject):
first_line: str = UserProperty(str)
second_line: str = UserProperty(str)
city: str = UserProperty(str)
postal_code: str = UserProperty(int)


class Person(UserObject):
first_name: str = UserProperty(str)
last_name: str = UserProperty(str)
current_address: Address = UserProperty(Address)
previous_addresses: List[Address] = UserProperty(SchemaArray(Address))
vehicles: Dict[str, Vehicle] = UserProperty(SchemaDict(Vehicle))
3 changes: 2 additions & 1 deletion features/steps/steps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from behave import *

from wysdom import document, parent, key
from wysdom import document, parent, key, schema

import os
import importlib.util
Expand Down Expand Up @@ -38,6 +38,7 @@ def step_impl(context):
assert callable(document)
assert callable(parent)
assert callable(key)
assert callable(schema)
for line in context.text.splitlines():
result = eval(line)
if not result:
Expand Down
2 changes: 1 addition & 1 deletion wysdom/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .__version__ import __version__
from . import mixins
from .exceptions import ValidationError
from .dom.functions import dom, document, parent, key
from .dom import document, parent, key, schema
from .dom import DOMInfo as DOMInfo
from .dom import DOMElement as Element
from .base_schema import Schema, SchemaAnything, SchemaConst
Expand Down
2 changes: 1 addition & 1 deletion wysdom/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
VERSION = (0, 1, 0)
VERSION = (0, 1, 1)

__version__ = '.'.join(map(str, VERSION))
1 change: 1 addition & 0 deletions wysdom/dom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from .DOMObject import DOMObject
from .DOMDict import DOMDict
from .DOMList import DOMList
from .functions import document, parent, key, schema
37 changes: 37 additions & 0 deletions wysdom/dom/functions.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,57 @@
from typing import Optional

from ..base_schema import Schema
from .DOMElement import DOMElement
from . import DOMInfo


def dom(element: DOMElement) -> DOMInfo:
"""
Retrieve a DOMInfo object for a DOMElement containing information about that
element's position in the DOM.
:param element: A DOM element
:return: The DOMInfo object for that DOM element
"""
return element.__json_dom_info__


def document(element: DOMElement) -> Optional[DOMElement]:
"""
Retrieve the owning document for a DOMElement, if it exists.
:param element: A DOM element
:return: The owning document for that DOM element, or None if none exists
"""
return dom(element).document


def parent(element: DOMElement) -> Optional[DOMElement]:
"""
Retrieve the parent element of a DOMElement, if it exists.
:param element: A DOM element
:return: The parent element of that DOM element, or None of none exists
"""
return dom(element).parent


def key(element: DOMElement) -> Optional[str]:
"""
Retrieve the key of a particular DOMElement in its parent element, if it can be
referred to by a key (i.e. if it its parent element is a Mapping).
:param element: A DOM element
:return: The key of that DOM element in its parent, or None if it has no key
"""
return dom(element).element_key


def schema(element: DOMElement) -> Schema:
"""
Retrieve the Schema object for a particular DOMElement.
:param element: A DOM element
:return: The Schema object associated with that DOM element
"""
return element.__json_schema__()

0 comments on commit ea31416

Please sign in to comment.