// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui.conflict.pair.nodes; import static org.fest.reflect.core.Reflection.field; import static org.fest.reflect.core.Reflection.method; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import javax.swing.DefaultListSelectionModel; import org.junit.Rule; import org.junit.Test; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.testutils.DatasetFactory; import org.openstreetmap.josm.testutils.JOSMTestRules; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** * Unit tests of {@link NodeListMergeModel}. */ public class NodeListMergeModelTest { private DatasetFactory my = new DatasetFactory(); private DatasetFactory their = new DatasetFactory(); /** * Setup test. */ @Rule @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") public JOSMTestRules test = new JOSMTestRules(); @SuppressWarnings("unchecked") protected List<Node> inspectNodeList(NodeListMergeModel model, String name) { return method("get" + name + "Entries") .withReturnType(List.class) .in(model) .invoke(); } protected DefaultListSelectionModel inspectListSelectionModel(NodeListMergeModel model, String name) { return field(name).ofType(DefaultListSelectionModel.class) .in(model) .get(); } protected void ensureSelected(DefaultListSelectionModel model, Object... idx) { if (idx == null) return; for (int i = 0; i < idx.length; i++) { if (idx[i] instanceof Integer) { int j = (Integer) idx[i]; assertTrue("expected row " + j + " to be selected", model.isSelectedIndex(j)); break; } int[] rows = (int[]) idx[i]; if (rows.length != 2) { fail("illegal selection range. Either null or not length 2: " + Arrays.toString(rows)); } if (rows[0] > rows[1]) { fail("illegal selection range. lower bound > upper bound "); } for (int j = rows[0]; j <= rows[1]; j++) { assertTrue("expected row " + j + " to be selected", model.isSelectedIndex(j)); } } } @Test public void testCopyMyNodesToTop1() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); model.copyMyToTop(new int[]{0}); List<Node> mergedNodes = inspectNodeList(model, "Merged"); assertEquals(1, mergedNodes.size()); assertEquals(2, mergedNodes.get(0).getId()); DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 0); } @Test public void testCopyMyNodesToTop2() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(1)); model.copyMyToTop(new int[]{0}); mergedNodes = inspectNodeList(model, "Merged"); assertEquals(2, mergedNodes.size()); assertEquals(2, mergedNodes.get(0).getId()); assertEquals(1, mergedNodes.get(1).getId()); DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 0); } @Test public void testCopyMyNodesToTop3() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(1)); model.copyMyToTop(new int[]{1}); // copy node 3 mergedNodes = inspectNodeList(model, "Merged"); assertEquals(2, mergedNodes.size()); assertEquals(3, mergedNodes.get(0).getId()); // my node 3 at position 0 assertEquals(1, mergedNodes.get(1).getId()); // already merged node 1 at position 1 DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 0); } @Test public void testCopyMyNodesToTop4() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); myWay.addNode(my.addNode(4)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(1)); model.copyMyToTop(new int[]{1, 2}); // copy node 3 and 4 mergedNodes = inspectNodeList(model, "Merged"); assertEquals(3, mergedNodes.size()); assertEquals(3, mergedNodes.get(0).getId()); // my node 3 at position 0 assertEquals(4, mergedNodes.get(1).getId()); // my node 4 at position 1 assertEquals(1, mergedNodes.get(2).getId()); // already merged node 1 at position 2 DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 0, 1); // first two rows selected } @Test public void testCopyMyNodesToEnd1() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); model.copyMyToEnd(new int[]{0}); List<Node> mergedNodes = inspectNodeList(model, "Merged"); assertEquals(1, mergedNodes.size()); assertEquals(2, mergedNodes.get(0).getId()); DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 0); } @Test public void testCopyMyNodesToEnd2() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(1)); model.copyMyToEnd(new int[]{0}); mergedNodes = inspectNodeList(model, "Merged"); assertEquals(2, mergedNodes.size()); assertEquals(1, mergedNodes.get(0).getId()); // already merged node 1 at position 0 assertEquals(2, mergedNodes.get(1).getId()); // copied node 2 at position 1 DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 1); } @Test public void testCopyMyNodesToEnd3() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(1)); model.copyMyToEnd(new int[]{1}); // copy node 3 mergedNodes = inspectNodeList(model, "Merged"); assertEquals(2, mergedNodes.size()); assertEquals(1, mergedNodes.get(0).getId()); // already merged node 1 at position 0 assertEquals(3, mergedNodes.get(1).getId()); // my node 3 at position 1 DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 1); } @Test public void testCopyMyNodesToEnd4() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); myWay.addNode(my.addNode(4)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(1)); model.copyMyToEnd(new int[]{1, 2}); // copy node 3 and 4 mergedNodes = inspectNodeList(model, "Merged"); assertEquals(3, mergedNodes.size()); assertEquals(1, mergedNodes.get(0).getId()); // already merged node 1 at position 0 assertEquals(3, mergedNodes.get(1).getId()); // my node 3 at position 1 assertEquals(4, mergedNodes.get(2).getId()); // my node 4 at position 2 DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 1, 2); // last two rows selected } /* ----------------------------------------------------------------------------- */ /* copyMyNodesBeforeCurrent */ /* ----------------------------------------------------------------------------- */ @Test public void testCopyMyNodesBeforeCurrent1() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(1)); myWay.addNode(my.addNode(2)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); model.copyMyBeforeCurrent(new int[]{0}, 1); assertEquals(4, mergedNodes.size()); assertEquals(10, mergedNodes.get(0).getId()); // already merged node assertEquals(1, mergedNodes.get(1).getId()); // copied node 1 at position 1 assertEquals(11, mergedNodes.get(2).getId()); // already merged node assertEquals(12, mergedNodes.get(3).getId()); // already merged node DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 1); // position 1 selected } @Test public void testCopyMyNodesBeforeCurrent2() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(1)); myWay.addNode(my.addNode(2)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); model.copyMyBeforeCurrent(new int[]{0, 1}, 0); assertEquals(5, mergedNodes.size()); assertEquals(1, mergedNodes.get(0).getId()); // copied node 1 at position 0 assertEquals(2, mergedNodes.get(1).getId()); // copied node 2 at position 1 assertEquals(10, mergedNodes.get(2).getId()); // already merged node assertEquals(11, mergedNodes.get(3).getId()); // already merged node assertEquals(12, mergedNodes.get(4).getId()); // already merged node DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 0, 1); // position 0 and 1 selected } @Test public void testCopyMyNodesBeforeCurrent3() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(1)); myWay.addNode(my.addNode(2)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); try { model.copyMyBeforeCurrent(new int[]{0, 1}, -1); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException e) { // OK Main.trace(e); } try { model.copyMyBeforeCurrent(new int[]{0, 1}, 4); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException e) { // OK Main.trace(e); } } /* ----------------------------------------------------------------------------- */ /* copyMyNodesAfterCurrent */ /* ----------------------------------------------------------------------------- */ @Test public void testCopyMyNodesAfterCurrent1() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(1)); myWay.addNode(my.addNode(2)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); model.copyMyAfterCurrent(new int[]{0}, 1); assertEquals(4, mergedNodes.size()); assertEquals(10, mergedNodes.get(0).getId()); // already merged node assertEquals(11, mergedNodes.get(1).getId()); // already merged node assertEquals(1, mergedNodes.get(2).getId()); // copied node 1 at position 2 assertEquals(12, mergedNodes.get(3).getId()); // already merged node DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 2); // position 1 selected } @Test public void testCopyMyNodesAfterCurrent2() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(1)); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); model.copyMyAfterCurrent(new int[]{0, 1}, 2); assertEquals(5, mergedNodes.size()); assertEquals(10, mergedNodes.get(0).getId()); // already merged node assertEquals(11, mergedNodes.get(1).getId()); // already merged node assertEquals(12, mergedNodes.get(2).getId()); // already merged node assertEquals(1, mergedNodes.get(3).getId()); // copied node 1 at position 3 assertEquals(2, mergedNodes.get(4).getId()); // copied node 2 at position 4 DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 3, 4); // position 3,4 selected } @Test public void testCopyMyNodesAfterCurrent3() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = my.addWay(1, 1); myWay.addNode(my.addNode(1)); myWay.addNode(my.addNode(2)); myWay.addNode(my.addNode(3)); Way theirWay = their.addWay(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); model.copyMyAfterCurrent(new int[]{0, 2}, 0); assertEquals(5, mergedNodes.size()); assertEquals(10, mergedNodes.get(0).getId()); // already merged node assertEquals(1, mergedNodes.get(1).getId()); // copied node 1 at position 1 assertEquals(3, mergedNodes.get(2).getId()); // copied node 3 at position 2 assertEquals(11, mergedNodes.get(3).getId()); // already merged node assertEquals(12, mergedNodes.get(4).getId()); // already merged node DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 1, 2); // position 1,2 selected } /* ----------------------------------------------------------------------------- */ /* moveUpMergedNodes */ /* ----------------------------------------------------------------------------- */ @Test public void testMoveUpMergedNodes1() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = new Way(1, 1); myWay.addNode(new Node(1)); myWay.addNode(new Node(2)); Way theirWay = new Way(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); model.moveUpMerged(new int[]{1}); assertEquals(3, mergedNodes.size()); assertEquals(11, mergedNodes.get(0).getId()); assertEquals(10, mergedNodes.get(1).getId()); assertEquals(12, mergedNodes.get(2).getId()); DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 0); // position 1 selecte0 } @Test public void testMoveUpMergedNodes2() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = new Way(1, 1); myWay.addNode(new Node(1)); myWay.addNode(new Node(2)); Way theirWay = new Way(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); mergedNodes.add(new Node(13)); mergedNodes.add(new Node(14)); model.moveUpMerged(new int[]{1, 4}); assertEquals(5, mergedNodes.size()); assertEquals(11, mergedNodes.get(0).getId()); assertEquals(10, mergedNodes.get(1).getId()); assertEquals(12, mergedNodes.get(2).getId()); assertEquals(14, mergedNodes.get(3).getId()); assertEquals(13, mergedNodes.get(4).getId()); DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 0, 3); // position 0 and 3 selecte0 } @Test public void testMoveUpMergedNodes3() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = new Way(1, 1); myWay.addNode(new Node(1)); myWay.addNode(new Node(2)); Way theirWay = new Way(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); mergedNodes.add(new Node(13)); mergedNodes.add(new Node(14)); model.moveUpMerged(new int[]{1, 2, 3, 4}); assertEquals(5, mergedNodes.size()); assertEquals(11, mergedNodes.get(0).getId()); assertEquals(12, mergedNodes.get(1).getId()); assertEquals(13, mergedNodes.get(2).getId()); assertEquals(14, mergedNodes.get(3).getId()); assertEquals(10, mergedNodes.get(4).getId()); DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 0, 1, 2, 3); } /* ----------------------------------------------------------------------------- */ /* moveDownMergedNodes */ /* ----------------------------------------------------------------------------- */ @Test public void testMoveDownMergedNodes1() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = new Way(1, 1); myWay.addNode(new Node(1)); myWay.addNode(new Node(2)); Way theirWay = new Way(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); model.moveDownMerged(new int[]{1}); assertEquals(3, mergedNodes.size()); assertEquals(10, mergedNodes.get(0).getId()); assertEquals(12, mergedNodes.get(1).getId()); assertEquals(11, mergedNodes.get(2).getId()); DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 2); } @Test public void testMoveDownMergedNodes2() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = new Way(1, 1); myWay.addNode(new Node(1)); myWay.addNode(new Node(2)); Way theirWay = new Way(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); mergedNodes.add(new Node(13)); mergedNodes.add(new Node(14)); model.moveDownMerged(new int[]{1, 3}); assertEquals(5, mergedNodes.size()); assertEquals(10, mergedNodes.get(0).getId()); assertEquals(12, mergedNodes.get(1).getId()); assertEquals(11, mergedNodes.get(2).getId()); assertEquals(14, mergedNodes.get(3).getId()); assertEquals(13, mergedNodes.get(4).getId()); DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 2, 4); } @Test public void testMoveDownMergedNodes3() { NodeListMergeModel model = new NodeListMergeModel(); Way myWay = new Way(1, 1); myWay.addNode(new Node(1)); myWay.addNode(new Node(2)); Way theirWay = new Way(1); model.populate(myWay, theirWay, null); List<Node> mergedNodes = inspectNodeList(model, "Merged"); mergedNodes.add(new Node(10)); mergedNodes.add(new Node(11)); mergedNodes.add(new Node(12)); mergedNodes.add(new Node(13)); mergedNodes.add(new Node(14)); model.moveDownMerged(new int[]{1, 2, 3}); assertEquals(5, mergedNodes.size()); assertEquals(10, mergedNodes.get(0).getId()); assertEquals(14, mergedNodes.get(1).getId()); assertEquals(11, mergedNodes.get(2).getId()); assertEquals(12, mergedNodes.get(3).getId()); assertEquals(13, mergedNodes.get(4).getId()); DefaultListSelectionModel mergedSelection = inspectListSelectionModel(model, "mergedEntriesSelectionModel"); ensureSelected(mergedSelection, 2, 3, 4); } /* ----------------------------------------------------------------------------- */ /* PropertyChangeListener */ /* ----------------------------------------------------------------------------- */ @SuppressWarnings("unchecked") @Test public void testAddPropertyChangeListener() { NodeListMergeModel model = new NodeListMergeModel(); PropertyChangeListener listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { } }; model.addPropertyChangeListener(listener); Set<PropertyChangeListener> listeners = field("listeners") .ofType(Set.class) .in(model) .get(); assertEquals(1, listeners.size()); assertEquals(listener, listeners.iterator().next()); } @SuppressWarnings("unchecked") @Test public void testRemovePropertyChangeListener() { NodeListMergeModel model = new NodeListMergeModel(); PropertyChangeListener listener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { } }; model.addPropertyChangeListener(listener); model.removePropertyChangeListener(listener); Set<PropertyChangeListener> listeners = field("listeners") .ofType(Set.class) .in(model) .get(); assertEquals(0, listeners.size()); } /* ----------------------------------------------------------------------------- */ /* property frozen */ /* ----------------------------------------------------------------------------- */ @Test public void testSetFrozen() { NodeListMergeModel model = new NodeListMergeModel(); model.setFrozen(true); assertTrue(model.isFrozen()); model.setFrozen(false); assertFalse(model.isFrozen()); } @Test public void testSetFrozenWithPropertyChangeNotification() { NodeListMergeModel model = new NodeListMergeModel(); class MyListener implements PropertyChangeListener { public ArrayList<PropertyChangeEvent> events = new ArrayList<>(); public void propertyChange(PropertyChangeEvent evt) { events.add(evt); } } MyListener listener = new MyListener(); model.addPropertyChangeListener(listener); boolean oldValue = model.isFrozen(); model.setFrozen(!oldValue); assertEquals(!oldValue, model.isFrozen()); assertEquals(1, listener.events.size()); assertEquals(oldValue, listener.events.get(0).getOldValue()); assertEquals(!oldValue, listener.events.get(0).getNewValue()); } }