package org.testory.plumbing.inject;
import static java.lang.String.format;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.testory.plumbing.Maker;
public class TestingMakers {
public static void assertFairDistribution(int expectedUniqueElements, List<?> elements) {
Map<Object, Integer> histogram = histogram(elements);
if (histogram.size() < expectedUniqueElements) {
fail(format("there was %s unique elements, expected at least %s",
histogram.size(), expectedUniqueElements));
}
float averageCount = 1f * elements.size() / histogram.size();
for (float frequency : histogram.values()) {
assertThat(frequency, withinRange(
averageCount / 3,
averageCount * 3));
}
}
private static Map<Object, Integer> histogram(List<?> elements) {
Map<Object, Integer> histogram = new HashMap<>();
for (Object element : elements) {
histogram.put(element, zeroIfNull(histogram.get(element)) + 1);
}
return histogram;
}
private static int zeroIfNull(Integer value) {
return value == null
? 0
: value;
}
public static <T extends Comparable<T>> Matcher<T> withinRange(final T lower, final T upper) {
return new TypeSafeMatcher<T>() {
public void describeTo(Description description) {
description.appendText(format("within range [%s, %s]", lower, upper));
}
protected boolean matchesSafely(T item) {
return lower.compareTo(item) <= 0 && upper.compareTo(item) >= 0;
}
};
}
public static <T> List<T> population(int count, Maker sampler, Class<T> type, String namePrefix) {
List<T> samples = new ArrayList<>();
for (int i = 0; i < count; i++) {
samples.add(sampler.make(type, namePrefix + i));
}
return samples;
}
}