1 /*
   2  * Copyright (c) 2011, 2017, 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 test.javafx.scene.control;
  27 
  28 import javafx.beans.InvalidationListener;
  29 import javafx.beans.Observable;
  30 import javafx.beans.property.BooleanProperty;
  31 import javafx.beans.property.SimpleBooleanProperty;
  32 import javafx.beans.property.SimpleStringProperty;
  33 import javafx.beans.property.StringProperty;
  34 import javafx.beans.value.ChangeListener;
  35 import javafx.beans.value.ObservableValue;
  36 import javafx.css.CssMetaData;
  37 import javafx.css.StyleableProperty;
  38 import javafx.event.EventHandler;
  39 import javafx.scene.Scene;
  40 import javafx.scene.input.KeyCode;
  41 import javafx.scene.input.KeyEvent;
  42 import javafx.scene.input.Clipboard;
  43 import javafx.scene.input.ClipboardContent;
  44 import javafx.scene.text.Font;
  45 import javafx.scene.layout.StackPane;
  46 import javafx.stage.Stage;
  47 import java.util.Arrays;
  48 import java.util.Collection;
  49 import java.util.Date;
  50 import javafx.scene.control.IndexRange;
  51 import javafx.scene.control.PasswordField;
  52 import javafx.scene.control.TextArea;
  53 import javafx.scene.control.TextField;
  54 import javafx.scene.control.TextInputControl;
  55 import com.sun.javafx.tk.Toolkit;
  56 import org.junit.Before;
  57 import org.junit.Ignore;
  58 import org.junit.Test;
  59 import org.junit.runner.RunWith;
  60 import org.junit.runners.Parameterized;
  61 import test.com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
  62 import test.com.sun.javafx.pgstub.StubToolkit;
  63 import static org.junit.Assert.assertEquals;
  64 import static org.junit.Assert.assertFalse;
  65 import static org.junit.Assert.assertNull;
  66 import static org.junit.Assert.assertTrue;
  67 
  68 /**
  69  */
  70 @RunWith(Parameterized.class)
  71 public class TextInputControlTest {
  72     @SuppressWarnings("rawtypes")
  73     @Parameterized.Parameters public static Collection implementations() {
  74         return Arrays.asList(new Object[][]{
  75                 {TextField.class},
  76                 {PasswordField.class},
  77                 {TextArea.class}
  78         });
  79     }
  80 
  81     private TextInputControl textInput;
  82     private Class type;
  83 
  84     public TextInputControlTest(Class type) {
  85         this.type = type;
  86     }
  87 
  88     @Before public void setup() throws Exception {
  89         textInput = (TextInputControl) type.newInstance();
  90     }
  91 
  92     /******************************************************
  93      * Test the default states                            *
  94      *****************************************************/
  95 
  96     @Test public void textDefaultsToEmptyString() {
  97         assertEquals("", textInput.getText());
  98     }
  99 
 100     @Test public void editableDefaultsToTrue() {
 101         assertTrue(textInput.isEditable());
 102     }
 103 
 104     @Test public void anchorDefaultsToZero() {
 105         assertEquals(0, textInput.getAnchor());
 106     }
 107 
 108     @Test public void caretPositionDefaultsToZero() {
 109         assertEquals(0, textInput.getCaretPosition());
 110     }
 111 
 112     @Test public void lengthDefaultsToZero() {
 113         assertEquals(0, textInput.getLength());
 114     }
 115 
 116     @Test public void selectedTextDefaultsToEmptyString() {
 117         assertEquals("", textInput.getSelectedText());
 118     }
 119 
 120     @Test public void selectionDefaultsToEmpty() {
 121         assertEquals(0, textInput.getSelection().getLength());
 122     }
 123 
 124     @Test public void selectionStartDefaultsToZero() {
 125         assertEquals(0, textInput.getSelection().getStart());
 126     }
 127 
 128     @Test public void selectionEndDefaultsToZero() {
 129         assertEquals(0, textInput.getSelection().getEnd());
 130     }
 131 
 132     /*********************************************************************
 133      * Tests for CSS                                                     *
 134      ********************************************************************/
 135 
 136     @Test public void fontSetFromCSS() {
 137         textInput.setStyle("-fx-font: 24 Helvetica");
 138         Scene s = new Scene(textInput);
 139         textInput.applyCss();
 140         assertEquals(Font.font("Helvetica", 24), textInput.getFont());
 141     }
 142 
 143     /******************************************************
 144      * Test for text                                      *
 145      *****************************************************/
 146 
 147     @Test public void settingTextUpdatesTheText() {
 148         textInput.setText("This is a test");
 149         assertEquals("This is a test", textInput.getText());
 150         assertEquals("This is a test", textInput.textProperty().get());
 151     }
 152 
 153     @Test public void textCanBeNull() {
 154         textInput.setText(null);
 155         assertNull(textInput.getText());
 156     }
 157 
 158     @Test public void textCanBeSwitchedBetweenNullAndAValue() {
 159         textInput.setText(null);
 160         textInput.setText("Test");
 161         assertEquals("Test", textInput.getText());
 162     }
 163 
 164     @Test public void textCanBeSwitchedFromAValueToNull() {
 165         textInput.setText("Test");
 166         textInput.setText(null);
 167         assertNull(textInput.getText());
 168     }
 169 
 170     @Test public void textIsNullThenBoundThenUnboundAndShouldReturnTheValueWhenBound() {
 171         textInput.setText(null);
 172         StringProperty other = new SimpleStringProperty("Peppers");
 173         textInput.textProperty().bind(other);
 174         textInput.textProperty().unbind();
 175         assertEquals("Peppers", textInput.getText());
 176     }
 177 
 178     @Test public void textHasValueThenIsBoundToNullShouldReturnNullFromGet() {
 179         textInput.setText("Value");
 180         StringProperty other = new SimpleStringProperty(null);
 181         textInput.textProperty().bind(other);
 182         assertNull(textInput.getText());
 183     }
 184 
 185     @Test public void textHasValueThenIsBoundToNullAndUnboundShouldReturnNullFromGet() {
 186         textInput.setText("Value");
 187         StringProperty other = new SimpleStringProperty(null);
 188         textInput.textProperty().bind(other);
 189         textInput.textProperty().unbind();
 190         assertNull(textInput.getText());
 191     }
 192 
 193     @Test public void textHasValueThenIsBoundToNullAndUnboundThenSetShouldReturnNewValueFromGet() {
 194         textInput.setText("Value");
 195         StringProperty other = new SimpleStringProperty(null);
 196         textInput.textProperty().bind(other);
 197         textInput.textProperty().unbind();
 198         textInput.setText("New Value");
 199         assertEquals("New Value", textInput.getText());
 200     }
 201 
 202     @Test public void textCanBeBound() {
 203         StringProperty other = new SimpleStringProperty("Apples");
 204         textInput.textProperty().bind(other);
 205         assertEquals("Apples", textInput.getText());
 206         other.set("Oranges");
 207         assertEquals("Oranges", textInput.getText());
 208     }
 209 
 210     @Ignore("getCssMetaData will return null for textProperty")
 211     @Test public void impl_cssSettable_ReturnsFalseForTextAlways() {
 212         CssMetaData styleable = ((StyleableProperty)textInput.textProperty()).getCssMetaData();
 213         assertTrue(styleable.isSettable(textInput));
 214         StringProperty other = new SimpleStringProperty("Apples");
 215         textInput.textProperty().bind(other);
 216         assertFalse(styleable.isSettable(textInput));
 217     }
 218 
 219     @Test public void cannotSpecifyTextViaCSS() {
 220         try {
 221             CssMetaData styleable = ((StyleableProperty)textInput.textProperty()).getCssMetaData();
 222             assertNull(styleable);
 223         } catch (ClassCastException ignored) {
 224             // pass!
 225         } catch (Exception e) {
 226             org.junit.Assert.fail(e.toString());
 227         }
 228     }
 229 
 230     @Test public void settingTextNotifiesOfChange() {
 231         final boolean[] passed = new boolean[] { false };
 232         textInput.textProperty().addListener((observable, oldValue, newValue) -> {
 233             passed[0] = true;
 234         });
 235         textInput.setText("Apples");
 236         assertTrue(passed[0]);
 237     }
 238 
 239     // TODO test that setting text which includes a \n works
 240     @Test public void controlCharactersAreOmitted_setText_getText() {
 241         String s = "This is " + '\0' + "a test";
 242         textInput.setText(s);
 243         assertEquals("This is a test", textInput.getText());
 244     }
 245 
 246     @Test public void controlCharactersAreOmitted_setText_textProperty_get() {
 247         String s = "This is " + '\0' + "a test";
 248         textInput.setText(s);
 249         assertEquals("This is a test", textInput.textProperty().get());
 250     }
 251 
 252     @Test public void controlCharactersAreOmitted_bound_getText() {
 253         StringProperty other = new SimpleStringProperty("This is " + '\0' + "a test");
 254         textInput.textProperty().bind(other);
 255         assertEquals("This is a test", textInput.getText());
 256         other.set("Bro" + '\5' + "ken");
 257         assertEquals("Broken", textInput.getText());
 258     }
 259 
 260     @Test public void controlCharactersAreOmitted_bound_textProperty_get() {
 261         StringProperty other = new SimpleStringProperty("This is " + '\0' + "a test");
 262         textInput.textProperty().bind(other);
 263         assertEquals("This is a test", textInput.textProperty().get());
 264         other.set("Bro" + '\5' + "ken");
 265         assertEquals("Broken", textInput.textProperty().get());
 266     }
 267 
 268     // selection is changed when text is changed??
 269     // anchor and caret position updated when selection is changed due to text change??
 270     // selected text is updated when selection changes due to a text change??
 271     // length is updated when text changes
 272 
 273     /******************************************************
 274      * Test for editable                                  *
 275      *****************************************************/
 276 
 277     @Test public void settingEditableValueShouldWork() {
 278         textInput.setEditable(false);
 279         assertFalse(textInput.isEditable());
 280     }
 281 
 282     @Test public void settingEditableAndThenCreatingAModelAndReadingTheValueStillWorks() {
 283         textInput.setEditable(false);
 284         assertFalse(textInput.editableProperty().get());
 285     }
 286 
 287     @Test public void editableCanBeBound() {
 288         BooleanProperty other = new SimpleBooleanProperty(false);
 289         textInput.editableProperty().bind(other);
 290         assertFalse(textInput.isEditable());
 291         other.set(true);
 292         assertTrue(textInput.isEditable());
 293     }
 294 
 295     @Ignore("getCssMetaData will return null for editableProperty")
 296     @Test public void impl_cssSettable_ReturnsFalseForEditableAlways() {
 297         CssMetaData styleable = ((StyleableProperty)textInput.editableProperty()).getCssMetaData();
 298         assertTrue(styleable.isSettable(textInput));
 299         StringProperty other = new SimpleStringProperty("Apples");
 300         textInput.textProperty().bind(other);
 301         assertFalse(styleable.isSettable(textInput));
 302     }
 303 
 304     @Test public void cannotSpecifyEditableViaCSS() {
 305         try {
 306             CssMetaData styleable = ((StyleableProperty)textInput.editableProperty()).getCssMetaData();
 307             assertNull(styleable);
 308         } catch (ClassCastException ignored) {
 309             // pass!
 310         } catch (Exception e) {
 311             org.junit.Assert.fail(e.toString());
 312         }
 313     }
 314 
 315     @Test public void settingEditableNotifiesOfChange() {
 316         final boolean[] passed = new boolean[] { false };
 317         textInput.editableProperty().addListener((observable, oldValue, newValue) -> {
 318             passed[0] = true;
 319         });
 320         textInput.setEditable(false);
 321         assertTrue(passed[0]);
 322     }
 323 
 324     /******************************************************
 325      * Test for anchor                                    *
 326      *****************************************************/
 327 
 328     @Test public void anchorIsSetWhenSelectionChanges() {
 329         textInput.setText("The quick brown fox");
 330         textInput.selectRange(4, 9);
 331         assertEquals(4, textInput.getAnchor());
 332     }
 333 
 334     @Test public void anchorIsSetWhenSelectionChanges2() {
 335         textInput.setText("The quick brown fox");
 336         textInput.selectRange(9, 4);
 337         assertEquals(9, textInput.getAnchor());
 338     }
 339 
 340     // updated when text changes
 341     @Test public void anchorIsSetToCaretPositionWhenTextChanges() {
 342         textInput.setText("The quick brown fox");
 343         textInput.selectRange(4, 9);
 344         textInput.setText("Gone");
 345         assertEquals(textInput.getCaretPosition(), textInput.getAnchor());
 346     }
 347 
 348     /******************************************************
 349      * Test for caretPosition                             *
 350      *****************************************************/
 351 
 352     @Test public void caretPositionIsSetWhenSelectionChanges() {
 353         textInput.setText("The quick brown fox");
 354         textInput.selectRange(4, 9);
 355         assertEquals(9, textInput.getCaretPosition());
 356     }
 357 
 358     @Test public void caretPositionIsSetWhenSelectionChanges2() {
 359         textInput.setText("The quick brown fox");
 360         textInput.selectRange(9, 4);
 361         assertEquals(4, textInput.getCaretPosition());
 362     }
 363 
 364     @Test
 365     public void caretAndAnchorPositionAfterSettingText() {
 366         textInput.setText("The quick brown fox");
 367         assertEquals(0, textInput.getCaretPosition());
 368         assertEquals(0, textInput.getAnchor());
 369     }
 370 
 371     // Test for JDK-8178417
 372     @Test public void caretPositionUndo() {
 373         Toolkit tk = (StubToolkit)Toolkit.getToolkit();
 374         StackPane root = new StackPane();
 375         Scene scene = new Scene(root);
 376         Stage stage = new Stage();
 377         String text = "01234";
 378 
 379         textInput.setText(text);
 380         stage.setScene(scene);
 381         root.getChildren().removeAll();
 382         root.getChildren().add(textInput);
 383         stage.show();
 384         tk.firePulse();
 385 
 386         KeyEventFirer keyboard = new KeyEventFirer(textInput);
 387         keyboard.doKeyPress(KeyCode.HOME);
 388 
 389         for(int i = 1; i < text.length() + 1; ++i) {
 390             keyboard.doKeyPress(KeyCode.RIGHT);
 391             tk.firePulse();
 392         }
 393         for(int i = 1; i < text.length() + 1; ++i) {
 394             textInput.undo();
 395         }
 396         assertEquals(text.length(), textInput.getCaretPosition());
 397         root.getChildren().removeAll();
 398         stage.hide();
 399         tk.firePulse();
 400     }
 401 
 402     /******************************************************
 403      * Test for length                                    *
 404      *****************************************************/
 405 
 406     // TODO null text results in 0 length
 407 
 408     @Test public void emptyTextResultsInZeroLength() {
 409         textInput.setText("Hello");
 410         textInput.setText("");
 411         assertEquals(0, textInput.getLength());
 412     }
 413 
 414     @Test public void lengthMatchesStringLength() {
 415         final String string = "Hello";
 416         textInput.setText(string);
 417         assertEquals(string.length(), textInput.getLength());
 418     }
 419 
 420     @Test public void lengthChangeNotificationWhenTextIsUpdatedToNonEmptyResult() {
 421         final boolean[] passed = new boolean[] { false };
 422         textInput.lengthProperty().addListener((observable, oldValue, newValue) -> {
 423             passed[0] = true;
 424         });
 425         textInput.setText("Hello");
 426         assertTrue(passed[0]);
 427     }
 428 
 429     @Ignore("The notification here doesn't happen because the invalid flag is set after the first set," +
 430             "however setting a change listener *must* clear that, but doesn't. I copied the code for this " +
 431             "straight from the beans package, so there may be a bug there.")
 432     @Test public void lengthChangeNotificationWhenTextIsSetToEmptyResult() {
 433         textInput.setText("Goodbye");
 434         final boolean[] passed = new boolean[] { false };
 435         textInput.lengthProperty().addListener((observable, oldValue, newValue) -> {
 436             passed[0] = true;
 437         });
 438         textInput.setText("");
 439         assertTrue(passed[0]);
 440     }
 441 
 442     /******************************************************
 443      * Test for maximumLength                             *
 444      *****************************************************/
 445 
 446     // set maximum length to less than current length
 447 
 448     /******************************************************
 449      * Test for selected text                             *
 450      *****************************************************/
 451 
 452     // TODO test null text and some random range
 453 
 454     @Test public void selectedTextMatchesTextAndSelection() {
 455         textInput.setText("The quick brown fox");
 456         textInput.selectRange(0, 3);
 457         assertEquals("The", textInput.getSelectedText());
 458     }
 459 
 460     @Test public void selectedTextMatchesTextAndSelection2() {
 461         textInput.setText("The quick brown fox");
 462         textInput.selectRange(4, 9);
 463         assertEquals("quick", textInput.getSelectedText());
 464     }
 465 
 466     @Test public void selectedTextMatchesTextAndSelection3() {
 467         textInput.setText("The quick brown fox");
 468         textInput.selectRange(10, 19);
 469         assertEquals("brown fox", textInput.getSelectedText());
 470     }
 471 
 472     @Test public void selectedTextIsClearedWhenTextChanges() {
 473         textInput.setText("The quick brown fox");
 474         textInput.selectRange(4, 9);
 475         textInput.setText("");
 476         assertEquals("", textInput.getSelectedText());
 477     }
 478 
 479     @Test public void selectedTextWorksWhenSelectionExceedsPossibleRange() {
 480         textInput.setText("The quick brown fox");
 481         textInput.selectRange(10, 180);
 482         assertEquals("brown fox", textInput.getSelectedText());
 483     }
 484 
 485     @Test public void selectedTextWorksWhenSelectionExceedsPossibleRange2() {
 486         textInput.setText("The quick brown fox");
 487         textInput.selectRange(100, 180);
 488         assertEquals("", textInput.getSelectedText());
 489     }
 490 
 491 //    @Test public void selectedTextWorksWhenSelectionIsBound() {
 492 //        ObjectProperty<IndexRange> other = new SimpleObjectProperty<IndexRange>(new IndexRange(4, 9));
 493 //        textInput.setText("The quick brown fox");
 494 //        textInput.selectionProperty().bind(other);
 495 //        assertEquals("quick", textInput.getSelectedText());
 496 //        other.set(new IndexRange(10, 19));
 497 //        assertEquals("brown fox", textInput.getSelectedText());
 498 //    }
 499 
 500     @Test public void selectedTextWorksWhenTextIsBound() {
 501         StringProperty other = new SimpleStringProperty("There and back again");
 502         textInput.textProperty().bind(other);
 503         textInput.selectRange(0, 5);
 504         assertEquals("There", textInput.getSelectedText());
 505         other.set("Cleared!");
 506         assertEquals("", textInput.getSelectedText());
 507     }
 508 
 509     @Test public void selectedTextChangeEvents() {
 510         final boolean[] passed = new boolean[] { false };
 511         textInput.setText("The quick brown fox");
 512         textInput.selectedTextProperty().addListener(observable -> {
 513             passed[0] = true;
 514         });
 515         textInput.selectRange(0, 3);
 516         assertTrue(passed[0]);
 517     }
 518 
 519     @Test public void selectedTextChangeEvents2() {
 520         final boolean[] passed = new boolean[] { false };
 521         textInput.setText("The quick brown fox");
 522         textInput.selectRange(0, 3);
 523         textInput.selectedTextProperty().addListener(observable -> {
 524             passed[0] = true;
 525         });
 526         textInput.selectRange(10, 180);
 527         assertTrue(passed[0]);
 528     }
 529 
 530     @Test public void selectedTextChangeEvents3() {
 531         final boolean[] passed = new boolean[] { false };
 532         StringProperty other = new SimpleStringProperty("There and back again");
 533         textInput.textProperty().bind(other);
 534         textInput.selectRange(0, 5);
 535         textInput.selectedTextProperty().addListener(observable -> {
 536             passed[0] = true;
 537         });
 538         other.set("Cleared!");
 539         assertTrue(passed[0]);
 540     }
 541 
 542     /******************************************************
 543      * Test for selection                                 *
 544      *****************************************************/
 545 
 546     @Test public void selectionIsClearedWhenTextChanges() {
 547         textInput.setText("The quick brown fox");
 548         textInput.selectRange(4, 9);
 549         textInput.setText("");
 550         assertEquals(new IndexRange(0, 0), textInput.getSelection());
 551     }
 552 
 553     @Test public void selectionCannotBeSetToBeOutOfRange() {
 554         textInput.setText("The quick brown fox");
 555         textInput.selectRange(4, 99);
 556         assertEquals(new IndexRange(4, 19), textInput.getSelection());
 557     }
 558 
 559     @Test public void selectionCannotBeSetToBeOutOfRange2() {
 560         textInput.setText("The quick brown fox");
 561         textInput.selectRange(44, 99);
 562         assertEquals(new IndexRange(19, 19), textInput.getSelection());
 563     }
 564 
 565 //    @Test public void selectionCanBeBound() {
 566 //        ObjectProperty<IndexRange> other = new SimpleObjectProperty<IndexRange>(new IndexRange(4, 9));
 567 //        textInput.selectionProperty().bind(other);
 568 //        assertEquals(new IndexRange(4, 9), textInput.getSelection());
 569 //        other.set(new IndexRange(10, 19));
 570 //        assertEquals(new IndexRange(10, 19), textInput.getSelection());
 571 //    }
 572 
 573     @Test public void selectionChangeEventsHappen() {
 574         final boolean[] passed = new boolean[] { false };
 575         textInput.selectionProperty().addListener(observable -> {
 576             passed[0] = true;
 577         });
 578         textInput.selectRange(0, 3);
 579         assertTrue(passed[0]);
 580     }
 581 
 582 //    @Test public void selectionChangeEventsHappenWhenBound() {
 583 //        final boolean[] passed = new boolean[] { false };
 584 //        ObjectProperty<IndexRange> other = new SimpleObjectProperty<IndexRange>(new IndexRange(0, 5));
 585 //        textInput.selectionProperty().addListener(new InvalidationListener() {
 586 //            @Override public void invalidated(Observable observable) {
 587 //                passed[0] = true;
 588 //            }
 589 //        });
 590 //        textInput.selectionProperty().bind(other);
 591 //        assertTrue(passed[0]);
 592 //    }
 593 
 594 //    @Test public void selectionChangeEventsHappenWhenBound2() {
 595 //        final boolean[] passed = new boolean[] { false };
 596 //        ObjectProperty<IndexRange> other = new SimpleObjectProperty<IndexRange>(new IndexRange(0, 5));
 597 //        textInput.selectionProperty().bind(other);
 598 //        textInput.selectionProperty().addListener(new InvalidationListener() {
 599 //            @Override public void invalidated(Observable observable) {
 600 //                passed[0] = true;
 601 //            }
 602 //        });
 603 //        assertFalse(passed[0]);
 604 //        other.set(new IndexRange(1, 2));
 605 //        assertTrue(passed[0]);
 606 //    }
 607 
 608     @Test public void selectionChangeEventsHappenWhenTextIsChanged() {
 609         final boolean[] passed = new boolean[] { false };
 610         StringProperty other = new SimpleStringProperty("There and back again");
 611         textInput.textProperty().bind(other);
 612         textInput.selectRange(0, 5);
 613         textInput.selectionProperty().addListener(observable -> {
 614             passed[0] = true;
 615         });
 616         other.set("Cleared!");
 617         assertTrue(passed[0]);
 618     }
 619 
 620     @Ignore
 621     @Test public void selectionCanBeNull() {
 622 
 623     }
 624 
 625     /******************************************************
 626      * Test for cut/copy/paste                            *
 627      *****************************************************/
 628 
 629     @Test public void cutRemovesSelection() {
 630         // Skip for PasswordField
 631         if (textInput instanceof PasswordField) return;
 632         textInput.setText("The quick brown fox");
 633         textInput.selectRange(4, 9);
 634         textInput.cut();
 635         assertEquals("The  brown fox", textInput.getText());
 636     }
 637 
 638     @Test public void pasteReplacesSelection() {
 639         textInput.setText("The quick brown fox");
 640         textInput.selectRange(4, 9);
 641         copy("slow");
 642         textInput.paste();
 643         assertEquals("The slow brown fox", textInput.getText());
 644     }
 645 
 646     @Test public void pasteIllegalCharacters() {
 647         textInput.setText("The quick brown fox");
 648         textInput.selectRange(19, 19);
 649         copy("" + '\0');
 650         textInput.paste();
 651         assertEquals("The quick brown fox", textInput.getText());
 652     }
 653 
 654     @Test public void pasteIllegalCharactersCaretNotAtZero() {
 655         textInput.setText("The quick brown fox");
 656         textInput.selectRange(4, 4);
 657         copy("slow" + '\0');
 658         textInput.paste();
 659         assertEquals(8, textInput.getCaretPosition());
 660         assertEquals(8, textInput.getAnchor());
 661     }
 662 
 663     @Test public void pasteIllegalCharactersSelection() {
 664         textInput.setText("The quick brown fox");
 665         textInput.selectRange(4, 9);
 666         copy("slow" + '\0');
 667         textInput.paste();
 668         assertEquals("The slow brown fox", textInput.getText());
 669     }
 670 
 671     @Test public void pasteIllegalCharactersIntoSelectionPositionsCaretCorrectly() {
 672         textInput.setText("The quick brown fox");
 673         textInput.selectRange(4, 9);
 674         copy("slow" + '\0');
 675         textInput.paste();
 676         assertEquals(8, textInput.getCaretPosition());
 677         assertEquals(8, textInput.getAnchor());
 678     }
 679 
 680     /******************************************************
 681      * Test for manipulating selection via methods        *
 682      *****************************************************/
 683 
 684     // cut ends up removing the selection, and setting anchor / caretPosition to match index
 685     @Test public void cutRemovesSelectionAndResetsAnchorAndCaretPositionToIndex() {
 686         // Skip for PasswordField
 687         if (textInput instanceof PasswordField) return;
 688         textInput.setText("The quick brown fox");
 689         textInput.selectRange(4, 9);
 690         textInput.cut();
 691         assertEquals(4, textInput.getAnchor());
 692         assertEquals(4, textInput.getCaretPosition());
 693         assertEquals(new IndexRange(4, 4), textInput.getSelection());
 694         assertEquals("", textInput.getSelectedText());
 695     }
 696 
 697     @Test public void pasteWithEmptySelection() {
 698         textInput.setText("quick brown fox");
 699         textInput.selectRange(0,0);
 700         copy("The ");
 701         textInput.paste();
 702         assertEquals(4, textInput.getAnchor());
 703         assertEquals(4, textInput.getCaretPosition());
 704         assertEquals(new IndexRange(4, 4), textInput.getSelection());
 705         assertEquals("", textInput.getSelectedText());
 706     }
 707 
 708     @Test public void pasteWithSelection() {
 709         textInput.setText("The quick brown fox");
 710         textInput.selectRange(4, 9);
 711         copy("slow");
 712         textInput.paste();
 713         assertEquals(8, textInput.getAnchor());
 714         assertEquals(8, textInput.getCaretPosition());
 715         assertEquals(new IndexRange(8, 8), textInput.getSelection());
 716         assertEquals("", textInput.getSelectedText());
 717     }
 718 
 719     @Test public void pasteAll() {
 720         textInput.setText("The quick brown fox");
 721         textInput.selectAll();
 722         copy("Gone");
 723         textInput.paste();
 724         assertEquals(4, textInput.getAnchor());
 725         assertEquals(4, textInput.getCaretPosition());
 726         assertEquals(new IndexRange(4, 4), textInput.getSelection());
 727         assertEquals("", textInput.getSelectedText());
 728     }
 729 
 730     @Test public void selectBackwardHasNoEffectWhenCaretPositionIsAlreadyZero() {
 731         textInput.setText("The quick brown fox");
 732         textInput.selectRange(3, 0);
 733         textInput.selectBackward();
 734         assertEquals(0, textInput.getCaretPosition());
 735         assertEquals(new IndexRange(0, 3), textInput.getSelection());
 736     }
 737 
 738     @Test public void selectBackwardMovesCaretPositionOnePlaceLeft_CaretPositionRightOfAnchor() {
 739         textInput.setText("The quick brown fox");
 740         textInput.selectRange(0, 3);
 741         textInput.selectBackward();
 742         assertEquals(2, textInput.getCaretPosition());
 743         assertEquals(new IndexRange(0, 2), textInput.getSelection());
 744     }
 745 
 746     @Test public void selectBackwardMovesCaretPositionOnePlaceLeft_CaretPositionEqualsAnchor() {
 747         textInput.setText("The quick brown fox");
 748         textInput.selectRange(3, 3);
 749         textInput.selectBackward();
 750         assertEquals(2, textInput.getCaretPosition());
 751         assertEquals(new IndexRange(2, 3), textInput.getSelection());
 752     }
 753 
 754     @Test public void selectBackwardMovesCaretPositionOnePlaceLeft_CaretPositionLeftOfAnchor() {
 755         textInput.setText("The quick brown fox");
 756         textInput.selectRange(6, 3);
 757         textInput.selectBackward();
 758         assertEquals(2, textInput.getCaretPosition());
 759         assertEquals(new IndexRange(2, 6), textInput.getSelection());
 760     }
 761 
 762     @Test public void selectForwardHasNoEffectWhenCaretPositionIsAtLength() {
 763         textInput.setText("The quick brown fox");
 764         textInput.selectRange(3, 19);
 765         textInput.selectForward();
 766         assertEquals(19, textInput.getCaretPosition());
 767         assertEquals(new IndexRange(3, 19), textInput.getSelection());
 768     }
 769 
 770     @Test public void selectForwardMovesCaretPositionOnePlaceRight_CaretPositionRightOfAnchor() {
 771         textInput.setText("The quick brown fox");
 772         textInput.selectRange(0, 3);
 773         textInput.selectForward();
 774         assertEquals(4, textInput.getCaretPosition());
 775         assertEquals(new IndexRange(0, 4), textInput.getSelection());
 776     }
 777 
 778     @Test public void selectForwardMovesCaretPositionOnePlaceRight_CaretPositionEqualsAnchor() {
 779         textInput.setText("The quick brown fox");
 780         textInput.selectRange(3, 3);
 781         textInput.selectForward();
 782         assertEquals(4, textInput.getCaretPosition());
 783         assertEquals(new IndexRange(3, 4), textInput.getSelection());
 784     }
 785 
 786     @Test public void selectForwardMovesCaretPositionOnePlaceRight_CaretPositionLeftOfAnchor() {
 787         textInput.setText("The quick brown fox");
 788         textInput.selectRange(6, 3);
 789         textInput.selectForward();
 790         assertEquals(4, textInput.getCaretPosition());
 791         assertEquals(new IndexRange(4, 6), textInput.getSelection());
 792     }
 793 
 794     @Test public void previousWordWithNoText() {
 795         textInput.previousWord();
 796         assertEquals(0, textInput.getCaretPosition());
 797         assertEquals(0, textInput.getAnchor());
 798         assertEquals(new IndexRange(0, 0), textInput.getSelection());
 799     }
 800 
 801     @Test public void previousWordWithSelection_caretPositionBeforeAnchor() {
 802         textInput.setText("The quick brown fox");
 803         textInput.selectRange(15, 10);
 804         textInput.previousWord();
 805         assertEquals(4, textInput.getCaretPosition());
 806         assertEquals(4, textInput.getAnchor());
 807         assertEquals(new IndexRange(4, 4), textInput.getSelection());
 808     }
 809 
 810     @Test public void previousWordWithSelection_caretPositionBeforeAnchor2() {
 811         textInput.setText("The quick brown fox");
 812         textInput.selectRange(12, 6);
 813         textInput.previousWord();
 814         assertEquals(4, textInput.getCaretPosition());
 815         assertEquals(4, textInput.getAnchor());
 816         assertEquals(new IndexRange(4, 4), textInput.getSelection());
 817     }
 818 
 819     @Test public void previousWordWithSelection_caretPositionAfterAnchor() {
 820         textInput.setText("The quick brown fox");
 821         textInput.selectRange(10, 15);
 822         textInput.previousWord();
 823         assertEquals(10, textInput.getCaretPosition());
 824         assertEquals(10, textInput.getAnchor());
 825         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 826     }
 827 
 828     @Test public void previousWordWithSelection_caretPositionAfterAnchor2() {
 829         textInput.setText("The quick brown fox");
 830         textInput.selectRange(6, 12);
 831         textInput.previousWord();
 832         assertEquals(10, textInput.getCaretPosition());
 833         assertEquals(10, textInput.getAnchor());
 834         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 835     }
 836 
 837     @Test public void previousWord_caretWithinAWord() {
 838         textInput.setText("The quick brown fox");
 839         textInput.positionCaret(12);
 840         textInput.previousWord();
 841         assertEquals(10, textInput.getCaretPosition());
 842         assertEquals(10, textInput.getAnchor());
 843         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 844     }
 845 
 846     @Test public void previousWord_caretAfterWord() {
 847         textInput.setText("The quick brown fox");
 848         textInput.positionCaret(15);
 849         textInput.previousWord();
 850         assertEquals(10, textInput.getCaretPosition());
 851         assertEquals(10, textInput.getAnchor());
 852         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 853     }
 854 
 855     @Test public void previousWord_caretBeforeWord() {
 856         textInput.setText("The quick brown fox");
 857         textInput.positionCaret(10);
 858         textInput.previousWord();
 859         assertEquals(4, textInput.getCaretPosition());
 860         assertEquals(4, textInput.getAnchor());
 861         assertEquals(new IndexRange(4, 4), textInput.getSelection());
 862     }
 863 
 864     @Test public void previousWord_caretWithinWhitespace() {
 865         textInput.setText("The quick  brown fox");
 866         textInput.positionCaret(10);
 867         textInput.previousWord();
 868         assertEquals(4, textInput.getCaretPosition());
 869         assertEquals(4, textInput.getAnchor());
 870         assertEquals(new IndexRange(4, 4), textInput.getSelection());
 871     }
 872 
 873     @Test public void previousWord_multipleWhitespaceInARow() {
 874         textInput.setText("The quick  brown fox");
 875         textInput.positionCaret(11);
 876         textInput.previousWord();
 877         assertEquals(4, textInput.getCaretPosition());
 878         assertEquals(4, textInput.getAnchor());
 879         assertEquals(new IndexRange(4, 4), textInput.getSelection());
 880     }
 881 
 882     @Test public void previousWord_withANumber() {
 883         textInput.setText("There are 5 cards in the hand");
 884         textInput.positionCaret(12);
 885         textInput.previousWord();
 886         assertEquals(10, textInput.getCaretPosition());
 887         assertEquals(10, textInput.getAnchor());
 888         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 889     }
 890 
 891     @Test public void previousWord_withALongNumber() {
 892         textInput.setText("There are 52 cards in the deck");
 893         textInput.positionCaret(13);
 894         textInput.previousWord();
 895         assertEquals(10, textInput.getCaretPosition());
 896         assertEquals(10, textInput.getAnchor());
 897         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 898     }
 899 
 900     @Test public void nextWordWithNoText() {
 901         textInput.nextWord();
 902         assertEquals(0, textInput.getCaretPosition());
 903         assertEquals(0, textInput.getAnchor());
 904         assertEquals(new IndexRange(0, 0), textInput.getSelection());
 905     }
 906 
 907     @Test public void nextWordWithSelection_caretPositionBeforeAnchor() {
 908         textInput.setText("The quick brown fox");
 909         textInput.selectRange(9, 4);
 910         textInput.nextWord();
 911         assertEquals(10, textInput.getCaretPosition());
 912         assertEquals(10, textInput.getAnchor());
 913         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 914     }
 915 
 916     @Test public void nextWordWithSelection_caretPositionBeforeAnchor2() {
 917         textInput.setText("The quick brown fox");
 918         textInput.selectRange(9, 2);
 919         textInput.nextWord();
 920         assertEquals(4, textInput.getCaretPosition());
 921         assertEquals(4, textInput.getAnchor());
 922         assertEquals(new IndexRange(4, 4), textInput.getSelection());
 923     }
 924 
 925     @Test public void nextWordWithSelection_caretPositionAfterAnchor() {
 926         textInput.setText("The quick brown fox");
 927         textInput.selectRange(4, 9);
 928         textInput.nextWord();
 929         assertEquals(10, textInput.getCaretPosition());
 930         assertEquals(10, textInput.getAnchor());
 931         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 932     }
 933 
 934     @Test public void nextWordWithSelection_caretPositionAfterAnchor2() {
 935         textInput.setText("The quick brown fox");
 936         textInput.selectRange(5, 11);
 937         textInput.nextWord();
 938         assertEquals(16, textInput.getCaretPosition());
 939         assertEquals(16, textInput.getAnchor());
 940         assertEquals(new IndexRange(16, 16), textInput.getSelection());
 941     }
 942 
 943     @Test public void nextWord_caretWithinAWord() {
 944         textInput.setText("The quick brown fox");
 945         textInput.positionCaret(6);
 946         textInput.nextWord();
 947         assertEquals(10, textInput.getCaretPosition());
 948         assertEquals(10, textInput.getAnchor());
 949         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 950     }
 951 
 952     @Test public void nextWord_caretAfterWord() {
 953         textInput.setText("The quick brown fox");
 954         textInput.positionCaret(9);
 955         textInput.nextWord();
 956         assertEquals(10, textInput.getCaretPosition());
 957         assertEquals(10, textInput.getAnchor());
 958         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 959     }
 960 
 961     @Test public void nextWord_caretBeforeWord() {
 962         textInput.setText("The quick brown fox");
 963         textInput.positionCaret(4);
 964         textInput.nextWord();
 965         assertEquals(10, textInput.getCaretPosition());
 966         assertEquals(10, textInput.getAnchor());
 967         assertEquals(new IndexRange(10, 10), textInput.getSelection());
 968     }
 969 
 970     @Test public void nextWord_caretWithinWhitespace() {
 971         textInput.setText("The quick  brown fox");
 972         textInput.positionCaret(10);
 973         textInput.nextWord();
 974         assertEquals(11, textInput.getCaretPosition());
 975         assertEquals(11, textInput.getAnchor());
 976         assertEquals(new IndexRange(11, 11), textInput.getSelection());
 977     }
 978 
 979     @Test public void nextWord_multipleWhitespaceInARow() {
 980         textInput.setText("The quick  brown fox");
 981         textInput.positionCaret(9);
 982         textInput.nextWord();
 983         assertEquals(11, textInput.getCaretPosition());
 984         assertEquals(11, textInput.getAnchor());
 985         assertEquals(new IndexRange(11, 11), textInput.getSelection());
 986     }
 987 
 988     @Test public void nextWord_toTheEnd() {
 989         textInput.setText("The quick brown fox");
 990         textInput.positionCaret(16);
 991         textInput.nextWord();
 992         assertEquals(19, textInput.getCaretPosition());
 993         assertEquals(19, textInput.getAnchor());
 994         assertEquals(new IndexRange(19, 19), textInput.getSelection());
 995     }
 996 
 997     @Test public void nextWord_withANumber() {
 998         textInput.setText("There are 5 cards in the hand");
 999         textInput.positionCaret(6);
1000         textInput.nextWord();
1001         assertEquals(10, textInput.getCaretPosition());
1002         assertEquals(10, textInput.getAnchor());
1003         assertEquals(new IndexRange(10, 10), textInput.getSelection());
1004     }
1005 
1006     @Test public void nextWord_withALongNumber() {
1007         textInput.setText("There are 52 cards in the deck");
1008         textInput.positionCaret(10);
1009         textInput.nextWord();
1010         assertEquals(13, textInput.getCaretPosition());
1011         assertEquals(13, textInput.getAnchor());
1012         assertEquals(new IndexRange(13, 13), textInput.getSelection());
1013     }
1014 
1015     @Test public void endOfNextWordWithNoText() {
1016         textInput.endOfNextWord();
1017         assertEquals(0, textInput.getCaretPosition());
1018         assertEquals(0, textInput.getAnchor());
1019         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1020     }
1021 
1022     @Test public void endOfNextWordWithSelection_caretPositionBeforeAnchor() {
1023         textInput.setText("The quick brown fox");
1024         textInput.selectRange(9, 4);
1025         textInput.endOfNextWord();
1026         assertEquals(9, textInput.getCaretPosition());
1027         assertEquals(9, textInput.getAnchor());
1028         assertEquals(new IndexRange(9, 9), textInput.getSelection());
1029     }
1030 
1031     @Test public void endOfNextWordWithSelection_caretPositionBeforeAnchor2() {
1032         textInput.setText("The quick brown fox");
1033         textInput.selectRange(9, 2);
1034         textInput.endOfNextWord();
1035         assertEquals(3, textInput.getCaretPosition());
1036         assertEquals(3, textInput.getAnchor());
1037         assertEquals(new IndexRange(3, 3), textInput.getSelection());
1038     }
1039 
1040     @Test public void endOfNextWordWithSelection_caretPositionAfterAnchor() {
1041         textInput.setText("The quick brown fox");
1042         textInput.selectRange(4, 9);
1043         textInput.endOfNextWord();
1044         assertEquals(15, textInput.getCaretPosition());
1045         assertEquals(15, textInput.getAnchor());
1046         assertEquals(new IndexRange(15, 15), textInput.getSelection());
1047     }
1048 
1049     @Test public void endOfNextWordWithSelection_caretPositionAfterAnchor2() {
1050         textInput.setText("The quick brown fox");
1051         textInput.selectRange(5, 11);
1052         textInput.endOfNextWord();
1053         assertEquals(15, textInput.getCaretPosition());
1054         assertEquals(15, textInput.getAnchor());
1055         assertEquals(new IndexRange(15, 15), textInput.getSelection());
1056     }
1057 
1058     @Test public void endOfNextWord_caretWithinAWord() {
1059         textInput.setText("The quick brown fox");
1060         textInput.positionCaret(6);
1061         textInput.endOfNextWord();
1062         assertEquals(9, textInput.getCaretPosition());
1063         assertEquals(9, textInput.getAnchor());
1064         assertEquals(new IndexRange(9, 9), textInput.getSelection());
1065     }
1066 
1067     @Test public void endOfNextWord_caretAfterWord() {
1068         textInput.setText("The quick brown fox");
1069         textInput.positionCaret(9);
1070         textInput.endOfNextWord();
1071         assertEquals(15, textInput.getCaretPosition());
1072         assertEquals(15, textInput.getAnchor());
1073         assertEquals(new IndexRange(15, 15), textInput.getSelection());
1074     }
1075 
1076     @Test public void endOfNextWord_caretBeforeWord() {
1077         textInput.setText("The quick brown fox");
1078         textInput.positionCaret(4);
1079         textInput.endOfNextWord();
1080         assertEquals(9, textInput.getCaretPosition());
1081         assertEquals(9, textInput.getAnchor());
1082         assertEquals(new IndexRange(9, 9), textInput.getSelection());
1083     }
1084 
1085     @Test public void endOfNextWord_caretWithinWhitespace() {
1086         textInput.setText("The quick  brown fox");
1087         textInput.positionCaret(10);
1088         textInput.endOfNextWord();
1089         assertEquals(16, textInput.getCaretPosition());
1090         assertEquals(16, textInput.getAnchor());
1091         assertEquals(new IndexRange(16, 16), textInput.getSelection());
1092     }
1093 
1094     @Test public void endOfNextWord_multipleWhitespaceInARow() {
1095         textInput.setText("The quick  brown fox");
1096         textInput.positionCaret(9);
1097         textInput.endOfNextWord();
1098         assertEquals(16, textInput.getCaretPosition());
1099         assertEquals(16, textInput.getAnchor());
1100         assertEquals(new IndexRange(16, 16), textInput.getSelection());
1101     }
1102 
1103     @Test public void endOfNextWord_withANumber() {
1104         textInput.setText("There are 5 cards in the hand");
1105         textInput.positionCaret(6);
1106         textInput.endOfNextWord();
1107         assertEquals(9, textInput.getCaretPosition());
1108         assertEquals(9, textInput.getAnchor());
1109         assertEquals(new IndexRange(9, 9), textInput.getSelection());
1110     }
1111 
1112     @Test public void endOfNextWord_withANumber_CaretOnANumber() {
1113         textInput.setText("There are 5 cards in the hand");
1114         textInput.positionCaret(10);
1115         textInput.endOfNextWord();
1116         assertEquals(11, textInput.getCaretPosition());
1117         assertEquals(11, textInput.getAnchor());
1118         assertEquals(new IndexRange(11, 11), textInput.getSelection());
1119     }
1120 
1121     @Test public void endOfNextWord_withALongNumber_CaretOnANumber() {
1122         textInput.setText("There are 52 cards in the deck");
1123         textInput.positionCaret(10);
1124         textInput.endOfNextWord();
1125         assertEquals(12, textInput.getCaretPosition());
1126         assertEquals(12, textInput.getAnchor());
1127         assertEquals(new IndexRange(12, 12), textInput.getSelection());
1128     }
1129 
1130     @Test public void selectPreviousWordWithNoText() {
1131         textInput.selectPreviousWord();
1132         assertEquals(0, textInput.getCaretPosition());
1133         assertEquals(0, textInput.getAnchor());
1134         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1135     }
1136 
1137     @Test public void selectPreviousWordWithSelection_caretPositionBeforeAnchor() {
1138         textInput.setText("The quick brown fox");
1139         textInput.selectRange(15, 10);
1140         textInput.selectPreviousWord();
1141         assertEquals(4, textInput.getCaretPosition());
1142         assertEquals(15, textInput.getAnchor());
1143         assertEquals(new IndexRange(4, 15), textInput.getSelection());
1144     }
1145 
1146     @Test public void selectPreviousWordWithSelection_caretPositionAfterAnchor() {
1147         textInput.setText("The quick brown fox");
1148         textInput.selectRange(10, 15);
1149         textInput.selectPreviousWord();
1150         assertEquals(10, textInput.getCaretPosition());
1151         assertEquals(10, textInput.getAnchor());
1152         assertEquals(new IndexRange(10, 10), textInput.getSelection());
1153     }
1154 
1155     @Test public void selectPreviousWordWithSelection_caretPositionAfterAnchor2() {
1156         textInput.setText("The quick brown fox");
1157         textInput.selectRange(11, 15);
1158         textInput.selectPreviousWord();
1159         assertEquals(10, textInput.getCaretPosition());
1160         assertEquals(11, textInput.getAnchor());
1161         assertEquals(new IndexRange(10, 11), textInput.getSelection());
1162     }
1163 
1164     @Test public void selectPreviousWord_caretWithinAWord() {
1165         textInput.setText("The quick brown fox");
1166         textInput.positionCaret(12);
1167         textInput.selectPreviousWord();
1168         assertEquals(10, textInput.getCaretPosition());
1169         assertEquals(12, textInput.getAnchor());
1170         assertEquals(new IndexRange(10, 12), textInput.getSelection());
1171     }
1172 
1173     @Test public void selectPreviousWord_caretAfterWord() {
1174         textInput.setText("The quick brown fox");
1175         textInput.positionCaret(15);
1176         textInput.selectPreviousWord();
1177         assertEquals(10, textInput.getCaretPosition());
1178         assertEquals(15, textInput.getAnchor());
1179         assertEquals(new IndexRange(10, 15), textInput.getSelection());
1180     }
1181 
1182     @Test public void selectPreviousWord_caretBeforeWord() {
1183         textInput.setText("The quick brown fox");
1184         textInput.positionCaret(10);
1185         textInput.selectPreviousWord();
1186         assertEquals(4, textInput.getCaretPosition());
1187         assertEquals(10, textInput.getAnchor());
1188         assertEquals(new IndexRange(4, 10), textInput.getSelection());
1189     }
1190 
1191     @Test public void selectPreviousWord_caretWithinWhitespace() {
1192         textInput.setText("The quick  brown fox");
1193         textInput.positionCaret(10);
1194         textInput.selectPreviousWord();
1195         assertEquals(4, textInput.getCaretPosition());
1196         assertEquals(10, textInput.getAnchor());
1197         assertEquals(new IndexRange(4, 10), textInput.getSelection());
1198     }
1199 
1200     @Test public void selectPreviousWord_multipleWhitespaceInARow() {
1201         textInput.setText("The quick  brown fox");
1202         textInput.positionCaret(11);
1203         textInput.selectPreviousWord();
1204         assertEquals(4, textInput.getCaretPosition());
1205         assertEquals(11, textInput.getAnchor());
1206         assertEquals(new IndexRange(4, 11), textInput.getSelection());
1207     }
1208 
1209     @Test public void selectNextWordWithNoText() {
1210         textInput.selectNextWord();
1211         assertEquals(0, textInput.getCaretPosition());
1212         assertEquals(0, textInput.getAnchor());
1213         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1214     }
1215 
1216     @Test public void selectNextWordWithSelection_caretPositionBeforeAnchor() {
1217         textInput.setText("The quick brown fox");
1218         textInput.selectRange(9, 4);
1219         textInput.selectNextWord();
1220         assertEquals(10, textInput.getCaretPosition());
1221         assertEquals(9, textInput.getAnchor());
1222         assertEquals(new IndexRange(9, 10), textInput.getSelection());
1223     }
1224 
1225     @Test public void selectNextWordWithSelection_caretPositionBeforeAnchor2() {
1226         textInput.setText("The quick brown fox");
1227         textInput.selectRange(9, 2);
1228         textInput.selectNextWord();
1229         assertEquals(4, textInput.getCaretPosition());
1230         assertEquals(9, textInput.getAnchor());
1231         assertEquals(new IndexRange(4, 9), textInput.getSelection());
1232     }
1233 
1234     @Test public void selectNextWordWithSelection_caretPositionAfterAnchor() {
1235         textInput.setText("The quick brown fox");
1236         textInput.selectRange(4, 9);
1237         textInput.selectNextWord();
1238         assertEquals(10, textInput.getCaretPosition());
1239         assertEquals(4, textInput.getAnchor());
1240         assertEquals(new IndexRange(4, 10), textInput.getSelection());
1241     }
1242 
1243     @Test public void selectNextWordWithSelection_caretPositionAfterAnchor2() {
1244         textInput.setText("The quick brown fox");
1245         textInput.selectRange(5, 11);
1246         textInput.selectNextWord();
1247         assertEquals(16, textInput.getCaretPosition());
1248         assertEquals(5, textInput.getAnchor());
1249         assertEquals(new IndexRange(5, 16), textInput.getSelection());
1250     }
1251 
1252     @Test public void selectNextWord_caretWithinAWord() {
1253         textInput.setText("The quick brown fox");
1254         textInput.positionCaret(6);
1255         textInput.selectNextWord();
1256         assertEquals(10, textInput.getCaretPosition());
1257         assertEquals(6, textInput.getAnchor());
1258         assertEquals(new IndexRange(6, 10), textInput.getSelection());
1259     }
1260 
1261     @Test public void selectNextWord_caretAfterWord() {
1262         textInput.setText("The quick brown fox");
1263         textInput.positionCaret(9);
1264         textInput.selectNextWord();
1265         assertEquals(10, textInput.getCaretPosition());
1266         assertEquals(9, textInput.getAnchor());
1267         assertEquals(new IndexRange(9, 10), textInput.getSelection());
1268     }
1269 
1270     @Test public void selectNextWord_caretBeforeWord() {
1271         textInput.setText("The quick brown fox");
1272         textInput.positionCaret(4);
1273         textInput.selectNextWord();
1274         assertEquals(10, textInput.getCaretPosition());
1275         assertEquals(4, textInput.getAnchor());
1276         assertEquals(new IndexRange(4, 10), textInput.getSelection());
1277     }
1278 
1279     @Test public void selectNextWord_caretWithinWhitespace() {
1280         textInput.setText("The quick  brown fox");
1281         textInput.positionCaret(10);
1282         textInput.selectNextWord();
1283         assertEquals(11, textInput.getCaretPosition());
1284         assertEquals(10, textInput.getAnchor());
1285         assertEquals(new IndexRange(10, 11), textInput.getSelection());
1286     }
1287 
1288     @Test public void selectNextWord_multipleWhitespaceInARow() {
1289         textInput.setText("The quick  brown fox");
1290         textInput.positionCaret(9);
1291         textInput.selectNextWord();
1292         assertEquals(11, textInput.getCaretPosition());
1293         assertEquals(9, textInput.getAnchor());
1294         assertEquals(new IndexRange(9, 11), textInput.getSelection());
1295     }
1296 
1297     @Test public void selectNextWord_toTheEnd() {
1298         textInput.setText("The quick brown fox");
1299         textInput.positionCaret(16);
1300         textInput.selectNextWord();
1301         assertEquals(19, textInput.getCaretPosition());
1302         assertEquals(16, textInput.getAnchor());
1303         assertEquals(new IndexRange(16, 19), textInput.getSelection());
1304     }
1305 
1306     @Test public void selectEndOfNextWordWithNoText() {
1307         textInput.selectEndOfNextWord();
1308         assertEquals(0, textInput.getCaretPosition());
1309         assertEquals(0, textInput.getAnchor());
1310         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1311     }
1312 
1313     @Test public void selectEndOfNextWordWithSelection_caretPositionBeforeAnchor() {
1314         textInput.setText("The quick brown fox");
1315         textInput.selectRange(9, 4);
1316         textInput.selectEndOfNextWord();
1317         assertEquals(9, textInput.getCaretPosition());
1318         assertEquals(9, textInput.getAnchor());
1319         assertEquals(new IndexRange(9, 9), textInput.getSelection());
1320     }
1321 
1322     @Test public void selectEndOfNextWordWithSelection_caretPositionBeforeAnchor2() {
1323         textInput.setText("The quick brown fox");
1324         textInput.selectRange(9, 2);
1325         textInput.selectEndOfNextWord();
1326         assertEquals(3, textInput.getCaretPosition());
1327         assertEquals(9, textInput.getAnchor());
1328         assertEquals(new IndexRange(3, 9), textInput.getSelection());
1329     }
1330 
1331     @Test public void selectEndOfNextWordWithSelection_caretPositionAfterAnchor() {
1332         textInput.setText("The quick brown fox");
1333         textInput.selectRange(4, 9);
1334         textInput.selectEndOfNextWord();
1335         assertEquals(15, textInput.getCaretPosition());
1336         assertEquals(4, textInput.getAnchor());
1337         assertEquals(new IndexRange(4, 15), textInput.getSelection());
1338     }
1339 
1340     @Test public void selectEndOfNextWordWithSelection_caretPositionAfterAnchor2() {
1341         textInput.setText("The quick brown fox");
1342         textInput.selectRange(5, 11);
1343         textInput.selectEndOfNextWord();
1344         assertEquals(15, textInput.getCaretPosition());
1345         assertEquals(5, textInput.getAnchor());
1346         assertEquals(new IndexRange(5, 15), textInput.getSelection());
1347     }
1348 
1349     @Test public void selectEndOfNextWord_caretWithinAWord() {
1350         textInput.setText("The quick brown fox");
1351         textInput.positionCaret(6);
1352         textInput.selectEndOfNextWord();
1353         assertEquals(9, textInput.getCaretPosition());
1354         assertEquals(6, textInput.getAnchor());
1355         assertEquals(new IndexRange(6, 9), textInput.getSelection());
1356     }
1357 
1358     @Test public void selectEndOfNextWord_caretAfterWord() {
1359         textInput.setText("The quick brown fox");
1360         textInput.positionCaret(9);
1361         textInput.selectEndOfNextWord();
1362         assertEquals(15, textInput.getCaretPosition());
1363         assertEquals(9, textInput.getAnchor());
1364         assertEquals(new IndexRange(9, 15), textInput.getSelection());
1365     }
1366 
1367     @Test public void selectEndOfNextWord_caretBeforeWord() {
1368         textInput.setText("The quick brown fox");
1369         textInput.positionCaret(4);
1370         textInput.selectEndOfNextWord();
1371         assertEquals(9, textInput.getCaretPosition());
1372         assertEquals(4, textInput.getAnchor());
1373         assertEquals(new IndexRange(4, 9), textInput.getSelection());
1374     }
1375 
1376     @Test public void selectEndOfNextWord_caretWithinWhitespace() {
1377         textInput.setText("The quick  brown fox");
1378         textInput.positionCaret(10);
1379         textInput.selectEndOfNextWord();
1380         assertEquals(16, textInput.getCaretPosition());
1381         assertEquals(10, textInput.getAnchor());
1382         assertEquals(new IndexRange(10, 16), textInput.getSelection());
1383     }
1384 
1385     @Test public void selectEndOfNextWord_multipleWhitespaceInARow() {
1386         textInput.setText("The quick  brown fox");
1387         textInput.positionCaret(9);
1388         textInput.selectEndOfNextWord();
1389         assertEquals(16, textInput.getCaretPosition());
1390         assertEquals(9, textInput.getAnchor());
1391         assertEquals(new IndexRange(9, 16), textInput.getSelection());
1392     }
1393 
1394     @Test public void selectAllWithNoText() {
1395         textInput.setText("");
1396         textInput.selectAll();
1397         assertEquals(0, textInput.getCaretPosition());
1398         assertEquals(0, textInput.getAnchor());
1399         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1400     }
1401 
1402     @Test public void selectAllWithText_caretPositionIsAlwaysAtTheEnd() {
1403         textInput.setText("The quick brown fox");
1404         textInput.selectAll();
1405         assertEquals(19, textInput.getCaretPosition());
1406         assertEquals(0, textInput.getAnchor());
1407         assertEquals(new IndexRange(0, 19), textInput.getSelection());
1408     }
1409 
1410     @Test public void homeClearsSelection() {
1411         textInput.setText("The quick brown fox");
1412         textInput.selectRange(4, 9);
1413         textInput.home();
1414         assertEquals(0, textInput.getCaretPosition());
1415         assertEquals(0, textInput.getAnchor());
1416         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1417     }
1418 
1419     @Test public void endClearsSelection() {
1420         textInput.setText("The quick brown fox");
1421         textInput.selectRange(4, 9);
1422         textInput.end();
1423         assertEquals(19, textInput.getCaretPosition());
1424         assertEquals(19, textInput.getAnchor());
1425         assertEquals(new IndexRange(19, 19), textInput.getSelection());
1426     }
1427 
1428     @Test public void selectHomeHasNoEffectWhenCaretPositionIsAtZero() {
1429         textInput.setText("The quick brown fox");
1430         textInput.selectRange(3, 0);
1431         textInput.selectHome();
1432         assertEquals(0, textInput.getCaretPosition());
1433         assertEquals(3, textInput.getAnchor());
1434         assertEquals(new IndexRange(0, 3), textInput.getSelection());
1435     }
1436 
1437     @Test public void selectHomeMovesCaretPositionToZero_CaretPositionRightOfAnchor() {
1438         textInput.setText("The quick brown fox");
1439         textInput.selectRange(4, 9);
1440         textInput.selectHome();
1441         assertEquals(0, textInput.getCaretPosition());
1442         assertEquals(4, textInput.getAnchor());
1443         assertEquals(new IndexRange(0, 4), textInput.getSelection());
1444     }
1445 
1446     @Test public void selectHomeMovesCaretPositionToZero_CaretPositionEqualsAnchor() {
1447         textInput.setText("The quick brown fox");
1448         textInput.selectRange(3, 3);
1449         textInput.selectHome();
1450         assertEquals(0, textInput.getCaretPosition());
1451         assertEquals(3, textInput.getAnchor());
1452         assertEquals(new IndexRange(0, 3), textInput.getSelection());
1453     }
1454 
1455     @Test public void selectHomeMovesCaretPositionToZero_CaretPositionLeftOfAnchor() {
1456         textInput.setText("The quick brown fox");
1457         textInput.selectRange(6, 3);
1458         textInput.selectHome();
1459         assertEquals(0, textInput.getCaretPosition());
1460         assertEquals(6, textInput.getAnchor());
1461         assertEquals(new IndexRange(0, 6), textInput.getSelection());
1462     }
1463 
1464     @Test public void selectEndHasNoEffectWhenCaretPositionIsAtLength() {
1465         textInput.setText("The quick brown fox");
1466         textInput.selectRange(3, 19);
1467         textInput.selectEnd();
1468         assertEquals(19, textInput.getCaretPosition());
1469         assertEquals(3, textInput.getAnchor());
1470         assertEquals(new IndexRange(3, 19), textInput.getSelection());
1471     }
1472 
1473     @Test public void selectEndMovesCaretPositionToLength_CaretPositionRightOfAnchor() {
1474         textInput.setText("The quick brown fox");
1475         textInput.selectRange(0, 3);
1476         textInput.selectEnd();
1477         assertEquals(19, textInput.getCaretPosition());
1478         assertEquals(0, textInput.getAnchor());
1479         assertEquals(new IndexRange(0, 19), textInput.getSelection());
1480     }
1481 
1482     @Test public void selectEndMovesCaretPositionToLength_CaretPositionEqualsAnchor() {
1483         textInput.setText("The quick brown fox");
1484         textInput.selectRange(3, 3);
1485         textInput.selectEnd();
1486         assertEquals(19, textInput.getCaretPosition());
1487         assertEquals(3, textInput.getAnchor());
1488         assertEquals(new IndexRange(3, 19), textInput.getSelection());
1489     }
1490 
1491     @Test public void selectEndMovesCaretPositionToLength_CaretPositionLeftOfAnchor() {
1492         textInput.setText("The quick brown fox");
1493         textInput.selectRange(6, 3);
1494         textInput.selectEnd();
1495         assertEquals(19, textInput.getCaretPosition());
1496         assertEquals(6, textInput.getAnchor());
1497         assertEquals(new IndexRange(6, 19), textInput.getSelection());
1498     }
1499 
1500     @Test public void deletePreviousCharDeletesOnlySelectedText_anchorLessThanCaretPosition() {
1501         textInput.setText("The quick brown fox");
1502         textInput.selectRange(4, 10);
1503         textInput.deletePreviousChar();
1504         assertEquals("The brown fox", textInput.getText());
1505         assertEquals(4, textInput.getCaretPosition());
1506         assertEquals(4, textInput.getAnchor());
1507         assertEquals(new IndexRange(4, 4), textInput.getSelection());
1508     }
1509 
1510     @Test public void deletePreviousCharDeletesOnlySelectedText_caretPositionLessThanAnchor() {
1511         textInput.setText("The quick brown fox");
1512         textInput.selectRange(10, 4);
1513         textInput.deletePreviousChar();
1514         assertEquals("The brown fox", textInput.getText());
1515         assertEquals(4, textInput.getCaretPosition());
1516         assertEquals(4, textInput.getAnchor());
1517         assertEquals(new IndexRange(4, 4), textInput.getSelection());
1518     }
1519 
1520     @Test public void deletePreviousCharDeletesPreviousCharWhenCaretPositionEqualsAnchor() {
1521         textInput.setText("The quick brown fox");
1522         textInput.selectRange(10, 10);
1523         textInput.deletePreviousChar();
1524         assertEquals("The quickbrown fox", textInput.getText());
1525         assertEquals(9, textInput.getCaretPosition());
1526         assertEquals(9, textInput.getAnchor());
1527         assertEquals(new IndexRange(9, 9), textInput.getSelection());
1528     }
1529 
1530     @Test public void deletePreviousCharDoesNothingWhenSelectionIs0_0() {
1531         textInput.setText("The quick brown fox");
1532         textInput.selectRange(0, 0);
1533         textInput.deletePreviousChar();
1534         assertEquals("The quick brown fox", textInput.getText());
1535         assertEquals(0, textInput.getCaretPosition());
1536         assertEquals(0, textInput.getAnchor());
1537         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1538     }
1539 
1540     @Test public void deleteNextCharDeletesOnlySelectedText_anchorLessThanCaretPosition() {
1541         textInput.setText("The quick brown fox");
1542         textInput.selectRange(4, 10);
1543         textInput.deleteNextChar();
1544         assertEquals("The brown fox", textInput.getText());
1545         assertEquals(4, textInput.getCaretPosition());
1546         assertEquals(4, textInput.getAnchor());
1547         assertEquals(new IndexRange(4, 4), textInput.getSelection());
1548     }
1549 
1550     @Test public void deleteNextCharDeletesOnlySelectedText_caretPositionLessThanAnchor() {
1551         textInput.setText("The quick brown fox");
1552         textInput.selectRange(10, 4);
1553         textInput.deleteNextChar();
1554         assertEquals("The brown fox", textInput.getText());
1555         assertEquals(4, textInput.getCaretPosition());
1556         assertEquals(4, textInput.getAnchor());
1557         assertEquals(new IndexRange(4, 4), textInput.getSelection());
1558     }
1559 
1560     @Test public void deleteNextCharDeletesNextCharWhenCaretPositionEqualsAnchor() {
1561         textInput.setText("The quick brown fox");
1562         textInput.selectRange(10, 10);
1563         textInput.deleteNextChar();
1564         assertEquals("The quick rown fox", textInput.getText());
1565         assertEquals(10, textInput.getCaretPosition());
1566         assertEquals(10, textInput.getAnchor());
1567         assertEquals(new IndexRange(10, 10), textInput.getSelection());
1568     }
1569 
1570     @Test public void deleteNextCharDoesNothingWhenSelectionIsEmptyAtEnd() {
1571         textInput.setText("The quick brown fox");
1572         textInput.selectRange(19, 19);
1573         textInput.deleteNextChar();
1574         assertEquals("The quick brown fox", textInput.getText());
1575         assertEquals(19, textInput.getCaretPosition());
1576         assertEquals(19, textInput.getAnchor());
1577         assertEquals(new IndexRange(19, 19), textInput.getSelection());
1578     }
1579 
1580     @Test public void forwardSkipsSelection() {
1581         textInput.setText("The quick brown fox");
1582         textInput.selectRange(4, 9);
1583         textInput.forward();
1584         assertEquals(9, textInput.getCaretPosition());
1585         assertEquals(9, textInput.getAnchor());
1586         assertEquals(new IndexRange(9, 9), textInput.getSelection());
1587     }
1588 
1589     @Test public void forwardSkipsSelection2() {
1590         textInput.setText("The quick brown fox");
1591         textInput.selectRange(9, 4);
1592         textInput.forward();
1593         assertEquals(9, textInput.getCaretPosition());
1594         assertEquals(9, textInput.getAnchor());
1595         assertEquals(new IndexRange(9, 9), textInput.getSelection());
1596     }
1597 
1598     @Test public void forwardMovesForwardWhenNotAtEnd() {
1599         textInput.setText("The quick brown fox");
1600         textInput.selectRange(0, 0);
1601         textInput.forward();
1602         assertEquals(1, textInput.getCaretPosition());
1603         assertEquals(1, textInput.getAnchor());
1604         assertEquals(new IndexRange(1, 1), textInput.getSelection());
1605     }
1606 
1607     @Test public void forwardDoesNothingWhenAtEnd() {
1608         textInput.setText("The quick brown fox");
1609         textInput.selectRange(19, 19);
1610         textInput.forward();
1611         assertEquals(19, textInput.getCaretPosition());
1612         assertEquals(19, textInput.getAnchor());
1613         assertEquals(new IndexRange(19, 19), textInput.getSelection());
1614     }
1615 
1616     @Test public void backwardSkipsSelection() {
1617         textInput.setText("The quick brown fox");
1618         textInput.selectRange(4, 9);
1619         textInput.backward();
1620         assertEquals(4, textInput.getCaretPosition());
1621         assertEquals(4, textInput.getAnchor());
1622         assertEquals(new IndexRange(4, 4), textInput.getSelection());
1623     }
1624 
1625     @Test public void backwardSkipsSelection2() {
1626         textInput.setText("The quick brown fox");
1627         textInput.selectRange(9, 4);
1628         textInput.backward();
1629         assertEquals(4, textInput.getCaretPosition());
1630         assertEquals(4, textInput.getAnchor());
1631         assertEquals(new IndexRange(4, 4), textInput.getSelection());
1632     }
1633 
1634     @Test public void backwardMovesBackwardWhenNotAtStart() {
1635         textInput.setText("The quick brown fox");
1636         textInput.positionCaret(14);
1637         textInput.backward();
1638         assertEquals(13, textInput.getCaretPosition());
1639         assertEquals(13, textInput.getAnchor());
1640         assertEquals(new IndexRange(13, 13), textInput.getSelection());
1641     }
1642 
1643     @Test public void backwardDoesNothingWhenAtStart() {
1644         textInput.setText("The quick brown fox");
1645         textInput.selectRange(0, 0);
1646         textInput.backward();
1647         assertEquals(0, textInput.getCaretPosition());
1648         assertEquals(0, textInput.getAnchor());
1649         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1650     }
1651 
1652     @Test public void positionCaretAtStart() {
1653         textInput.setText("The quick brown fox");
1654         textInput.positionCaret(0);
1655         assertEquals(0, textInput.getCaretPosition());
1656         assertEquals(0, textInput.getAnchor());
1657         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1658     }
1659 
1660     @Test public void positionCaretInMiddle() {
1661         textInput.setText("The quick brown fox");
1662         textInput.positionCaret(10);
1663         assertEquals(10, textInput.getCaretPosition());
1664         assertEquals(10, textInput.getAnchor());
1665         assertEquals(new IndexRange(10, 10), textInput.getSelection());
1666     }
1667 
1668     @Test public void positionCaretAtEnd() {
1669         textInput.setText("The quick brown fox");
1670         textInput.positionCaret(19);
1671         assertEquals(19, textInput.getCaretPosition());
1672         assertEquals(19, textInput.getAnchor());
1673         assertEquals(new IndexRange(19, 19), textInput.getSelection());
1674     }
1675 
1676     @Test public void positionCaretBeyondStartClamps() {
1677         textInput.setText("The quick brown fox");
1678         textInput.positionCaret(-10);
1679         assertEquals(0, textInput.getCaretPosition());
1680         assertEquals(0, textInput.getAnchor());
1681         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1682     }
1683 
1684     @Test public void positionCaretBeyondEndClamps() {
1685         textInput.setText("The quick brown fox");
1686         textInput.positionCaret(1000);
1687         assertEquals(19, textInput.getCaretPosition());
1688         assertEquals(19, textInput.getAnchor());
1689         assertEquals(new IndexRange(19, 19), textInput.getSelection());
1690     }
1691 
1692     @Test public void selectPositionCaretWhenAnchorAndCaretAreBothZero() {
1693         textInput.setText("The quick brown fox");
1694         textInput.selectRange(0, 0);
1695         textInput.selectPositionCaret(10);
1696         assertEquals(10, textInput.getCaretPosition());
1697         assertEquals(0, textInput.getAnchor());
1698         assertEquals(new IndexRange(0, 10), textInput.getSelection());
1699     }
1700 
1701     @Test public void selectPositionCaret_anchorLessThanCaretPosition() {
1702         textInput.setText("The quick brown fox");
1703         textInput.selectRange(4, 10);
1704         textInput.selectPositionCaret(1);
1705         assertEquals(1, textInput.getCaretPosition());
1706         assertEquals(4, textInput.getAnchor());
1707         assertEquals(new IndexRange(1, 4), textInput.getSelection());
1708     }
1709 
1710     @Test public void selectPositionCaret_anchorLessThanCaretPosition2() {
1711         textInput.setText("The quick brown fox");
1712         textInput.selectRange(4, 10);
1713         textInput.selectPositionCaret(15);
1714         assertEquals(15, textInput.getCaretPosition());
1715         assertEquals(4, textInput.getAnchor());
1716         assertEquals(new IndexRange(4, 15), textInput.getSelection());
1717     }
1718 
1719     @Test public void selectPositionCaret_anchorLessThanCaretPosition3() {
1720         textInput.setText("The quick brown fox");
1721         textInput.selectRange(4, 10);
1722         textInput.selectPositionCaret(4);
1723         assertEquals(4, textInput.getCaretPosition());
1724         assertEquals(4, textInput.getAnchor());
1725         assertEquals(new IndexRange(4, 4), textInput.getSelection());
1726     }
1727 
1728     @Test public void selectPositionCaret_caretPositionLessThanAnchor() {
1729         textInput.setText("The quick brown fox");
1730         textInput.selectRange(10, 4);
1731         textInput.selectPositionCaret(1);
1732         assertEquals(1, textInput.getCaretPosition());
1733         assertEquals(10, textInput.getAnchor());
1734         assertEquals(new IndexRange(1, 10), textInput.getSelection());
1735     }
1736 
1737     @Test public void selectPositionCaret_caretPositionLessThanAnchor2() {
1738         textInput.setText("The quick brown fox");
1739         textInput.selectRange(10, 4);
1740         textInput.selectPositionCaret(14);
1741         assertEquals(14, textInput.getCaretPosition());
1742         assertEquals(10, textInput.getAnchor());
1743         assertEquals(new IndexRange(10, 14), textInput.getSelection());
1744     }
1745 
1746     @Test public void selectPositionCaret_caretPositionLessThanAnchor3() {
1747         textInput.setText("The quick brown fox");
1748         textInput.selectRange(10, 4);
1749         textInput.selectPositionCaret(10);
1750         assertEquals(10, textInput.getCaretPosition());
1751         assertEquals(10, textInput.getAnchor());
1752         assertEquals(new IndexRange(10, 10), textInput.getSelection());
1753     }
1754 
1755     @Test public void selectPositionCaretWhenCaretPositionEqualsAnchor() {
1756         textInput.setText("The quick brown fox");
1757         textInput.selectRange(10, 10);
1758         textInput.selectPositionCaret(4);
1759         assertEquals(4, textInput.getCaretPosition());
1760         assertEquals(10, textInput.getAnchor());
1761         assertEquals(new IndexRange(4, 10), textInput.getSelection());
1762     }
1763 
1764     @Test public void selectPositionCaretWhenCaretPositionEqualsAnchor2() {
1765         textInput.setText("The quick brown fox");
1766         textInput.selectRange(10, 10);
1767         textInput.selectPositionCaret(14);
1768         assertEquals(14, textInput.getCaretPosition());
1769         assertEquals(10, textInput.getAnchor());
1770         assertEquals(new IndexRange(10, 14), textInput.getSelection());
1771     }
1772 
1773     @Test public void extendSelectionWithNoText() {
1774         textInput.extendSelection(0);
1775         assertEquals(0, textInput.getCaretPosition());
1776         assertEquals(0, textInput.getAnchor());
1777         assertEquals(new IndexRange(0, 0), textInput.getSelection());
1778     }
1779 
1780     @Test public void extendSelectionWithOutOfRangePos() {
1781         textInput.setText("The quick brown fox");
1782         textInput.selectRange(0, 0);
1783         textInput.extendSelection(1000);
1784         assertEquals(19, textInput.getCaretPosition());
1785         assertEquals(0, textInput.getAnchor());
1786         assertEquals(new IndexRange(0, 19), textInput.getSelection());
1787     }
1788 
1789     @Test public void extendSelectionWithOutOfRangePos2() {
1790         textInput.setText("The quick brown fox");
1791         textInput.positionCaret(4);
1792         textInput.extendSelection(-19);
1793         assertEquals(0, textInput.getCaretPosition());
1794         assertEquals(4, textInput.getAnchor());
1795         assertEquals(new IndexRange(0, 4), textInput.getSelection());
1796     }
1797 
1798     @Test public void test_rt26250_caret_issue_for_thai_characters() {
1799         // Thai string containing two characters, consisting of three
1800         // codepoints each.
1801         String thaiStr = "\u0E17\u0E35\u0E48\u0E17\u0E35\u0E48";
1802         textInput.setText(thaiStr);
1803         textInput.positionCaret(0);
1804 
1805         // Step past one character
1806         textInput.forward();
1807         assertEquals(3, textInput.getCaretPosition());
1808 
1809         // Goto beginning
1810         textInput.backward();
1811         assertEquals(0, textInput.getCaretPosition());
1812 
1813         // Delete entire first character forwards
1814         textInput.deleteNextChar();
1815         assertEquals("\u0E17\u0E35\u0E48", textInput.getText());
1816 
1817         // Break up and delete remaining character backwards in three steps
1818         textInput.forward();
1819         textInput.deletePreviousChar();
1820         assertEquals("\u0E17\u0E35", textInput.getText());
1821         textInput.deletePreviousChar();
1822         assertEquals("\u0E17", textInput.getText());
1823         textInput.deletePreviousChar();
1824         assertEquals("", textInput.getText());
1825     }
1826 
1827     @Test public void test_rt40376_delete_next_when_text_is_null() {
1828         textInput.setText(null);
1829         textInput.deleteNextChar();
1830     }
1831 
1832     @Test public void test_jdk_8171229_replaceText() {
1833         textInput.setText("");
1834         assertEquals("", textInput.getText());
1835 
1836         textInput.replaceText(0, 0, "a");
1837         assertEquals("a", textInput.getText());
1838 
1839         textInput.replaceText(1, 1, "b");
1840         assertEquals("ab", textInput.getText());
1841 
1842         textInput.replaceText(2, 2, "c");
1843         assertEquals("abc", textInput.getText());
1844 
1845         textInput.replaceText(3, 3, "d");
1846         assertEquals("abcd", textInput.getText());
1847 
1848         textInput.replaceText(3, 4, "efg");
1849         assertEquals("abcefg", textInput.getText());
1850 
1851         textInput.replaceText(3, 6, "d");
1852         assertEquals("abcd", textInput.getText());
1853 
1854         textInput.replaceText(0, 4, "");
1855         assertEquals("", textInput.getText());
1856 
1857         textInput.undo();
1858         assertEquals("abcd", textInput.getText());
1859 
1860         textInput.undo();
1861         assertEquals("abcefg", textInput.getText());
1862 
1863         textInput.undo();
1864         assertEquals("abcd", textInput.getText());
1865 
1866         textInput.undo();
1867         assertEquals("", textInput.getText());
1868     }
1869 
1870     // Test for JDK-8178418
1871     @Test public void UndoRedoSpaceSequence() {
1872         Toolkit tk = (StubToolkit)Toolkit.getToolkit();
1873         StackPane root = new StackPane();
1874         Scene scene = new Scene(root);
1875         Stage stage = new Stage();
1876         String text = "123456789";
1877         String tempText = "";
1878 
1879         textInput.setText(text);
1880         stage.setScene(scene);
1881         root.getChildren().removeAll();
1882         root.getChildren().add(textInput);
1883         stage.show();
1884         tk.firePulse();
1885 
1886         KeyEventFirer keyboard = new KeyEventFirer(textInput);
1887 
1888         // Test sequence of spaces
1889         keyboard.doKeyPress(KeyCode.HOME);
1890         tk.firePulse();
1891         for(int i = 0; i < 10; ++i) {
1892             keyboard.doKeyTyped(KeyCode.SPACE);
1893             tk.firePulse();
1894             tempText += " ";
1895         }
1896         assertTrue(textInput.getText().equals(tempText + text));
1897 
1898         textInput.undo();
1899         assertTrue(textInput.getText().equals(text));
1900 
1901         textInput.redo();
1902         assertTrue(textInput.getText().equals(tempText + text));
1903 
1904         root.getChildren().removeAll();
1905         stage.hide();
1906         tk.firePulse();
1907     }
1908 
1909     // Test for JDK-8178418
1910     @Test public void UndoRedoReverseSpaceSequence() {
1911         Toolkit tk = (StubToolkit)Toolkit.getToolkit();
1912         StackPane root = new StackPane();
1913         Scene scene = new Scene(root);
1914         Stage stage = new Stage();
1915         String text = "123456789";
1916         String tempText = "";
1917 
1918         textInput.setText(text);
1919         stage.setScene(scene);
1920         root.getChildren().removeAll();
1921         root.getChildren().add(textInput);
1922         stage.show();
1923         tk.firePulse();
1924 
1925         KeyEventFirer keyboard = new KeyEventFirer(textInput);
1926         // Test reverse sequence of spaces
1927         keyboard.doKeyPress(KeyCode.HOME);
1928         tk.firePulse();
1929         for(int i = 0; i < 10; ++i) {
1930             keyboard.doKeyTyped(KeyCode.SPACE);
1931             keyboard.doKeyPress(KeyCode.LEFT);
1932             tk.firePulse();
1933             tempText += " ";
1934             assertTrue(textInput.getText().equals(tempText + text));
1935         }
1936 
1937         for(int i = 0; i < 10; ++i) {
1938             textInput.undo();
1939             tk.firePulse();
1940         }
1941         assertTrue(textInput.getText().equals(text));
1942 
1943         tempText = "";
1944         for(int i = 0; i < 10; ++i) {
1945             textInput.redo();
1946             tk.firePulse();
1947             tempText += " ";
1948             assertTrue(textInput.getText().equals(tempText + text));
1949         }
1950 
1951         root.getChildren().removeAll();
1952         stage.hide();
1953         tk.firePulse();
1954     }
1955 
1956     // Test for JDK-8178418
1957     @Test public void UndoRedoWords() {
1958         Toolkit tk = (StubToolkit)Toolkit.getToolkit();
1959         StackPane root = new StackPane();
1960         Scene scene = new Scene(root);
1961         Stage stage = new Stage();
1962         String text = "123456789";
1963         String tempText = "";
1964 
1965         textInput.setText(text);
1966         stage.setScene(scene);
1967         root.getChildren().removeAll();
1968         root.getChildren().add(textInput);
1969         stage.show();
1970         tk.firePulse();
1971 
1972         KeyEventFirer keyboard = new KeyEventFirer(textInput);
1973         
1974         // Test words separated by space
1975         keyboard.doKeyPress(KeyCode.HOME);
1976         tk.firePulse();
1977         for(int i = 0; i < 10; ++i) {
1978             keyboard.doKeyTyped(KeyCode.SPACE);
1979             keyboard.doKeyTyped(KeyCode.A);
1980             keyboard.doKeyTyped(KeyCode.B);
1981             tk.firePulse();
1982             tempText += " AB";
1983             assertTrue(textInput.getText().equals(tempText + text));
1984         }
1985 
1986         for(int i = 0; i < 10; ++i) {
1987             textInput.undo();
1988             tk.firePulse();
1989         }
1990         assertTrue(textInput.getText().equals(text));
1991 
1992         tempText = "";
1993         for(int i = 0; i < 10; ++i) {
1994             textInput.redo();
1995             tk.firePulse();
1996             tempText += " AB";
1997             assertTrue(textInput.getText().equals(tempText + text));
1998         }
1999 
2000         root.getChildren().removeAll();
2001         stage.hide();
2002         tk.firePulse();
2003     }
2004 
2005     // Test for JDK-8178418
2006     @Test public void UndoRedoTimestampBased() {
2007         Toolkit tk = (StubToolkit)Toolkit.getToolkit();
2008         StackPane root = new StackPane();
2009         Scene scene = new Scene(root);
2010         Stage stage = new Stage();
2011         String text = "123456789";
2012         String tempText = "";
2013 
2014         textInput.setText(text);
2015         stage.setScene(scene);
2016         root.getChildren().removeAll();
2017         root.getChildren().add(textInput);
2018         stage.show();
2019         tk.firePulse();
2020 
2021         KeyEventFirer keyboard = new KeyEventFirer(textInput);
2022         
2023         // Test continuos sequence of characters
2024         // in this case an undo-redo record is added after 2500 mili seconds.
2025         keyboard.doKeyPress(KeyCode.HOME);
2026         tk.firePulse();
2027 
2028         long startTime = (new Date()).getTime();
2029         while(((new Date()).getTime() - startTime < 4000)) {
2030 
2031             keyboard.doKeyTyped(KeyCode.A);
2032             tk.firePulse();
2033             tempText += "A";
2034             assertTrue(textInput.getText().equals(tempText + text));
2035         }
2036 
2037         textInput.undo();
2038         assertFalse(textInput.getText().equals(text));
2039         textInput.undo();
2040         tk.firePulse();
2041         assertTrue(textInput.getText().equals(text));
2042 
2043         root.getChildren().removeAll();
2044         stage.hide();
2045         tk.firePulse();
2046     }
2047 
2048     // TODO tests for Content firing event notification properly
2049 
2050     // TODO tests for Content not allowing illegal characters
2051 
2052     private void copy(String string) {
2053         ClipboardContent content = new ClipboardContent();
2054         content.putString(string);
2055         Clipboard.getSystemClipboard().setContent(content);
2056     }
2057 }