-
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
Fixes for #637, making theory parameters assignment more consistent across sources #651
Changes from 4 commits
2ade5fd
cc8497f
e9d4de8
278d76f
b1832b2
3209ce6
ccf0c0a
c60d087
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,9 +5,32 @@ | |
import java.lang.reflect.Method; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Map.Entry; | ||
|
||
public class ParameterSignature { | ||
|
||
@SuppressWarnings("serial") | ||
private static final Map<Class<?>, Class<?>> convertableTypesMap = new HashMap<Class<?>, Class<?>>() {{ | ||
put(boolean.class, Boolean.class); | ||
put(byte.class, Byte.class); | ||
put(short.class, Short.class); | ||
put(char.class, Character.class); | ||
put(int.class, Integer.class); | ||
put(long.class, Long.class); | ||
put(float.class, Float.class); | ||
put(double.class, Double.class); | ||
|
||
// Make all type conversions symmetric | ||
Iterable<Entry<Class<?>, Class<?>>> initialEntries = new HashSet<Entry<Class<?>, Class<?>>>(entrySet()); | ||
for (Entry<Class<?>, Class<?>> entry : initialEntries) { | ||
this.put(entry.getValue(), entry.getKey()); | ||
} | ||
}}; | ||
|
||
public static ArrayList<ParameterSignature> signatures(Method method) { | ||
return signatures(method.getParameterTypes(), method | ||
.getParameterAnnotations()); | ||
|
@@ -42,21 +65,33 @@ public boolean canAcceptValue(Object candidate) { | |
} | ||
|
||
public boolean canAcceptType(Class<?> candidate) { | ||
return type.isAssignableFrom(candidate); | ||
return type.isAssignableFrom(candidate) || | ||
isAssignableViaTypeConversion(type, candidate); | ||
} | ||
|
||
public boolean canPotentiallyAcceptType(Class<?> candidate) { | ||
return candidate.isAssignableFrom(type) || | ||
isAssignableViaTypeConversion(candidate, type) || | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since CONVERTABLE_TYPES_MAP is symmetric, and canAcceptType already checks one direction, we don't have to also check the other direction here, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never mind, I should have re-loaded the code into my wetware memory before commenting. No change needed here. |
||
canAcceptType(candidate); | ||
} | ||
|
||
public Class<?> getType() { | ||
private boolean isAssignableViaTypeConversion(Class<?> targetType, Class<?> candidate) { | ||
if (convertableTypesMap.containsKey(candidate)) { | ||
Class<?> wrapperClass = convertableTypesMap.get(candidate); | ||
return targetType.isAssignableFrom(wrapperClass); | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
public Class<?> getType() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation went weird here? |
||
return type; | ||
} | ||
|
||
public List<Annotation> getAnnotations() { | ||
return Arrays.asList(annotations); | ||
} | ||
|
||
public boolean canAcceptArrayType(Class<?> type) { | ||
return type.isArray() && canAcceptType(type.getComponentType()); | ||
} | ||
|
||
public boolean hasAnnotation(Class<? extends Annotation> type) { | ||
return getAnnotation(type) != null; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,42 @@ | ||
package org.junit.tests.experimental.theories; | ||
|
||
import static org.junit.tests.experimental.theories.TheoryTestUtils.runTheoryClass; | ||
import org.junit.Assert; | ||
import org.junit.Assume; | ||
import org.junit.Test; | ||
import org.junit.experimental.theories.DataPoint; | ||
import org.junit.experimental.theories.Theories; | ||
import org.junit.experimental.theories.Theory; | ||
import org.junit.runner.JUnitCore; | ||
import org.junit.runner.Request; | ||
import org.junit.runner.Result; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runner.Runner; | ||
import org.junit.runners.model.InitializationError; | ||
|
||
@RunWith(Theories.class) | ||
public class AssumingInTheoriesTest { | ||
|
||
@Test | ||
public void noTheoryAnnotationMeansAssumeShouldIgnore() { | ||
Assume.assumeTrue(false); | ||
} | ||
|
||
@Test | ||
public void theoryMeansOnlyAssumeShouldFail() throws InitializationError { | ||
JUnitCore junitRunner = new JUnitCore(); | ||
Runner theoryRunner = new Theories(TheoryWithNoUnassumedParameters.class); | ||
Request request = Request.runner(theoryRunner); | ||
Result result = junitRunner.run(request); | ||
Assert.assertEquals(1, result.getFailureCount()); | ||
} | ||
|
||
/** | ||
* Simple class that SHOULD fail because no parameters are met. | ||
*/ | ||
public static class TheoryWithNoUnassumedParameters { | ||
|
||
@DataPoint | ||
public final static boolean FALSE = false; | ||
|
||
@Theory | ||
public void theoryWithNoUnassumedParameters(boolean value) { | ||
Assume.assumeTrue(value); | ||
} | ||
} | ||
@Test | ||
public void noTheoryAnnotationMeansAssumeShouldIgnore() { | ||
Assume.assumeTrue(false); | ||
} | ||
|
||
@Test | ||
public void theoryMeansOnlyAssumeShouldFail() throws InitializationError { | ||
Result result = runTheoryClass(TheoryWithNoUnassumedParameters.class); | ||
Assert.assertEquals(1, result.getFailureCount()); | ||
} | ||
|
||
/** | ||
* Simple class that SHOULD fail because no parameters are met. | ||
*/ | ||
public static class TheoryWithNoUnassumedParameters { | ||
|
||
@DataPoint | ||
public final static boolean FALSE = false; | ||
|
||
@Theory | ||
public void theoryWithNoUnassumedParameters(boolean value) { | ||
Assume.assumeTrue(value); | ||
} | ||
} | ||
|
||
} |
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 would really prefer that we don't use instance initializers in JUnit. In a constructor like this:
It is very surprising that there is code magically executed between these two lines.
Could we instead do:
As a bonus, 1)
convertableTypeMap()
can return an unmodifiable map and 2) you can remove the@SuppressWarnings("serial")
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, that's nicer, done.