// 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.assertTrue; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.command.CommandTest.CommandTestDataWithRelation; import org.openstreetmap.josm.data.coor.EastNorth; 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.OsmPrimitive; import org.openstreetmap.josm.data.osm.User; 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 MoveCommand} class. */ public class MoveCommandTest { /** * We need prefs for nodes. */ @Rule @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") public JOSMTestRules test = new JOSMTestRules().preferences().i18n().projection(); private CommandTestDataWithRelation testData; /** * Set up the test data. */ @Before public void createTestData() { testData = new CommandTestDataWithRelation(); } /** * Test the various constructors. */ @Test public void testConstructors() { EastNorth offset = new EastNorth(1, 2); LatLon destLatLon = Main.getProjection().eastNorth2latlon(offset); EastNorth start = new EastNorth(2, 0); Set<OsmPrimitive> nodeAsCollection = Collections.<OsmPrimitive>singleton(testData.existingNode); assertEquals(1, nodeAsCollection.size()); checkCommandAfterConstructor(new MoveCommand(nodeAsCollection, offset)); checkCommandAfterConstructor(new MoveCommand(testData.existingNode, destLatLon)); checkCommandAfterConstructor(new MoveCommand(nodeAsCollection, 1, 2)); checkCommandAfterConstructor(new MoveCommand(nodeAsCollection, start, start.add(offset))); checkCommandAfterConstructor(new MoveCommand(testData.existingNode, 1, 2)); checkCommandAfterConstructor(new MoveCommand(testData.existingNode, start, start.add(offset))); } private void checkCommandAfterConstructor(MoveCommand moveCommand) { ArrayList<OsmPrimitive> nodes = new ArrayList<>(); moveCommand.fillModifiedData(nodes, null, null); assertEquals(nodes, new ArrayList<>(Collections.<OsmPrimitive>singleton(testData.existingNode))); assertEquals("east", 1, moveCommand.getOffset().east(), 0.0001); assertEquals("north", 2, moveCommand.getOffset().north(), 0.0001); } /** * Test {@link MoveCommand#executeCommand()} for simple nodes. */ @Test public void testSingleMove() { MoveCommand command = new MoveCommand(testData.existingNode, 1, 2); testData.existingNode.setEastNorth(new EastNorth(3, 7)); command.executeCommand(); assertEquals("east", 4, testData.existingNode.getEastNorth().east(), 0.0001); assertEquals("north", 9, testData.existingNode.getEastNorth().north(), 0.0001); } /** * Test {@link MoveCommand#executeCommand()} for multiple nodes. */ @Test public void testMultipleMove() { MoveCommand command = new MoveCommand( Arrays.asList(testData.existingNode, testData.existingNode2, testData.existingWay), new EastNorth(1, 2)); testData.existingNode.setEastNorth(new EastNorth(3, 7)); testData.existingNode2.setEastNorth(new EastNorth(4, 7)); command.executeCommand(); assertEquals("east", 4, testData.existingNode.getEastNorth().east(), 0.0001); assertEquals("north", 9, testData.existingNode.getEastNorth().north(), 0.0001); assertEquals("east", 5, testData.existingNode2.getEastNorth().east(), 0.0001); assertEquals("north", 9, testData.existingNode2.getEastNorth().north(), 0.0001); } /** * Test {@link MoveCommand#moveAgain(double, double)} and {@link MoveCommand#moveAgainTo(double, double)}. */ @Test public void testMoveAgain() { MoveCommand command = new MoveCommand(testData.existingNode, 1, 2); assertEquals("east", 1, command.getOffset().east(), 0.0001); assertEquals("north", 2, command.getOffset().north(), 0.0001); command.moveAgain(1, 2); assertEquals("east", 2, command.getOffset().east(), 0.0001); assertEquals("north", 4, command.getOffset().north(), 0.0001); command.moveAgain(-9, -3); assertEquals("east", -7, command.getOffset().east(), 0.0001); assertEquals("north", 1, command.getOffset().north(), 0.0001); command.moveAgainTo(1, 2); assertEquals("east", 1, command.getOffset().east(), 0.0001); assertEquals("north", 2, command.getOffset().north(), 0.0001); } /** * Test {@link MoveCommand#saveCheckpoint()} and {@link MoveCommand#resetToCheckpoint()} */ @Test public void testCheckpoint() { MoveCommand command = new MoveCommand(testData.existingNode, 2, 4); assertEquals("east", 2, command.getOffset().east(), 0.0001); assertEquals("north", 4, command.getOffset().north(), 0.0001); command.saveCheckpoint(); command.moveAgain(3, 7); assertEquals("east", 5, command.getOffset().east(), 0.0001); assertEquals("north", 11, command.getOffset().north(), 0.0001); command.resetToCheckpoint(); assertEquals("east", 2, command.getOffset().east(), 0.0001); assertEquals("north", 4, command.getOffset().north(), 0.0001); } /** * Test the start point mechanism. */ @Test public void testStartPoint() { EastNorth start = new EastNorth(10, 20); MoveCommand command = new MoveCommand(testData.existingNode, start, start.add(1, 2)); assertEquals("east", 1, command.getOffset().east(), 0.0001); assertEquals("north", 2, command.getOffset().north(), 0.0001); command.applyVectorTo(start.add(3, 4)); assertEquals("east", 3, command.getOffset().east(), 0.0001); assertEquals("north", 4, command.getOffset().north(), 0.0001); // set to 100, 200 command.changeStartPoint(new EastNorth(103, 204)); command.applyVectorTo(new EastNorth(101, 202)); assertEquals("east", 1, command.getOffset().east(), 0.0001); assertEquals("north", 2, command.getOffset().north(), 0.0001); } /** * Test the start point mechanism ignored. */ @Test public void testNoStartPoint() { MoveCommand command = new MoveCommand(testData.existingNode, 1, 0); // ignored command.applyVectorTo(new EastNorth(3, 4)); assertEquals("east", 1, command.getOffset().east(), 0.0001); assertEquals("north", 0, command.getOffset().north(), 0.0001); // set to 100, 200 command.changeStartPoint(new EastNorth(101, 200)); // works command.applyVectorTo(new EastNorth(101, 202)); assertEquals("east", 1, command.getOffset().east(), 0.0001); assertEquals("north", 2, command.getOffset().north(), 0.0001); } /** * Test {@link MoveCommand#undoCommand()} */ @Test public void testUndo() { testData.existingNode.setEastNorth(new EastNorth(3, 7)); MoveCommand command = new MoveCommand(testData.existingNode, 1, 2); command.executeCommand(); assertEquals("east", 4, testData.existingNode.getEastNorth().east(), 0.0001); assertEquals("north", 9, testData.existingNode.getEastNorth().north(), 0.0001); command.undoCommand(); assertEquals("east", 3, testData.existingNode.getEastNorth().east(), 0.0001); assertEquals("north", 7, testData.existingNode.getEastNorth().north(), 0.0001); command.executeCommand(); assertEquals("east", 4, testData.existingNode.getEastNorth().east(), 0.0001); assertEquals("north", 9, testData.existingNode.getEastNorth().north(), 0.0001); } /** * Tests {@link MoveCommand#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<>(); new MoveCommand(Arrays.<OsmPrimitive>asList(testData.existingNode), 1, 2).fillModifiedData(modified, deleted, added); assertArrayEquals(new Object[] {testData.existingNode }, modified.toArray()); assertArrayEquals(new Object[] {}, deleted.toArray()); assertArrayEquals(new Object[] {}, added.toArray()); } /** * Tests {@link MoveCommand#getParticipatingPrimitives()} */ @Test public void testGetParticipatingPrimitives() { MoveCommand command = new MoveCommand(Arrays.<OsmPrimitive>asList(testData.existingNode), 1, 2); command.executeCommand(); assertArrayEquals(new Object[] {testData.existingNode}, command.getParticipatingPrimitives().toArray()); MoveCommand command2 = new MoveCommand( Arrays.<OsmPrimitive>asList(testData.existingNode, testData.existingWay), 1, 2); command2.executeCommand(); assertArrayEquals(new Object[] {testData.existingNode, testData.existingNode2}, command2.getParticipatingPrimitives().toArray()); } /** * Test {@link MoveCommand#getDescriptionText()} */ @Test public void testDescription() { Node node = new Node(LatLon.ZERO); node.put("name", "xy"); List<OsmPrimitive> nodeList = Arrays.<OsmPrimitive>asList(node); assertTrue(new MoveCommand(nodeList, 1, 2).getDescriptionText().matches("Move 1 node")); List<OsmPrimitive> nodes = Arrays.<OsmPrimitive>asList(node, testData.existingNode, testData.existingNode2); assertTrue(new MoveCommand(nodes, 1, 2).getDescriptionText().matches("Move 3 nodes")); } /** * Unit test of methods {@link MoveCommand#equals} and {@link MoveCommand#hashCode}. */ @Test public void testEqualsContract() { EqualsVerifier.forClass(MoveCommand.class).usingGetClass() .withPrefabValues(LatLon.class, LatLon.ZERO, new LatLon(45, 45)) .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(); } }