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