/* * PlanControllerTest.java 31 mai 2006 * * Copyright (c) 2006 Emmanuel PUYBARET / eTeks <info@eteks.com>. All Rights * Reserved. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA */ package com.eteks.sweethome3d.junit; import java.awt.EventQueue; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Locale; import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEditSupport; import junit.framework.TestCase; import com.eteks.sweethome3d.io.DefaultUserPreferences; import com.eteks.sweethome3d.model.CollectionEvent; import com.eteks.sweethome3d.model.CollectionListener; import com.eteks.sweethome3d.model.Home; import com.eteks.sweethome3d.model.Selectable; import com.eteks.sweethome3d.model.UserPreferences; import com.eteks.sweethome3d.model.Wall; import com.eteks.sweethome3d.swing.SwingViewFactory; import com.eteks.sweethome3d.viewcontroller.PlanController; import com.eteks.sweethome3d.viewcontroller.ViewFactory; /** * Tests {@link com.eteks.sweethome3d.viewcontroller.PlanController plan controller}. * @author Emmanuel Puybaret */ public class PlanControllerTest extends TestCase { /** * Performs the same tests as {@link PlanComponentTest#testPlanComponent()} * but with direct calls to controller in memory. */ public void testPlanContoller() throws InterruptedException, InvocationTargetException { // Run test in Event Dispatch Thread because the default view associated // to plan controller instance performs some actions in EDT even if it's not displayed EventQueue.invokeAndWait(new Runnable() { public void run() { runPlanContollerTest(); } }); } private void runPlanContollerTest() { // 1. Create a frame that displays a PlanComponent at its preferred size, Home home = new Home(); Locale.setDefault(Locale.FRANCE); UserPreferences preferences = new DefaultUserPreferences(); ViewFactory viewFactory = new SwingViewFactory(); UndoableEditSupport undoSupport = new UndoableEditSupport(); UndoManager undoManager = new UndoManager(); undoSupport.addUndoableEditListener(undoManager); PlanController planController = new PlanController(home, preferences, viewFactory, null, undoSupport); // Build an ordered list of walls added to home final ArrayList<Wall> orderedWalls = new ArrayList<Wall>(); home.addWallsListener(new CollectionListener<Wall> () { public void collectionChanged(CollectionEvent<Wall> ev) { if (ev.getType() == CollectionEvent.Type.ADD) { orderedWalls.add(ev.getItem()); } } }); // 2. Use WALL_CREATION mode planController.setMode(PlanController.Mode.WALL_CREATION); // Click at (20, 20), (500, 22), (498, 300), then double click at (20, 302) in home coordinates space planController.moveMouse(20, 20); planController.pressMouse(20, 20, 1, false, false); planController.toggleMagnetism(false); planController.releaseMouse(20, 20); planController.moveMouse(500, 22); planController.pressMouse(500, 22, 1, false, false); planController.releaseMouse(500, 22); planController.moveMouse(498, 300); planController.pressMouse(498, 300, 1, false, false); planController.releaseMouse(498, 300); planController.moveMouse(20, 302); planController.pressMouse(20, 302, 1, false, false); planController.releaseMouse(20, 302); planController.pressMouse(20, 302, 2, false, false); planController.releaseMouse(20, 302); // Check 3 walls were created at (20, 20), (500, 20), (500, 300) and (20, 300) coordinates Wall wall1 = orderedWalls.get(0); assertCoordinatesEqualWallPoints(20, 20, 500, 20, wall1); Wall wall2 = orderedWalls.get(1); assertCoordinatesEqualWallPoints(500, 20, 500, 300, wall2); Wall wall3 = orderedWalls.get(2); assertCoordinatesEqualWallPoints(500, 300, 20, 300, wall3); // Check they are joined to each other end point assertWallsAreJoined(null, wall1, wall2); assertWallsAreJoined(wall1, wall2, wall3); assertWallsAreJoined(wall2, wall3, null); // Check they are selected assertSelectionContains(home, wall1, wall2, wall3); // 3. Click at (20, 300), then double click at (60, 60) with Alt key depressed planController.moveMouse(20, 300); planController.pressMouse(20, 300, 1, false, false); planController.releaseMouse(20, 300); planController.toggleMagnetism(true); planController.moveMouse(60, 60); planController.pressMouse(60, 60, 1, false, false); planController.releaseMouse(60, 60); planController.pressMouse(60, 60, 2, false, false); planController.releaseMouse(60, 60); planController.toggleMagnetism(false); // Check a forth wall was created at (20, 300), (60, 60) coordinates Wall wall4 = orderedWalls.get(orderedWalls.size() - 1); assertCoordinatesEqualWallPoints(20, 300, 60, 60, wall4); assertSelectionContains(home, wall4); assertWallsAreJoined(wall3, wall4, null); // 4. Use SELECTION mode planController.setMode(PlanController.Mode.SELECTION); // Check current mode is SELECTION assertEquals("Current mode isn't " + PlanController.Mode.SELECTION, PlanController.Mode.SELECTION, planController.getMode()); // Press the delete key planController.deleteSelection(); // Check plan contains only the first three walls assertHomeContains(home, wall1, wall2, wall3); // 5. Use WALL_CREATION mode planController.setMode(PlanController.Mode.WALL_CREATION); // Click at (22, 18), then double click at (20, 300) planController.moveMouse(22, 18); planController.pressMouse(22, 18, 1, false, false); planController.releaseMouse(22, 18); planController.moveMouse(20, 300); planController.pressMouse(20, 300, 1, false, false); planController.releaseMouse(20, 300); planController.pressMouse(20, 300, 2, false, false); planController.releaseMouse(20, 300); // Check a new forth wall was created at (20, 20), (20, 300) coordinates wall4 = orderedWalls.get(orderedWalls.size() - 1); assertCoordinatesEqualWallPoints(20, 20, 20, 300, wall4); // Check its end points are joined to the first and third wall assertWallsAreJoined(wall1, wall4, wall3); // 6. Use SELECTION mode planController.setMode(PlanController.Mode.SELECTION); // Drag and drop cursor from (360, 160) to (560, 320) planController.moveMouse(360, 160); planController.pressMouse(360, 160, 1, false, false); planController.moveMouse(560, 320); planController.releaseMouse(560, 320); // Check the selected walls are the second and third ones assertSelectionContains(home, wall2, wall3); // 7. Press twice right arrow key planController.moveSelection(2, 0); planController.moveSelection(2, 0); // Check the 4 walls coordinates are (20, 20), (504, 20), (504, 300), (24, 300) assertCoordinatesEqualWallPoints(20, 20, 504, 20, wall1); assertCoordinatesEqualWallPoints(504, 20, 504, 300, wall2); assertCoordinatesEqualWallPoints(504, 300, 24, 300, wall3); assertCoordinatesEqualWallPoints(20, 20, 24, 300, wall4); // 8. Click at (504, 40) planController.moveMouse(504, 40); planController.pressMouse(504, 40, 1, true, false); planController.releaseMouse(504, 40); // Check the second wall was removed from selection assertSelectionContains(home, wall3); // 9. Drag cursor from (60, 20) to (60, 60) planController.moveMouse(60, 20); planController.pressMouse(60, 20, 1, false, false); planController.moveMouse(60, 60); // Check first wall is selected and that it moved assertSelectionContains(home, wall1); assertCoordinatesEqualWallPoints(20, 60, 504, 60, wall1); // Lose focus planController.escape(); // Check the wall didn't move at end assertCoordinatesEqualWallPoints(20, 20, 504, 20, wall1); // 10. Undo 8 times for (int i = 0; i < 6; i++) { undoManager.undo(); } // Check home doesn't contain any wall assertHomeContains(home); // 11. Redo 8 times for (int i = 0; i < 6; i++) { undoManager.redo(); } // Check plan contains the four wall assertHomeContains(home, wall1, wall2, wall3, wall4); // Check the second and the third wall are selected assertSelectionContains(home, wall2, wall3); } /** * Asserts the start point and the end point of * <code>wall</code> are at (<code>xStart</code>, <code>yStart</code>), (<code>xEnd</code>, <code>yEnd</code>). */ private void assertCoordinatesEqualWallPoints(float xStart, float yStart, float xEnd, float yEnd, Wall wall) { assertTrue("Incorrect X start " + xStart + " " + wall.getXStart(), Math.abs(xStart - wall.getXStart()) < 1E-10); assertTrue("Incorrect Y start " + yStart + " " + wall.getYStart(), Math.abs(yStart - wall.getYStart()) < 1E-10); assertTrue("Incorrect X end " + xEnd + " " + wall.getXEnd(), Math.abs(xEnd - wall.getXEnd()) < 1E-10); assertTrue("Incorrect Y end " + yEnd + " " + wall.getYEnd(), Math.abs(yEnd - wall.getYEnd()) < 1E-10); } /** * Asserts <code>wall</code> is joined to <code>wallAtStart</code> * and <code>wallAtEnd</code>. */ private void assertWallsAreJoined(Wall wallAtStart, Wall wall, Wall wallAtEnd) { assertSame("Incorrect wall at start", wallAtStart, wall.getWallAtStart()); assertSame("Incorrect wall at end", wallAtEnd, wall.getWallAtEnd()); } /** * Asserts <code>home</code> contains <code>walls</code>. */ private void assertHomeContains(Home home, Wall ... walls) { Collection<Wall> planWalls = home.getWalls(); assertEquals("Home walls incorrect count", walls.length, planWalls.size()); for (Wall wall : walls) { assertTrue("Wall doesn't belong to plan", planWalls.contains(wall)); } } /** * Asserts <code>walls</code> are the current selected ones in <code>home</code>. */ private void assertSelectionContains(Home home, Wall ... walls) { List<Selectable> selectedItems = home.getSelectedItems(); assertEquals(walls.length, selectedItems.size()); for (Wall wall : walls) { assertTrue("Wall not selected", selectedItems.contains(wall)); } } }