1 /*
2  * FurnitureTableTest.java 11 mai 2006
3  *
4  * Copyright (c) 2006 Emmanuel PUYBARET / eTeks <info@eteks.com>. All Rights
5  * Reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option) any later
10  * version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19  * Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 package com.eteks.sweethome3d.junit;
22 
23 import java.awt.Component;
24 import java.text.Collator;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.Comparator;
28 import java.util.List;
29 import java.util.Locale;
30 
31 import javax.swing.JComponent;
32 import javax.swing.JFrame;
33 import javax.swing.JLabel;
34 import javax.swing.JScrollPane;
35 import javax.swing.JTable;
36 import javax.swing.table.TableCellRenderer;
37 import javax.swing.table.TableColumn;
38 import javax.swing.table.TableModel;
39 
40 import com.eteks.sweethome3d.io.DefaultUserPreferences;
41 import com.eteks.sweethome3d.model.CatalogPieceOfFurniture;
42 import com.eteks.sweethome3d.model.FurnitureCatalog;
43 import com.eteks.sweethome3d.model.FurnitureCategory;
44 import com.eteks.sweethome3d.model.Home;
45 import com.eteks.sweethome3d.model.HomePieceOfFurniture;
46 import com.eteks.sweethome3d.model.LengthUnit;
47 import com.eteks.sweethome3d.model.UserPreferences;
48 import com.eteks.sweethome3d.swing.FurnitureTable;
49 import com.eteks.sweethome3d.swing.SwingTools;
50 import com.eteks.sweethome3d.swing.SwingViewFactory;
51 import com.eteks.sweethome3d.viewcontroller.FurnitureController;
52 import com.eteks.sweethome3d.viewcontroller.FurnitureView;
53 
54 import junit.framework.TestCase;
55 
56 /**
57  * Tests furniture table component.
58  * @author Emmanuel Puybaret
59  */
60 public class FurnitureTableTest extends TestCase {
61   /**
62    * Tests furniture table creation and localization.
63    */
testFurnitureTableCreation()64   public void testFurnitureTableCreation()  {
65     // 1. Choose a locale that displays furniture dimensions in inches
66     Locale.setDefault(Locale.US);
67     // Read default user preferences
68     UserPreferences preferences = new DefaultUserPreferences();
69     // Check the current unit isn't centimeter
70     LengthUnit currentUnit = preferences.getLengthUnit();
71     assertFalse("Unit is in centimeter", currentUnit == LengthUnit.CENTIMETER);
72     // Get furniture catalog
73     FurnitureCatalog catalog = preferences.getFurnitureCatalog();
74 
75     // 2. Create a home that contains furniture matching catalog furniture
76     List<HomePieceOfFurniture> homeFurniture = createHomeFurnitureFromCatalog(catalog);
77     Home home = new Home(homeFurniture);
78     // Check catalog furniture count equals home furniture count
79     assertEquals("Different furniture count in list and home",
80         homeFurniture.size(), home.getFurniture().size());
81 
82     // 3. Create a table that displays home furniture
83     JTable table = new FurnitureTable(home, preferences);
84     // Check home furniture count equals table row count
85     assertEquals("Different furniture count in home and table",
86         home.getFurniture().size(), table.getRowCount());
87 
88     // 4. Check the displayed depth in table are different in French and US version
89     for (int row = 0, n = table.getRowCount(); row < n; row++) {
90       preferences.setUnit(LengthUnit.INCH);
91       String widthInInch = getRenderedDepth(table, row);
92       preferences.setUnit(LengthUnit.CENTIMETER);
93       String widthInMeter = getRenderedDepth(table, row);
94       assertFalse("Same depth in different units",
95           widthInInch.equals(widthInMeter));
96     }
97   }
98 
createHomeFurnitureFromCatalog( FurnitureCatalog catalog)99   private static List<HomePieceOfFurniture> createHomeFurnitureFromCatalog(
100       FurnitureCatalog catalog) {
101     List<HomePieceOfFurniture> homeFurniture = new ArrayList<HomePieceOfFurniture>();
102     for (FurnitureCategory category : catalog.getCategories()) {
103       for (CatalogPieceOfFurniture piece : category.getFurniture()) {
104         homeFurniture.add(new HomePieceOfFurniture(piece));
105       }
106     }
107     return homeFurniture;
108   }
109 
getRenderedDepth(JTable table, int row)110   private String getRenderedDepth(JTable table, int row) {
111     // Get index of detph column in model
112     TableColumn depthColumn = table.getColumn(HomePieceOfFurniture.SortableProperty.DEPTH);
113 
114     // Get depth value at row
115     TableModel model = table.getModel();
116     Object cellValue = model.getValueAt(row, depthColumn.getModelIndex());
117 
118     // Get component used to render the depth cell at row
119     int tableColumnIndex = table.getColumnModel().getColumnIndex(HomePieceOfFurniture.SortableProperty.DEPTH);
120     TableCellRenderer renderer = table.getCellRenderer(row, tableColumnIndex);
121     Component cellLabel = renderer.getTableCellRendererComponent(
122         table, cellValue, false, false, row, tableColumnIndex);
123 
124     // Return rendered depth
125     return ((JLabel)cellLabel).getText();
126   }
127 
128   /**
129    * Tests sort in furniture table.
130    */
testFurnitureTableSort()131   public void testFurnitureTableSort() {
132     // 1.  Create a home that contains furniture matching catalog furniture
133     UserPreferences preferences = new DefaultUserPreferences();
134     List<HomePieceOfFurniture> homeFurniture =
135       createHomeFurnitureFromCatalog(preferences.getFurnitureCatalog());
136     Home home = new Home(homeFurniture);
137     // Check home furniture isn't empty
138     assertTrue("Home furniture is empty", homeFurniture.size() > 0);
139 
140     // 2. Create a table that displays home furniture with its controller
141     FurnitureController furnitureController =
142         new FurnitureController(home, preferences, new SwingViewFactory());
143     FurnitureTable table = SwingTools.findChildren((JComponent)furnitureController.getView(), FurnitureTable.class).get(0);
144 
145     // 3. Sort furniture table in alphabetical order of furniture name
146     furnitureController.sortFurniture(HomePieceOfFurniture.SortableProperty.NAME);
147     // Check the alphabetical order of table data
148     assertFurnitureIsSortedByName(table, true);
149 
150     // 4. Sort in descending order and check order
151     furnitureController.sortFurniture(HomePieceOfFurniture.SortableProperty.NAME);
152     // Check table data is sorted in alphabetical descending order
153     assertFurnitureIsSortedByName(table, false);
154 
155     // 5. Change first furniture name
156     HomePieceOfFurniture firstPiece = home.getFurniture().get(0);
157     firstPiece.setName("Aaaa");
158     // Check table data is sorted in alphabetical descending order
159     assertFurnitureIsSortedByName(table, false);
160   }
161 
assertFurnitureIsSortedByName(JTable table, boolean ascendingOrder)162   private void assertFurnitureIsSortedByName(JTable table,
163                                              boolean ascendingOrder) {
164     int modelColumnIndex = table.getColumn(HomePieceOfFurniture.SortableProperty.NAME).getModelIndex();
165     TableModel model = table.getModel();
166     Comparator<Object> comparator = Collator.getInstance();
167     if (!ascendingOrder) {
168       comparator = Collections.reverseOrder(comparator);
169     }
170     // For each row
171     for (int row = 0, n = model.getRowCount() - 1; row < n; row++) {
172       Object value = model.getValueAt(row, modelColumnIndex);
173       Object nextValue = model.getValueAt(row + 1, modelColumnIndex);
174       // Check alphabetical order of values at a row and next row
175       assertTrue("Column not sorted",
176           comparator.compare(((HomePieceOfFurniture)value).getName(),
177                              ((HomePieceOfFurniture)nextValue).getName()) <= 0);
178     }
179   }
180 
181   /**
182    * Tests filter in furniture table.
183    */
testFurnitureTableFilter()184   public void testFurnitureTableFilter() {
185     // 1.  Create a home that contains furniture matching catalog furniture
186     UserPreferences preferences = new DefaultUserPreferences();
187     List<HomePieceOfFurniture> homeFurniture =
188       createHomeFurnitureFromCatalog(preferences.getFurnitureCatalog());
189     Home home = new Home(homeFurniture);
190     // Check home furniture isn't empty
191     assertTrue("Home furniture is empty", homeFurniture.size() > 0);
192 
193     // 2. Create a table that displays home furniture with its controller
194     FurnitureController furnitureController =
195         new FurnitureController(home, preferences, new SwingViewFactory());
196     FurnitureTable table = SwingTools.findChildren((JComponent)furnitureController.getView(), FurnitureTable.class).get(0);
197     assertEquals("Home furniture count and row count different", homeFurniture.size(), table.getRowCount());
198     // Apply a filter on furniture that refuses pieces that are windows
199     table.setFurnitureFilter(new FurnitureView.FurnitureFilter() {
200         public boolean include(Home home, HomePieceOfFurniture piece) {
201           return !piece.isDoorOrWindow();
202         }
203       });
204     // Count how many doors and windows are in home
205     int doorsAndWindowsCount = 0;
206     HomePieceOfFurniture doorOrWindowPiece = null;
207     HomePieceOfFurniture otherPiece = null;
208     for (HomePieceOfFurniture piece : home.getFurniture()) {
209       if (piece.isDoorOrWindow()) {
210         doorsAndWindowsCount++;
211         doorOrWindowPiece = piece;
212       } else {
213         otherPiece = piece;
214       }
215     }
216     // Check there's no door or window in table
217     int homeFurnitureCount = homeFurniture.size();
218     int tableFilterRowCount = table.getRowCount();
219     assertEquals("Home furniture count and row count same",
220         homeFurnitureCount - doorsAndWindowsCount, tableFilterRowCount);
221 
222     // 3. Add a door or window to home
223     home.addPieceOfFurniture(new HomePieceOfFurniture(doorOrWindowPiece));
224     // Check no row were added in table
225     assertEquals("Wrong furniture count in home", homeFurnitureCount + 1, home.getFurniture().size());
226     assertEquals("Wrong row count in table", tableFilterRowCount, table.getRowCount());
227 
228     // 4. Add an other kind of piece to home
229     home.addPieceOfFurniture(new HomePieceOfFurniture(otherPiece));
230     // Check one row was added in table
231     assertEquals("Wrong furniture count in home", homeFurnitureCount + 2, home.getFurniture().size());
232     assertEquals("Wrong row count in table", tableFilterRowCount + 1, table.getRowCount());
233 
234     // 5. Test sort and filter internal buffer of the table
235     furnitureController.sortFurniture(HomePieceOfFurniture.SortableProperty.NAME);
236     // Check the alphabetical order of table data
237     assertFurnitureIsSortedByName(table, true);
238     // Add a door or window and an other kind of piece to home
239     home.addPieceOfFurniture(new HomePieceOfFurniture(doorOrWindowPiece));
240     home.addPieceOfFurniture(new HomePieceOfFurniture(otherPiece));
241     // Check one row was added in sorted table
242     assertEquals("Wrong furniture count in home", homeFurnitureCount + 4, home.getFurniture().size());
243     assertEquals("Wrong row count in table", tableFilterRowCount + 2, table.getRowCount());
244     assertFurnitureIsSortedByName(table, true);
245 
246     // 6. Remove filter
247     table.setFurnitureFilter(null);
248     // Check missing rows are back
249     assertEquals("Home furniture count and row count different",
250         home.getFurniture().size(), table.getRowCount());
251     assertFurnitureIsSortedByName(table, true);
252   }
253 
main(String [] args)254   public static void main(String [] args) {
255     UserPreferences preferences = new DefaultUserPreferences();
256     List<HomePieceOfFurniture> homeFurniture =
257       createHomeFurnitureFromCatalog(preferences.getFurnitureCatalog());
258     Home home = new Home(homeFurniture);
259 
260     // Create a furniture table
261     JTable table = new FurnitureTable(home, preferences);
262     JFrame frame = new JFrame("Furniture table Test");
263     frame.add(new JScrollPane(table));
264     frame.pack();
265     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
266     frame.setVisible(true);
267   }
268 }
269