Permalink
Browse files

more extractors; using ServiceLoader to find others.

  • Loading branch information...
pholser authored and marcphilipp committed Oct 28, 2010
1 parent d021dd2 commit 13d8db710c13e65edaaed4754bfad7056b82a0f1
Showing with 218 additions and 111 deletions.
  1. +5 −0 pom.xml
  2. +10 −0 src/META-INF/services/com.pholser.junit.parameters.extractors.RandomValueExtractor
  3. +0 −13 src/main/java/com/pholser/junit/parameters/ExtractedBy.java
  4. +19 −68 src/main/java/com/pholser/junit/parameters/GeneratingParameterSupplier.java
  5. +0 −5 src/main/java/com/pholser/junit/parameters/RandomValueExtractor.java
  6. +7 −0 src/main/java/com/pholser/junit/parameters/extractors/RandomValueExtractor.java
  7. +7 −0 src/main/java/com/pholser/junit/parameters/extractors/RandomValueExtractorSource.java
  8. +32 −0 src/main/java/com/pholser/junit/parameters/extractors/ServiceLoaderExtractorSource.java
  9. +11 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/BooleanExtractor.java
  10. +11 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/ByteExtractor.java
  11. +11 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/CharacterExtractor.java
  12. +13 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/DateExtractor.java
  13. +11 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/DoubleExtractor.java
  14. +11 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/FloatExtractor.java
  15. +11 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/IntegerExtractor.java
  16. +11 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/LongExtractor.java
  17. +11 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/ShortExtractor.java
  18. +17 −0 src/main/java/com/pholser/junit/parameters/internal/extractors/StringExtractor.java
  19. +2 −2 src/main/java/com/pholser/junit/parameters/{ → random}/AbstractJDKSourceOfRandomness.java
  20. +1 −1 src/main/java/com/pholser/junit/parameters/{ → random}/JDKSourceOfRandomness.java
  21. +1 −1 src/main/java/com/pholser/junit/parameters/{ → random}/SecureJDKSourceOfRandomness.java
  22. +1 −1 src/main/java/com/pholser/junit/parameters/{ → random}/SourceOfRandomness.java
  23. +15 −20 src/test/java/com/pholser/junit/parameters/MarkingTheoryParametersAsForAllTest.java
View
@@ -29,6 +29,11 @@
</developers>
<dependencies>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.5</version>
+ </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@@ -0,0 +1,10 @@
+com.pholser.junit.parameters.internal.extractors.BooleanExtractor
+com.pholser.junit.parameters.internal.extractors.ByteExtractor
+com.pholser.junit.parameters.internal.extractors.CharacterExtractor
+com.pholser.junit.parameters.internal.extractors.DateExtractor
+com.pholser.junit.parameters.internal.extractors.DoubleExtractor
+com.pholser.junit.parameters.internal.extractors.FloatExtractor
+com.pholser.junit.parameters.internal.extractors.IntegerExtractor
+com.pholser.junit.parameters.internal.extractors.LongExtractor
+com.pholser.junit.parameters.internal.extractors.ShortExtractor
+com.pholser.junit.parameters.internal.extractors.StringExtractor
@@ -1,13 +0,0 @@
-package com.pholser.junit.parameters;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-@Target(PARAMETER)
-@Retention(RUNTIME)
-public @interface ExtractedBy {
- Class<? extends RandomValueExtractor> value();
-}
@@ -1,73 +1,38 @@
package com.pholser.junit.parameters;
-import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import com.pholser.junit.parameters.extractors.RandomValueExtractorSource;
+
+import com.pholser.junit.parameters.extractors.ServiceLoaderExtractorSource;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SecureJDKSourceOfRandomness;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
import org.junit.experimental.theories.ParameterSignature;
import org.junit.experimental.theories.ParameterSupplier;
import org.junit.experimental.theories.PotentialAssignment;
-public class GeneratingParameterSupplier extends ParameterSupplier {
- private static final Map<Class<?>, RandomValueExtractor> extractors =
- new HashMap<Class<?>, RandomValueExtractor>();
-
- static {
- extractors.put(int.class, new RandomValueExtractor() {
- @Override
- public Object randomValue(SourceOfRandomness random) {
- return random.nextInt();
- }
- });
- extractors.put(Integer.class, extractors.get(int.class));
- extractors.put(double.class, new RandomValueExtractor() {
- @Override
- public Object randomValue(SourceOfRandomness random) {
- return random.nextDouble();
- }
- });
- extractors.put(Double.class, extractors.get(double.class));
- extractors.put(float.class, new RandomValueExtractor() {
- @Override
- public Object randomValue(SourceOfRandomness random) {
- return random.nextFloat();
- }
- });
- extractors.put(Float.class, extractors.get(float.class));
- extractors.put(boolean.class, new RandomValueExtractor() {
- @Override
- public Object randomValue(SourceOfRandomness random) {
- return random.nextBoolean();
- }
- });
- extractors.put(Boolean.class, extractors.get(boolean.class));
- extractors.put(String.class, new RandomValueExtractor() {
- @Override
- public Object randomValue(SourceOfRandomness random) {
- try {
- return new String(random.nextBytes(16), "US-ASCII");
- } catch (UnsupportedEncodingException ex) {
- throw new AssertionError(ex);
- }
- }
- });
- }
+import static org.apache.commons.lang.ClassUtils.*;
+public class GeneratingParameterSupplier extends ParameterSupplier {
private final SourceOfRandomness random;
+ private final Map<Class<?>, RandomValueExtractor<?>> extractors;
public GeneratingParameterSupplier() {
- this(new SecureJDKSourceOfRandomness());
+ this(new SecureJDKSourceOfRandomness(), new ServiceLoaderExtractorSource());
}
- public GeneratingParameterSupplier(SourceOfRandomness random) {
+ public GeneratingParameterSupplier(SourceOfRandomness random, RandomValueExtractorSource extractorSource) {
this.random = random;
+ extractors = extractorSource.extractors();
}
@Override
public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
- RandomValueExtractor extractor = extractor(sig);
+ RandomValueExtractor<?> extractor = extractor(sig);
int sampleSize = sampleSizeFor(sig);
List<PotentialAssignment> potentials = new ArrayList<PotentialAssignment>();
@@ -79,27 +44,13 @@ public GeneratingParameterSupplier(SourceOfRandomness random) {
}
private static int sampleSizeFor(ParameterSignature sig) {
- Class<?> type = sig.getType();
- if (boolean.class.equals(type) || Boolean.class.equals(type))
- return 2;
return sig.getAnnotation(ForAll.class).sampleSize();
}
- private RandomValueExtractor extractor(ParameterSignature sig) {
- ExtractedBy extractedBy = sig.getAnnotation(ExtractedBy.class);
-
- if (extractedBy != null)
- return instantiate(extractedBy.value());
- return extractors.get(sig.getType());
- }
-
- private RandomValueExtractor instantiate(Class<? extends RandomValueExtractor> type) {
- try {
- return type.newInstance();
- } catch (InstantiationException ex) {
- throw new IllegalStateException(ex);
- } catch (IllegalAccessException ex) {
- throw new IllegalStateException(ex);
- }
+ private RandomValueExtractor<?> extractor(ParameterSignature sig) {
+ Class<?> key = primitiveToWrapper(sig.getType());
+ if (!extractors.containsKey(key))
+ throw new IllegalStateException("Don't know how to generate values of " + sig.getType());
+ return extractors.get(key);
}
}
@@ -1,5 +0,0 @@
-package com.pholser.junit.parameters;
-
-interface RandomValueExtractor {
- Object randomValue(SourceOfRandomness random);
-}
@@ -0,0 +1,7 @@
+package com.pholser.junit.parameters.extractors;
+
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public interface RandomValueExtractor<T> {
+ T randomValue(SourceOfRandomness random);
+}
@@ -0,0 +1,7 @@
+package com.pholser.junit.parameters.extractors;
+
+import java.util.Map;
+
+public interface RandomValueExtractorSource {
+ Map<Class<?>, RandomValueExtractor<?>> extractors();
+}
@@ -0,0 +1,32 @@
+package com.pholser.junit.parameters.extractors;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+public class ServiceLoaderExtractorSource implements RandomValueExtractorSource {
+ @Override
+ public Map<Class<?>, RandomValueExtractor<?>> extractors() {
+ Map<Class<?>, RandomValueExtractor<?>> extractors = new HashMap<Class<?>, RandomValueExtractor<?>>();
+ for (RandomValueExtractor<?> each : ServiceLoader.load(RandomValueExtractor.class))
+ addExtractor(extractors, each);
+ return extractors;
+ }
+
+ private void addExtractor(Map<Class<?>, RandomValueExtractor<?>> extractors,
+ RandomValueExtractor<?> newExtractor) {
+
+ for (Type each : newExtractor.getClass().getGenericInterfaces()) {
+ if (each instanceof ParameterizedType) {
+ ParameterizedType parameterized = (ParameterizedType) each;
+ if (RandomValueExtractor.class.equals(parameterized.getRawType())) {
+ Type typeArgument = parameterized.getActualTypeArguments()[0];
+ if (typeArgument instanceof Class<?>)
+ extractors.put((Class<?>) typeArgument, newExtractor);
+ }
+ }
+ }
+ }
+}
@@ -0,0 +1,11 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class BooleanExtractor implements RandomValueExtractor<Boolean> {
+ @Override
+ public Boolean randomValue(SourceOfRandomness random) {
+ return random.nextBoolean();
+ }
+}
@@ -0,0 +1,11 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class ByteExtractor implements RandomValueExtractor<Byte> {
+ @Override
+ public Byte randomValue(SourceOfRandomness random) {
+ return (byte) random.nextInt();
+ }
+}
@@ -0,0 +1,11 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class CharacterExtractor implements RandomValueExtractor<Character> {
+ @Override
+ public Character randomValue(SourceOfRandomness random) {
+ return (char) random.nextInt();
+ }
+}
@@ -0,0 +1,13 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import java.util.Date;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class DateExtractor implements RandomValueExtractor<Date> {
+ @Override
+ public Date randomValue(SourceOfRandomness random) {
+ return new Date(random.nextLong());
+ }
+}
@@ -0,0 +1,11 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class DoubleExtractor implements RandomValueExtractor<Double> {
+ @Override
+ public Double randomValue(SourceOfRandomness random) {
+ return random.nextDouble();
+ }
+}
@@ -0,0 +1,11 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class FloatExtractor implements RandomValueExtractor<Float> {
+ @Override
+ public Float randomValue(SourceOfRandomness random) {
+ return random.nextFloat();
+ }
+}
@@ -0,0 +1,11 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class IntegerExtractor implements RandomValueExtractor<Integer> {
+ @Override
+ public Integer randomValue(SourceOfRandomness random) {
+ return random.nextInt();
+ }
+}
@@ -0,0 +1,11 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class LongExtractor implements RandomValueExtractor<Long> {
+ @Override
+ public Long randomValue(SourceOfRandomness random) {
+ return random.nextLong();
+ }
+}
@@ -0,0 +1,11 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class ShortExtractor implements RandomValueExtractor<Short> {
+ @Override
+ public Short randomValue(SourceOfRandomness random) {
+ return (short) random.nextInt();
+ }
+}
@@ -0,0 +1,17 @@
+package com.pholser.junit.parameters.internal.extractors;
+
+import java.io.UnsupportedEncodingException;
+
+import com.pholser.junit.parameters.extractors.RandomValueExtractor;
+import com.pholser.junit.parameters.random.SourceOfRandomness;
+
+public class StringExtractor implements RandomValueExtractor<String> {
+ @Override
+ public String randomValue(SourceOfRandomness random) {
+ try {
+ return new String(random.nextBytes(16), "US-ASCII");
+ } catch (UnsupportedEncodingException ex) {
+ throw new AssertionError(ex);
+ }
+ }
+}
@@ -1,8 +1,8 @@
-package com.pholser.junit.parameters;
+package com.pholser.junit.parameters.random;
import java.util.Random;
-public abstract class AbstractJDKSourceOfRandomness implements SourceOfRandomness {
+abstract class AbstractJDKSourceOfRandomness implements SourceOfRandomness {
private final Random random;
protected AbstractJDKSourceOfRandomness(Random random) {
@@ -1,4 +1,4 @@
-package com.pholser.junit.parameters;
+package com.pholser.junit.parameters.random;
import java.util.Random;
@@ -1,4 +1,4 @@
-package com.pholser.junit.parameters;
+package com.pholser.junit.parameters.random;
import java.security.SecureRandom;
@@ -1,4 +1,4 @@
-package com.pholser.junit.parameters;
+package com.pholser.junit.parameters.random;
public interface SourceOfRandomness {
boolean nextBoolean();
Oops, something went wrong.

0 comments on commit 13d8db7

Please sign in to comment.