Cleanup DataTreeCandidatesAggregateTest
[yangtools.git] / data / yang-data-tree-spi / src / test / java / org / opendaylight / yangtools / yang / data / tree / spi / DataTreeCandidatesAggregateTest.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.tree.spi;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertThrows;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.mock;
14 import static org.opendaylight.yangtools.yang.data.tree.api.ModificationType.APPEARED;
15 import static org.opendaylight.yangtools.yang.data.tree.api.ModificationType.DELETE;
16 import static org.opendaylight.yangtools.yang.data.tree.api.ModificationType.DISAPPEARED;
17 import static org.opendaylight.yangtools.yang.data.tree.api.ModificationType.SUBTREE_MODIFIED;
18 import static org.opendaylight.yangtools.yang.data.tree.api.ModificationType.UNMODIFIED;
19 import static org.opendaylight.yangtools.yang.data.tree.api.ModificationType.WRITE;
20
21 import java.util.List;
22 import java.util.Optional;
23 import org.junit.Test;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
29 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
30 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
31 import org.opendaylight.yangtools.yang.data.tree.api.ModificationType;
32
33 public class DataTreeCandidatesAggregateTest {
34     private static final YangInstanceIdentifier ROOT_PATH = YangInstanceIdentifier.of(QName.create(
35             "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:container",
36             "2014-03-13", "container"));
37     private static final YangInstanceIdentifier.PathArgument CHILD_ID = new NodeIdentifier(QName.create(
38             "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test:container:data",
39             "2014-03-13", "data"));
40
41     @Test
42     public void testLeafUnmodifiedUnmodified() {
43         NormalizedNode normalizedNode1 = normalizedNode("value1");
44         NormalizedNode normalizedNode2 = normalizedNode("value1");
45         NormalizedNode normalizedNode3 = normalizedNode("value1");
46
47         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2, UNMODIFIED);
48         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
49
50         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, normalizedNode3, UNMODIFIED);
51         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
52
53         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
54
55         assertEquals(UNMODIFIED, aggregationResult.getRootNode().getModificationType());
56         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().orElseThrow().body());
57         assertEquals("value1", aggregationResult.getRootNode().getDataAfter().orElseThrow().body());
58     }
59
60     @Test
61     public void testLeaftUnmodifiedWrite() {
62         NormalizedNode normalizedNode1 = normalizedNode("value1");
63         NormalizedNode normalizedNode2 = normalizedNode("value1");
64         NormalizedNode normalizedNode3 = normalizedNode("value2");
65
66         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2, UNMODIFIED);
67         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
68
69         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, normalizedNode3, WRITE);
70         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
71
72         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
73
74         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
75         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().orElseThrow().body());
76         assertEquals("value2", aggregationResult.getRootNode().getDataAfter().orElseThrow().body());
77     }
78
79     @Test
80     public void testLeafUnmodifiedDelete() {
81         NormalizedNode normalizedNode1 = normalizedNode("value1");
82         NormalizedNode normalizedNode2 = normalizedNode("value1");
83
84         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2, UNMODIFIED);
85         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
86
87         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, null, DELETE);
88         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
89
90         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
91
92         assertEquals(DELETE, aggregationResult.getRootNode().getModificationType());
93         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().orElseThrow().body());
94         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataAfter());
95     }
96
97     @Test
98     public void testLeafUnmodifiedDeleteWithoutDataBefore() {
99         DataTreeCandidateNode node1 = dataTreeCandidateNode(null, null, UNMODIFIED);
100         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
101
102         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, DELETE);
103         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
104
105         assertThrows(IllegalArgumentException.class,
106             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
107     }
108
109     @Test
110     public void testLeafUnmodifiedSubtreeModifiedWithoutDataBefore() {
111         DataTreeCandidateNode node1 = dataTreeCandidateNode(null, null, UNMODIFIED);
112         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
113
114         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, SUBTREE_MODIFIED);
115         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
116
117         assertThrows(IllegalArgumentException.class,
118             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
119     }
120
121     @Test
122     public void testLeafWriteUnmodified() {
123         NormalizedNode normalizedNode1 = normalizedNode("value1");
124         NormalizedNode normalizedNode2 = normalizedNode("value2");
125
126         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2, WRITE);
127         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
128
129         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, normalizedNode2, UNMODIFIED);
130         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
131
132         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
133
134         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
135         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().orElseThrow().body());
136         assertEquals("value2", aggregationResult.getRootNode().getDataAfter().orElseThrow().body());
137     }
138
139     @Test
140     public void testLeafWriteWrite() {
141         NormalizedNode normalizedNode1 = normalizedNode("value1");
142         NormalizedNode normalizedNode2 = normalizedNode("value2");
143         NormalizedNode normalizedNode3 = normalizedNode("value3");
144
145         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2, WRITE);
146         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
147
148         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, normalizedNode3, WRITE);
149         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
150
151         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
152
153         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
154         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().orElseThrow().body());
155         assertEquals("value3", aggregationResult.getRootNode().getDataAfter().orElseThrow().body());
156     }
157
158     @Test
159     public void testLeafWriteDeleteWithoutChanges() {
160         NormalizedNode normalizedNode = normalizedNode("value1");
161
162         DataTreeCandidateNode node1 = dataTreeCandidateNode(null, normalizedNode, WRITE);
163         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
164
165         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode, null, DELETE);
166         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
167
168         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
169
170         assertEquals(UNMODIFIED, aggregationResult.getRootNode().getModificationType());
171         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataBefore());
172         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataAfter());
173     }
174
175     @Test
176     public void testLeafWriteDelete() {
177         NormalizedNode normalizedNode1 = normalizedNode("value1");
178         NormalizedNode normalizedNode2 = normalizedNode("value2");
179
180         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, normalizedNode2, WRITE);
181         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
182
183         DataTreeCandidateNode node2 = dataTreeCandidateNode(normalizedNode2, null, DELETE);
184         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
185
186         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
187
188         assertEquals(DELETE, aggregationResult.getRootNode().getModificationType());
189         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().orElseThrow().body());
190         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataAfter());
191     }
192
193     @Test
194     public void testLeafDeleteUnmodified() {
195         NormalizedNode normalizedNode = normalizedNode("value");
196
197         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode, null, DELETE);
198         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
199
200         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, UNMODIFIED);
201         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
202
203         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
204
205         assertEquals(DELETE, aggregationResult.getRootNode().getModificationType());
206         assertEquals("value", aggregationResult.getRootNode().getDataBefore().orElseThrow().body());
207         assertEquals(Optional.empty(), aggregationResult.getRootNode().getDataAfter());
208     }
209
210     @Test
211     public void testLeafDeleteWrite() {
212         NormalizedNode normalizedNode1 = normalizedNode("value1");
213         NormalizedNode normalizedNode2 = normalizedNode("value2");
214
215         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, null, DELETE);
216         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
217
218         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, normalizedNode2, WRITE);
219         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
220
221         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
222
223         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
224         assertEquals("value1", aggregationResult.getRootNode().getDataBefore().orElseThrow().body());
225         assertEquals("value2", aggregationResult.getRootNode().getDataAfter().orElseThrow().body());
226     }
227
228     @Test
229     public void testLeafDeleteDelete() {
230         NormalizedNode normalizedNode1 = normalizedNode("value1");
231
232         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, null, DELETE);
233         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
234
235         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, DELETE);
236         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
237
238         assertThrows(IllegalArgumentException.class,
239             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
240     }
241
242     @Test
243     public void testLeafDeleteDisappear() {
244         NormalizedNode normalizedNode1 = normalizedNode("value1");
245
246         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, null, DELETE);
247         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
248
249         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, DISAPPEARED);
250         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
251
252         assertThrows(IllegalArgumentException.class,
253             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
254     }
255
256     @Test
257     public void testLeafDeleteSubtreeModified() {
258         NormalizedNode normalizedNode1 = normalizedNode("value1");
259
260         DataTreeCandidateNode node1 = dataTreeCandidateNode(normalizedNode1, null, DELETE);
261         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
262
263         DataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, SUBTREE_MODIFIED);
264         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
265
266         assertThrows(IllegalArgumentException.class,
267             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
268     }
269
270     @Test
271     public void testUnmodifiedUnmodified() throws NoSuchFieldException {
272         NormalizedNode parentNode = normalizedNode("container");
273         NormalizedNode childNode = normalizedNode("child");
274
275         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode, parentNode, UNMODIFIED);
276         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode, UNMODIFIED);
277         setChildNodes(node1, List.of(child1));
278         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
279
280         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode, UNMODIFIED);
281         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, childNode, UNMODIFIED);
282         setChildNodes(node2, List.of(child2));
283         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
284
285         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
286
287         assertEquals(UNMODIFIED, aggregationResult.getRootNode().getModificationType());
288     }
289
290     @Test
291     public void testUnmodifiedDelete() {
292         NormalizedNode parentNode = normalizedNode("container");
293         NormalizedNode childNode = normalizedNode("child");
294
295         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode, parentNode, UNMODIFIED);
296         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode, UNMODIFIED);
297         setChildNodes(node1, List.of(child1));
298         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
299
300         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, null, DELETE);
301         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, null, DELETE);
302         setChildNodes(node2, List.of(child2));
303         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
304
305         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
306
307         assertEquals(DELETE, aggregationResult.getRootNode().getModificationType());
308     }
309
310     @Test
311     public void testUnmodifiedWrite() {
312         NormalizedNode parentNode1 = normalizedNode("container1");
313         NormalizedNode childNode1 = normalizedNode("child1");
314         NormalizedNode parentNode2 = normalizedNode("container2");
315         NormalizedNode childNode2 = normalizedNode("child2");
316
317         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1, UNMODIFIED);
318         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode1, UNMODIFIED);
319         setChildNodes(node1, List.of(child1));
320         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
321
322         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2, WRITE);
323         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
324         setChildNodes(node2, List.of(child2));
325         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
326
327         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
328
329         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
330     }
331
332     @Test
333     public void testUnmodifiedSubtreeModifiedWithoutDataBefore() {
334         NormalizedNode parentNode = normalizedNode("container");
335         NormalizedNode childNode = normalizedNode("child");
336
337         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, null, UNMODIFIED);
338         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, null, UNMODIFIED);
339         setChildNodes(node1, List.of(child1));
340         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
341
342         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode, SUBTREE_MODIFIED);
343         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode, WRITE);
344         setChildNodes(node2, List.of(child2));
345         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
346
347         assertThrows(IllegalArgumentException.class,
348             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
349     }
350
351     //FIXME
352     @Test
353     public void testUnmodifiedSubtreeModified() {
354         NormalizedNode parentNode1 = normalizedNode("container1");
355         NormalizedNode childNode1 = normalizedNode("child1");
356         NormalizedNode parentNode2 = normalizedNode("container1");
357         NormalizedNode childNode2 = normalizedNode("child2");
358
359         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1, UNMODIFIED);
360         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode1, UNMODIFIED);
361         setChildNodes(node1, List.of(child1));
362         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
363
364         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2, SUBTREE_MODIFIED);
365         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
366         setChildNodes(node2, List.of(child2));
367         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
368
369         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
370
371         assertEquals(SUBTREE_MODIFIED, aggregationResult.getRootNode().getModificationType());
372     }
373
374     @Test
375     public void testUnmodifiedAppearedWithDataBefore() {
376         NormalizedNode parentNode1 = normalizedNode("container1");
377         NormalizedNode childNode1 = normalizedNode("child1");
378         NormalizedNode parentNode2 = normalizedNode("container1");
379         NormalizedNode childNode2 = normalizedNode("child2");
380
381         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1, UNMODIFIED);
382         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode1, UNMODIFIED);
383         setChildNodes(node1, List.of(child1));
384         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
385
386         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2, APPEARED);
387         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
388         setChildNodes(node2, List.of(child2));
389         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
390
391         assertThrows(IllegalArgumentException.class,
392             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
393     }
394
395     //FIXME
396     @Test
397     public void testUnmodifiedAppeared() {
398         NormalizedNode parentNode = normalizedNode("container");
399         NormalizedNode childNode = normalizedNode("child");
400
401         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, null, UNMODIFIED);
402         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, null, UNMODIFIED);
403         setChildNodes(node1, List.of(child1));
404         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
405
406         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode, APPEARED);
407         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode, WRITE);
408         setChildNodes(node2, List.of(child2));
409         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
410
411         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
412
413         assertEquals(APPEARED, aggregationResult.getRootNode().getModificationType());
414     }
415
416     @Test
417     public void testUnmodifiedDisappearWithoutDataBefore() {
418         NormalizedNode parentNode = normalizedNode("container");
419         NormalizedNode childNode = normalizedNode("child");
420
421         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, null, UNMODIFIED);
422         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, null, UNMODIFIED);
423         setChildNodes(node1, List.of(child1));
424         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
425
426         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode, DISAPPEARED);
427         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode, DELETE);
428         setChildNodes(node2, List.of(child2));
429         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
430
431         assertThrows(IllegalArgumentException.class,
432             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
433     }
434
435     @Test
436     public void testUnmodifiedDisappear() {
437         NormalizedNode parentNode1 = normalizedNode("container1");
438         NormalizedNode childNode1 = normalizedNode("child1");
439
440         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1, UNMODIFIED);
441         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode1, UNMODIFIED);
442         setChildNodes(node1, List.of(child1));
443         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
444
445         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, null, DISAPPEARED);
446         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, null, DELETE);
447         setChildNodes(node2, List.of(child2));
448         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
449
450         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
451
452         assertEquals(DISAPPEARED, aggregationResult.getRootNode().getModificationType());
453     }
454
455     @Test
456     public void testDeleteUnmodified() {
457         NormalizedNode parentNode = normalizedNode("container");
458         NormalizedNode childNode = normalizedNode("child");
459
460         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode, null, DELETE);
461         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, null, DELETE);
462         setChildNodes(node1, List.of(child1));
463         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
464
465         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, UNMODIFIED);
466         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, null, UNMODIFIED);
467         setChildNodes(node2, List.of(child2));
468         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
469
470         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
471
472         assertEquals(DELETE, aggregationResult.getRootNode().getModificationType());
473     }
474
475     @Test
476     public void testDeleteWrite() {
477         NormalizedNode parentNode1 = normalizedNode("container1");
478         NormalizedNode parentNode2 = normalizedNode("container2");
479         NormalizedNode childNode1 = normalizedNode("child1");
480         NormalizedNode childNode2 = normalizedNode("child2");
481
482         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null, DELETE);
483         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null, DELETE);
484         setChildNodes(node1, List.of(child1));
485         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
486
487         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2, WRITE);
488         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2, WRITE);
489         setChildNodes(node2, List.of(child2));
490         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
491
492         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
493
494         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
495     }
496
497     @Test
498     public void testDeleteAppear() {
499         NormalizedNode parentNode1 = normalizedNode("container1");
500         NormalizedNode parentNode2 = normalizedNode("container2");
501         NormalizedNode childNode1 = normalizedNode("child1");
502         NormalizedNode childNode2 = normalizedNode("child2");
503
504         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null, DELETE);
505         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null, DELETE);
506         setChildNodes(node1, List.of(child1));
507         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
508
509         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2, APPEARED);
510         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2, WRITE);
511         setChildNodes(node2, List.of(child2));
512         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
513
514         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
515
516         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
517     }
518
519     @Test
520     public void testWriteUnmodified() {
521         NormalizedNode parentNode = normalizedNode("container");
522         NormalizedNode childNode = normalizedNode("child");
523
524         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode, WRITE);
525         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode, WRITE);
526         setChildNodes(node1, List.of(child1));
527         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
528
529         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, parentNode, UNMODIFIED);
530         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, childNode, UNMODIFIED);
531         setChildNodes(node2, List.of(child2));
532         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
533
534         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
535
536         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
537     }
538
539     @Test
540     public void testWriteDeleteWithoutChanges() {
541         NormalizedNode parentNode = normalizedNode("container");
542         NormalizedNode childNode = normalizedNode("child");
543
544         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode, WRITE);
545         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode, WRITE);
546         setChildNodes(node1, List.of(child1));
547         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
548
549         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, null, DELETE);
550         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, null, DELETE);
551         setChildNodes(node2, List.of(child2));
552         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
553
554         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
555
556         assertEquals(UNMODIFIED, aggregationResult.getRootNode().getModificationType());
557     }
558
559     @Test
560     public void testWriteDelete() {
561         NormalizedNode parentNode1 = normalizedNode("container1");
562         NormalizedNode parentNode2 = normalizedNode("container2");
563         NormalizedNode childNode1 = normalizedNode("child1");
564         NormalizedNode childNode2 = normalizedNode("child2");
565
566         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2, WRITE);
567         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
568         setChildNodes(node1, List.of(child1));
569         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
570
571         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, null, DELETE);
572         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, null, DELETE);
573         setChildNodes(node2, List.of(child2));
574         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
575
576         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
577
578         assertEquals(DELETE, aggregationResult.getRootNode().getModificationType());
579     }
580
581     @Test
582     public void testWriteWrite() {
583         NormalizedNode parentNode1 = normalizedNode("container1");
584         NormalizedNode parentNode2 = normalizedNode("container2");
585         NormalizedNode childNode1 = normalizedNode("child1");
586         NormalizedNode childNode2 = normalizedNode("child2");
587
588         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1, WRITE);
589         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1, WRITE);
590         setChildNodes(node1, List.of(child1));
591         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
592
593         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2, WRITE);
594         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
595         setChildNodes(node2, List.of(child2));
596         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
597
598         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
599
600         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
601     }
602
603     @Test
604     public void testWriteSubtreeModified() {
605         NormalizedNode parentNode = normalizedNode("container");
606         NormalizedNode parentNode1 = normalizedNode("container1");
607         NormalizedNode parentNode2 = normalizedNode("container1");
608         NormalizedNode childNode = normalizedNode("child");
609         NormalizedNode childNode1 = normalizedNode("child1");
610         NormalizedNode childNode2 = normalizedNode("child2");
611
612         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode, parentNode1, WRITE);
613         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1, WRITE);
614         setChildNodes(node1, List.of(child1));
615         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
616
617         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2, SUBTREE_MODIFIED);
618         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
619         setChildNodes(node2, List.of(child2));
620         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
621
622         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
623
624         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
625     }
626
627     @Test
628     public void testWriteAppear() {
629         NormalizedNode parentNode1 = normalizedNode("container1");
630         NormalizedNode parentNode2 = normalizedNode("container2");
631         NormalizedNode childNode1 = normalizedNode("child1");
632         NormalizedNode childNode2 = normalizedNode("child2");
633         NormalizedNode childNode3 = normalizedNode("child3");
634
635         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2, WRITE);
636         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
637         setChildNodes(node1, List.of(child1));
638         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
639
640         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, parentNode2, APPEARED);
641         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, childNode3, WRITE);
642         setChildNodes(node2, List.of(child2));
643         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
644
645         assertThrows(IllegalArgumentException.class,
646             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
647     }
648
649     @Test
650     public void testWriteDisappearWithoutChanges() {
651         NormalizedNode parentNode = normalizedNode("container");
652         NormalizedNode childNode = normalizedNode("child");
653
654         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode, WRITE);
655         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode, WRITE);
656         setChildNodes(node1, List.of(child1));
657         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
658
659         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode, null, DISAPPEARED);
660         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode, null, DELETE);
661         setChildNodes(node2, List.of(child2));
662         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
663
664         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
665
666         assertEquals(UNMODIFIED, aggregationResult.getRootNode().getModificationType());
667     }
668
669     @Test
670     public void testWriteDisappear() {
671         NormalizedNode parentNode1 = normalizedNode("container1");
672         NormalizedNode parentNode2 = normalizedNode("container2");
673         NormalizedNode childNode1 = normalizedNode("child1");
674         NormalizedNode childNode2 = normalizedNode("child2");
675
676         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2, WRITE);
677         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
678         setChildNodes(node1, List.of(child1));
679         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
680
681         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, null, DISAPPEARED);
682         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, null, DELETE);
683         setChildNodes(node2, List.of(child2));
684         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
685
686         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
687
688         assertEquals(DISAPPEARED, aggregationResult.getRootNode().getModificationType());
689     }
690
691     @Test
692     public void testSubtreeModifiedUnmodified() {
693         NormalizedNode parentNode1 = normalizedNode("container1");
694         NormalizedNode parentNode2 = normalizedNode("container1");
695         NormalizedNode childNode1 = normalizedNode("child1");
696         NormalizedNode childNode2 = normalizedNode("child2");
697
698         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2, SUBTREE_MODIFIED);
699         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
700         setChildNodes(node1, List.of(child1));
701         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
702
703         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, parentNode2, UNMODIFIED);
704         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, childNode2, UNMODIFIED);
705         setChildNodes(node2, List.of(child2));
706         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
707
708         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
709
710         assertEquals(SUBTREE_MODIFIED, aggregationResult.getRootNode().getModificationType());
711     }
712
713     @Test
714     public void testSubtreeModifiedDelete() {
715         NormalizedNode parentNode1 = normalizedNode("container1");
716         NormalizedNode parentNode2 = normalizedNode("container1");
717         NormalizedNode childNode1 = normalizedNode("child1");
718         NormalizedNode childNode2 = normalizedNode("child2");
719
720         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode2, SUBTREE_MODIFIED);
721         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
722         setChildNodes(node1, List.of(child1));
723         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
724
725         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode2, null, DELETE);
726         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode2, null, DELETE);
727         setChildNodes(node2, List.of(child2));
728         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
729
730         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
731
732         assertEquals(DELETE, aggregationResult.getRootNode().getModificationType());
733     }
734
735     @Test
736     public void testSubtreeModifiedWrite() {
737         NormalizedNode parentNode1 = normalizedNode("container");
738         NormalizedNode parentNode2 = normalizedNode("value2");
739         NormalizedNode childNode = normalizedNode("childNode");
740         NormalizedNode childNode1 = normalizedNode("child1");
741         NormalizedNode childNode2 = normalizedNode("child2");
742
743         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1, SUBTREE_MODIFIED);
744         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1, WRITE);
745         setChildNodes(node1, List.of(child1));
746         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
747
748         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2, WRITE);
749         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
750         setChildNodes(node2, List.of(child2));
751         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
752
753         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
754
755         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
756     }
757
758     @Test
759     public void testSubtreeModifiedSubtreeModified() {
760         NormalizedNode parentNode1 = normalizedNode("container");
761         NormalizedNode childNode = normalizedNode("childNode");
762         NormalizedNode childNode1 = normalizedNode("child1");
763         NormalizedNode childNode2 = normalizedNode("child2");
764
765         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1, SUBTREE_MODIFIED);
766         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1, WRITE);
767         setChildNodes(node1, List.of(child1));
768         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
769
770         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode1, SUBTREE_MODIFIED);
771         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
772         setChildNodes(node2, List.of(child2));
773         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
774
775         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
776
777         assertEquals(SUBTREE_MODIFIED, aggregationResult.getRootNode().getModificationType());
778     }
779
780     @Test
781     public void testSubtreeModifiedAppear() {
782         NormalizedNode parentNode1 = normalizedNode("container");
783         NormalizedNode parentNode2 = normalizedNode("value2");
784         NormalizedNode childNode = normalizedNode("childNode");
785         NormalizedNode childNode1 = normalizedNode("child1");
786         NormalizedNode childNode2 = normalizedNode("child2");
787
788         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1, SUBTREE_MODIFIED);
789         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1, WRITE);
790         setChildNodes(node1, List.of(child1));
791         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
792
793         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2, APPEARED);
794         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2, WRITE);
795         setChildNodes(node2, List.of(child2));
796         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
797
798         assertThrows(IllegalArgumentException.class,
799             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
800     }
801
802     @Test
803     public void testSubtreeModifiedDisappear() {
804         NormalizedNode parentNode1 = normalizedNode("container");
805         NormalizedNode childNode = normalizedNode("childNode");
806         NormalizedNode childNode1 = normalizedNode("child1");
807
808         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, parentNode1, SUBTREE_MODIFIED);
809         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode, childNode1, WRITE);
810         setChildNodes(node1, List.of(child1));
811         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
812
813         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, null, DISAPPEARED);
814         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, null, DELETE);
815         setChildNodes(node2, List.of(child2));
816         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
817
818         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
819
820         assertEquals(DISAPPEARED, aggregationResult.getRootNode().getModificationType());
821     }
822
823     @Test
824     public void testAppearedUnmodified() {
825         NormalizedNode parentNode1 = normalizedNode("container");
826         NormalizedNode childNode1 = normalizedNode("child1");
827
828         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1, APPEARED);
829         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1, WRITE);
830         setChildNodes(node1, List.of(child1));
831         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
832
833         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode1, UNMODIFIED);
834         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode1, UNMODIFIED);
835         setChildNodes(node2, List.of(child2));
836         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
837
838         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
839
840         assertEquals(APPEARED, aggregationResult.getRootNode().getModificationType());
841     }
842
843     @Test
844     public void testAppearedDelete() {
845         NormalizedNode parentNode1 = normalizedNode("container");
846         NormalizedNode childNode1 = normalizedNode("child1");
847
848         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1, APPEARED);
849         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1, WRITE);
850         setChildNodes(node1, List.of(child1));
851         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
852
853         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, null, DELETE);
854         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, null, DELETE);
855         setChildNodes(node2, List.of(child2));
856         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
857
858         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
859
860         assertEquals(UNMODIFIED, aggregationResult.getRootNode().getModificationType());
861     }
862
863     @Test
864     public void testAppearedWriteWithoutChanges() {
865         NormalizedNode parentNode1 = normalizedNode("container");
866         NormalizedNode parentNode2 = normalizedNode("value2");
867         NormalizedNode childNode1 = normalizedNode("child1");
868         NormalizedNode childNode2 = normalizedNode("child2");
869
870         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1, APPEARED);
871         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1, WRITE);
872         setChildNodes(node1, List.of(child1));
873         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
874
875         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode2, WRITE);
876         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
877         setChildNodes(node2, List.of(child2));
878         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
879
880         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
881
882         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
883     }
884
885     @Test
886     public void testAppearedSubtreeModified() {
887         NormalizedNode parentNode1 = normalizedNode("container");
888         NormalizedNode childNode1 = normalizedNode("child1");
889         NormalizedNode childNode2 = normalizedNode("child2");
890
891         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1, APPEARED);
892         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1, WRITE);
893         setChildNodes(node1, List.of(child1));
894         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
895
896         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, parentNode1, SUBTREE_MODIFIED);
897         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, childNode2, WRITE);
898         setChildNodes(node2, List.of(child2));
899         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
900
901         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
902
903         assertEquals(APPEARED, aggregationResult.getRootNode().getModificationType());
904     }
905
906     @Test
907     public void testAppearedAppeared() {
908         NormalizedNode parentNode1 = normalizedNode("container");
909         NormalizedNode childNode1 = normalizedNode("child1");
910
911         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1, APPEARED);
912         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1, WRITE);
913         setChildNodes(node1, List.of(child1));
914         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
915
916         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode1, APPEARED);
917         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode1, WRITE);
918         setChildNodes(node2, List.of(child2));
919         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
920
921         assertThrows(IllegalArgumentException.class,
922             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
923     }
924
925     @Test
926     public void testAppearedDisappeared() {
927         NormalizedNode parentNode1 = normalizedNode("container");
928         NormalizedNode childNode1 = normalizedNode("child1");
929
930         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(null, parentNode1, APPEARED);
931         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(null, childNode1, WRITE);
932         setChildNodes(node1, List.of(child1));
933         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
934
935         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(parentNode1, null, DISAPPEARED);
936         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(childNode1, null, DELETE);
937         setChildNodes(node2, List.of(child2));
938         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
939
940         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
941
942         assertEquals(UNMODIFIED, aggregationResult.getRootNode().getModificationType());
943     }
944
945     @Test
946     public void testDisappearedUnmodified() {
947         NormalizedNode parentNode1 = normalizedNode("container");
948         NormalizedNode childNode1 = normalizedNode("child1");
949
950         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null, DISAPPEARED);
951         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null, DELETE);
952         setChildNodes(node1, List.of(child1));
953         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
954
955         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, UNMODIFIED);
956         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, null, UNMODIFIED);
957         setChildNodes(node2, List.of(child2));
958         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
959
960         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
961
962         assertEquals(DISAPPEARED, aggregationResult.getRootNode().getModificationType());
963     }
964
965     @Test
966     public void testDisappearedDelete() {
967         NormalizedNode parentNode1 = normalizedNode("container");
968         NormalizedNode childNode1 = normalizedNode("child1");
969
970         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null, DISAPPEARED);
971         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null, DELETE);
972         setChildNodes(node1, List.of(child1));
973         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
974
975         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, DELETE);
976         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, null, DELETE);
977         setChildNodes(node2, List.of(child2));
978         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
979
980         assertThrows(IllegalArgumentException.class,
981             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
982     }
983
984     @Test
985     public void testDisappearedWrite() {
986         NormalizedNode parentNode1 = normalizedNode("container1");
987         NormalizedNode parentNode2 = normalizedNode("container2");
988         NormalizedNode childNode1 = normalizedNode("child1");
989         NormalizedNode childNode2 = normalizedNode("child2");
990
991         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null, DISAPPEARED);
992         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null, DELETE);
993         setChildNodes(node1, List.of(child1));
994         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
995
996         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2, WRITE);
997         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2, WRITE);
998         setChildNodes(node2, List.of(child2));
999         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1000
1001         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
1002
1003         assertEquals(WRITE, aggregationResult.getRootNode().getModificationType());
1004     }
1005
1006     @Test
1007     public void testDisappearedSubtreeModified() {
1008         NormalizedNode parentNode1 = normalizedNode("container");
1009         NormalizedNode childNode1 = normalizedNode("child1");
1010         NormalizedNode childNode2 = normalizedNode("child2");
1011
1012         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null, DISAPPEARED);
1013         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null, DELETE);
1014         setChildNodes(node1, List.of(child1));
1015         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1016
1017         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, SUBTREE_MODIFIED);
1018         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2, WRITE);
1019         setChildNodes(node2, List.of(child2));
1020         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1021
1022         assertThrows(IllegalArgumentException.class,
1023             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
1024     }
1025
1026     @Test
1027     public void testDisappearedAppeared() {
1028         NormalizedNode parentNode1 = normalizedNode("container");
1029         NormalizedNode parentNode2 = normalizedNode("container");
1030         NormalizedNode childNode1 = normalizedNode("child1");
1031         NormalizedNode childNode2 = normalizedNode("child2");
1032
1033         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null, DISAPPEARED);
1034         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null, DELETE);
1035         setChildNodes(node1, List.of(child1));
1036         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1037
1038         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, parentNode2, APPEARED);
1039         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, childNode2, WRITE);
1040         setChildNodes(node2, List.of(child2));
1041         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1042
1043         DataTreeCandidate aggregationResult = DataTreeCandidates.aggregate(List.of(candidate1, candidate2));
1044
1045         assertEquals(SUBTREE_MODIFIED, aggregationResult.getRootNode().getModificationType());
1046     }
1047
1048     @Test
1049     public void testDisappearedDisappear() {
1050         NormalizedNode parentNode1 = normalizedNode("container");
1051         NormalizedNode childNode1 = normalizedNode("child1");
1052
1053         TerminalDataTreeCandidateNode node1 = dataTreeCandidateNode(parentNode1, null, DISAPPEARED);
1054         TerminalDataTreeCandidateNode child1 = dataTreeCandidateNode(childNode1, null, DELETE);
1055         setChildNodes(node1, List.of(child1));
1056         DataTreeCandidate candidate1 = new DefaultDataTreeCandidate(ROOT_PATH, node1);
1057
1058         TerminalDataTreeCandidateNode node2 = dataTreeCandidateNode(null, null, DISAPPEARED);
1059         TerminalDataTreeCandidateNode child2 = dataTreeCandidateNode(null, null, DELETE);
1060         setChildNodes(node2, List.of(child2));
1061         DataTreeCandidate candidate2 = new DefaultDataTreeCandidate(ROOT_PATH, node2);
1062
1063         assertThrows(IllegalArgumentException.class,
1064             () -> DataTreeCandidates.aggregate(List.of(candidate1, candidate2)));
1065     }
1066
1067     private static LeafNode<String> normalizedNode(final String value) {
1068         LeafNode<String> node = mock(LeafNode.class);
1069         doReturn(value).when(node).body();
1070         return node;
1071     }
1072
1073     private static TerminalDataTreeCandidateNode dataTreeCandidateNode(final NormalizedNode before,
1074                                                                        final NormalizedNode after,
1075                                                                        final ModificationType modification) {
1076         TerminalDataTreeCandidateNode dataTreeCandidateNode = mock(TerminalDataTreeCandidateNode.class);
1077         doReturn(null).when(dataTreeCandidateNode).getIdentifier();
1078         doReturn(Optional.ofNullable(before)).when(dataTreeCandidateNode).getDataBefore();
1079         doReturn(Optional.ofNullable(after)).when(dataTreeCandidateNode).getDataAfter();
1080         doReturn(modification).when(dataTreeCandidateNode).getModificationType();
1081         return dataTreeCandidateNode;
1082     }
1083
1084     private static void setChildNodes(final TerminalDataTreeCandidateNode parentNode,
1085                                       final List<DataTreeCandidateNode> childNodes) {
1086         doReturn(null).when(parentNode).getIdentifier();
1087         childNodes.forEach(child -> doReturn(CHILD_ID).when(child).getIdentifier());
1088         doReturn(childNodes).when(parentNode).getChildNodes();
1089     }
1090 }