Coverage for tests/test_Config.py : 19%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# This file is part of pex_config. # # Developed for the LSST Data Management System. # This product includes software developed by the LSST Project # (http://www.lsst.org). # See the COPYRIGHT file at the top-level directory of this distribution # for details of code ownership. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>.
# Some tests depend on daf_base or pex_policy. # Skip them if they are not found. except ImportError: dafBase = None except ImportError: pexPolicy = None
allowed={"Hello": "First choice", "World": "second choice"}) min=3.0, inclusiveMin=True) itemCheck=lambda x: x is not None and x > 0) itemCheck=lambda x: x.startswith('v'))
pexConfig.Config.__init__(self) self.i.f = 5.0
pexConfig.Config.validate(self) if self.i.f < 5: raise ValueError("validation failed, outer.i.f must be greater than 5")
default="AAA", optional=False) default="BBB", optional=True)
self.simple = Simple() self.inner = InnerConfig() self.outer = OuterConfig() self.comp = Complex() self.deprecation = Deprecation()
del self.simple del self.inner del self.outer del self.comp
self.assertIsNone(self.simple.i) self.assertEqual(self.simple.f, 3.0) self.assertFalse(self.simple.b) self.assertEqual(self.simple.c, "Hello") self.assertEqual(list(self.simple.ll), [1, 2, 3]) self.assertEqual(self.simple.d["key"], "value") self.assertEqual(self.inner.f, 0.0) self.assertEqual(self.deprecation.old, 10)
self.assertEqual(self.deprecation._fields['old'].doc, "Something. Deprecated: not used!")
self.assertEqual(self.outer.i.f, 5.0) self.assertEqual(self.outer.f, 0.0)
self.assertEqual(self.comp.c.f, 0.0) self.assertEqual(self.comp.r.name, "AAA") self.assertEqual(self.comp.r.active.f, 3.0) self.assertEqual(self.comp.r["BBB"].f, 0.0)
"""Test that a deprecated field emits a warning when it is set. """ with self.assertWarns(FutureWarning) as w: self.deprecation.old = 5 self.assertEqual(self.deprecation.old, 5)
self.assertIn(self.deprecation._fields['old'].deprecated, str(w.warnings[-1].message))
self.simple.validate()
self.inner.validate() self.assertRaises(ValueError, setattr, self.outer.i, "f", -5) self.outer.i.f = 10. self.outer.validate()
try: self.simple.d["failKey"] = "failValue" except pexConfig.FieldValidationError: pass except Exception: raise "Validation error Expected" self.simple.validate()
self.outer.i = InnerConfig self.assertRaises(ValueError, self.outer.validate) self.outer.i = InnerConfig() self.assertRaises(ValueError, self.outer.validate)
self.comp.validate() self.comp.r = None self.assertRaises(ValueError, self.comp.validate) self.comp.r = "BBB" self.comp.validate()
"""Test RangeField constructor's checking of min, max """ val = 3 self.assertRaises(ValueError, pexConfig.RangeField, "", int, default=val, min=val, max=val-1) self.assertRaises(ValueError, pexConfig.RangeField, "", float, default=val, min=val, max=val-1e-15) for inclusiveMin, inclusiveMax in itertools.product((False, True), (False, True)): if inclusiveMin and inclusiveMax: # should not raise class Cfg1(pexConfig.Config): r1 = pexConfig.RangeField(doc="", dtype=int, default=val, min=val, max=val, inclusiveMin=inclusiveMin, inclusiveMax=inclusiveMax) r2 = pexConfig.RangeField(doc="", dtype=float, default=val, min=val, max=val, inclusiveMin=inclusiveMin, inclusiveMax=inclusiveMax) Cfg1() else: # raise while constructing the RangeField (hence cannot make it part of a Config) self.assertRaises(ValueError, pexConfig.RangeField, doc="", dtype=int, default=val, min=val, max=val, inclusiveMin=inclusiveMin, inclusiveMax=inclusiveMax) self.assertRaises(ValueError, pexConfig.RangeField, doc="", dtype=float, default=val, min=val, max=val, inclusiveMin=inclusiveMin, inclusiveMax=inclusiveMax)
"""Test RangeField's checking of the default value """ minVal = 3 maxVal = 4 for val, inclusiveMin, inclusiveMax, shouldRaise in ( (minVal, False, True, True), (minVal, True, True, False), (maxVal, True, False, True), (maxVal, True, True, False), ): class Cfg1(pexConfig.Config): r = pexConfig.RangeField(doc="", dtype=int, default=val, min=minVal, max=maxVal, inclusiveMin=inclusiveMin, inclusiveMax=inclusiveMax)
class Cfg2(pexConfig.Config): r2 = pexConfig.RangeField(doc="", dtype=float, default=val, min=minVal, max=maxVal, inclusiveMin=inclusiveMin, inclusiveMax=inclusiveMax) if shouldRaise: self.assertRaises(pexConfig.FieldValidationError, Cfg1) self.assertRaises(pexConfig.FieldValidationError, Cfg2) else: Cfg1() Cfg2()
self.comp.r = "BBB" self.comp.p = "AAA" self.comp.c.f = 5. self.comp.save("roundtrip.test")
roundTrip = Complex() roundTrip.load("roundtrip.test") os.remove("roundtrip.test")
self.assertEqual(self.comp.c.f, roundTrip.c.f) self.assertEqual(self.comp.r.name, roundTrip.r.name)
del roundTrip # test saving to an open file outfile = open("roundtrip.test", "w") self.comp.saveToStream(outfile) outfile.close()
roundTrip = Complex() roundTrip.load("roundtrip.test") os.remove("roundtrip.test")
self.assertEqual(self.comp.c.f, roundTrip.c.f) self.assertEqual(self.comp.r.name, roundTrip.r.name)
# test backwards compatibility feature of allowing "root" instead of "config" outfile = open("roundtrip.test", "w") self.comp.saveToStream(outfile, root="root") outfile.close()
roundTrip = Complex() roundTrip.load("roundtrip.test") os.remove("roundtrip.test")
self.assertEqual(self.comp.c.f, roundTrip.c.f) self.assertEqual(self.comp.r.name, roundTrip.r.name)
self.comp.r["AAA"].f = 5.0 self.assertEqual(self.comp.p["AAA"].f, 3.0)
class AAA(pexConfig.Config): a = pexConfig.Field("AAA.a", int, default=4)
class BBB(AAA): b = pexConfig.Field("BBB.b", int, default=3)
class CCC(BBB): c = pexConfig.Field("CCC.c", int, default=2)
# test multi-level inheritance c = CCC() self.assertIn("a", c.toDict()) self.assertEqual(c._fields["a"].dtype, int) self.assertEqual(c.a, 4)
# test conflicting multiple inheritance class DDD(pexConfig.Config): a = pexConfig.Field("DDD.a", float, default=0.0)
class EEE(DDD, AAA): pass
e = EEE() self.assertEqual(e._fields["a"].dtype, float) self.assertIn("a", e.toDict()) self.assertEqual(e.a, 0.0)
class FFF(AAA, DDD): pass f = FFF() self.assertEqual(f._fields["a"].dtype, int) self.assertIn("a", f.toDict()) self.assertEqual(f.a, 4)
# test inheritance from non Config objects class GGG: a = pexConfig.Field("AAA.a", float, default=10.)
class HHH(GGG, AAA): pass h = HHH() self.assertEqual(h._fields["a"].dtype, float) self.assertIn("a", h.toDict()) self.assertEqual(h.a, 10.0)
# test partial Field redefinition
class III(AAA): pass III.a.default = 5
self.assertEqual(III.a.default, 5) self.assertEqual(AAA.a.default, 4)
def testConvertPolicy(self): pol = pexConfig.makePolicy(self.simple) self.assertFalse(pol.exists("i")) self.assertEqual(pol.get("f"), self.simple.f) self.assertEqual(pol.get("b"), self.simple.b) self.assertEqual(pol.get("c"), self.simple.c) self.assertEqual(pol.getArray("ll"), list(self.simple.ll))
pol = pexConfig.makePolicy(self.comp) self.assertEqual(pol.get("c.f"), self.comp.c.f)
def testConvertPropertySet(self): ps = pexConfig.makePropertySet(self.simple) self.assertFalse(ps.exists("i")) self.assertEqual(ps.getScalar("f"), self.simple.f) self.assertEqual(ps.getScalar("b"), self.simple.b) self.assertEqual(ps.getScalar("c"), self.simple.c) self.assertEqual(list(ps.getArray("ll")), list(self.simple.ll))
ps = pexConfig.makePropertySet(self.comp) self.assertEqual(ps.getScalar("c.f"), self.comp.c.f)
self.comp.freeze()
self.assertRaises(pexConfig.FieldValidationError, setattr, self.comp.c, "f", 10.0) self.assertRaises(pexConfig.FieldValidationError, setattr, self.comp, "r", "AAA") self.assertRaises(pexConfig.FieldValidationError, setattr, self.comp, "p", "AAA") self.assertRaises(pexConfig.FieldValidationError, setattr, self.comp.p["AAA"], "f", 5.0)
self.comp.c.f = 5.
# Generate a Config through loading stream = io.StringIO() stream.write(str(importStatement)) self.comp.saveToStream(stream) roundtrip = Complex() roundtrip.loadFromStream(stream.getvalue()) self.assertEqual(self.comp.c.f, roundtrip.c.f)
# Check the save stream stream = io.StringIO() roundtrip.saveToStream(stream) self.assertEqual(self.comp.c.f, roundtrip.c.f) streamStr = stream.getvalue() if shouldBeThere: self.assertTrue(re.search(searchString, streamStr)) else: self.assertFalse(re.search(searchString, streamStr))
# A module not used by anything else, but which exists importing = "import lsst.pex.config._doNotImportMe\n" self.checkImportRoundTrip(importing, importing, True)
dummy = "somethingThatDoesntExist" importing = """ try: import %s except ImportError: pass """ % dummy self.checkImportRoundTrip(importing, dummy, False)
self.simple.f = 5 simple = pickle.loads(pickle.dumps(self.simple)) self.assertIsInstance(simple, Simple) self.assertEqual(self.simple.f, simple.f)
self.comp.c.f = 5 comp = pickle.loads(pickle.dumps(self.comp)) self.assertIsInstance(comp, Complex) self.assertEqual(self.comp.c.f, comp.c.f)
comp2 = Complex() inner2 = InnerConfig() simple2 = Simple() self.assertTrue(self.comp.compare(comp2)) self.assertTrue(comp2.compare(self.comp)) self.assertTrue(self.comp.c.compare(inner2)) self.assertTrue(self.simple.compare(simple2)) self.assertTrue(simple2.compare(self.simple)) self.assertEqual(self.simple, simple2) self.assertEqual(simple2, self.simple) outList = []
def outFunc(msg): outList.append(msg) simple2.b = True simple2.ll.append(4) simple2.d["foo"] = "var" self.assertFalse(self.simple.compare(simple2, shortcut=True, output=outFunc)) self.assertEqual(len(outList), 1) del outList[:] self.assertFalse(self.simple.compare(simple2, shortcut=False, output=outFunc)) output = "\n".join(outList) self.assertIn("Inequality in b", output) self.assertIn("Inequality in size for ll", output) self.assertIn("Inequality in keys for d", output) del outList[:] self.simple.d["foo"] = "vast" self.simple.ll.append(5) self.simple.b = True self.simple.f += 1E8 self.assertFalse(self.simple.compare(simple2, shortcut=False, output=outFunc)) output = "\n".join(outList) self.assertIn("Inequality in f", output) self.assertIn("Inequality in ll[3]", output) self.assertIn("Inequality in d['foo']", output) del outList[:] comp2.r["BBB"].f = 1.0 # changing the non-selected item shouldn't break equality self.assertTrue(self.comp.compare(comp2)) comp2.r["AAA"].i = 56 # changing the selected item should break equality comp2.c.f = 1.0 self.assertFalse(self.comp.compare(comp2, shortcut=False, output=outFunc)) output = "\n".join(outList) self.assertIn("Inequality in c.f", output) self.assertIn("Inequality in r['AAA']", output) self.assertNotIn("Inequality in r['BBB']", output)
# Before DM-16561, this incorrectly returned `True`. self.assertFalse(self.inner.compare(self.outer)) # Before DM-16561, this raised. self.assertFalse(self.outer.compare(self.inner))
"""Check that loading allows errors in the file being loaded to propagate """ self.assertRaises(SyntaxError, self.simple.loadFromStream, "bork bork bork") self.assertRaises(NameError, self.simple.loadFromStream, "config.f = bork")
"""Check that the names() method returns valid keys
Also check that we have the right number of keys, and as they are all known to be valid we know that we got them all """
names = self.simple.names() self.assertEqual(len(names), 8) for name in names: self.assertTrue(hasattr(self.simple, name))
unittest.main() |