1 /*
   2  * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.scene.control.cell;
  27 
  28 import com.sun.javafx.scene.control.infrastructure.MouseEventFirer;
  29 import com.sun.javafx.scene.control.infrastructure.VirtualFlowTestUtils;
  30 import javafx.scene.control.skin.VirtualFlow;
  31 import javafx.beans.property.ReadOnlyStringWrapper;
  32 import javafx.beans.value.ObservableValue;
  33 import javafx.collections.FXCollections;
  34 import javafx.scene.control.TableCell;
  35 import javafx.scene.control.TableColumn;
  36 import javafx.scene.control.TableView;
  37 import javafx.scene.control.TextField;
  38 import javafx.scene.input.MouseButton;
  39 import javafx.util.Callback;
  40 import javafx.util.StringConverter;
  41 import org.junit.Before;
  42 import org.junit.Test;
  43 
  44 import static org.junit.Assert.*;
  45 
  46 public class TextFieldTableCellTest {
  47     
  48     private StringConverter<Object> converter;
  49     
  50     @Before public void setup() {
  51         converter = new StringConverter<Object>() {
  52             @Override public String toString(Object object) {
  53                 return null;
  54             }
  55 
  56             @Override public Object fromString(String string) {
  57                 return null;
  58             }
  59         };
  60     }
  61     
  62     /**************************************************************************
  63      * 
  64      * Test for public static Callback<TableColumn<String>, TableCell<String>> forTableColumn()
  65      * 
  66      **************************************************************************/
  67 
  68     
  69     @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryIsNotNull() {
  70         Callback<TableColumn<Object,String>, TableCell<Object,String>> cellFactory = TextFieldTableCell.forTableColumn();
  71         assertNotNull(cellFactory);
  72     }
  73     
  74     @Test public void testStatic_forTableColumn_noArgs_ensureCellFactoryCreatesCells() {
  75         Callback<TableColumn<Object,String>, TableCell<Object,String>> cellFactory = TextFieldTableCell.forTableColumn();
  76         
  77         TableColumn<Object,String> tableColumn = new TableColumn<>();
  78         TextFieldTableCell<Object,String> cell = (TextFieldTableCell<Object,String>)cellFactory.call(tableColumn);
  79         assertNotNull(cell);
  80     }
  81 
  82     @Test public void testStatic_forTableColumn_callback_ensureCellHasNonNullStringConverter() {
  83         Callback<TableColumn<Object,String>, TableCell<Object,String>> cellFactory = TextFieldTableCell.forTableColumn();
  84         
  85         TableColumn<Object,String> tableColumn = new TableColumn<>();
  86         TextFieldTableCell<Object,String> cell = (TextFieldTableCell<Object,String>)cellFactory.call(tableColumn);
  87         assertNotNull(cell.getConverter());
  88     }
  89     
  90     
  91     
  92     /**************************************************************************
  93      * 
  94      * Test for public static <T> Callback<TableColumn<T>, TableCell<T>> forTableColumn(
  95      *       final StringConverter<T> converter)
  96      * 
  97      **************************************************************************/
  98 
  99     
 100     @Test public void testStatic_forTableColumn_converter_ensureCellFactoryIsNotNull() {
 101         Callback<TableColumn<Object,Object>, TableCell<Object,Object>> cellFactory = TextFieldTableCell.forTableColumn(converter);
 102         assertNotNull(cellFactory);
 103     }
 104     
 105     @Test public void testStatic_forTableColumn_converter_ensureCellFactoryCreatesCells() {
 106         Callback<TableColumn<Object,Object>, TableCell<Object,Object>> cellFactory = TextFieldTableCell.forTableColumn(converter);
 107         
 108         TableColumn<Object,Object> tableColumn = new TableColumn<>();
 109         TextFieldTableCell<Object,Object> cell = (TextFieldTableCell<Object,Object>)cellFactory.call(tableColumn);
 110         assertNotNull(cell);
 111     }
 112 
 113     @Test public void testStatic_forTableColumn_converter_ensureCellHasSetStringConverter() {
 114         Callback<TableColumn<Object,Object>, TableCell<Object,Object>> cellFactory = TextFieldTableCell.forTableColumn(converter);
 115         
 116         TableColumn<Object,Object> tableColumn = new TableColumn<>();
 117         TextFieldTableCell<Object,Object> cell = (TextFieldTableCell<Object,Object>)cellFactory.call(tableColumn);
 118         assertNotNull(cell.getConverter());
 119         assertEquals(converter, cell.getConverter());
 120     }
 121     
 122     
 123     
 124     /**************************************************************************
 125      * 
 126      * Constructor tests for default constructor
 127      * 
 128      **************************************************************************/
 129 
 130     @Test public void testConstructor_noArgs_defaultStringConverterIsNull() {
 131         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
 132         assertNull(cell.getConverter());
 133     }
 134     
 135     @Test public void testConstructor_noArgs_defaultStyleClass() {
 136         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
 137         assertTrue(cell.getStyleClass().contains("text-field-table-cell"));
 138     }
 139     
 140     @Test public void testConstructor_noArgs_defaultGraphicIsNull() {
 141         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
 142         assertNull(cell.getGraphic());
 143     }
 144     
 145     
 146     /**************************************************************************
 147      * 
 148      * Constructor tests for one-arg constructor
 149      * 
 150      **************************************************************************/
 151     
 152     @Test public void testConstructor_converter_defaultStringConverterIsNotNull() {
 153         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>(converter);
 154         assertNotNull(cell.getConverter());
 155     }
 156     
 157     @Test public void testConstructor_converter_defaultStyleClass() {
 158         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>(converter);
 159         assertTrue(cell.getStyleClass().contains("text-field-table-cell"));
 160     }
 161     
 162     @Test public void testConstructor_converter_defaultGraphicIsACheckBox() {
 163         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>(converter);
 164         assertNull(cell.getGraphic());
 165     }
 166     
 167     
 168     /**************************************************************************
 169      * 
 170      * updateItem tests
 171      * 
 172      **************************************************************************/
 173 
 174     @Test public void test_updateItem_isEmpty_graphicIsNull() {
 175         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
 176         cell.updateItem("TEST", true);
 177         assertNull(cell.getGraphic());
 178     }
 179     
 180     @Test public void test_updateItem_isEmpty_textIsNull() {
 181         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
 182         cell.updateItem("TEST", true);
 183         assertNull(cell.getText());
 184     }
 185     
 186     @Test public void test_updateItem_isNotEmpty_textIsNotNull() {
 187         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
 188         cell.updateItem("TEST", false);
 189         assertNotNull(cell.getText());
 190         assertEquals("TEST", cell.getText());
 191     }
 192     
 193     @Test public void test_updateItem_isNotEmpty_textIsNotNull_nullConverter() {
 194         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
 195         cell.setConverter(null);
 196         cell.updateItem("TEST", false);
 197         assertNotNull(cell.getText());
 198         assertEquals("TEST", cell.getText());
 199     }
 200     
 201     @Test public void test_updateItem_isNotEmpty_textIsNotNull_nonNullConverter() {
 202         TextFieldTableCell<?,Object> cell = new TextFieldTableCell<>();
 203         cell.setConverter(
 204                 new StringConverter<Object>() {
 205                     @Override public Object fromString(String string) {
 206                         return null;
 207                     }
 208 
 209                     @Override public String toString(Object object) {
 210                         return "CONVERTED";
 211                     }
 212                 });
 213         cell.updateItem("TEST", false);
 214         assertNotNull(cell.getText());
 215         assertEquals("CONVERTED", cell.getText());
 216     }
 217 
 218 
 219     /**************************************************************************
 220      *
 221      * editing tests
 222      *
 223      **************************************************************************/
 224 
 225     // --- is Empty
 226     @Test public void test_startEdit_cellEditableIsFalse_isEmpty() {
 227         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 228         cell.setEditable(false);
 229         cell.startEdit();
 230         assertFalse(cell.isEditing());
 231         assertNull(cell.getGraphic());
 232     }
 233 
 234     @Test public void test_startEdit_tableViewEditableIsFalse_isEmpty() {
 235         TableView tableView = new TableView();
 236         tableView.setEditable(false);
 237         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 238         cell.updateTableView(tableView);
 239 
 240         cell.startEdit();
 241         assertFalse(cell.isEditing());
 242         assertNull(cell.getGraphic());
 243     }
 244 
 245     @Test(expected = NullPointerException.class)
 246     public void test_startEdit_cellEditableIsTrue_tableColumnIsNull_isEmpty() {
 247         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 248         cell.setEditable(true);
 249         cell.startEdit();
 250     }
 251 
 252     @Test public void test_startEdit_tableViewEditableIsTrue_isEmpty() {
 253         TableColumn tc = new TableColumn();
 254         TableView tableView = new TableView();
 255         tableView.setEditable(true);
 256         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 257         cell.updateTableView(tableView);
 258         cell.updateTableColumn(tc);
 259 
 260         tableView.edit(0, tc);
 261         assertFalse(cell.isEditing());
 262         assertNull(cell.getGraphic());
 263     }
 264 
 265 //    @Test public void test_startEdit_tableColumnEditableIsTrue_cellEditableIsTrue_isEmpty() {
 266 //        TableColumn tc = new TableColumn();
 267 //        TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
 268 //        tableView.getColumns().add(tc);
 269 //        tableView.setEditable(true);
 270 //        TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 271 //        cell.updateTableView(tableView);
 272 //        cell.updateIndex(0);
 273 //        cell.updateTableColumn(tc);
 274 //        cell.setEditable(true);
 275 //
 276 //        tableView.edit(0, tc);
 277 //        assertFalse(cell.isEditing());
 278 //        assertNull(cell.getGraphic());
 279 //    }
 280 
 281     // --- is Not Empty
 282     @Test public void test_startEdit_cellEditableIsFalse_isNotEmpty() {
 283         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 284         cell.updateItem("TEST", false);
 285         cell.setEditable(false);
 286         cell.startEdit();
 287         assertFalse(cell.isEditing());
 288         assertNull(cell.getGraphic());
 289     }
 290 
 291     @Test public void test_startEdit_tableColumnEditableIsFalse_isNotEmpty() {
 292         TableColumn<Object,Object> tableColumn = new TableColumn<>();
 293         tableColumn.setEditable(false);
 294         TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
 295         tableView.getColumns().add(tableColumn);
 296         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 297         cell.updateTableColumn(tableColumn);
 298         cell.updateTableView(tableView);
 299         cell.updateItem("TEST", false);
 300 
 301         cell.startEdit();
 302         assertFalse(cell.isEditing());
 303         assertNull(cell.getGraphic());
 304     }
 305 
 306     @Test(expected = NullPointerException.class)
 307     public void test_startEdit_cellEditableIsTrue_tableColumnIsNull_isNotEmpty() {
 308         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 309         cell.updateItem("TEST", false);
 310         cell.setEditable(true);
 311         cell.startEdit();
 312     }
 313 
 314     @Test public void test_startEdit_tableViewEditableIsTrue_isNotEmpty() {
 315         TableColumn tc = new TableColumn();
 316         TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
 317         tableView.getColumns().add(tc);
 318         tableView.setEditable(true);
 319         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 320         cell.updateTableView(tableView);
 321         cell.updateIndex(0);
 322         cell.updateTableColumn(tc);
 323 
 324         tableView.edit(0, tc);
 325         assertTrue(cell.isEditing());
 326         assertNotNull(cell.getGraphic());
 327     }
 328 
 329     @Test public void test_startEdit_tableColumnEditableIsTrue_cellEditableIsTrue_isNotEmpty() {
 330         TableColumn tc = new TableColumn();
 331         TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
 332         tableView.getColumns().add(tc);
 333         tableView.setEditable(true);
 334         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 335         cell.updateTableView(tableView);
 336         cell.updateIndex(0);
 337         cell.updateTableColumn(tc);
 338         cell.setEditable(true);
 339 
 340         tableView.edit(0, tc);
 341         assertTrue(cell.isEditing());
 342         assertNotNull(cell.getGraphic());
 343     }
 344 
 345     // --- cancel edit
 346     @Test public void test_cancelEdit_usingCellCancelEdit() {
 347         TableColumn tc = new TableColumn();
 348         TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
 349         tableView.getColumns().add(tc);
 350         tableView.setEditable(true);
 351         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 352         cell.updateTableView(tableView);
 353         cell.updateIndex(0);
 354         cell.updateTableColumn(tc);
 355         cell.setEditable(true);
 356 
 357         tableView.edit(0, tc);
 358         assertTrue(cell.isEditing());
 359         assertNotNull(cell.getGraphic());
 360 
 361         cell.cancelEdit();
 362         assertFalse(cell.isEditing());
 363         assertNull(cell.getGraphic());
 364     }
 365 
 366     @Test public void test_cancelEdit_usingTableCancelEdit() {
 367         TableColumn tc = new TableColumn();
 368         TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
 369         tableView.getColumns().add(tc);
 370         tableView.setEditable(true);
 371         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 372         cell.updateTableView(tableView);
 373         cell.updateIndex(0);
 374         cell.updateTableColumn(tc);
 375         cell.setEditable(true);
 376 
 377         tableView.edit(0, tc);
 378         assertTrue(cell.isEditing());
 379         assertNotNull(cell.getGraphic());
 380 
 381         tableView.edit(-1, null);
 382         assertFalse(cell.isEditing());
 383         assertNull(cell.getGraphic());
 384     }
 385 
 386 
 387     /**************************************************************************
 388      *
 389      * Tests for specific bugs
 390      *
 391      **************************************************************************/
 392 
 393     @Test public void test_rt_32869() {
 394         TableColumn tc = new TableColumn();
 395         tc.setCellValueFactory(param -> new ReadOnlyStringWrapper("Dummy Text"));
 396 
 397         TableView tableView = new TableView(FXCollections.observableArrayList("TEST"));
 398         tableView.getColumns().add(tc);
 399         tableView.setEditable(true);
 400         TextFieldTableCell<Object,Object> cell = new TextFieldTableCell<>();
 401         cell.updateTableView(tableView);
 402         cell.updateIndex(0);
 403         cell.updateTableColumn(tc);
 404         cell.setEditable(true);
 405 
 406         tableView.edit(0, tc);
 407         assertTrue(cell.isEditing());
 408         assertNotNull(cell.getGraphic());
 409 
 410         TextField textField = (TextField) cell.getGraphic();
 411         MouseEventFirer mouse = new MouseEventFirer(textField);
 412 
 413         textField.requestFocus();
 414         textField.selectAll();
 415         assertEquals("Dummy Text", textField.getSelectedText());
 416 
 417         assertEquals("Dummy Text", textField.getSelectedText());
 418 
 419         mouse.fireMousePressed(MouseButton.SECONDARY);
 420         assertEquals("Dummy Text", textField.getSelectedText());
 421         mouse.fireMouseReleased(MouseButton.SECONDARY);
 422         assertEquals("Dummy Text", textField.getSelectedText());
 423 
 424         mouse.dispose();
 425     }
 426 }