Coverage for tests/test_registry.py: 15%
89 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-20 11:16 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-03-20 11:16 +0000
1# This file is part of pex_config.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This software is dual licensed under the GNU General Public License and also
10# under a 3-clause BSD license. Recipients may choose which of these licenses
11# to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12# respectively. If you choose the GPL option then the following text applies
13# (but note that there is still no warranty even if you opt for BSD instead):
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU General Public License as published by
17# the Free Software Foundation, either version 3 of the License, or
18# (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
28import unittest
30import lsst.pex.config as pexConfig
33class ConfigTest(unittest.TestCase):
34 """Test registry."""
36 def setUp(self):
37 """Note: the classes are defined here in order to test the register
38 decorator.
39 """
41 class ParentConfig(pexConfig.Config):
42 pass
44 self.registry = pexConfig.makeRegistry(doc="unit test configs", configBaseType=ParentConfig)
46 class FooConfig1(ParentConfig):
47 pass
49 self.fooConfig1Class = FooConfig1
51 class FooConfig2(ParentConfig):
52 pass
54 self.fooConfig2Class = FooConfig2
56 class Config1(pexConfig.Config):
57 pass
59 self.config1Class = Config1
61 class Config2(pexConfig.Config):
62 pass
64 self.config2Class = Config2
66 @pexConfig.registerConfigurable("foo1", self.registry)
67 class FooAlg1:
68 ConfigClass = FooConfig1
70 def __init__(self, config):
71 self.config = config
73 def foo(self):
74 pass
76 self.fooAlg1Class = FooAlg1
78 class FooAlg2:
79 ConfigClass = FooConfig2
81 def __init__(self, config):
82 self.config = config
84 def foo(self):
85 pass
87 self.registry.register("foo2", FooAlg2, FooConfig2)
88 self.fooAlg2Class = FooAlg2
90 # override Foo2 with FooConfig1
91 self.registry.register("foo21", FooAlg2, FooConfig1)
93 def tearDown(self):
94 del self.registry
95 del self.fooConfig1Class
96 del self.fooConfig2Class
97 del self.fooAlg1Class
98 del self.fooAlg2Class
100 def testBasics(self):
101 self.assertEqual(self.registry["foo1"], self.fooAlg1Class)
102 self.assertEqual(self.registry["foo2"].ConfigClass, self.fooConfig2Class)
103 self.assertEqual(self.registry["foo21"].ConfigClass, self.fooConfig1Class)
105 self.assertEqual(set(self.registry.keys()), {"foo1", "foo2", "foo21"})
107 def testWrapper(self):
108 wrapper21 = self.registry["foo21"]
109 foo21 = wrapper21(wrapper21.ConfigClass())
110 self.assertIsInstance(foo21, self.fooAlg2Class)
112 def testReplace(self):
113 """Test replacement in registry (should always fail)."""
114 self.assertRaises(Exception, self.registry.register, "foo1", self.fooAlg2Class)
115 self.assertEqual(self.registry["foo1"], self.fooAlg1Class)
117 def testNesting(self):
118 """Make sure nesting a config with a RegistryField doesn't deep-copy
119 the registry.
120 """
122 class MidConfig(pexConfig.Config):
123 field = self.registry.makeField("docs for registry field")
125 class TopConfig(pexConfig.Config):
126 middle = pexConfig.ConfigField(dtype=MidConfig, doc="docs for middle")
128 self.assertIs(MidConfig.field.registry, self.registry)
129 middle = MidConfig()
130 top = TopConfig()
131 self.assertIs(middle.field.registry, self.registry)
132 self.assertIs(top.middle.field.registry, self.registry)
134 def testRegistryField(self):
135 class C1(pexConfig.Config):
136 r = self.registry.makeField("registry field")
138 for t in C1.r.typemap:
139 self.assertEqual(C1.r.typemap[t], self.registry[t].ConfigClass)
141 c = C1()
142 c.r = "foo2"
143 c.r.apply()
145 def testExceptions(self):
146 class C1(pexConfig.Config):
147 r = self.registry.makeField("registry field", multi=True, default=[])
149 c = C1()
151 def fail(name): # lambda doesn't like |=
152 c.r.names |= [name]
154 self.assertRaises(pexConfig.FieldValidationError, fail, "bar")
156 def test_on_none(self):
157 """Test the on_none callback argument to RegistryField."""
159 def on_none_callback(config_dict, *args, **kwargs):
160 return config_dict.apply_with("foo1", *args, **kwargs)
162 class C1(pexConfig.Config):
163 r = self.registry.makeField(
164 "registry field with callback default", default=None, optional=True, on_none=on_none_callback
165 )
167 c = C1()
168 self.assertIsNone(c.r.name)
169 self.assertIsInstance(c.r.apply(), self.fooAlg1Class)
172if __name__ == "__main__": 172 ↛ 173line 172 didn't jump to line 173, because the condition on line 172 was never true
173 unittest.main()