// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.command; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.junit.Rule; import org.junit.Test; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.NodeData; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.PrimitiveData; import org.openstreetmap.josm.data.osm.User; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.data.osm.WayData; import org.openstreetmap.josm.gui.layer.OsmDataLayer; import org.openstreetmap.josm.testutils.JOSMTestRules; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import nl.jqno.equalsverifier.EqualsVerifier; import nl.jqno.equalsverifier.Warning; /** * Unit tests of {@link AddPrimitivesCommand} class. */ public class AddPrimitivesCommandTest { /** * We need prefs for nodes. */ @Rule @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") public JOSMTestRules test = new JOSMTestRules().preferences().i18n(); /** * Test if the add command is executed correctly and does not set the modified flag. */ @Test public void testAdd() { OsmDataLayer layer1 = new OsmDataLayer(new DataSet(), "l1", null); Main.getLayerManager().addLayer(layer1); List<PrimitiveData> testData = createTestData(); assertTrue(new AddPrimitivesCommand(testData).executeCommand()); testContainsTestData(layer1); assertEquals(3, layer1.data.getAllSelected().size()); } /** * Test if the add command sets the selection. */ @Test public void testAddSetSelection() { OsmDataLayer layer1 = new OsmDataLayer(new DataSet(), "l1", null); Main.getLayerManager().addLayer(layer1); List<PrimitiveData> testData = createTestData(); assertTrue(new AddPrimitivesCommand(testData, testData.subList(2, 3)).executeCommand()); testContainsTestData(layer1); assertEquals(1, layer1.data.getAllSelected().size()); assertEquals(1, layer1.data.getSelectedWays().size()); } /** * Tests if the add command respects the layer. */ @Test public void testAddToLayer() { OsmDataLayer layer1 = new OsmDataLayer(new DataSet(), "l1", null); OsmDataLayer layer2 = new OsmDataLayer(new DataSet(), "l1", null); Main.getLayerManager().addLayer(layer1); Main.getLayerManager().addLayer(layer2); List<PrimitiveData> testData = createTestData(); assertTrue(new AddPrimitivesCommand(testData, testData.subList(2, 3), layer1).executeCommand()); testContainsTestData(layer1); assertTrue(layer2.data.allPrimitives().isEmpty()); assertEquals(1, layer1.data.getAllSelected().size()); assertEquals(1, layer1.data.getSelectedWays().size()); } /** * Tests if the add command ignores existing data */ @Test public void testAddIgnoresExisting() { OsmDataLayer layer1 = new OsmDataLayer(new DataSet(), "l1", null); Main.getLayerManager().addLayer(layer1); List<PrimitiveData> testData = createTestData(); assertTrue(new AddPrimitivesCommand(testData).executeCommand()); assertEquals(2, layer1.data.getNodes().size()); assertEquals(1, layer1.data.getWays().size()); testData.set(2, createTestNode(7)); assertTrue(new AddPrimitivesCommand(testData).executeCommand()); assertEquals(3, layer1.data.getNodes().size()); assertEquals(1, layer1.data.getWays().size()); } /** * Test {@link AddPrimitivesCommand#getDescriptionText()} */ @Test public void testDescription() { OsmDataLayer layer1 = new OsmDataLayer(new DataSet(), "l1", null); Main.getLayerManager().addLayer(layer1); List<PrimitiveData> testData = createTestData(); NodeData data2 = createTestNode(7); AddPrimitivesCommand command1 = new AddPrimitivesCommand(testData); AddPrimitivesCommand command2 = new AddPrimitivesCommand(Arrays.<PrimitiveData>asList(data2)); assertEquals("Added 3 objects", command1.getDescriptionText()); assertEquals("Added 1 object", command2.getDescriptionText()); // Name must be the same after execution. assertTrue(command1.executeCommand()); assertTrue(command2.executeCommand()); assertEquals("Added 3 objects", command1.getDescriptionText()); assertEquals("Added 1 object", command2.getDescriptionText()); } /** * Test {@link AddPrimitivesCommand#undoCommand()} */ @Test public void testUndo() { OsmDataLayer layer1 = new OsmDataLayer(new DataSet(), "l1", null); Main.getLayerManager().addLayer(layer1); List<PrimitiveData> testData = createTestData(); AddPrimitivesCommand command = new AddPrimitivesCommand(testData); assertTrue(command.executeCommand()); assertEquals(3, layer1.data.allPrimitives().size()); assertEquals(1, layer1.data.getWays().size()); Way way = layer1.data.getWays().iterator().next(); for (int i = 0; i < 2; i++) { // Needs to work multiple times. command.undoCommand(); assertEquals(0, layer1.data.allPrimitives().size()); assertEquals(0, layer1.data.getWays().size()); // redo assertTrue(command.executeCommand()); assertEquals(3, layer1.data.allPrimitives().size()); assertEquals(1, layer1.data.getWays().size()); assertSame(way, layer1.data.getWays().iterator().next()); } } /** * Tests if the undo command does not remove * data ignored by by the add command because they where already existing. */ @Test public void testUndoIgnoresExisting() { OsmDataLayer layer1 = new OsmDataLayer(new DataSet(), "l1", null); Main.getLayerManager().addLayer(layer1); List<PrimitiveData> testData = createTestData(); assertTrue(new AddPrimitivesCommand(testData).executeCommand()); assertEquals(2, layer1.data.getNodes().size()); assertEquals(1, layer1.data.getWays().size()); testData.set(2, createTestNode(7)); AddPrimitivesCommand command = new AddPrimitivesCommand(testData); assertTrue(command.executeCommand()); assertEquals(3, layer1.data.getNodes().size()); assertEquals(1, layer1.data.getWays().size()); for (int i = 0; i < 2; i++) { // Needs to work multiple times. command.undoCommand(); assertEquals(2, layer1.data.getNodes().size()); assertEquals(1, layer1.data.getWays().size()); // redo assertTrue(command.executeCommand()); assertEquals(3, layer1.data.getNodes().size()); assertEquals(1, layer1.data.getWays().size()); } } /** * Test {@link AddCommand#getParticipatingPrimitives()} */ @Test public void testParticipatingPrimitives() { OsmDataLayer layer1 = new OsmDataLayer(new DataSet(), "l1", null); Main.getLayerManager().addLayer(layer1); List<PrimitiveData> testData = createTestData(); AddPrimitivesCommand command = new AddPrimitivesCommand(testData); assertTrue(command.executeCommand()); assertEquals(3, command.getParticipatingPrimitives().size()); HashSet<OsmPrimitive> should = new HashSet<>(layer1.data.allPrimitives()); assertEquals(should, new HashSet<>(command.getParticipatingPrimitives())); // needs to be the same after undo command.undoCommand(); assertEquals(should, new HashSet<>(command.getParticipatingPrimitives())); } /** * Tests {@link AddPrimitivesCommand#fillModifiedData(java.util.Collection, java.util.Collection, java.util.Collection)} */ @Test public void testFillModifiedData() { ArrayList<OsmPrimitive> modified = new ArrayList<>(); ArrayList<OsmPrimitive> deleted = new ArrayList<>(); ArrayList<OsmPrimitive> added = new ArrayList<>(); List<PrimitiveData> testData = createTestData(); new AddPrimitivesCommand(testData).fillModifiedData(modified, deleted, added); assertArrayEquals(new Object[] {}, modified.toArray()); assertArrayEquals(new Object[] {}, deleted.toArray()); assertArrayEquals(new Object[] {}, added.toArray()); } private void testContainsTestData(OsmDataLayer layer1) { assertEquals(3, layer1.data.allPrimitives().size()); assertEquals(2, layer1.data.getNodes().size()); assertEquals(1, layer1.data.getWays().size()); assertEquals(3, layer1.data.allModifiedPrimitives().size()); for (OsmPrimitive n : layer1.data.allPrimitives()) { assertEquals("test", n.get("test")); assertTrue(n.isModified()); } for (Node n : layer1.data.getNodes()) { assertEquals(LatLon.ZERO, n.getCoor()); } for (Way w : layer1.data.getWays()) { assertEquals(2, w.getNodes().size()); assertEquals(5, w.getNode(0).getId()); assertEquals(6, w.getNode(1).getId()); } } private List<PrimitiveData> createTestData() { NodeData node1 = createTestNode(5); NodeData node2 = createTestNode(6); WayData way = new WayData(); way.put("test", "test"); way.setNodes(Arrays.asList(node1.getId(), node2.getId())); List<PrimitiveData> testData = Arrays.<PrimitiveData>asList(node1, node2, way); return testData; } private NodeData createTestNode(int id) { NodeData node1 = new NodeData(); node1.setCoor(LatLon.ZERO); node1.put("test", "test"); node1.setId(id); return node1; } /** * Unit test of methods {@link AddPrimitivesCommand#equals} and {@link AddPrimitivesCommand#hashCode}. */ @Test public void testEqualsContract() { EqualsVerifier.forClass(AddPrimitivesCommand.class).usingGetClass() .withPrefabValues(DataSet.class, new DataSet(), new DataSet()) .withPrefabValues(User.class, User.createOsmUser(1, "foo"), User.createOsmUser(2, "bar")) .withPrefabValues(OsmDataLayer.class, new OsmDataLayer(new DataSet(), "1", null), new OsmDataLayer(new DataSet(), "2", null)) .suppress(Warning.NONFINAL_FIELDS) .verify(); } }