File: test_entry_points.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 (102 lines) | stat: -rw-r--r-- 3,634 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
93
94
95
96
97
98
99
100
101
102
from importlib.metadata import entry_points
from unittest import TestCase

from class_registry import EntryPointClassRegistry, RegistryKeyError
from test import Bulbasaur, Charmander, Mew, PokemonFactory, Squirtle
from test.helper import DummyDistributionFinder


def setUpModule():
    # Inject a distribution that defines some entry points.
    DummyDistributionFinder.install()


def tearDownModule():
    DummyDistributionFinder.uninstall()


class EntryPointClassRegistryTestCase(TestCase):
    def test_happy_path(self):
        """
        Loading classes automatically via entry points.

        See ``dummy_package.egg-info/entry_points.txt`` for more info.
        """
        registry = EntryPointClassRegistry('pokemon')

        fire = registry['fire']
        self.assertIsInstance(fire, Charmander)
        self.assertIsNone(fire.name)

        grass = registry.get('grass')
        self.assertIsInstance(grass, Bulbasaur)
        self.assertIsNone(grass.name)

        water = registry.get('water', name='archibald')
        self.assertIsInstance(water, Squirtle)
        self.assertEqual(water.name, 'archibald')

        # The 'psychic' entry point actually references a function, but it
        # works exactly the same as a class.
        psychic = registry.get('psychic', 'snuggles')
        self.assertIsInstance(psychic, Mew)
        self.assertEqual(psychic.name, 'snuggles')

    def test_branding(self):
        """
        Configuring the registry to "brand" each class/instance with its
        corresponding key.
        """
        registry = EntryPointClassRegistry('pokemon', attr_name='poke_type')
        try:
            # Branding is applied immediately to each registered class.
            self.assertEqual(getattr(Charmander, 'poke_type'), 'fire')
            self.assertEqual(getattr(Squirtle, 'poke_type'), 'water')

            # Instances, too!
            self.assertEqual(registry['fire'].poke_type, 'fire')
            self.assertEqual(registry.get('water', 'phil').poke_type, 'water')

            # Registered functions and methods can't be branded this way,
            # though...
            self.assertFalse(
                hasattr(PokemonFactory.create_psychic_pokemon, 'poke_type'),
            )

            # ... but we can brand the resulting instances.
            self.assertEqual(registry['psychic'].poke_type, 'psychic')
            self.assertEqual(registry.get('psychic').poke_type, 'psychic')
        finally:
            # Clean up after ourselves.
            for cls in registry.values():
                if isinstance(cls, type):
                    try:
                        delattr(cls, 'poke_type')
                    except AttributeError:
                        pass

    def test_len(self):
        """
        Getting the length of an entry point class registry.
        """
        # Just in case some other package defines pokémon entry
        # points (:
        expected = len(list(entry_points(group='pokemon')))

        # Quick sanity check, to make sure our test pokémon are
        # registered correctly.
        self.assertGreaterEqual(expected, 4)

        registry = EntryPointClassRegistry('pokemon')
        self.assertEqual(len(registry), expected)

    def test_error_wrong_group(self):
        """
        The registry can't find entry points associated with the wrong group.
        """
        # Pokémon get registered (unsurprisingly) under the ``pokemon`` group,
        # not ``random``.
        registry = EntryPointClassRegistry('random')

        with self.assertRaises(RegistryKeyError):
            registry.get('fire')