jocarreira / hamcrest

Automatically exported from code.google.com/p/hamcrest
0 stars 0 forks source link

Checked allOf/anyOf (avoid non-reifiable type array) #27

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
In order to avoid the unchecked casts due to the varargs parameter of a
parametrized type in methods anyOf and allOf, provide some overloads

allOf(Matcher<? extends T> matcher1)
allOf(Matcher<? extends T> matcher1, Matcher<? extends T> matcher2)

etc, for 1 to N matchers.

More on the problem here
http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#Why
%20does%20the%20compiler%20sometimes%20issue%20an%20unchecked%20warning%20when%2
0I%20invoke%20a
and at section 6.8 of Java Generics and Collections.

An alternative that seems nicer to my eye is to add 'and' and 'or' methods
to the matchers (implementing them at BaseMatcher, maybe as simple stubs
that delegate to anyOf/allOf). Then boolean expression would look like:

(instanceOf(String.class).or(instanceOf(Integer.class))).and(notNullValue())

Both changes can be implemented in a simple and backwards compatible way.

Original issue reported on code.google.com by carlosjo...@gmail.com on 1 Jan 2008 at 10:46

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Hi, I really like the idea, that you can concatenate matchers via foo().and(...)
and/or bar().or(...) - This makes the code much more readable than using allOf 
and anyOf.

E.g. compare this line:

  assertThat(input, hasAttribute("type", equalTo("checkbox")).and(isNotSelected()));

to this:

  assertThat(input, allOf(hasAttribute("type", equalTo("checkbox")), isNotSelected()));

The first line clearly reads more naturally - like spoken english.

I have attached a patch, which adds this feature to Hamcrest.

Original comment by michael.tamm2 on 27 Feb 2008 at 2:47

Attachments:

GoogleCodeExporter commented 8 years ago
Hi Michael,

it's true, your first line definitely reads more naturally. We did talk about
something like this once before. The problem comes when you want to do 
something like

A and (B or C) 

we thought it would be tricky to get the precedence right. What do you think?

cheers,
--Robert

Original comment by rchatley@gmail.com on 29 Feb 2008 at 2:25

GoogleCodeExporter commented 8 years ago
Yep, precedence would be very tricky.

But when you think about it: How often do you write a statement with AND and OR
together? In natural language this is rarely the case, isn't it?

So I would say, the advantage to be able to write simple logical conjunctions 
with
just  one (or may be two) ANDs is much greater then the problems in the rare 
cases,
when you need to write a rather complex logical statement.

I would even say, that a complex logical statement is especially bad when 
writing
tests, which sould be easy to read!

Original comment by michael.tamm2 on 3 Mar 2008 at 9:27

GoogleCodeExporter commented 8 years ago
We have generally tried to avoid mixing syntaxy stuff directly into matcher 
code.
Instead absrtracting all that stuff out into our own "sugar bowl". However I 
don't
think it's that bad in this scenario as we can just extend BaseMatcher to 
provide the
two methods.

An alternative is to externalize the builder:

when(instanceOf(Foo.class)).and(hasToString("blah"))

where the when() method returns a builder..

Original comment by neild...@gmail.com on 4 Mar 2008 at 9:11

GoogleCodeExporter commented 8 years ago
have added both().and() , and either().or()

Original comment by smgfree...@gmail.com on 15 Oct 2008 at 6:50

GoogleCodeExporter commented 8 years ago

Original comment by smgfree...@gmail.com on 22 Nov 2008 at 12:20