-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Upgrade to Hamcrest 1.3 #404
Conversation
- Matchers in JUnitMatchers that are now provided by hamcrest-core are deprecated - Using CoreMatchers where possible *Important:* In some but not all cases, this change will cause compiler errors for people using JUnitMatchers.hasItem(s), both(), and either().
@tradej Can you please take a look? |
@marcphilipp I certainly can and will, but since I don't have any rights in this project, I can't do anything about it. Thank you, though, for the contribution. |
Do we anywhere have a link to the Hamcrest javadoc, so we can reference it from the deprecated comments? This would help resolve whether this patch will resolve issues like #272 |
The reason the methods in JUnitMatchers are deprecated is that these matchers are now provided by Hamcrest Code, i.e. CoreMatchers. Are you looking for the reason Hamcrest changed the signature from Here's a link to the Hamcrest commit where this change was introduced: http://code.google.com/p/hamcrest/source/detail?r=194&path=/trunk/hamcrest-java/hamcrest-library/src/main/java/org/hamcrest/collection/IsCollectionContaining.java |
Regarding #272: We are now using Edit: A patch has already been submitted to Hamcrest, http://code.google.com/p/hamcrest/issues/detail?id=154. |
@marcphilipp, I understand why the methods are deprecated. And I had forgotten that I believe when you run "ant javadoc", javadoc links like {@link CoreMatchers#hasItem(Object)} should work, so scratch that comment. |
import org.hamcrest.BaseMatcher; | ||
import org.hamcrest.Description; | ||
import org.hamcrest.Matcher; | ||
|
||
public class Each { | ||
public static <T> Matcher<Iterable<T>> each(final Matcher<T> individual) { | ||
final Matcher<Iterable<T>> allItemsAre = not(hasItem(not(individual))); | ||
public static <T> Matcher<Iterable<? super T>> each(final Matcher<? super T> individual) { |
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.
Here, and everywhere, I'm trusting you on the typing. I'd recommend you reach out to the junit and hamcrest lists, to get people to compile this with their favorite Java SDKs, to make sure that the generics match up on all compilers (it could be that everything's just that much more standards-compliant than the last time I tried it. If not, there's bound to be someone broken, it seems).
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 changed the signature to be the same as for the hasItem
matcher (which is also used by Each
internally).
Thanks for this. A couple comments inline. |
I posted a request for feedback to both the JUnit and Hamcrest mailing lists. |
for the record, hamcrest java is now in hamcrest/JavaHamcrest on git hub, so you can clone and send us pull requests |
As pointed out by Steve Freeman of Hamcrest, the Matcher interface now has an additional method describeMismatch. To be safe to catch such improvements in the future, MatcherAssert is used instead of duplicating its implementation.
@dsaff I've found even more code to delete... ;-)
Eagerly waiting for your feedback. |
There seems to be a problem compiling calls of the new assertThat(T actual, Matcher<? super T> matcher) using javac and matchers like `hasItem` and `both` that also use `Matcher<? super T>` as parameter.
Marc, It looks like you need to merge with KentBeck/junit/master. Can you do that? Thanks. |
Conflicts: src/main/java/org/junit/rules/ExpectedException.java src/test/java/org/junit/tests/experimental/rules/ExpectedExceptionRuleTest.java
@dsaff Done, merged KentBeck/master. |
assertThat(runner.getFailures().toString(), both(containsString("hereAfter")).and(containsString("inTest"))); | ||
assertThat( | ||
runner.getFailures().toString(), | ||
CoreMatchers.<String> both(containsString("hereAfter")).and( |
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.
Ugh. All of these explicit type parameters still make me think that the typing in hamcrest is more trouble than its worth. What do you think?
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.
Definitely!
As @sf105 has written via email, for both()
a different solution would have been to replace it with allOf()
which javac seems to like better. I did it this way to demonstrate the problem. I could replace it with allOf()
now. What do you think?
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.
On 12 Apr 2012, at 21:56, David Saff wrote:
@@ -143,7 +143,10 @@ public void testTestAndTeardownFailure() throws Exception {
Result runner= core.run(TestAndTeardownFailureTest.class);
assertEquals(1, runner.getRunCount());
assertEquals(2, runner.getFailureCount());
assertThat(runner.getFailures().toString(), both(containsString("hereAfter")).and(containsString("inTest")));
assertThat(
runner.getFailures().toString(),
CoreMatchers.<String> both(containsString("hereAfter")).and(
Ugh. All of these explicit type parameters still make me think that the typing in hamcrest is more trouble than its worth. What do you think?
my point exactly. That's why I use allof() instead of both()
In real life, it works most of the time and I find myself writing little helper methods that often end up improving the code. Anything with typed collections, though, is unpleasant.
S.
Steve Freeman
Winner of the Agile Alliance Gordon Pask award 2006
Book: http://www.growing-object-oriented-software.com
+44 797 179 4105
Twitter: @sf105
Higher Order Logic Limited
Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ.
Company registered in England & Wales. Number 7522677
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.
OK with allOf if it compiles here.
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.
Fixed in latest commit 2d886e2.
Looks good in general, pending beta testing. |
The upgrade from hamcrest 1.1 to hamcrest 1.2 was rejected because hamcrest 1.2 was not fully backwards compatible with hamcrest 1.1 forcing all JUnit users to possibly upgrade their matchers or other code. See Issue #36. Has this incompatibility been resolved? Is hamcrest 1.3 backwards compatible with hamcrest 1.1? Or do you expect the junit users to upgrade their tests and libraries? |
*/ | ||
@Deprecated |
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 delete this one, as well?
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 about deleting it a couple of month ago in a comment:
TypeSafeMatcher is also shipped with Hamcrest core now. I wasn't sure whether I could delete the class right away. Some people might have written custom matchers using it. I know I have... Thus, I decided to leave it as is but deprecate it as well.
Would you rather delete it right away?
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.
No, I think leaving it deprecated makes sense. I've probably reused it, as well. :-)
This is a lot of great work. Thanks, Marc! Some comments inline. |
Suggestions:
andAlso(hasMessage(equalTo(...))) andAlso(hasCause()))) It looks like ExpectedException is really a matcher builder than a matcher itself.
|
Following suggestion by @sf105
@sf105 I've followed your suggestions. Would you mind taking another look? |
Couple more comments. Looking good! |
Looking better. Thinking that some of this eventually belongs in Hamcrest |
@dsaff So, what's the idea for testing and merging this pull request? Should we publish a snapshot release before merging it or first merge it and then publish a beta version/snapshot? |
I'll go through one more review, and merge, and then we'll publish a snapshot for testing. It's easy enough to back up, but I don't want to have an "unofficial branch". |
Thanks, Marc. This was a monster effort, and putting up with my intermittent attention span was no small part of the difficulty. Do you have time to spin up a snapshot for community testing? |
New snapshots are available through Maven and GitHub. I will write an announcement to the JUnit mailing list. |
Thanks S. On 5 Aug 2012, at 07:11, Marc Philipp wrote:
|
Important:
In some but not all cases, this change will cause compile errors for people
using JUnitMatchers.hasItem(s), both(), and either().
Merging this pull request would fix #36.