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

Upgrade to Hamcrest 1.3 #404

Merged
merged 29 commits into from
Aug 2, 2012
Merged

Upgrade to Hamcrest 1.3 #404

merged 29 commits into from
Aug 2, 2012

Conversation

marcphilipp
Copy link
Member

  • Matchers in JUnitMatchers that are now provided by hamcrest-core are deprecated.
  • The static methods now delegate to CoreMatchers
  • The four Matcher classes copied from Hamcrest have been deleted.
  • Using CoreMatchers where possible

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.

- 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().
@marcphilipp
Copy link
Member Author

@tradej Can you please take a look?

@tradej
Copy link

tradej commented Mar 22, 2012

@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.

@dsaff
Copy link
Member

dsaff commented Mar 27, 2012

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

@dsaff dsaff mentioned this pull request Mar 27, 2012
@marcphilipp
Copy link
Member Author

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 Matcher<? extends T> to Matcher<? super T>?

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

@marcphilipp
Copy link
Member Author

Regarding #272: We are now using CoreMatchers.both and CoreMatchers.either. Both return a CombinableMatcher which allows calls of and as well as or. So, botheither().and()andboth().or()` would still be possible. This has to be changed in Hamcrest Core IMHO.

Edit: A patch has already been submitted to Hamcrest, http://code.google.com/p/hamcrest/issues/detail?id=154.

@dsaff
Copy link
Member

dsaff commented Mar 28, 2012

@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) {
Copy link
Member

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).

Copy link
Member Author

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).

@dsaff
Copy link
Member

dsaff commented Mar 28, 2012

Thanks for this. A couple comments inline.

@marcphilipp
Copy link
Member Author

I posted a request for feedback to both the JUnit and Hamcrest mailing lists.

@sf105
Copy link

sf105 commented Apr 2, 2012

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.
@marcphilipp
Copy link
Member Author

@dsaff I've found even more code to delete... ;-)

  • The Each (everyItem) matcher is also shipped with Hamcrest core. Therefore, I deprecated it in JUnitMatchers.
  • 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.
  • As pointed out by @sf105, I've used MatcherAssert in Assert.assertThat.

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.
@dsaff
Copy link
Member

dsaff commented Apr 12, 2012

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
@marcphilipp
Copy link
Member Author

@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(
Copy link
Member

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?

Copy link
Member Author

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?

Copy link

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

Copy link
Member

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.

Copy link
Member Author

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.

@dsaff
Copy link
Member

dsaff commented Apr 12, 2012

Looks good in general, pending beta testing.

@StefanPenndorf
Copy link

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
Copy link
Member

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?

Copy link
Member Author

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?

Copy link
Member

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. :-)

@dsaff
Copy link
Member

dsaff commented Jul 19, 2012

This is a lot of great work. Thanks, Marc! Some comments inline.

@sf105
Copy link

sf105 commented Jul 20, 2012

Suggestions:

  • if StacktracePrintingMatcher is useful, then make it accessible. I would call it isException() because withStacktrace() reads like it's asserting against the stacktrace--and what will you call the matcher that does that when you get around to writing it?
  • the alsoHasX() chain is not really in the hamcrest model as it's not a composable API. At the least,

andAlso(hasMessage(equalTo(...))) andAlso(hasCause())))

It looks like ExpectedException is really a matcher builder than a matcher itself.

  • also, hasMessage/hasCause matchers do not report the mismatch, which is the one thing we learned to do, dumping the stack trace isn't always the easiest way to get to the point.

@marcphilipp
Copy link
Member Author

@sf105 I've followed your suggestions. Would you mind taking another look?

@dsaff
Copy link
Member

dsaff commented Jul 20, 2012

Couple more comments. Looking good!

@sf105
Copy link

sf105 commented Jul 22, 2012

Looking better. Thinking that some of this eventually belongs in Hamcrest

@marcphilipp
Copy link
Member Author

@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?

@djh82 djh82 mentioned this pull request Jul 31, 2012
@dsaff
Copy link
Member

dsaff commented Aug 2, 2012

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".

dsaff pushed a commit that referenced this pull request Aug 2, 2012
@dsaff dsaff merged commit 185a219 into junit-team:master Aug 2, 2012
@dsaff
Copy link
Member

dsaff commented Aug 2, 2012

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?

@marcphilipp
Copy link
Member Author

New snapshots are available through Maven and GitHub. I will write an announcement to the JUnit mailing list.

@sf105
Copy link

sf105 commented Aug 5, 2012

Thanks

S.

On 5 Aug 2012, at 07:11, Marc Philipp wrote:

New snapshots are available through Maven and GitHub. I will write an announcement to the JUnit mailing list.

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.

Sync with most recent hamcrest?
9 participants