Passed
Branch master (9e8f7a)
by Oleksandr
01:29
created

tests.test_core   F

Complexity

Total Complexity 65

Size/Duplication

Total Lines 866
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 65
eloc 561
dl 0
loc 866
rs 3.2
c 0
b 0
f 0

59 Methods

Rating   Name   Duplication   Size   Complexity  
A GrouppingTestCase.test_group_as_container() 0 9 1
A ConstantsTestCase.test_has_name() 0 7 1
A ConstantsTestCase.test_len() 0 8 1
A ConstantsTestCase.test_iternames() 0 16 1
A ConstantsTestCase.test_iterconstants() 0 16 1
A GrouppingTestCase.test_group_iter() 0 17 1
A ConstantsTestCase.test_constant_class() 0 17 1
A ConstantsTestCase.test_name() 0 6 1
A GrouppingTestCase.test_group_values() 0 19 1
A GrouppingTestCase.test_container_names() 0 10 1
A GrouppingTestCase.test_group_names() 0 19 1
A ConstantsTestCase.test_values() 0 16 1
A GrouppingTestCase.test_invalid_group() 0 14 2
A ConstantsTestCase.test_get_item_missing() 0 12 2
A GrouppingTestCase.test_group_contains() 0 10 1
A SimpleConstantTestCase.test_repr() 0 6 1
A GrouppingTestCase.test_group_full_name() 0 6 1
A ConstantsTestCase.test_full_name() 0 6 1
A SimpleConstantTestCase.test_name() 0 6 1
A GrouppingTestCase.test_group_len() 0 11 1
A GrouppingTestCase.test_to_primitive() 0 23 1
A GrouppingTestCase.test_group_repr() 0 6 1
A ConstantsTestCase.test_get_item() 0 6 1
A GrouppingTestCase.test_group_itervalues() 0 19 1
A GrouppingTestCase.test_group_has_name() 0 10 1
A ConstantsTestCase.test_to_primitive() 0 15 1
A GrouppingTestCase.test_group_member_full_name() 0 9 1
A ConstantsTestCase.test_mixed_constant_classes() 0 14 1
A ConstantsTestCase.test_reuse_of_constant() 0 14 2
A GrouppingTestCase.test_group_container() 0 9 1
A ConstantsTestCase.test_duplicates() 0 9 1
A ConstantsTestCase.test_container_instantiation() 0 9 2
A GrouppingTestCase.test_group_iterconstants() 0 19 1
A GrouppingTestCase.test_get_from_container() 0 9 1
A ConstantsTestCase.test_names() 0 16 1
A ConstantsTestCase.test_items() 0 16 1
A GrouppingTestCase.test_group_items() 0 19 1
A GrouppingTestCase.test_group_get_item() 0 9 1
A SimpleConstantTestCase.test_container() 0 6 1
A GrouppingTestCase.test_group_iteritems() 0 19 1
A SimpleConstantTestCase.test_full_name() 0 6 1
A ConstantsTestCase.test_iteritems() 0 16 1
A ConstantClassMixinTestCase.test_constant_class_mixin_factory() 0 15 1
A ConstantsTestCase.test_invalid_constant_class() 0 11 2
A ConstantsTestCase.test_itervalues() 0 16 1
A ConstantsTestCase.test_unbound_constant() 0 21 1
A ConstantsTestCase.test_iter() 0 14 1
A GrouppingTestCase.test_group_name() 0 6 1
A ConstantsTestCase.test_picking() 0 5 1
A GrouppingTestCase.test_group_get_item_missing() 0 14 2
A SimpleConstantTestCase.test_to_primitive() 0 8 1
A ConstantsTestCase.test_get() 0 7 1
A GrouppingTestCase.test_group_get() 0 10 1
A ConstantsTestCase.test_repr() 0 6 1
A ConstantsTestCase.test_different_imports() 0 8 1
A GrouppingTestCase.test_group_constants() 0 19 1
A ConstantsTestCase.test_contains() 0 7 1
A ConstantsTestCase.test_constants() 0 15 1
A GrouppingTestCase.test_group_iternames() 0 19 1

How to fix   Complexity   

Complexity

Complex classes like tests.test_core often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import pickle
2
import sys
3
import unittest
4
5
from collections.abc import Iterable
6
from collections.abc import Iterator
7
8
from pathlib import Path
9
10
from candv.core import Constants
11
from candv.core import SimpleConstant
12
from candv.core import with_constant_class
13
14
from candv.exceptions import CandvConstantAlreadyBoundError
15
from candv.exceptions import CandvContainerMisusedError
16
from candv.exceptions import CandvInvalidConstantClass
17
from candv.exceptions import CandvInvalidGroupMemberError
18
from candv.exceptions import CandvMissingConstantError
19
20
21
class ConstantsTestCase(unittest.TestCase):
22
23
  def test_container_instantiation(self):
24
25
    with self.assertRaises(CandvContainerMisusedError) as cm:
26
      Constants()
27
28
    self.assertEqual(
29
      cm.exception.args[0],
30
      (
31
        "\"<constants container 'Constants'>\" cannot be instantiated: "
32
        "constant containers are not designed for that"
33
      ),
34
    )
35
36
  def test_name(self):
37
38
    class FOO(Constants):
39
      ...
40
41
    self.assertEqual(FOO.name, "FOO")
42
43
  def test_full_name(self):
44
45
    class FOO(Constants):
46
      ...
47
48
    self.assertEqual(FOO.full_name, "FOO")
49
50
  def test_repr(self):
51
52
    class FOO(Constants):
53
      ...
54
55
    self.assertEqual(repr(FOO), "<constants container 'FOO'>")
56
57
  def test_names(self):
58
59
    class FOO(Constants):
60
      CONSTANT_2 = SimpleConstant()
61
      CONSTANT_3 = SimpleConstant()
62
      CONSTANT_1 = SimpleConstant()
63
64
    names = FOO.names()
65
66
    self.assertIsInstance(names, list)
67
    self.assertEqual(
68
      names,
69
      [
70
        "CONSTANT_2",
71
        "CONSTANT_3",
72
        "CONSTANT_1",
73
      ],
74
    )
75
76
  def test_iternames(self):
77
78
    class FOO(Constants):
79
      CONSTANT_2 = SimpleConstant()
80
      CONSTANT_3 = SimpleConstant()
81
      CONSTANT_1 = SimpleConstant()
82
83
    names = FOO.iternames()
84
85
    self.assertIsInstance(names, Iterator)
86
    self.assertEqual(
87
      list(names),
88
      [
89
        "CONSTANT_2",
90
        "CONSTANT_3",
91
        "CONSTANT_1",
92
      ],
93
    )
94
95
  def test_values(self):
96
97
    class FOO(Constants):
98
      CONSTANT_2 = SimpleConstant()
99
      CONSTANT_3 = SimpleConstant()
100
      CONSTANT_1 = SimpleConstant()
101
102
    values = FOO.values()
103
104
    self.assertIsInstance(values, list)
105
    self.assertEqual(
106
      values,
107
      [
108
        FOO.CONSTANT_2,
109
        FOO.CONSTANT_3,
110
        FOO.CONSTANT_1,
111
      ],
112
    )
113
114
  def test_itervalues(self):
115
116
    class FOO(Constants):
117
      CONSTANT_2 = SimpleConstant()
118
      CONSTANT_3 = SimpleConstant()
119
      CONSTANT_1 = SimpleConstant()
120
121
    values = FOO.itervalues()
122
123
    self.assertIsInstance(values, Iterator)
124
    self.assertEqual(
125
      list(values),
126
      [
127
        FOO.CONSTANT_2,
128
        FOO.CONSTANT_3,
129
        FOO.CONSTANT_1,
130
      ],
131
    )
132
133
  def test_constants(self):
134
    class FOO(Constants):
135
      CONSTANT_2 = SimpleConstant()
136
      CONSTANT_3 = SimpleConstant()
137
      CONSTANT_1 = SimpleConstant()
138
139
    constants = FOO.constants()
140
141
    self.assertIsInstance(constants, list)
142
    self.assertEqual(
143
      constants,
144
      [
145
        FOO.CONSTANT_2,
146
        FOO.CONSTANT_3,
147
        FOO.CONSTANT_1,
148
      ],
149
    )
150
151
  def test_iterconstants(self):
152
153
    class FOO(Constants):
154
      CONSTANT_2 = SimpleConstant()
155
      CONSTANT_3 = SimpleConstant()
156
      CONSTANT_1 = SimpleConstant()
157
158
    constants = FOO.iterconstants()
159
160
    self.assertIsInstance(constants, Iterator)
161
    self.assertEqual(
162
      list(constants),
163
      [
164
        FOO.CONSTANT_2,
165
        FOO.CONSTANT_3,
166
        FOO.CONSTANT_1,
167
      ],
168
    )
169
170
  def test_items(self):
171
172
    class FOO(Constants):
173
      CONSTANT_2 = SimpleConstant()
174
      CONSTANT_3 = SimpleConstant()
175
      CONSTANT_1 = SimpleConstant()
176
177
    items = FOO.items()
178
179
    self.assertIsInstance(items, list)
180
    self.assertEqual(
181
      items,
182
      [
183
        ("CONSTANT_2", FOO.CONSTANT_2),
184
        ("CONSTANT_3", FOO.CONSTANT_3),
185
        ("CONSTANT_1", FOO.CONSTANT_1),
186
      ],
187
    )
188
189
  def test_iteritems(self):
190
191
    class FOO(Constants):
192
      CONSTANT_2 = SimpleConstant()
193
      CONSTANT_3 = SimpleConstant()
194
      CONSTANT_1 = SimpleConstant()
195
196
    items = FOO.iteritems()
197
198
    self.assertIsInstance(items, Iterator)
199
    self.assertEqual(
200
      list(items),
201
      [
202
        ("CONSTANT_2", FOO.CONSTANT_2),
203
        ("CONSTANT_3", FOO.CONSTANT_3),
204
        ("CONSTANT_1", FOO.CONSTANT_1),
205
      ],
206
    )
207
208
  def test_iter(self):
209
210
    class FOO(Constants):
211
      CONSTANT_2 = SimpleConstant()
212
      CONSTANT_3 = SimpleConstant()
213
      CONSTANT_1 = SimpleConstant()
214
215
    self.assertIsInstance(FOO, Iterable)
216
    self.assertEqual(
217
      list(FOO),
218
      [
219
        "CONSTANT_2",
220
        "CONSTANT_3",
221
        "CONSTANT_1",
222
      ],
223
    )
224
225
  def test_len(self):
226
227
    class FOO(Constants):
228
      CONSTANT_2 = SimpleConstant()
229
      CONSTANT_3 = SimpleConstant()
230
      CONSTANT_1 = SimpleConstant()
231
232
    self.assertEqual(len(FOO), 3)
233
234
  def test_contains(self):
235
236
    class FOO(Constants):
237
      CONSTANT_1 = SimpleConstant()
238
239
    self.assertTrue("CONSTANT_1" in FOO)
240
    self.assertFalse("CONSTANT_X" in FOO)
241
242
  def test_has_name(self):
243
244
    class FOO(Constants):
245
      CONSTANT_1 = SimpleConstant()
246
247
    self.assertTrue(FOO.has_name("CONSTANT_1"))
248
    self.assertFalse(FOO.has_name("CONSTANT_X"))
249
250
  def test_get_item(self):
251
252
    class FOO(Constants):
253
      CONSTANT_1 = SimpleConstant()
254
255
    self.assertEqual(FOO["CONSTANT_1"], FOO.CONSTANT_1)
256
257
  def test_get_item_missing(self):
258
259
    class FOO(Constants):
260
      CONSTANT_1 = SimpleConstant()
261
262
    with self.assertRaises(CandvMissingConstantError) as cm:
263
      FOO["CONSTANT_X"]
264
265
    self.assertEqual(
266
      cm.exception.args[0],
267
      (
268
        "constant \"CONSTANT_X\" is not present in "
269
        "\"<constants container 'FOO'>\""
270
      ),
271
    )
272
273
  def test_get(self):
274
275
    class FOO(Constants):
276
      CONSTANT_1 = SimpleConstant()
277
278
    self.assertEqual(FOO.get("CONSTANT_1"), FOO.CONSTANT_1)
279
    self.assertEqual(FOO.get("CONSTANT_X"), None)
280
281
  def test_invalid_constant_class(self):
282
283
    with self.assertRaises(CandvInvalidConstantClass) as cm:
284
285
      class FOO(Constants):
286
        constant_class = int
287
288
    self.assertEqual(
289
      cm.exception.args[0],
290
      (
291
        f"invalid \"constant_class\" for \"<constants container 'FOO'>\": "
292
        f"must be derived from \"<class 'candv.core.SimpleConstant'>\", "
293
        f"but got \"{repr(int)}\""
294
      ),
295
    )
296
297
  def test_reuse_of_constant(self):
298
299
    with self.assertRaises(CandvConstantAlreadyBoundError) as cm:
300
301
      class FOO(Constants):
302
        CONSTANT_1 = SimpleConstant()
303
304
      class BAR(Constants):
305
        CONSTANT_1 = FOO.CONSTANT_1
306
307
    self.assertEqual(
308
      cm.exception.args[0],
309
      (
310
        "cannot use \"<constant 'FOO.CONSTANT_1'>\" as value for \"CONSTANT_1\" "
311
        "attribute of \"<constants container 'BAR'>\" container: already bound "
312
        "to \"<constants container 'FOO'>\""
313
      ),
314
    )
315
316
  def test_duplicates(self):
317
318
    class FOO(Constants):
319
      CONSTANT_1 = SimpleConstant()
320
      CONSTANT_1 = SimpleConstant()
321
322
    self.assertEqual(
323
      list(FOO),
324
      ["CONSTANT_1", ],
325
    )
326
327
  def test_mixed_constant_classes(self):
328
329
    class CustomConstant(SimpleConstant):
330
      pass
331
332
    class FOO(Constants):
333
      CONSTANT_1 = SimpleConstant()
334
      CONSTANT_2 = CustomConstant()
335
336
    self.assertEqual(
337
      list(FOO),
338
      [
339
        "CONSTANT_1",
340
        "CONSTANT_2",
341
      ],
342
    )
343
344
  def test_constant_class(self):
345
346
    class CustomConstant(SimpleConstant):
347
      pass
348
349
    class FOO(Constants):
350
      constant_class = CustomConstant
351
352
      CONSTANT_1 = CustomConstant()
353
      CONSTANT_2 = CustomConstant()
354
      CONSTANT_X = SimpleConstant()  # more generic, hence insivible
355
356
    self.assertEqual(
357
      list(FOO),
358
      [
359
        "CONSTANT_1",
360
        "CONSTANT_2",
361
      ],
362
    )
363
364
  def test_unbound_constant(self):
365
366
    class CustomConstant(SimpleConstant):
367
      pass
368
369
    class FOO(Constants):
370
      constant_class = CustomConstant
371
372
      CONSTANT_1 = SimpleConstant()  # more generic, not owned
373
374
    self.assertEqual(
375
      FOO.CONSTANT_1.name,
376
      "CONSTANT_1",
377
    )
378
    self.assertEqual(
379
      FOO.CONSTANT_1.full_name,
380
      "__UNBOUND__.CONSTANT_1",
381
    )
382
    self.assertEqual(
383
      repr(FOO.CONSTANT_1),
384
      "<constant '__UNBOUND__.CONSTANT_1'>",
385
    )
386
387
  def test_to_primitive(self):
388
389
    class FOO(Constants):
390
      CONSTANT_2 = SimpleConstant()
391
      CONSTANT_3 = SimpleConstant()
392
      CONSTANT_1 = SimpleConstant()
393
394
    self.assertEqual(
395
      FOO.to_primitive(),
396
      {
397
        'name': "FOO",
398
        'items': [
399
          {'name': "CONSTANT_2", },
400
          {'name': "CONSTANT_3", },
401
          {'name': "CONSTANT_1", },
402
        ],
403
      },
404
    )
405
406
  def test_different_imports(self):
407
    sys.path.insert(0, str(Path(__file__).absolute().parent / "package"))
408
409
    from .package.subpackage.constants import CONSTANTS
410
    from subpackage.constants import CONSTANTS as SUBCONSTANTS
411
412
    self.assertNotEqual(CONSTANTS.__module__, SUBCONSTANTS.__module__)
413
    self.assertEqual(CONSTANTS.PRIMARY, SUBCONSTANTS.PRIMARY)
414
415
  def test_picking(self):
416
    from .package.subpackage.constants import CONSTANTS
417
418
    restored = pickle.loads(pickle.dumps(CONSTANTS))
419
    self.assertEqual(CONSTANTS, restored)
420
421
422
class ConstantClassMixinTestCase(unittest.TestCase):
423
424
  def test_constant_class_mixin_factory(self):
425
426
    class CustomConstant(SimpleConstant):
427
      pass
428
429
    class FOO(with_constant_class(CustomConstant), Constants):
430
      CONSTANT_1 = CustomConstant()
431
      CONSTANT_2 = CustomConstant()
432
433
    self.assertEqual(FOO.constant_class, CustomConstant)
434
    self.assertEqual(
435
      FOO.constants(),
436
      [
437
        FOO.CONSTANT_1,
438
        FOO.CONSTANT_2,
439
      ],
440
    )
441
442
443
class SimpleConstantTestCase(unittest.TestCase):
444
445
  def test_name(self):
446
447
    class FOO(Constants):
448
      CONSTANT = SimpleConstant()
449
450
    self.assertEqual(FOO.CONSTANT.name, "CONSTANT")
451
452
  def test_full_name(self):
453
454
    class FOO(Constants):
455
      CONSTANT = SimpleConstant()
456
457
    self.assertEqual(FOO.CONSTANT.full_name, "FOO.CONSTANT")
458
459
  def test_repr(self):
460
461
    class FOO(Constants):
462
      CONSTANT = SimpleConstant()
463
464
    self.assertEqual(repr(FOO.CONSTANT), "<constant 'FOO.CONSTANT'>")
465
466
  def test_container(self):
467
468
    class FOO(Constants):
469
      CONSTANT = SimpleConstant()
470
471
    self.assertEqual(FOO.CONSTANT.container, FOO)
472
473
  def test_to_primitive(self):
474
475
    class FOO(Constants):
476
      CONSTANT = SimpleConstant()
477
478
    self.assertEqual(
479
      FOO.CONSTANT.to_primitive(),
480
      {'name': "CONSTANT"},
481
    )
482
483
484
class GrouppingTestCase(unittest.TestCase):
485
486
  def test_group_name(self):
487
488
    class FOO(Constants):
489
      G = SimpleConstant().to_group(group_class=Constants)
490
491
    self.assertEqual(FOO.G.name, "G")
492
493
  def test_group_full_name(self):
494
495
    class FOO(Constants):
496
      G = SimpleConstant().to_group(group_class=Constants)
497
498
    self.assertEqual(FOO.G.full_name, "FOO.G")
499
500
  def test_group_repr(self):
501
502
    class FOO(Constants):
503
      G = SimpleConstant().to_group(group_class=Constants)
504
505
    self.assertEqual(repr(FOO.G), "<constants group 'FOO.G'>")
506
507
  def test_group_names(self):
508
509
    class FOO(Constants):
510
      G = SimpleConstant().to_group(
511
        group_class=Constants,
512
        G_3=SimpleConstant(),
513
        G_1=SimpleConstant(),
514
        G_2=SimpleConstant(),
515
      )
516
517
    names = FOO.G.names()
518
519
    self.assertIsInstance(names, list)
520
    self.assertEqual(
521
      names,
522
      [
523
        "G_3",
524
        "G_1",
525
        "G_2",
526
      ],
527
    )
528
529
  def test_group_iternames(self):
530
531
    class FOO(Constants):
532
      G = SimpleConstant().to_group(
533
        group_class=Constants,
534
        G_3=SimpleConstant(),
535
        G_1=SimpleConstant(),
536
        G_2=SimpleConstant(),
537
      )
538
539
    names = FOO.G.iternames()
540
541
    self.assertIsInstance(names, Iterator)
542
    self.assertEqual(
543
      list(names),
544
      [
545
        "G_3",
546
        "G_1",
547
        "G_2",
548
      ],
549
    )
550
551
  def test_group_values(self):
552
553
    class FOO(Constants):
554
      G = SimpleConstant().to_group(
555
        group_class=Constants,
556
        G_3=SimpleConstant(),
557
        G_1=SimpleConstant(),
558
        G_2=SimpleConstant(),
559
      )
560
561
    values = FOO.G.values()
562
563
    self.assertIsInstance(values, list)
564
    self.assertEqual(
565
      values,
566
      [
567
        FOO.G.G_3,
568
        FOO.G.G_1,
569
        FOO.G.G_2,
570
      ],
571
    )
572
573
  def test_group_itervalues(self):
574
575
    class FOO(Constants):
576
      G = SimpleConstant().to_group(
577
        group_class=Constants,
578
        G_3=SimpleConstant(),
579
        G_1=SimpleConstant(),
580
        G_2=SimpleConstant(),
581
      )
582
583
    values = FOO.G.itervalues()
584
585
    self.assertIsInstance(values, Iterator)
586
    self.assertEqual(
587
      list(values),
588
      [
589
        FOO.G.G_3,
590
        FOO.G.G_1,
591
        FOO.G.G_2,
592
      ],
593
    )
594
595
  def test_group_constants(self):
596
597
    class FOO(Constants):
598
      G = SimpleConstant().to_group(
599
        group_class=Constants,
600
        G_3=SimpleConstant(),
601
        G_1=SimpleConstant(),
602
        G_2=SimpleConstant(),
603
      )
604
605
    constants = FOO.G.constants()
606
607
    self.assertIsInstance(constants, list)
608
    self.assertEqual(
609
      constants,
610
      [
611
        FOO.G.G_3,
612
        FOO.G.G_1,
613
        FOO.G.G_2,
614
      ],
615
    )
616
617
  def test_group_iterconstants(self):
618
619
    class FOO(Constants):
620
      G = SimpleConstant().to_group(
621
        group_class=Constants,
622
        G_3=SimpleConstant(),
623
        G_1=SimpleConstant(),
624
        G_2=SimpleConstant(),
625
      )
626
627
    constants = FOO.G.iterconstants()
628
629
    self.assertIsInstance(constants, Iterator)
630
    self.assertEqual(
631
      list(constants),
632
      [
633
        FOO.G.G_3,
634
        FOO.G.G_1,
635
        FOO.G.G_2,
636
      ],
637
    )
638
639
  def test_group_items(self):
640
641
    class FOO(Constants):
642
      G = SimpleConstant().to_group(
643
        group_class=Constants,
644
        G_3=SimpleConstant(),
645
        G_1=SimpleConstant(),
646
        G_2=SimpleConstant(),
647
      )
648
649
    items = FOO.G.items()
650
651
    self.assertIsInstance(items, list)
652
    self.assertEqual(
653
      items,
654
      [
655
        ("G_3", FOO.G.G_3),
656
        ("G_1", FOO.G.G_1),
657
        ("G_2", FOO.G.G_2),
658
      ]
659
    )
660
661
  def test_group_iteritems(self):
662
663
    class FOO(Constants):
664
      G = SimpleConstant().to_group(
665
        group_class=Constants,
666
        G_3=SimpleConstant(),
667
        G_1=SimpleConstant(),
668
        G_2=SimpleConstant(),
669
      )
670
671
    items = FOO.G.iteritems()
672
673
    self.assertIsInstance(items, Iterator)
674
    self.assertEqual(
675
      list(items),
676
      [
677
        ("G_3", FOO.G.G_3),
678
        ("G_1", FOO.G.G_1),
679
        ("G_2", FOO.G.G_2),
680
      ]
681
    )
682
683
  def test_group_iter(self):
684
685
    class FOO(Constants):
686
      G = SimpleConstant().to_group(
687
        group_class=Constants,
688
        G_3=SimpleConstant(),
689
        G_1=SimpleConstant(),
690
        G_2=SimpleConstant(),
691
      )
692
693
    self.assertIsInstance(FOO.G, Iterable)
694
    self.assertEqual(
695
      list(FOO.G),
696
      [
697
        "G_3",
698
        "G_1",
699
        "G_2",
700
      ]
701
    )
702
703
  def test_group_len(self):
704
705
    class FOO(Constants):
706
      G = SimpleConstant().to_group(
707
        group_class=Constants,
708
        G_3=SimpleConstant(),
709
        G_1=SimpleConstant(),
710
        G_2=SimpleConstant(),
711
      )
712
713
    self.assertEqual(len(FOO.G), 3)
714
715
  def test_group_contains(self):
716
717
    class FOO(Constants):
718
      G = SimpleConstant().to_group(
719
        group_class=Constants,
720
        G_1=SimpleConstant(),
721
      )
722
723
    self.assertTrue("G_1" in FOO.G)
724
    self.assertFalse("G_X" in FOO.G)
725
726
  def test_group_has_name(self):
727
728
    class FOO(Constants):
729
      G = SimpleConstant().to_group(
730
        group_class=Constants,
731
        G_1=SimpleConstant(),
732
      )
733
734
    self.assertTrue(FOO.G.has_name("G_1"))
735
    self.assertFalse(FOO.G.has_name("G_X"))
736
737
  def test_group_get_item(self):
738
739
    class FOO(Constants):
740
      G = SimpleConstant().to_group(
741
        group_class=Constants,
742
        G_1=SimpleConstant(),
743
      )
744
745
    self.assertEqual(FOO.G["G_1"], FOO.G.G_1)
746
747
  def test_group_get_item_missing(self):
748
749
    class FOO(Constants):
750
      G = SimpleConstant().to_group(
751
        group_class=Constants,
752
        G_1=SimpleConstant(),
753
      )
754
755
    with self.assertRaises(CandvMissingConstantError) as cm:
756
      FOO.G["G_X"]
757
758
    self.assertEqual(
759
      cm.exception.args[0],
760
      "constant \"G_X\" is not present in \"<constants group 'FOO.G'>\"",
761
    )
762
763
  def test_group_get(self):
764
765
    class FOO(Constants):
766
      G = SimpleConstant().to_group(
767
        group_class=Constants,
768
        G_1=SimpleConstant(),
769
      )
770
771
    self.assertEqual(FOO.G.get("G_1"), FOO.G.G_1)
772
    self.assertEqual(FOO.G.get("G_X"), None)
773
774
  def test_group_container(self):
775
776
    class FOO(Constants):
777
      G = SimpleConstant().to_group(
778
        group_class=Constants,
779
        G_1=SimpleConstant(),
780
      )
781
782
    self.assertEqual(FOO.G.container, FOO)
783
784
  def test_group_as_container(self):
785
786
    class FOO(Constants):
787
      G = SimpleConstant().to_group(
788
        group_class=Constants,
789
        G_1=SimpleConstant(),
790
      )
791
792
    self.assertEqual(FOO.G.G_1.container, FOO.G)
793
794
  def test_container_names(self):
795
796
    class FOO(Constants):
797
      A = SimpleConstant()
798
      G = SimpleConstant().to_group(
799
        group_class=Constants,
800
        G_1=SimpleConstant(),
801
      )
802
803
    self.assertEqual(FOO.names(), ["A", "G", ])
804
805
  def test_get_from_container(self):
806
807
    class FOO(Constants):
808
      G = SimpleConstant().to_group(
809
        group_class=Constants,
810
        G_1=SimpleConstant(),
811
      )
812
813
    self.assertEqual(FOO["G"], FOO.G)
814
815
  def test_group_member_full_name(self):
816
817
    class FOO(Constants):
818
      G = SimpleConstant().to_group(
819
        group_class=Constants,
820
        G_1=SimpleConstant(),
821
      )
822
823
    self.assertEqual(FOO.G.G_1.full_name, "FOO.G.G_1")
824
825
  def test_invalid_group(self):
826
    with self.assertRaises(CandvInvalidGroupMemberError) as cm:
827
828
      class FOO(Constants):
829
        G = SimpleConstant().to_group(
830
          group_class=Constants,
831
          G_1=SimpleConstant(),
832
          G_2=1,
833
        )
834
835
    self.assertEqual(
836
      cm.exception.args[0],
837
      (
838
        "invalid group member \"1\": only instances of "
839
        "\"<class 'candv.core.SimpleConstant'>\" or other groups are allowed"
840
      ),
841
    )
842
843
  def test_to_primitive(self):
844
845
    class FOO(Constants):
846
      A = SimpleConstant()
847
      G = SimpleConstant().to_group(
848
        group_class=Constants,
849
        G_3=SimpleConstant(),
850
        G_1=SimpleConstant(),
851
        G_2=SimpleConstant(),
852
      )
853
854
    self.assertEqual(
855
      FOO.to_primitive(),
856
      {
857
        'name': "FOO",
858
        'items': [
859
          {'name': "A", },
860
          {
861
            'name': "G",
862
            'items': [
863
              {'name': "G_3", },
864
              {'name': "G_1", },
865
              {'name': "G_2", },
866
            ],
867
          },
868
        ],
869
      },
870
    )
871