-
Notifications
You must be signed in to change notification settings - Fork 479
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
8338468: [TestBug] Convert controls tests to JUnit 5 #1561
8338468: [TestBug] Convert controls tests to JUnit 5 #1561
Conversation
👋 Welcome back angorya! A progress list of the required criteria for merging this PR into |
@andy-goryachev-oracle This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 2 new commits pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the ➡️ To integrate this PR with the above commit message to the |
I can also help on that if desired since I also think this is a good idea and logical step for the future of our tests (and all tests that will be written in the future of course). |
Thank you @Maran23 ! It's pretty surprising that junit people thought it will be a good idea to drop support for class-wide parameterized tests... |
Well, I would rephrase it:
So I would not compare it directly but rather say it is a new, better and more flexible way to write them. |
To clarify, the main problem introduced by the decision not to support class-level parameterization is backward compatibility (our use case). The issue is that in many tests we have, the Keeping backward compatibility should have been a priority.
|
Webrevs
|
For reviewers: it might be easier to review commit-by-commit, just keep in mind that in several places I had to go back to fix things (just check the final version). @aghaisas and/or @lukostyra could you be the reviewers please? @Maran23 I can't ask you to do a (full) review, but if you could do a spot check, I'd appreciate! thank you all in advance! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. Could not spot any obvious error.
Left some comments regarding code style to reduce warnings or use newer/better API.
IntegerProperty p = new SimpleIntegerProperty(); | ||
assertNull(unregisterListeners(p)); | ||
assertTrue(unregisterListeners(useChangeListener, p) == null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be assertNull
still?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes! I don't know what I was thinking... good catch!
@ParameterizedTest | ||
@MethodSource("data") | ||
public void testUnregistersNull(boolean useChangeListener) { | ||
assertTrue(unregisterListeners(useChangeListener, null) == null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be assertNull
still?
@Parameterized.Parameters //(name = "{index}: changeListener {0} ") | ||
public static Collection<Object[]> data() { | ||
/** parameters */ | ||
private static Collection<Object[]> data() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: This could also be just a Stream of Boolean Arguments
@Test public void focusGainedIsCaughtByBehavior() { | ||
|
||
@Test | ||
public void focusGainedIsCaughtByBehavior() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, is this an empty test? Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intentionally did not want to change the number of tests, which should be double checked during the review. Leaving as is for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree.
} | ||
|
||
// ------------- parameterized in not/alternative mouseEvent creation | ||
|
||
private boolean useAlternative; | ||
|
||
@Parameterized.Parameters | ||
public static Collection<Object[]> data() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: Could also be simplified with the argument stream
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was fixed in one of the subsequent commits.
{NodeOrientation.RIGHT_TO_LEFT} | ||
}); | ||
private static Collection<NodeOrientation> parameters() { | ||
return Arrays.asList( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: Could also use List.of(..)
try { | ||
@Test | ||
public void testArrayLinkedList_Empty_GetResultsInArrayIndexOutOfBounds() { | ||
assertThrows(IndexOutOfBoundsException.class, () -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
} | ||
|
||
public LabelSkinCreationTest( | ||
public record Parameter( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: Can also imagine a name like LabelParameter
or LabelConfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather, this record should be declared private
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also that is a good idea.
public void setup() { | ||
// @BeforeEach | ||
// junit5 does not support parameterized class-level tests yet | ||
public void setup(Class<Node> nodeClass) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: Since Control
is used above, should also be used here and below as Generic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, the code is technically correct since Control extends Node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, just a minor nitpick since relaxing the bounds is not really needed
|
||
public SkinLabeledCleanupTest(Class<Labeled> labeledClass) { | ||
this.labeledClass = labeledClass; | ||
private static Collection<Class> parameters() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: Class<?>
Thank you @Maran23 for taking a look! I'll fix the small things you pointed out; I would rather avoid making more involved structural changes now. Again, thanks! |
@lukostyra @jaybhaskar please review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
@Test(timeout = 1000) | ||
@Test | ||
public void testCloseValues() { | ||
axis.setForceZeroInRange(false); | ||
axis.setSide(Side.LEFT); | ||
double minValue = 1.0; | ||
double maxValue = minValue + Math.ulp(minValue); | ||
NumberAxisShim.autoRange(axis, minValue, maxValue, 500, 50); | ||
assertTimeout(Duration.ofMillis(1000), () -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use the Timeout annotation as : @Timeout(1)
or @Timeout(1000 ms)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, please. I made a similar comment on Draft PR #1569
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, would be good to be consistent, especially now, where we anyway convert everything to JUnit 5 and have the chance to be consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, for some reason I incorrectly decided that Timeout was not applicable. will change to Timeout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went through about 2/3rd of your changes, will continue tomorrow starting from javafx/scene/control/TreeViewKeyInputTest.java
. In the meantime, a couple comments.
import org.junit.Before; | ||
import org.junit.Ignore; | ||
import org.junit.Test; | ||
import org.junit.jupiter.api.Assumptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Minor] Why not import static org.junit.jupiter.api.Assumptions.assumeTrue
? We're directly importing Assertions
this way anyway.
import static org.junit.jupiter.api.Assertions.assertArrayEquals; | ||
import static org.junit.jupiter.api.Assertions.assertTimeout; | ||
import static org.junit.jupiter.api.Assertions.assertNotEquals; | ||
import org.junit.jupiter.api.Assumptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not import static org.junit.jupiter.api.Assumptions.assumeTrue
? We're directly importing Assertions
this way anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a) I do prefer qualifiers, it makes it easier to see where things are coming from
b) but in this case, and in this PR in general, there is a mixture of static imports and class imports - for convenience and speed.
should be ok, it does not change the bytecode.
textInput.setText("The quick brown fox"); | ||
textInput.selectRange(100, 180); | ||
assertEquals("", textInput.getSelectedText()); | ||
} | ||
|
||
// @Test public void selectedTextWorksWhenSelectionIsBound() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test was removed. Shouldn't we keep even commented tests around?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of scope, for this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand. If removing old/commented out tests is out of scope of this PR then why is this one (and others) removed by this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @lukostyra -- we should not be removing any commented out tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that commented out tests have only historical value (or should be removed).
If not, they should be disabled.
If they are commented out, a comment must be added as to why.
in this case, will apply the change to commented out test.
textInput.setText("The quick brown fox"); | ||
textInput.selectRange(44, 99); | ||
assertEquals(new IndexRange(19, 19), textInput.getSelection()); | ||
} | ||
|
||
// @Test public void selectionCanBeBound() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, removed test that was commented out
@@ -605,33 +750,10 @@ public void caretAndAnchorPositionAfterSettingText() { | |||
assertTrue(passed[0]); | |||
} | |||
|
|||
// @Test public void selectionChangeEventsHappenWhenBound() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above
import static org.junit.jupiter.api.Assertions.assertArrayEquals; | ||
import static org.junit.jupiter.api.Assertions.assertTimeout; | ||
import static org.junit.jupiter.api.Assertions.assertNotEquals; | ||
import org.junit.jupiter.api.Assumptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar situation with Assumptions
as earlier
import static org.junit.jupiter.api.Assertions.assertArrayEquals; | ||
import static org.junit.jupiter.api.Assertions.assertTimeout; | ||
import static org.junit.jupiter.api.Assertions.assertNotEquals; | ||
import org.junit.jupiter.api.Assumptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar Assumptions
question/situation
I reviewed the rest of your change, looks good outside of comments above. Will approve once we resolve those. |
@@ -257,72 +257,67 @@ public void checkTickUnitPropertyBind() { | |||
} | |||
|
|||
@Test | |||
@Timeout(value=1000, unit=TimeUnit.MILLISECONDS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: I think the convention is to have spaces around the parameters,
e.g. @Timeout(value = 1000, unit = TimeUnit.MILLISECONDS)
Just scanned the JavaFX code and we seem to be inconsiostent on that, so I will leave that up to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we have a (different) format for annotation arguments, so I've used the function arguments format convention here, no spaces.
One point we could use later is to omit TimeUnit and express the value in seconds, but I kept milliseconds for sake of reviewers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Maran23 is correct about the convention when there is an annotation (or a function call, for that matter) with an embedded parameter assignment. For example, see various @Deprecated
annotations in the JDK and JavaFX.
However, as he pointed out, we are not consistent on that, so I would leave it as is for this PR to avoid more churn.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thank you all for the time and effort reviewing it! |
@arapte plans to review this as the needed "R"eviewer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
/integrate |
Going to push as commit 5171753.
Your commit was automatically rebased without conflicts. |
@andy-goryachev-oracle Pushed as commit 5171753. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Converting control module tests to junit5.
The following notes might help reviewers and people migrating other parts of https://bugs.openjdk.org/browse/JDK-8339170. The direct link to the notes:
https://github.com/andy-goryachev-oracle/Test/blob/main/doc/Tests/JUnit5Migration.md
JUnit5 Migration Notes
Most of the changes are trivial, except for the following:
@BeforeEach
and@AfterEach
: (see discussion below)@ParameterizedTest @MethodSource
Parameterized Class-Level Tests
junit5 does not support parameterized class-level tests yet (see junit-team/junit5#878)
The workaround is to setup each test explicitly by calling the method that used to be annotated with
@Before
in each parameterized test method. There might be another solutions (see, for example, https://stackoverflow.com/questions/62036724/how-to-parameterize-beforeeach-in-junit-5/69265907#69265907) but I thought explicit setup might be simpler to deploy.To summarize:
@Before
from the setup method@Test
withwhere parameters() is a static method which supplies the parameters. In the case when parameters have more than one element, the following code might be useful:
Migration Tricks
Here are the steps that might speed up the process:
junit5 imports (in no particular order):
The following command verifies that there is no junit4 imports and inline fully qualified names:
(thank you @lukostyra @arapte @kevinrushforth !)
Acceptance Criteria
Aside from the standard review process, I think the following criteria should be sufficient:
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1561/head:pull/1561
$ git checkout pull/1561
Update a local copy of the PR:
$ git checkout pull/1561
$ git pull https://git.openjdk.org/jfx.git pull/1561/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1561
View PR using the GUI difftool:
$ git pr show -t 1561
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1561.diff
Webrev
Link to Webrev Comment