1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.geometry.core.partitioning.bsp;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.List;
22 import java.util.function.Consumer;
23 import java.util.function.Supplier;
24
25 import org.apache.commons.geometry.core.RegionLocation;
26 import org.apache.commons.geometry.core.partitioning.test.PartitionTestUtils;
27 import org.apache.commons.geometry.core.partitioning.test.TestPoint2D;
28 import org.apache.commons.geometry.core.partitioning.test.TestRegionBSPTree;
29 import org.junit.jupiter.api.Assertions;
30
31
32
33 class MergeChecker {
34
35
36
37 @FunctionalInterface
38 public interface Operation {
39 TestRegionBSPTree apply(TestRegionBSPTree tree1, TestRegionBSPTree tree2);
40 }
41
42
43 private final Supplier<TestRegionBSPTree> tree1Factory;
44
45
46 private final Supplier<TestRegionBSPTree> tree2Factory;
47
48
49 private final Operation constOperation;
50
51
52
53
54 private final Operation inPlaceOperation;
55
56
57 private int expectedCount = -1;
58
59
60 private boolean expectedFull;
61
62
63 private boolean expectedEmpty;
64
65
66 private final List<TestPoint2D> insidePoints = new ArrayList<>();
67
68
69 private final List<TestPoint2D> outsidePoints = new ArrayList<>();
70
71
72 private final List<TestPoint2D> boundaryPoints = new ArrayList<>();
73
74
75
76
77
78
79
80
81
82
83
84 MergeChecker(
85 final Supplier<TestRegionBSPTree> tree1Factory,
86 final Supplier<TestRegionBSPTree> tree2Factory,
87 final Operation constOperation,
88 final Operation inPlaceOperation) {
89
90 this.tree1Factory = tree1Factory;
91 this.tree2Factory = tree2Factory;
92 this.constOperation = constOperation;
93 this.inPlaceOperation = inPlaceOperation;
94 }
95
96
97
98
99
100 public MergeChecker count(final int expectedCountVal) {
101 this.expectedCount = expectedCountVal;
102 return this;
103 }
104
105
106
107
108
109 public MergeChecker full(final boolean expectedFullVal) {
110 this.expectedFull = expectedFullVal;
111 return this;
112 }
113
114
115
116
117
118 public MergeChecker empty(final boolean expectedEmptyVal) {
119 this.expectedEmpty = expectedEmptyVal;
120 return this;
121 }
122
123
124
125
126
127
128 public MergeChecker inside(final TestPoint2D... points) {
129 insidePoints.addAll(Arrays.asList(points));
130 return this;
131 }
132
133
134
135
136
137
138 public MergeChecker outside(final TestPoint2D... points) {
139 outsidePoints.addAll(Arrays.asList(points));
140 return this;
141 }
142
143
144
145
146
147
148 public MergeChecker boundary(final TestPoint2D... points) {
149 boundaryPoints.addAll(Arrays.asList(points));
150 return this;
151 }
152
153
154
155 public void check() {
156 check(null);
157 }
158
159
160
161
162
163
164 public void check(final Consumer<TestRegionBSPTree> assertions) {
165 checkConst(assertions);
166 checkInPlace(assertions);
167 }
168
169 private void checkConst(final Consumer<TestRegionBSPTree> assertions) {
170 checkInternal(false, constOperation, assertions);
171 }
172
173 private void checkInPlace(final Consumer<TestRegionBSPTree> assertions) {
174 checkInternal(true, inPlaceOperation, assertions);
175 }
176
177 private void checkInternal(final boolean inPlace, final Operation operation,
178 final Consumer<? super TestRegionBSPTree> assertions) {
179
180 final TestRegionBSPTree tree1 = tree1Factory.get();
181 final TestRegionBSPTree tree2 = tree2Factory.get();
182
183
184 final int tree1BeforeCount = tree1.count();
185 final int tree2BeforeCount = tree2.count();
186
187
188 final TestRegionBSPTree result = operation.apply(tree1, tree2);
189
190
191 PartitionTestUtils.assertTreeStructure(tree1);
192 PartitionTestUtils.assertTreeStructure(tree2);
193 PartitionTestUtils.assertTreeStructure(result);
194
195
196 Assertions.assertEquals(expectedFull, result.isFull(), "Unexpected tree 'full' property");
197 Assertions.assertEquals(expectedEmpty, result.isEmpty(), "Unexpected tree 'empty' property");
198
199
200 if (expectedCount > -1) {
201 Assertions.assertEquals(expectedCount, result.count(), "Unexpected node count");
202 }
203
204
205 if (inPlace) {
206 Assertions.assertSame(tree1, result, "Expected merge operation to be in place");
207 } else {
208 Assertions.assertNotSame(tree1, result, "Expected merge operation to return a new instance");
209
210
211 Assertions.assertEquals(tree1BeforeCount, tree1.count(), "Tree 1 node count should not have changed");
212 }
213
214
215 Assertions.assertEquals(tree2BeforeCount, tree2.count(), "Tree 2 node count should not have changed");
216
217
218 PartitionTestUtils.assertPointLocations(result, RegionLocation.INSIDE, insidePoints);
219 PartitionTestUtils.assertPointLocations(result, RegionLocation.OUTSIDE, outsidePoints);
220 PartitionTestUtils.assertPointLocations(result, RegionLocation.BOUNDARY, boundaryPoints);
221
222
223 if (assertions != null) {
224 assertions.accept(result);
225 }
226 }
227 }