2011-11-01 4 views
13

JodaTime tieneGenerics Hell - ¿Cómo paso un joda.DateTime a Hamcrest Matcher.greaterThan?

public final class DateTime extends BaseDateTime {...} 

la que se abre camino hasta

public interface ReadableInstant extends Comparable<ReadableInstant> 

Hamcrest tiene

public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<? super T> 
    greaterThan(T value) {...} 

Si intento

greaterThan(new DateTime()); 

cuando me siento un error de compilación (Eclipse gi ves más pista)

El método genérico greaterThan (T) de adaptadores de tipo no es aplicable para los argumentos (DateTime). El tipo DateTime inferido no es un sustituto válido para el parámetro acotada>

Estoy en lo cierto al pensar que la firma de greaterThan debe ser en realidad

public static <T extends java.lang.Comparable<? super T>> org.hamcrest.Matcher<? super T>  
    greaterThan(T value) 

? ¿Y hay una manera de encajar estos junto menos de fundición en el Comparable crudo?

+0

Véase también http://stackoverflow.com/questions/6452313/how-to-implement-a-generic-maxcomparable-a-comparable-b-function-in-java –

+0

La [fuente actual de 'OrderingComparison'] (http://code.google.com/p/hamcrest/source/browse/trunk/hamcrest-java/hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparison.java) tiene '> Matcher mayorThan (valor T) '. –

+0

@DavidHarkness - Debo decir que estaba mirando 1.3.0RC1, pero ¿RC2 no solo cambia el tipo de devolución? Es el argumento que no es aceptado. –

Respuesta

16

Sí, me parece que sería una mejor firma.

¿Ha intentado especificar el tipo de comparación explícitamente?

Matchers.<ReadableInstant>greaterThan(new DateTime()); 

no creo que se puede llamar usando una importación estática y también especificar el argumento de tipo, por desgracia - pero eso no puede ser demasiado de dificultad.

Por supuesto es una alternativa a emitir el argumento:

greaterThan((ReadableInstant) new DateTime()); 

no tengo Hamcrest a mano, pero lo anterior funcionó bien para mí el uso de la firma que me había dado, en un tipo de prueba.

+0

No sabía que podía "lanzar" el método, ¡eso abre un nuevo mundo de sintaxis de Java! –

+0

@Duncan No utilizas el método. Especifica el parámetro de tipo de método, por lo que el compilador no tiene que deducirlo del tipo de argumento. –

+0

En realidad es Matchers, no Matcher: (Matchers. greaterThan (DateTime.now()) –

2

Si lo usa a menudo y molesta por la conversión, también se puede implementar su propio Matcher así:

public static Matcher<AbstractPartial> isAfter(final AbstractPartial partial) { 
    return new BaseMatcher<AbstractPartial>(){ 

     @Override 
     public void describeTo(final Description description) { 
      description.appendText("after partial: ").appendValue(partial); 
     } 

     @Override 
     public boolean matches(final Object object) { 
      if (object instanceof AbstractPartial) { 
       return ((LocalDate) object).isAfter(partial); 
      } 
      return false; 
     } 
    }; 
} 

Y probarlo de esta forma:

Set<LocalDate> dates = Sets.newHashSet(new LocalDate(2013, 1, 1), new LocalDate(2013, 1, 2), new LocalDate(
     2013, 1, 3)); 
    assertThat(
     CollectionUtils.isEqualCollection(filter(isAfter(new LocalDate(2013, 1, 1)), dates), 
      Lists.newArrayList(new LocalDate(2013, 1, 2), new LocalDate(2013, 1, 3))), is(true)); 

Si desea utilice DateTime en lugar de LocalDate, simplemente sustituya AbstractPartial con AbstractInstant en la primera lista.