Coverage for tests/test_utils.py : 30%

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
1# This file is part of daf_butler.
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 program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
22from collections import Counter, namedtuple
23from glob import glob
24import os
25import re
26import unittest
28from lsst.daf.butler.core.utils import findFileResources, getFullTypeName, globToRegex, iterable, Singleton
29from lsst.daf.butler import Formatter, Registry
30from lsst.daf.butler import NamedKeyDict, StorageClass
33TESTDIR = os.path.dirname(__file__)
36class IterableTestCase(unittest.TestCase):
37 """Tests for `iterable` helper.
38 """
40 def testNonIterable(self):
41 self.assertEqual(list(iterable(0)), [0, ])
43 def testString(self):
44 self.assertEqual(list(iterable("hello")), ["hello", ])
46 def testIterableNoString(self):
47 self.assertEqual(list(iterable([0, 1, 2])), [0, 1, 2])
48 self.assertEqual(list(iterable(["hello", "world"])), ["hello", "world"])
51class SingletonTestCase(unittest.TestCase):
52 """Tests of the Singleton metaclass"""
54 class IsSingleton(metaclass=Singleton):
55 def __init__(self):
56 self.data = {}
57 self.id = 0
59 class IsBadSingleton(IsSingleton):
60 def __init__(self, arg):
61 """A singleton can not accept any arguments."""
62 self.arg = arg
64 class IsSingletonSubclass(IsSingleton):
65 def __init__(self):
66 super().__init__()
68 def testSingleton(self):
69 one = SingletonTestCase.IsSingleton()
70 two = SingletonTestCase.IsSingleton()
72 # Now update the first one and check the second
73 one.data["test"] = 52
74 self.assertEqual(one.data, two.data)
75 two.id += 1
76 self.assertEqual(one.id, two.id)
78 three = SingletonTestCase.IsSingletonSubclass()
79 self.assertNotEqual(one.id, three.id)
81 with self.assertRaises(TypeError):
82 SingletonTestCase.IsBadSingleton(52)
85class NamedKeyDictTest(unittest.TestCase):
87 def setUp(self):
88 self.TestTuple = namedtuple("TestTuple", ("name", "id"))
89 self.a = self.TestTuple(name="a", id=1)
90 self.b = self.TestTuple(name="b", id=2)
91 self.dictionary = {self.a: 10, self.b: 20}
92 self.names = {self.a.name, self.b.name}
94 def check(self, nkd):
95 self.assertEqual(len(nkd), 2)
96 self.assertEqual(nkd.names, self.names)
97 self.assertEqual(nkd.keys(), self.dictionary.keys())
98 self.assertEqual(list(nkd.values()), list(self.dictionary.values()))
99 self.assertEqual(list(nkd.items()), list(self.dictionary.items()))
100 self.assertEqual(list(nkd.byName().values()), list(self.dictionary.values()))
101 self.assertEqual(list(nkd.byName().keys()), list(nkd.names))
103 def testConstruction(self):
104 self.check(NamedKeyDict(self.dictionary))
105 self.check(NamedKeyDict(iter(self.dictionary.items())))
107 def testDuplicateNameConstruction(self):
108 self.dictionary[self.TestTuple(name="a", id=3)] = 30
109 with self.assertRaises(AssertionError):
110 NamedKeyDict(self.dictionary)
111 with self.assertRaises(AssertionError):
112 NamedKeyDict(iter(self.dictionary.items()))
114 def testNoNameConstruction(self):
115 self.dictionary["a"] = 30
116 with self.assertRaises(AttributeError):
117 NamedKeyDict(self.dictionary)
118 with self.assertRaises(AttributeError):
119 NamedKeyDict(iter(self.dictionary.items()))
121 def testGetItem(self):
122 nkd = NamedKeyDict(self.dictionary)
123 self.assertEqual(nkd["a"], 10)
124 self.assertEqual(nkd[self.a], 10)
125 self.assertEqual(nkd["b"], 20)
126 self.assertEqual(nkd[self.b], 20)
127 self.assertIn("a", nkd)
128 self.assertIn(self.b, nkd)
130 def testSetItem(self):
131 nkd = NamedKeyDict(self.dictionary)
132 nkd[self.a] = 30
133 self.assertEqual(nkd["a"], 30)
134 nkd["b"] = 40
135 self.assertEqual(nkd[self.b], 40)
136 with self.assertRaises(KeyError):
137 nkd["c"] = 50
138 with self.assertRaises(AssertionError):
139 nkd[self.TestTuple("a", 3)] = 60
141 def testDelItem(self):
142 nkd = NamedKeyDict(self.dictionary)
143 del nkd[self.a]
144 self.assertNotIn("a", nkd)
145 del nkd["b"]
146 self.assertNotIn(self.b, nkd)
147 self.assertEqual(len(nkd), 0)
149 def testIter(self):
150 self.assertEqual(set(iter(NamedKeyDict(self.dictionary))), set(self.dictionary))
152 def testEquality(self):
153 nkd = NamedKeyDict(self.dictionary)
154 self.assertEqual(nkd, self.dictionary)
155 self.assertEqual(self.dictionary, nkd)
158class TestButlerUtils(unittest.TestCase):
159 """Tests of the simple utilities."""
161 def testTypeNames(self):
162 # Check types and also an object
163 tests = [(Formatter, "lsst.daf.butler.core.formatter.Formatter"),
164 (int, "int"),
165 (StorageClass, "lsst.daf.butler.core.storageClass.StorageClass"),
166 (StorageClass(None), "lsst.daf.butler.core.storageClass.StorageClass"),
167 (Registry, "lsst.daf.butler.registry.Registry")]
169 for item, typeName in tests:
170 self.assertEqual(getFullTypeName(item), typeName)
173class FindFileResourcesTestCase(unittest.TestCase):
175 def test_getSingleFile(self):
176 """Test getting a file by its file name."""
177 filename = os.path.join(TESTDIR, "config/basic/butler.yaml")
178 self.assertEqual([filename], findFileResources([filename]))
180 def test_getAllFiles(self):
181 """Test getting all the files by not passing a regex."""
182 expected = Counter([p for p in glob(os.path.join(TESTDIR, "config", "**"), recursive=True)
183 if os.path.isfile(p)])
184 self.assertNotEqual(len(expected), 0) # verify some files were found
185 files = Counter(findFileResources([os.path.join(TESTDIR, "config")]))
186 self.assertEqual(expected, files)
188 def test_getAllFilesRegex(self):
189 """Test getting all the files with a regex-specified file ending."""
190 expected = Counter(glob(os.path.join(TESTDIR, "config", "**", "*.yaml"), recursive=True))
191 self.assertNotEqual(len(expected), 0) # verify some files were found
192 files = Counter(findFileResources([os.path.join(TESTDIR, "config")], r"\.yaml\b"))
193 self.assertEqual(expected, files)
195 def test_multipleInputs(self):
196 """Test specifying more than one location to find a files."""
197 expected = Counter(glob(os.path.join(TESTDIR, "config", "basic", "**", "*.yaml"), recursive=True))
198 expected.update(glob(os.path.join(TESTDIR, "config", "templates", "**", "*.yaml"), recursive=True))
199 self.assertNotEqual(len(expected), 0) # verify some files were found
200 files = Counter(findFileResources([os.path.join(TESTDIR, "config", "basic"),
201 os.path.join(TESTDIR, "config", "templates")],
202 r"\.yaml\b"))
203 self.assertEqual(expected, files)
206class GlobToRegexTestCase(unittest.TestCase):
208 def testStarInList(self):
209 """Test that if a one of the items in the expression list is a star
210 (stand-alone) then no search terms are returned (which implies no
211 restrictions) """
212 self.assertEqual(globToRegex(["foo", "*", "bar"]), [])
214 def testGlobList(self):
215 """Test that a list of glob strings converts as expected to a regex and
216 returns in the expected list.
217 """
218 # test an absolute string
219 patterns = globToRegex(["bar"])
220 self.assertEquals(len(patterns), 1)
221 self.assertTrue(bool(re.fullmatch(patterns[0], "bar")))
222 self.assertIsNone(re.fullmatch(patterns[0], "boz"))
224 # test leading & trailing wildcard in multiple patterns
225 patterns = globToRegex(["ba*", "*.fits"])
226 self.assertEquals(len(patterns), 2)
227 # check the "ba*" pattern:
228 self.assertTrue(bool(re.fullmatch(patterns[0], "bar")))
229 self.assertTrue(bool(re.fullmatch(patterns[0], "baz")))
230 self.assertIsNone(re.fullmatch(patterns[0], "boz.fits"))
231 # check the "*.fits" pattern:
232 self.assertTrue(bool(re.fullmatch(patterns[1], "bar.fits")))
233 self.assertTrue(re.fullmatch(patterns[1], "boz.fits"))
234 self.assertIsNone(re.fullmatch(patterns[1], "boz.hdf5"))
237if __name__ == "__main__": 237 ↛ 238line 237 didn't jump to line 238, because the condition on line 237 was never true
238 unittest.main()