diff --git a/richtextfx/build.gradle b/richtextfx/build.gradle
index 2aefded09..d53d1a313 100644
--- a/richtextfx/build.gradle
+++ b/richtextfx/build.gradle
@@ -20,7 +20,6 @@ testSets {
check.dependsOn integrationTest
integrationTest.mustRunAfter test
-integrationTest.systemProperty "testfx.robot", "glass"
if (gradle.gradleVersion.substring(0, 1) >= "4") {
// required for Gradle 4 to see custom integrationTest test suite
integrationTest.testClassesDirs = sourceSets.integrationTest.output.classesDirs
@@ -106,6 +105,35 @@ test {
}
}
+integrationTest {
+ testLogging {
+ // Fancy formatting from http://stackoverflow.com/a/36130467/3634630
+ // set options for log level LIFECYCLE
+ events TestLogEvent.PASSED, TestLogEvent.SKIPPED,
+ TestLogEvent.FAILED, TestLogEvent.STANDARD_OUT
+ showExceptions true
+ exceptionFormat TestExceptionFormat.FULL
+ showCauses true
+ showStackTraces true
+
+ // set options for log level DEBUG and INFO
+ debug {
+ events TestLogEvent.STARTED, TestLogEvent.PASSED,
+ TestLogEvent.SKIPPED, TestLogEvent.FAILED,
+ TestLogEvent.STANDARD_OUT, TestLogEvent.STANDARD_ERROR
+ }
+ info.events = debug.events
+ afterSuite { desc, result ->
+ if (!desc.parent) { // will match the outermost suite
+ def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)"
+ def startItem = '| ', endItem = ' |'
+ def repeatLength = startItem.length() + output.length() + endItem.length()
+ println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
+ }
+ }
+ }
+}
+
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from 'build/docs/javadoc'
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/InlineCssTextAreaAppTest.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/InlineCssTextAreaAppTest.java
index 81a171fbd..249b63265 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/InlineCssTextAreaAppTest.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/InlineCssTextAreaAppTest.java
@@ -1,41 +1,21 @@
package org.fxmisc.richtext;
import javafx.geometry.Pos;
-import javafx.scene.Node;
import javafx.scene.Scene;
-import javafx.scene.control.ContextMenu;
-import javafx.scene.control.MenuItem;
import javafx.scene.input.MouseButton;
import javafx.stage.Stage;
-import javafx.stage.Window;
import org.testfx.api.FxRobotInterface;
-import org.testfx.framework.junit.ApplicationTest;
import org.testfx.service.query.PointQuery;
-import static org.junit.Assume.assumeTrue;
-
/**
* TestFX tests should subclass this if it needs to run tests on a simple area. Any view-related API needs to be
* wrapped in a {@link #interact(Runnable)} call, but model API does not need to be wrapped in it.
*/
-public class InlineCssTextAreaAppTest extends ApplicationTest {
-
- static {
- String osName = System.getProperty("os.name").toLowerCase();
-
- isWindows = osName.startsWith("win");
- isMac = osName.startsWith("mac");
- isLinux = osName.startsWith("linux");
- }
-
- public static final boolean isWindows;
- public static final boolean isMac;
- public static final boolean isLinux;
+public class InlineCssTextAreaAppTest extends RichTextFXTestBase {
public Stage stage;
public Scene scene;
public InlineCssTextArea area;
- public ContextMenu menu;
@Override
public void start(Stage stage) throws Exception {
@@ -48,28 +28,10 @@ public void start(Stage stage) throws Exception {
stage.setHeight(400);
stage.show();
- menu = new ContextMenu(new MenuItem("A menu item"));
- area.setContextMenu(menu);
- // offset needs to be 5+ to prevent test failures
- area.setContextMenuXOffset(30);
- area.setContextMenuYOffset(30);
-
// so tests don't need to do this themselves
area.requestFocus();
}
- public final PointQuery position(Scene scene, Pos pos, double xOffset, double yOffset) {
- return point(scene).atPosition(pos).atOffset(xOffset, yOffset);
- }
-
- public final PointQuery position(Window window, Pos pos, double xOffset, double yOffset) {
- return point(window).atPosition(pos).atOffset(xOffset, yOffset);
- }
-
- public final PointQuery position(Node node, Pos pos, double xOffset, double yOffset) {
- return point(node).atPosition(pos).atOffset(xOffset, yOffset);
- }
-
public final PointQuery position(Pos pos, double xOffset, double yOffset) {
return position(area, pos, xOffset, yOffset);
}
@@ -98,51 +60,4 @@ public final FxRobotInterface rightClickOnFirstLine() {
return clickOnFirstLine(MouseButton.SECONDARY);
}
- /**
- * If not on Windows environment, calling this in @Before method will skip the entire test suite whereas calling
- * this in @Test will skip just that test method
- */
- public final void run_only_on_windows() {
- assumeTrue(isWindows);
- }
-
- /**
- * If not on Linux environment, calling this in @Before method will skip the entire test suite whereas calling
- * this in @Test will skip just that test method
- */
- public final void run_only_on_linux() {
- assumeTrue(isLinux);
- }
-
- /**
- * If not on Mac environment, calling this in @Before method will skip the entire test suite whereas calling
- * this in @Test will skip just that test method
- */
- public final void run_only_on_mac() {
- assumeTrue(isMac);
- }
-
- /**
- * If on Windows environment, calling this in @Before method will skip the entire test suite whereas calling
- * this in @Test will skip just that test method
- */
- public final void skip_if_on_windows() {
- assumeTrue(!isWindows);
- }
-
- /**
- * If on Linux environment, calling this in @Before method will skip the entire test suite whereas calling
- * this in @Test will skip just that test method
- */
- public final void skip_if_on_linux() {
- assumeTrue(!isLinux);
- }
-
- /**
- * If on Mac environment, calling this in @Before method will skip the entire test suite whereas calling
- * this in @Test will skip just that test method
- */
- public final void skip_if_on_mac() {
- assumeTrue(!isMac);
- }
}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/RichTextFXTestBase.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/RichTextFXTestBase.java
new file mode 100644
index 000000000..67a20f8bf
--- /dev/null
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/RichTextFXTestBase.java
@@ -0,0 +1,117 @@
+package org.fxmisc.richtext;
+
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.stage.Window;
+import org.testfx.framework.junit.ApplicationTest;
+import org.testfx.service.query.PointQuery;
+
+import static org.junit.Assume.assumeTrue;
+
+/**
+ * Provides useful static fields and helper methods for RichTextFX integration tests.
+ *
+ *
+ * -
+ * Helps determine which OS is currently running the test and whether to run/skip a test on that OS
+ *
+ * -
+ * Getting the position o
+ *
+ *
+ */
+public abstract class RichTextFXTestBase extends ApplicationTest {
+
+ static {
+ String osName = System.getProperty("os.name").toLowerCase();
+
+ IS_WINDOWS = osName.startsWith("win");
+ IS_MAC = osName.startsWith("mac");
+ IS_LINUX = osName.startsWith("linux");
+ }
+
+ /* *********************************************** *
+ * OS-RELATED
+ * *********************************************** */
+
+ public static final boolean IS_WINDOWS;
+ public static final boolean IS_MAC;
+ public static final boolean IS_LINUX;
+
+ /**
+ * If not on Windows environment, calling this in @Before method will skip the entire test suite whereas calling
+ * this in @Test will skip just that test method
+ */
+ public final void run_only_on_windows() {
+ assumeTrue(IS_WINDOWS);
+ }
+
+ /**
+ * If not on Linux environment, calling this in @Before method will skip the entire test suite whereas calling
+ * this in @Test will skip just that test method
+ */
+ public final void run_only_on_linux() {
+ assumeTrue(IS_LINUX);
+ }
+
+ /**
+ * If not on Mac environment, calling this in @Before method will skip the entire test suite whereas calling
+ * this in @Test will skip just that test method
+ */
+ public final void run_only_on_mac() {
+ assumeTrue(IS_MAC);
+ }
+
+ /**
+ * If on Windows environment, calling this in @Before method will skip the entire test suite whereas calling
+ * this in @Test will skip just that test method
+ */
+ public final void skip_if_on_windows() {
+ assumeTrue(!IS_WINDOWS);
+ }
+
+ /**
+ * If on Linux environment, calling this in @Before method will skip the entire test suite whereas calling
+ * this in @Test will skip just that test method
+ */
+ public final void skip_if_on_linux() {
+ assumeTrue(!IS_LINUX);
+ }
+
+ /**
+ * If on Mac environment, calling this in @Before method will skip the entire test suite whereas calling
+ * this in @Test will skip just that test method
+ */
+ public final void skip_if_on_mac() {
+ assumeTrue(!IS_MAC);
+ }
+
+ /* *********************************************** *
+ * Position-Related
+ * *********************************************** */
+
+ /**
+ * Returns a specific position in the scene, starting at {@code pos} and offsetting from that place by
+ * {@code xOffset} and {@code yOffset}
+ */
+ public final PointQuery position(Scene scene, Pos pos, double xOffset, double yOffset) {
+ return point(scene).atPosition(pos).atOffset(xOffset, yOffset);
+ }
+
+ /**
+ * Returns a specific position in the window, starting at {@code pos} and offsetting from that place by
+ * {@code xOffset} and {@code yOffset}
+ */
+ public final PointQuery position(Window window, Pos pos, double xOffset, double yOffset) {
+ return point(window).atPosition(pos).atOffset(xOffset, yOffset);
+ }
+
+ /**
+ * Returns a specific position in the node, starting at {@code pos} and offsetting from that place by
+ * {@code xOffset} and {@code yOffset}
+ */
+ public final PointQuery position(Node node, Pos pos, double xOffset, double yOffset) {
+ return point(node).atPosition(pos).atOffset(xOffset, yOffset);
+ }
+}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/CaretTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/CaretTests.java
index 4f5d47e56..ac1ebcd53 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/CaretTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/CaretTests.java
@@ -11,24 +11,30 @@
public class CaretTests extends InlineCssTextAreaAppTest {
+ private static final String FIFTY_PARS_OF_TEXT;
+
+ static {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 50; i++) {
+ sb.append(i).append("\n");
+ }
+ sb.append(50);
+ FIFTY_PARS_OF_TEXT = sb.toString();
+ }
+
@Override
public void start(Stage stage) throws Exception {
super.start(stage);
// insure caret is always visible
area.setShowCaret(Caret.CaretVisibility.ON);
-
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < 50; i++) {
- sb.append(i).append("\n");
- }
- area.replaceText(sb.toString());
+ area.replaceText(FIFTY_PARS_OF_TEXT);
area.moveTo(0);
area.showParagraphAtTop(0);
}
@Test
- public void testMoveCaretAndFollowIt() {
+ public void caret_bounds_are_present_after_moving_caret_and_following_it() {
assertTrue(area.getCaretBounds().isPresent());
// move caret outside of viewport
@@ -43,7 +49,7 @@ public void testMoveCaretAndFollowIt() {
}
@Test
- public void testMoveCaretWithoutFollowingIt() {
+ public void caret_bounds_are_absent_after_moving_caret_without_following_it() {
assertTrue(area.getCaretBounds().isPresent());
// move caret outside of viewport
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/CharacterBoundsTest.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/CharacterBoundsTest.java
index 72813fab0..580f57b35 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/CharacterBoundsTest.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/CharacterBoundsTest.java
@@ -16,7 +16,7 @@ public void start(Stage stage) throws Exception {
}
@Test
- public void selectionBoundsUnchangedWhenCallGetCharacterBounds() {
+ public void selection_bounds_are_unchanged_when_call_getCharacterBounds() {
area.selectAll();
Bounds bounds = area.getSelectionBounds().get();
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/ClipboardTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/ClipboardTests.java
deleted file mode 100644
index 127ab3744..000000000
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/ClipboardTests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.fxmisc.richtext.api;
-
-import com.nitorcreations.junit.runners.NestedRunner;
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-import org.fxmisc.flowless.VirtualizedScrollPane;
-import org.fxmisc.richtext.CodeArea;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.testfx.framework.junit.ApplicationTest;
-
-import static javafx.scene.input.KeyCode.*;
-
-@RunWith(NestedRunner.class)
-public class ClipboardTests {
-
- public class CopyTests extends ApplicationTest {
-
- CodeArea area;
-
- @Override
- public void start(Stage primaryStage) throws Exception {
- area = new CodeArea("abc\ndef\nghi");
- VirtualizedScrollPane vsPane = new VirtualizedScrollPane<>(area);
-
- Scene scene = new Scene(vsPane, 400, 400);
- primaryStage.setScene(scene);
- primaryStage.show();
- }
-
-
- public class WhenUserMakesSelectionEndingInNewLineCharacter {
-
- @Before
- public void setup() {
- area.selectRange(2, 4);
- }
-
- @Test
- public void copyingShouldNotThrowException() {
- push(CONTROL, C);
-
- push(CONTROL, V);
- }
- }
- }
-
-}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/HitTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/HitTests.java
index 9aa587174..4ec7ef34c 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/HitTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/HitTests.java
@@ -5,6 +5,7 @@
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
+import javafx.stage.Stage;
import org.fxmisc.richtext.InlineCssTextAreaAppTest;
import org.fxmisc.richtext.model.NavigationActions;
import org.junit.Before;
@@ -19,15 +20,39 @@
@RunWith(NestedRunner.class)
public class HitTests extends InlineCssTextAreaAppTest {
+ private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
+ private static final String FIFTY_PARS;
+ private static final double PADDING_AMOUNT = 20;
+
+ static {
+ int totalPars = 50;
+ int indexLimit = totalPars - 1;
+ StringBuilder sb = new StringBuilder();
+ Consumer appendParagraph = i -> sb.append("Par #").append(i).append(" ").append(ALPHABET);
+ for (int i = 0; i < indexLimit; i++) {
+ appendParagraph.accept(i);
+ sb.append("\n");
+ }
+ appendParagraph.accept(indexLimit);
+ FIFTY_PARS = sb.toString();
+ }
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ super.start(stage);
+
+ // insure stage width doesn't change irregardless of changes in superclass' start method
+ stage.setWidth(400);
+ stage.setHeight(400);
+ }
+
private void moveCaretToAreaEnd() {
area.moveTo(area.getLength());
}
- public class WhenAreaIsPadded {
+ public class When_Area_Is_Padded {
- double paddingAmount = 20;
-
- public class AndHitsOccurOutsideArea {
+ public class And_Hits_Occur_Outside_Area {
String text = "text";
String fullText = text + "\n" + text;
@@ -38,8 +63,8 @@ public void setup() {
}
@Test
- public void clickingInTopPaddingMovesCaretToTopLine() {
- interact(() -> area.setPadding(new Insets(paddingAmount, 0, 0, 0)));
+ public void clicking_in_top_padding_moves_caret_to_top_line() {
+ interact(() -> area.setPadding(new Insets(PADDING_AMOUNT, 0, 0, 0)));
moveCaretToAreaEnd();
moveTo(position(Pos.TOP_LEFT, 1, 2)).clickOn(PRIMARY);
@@ -51,8 +76,8 @@ public void clickingInTopPaddingMovesCaretToTopLine() {
}
@Test
- public void clickingInLeftPaddingMovesCaretToBeginningOfLineOnSingleLineParagraph() {
- interact(() -> area.setPadding(new Insets(0, 0, 0, paddingAmount)));
+ public void clicking_in_left_padding_moves_caret_to_beginning_of_line_on_single_line_paragraph() {
+ interact(() -> area.setPadding(new Insets(0, 0, 0, PADDING_AMOUNT)));
moveCaretToAreaEnd();
moveTo(position(Pos.TOP_LEFT, 1, 1)).clickOn(PRIMARY);
@@ -60,9 +85,9 @@ public void clickingInLeftPaddingMovesCaretToBeginningOfLineOnSingleLineParagrap
}
@Test
- public void clickingInRightPaddingMovesCaretToEndOfLineOnSingleLineParagraph() {
+ public void clicking_in_right_padding_moves_caret_to_end_of_line_on_single_line_paragraph() {
interact(() -> {
- area.setPadding(new Insets(0, paddingAmount, 0, 0));
+ area.setPadding(new Insets(0, PADDING_AMOUNT, 0, 0));
area.moveTo(0);
// insure we're scrolled all the way to the right
@@ -74,9 +99,9 @@ public void clickingInRightPaddingMovesCaretToEndOfLineOnSingleLineParagraph() {
}
@Test
- public void clickingInBottomPaddingMovesCaretToBottomLine() {
+ public void clicking_in_bottom_padding_moves_caret_to_bottom_line() {
interact(() -> {
- area.setPadding(new Insets(0, 0, paddingAmount, 0));
+ area.setPadding(new Insets(0, 0, PADDING_AMOUNT, 0));
area.moveTo(0);
// insure we're scrolled all the way to the bottom
@@ -89,35 +114,19 @@ public void clickingInBottomPaddingMovesCaretToBottomLine() {
}
- public class AndHitsOccurInsideArea {
-
- String text = "abcdefghijklmnopqrstuvwxyz";
- String fullText;
-
- {
- int totalPars = 50;
- int indexLimit = totalPars - 1;
- StringBuilder sb = new StringBuilder();
- Consumer appendParagraph = i -> sb.append("Par #").append(i).append(" ").append(text);
- for (int i = 0; i < indexLimit; i++) {
- appendParagraph.accept(i);
- sb.append("\n");
- }
- appendParagraph.accept(indexLimit);
- fullText = sb.toString();
- }
+ public class And_Hits_Occur_Inside_Area {
@Before
public void setup() {
interact(() -> {
- area.replaceText(fullText);
- area.setPadding(new Insets(paddingAmount));
+ area.replaceText(FIFTY_PARS);
+ area.setPadding(new Insets(PADDING_AMOUNT));
area.setStyle("-fx-font-family: monospace; -fx-font-size: 12pt;");
});
}
@Test
- public void clickingCharacterShouldMoveCaretToThatPosition() {
+ public void clicking_character_should_move_caret_to_that_position() {
int start = area.getAbsolutePosition(3, 8);
Bounds b = area.getCharacterBoundsOnScreen(start, start + 1).get();
moveTo(b).clickOn(PRIMARY);
@@ -125,11 +134,7 @@ public void clickingCharacterShouldMoveCaretToThatPosition() {
}
@Test
- public void prevPageMovesCaretToTopOfPage() {
- // Mac: failed; Windows: untested
- // TODO: test on respective OS and update expected values to be correct
- run_only_on_linux();
-
+ public void prev_page_moves_caret_to_top_of_page() {
area.showParagraphAtBottom(area.getParagraphs().size() - 1);
// move to last line, column 0
area.moveTo(area.getParagraphs().size() - 1, 0);
@@ -140,15 +145,11 @@ public void prevPageMovesCaretToTopOfPage() {
});
assertEquals(0, area.getCaretColumn());
- assertEquals(32, area.getCurrentParagraph());
+ assertEquals(area.firstVisibleParToAllParIndex(), area.getCurrentParagraph());
}
@Test
- public void nextPageMovesCaretToBottomOfPage() {
- // Mac: failed; Windows: untested
- // TODO: test on respective OS and update expected values to be correct
- run_only_on_linux();
-
+ public void next_page_moves_caret_to_bottom_of_page() {
area.showParagraphAtTop(0);
area.moveTo(0);
@@ -158,37 +159,19 @@ public void nextPageMovesCaretToBottomOfPage() {
});
assertEquals(0, area.getCaretColumn());
- assertEquals(17, area.getCurrentParagraph());
+ assertEquals(area.lastVisibleParToAllParIndex(), area.getCurrentParagraph());
}
}
}
- public class WhenParagraphBoxIsPadded {
-
- double paddingAmount = 20;
-
- String text = "abcdefghijklmnopqrstuvwxyz";
- String fullText;
-
- {
- int totalPars = 50;
- int indexLimit = totalPars - 1;
- StringBuilder sb = new StringBuilder();
- Consumer appendParagraph = i -> sb.append("Par #").append(i).append(" ").append(text);
- for (int i = 0; i < indexLimit; i++) {
- appendParagraph.accept(i);
- sb.append("\n");
- }
- appendParagraph.accept(indexLimit);
- fullText = sb.toString();
- }
+ public class When_ParagraphBox_Is_Padded {
@Before
public void setup() {
interact(() -> {
- area.replaceText(fullText);
+ area.replaceText(FIFTY_PARS);
area.setStyle("-fx-font-family: monospace; -fx-font-size: 12pt;");
scene.getStylesheets().add(HitTests.class.getResource("padded-paragraph-box.css").toExternalForm());
});
@@ -201,20 +184,20 @@ private void runTest() {
assertEquals(start, area.getCaretPosition());
}
- public class AndAreaIsPadded {
+ public class And_Area_Is_Padded {
@Test
- public void clickingCharacterShouldMoveCaretToThatPosition() {
- interact(() -> area.setPadding(new Insets(paddingAmount)));
+ public void clicking_character_should_move_caret_to_that_position() {
+ interact(() -> area.setPadding(new Insets(PADDING_AMOUNT)));
runTest();
}
}
- public class AndAreaIsNotPadded {
+ public class And_Area_Is_Not_Padded {
@Test
- public void clickingCharacterShouldMoveCaretToThatPosition() {
+ public void clicking_character_should_move_caret_to_that_position() {
runTest();
}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/MiscellaneousTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/MiscellaneousTests.java
deleted file mode 100644
index 2d4a4e106..000000000
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/MiscellaneousTests.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.fxmisc.richtext.api;
-
-import com.nitorcreations.junit.runners.NestedRunner;
-import javafx.stage.Stage;
-import org.fxmisc.richtext.InlineCssTextAreaAppTest;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static javafx.scene.input.KeyCode.DELETE;
-
-@RunWith(NestedRunner.class)
-public class MiscellaneousTests {
-
- public class WhenAreaEndsWithEmptyLine extends InlineCssTextAreaAppTest {
-
- @Override
- public void start(Stage stage) throws Exception {
- super.start(stage);
- area.replaceText(0, 0, "abc\n");
- }
-
- public class AndAllTextIsSelected {
-
- @Before
- public void selectAllText() {
- interact(() -> area.selectAll());
- }
-
-
- @Test
- public void pressingDeleteShouldNotThrowException() {
- push(DELETE);
- }
-
- }
- }
-}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/MouseOverTextDelayTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/MouseOverTextDelayTests.java
index 986eac5c3..d526c290d 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/MouseOverTextDelayTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/MouseOverTextDelayTests.java
@@ -50,7 +50,7 @@ private void setDelay(long milliseconds) {
}
@Test
- public void nullDelayNeverFires() {
+ public void null_delay_never_fires() {
setDelay(null);
moveTo(firstLineOfArea()).sleep(300);
@@ -60,7 +60,7 @@ public void nullDelayNeverFires() {
@Ignore("END events are fired multiple times when BEGIN event hasn't yet fired")
@Test
- public void eventsFireAfterDelayAndPostMove() {
+ public void events_fire_after_delay_and_post_move() {
setDelay(100);
moveTo(firstLineOfArea()).sleep(300);
@@ -76,7 +76,7 @@ public void eventsFireAfterDelayAndPostMove() {
@Ignore("setting delay while mouse is over text fires END event when BEGIN event hasn't yet fired")
@Test
- public void settingDelayWhileMouseOverTextDoesNotFireEvent() {
+ public void setting_delay_while_mouse_is_over_text_does_not_fire_event() {
setDelay(null);
moveTo(firstLineOfArea()).sleep(300);
@@ -94,7 +94,7 @@ public void settingDelayWhileMouseOverTextDoesNotFireEvent() {
@Ignore("this test is only important when above two tests get fixed")
@Test
- public void settingDelayBeforeEndFiresPreventsEndFromFiring() {
+ public void setting_delay_before_end_fires_prevents_end_from_firing() {
setDelay(100);
moveTo(firstLineOfArea()).sleep(200);
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/ParagraphLinesCountTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/ParagraphLinesCountTests.java
index f8d42843e..f4ea1d3e0 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/ParagraphLinesCountTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/ParagraphLinesCountTests.java
@@ -9,7 +9,7 @@
public class ParagraphLinesCountTests extends InlineCssTextAreaAppTest {
@Test
- public void multiLineReturnsCorrectCount() {
+ public void multi_line_returns_correct_count() {
String[] lines = {
"01 02 03 04 05",
"11 12 13 14 15",
@@ -25,7 +25,7 @@ public void multiLineReturnsCorrectCount() {
}
@Test
- public void singleLineReturnsOne() {
+ public void single_line_returns_one() {
interact(() -> area.replaceText("some text"));
assertFalse(area.isWrapText());
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/UndoManagerTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/UndoManagerTests.java
index a9c162efc..3187e314c 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/UndoManagerTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/UndoManagerTests.java
@@ -9,7 +9,7 @@
public class UndoManagerTests extends InlineCssTextAreaAppTest {
@Test
- public void preventMergeOfIncomingChangeAfterPeriodOfUserInactivity() {
+ public void incoming_change_is_not_merged_after_period_of_user_inactivity() {
String text1 = "text1";
String text2 = "text2";
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/CutCopyPasteTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/CutCopyPasteTests.java
index b47af6c71..bd4a65657 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/CutCopyPasteTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/CutCopyPasteTests.java
@@ -1,14 +1,17 @@
package org.fxmisc.richtext.keyboard;
import com.nitorcreations.junit.runners.NestedRunner;
+import javafx.scene.Scene;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.stage.Stage;
+import org.fxmisc.flowless.VirtualizedScrollPane;
+import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.InlineCssTextAreaAppTest;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.testfx.framework.junit.ApplicationTest;
import static javafx.scene.input.KeyCode.*;
import static junit.framework.TestCase.assertEquals;
@@ -32,7 +35,7 @@ public void start(Stage stage) throws Exception {
area.replaceText(fullText);
}
- public class WhenNothingIsSelected {
+ public class When_Nothing_Is_Selected {
@Before
public void insureSelectionIsEmpty() {
@@ -40,7 +43,7 @@ public void insureSelectionIsEmpty() {
assertTrue(area.getSelectedText().isEmpty());
}
- public class NothingIsStoredInClipboardWhenCopyVia {
+ public class Nothing_Is_Stored_In_Clipboard_When_Copy_Via {
private void runAssert() {
interact(() -> assertFalse(Clipboard.getSystemClipboard().hasString()));
@@ -59,14 +62,14 @@ public void copy() {
}
@Test
- public void shortcut_C() {
+ public void shortcut_c() {
press(SHORTCUT, C);
runAssert();
}
@Test
- public void shortcut_Insert() {
+ public void shortcut_insert() {
press(SHORTCUT, INSERT);
runAssert();
@@ -74,7 +77,7 @@ public void shortcut_Insert() {
}
- public class NothingIsRemovedInAreaWhenCutVia {
+ public class Nothing_Is_Removed_In_Area_When_Cut_Via {
private void runAssert() {
assertEquals(fullText, area.getText());
@@ -88,14 +91,14 @@ public void cut() {
}
@Test
- public void shortcut_X() {
+ public void shortcut_x() {
press(SHORTCUT, X);
runAssert();
}
@Test
- public void shift_Delete() {
+ public void shift_delete() {
press(SHIFT, DELETE);
runAssert();
@@ -103,7 +106,7 @@ public void shift_Delete() {
}
- public class TextIsInsertedInAreaWhenPasteVia {
+ public class Text_Is_Inserted_In_Area_When_Paste_Via {
private void runAssert() {
assertEquals(beginning + text + middle + end, area.getText());
@@ -131,14 +134,14 @@ public void paste() {
}
@Test
- public void shortcut_V() {
+ public void shortcut_v() {
press(SHORTCUT, V);
runAssert();
}
@Test
- public void shift_Insert() {
+ public void shift_insert() {
press(SHIFT, INSERT);
runAssert();
@@ -146,18 +149,19 @@ public void shift_Insert() {
}
}
- public class WhenTextIsSelected {
+ public class When_Text_Is_Selected {
int startMiddle = beginning.length();
int endMiddle = startMiddle + middle.length();
@Before
- public void selectMiddle() {
+ public void selectMiddleAndClearClipboard() {
area.selectRange(startMiddle, endMiddle);
assertEquals(middle, area.getSelectedText());
+ interact(() -> Clipboard.getSystemClipboard().clear());
}
- public class SelectionIsStoredInClipboardWhenCopyVia {
+ public class Selection_Is_Stored_In_Clipboard_When_Copy_Via {
private void runAssert() {
interact(() -> {
@@ -168,20 +172,25 @@ private void runAssert() {
@Test
public void copy() {
+ // this test fails on Linux; Windows is untested
+ // so for now, only run on Mac
+ // TODO: update if test succeeds on Windows, too
+ run_only_on_mac();
+
press(COPY);
runAssert();
}
@Test
- public void shortcut_C() {
+ public void shortcut_c() {
press(SHORTCUT, C);
runAssert();
}
@Test
- public void shortcut_Insert() {
+ public void shortcut_insert() {
press(SHORTCUT, INSERT);
runAssert();
@@ -189,7 +198,7 @@ public void shortcut_Insert() {
}
- public class SelectionIsRemovedAndStoredInClipboardWhenCutVia {
+ public class Selection_Is_Removed_And_Stored_In_Clipboard_When_Cut_Via {
private void runAssert() {
assertEquals(beginning + end, area.getText());
@@ -200,7 +209,7 @@ private void runAssert() {
}
@Test
- public void cut() {
+ public void cut() {
// this test fails on Linux; Windows is untested
// so for now, only run on Mac
// TODO: update if test succeeds on Windows, too
@@ -212,14 +221,14 @@ public void cut() {
}
@Test
- public void shortcut_X() {
+ public void shortcut_x() {
press(SHORTCUT, X);
runAssert();
}
@Test
- public void shift_Delete() {
+ public void shift_delete() {
press(SHIFT, DELETE);
runAssert();
@@ -227,7 +236,7 @@ public void shift_Delete() {
}
- public class SelectionIsReplacedInAreaWhenPasteVia {
+ public class Selection_Is_Replaced_In_Area_When_Paste_Via {
@Before
public void storeTextInClipboard() {
@@ -242,9 +251,8 @@ private void runAssert() {
assertEquals(beginning + text + end, area.getText());
}
- @Ignore("Flaky test when all others of equivalent tests pass")
@Test
- public void paste() {
+ public void paste() {
// this test fails on Linux; Windows is untested
// so for now, only run on Mac
// TODO: update if test succeeds on Windows, too
@@ -256,14 +264,14 @@ public void paste() {
}
@Test
- public void shortcut_V() {
+ public void shortcut_v() {
press(SHORTCUT, V);
runAssert();
}
@Test
- public void shift_Insert() {
+ public void shift_insert() {
press(SHIFT, INSERT);
runAssert();
@@ -271,4 +279,35 @@ public void shift_Insert() {
}
}
+
+ public class MiscellaneousCases extends ApplicationTest {
+
+ CodeArea area;
+
+ @Override
+ public void start(Stage primaryStage) throws Exception {
+ area = new CodeArea("abc\ndef\nghi");
+ VirtualizedScrollPane vsPane = new VirtualizedScrollPane<>(area);
+
+ Scene scene = new Scene(vsPane, 400, 400);
+ primaryStage.setScene(scene);
+ primaryStage.show();
+ }
+
+ public class When_User_Makes_Selection_Ending_In_Newline_Character {
+
+ @Before
+ public void setup() {
+ area.selectRange(2, 4);
+ }
+
+ @Test
+ public void copying_and_pasting_should_not_throw_exception() {
+ push(CONTROL, C);
+
+ push(CONTROL, V);
+ }
+ }
+ }
+
}
\ No newline at end of file
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/DeletionTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/DeletionTests.java
index 161d0531a..e90c9fcbb 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/DeletionTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/DeletionTests.java
@@ -3,6 +3,7 @@
import com.nitorcreations.junit.runners.NestedRunner;
import javafx.stage.Stage;
import org.fxmisc.richtext.InlineCssTextAreaAppTest;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -31,7 +32,7 @@ private String withoutFirstChar(String s) {
return s.substring(1);
}
- public class WhenShortcutIsDown extends InlineCssTextAreaAppTest {
+ public class When_Shortcut_Is_Down extends InlineCssTextAreaAppTest {
@Override
public void start(Stage stage) throws Exception {
@@ -42,7 +43,7 @@ public void start(Stage stage) throws Exception {
}
@Test
- public void pressingDeleteRemovesNextWordAndSpace() {
+ public void pressing_delete_removes_next_word_and_space() {
area.moveTo(0);
int pos = area.getCaretPosition();
@@ -53,7 +54,7 @@ public void pressingDeleteRemovesNextWordAndSpace() {
}
@Test
- public void pressingBackspaceRemovesPreviousWordAndSpace() {
+ public void pressing_backspace_removes_previous_word_and_space() {
area.end(CLEAR);
int pos = area.getCaretPosition();
@@ -64,7 +65,7 @@ public void pressingBackspaceRemovesPreviousWordAndSpace() {
}
}
- public class WhenModifiersAreNotDown extends InlineCssTextAreaAppTest {
+ public class When_No_Modifiers extends InlineCssTextAreaAppTest {
@Override
public void start(Stage stage) throws Exception {
@@ -73,7 +74,7 @@ public void start(Stage stage) throws Exception {
}
@Test
- public void pressingDeleteRemovesNextChar() {
+ public void pressing_delete_removes_next_char() {
area.moveTo(0);
int pos = area.getCaretPosition();
@@ -84,7 +85,7 @@ public void pressingDeleteRemovesNextChar() {
}
@Test
- public void pressingBackspaceRemovesPreviousChar() {
+ public void pressing_backspace_removes_previous_char() {
area.end(CLEAR);
int pos = area.getCaretPosition();
@@ -95,4 +96,35 @@ public void pressingBackspaceRemovesPreviousChar() {
}
}
+
+ // miscellaneous cases
+
+ public class When_Area_Ends_With_Empty_Line extends InlineCssTextAreaAppTest {
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ super.start(stage);
+ area.replaceText(0, 0, "abc\n");
+ }
+
+ public class And_All_Text_Is_Selected {
+
+ @Before
+ public void selectAllText() {
+ interact(() -> area.selectAll());
+ }
+
+
+ @Test
+ public void pressing_delete_should_not_throw_exception() {
+ push(DELETE);
+ }
+
+ @Test
+ public void pressing_backspace_should_not_throw_exceptions() {
+ push(BACK_SPACE);
+ }
+
+ }
+ }
}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/NavigationTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/NavigationTests.java
deleted file mode 100644
index ae2b67413..000000000
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/NavigationTests.java
+++ /dev/null
@@ -1,633 +0,0 @@
-package org.fxmisc.richtext.keyboard;
-
-import com.nitorcreations.junit.runners.NestedRunner;
-import javafx.geometry.Bounds;
-import javafx.stage.Stage;
-import org.fxmisc.richtext.GenericStyledArea;
-import org.fxmisc.richtext.InlineCssTextAreaAppTest;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.testfx.util.WaitForAsyncUtils;
-
-import java.util.Arrays;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import static javafx.scene.input.KeyCode.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-@RunWith(NestedRunner.class)
-public class NavigationTests {
-
- private int entityStart(int entityIndex, String[] array) {
- if (entityIndex == 0) {
- return 0;
- } else {
- return Arrays.stream(array)
- .map(String::length)
- .limit(entityIndex)
- .reduce(0, (a, b) -> a + b)
- + entityIndex; // for delimiter characters
- }
- }
-
- private int entityEnd(int entityIndex, String[] array, GenericStyledArea, ?, ?> area) {
- if (entityIndex == array.length - 1) {
- return area.getLength();
- } else {
- return entityStart(entityIndex + 1, array) - 1;
- }
- }
-
- public class SingleLineTests extends InlineCssTextAreaAppTest {
-
- String[] words = { "the", "cat", "can", "walk" };
- String fullText = String.join(" ", words);
-
- private int wordStart(int wordIndex) {
- return entityStart(wordIndex, words);
- }
-
- private int wordEnd(int wordIndex) {
- return entityEnd(wordIndex, words, area);
- }
-
- private void moveCaretTo(int position) {
- area.moveTo(position);
- }
-
- @Override
- public void start(Stage stage) throws Exception {
- super.start(stage);
- stage.setWidth(300);
- area.replaceText(fullText);
- }
-
- public class NoModifiers {
-
- @Test
- public void left() {
- moveCaretTo(wordStart(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(LEFT);
-
- assertEquals(wordEnd(0), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void right() {
- moveCaretTo(wordStart(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(RIGHT);
-
- assertEquals(wordStart(1) + 1, area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- }
-
- public class ShortcutDown {
-
- @Before
- public void setup() {
- press(SHORTCUT);
- }
-
- @Test
- public void left() {
- moveCaretTo(wordEnd(3));
- assertTrue(area.getSelectedText().isEmpty());
-
- // first left goes to boundary of current word
- type(LEFT);
-
- assertEquals(wordStart(3), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
-
- // second left skips space and goes to end boundary of prev word
- type(LEFT);
-
- assertEquals(wordStart(2), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void right() {
- moveCaretTo(wordStart(0));
- assertTrue(area.getSelectedText().isEmpty());
-
- // first right goes to boundary of current word
- type(RIGHT);
-
- assertEquals(wordEnd(0), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
-
- // second right skips space and goes to end boundary of next word
- type(RIGHT);
-
- assertEquals(wordEnd(1), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void a() {
- assertTrue(area.getSelectedText().isEmpty());
-
- type(A);
-
- assertEquals(area.getText(), area.getSelectedText());
- }
-
- }
-
- public class ShiftDown {
-
- @Before
- public void setup() {
- press(SHIFT);
- }
-
- @Test
- public void left() {
- moveCaretTo(wordStart(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(LEFT);
-
- assertEquals(wordEnd(0), area.getCaretPosition());
- assertEquals(" ", area.getSelectedText());
- }
-
- @Test
- public void right() {
- moveCaretTo(wordEnd(0));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(RIGHT);
-
- assertEquals(wordStart(1), area.getCaretPosition());
- assertEquals(" ", area.getSelectedText());
- }
-
- }
-
- public class ShortcutShiftDown {
-
- @Before
- public void setup() {
- press(SHORTCUT, SHIFT);
- }
-
- @Test
- public void left() {
- moveCaretTo(wordEnd(3));
- assertTrue(area.getSelectedText().isEmpty());
-
- // first left goes to boundary of current word
- type(LEFT);
-
- assertEquals(wordStart(3), area.getCaretPosition());
- assertEquals(words[3], area.getSelectedText());
-
- // second left skips space and goes to end boundary of prev word
- type(LEFT);
-
- assertEquals(wordStart(2), area.getCaretPosition());
- assertEquals(words[2] + " " + words[3], area.getSelectedText());
- }
-
- @Test
- public void right() {
- moveCaretTo(wordStart(0));
- assertTrue(area.getSelectedText().isEmpty());
-
- // first right goes to boundary of current word
- type(RIGHT);
-
- assertEquals(wordEnd(0), area.getCaretPosition());
- assertEquals(words[0], area.getSelectedText());
-
- // second right skips space and goes to end boundary of next word
- type(RIGHT);
-
- assertEquals(wordEnd(1), area.getCaretPosition());
- assertEquals(words[0] + " " + words[1], area.getSelectedText());
- }
-
- }
-
- }
-
- public class MultiLineGridlikeTextTests extends InlineCssTextAreaAppTest {
-
- public final String[] lines = {
- "01 02 03 04 05",
- "11 12 13 14 15",
- "21 22 23 24 25",
- "31 32 33 34 35",
- "41 42 43 44 45"
- };
-
- private int lineStart(int lineIndex) {
- return entityStart(lineIndex, lines);
- }
-
- private int lineEnd(int lineIndex) {
- return entityEnd(lineIndex, lines, area);
- }
-
- String fullText = String.join(" ", lines);
-
- private void moveCaretTo(int position) {
- area.moveTo(position);
- }
-
- private void waitForMultiLineRegistration() throws TimeoutException {
- // When the stage's width changes, TextFlow does not properly handle API calls to a
- // multi-line paragraph immediately. So, wait until it correctly responds
- // to the stage width change
- Future textFlowIsReady = WaitForAsyncUtils.asyncFx(() -> {
- while (area.getParagraphLinesCount(0) != lines.length) {
- sleep(10);
- }
- });
- WaitForAsyncUtils.waitFor(5, TimeUnit.SECONDS, textFlowIsReady);
- }
-
- @Override
- public void start(Stage stage) throws Exception {
- super.start(stage);
- area.setWrapText(true);
- area.replaceText(fullText);
-
- // insures area's text appears exactly as the declaration of `lines`
- stage.setWidth(150);
- area.setStyle(
- "-fx-font-family: monospace;" +
- "-fx-font-size: 12pt;"
- );
- }
-
- public class NoModifiers {
-
- @Before
- public void setup() throws TimeoutException {
- waitForMultiLineRegistration();
- }
-
- @Test
- public void up() {
- moveCaretTo(lineStart(2));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(UP);
-
- assertEquals(lineStart(1), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void down() {
- moveCaretTo(lineStart(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(DOWN);
-
- assertEquals(lineStart(2), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void home() {
- moveCaretTo(lineEnd(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(HOME);
-
- assertEquals(lineStart(1), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void end() {
- moveCaretTo(lineStart(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(END);
-
- assertEquals(lineEnd(1), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- }
-
- public class ShortcutDown {
-
- @Before
- public void setup() throws TimeoutException {
- waitForMultiLineRegistration();
-
- press(SHORTCUT);
- }
-
- // up/down do nothing
- @Test
- public void up() {
- assertTrue(area.getSelectedText().isEmpty());
- moveCaretTo(lineStart(2));
-
- type(UP);
-
- assertEquals(lineStart(2), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void down() {
- assertTrue(area.getSelectedText().isEmpty());
- moveCaretTo(lineStart(2));
-
- type(DOWN);
-
- assertEquals(lineStart(2), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void home() {
- moveCaretTo(lineStart(2));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(HOME);
-
- assertEquals(0, area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void end() {
- moveCaretTo(lineStart(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(END);
-
- assertEquals(area.getLength(), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- }
-
- public class ShiftDown {
-
- @Before
- public void setup() throws TimeoutException {
- waitForMultiLineRegistration();
-
- press(SHIFT);
- }
-
- @Test
- public void up() {
- moveCaretTo(lineStart(2));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(UP);
-
- assertEquals(lineStart(1), area.getCaretPosition());
- assertEquals(lines[1] + " ", area.getSelectedText());
- }
-
- @Test
- public void down() {
- moveCaretTo(lineStart(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(DOWN);
-
- assertEquals(lineStart(2), area.getCaretPosition());
- assertEquals(lines[1] + " ", area.getSelectedText());
- }
-
- @Test
- public void home() {
- moveCaretTo(lineEnd(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(HOME);
-
- assertEquals(lineStart(1), area.getCaretPosition());
- assertEquals(lines[1], area.getSelectedText());
- }
-
- @Test
- public void end() {
- moveCaretTo(lineStart(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(END);
-
- assertEquals(lineEnd(1), area.getCaretPosition());
- assertEquals(lines[1], area.getSelectedText());
- }
-
- }
-
- public class ShortcutShiftDown {
-
- @Before
- public void setup() throws TimeoutException {
- waitForMultiLineRegistration();
-
- press(SHORTCUT, SHIFT);
- }
-
- @Test
- public void up() {
- moveCaretTo(lineStart(2));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(UP);
-
- assertEquals(lineStart(2), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void down() {
- moveCaretTo(lineStart(1));
- assertTrue(area.getSelectedText().isEmpty());
-
- type(DOWN);
-
- assertEquals(lineStart(1), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- }
-
- @Test
- public void home() {
- moveCaretTo(area.getLength());
- assertTrue(area.getSelectedText().isEmpty());
-
- type(HOME);
-
- assertEquals(0, area.getCaretPosition());
- assertEquals(area.getText(), area.getSelectedText());
- }
-
- @Test
- public void end() {
- moveCaretTo(0);
- assertTrue(area.getSelectedText().isEmpty());
-
- type(END);
-
- assertEquals(area.getLength(), area.getCaretPosition());
- assertEquals(area.getText(), area.getSelectedText());
- }
-
- }
-
- }
-
- public class MultiLineJaggedTextTests extends InlineCssTextAreaAppTest {
-
- String threeLinesOfText = "Some long amount of text to take up a lot of space in the given area.";
-
- @Override
- public void start(Stage stage) throws Exception {
- super.start(stage);
- stage.setWidth(200);
- area.replaceText(threeLinesOfText);
- area.setWrapText(true);
- }
-
- private void waitForMultiLineRegistration() throws TimeoutException {
- // When the stage's width changes, TextFlow does not properly handle API calls to a
- // multi-line paragraph immediately. So, wait until it correctly responds
- // to the stage width change
- Future textFlowIsReady = WaitForAsyncUtils.asyncFx(() -> {
- while (area.getParagraphLinesCount(0) != 3) {
- sleep(10);
- }
- });
- WaitForAsyncUtils.waitFor(5, TimeUnit.SECONDS, textFlowIsReady);
- }
-
- @Test
- public void pressingDownMovesCaretToNextLine() throws TimeoutException {
- waitForMultiLineRegistration();
-
- area.moveTo(27);
-
- push(DOWN);
-
- assertEquals(57, area.getCaretPosition());
- }
-
- @Test
- public void pressingUpMovesCaretToPrevLine() throws TimeoutException {
- waitForMultiLineRegistration();
-
- area.moveTo(66);
-
- push(UP);
-
- assertEquals(36, area.getCaretPosition());
- }
- }
-
- public class ViewportTests extends InlineCssTextAreaAppTest {
-
- @Override
- public void start(Stage stage) throws Exception {
- super.start(stage);
-
- // allow 6 lines to be displayed
- stage.setHeight(90);
-
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < 8; i++) {
- sb.append(i).append("\n");
- }
- sb.append(9);
- area.replaceText(sb.toString());
- }
-
- @Test
- public void testPageUp() {
- interact(() -> {
- area.moveTo(5, 0);
- area.requestFollowCaret();
- });
- assertTrue(area.getSelectedText().isEmpty());
- Bounds beforeBounds = area.getCaretBounds().get();
-
- type(PAGE_UP);
-
- Bounds afterBounds = area.getCaretBounds().get();
- assertEquals(0, area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- assertTrue(beforeBounds.getMinY() > afterBounds.getMinY());
- }
-
- @Ignore("doesn't work despite 'testShiftPageDown' working fine using the same code")
- @Test
- public void testPageDown() throws Exception {
- interact(() -> {
- area.moveTo(0);
- area.requestFollowCaret();
- });
- assertTrue(area.getSelectedText().isEmpty());
- Bounds beforeBounds = area.getCaretBounds().get();
-
- type(PAGE_DOWN);
-
- Bounds afterBounds = area.getCaretBounds().get();
- assertEquals(area.getAbsolutePosition(5, 0), area.getCaretPosition());
- assertTrue(area.getSelectedText().isEmpty());
- assertTrue(beforeBounds.getMinY() < afterBounds.getMinY());
- }
-
- @Test
- public void testShiftPageUp() {
- interact(() -> {
- area.moveTo(5, 0);
- area.requestFollowCaret();
- });
- assertTrue(area.getSelectedText().isEmpty());
- Bounds beforeBounds = area.getCaretBounds().get();
-
- press(SHIFT).type(PAGE_UP).release(SHIFT);
-
- Bounds afterBounds = area.getCaretBounds().get();
- assertEquals(0, area.getCaretPosition());
- assertEquals(area.getText(0, 0, 5, 0), area.getSelectedText());
- assertTrue(beforeBounds.getMinY() > afterBounds.getMinY());
- }
-
- @Test
- public void testShiftPageDown() {
- interact(() -> {
- area.moveTo(0);
- area.requestFollowCaret();
- });
- assertTrue(area.getSelectedText().isEmpty());
- Bounds beforeBounds = area.getCaretBounds().get();
-
- press(SHIFT).type(PAGE_DOWN).release(SHIFT);
-
- Bounds afterBounds = area.getCaretBounds().get();
- assertEquals(area.getAbsolutePosition(5, 0), area.getCaretPosition());
- assertEquals(area.getText(0, 0, 5, 0), area.getSelectedText());
- assertTrue(beforeBounds.getMinY() < afterBounds.getMinY());
- }
-
- }
-}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/PageUpDownTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/PageUpDownTests.java
new file mode 100644
index 000000000..782913d9e
--- /dev/null
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/PageUpDownTests.java
@@ -0,0 +1,107 @@
+package org.fxmisc.richtext.keyboard;
+
+import javafx.geometry.Bounds;
+import javafx.stage.Stage;
+import org.fxmisc.richtext.InlineCssTextAreaAppTest;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static javafx.scene.input.KeyCode.PAGE_DOWN;
+import static javafx.scene.input.KeyCode.PAGE_UP;
+import static javafx.scene.input.KeyCode.SHIFT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class PageUpDownTests extends InlineCssTextAreaAppTest {
+
+ private static final String EIGHT_LINES;
+
+ static {
+ StringBuilder sb = new StringBuilder();
+ int totalLines = 8;
+ for (int i = 0; i < totalLines - 1; i++) {
+ sb.append(i).append("\n");
+ }
+ sb.append(totalLines);
+ EIGHT_LINES = sb.toString();
+ }
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ super.start(stage);
+
+ // allow 6 lines to be displayed
+ stage.setHeight(90);
+ area.replaceText(EIGHT_LINES);
+ }
+
+ @Test
+ public void page_up_moves_caret_to_top_of_viewport() {
+ interact(() -> {
+ area.moveTo(5, 0);
+ area.requestFollowCaret();
+ });
+ assertTrue(area.getSelectedText().isEmpty());
+ Bounds beforeBounds = area.getCaretBounds().get();
+
+ type(PAGE_UP);
+
+ Bounds afterBounds = area.getCaretBounds().get();
+ assertEquals(0, area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ assertTrue(beforeBounds.getMinY() > afterBounds.getMinY());
+ }
+
+ @Test
+ public void page_down_moves_caret_to_bottom_of_viewport() throws Exception {
+ interact(() -> {
+ area.moveTo(0);
+ area.requestFollowCaret();
+ });
+ assertTrue(area.getSelectedText().isEmpty());
+ Bounds beforeBounds = area.getCaretBounds().get();
+
+ type(PAGE_DOWN);
+
+ Bounds afterBounds = area.getCaretBounds().get();
+ assertEquals(area.getAbsolutePosition(5, 0), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ assertTrue(beforeBounds.getMinY() < afterBounds.getMinY());
+ }
+
+ @Test
+ public void shift_page_up_moves_caret_to_top_of_viewport_and_makes_selection() {
+ interact(() -> {
+ area.moveTo(5, 0);
+ area.requestFollowCaret();
+ });
+ assertTrue(area.getSelectedText().isEmpty());
+ Bounds beforeBounds = area.getCaretBounds().get();
+
+ press(SHIFT).type(PAGE_UP).release(SHIFT);
+
+ Bounds afterBounds = area.getCaretBounds().get();
+ assertEquals(0, area.getCaretPosition());
+ assertEquals(area.getText(0, 0, 5, 0), area.getSelectedText());
+ assertTrue(beforeBounds.getMinY() > afterBounds.getMinY());
+ }
+
+ @Test
+ public void shift_page_down_moves_caret_to_bottom_of_viewport_and_makes_selection() {
+ interact(() -> {
+ area.moveTo(0);
+ area.requestFollowCaret();
+ });
+ assertTrue(area.getSelectedText().isEmpty());
+ Bounds beforeBounds = area.getCaretBounds().get();
+
+ press(SHIFT).type(PAGE_DOWN).release(SHIFT);
+
+ Bounds afterBounds = area.getCaretBounds().get();
+ assertEquals(area.getAbsolutePosition(5, 0), area.getCaretPosition());
+ assertEquals(area.getText(0, 0, 5, 0), area.getSelectedText());
+ assertTrue(beforeBounds.getMinY() < afterBounds.getMinY());
+ }
+
+}
+
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/TypingTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/TypingTests.java
index cc8c81b5b..88d4e81e2 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/TypingTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/TypingTests.java
@@ -9,7 +9,7 @@
public class TypingTests extends InlineCssTextAreaAppTest {
@Test
- public void typingALetterMovesTheCaretAfterThatInsertedLetter() {
+ public void typing_a_letter_moves_caret_after_the_inserted_letter() {
interact(() -> {
area.moveTo(0);
area.clear();
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/MultiLineGridlikeTextTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/MultiLineGridlikeTextTests.java
new file mode 100644
index 000000000..6afc0ba0e
--- /dev/null
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/MultiLineGridlikeTextTests.java
@@ -0,0 +1,295 @@
+package org.fxmisc.richtext.keyboard.navigation;
+
+import com.nitorcreations.junit.runners.NestedRunner;
+import javafx.stage.Stage;
+import org.fxmisc.richtext.InlineCssTextAreaAppTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.testfx.util.WaitForAsyncUtils;
+
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import static javafx.scene.input.KeyCode.DOWN;
+import static javafx.scene.input.KeyCode.END;
+import static javafx.scene.input.KeyCode.HOME;
+import static javafx.scene.input.KeyCode.SHIFT;
+import static javafx.scene.input.KeyCode.SHORTCUT;
+import static javafx.scene.input.KeyCode.UP;
+import static org.fxmisc.richtext.keyboard.navigation.Utils.entityEnd;
+import static org.fxmisc.richtext.keyboard.navigation.Utils.entityStart;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(NestedRunner.class)
+public class MultiLineGridlikeTextTests extends InlineCssTextAreaAppTest {
+
+ public final String[] lines = {
+ "01 02 03 04 05",
+ "11 12 13 14 15",
+ "21 22 23 24 25",
+ "31 32 33 34 35",
+ "41 42 43 44 45"
+ };
+
+ private int lineStart(int lineIndex) {
+ return entityStart(lineIndex, lines);
+ }
+
+ private int lineEnd(int lineIndex) {
+ return entityEnd(lineIndex, lines, area);
+ }
+
+ String fullText = String.join(" ", lines);
+
+ private void moveCaretTo(int position) {
+ area.moveTo(position);
+ }
+
+ private void waitForMultiLineRegistration() throws TimeoutException {
+ // When the stage's width changes, TextFlow does not properly handle API calls to a
+ // multi-line paragraph immediately. So, wait until it correctly responds
+ // to the stage width change
+ Future textFlowIsReady = WaitForAsyncUtils.asyncFx(() -> {
+ while (area.getParagraphLinesCount(0) != lines.length) {
+ sleep(10);
+ }
+ });
+ WaitForAsyncUtils.waitFor(5, TimeUnit.SECONDS, textFlowIsReady);
+ }
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ super.start(stage);
+ area.setWrapText(true);
+ area.replaceText(fullText);
+
+ // insures area's text appears exactly as the declaration of `lines`
+ stage.setWidth(150);
+ area.setStyle(
+ "-fx-font-family: monospace;" +
+ "-fx-font-size: 12pt;"
+ );
+ }
+
+ public class When_No_Modifiers_Pressed {
+
+ @Before
+ public void setup() throws TimeoutException {
+ waitForMultiLineRegistration();
+ }
+
+ @Test
+ public void up_moves_caret_to_previous_line() {
+ moveCaretTo(lineStart(2));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(UP);
+
+ assertEquals(lineStart(1), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void down_moves_caret_to_next_line() {
+ moveCaretTo(lineStart(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(DOWN);
+
+ assertEquals(lineStart(2), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void home_moves_caret_to_start_of_current_line() {
+ moveCaretTo(lineEnd(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(HOME);
+
+ assertEquals(lineStart(1), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void end_moves_caret_to_end_of_current_line() {
+ moveCaretTo(lineStart(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(END);
+
+ assertEquals(lineEnd(1), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ }
+
+ public class When_Shortcut_Is_Pressed {
+
+ @Before
+ public void setup() throws TimeoutException {
+ waitForMultiLineRegistration();
+
+ press(SHORTCUT);
+ }
+
+ @Test
+ public void up_does_not_move_caret() {
+ assertTrue(area.getSelectedText().isEmpty());
+ moveCaretTo(lineStart(2));
+
+ type(UP);
+
+ assertEquals(lineStart(2), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void down_does_not_move_caret() {
+ assertTrue(area.getSelectedText().isEmpty());
+ moveCaretTo(lineStart(2));
+
+ type(DOWN);
+
+ assertEquals(lineStart(2), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void home_moves_caret_to_start_of_current_paragraph() {
+ moveCaretTo(lineStart(2));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(HOME);
+
+ assertEquals(0, area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void end_moves_caret_to_end_of_current_paragraph() {
+ moveCaretTo(lineStart(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(END);
+
+ assertEquals(area.getLength(), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ }
+
+ public class When_Shift_Is_Pressed {
+
+ @Before
+ public void setup() throws TimeoutException {
+ waitForMultiLineRegistration();
+
+ press(SHIFT);
+ }
+
+ @Test
+ public void up() {
+ moveCaretTo(lineStart(2));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(UP);
+
+ assertEquals(lineStart(1), area.getCaretPosition());
+ assertEquals(lines[1] + " ", area.getSelectedText());
+ }
+
+ @Test
+ public void down() {
+ moveCaretTo(lineStart(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(DOWN);
+
+ assertEquals(lineStart(2), area.getCaretPosition());
+ assertEquals(lines[1] + " ", area.getSelectedText());
+ }
+
+ @Test
+ public void home_selects_up_to_the_start_of_current_line() {
+ moveCaretTo(lineEnd(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(HOME);
+
+ assertEquals(lineStart(1), area.getCaretPosition());
+ assertEquals(lines[1], area.getSelectedText());
+ }
+
+ @Test
+ public void end_selects_up_to_the_end_of_current_line() {
+ moveCaretTo(lineStart(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(END);
+
+ assertEquals(lineEnd(1), area.getCaretPosition());
+ assertEquals(lines[1], area.getSelectedText());
+ }
+
+ }
+
+ public class When_Shortcut_And_Shift_Pressed {
+
+ @Before
+ public void setup() throws TimeoutException {
+ waitForMultiLineRegistration();
+
+ press(SHORTCUT, SHIFT);
+ }
+
+ @Test
+ public void up_does_not_move_caret() {
+ moveCaretTo(lineStart(2));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(UP);
+
+ assertEquals(lineStart(2), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void down_does_not_move_caret() {
+ moveCaretTo(lineStart(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(DOWN);
+
+ assertEquals(lineStart(1), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void home_selects_up_to_the_start_of_current_paragraph() {
+ moveCaretTo(area.getLength());
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(HOME);
+
+ assertEquals(0, area.getCaretPosition());
+ assertEquals(area.getText(), area.getSelectedText());
+ }
+
+ @Test
+ public void end_selects_up_to_the_end_of_current_paragraph() {
+ moveCaretTo(0);
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(END);
+
+ assertEquals(area.getLength(), area.getCaretPosition());
+ assertEquals(area.getText(), area.getSelectedText());
+ }
+
+ }
+
+}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/MultiLineJaggedTextTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/MultiLineJaggedTextTests.java
new file mode 100644
index 000000000..9a76fc5af
--- /dev/null
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/MultiLineJaggedTextTests.java
@@ -0,0 +1,61 @@
+package org.fxmisc.richtext.keyboard.navigation;
+
+import javafx.stage.Stage;
+import org.fxmisc.richtext.InlineCssTextAreaAppTest;
+import org.junit.Test;
+import org.testfx.util.WaitForAsyncUtils;
+
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import static javafx.scene.input.KeyCode.DOWN;
+import static javafx.scene.input.KeyCode.UP;
+import static org.junit.Assert.assertEquals;
+
+public class MultiLineJaggedTextTests extends InlineCssTextAreaAppTest {
+
+ String threeLinesOfText = "Some long amount of text to take up a lot of space in the given area.";
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ super.start(stage);
+ stage.setWidth(200);
+ area.replaceText(threeLinesOfText);
+ area.setWrapText(true);
+ }
+
+ private void waitForMultiLineRegistration() throws TimeoutException {
+ // When the stage's width changes, TextFlow does not properly handle API calls to a
+ // multi-line paragraph immediately. So, wait until it correctly responds
+ // to the stage width change
+ Future textFlowIsReady = WaitForAsyncUtils.asyncFx(() -> {
+ while (area.getParagraphLinesCount(0) != 3) {
+ sleep(10);
+ }
+ });
+ WaitForAsyncUtils.waitFor(5, TimeUnit.SECONDS, textFlowIsReady);
+ }
+
+ @Test
+ public void pressing_down_moves_caret_to_next_line() throws TimeoutException {
+ waitForMultiLineRegistration();
+
+ area.moveTo(27);
+
+ push(DOWN);
+
+ assertEquals(57, area.getCaretPosition());
+ }
+
+ @Test
+ public void pressing_up_moves_caret_to_previous_line() throws TimeoutException {
+ waitForMultiLineRegistration();
+
+ area.moveTo(66);
+
+ push(UP);
+
+ assertEquals(36, area.getCaretPosition());
+ }
+}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/SingleLineTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/SingleLineTests.java
new file mode 100644
index 000000000..365d28153
--- /dev/null
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/SingleLineTests.java
@@ -0,0 +1,220 @@
+package org.fxmisc.richtext.keyboard.navigation;
+
+import com.nitorcreations.junit.runners.NestedRunner;
+import javafx.stage.Stage;
+import org.fxmisc.richtext.InlineCssTextAreaAppTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static javafx.scene.input.KeyCode.A;
+import static javafx.scene.input.KeyCode.LEFT;
+import static javafx.scene.input.KeyCode.RIGHT;
+import static javafx.scene.input.KeyCode.SHIFT;
+import static javafx.scene.input.KeyCode.SHORTCUT;
+import static org.fxmisc.richtext.keyboard.navigation.Utils.entityEnd;
+import static org.fxmisc.richtext.keyboard.navigation.Utils.entityStart;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(NestedRunner.class)
+public class SingleLineTests extends InlineCssTextAreaAppTest {
+
+ String[] words = { "the", "cat", "can", "walk" };
+ String fullText = String.join(" ", words);
+
+ private int wordStart(int wordIndex) {
+ return entityStart(wordIndex, words);
+ }
+
+ private int wordEnd(int wordIndex) {
+ return entityEnd(wordIndex, words, area);
+ }
+
+ private void moveCaretTo(int position) {
+ area.moveTo(position);
+ }
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ super.start(stage);
+ stage.setWidth(300);
+ area.replaceText(fullText);
+ }
+
+ public class When_No_Modifiers_Pressed {
+
+ @Test
+ public void left_moves_caret_one_position() {
+ moveCaretTo(wordStart(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(LEFT);
+
+ assertEquals(wordEnd(0), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void right_moves_caret_one_position() {
+ moveCaretTo(wordStart(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(RIGHT);
+
+ assertEquals(wordStart(1) + 1, area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ }
+
+ public class When_Shortcut_Is_Pressed {
+
+ @Before
+ public void setup() {
+ press(SHORTCUT);
+ }
+
+ @Test
+ public void left_once_moves_caret_to_left_boundary_of_current_word() {
+ moveCaretTo(wordEnd(3));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ // first left goes to boundary of current word
+ type(LEFT);
+
+ assertEquals(wordStart(3), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void left_twice_moves_caret_to_left_boundary_of_previous_word() {
+ moveCaretTo(wordEnd(3));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(LEFT).type(LEFT);
+
+ assertEquals(wordStart(2), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void right_once_moves_caret_to_right_boundary_of_current_word() {
+ moveCaretTo(wordStart(0));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ // first right goes to boundary of current word
+ type(RIGHT);
+
+ assertEquals(wordEnd(0), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void right_twice_moves_caret_to_right_boundary_of_next_word() {
+ moveCaretTo(wordStart(0));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(RIGHT).type(RIGHT);
+
+ assertEquals(wordEnd(1), area.getCaretPosition());
+ assertTrue(area.getSelectedText().isEmpty());
+ }
+
+ @Test
+ public void a_selects_all() {
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(A);
+
+ assertEquals(area.getText(), area.getSelectedText());
+ }
+
+ }
+
+ public class When_Shift_Is_Pressed {
+
+ @Before
+ public void setup() {
+ press(SHIFT);
+ }
+
+ @Test
+ public void left_selects_previous_character() {
+ moveCaretTo(wordStart(1));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(LEFT);
+
+ assertEquals(wordEnd(0), area.getCaretPosition());
+ assertEquals(" ", area.getSelectedText());
+ }
+
+ @Test
+ public void right_selects_next_character() {
+ moveCaretTo(wordEnd(0));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(RIGHT);
+
+ assertEquals(wordStart(1), area.getCaretPosition());
+ assertEquals(" ", area.getSelectedText());
+ }
+
+ }
+
+ public class When_Shortcut_And_Shift_Pressed {
+
+ @Before
+ public void setup() {
+ press(SHORTCUT, SHIFT);
+ }
+
+ @Test
+ public void left_once_selects_up_to_left_boundary_of_current_word() {
+ moveCaretTo(wordEnd(3));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ // first left goes to boundary of current word
+ type(LEFT);
+
+ assertEquals(wordStart(3), area.getCaretPosition());
+ assertEquals(words[3], area.getSelectedText());
+ }
+
+ @Test
+ public void left_twice_selects_up_to_start_boundary_of_previous_word() {
+ moveCaretTo(wordEnd(3));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(LEFT).type(LEFT);
+
+ assertEquals(wordStart(2), area.getCaretPosition());
+ assertEquals(words[2] + " " + words[3], area.getSelectedText());
+ }
+
+ @Test
+ public void right_once_selects_up_to_right_boundary_of_current_word() {
+ moveCaretTo(wordStart(0));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(RIGHT);
+
+ assertEquals(wordEnd(0), area.getCaretPosition());
+ assertEquals(words[0], area.getSelectedText());
+ }
+
+ @Test
+ public void right_twice_selects_up_to_end_boundary_of_next_word() {
+ moveCaretTo(wordStart(0));
+ assertTrue(area.getSelectedText().isEmpty());
+
+ type(RIGHT).type(RIGHT);
+
+ assertEquals(wordEnd(1), area.getCaretPosition());
+ assertEquals(words[0] + " " + words[1], area.getSelectedText());
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/Utils.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/Utils.java
new file mode 100644
index 000000000..627084df9
--- /dev/null
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/keyboard/navigation/Utils.java
@@ -0,0 +1,32 @@
+package org.fxmisc.richtext.keyboard.navigation;
+
+import org.fxmisc.richtext.GenericStyledArea;
+
+import java.util.Arrays;
+
+public final class Utils {
+
+ private Utils() {
+ throw new IllegalStateException("Cannot instantiate Utils class");
+ }
+
+ public static int entityStart(int entityIndex, String[] array) {
+ if (entityIndex == 0) {
+ return 0;
+ } else {
+ return Arrays.stream(array)
+ .map(String::length)
+ .limit(entityIndex)
+ .reduce(0, (a, b) -> a + b)
+ + entityIndex; // for delimiter characters
+ }
+ }
+
+ public static int entityEnd(int entityIndex, String[] array, GenericStyledArea, ?, ?> area) {
+ if (entityIndex == array.length - 1) {
+ return area.getLength();
+ } else {
+ return entityStart(entityIndex + 1, array) - 1;
+ }
+ }
+}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/mouse/ClickAndDragTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/mouse/ClickAndDragTests.java
index bc2a576bd..727b69b83 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/mouse/ClickAndDragTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/mouse/ClickAndDragTests.java
@@ -1,6 +1,7 @@
package org.fxmisc.richtext.mouse;
import com.nitorcreations.junit.runners.NestedRunner;
+import javafx.geometry.Bounds;
import javafx.stage.Stage;
import org.fxmisc.richtext.InlineCssTextAreaAppTest;
import org.junit.Test;
@@ -15,7 +16,7 @@
@RunWith(NestedRunner.class)
public class ClickAndDragTests {
- public class WhenAreaIsDisabled extends InlineCssTextAreaAppTest {
+ public class When_Area_Is_Disabled extends InlineCssTextAreaAppTest {
@Override
public void start(Stage stage) throws Exception {
@@ -26,7 +27,7 @@ public void start(Stage stage) throws Exception {
}
@Test
- public void shiftClickingAreaDoesNothing() {
+ public void shift_clicking_area_does_nothing() {
moveTo(firstLineOfArea())
.moveBy(20, 0)
.press(SHIFT)
@@ -36,28 +37,28 @@ public void shiftClickingAreaDoesNothing() {
}
@Test
- public void singleClickingAreaDoesNothing() {
+ public void single_clicking_area_does_nothing() {
leftClickOnFirstLine();
assertFalse(area.isFocused());
}
@Test
- public void doubleClickingAreaDoesNothing() {
+ public void double_clicking_area_does_nothing() {
doubleClickOnFirstLine();
assertFalse(area.isFocused());
}
@Test
- public void tripleClickingAreaDoesNothing() {
+ public void triple_clicking_area_does_nothing() {
tripleClickOnFirstLine();
assertFalse(area.isFocused());
}
@Test
- public void draggingTheMouseDoesNotSelectText() {
+ public void dragging_the_mouse_does_not_select_text() {
moveTo(firstLineOfArea())
.press(PRIMARY)
.moveBy(20, 0);
@@ -66,7 +67,7 @@ public void draggingTheMouseDoesNotSelectText() {
}
@Test
- public void releasingTheMouseAfterDragDoesNothing() {
+ public void releasing_the_mouse_after_drag_does_nothing() {
assertEquals(0, area.getCaretPosition());
moveTo(firstLineOfArea())
@@ -78,9 +79,9 @@ public void releasingTheMouseAfterDragDoesNothing() {
}
- public class WhenAreaIsEnabled {
+ public class When_Area_Is_Enabled {
- public class AndTextIsNotSelected extends InlineCssTextAreaAppTest {
+ public class And_Text_Is_Not_Selected extends InlineCssTextAreaAppTest {
private String firstWord = "Some";
private String firstParagraph = firstWord + " text goes here";
@@ -93,32 +94,33 @@ public void start(Stage stage) throws Exception {
}
@Test
- public void singleClickingAreaMovesCaretToThatPosition() {
+ public void single_clicking_area_moves_caret_to_that_position() {
assertEquals(0, area.getCaretPosition());
- moveTo(firstLineOfArea())
- .moveBy(20, 0)
- .clickOn(PRIMARY);
+ Bounds bounds = area.getCharacterBoundsOnScreen(
+ firstWord.length(), firstWord.length() + 1).get();
+
+ moveTo(bounds).clickOn(PRIMARY);
- assertTrue(0 != area.getCaretPosition());
+ assertEquals(firstWord.length(), area.getCaretPosition());
}
@Test
- public void doubleClickingTextInAreaSelectsClosestWord() {
+ public void double_clicking_text_in_area_selects_closest_word() {
doubleClickOnFirstLine();
assertEquals(firstWord, area.getSelectedText());
}
@Test
- public void tripleClickingLineInAreaSelectsParagraph() {
+ public void triple_clicking_line_in_area_selects_paragraph() {
tripleClickOnFirstLine();
assertEquals(firstParagraph, area.getSelectedText());
}
@Test
- public void pressingMouseOverTextAndDraggingMouseSelectsText() {
+ public void pressing_mouse_over_text_and_dragging_mouse_selects_text() {
moveTo(firstLineOfArea())
.press(PRIMARY)
.moveBy(20, 0);
@@ -128,29 +130,30 @@ public void pressingMouseOverTextAndDraggingMouseSelectsText() {
}
- public class AndTextIsSelected extends InlineCssTextAreaAppTest {
+ public class And_Text_Is_Selected extends InlineCssTextAreaAppTest {
private String firstWord = "Some";
private String firstParagraph = firstWord + " text goes here";
private String extraText = "This is extra text";
@Test
- public void singleClickingWithinSelectedTextMovesCaretToThatPosition() {
+ public void single_clicking_within_selected_text_moves_caret_to_that_position() {
// setup
interact(() -> {
area.replaceText(firstParagraph);
area.selectAll();
});
- moveTo(firstLineOfArea())
- .moveBy(20, 0)
- .clickOn(PRIMARY);
+ Bounds bounds = area.getCharacterBoundsOnScreen(
+ firstWord.length(), firstWord.length() + 1).get();
+
+ moveTo(bounds).clickOn(PRIMARY);
- assertTrue(0 != area.getCaretPosition());
+ assertEquals(firstWord.length(), area.getCaretPosition());
}
@Test
- public void doubleClickingWithinSelectedTextSelectsClosestWord() {
+ public void double_clicking_within_selected_text_selects_closest_word() {
// setup
interact(() -> {
area.replaceText(firstParagraph);
@@ -163,7 +166,7 @@ public void doubleClickingWithinSelectedTextSelectsClosestWord() {
}
@Test
- public void tripleClickingWithinSelectedTextSelectsParagraph() {
+ public void triple_clicking_within_selected_text_selects_paragraph() {
// setup
interact(() -> {
area.replaceText(firstParagraph);
@@ -176,24 +179,23 @@ public void tripleClickingWithinSelectedTextSelectsParagraph() {
}
@Test
- public void singleClickingOutsideOfSelectedTextMovesCaretToThatPosition() {
+ public void single_clicking_outside_of_selected_text_moves_caret_to_that_position() {
// setup
interact(() -> {
area.replaceText(firstParagraph + "\n" + "this is the selected text");
area.selectRange(1, 0, 2, -1);
});
- int caretPos = area.getCaretPosition();
+ Bounds bounds = area.getCharacterBoundsOnScreen(
+ firstWord.length(), firstWord.length() + 1).get();
- moveTo(firstLineOfArea())
- .moveBy(20, 0)
- .clickOn(PRIMARY);
+ moveTo(bounds).clickOn(PRIMARY);
- assertTrue(caretPos != area.getCaretPosition());
+ assertEquals(firstWord.length(), area.getCaretPosition());
}
@Test
- public void doubleClickingOutsideOfSelectedTextSelectsClosestWord() {
+ public void double_clicking_outside_of_selected_text_selects_closest_word() {
// setup
interact(() -> {
area.replaceText(firstParagraph + "\n" + "this is the selected text");
@@ -206,7 +208,7 @@ public void doubleClickingOutsideOfSelectedTextSelectsClosestWord() {
}
@Test
- public void tripleClickingOutsideOfSelectedTextSelectsParagraph() {
+ public void triple_clicking_outside_of_selected_text_selects_paragraph() {
// setup
interact(() -> {
area.replaceText(firstParagraph + "\n" + "this is the selected text");
@@ -219,7 +221,7 @@ public void tripleClickingOutsideOfSelectedTextSelectsParagraph() {
}
@Test
- public void pressingMouseOnUnselectedTextAndDraggingMakesNewSelection() {
+ public void pressing_mouse_on_unselected_text_and_dragging_makes_new_selection() {
// setup
interact(() -> {
area.replaceText(firstParagraph + "\n" + "this is the selected text");
@@ -236,41 +238,56 @@ public void pressingMouseOnUnselectedTextAndDraggingMakesNewSelection() {
}
@Test
- public void pressingMouseOnSelectionAndDraggingDisplacesCaret() {
+ public void pressing_mouse_on_selection_and_dragging_displaces_caret() {
// setup
interact(() -> {
area.replaceText(firstParagraph + "\n" + extraText);
- area.selectRange(0, firstWord.length());
+ area.selectRange(0, firstParagraph.length());
});
String selText = area.getSelectedText();
- moveTo(firstLineOfArea())
+ Bounds firstLetterBounds = area.getCharacterBoundsOnScreen(1, 2).get();
+ Bounds firstWordEndBounds = area.getCharacterBoundsOnScreen(
+ firstWord.length(), firstWord.length() + 1).get();
+
+ moveTo(firstLetterBounds)
.press(PRIMARY)
- .moveBy(0, 22);
+ .moveTo(firstWordEndBounds);
- assertEquals(firstParagraph.length() + 1, area.getCaretPosition());
+ assertEquals(firstWord.length(), area.getCaretPosition());
assertEquals(selText, area.getSelectedText());
}
@Test
- public void pressingMouseOnSelectionAndDraggingAndReleasingMovesSelectedTextToThatPosition() {
+ public void pressing_mouse_on_selection_and_dragging_and_releasing_moves_selected_text_to_that_position() {
+ // Linux passes; Mac fails at "assertEquals(selText, area.getSelectedText())"; Windows is untested
+ // so only run on Linux
+ // TODO: update test to see if it works on Windows
+ run_only_on_linux();
+
// setup
+ String twoSpaces = " ";
interact(() -> {
- area.replaceText(firstParagraph + "\n" + extraText);
+ area.replaceText(firstParagraph + "\n" + twoSpaces + extraText);
area.selectRange(0, firstWord.length());
});
String selText = area.getSelectedText();
- moveTo(firstLineOfArea())
+ Bounds letterInFirstWord = area.getCharacterBoundsOnScreen(1, 2).get();
+
+ int insertionPosition = firstParagraph.length() + 2;
+ Bounds insertionBounds = area.getCharacterBoundsOnScreen(insertionPosition, insertionPosition + 1).get();
+
+ moveTo(letterInFirstWord)
.press(PRIMARY)
- .dropBy(0, 22);
+ .dropTo(insertionBounds);
String expectedText = firstParagraph.substring(firstWord.length())
- + "\n" + firstWord + extraText;
+ + "\n" + " " + firstWord + " " + extraText;
- assertEquals(firstParagraph.length() + 1, area.getCaretPosition());
+ assertEquals(insertionPosition, area.getCaretPosition());
assertEquals(selText, area.getSelectedText());
assertEquals(expectedText, area.getText());
}
diff --git a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/mouse/ContextMenuTests.java b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/mouse/ContextMenuTests.java
index 377a87b6e..010dde521 100644
--- a/richtextfx/src/integrationTest/java/org/fxmisc/richtext/mouse/ContextMenuTests.java
+++ b/richtextfx/src/integrationTest/java/org/fxmisc/richtext/mouse/ContextMenuTests.java
@@ -2,9 +2,13 @@
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;
+import javafx.stage.Stage;
import org.fxmisc.richtext.InlineCssTextAreaAppTest;
+import org.junit.After;
import org.junit.Test;
import static junit.framework.TestCase.assertFalse;
@@ -12,8 +16,27 @@
public class ContextMenuTests extends InlineCssTextAreaAppTest {
+ private ContextMenu menu;
+
+ // offset needs to be 5+ to prevent test failures
+ private double offset = 30;
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ super.start(stage);
+ menu = new ContextMenu(new MenuItem("A menu item"));
+ area.setContextMenu(menu);
+ area.setContextMenuXOffset(offset);
+ area.setContextMenuYOffset(offset);
+ }
+
+ @After
+ public void cleanup() {
+ interact(menu::hide);
+ }
+
@Test
- public void clickingSecondaryShowsContextMenu() {
+ public void clicking_secondary_shows_context_menu() {
// Linux passes; Mac fails; Windows untested
// so for now, only run on Linux
// TODO: See if tests pass on Windows
@@ -27,7 +50,7 @@ public void clickingSecondaryShowsContextMenu() {
}
@Test
- public void pressingSecondaryShowsContextMenu() {
+ public void pressing_secondary_shows_context_menu() {
// Linux passes; Mac fails; Windows untested
// so for now, only run on Linux
// TODO: See if tests pass on Windows
@@ -41,25 +64,27 @@ public void pressingSecondaryShowsContextMenu() {
}
@Test
- public void pressingPrimaryMouseButtonHidesContextMenu() {
+ public void pressing_primary_mouse_button_hides_context_menu() {
// given menu is showing
- showContextMenuAt(Pos.TOP_LEFT, 30);
+ showContextMenuAt();
moveTo(firstLineOfArea()).press(MouseButton.PRIMARY);
+
assertFalse(area.getContextMenu().isShowing());
}
@Test
- public void pressingMiddleMouseButtonHidesContextMenu() {
+ public void pressing_middle_mouse_button_hides_context_menu() {
// given menu is showing
- showContextMenuAt(Pos.TOP_LEFT, 30);
+ showContextMenuAt();
moveTo(firstLineOfArea()).press(MouseButton.MIDDLE);
+
assertFalse(area.getContextMenu().isShowing());
}
@Test
- public void requestingContextMenuViaKeyboardWorksOnWindows() {
+ public void requesting_context_nenu_via_keyboard_works_on_windows() {
run_only_on_windows();
leftClickOnFirstLine();
@@ -68,8 +93,8 @@ public void requestingContextMenuViaKeyboardWorksOnWindows() {
assertTrue(area.getContextMenu().isShowing());
}
- private void showContextMenuAt(Pos posInArea, double offset) {
- Point2D screenPoint = point(area).atPosition(posInArea).atOffset(offset, offset).query();
+ private void showContextMenuAt() {
+ Point2D screenPoint = position(Pos.TOP_LEFT, offset, offset).query();
interact(() -> area.getContextMenu().show(area, screenPoint.getX(), screenPoint.getY()));
}