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

(feat) TextFlowMatchers: Add matchers for the text of a TextFlow. #259

Merged
merged 3 commits into from Mar 25, 2016

Conversation

brcolow
Copy link
Collaborator

@brcolow brcolow commented Mar 22, 2016

Currently there are two ways to match the text contained in a TextFlow.
The first one is based simply off the contained text. The second is
based on the contained text and the color of that text. The expected
colors are encoded in the expected String like:

<COLOR>some text</COLOR>

where COLOR is one of the named colors in JavaFX. For a list of all such
colors, see:

https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html#typecolor

We also extracted out a method for computing the distance between two
colors from PixelMatcherRgb as that functionality was also needed for
finding the color nearest to a named color.


I am open to suggestions on a better way to test for colored text in a text flow as I just thought of the simplest thing I could. I could see the TextFlowMatchers being very useful for testing things that mimic
text editor functionality or also in cases where color-coded text helps the user understand the text (for example, using red for negative monetary balances and green for positive monetary balances) and provide better UX.

Let me know what you think!

@brcolow brcolow force-pushed the text-flow-matchers branch 2 times, most recently from 44aafe0 to 73dc264 Compare March 22, 2016 08:15
@hastebrot
Copy link
Member

Is it possible to use the CSS color names of javafx.scene.paint.Color directly?

Update: Seems the color names are behind private methods or only retrievable reflection.

Things to consider:

  • Does it make sense to have a hasColoredText(TextFlow, String) that matches a color name exactly and a hasColoredText(TextFlow, String, PixelMatcher) to match the color perceptional (or even extract a ColorMatcher from PixelMatcher)?
  • Can we implement the functionality using colorName → colorValue (via Color.web(colorName)) instead of colorValue → colorName?

My plan was to implement another PixelMatcher later that uses a better color model than the linear RGB one.

Currently there are two ways to match the text contained in a TextFlow.
The first one is based simply off the contained text. The second is
based on the contained text *and* the color of that text. The expected
colors are encoded in the expected String like:

<COLOR>some text</COLOR>

where COLOR is one of the named colors in JavaFX. For a list of all such
colors, see:

https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html#typecolor

We also extracted out a method for computing the distance between two
colors from PixelMatcherRgb as that functionality was also needed for
finding the color nearest to a named color.
@brcolow
Copy link
Collaborator Author

brcolow commented Mar 22, 2016

I think these a really good questions and valid feedback, I will look into them hopefully within the next 24 hours or so. Thanks Benjamin.

Update:

I am not sure how to implement your suggestions given that one could be matching multiple different colors within a single TextFlow. For example, consider the assertion:

assertThat(lookup(#myTextFlow), TextFlowMatchers.containsText("You have insufficient funds. Your available balance is <RED>$5.00</RED> but this action requires <GREEN>$8.00</GREEN>."));

Given that there can be multiple colors to match, I am not sure how a PixelMatcher/ColorMatcher could be used.

Lastly could you please explain a bit more about what you mean by:

Can we implement the functionality using colorName → colorValue (via Color.web(colorName)) instead of colorValue → colorName?

Do you mean having the "markup" look like this:

<ff00ff>Some</ff00ff> text that is <ffffff>colored</ffffff> ?

I think having named colors makes for much more readable assertions, but maybe I misunderstand. Given that we we both agree that having named colors makes for more readable assertions, I do not see how to verify a match any other way than iterating through the list of known named colors and finding the color with the least distance.

I could see creating two different methods:

hasExactlyColoredText(TextFlow textFlow, String string)
hasColoredText(TextFlow textFlow, String string, double minColorDistFactor)

Add a method to TextFlowMatchers that allows for testing that the colors
of a TextFlow are *exactly* the same. This usage encouraged us to refactor
the named colors ArrayList to a HashMap so that the ColorUtils function
that looks up exact matches is quite peformant.

To test the hasExactlyColoredText(String string) method it is sufficient
to test the failing case, which is demonstrated by creating a TextFlow
with the text "exact" with a fill set to rgb(51, 200, 50) which is one
red value away from the named color "LimeGreen" and then asserting that:

TextFlowMatchers.hasExactlyColoredText("<LIMEGREEN>exact</LIMEGREEN>");

fails, as expected.
@brcolow
Copy link
Collaborator Author

brcolow commented Mar 23, 2016

I updated the PR so that we now have two functions for testing the color of the text of a TextFlow:

hasColoredText:
Given the markup: <COLOR>text</COLOR>
and a TextFlow:

Text text = new Text("text");
text.setFill(someColor);
TextFlow textFlow = new TextFlow(text);

Matches iff the named color that has the least distance from someColor is COLOR.

hasExactlyColoredText:
Given the markup: <COLOR>text</COLOR>
and a TextFlow:

Text text = new Text("text");
text.setFill(someColor);
TextFlow textFlow = new TextFlow(text);

Matches iff someColor and COLOR are both named colors and they have exactly the same RGB values.

I also refactored the named colors ArrayList to a HashMap so that looking up exact color matches is O(1).

@hastebrot hastebrot changed the title Add TextFlowMatchers used for matching the Text of a TextFlow. (feat) TextFlowMatchers: Add matchers for the text of a TextFlow. Mar 24, 2016
@hastebrot hastebrot merged commit c642ea6 into TestFX:master Mar 25, 2016
@brcolow brcolow deleted the text-flow-matchers branch March 25, 2016 21:44
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.

None yet

2 participants