Completed
Push — master ( 98e1d4...d1821a )
by Satoru
01:27
created

Test_40_multi_load_with_strategies   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 51
Duplicated Lines 41.18 %

Importance

Changes 5
Bugs 1 Features 0
Metric Value
c 5
b 1
f 0
dl 21
loc 51
rs 10
wmc 7

6 Methods

Rating   Name   Duplication   Size   Complexity  
A test_30_merge_with_replace() 0 4 1
A test_60_wrong_merge_strategy() 0 8 2
A test_10_default_merge_strategy() 0 7 1
A test_40_merge_wo_replace() 0 4 1
A _check_multi_load_with_strategy() 15 15 1
A test_20_merge_dicts_and_lists() 6 6 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
#
2
# Copyright (C) 2012 - 2017 Satoru SATOH <ssato at redhat.com>
3
# License: MIT
4
#
5
# pylint: disable=missing-docstring, invalid-name, no-member
6
from __future__ import absolute_import
7
8
import copy
9
import logging
10
import io
11
import os
12
import os.path
13
import unittest
14
15
import anyconfig.api as TT
16
import anyconfig.backends
17
import anyconfig.compat
18
import anyconfig.dicts
19
import anyconfig.template
20
import tests.common
21
22
from tests.common import CNF_0, SCM_0, dicts_equal
23
24
25
# suppress logging messages.
26
TT.LOGGER.setLevel(logging.CRITICAL)
27
28
CNF_TMPL_0 = """name: {{ name|default('a') }}
29
a: {{ a }}
30
b:
31
    b:
32
      {% for x in b.b -%}
33
      - {{ x }}
34
      {% endfor %}
35
    c: {{ b.c }}
36
"""
37
38
CNF_TMPL_1 = """a: {{ a }}
39
b:
40
    b:
41
        {% for x in b.b -%}
42
        - {{ x }}
43
        {% endfor %}
44
    c: {{ b.c }}
45
46
name: {{ name }}
47
"""
48
49
CNF_TMPL_2 = """a: {{ a }}
50
b:
51
    b:
52
        {% for x in b.b -%}
53
        - {{ x }}
54
        {% endfor %}
55
    d: {{ b.d }}
56
e: 0
57
"""
58
59
CNF_XML_1 = {'config': {'@attrs': {'name': 'foo'},
60
                        'a': '0',
61
                        'b': {'@attrs': {'id': 'b0'}, '@text': 'bbb'},
62
                        'c': None,
63
                        'sect0': {'d': 'x, y, z'},
64
                        'list1': [{'item': '0'}, {'item': '1'},
65
                                  {'item': '2'}],
66
                        'list2': {'@attrs': {'id': 'list2'},
67
                                  '@children': [{'item': 'i'},
68
                                                {'item': 'j'}]}}}
69
70
NULL_CNTNR = TT.anyconfig.dicts.convert_to({})
71
72
73
class MyODict(anyconfig.compat.OrderedDict):
74
    pass
75
76
77
def _is_file_object(obj):
78
    try:
79
        return isinstance(obj, file)
80
    except NameError:  # python 3.x
81
        return isinstance(obj, io.IOBase)
82
83
84
class Test_10_find_loader(unittest.TestCase):
85
86
    def _assert_isinstance(self, obj, cls, msg=False):
87
        self.assertTrue(isinstance(obj, cls), msg or repr(obj))
88
89
    def test_10_find_loader__w_given_parser_type(self):
90
        cpath = "dummy.conf"
91
        for psr in anyconfig.backends.PARSERS:
92
            self._assert_isinstance(TT.find_loader(cpath, psr.type()), psr)
93
94
    def test_12_find_loader__w_given_parser_instance(self):
95
        cpath = "dummy.conf"
96
        for psr in anyconfig.backends.PARSERS:
97
            self._assert_isinstance(TT.find_loader(cpath, psr()), psr)
98
99
    def test_20_find_loader__by_file(self):
100
        for psr in anyconfig.backends.PARSERS:
101
            for ext in psr.extensions():
102
                self._assert_isinstance(TT.find_loader("dummy." + ext), psr,
103
                                        "ext=%s, psr=%r" % (ext, psr))
104
105
    def test_30_find_loader__unknown_parser_type(self):
106
        self.assertRaises(TT.UnknownParserTypeError,
107
                          TT.find_loader, "a.cnf", "type_not_exist")
108
109
    def test_40_find_loader__unknown_file_type(self):
110
        self.assertRaises(TT.UnknownFileTypeError,
111
                          TT.find_loader, "dummy.ext_not_found")
112
113
114
class TestBase(unittest.TestCase):
115
116
    cnf = dic = dict(a=1, b=dict(b=[0, 1], c="C"), name="a")
117
    upd = dict(a=2, b=dict(b=[1, 2, 3, 4, 5], d="D"), e=0)
118
119
    def assert_dicts_equal(self, dic, ref, ordered=False):
120
        self.assertTrue(dicts_equal(dic, ref, ordered=ordered),
121
                        "%r\nvs.\n%r" % (dic, ref))
122
123
124
class Test_20_dumps_and_loads(TestBase):
125
126
    def test_30_dumps_and_loads(self):
127
        res = TT.loads(TT.dumps(self.cnf, "json"), "json")
128
        self.assert_dicts_equal(res, self.cnf)
129
130
    def test_30_dumps_and_loads__w_options(self):
131
        res = TT.loads(TT.dumps(self.cnf, "json", indent=2), "json",
132
                       ensure_ascii=False)
133
        self.assert_dicts_equal(res, self.cnf)
134
135
    def test_40_loads_wo_type(self):
136
        cnf_s = "requires:bash,zsh"
137
        self.assertTrue(TT.loads(cnf_s) is None)
138
139
    def test_42_loads_w_type_not_exist(self):
140
        a_s = "requires:bash,zsh"
141
        self.assertRaises(TT.UnknownParserTypeError,
142
                          TT.loads, a_s, "type_not_exist")
143
144
    def test_44_loads_w_type__template(self):
145
        if not anyconfig.template.SUPPORTED:
146
            return
147
148
        a_s = "requires: [{{ requires|join(', ') }}]"
149
        reqs = dict(requires=["bash", "zsh"])
150
151
        a1 = TT.loads(a_s, ac_parser="yaml", ac_template=True,
152
                      ac_context=reqs)
153
154
        self.assertEqual(a1["requires"], reqs["requires"])
155
156 View Code Duplication
    def test_46_loads_w_type__broken_template(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
157
        if not anyconfig.template.SUPPORTED:
158
            return
159
160
        a = dict(requires="{% }}", )
161
        a_s = 'requires: "{% }}"'
162
        a1 = TT.loads(a_s, ac_parser="yaml", ac_template=True,
163
                      ac_context={})
164
165
        self.assertEqual(a1["requires"], a["requires"])
166
167
    def test_48_loads_w_validation(self):
168
        cnf_s = TT.dumps(CNF_0, "json")
169
        scm_s = TT.dumps(SCM_0, "json")
170
        cnf_2 = TT.loads(cnf_s, ac_parser="json", ac_context={},
171
                         ac_validate=scm_s)
172
173
        self.assertEqual(cnf_2["name"], CNF_0["name"])
174
        self.assertEqual(cnf_2["a"], CNF_0["a"])
175
        self.assertEqual(cnf_2["b"]["b"], CNF_0["b"]["b"])
176
        self.assertEqual(cnf_2["b"]["c"], CNF_0["b"]["c"])
177
178
    def test_49_loads_w_validation_error(self):
179
        cnf_s = """{"a": "aaa"}"""
180
        scm_s = TT.dumps(SCM_0, "json")
181
        cnf_2 = TT.loads(cnf_s, ac_parser="json", ac_schema=scm_s)
182
        self.assertTrue(cnf_2 is None, cnf_2)
183
184
185
class TestBaseWithIO(TestBase):
186
187
    def setUp(self):
188
        self.workdir = tests.common.setup_workdir()
189
        self.a_path = os.path.join(self.workdir, "a.json")
190
        self.exp = copy.deepcopy(self.dic)
191
192
    def tearDown(self):
193
        tests.common.cleanup_workdir(self.workdir)
194
195
196
class Test_30_single_load(TestBaseWithIO):
197
198
    def test_10_dump_and_single_load(self):
199
        TT.dump(self.cnf, self.a_path)
200
        self.assertTrue(os.path.exists(self.a_path))
201
202
        res = TT.single_load(self.a_path)
203
        self.assert_dicts_equal(res, self.cnf)
204
205
    def test_11_dump_and_single_load__to_from_stream(self):
206
        TT.dump(self.cnf, TT.open(self.a_path, mode='w'))
207
        self.assertTrue(os.path.exists(self.a_path))
208
209
        res = TT.single_load(TT.open(self.a_path))
210
        self.assert_dicts_equal(res, self.cnf)
211
212
    def test_12_dump_and_single_load__no_parser(self):
213
        self.assertRaises(TT.UnknownFileTypeError,
214
                          TT.single_load, "dummy.ext_not_exist")
215
216
    def test_14_single_load__ignore_missing(self):
217
        cpath = os.path.join(os.curdir, "conf_file_should_not_exist")
218
        assert not os.path.exists(cpath)
219
220
        self.assertEqual(TT.single_load(cpath, "ini", ignore_missing=True),
221
                         NULL_CNTNR)
222
223
    def test_15_single_load__fail_to_render_template(self):
224
        if not anyconfig.template.SUPPORTED:
225
            return
226
227
        cnf_s = "name: '{{ name'"  # Should cause template renering error.
228
        cpath = os.path.join(self.workdir, "a.yaml")
229
        TT.open(cpath, mode='w').write(cnf_s)
230
231
        cnf = TT.single_load(cpath, ac_template=True, ac_context=dict(a=1))
232
        self.assertEqual(cnf["name"], "{{ name")
233
234
    def test_16_single_load__template(self):
235
        if not anyconfig.template.SUPPORTED:
236
            return
237
238
        cpath = os.path.join(self.workdir, "a.yaml")
239
        TT.open(cpath, mode='w').write(CNF_TMPL_0)
240
241
        cnf = TT.single_load(cpath, ac_template=True, ac_context=self.cnf)
242
        self.assert_dicts_equal(cnf, self.cnf)
243
244
        spath = os.path.join(self.workdir, "scm.json")
245
        TT.dump(dict(type="integer"), spath)  # Validation should fail.
246
247
        cnf2 = TT.single_load(cpath, ac_template=True, ac_context=self.cnf,
248
                              ac_schema=spath)
249
        self.assertTrue(cnf2 is None)
250
251
    def test_18_single_load__templates(self):
252
        if not anyconfig.template.SUPPORTED:
253
            return
254
255
        a_path = os.path.join(self.workdir, "a.yml")
256
        b_path = os.path.join(self.workdir, "b.yml")
257
        a2_path = os.path.join(self.workdir, "x/y/z", "a.yml")
258
259
        open(a_path, 'w').write("{% include 'b.yml' %}")
260
        open(b_path, 'w').write(CNF_TMPL_0)
261
        os.makedirs(os.path.dirname(a2_path))
262
        open(a2_path, 'w').write("a: 'xyz'")
263
264
        cnf1 = TT.single_load(a_path, ac_template=True, ac_context=self.cnf)
265
        self.assertTrue(dicts_equal(self.cnf, cnf1), str(cnf1))
266
267
        cnf2 = TT.single_load(a2_path, ac_template=True)
268
        self.assertEqual(cnf2["a"], "xyz")
269
270
    def test_19_dump_and_single_load_with_validation(self):
271
        cnf = CNF_0
272
        scm = SCM_0
273
274
        cnf_path = os.path.join(self.workdir, "cnf_19.json")
275
        scm_path = os.path.join(self.workdir, "scm_19.json")
276
277
        TT.dump(cnf, cnf_path)
278
        TT.dump(scm, scm_path)
279
        self.assertTrue(os.path.exists(cnf_path))
280
        self.assertTrue(os.path.exists(scm_path))
281
282
        cnf_1 = TT.single_load(cnf_path, ac_schema=scm_path)
283
284
        self.assertFalse(cnf_1 is None)  # Validation should succeed.
285
        self.assertTrue(dicts_equal(cnf_1, cnf), cnf_1)
286
287
        cnf_2 = cnf.copy()
288
        cnf_2["a"] = "aaa"  # It's type should be integer not string.
289
        cnf_2_path = os.path.join(self.workdir, "cnf_19_2.json")
290
        TT.dump(cnf_2, cnf_2_path)
291
        self.assertTrue(os.path.exists(cnf_2_path))
292
293
        cnf_3 = TT.single_load(cnf_2_path, ac_schema=scm_path)
294
        self.assertTrue(cnf_3 is None)  # Validation should fail.
295
296
    def test_20_dump_and_single_load__w_ordered_option(self):
297
        TT.dump(self.cnf, self.a_path)
298
        self.assertTrue(os.path.exists(self.a_path))
299
300
        # It works w/ JSON backend but some backend cannot keep the order of
301
        # items and the tests might fail.
302
        res = TT.single_load(self.a_path, ac_ordered=True)
303
        self.assert_dicts_equal(res, self.cnf, ordered=True)
304
        self.assertTrue(isinstance(res, anyconfig.compat.OrderedDict))
305
306
    def test_22_dump_and_single_load__w_ac_dict_option(self):
307
        TT.dump(self.cnf, self.a_path)
308
        self.assertTrue(os.path.exists(self.a_path))
309
310
        res = TT.single_load(self.a_path, ac_dict=MyODict)
311
        self.assert_dicts_equal(res, self.cnf, ordered=True)
312
        self.assertTrue(isinstance(res, MyODict))
313
314
315
class Test_32_single_load(unittest.TestCase):
316
317
    cnf = CNF_XML_1
318
319
    def setUp(self):
320
        self.workdir = tests.common.setup_workdir()
321
322
    def tearDown(self):
323
        tests.common.cleanup_workdir(self.workdir)
324
325
    def _load_and_dump_with_opened_files(self, filename, rmode='r', wmode='w',
326
                                         **oopts):
327
        cpath = os.path.join(self.workdir, filename)
328
329
        with TT.open(cpath, 'w', **oopts) as out:
330
            TT.dump(self.cnf, out)
331
            self.assertTrue(_is_file_object(out))
332
            self.assertEqual(out.mode, wmode)
333
334
        with TT.open(cpath, 'rb', **oopts) as inp:
335
            cnf1 = TT.single_load(inp)
336
            self.assertTrue(_is_file_object(inp))
337
            self.assertEqual(inp.mode, rmode)
338
            cpair = (self.cnf, cnf1)
339
            self.assertTrue(dicts_equal(*cpair), "%r vs. %r" % cpair)
340
341
    def test_10_open_json_file(self):
342
        self._load_and_dump_with_opened_files("a.json")
343
344
    def test_20_open_xml_file(self):
345
        if "xml" in anyconfig.backends.list_types():
346
            self._load_and_dump_with_opened_files("a.xml", 'rb', 'wb')
347
348
    def test_30_open_bson_file(self):
349
        if "bson" in anyconfig.backends.list_types():
350
            self._load_and_dump_with_opened_files("a.bson", 'rb', 'wb')
351
352
    def test_40_open_yaml_file(self):
353
        if "yaml" in anyconfig.backends.list_types():
354
            self._load_and_dump_with_opened_files("a.yaml")
355
            self._load_and_dump_with_opened_files("a.yml")
356
357
358
class TestBaseWithIOMultiFiles(TestBaseWithIO):
359
360
    def setUp(self):
361
        super(TestBaseWithIOMultiFiles, self).setUp()
362
        self.b_path = os.path.join(self.workdir, "b.json")
363
        self.g_path = os.path.join(self.workdir, "*.json")
364
365
        exp = copy.deepcopy(self.upd)  # Assume MS_DICTS strategy was used.
366
        exp["b"]["c"] = self.dic["b"]["c"]
367
        exp["name"] = self.dic["name"]
368
        self.exp = exp
369
370
371
class Test_40_multi_load_with_strategies(TestBaseWithIOMultiFiles):
372
373 View Code Duplication
    def _check_multi_load_with_strategy(self, exp, merge=TT.MS_DICTS):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
374
        TT.dump(self.dic, self.a_path)
375
        TT.dump(self.upd, self.b_path)
376
377
        self.assertTrue(os.path.exists(self.a_path))
378
        self.assertTrue(os.path.exists(self.b_path))
379
380
        res0 = TT.multi_load(self.g_path, ac_merge=merge)
381
        res1 = TT.multi_load([self.g_path, self.b_path], ac_merge=merge)
382
383
        self.assertTrue(res0)
384
        self.assertTrue(res1)
385
386
        self.assert_dicts_equal(res0, exp)
387
        self.assert_dicts_equal(res1, exp)
388
389
    def test_10_default_merge_strategy(self):
390
        exp = copy.deepcopy(self.upd)
391
        exp["b"]["c"] = self.dic["b"]["c"]
392
        exp["name"] = self.dic["name"]
393
394
        self._check_multi_load_with_strategy(exp, merge=None)
395
        self._check_multi_load_with_strategy(exp)
396
397 View Code Duplication
    def test_20_merge_dicts_and_lists(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
398
        exp = copy.deepcopy(self.upd)
399
        exp["b"]["b"] = [0] + self.upd["b"]["b"]
400
        exp["b"]["c"] = self.dic["b"]["c"]
401
        exp["name"] = self.dic["name"]
402
        self._check_multi_load_with_strategy(exp, merge=TT.MS_DICTS_AND_LISTS)
403
404
    def test_30_merge_with_replace(self):
405
        exp = copy.deepcopy(self.upd)
406
        exp["name"] = self.dic["name"]
407
        self._check_multi_load_with_strategy(exp, merge=TT.MS_REPLACE)
408
409
    def test_40_merge_wo_replace(self):
410
        exp = copy.deepcopy(self.dic)
411
        exp["e"] = self.upd["e"]
412
        self._check_multi_load_with_strategy(exp, merge=TT.MS_NO_REPLACE)
413
414
    def test_60_wrong_merge_strategy(self):
415
        cpath = os.path.join(self.workdir, "a.json")
416
        TT.dump(dict(a=1, b=2), cpath)
417
        try:
418
            TT.multi_load([cpath, cpath], ac_merge="merge_st_not_exist")
419
            raise RuntimeError("Wrong merge strategy was not handled!")
420
        except ValueError:
421
            self.assertTrue(1 == 1)  # To suppress warn of pylint.
422
423
424
class Test_42_multi_load(TestBaseWithIOMultiFiles):
425
426
    def test_10_multi_load__empty_path_list(self):
427
        self.assertEqual(TT.multi_load([]), NULL_CNTNR)
428
429
    def test_20_dump_and_multi_load__mixed_file_types(self):
430
        c_path = os.path.join(self.workdir, "c.yml")
431
432
        TT.dump(self.dic, self.a_path)  # JSON
433
        try:
434
            TT.dump(self.upd, c_path)  # YAML
435
        except (TT.UnknownParserTypeError, TT.UnknownFileTypeError):
436
            return  # YAML backend is not available in this env.
437
438
        self.assertTrue(os.path.exists(self.a_path))
439
        self.assertTrue(os.path.exists(c_path))
440
441
        res = TT.multi_load([self.a_path, c_path])
442
        self.assert_dicts_equal(res, self.exp)
443
444
    def test_30_dump_and_multi_load__to_from_stream(self):
445
        TT.dump(self.dic, self.a_path)
446
        TT.dump(self.upd, self.b_path)
447
448
        res = TT.multi_load([TT.open(self.a_path), TT.open(self.b_path)])
449
        self.assert_dicts_equal(res, self.exp)
450
451
    def test_40_multi_load__ignore_missing(self):
452
        cpath = os.path.join(os.curdir, "conf_file_should_not_exist")
453
        assert not os.path.exists(cpath)
454
455
        self.assertEqual(TT.multi_load([cpath], ac_parser="ini",
456
                                       ignore_missing=True),
457
                         NULL_CNTNR)
458
459
    def test_50_multi_load__templates(self):
460
        if not anyconfig.template.SUPPORTED:
461
            return
462
463
        ctx = self.dic.copy()
464
        TT.merge(ctx, self.upd, ac_merge=TT.MS_DICTS)
465
466
        a_path = self.a_path.replace(".json", ".yml")
467
        b_path = self.b_path.replace(".json", ".yml")
468
        g_path = self.g_path.replace(".json", ".yml")
469
470
        TT.open(a_path, mode='w').write(CNF_TMPL_1)
471
        TT.open(b_path, mode='w').write(CNF_TMPL_2)
472
473
        opts = dict(ac_merge=TT.MS_DICTS, ac_template=True, ac_context=ctx)
474
        try:
475
            res0 = TT.multi_load(g_path, **opts)
476
            res1 = TT.multi_load([g_path, b_path], **opts)
477
        except (TT.UnknownParserTypeError, TT.UnknownFileTypeError):
478
            return
479
480
        self.assert_dicts_equal(res0, self.exp)
481
        self.assert_dicts_equal(res1, self.exp)
482
483
    def test_60_multi_load__w_ac_dict_option(self):
484
        TT.dump(self.dic, self.a_path)
485
        TT.dump(self.upd, self.b_path)
486
487
        res = TT.multi_load(self.g_path, ac_dict=MyODict)
488
        self.assert_dicts_equal(res, self.exp)
489
        self.assertTrue(isinstance(res, MyODict))
490
491
492
class Test_50_load_and_dump(TestBaseWithIOMultiFiles):
493
494 View Code Duplication
    def test_30_dump_and_load(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
495
        TT.dump(self.dic, self.a_path)
496
        TT.dump(self.upd, self.b_path)
497
498
        self.assertTrue(os.path.exists(self.a_path))
499
        self.assertTrue(os.path.exists(self.b_path))
500
501
        res = TT.load(self.a_path)
502
        self.assert_dicts_equal(res, self.dic)
503
504
        res = TT.load(self.g_path)
505
        self.assert_dicts_equal(res, self.exp)
506
507
        res = TT.load([self.a_path, self.b_path])
508
        self.assert_dicts_equal(res, self.exp)
509
510
    def test_31_dump_and_load__to_from_stream(self):
511
        with TT.open(self.a_path, mode='w') as strm:
512
            TT.dump(self.dic, strm)
513
514
        self.assertTrue(os.path.exists(self.a_path))
515
516
        with TT.open(self.a_path) as strm:
517
            res = TT.load(strm, ac_parser="json")
518
            self.assert_dicts_equal(res, self.dic)
519
520
    def test_32_dump_and_load__w_options(self):
521
        TT.dump(self.dic, self.a_path, indent=2)
522
        self.assertTrue(os.path.exists(self.a_path))
523
524
        TT.dump(self.upd, self.b_path, indent=2)
525
        self.assertTrue(os.path.exists(self.b_path))
526
527
        res = TT.load(self.a_path, parse_int=int)
528
        dic = copy.deepcopy(self.dic)
529
        self.assert_dicts_equal(res, dic)
530
531
        res = TT.load(self.g_path, parse_int=int)
532
        exp = copy.deepcopy(self.exp)
533
        self.assert_dicts_equal(res, exp)
534
535
        res = TT.load([self.a_path, self.b_path], parse_int=int)
536
        exp = copy.deepcopy(self.exp)
537
        self.assert_dicts_equal(res, exp)
538
539
    def test_34_load__ignore_missing(self):
540
        cpath = os.path.join(os.curdir, "conf_file_should_not_exist")
541
        assert not os.path.exists(cpath)
542
543
        self.assertEqual(TT.load([cpath], ac_parser="ini",
544
                                 ignore_missing=True),
545
                         NULL_CNTNR)
546
547
    def test_36_load_w_validation(self):
548
        cnf_path = os.path.join(self.workdir, "cnf.json")
549
        scm_path = os.path.join(self.workdir, "scm.json")
550
        TT.dump(CNF_0, cnf_path)
551
        TT.dump(SCM_0, scm_path)
552
553
        cnf_2 = TT.load(cnf_path, ac_context={}, ac_validate=scm_path)
554
555
        self.assertEqual(cnf_2["name"], CNF_0["name"])
556
        self.assertEqual(cnf_2["a"], CNF_0["a"])
557
        self.assertEqual(cnf_2["b"]["b"], CNF_0["b"]["b"])
558
        self.assertEqual(cnf_2["b"]["c"], CNF_0["b"]["c"])
559
560
    def test_38_load_w_validation_yaml(self):
561
        cnf_path = os.path.join(self.workdir, "cnf.yml")
562
        scm_path = os.path.join(self.workdir, "scm.yml")
563
        TT.dump(CNF_0, cnf_path)
564
        TT.dump(SCM_0, scm_path)
565
566
        cnf_2 = TT.load(cnf_path, ac_context={}, ac_validate=scm_path)
567
568
        self.assertEqual(cnf_2["name"], CNF_0["name"])
569
        self.assertEqual(cnf_2["a"], CNF_0["a"])
570
        self.assertEqual(cnf_2["b"]["b"], CNF_0["b"]["b"])
571
        self.assertEqual(cnf_2["b"]["c"], CNF_0["b"]["c"])
572
573
    def test_39_single_load__w_validation(self):
574
        (cnf, scm) = (CNF_0, SCM_0)
575
        cpath = os.path.join(self.workdir, "cnf.json")
576
        spath = os.path.join(self.workdir, "scm.json")
577
578
        TT.dump(cnf, cpath)
579
        TT.dump(scm, spath)
580
581
        cnf1 = TT.single_load(cpath, ac_schema=spath)
582
        self.assert_dicts_equal(cnf, cnf1)
583
584
    def test_40_load_w_query(self):
585
        cnf_path = os.path.join(self.workdir, "cnf.json")
586
        TT.dump(CNF_0, cnf_path)
587
588
        try:
589
            if TT.query.jmespath:
590
                self.assertEqual(TT.load(cnf_path, ac_query="a"), 1)
591
                self.assertEqual(TT.load(cnf_path, ac_query="b.b"), [1, 2])
592
                self.assertEqual(TT.load(cnf_path, ac_query="b.b[1]"), 2)
593
                self.assertEqual(TT.load(cnf_path, ac_query="b.b[1:]"), [2])
594
                self.assertEqual(TT.load(cnf_path, ac_query="b.b[::-1]"),
595
                                 [2, 1])
596
                self.assertEqual(TT.load(cnf_path, ac_query="length(b.b)"), 2)
597
        except (NameError, AttributeError):
598
            pass  # jmespath is not available.
599
600
# vim:sw=4:ts=4:et:
601