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