Coverage for tests/test_utils.py: 19%

140 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-02-05 02:04 -0800

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/>. 

21 

22import os 

23import re 

24import unittest 

25from collections import namedtuple 

26 

27from lsst.daf.butler import NamedKeyDict, NamedValueSet 

28from lsst.daf.butler.core.utils import globToRegex 

29 

30TESTDIR = os.path.dirname(__file__) 

31 

32 

33class NamedKeyDictTest(unittest.TestCase): 

34 def setUp(self): 

35 self.TestTuple = namedtuple("TestTuple", ("name", "id")) 

36 self.a = self.TestTuple(name="a", id=1) 

37 self.b = self.TestTuple(name="b", id=2) 

38 self.dictionary = {self.a: 10, self.b: 20} 

39 self.names = {self.a.name, self.b.name} 

40 

41 def check(self, nkd): 

42 self.assertEqual(len(nkd), 2) 

43 self.assertEqual(nkd.names, self.names) 

44 self.assertEqual(nkd.keys(), self.dictionary.keys()) 

45 self.assertEqual(list(nkd.values()), list(self.dictionary.values())) 

46 self.assertEqual(list(nkd.items()), list(self.dictionary.items())) 

47 self.assertEqual(list(nkd.byName().values()), list(self.dictionary.values())) 

48 self.assertEqual(list(nkd.byName().keys()), list(nkd.names)) 

49 

50 def testConstruction(self): 

51 self.check(NamedKeyDict(self.dictionary)) 

52 self.check(NamedKeyDict(iter(self.dictionary.items()))) 

53 

54 def testDuplicateNameConstruction(self): 

55 self.dictionary[self.TestTuple(name="a", id=3)] = 30 

56 with self.assertRaises(AssertionError): 

57 NamedKeyDict(self.dictionary) 

58 with self.assertRaises(AssertionError): 

59 NamedKeyDict(iter(self.dictionary.items())) 

60 

61 def testNoNameConstruction(self): 

62 self.dictionary["a"] = 30 

63 with self.assertRaises(AttributeError): 

64 NamedKeyDict(self.dictionary) 

65 with self.assertRaises(AttributeError): 

66 NamedKeyDict(iter(self.dictionary.items())) 

67 

68 def testGetItem(self): 

69 nkd = NamedKeyDict(self.dictionary) 

70 self.assertEqual(nkd["a"], 10) 

71 self.assertEqual(nkd[self.a], 10) 

72 self.assertEqual(nkd["b"], 20) 

73 self.assertEqual(nkd[self.b], 20) 

74 self.assertIn("a", nkd) 

75 self.assertIn(self.b, nkd) 

76 

77 def testSetItem(self): 

78 nkd = NamedKeyDict(self.dictionary) 

79 nkd[self.a] = 30 

80 self.assertEqual(nkd["a"], 30) 

81 nkd["b"] = 40 

82 self.assertEqual(nkd[self.b], 40) 

83 with self.assertRaises(KeyError): 

84 nkd["c"] = 50 

85 with self.assertRaises(AssertionError): 

86 nkd[self.TestTuple("a", 3)] = 60 

87 

88 def testDelItem(self): 

89 nkd = NamedKeyDict(self.dictionary) 

90 del nkd[self.a] 

91 self.assertNotIn("a", nkd) 

92 del nkd["b"] 

93 self.assertNotIn(self.b, nkd) 

94 self.assertEqual(len(nkd), 0) 

95 

96 def testIter(self): 

97 self.assertEqual(set(iter(NamedKeyDict(self.dictionary))), set(self.dictionary)) 

98 

99 def testEquality(self): 

100 nkd = NamedKeyDict(self.dictionary) 

101 self.assertEqual(nkd, self.dictionary) 

102 self.assertEqual(self.dictionary, nkd) 

103 

104 

105class NamedValueSetTest(unittest.TestCase): 

106 def setUp(self): 

107 self.TestTuple = namedtuple("TestTuple", ("name", "id")) 

108 self.a = self.TestTuple(name="a", id=1) 

109 self.b = self.TestTuple(name="b", id=2) 

110 self.c = self.TestTuple(name="c", id=3) 

111 

112 def testConstruction(self): 

113 for arg in ({self.a, self.b}, (self.a, self.b)): 

114 for nvs in (NamedValueSet(arg), NamedValueSet(arg).freeze()): 

115 self.assertEqual(len(nvs), 2) 

116 self.assertEqual(nvs.names, {"a", "b"}) 

117 self.assertCountEqual(nvs, {self.a, self.b}) 

118 self.assertCountEqual(nvs.asMapping().items(), [(self.a.name, self.a), (self.b.name, self.b)]) 

119 

120 def testNoNameConstruction(self): 

121 with self.assertRaises(AttributeError): 

122 NamedValueSet([self.a, "a"]) 

123 

124 def testGetItem(self): 

125 nvs = NamedValueSet({self.a, self.b, self.c}) 

126 self.assertEqual(nvs["a"], self.a) 

127 self.assertEqual(nvs[self.a], self.a) 

128 self.assertEqual(nvs["b"], self.b) 

129 self.assertEqual(nvs[self.b], self.b) 

130 self.assertIn("a", nvs) 

131 self.assertIn(self.b, nvs) 

132 

133 def testEquality(self): 

134 s = {self.a, self.b, self.c} 

135 nvs = NamedValueSet(s) 

136 self.assertEqual(nvs, s) 

137 self.assertEqual(s, nvs) 

138 

139 def checkOperator(self, result, expected): 

140 self.assertIsInstance(result, NamedValueSet) 

141 self.assertEqual(result, expected) 

142 

143 def testOperators(self): 

144 ab = NamedValueSet({self.a, self.b}) 

145 bc = NamedValueSet({self.b, self.c}) 

146 self.checkOperator(ab & bc, {self.b}) 

147 self.checkOperator(ab | bc, {self.a, self.b, self.c}) 

148 self.checkOperator(ab ^ bc, {self.a, self.c}) 

149 self.checkOperator(ab - bc, {self.a}) 

150 

151 def testPop(self): 

152 # Construct with list for repeatable ordering. 

153 nvs = NamedValueSet([self.a, self.b, self.c]) 

154 self.assertEqual(nvs.pop("c"), self.c) 

155 self.assertEqual(nvs.pop(), self.a) 

156 self.assertEqual(nvs.pop(), self.b) 

157 self.assertEqual(nvs.pop("d", self.c), self.c) 

158 with self.assertRaises(KeyError): 

159 nvs.pop() 

160 

161 def testRemove(self): 

162 nvs = NamedValueSet([self.a, self.b, self.c]) 

163 nvs.remove("b") 

164 self.assertIn("a", nvs) 

165 self.assertNotIn("b", nvs) 

166 with self.assertRaises(KeyError): 

167 nvs.remove("d") 

168 nvs.discard("d") 

169 nvs.discard("a") 

170 self.assertNotIn("a", nvs) 

171 

172 

173class GlobToRegexTestCase(unittest.TestCase): 

174 def testStarInList(self): 

175 """Test that if a one of the items in the expression list is a star 

176 (stand-alone) then ``...`` is returned (which implies no restrictions) 

177 """ 

178 self.assertIs(globToRegex(["foo", "*", "bar"]), ...) 

179 

180 def testGlobList(self): 

181 """Test that a list of glob strings converts as expected to a regex and 

182 returns in the expected list. 

183 """ 

184 # These strings should be returned unchanged. 

185 strings = ["bar", "😺", "ingésτ", "ex]", "[xe", "[!no", "e[x"] 

186 self.assertEqual(globToRegex(strings), strings) 

187 

188 # Globs with strings that match the glob and strings that do not. 

189 tests = ( 

190 ("bar", ["bar"], ["baz"]), 

191 ("ba*", ["bar", "baz"], ["az"]), 

192 ("ba[rz]", ["bar", "baz"], ["bat"]), 

193 ("ba[rz]x[y", ["barx[y", "bazx[y"], ["batx[y"]), 

194 ("ba[!rz]", ["bat", "baτ"], ["bar", "baz"]), 

195 ("b?r", ["bor", "bar", "b😺r"], ["bat"]), 

196 ("*.fits", ["boz.fits"], ["boz.fits.gz", "boz.hdf5"]), 

197 ) 

198 

199 for glob, matches, no_matches in tests: 

200 patterns = globToRegex(glob) 

201 for match in matches: 

202 self.assertTrue(bool(re.fullmatch(patterns[0], match))) 

203 for no_match in no_matches: 

204 self.assertIsNone(re.fullmatch(patterns[0], no_match)) 

205 

206 

207if __name__ == "__main__": 207 ↛ 208line 207 didn't jump to line 208, because the condition on line 207 was never true

208 unittest.main()