Coverage for tests/test_leaf_relation.py: 15%
77 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-22 02:59 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-22 02:59 -0800
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 engine = iteration.Engine()
75 join_identity_leaf = LeafRelation.make_join_identity(engine)
76 self.assertEqual(join_identity_leaf, LeafRelation.make_join_identity(engine))
77 self.assertEqual(join_identity_leaf.engine, engine)
78 self.assertEqual(join_identity_leaf.columns, set())
79 self.assertEqual(join_identity_leaf.min_rows, 1)
80 self.assertEqual(join_identity_leaf.max_rows, 1)
81 self.assertTrue(join_identity_leaf.is_locked)
82 self.assertTrue(join_identity_leaf.is_join_identity)
83 self.assertTrue(join_identity_leaf.is_trivial)
84 self.assertIsNone(join_identity_leaf.parameters)
85 self.assertEqual(join_identity_leaf.name, "I")
86 self.assertCountEqual(join_identity_leaf.payload, [{}])
88 def test_doomed(self) -> None:
89 """Test `LeafRelation.make_doomed and the iteration engine's
90 get_doomed_payload."""
91 engine = iteration.Engine()
92 doomed_leaf = LeafRelation.make_doomed(engine, {self.a, self.b}, ["doomed 1"])
93 self.assertEqual(
94 doomed_leaf,
95 LeafRelation(
96 engine,
97 frozenset({self.a, self.b}),
98 [],
99 messages=["doomed 1"],
100 name="0",
101 min_rows=0,
102 max_rows=0,
103 ),
104 )
105 # Messages not important for equality.
106 self.assertEqual(doomed_leaf, LeafRelation.make_doomed(engine, {self.a, self.b}, ["doomed 2"]))
107 # Columns are important for equality.
108 self.assertNotEqual(doomed_leaf, LeafRelation.make_doomed(engine, {self.a}, ["doomed 1"]))
109 # Name is important for equality.
110 self.assertNotEqual(
111 doomed_leaf, LeafRelation.make_doomed(engine, {self.a, self.b}, ["doomed 1"], name="c")
112 )
113 self.assertEqual(doomed_leaf.engine, engine)
114 self.assertEqual(doomed_leaf.columns, {self.a, self.b})
115 self.assertEqual(doomed_leaf.min_rows, 0)
116 self.assertEqual(doomed_leaf.max_rows, 0)
117 self.assertTrue(doomed_leaf.is_locked)
118 self.assertFalse(doomed_leaf.is_join_identity)
119 self.assertTrue(doomed_leaf.is_trivial)
120 self.assertIsNone(doomed_leaf.parameters, None)
121 self.assertEqual(doomed_leaf.name, "0")
122 self.assertCountEqual(doomed_leaf.payload, [])
124 def test_bad_min_max_rows(self) -> None:
125 """Test construction checks for inconsistent min_rows / max_rows."""
126 engine = iteration.Engine()
127 with self.assertRaises(ValueError):
128 LeafRelation(engine, frozenset({self.a, self.b}), payload=..., min_rows=2, max_rows=1)
130 def test_str(self) -> None:
131 """Test str(LeafRelation)."""
132 engine = iteration.Engine()
133 self.assertEqual(
134 str(LeafRelation(engine, frozenset({self.a, self.b}), payload=..., name="leaf1")), "leaf1"
135 )
136 self.assertEqual(
137 str(
138 LeafRelation(
139 engine, frozenset({self.a, self.b}), payload=..., name="leaf2", parameters=[1, 2]
140 )
141 ),
142 "leaf2([1, 2])",
143 )
146if __name__ == "__main__": 146 ↛ 147line 146 didn't jump to line 147, because the condition on line 146 was never true
147 unittest.main()