File: test_auto_register.py

package info (click to toggle)
python-phx-class-registry 4.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 260 kB
  • sloc: python: 886; makefile: 19
file content (92 lines) | stat: -rw-r--r-- 2,713 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from abc import ABCMeta, abstractmethod as abstract_method
from unittest import TestCase

from class_registry import AutoRegister, ClassRegistry


class AutoRegisterTestCase(TestCase):
    def test_auto_register(self):
        """
        Using :py:func:`AutoRegister` to, well, auto-register classes.
        """
        registry = ClassRegistry(attr_name='element')

        # Note that we declare :py:func:`AutoRegister` as the metaclass
        # for our base class.
        class BasePokemon(metaclass=AutoRegister(registry)):
            """
            Abstract base class; will not get registered.
            """

            @abstract_method
            def get_abilities(self):
                raise NotImplementedError()

        class Sandslash(BasePokemon):
            """
            Non-abstract subclass; will get registered automatically.
            """
            element = 'ground'

            def get_abilities(self):
                return ['sand veil']

        class BaseEvolvingPokemon(BasePokemon, metaclass=ABCMeta):
            """
            Abstract subclass; will not get registered.
            """

            @abstract_method
            def evolve(self):
                raise NotImplementedError()

        class Ekans(BaseEvolvingPokemon):
            """
            Non-abstract subclass; will get registered automatically.
            """
            element = 'poison'

            def get_abilities(self):
                return ['intimidate', 'shed skin']

            def evolve(self):
                return 'Congratulations! Your EKANS evolved into ARBOK!'

        self.assertListEqual(
            list(registry.items()),

            [
                # Note that only non-abstract classes got registered.
                ('ground', Sandslash),
                ('poison', Ekans),
            ],
        )

    def test_abstract_strict_definition(self):
        """
        If a class has no unimplemented abstract methods, it gets registered.
        """
        registry = ClassRegistry(attr_name='element')

        class FightingPokemon(metaclass=AutoRegister(registry)):
            element = 'fighting'

        self.assertListEqual(
            list(registry.items()),

            [
                # :py:class:`FightingPokemon` does not define any
                # abstract methods, so it is not considered to be
                # abstract!
                ('fighting', FightingPokemon),
            ],
        )

    def test_error_attr_name_missing(self):
        """
        The registry doesn't have an ``attr_name``.
        """
        registry = ClassRegistry()

        with self.assertRaises(ValueError):
            AutoRegister(registry)