Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #594: Properly calculate the background and underline shapes fo… #595

Merged
merged 1 commit into from
Oct 11, 2017

Conversation

afester
Copy link
Collaborator

@afester afester commented Sep 28, 2017

…r non-consecutive ranges

  • Added an integration test which does some simple styling tests
  • The underline test fails without the code modifications in ParagraphText.java
  • Fixed the calculation of shapes in ParagraphText.java: shapes must only be combined when the ranges are consecutive

Copy link
Contributor

@JordanMartinez JordanMartinez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR.

There's a few things that can be cleaned up before merging this

import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;

@RunWith(NestedRunner.class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NestedRunner is only necessary if you want to use a class to set up common things among multiple tests. Since you're not doing that here, you can remove it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. It was essentially a preparation for later enhancements, but it is indeed better to add it once it is really required.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like NestedRunner because it reduces code duplication when setting up similar tests. However, it doesn't allow one to run tests within the nested classes in my IDE. I'm not sure how to fix that, but even if we did, I would think that such a thing should not need to be explained for the tests to work on someone else's computer.

Region paragraphBox = getParagraphBox(0);

// get the ParagraphText (protected subclass of TextFlow)
TextFlow tf = (TextFlow) paragraphBox.getChildrenUnmodifiable().get(0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be changed to check for the instance first, only cast if it's valid and throw an exception if it's not? Otherwise, I am not sure it will be the first one if a selection is made.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. get(0) is not always correct - I need to iterate over the children and look up the TextFlow (for which there should be only one, though),


// expected: one text node which contains the complete text
List<Text> textNodes = getTextNodes();
assertEquals(1, textNodes.size());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should be its own test?

List<Text> textNodes = getTextNodes();
assertEquals(1, textNodes.size());

// Set word "World" to bold
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment forces me to look up what String object is equated with "World".

private final static String styledWord1 = "World";
private final static String moreText = " and also the ";
private final static String styledWord2 = "Sun";
private final static String remainingLine = " and Moon";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relating to line 89's comment, since the string itself does not contain the style, it should equal to what the text it is assigned is. Otherwise, styledWord1 is unstyled in one moment and styled in a later moment.

// setup
interact(() -> {
area.replaceText(firstWord + styledWord1 + moreText + styledWord2 + remainingLine);
// "Hello World and also the Sun and Moon"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comment isn't necessary if we rename the strings to the text they represent

final int start2 = end1 + moreText.length();
final int end2 = start2 + styledWord2.length();
area.setStyle(start2, end2,
"-rtfx-underline-color: red; -rtfx-underline-dash-array: 2 2; -rtfx-underline-width: 1; -rtfx-underline-cap: butt;");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be declared once in a variable and then just pass that variable in to both area.setStyle() calls?

@afester
Copy link
Collaborator Author

afester commented Oct 2, 2017

Won't this return the background shapes and border shapes as well if we add more tests that test for those things, too.

Yes, that is true. In general those methods rely on a particular order how the nodes are inserted into the text flow. It would be better if the node objects themselves know "what" they are. The straight forward solution would be to subclass Path as CaretPath, SelectionPath, BackgroundPath and UnderlinePath - and then use the sub classes instead of plain Path. This would make debugging and inspection of the scene graph (and writing scene related tests) MUCH simpler, since it is immediately visible what kind of path that particular node represents. Alternatively, we could set the id with a specific prefix for each path, but that would require unique id generation (like "bg1,", "bg2" etc.) and it would refer to the instance, not type. Finally, we could also subclass Path once and user a getter to retrieve the type attribute, something like

Path underlinePath = new TypedPath(PATHTYPE.UNDERLINE);
...
if (underlinePath.getType() == PATHTYPE.UNDERLINE) { ...}

@JordanMartinez
Copy link
Contributor

Very good points. I definitely like the subclass or path type approach better than setting the ID. However, which would be easier to use when writing tests and would scale well if we need to add more components to it?

@JordanMartinez
Copy link
Contributor

However, which would be easier to use when writing tests and would scale well if we need to add more components to it?

Actually, since we may never add more rtfx-specific components (YAGNI principle), which approach (and its API) will make reading through the tests easy?

@JordanMartinez
Copy link
Contributor

Looks like #596 is going to work soon. Once it gets merged, can you rebase this (with the changes mentioned) on top of that PR's work?

@JordanMartinez
Copy link
Contributor

Alright #596 has been merged. Looking forward to your update.

@afester
Copy link
Collaborator Author

afester commented Oct 4, 2017

Updated PR primarily for review of the path subclass approach.
The one failed Travis test seems to be
org.fxmisc.richtext.api.CaretTests > caret_bounds_are_absent_after_moving_caret_without_following_it FAILED
java.util.concurrent.TimeoutException

@JordanMartinez
Copy link
Contributor

I still see your original commits at the start of this PR and a whole lot of "commit noise" from my other PR. Did you rebase your commits or is this a GitHub issue?

Yeah... that test apparently failed in my PR, too. However, Travis had some backlog and it didn't report the issue correctly or something, so I thought it passed. They emailed me the failure later.

The issue is that the first test fails, irregardless of which one is run first in that class. I'm not sure where it's timing out thought. Might need to add TestLoggingEvent.STANDARD_ERROR to the build.gradle's integrationTest.testLogging closure.

I'll look over the code later on this week (got other things to do today unfortunately...). However, could you move the test itself to integrationTest?

@afester
Copy link
Collaborator Author

afester commented Oct 4, 2017

I still see your original commits at the start of this PR and a whole lot of "commit noise" from my other PR. Did you rebase your commits or is this a GitHub issue?

Yes, I rebased but forgot that the rebased local branch needs to be force-pushed 🥇
I just re-did the rebase, looks much better now...

However, could you move the test itself to integrationTest?
The tests are in the src/integrationTest directory - I suppose that this is the right location?

Copy link
Contributor

@JordanMartinez JordanMartinez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please amend your commit to fix the issue and force push it.

I'll merge it after that. The TimeoutException thrown in the Mac build isn't related to this at all, so we'll ignore it. That'll need to be addressed in another PR later.


/**
* A path which describes a selection shape in the Scene graph.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"selection" is written instead of what you actually meant: "caret."

Otherwise, everything looks good!

@JordanMartinez
Copy link
Contributor

Ok. The Mac build issue has been resolved now.

@JordanMartinez
Copy link
Contributor

@afester Can you fix the javadoc issue and rebase on top of master? Then the mac build should pass.

@JordanMartinez
Copy link
Contributor

Thanks for your work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants