Source code for brunns.matchers.data
import json
from typing import Any, Union
from hamcrest.core.base_matcher import BaseMatcher
from hamcrest.core.description import Description
from hamcrest.core.helpers.wrap_matcher import wrap_matcher
from hamcrest.core.matcher import Matcher
# JsonStructure = Union[MutableMapping[str, "JsonStructure"],
# Iterable["JsonStructure"], str, int, bool, None]
JsonStructure = Any # TODO Pending a better solution to https://github.com/python/typing/issues/182
[docs]
class JsonMatching(BaseMatcher[str]):
"""Matches string containing JSON data.
:param matcher: Value to match against deserialised JSON.
"""
def __init__(self, matcher: Union[JsonStructure, Matcher[JsonStructure]]) -> None:
self.matcher: Matcher[JsonStructure] = wrap_matcher(matcher)
[docs]
def describe_to(self, description: Description) -> None:
description.append_text("JSON structure matching ").append_description_of(self.matcher)
def _matches(self, json_string: str) -> bool:
try:
loads = json.loads(json_string)
except ValueError:
return False
return self.matcher.matches(loads)
[docs]
def describe_mismatch(self, json_string: str, description: Description) -> None:
try:
loads = json.loads(json_string)
except ValueError:
description.append_text("Got invalid JSON ").append_description_of(json_string)
else:
self.matcher.describe_mismatch(loads, description)
[docs]
def json_matching(matcher: Union[Matcher[JsonStructure], JsonStructure]) -> JsonMatching:
"""Matches string containing JSON data.
:param matcher: Value to match against deserialised JSON.
"""
return JsonMatching(matcher)