1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
import json
import os.path
import typing as t
import uritemplate
def fixture_file_path(filename: str) -> str:
absolute_dir = os.path.abspath(os.path.dirname(__file__))
filename = filename + ".json"
return os.path.join(absolute_dir, "fixtures", filename)
ExampleVariables = uritemplate.variable.VariableValueDict
ExampleTemplatesAndResults = t.List[t.Tuple[str, t.Union[str, t.List[str]]]]
class ExampleWithVariables(t.TypedDict):
variables: ExampleVariables
testcases: ExampleTemplatesAndResults
Examples = t.Dict[str, ExampleWithVariables]
def load_examples(filename: str) -> Examples:
path = fixture_file_path(filename)
with open(path, encoding="utf-8") as examples_file:
examples = t.cast(Examples, json.load(examples_file))
return examples
def expected_set(expected: t.Union[t.List[str], str]) -> t.Set[str]:
if isinstance(expected, list):
return set(expected)
return {expected}
class FixtureMixin:
examples: Examples
def _get_test(
self, section: str
) -> t.Tuple[ExampleVariables, ExampleTemplatesAndResults]:
test = t.cast(ExampleWithVariables, self.examples.get(section, {}))
return (
test.get("variables", {}),
test.get("testcases", []),
)
def _test(self, testname: str) -> None:
variables, testcases = self._get_test(testname)
for template, expected in testcases:
expected_templates = expected_set(expected)
expanded = uritemplate.expand(template, variables)
assert expanded in expected_templates, ( # nosec
f"expanded {template!r} with {variables!r} "
f"and got {expanded!r} but expected one of "
f"{expected_templates!r}"
)
class TestSpecExamples(FixtureMixin):
examples = load_examples("spec-examples")
def test_level_1(self) -> None:
"""Check that uritemplate.expand matches Level 1 expectations."""
self._test("Level 1 Examples")
def test_level_2(self) -> None:
"""Check that uritemplate.expand matches Level 2 expectations."""
self._test("Level 2 Examples")
def test_level_3(self) -> None:
"""Check that uritemplate.expand matches Level 3 expectations."""
self._test("Level 3 Examples")
def test_level_4(self) -> None:
"""Check that uritemplate.expand matches Level 4 expectations."""
self._test("Level 4 Examples")
class TestSpecExamplesByRFCSection(FixtureMixin):
examples = load_examples("spec-examples-by-section")
def test_variable_expansion(self) -> None:
"""Check variable expansion."""
self._test("3.2.1 Variable Expansion")
def test_simple_string_expansion(self) -> None:
"""Check simple string expansion."""
self._test("3.2.2 Simple String Expansion")
def test_reserved_expansion(self) -> None:
"""Check reserved expansion."""
self._test("3.2.3 Reserved Expansion")
def test_fragment_expansion(self) -> None:
"""Check fragment expansion."""
self._test("3.2.4 Fragment Expansion")
def test_dot_prefixed_label_expansion(self) -> None:
"""Check label expansion with dot-prefix."""
self._test("3.2.5 Label Expansion with Dot-Prefix")
def test_path_segment_expansion(self) -> None:
"""Check path segment expansion."""
self._test("3.2.6 Path Segment Expansion")
def test_path_style_parameter_expansion(self) -> None:
"""Check path-style param expansion."""
self._test("3.2.7 Path-Style Parameter Expansion")
def test_form_style_query_expansion(self) -> None:
"""Check form-style query expansion."""
self._test("3.2.8 Form-Style Query Expansion")
def test_form_style_query_cntinuation(self) -> None:
"""Check form-style query continuation."""
self._test("3.2.9 Form-Style Query Continuation")
class TestExtendedTests(FixtureMixin):
examples = load_examples("extended-tests")
def test_additional_examples_1(self) -> None:
"""Check Additional Examples 1."""
self._test("Additional Examples 1")
def test_additional_examples_2(self) -> None:
"""Check Additional Examples 2."""
self._test("Additional Examples 2")
def test_additional_examples_3(self) -> None:
"""Check Additional Examples 3."""
self._test("Additional Examples 3: Empty Variables")
def test_additional_examples_4(self) -> None:
"""Check Additional Examples 4."""
self._test("Additional Examples 4: Numeric Keys")
def test_additional_examples_5(self) -> None:
"""Check Additional Examples 5."""
self._test("Additional Examples 5: Explode Combinations")
def test_additional_examples_6(self) -> None:
"""Check Additional Examples 6."""
self._test("Additional Examples 6: Reserved Expansion")
|