package org.codefx.libfx.collection.transform; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.function.BiPredicate; import java.util.function.ToIntFunction; import junit.framework.JUnit4TestAdapter; import junit.framework.Test; import junit.framework.TestSuite; import org.junit.Before; import com.google.common.collect.testing.SampleElements; import com.google.common.collect.testing.SetTestSuiteBuilder; import com.google.common.collect.testing.TestSetGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.Feature; /** * Tests {@link EqualityTransformingSet}. */ public class EqualityTransformingSetTest { /** * JUnit-3-style method to create the tests run for this class. * * @return the tests to run */ public static Test suite() { TestSuite suite = new TestSuite("org.codefx.libfx.collection.transform.TransformingSet"); suite.addTest(originalEquality()); suite.addTest(lengthBasedEquality()); return suite; } private static Feature<?>[] features() { return new Feature<?>[] { // since 'EqualityTransformingSet' passes all calls along, // the features are determined by the backing data structure (which is a 'HashSet') CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, CollectionFeature.SUPPORTS_ADD, CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionFeature.SUPPORTS_REMOVE, }; } /** * Creates a test which uses hashCode and equals of the original keys. * * @return the test case */ private static Test originalEquality() { return SetTestSuiteBuilder .using(new TransformingSetGenerator(String::equals, String::hashCode)) .named("original equality and hashCode") .withFeatures(features()) .createTestSuite(); } /** * Creates a test which uses hashCode and equals based on the string's lengths. * * @return the test case */ private static Test lengthBasedEquality() { BiPredicate<String, String> equals = (s1, s2) -> s1.length() == s2.length(); ToIntFunction<String> hash = s -> s.length(); Test generalTests = SetTestSuiteBuilder .using(new TransformingSetGenerator(equals, hash)) .named("length-based equality and hashCode - general tests") .withFeatures(features()) .createTestSuite(); TestSuite specificTests = new TestSuite("length-based equality and hashCode - specific tests"); specificTests.addTest(new JUnit4TestAdapter(LengthBasedEqualityAndHashCodeTests.class)); TestSuite tests = new TestSuite("length-based equality and hashCode"); tests.addTest(generalTests); tests.addTest(specificTests); return tests; } /** * Tests {@link EqualityTransformingSet} with a specific set of tests geared towards its special functionality, i.e. * transforming equals and hashCode. */ public static class LengthBasedEqualityAndHashCodeTests { private Set<String> testedSet; private final BiPredicate<String, String> equals = (s1, s2) -> s1.length() == s2.length(); private final ToIntFunction<String> hash = s -> s.length(); @Before @SuppressWarnings("javadoc") public void createSet() { testedSet = EqualityTransformingCollectionBuilder .forType(String.class) .withEquals(equals) .withHash(hash) .buildSet(); } @org.junit.Test @SuppressWarnings("javadoc") public void add_containsWithSameLengthElement_true() { testedSet.add("aaa"); assertTrue(testedSet.contains("bbb")); } } private static class TransformingSetGenerator implements TestSetGenerator<String> { private final BiPredicate<String, String> equals; private final ToIntFunction<String> hash; public TransformingSetGenerator(BiPredicate<String, String> equals, ToIntFunction<String> hash) { this.equals = equals; this.hash = hash; } @Override public Set<String> create(Object... elements) { Set<String> transformingSet = EqualityTransformingCollectionBuilder .forType(String.class) .withEquals(equals) .withHash(hash) .buildSet(); Arrays.stream(elements) .map(String.class::cast) .forEach(transformingSet::add); return transformingSet; } @Override public SampleElements<String> samples() { return new SampleElements<String>("A", "AA", "AAA", "AAAA", "AAAAA"); } @Override public String[] createArray(int length) { return new String[length]; } @Override public Iterable<String> order(List<String> insertionOrder) { return insertionOrder; } } }