1 | # |
||
2 | # Copyright (C) 2013 Satoru SATOH <ssato @ redhat.com> |
||
3 | # License: MIT |
||
4 | # |
||
5 | # pylint: disable=missing-docstring, invalid-name, too-many-public-methods |
||
6 | from __future__ import absolute_import |
||
7 | |||
8 | import os |
||
9 | import os.path |
||
10 | import unittest |
||
11 | |||
12 | import anyconfig.cli as TT |
||
13 | import anyconfig.api |
||
14 | import anyconfig.template |
||
15 | import tests.common |
||
16 | import tests.api |
||
17 | |||
18 | from tests.common import CNF_0 |
||
19 | |||
20 | |||
21 | CNF_0_PATH = os.path.join(tests.common.selfdir(), "00-cnf.yml") |
||
22 | SCM_0_PATH = os.path.join(tests.common.selfdir(), "00-scm.yml") |
||
23 | CNF_TMPL_0 = tests.api.CNF_TMPL_1 |
||
24 | |||
25 | |||
26 | def _run(*args): |
||
27 | TT.main(["dummy"] + list(args)) |
||
28 | |||
29 | |||
30 | class Test_00(unittest.TestCase): |
||
31 | """ |
||
32 | |||
33 | >>> psr = TT.make_parser() |
||
34 | >>> assert isinstance(psr, TT.argparse.ArgumentParser) |
||
35 | >>> psr.parse_args([]) # doctest: +NORMALIZE_WHITESPACE |
||
36 | Namespace(args=None, atype=None, env=False, gen_schema=False, get=None, |
||
37 | ignore_missing=False, inputs=[], itype=None, list=False, |
||
38 | loglevel=0, merge='merge_dicts', otype=None, output=None, |
||
39 | query=None, schema=None, set=None, template=False, |
||
40 | validate=False) |
||
41 | """ |
||
42 | |||
43 | |||
44 | class RunTestBase(unittest.TestCase): |
||
45 | |||
46 | def run_and_check_exit_code(self, args=None, code=0, _not=False, |
||
47 | exc_cls=SystemExit): |
||
48 | try: |
||
49 | TT.main(["dummy"] + ([] if args is None else args)) |
||
50 | except exc_cls as exc: |
||
51 | ecode = getattr(exc, "code", 1) |
||
52 | (self.assertNotEqual if _not else self.assertEqual)(ecode, code) |
||
53 | |||
54 | |||
55 | class Test_10(RunTestBase): |
||
56 | infile = os.path.join(tests.common.selfdir(), "00-cnf.json") |
||
57 | |||
58 | def test_10_show_usage(self): |
||
59 | self.run_and_check_exit_code(["--help"]) |
||
60 | |||
61 | def test_20_wo_args(self): |
||
62 | self.run_and_check_exit_code(_not=True) |
||
63 | |||
64 | def test_30_wrong_option(self): |
||
65 | self.run_and_check_exit_code(["--wrong-option-xyz"], _not=True) |
||
66 | |||
67 | def test_40_list(self): |
||
68 | self.run_and_check_exit_code(["--list"]) |
||
69 | |||
70 | View Code Duplication | def test_50_unknown_input_file_type(self): |
|
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
71 | self.run_and_check_exit_code([__file__], _not=True) |
||
72 | |||
73 | def test_52_unknown_input_parser_type(self): |
||
74 | self.run_and_check_exit_code([__file__, "-I", "unknown_psr"], |
||
75 | _not=True) |
||
76 | |||
77 | def test_54_no_input_type_and_unknown_out_file_type(self): |
||
78 | self.run_and_check_exit_code([__file__, __file__ + '.un_ext'], |
||
79 | _not=True) |
||
80 | |||
81 | def test_60_unknown_out_file_type(self): |
||
82 | self.run_and_check_exit_code([self.infile, "-o", "t.unknown_ext"], |
||
83 | _not=True) |
||
84 | |||
85 | def test_62_unknown_out_parser_type(self): |
||
86 | self.run_and_check_exit_code([self.infile, "-O", "unknown_psr"], |
||
87 | _not=True) |
||
88 | |||
89 | |||
90 | class Test_20_Base(RunTestBase): |
||
91 | |||
92 | View Code Duplication | def setUp(self): |
|
0 ignored issues
–
show
|
|||
93 | self.workdir = tests.common.setup_workdir() |
||
94 | self.script = os.path.join(tests.common.selfdir(), |
||
95 | "..", "cli.py") |
||
96 | |||
97 | def tearDown(self): |
||
98 | tests.common.cleanup_workdir(self.workdir) |
||
99 | |||
100 | def _assert_run_and_exit(self, *args): |
||
101 | raised = False |
||
102 | try: |
||
103 | _run(*args) |
||
104 | except SystemExit: |
||
105 | raised = True |
||
106 | |||
107 | View Code Duplication | self.assertTrue(raised) |
|
0 ignored issues
–
show
|
|||
108 | |||
109 | |||
110 | class Test_30_single_input(Test_20_Base): |
||
111 | |||
112 | def test_10(self): |
||
113 | a = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
||
114 | |||
115 | infile = os.path.join(self.workdir, "a.json") |
||
116 | output = os.path.join(self.workdir, "b.json") |
||
117 | |||
118 | anyconfig.api.dump(a, infile) |
||
119 | self.assertTrue(os.path.exists(infile)) |
||
120 | |||
121 | TT.main(["dummy", "-o", output, infile]) |
||
122 | self.assertTrue(os.path.exists(output)) |
||
123 | |||
124 | def test_20_wo_input_type(self): |
||
125 | self._assert_run_and_exit("a.conf") |
||
126 | |||
127 | def test_30_w_get_option(self): |
||
128 | d = dict(name="a", a=dict(b=dict(c=[1, 2], d="C"))) |
||
129 | |||
130 | View Code Duplication | infile = os.path.join(self.workdir, "a.json") |
|
0 ignored issues
–
show
|
|||
131 | output = os.path.join(self.workdir, "b.json") |
||
132 | |||
133 | anyconfig.api.dump(d, infile) |
||
134 | self.assertTrue(os.path.exists(infile)) |
||
135 | |||
136 | TT.main(["dummy", "-o", output, "--get", "a.b", infile]) |
||
137 | self.assertTrue(os.path.exists(output)) |
||
138 | |||
139 | x = anyconfig.api.load(output) |
||
140 | self.assertEqual(x, d['a']['b']) |
||
141 | |||
142 | def test_31_w_get_option_failure(self): |
||
143 | (key, no_get_q) = ('a', "wrong_key_0.wrong_key_1") |
||
144 | infile = os.path.join(self.workdir, "a.json") |
||
145 | anyconfig.api.dump({key: "A"}, infile) |
||
146 | self.assertTrue(os.path.exists(infile)) |
||
147 | |||
148 | self.run_and_check_exit_code(["--get", no_get_q, infile], 1) |
||
149 | |||
150 | def test_32_w_set_option(self): |
||
151 | d = dict(name="a", a=dict(b=dict(c=[1, 2], d="C"))) |
||
152 | |||
153 | infile = os.path.join(self.workdir, "a.json") |
||
154 | output = os.path.join(self.workdir, "b.json") |
||
155 | |||
156 | anyconfig.api.dump(d, infile) |
||
157 | self.assertTrue(os.path.exists(infile)) |
||
158 | |||
159 | TT.main(["dummy", "-o", output, "--set", "a.b.d=E", infile]) |
||
160 | self.assertTrue(os.path.exists(output)) |
||
161 | |||
162 | ref = d.copy() |
||
163 | ref['a']['b']['d'] = 'E' |
||
164 | |||
165 | x = anyconfig.api.load(output) |
||
166 | self.assertEqual(x, ref) |
||
167 | |||
168 | def test_40_ignore_missing(self): |
||
169 | infile = os.path.join(os.curdir, "conf_file_should_not_exist.json") |
||
170 | assert not os.path.exists(infile) |
||
171 | |||
172 | self.assertFalse(TT.main(["dummy", "-O", "json", |
||
173 | View Code Duplication | "--ignore-missing", infile])) |
|
0 ignored issues
–
show
|
|||
174 | |||
175 | def test_50_w_schema(self): |
||
176 | (infile, scmfile) = (CNF_0_PATH, SCM_0_PATH) |
||
177 | output = os.path.join(self.workdir, "output.json") |
||
178 | self.run_and_check_exit_code(["--schema", scmfile, "--validate", |
||
179 | infile], 0) |
||
180 | self.run_and_check_exit_code(["--schema", scmfile, "-o", output, |
||
181 | infile], 0) |
||
182 | |||
183 | infile2 = os.path.join(self.workdir, "input.yml") |
||
184 | cnf = CNF_0.copy() |
||
185 | cnf["a"] = "aaa" # Validation should fail. |
||
186 | anyconfig.api.dump(cnf, infile2) |
||
187 | self.run_and_check_exit_code(["--schema", scmfile, "--validate", |
||
188 | infile2], 1) |
||
189 | |||
190 | def test_52_wo_schema(self): |
||
191 | self.run_and_check_exit_code(["--validate", CNF_0_PATH], 1) |
||
192 | |||
193 | def test_54_gen_schema_and_validate_with_it(self): |
||
194 | cnf = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
||
195 | infile = os.path.join(self.workdir, "cnf.json") |
||
196 | output = os.path.join(self.workdir, "out.yml") |
||
197 | anyconfig.api.dump(cnf, infile) |
||
198 | |||
199 | self.run_and_check_exit_code(["--gen-schema", "-o", output, infile], 0) |
||
200 | self.assertTrue(os.path.exists(output)) |
||
201 | self.run_and_check_exit_code(["--schema", output, "--validate", |
||
202 | infile], 0) |
||
203 | |||
204 | def test_60_w_arg_option(self): |
||
205 | a = dict(name="a", a=1, b=dict(b=[1, 2], c="C"), d=[1, 2]) |
||
206 | |||
207 | infile = os.path.join(self.workdir, "a.json") |
||
208 | output = os.path.join(self.workdir, "b.json") |
||
209 | |||
210 | anyconfig.api.dump(a, infile) |
||
211 | self.assertTrue(os.path.exists(infile)) |
||
212 | |||
213 | TT.main(["dummy", "-o", output, "-A", |
||
214 | "a:10;name:x;d:3,4", infile]) |
||
215 | self.assertTrue(os.path.exists(output)) |
||
216 | |||
217 | x = anyconfig.api.load(output) |
||
218 | |||
219 | self.assertNotEqual(a["name"], x["name"]) |
||
220 | self.assertNotEqual(a["a"], x["a"]) |
||
221 | self.assertNotEqual(a["d"], x["d"]) |
||
222 | |||
223 | self.assertEqual(x["name"], 'x') |
||
224 | self.assertEqual(x["a"], 10) |
||
225 | self.assertEqual(x["d"], [3, 4]) |
||
226 | |||
227 | def test_70_no_template(self): |
||
228 | a = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
||
229 | |||
230 | infile = os.path.join(self.workdir, "a.json") |
||
231 | output = os.path.join(self.workdir, "b.json") |
||
232 | |||
233 | anyconfig.api.dump(a, infile) |
||
234 | self.assertTrue(os.path.exists(infile)) |
||
235 | |||
236 | TT.main(["dummy", "-o", output, infile]) |
||
237 | self.assertTrue(os.path.exists(output)) |
||
238 | |||
239 | |||
240 | class Test_40_multi_inputs(Test_20_Base): |
||
241 | |||
242 | def test_10(self): |
||
243 | xs = [dict(a=1, ), |
||
244 | dict(b=dict(b=[1, 2], c="C")), ] |
||
245 | |||
246 | a = xs[0].copy() |
||
247 | a.update(xs[1]) |
||
248 | |||
249 | output = os.path.join(self.workdir, "b.json") |
||
250 | |||
251 | inputs = [] |
||
252 | for i in [0, 1]: |
||
253 | infile = os.path.join(self.workdir, "a%d.json" % i) |
||
254 | inputs.append(infile) |
||
255 | |||
256 | anyconfig.api.dump(xs[i], infile) |
||
257 | self.assertTrue(os.path.exists(infile)) |
||
258 | |||
259 | TT.main(["dummy", "-o", output] + inputs) |
||
260 | self.assertTrue(os.path.exists(output)) |
||
261 | |||
262 | def test_20_w_template(self): |
||
263 | if not anyconfig.template.SUPPORTED: |
||
264 | return |
||
265 | |||
266 | a = dict(name="a", a=1, b=dict(b=[1, 2], c="C")) |
||
267 | |||
268 | inputsdir = os.path.join(self.workdir, "in") |
||
269 | os.makedirs(inputsdir) |
||
270 | |||
271 | anyconfig.api.dump(a, os.path.join(inputsdir, "a0.yml")) |
||
272 | open(os.path.join(inputsdir, "a1.yml"), 'w').write(CNF_TMPL_0) |
||
273 | output = os.path.join(self.workdir, "b.json") |
||
274 | |||
275 | TT.main(["dummy", "--template", "-o", output, |
||
276 | os.path.join(inputsdir, "*.yml")]) |
||
277 | self.assertTrue(os.path.exists(output)) |
||
278 | |||
279 | def test_30_w_template(self): |
||
280 | if not anyconfig.template.SUPPORTED: |
||
281 | return |
||
282 | |||
283 | curdir = tests.common.selfdir() |
||
284 | |||
285 | infile = os.path.join(curdir, "*template-c*.yml") |
||
286 | output = os.path.join(self.workdir, "output.yml") |
||
287 | |||
288 | TT.main(["dummy", "--template", "-o", output, infile]) |
||
289 | |||
290 | |||
291 | class Test_50_others_w_input(Test_20_Base): |
||
292 | |||
293 | def setUp(self): |
||
294 | super(Test_50_others_w_input, self).setUp() |
||
295 | dic = dict(name="a", a=1, b=dict(b=[1, 2], c="C"), d=[1, 2]) |
||
296 | self.infile = os.path.join(self.workdir, "a.json") |
||
297 | anyconfig.api.dump(dic, self.infile) |
||
298 | |||
299 | def test_10_output_wo_output_option_w_otype(self): |
||
300 | self.run_and_check_exit_code(["--otype", "json", self.infile]) |
||
301 | |||
302 | def test_12_output_wo_output_option_and_otype_w_itype(self): |
||
303 | self.run_and_check_exit_code(["--itype", "json", self.infile]) |
||
304 | |||
305 | def test_20_no_out_dumper(self): |
||
306 | outfile = os.path.join(self.workdir, "out.conf") |
||
307 | self.run_and_check_exit_code(["-o", outfile, self.infile], 1) |
||
308 | |||
309 | def test_22_no_out_dumper_nor_itype(self): |
||
310 | infile = self.infile.replace(".json", ".conf") |
||
311 | outfile = os.path.join(self.workdir, "out.conf") |
||
312 | self.run_and_check_exit_code(["-o", outfile, infile], 1) |
||
313 | |||
314 | def test_30_w_query_option(self): |
||
315 | self.run_and_check_exit_code(["-Q", "b.b[::-1]", self.infile], 0) |
||
316 | |||
317 | |||
318 | class Test_50_others_wo_input(Test_20_Base): |
||
319 | |||
320 | def test_30_no_itype_and_otype(self): |
||
321 | outfile = os.path.join(self.workdir, "out.conf") |
||
322 | self.run_and_check_exit_code(["-o", outfile, "in.conf"], 1) |
||
323 | |||
324 | def test_40_no_inputs__w_env_option(self): |
||
325 | output = os.path.join(self.workdir, "out.json") |
||
326 | self.run_and_check_exit_code(["--env", "-o", output], 0) |
||
327 | data = anyconfig.api.load(output) |
||
328 | |||
329 | for env_var, env_val in os.environ.items(): |
||
330 | self.assertTrue(env_var in data) |
||
331 | self.assertEqual(env_val, os.environ[env_var]) |
||
332 | |||
333 | # vim:sw=4:ts=4:et: |
||
334 |