Coverage for tests/test_leaf_relation.py: 13%
75 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-21 09:39 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-21 09:39 +0000
1# This file is part of daf_relation.
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 __future__ import annotations
24import unittest
26from lsst.daf.relation import LeafRelation, iteration, tests
29class LeafRelationTestCase(unittest.TestCase):
30 """Tests for LeafRelation and closely-related iteration-engine methods."""
32 def setUp(self) -> None:
33 self.a = tests.ColumnTag("a")
34 self.b = tests.ColumnTag("b")
36 def test_iteration_make_leaf(self) -> None:
37 """Test the iteration engine's `make_leaf` function, and with it
38 the dataclass field definitions for `LeafRelation` itself`.
39 """
40 engine = iteration.Engine()
41 columns = {self.a, self.b}
42 sequence_payload = iteration.RowSequence(
43 [{self.a: 0, self.b: 0}, {self.a: 0, self.b: 1}, {self.a: 1, self.b: 0}, {self.a: 0, self.b: 0}]
44 )
45 mapping_payload = sequence_payload.to_mapping((self.a, self.b))
46 sequence_leaf = engine.make_leaf(columns, payload=sequence_payload)
47 self.assertEqual(sequence_leaf.engine, engine)
48 self.assertEqual(sequence_leaf.columns, columns)
49 self.assertEqual(sequence_leaf.min_rows, 4)
50 self.assertEqual(sequence_leaf.max_rows, 4)
51 self.assertTrue(sequence_leaf.is_locked)
52 self.assertFalse(sequence_leaf.is_join_identity)
53 self.assertFalse(sequence_leaf.is_trivial)
54 self.assertIsNone(sequence_leaf.parameters)
55 self.assertTrue(sequence_leaf.name.startswith("leaf"))
56 self.assertCountEqual(sequence_leaf.payload, sequence_payload)
57 mapping_leaf = engine.make_leaf(columns=columns, payload=mapping_payload)
58 self.assertEqual(mapping_leaf.engine, engine)
59 self.assertEqual(mapping_leaf.columns, columns)
60 self.assertEqual(mapping_leaf.min_rows, 3)
61 self.assertEqual(mapping_leaf.max_rows, 3)
62 self.assertTrue(mapping_leaf.is_locked)
63 self.assertFalse(mapping_leaf.is_join_identity)
64 self.assertFalse(mapping_leaf.is_trivial)
65 self.assertIsNone(mapping_leaf.parameters)
66 self.assertTrue(mapping_leaf.name.startswith("leaf"))
67 self.assertCountEqual(mapping_leaf.payload, mapping_payload)
68 self.assertNotEqual(mapping_leaf.name, sequence_leaf.name)
69 self.assertNotEqual(mapping_leaf, sequence_leaf)
71 def test_join_identity(self) -> None:
72 """Test `LeafRelation.make_join_identity and the iteration engine's
73 get_join_identity_payload.
74 """
75 engine = iteration.Engine()
76 join_identity_leaf = LeafRelation.make_join_identity(engine)
77 self.assertEqual(join_identity_leaf, LeafRelation.make_join_identity(engine))
78 self.assertEqual(join_identity_leaf.engine, engine)
79 self.assertEqual(join_identity_leaf.columns, set())
80 self.assertEqual(join_identity_leaf.min_rows, 1)
81 self.assertEqual(join_identity_leaf.max_rows, 1)
82 self.assertTrue(join_identity_leaf.is_locked)
83 self.assertTrue(join_identity_leaf.is_join_identity)
84 self.assertTrue(join_identity_leaf.is_trivial)
85 self.assertIsNone(join_identity_leaf.parameters)
86 self.assertEqual(join_identity_leaf.name, "I")
87 self.assertCountEqual(join_identity_leaf.payload, [{}])
89 def test_doomed(self) -> None:
90 """Test `LeafRelation.make_doomed and the iteration engine's
91 get_doomed_payload.
92 """
93 engine = iteration.Engine()
94 doomed_leaf = LeafRelation.make_doomed(engine, {self.a, self.b}, ["doomed 1"])
95 self.assertEqual(
96 doomed_leaf,
97 LeafRelation(
98 engine,
99 frozenset({self.a, self.b}),
100 [],
101 messages=["doomed 1"],
102 name="0",
103 min_rows=0,
104 max_rows=0,
105 ),
106 )
107 # Messages not important for equality.
108 self.assertEqual(doomed_leaf, LeafRelation.make_doomed(engine, {self.a, self.b}, ["doomed 2"]))
109 # Columns are important for equality.
110 self.assertNotEqual(doomed_leaf, LeafRelation.make_doomed(engine, {self.a}, ["doomed 1"]))
111 # Name is important for equality.
112 self.assertNotEqual(
113 doomed_leaf, LeafRelation.make_doomed(engine, {self.a, self.b}, ["doomed 1"], name="c")
114 )
115 self.assertEqual(doomed_leaf.engine, engine)
116 self.assertEqual(doomed_leaf.columns, {self.a, self.b})
117 self.assertEqual(doomed_leaf.min_rows, 0)
118 self.assertEqual(doomed_leaf.max_rows, 0)
119 self.assertTrue(doomed_leaf.is_locked)
120 self.assertFalse(doomed_leaf.is_join_identity)
121 self.assertTrue(doomed_leaf.is_trivial)
122 self.assertIsNone(doomed_leaf.parameters, None)
123 self.assertEqual(doomed_leaf.name, "0")
124 self.assertCountEqual(doomed_leaf.payload, [])
126 def test_bad_min_max_rows(self) -> None:
127 """Test construction checks for inconsistent min_rows / max_rows."""
128 engine = iteration.Engine()
129 with self.assertRaises(ValueError):
130 LeafRelation(engine, frozenset({self.a, self.b}), payload=..., min_rows=2, max_rows=1)
132 def test_str(self) -> None:
133 """Test str(LeafRelation)."""
134 engine = iteration.Engine()
135 self.assertEqual(
136 str(LeafRelation(engine, frozenset({self.a, self.b}), payload=..., name="leaf1")), "leaf1"
137 )
138 self.assertEqual(
139 str(
140 LeafRelation(
141 engine, frozenset({self.a, self.b}), payload=..., name="leaf2", parameters=[1, 2]
142 )
143 ),
144 "leaf2([1, 2])",
145 )
148if __name__ == "__main__":
149 unittest.main()