1 | #!/usr/bin/env python3 |
---|
2 | import unittest |
---|
3 | from parameterized import parameterized |
---|
4 | import os |
---|
5 | import json |
---|
6 | import re |
---|
7 | import glob |
---|
8 | |
---|
9 | from ..reader import loads, load, parse_value |
---|
10 | |
---|
11 | test_files_root = "test_files" |
---|
12 | input_files_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), test_files_root, "inputs") |
---|
13 | output_files_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), test_files_root, "outputs") |
---|
14 | input_files = glob.glob(os.path.join(input_files_root, '*', '*')) |
---|
15 | |
---|
16 | parse_value_testcases = [ |
---|
17 | ('1', 1), |
---|
18 | ('0', 0), |
---|
19 | ('a', 'a'), |
---|
20 | # TODO tilde should also be escaped in single-line values (now it is only escaped in multi-line values) |
---|
21 | ('generic string ~ with tylda', 'generic string ~ with tylda'), |
---|
22 | ('123', 123), |
---|
23 | ('0x123', 0x123), |
---|
24 | ('0X123', 0x123), |
---|
25 | ('+0X10', 16), |
---|
26 | ('-0x125', -0x125), |
---|
27 | ('-0xaa', -0xaa), |
---|
28 | ('0xaa', 0xaa), |
---|
29 | ('0xAA', 0xaa), |
---|
30 | ('-12.3', -12.3), |
---|
31 | ('12.3e+05', 12.3e+05), |
---|
32 | ('@Serialized:null', None), |
---|
33 | ('@Serialized: null', None), |
---|
34 | ('@Serialized:"@Serialized:"', '@Serialized:'), |
---|
35 | ('@Serialized:"\\""', '"'), |
---|
36 | ('@Serialized:"\\t"', '\t'), |
---|
37 | ('@Serialized:"\\n"', '\n'), |
---|
38 | ('@Serialized:1', 1), |
---|
39 | ('@Serialized:2.1', 2.1), |
---|
40 | ('@Serialized:+2.1', 2.1), |
---|
41 | ('@Serialized:-2.1', -2.1), |
---|
42 | ('@Serialized: +0X10 ', 16), |
---|
43 | ('@Serialized: 0X10 ', 16), |
---|
44 | ('@Serialized: 0XAA ', 0xaa), |
---|
45 | ('@Serialized: 0Xaa ', 0xaa), |
---|
46 | ('@Serialized:[]', []), |
---|
47 | ('@Serialized:[1,2,3]', [1, 2, 3]), |
---|
48 | ('@Serialized: [ +0X10 ] ', [16]), |
---|
49 | ('@Serialized:[ +0X10, null, "abc"] ', [16, None, "abc"]), |
---|
50 | ('@Serialized:[[[]]]', [[[]]]), |
---|
51 | ('@Serialized:{}', {}), |
---|
52 | ('@Serialized:{"a":123 }', {"a": 123}), |
---|
53 | ('@Serialized:{"a":123,"b":2 }', {"a": 123, "b": 2}), |
---|
54 | ('@Serialized:{"a":123,"b":[1,2,3] }', {"a": 123, "b": [1, 2, 3]}), |
---|
55 | ('@Serialized:XYZ[0,1,2]', (0, 1, 2)), |
---|
56 | ('@Serialized:Population<0x85f53a8>', 'Population<0x85f53a8>'), |
---|
57 | ('@Serialized:CrazyObject[{},{},[[]]]', 'CrazyObject[{},{},[[]]]'), |
---|
58 | ('@Serialized:[co[{},{},[[]]],[]]', ['co[{},{},[[]]]', []]), |
---|
59 | ('@Serialized:[co[{},{},[[]]],[1,2,3]]', ['co[{},{},[[]]]', [1, 2, 3]]), |
---|
60 | ('@Serialized:[[1,2, 3], co[{},{},[[]]]]', [[1, 2, 3], 'co[{},{},[[]]]']), |
---|
61 | # TODO maybe raise if there is a space? |
---|
62 | ('@Serialized:Population <0x85f53a8>', 'Population <0x85f53a8>'), |
---|
63 | |
---|
64 | ] |
---|
65 | context_parse_value_testcases = [ |
---|
66 | ({'value': '1', 'classname': 'expdef', 'key': 'name', 'context': 'expdef file'}, '1'), |
---|
67 | ({'value': '234.5', 'classname': 'Creature', 'key': 'energ0', 'context': 'Global Context'}, 234.5) |
---|
68 | ] |
---|
69 | parse_value_exception_testcases = [ |
---|
70 | '@Serialized: ' |
---|
71 | ] |
---|
72 | |
---|
73 | loads_testcases = [ |
---|
74 | ('class:\nmlprop:~\nbla bla bla\n~\n', [{"_classname": "class", "mlprop": "bla bla bla\n"}]), |
---|
75 | ('class:\nmlprop:~\n\\~\n~\n', [{"_classname": "class", "mlprop": "~\n"}]) |
---|
76 | ] |
---|
77 | loads_exception_testcases = [ |
---|
78 | 'class:\nmlprop:~\n\\~\n~\nasdasd', |
---|
79 | 'class:\nmlprop:~\n~\n~\n', |
---|
80 | ] |
---|
81 | |
---|
82 | |
---|
83 | # TODO make more atomic tests, maybe |
---|
84 | class ReferenceTest(unittest.TestCase): |
---|
85 | def test0(self): |
---|
86 | str_in = '@Serialized:[^0] ' |
---|
87 | result = parse_value(str_in) |
---|
88 | self.assertTrue(isinstance(result, list)) |
---|
89 | self.assertEqual(len(result), 1) |
---|
90 | self.assertTrue(result is result[0]) |
---|
91 | |
---|
92 | def test1(self): |
---|
93 | str_in = '@Serialized:[44,[^1]]' |
---|
94 | result = parse_value(str_in) |
---|
95 | self.assertTrue(isinstance(result, list)) |
---|
96 | self.assertEqual(len(result), 2) |
---|
97 | self.assertEqual(result[0], 44) |
---|
98 | self.assertTrue(result[1] is result[1][0]) |
---|
99 | |
---|
100 | def test2(self): |
---|
101 | str_in = '@Serialized:[[100],["abc"],[300,^2]]' |
---|
102 | result = parse_value(str_in) |
---|
103 | self.assertTrue(isinstance(result, list)) |
---|
104 | self.assertEqual(len(result), 3) |
---|
105 | self.assertEqual(result[0], [100]) |
---|
106 | self.assertEqual(result[1], ["abc"]) |
---|
107 | self.assertEqual(result[2][0], 300) |
---|
108 | self.assertTrue(result[2][1] is result[1]) |
---|
109 | |
---|
110 | def test3(self): |
---|
111 | str_in = '@Serialized:[[123,[]],["x",^0],^2]' |
---|
112 | result = parse_value(str_in) |
---|
113 | self.assertTrue(isinstance(result, list)) |
---|
114 | self.assertEqual(len(result), 3) |
---|
115 | self.assertEqual(result[0], [123, []]) |
---|
116 | self.assertTrue(isinstance(result[1], list)) |
---|
117 | self.assertEqual(result[1][0], "x") |
---|
118 | self.assertTrue(result[2] is result[0][1]) |
---|
119 | self.assertTrue(result[1][1] is result) |
---|
120 | |
---|
121 | def test4(self): |
---|
122 | str_in = '@Serialized:{"a":[33,44],"b":^1,"c":[33,44]}' |
---|
123 | result = parse_value(str_in) |
---|
124 | self.assertTrue(isinstance(result, dict)) |
---|
125 | self.assertEqual(len(result), 3) |
---|
126 | self.assertListEqual(sorted(result.keys()), ["a", "b", "c"]) |
---|
127 | |
---|
128 | self.assertEqual(result["a"], [33, 44]) |
---|
129 | self.assertEqual(result["c"], [33, 44]) |
---|
130 | |
---|
131 | self.assertFalse(result["c"] is result["a"]) |
---|
132 | self.assertTrue(result["b"], result["a"]) |
---|
133 | |
---|
134 | def test5(self): |
---|
135 | str_in = '@Serialized:[null, null, [1, 2], null, ^ 1]' |
---|
136 | result = parse_value(str_in) |
---|
137 | self.assertTrue(isinstance(result, list)) |
---|
138 | self.assertEqual(len(result), 5) |
---|
139 | self.assertListEqual(result[0:4], [None, None, [1, 2], None]) |
---|
140 | self.assertTrue(result[2] is result[4]) |
---|
141 | |
---|
142 | |
---|
143 | class ParseValueTest(unittest.TestCase): |
---|
144 | @parameterized.expand(parse_value_testcases) |
---|
145 | def test_correct_parsing(self, input_val, output): |
---|
146 | self.assertEqual(output, parse_value(input_val)) |
---|
147 | |
---|
148 | @parameterized.expand(context_parse_value_testcases) |
---|
149 | def test_correct_context_parsing(self, input_val, output): |
---|
150 | self.assertEqual(output, parse_value(**input_val)) |
---|
151 | |
---|
152 | @parameterized.expand(parse_value_exception_testcases) |
---|
153 | def test_parsing_exceptions(self, input_val): |
---|
154 | self.assertRaises(ValueError, parse_value, input_val) |
---|
155 | |
---|
156 | |
---|
157 | class LoadsTest(unittest.TestCase): |
---|
158 | @parameterized.expand(loads_testcases) |
---|
159 | def test_correct_loads(self, input_val, output): |
---|
160 | self.assertEqual(output, loads(input_val)) |
---|
161 | |
---|
162 | @parameterized.expand(loads_exception_testcases) |
---|
163 | def test_load_exceptions(self, input_val): |
---|
164 | self.assertRaises(ValueError, loads, input_val) |
---|
165 | |
---|
166 | |
---|
167 | class LoadTest(unittest.TestCase): |
---|
168 | @parameterized.expand(input_files) |
---|
169 | def test_correct_load(self, filename): |
---|
170 | json_output_path = output_files_root + filename[len(input_files_root):] + ".json" |
---|
171 | with self.subTest(i=filename): |
---|
172 | result = load(filename) |
---|
173 | with open(json_output_path, encoding='UTF-8') as json_file: |
---|
174 | correct = json.load(json_file) |
---|
175 | self.assertEqual(len(result), len(correct)) |
---|
176 | for r, c in zip(result, correct): |
---|
177 | self.assertDictEqual(r, c) |
---|
178 | |
---|
179 | |
---|
180 | if __name__ == '__main__': |
---|
181 | unittest.main() |
---|