Coverage for tests/test_configChoiceField.py: 29%
87 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-10 09:56 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-10 09:56 +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 pickle
29import tempfile
30import unittest
32import lsst.pex.config as pexConfig
35class Config1(pexConfig.Config):
36 """The first test config."""
38 f = pexConfig.Field(doc="Config1.f", dtype=int, default=4)
40 def validate(self):
41 pexConfig.Config.validate(self)
42 if self.f <= 0:
43 raise pexConfig.FieldValidationError(Config1.f, self, "f should be > 0")
46class Config2(pexConfig.Config):
47 """The second test config."""
49 f = pexConfig.Field(doc="Config2.f", dtype=float, default=0.5, check=lambda x: x > 0) 49 ↛ exitline 49 didn't run the lambda on line 49
52TYPEMAP = {"AAA": Config1, "BBB": Config2, "CCC": Config1}
55class Config3(pexConfig.Config):
56 """A test config with choice fields."""
58 a = pexConfig.ConfigChoiceField(
59 doc="single non-optional", typemap=TYPEMAP, default="AAA", multi=False, optional=False
60 )
61 b = pexConfig.ConfigChoiceField(
62 doc="single optional", typemap=TYPEMAP, default="AAA", multi=False, optional=True
63 )
64 c = pexConfig.ConfigChoiceField(
65 doc="multi non-optional", typemap=TYPEMAP, default=["AAA"], multi=True, optional=False
66 )
67 d = pexConfig.ConfigChoiceField(
68 doc="multi optional", typemap=TYPEMAP, default=["AAA"], multi=True, optional=True
69 )
72class ConfigChoiceFieldTest(unittest.TestCase):
73 """Tests for ConfigChoiceField."""
75 def setUp(self):
76 self.config = Config3()
78 def tearDown(self):
79 del self.config
81 def testInit(self):
82 self.assertEqual(self.config.a.name, "AAA")
83 self.assertEqual(self.config.a.active.f, 4)
84 self.assertEqual(self.config.a["AAA"].f, 4)
85 self.assertEqual(self.config.a["BBB"].f, 0.5)
87 def testSave(self):
88 self.config.a["AAA"].f = 1
89 self.config.a["BBB"].f = 1.0
90 self.config.a = "BBB"
92 with tempfile.NamedTemporaryFile(prefix="choiceFieldTest-", suffix=".config") as temp:
93 path = temp.name
94 print(path)
95 self.config.save(path)
96 roundtrip = Config3()
97 roundtrip.load(path)
99 self.assertEqual(self.config.a.name, roundtrip.a.name)
100 self.assertEqual(self.config.a["AAA"].f, roundtrip.a["AAA"].f)
101 self.assertEqual(self.config.a["BBB"].f, roundtrip.a["BBB"].f)
103 def testValidate(self):
104 self.config.validate()
105 self.config.a = "AAA"
106 self.config.a["AAA"].f = 0
108 self.assertRaises(pexConfig.FieldValidationError, self.config.validate)
110 self.config.a = "BBB"
111 self.config.validate()
113 self.config.a = None
114 self.assertRaises(pexConfig.FieldValidationError, self.config.validate)
116 def testFreeze(self):
117 self.config.freeze()
118 self.assertRaises(pexConfig.FieldValidationError, setattr, self.config.a, "name", "AAA")
119 self.assertRaises(pexConfig.FieldValidationError, setattr, self.config.a["AAA"], "f", "1")
121 # Create a new unfrozen config
122 unfrozenConfig = Config3()
124 # Add a new entries to the typemap after the config is frozen and check
125 # that it is not in the frozen configs keys
126 TYPEMAP["DDD"] = Config1
127 self.assertNotIn("DDD", self.config.a.keys())
129 # Verify that the entry added to the typemap does show up in the
130 # unfrozen config
131 self.assertIn("DDD", unfrozenConfig.a.keys())
133 def testNoArbitraryAttributes(self):
134 self.assertRaises(pexConfig.FieldValidationError, setattr, self.config.a, "should", "fail")
136 def testSelectionSet(self):
137 # test in place modification
138 self.config.c.names.add("BBB")
139 self.assertEqual(set(self.config.c.names), {"AAA", "BBB"})
140 self.config.c.names.remove("AAA")
141 self.assertEqual(set(self.config.c.names), {"BBB"})
142 self.assertRaises(KeyError, self.config.c.names.remove, "AAA")
143 self.config.c.names.discard("AAA")
145 # test bad assignment
146 self.assertRaises(pexConfig.FieldValidationError, setattr, self.config.c, "names", "AAA")
147 self.config.c.names = ["AAA"]
149 def testNoneValue(self):
150 self.config.a = None
151 self.assertRaises(pexConfig.FieldValidationError, self.config.validate)
152 self.config.a = "AAA"
153 self.config.b = None
154 self.config.validate()
155 self.config.c = None
156 self.assertRaises(pexConfig.FieldValidationError, self.config.validate)
157 self.config.c = ["AAA"]
158 self.config.d = None
159 self.config.validate()
161 def testNoPickle(self):
162 """Test that pickle support is disabled for the proxy container."""
163 with self.assertRaises(pexConfig.UnexpectedProxyUsageError):
164 pickle.dumps(self.config.c)
165 with self.assertRaises(pexConfig.UnexpectedProxyUsageError):
166 pickle.dumps(self.config.c.names)
169if __name__ == "__main__": 169 ↛ 170line 169 didn't jump to line 170, because the condition on line 169 was never true
170 unittest.main()