Coverage for tests/test_dataid_match.py: 13%
52 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-12 11:14 -0700
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-12 11:14 -0700
1# This file is part of ctrl_mpexec.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://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 <https://www.gnu.org/licenses/>.
22import unittest
24from lsst.pipe.base.tests.mocks import DataIdMatch
27class DataIdMatchTestCase(unittest.TestCase):
28 """A test case for DataidMatch class"""
30 dataIds = (
31 {"instrument": "INSTR", "detector": 1, "number": 4},
32 {"instrument": "INSTR", "detector": 2, "number": 3},
33 {"instrument": "LSST", "detector": 3, "number": 2},
34 {"instrument": "LSST", "detector": 4, "number": 1},
35 )
37 def test_strings(self):
38 """Tests for string comparisons method"""
39 tests = (
40 ("instrument = 'INSTR'", [True, True, False, False]),
41 ("instrument = 'LSST'", [False, False, True, True]),
42 ("instrument < 'LSST'", [True, True, False, False]),
43 ("instrument IN ('LSST', 'INSTR')", [True, True, True, True]),
44 )
46 for expr, result in tests:
47 dataIdMatch = DataIdMatch(expr)
48 self.assertEqual([dataIdMatch.match(dataId) for dataId in self.dataIds], result)
50 def test_comparisons(self):
51 """Test all supported comparison operators"""
52 tests = (
53 ("detector = 1", [True, False, False, False]),
54 ("detector != 1", [False, True, True, True]),
55 ("detector > 2", [False, False, True, True]),
56 ("2 <= detector", [False, True, True, True]),
57 ("2 > detector", [True, False, False, False]),
58 ("2 >= detector", [True, True, False, False]),
59 )
61 for expr, result in tests:
62 dataIdMatch = DataIdMatch(expr)
63 self.assertEqual([dataIdMatch.match(dataId) for dataId in self.dataIds], result)
65 def test_arith(self):
66 """Test all supported arithmetical operators"""
67 tests = (
68 ("detector + number = 5", [True, True, True, True]),
69 ("detector - number = 1", [False, False, True, False]),
70 ("detector * number = 6", [False, True, True, False]),
71 ("detector / number = 1.5", [False, False, True, False]),
72 ("detector % number = 1", [True, False, True, False]),
73 ("+detector = 1", [True, False, False, False]),
74 ("-detector = -4", [False, False, False, True]),
75 )
77 for expr, result in tests:
78 dataIdMatch = DataIdMatch(expr)
79 self.assertEqual([dataIdMatch.match(dataId) for dataId in self.dataIds], result)
81 def test_logical(self):
82 """Test all supported logical operators"""
83 tests = (
84 ("detector = 1 OR instrument = 'LSST'", [True, False, True, True]),
85 ("detector = 1 AND instrument = 'INSTR'", [True, False, False, False]),
86 ("NOT detector = 1", [False, True, True, True]),
87 )
89 for expr, result in tests:
90 dataIdMatch = DataIdMatch(expr)
91 self.assertEqual([dataIdMatch.match(dataId) for dataId in self.dataIds], result)
93 def test_parens(self):
94 """Test parentheses"""
95 tests = (("(detector = 1 OR number = 1) AND instrument = 'LSST'", [False, False, False, True]),)
97 for expr, result in tests:
98 dataIdMatch = DataIdMatch(expr)
99 self.assertEqual([dataIdMatch.match(dataId) for dataId in self.dataIds], result)
101 def test_in(self):
102 """Test IN expression"""
103 tests = (
104 ("detector in (1, 3, 2)", [True, True, True, False]),
105 ("detector not in (1, 3, 2)", [False, False, False, True]),
106 ("detector in (1..4:2)", [True, False, True, False]),
107 ("detector in (1..4:2, 4)", [True, False, True, True]),
108 )
110 for expr, result in tests:
111 dataIdMatch = DataIdMatch(expr)
112 self.assertEqual([dataIdMatch.match(dataId) for dataId in self.dataIds], result)
114 def test_errors(self):
115 """Test for errors in expressions"""
116 dataId = {"instrument": "INSTR", "detector": 1}
118 # Unknown identifier
119 expr = "INSTRUMENT = 'INSTR'"
120 dataIdMatch = DataIdMatch(expr)
121 with self.assertRaisesRegex(KeyError, "INSTRUMENT"):
122 dataIdMatch.match(dataId)
124 # non-boolean expression
125 expr = "instrument"
126 dataIdMatch = DataIdMatch(expr)
127 with self.assertRaisesRegex(TypeError, "Expression 'instrument' returned non-boolean object"):
128 dataIdMatch.match(dataId)
130 # operations on unsupported combination of types
131 expr = "instrument - detector = 0"
132 dataIdMatch = DataIdMatch(expr)
133 with self.assertRaisesRegex(TypeError, "unsupported operand type"):
134 dataIdMatch.match(dataId)
136 # function calls are not implemented
137 expr = "POINT(2, 1) != POINT(1, 2)"
138 dataIdMatch = DataIdMatch(expr)
139 with self.assertRaises(NotImplementedError):
140 dataIdMatch.match(dataId)
143if __name__ == "__main__":
144 unittest.main()