diff options
author | Paul Duffin <paulduffin@google.com> | 2015-01-23 14:38:46 +0000 |
---|---|---|
committer | Paul Duffin <paulduffin@google.com> | 2015-02-12 20:44:38 +0000 |
commit | 0888a09821a98ac0680fad765217302858e70fa4 (patch) | |
tree | 6f6fc4b017cd2d7870406f435fa44796fb3ac1f1 /guava-tests/test/com | |
parent | 8733ee5d13d66d24cf2cce4f23fc1be2aac2f49e (diff) | |
download | android_external_guava-0888a09821a98ac0680fad765217302858e70fa4.tar.gz android_external_guava-0888a09821a98ac0680fad765217302858e70fa4.tar.bz2 android_external_guava-0888a09821a98ac0680fad765217302858e70fa4.zip |
Upgraded Guava to unmodified jdk5-backport-v17.0-compatibility
This simply copies the Guava source for jdk5-backport-v17.0-compatibility
straight from the github repository into this one.
See https://github.com/google/guava.git
Additional commits will be made which will allow this to compile
on Android.
Change-Id: I07db3bd92bb7370cad9d9b9c9cc4d67733b079b6
Diffstat (limited to 'guava-tests/test/com')
310 files changed, 15012 insertions, 9546 deletions
diff --git a/guava-tests/test/com/google/common/base/AbstractIteratorTest.java b/guava-tests/test/com/google/common/base/AbstractIteratorTest.java index 1d46221..273327b 100644 --- a/guava-tests/test/com/google/common/base/AbstractIteratorTest.java +++ b/guava-tests/test/com/google/common/base/AbstractIteratorTest.java @@ -17,19 +17,21 @@ package com.google.common.base; import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; +import com.google.common.testing.GcFinalization; +import junit.framework.TestCase; + +import java.lang.ref.WeakReference; import java.util.Iterator; import java.util.NoSuchElementException; -import junit.framework.TestCase; - /** * Unit test for {@code AbstractIterator}. * * @author Kevin Bourrillion */ -@SuppressWarnings("serial") // No serialization is used in this test -@GwtCompatible +@GwtCompatible(emulated = true) // TODO(cpovirk): why is this slow (>1m/test) under GWT when fully optimized? public class AbstractIteratorTest extends TestCase { @@ -159,6 +161,17 @@ public class AbstractIteratorTest extends TestCase { } } + @GwtIncompatible("weak references") + public void testFreesNextReference() { + Iterator<Object> itr = new AbstractIterator<Object>() { + @Override public Object computeNext() { + return new Object(); + } + }; + WeakReference<Object> ref = new WeakReference<Object>(itr.next()); + GcFinalization.awaitClear(ref); + } + public void testReentrantHasNext() { Iterator<Integer> iter = new AbstractIterator<Integer>() { @Override protected Integer computeNext() { @@ -174,7 +187,7 @@ public class AbstractIteratorTest extends TestCase { } // Technically we should test other reentrant scenarios (4 combinations of - // hasNext/next), but we'll cop out for now, knowing that + // hasNext/next), but we'll cop out for now, knowing that // next() both start by invoking hasNext() anyway. /** @@ -182,7 +195,7 @@ public class AbstractIteratorTest extends TestCase { */ private static void sneakyThrow(Throwable t) { class SneakyThrower<T extends Throwable> { - @SuppressWarnings("unchecked") // not really safe, but that's the point + @SuppressWarnings("unchecked") // intentionally unsafe for test void throwIt(Throwable t) throws T { throw (T) t; } diff --git a/guava-tests/test/com/google/common/base/AsciiTest.java b/guava-tests/test/com/google/common/base/AsciiTest.java index 579b388..8aaff5e 100644 --- a/guava-tests/test/com/google/common/base/AsciiTest.java +++ b/guava-tests/test/com/google/common/base/AsciiTest.java @@ -39,14 +39,16 @@ public class AsciiTest extends TestCase { public void testToLowerCase() { assertEquals(LOWER, Ascii.toLowerCase(UPPER)); - assertEquals(LOWER, Ascii.toLowerCase(LOWER)); - assertEquals(IGNORED, Ascii.toUpperCase(IGNORED)); + assertSame(LOWER, Ascii.toLowerCase(LOWER)); + assertEquals(IGNORED, Ascii.toLowerCase(IGNORED)); + assertEquals("foobar", Ascii.toLowerCase("fOobaR")); } public void testToUpperCase() { assertEquals(UPPER, Ascii.toUpperCase(LOWER)); - assertEquals(UPPER, Ascii.toUpperCase(UPPER)); + assertSame(UPPER, Ascii.toUpperCase(UPPER)); assertEquals(IGNORED, Ascii.toUpperCase(IGNORED)); + assertEquals("FOOBAR", Ascii.toUpperCase("FoOBAr")); } public void testCharsIgnored() { @@ -78,4 +80,70 @@ public class AsciiTest extends TestCase { assertTrue(str, Ascii.isUpperCase(c)); } } + + public void testTruncate() { + assertEquals("foobar", Ascii.truncate("foobar", 10, "...")); + assertEquals("fo...", Ascii.truncate("foobar", 5, "...")); + assertEquals("foobar", Ascii.truncate("foobar", 6, "...")); + assertEquals("...", Ascii.truncate("foobar", 3, "...")); + assertEquals("foobar", Ascii.truncate("foobar", 10, "…")); + assertEquals("foo…", Ascii.truncate("foobar", 4, "…")); + assertEquals("fo--", Ascii.truncate("foobar", 4, "--")); + assertEquals("foobar", Ascii.truncate("foobar", 6, "…")); + assertEquals("foob…", Ascii.truncate("foobar", 5, "…")); + assertEquals("foo", Ascii.truncate("foobar", 3, "")); + assertEquals("", Ascii.truncate("", 5, "")); + assertEquals("", Ascii.truncate("", 5, "...")); + assertEquals("", Ascii.truncate("", 0, "")); + } + + public void testTruncateIllegalArguments() { + String truncated = null; + try { + truncated = Ascii.truncate("foobar", 2, "..."); + fail(); + } catch (IllegalArgumentException expected) {} + + try { + truncated = Ascii.truncate("foobar", 8, "1234567890"); + fail(); + } catch (IllegalArgumentException expected) {} + + try { + truncated = Ascii.truncate("foobar", -1, "..."); + fail(); + } catch (IllegalArgumentException expected) {} + + try { + truncated = Ascii.truncate("foobar", -1, ""); + fail(); + } catch (IllegalArgumentException expected) {} + } + + public void testEqualsIgnoreCase() { + assertTrue(Ascii.equalsIgnoreCase("", "")); + assertFalse(Ascii.equalsIgnoreCase("", "x")); + assertFalse(Ascii.equalsIgnoreCase("x", "")); + assertTrue(Ascii.equalsIgnoreCase(LOWER, UPPER)); + assertTrue(Ascii.equalsIgnoreCase(UPPER, LOWER)); + // Create new strings here to avoid early-out logic. + assertTrue(Ascii.equalsIgnoreCase(new String(IGNORED), new String(IGNORED))); + // Compare to: "\u00c1".equalsIgnoreCase("\u00e1") == true + assertFalse(Ascii.equalsIgnoreCase("\u00c1", "\u00e1")); + // Test chars just outside the alphabetic range ('A'-1 vs 'a'-1, 'Z'+1 vs 'z'+1) + assertFalse(Ascii.equalsIgnoreCase("@", "`")); + assertFalse(Ascii.equalsIgnoreCase("[", "{")); + } + + public void testEqualsIgnoreCaseUnicodeEquivalence() { + // Note that it's possible in future that the JDK's idea to toUpperCase() or equalsIgnoreCase() + // may change and break assumptions in this test [*]. This is not a bug in the implementation of + // Ascii.equalsIgnoreCase(), but it is a signal that its documentation may need updating as + // regards edge cases. + + // The Unicode point {@code 00df} is the lowercase form of sharp-S (ß), whose uppercase is "SS". + assertEquals("pa\u00dfword".toUpperCase(), "PASSWORD"); // [*] + assertFalse("pa\u00dfword".equalsIgnoreCase("PASSWORD")); // [*] + assertFalse(Ascii.equalsIgnoreCase("pa\u00dfword", "PASSWORD")); + } } diff --git a/guava-tests/test/com/google/common/base/CaseFormatTest.java b/guava-tests/test/com/google/common/base/CaseFormatTest.java index d42bfc4..e900f49 100644 --- a/guava-tests/test/com/google/common/base/CaseFormatTest.java +++ b/guava-tests/test/com/google/common/base/CaseFormatTest.java @@ -25,6 +25,7 @@ import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.testing.NullPointerTester; +import com.google.common.testing.SerializableTester; import junit.framework.TestCase; @@ -186,4 +187,41 @@ public class CaseFormatTest extends TestCase { assertEquals("FOO", UPPER_UNDERSCORE.to(UPPER_UNDERSCORE, "FOO")); assertEquals("FOO_BAR", UPPER_UNDERSCORE.to(UPPER_UNDERSCORE, "FOO_BAR")); } + + public void testConverterToForward() { + assertEquals("FooBar", UPPER_UNDERSCORE.converterTo(UPPER_CAMEL).convert("FOO_BAR")); + assertEquals("fooBar", UPPER_UNDERSCORE.converterTo(LOWER_CAMEL).convert("FOO_BAR")); + assertEquals("FOO_BAR", UPPER_CAMEL.converterTo(UPPER_UNDERSCORE).convert("FooBar")); + assertEquals("FOO_BAR", LOWER_CAMEL.converterTo(UPPER_UNDERSCORE).convert("fooBar")); + } + + public void testConverterToBackward() { + assertEquals("FOO_BAR", UPPER_UNDERSCORE.converterTo(UPPER_CAMEL).reverse().convert("FooBar")); + assertEquals("FOO_BAR", UPPER_UNDERSCORE.converterTo(LOWER_CAMEL).reverse().convert("fooBar")); + assertEquals("FooBar", UPPER_CAMEL.converterTo(UPPER_UNDERSCORE).reverse().convert("FOO_BAR")); + assertEquals("fooBar", LOWER_CAMEL.converterTo(UPPER_UNDERSCORE).reverse().convert("FOO_BAR")); + } + + public void testConverter_nullConversions() { + for (CaseFormat outer : CaseFormat.values()) { + for (CaseFormat inner : CaseFormat.values()) { + assertNull(outer.converterTo(inner).convert(null)); + assertNull(outer.converterTo(inner).reverse().convert(null)); + } + } + } + + public void testConverter_toString() { + assertEquals( + "LOWER_HYPHEN.converterTo(UPPER_CAMEL)", + LOWER_HYPHEN.converterTo(UPPER_CAMEL).toString()); + } + + public void testConverter_serialization() { + for (CaseFormat outer : CaseFormat.values()) { + for (CaseFormat inner : CaseFormat.values()) { + SerializableTester.reserializeAndAssert(outer.converterTo(inner)); + } + } + } } diff --git a/guava-tests/test/com/google/common/base/CharMatcherTest.java b/guava-tests/test/com/google/common/base/CharMatcherTest.java index 2011c18..19dad23 100644 --- a/guava-tests/test/com/google/common/base/CharMatcherTest.java +++ b/guava-tests/test/com/google/common/base/CharMatcherTest.java @@ -16,6 +16,8 @@ package com.google.common.base; +import static com.google.common.base.CharMatcher.BREAKING_WHITESPACE; +import static com.google.common.base.CharMatcher.WHITESPACE; import static com.google.common.base.CharMatcher.anyOf; import static com.google.common.base.CharMatcher.forPredicate; import static com.google.common.base.CharMatcher.inRange; @@ -28,15 +30,15 @@ import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.Sets; import com.google.common.testing.NullPointerTester; +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.BitSet; import java.util.HashSet; import java.util.Random; import java.util.Set; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - /** * Unit test for {@link CharMatcher}. * @@ -78,6 +80,14 @@ public class CharMatcherTest extends TestCase { // The rest of the behavior of ANY and DEFAULT will be covered in the tests for // the text processing methods below. + public void testWhitespaceBreakingWhitespaceSubset() throws Exception { + for (int c = 0; c <= Character.MAX_VALUE; c++) { + if (BREAKING_WHITESPACE.apply((char) c)) { + assertTrue(Integer.toHexString(c), WHITESPACE.apply((char) c)); + } + } + } + // The next tests require ICU4J and have, at least for now, been sliced out // of the open-source view of the tests. @@ -115,6 +125,7 @@ public class CharMatcherTest extends TestCase { doTestSetBits(CharMatcher.ASCII); doTestSetBits(CharMatcher.DIGIT); doTestSetBits(CharMatcher.INVISIBLE); + doTestSetBits(CharMatcher.WHITESPACE); doTestSetBits(inRange('A', 'Z').and(inRange('F', 'K').negate())); } @@ -736,12 +747,21 @@ public class CharMatcherTest extends TestCase { } public void testToString() { - assertEquals("CharMatcher.NONE", CharMatcher.anyOf("").toString()); - assertEquals("CharMatcher.is('\\u0031')", CharMatcher.anyOf("1").toString()); - assertEquals("CharMatcher.anyOf(\"\\u0031\\u0032\")", CharMatcher.anyOf("12").toString()); - assertEquals("CharMatcher.anyOf(\"\\u0031\\u0032\\u0033\")", - CharMatcher.anyOf("321").toString()); - assertEquals("CharMatcher.inRange('\\u0031', '\\u0033')", - CharMatcher.inRange('1', '3').toString()); + assertToStringWorks("CharMatcher.NONE", CharMatcher.anyOf("")); + assertToStringWorks("CharMatcher.is('\\u0031')", CharMatcher.anyOf("1")); + assertToStringWorks("CharMatcher.isNot('\\u0031')", CharMatcher.isNot('1')); + assertToStringWorks("CharMatcher.anyOf(\"\\u0031\\u0032\")", CharMatcher.anyOf("12")); + assertToStringWorks("CharMatcher.anyOf(\"\\u0031\\u0032\\u0033\")", + CharMatcher.anyOf("321")); + assertToStringWorks("CharMatcher.inRange('\\u0031', '\\u0033')", + CharMatcher.inRange('1', '3')); + } + + private static void assertToStringWorks(String expected, CharMatcher matcher) { + assertEquals(expected, matcher.toString()); + assertEquals(expected, matcher.precomputed().toString()); + assertEquals(expected, matcher.negate().negate().toString()); + assertEquals(expected, matcher.negate().precomputed().negate().toString()); + assertEquals(expected, matcher.negate().precomputed().negate().precomputed().toString()); } } diff --git a/guava-tests/test/com/google/common/base/CharsetsTest.java b/guava-tests/test/com/google/common/base/CharsetsTest.java index f76a318..bf0b177 100644 --- a/guava-tests/test/com/google/common/base/CharsetsTest.java +++ b/guava-tests/test/com/google/common/base/CharsetsTest.java @@ -19,10 +19,12 @@ package com.google.common.base; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; -import java.nio.charset.Charset; - import junit.framework.TestCase; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.Arrays; + /** * Unit test for {@link Charsets}. * @@ -59,4 +61,18 @@ public class CharsetsTest extends TestCase { public void testUtf16() { assertEquals(Charset.forName("UTF-16"), Charsets.UTF_16); } + + @GwtIncompatible("Non-UTF-8 Charset") + public void testWhyUsAsciiIsDangerous() throws UnsupportedEncodingException { + byte[] b1 = "朝日新聞".getBytes(Charsets.US_ASCII.name()); + byte[] b2 = "聞朝日新".getBytes(Charsets.US_ASCII.name()); + byte[] b3 = "????".getBytes(Charsets.US_ASCII.name()); + byte[] b4 = "ニュース".getBytes(Charsets.US_ASCII.name()); + byte[] b5 = "スューー".getBytes(Charsets.US_ASCII.name()); + // Assert they are all equal (using the transitive property) + assertTrue(Arrays.equals(b1, b2)); + assertTrue(Arrays.equals(b2, b3)); + assertTrue(Arrays.equals(b3, b4)); + assertTrue(Arrays.equals(b4, b5)); + } } diff --git a/guava-tests/test/com/google/common/base/ConverterTest.java b/guava-tests/test/com/google/common/base/ConverterTest.java new file mode 100644 index 0000000..656721d --- /dev/null +++ b/guava-tests/test/com/google/common/base/ConverterTest.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.base; + +import static com.google.common.base.Functions.toStringFunction; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.primitives.Longs; +import com.google.common.testing.EqualsTester; +import com.google.common.testing.SerializableTester; + +import junit.framework.TestCase; + +import java.util.Iterator; +import java.util.List; + +/** + * Unit tests for {@link Converter}. + */ +@GwtCompatible +public class ConverterTest extends TestCase { + + private static final Converter<String, Long> STR_TO_LONG = + new Converter<String, Long>() { + @Override public Long doForward(String object) { + return Long.valueOf(object); + } + + @Override public String doBackward(Long object) { + return String.valueOf(object); + } + + @Override public String toString() { + return "string2long"; + } + }; + + private static final Long LONG_VAL = 12345L; + private static final String STR_VAL = "12345"; + + private static final ImmutableList<String> STRINGS = ImmutableList.of("123", "456"); + private static final ImmutableList<Long> LONGS = ImmutableList.of(123L, 456L); + + public void testConverter() { + assertEquals(LONG_VAL, STR_TO_LONG.convert(STR_VAL)); + assertEquals(STR_VAL, STR_TO_LONG.reverse().convert(LONG_VAL)); + + Iterable<Long> convertedValues = STR_TO_LONG.convertAll(STRINGS); + assertEquals(LONGS, ImmutableList.copyOf(convertedValues)); + } + + public void testConvertAllIsView() { + List<String> mutableList = Lists.newArrayList("789", "123"); + Iterable<Long> convertedValues = STR_TO_LONG.convertAll(mutableList); + assertEquals(ImmutableList.of(789L, 123L), ImmutableList.copyOf(convertedValues)); + + Iterator<Long> iterator = convertedValues.iterator(); + iterator.next(); + iterator.remove(); + assertEquals(ImmutableList.of("123"), mutableList); + } + + public void testReverse() { + Converter<Long, String> reverseConverter = STR_TO_LONG.reverse(); + + assertEquals(STR_VAL, reverseConverter.convert(LONG_VAL)); + assertEquals(LONG_VAL, reverseConverter.reverse().convert(STR_VAL)); + + Iterable<String> convertedValues = reverseConverter.convertAll(LONGS); + assertEquals(STRINGS, ImmutableList.copyOf(convertedValues)); + + assertSame(STR_TO_LONG, reverseConverter.reverse()); + + assertEquals("string2long.reverse()", reverseConverter.toString()); + + new EqualsTester() + .addEqualityGroup(STR_TO_LONG, STR_TO_LONG.reverse().reverse()) + .addEqualityGroup(STR_TO_LONG.reverse(), STR_TO_LONG.reverse()) + .testEquals(); + } + + public void testReverseReverse() { + Converter<String, Long> converter = STR_TO_LONG; + assertEquals(converter, converter.reverse().reverse()); + } + + public void testApply() { + assertEquals(LONG_VAL, STR_TO_LONG.apply(STR_VAL)); + } + + private static class StringWrapper { + private final String value; + + public StringWrapper(String value) { + this.value = value; + } + } + + public void testAndThen() { + Converter<StringWrapper, String> first = new Converter<StringWrapper, String>() { + @Override public String doForward(StringWrapper object) { + return object.value; + } + + @Override public StringWrapper doBackward(String object) { + return new StringWrapper(object); + } + + @Override public String toString() { + return "StringWrapper"; + } + }; + + Converter<StringWrapper, Long> converter = first.andThen(STR_TO_LONG); + + assertEquals(LONG_VAL, converter.convert(new StringWrapper(STR_VAL))); + assertEquals(STR_VAL, converter.reverse().convert(LONG_VAL).value); + + assertEquals("StringWrapper.andThen(string2long)", converter.toString()); + + assertEquals(first.andThen(STR_TO_LONG), first.andThen(STR_TO_LONG)); + } + + public void testIdentityConverter() { + Converter<String, String> stringIdentityConverter = Converter.identity(); + + assertSame(stringIdentityConverter, stringIdentityConverter.reverse()); + assertSame(STR_TO_LONG, stringIdentityConverter.andThen(STR_TO_LONG)); + + assertSame(STR_VAL, stringIdentityConverter.convert(STR_VAL)); + assertSame(STR_VAL, stringIdentityConverter.reverse().convert(STR_VAL)); + + assertEquals("Converter.identity()", stringIdentityConverter.toString()); + + assertSame(Converter.identity(), Converter.identity()); + } + + public void testFrom() { + Function<String, Integer> forward = new Function<String, Integer>() { + @Override public Integer apply(String input) { + return Integer.parseInt(input); + } + }; + Function<Object, String> backward = toStringFunction(); + + Converter<String, Number> converter = Converter.<String, Number>from(forward, backward); + + assertNull(converter.convert(null)); + assertNull(converter.reverse().convert(null)); + + assertEquals((Integer) 5, converter.convert("5")); + assertEquals("5", converter.reverse().convert(5)); + } + + public void testNullIsPassedThrough() { + Converter<String, String> nullsArePassed = sillyConverter(false); + assertEquals("forward", nullsArePassed.convert("foo")); + assertEquals("forward", nullsArePassed.convert(null)); + assertEquals("backward", nullsArePassed.reverse().convert("foo")); + assertEquals("backward", nullsArePassed.reverse().convert(null)); + } + + public void testNullIsNotPassedThrough() { + Converter<String, String> nullsAreHandled = sillyConverter(true); + assertEquals("forward", nullsAreHandled.convert("foo")); + assertEquals(null, nullsAreHandled.convert(null)); + assertEquals("backward", nullsAreHandled.reverse().convert("foo")); + assertEquals(null, nullsAreHandled.reverse().convert(null)); + } + + private static Converter<String, String> sillyConverter(final boolean handleNullAutomatically) { + return new Converter<String, String>(handleNullAutomatically) { + @Override public String doForward(String string) { + return "forward"; + } + @Override public String doBackward(String string) { + return "backward"; + } + }; + } + + public void testSerialization_identity() { + Converter<String, String> identityConverter = Converter.identity(); + SerializableTester.reserializeAndAssert(identityConverter); + } + + public void testSerialization_reverse() { + Converter<Long, String> reverseConverter = Longs.stringConverter().reverse(); + SerializableTester.reserializeAndAssert(reverseConverter); + } + + public void testSerialization_andThen() { + Converter<String, Long> converterA = Longs.stringConverter(); + Converter<Long, String> reverseConverter = Longs.stringConverter().reverse(); + Converter<String, String> composedConverter = converterA.andThen(reverseConverter); + SerializableTester.reserializeAndAssert(composedConverter); + } + + public void testSerialization_from() { + Converter<String, String> dumb = Converter.from(toStringFunction(), toStringFunction()); + SerializableTester.reserializeAndAssert(dumb); + } +} diff --git a/guava-tests/test/com/google/common/base/EnumsTest.java b/guava-tests/test/com/google/common/base/EnumsTest.java index ada1b13..c85455c 100644 --- a/guava-tests/test/com/google/common/base/EnumsTest.java +++ b/guava-tests/test/com/google/common/base/EnumsTest.java @@ -18,15 +18,21 @@ package com.google.common.base; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; +import com.google.common.collect.ImmutableSet; import com.google.common.testing.EqualsTester; +import com.google.common.testing.GcFinalization; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; import java.lang.reflect.Field; - -import junit.framework.TestCase; +import java.net.URLClassLoader; +import java.util.HashSet; +import java.util.Set; /** * Tests for {@link Enums}. @@ -101,6 +107,86 @@ public class EnumsTest extends TestCase { assertEquals(Optional.absent(), Enums.getIfPresent(TestEnum.class, "WOMBAT")); } + @GwtIncompatible("weak references") + public void testGetIfPresent_doesNotPreventClassUnloading() throws Exception { + WeakReference<?> shadowLoaderReference = doTestClassUnloading(); + GcFinalization.awaitClear(shadowLoaderReference); + } + + // Create a second ClassLoader and use it to get a second version of the TestEnum class. + // Run Enums.getIfPresent on that other TestEnum and then return a WeakReference containing the + // new ClassLoader. If Enums.getIfPresent does caching that prevents the shadow TestEnum + // (and therefore its ClassLoader) from being unloaded, then this WeakReference will never be + // cleared. + @GwtIncompatible("weak references") + private WeakReference<?> doTestClassUnloading() throws Exception { + URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader(); + URLClassLoader shadowLoader = new URLClassLoader(myLoader.getURLs(), null); + @SuppressWarnings("unchecked") + Class<TestEnum> shadowTestEnum = + (Class<TestEnum>) Class.forName(TestEnum.class.getName(), false, shadowLoader); + assertNotSame(shadowTestEnum, TestEnum.class); + Set<TestEnum> shadowConstants = new HashSet<TestEnum>(); + for (TestEnum constant : TestEnum.values()) { + Optional<TestEnum> result = Enums.getIfPresent(shadowTestEnum, constant.name()); + assertTrue(result.isPresent()); + shadowConstants.add(result.get()); + } + assertEquals(ImmutableSet.copyOf(shadowTestEnum.getEnumConstants()), shadowConstants); + Optional<TestEnum> result = Enums.getIfPresent(shadowTestEnum, "blibby"); + assertFalse(result.isPresent()); + return new WeakReference<ClassLoader>(shadowLoader); + } + + public void testStringConverter_convert() { + Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); + assertEquals(TestEnum.CHEETO, converter.convert("CHEETO")); + assertEquals(TestEnum.HONDA, converter.convert("HONDA")); + assertEquals(TestEnum.POODLE, converter.convert("POODLE")); + assertNull(converter.convert(null)); + assertNull(converter.reverse().convert(null)); + } + + public void testStringConverter_convertError() { + Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); + try { + converter.convert("xxx"); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testStringConverter_reverse() { + Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); + assertEquals("CHEETO", converter.reverse().convert(TestEnum.CHEETO)); + assertEquals("HONDA", converter.reverse().convert(TestEnum.HONDA)); + assertEquals("POODLE", converter.reverse().convert(TestEnum.POODLE)); + } + + @GwtIncompatible("NullPointerTester") + public void testStringConverter_nullPointerTester() throws Exception { + Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicInstanceMethods(converter); + } + + public void testStringConverter_nullConversions() { + Converter<String, TestEnum> converter = Enums.stringConverter(TestEnum.class); + assertNull(converter.convert(null)); + assertNull(converter.reverse().convert(null)); + } + + @GwtIncompatible("Class.getName()") + public void testStringConverter_toString() { + assertEquals( + "Enums.stringConverter(com.google.common.base.EnumsTest$TestEnum.class)", + Enums.stringConverter(TestEnum.class).toString()); + } + + public void testStringConverter_serialization() { + SerializableTester.reserializeAndAssert(Enums.stringConverter(TestEnum.class)); + } + @GwtIncompatible("NullPointerTester") public void testNullPointerExceptions() { NullPointerTester tester = new NullPointerTester(); diff --git a/guava-tests/test/com/google/common/base/EquivalenceTest.java b/guava-tests/test/com/google/common/base/EquivalenceTest.java index cced838..8649d86 100644 --- a/guava-tests/test/com/google/common/base/EquivalenceTest.java +++ b/guava-tests/test/com/google/common/base/EquivalenceTest.java @@ -34,8 +34,7 @@ import junit.framework.TestCase; */ @GwtCompatible(emulated = true) public class EquivalenceTest extends TestCase { - - @SuppressWarnings("unchecked") // Iterable<String>... + @SuppressWarnings("unchecked") // varargs public void testPairwiseEquivalent() { EquivalenceTester.of(Equivalence.equals().<String>pairwise()) .addEquivalenceGroup(ImmutableList.<String>of()) diff --git a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java index d1f2fd5..7f498b6 100644 --- a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java +++ b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java @@ -119,19 +119,15 @@ public class FinalizableReferenceQueueClassLoaderUnloadingTest extends TestCase // Now make a parallel FRQ and an associated FinalizableWeakReference to an object, in order to // exercise some classes from the parallel ClassLoader. AtomicReference<Object> sepFrqA = new AtomicReference<Object>(sepFrqC.newInstance()); - @SuppressWarnings("unchecked") - Class<? extends WeakReference<?>> sepFwrC = (Class<? extends WeakReference<?>>) - sepLoader.loadClass(MyFinalizableWeakReference.class.getName()); - Constructor<? extends WeakReference<?>> sepFwrCons = - sepFwrC.getConstructor(Object.class, sepFrqC); + Class<?> sepFwrC = sepLoader.loadClass(MyFinalizableWeakReference.class.getName()); + Constructor<?> sepFwrCons = sepFwrC.getConstructor(Object.class, sepFrqC); // The object that we will wrap in FinalizableWeakReference is a Stopwatch. Class<?> sepStopwatchC = sepLoader.loadClass(Stopwatch.class.getName()); assertSame(sepLoader, sepStopwatchC.getClassLoader()); AtomicReference<Object> sepStopwatchA = - new AtomicReference<Object>(sepStopwatchC.newInstance()); - AtomicReference<WeakReference<?>> sepStopwatchRef = - new AtomicReference<WeakReference<?>>( - sepFwrCons.newInstance(sepStopwatchA.get(), sepFrqA.get())); + new AtomicReference<Object>(sepStopwatchC.getMethod("createUnstarted").invoke(null)); + AtomicReference<WeakReference<?>> sepStopwatchRef = new AtomicReference<WeakReference<?>>( + (WeakReference<?>) sepFwrCons.newInstance(sepStopwatchA.get(), sepFrqA.get())); assertNotNull(sepStopwatchA.get()); // Clear all references to the Stopwatch and wait for it to be gc'd. sepStopwatchA.set(null); @@ -237,10 +233,8 @@ public class FinalizableReferenceQueueClassLoaderUnloadingTest extends TestCase assertNotSame(frqUserC, sepFrqUserC); assertSame(sepLoader, sepFrqUserC.getClassLoader()); - @SuppressWarnings("unchecked") - Callable<WeakReference<Object>> sepFrqUser = - (Callable<WeakReference<Object>>) sepFrqUserC.newInstance(); - WeakReference<Object> finalizableWeakReference = sepFrqUser.call(); + Callable<?> sepFrqUser = (Callable<?>) sepFrqUserC.newInstance(); + WeakReference<?> finalizableWeakReference = (WeakReference<?>) sepFrqUser.call(); GcFinalization.awaitClear(finalizableWeakReference); diff --git a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java index 1064cc0..de52bbe 100644 --- a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java +++ b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java @@ -19,12 +19,14 @@ package com.google.common.base; import com.google.common.base.internal.Finalizer; import com.google.common.testing.GcFinalization; +import junit.framework.TestCase; + import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.net.URL; import java.net.URLClassLoader; - -import junit.framework.TestCase; +import java.util.Arrays; +import java.util.Collections; /** * Unit test for {@link FinalizableReferenceQueue}. @@ -45,7 +47,6 @@ public class FinalizableReferenceQueueTest extends TestCase { frq = new FinalizableReferenceQueue()); GcFinalization.awaitDone(new GcFinalization.FinalizationPredicate() { - @Override public boolean isDone() { return reference.finalizeReferentCalled; } @@ -148,4 +149,10 @@ public class FinalizableReferenceQueueTest extends TestCase { public void testGetFinalizerUrl() { assertNotNull(getClass().getResource("internal/Finalizer.class")); } + + public void testFinalizeClassHasNoNestedClases() throws Exception { + // Ensure that the Finalizer class has no nested classes. + // See https://code.google.com/p/guava-libraries/issues/detail?id=1505 + assertEquals(Collections.emptyList(), Arrays.asList(Finalizer.class.getDeclaredClasses())); + } } diff --git a/guava-tests/test/com/google/common/base/FunctionsTest.java b/guava-tests/test/com/google/common/base/FunctionsTest.java index 0db53cb..cc7b4f2 100644 --- a/guava-tests/test/com/google/common/base/FunctionsTest.java +++ b/guava-tests/test/com/google/common/base/FunctionsTest.java @@ -25,11 +25,11 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.io.Serializable; import java.util.Map; -import junit.framework.TestCase; - /** * Tests for {@link Functions}. * diff --git a/guava-tests/test/com/google/common/base/JoinerTest.java b/guava-tests/test/com/google/common/base/JoinerTest.java index 5ab3ee7..169313e 100644 --- a/guava-tests/test/com/google/common/base/JoinerTest.java +++ b/guava-tests/test/com/google/common/base/JoinerTest.java @@ -27,14 +27,15 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.testing.NullPointerTester; +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + import java.io.IOException; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.Set; -import junit.framework.TestCase; - /** * Unit test for {@link Joiner}. * @@ -210,47 +211,6 @@ public class JoinerTest extends TestCase { } } - public void testIterableIterator() { - Joiner onChar = Joiner.on('-'); - checkIterableIterator(onChar, "1-2-3-4"); - - Joiner skipNulls = J.skipNulls(); - checkIterableIterator(skipNulls, "1-2-3-4"); - - Joiner zeroForNull = J.useForNull("0"); - checkIterableIterator(zeroForNull, "1-2-3-4"); - } - - private static void checkIterableIterator(Joiner joiner, String expected) { - assertEquals(expected, joiner.join(new IterableIterator())); - - StringBuilder sb1 = new StringBuilder().append('x'); - joiner.appendTo(sb1, new IterableIterator()); - assertEquals("x" + expected, sb1.toString()); - - Integer[] partsArray = - Lists.newArrayList(new IterableIterator().iterator()).toArray(new Integer[0]); - assertEquals(expected, joiner.join(partsArray)); - - StringBuilder sb2 = new StringBuilder().append('x'); - joiner.appendTo(sb2, partsArray); - assertEquals("x" + expected, sb2.toString()); - - int num = partsArray.length - 2; - if (num >= 0) { - Object[] rest = new Integer[num]; - for (int i = 0; i < num; i++) { - rest[i] = partsArray[i + 2]; - } - - assertEquals(expected, joiner.join(partsArray[0], partsArray[1], rest)); - - StringBuilder sb3 = new StringBuilder().append('x'); - joiner.appendTo(sb3, partsArray[0], partsArray[1], rest); - assertEquals("x" + expected, sb3.toString()); - } - } - public void test_useForNull_skipNulls() { Joiner j = Joiner.on("x").useForNull("y"); try { @@ -338,7 +298,7 @@ public class JoinerTest extends TestCase { assertEquals("1:2;1:3;3:4;5:6;5:10", sb2.toString()); } - @SuppressWarnings("ReturnValueIgnored") + @SuppressWarnings("ReturnValueIgnored") // testing for exception public void test_skipNulls_onMap() { Joiner j = Joiner.on(",").skipNulls(); try { @@ -362,8 +322,7 @@ public class JoinerTest extends TestCase { return "foo".subSequence(start, end); } @Override public String toString() { - fail("shouldn't be invoked"); - return null; + throw new AssertionFailedError("shouldn't be invoked"); } } diff --git a/guava-tests/test/com/google/common/base/ObjectsTest.java b/guava-tests/test/com/google/common/base/ObjectsTest.java index f5d0899..c8de82b 100644 --- a/guava-tests/test/com/google/common/base/ObjectsTest.java +++ b/guava-tests/test/com/google/common/base/ObjectsTest.java @@ -29,6 +29,7 @@ import junit.framework.TestCase; */ @GwtCompatible(emulated = true) public class ObjectsTest extends TestCase { + public void testEqual() throws Exception { assertTrue(Objects.equal(1, 1)); assertTrue(Objects.equal(null, null)); @@ -46,8 +47,8 @@ public class ObjectsTest extends TestCase { public void testHashCode() throws Exception { int h1 = Objects.hashCode(1, "two", 3.0); - int h2 = Objects.hashCode(new Integer(1), new String("two"), - new Double(3.0)); + int h2 = Objects.hashCode( + new Integer(1), new String("two"), new Double(3.0)); // repeatable assertEquals(h1, h2); diff --git a/guava-tests/test/com/google/common/base/OptionalTest.java b/guava-tests/test/com/google/common/base/OptionalTest.java index 6698b99..113e331 100644 --- a/guava-tests/test/com/google/common/base/OptionalTest.java +++ b/guava-tests/test/com/google/common/base/OptionalTest.java @@ -25,14 +25,12 @@ import com.google.common.collect.ImmutableList; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.util.Collections; import java.util.List; import java.util.Set; -import junit.framework.TestCase; - -import org.truth0.subjects.IterableSubject; - /** * Unit test for {@link Optional}. * @@ -53,7 +51,8 @@ public final class OptionalTest extends TestCase { try { Optional.of(null); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testFromNullable() { @@ -79,7 +78,8 @@ public final class OptionalTest extends TestCase { try { optional.get(); fail(); - } catch (IllegalStateException expected) {} + } catch (IllegalStateException expected) { + } } public void testGet_present() { @@ -108,7 +108,8 @@ public final class OptionalTest extends TestCase { try { absentOptional.or(nullSupplier); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testOr_nullSupplier_present() { @@ -146,7 +147,8 @@ public final class OptionalTest extends TestCase { try { presentAsSet.add("b"); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } } public void testAsSet_absentIsImmutable() { @@ -154,7 +156,8 @@ public final class OptionalTest extends TestCase { try { absentAsSet.add("foo"); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } } public void testTransform_absent() { @@ -172,23 +175,25 @@ public final class OptionalTest extends TestCase { public void testTransform_present_functionReturnsNull() { try { - Optional.of("a").transform(new Function<String, String>() { - @Override - public String apply(String input) { - return null; - } - }); + Optional.of("a").transform( + new Function<String, String>() { + @Override public String apply(String input) { + return null; + } + }); fail("Should throw if Function returns null."); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testTransform_abssent_functionReturnsNull() { - assertEquals(Optional.absent(), Optional.absent().transform(new Function<Object, Object>() { - @Override - public Object apply(Object input) { - return null; - } - })); + assertEquals(Optional.absent(), + Optional.absent().transform( + new Function<Object, Object>() { + @Override public Object apply(Object input) { + return null; + } + })); } // TODO(kevinb): use EqualsTester @@ -214,35 +219,36 @@ public final class OptionalTest extends TestCase { } public void testPresentInstances_allPresent() { - List<Optional<String>> optionals = ImmutableList.of(Optional.of("a"), Optional.of("b"), - Optional.of("c")); - assertThat(Optional.presentInstances(optionals)).iteratesOverSequence("a", "b", "c"); + List<Optional<String>> optionals = + ImmutableList.of(Optional.of("a"), Optional.of("b"), Optional.of("c")); + ASSERT.that(Optional.presentInstances(optionals)).iteratesOverSequence("a", "b", "c"); } public void testPresentInstances_allAbsent() { - List<Optional<Object>> optionals = ImmutableList.of(Optional.absent(), Optional.absent()); - assertThat(Optional.presentInstances(optionals)).isEmpty(); + List<Optional<Object>> optionals = + ImmutableList.of(Optional.absent(), Optional.absent()); + ASSERT.that(Optional.presentInstances(optionals)).isEmpty(); } public void testPresentInstances_somePresent() { - List<Optional<String>> optionals = ImmutableList.of(Optional.of("a"), - Optional.<String>absent(), Optional.of("c")); - assertThat(Optional.presentInstances(optionals)).iteratesOverSequence("a", "c"); + List<Optional<String>> optionals = + ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c")); + ASSERT.that(Optional.presentInstances(optionals)).iteratesOverSequence("a", "c"); } public void testPresentInstances_callingIteratorTwice() { - List<Optional<String>> optionals = ImmutableList.of(Optional.of("a"), - Optional.<String>absent(), Optional.of("c")); + List<Optional<String>> optionals = + ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c")); Iterable<String> onlyPresent = Optional.presentInstances(optionals); - assertThat(onlyPresent).iteratesOverSequence("a", "c"); - assertThat(onlyPresent).iteratesOverSequence("a", "c"); + ASSERT.that(onlyPresent).iteratesOverSequence("a", "c"); + ASSERT.that(onlyPresent).iteratesOverSequence("a", "c"); } public void testPresentInstances_wildcards() { - List<Optional<? extends Number>> optionals = ImmutableList.<Optional<? extends Number>>of( - Optional.<Double>absent(), Optional.of(2)); + List<Optional<? extends Number>> optionals = + ImmutableList.<Optional<? extends Number>>of(Optional.<Double>absent(), Optional.of(2)); Iterable<Number> onlyPresent = Optional.presentInstances(optionals); - assertThat(onlyPresent).iteratesOverSequence(2); + ASSERT.that(onlyPresent).iteratesOverSequence(2); } private static Optional<Integer> getSomeOptionalInt() { @@ -258,28 +264,32 @@ public final class OptionalTest extends TestCase { * mentioned in the method Javadoc does in fact compile. */ + @SuppressWarnings("unused") // compilation test public void testSampleCodeError1() { Optional<Integer> optionalInt = getSomeOptionalInt(); // Number value = optionalInt.or(0.5); // error } + @SuppressWarnings("unused") // compilation test public void testSampleCodeError2() { FluentIterable<? extends Number> numbers = getSomeNumbers(); Optional<? extends Number> first = numbers.first(); // Number value = first.or(0.5); // error } - @SuppressWarnings("unchecked") - // safe covariant cast + @SuppressWarnings("unused") // compilation test public void testSampleCodeFine1() { - Optional<Number> optionalInt = (Optional) getSomeOptionalInt(); + Optional<Number> optionalInt = Optional.of((Number) 1); Number value = optionalInt.or(0.5); // fine } - @SuppressWarnings("unchecked") - // safe covariant cast + @SuppressWarnings("unused") // compilation test public void testSampleCodeFine2() { FluentIterable<? extends Number> numbers = getSomeNumbers(); + + // Sadly, the following is what users will have to do in some circumstances. + + @SuppressWarnings("unchecked") // safe covariant cast Optional<Number> first = (Optional) numbers.first(); Number value = first.or(0.5); // fine } @@ -298,10 +308,4 @@ public final class OptionalTest extends TestCase { npTester.testAllPublicInstanceMethods(Optional.absent()); npTester.testAllPublicInstanceMethods(Optional.of("training")); } - - // Hack for JDK5 type inference. - private static <T> IterableSubject<? extends IterableSubject<?, T, Iterable<T>>, T, Iterable<T>> assertThat( - Iterable<T> collection) { - return ASSERT.<T, Iterable<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/base/PreconditionsTest.java b/guava-tests/test/com/google/common/base/PreconditionsTest.java index c3f8c98..df44a3f 100644 --- a/guava-tests/test/com/google/common/base/PreconditionsTest.java +++ b/guava-tests/test/com/google/common/base/PreconditionsTest.java @@ -20,6 +20,7 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.testing.NullPointerTester; +import junit.framework.AssertionFailedError; import junit.framework.TestCase; /** @@ -347,8 +348,7 @@ public class PreconditionsTest extends TestCase { private static final Object IGNORE_ME = new Object() { @Override public String toString() { - fail(); - return null; + throw new AssertionFailedError(); } }; diff --git a/guava-tests/test/com/google/common/base/PredicatesTest.java b/guava-tests/test/com/google/common/base/PredicatesTest.java index 33edbc6..3864dda 100644 --- a/guava-tests/test/com/google/common/base/PredicatesTest.java +++ b/guava-tests/test/com/google/common/base/PredicatesTest.java @@ -17,6 +17,7 @@ package com.google.common.base; import static com.google.common.base.CharMatcher.WHITESPACE; +import static com.google.common.collect.Lists.newArrayList; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -26,6 +27,9 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -35,8 +39,6 @@ import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; -import junit.framework.TestCase; - /** * Unit test for {@link Predicates}. * @@ -50,8 +52,8 @@ public class PredicatesTest extends TestCase { new Predicate<Integer>() { @Override public boolean apply(Integer i) { - fail("This predicate should never have been evaluated"); - return false; + throw new AssertionFailedError( + "This predicate should never have been evaluated"); } }; @@ -178,12 +180,12 @@ public class PredicatesTest extends TestCase { * Tests for all the different flavors of Predicates.and(). */ - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_applyNoArgs() { assertEvalsToTrue(Predicates.and()); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_equalityNoArgs() { new EqualsTester() .addEqualityGroup(Predicates.and(), Predicates.and()) @@ -193,17 +195,17 @@ public class PredicatesTest extends TestCase { } @GwtIncompatible("SerializableTester") - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_serializationNoArgs() { checkSerialization(Predicates.and()); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_applyOneArg() { assertEvalsLikeOdd(Predicates.and(isOdd())); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_equalityOneArg() { Object[] notEqualObjects = {Predicates.and(NEVER_REACHED, FALSE)}; new EqualsTester() @@ -217,7 +219,7 @@ public class PredicatesTest extends TestCase { } @GwtIncompatible("SerializableTester") - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_serializationOneArg() { checkSerialization(Predicates.and(isOdd())); } @@ -228,7 +230,7 @@ public class PredicatesTest extends TestCase { assertEvalsToFalse(Predicates.and(FALSE, NEVER_REACHED)); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_equalityBinary() { new EqualsTester() .addEqualityGroup( @@ -245,7 +247,7 @@ public class PredicatesTest extends TestCase { checkSerialization(Predicates.and(TRUE, isOdd())); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_applyTernary() { assertEvalsLikeOdd(Predicates.and(isOdd(), TRUE, TRUE)); assertEvalsLikeOdd(Predicates.and(TRUE, isOdd(), TRUE)); @@ -253,7 +255,7 @@ public class PredicatesTest extends TestCase { assertEvalsToFalse(Predicates.and(TRUE, FALSE, NEVER_REACHED)); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_equalityTernary() { new EqualsTester() .addEqualityGroup( @@ -266,12 +268,12 @@ public class PredicatesTest extends TestCase { } @GwtIncompatible("SerializableTester") - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_serializationTernary() { checkSerialization(Predicates.and(TRUE, isOdd(), FALSE)); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_applyIterable() { Collection<Predicate<Integer>> empty = Arrays.asList(); assertEvalsToTrue(Predicates.and(empty)); @@ -280,7 +282,7 @@ public class PredicatesTest extends TestCase { assertEvalsToFalse(Predicates.and(Arrays.asList(FALSE, NEVER_REACHED))); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_equalityIterable() { new EqualsTester() .addEqualityGroup( @@ -293,12 +295,12 @@ public class PredicatesTest extends TestCase { } @GwtIncompatible("SerializableTester") - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_serializationIterable() { checkSerialization(Predicates.and(Arrays.asList(TRUE, FALSE))); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testAnd_arrayDefensivelyCopied() { Predicate[] array = {Predicates.alwaysFalse()}; Predicate<Object> predicate = Predicates.and(array); @@ -307,21 +309,19 @@ public class PredicatesTest extends TestCase { assertFalse(predicate.apply(1)); } - @SuppressWarnings("unchecked") public void testAnd_listDefensivelyCopied() { - List list = new ArrayList<Predicate>(); + List<Predicate<Object>> list = newArrayList(); Predicate<Object> predicate = Predicates.and(list); assertTrue(predicate.apply(1)); list.add(Predicates.alwaysFalse()); assertTrue(predicate.apply(1)); } - @SuppressWarnings("unchecked") public void testAnd_iterableDefensivelyCopied() { - final List list = new ArrayList<Predicate>(); - Iterable iterable = new Iterable<Predicate>() { + final List<Predicate<Object>> list = newArrayList(); + Iterable<Predicate<Object>> iterable = new Iterable<Predicate<Object>>() { @Override - public Iterator<Predicate> iterator() { + public Iterator<Predicate<Object>> iterator() { return list.iterator(); } }; @@ -335,12 +335,12 @@ public class PredicatesTest extends TestCase { * Tests for all the different flavors of Predicates.or(). */ - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_applyNoArgs() { assertEvalsToFalse(Predicates.or()); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_equalityNoArgs() { new EqualsTester() .addEqualityGroup(Predicates.or(), Predicates.or()) @@ -350,18 +350,18 @@ public class PredicatesTest extends TestCase { } @GwtIncompatible("SerializableTester") - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_serializationNoArgs() { checkSerialization(Predicates.or()); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_applyOneArg() { assertEvalsToTrue(Predicates.or(TRUE)); assertEvalsToFalse(Predicates.or(FALSE)); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_equalityOneArg() { new EqualsTester() .addEqualityGroup( @@ -374,7 +374,7 @@ public class PredicatesTest extends TestCase { } @GwtIncompatible("SerializableTester") - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_serializationOneArg() { checkSerialization(Predicates.or(isOdd())); } @@ -389,7 +389,7 @@ public class PredicatesTest extends TestCase { assertEvalsToTrue(trueOrAnything); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_equalityBinary() { new EqualsTester() .addEqualityGroup( @@ -406,7 +406,7 @@ public class PredicatesTest extends TestCase { checkSerialization(Predicates.or(isOdd(), TRUE)); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_applyTernary() { assertEvalsLikeOdd(Predicates.or(isOdd(), FALSE, FALSE)); assertEvalsLikeOdd(Predicates.or(FALSE, isOdd(), FALSE)); @@ -414,7 +414,7 @@ public class PredicatesTest extends TestCase { assertEvalsToTrue(Predicates.or(FALSE, TRUE, NEVER_REACHED)); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_equalityTernary() { new EqualsTester() .addEqualityGroup( @@ -427,12 +427,12 @@ public class PredicatesTest extends TestCase { } @GwtIncompatible("SerializableTester") - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_serializationTernary() { checkSerialization(Predicates.or(FALSE, isOdd(), TRUE)); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_applyIterable() { Predicate<Integer> vacuouslyFalse = Predicates.or(Collections.<Predicate<Integer>>emptyList()); @@ -448,7 +448,7 @@ public class PredicatesTest extends TestCase { assertEvalsToTrue(trueAndFalse); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_equalityIterable() { new EqualsTester() .addEqualityGroup( @@ -461,14 +461,14 @@ public class PredicatesTest extends TestCase { } @GwtIncompatible("SerializableTester") - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_serializationIterable() { Predicate<Integer> pre = Predicates.or(Arrays.asList(TRUE, FALSE)); Predicate<Integer> post = SerializableTester.reserializeAndAssert(pre); assertEquals(pre.apply(0), post.apply(0)); } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") // varargs public void testOr_arrayDefensivelyCopied() { Predicate[] array = {Predicates.alwaysFalse()}; Predicate<Object> predicate = Predicates.or(array); @@ -477,21 +477,19 @@ public class PredicatesTest extends TestCase { assertFalse(predicate.apply(1)); } - @SuppressWarnings("unchecked") public void testOr_listDefensivelyCopied() { - List list = new ArrayList<Predicate>(); + List<Predicate<Object>> list = newArrayList(); Predicate<Object> predicate = Predicates.or(list); assertFalse(predicate.apply(1)); list.add(Predicates.alwaysTrue()); assertFalse(predicate.apply(1)); } - @SuppressWarnings("unchecked") public void testOr_iterableDefensivelyCopied() { - final List list = new ArrayList<Predicate>(); - Iterable iterable = new Iterable<Predicate>() { + final List<Predicate<Object>> list = newArrayList(); + Iterable<Predicate<Object>> iterable = new Iterable<Predicate<Object>>() { @Override - public Iterator<Predicate> iterator() { + public Iterator<Predicate<Object>> iterator() { return list.iterator(); } }; @@ -608,7 +606,7 @@ public class PredicatesTest extends TestCase { try { isInteger.apply(null); fail(); - } catch(NullPointerException expected) {} + } catch (NullPointerException expected) {} } @GwtIncompatible("Predicates.assignableFrom") @@ -753,7 +751,7 @@ public class PredicatesTest extends TestCase { /* * Tests that compilation will work when applying explicit types. */ - @SuppressWarnings("unused") + @SuppressWarnings("unused") // compilation test public void testIn_compilesWithExplicitSupertype() { Collection<Number> nums = ImmutableSet.of(); Predicate<Number> p1 = Predicates.in(nums); @@ -889,8 +887,7 @@ public class PredicatesTest extends TestCase { public void assertEqualHashCode( Predicate<? super Integer> expected, Predicate<? super Integer> actual) { - assertEquals(actual.toString() + " should hash like " + expected.toString(), - expected.hashCode(), actual.hashCode()); + assertEquals(actual + " should hash like " + expected, expected.hashCode(), actual.hashCode()); } public void testHashCodeForBooleanOperations() { diff --git a/guava-tests/test/com/google/common/base/SplitterTest.java b/guava-tests/test/com/google/common/base/SplitterTest.java index 89b9698..0ac09cf 100644 --- a/guava-tests/test/com/google/common/base/SplitterTest.java +++ b/guava-tests/test/com/google/common/base/SplitterTest.java @@ -16,21 +16,22 @@ package com.google.common.base; +import static org.truth0.Truth.ASSERT; + import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Pattern; -import junit.framework.TestCase; - /** * @author Julien Silland */ @@ -50,7 +51,21 @@ public class SplitterTest extends TestCase { public void testCharacterSimpleSplit() { String simple = "a,b,c"; Iterable<String> letters = COMMA_SPLITTER.split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c"); + } + + /** + * All of the infrastructure of split and splitToString is identical, so we + * do one test of splitToString. All other cases should be covered by testing + * of split. + * + * <p>TODO(user): It would be good to make all the relevant tests run on + * both split and splitToString automatically. + */ + public void testCharacterSimpleSplitToList() { + String simple = "a,b,c"; + List<String> letters = COMMA_SPLITTER.splitToList(simple); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c"); } public void testToString() { @@ -62,37 +77,37 @@ public class SplitterTest extends TestCase { public void testCharacterSimpleSplitWithNoDelimiter() { String simple = "a,b,c"; Iterable<String> letters = Splitter.on('.').split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("a,b,c"); + ASSERT.that(letters).iteratesOverSequence("a,b,c"); } public void testCharacterSplitWithDoubleDelimiter() { String doubled = "a,,b,c"; Iterable<String> letters = COMMA_SPLITTER.split(doubled); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "", "b", "c"); } public void testCharacterSplitWithDoubleDelimiterAndSpace() { String doubled = "a,, b,c"; Iterable<String> letters = COMMA_SPLITTER.split(doubled); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "", " b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "", " b", "c"); } public void testCharacterSplitWithTrailingDelimiter() { String trailing = "a,b,c,"; Iterable<String> letters = COMMA_SPLITTER.split(trailing); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c", ""); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c", ""); } public void testCharacterSplitWithLeadingDelimiter() { String leading = ",a,b,c"; Iterable<String> letters = COMMA_SPLITTER.split(leading); - FluentAsserts.assertThat(letters).iteratesOverSequence("", "a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c"); } public void testCharacterSplitWithMulitpleLetters() { Iterable<String> testCharacteringMotto = Splitter.on('-').split( "Testing-rocks-Debugging-sucks"); - FluentAsserts.assertThat(testCharacteringMotto).iteratesOverSequence( + ASSERT.that(testCharacteringMotto).iteratesOverSequence( "Testing", "rocks", "Debugging", "sucks"); } @@ -100,7 +115,7 @@ public class SplitterTest extends TestCase { Iterable<String> testCharacteringMotto = Splitter .on(CharMatcher.WHITESPACE) .split("Testing\nrocks\tDebugging sucks"); - FluentAsserts.assertThat(testCharacteringMotto).iteratesOverSequence( + ASSERT.that(testCharacteringMotto).iteratesOverSequence( "Testing", "rocks", "Debugging", "sucks"); } @@ -108,40 +123,40 @@ public class SplitterTest extends TestCase { String doubled = "a..b.c"; Iterable<String> letters = Splitter.on('.') .omitEmptyStrings().split(doubled); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c"); } public void testCharacterSplitEmptyToken() { String emptyToken = "a. .c"; Iterable<String> letters = Splitter.on('.').trimResults() .split(emptyToken); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "", "c"); } public void testCharacterSplitEmptyTokenOmitEmptyStrings() { String emptyToken = "a. .c"; Iterable<String> letters = Splitter.on('.') .omitEmptyStrings().trimResults().split(emptyToken); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "c"); } public void testCharacterSplitOnEmptyString() { Iterable<String> nothing = Splitter.on('.').split(""); - FluentAsserts.assertThat(nothing).iteratesOverSequence(""); + ASSERT.that(nothing).iteratesOverSequence(""); } public void testCharacterSplitOnEmptyStringOmitEmptyStrings() { - FluentAsserts.assertThat(Splitter.on('.').omitEmptyStrings().split("")).isEmpty(); + ASSERT.that(Splitter.on('.').omitEmptyStrings().split("")).isEmpty(); } public void testCharacterSplitOnOnlyDelimiter() { Iterable<String> blankblank = Splitter.on('.').split("."); - FluentAsserts.assertThat(blankblank).iteratesOverSequence("", ""); + ASSERT.that(blankblank).iteratesOverSequence("", ""); } public void testCharacterSplitOnOnlyDelimitersOmitEmptyStrings() { Iterable<String> empty = Splitter.on('.').omitEmptyStrings().split("..."); - FluentAsserts.assertThat(empty); + ASSERT.that(empty).isEmpty(); } public void testCharacterSplitWithTrim() { @@ -150,50 +165,50 @@ public class SplitterTest extends TestCase { Iterable<String> family = COMMA_SPLITTER .trimResults(CharMatcher.anyOf("afro").or(CharMatcher.WHITESPACE)) .split(jacksons); - FluentAsserts.assertThat(family).iteratesOverSequence( + ASSERT.that(family).iteratesOverSequence( "(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)"); } public void testStringSimpleSplit() { String simple = "a,b,c"; Iterable<String> letters = Splitter.on(',').split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c"); } public void testStringSimpleSplitWithNoDelimiter() { String simple = "a,b,c"; Iterable<String> letters = Splitter.on('.').split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("a,b,c"); + ASSERT.that(letters).iteratesOverSequence("a,b,c"); } public void testStringSplitWithDoubleDelimiter() { String doubled = "a,,b,c"; Iterable<String> letters = Splitter.on(',').split(doubled); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "", "b", "c"); } public void testStringSplitWithDoubleDelimiterAndSpace() { String doubled = "a,, b,c"; Iterable<String> letters = Splitter.on(',').split(doubled); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "", " b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "", " b", "c"); } public void testStringSplitWithTrailingDelimiter() { String trailing = "a,b,c,"; Iterable<String> letters = Splitter.on(',').split(trailing); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c", ""); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c", ""); } public void testStringSplitWithLeadingDelimiter() { String leading = ",a,b,c"; Iterable<String> letters = Splitter.on(',').split(leading); - FluentAsserts.assertThat(letters).iteratesOverSequence("", "a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c"); } public void testStringSplitWithMultipleLetters() { Iterable<String> testStringingMotto = Splitter.on('-').split( "Testing-rocks-Debugging-sucks"); - FluentAsserts.assertThat(testStringingMotto).iteratesOverSequence( + ASSERT.that(testStringingMotto).iteratesOverSequence( "Testing", "rocks", "Debugging", "sucks"); } @@ -201,46 +216,46 @@ public class SplitterTest extends TestCase { String doubled = "a..b.c"; Iterable<String> letters = Splitter.on('.') .omitEmptyStrings().split(doubled); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c"); } public void testStringSplitEmptyToken() { String emptyToken = "a. .c"; Iterable<String> letters = Splitter.on('.').trimResults() .split(emptyToken); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "", "c"); } public void testStringSplitEmptyTokenOmitEmptyStrings() { String emptyToken = "a. .c"; Iterable<String> letters = Splitter.on('.') .omitEmptyStrings().trimResults().split(emptyToken); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "c"); } public void testStringSplitWithLongDelimiter() { String longDelimiter = "a, b, c"; Iterable<String> letters = Splitter.on(", ").split(longDelimiter); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c"); } public void testStringSplitWithLongLeadingDelimiter() { String longDelimiter = ", a, b, c"; Iterable<String> letters = Splitter.on(", ").split(longDelimiter); - FluentAsserts.assertThat(letters).iteratesOverSequence("", "a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c"); } public void testStringSplitWithLongTrailingDelimiter() { String longDelimiter = "a, b, c, "; Iterable<String> letters = Splitter.on(", ").split(longDelimiter); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c", ""); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c", ""); } public void testStringSplitWithDelimiterSubstringInValue() { String fourCommasAndFourSpaces = ",,,, "; Iterable<String> threeCommasThenThreeSpaces = Splitter.on(", ").split( fourCommasAndFourSpaces); - FluentAsserts.assertThat(threeCommasThenThreeSpaces).iteratesOverSequence(",,,", " "); + ASSERT.that(threeCommasThenThreeSpaces).iteratesOverSequence(",,,", " "); } public void testStringSplitWithEmptyString() { @@ -253,21 +268,21 @@ public class SplitterTest extends TestCase { public void testStringSplitOnEmptyString() { Iterable<String> notMuch = Splitter.on('.').split(""); - FluentAsserts.assertThat(notMuch).iteratesOverSequence(""); + ASSERT.that(notMuch).iteratesOverSequence(""); } public void testStringSplitOnEmptyStringOmitEmptyString() { - FluentAsserts.assertThat(Splitter.on('.').omitEmptyStrings().split("")).isEmpty(); + ASSERT.that(Splitter.on('.').omitEmptyStrings().split("")).isEmpty(); } public void testStringSplitOnOnlyDelimiter() { Iterable<String> blankblank = Splitter.on('.').split("."); - FluentAsserts.assertThat(blankblank).iteratesOverSequence("", ""); + ASSERT.that(blankblank).iteratesOverSequence("", ""); } public void testStringSplitOnOnlyDelimitersOmitEmptyStrings() { Iterable<String> empty = Splitter.on('.').omitEmptyStrings().split("..."); - FluentAsserts.assertThat(empty).isEmpty(); + ASSERT.that(empty).isEmpty(); } public void testStringSplitWithTrim() { @@ -276,7 +291,7 @@ public class SplitterTest extends TestCase { Iterable<String> family = Splitter.on(',') .trimResults(CharMatcher.anyOf("afro").or(CharMatcher.WHITESPACE)) .split(jacksons); - FluentAsserts.assertThat(family).iteratesOverSequence( + ASSERT.that(family).iteratesOverSequence( "(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)"); } @@ -284,42 +299,42 @@ public class SplitterTest extends TestCase { public void testPatternSimpleSplit() { String simple = "a,b,c"; Iterable<String> letters = Splitter.onPattern(",").split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c"); } @GwtIncompatible("Splitter.onPattern") public void testPatternSimpleSplitWithNoDelimiter() { String simple = "a,b,c"; Iterable<String> letters = Splitter.onPattern("foo").split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("a,b,c"); + ASSERT.that(letters).iteratesOverSequence("a,b,c"); } @GwtIncompatible("Splitter.onPattern") public void testPatternSplitWithDoubleDelimiter() { String doubled = "a,,b,c"; Iterable<String> letters = Splitter.onPattern(",").split(doubled); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "", "b", "c"); } @GwtIncompatible("Splitter.onPattern") public void testPatternSplitWithDoubleDelimiterAndSpace() { String doubled = "a,, b,c"; Iterable<String> letters = Splitter.onPattern(",").split(doubled); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "", " b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "", " b", "c"); } @GwtIncompatible("Splitter.onPattern") public void testPatternSplitWithTrailingDelimiter() { String trailing = "a,b,c,"; Iterable<String> letters = Splitter.onPattern(",").split(trailing); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c", ""); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c", ""); } @GwtIncompatible("Splitter.onPattern") public void testPatternSplitWithLeadingDelimiter() { String leading = ",a,b,c"; Iterable<String> letters = Splitter.onPattern(",").split(leading); - FluentAsserts.assertThat(letters).iteratesOverSequence("", "a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c"); } // TODO(kevinb): the name of this method suggests it might not actually be testing what it @@ -328,7 +343,7 @@ public class SplitterTest extends TestCase { public void testPatternSplitWithMultipleLetters() { Iterable<String> testPatterningMotto = Splitter.onPattern("-").split( "Testing-rocks-Debugging-sucks"); - FluentAsserts.assertThat(testPatterningMotto).iteratesOverSequence("Testing", "rocks", "Debugging", "sucks"); + ASSERT.that(testPatterningMotto).iteratesOverSequence("Testing", "rocks", "Debugging", "sucks"); } @GwtIncompatible("java.util.regex.Pattern") @@ -341,7 +356,7 @@ public class SplitterTest extends TestCase { String doubled = "a..b.c"; Iterable<String> letters = Splitter.on(literalDotPattern()) .omitEmptyStrings().split(doubled); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c"); } @GwtIncompatible("java.util.regex.Pattern") @@ -349,7 +364,7 @@ public class SplitterTest extends TestCase { String toSplit = ":foo::barbaz:"; String regexPattern = "(?<=:)"; Iterable<String> split = Splitter.onPattern(regexPattern).split(toSplit); - FluentAsserts.assertThat(split).iteratesOverSequence(":", "foo:", ":", "barbaz:"); + ASSERT.that(split).iteratesOverSequence(":", "foo:", ":", "barbaz:"); // splits into chunks ending in : } @@ -357,14 +372,14 @@ public class SplitterTest extends TestCase { public void testPatternSplitWordBoundary() { String string = "foo<bar>bletch"; Iterable<String> words = Splitter.on(Pattern.compile("\\b")).split(string); - FluentAsserts.assertThat(words).iteratesOverSequence("foo", "<", "bar", ">", "bletch"); + ASSERT.that(words).iteratesOverSequence("foo", "<", "bar", ">", "bletch"); } @GwtIncompatible("java.util.regex.Pattern") public void testPatternSplitEmptyToken() { String emptyToken = "a. .c"; Iterable<String> letters = Splitter.on(literalDotPattern()).trimResults().split(emptyToken); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "", "c"); } @GwtIncompatible("java.util.regex.Pattern") @@ -372,21 +387,21 @@ public class SplitterTest extends TestCase { String emptyToken = "a. .c"; Iterable<String> letters = Splitter.on(literalDotPattern()) .omitEmptyStrings().trimResults().split(emptyToken); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "c"); } @GwtIncompatible("java.util.regex.Pattern") public void testPatternSplitOnOnlyDelimiter() { Iterable<String> blankblank = Splitter.on(literalDotPattern()).split("."); - FluentAsserts.assertThat(blankblank).iteratesOverSequence("", ""); + ASSERT.that(blankblank).iteratesOverSequence("", ""); } @GwtIncompatible("java.util.regex.Pattern") public void testPatternSplitOnOnlyDelimitersOmitEmptyStrings() { Iterable<String> empty = Splitter.on(literalDotPattern()).omitEmptyStrings() .split("..."); - FluentAsserts.assertThat(empty).isEmpty(); + ASSERT.that(empty).isEmpty(); } @GwtIncompatible("java.util.regex.Pattern") @@ -394,7 +409,7 @@ public class SplitterTest extends TestCase { String longDelimiter = "a, b, c"; Iterable<String> letters = Splitter.on(Pattern.compile(",\\s*")) .split(longDelimiter); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c"); } @GwtIncompatible("java.util.regex.Pattern") @@ -402,7 +417,7 @@ public class SplitterTest extends TestCase { String longDelimiter = ", a, b, c"; Iterable<String> letters = Splitter.on(Pattern.compile(", ")) .split(longDelimiter); - FluentAsserts.assertThat(letters).iteratesOverSequence("", "a", "b", "c"); + ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c"); } @GwtIncompatible("java.util.regex.Pattern") @@ -410,7 +425,7 @@ public class SplitterTest extends TestCase { String longDelimiter = "a, b, c/ "; Iterable<String> letters = Splitter.on(Pattern.compile("[,/]\\s")) .split(longDelimiter); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c", ""); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c", ""); } @GwtIncompatible("java.util.regex.Pattern") @@ -429,7 +444,7 @@ public class SplitterTest extends TestCase { Iterable<String> family = Splitter.on(Pattern.compile(",")) .trimResults(CharMatcher.anyOf("afro").or(CharMatcher.WHITESPACE)) .split(jacksons); - FluentAsserts.assertThat(family).iteratesOverSequence( + ASSERT.that(family).iteratesOverSequence( "(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)"); } @@ -490,41 +505,41 @@ public class SplitterTest extends TestCase { public void testFixedLengthSimpleSplit() { String simple = "abcde"; Iterable<String> letters = Splitter.fixedLength(2).split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("ab", "cd", "e"); + ASSERT.that(letters).iteratesOverSequence("ab", "cd", "e"); } public void testFixedLengthSplitEqualChunkLength() { String simple = "abcdef"; Iterable<String> letters = Splitter.fixedLength(2).split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("ab", "cd", "ef"); + ASSERT.that(letters).iteratesOverSequence("ab", "cd", "ef"); } public void testFixedLengthSplitOnlyOneChunk() { String simple = "abc"; Iterable<String> letters = Splitter.fixedLength(3).split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("abc"); + ASSERT.that(letters).iteratesOverSequence("abc"); } public void testFixedLengthSplitSmallerString() { String simple = "ab"; Iterable<String> letters = Splitter.fixedLength(3).split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("ab"); + ASSERT.that(letters).iteratesOverSequence("ab"); } public void testFixedLengthSplitEmptyString() { String simple = ""; Iterable<String> letters = Splitter.fixedLength(3).split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence(""); + ASSERT.that(letters).iteratesOverSequence(""); } public void testFixedLengthSplitEmptyStringWithOmitEmptyStrings() { - FluentAsserts.assertThat(Splitter.fixedLength(3).omitEmptyStrings().split("")).isEmpty(); + ASSERT.that(Splitter.fixedLength(3).omitEmptyStrings().split("")).isEmpty(); } public void testFixedLengthSplitIntoChars() { String simple = "abcd"; Iterable<String> letters = Splitter.fixedLength(1).split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c", "d"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "d"); } public void testFixedLengthSplitZeroChunkLen() { @@ -546,82 +561,82 @@ public class SplitterTest extends TestCase { public void testLimitLarge() { String simple = "abcd"; Iterable<String> letters = Splitter.fixedLength(1).limit(100).split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "b", "c", "d"); + ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "d"); } public void testLimitOne() { String simple = "abcd"; Iterable<String> letters = Splitter.fixedLength(1).limit(1).split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("abcd"); + ASSERT.that(letters).iteratesOverSequence("abcd"); } public void testLimitFixedLength() { String simple = "abcd"; Iterable<String> letters = Splitter.fixedLength(1).limit(2).split(simple); - FluentAsserts.assertThat(letters).iteratesOverSequence("a", "bcd"); + ASSERT.that(letters).iteratesOverSequence("a", "bcd"); } public void testLimitSeparator() { String simple = "a,b,c,d"; Iterable<String> items = COMMA_SPLITTER.limit(2).split(simple); - FluentAsserts.assertThat(items).iteratesOverSequence("a", "b,c,d"); + ASSERT.that(items).iteratesOverSequence("a", "b,c,d"); } public void testLimitExtraSeparators() { String text = "a,,,b,,c,d"; Iterable<String> items = COMMA_SPLITTER.limit(2).split(text); - FluentAsserts.assertThat(items).iteratesOverSequence("a", ",,b,,c,d"); + ASSERT.that(items).iteratesOverSequence("a", ",,b,,c,d"); } public void testLimitExtraSeparatorsOmitEmpty() { String text = "a,,,b,,c,d"; Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().split(text); - FluentAsserts.assertThat(items).iteratesOverSequence("a", "b,,c,d"); + ASSERT.that(items).iteratesOverSequence("a", "b,,c,d"); } public void testLimitExtraSeparatorsOmitEmpty3() { String text = "a,,,b,,c,d"; Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().split(text); - FluentAsserts.assertThat(items).iteratesOverSequence("a", "b", "c,d"); + ASSERT.that(items).iteratesOverSequence("a", "b", "c,d"); } public void testLimitExtraSeparatorsTrim() { String text = ",,a,, , b ,, c,d "; Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().trimResults().split(text); - FluentAsserts.assertThat(items).iteratesOverSequence("a", "b ,, c,d"); + ASSERT.that(items).iteratesOverSequence("a", "b ,, c,d"); } public void testLimitExtraSeparatorsTrim3() { String text = ",,a,, , b ,, c,d "; Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().trimResults().split(text); - FluentAsserts.assertThat(items).iteratesOverSequence("a", "b", "c,d"); + ASSERT.that(items).iteratesOverSequence("a", "b", "c,d"); } public void testLimitExtraSeparatorsTrim1() { String text = ",,a,, , b ,, c,d "; Iterable<String> items = COMMA_SPLITTER.limit(1).omitEmptyStrings().trimResults().split(text); - FluentAsserts.assertThat(items).iteratesOverSequence("a,, , b ,, c,d"); + ASSERT.that(items).iteratesOverSequence("a,, , b ,, c,d"); } public void testLimitExtraSeparatorsTrim1NoOmit() { String text = ",,a,, , b ,, c,d "; Iterable<String> items = COMMA_SPLITTER.limit(1).trimResults().split(text); - FluentAsserts.assertThat(items).iteratesOverSequence(",,a,, , b ,, c,d"); + ASSERT.that(items).iteratesOverSequence(",,a,, , b ,, c,d"); } public void testLimitExtraSeparatorsTrim1Empty() { String text = ""; Iterable<String> items = COMMA_SPLITTER.limit(1).split(text); - FluentAsserts.assertThat(items).iteratesOverSequence(""); + ASSERT.that(items).iteratesOverSequence(""); } public void testLimitExtraSeparatorsTrim1EmptyOmit() { String text = ""; Iterable<String> items = COMMA_SPLITTER.omitEmptyStrings().limit(1).split(text); - FluentAsserts.assertThat(items).isEmpty(); + ASSERT.that(items).isEmpty(); } - @SuppressWarnings("ReturnValueIgnored") + @SuppressWarnings("ReturnValueIgnored") // testing for exception public void testInvalidZeroLimit() { try { COMMA_SPLITTER.limit(0); @@ -638,7 +653,7 @@ public class SplitterTest extends TestCase { tester.testAllPublicInstanceMethods(Splitter.on(',').trimResults()); } - private static <E> List<E> asList(Collection<E> collection){ + private static <E> List<E> asList(Collection<E> collection) { return ImmutableList.copyOf(collection); } @@ -649,8 +664,8 @@ public class SplitterTest extends TestCase { .split("boy : tom , girl: tina , cat : kitty , dog: tommy "); ImmutableMap<String, String> expected = ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"); - FluentAsserts.assertThat(m).isEqualTo(expected); - FluentAsserts.assertThat(asList(m.entrySet())).is(asList(expected.entrySet())); + ASSERT.that(m).isEqualTo(expected); + ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet())); } public void testMapSplitter_trimmedEntries() { @@ -661,8 +676,8 @@ public class SplitterTest extends TestCase { ImmutableMap<String, String> expected = ImmutableMap.of("boy ", " tom", "girl", " tina", "cat ", " kitty", "dog", " tommy"); - FluentAsserts.assertThat(m).isEqualTo(expected); - FluentAsserts.assertThat(asList(m.entrySet())).is(asList(expected.entrySet())); + ASSERT.that(m).isEqualTo(expected); + ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet())); } public void testMapSplitter_trimmedKeyValue() { @@ -671,8 +686,8 @@ public class SplitterTest extends TestCase { "boy : tom , girl: tina , cat : kitty , dog: tommy "); ImmutableMap<String, String> expected = ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"); - FluentAsserts.assertThat(m).isEqualTo(expected); - FluentAsserts.assertThat(asList(m.entrySet())).is(asList(expected.entrySet())); + ASSERT.that(m).isEqualTo(expected); + ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet())); } public void testMapSplitter_notTrimmed() { @@ -680,8 +695,8 @@ public class SplitterTest extends TestCase { " boy:tom , girl: tina , cat :kitty , dog: tommy "); ImmutableMap<String, String> expected = ImmutableMap.of(" boy", "tom ", " girl", " tina ", " cat ", "kitty ", " dog", " tommy "); - FluentAsserts.assertThat(m).isEqualTo(expected); - FluentAsserts.assertThat(asList(m.entrySet())).is(asList(expected.entrySet())); + ASSERT.that(m).isEqualTo(expected); + ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet())); } public void testMapSplitter_CharacterSeparator() { @@ -693,8 +708,8 @@ public class SplitterTest extends TestCase { ImmutableMap<String, String> expected = ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"); - FluentAsserts.assertThat(m).isEqualTo(expected); - FluentAsserts.assertThat(asList(m.entrySet())).is(asList(expected.entrySet())); + ASSERT.that(m).isEqualTo(expected); + ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet())); } public void testMapSplitter_multiCharacterSeparator() { @@ -706,11 +721,11 @@ public class SplitterTest extends TestCase { ImmutableMap<String, String> expected = ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"); - FluentAsserts.assertThat(m).isEqualTo(expected); - FluentAsserts.assertThat(asList(m.entrySet())).is(asList(expected.entrySet())); + ASSERT.that(m).isEqualTo(expected); + ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet())); } - @SuppressWarnings("ReturnValueIgnored") + @SuppressWarnings("ReturnValueIgnored") // testing for exception public void testMapSplitter_emptySeparator() { try { COMMA_SPLITTER.withKeyValueSeparator(""); @@ -723,7 +738,7 @@ public class SplitterTest extends TestCase { try { COMMA_SPLITTER.withKeyValueSeparator("=").split("a=1,b,c=2"); fail(); - } catch(IllegalArgumentException expected) { + } catch (IllegalArgumentException expected) { } } @@ -732,8 +747,8 @@ public class SplitterTest extends TestCase { .withKeyValueSeparator(":") .split("boy:tom,girl:tina,cat:kitty,dog:tommy"); - FluentAsserts.assertThat(m.keySet()).iteratesOverSequence("boy", "girl", "cat", "dog"); - FluentAsserts.assertThat(m).isEqualTo( + ASSERT.that(m.keySet()).iteratesOverSequence("boy", "girl", "cat", "dog"); + ASSERT.that(m).isEqualTo( ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy")); // try in a different order @@ -741,8 +756,8 @@ public class SplitterTest extends TestCase { .withKeyValueSeparator(":") .split("girl:tina,boy:tom,dog:tommy,cat:kitty"); - FluentAsserts.assertThat(m.keySet()).iteratesOverSequence("girl", "boy", "dog", "cat"); - FluentAsserts.assertThat(m).isEqualTo( + ASSERT.that(m.keySet()).iteratesOverSequence("girl", "boy", "dog", "cat"); + ASSERT.that(m).isEqualTo( ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy")); } diff --git a/guava-tests/test/com/google/common/base/StandardSystemPropertyTest.java b/guava-tests/test/com/google/common/base/StandardSystemPropertyTest.java new file mode 100644 index 0000000..6766ece --- /dev/null +++ b/guava-tests/test/com/google/common/base/StandardSystemPropertyTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.base; + +import junit.framework.TestCase; + +/** + * Tests for {@link StandardSystemProperty}. + * + * @author Kurt Alfred Kluever + */ +public class StandardSystemPropertyTest extends TestCase { + + public void testGetKeyMatchesString() { + for (StandardSystemProperty property : StandardSystemProperty.values()) { + String fieldName = property.name(); + String expected = Ascii.toLowerCase(fieldName).replaceAll("_", "."); + assertEquals(expected, property.key()); + } + } + + public void testGetValue() { + for (StandardSystemProperty property : StandardSystemProperty.values()) { + assertEquals(System.getProperty(property.key()), property.value()); + } + } + + public void testToString() { + for (StandardSystemProperty property : StandardSystemProperty.values()) { + assertEquals(property.key() + "=" + property.value(), property.toString()); + } + } + + public void testNoNullValues() { + for (StandardSystemProperty property : StandardSystemProperty.values()) { + // Even though the contract in System.getProperties() specifies that a value will exist for + // all of the listed keys, for some reason the "java.compiler" key returns null in some JVMs. + if (property != StandardSystemProperty.JAVA_COMPILER) { + assertNotNull(property.value()); + } + } + } +} diff --git a/guava-tests/test/com/google/common/base/StopwatchTest.java b/guava-tests/test/com/google/common/base/StopwatchTest.java index da4f15b..4787343 100644 --- a/guava-tests/test/com/google/common/base/StopwatchTest.java +++ b/guava-tests/test/com/google/common/base/StopwatchTest.java @@ -31,12 +31,23 @@ import junit.framework.TestCase; * * @author Kevin Bourrillion */ -@GwtCompatible(emulated=true) +@GwtCompatible(emulated = true) public class StopwatchTest extends TestCase { private final FakeTicker ticker = new FakeTicker(); private final Stopwatch stopwatch = new Stopwatch(ticker); + public void testCreateStarted() { + Stopwatch startedStopwatch = Stopwatch.createStarted(); + assertTrue(startedStopwatch.isRunning()); + } + + public void testCreateUnstarted() { + Stopwatch unstartedStopwatch = Stopwatch.createUnstarted(); + assertFalse(unstartedStopwatch.isRunning()); + assertEquals(0, unstartedStopwatch.elapsed(NANOSECONDS)); + } + public void testInitialState() { assertFalse(stopwatch.isRunning()); assertEquals(0, stopwatch.elapsed(NANOSECONDS)); @@ -140,7 +151,7 @@ public class StopwatchTest extends TestCase { ticker.advance(36); assertEquals(34, stopwatch.elapsed(NANOSECONDS)); } - + public void testElapsed_micros() { stopwatch.start(); ticker.advance(999); diff --git a/guava-tests/test/com/google/common/base/SuppliersTest.java b/guava-tests/test/com/google/common/base/SuppliersTest.java index bf1a181..6e6ea9c 100644 --- a/guava-tests/test/com/google/common/base/SuppliersTest.java +++ b/guava-tests/test/com/google/common/base/SuppliersTest.java @@ -24,6 +24,8 @@ import com.google.common.collect.Lists; import com.google.common.testing.ClassSanityTester; import com.google.common.testing.EqualsTester; +import junit.framework.TestCase; + import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -32,8 +34,6 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import junit.framework.TestCase; - /** * Tests com.google.common.base.Suppliers. * diff --git a/guava-tests/test/com/google/common/base/ThrowablesTest.java b/guava-tests/test/com/google/common/base/ThrowablesTest.java index 0166106..52d8a74 100644 --- a/guava-tests/test/com/google/common/base/ThrowablesTest.java +++ b/guava-tests/test/com/google/common/base/ThrowablesTest.java @@ -23,17 +23,16 @@ import static java.util.regex.Pattern.quote; import com.google.common.collect.Iterables; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.io.FileNotFoundException; import java.util.List; -import junit.framework.TestCase; - /** * Unit test for {@link Throwables}. * * @author Kevin Bourrillion */ -@SuppressWarnings("serial") // this warning is silly for exceptions in tests public class ThrowablesTest extends TestCase { public void testPropagateIfPossible_NoneDeclared_NoneThrown() { Sample sample = new Sample() { @@ -455,15 +454,7 @@ public class ThrowablesTest extends TestCase { static class Sample { void noneDeclared() {} - /* - * Subclasses of Sample will define methods with these signatures that throw - * these exceptions, so we must declare them in the throws clause here. - * Eclipse doesn't think being thrown from a subclass's non-public, - * non-protected method with the same signature counts as being "used." - */ - @SuppressWarnings("unused") void oneDeclared() throws SomeCheckedException {} - @SuppressWarnings("unused") void twoDeclared() throws SomeCheckedException, SomeOtherCheckedException {} } diff --git a/guava-tests/test/com/google/common/base/ToStringHelperTest.java b/guava-tests/test/com/google/common/base/ToStringHelperTest.java index 0adf100..7817c4d 100644 --- a/guava-tests/test/com/google/common/base/ToStringHelperTest.java +++ b/guava-tests/test/com/google/common/base/ToStringHelperTest.java @@ -20,11 +20,11 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.ImmutableMap; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Map; -import junit.framework.TestCase; - /** * Tests for {@link Objects#toStringHelper(Object)}. * diff --git a/guava-tests/test/com/google/common/base/Utf8Test.java b/guava-tests/test/com/google/common/base/Utf8Test.java new file mode 100644 index 0000000..e56a53a --- /dev/null +++ b/guava-tests/test/com/google/common/base/Utf8Test.java @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.base; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; + +import junit.framework.TestCase; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Random; + +/** + * Unit tests for {@link Utf8}. + * + * @author Jon Perlow + * @author Martin Buchholz + * @author Clément Roux + */ +@GwtCompatible(emulated = true) +public class Utf8Test extends TestCase { + public void testEncodedLength_validStrings() { + assertEquals(0, Utf8.encodedLength("")); + assertEquals(11, Utf8.encodedLength("Hello world")); + assertEquals(8, Utf8.encodedLength("Résumé")); + assertEquals(461, Utf8.encodedLength("威廉·莎士比亞(William Shakespeare," + + "1564年4月26號—1616年4月23號[1])係隻英國嗰演員、劇作家同詩人," + + "有時間佢簡稱莎翁;中國清末民初哈拕翻譯做舌克斯毕、沙斯皮耳、筛斯比耳、" + + "莎基斯庇尔、索士比尔、夏克思芘尔、希哀苦皮阿、叶斯壁、沙克皮尔、" + + "狹斯丕爾。[2]莎士比亞編寫過好多作品,佢嗰劇作響西洋文學好有影響," + + "哈都拕人翻譯做好多話。")); + // A surrogate pair + assertEquals(4, Utf8.encodedLength( + newString(Character.MIN_HIGH_SURROGATE, Character.MIN_LOW_SURROGATE))); + } + + @GwtIncompatible("StringBuilder.appendCodePoint()") + public void testEncodedLength_validStrings2() { + HashMap<Integer, Integer> utf8Lengths = new HashMap<Integer, Integer>(); + utf8Lengths.put(0x00, 1); + utf8Lengths.put(0x7f, 1); + utf8Lengths.put(0x80, 2); + utf8Lengths.put(0x7ff, 2); + utf8Lengths.put(0x800, 3); + utf8Lengths.put(Character.MIN_SUPPLEMENTARY_CODE_POINT - 1, 3); + utf8Lengths.put(Character.MIN_SUPPLEMENTARY_CODE_POINT, 4); + utf8Lengths.put(Character.MAX_CODE_POINT, 4); + + Integer[] codePoints = utf8Lengths.keySet().toArray(new Integer[]{}); + StringBuilder sb = new StringBuilder(); + Random rnd = new Random(); + for (int trial = 0; trial < 100; trial++) { + sb.setLength(0); + int utf8Length = 0; + for (int i = 0; i < 6; i++) { + Integer randomCodePoint = codePoints[rnd.nextInt(codePoints.length)]; + sb.appendCodePoint(randomCodePoint); + utf8Length += utf8Lengths.get(randomCodePoint); + if (utf8Length != Utf8.encodedLength(sb)) { + StringBuilder repro = new StringBuilder(); + for (int j = 0; j < sb.length(); j++) { + repro.append(" " + (int) sb.charAt(j)); // GWT compatible + } + assertEquals(repro.toString(), utf8Length, Utf8.encodedLength(sb)); + } + } + } + } + + public void testEncodedLength_invalidStrings() { + testEncodedLengthFails(newString(Character.MIN_HIGH_SURROGATE), 0); + testEncodedLengthFails("foobar" + newString(Character.MIN_HIGH_SURROGATE), 6); + testEncodedLengthFails(newString(Character.MIN_LOW_SURROGATE), 0); + testEncodedLengthFails("foobar" + newString(Character.MIN_LOW_SURROGATE), 6); + testEncodedLengthFails( + newString( + Character.MIN_HIGH_SURROGATE, + Character.MIN_HIGH_SURROGATE), 0); + } + + private static void testEncodedLengthFails(String invalidString, + int invalidCodePointIndex) { + try { + Utf8.encodedLength(invalidString); + fail(); + } catch (IllegalArgumentException expected) { + assertEquals("Unpaired surrogate at index " + invalidCodePointIndex, + expected.getMessage()); + } + } + + // 128 - [chars 0x0000 to 0x007f] + private static final long ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS = + 0x007f - 0x0000 + 1; + + // 128 + private static final long EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT = + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS; + + // 1920 [chars 0x0080 to 0x07FF] + private static final long TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS = + 0x07FF - 0x0080 + 1; + + // 18,304 + private static final long EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT = + // Both bytes are one byte characters + (long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 2) + + // The possible number of two byte characters + TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS; + + // 2048 + private static final long THREE_BYTE_SURROGATES = 2 * 1024; + + // 61,440 [chars 0x0800 to 0xFFFF, minus surrogates] + private static final long THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS = + 0xFFFF - 0x0800 + 1 - THREE_BYTE_SURROGATES; + + // 2,650,112 + private static final long EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT = + // All one byte characters + (long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 3) + + // One two byte character and a one byte character + 2 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS + + // Three byte characters + THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS; + + // 1,048,576 [chars 0x10000L to 0x10FFFF] + private static final long FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS = + 0x10FFFF - 0x10000L + 1; + + // 289,571,839 + private static final long EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT = + // All one byte characters + (long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 4) + + // One and three byte characters + 2 * THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS * + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS + + // Two two byte characters + TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS + + // Permutations of one and two byte characters + 3 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS * + ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS + + // Four byte characters + FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS; + + /** Tests that round tripping of all two byte permutations work. */ + @GwtIncompatible("java.nio.charset.Charset") + public void testIsWellFormed_1Byte() { + testBytes(1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT); + } + + /** Tests that round tripping of all two byte permutations work. */ + @GwtIncompatible("java.nio.charset.Charset") + public void testIsWellFormed_2Bytes() { + testBytes(2, EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT); + } + + /** Tests that round tripping of all three byte permutations work. */ + @GwtIncompatible("java.nio.charset.Charset") + public void testIsWellFormed_3Bytes() { + testBytes(3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT); + } + + /** + * Tests that round tripping of a sample of four byte permutations work. + * All permutations are prohibitively expensive to test for automated runs. + * This method tests specific four-byte cases. + */ + public void testIsWellFormed_4BytesSamples() { + // Valid 4 byte. + assertWellFormed(0xF0, 0xA4, 0xAD, 0xA2); + // Bad trailing bytes + assertNotWellFormed(0xF0, 0xA4, 0xAD, 0x7F); + assertNotWellFormed(0xF0, 0xA4, 0xAD, 0xC0); + // Special cases for byte2 + assertNotWellFormed(0xF0, 0x8F, 0xAD, 0xA2); + assertNotWellFormed(0xF4, 0x90, 0xAD, 0xA2); + } + + /** Tests some hard-coded test cases. */ + public void testSomeSequences() { + // Empty + assertWellFormed(); + // One-byte characters, including control characters + assertWellFormed(0x00, 0x61, 0x62, 0x63, 0x7F); // "\u0000abc\u007f" + // Two-byte characters + assertWellFormed(0xC2, 0xA2, 0xC2, 0xA2); // "\u00a2\u00a2" + // Three-byte characters + assertWellFormed(0xc8, 0x8a, 0x63, 0xc8, 0x8a, 0x63); // "\u020ac\u020ac" + // Four-byte characters + // "\u024B62\u024B62" + assertWellFormed(0xc9, 0x8b, 0x36, 0x32, 0xc9, 0x8b, 0x36, 0x32); + // Mixed string + // "a\u020ac\u00a2b\\u024B62u020acc\u00a2de\u024B62" + assertWellFormed(0x61, 0xc8, 0x8a, 0x63, 0xc2, 0xa2, 0x62, 0x5c, 0x75, 0x30, + 0x32, 0x34, 0x42, 0x36, 0x32, 0x75, 0x30, 0x32, 0x30, 0x61, 0x63, 0x63, + 0xc2, 0xa2, 0x64, 0x65, 0xc9, 0x8b, 0x36, 0x32); + // Not a valid string + assertNotWellFormed(-1, 0, -1, 0); + } + + public void testShardsHaveExpectedRoundTrippables() { + // A sanity check. + long actual = 0; + for (long expected : generateFourByteShardsExpectedRunnables()) { + actual += expected; + } + assertEquals(EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT, actual); + } + + private String newString(char... chars) { + return new String(chars); + } + + private byte[] toByteArray(int... bytes) { + byte[] realBytes = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + realBytes[i] = (byte) bytes[i]; + } + return realBytes; + } + + private void assertWellFormed(int... bytes) { + assertTrue(Utf8.isWellFormed(toByteArray(bytes))); + } + + private void assertNotWellFormed(int... bytes) { + assertFalse(Utf8.isWellFormed(toByteArray(bytes))); + } + + private static long[] generateFourByteShardsExpectedRunnables() { + long[] expected = new long[128]; + // 0-63 are all 5300224 + for (int i = 0; i <= 63; i++) { + expected[i] = 5300224; + } + // 97-111 are all 2342912 + for (int i = 97; i <= 111; i++) { + expected[i] = 2342912; + } + // 113-117 are all 1048576 + for (int i = 113; i <= 117; i++) { + expected[i] = 1048576; + } + // One offs + expected[112] = 786432; + expected[118] = 786432; + expected[119] = 1048576; + expected[120] = 458752; + expected[121] = 524288; + expected[122] = 65536; + // Anything not assigned was the default 0. + return expected; + } + + /** + * Helper to run the loop to test all the permutations for the number of bytes + * specified. + * + * @param numBytes the number of bytes in the byte array + * @param expectedCount the expected number of roundtrippable permutations + */ + @GwtIncompatible("java.nio.charset.Charset") + private static void testBytes(int numBytes, long expectedCount) { + testBytes(numBytes, expectedCount, 0, -1); + } + + /** + * Helper to run the loop to test all the permutations for the number of bytes + * specified. This overload is useful for debugging to get the loop to start + * at a certain character. + * + * @param numBytes the number of bytes in the byte array + * @param expectedCount the expected number of roundtrippable permutations + * @param start the starting bytes encoded as a long as big-endian + * @param lim the limit of bytes to process encoded as a long as big-endian, + * or -1 to mean the max limit for numBytes + */ + @GwtIncompatible("java.nio.charset.Charset") + private static void testBytes(int numBytes, long expectedCount, long start, + long lim) { + byte[] bytes = new byte[numBytes]; + if (lim == -1) { + lim = 1L << (numBytes * 8); + } + long countRoundTripped = 0; + for (long byteChar = start; byteChar < lim; byteChar++) { + long tmpByteChar = byteChar; + for (int i = 0; i < numBytes; i++) { + bytes[bytes.length - i - 1] = (byte) tmpByteChar; + tmpByteChar = tmpByteChar >> 8; + } + boolean isRoundTrippable = Utf8.isWellFormed(bytes); + assertEquals(isRoundTrippable, Utf8.isWellFormed(bytes, 0, numBytes)); + boolean bytesEqual; + try { + String s = new String(bytes, Charsets.UTF_8.name()); + byte[] bytesReencoded = s.getBytes(Charsets.UTF_8.name()); + bytesEqual = Arrays.equals(bytes, bytesReencoded); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } + + if (bytesEqual != isRoundTrippable) { + fail(); + } + if (isRoundTrippable) { + countRoundTripped++; + } + } + assertEquals(expectedCount, countRoundTripped); + } +} diff --git a/guava-tests/test/com/google/common/base/VerifyTest.java b/guava-tests/test/com/google/common/base/VerifyTest.java new file mode 100644 index 0000000..bb08980 --- /dev/null +++ b/guava-tests/test/com/google/common/base/VerifyTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.base; + +import static com.google.common.base.Verify.verify; +import static com.google.common.base.Verify.verifyNotNull; + +import com.google.common.annotations.GwtCompatible; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +/** + * Unit test for {@link com.google.common.base.Verify}. + */ +@GwtCompatible +public class VerifyTest extends TestCase { + public void testVerify_simple_success() { + verify(true); + } + + public void testVerify_simple_failure() { + try { + verify(false); + fail(); + } catch (VerifyException expected) { + } + } + + public void testVerify_simpleMessage_success() { + verify(true, "message"); + } + + public void testVerify_simpleMessage_failure() { + try { + verify(false, "message"); + fail(); + } catch (VerifyException expected) { + assertEquals("message", expected.getMessage()); + } + } + + public void testVerify_complexMessage_success() { + verify(true, "%s", IGNORE_ME); + } + + public void testVerify_complexMessage_failure() { + try { + verify(false, FORMAT, 5); + fail(); + } catch (VerifyException expected) { + checkMessage(expected); + } + } + + private static final String NON_NULL_STRING = "foo"; + + public void testVerifyNotNull_simple_success() { + String result = verifyNotNull(NON_NULL_STRING); + assertSame(NON_NULL_STRING, result); + } + + public void testVerifyNotNull_simple_failure() { + try { + verifyNotNull(null); + fail(); + } catch (VerifyException expected) { + } + } + + public void testVerifyNotNull_complexMessage_success() { + String result = verifyNotNull(NON_NULL_STRING, "%s", IGNORE_ME); + assertSame(NON_NULL_STRING, result); + } + + public void testVerifyNotNull_simpleMessage_failure() { + try { + verifyNotNull(null, FORMAT, 5); + fail(); + } catch (VerifyException expected) { + checkMessage(expected); + } + } + + private static final Object IGNORE_ME = new Object() { + @Override public String toString() { + throw new AssertionFailedError(); + } + }; + + private static final String FORMAT = "I ate %s pies."; + + private static void checkMessage(Exception e) { + assertEquals("I ate 5 pies.", e.getMessage()); + } +} diff --git a/guava-tests/test/com/google/common/cache/AbstractCacheTest.java b/guava-tests/test/com/google/common/cache/AbstractCacheTest.java index 574592a..6935133 100644 --- a/guava-tests/test/com/google/common/cache/AbstractCacheTest.java +++ b/guava-tests/test/com/google/common/cache/AbstractCacheTest.java @@ -21,11 +21,11 @@ import com.google.common.cache.AbstractCache.StatsCounter; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import junit.framework.TestCase; + import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import junit.framework.TestCase; - /** * Unit test for {@link AbstractCache}. * @@ -105,15 +105,15 @@ public class AbstractCacheTest extends TestCase { int requestCount = 11 + 23; assertEquals(requestCount, stats.requestCount()); assertEquals(11, stats.hitCount()); - assertEquals(11.0/requestCount, stats.hitRate()); + assertEquals(11.0 / requestCount, stats.hitRate()); int missCount = 23; assertEquals(missCount, stats.missCount()); - assertEquals(((double) missCount)/requestCount, stats.missRate()); + assertEquals(((double) missCount) / requestCount, stats.missRate()); assertEquals(13, stats.loadSuccessCount()); assertEquals(17, stats.loadExceptionCount()); assertEquals(13 + 17, stats.loadCount()); assertEquals(214, stats.totalLoadTime()); - assertEquals(214.0/(13 + 17), stats.averageLoadPenalty()); + assertEquals(214.0 / (13 + 17), stats.averageLoadPenalty()); assertEquals(27, stats.evictionCount()); } diff --git a/guava-tests/test/com/google/common/cache/AbstractLoadingCacheTest.java b/guava-tests/test/com/google/common/cache/AbstractLoadingCacheTest.java index 48f95a1..1fa1b87 100644 --- a/guava-tests/test/com/google/common/cache/AbstractLoadingCacheTest.java +++ b/guava-tests/test/com/google/common/cache/AbstractLoadingCacheTest.java @@ -19,11 +19,11 @@ package com.google.common.cache; import com.google.common.util.concurrent.ExecutionError; import com.google.common.util.concurrent.UncheckedExecutionException; +import junit.framework.TestCase; + import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicReference; -import junit.framework.TestCase; - /** * Unit test for {@link AbstractLoadingCache}. * diff --git a/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java b/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java index 8f02fe2..b93db3f 100644 --- a/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java +++ b/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java @@ -23,6 +23,8 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.google.common.testing.FakeTicker; +import junit.framework.TestCase; + import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; @@ -32,8 +34,6 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import junit.framework.TestCase; - /** * Test suite for {@link CacheBuilder}. * TODO(cpovirk): merge into CacheBuilderTest? diff --git a/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java b/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java index b1c70a2..aae9a46 100644 --- a/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java +++ b/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java @@ -263,26 +263,26 @@ public class CacheBuilderSpecTest extends TestCase { assertNull(spec.keyStrength); assertNull(spec.valueStrength); assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit); - assertEquals(24*60*60*10L, spec.writeExpirationDuration); + assertEquals(24 * 60 * 60 * 10L, spec.writeExpirationDuration); assertNull(spec.accessExpirationTimeUnit); assertCacheBuilderEquivalence( - CacheBuilder.newBuilder().expireAfterWrite(24*60*60*10L, TimeUnit.SECONDS), CacheBuilder.from(spec)); + CacheBuilder.newBuilder().expireAfterWrite(24 * 60 * 60 * 10L, TimeUnit.SECONDS), CacheBuilder.from(spec)); } public void testParse_writeExpirationHours() { CacheBuilderSpec spec = parse("expireAfterWrite=150h"); assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit); - assertEquals(60*60*150L, spec.writeExpirationDuration); + assertEquals(60 * 60 * 150L, spec.writeExpirationDuration); assertCacheBuilderEquivalence( - CacheBuilder.newBuilder().expireAfterWrite(60*60*150L, TimeUnit.SECONDS), CacheBuilder.from(spec)); + CacheBuilder.newBuilder().expireAfterWrite(60 * 60 * 150L, TimeUnit.SECONDS), CacheBuilder.from(spec)); } public void testParse_writeExpirationMinutes() { CacheBuilderSpec spec = parse("expireAfterWrite=10m"); assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit); - assertEquals(60*10L, spec.writeExpirationDuration); + assertEquals(60 * 10L, spec.writeExpirationDuration); assertCacheBuilderEquivalence( - CacheBuilder.newBuilder().expireAfterWrite(60*10L, TimeUnit.SECONDS), CacheBuilder.from(spec)); + CacheBuilder.newBuilder().expireAfterWrite(60 * 10L, TimeUnit.SECONDS), CacheBuilder.from(spec)); } public void testParse_writeExpirationSeconds() { @@ -313,25 +313,25 @@ public class CacheBuilderSpecTest extends TestCase { assertNull(spec.valueStrength); assertNull(spec.writeExpirationTimeUnit); assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit); - assertEquals(24*60*60*10L, spec.accessExpirationDuration); + assertEquals(24 * 60 * 60 * 10L, spec.accessExpirationDuration); assertCacheBuilderEquivalence( - CacheBuilder.newBuilder().expireAfterAccess(24*60*60*10L, TimeUnit.SECONDS), CacheBuilder.from(spec)); + CacheBuilder.newBuilder().expireAfterAccess(24 * 60 * 60 * 10L, TimeUnit.SECONDS), CacheBuilder.from(spec)); } public void testParse_accessExpirationHours() { CacheBuilderSpec spec = parse("expireAfterAccess=150h"); assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit); - assertEquals(60*60*150L, spec.accessExpirationDuration); + assertEquals(60 * 60 * 150L, spec.accessExpirationDuration); assertCacheBuilderEquivalence( - CacheBuilder.newBuilder().expireAfterAccess(60*60*150L, TimeUnit.SECONDS), CacheBuilder.from(spec)); + CacheBuilder.newBuilder().expireAfterAccess(60 * 60 * 150L, TimeUnit.SECONDS), CacheBuilder.from(spec)); } public void testParse_accessExpirationMinutes() { CacheBuilderSpec spec = parse("expireAfterAccess=10m"); assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit); - assertEquals(60*10L, spec.accessExpirationDuration); + assertEquals(60 * 10L, spec.accessExpirationDuration); assertCacheBuilderEquivalence( - CacheBuilder.newBuilder().expireAfterAccess(60*10L, TimeUnit.SECONDS), + CacheBuilder.newBuilder().expireAfterAccess(60 * 10L, TimeUnit.SECONDS), CacheBuilder.from(spec)); } @@ -354,16 +354,40 @@ public class CacheBuilderSpecTest extends TestCase { } } + public void testParse_recordStats() { + CacheBuilderSpec spec = parse("recordStats"); + assertTrue(spec.recordStats); + assertCacheBuilderEquivalence(CacheBuilder.newBuilder().recordStats(), CacheBuilder.from(spec)); + } + + public void testParse_recordStatsValueSpecified() { + try { + parse("recordStats=True"); + fail("Expected exception"); + } catch (IllegalArgumentException expected) { + // expected + } + } + + public void testParse_recordStatsRepeated() { + try { + parse("recordStats,recordStats"); + fail("Expected exception"); + } catch (IllegalArgumentException expected) { + // expected + } + } + public void testParse_accessExpirationAndWriteExpiration() { CacheBuilderSpec spec = parse("expireAfterAccess=10s,expireAfterWrite=9m"); assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit); - assertEquals(60*9L, spec.writeExpirationDuration); + assertEquals(60 * 9L, spec.writeExpirationDuration); assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit); assertEquals(10L, spec.accessExpirationDuration); assertCacheBuilderEquivalence( CacheBuilder.newBuilder() .expireAfterAccess(10L, TimeUnit.SECONDS) - .expireAfterWrite(60*9L, TimeUnit.SECONDS), + .expireAfterWrite(60 * 9L, TimeUnit.SECONDS), CacheBuilder.from(spec)); } @@ -378,16 +402,16 @@ public class CacheBuilderSpecTest extends TestCase { assertEquals(Strength.WEAK, spec.valueStrength); assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit); assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit); - assertEquals(60*60*1L, spec.writeExpirationDuration); - assertEquals(60*10L, spec.accessExpirationDuration); - CacheBuilder expected = CacheBuilder.newBuilder() + assertEquals(60 * 60 * 1L, spec.writeExpirationDuration); + assertEquals(60 * 10L, spec.accessExpirationDuration); + CacheBuilder<?, ?> expected = CacheBuilder.newBuilder() .initialCapacity(10) .maximumSize(20) .concurrencyLevel(30) .weakKeys() .weakValues() - .expireAfterAccess(60*10L, TimeUnit.SECONDS) - .expireAfterWrite(60*60*1L, TimeUnit.SECONDS); + .expireAfterAccess(60 * 10L, TimeUnit.SECONDS) + .expireAfterWrite(60 * 60 * 1L, TimeUnit.SECONDS); assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec)); } @@ -403,7 +427,7 @@ public class CacheBuilderSpecTest extends TestCase { assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit); assertEquals(15L, spec.writeExpirationDuration); assertNull(spec.accessExpirationTimeUnit); - CacheBuilder expected = CacheBuilder.newBuilder() + CacheBuilder<?, ?> expected = CacheBuilder.newBuilder() .initialCapacity(10) .maximumSize(20) .weakKeys() @@ -462,6 +486,7 @@ public class CacheBuilderSpecTest extends TestCase { .addEqualityGroup(parse("weakKeys"), parse("weakKeys")) .addEqualityGroup(parse("softValues"), parse("softValues")) .addEqualityGroup(parse("weakValues"), parse("weakValues")) + .addEqualityGroup(parse("recordStats"), parse("recordStats")) .testEquals(); } @@ -506,20 +531,20 @@ public class CacheBuilderSpecTest extends TestCase { } public void testCacheBuilderFrom_string() { - CacheBuilder fromString = CacheBuilder.from( + CacheBuilder<?, ?> fromString = CacheBuilder.from( "initialCapacity=10,maximumSize=20,concurrencyLevel=30," + "weakKeys,weakValues,expireAfterAccess=10m"); - CacheBuilder expected = CacheBuilder.newBuilder() + CacheBuilder<?, ?> expected = CacheBuilder.newBuilder() .initialCapacity(10) .maximumSize(20) .concurrencyLevel(30) .weakKeys() .weakValues() - .expireAfterAccess(60*10L, TimeUnit.SECONDS); + .expireAfterAccess(60 * 10L, TimeUnit.SECONDS); assertCacheBuilderEquivalence(expected, fromString); } - private static void assertCacheBuilderEquivalence(CacheBuilder a, CacheBuilder b) { + private static void assertCacheBuilderEquivalence(CacheBuilder<?, ?> a, CacheBuilder<?, ?> b) { assertEquals("concurrencyLevel", a.concurrencyLevel, b.concurrencyLevel); assertEquals("expireAfterAccessNanos", a.expireAfterAccessNanos, b.expireAfterAccessNanos); assertEquals("expireAfterWriteNanos", a.expireAfterWriteNanos, b.expireAfterWriteNanos); @@ -535,5 +560,6 @@ public class CacheBuilderSpecTest extends TestCase { assertEquals("valueStrength", a.valueStrength, b.valueStrength); assertEquals("statsCounterSupplier", a.statsCounterSupplier, b.statsCounterSupplier); assertEquals("ticker", a.ticker, b.ticker); + assertEquals("recordStats", a.isRecordingStats(), b.isRecordingStats()); } } diff --git a/guava-tests/test/com/google/common/cache/CacheBuilderTest.java b/guava-tests/test/com/google/common/cache/CacheBuilderTest.java index fecd13e..1d882e6 100644 --- a/guava-tests/test/com/google/common/cache/CacheBuilderTest.java +++ b/guava-tests/test/com/google/common/cache/CacheBuilderTest.java @@ -34,6 +34,8 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Map; import java.util.Random; import java.util.Set; @@ -44,8 +46,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import junit.framework.TestCase; - /** * Unit tests for CacheBuilder. */ diff --git a/guava-tests/test/com/google/common/cache/CacheEvictionTest.java b/guava-tests/test/com/google/common/cache/CacheEvictionTest.java index 6f948fc..6746b7e 100644 --- a/guava-tests/test/com/google/common/cache/CacheEvictionTest.java +++ b/guava-tests/test/com/google/common/cache/CacheEvictionTest.java @@ -26,13 +26,10 @@ import com.google.common.cache.LocalCache.ReferenceEntry; import com.google.common.cache.TestingCacheLoaders.IdentityLoader; import com.google.common.cache.TestingRemovalListeners.CountingRemovalListener; -import java.util.Collection; -import java.util.List; -import java.util.Set; - import junit.framework.TestCase; -import org.truth0.subjects.CollectionSubject; +import java.util.List; +import java.util.Set; /** * Tests relating to cache eviction: what does and doesn't count toward maximumSize, what happens @@ -172,27 +169,27 @@ public class CacheEvictionTest extends TestCase { .build(loader); CacheTesting.warmUp(cache, 0, 10); Set<Integer> keySet = cache.asMap().keySet(); - assertThat(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + ASSERT.that(keySet).has().exactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); // re-order getAll(cache, asList(0, 1, 2)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0, 1, 2); + ASSERT.that(keySet).has().exactly(3, 4, 5, 6, 7, 8, 9, 0, 1, 2); // evict 3, 4, 5 getAll(cache, asList(10, 11, 12)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(6, 7, 8, 9, 0, 1, 2, 10, 11, 12); + ASSERT.that(keySet).has().exactly(6, 7, 8, 9, 0, 1, 2, 10, 11, 12); // re-order getAll(cache, asList(6, 7, 8)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(9, 0, 1, 2, 10, 11, 12, 6, 7, 8); + ASSERT.that(keySet).has().exactly(9, 0, 1, 2, 10, 11, 12, 6, 7, 8); // evict 9, 0, 1 getAll(cache, asList(13, 14, 15)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(2, 10, 11, 12, 6, 7, 8, 13, 14, 15); + ASSERT.that(keySet).has().exactly(2, 10, 11, 12, 6, 7, 8, 13, 14, 15); } public void testEviction_weightedLru() { @@ -205,37 +202,37 @@ public class CacheEvictionTest extends TestCase { .build(loader); CacheTesting.warmUp(cache, 0, 10); Set<Integer> keySet = cache.asMap().keySet(); - assertThat(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + ASSERT.that(keySet).has().exactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); // re-order getAll(cache, asList(0, 1, 2)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0, 1, 2); + ASSERT.that(keySet).has().exactly(3, 4, 5, 6, 7, 8, 9, 0, 1, 2); // evict 3, 4, 5 getAll(cache, asList(10)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(6, 7, 8, 9, 0, 1, 2, 10); + ASSERT.that(keySet).has().exactly(6, 7, 8, 9, 0, 1, 2, 10); // re-order getAll(cache, asList(6, 7, 8)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(9, 0, 1, 2, 10, 6, 7, 8); + ASSERT.that(keySet).has().exactly(9, 0, 1, 2, 10, 6, 7, 8); // evict 9, 1, 2, 10 getAll(cache, asList(15)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(0, 6, 7, 8, 15); + ASSERT.that(keySet).has().exactly(0, 6, 7, 8, 15); // fill empty space getAll(cache, asList(9)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(0, 6, 7, 8, 15, 9); + ASSERT.that(keySet).has().exactly(0, 6, 7, 8, 15, 9); // evict 6 getAll(cache, asList(1)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(0, 7, 8, 15, 9, 1); + ASSERT.that(keySet).has().exactly(0, 7, 8, 15, 9, 1); } public void testEviction_overweight() { @@ -248,17 +245,17 @@ public class CacheEvictionTest extends TestCase { .build(loader); CacheTesting.warmUp(cache, 0, 10); Set<Integer> keySet = cache.asMap().keySet(); - assertThat(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + ASSERT.that(keySet).has().exactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); // add an at-the-maximum-weight entry getAll(cache, asList(45)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(0, 45); + ASSERT.that(keySet).has().exactly(0, 45); // add an over-the-maximum-weight entry getAll(cache, asList(46)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().item(0); + ASSERT.that(keySet).has().item(0); } public void testEviction_invalidateAll() { @@ -270,22 +267,22 @@ public class CacheEvictionTest extends TestCase { .build(loader); Set<Integer> keySet = cache.asMap().keySet(); - assertThat(keySet).isEmpty(); + ASSERT.that(keySet).isEmpty(); // add 0, 1, 2, 3, 4 getAll(cache, asList(0, 1, 2, 3, 4)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(0, 1, 2, 3, 4); + ASSERT.that(keySet).has().exactly(0, 1, 2, 3, 4); // invalidate all cache.invalidateAll(); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).isEmpty(); + ASSERT.that(keySet).isEmpty(); // add 5, 6, 7, 8, 9, 10, 11, 12 getAll(cache, asList(5, 6, 7, 8, 9, 10, 11, 12)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(5, 6, 7, 8, 9, 10, 11, 12); + ASSERT.that(keySet).has().exactly(5, 6, 7, 8, 9, 10, 11, 12); } private void getAll(LoadingCache<Integer, Integer> cache, List<Integer> keys) { @@ -293,10 +290,4 @@ public class CacheEvictionTest extends TestCase { cache.getUnchecked(i); } } - - // Hack for JDK5 type inference. - private <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/cache/CacheExpirationTest.java b/guava-tests/test/com/google/common/cache/CacheExpirationTest.java index 07809ff..d39374d 100644 --- a/guava-tests/test/com/google/common/cache/CacheExpirationTest.java +++ b/guava-tests/test/com/google/common/cache/CacheExpirationTest.java @@ -26,24 +26,20 @@ import com.google.common.collect.Iterators; import com.google.common.testing.FakeTicker; import com.google.common.util.concurrent.Callables; -import java.util.Collection; +import junit.framework.TestCase; + import java.util.List; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicInteger; -import junit.framework.TestCase; - -import org.truth0.subjects.CollectionSubject; - /** * Tests relating to cache expiration: make sure entries expire at the right times, make sure * expired entries don't show up, etc. * * @author mike nonemacher */ -@SuppressWarnings("deprecation") -// tests of deprecated method +@SuppressWarnings("deprecation") // tests of deprecated method public class CacheExpirationTest extends TestCase { private static final long EXPIRING_TIME = 1000; @@ -55,8 +51,10 @@ public class CacheExpirationTest extends TestCase { CountingRemovalListener<String, Integer> removalListener = countingRemovalListener(); WatchedCreatorLoader loader = new WatchedCreatorLoader(); LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() - .expireAfterWrite(EXPIRING_TIME, MILLISECONDS).removalListener(removalListener) - .ticker(ticker).build(loader); + .expireAfterWrite(EXPIRING_TIME, MILLISECONDS) + .removalListener(removalListener) + .ticker(ticker) + .build(loader); checkExpiration(cache, loader, ticker, removalListener); } @@ -65,8 +63,10 @@ public class CacheExpirationTest extends TestCase { CountingRemovalListener<String, Integer> removalListener = countingRemovalListener(); WatchedCreatorLoader loader = new WatchedCreatorLoader(); LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() - .expireAfterAccess(EXPIRING_TIME, MILLISECONDS).removalListener(removalListener) - .ticker(ticker).build(loader); + .expireAfterAccess(EXPIRING_TIME, MILLISECONDS) + .removalListener(removalListener) + .ticker(ticker) + .build(loader); checkExpiration(cache, loader, ticker, removalListener); } @@ -83,14 +83,16 @@ public class CacheExpirationTest extends TestCase { assertFalse("Creator should not have been called @#" + i, loader.wasCalled()); } - CacheTesting.expireEntries(cache, EXPIRING_TIME, ticker); + CacheTesting.expireEntries((LoadingCache<?, ?>) cache, EXPIRING_TIME, ticker); assertEquals("Map must be empty by now", 0, cache.size()); - assertEquals("Eviction notifications must be received", 10, removalListener.getCount()); + assertEquals("Eviction notifications must be received", 10, + removalListener.getCount()); - CacheTesting.expireEntries(cache, EXPIRING_TIME, ticker); + CacheTesting.expireEntries((LoadingCache<?, ?>) cache, EXPIRING_TIME, ticker); // ensure that no new notifications are sent - assertEquals("Eviction notifications must be received", 10, removalListener.getCount()); + assertEquals("Eviction notifications must be received", 10, + removalListener.getCount()); } public void testExpiringGet_expireAfterWrite() { @@ -98,8 +100,10 @@ public class CacheExpirationTest extends TestCase { CountingRemovalListener<String, Integer> removalListener = countingRemovalListener(); WatchedCreatorLoader loader = new WatchedCreatorLoader(); LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() - .expireAfterWrite(EXPIRING_TIME, MILLISECONDS).removalListener(removalListener) - .ticker(ticker).build(loader); + .expireAfterWrite(EXPIRING_TIME, MILLISECONDS) + .removalListener(removalListener) + .ticker(ticker) + .build(loader); runExpirationTest(cache, loader, ticker, removalListener); } @@ -108,8 +112,10 @@ public class CacheExpirationTest extends TestCase { CountingRemovalListener<String, Integer> removalListener = countingRemovalListener(); WatchedCreatorLoader loader = new WatchedCreatorLoader(); LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() - .expireAfterAccess(EXPIRING_TIME, MILLISECONDS).removalListener(removalListener) - .ticker(ticker).build(loader); + .expireAfterAccess(EXPIRING_TIME, MILLISECONDS) + .removalListener(removalListener) + .ticker(ticker) + .build(loader); runExpirationTest(cache, loader, ticker, removalListener); } @@ -137,7 +143,7 @@ public class CacheExpirationTest extends TestCase { assertEquals(1, Iterators.size(cache.asMap().keySet().iterator())); assertEquals(1, Iterators.size(cache.asMap().values().iterator())); - CacheTesting.expireEntries(cache, EXPIRING_TIME, ticker); + CacheTesting.expireEntries((LoadingCache<?, ?>) cache, EXPIRING_TIME, ticker); for (int i = 0; i < 11; i++) { assertFalse(cache.asMap().containsKey(KEY_PREFIX + i)); @@ -152,12 +158,14 @@ public class CacheExpirationTest extends TestCase { } // expire new values we just created - CacheTesting.expireEntries(cache, EXPIRING_TIME, ticker); - assertEquals("Eviction notifications must be received", 21, removalListener.getCount()); + CacheTesting.expireEntries((LoadingCache<?, ?>) cache, EXPIRING_TIME, ticker); + assertEquals("Eviction notifications must be received", 21, + removalListener.getCount()); - CacheTesting.expireEntries(cache, EXPIRING_TIME, ticker); + CacheTesting.expireEntries((LoadingCache<?, ?>) cache, EXPIRING_TIME, ticker); // ensure that no new notifications are sent - assertEquals("Eviction notifications must be received", 21, removalListener.getCount()); + assertEquals("Eviction notifications must be received", 21, + removalListener.getCount()); } public void testRemovalListener_expireAfterWrite() { @@ -166,26 +174,28 @@ public class CacheExpirationTest extends TestCase { final AtomicInteger applyCount = new AtomicInteger(); final AtomicInteger totalSum = new AtomicInteger(); - RemovalListener<Integer, AtomicInteger> removalListener = new RemovalListener<Integer, AtomicInteger>() { - @Override - public void onRemoval(RemovalNotification<Integer, AtomicInteger> notification) { - if (notification.wasEvicted()) { - evictionCount.incrementAndGet(); - totalSum.addAndGet(notification.getValue().get()); - } - } - }; + RemovalListener<Integer, AtomicInteger> removalListener = + new RemovalListener<Integer, AtomicInteger>() { + @Override + public void onRemoval(RemovalNotification<Integer, AtomicInteger> notification) { + if (notification.wasEvicted()) { + evictionCount.incrementAndGet(); + totalSum.addAndGet(notification.getValue().get()); + } + } + }; CacheLoader<Integer, AtomicInteger> loader = new CacheLoader<Integer, AtomicInteger>() { - @Override - public AtomicInteger load(Integer key) { + @Override public AtomicInteger load(Integer key) { applyCount.incrementAndGet(); return new AtomicInteger(); } }; LoadingCache<Integer, AtomicInteger> cache = CacheBuilder.newBuilder() - .removalListener(removalListener).expireAfterWrite(10, MILLISECONDS).ticker(ticker) + .removalListener(removalListener) + .expireAfterWrite(10, MILLISECONDS) + .ticker(ticker) .build(loader); // Increment 100 times @@ -204,8 +214,10 @@ public class CacheExpirationTest extends TestCase { CountingRemovalListener<String, Integer> removalListener = countingRemovalListener(); WatchedCreatorLoader loader = new WatchedCreatorLoader(); LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() - .expireAfterWrite(EXPIRING_TIME, MILLISECONDS).removalListener(removalListener) - .ticker(ticker).build(loader); + .expireAfterWrite(EXPIRING_TIME, MILLISECONDS) + .removalListener(removalListener) + .ticker(ticker) + .build(loader); runRemovalScheduler(cache, removalListener, loader, ticker, KEY_PREFIX, EXPIRING_TIME); } @@ -214,8 +226,10 @@ public class CacheExpirationTest extends TestCase { CountingRemovalListener<String, Integer> removalListener = countingRemovalListener(); WatchedCreatorLoader loader = new WatchedCreatorLoader(); LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() - .expireAfterAccess(EXPIRING_TIME, MILLISECONDS).removalListener(removalListener) - .ticker(ticker).build(loader); + .expireAfterAccess(EXPIRING_TIME, MILLISECONDS) + .removalListener(removalListener) + .ticker(ticker) + .build(loader); runRemovalScheduler(cache, removalListener, loader, ticker, KEY_PREFIX, EXPIRING_TIME); } @@ -225,8 +239,10 @@ public class CacheExpirationTest extends TestCase { WatchedCreatorLoader loader = new WatchedCreatorLoader(); LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() .expireAfterAccess(EXPIRING_TIME, MILLISECONDS) - .expireAfterWrite(EXPIRING_TIME, MILLISECONDS).removalListener(removalListener) - .ticker(ticker).build(loader); + .expireAfterWrite(EXPIRING_TIME, MILLISECONDS) + .removalListener(removalListener) + .ticker(ticker) + .build(loader); runRemovalScheduler(cache, removalListener, loader, ticker, KEY_PREFIX, EXPIRING_TIME); } @@ -234,101 +250,110 @@ public class CacheExpirationTest extends TestCase { // test lru within a single segment FakeTicker ticker = new FakeTicker(); IdentityLoader<Integer> loader = identityLoader(); - LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder().concurrencyLevel(1) - .expireAfterAccess(11, MILLISECONDS).ticker(ticker).build(loader); + LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder() + .concurrencyLevel(1) + .expireAfterAccess(11, MILLISECONDS) + .ticker(ticker) + .build(loader); for (int i = 0; i < 10; i++) { cache.getUnchecked(i); ticker.advance(1, MILLISECONDS); } Set<Integer> keySet = cache.asMap().keySet(); - assertThat(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + ASSERT.that(keySet).has().exactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); // 0 expires ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(1, 2, 3, 4, 5, 6, 7, 8, 9); + ASSERT.that(keySet).has().exactly(1, 2, 3, 4, 5, 6, 7, 8, 9); // reorder getAll(cache, asList(0, 1, 2)); CacheTesting.drainRecencyQueues(cache); ticker.advance(2, MILLISECONDS); - assertThat(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0, 1, 2); + ASSERT.that(keySet).has().exactly(3, 4, 5, 6, 7, 8, 9, 0, 1, 2); // 3 expires ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(4, 5, 6, 7, 8, 9, 0, 1, 2); + ASSERT.that(keySet).has().exactly(4, 5, 6, 7, 8, 9, 0, 1, 2); // reorder getAll(cache, asList(5, 7, 9)); CacheTesting.drainRecencyQueues(cache); - assertThat(keySet).has().allOf(4, 6, 8, 0, 1, 2, 5, 7, 9); + ASSERT.that(keySet).has().exactly(4, 6, 8, 0, 1, 2, 5, 7, 9); // 4 expires ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(6, 8, 0, 1, 2, 5, 7, 9); + ASSERT.that(keySet).has().exactly(6, 8, 0, 1, 2, 5, 7, 9); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(6, 8, 0, 1, 2, 5, 7, 9); + ASSERT.that(keySet).has().exactly(6, 8, 0, 1, 2, 5, 7, 9); // 6 expires ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(8, 0, 1, 2, 5, 7, 9); + ASSERT.that(keySet).has().exactly(8, 0, 1, 2, 5, 7, 9); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(8, 0, 1, 2, 5, 7, 9); + ASSERT.that(keySet).has().exactly(8, 0, 1, 2, 5, 7, 9); // 8 expires ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(0, 1, 2, 5, 7, 9); + ASSERT.that(keySet).has().exactly(0, 1, 2, 5, 7, 9); } public void testExpirationOrder_write() throws ExecutionException { // test lru within a single segment FakeTicker ticker = new FakeTicker(); IdentityLoader<Integer> loader = identityLoader(); - LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder().concurrencyLevel(1) - .expireAfterWrite(11, MILLISECONDS).ticker(ticker).build(loader); + LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder() + .concurrencyLevel(1) + .expireAfterWrite(11, MILLISECONDS) + .ticker(ticker) + .build(loader); for (int i = 0; i < 10; i++) { cache.getUnchecked(i); ticker.advance(1, MILLISECONDS); } Set<Integer> keySet = cache.asMap().keySet(); - assertThat(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + ASSERT.that(keySet).has().exactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); // 0 expires ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(1, 2, 3, 4, 5, 6, 7, 8, 9); + ASSERT.that(keySet).has().exactly(1, 2, 3, 4, 5, 6, 7, 8, 9); // get doesn't stop 1 from expiring getAll(cache, asList(0, 1, 2)); CacheTesting.drainRecencyQueues(cache); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(2, 3, 4, 5, 6, 7, 8, 9, 0); + ASSERT.that(keySet).has().exactly(2, 3, 4, 5, 6, 7, 8, 9, 0); // get(K, Callable) doesn't stop 2 from expiring cache.get(2, Callables.returning(-2)); CacheTesting.drainRecencyQueues(cache); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0); + ASSERT.that(keySet).has().exactly(3, 4, 5, 6, 7, 8, 9, 0); // asMap.put saves 3 cache.asMap().put(3, -3); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(4, 5, 6, 7, 8, 9, 0, 3); + ASSERT.that(keySet).has().exactly(4, 5, 6, 7, 8, 9, 0, 3); // asMap.replace saves 4 cache.asMap().replace(4, -4); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(5, 6, 7, 8, 9, 0, 3, 4); + ASSERT.that(keySet).has().exactly(5, 6, 7, 8, 9, 0, 3, 4); // 5 expires ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(6, 7, 8, 9, 0, 3, 4); + ASSERT.that(keySet).has().exactly(6, 7, 8, 9, 0, 3, 4); } public void testExpirationOrder_writeAccess() throws ExecutionException { // test lru within a single segment FakeTicker ticker = new FakeTicker(); IdentityLoader<Integer> loader = identityLoader(); - LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder().concurrencyLevel(1) - .expireAfterWrite(5, MILLISECONDS).expireAfterAccess(3, MILLISECONDS).ticker(ticker) + LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder() + .concurrencyLevel(1) + .expireAfterWrite(5, MILLISECONDS) + .expireAfterAccess(3, MILLISECONDS) + .ticker(ticker) .build(loader); for (int i = 0; i < 5; i++) { cache.getUnchecked(i); @@ -340,37 +365,38 @@ public class CacheExpirationTest extends TestCase { ticker.advance(1, MILLISECONDS); Set<Integer> keySet = cache.asMap().keySet(); - assertThat(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + ASSERT.that(keySet).has().exactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); // get saves 1, 3; 0, 2, 4 expire getAll(cache, asList(1, 3)); CacheTesting.drainRecencyQueues(cache); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(5, 6, 7, 8, 9, 1, 3); + ASSERT.that(keySet).has().exactly(5, 6, 7, 8, 9, 1, 3); // get saves 6, 8; 5, 7, 9 expire getAll(cache, asList(6, 8)); CacheTesting.drainRecencyQueues(cache); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(1, 3, 6, 8); + ASSERT.that(keySet).has().exactly(1, 3, 6, 8); // get fails to save 1, put saves 3 cache.asMap().put(3, -3); getAll(cache, asList(1)); CacheTesting.drainRecencyQueues(cache); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(6, 8, 3); + ASSERT.that(keySet).has().exactly(6, 8, 3); // get(K, Callable) fails to save 8, replace saves 6 cache.asMap().replace(6, -6); cache.get(8, Callables.returning(-8)); CacheTesting.drainRecencyQueues(cache); ticker.advance(1, MILLISECONDS); - assertThat(keySet).has().allOf(3, 6); + ASSERT.that(keySet).has().exactly(3, 6); } private void runRemovalScheduler(LoadingCache<String, Integer> cache, - CountingRemovalListener<String, Integer> removalListener, WatchedCreatorLoader loader, + CountingRemovalListener<String, Integer> removalListener, + WatchedCreatorLoader loader, FakeTicker ticker, String keyPrefix, long ttl) { int shift1 = 10 + VALUE_PREFIX; @@ -393,11 +419,11 @@ public class CacheExpirationTest extends TestCase { // fill with new data - has to live for 20 ms more for (int i = 0; i < 10; i++) { cache.invalidate(keyPrefix + i); - assertEquals("key: " + keyPrefix + i, Integer.valueOf(i + shift2), - cache.getUnchecked(keyPrefix + i)); + assertEquals("key: " + keyPrefix + i, + Integer.valueOf(i + shift2), cache.getUnchecked(keyPrefix + i)); } assertEquals(10, CacheTesting.expirationQueueSize(cache)); - assertEquals(10, removalListener.getCount()); // these are the invalidated ones + assertEquals(10, removalListener.getCount()); // these are the invalidated ones // old timeouts must expire after this wait ticker.advance(ttl * 2 / 3, MILLISECONDS); @@ -425,7 +451,8 @@ public class CacheExpirationTest extends TestCase { String keyPrefix = KEY_PREFIX; int valuePrefix = VALUE_PREFIX; - public WatchedCreatorLoader() {} + public WatchedCreatorLoader() { + } public void reset() { wasCalled = false; @@ -443,16 +470,9 @@ public class CacheExpirationTest extends TestCase { this.valuePrefix = valuePrefix; } - @Override - public Integer load(String key) { + @Override public Integer load(String key) { wasCalled = true; return valuePrefix + Integer.parseInt(key.substring(keyPrefix.length())); } } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/cache/CacheLoaderTest.java b/guava-tests/test/com/google/common/cache/CacheLoaderTest.java new file mode 100644 index 0000000..9fcb7e8 --- /dev/null +++ b/guava-tests/test/com/google/common/cache/CacheLoaderTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2011 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.cache; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +import junit.framework.TestCase; + +import java.util.LinkedList; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Unit tests for {@link CacheLoader}. + * + * @author Charles Fry + */ +public class CacheLoaderTest extends TestCase { + + private static class QueuingExecutor implements Executor { + private LinkedList<Runnable> tasks = Lists.newLinkedList(); + + @Override + public void execute(Runnable task) { + tasks.add(task); + } + + private void runNext() { + tasks.removeFirst().run(); + } + } + + public void testAsyncReload() throws Exception { + final AtomicInteger loadCount = new AtomicInteger(); + final AtomicInteger reloadCount = new AtomicInteger(); + final AtomicInteger loadAllCount = new AtomicInteger(); + + CacheLoader<Object, Object> baseLoader = new CacheLoader<Object, Object>() { + @Override + public Object load(Object key) { + loadCount.incrementAndGet(); + return new Object(); + } + + @Override + public ListenableFuture<Object> reload(Object key, Object oldValue) { + reloadCount.incrementAndGet(); + return Futures.immediateFuture(new Object()); + } + + @Override + public Map<Object, Object> loadAll(Iterable<? extends Object> keys) { + loadAllCount.incrementAndGet(); + return ImmutableMap.of(); + } + }; + + assertEquals(0, loadCount.get()); + assertEquals(0, reloadCount.get()); + assertEquals(0, loadAllCount.get()); + + baseLoader.load(new Object()); + baseLoader.reload(new Object(), new Object()); + baseLoader.loadAll(ImmutableList.of(new Object())); + assertEquals(1, loadCount.get()); + assertEquals(1, reloadCount.get()); + assertEquals(1, loadAllCount.get()); + + QueuingExecutor executor = new QueuingExecutor(); + CacheLoader<Object, Object> asyncReloader = + CacheLoader.asyncReloading(baseLoader, executor); + + asyncReloader.load(new Object()); + asyncReloader.reload(new Object(), new Object()); + asyncReloader.loadAll(ImmutableList.of(new Object())); + assertEquals(2, loadCount.get()); + assertEquals(1, reloadCount.get()); + assertEquals(2, loadAllCount.get()); + + executor.runNext(); + assertEquals(2, loadCount.get()); + assertEquals(2, reloadCount.get()); + assertEquals(2, loadAllCount.get()); + } +} diff --git a/guava-tests/test/com/google/common/cache/CacheLoadingTest.java b/guava-tests/test/com/google/common/cache/CacheLoadingTest.java index 51cf06a..7d984d7 100644 --- a/guava-tests/test/com/google/common/cache/CacheLoadingTest.java +++ b/guava-tests/test/com/google/common/cache/CacheLoadingTest.java @@ -1,5 +1,5 @@ /* -g * Copyright (C) 2011 The Guava Authors + * Copyright (C) 2011 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -20,6 +20,7 @@ import static com.google.common.cache.TestingCacheLoaders.errorLoader; import static com.google.common.cache.TestingCacheLoaders.exceptionLoader; import static com.google.common.cache.TestingCacheLoaders.identityLoader; import static com.google.common.cache.TestingRemovalListeners.countingRemovalListener; +import static java.lang.Thread.currentThread; import static java.util.Arrays.asList; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.truth0.Truth.ASSERT; @@ -40,11 +41,12 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.UncheckedExecutionException; +import junit.framework.TestCase; + import java.io.IOException; import java.lang.ref.WeakReference; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CountDownLatch; @@ -54,8 +56,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.logging.LogRecord; -import junit.framework.TestCase; - /** * Tests relating to cache loading: concurrent loading, exceptions during loading, etc. * @@ -74,6 +74,8 @@ public class CacheLoadingTest extends TestCase { @Override public void tearDown() throws Exception { super.tearDown(); + // TODO(cpovirk): run tests in other thread instead of messing with main thread interrupt status + currentThread().interrupted(); LocalCache.logger.removeHandler(logHandler); } @@ -98,7 +100,8 @@ public class CacheLoadingTest extends TestCase { } public void testLoad() throws ExecutionException { - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats() + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() .build(identityLoader()); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -218,8 +221,11 @@ public class CacheLoadingTest extends TestCase { } }; - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().ticker(ticker) - .refreshAfterWrite(1, MILLISECONDS).build(loader); + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() + .ticker(ticker) + .refreshAfterWrite(1, MILLISECONDS) + .build(loader); Object key = new Object(); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -275,8 +281,11 @@ public class CacheLoadingTest extends TestCase { } }; - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().ticker(ticker) - .refreshAfterWrite(1, MILLISECONDS).build(loader); + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() + .ticker(ticker) + .refreshAfterWrite(1, MILLISECONDS) + .build(loader); Object key = new Object(); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -317,7 +326,8 @@ public class CacheLoadingTest extends TestCase { } public void testBulkLoad_default() throws ExecutionException { - LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder().recordStats() + LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder() + .recordStats() .build(TestingCacheLoaders.<Integer>identityLoader()); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -430,7 +440,7 @@ public class CacheLoadingTest extends TestCase { Object[] lookupKeys = new Object[] { new Object(), new Object(), new Object() }; Map<Object, Object> result = cache.getAll(asList(lookupKeys)); - ASSERT.<Object, Set<Object>>that(result.keySet()).has().allFrom(asList(lookupKeys)); + ASSERT.that(result.keySet()).has().exactlyAs(asList(lookupKeys)); for (Map.Entry<Object, Object> entry : result.entrySet()) { Object key = entry.getKey(); Object value = entry.getValue(); @@ -467,7 +477,7 @@ public class CacheLoadingTest extends TestCase { Object[] lookupKeys = new Object[] { new Object(), new Object(), new Object() }; Map<Object, Object> result = cache.getAll(asList(lookupKeys)); - ASSERT.<Object, Set<Object>>that(result.keySet()).has().allFrom(asList(lookupKeys)); + ASSERT.that(result.keySet()).has().exactlyAs(asList(lookupKeys)); for (Map.Entry<Object, Object> entry : result.entrySet()) { Object key = entry.getKey(); Object value = entry.getValue(); @@ -582,7 +592,8 @@ public class CacheLoadingTest extends TestCase { } public void testLoadNull() throws ExecutionException { - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats() + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() .build(constantLoader(null)); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -744,8 +755,11 @@ public class CacheLoadingTest extends TestCase { } }; - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().ticker(ticker) - .refreshAfterWrite(1, MILLISECONDS).build(loader); + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() + .ticker(ticker) + .refreshAfterWrite(1, MILLISECONDS) + .build(loader); Object key = new Object(); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -787,7 +801,8 @@ public class CacheLoadingTest extends TestCase { } public void testBulkLoadNull() throws ExecutionException { - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats() + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() .build(bulkLoader(constantLoader(null))); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -807,7 +822,8 @@ public class CacheLoadingTest extends TestCase { } public void testBulkLoadNullMap() throws ExecutionException { - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats() + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() .build(new CacheLoader<Object, Object>() { @Override public Object load(Object key) { @@ -1018,8 +1034,11 @@ public class CacheLoadingTest extends TestCase { } }; - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().ticker(ticker) - .refreshAfterWrite(1, MILLISECONDS).build(loader); + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() + .ticker(ticker) + .refreshAfterWrite(1, MILLISECONDS) + .build(loader); Object key = new Object(); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -1063,7 +1082,8 @@ public class CacheLoadingTest extends TestCase { public void testBulkLoadError() throws ExecutionException { Error e = new Error(); CacheLoader<Object, Object> loader = errorLoader(e); - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats() + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() .build(bulkLoader(loader)); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -1152,6 +1172,82 @@ public class CacheLoadingTest extends TestCase { assertEquals(0, stats.hitCount()); } + public void testLoadInterruptedException() { + Exception e = new InterruptedException(); + CacheLoader<Object, Object> loader = exceptionLoader(e); + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader); + CacheStats stats = cache.stats(); + assertEquals(0, stats.missCount()); + assertEquals(0, stats.loadSuccessCount()); + assertEquals(0, stats.loadExceptionCount()); + assertEquals(0, stats.hitCount()); + + // Sanity check: + assertFalse(currentThread().interrupted()); + + try { + cache.get(new Object()); + fail(); + } catch (ExecutionException expected) { + assertSame(e, expected.getCause()); + } + assertTrue(currentThread().interrupted()); + stats = cache.stats(); + assertEquals(1, stats.missCount()); + assertEquals(0, stats.loadSuccessCount()); + assertEquals(1, stats.loadExceptionCount()); + assertEquals(0, stats.hitCount()); + + try { + cache.getUnchecked(new Object()); + fail(); + } catch (UncheckedExecutionException expected) { + assertSame(e, expected.getCause()); + } + assertTrue(currentThread().interrupted()); + stats = cache.stats(); + assertEquals(2, stats.missCount()); + assertEquals(0, stats.loadSuccessCount()); + assertEquals(2, stats.loadExceptionCount()); + assertEquals(0, stats.hitCount()); + + cache.refresh(new Object()); + assertTrue(currentThread().interrupted()); + checkLoggedCause(e); + stats = cache.stats(); + assertEquals(2, stats.missCount()); + assertEquals(0, stats.loadSuccessCount()); + assertEquals(3, stats.loadExceptionCount()); + assertEquals(0, stats.hitCount()); + + Exception callableException = new InterruptedException(); + try { + cache.get(new Object(), throwing(callableException)); + fail(); + } catch (ExecutionException expected) { + assertSame(callableException, expected.getCause()); + } + assertTrue(currentThread().interrupted()); + stats = cache.stats(); + assertEquals(3, stats.missCount()); + assertEquals(0, stats.loadSuccessCount()); + assertEquals(4, stats.loadExceptionCount()); + assertEquals(0, stats.hitCount()); + + try { + cache.getAll(asList(new Object())); + fail(); + } catch (ExecutionException expected) { + assertSame(e, expected.getCause()); + } + assertTrue(currentThread().interrupted()); + stats = cache.stats(); + assertEquals(4, stats.missCount()); + assertEquals(0, stats.loadSuccessCount()); + assertEquals(5, stats.loadExceptionCount()); + assertEquals(0, stats.hitCount()); + } + public void testReloadCheckedException() { final Object one = new Object(); final Exception e = new Exception(); @@ -1260,8 +1356,11 @@ public class CacheLoadingTest extends TestCase { } }; - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().ticker(ticker) - .refreshAfterWrite(1, MILLISECONDS).build(loader); + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() + .ticker(ticker) + .refreshAfterWrite(1, MILLISECONDS) + .build(loader); Object key = new Object(); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -1305,7 +1404,33 @@ public class CacheLoadingTest extends TestCase { public void testBulkLoadCheckedException() { Exception e = new Exception(); CacheLoader<Object, Object> loader = exceptionLoader(e); - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats() + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() + .build(bulkLoader(loader)); + CacheStats stats = cache.stats(); + assertEquals(0, stats.missCount()); + assertEquals(0, stats.loadSuccessCount()); + assertEquals(0, stats.loadExceptionCount()); + assertEquals(0, stats.hitCount()); + + try { + cache.getAll(asList(new Object())); + fail(); + } catch (ExecutionException expected) { + assertSame(e, expected.getCause()); + } + stats = cache.stats(); + assertEquals(1, stats.missCount()); + assertEquals(0, stats.loadSuccessCount()); + assertEquals(1, stats.loadExceptionCount()); + assertEquals(0, stats.hitCount()); + } + + public void testBulkLoadInterruptedException() { + Exception e = new InterruptedException(); + CacheLoader<Object, Object> loader = exceptionLoader(e); + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() .build(bulkLoader(loader)); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -1319,6 +1444,7 @@ public class CacheLoadingTest extends TestCase { } catch (ExecutionException expected) { assertSame(e, expected.getCause()); } + assertTrue(currentThread().interrupted()); stats = cache.stats(); assertEquals(1, stats.missCount()); assertEquals(0, stats.loadSuccessCount()); @@ -1502,8 +1628,11 @@ public class CacheLoadingTest extends TestCase { } }; - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().ticker(ticker) - .refreshAfterWrite(1, MILLISECONDS).build(loader); + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() + .ticker(ticker) + .refreshAfterWrite(1, MILLISECONDS) + .build(loader); Object key = new Object(); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -1547,7 +1676,8 @@ public class CacheLoadingTest extends TestCase { public void testBulkLoadUncheckedException() throws ExecutionException { Exception e = new RuntimeException(); CacheLoader<Object, Object> loader = exceptionLoader(e); - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats() + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .recordStats() .build(bulkLoader(loader)); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); @@ -1583,7 +1713,8 @@ public class CacheLoadingTest extends TestCase { }; CountingRemovalListener<Integer, String> removalListener = countingRemovalListener(); LoadingCache<Integer, String> cache = CacheBuilder.newBuilder() - .removalListener(removalListener).build(failOnceFunction); + .removalListener(removalListener) + .build(failOnceFunction); try { cache.getUnchecked(1); @@ -1606,8 +1737,8 @@ public class CacheLoadingTest extends TestCase { public void testReloadAfterValueReclamation() throws InterruptedException, ExecutionException { CountingLoader countingLoader = new CountingLoader(); - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().weakValues() - .build(countingLoader); + LoadingCache<Object, Object> cache = + CacheBuilder.newBuilder().weakValues().build(countingLoader); ConcurrentMap<Object, Object> map = cache.asMap(); int iterations = 10; @@ -1644,7 +1775,9 @@ public class CacheLoadingTest extends TestCase { public void testReloadAfterSimulatedValueReclamation() throws ExecutionException { CountingLoader countingLoader = new CountingLoader(); - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().concurrencyLevel(1).weakValues() + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .concurrencyLevel(1) + .weakValues() .build(countingLoader); Object key = new Object(); @@ -1666,7 +1799,9 @@ public class CacheLoadingTest extends TestCase { public void testReloadAfterSimulatedKeyReclamation() throws ExecutionException { CountingLoader countingLoader = new CountingLoader(); - LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().concurrencyLevel(1).weakKeys() + LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() + .concurrencyLevel(1) + .weakKeys() .build(countingLoader); Object key = new Object(); @@ -1693,10 +1828,10 @@ public class CacheLoadingTest extends TestCase { final UncheckedExecutionException uee = new UncheckedExecutionException(cause); final ExecutionException ee = new ExecutionException(cause); - LoadingCache<Object, Object> cacheUnchecked = CacheBuilder.newBuilder().build( - exceptionLoader(uee)); - LoadingCache<Object, Object> cacheChecked = CacheBuilder.newBuilder() - .build(exceptionLoader(ee)); + LoadingCache<Object, Object> cacheUnchecked = + CacheBuilder.newBuilder().build(exceptionLoader(uee)); + LoadingCache<Object, Object> cacheChecked = + CacheBuilder.newBuilder().build(exceptionLoader(ee)); try { cacheUnchecked.get(new Object()); @@ -1756,10 +1891,10 @@ public class CacheLoadingTest extends TestCase { final UncheckedExecutionException uee = new UncheckedExecutionException(cause); final ExecutionException ee = new ExecutionException(cause); - LoadingCache<Object, Object> cacheUnchecked = CacheBuilder.newBuilder().build( - bulkLoader(exceptionLoader(uee))); - LoadingCache<Object, Object> cacheChecked = CacheBuilder.newBuilder().build( - bulkLoader(exceptionLoader(ee))); + LoadingCache<Object, Object> cacheUnchecked = + CacheBuilder.newBuilder().build(bulkLoader(exceptionLoader(uee))); + LoadingCache<Object, Object> cacheChecked = + CacheBuilder.newBuilder().build(bulkLoader(exceptionLoader(ee))); try { cacheUnchecked.getAll(asList(new Object())); @@ -1806,14 +1941,14 @@ public class CacheLoadingTest extends TestCase { final CountDownLatch startSignal = new CountDownLatch(count + 1); final Object result = new Object(); - LoadingCache<String, Object> cache = builder.build(new CacheLoader<String, Object>() { - @Override - public Object load(String key) throws InterruptedException { - callCount.incrementAndGet(); - startSignal.await(); - return result; - } - }); + LoadingCache<String, Object> cache = builder.build( + new CacheLoader<String, Object>() { + @Override public Object load(String key) throws InterruptedException { + callCount.incrementAndGet(); + startSignal.await(); + return result; + } + }); List<Object> resultArray = doConcurrentGet(cache, "bar", count, startSignal); @@ -1835,14 +1970,14 @@ public class CacheLoadingTest extends TestCase { final AtomicInteger callCount = new AtomicInteger(); final CountDownLatch startSignal = new CountDownLatch(count + 1); - LoadingCache<String, String> cache = builder.build(new CacheLoader<String, String>() { - @Override - public String load(String key) throws InterruptedException { - callCount.incrementAndGet(); - startSignal.await(); - return null; - } - }); + LoadingCache<String, String> cache = builder.build( + new CacheLoader<String, String>() { + @Override public String load(String key) throws InterruptedException { + callCount.incrementAndGet(); + startSignal.await(); + return null; + } + }); List<Object> result = doConcurrentGet(cache, "bar", count, startSignal); @@ -1855,7 +1990,8 @@ public class CacheLoadingTest extends TestCase { try { cache.getUnchecked("bar"); fail(); - } catch (InvalidCacheLoadException expected) {} + } catch (InvalidCacheLoadException expected) { + } assertEquals(2, callCount.get()); } @@ -1864,22 +2000,22 @@ public class CacheLoadingTest extends TestCase { * (wrapped) exception, with the loader called only once. The result should not be cached (a later * request should call the loader again). */ - private static void testConcurrentLoadingUncheckedException(CacheBuilder<Object, Object> builder) - throws InterruptedException { + private static void testConcurrentLoadingUncheckedException( + CacheBuilder<Object, Object> builder) throws InterruptedException { int count = 10; final AtomicInteger callCount = new AtomicInteger(); final CountDownLatch startSignal = new CountDownLatch(count + 1); final RuntimeException e = new RuntimeException(); - LoadingCache<String, String> cache = builder.build(new CacheLoader<String, String>() { - @Override - public String load(String key) throws InterruptedException { - callCount.incrementAndGet(); - startSignal.await(); - throw e; - } - }); + LoadingCache<String, String> cache = builder.build( + new CacheLoader<String, String>() { + @Override public String load(String key) throws InterruptedException { + callCount.incrementAndGet(); + startSignal.await(); + throw e; + } + }); List<Object> result = doConcurrentGet(cache, "bar", count, startSignal); @@ -1895,7 +2031,8 @@ public class CacheLoadingTest extends TestCase { try { cache.getUnchecked("bar"); fail(); - } catch (UncheckedExecutionException expected) {} + } catch (UncheckedExecutionException expected) { + } assertEquals(2, callCount.get()); } @@ -1904,22 +2041,22 @@ public class CacheLoadingTest extends TestCase { * (wrapped) exception, with the loader called only once. The result should not be cached (a later * request should call the loader again). */ - private static void testConcurrentLoadingCheckedException(CacheBuilder<Object, Object> builder) - throws InterruptedException { + private static void testConcurrentLoadingCheckedException( + CacheBuilder<Object, Object> builder) throws InterruptedException { int count = 10; final AtomicInteger callCount = new AtomicInteger(); final CountDownLatch startSignal = new CountDownLatch(count + 1); final IOException e = new IOException(); - LoadingCache<String, String> cache = builder.build(new CacheLoader<String, String>() { - @Override - public String load(String key) throws IOException, InterruptedException { - callCount.incrementAndGet(); - startSignal.await(); - throw e; - } - }); + LoadingCache<String, String> cache = builder.build( + new CacheLoader<String, String>() { + @Override public String load(String key) throws IOException, InterruptedException { + callCount.incrementAndGet(); + startSignal.await(); + throw e; + } + }); List<Object> result = doConcurrentGet(cache, "bar", count, startSignal); @@ -1942,7 +2079,8 @@ public class CacheLoadingTest extends TestCase { try { cache.getUnchecked("bar"); fail(); - } catch (UncheckedExecutionException expected) {} + } catch (UncheckedExecutionException expected) { + } assertEquals(2, callCount.get()); } @@ -1964,8 +2102,7 @@ public class CacheLoadingTest extends TestCase { for (int i = 0; i < nThreads; i++) { final int index = i; Thread thread = new Thread(new Runnable() { - @Override - public void run() { + @Override public void run() { gettersStartedSignal.countDown(); Object value = null; try { @@ -2019,8 +2156,9 @@ public class CacheLoadingTest extends TestCase { } }; - final LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(computeFunction); - ConcurrentMap<String, String> map = cache.asMap(); + final LoadingCache<String, String> cache = CacheBuilder.newBuilder() + .build(computeFunction); + ConcurrentMap<String,String> map = cache.asMap(); map.put(refreshKey, refreshKey); assertEquals(1, map.size()); assertFalse(map.containsKey(getKey)); @@ -2077,8 +2215,9 @@ public class CacheLoadingTest extends TestCase { } }; - final LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(computeFunction); - ConcurrentMap<String, String> map = cache.asMap(); + final LoadingCache<String, String> cache = CacheBuilder.newBuilder() + .build(computeFunction); + ConcurrentMap<String,String> map = cache.asMap(); map.put(refreshKey, refreshKey); new Thread() { @@ -2114,8 +2253,8 @@ public class CacheLoadingTest extends TestCase { assertEquals(2, cache.size()); } - public void testInvalidateAndReloadDuringLoading() throws InterruptedException, - ExecutionException { + public void testInvalidateAndReloadDuringLoading() + throws InterruptedException, ExecutionException { // computation starts; clear() is called, computation finishes final CountDownLatch computationStarted = new CountDownLatch(2); final CountDownLatch letGetFinishSignal = new CountDownLatch(1); @@ -2133,8 +2272,9 @@ public class CacheLoadingTest extends TestCase { } }; - final LoadingCache<String, String> cache = CacheBuilder.newBuilder().build(computeFunction); - ConcurrentMap<String, String> map = cache.asMap(); + final LoadingCache<String, String> cache = CacheBuilder.newBuilder() + .build(computeFunction); + ConcurrentMap<String,String> map = cache.asMap(); map.put(refreshKey, refreshKey); new Thread() { @@ -2209,7 +2349,8 @@ public class CacheLoadingTest extends TestCase { } }; - final LoadingCache<String, String> cache = CacheBuilder.newBuilder().weakKeys() + final LoadingCache<String, String> cache = CacheBuilder.newBuilder() + .weakKeys() .build(computeFunction); final AtomicReferenceArray<String> result = new AtomicReferenceArray<String>(count); @@ -2272,10 +2413,96 @@ public class CacheLoadingTest extends TestCase { assertEquals("barfoo", cache.getUnchecked(key)); } + public void testExpandDuringRefresh() throws InterruptedException, ExecutionException { + final AtomicInteger callCount = new AtomicInteger(); + // tells the computing thread when to start computing + final CountDownLatch computeSignal = new CountDownLatch(1); + // tells the main thread when computation is pending + final CountDownLatch secondSignal = new CountDownLatch(1); + // tells the main thread when the second get has started + final CountDownLatch thirdSignal = new CountDownLatch(1); + // tells the main thread when the third get has started + final CountDownLatch fourthSignal = new CountDownLatch(1); + // tells the test when all gets have returned + final CountDownLatch doneSignal = new CountDownLatch(3); + final String suffix = "Suffix"; + + CacheLoader<String, String> computeFunction = new CacheLoader<String, String>() { + @Override + public String load(String key) throws InterruptedException { + callCount.incrementAndGet(); + secondSignal.countDown(); + computeSignal.await(); + return key + suffix; + } + }; + + final AtomicReferenceArray<String> result = new AtomicReferenceArray<String>(2); + + final LoadingCache<String, String> cache = CacheBuilder.newBuilder() + .build(computeFunction); + final String key = "bar"; + cache.asMap().put(key, key); + + // start computing thread + new Thread() { + @Override + public void run() { + cache.refresh(key); + doneSignal.countDown(); + } + }.start(); + + // wait for computation to start + secondSignal.await(); + checkNothingLogged(); + + // start waiting thread + new Thread() { + @Override + public void run() { + thirdSignal.countDown(); + result.set(0, cache.getUnchecked(key)); + doneSignal.countDown(); + } + }.start(); + + // give the second get a chance to run; it is okay for this to be racy + // as the end result should be the same either way + thirdSignal.await(); + Thread.yield(); + + // Expand! + CacheTesting.forceExpandSegment(cache, key); + + // start another waiting thread + new Thread() { + @Override + public void run() { + fourthSignal.countDown(); + result.set(1, cache.getUnchecked(key)); + doneSignal.countDown(); + } + }.start(); + + // give the third get a chance to run; it is okay for this to be racy + // as the end result should be the same either way + fourthSignal.await(); + Thread.yield(); + + // let computation finish + computeSignal.countDown(); + doneSignal.await(); + + assertTrue(callCount.get() == 1); + assertEquals(key, result.get(0)); + assertEquals(key, result.get(1)); + assertEquals(key + suffix, cache.getUnchecked(key)); + } + static <T> Callable<T> throwing(final Exception exception) { return new Callable<T>() { - @Override - public T call() throws Exception { + @Override public T call() throws Exception { throw exception; } }; diff --git a/guava-tests/test/com/google/common/cache/CacheReferencesTest.java b/guava-tests/test/com/google/common/cache/CacheReferencesTest.java index 74bb69a..8c7850c 100644 --- a/guava-tests/test/com/google/common/cache/CacheReferencesTest.java +++ b/guava-tests/test/com/google/common/cache/CacheReferencesTest.java @@ -15,7 +15,6 @@ package com.google.common.cache; import static com.google.common.cache.LocalCache.Strength.STRONG; -import static com.google.common.cache.TestingRemovalListeners.countingRemovalListener; import static com.google.common.collect.Maps.immutableEntry; import static org.truth0.Truth.ASSERT; @@ -25,11 +24,10 @@ import com.google.common.cache.TestingRemovalListeners.CountingRemovalListener; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import java.lang.ref.WeakReference; -import java.util.Collection; - import junit.framework.TestCase; +import java.lang.ref.WeakReference; + /** * Tests of basic {@link LoadingCache} operations with all possible combinations of key & value * strengths. @@ -96,7 +94,7 @@ public class CacheReferencesTest extends TestCase { assertSame(value1, cache.getUnchecked(key1)); assertSame(value2, cache.getUnchecked(key2)); assertEquals(ImmutableSet.of(key1, key2), cache.asMap().keySet()); - ASSERT.<String, Collection<String>>that(cache.asMap().values()).has().allOf(value1, value2); + ASSERT.that(cache.asMap().values()).has().exactly(value1, value2); assertEquals(ImmutableSet.of(immutableEntry(key1, value1), immutableEntry(key2, value2)), cache.asMap().entrySet()); } @@ -115,40 +113,12 @@ public class CacheReferencesTest extends TestCase { assertTrue(cache.asMap().containsKey(key2)); assertEquals(1, cache.size()); assertEquals(ImmutableSet.of(key2), cache.asMap().keySet()); - ASSERT.<String, Collection<String>>that(cache.asMap().values()).has().item(value2); + ASSERT.that(cache.asMap().values()).has().item(value2); assertEquals(ImmutableSet.of(immutableEntry(key2, value2)), cache.asMap().entrySet()); } } - public void notestCleanupOnReferenceCollection() { - for (CacheBuilder<Object, Object> builder - : factoryWithAllKeyStrengths().buildAllPermutations()) { - if (builder.keyStrength == STRONG && builder.valueStrength == STRONG) { - continue; - } - CountingRemovalListener<Integer, String> removalListener = countingRemovalListener(); - CacheLoader<Integer, String> toStringLoader = - new CacheLoader<Integer, String>() { - @Override public String load(Integer key) { - return key.toString(); - } - }; - LoadingCache<Integer, String> cache = - builder.removalListener(removalListener).build(toStringLoader); - - // ints in [-128, 127] have their wrappers precomputed and cached, so they won't be GCed - Integer key1 = 1001; - Integer key2 = 1002; - String value1 = cache.getUnchecked(key1); - String value2 = cache.getUnchecked(key2); - // make (key1, value1) eligible for collection - key1 = null; - value1 = null; - assertCleanup(cache, removalListener); - // make sure the GC isn't going to see key2 or value2 as dead in assertCleanup - assertSame(value2, cache.getUnchecked(key2)); - } - } + // fails in Maven with 64-bit JDK: http://code.google.com/p/guava-libraries/issues/detail?id=1568 private void assertCleanup(LoadingCache<Integer, String> cache, CountingRemovalListener<Integer, String> removalListener) { diff --git a/guava-tests/test/com/google/common/cache/CacheTesting.java b/guava-tests/test/com/google/common/cache/CacheTesting.java index 62a7270..660fecd 100644 --- a/guava-tests/test/com/google/common/cache/CacheTesting.java +++ b/guava-tests/test/com/google/common/cache/CacheTesting.java @@ -134,7 +134,7 @@ class CacheTesting { static void drainRecencyQueues(Cache<?, ?> cache) { if (hasLocalCache(cache)) { LocalCache<?, ?> map = toLocalCache(cache); - for (Segment segment : map.segments) { + for (Segment<?, ?> segment : map.segments) { drainRecencyQueue(segment); } } @@ -156,7 +156,7 @@ class CacheTesting { } static void drainReferenceQueues(LocalCache<?, ?> cchm) { - for (LocalCache.Segment segment : cchm.segments) { + for (LocalCache.Segment<?, ?> segment : cchm.segments) { drainReferenceQueue(segment); } } @@ -200,7 +200,7 @@ class CacheTesting { segment.cleanUp(); // under high memory pressure keys/values may be nulled out but not yet enqueued assertTrue(table.size() <= segment.count); - for (Entry entry : table.entrySet()) { + for (Entry<?, ?> entry : table.entrySet()) { assertNotNull(entry.getKey()); assertNotNull(entry.getValue()); assertSame(entry.getValue(), cchm.get(entry.getKey())); @@ -303,7 +303,7 @@ class CacheTesting { } } } else { - for (Segment segment : map.segments) { + for (Segment<?, ?> segment : map.segments) { assertEquals(0, segment.recencyQueue.size()); } } @@ -467,7 +467,7 @@ class CacheTesting { checkValidState(cchm); assertTrue(cchm.isEmpty()); assertEquals(0, cchm.size()); - for (LocalCache.Segment segment : cchm.segments) { + for (LocalCache.Segment<?, ?> segment : cchm.segments) { assertEquals(0, segment.count); assertEquals(0, segmentSize(segment)); assertTrue(segment.writeQueue.isEmpty()); diff --git a/guava-tests/test/com/google/common/cache/ForwardingCacheTest.java b/guava-tests/test/com/google/common/cache/ForwardingCacheTest.java index 0fce47c..3d76288 100644 --- a/guava-tests/test/com/google/common/cache/ForwardingCacheTest.java +++ b/guava-tests/test/com/google/common/cache/ForwardingCacheTest.java @@ -24,10 +24,10 @@ import static org.easymock.EasyMock.verify; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import java.util.concurrent.ExecutionException; - import junit.framework.TestCase; +import java.util.concurrent.ExecutionException; + /** * Unit test for {@link ForwardingCache}. * diff --git a/guava-tests/test/com/google/common/cache/ForwardingLoadingCacheTest.java b/guava-tests/test/com/google/common/cache/ForwardingLoadingCacheTest.java index 1d6e9a7..25a154b 100644 --- a/guava-tests/test/com/google/common/cache/ForwardingLoadingCacheTest.java +++ b/guava-tests/test/com/google/common/cache/ForwardingLoadingCacheTest.java @@ -24,10 +24,10 @@ import static org.easymock.EasyMock.verify; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import java.util.concurrent.ExecutionException; - import junit.framework.TestCase; +import java.util.concurrent.ExecutionException; + /** * Unit test for {@link ForwardingLoadingCache}. * diff --git a/guava-tests/test/com/google/common/cache/LocalCacheTest.java b/guava-tests/test/com/google/common/cache/LocalCacheTest.java index b82c67b..9801f12 100644 --- a/guava-tests/test/com/google/common/cache/LocalCacheTest.java +++ b/guava-tests/test/com/google/common/cache/LocalCacheTest.java @@ -45,14 +45,22 @@ import com.google.common.cache.TestingRemovalListeners.CountingRemovalListener; import com.google.common.cache.TestingRemovalListeners.QueuingRemovalListener; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.testing.MapTestSuiteBuilder; +import com.google.common.collect.testing.TestStringMapGenerator; +import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.features.MapFeature; import com.google.common.testing.FakeTicker; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; import com.google.common.testing.TestLogHandler; +import junit.framework.Test; import junit.framework.TestCase; +import junit.framework.TestSuite; import java.io.Serializable; import java.lang.ref.Reference; @@ -61,7 +69,9 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Random; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -73,6 +83,26 @@ import java.util.logging.LogRecord; */ public class LocalCacheTest extends TestCase { + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTestSuite(LocalCacheTest.class); + suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() { + @Override public Map<String, String> create( + Entry<String, String>[] entries) { + LocalCache<String, String> map = makeLocalCache(createCacheBuilder()); + for (Entry<String, String> entry : entries) { + map.put(entry.getKey(), entry.getValue()); + } + return map; + } + + }).named("LocalCache with defaults") + .withFeatures(CollectionSize.ANY, MapFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE) + .createTestSuite()); + return suite; + } + static final int SMALL_MAX_SIZE = DRAIN_THRESHOLD * 5; TestLogHandler logHandler; @@ -106,7 +136,8 @@ public class LocalCacheTest extends TestCase { assertSame(t, popLoggedThrowable()); } - private static <K, V> LocalCache<K, V> makeLocalCache(CacheBuilder<K, V> builder) { + private static <K, V> LocalCache<K, V> makeLocalCache( + CacheBuilder<? super K, ? super V> builder) { return new LocalCache<K, V>(builder, null); } @@ -544,6 +575,16 @@ public class LocalCacheTest extends TestCase { assertEquals(2, loader.getCount()); } + public void testValues() { + LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()); + map.put("foo", "bar"); + map.put("baz", "bar"); + map.put("quux", "quux"); + assertFalse(map.values() instanceof Set); + assertTrue(map.values().removeAll(ImmutableSet.of("bar"))); + assertEquals(1, map.size()); + } + public void testCopyEntry_computing() { final CountDownLatch startSignal = new CountDownLatch(1); final CountDownLatch computingSignal = new CountDownLatch(1); @@ -2040,8 +2081,8 @@ public class LocalCacheTest extends TestCase { int size = expectedEntries.size(); assertEquals(size, actualEntries.size()); for (int i = 0; i < size; i++) { - ReferenceEntry<K, V> expectedEntry = expectedEntries.get(0); - ReferenceEntry<K, V> actualEntry = actualEntries.get(0); + ReferenceEntry<K, V> expectedEntry = expectedEntries.get(i); + ReferenceEntry<K, V> actualEntry = actualEntries.get(i); assertSame(expectedEntry.getKey(), actualEntry.getKey()); assertSame(expectedEntry.getValueReference().get(), actualEntry.getValueReference().get()); } diff --git a/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java b/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java index 8f1d8c7..f4684fc 100644 --- a/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java +++ b/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java @@ -42,8 +42,8 @@ import java.util.concurrent.atomic.AtomicReference; */ public class LocalLoadingCacheTest extends TestCase { - private static <K, V> LocalLoadingCache<K, V> makeCache(CacheBuilder<K, V> builder, - CacheLoader<? super K, V> loader) { + private static <K, V> LocalLoadingCache<K, V> makeCache( + CacheBuilder<K, V> builder, CacheLoader<? super K, V> loader) { return new LocalLoadingCache<K, V>(builder, loader); } @@ -74,8 +74,10 @@ public class LocalLoadingCacheTest extends TestCase { // stats tests - public void __flaky_testStats() { - CacheBuilder<Object, Object> builder = createCacheBuilder().concurrencyLevel(1).maximumSize(2); + public void testStats() { + CacheBuilder<Object, Object> builder = createCacheBuilder() + .concurrencyLevel(1) + .maximumSize(2); LocalLoadingCache<Object, Object> cache = makeCache(builder, identityLoader()); assertEquals(EMPTY_STATS, cache.stats()); @@ -89,17 +91,17 @@ public class LocalLoadingCacheTest extends TestCase { assertEquals(1.0, stats.missRate()); assertEquals(1, stats.loadCount()); long totalLoadTime = stats.totalLoadTime(); - assertTrue(totalLoadTime > 0); - assertTrue(stats.averageLoadPenalty() > 0.0); + assertTrue(totalLoadTime >= 0); + assertTrue(stats.averageLoadPenalty() >= 0.0); assertEquals(0, stats.evictionCount()); cache.getUnchecked(one); stats = cache.stats(); assertEquals(2, stats.requestCount()); assertEquals(1, stats.hitCount()); - assertEquals(1.0 / 2, stats.hitRate()); + assertEquals(1.0/2, stats.hitRate()); assertEquals(1, stats.missCount()); - assertEquals(1.0 / 2, stats.missRate()); + assertEquals(1.0/2, stats.missRate()); assertEquals(1, stats.loadCount()); assertEquals(0, stats.evictionCount()); @@ -108,13 +110,13 @@ public class LocalLoadingCacheTest extends TestCase { stats = cache.stats(); assertEquals(3, stats.requestCount()); assertEquals(1, stats.hitCount()); - assertEquals(1.0 / 3, stats.hitRate()); + assertEquals(1.0/3, stats.hitRate()); assertEquals(2, stats.missCount()); - assertEquals(2.0 / 3, stats.missRate()); + assertEquals(2.0/3, stats.missRate()); assertEquals(2, stats.loadCount()); - assertTrue(stats.totalLoadTime() > totalLoadTime); + assertTrue(stats.totalLoadTime() >= totalLoadTime); totalLoadTime = stats.totalLoadTime(); - assertTrue(stats.averageLoadPenalty() > 0.0); + assertTrue(stats.averageLoadPenalty() >= 0.0); assertEquals(0, stats.evictionCount()); Object three = new Object(); @@ -122,18 +124,19 @@ public class LocalLoadingCacheTest extends TestCase { stats = cache.stats(); assertEquals(4, stats.requestCount()); assertEquals(1, stats.hitCount()); - assertEquals(1.0 / 4, stats.hitRate()); + assertEquals(1.0/4, stats.hitRate()); assertEquals(3, stats.missCount()); - assertEquals(3.0 / 4, stats.missRate()); + assertEquals(3.0/4, stats.missRate()); assertEquals(3, stats.loadCount()); - assertTrue(stats.totalLoadTime() > totalLoadTime); + assertTrue(stats.totalLoadTime() >= totalLoadTime); totalLoadTime = stats.totalLoadTime(); - assertTrue(stats.averageLoadPenalty() > 0.0); + assertTrue(stats.averageLoadPenalty() >= 0.0); assertEquals(1, stats.evictionCount()); } public void testStatsNoops() { - CacheBuilder<Object, Object> builder = createCacheBuilder().concurrencyLevel(1); + CacheBuilder<Object, Object> builder = createCacheBuilder() + .concurrencyLevel(1); LocalLoadingCache<Object, Object> cache = makeCache(builder, identityLoader()); ConcurrentMap<Object, Object> map = cache.localCache; // modifiable map view assertEquals(EMPTY_STATS, cache.stats()); @@ -157,17 +160,17 @@ public class LocalLoadingCacheTest extends TestCase { assertNull(map.put(three, one)); assertNull(map.put(one, two)); - ASSERT.<Object, Object, Map<Object, Object>>that(map).hasKey(three).withValue(one); - ASSERT.<Object, Object, Map<Object, Object>>that(map).hasKey(one).withValue(two); + ASSERT.that(map).hasKey(three).withValue(one); + ASSERT.that(map).hasKey(one).withValue(two); //TODO(user): Confirm with fry@ that this is a reasonable substitute. //Set<Map.Entry<Object, Object>> entries = map.entrySet(); - //FluentAsserts.assertThat(entries).has().allOf( + //ASSERT.that(entries).has().exactly( // Maps.immutableEntry(three, one), Maps.immutableEntry(one, two)); //Set<Object> keys = map.keySet(); - //FluentAsserts.assertThat(keys).has().allOf(one, three); + //ASSERT.that(keys).has().exactly(one, three); //Collection<Object> values = map.values(); - //FluentAsserts.assertThat(values).has().allOf(one, two); + //ASSERT.that(values).has().exactly(one, two); map.clear(); @@ -175,7 +178,8 @@ public class LocalLoadingCacheTest extends TestCase { } public void testNoStats() { - CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder().concurrencyLevel(1) + CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder() + .concurrencyLevel(1) .maximumSize(2); LocalLoadingCache<Object, Object> cache = makeCache(builder, identityLoader()); assertEquals(EMPTY_STATS, cache.stats()); @@ -197,7 +201,9 @@ public class LocalLoadingCacheTest extends TestCase { } public void testRecordStats() { - CacheBuilder<Object, Object> builder = createCacheBuilder().recordStats().concurrencyLevel(1) + CacheBuilder<Object, Object> builder = createCacheBuilder() + .recordStats() + .concurrencyLevel(1) .maximumSize(2); LocalLoadingCache<Object, Object> cache = makeCache(builder, identityLoader()); assertEquals(0, cache.stats().hitCount()); @@ -283,8 +289,9 @@ public class LocalLoadingCacheTest extends TestCase { * Lookups on the map view shouldn't impact the recency queue. */ public void testAsMapRecency() { - CacheBuilder<Object, Object> builder = createCacheBuilder().concurrencyLevel(1).maximumSize( - SMALL_MAX_SIZE); + CacheBuilder<Object, Object> builder = createCacheBuilder() + .concurrencyLevel(1) + .maximumSize(SMALL_MAX_SIZE); LocalLoadingCache<Object, Object> cache = makeCache(builder, identityLoader()); Segment<Object, Object> segment = cache.localCache.segments[0]; ConcurrentMap<Object, Object> map = cache.asMap(); @@ -299,7 +306,8 @@ public class LocalLoadingCacheTest extends TestCase { } public void testRecursiveComputation() throws InterruptedException { - final AtomicReference<LoadingCache<Integer, String>> cacheRef = new AtomicReference<LoadingCache<Integer, String>>(); + final AtomicReference<LoadingCache<Integer, String>> cacheRef = + new AtomicReference<LoadingCache<Integer, String>>(); CacheLoader<Integer, String> recursiveLoader = new CacheLoader<Integer, String>() { @Override public String load(Integer key) { @@ -311,8 +319,10 @@ public class LocalLoadingCacheTest extends TestCase { } }; - LoadingCache<Integer, String> recursiveCache = new CacheBuilder<Integer, String>().weakKeys() - .weakValues().build(recursiveLoader); + LoadingCache<Integer, String> recursiveCache = new CacheBuilder<Integer, String>() + .weakKeys() + .weakValues() + .build(recursiveLoader); cacheRef.set(recursiveCache); assertEquals("3, 2, 1, 0", recursiveCache.getUnchecked(3)); @@ -323,7 +333,9 @@ public class LocalLoadingCacheTest extends TestCase { } }; - recursiveCache = new CacheBuilder<Integer, String>().weakKeys().weakValues() + recursiveCache = new CacheBuilder<Integer, String>() + .weakKeys() + .weakValues() .build(recursiveLoader); cacheRef.set(recursiveCache); diff --git a/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java b/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java index ee9ab81..6d50030 100644 --- a/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java +++ b/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java @@ -18,6 +18,7 @@ import static com.google.common.cache.CacheTesting.checkEmpty; import static com.google.common.cache.CacheTesting.checkValidState; import static com.google.common.cache.TestingCacheLoaders.identityLoader; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.truth0.Truth.ASSERT; import com.google.common.base.Function; import com.google.common.cache.CacheBuilderFactory.DurationSpec; @@ -29,7 +30,8 @@ import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.testing.EqualsTester; -import com.google.common.testing.FluentAsserts; + +import junit.framework.TestCase; import junit.framework.TestCase; @@ -194,9 +196,9 @@ public class PopulatedCachesTest extends TestCase { List<Entry<Object, Object>> warmed = warmUp(cache); Set<Object> expected = Maps.newHashMap(cache.asMap()).keySet(); - FluentAsserts.assertThat(keys).has().allFrom(expected); - FluentAsserts.assertThat(keys.toArray()).has().allFrom(expected); - FluentAsserts.assertThat(keys.toArray(new Object[0])).has().allFrom(expected); + ASSERT.that(keys).has().exactlyAs(expected); + ASSERT.that(keys.toArray()).has().exactlyAs(expected); + ASSERT.that(keys.toArray(new Object[0])).has().exactlyAs(expected); new EqualsTester() .addEqualityGroup(cache.asMap().keySet(), keys) @@ -221,9 +223,9 @@ public class PopulatedCachesTest extends TestCase { List<Entry<Object, Object>> warmed = warmUp(cache); Collection<Object> expected = Maps.newHashMap(cache.asMap()).values(); - FluentAsserts.assertThat(values).has().allFrom(expected); - FluentAsserts.assertThat(values.toArray()).has().allFrom(expected); - FluentAsserts.assertThat(values.toArray(new Object[0])).has().allFrom(expected); + ASSERT.that(values).has().exactlyAs(expected); + ASSERT.that(values.toArray()).has().exactlyAs(expected); + ASSERT.that(values.toArray(new Object[0])).has().exactlyAs(expected); assertEquals(WARMUP_SIZE, values.size()); for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) { @@ -246,9 +248,9 @@ public class PopulatedCachesTest extends TestCase { List<Entry<Object, Object>> warmed = warmUp(cache, WARMUP_MIN, WARMUP_MAX); Set<?> expected = Maps.newHashMap(cache.asMap()).entrySet(); - FluentAsserts.assertThat(entries).has().allFrom((Collection<Entry<Object, Object>>)expected); - FluentAsserts.assertThat(entries.toArray()).has().allFrom((Collection<Object>)expected); - FluentAsserts.assertThat(entries.toArray(new Entry[0])).has().allFrom((Collection<Entry>)expected); + ASSERT.that(entries).has().exactlyAs((Collection<Entry<Object, Object>>) expected); + ASSERT.that(entries.toArray()).has().exactlyAs((Collection<Object>) expected); + ASSERT.that(entries.toArray(new Entry[0])).has().exactlyAs((Collection<Entry>) expected); new EqualsTester() .addEqualityGroup(cache.asMap().entrySet(), entries) diff --git a/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java b/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java index f1ccf92..5616ecc 100644 --- a/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java +++ b/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java @@ -14,12 +14,12 @@ package com.google.common.collect; +import junit.framework.TestCase; + import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Map.Entry; -import junit.framework.TestCase; - /** * Tests for {@code AbstractBiMap}. * diff --git a/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java b/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java deleted file mode 100644 index 4312b44..0000000 --- a/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static java.util.Arrays.asList; -import static org.truth0.Truth.ASSERT; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.testing.NullPointerTester; - -import java.util.Collection; -import java.util.Collections; - -import junit.framework.TestCase; - -/** - * Common tests for a {@code Collection}. - * - * @author Kevin Bourrillion - * @author Mike Bostock - */ -@GwtCompatible(emulated = true) -public abstract class AbstractCollectionTest extends TestCase { - - protected abstract <E> Collection<E> create(); - - protected Collection<String> c; - - // public for GWT - @Override public void setUp() throws Exception { - super.setUp(); - c = create(); - } - - public void testIsEmptyYes() { - assertTrue(c.isEmpty()); - } - - public void testIsEmptyNo() { - c.add("a"); - assertFalse(c.isEmpty()); - } - - public void testAddOne() { - assertTrue(c.add("a")); - assertContents("a"); - } - - public void testAddSeveralTimes() { - assertTrue(c.add("a")); - assertTrue(c.add("b")); - c.add("a"); - c.add("b"); - assertTrue(c.contains("a")); - assertTrue(c.contains("b")); - } - - public void testRemoveOneFromNoneStandard() { - assertFalse(c.remove("a")); - assertContents(); - } - - public void testRemoveOneFromOneStandard() { - c.add("a"); - assertTrue(c.remove("a")); - assertContents(); - } - - public void testContainsNo() { - c.add("a"); - assertFalse(c.contains("b")); - } - - public void testContainsOne() { - c.add("a"); - assertTrue(c.contains(new String("a"))); - } - - public void testContainsAfterRemoval() { - c.add("a"); - c.remove("a"); - assertFalse(c.contains("a")); - } - - public void testContainsAllVacuous() { - assertTrue(c.containsAll(Collections.emptySet())); - } - - public void testRemoveAllVacuous() { - assertFalse(c.removeAll(Collections.emptySet())); - } - - public void testRetainAllVacuous() { - assertFalse(c.retainAll(asList("a"))); - assertContents(); - } - - public void testRetainAllOfNothing() { - c.add("a"); - assertTrue(c.retainAll(Collections.emptySet())); - assertContents(); - } - - public void testClearNothing() { - c.clear(); - assertContents(); - } - - public void testClear() { - c = createSample(); - c.clear(); - assertContents(); - } - - public void testEqualsNo() { - c.add("a"); - - Collection<String> c2 = create(); - c2.add("b"); - - assertFalse(c.equals(c2)); - } - - public void testEqualsYes() { - c.add("a"); - c.add("b"); - c.add("b"); - - Collection<String> c2 = create(); - c2.add("a"); - c2.add("b"); - c2.add("b"); - - assertEquals(c, c2); - } - - public void testEqualsSelf() { - c.add("a"); - c.add("b"); - c.add("b"); - - assertEquals(c, c); - } - - public void testEqualsTricky() { - c.add("a"); - c.add("a"); - - Collection<String> c2 = create(); - c2.add("a"); - c2.add("a"); - c2.add("b"); - c2.add("b"); - c2.remove("b"); - c2.remove("b"); - - assertEquals(c, c2); - } - - public void testEqualsPartial() { - c.add("a"); - c.add("b"); - - Collection<String> c2 = create(); - c2.add("a"); - c2.add("c"); - - assertFalse(c.equals(c2)); - - Collection<String> c3 = create(); - c2.add("b"); - c2.add("c"); - - assertFalse(c2.equals(c3)); - } - - public void testEqualsDifferentTypes() { - c.add("a"); - assertFalse(c.equals("a")); - } - - public void testToArrayOne() { - c.add("a"); - String[] array = new String[3]; - assertSame(array, c.toArray(array)); - assertEquals("a", array[0]); - assertNull(array[1]); - } - - @GwtIncompatible("NullPointerTester") - public void testNullPointerExceptions() { - NullPointerTester tester = new NullPointerTester(); - tester.testAllPublicInstanceMethods(c); - } - - protected Collection<String> createSample() { - Collection<String> c = create(); - c.add("a"); - c.add("b"); - c.add("b"); - c.add("c"); - c.add("d"); - c.add("d"); - c.add("d"); - return c; - } - - protected void assertContents(String... expected) { - ASSERT.<String, Collection<String>>that(c).has().allFrom(asList(expected)); - } -} diff --git a/guava-tests/test/com/google/common/collect/AbstractConcurrentHashMultisetTest.java b/guava-tests/test/com/google/common/collect/AbstractConcurrentHashMultisetTest.java deleted file mode 100644 index 514e7e9..0000000 --- a/guava-tests/test/com/google/common/collect/AbstractConcurrentHashMultisetTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static java.util.Arrays.asList; - -/** - * Unit test for {@link ConcurrentHashMultiset}. - * - * @author Kevin Bourrillion - * @author Jared Levy - */ -public abstract class AbstractConcurrentHashMultisetTest - extends AbstractMultisetTest { - // we don't support null - @Override public void testToStringNull() {} - - // our entries are snapshots, not live views. at least for now. - - @Override public void testEntryAfterRemove() {} - @Override public void testEntryAfterClear() {} - @Override public void testEntryAfterEntrySetClear() {} - @Override public void testEntryAfterEntrySetIteratorRemove() {} - @Override public void testEntryAfterElementSetIteratorRemove() {} - - public void testCopyConstructor() { - ms = ConcurrentHashMultiset.create(asList("a", "b", "a", "c")); - assertEquals(4, ms.size()); - assertEquals(2, ms.count("a")); - assertEquals(1, ms.count("b")); - assertEquals(1, ms.count("c")); - } - - public void testSetCount() { - ConcurrentHashMultiset<String> cms = ConcurrentHashMultiset.create(); - cms.add("a", 2); - cms.add("b", 3); - - try { - cms.setCount("a", -1); - fail(); - } catch (IllegalArgumentException expected) {} - assertEquals(2, cms.count("a")); - - assertEquals(2, cms.setCount("a", 0)); - assertEquals(0, cms.count("a")); - assertEquals(3, cms.setCount("b", 4)); - assertEquals(4, cms.count("b")); - assertEquals(0, cms.setCount("c", 5)); - assertEquals(5, cms.count("c")); - } - - public void testSetCountConditional() { - ConcurrentHashMultiset<String> cms = ConcurrentHashMultiset.create(); - cms.add("a", 2); - cms.add("b", 3); - - try { - cms.setCount("a", -1, 1); - fail(); - } catch (IllegalArgumentException expected) {} - try { - cms.setCount("a", 1, -1); - fail(); - } catch (IllegalArgumentException expected) {} - assertEquals(2, cms.count("a")); - - assertTrue(cms.setCount("c", 0, 0)); - assertEquals(0, cms.count("c")); - assertFalse(cms.setCount("c", 1, 0)); - assertEquals(0, cms.count("c")); - assertFalse(cms.setCount("a", 0, 0)); - assertEquals(2, cms.count("a")); - assertFalse(cms.setCount("a", 1, 0)); - assertEquals(2, cms.count("a")); - assertTrue(cms.setCount("a", 2, 0)); - assertEquals(0, cms.count("a")); - - assertTrue(cms.setCount("d", 0, 4)); - assertEquals(4, cms.count("d")); - assertFalse(cms.setCount("b", 0, 5)); - assertEquals(3, cms.count("b")); - assertFalse(cms.setCount("b", 1, 5)); - assertEquals(3, cms.count("b")); - assertTrue(cms.setCount("b", 3, 5)); - assertEquals(5, cms.count("b")); - } - - public void testRemoveExactly() { - ConcurrentHashMultiset<String> cms = ConcurrentHashMultiset.create(); - cms.add("a", 2); - cms.add("b", 3); - - try { - cms.removeExactly("a", -2); - } catch (IllegalArgumentException expected) {} - - assertTrue(cms.removeExactly("a", 0)); - assertEquals(2, cms.count("a")); - assertTrue(cms.removeExactly("c", 0)); - assertEquals(0, cms.count("c")); - - assertFalse(cms.removeExactly("a", 4)); - assertEquals(2, cms.count("a")); - assertTrue(cms.removeExactly("a", 2)); - assertEquals(0, cms.count("a")); - assertTrue(cms.removeExactly("b", 2)); - assertEquals(1, cms.count("b")); - } -} diff --git a/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java b/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java index 723aadb..16d5fd8 100644 --- a/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java +++ b/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java @@ -27,16 +27,14 @@ import com.google.common.collect.testing.IteratorTester; import com.google.common.collect.testing.MinimalCollection; import com.google.common.collect.testing.MinimalIterable; +import junit.framework.TestCase; + import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; -import junit.framework.TestCase; - -import org.truth0.subjects.CollectionSubject; - /** * Base class for {@link ImmutableSet} and {@link ImmutableSortedSet} tests. * @@ -123,7 +121,7 @@ public abstract class AbstractImmutableSetTest extends TestCase { try { copyOf((String[]) null); fail(); - } catch(NullPointerException expected) { + } catch (NullPointerException expected) { } } @@ -297,7 +295,7 @@ public abstract class AbstractImmutableSetTest extends TestCase { .add("d", "e", "f") .add("g", "h", "i", "j") .build(); - assertThat(set).has().allOf( + ASSERT.that(set).has().exactly( "a", "b", "c", "d", "e", "f", "g", "h", "i", "j").inOrder(); } @@ -305,9 +303,9 @@ public abstract class AbstractImmutableSetTest extends TestCase { ImmutableSet.Builder<String> builder = this.<String>builder() .add("a") .add("b"); - assertThat(builder.build()).has().allOf("a", "b").inOrder(); + ASSERT.that(builder.build()).has().exactly("a", "b").inOrder(); builder.add("c", "d"); - assertThat(builder.build()).has().allOf("a", "b", "c", "d").inOrder(); + ASSERT.that(builder.build()).has().exactly("a", "b", "c", "d").inOrder(); } public void testBuilderWithDuplicateElements() { @@ -327,9 +325,9 @@ public abstract class AbstractImmutableSetTest extends TestCase { .add("a") .add("a", "a") .add("b"); - assertThat(builder.build()).has().allOf("a", "b").inOrder(); + ASSERT.that(builder.build()).has().exactly("a", "b").inOrder(); builder.add("a", "b", "c", "c"); - assertThat(builder.build()).has().allOf("a", "b", "c").inOrder(); + ASSERT.that(builder.build()).has().exactly("a", "b", "c").inOrder(); } public void testBuilderAddAll() { @@ -339,7 +337,7 @@ public abstract class AbstractImmutableSetTest extends TestCase { .addAll(a) .addAll(b) .build(); - assertThat(set).has().allOf("a", "b", "c", "d", "e").inOrder(); + ASSERT.that(set).has().exactly("a", "b", "c", "d", "e").inOrder(); } static final int LAST_COLOR_ADDED = 0x00BFFF; @@ -475,10 +473,4 @@ public abstract class AbstractImmutableSetTest extends TestCase { } } } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/AbstractIteratorTest.java b/guava-tests/test/com/google/common/collect/AbstractIteratorTest.java index 668a5e8..62355c2 100644 --- a/guava-tests/test/com/google/common/collect/AbstractIteratorTest.java +++ b/guava-tests/test/com/google/common/collect/AbstractIteratorTest.java @@ -17,19 +17,22 @@ package com.google.common.collect; import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; +import com.google.common.testing.GcFinalization; +import junit.framework.TestCase; + +import java.lang.ref.WeakReference; import java.util.Iterator; import java.util.NoSuchElementException; -import junit.framework.TestCase; - /** * Unit test for {@code AbstractIterator}. * * @author Kevin Bourrillion */ @SuppressWarnings("serial") // No serialization is used in this test -@GwtCompatible +@GwtCompatible(emulated = true) // TODO(cpovirk): why is this slow (>1m/test) under GWT when fully optimized? public class AbstractIteratorTest extends TestCase { @@ -131,6 +134,17 @@ public class AbstractIteratorTest extends TestCase { } } + @GwtIncompatible("weak references") + public void testFreesNextReference() { + Iterator<Object> itr = new AbstractIterator<Object>() { + @Override public Object computeNext() { + return new Object(); + } + }; + WeakReference<Object> ref = new WeakReference<Object>(itr.next()); + GcFinalization.awaitClear(ref); + } + public void testDefaultBehaviorOfPeekForEmptyIteration() { AbstractIterator<Integer> empty = new AbstractIterator<Integer>() { diff --git a/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java b/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java deleted file mode 100644 index 9c4340a..0000000 --- a/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE; -import static java.util.Arrays.asList; -import static org.truth0.Truth.ASSERT; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.collect.testing.ListIteratorTester; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import org.truth0.subjects.CollectionSubject; - -/** - * Tests for {@code ListMultimap} implementations. - * - * @author Jared Levy - */ -@GwtCompatible(emulated = true) -public abstract class AbstractListMultimapTest extends AbstractMultimapTest { - - @Override protected abstract ListMultimap<String, Integer> create(); - - /** - * Test adding duplicate key-value pairs to multimap. - */ - public void testDuplicates() { - Multimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("bar", 3); - multimap.put("foo", 1); - assertEquals(4, multimap.size()); - assertTrue(multimap.containsEntry("foo", 1)); - multimap.remove("foo", 1); - assertEquals(3, multimap.size()); - assertTrue(multimap.containsEntry("foo", 1)); - } - - /** - * Test returned boolean when adding duplicate key-value pairs to multimap. - */ - public void testPutReturn() { - Multimap<String, Integer> multimap = create(); - assertTrue(multimap.put("foo", 1)); - assertTrue(multimap.put("foo", 1)); - assertTrue(multimap.put("foo", 3)); - assertTrue(multimap.put("bar", 5)); - } - - public void testPutAllReturn_existingElements() { - Multimap<String, Integer> multimap = create(); - assertTrue(multimap.putAll("foo", asList(1, 2, 3))); - assertTrue(multimap.put("foo", 1)); - assertTrue(multimap.putAll("foo", asList(1, 2, 3))); - assertTrue(multimap.putAll("foo", asList(1, 3))); - - Multimap<String, Integer> other = create(); - other.putAll("foo", asList(1, 2)); - assertTrue(multimap.putAll(other)); - - other.putAll("bar", asList(1, 2)); - assertTrue(multimap.putAll(other)); - assertTrue(other.putAll(multimap)); - } - - /** - * Confirm that get() returns a collection equal to a List. - */ - public void testGetEquals() { - Multimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 3); - assertEquals(ImmutableList.of(1, 3), multimap.get("foo")); - } - - public void testAsMapEquals() { - Multimap<String, Integer> multimap = getMultimap(); - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Map<String, Collection<Integer>> map = multimap.asMap(); - - Map<String, Collection<Integer>> equalMap = Maps.newHashMap(); - equalMap.put("foo", asList(1, nullValue())); - equalMap.put(nullKey(), asList(3)); - assertEquals(map, equalMap); - assertEquals(equalMap, map); - assertEquals(equalMap.hashCode(), multimap.hashCode()); - - Map<String, Collection<Integer>> unequalMap = Maps.newHashMap(); - equalMap.put("foo", asList(3, nullValue())); - equalMap.put(nullKey(), asList(1)); - assertFalse(map.equals(unequalMap)); - assertFalse(unequalMap.equals(map)); - } - - /** - * Confirm that asMap().entrySet() returns values equal to a List. - */ - public void testAsMapEntriesEquals() { - Multimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 3); - Iterator<Map.Entry<String, Collection<Integer>>> i = - multimap.asMap().entrySet().iterator(); - Map.Entry<String, Collection<Integer>> entry = i.next(); - assertEquals("foo", entry.getKey()); - assertEquals(ImmutableList.of(1, 3), entry.getValue()); - assertFalse(i.hasNext()); - } - - public void testAsMapValuesRemove() { - Multimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("bar", 3); - Collection<Collection<Integer>> asMapValues = multimap.asMap().values(); - assertFalse(asMapValues.remove(asList(3, 1))); - assertEquals(3, multimap.size()); - assertTrue(asMapValues.remove(asList(1, 3))); - assertEquals(1, multimap.size()); - } - - /** - * Test multimap.equals() for multimaps with different insertion orderings. - */ - public void testEqualsOrdering() { - Multimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("bar", 3); - Multimap<String, Integer> multimap2 = create(); - multimap2.put("foo", 3); - multimap2.put("foo", 1); - multimap2.put("bar", 3); - assertFalse(multimap.equals(multimap2)); - } - - /** - * Test the ordering of the values returned by multimap.get(). - */ - public void testPutGetOrdering() { - Multimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("bar", 3); - Iterator<Integer> values = multimap.get("foo").iterator(); - assertEquals(Integer.valueOf(1), values.next()); - assertEquals(Integer.valueOf(3), values.next()); - } - - /** - * Test List-specific methods on List returned by get(). - */ - public void testListMethods() { - ListMultimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("foo", 5); - List<Integer> list = multimap.get("foo"); - - list.add(1, 2); - assertEquals(4, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 5).inOrder(); - - list.addAll(3, asList(4, 8)); - assertEquals(6, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 4, 8, 5).inOrder(); - - assertEquals(8, list.get(4).intValue()); - assertEquals(4, list.indexOf(8)); - assertEquals(4, list.lastIndexOf(8)); - - list.remove(4); - assertEquals(5, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder(); - - list.set(4, 10); - assertEquals(5, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 4, 10).inOrder(); - } - - public void testListMethodsIncludingSublist() { - ListMultimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 2); - multimap.put("foo", 3); - multimap.put("foo", 4); - multimap.put("foo", 10); - List<Integer> list = multimap.get("foo"); - - List<Integer> sublist = list.subList(1, 4); - assertThat(sublist).has().allOf(2, 3, 4).inOrder(); - list.set(3, 6); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 6, 10).inOrder(); - } - - /** - * Test sublist of List returned by get() after the original list is updated. - */ - public void testSublistAfterListUpdate() { - ListMultimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 2); - multimap.put("foo", 3); - multimap.put("foo", 4); - multimap.put("foo", 5); - - List<Integer> list = multimap.get("foo"); - List<Integer> sublist = list.subList(1, 4); - assertThat(sublist).has().allOf(2, 3, 4).inOrder(); - list.set(3, 6); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 6, 5).inOrder(); - assertThat(sublist).has().allOf(2, 3, 6).inOrder(); - } - - /** - * Test ListIterator methods that don't change the multimap. - */ - public void testListIteratorNavigate() { - ListMultimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 3); - List<Integer> list = multimap.get("foo"); - ListIterator<Integer> iterator = list.listIterator(); - - assertFalse(iterator.hasPrevious()); - assertTrue(iterator.hasNext()); - assertEquals(0, iterator.nextIndex()); - assertEquals(-1, iterator.previousIndex()); - - assertEquals(1, iterator.next().intValue()); - assertEquals(3, iterator.next().intValue()); - assertTrue(iterator.hasPrevious()); - assertFalse(iterator.hasNext()); - - assertEquals(3, iterator.previous().intValue()); - assertEquals(1, iterator.previous().intValue()); - } - - /** - * Test ListIterator methods that change the multimap. - */ - public void testListIteratorUpdate() { - ListMultimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("foo", 5); - List<Integer> list = multimap.get("foo"); - ListIterator<Integer> iterator = list.listIterator(); - - assertEquals(1, iterator.next().intValue()); - iterator.set(2); - assertThat(multimap.get("foo")).has().allOf(2, 3, 5).inOrder(); - - assertEquals(3, iterator.next().intValue()); - iterator.remove(); - assertThat(multimap.get("foo")).has().allOf(2, 5).inOrder(); - } - - /** - * Test calling toString() on the multimap, which does not have a - * deterministic iteration order for keys but does for values. - */ - public void testToString() { - String s = createSample().toString(); - assertTrue(s.equals("{foo=[3, -1, 2, 4, 1], bar=[1, 2, 3, 1]}") - || s.equals("{bar=[1, 2, 3, 1], foo=[3, -1, 2, 4, 1]}")); - } - - /** - * Test calling set() on a sublist. - */ - public void testSublistSet() { - ListMultimap<String, Integer> multimap = create(); - multimap.putAll("foo", asList(1, 2, 3, 4, 5)); - List<Integer> list = multimap.get("foo"); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder(); - List<Integer> sublist = list.subList(1, 4); - ASSERT.<Integer, List<Integer>>that(sublist).has().allOf(2, 3, 4).inOrder(); - - sublist.set(1, 6); - ASSERT.<Integer, List<Integer>>that(multimap.get("foo")).has().allOf(1, 2, 6, 4, 5).inOrder(); - } - - /** - * Test removing elements from a sublist. - */ - public void testSublistRemove() { - ListMultimap<String, Integer> multimap = create(); - multimap.putAll("foo", asList(1, 2, 3, 4, 5)); - List<Integer> list = multimap.get("foo"); - ASSERT.<Integer, List<Integer>>that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder(); - List<Integer> sublist = list.subList(1, 4); - ASSERT.<Integer, List<Integer>>that(sublist).has().allOf(2, 3, 4).inOrder(); - - sublist.remove(1); - assertEquals(4, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 2, 4, 5).inOrder(); - - sublist.removeAll(Collections.singleton(4)); - assertEquals(3, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 2, 5).inOrder(); - - sublist.remove(0); - assertEquals(2, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 5).inOrder(); - } - - /** - * Test adding elements to a sublist. - */ - public void testSublistAdd() { - ListMultimap<String, Integer> multimap = create(); - multimap.putAll("foo", asList(1, 2, 3, 4, 5)); - List<Integer> list = multimap.get("foo"); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder(); - List<Integer> sublist = list.subList(1, 4); - assertThat(sublist).has().allOf(2, 3, 4).inOrder(); - - sublist.add(6); - assertEquals(6, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 4, 6, 5).inOrder(); - - sublist.add(0, 7); - assertEquals(7, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 7, 2, 3, 4, 6, 5).inOrder(); - } - - /** - * Test clearing a sublist. - */ - public void testSublistClear() { - ListMultimap<String, Integer> multimap = create(); - multimap.putAll("foo", asList(1, 2, 3, 4, 5)); - List<Integer> list = multimap.get("foo"); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder(); - List<Integer> sublist = list.subList(1, 4); - assertThat(sublist).has().allOf(2, 3, 4).inOrder(); - - sublist.clear(); - assertEquals(2, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 5).inOrder(); - } - - /** - * Test adding elements to an empty sublist with an empty ancestor. - */ - public void testSublistAddToEmpty() { - ListMultimap<String, Integer> multimap = create(); - multimap.putAll("foo", asList(1, 2, 3, 4, 5)); - List<Integer> list = multimap.get("foo"); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder(); - List<Integer> sublist = list.subList(0, 5); - assertThat(sublist).has().allOf(1, 2, 3, 4, 5).inOrder(); - - sublist.retainAll(Collections.EMPTY_LIST); - assertTrue(multimap.isEmpty()); - - sublist.add(6); - assertEquals(1, multimap.size()); - assertTrue(multimap.containsEntry("foo", 6)); - } - - /** - * Test updates through a list iterator retrieved by - * multimap.get(key).listIterator(index). - */ - public void testListIteratorIndexUpdate() { - ListMultimap<String, Integer> multimap = create(); - multimap.putAll("foo", asList(1, 2, 3, 4, 5)); - ListIterator<Integer> iterator = multimap.get("foo").listIterator(1); - - assertEquals(2, iterator.next().intValue()); - iterator.set(6); - assertThat(multimap.get("foo")).has().allOf(1, 6, 3, 4, 5).inOrder(); - - assertTrue(iterator.hasNext()); - assertEquals(3, iterator.next().intValue()); - iterator.remove(); - assertThat(multimap.get("foo")).has().allOf(1, 6, 4, 5).inOrder(); - assertEquals(4, multimap.size()); - } - - @GwtIncompatible("unreasonable slow") - public void testGetIteration() { - List<Integer> addItems = ImmutableList.of(99, 88, 77); - - for (final int startIndex : new int[] {0, 3, 5}) { - new ListIteratorTester<Integer>(3, addItems, MODIFIABLE, - Lists.newArrayList(2, 3, 4, 7, 8), startIndex) { - private ListMultimap<String, Integer> multimap; - - @Override protected ListIterator<Integer> newTargetIterator() { - multimap = create(); - multimap.put("bar", 1); - multimap.putAll("foo", asList(2, 3, 4)); - multimap.putAll("bar", asList(5, 6)); - multimap.putAll("foo", asList(7, 8)); - return multimap.get("foo").listIterator(startIndex); - } - - @Override protected void verify(List<Integer> elements) { - assertEquals(elements, multimap.get("foo")); - } - }.test(); - } - } - - public void testListGetSet() { - ListMultimap<String, Integer> map = create(); - map.put("bar", 1); - map.get("bar").set(0, 2); - assertEquals("{bar=[2]}", map.toString()); - assertEquals("[bar=2]", map.entries().toString()); - } - - public void testListPutAllIterable() { - Multimap<String, Integer> map = create(); - map.putAll("foo", asList(1, 2)); - assertEquals("{foo=[1, 2]}", map.toString()); - assertEquals("[foo=1, foo=2]", map.entries().toString()); - } - - public void testListRemoveAll() { - Multimap<String, Integer> map = create(); - map.put("bar", 1); - map.put("foo", 2); - map.put("bar", 3); - map.put("bar", 4); - map.removeAll("foo"); - assertEquals("[bar=1, bar=3, bar=4]", map.entries().toString()); - assertEquals("{bar=[1, 3, 4]}", map.toString()); - map.removeAll("bar"); - assertEquals("[]", map.entries().toString()); - assertEquals("{}", map.toString()); - } - - public void testListEquals() { - Multimap<String, Integer> map1 = create(); - map1.put("bar", 1); - map1.put("foo", 2); - map1.put("bar", 3); - Multimap<String, Integer> map2 = ArrayListMultimap.create(); - map2.putAll(map1); - assertTrue(map1.equals(map2)); - assertTrue(map2.equals(map1)); - assertFalse(map1.equals(null)); - assertFalse(map1.equals(new Object())); - } - - public void testListHashCode() { - Multimap<String, Integer> map1 = create(); - map1.put("bar", 1); - map1.put("foo", 2); - map1.put("bar", 3); - Multimap<String, Integer> map2 = ArrayListMultimap.create(); - map2.putAll(map1); - assertEquals(map1.hashCode(), map2.hashCode()); - } - - public void testListAddIndex() { - ListMultimap<String, Integer> multimap = create(); - multimap.put("bar", 11); - multimap.put("bar", 12); - multimap.get("bar").add(0, 13); - assertThat(multimap.get("bar")).has().allOf(13, 11, 12).inOrder(); - } - - /** - * According to the AbstractCollection.retainAll() implementation, - * {@code A.retainAll(B)} should keep all occurrences of each object in B, - * so even though the collection that this test passes to retainAll() has - * fewer occurrences of 2 than the multimap has, all of the 2s should be - * retained. - */ - public void testGetRetainAll() { - // TODO: test this logic in ListRetainAllTester - ListMultimap<String, Integer> multimap = create(); - multimap.putAll("foo", asList(1, 2, 2, 3, 3, 3)); - - multimap.get("foo").retainAll(asList(1, 2, 4)); - assertThat(multimap.get("foo")).has().allOf(1, 2, 2).inOrder(); - } - - /** - * According to the AbstractCollection.removeAll() implementation, - * {@code A.removeAll(B)} should remove all occurrences of each object in B, - * so even though the collection that this test passes to removeAll() has - * fewer occurrences of 2 and 3 than the multimap has, there should be no - * 2s or 3s remaining in the collection. - */ - public void testGetRemoveAll_someValuesRemain() { - // TODO: test this logic in ListRemoveAllTester - ListMultimap<String, Integer> multimap = create(); - multimap.putAll("foo", asList(1, 2, 2, 3, 3, 3)); - - multimap.get("foo").removeAll(asList(2, 3, 3, 4)); - assertThat(multimap.get("foo")).has().item(1); - } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } -} diff --git a/guava-tests/test/com/google/common/collect/AbstractMapEntryTest.java b/guava-tests/test/com/google/common/collect/AbstractMapEntryTest.java index d9884e4..f106dcc 100644 --- a/guava-tests/test/com/google/common/collect/AbstractMapEntryTest.java +++ b/guava-tests/test/com/google/common/collect/AbstractMapEntryTest.java @@ -18,11 +18,11 @@ package com.google.common.collect; import com.google.common.annotations.GwtCompatible; +import junit.framework.TestCase; + import java.util.Collections; import java.util.Map.Entry; -import junit.framework.TestCase; - /** * Tests for {@code AbstractMapEntry}. * diff --git a/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java b/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java deleted file mode 100644 index 2da04e2..0000000 --- a/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java +++ /dev/null @@ -1,1449 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static java.util.Arrays.asList; -import static org.truth0.Truth.ASSERT; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.testing.SerializableTester; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Set; - -import junit.framework.TestCase; - -import org.truth0.subjects.CollectionSubject; -import org.truth0.subjects.ListSubject; - -/** - * Tests for {@code Multimap} implementations. Caution: when subclassing avoid - * accidental naming collisions with tests in this class! - * - * @author Jared Levy - */ -@GwtCompatible(emulated = true) -public abstract class AbstractMultimapTest extends TestCase { - - private Multimap<String, Integer> multimap; - - protected abstract Multimap<String, Integer> create(); - - protected Multimap<String, Integer> createSample() { - Multimap<String, Integer> sample = create(); - sample.putAll("foo", asList(3, -1, 2, 4, 1)); - sample.putAll("bar", asList(1, 2, 3, 1)); - return sample; - } - - // public for GWT - @Override public void setUp() throws Exception { - super.setUp(); - multimap = create(); - } - - protected Multimap<String, Integer> getMultimap() { - return multimap; - } - - /** - * Returns the key to use as a null placeholder in tests. The default - * implementation returns {@code null}, but tests for multimaps that don't - * support null keys should override it. - */ - protected String nullKey() { - return null; - } - - /** - * Returns the value to use as a null placeholder in tests. The default - * implementation returns {@code null}, but tests for multimaps that don't - * support null values should override it. - */ - protected Integer nullValue() { - return null; - } - - /** - * Validate multimap size by calling {@code size()} and also by iterating - * through the entries. This tests cases where the {@code entries()} list is - * stored separately, such as the {@link LinkedHashMultimap}. It also - * verifies that the multimap contains every multimap entry. - */ - protected void assertSize(int expectedSize) { - assertEquals(expectedSize, multimap.size()); - - int size = 0; - for (Entry<String, Integer> entry : multimap.entries()) { - assertTrue(multimap.containsEntry(entry.getKey(), entry.getValue())); - size++; - } - assertEquals(expectedSize, size); - - int size2 = 0; - for (Entry<String, Collection<Integer>> entry2 : - multimap.asMap().entrySet()) { - size2 += entry2.getValue().size(); - } - assertEquals(expectedSize, size2); - } - - protected boolean removedCollectionsAreModifiable() { - return false; - } - - public void testSize0() { - assertSize(0); - } - - public void testSize1() { - multimap.put("foo", 1); - assertSize(1); - } - - public void testSize2Keys() { - multimap.put("foo", 1); - multimap.put("bar", 5); - assertSize(2); - } - - public void testSize2Values() { - multimap.put("foo", 1); - multimap.put("foo", 7); - assertSize(2); - } - - public void testSizeNull() { - multimap.put("foo", 1); - multimap.put("bar", 5); - multimap.put(nullKey(), nullValue()); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 5); - assertSize(5); - } - - public void testIsEmptyYes() { - assertTrue(multimap.isEmpty()); - } - - public void testIsEmptyNo() { - multimap.put("foo", 1); - assertFalse(multimap.isEmpty()); - } - - public void testIsEmptyNull() { - multimap.put(nullKey(), nullValue()); - assertFalse(multimap.isEmpty()); - } - - public void testIsEmptyRemoved() { - multimap.put("foo", 1); - multimap.remove("foo", 1); - assertTrue(multimap.isEmpty()); - } - - public void testContainsKeyTrue() { - multimap.put("foo", 1); - assertTrue(multimap.containsKey("foo")); - } - - public void testContainsKeyFalse() { - multimap.put("foo", 1); - assertFalse(multimap.containsKey("bar")); - assertFalse(multimap.containsKey(nullKey())); - } - - public void testContainsKeyNull() { - multimap.put(nullKey(), 1); - assertTrue(multimap.containsKey(nullKey())); - } - - public void testContainsValueTrue() { - multimap.put("foo", 1); - assertTrue(multimap.containsValue(1)); - } - - public void testContainsValueFalse() { - multimap.put("foo", 1); - assertFalse(multimap.containsValue(2)); - assertFalse(multimap.containsValue(nullValue())); - } - - public void testContainsValueNull() { - multimap.put("foo", nullValue()); - assertTrue(multimap.containsValue(nullValue())); - } - - public void testContainsKeyValueTrue() { - multimap.put("foo", 1); - assertTrue(multimap.containsEntry("foo", 1)); - } - - public void testContainsKeyValueRemoved() { - multimap.put("foo", 1); - multimap.remove("foo", 1); - assertFalse(multimap.containsEntry("foo", 1)); - } - - public void testGet0() { - multimap.put("foo", 1); - Collection<Integer> values = multimap.get("bar"); - assertEquals(0, values.size()); - } - - public void testGet1() { - multimap.put("foo", 1); - multimap.put("bar", 3); - Collection<Integer> values = multimap.get("bar"); - assertEquals(1, values.size()); - assertTrue(values.contains(3)); - assertFalse(values.contains(5)); - } - - public void testGet2() { - multimap.put("foo", 1); - multimap.put("foo", 3); - Collection<Integer> values = multimap.get("foo"); - assertEquals(2, values.size()); - assertTrue(values.contains(1)); - assertTrue(values.contains(3)); - } - - public void testGetNull() { - multimap.put(nullKey(), nullValue()); - multimap.put(nullKey(), 3); - Collection<Integer> values = multimap.get(nullKey()); - assertEquals(2, values.size()); - assertTrue(values.contains(nullValue())); - assertTrue(values.contains(3)); - } - - public void testPutAllIterable() { - Iterable<Integer> iterable = new Iterable<Integer>() { - @Override - public Iterator<Integer> iterator() { - return Lists.newArrayList(1, 3).iterator(); - } - }; - multimap.putAll("foo", iterable); - assertTrue(multimap.containsEntry("foo", 1)); - assertTrue(multimap.containsEntry("foo", 3)); - assertSize(2); - - Iterable<Integer> emptyIterable = new Iterable<Integer>() { - @Override - public Iterator<Integer> iterator() { - return Iterators.emptyIterator(); - } - }; - multimap.putAll("bar", emptyIterable); - assertSize(2); - assertEquals(Collections.singleton("foo"), multimap.keySet()); - } - - public void testPutAllCollection() { - Collection<Integer> collection = Lists.newArrayList(1, 3); - multimap.putAll("foo", collection); - assertTrue(multimap.containsEntry("foo", 1)); - assertTrue(multimap.containsEntry("foo", 3)); - assertSize(2); - - Collection<Integer> emptyCollection = Lists.newArrayList(); - multimap.putAll("bar", emptyCollection); - assertSize(2); - assertEquals(Collections.singleton("foo"), multimap.keySet()); - } - - public void testPutAllCollectionNull() { - Collection<Integer> collection = Lists.newArrayList(1, nullValue()); - multimap.putAll(nullKey(), collection); - assertTrue(multimap.containsEntry(nullKey(), 1)); - assertTrue(multimap.containsEntry(nullKey(), nullValue())); - assertSize(2); - } - - public void testPutAllEmptyCollection() { - Collection<Integer> collection = Lists.newArrayList(); - multimap.putAll("foo", collection); - assertSize(0); - assertTrue(multimap.isEmpty()); - } - - public void testPutAllMultimap() { - multimap.put("foo", 2); - multimap.put("cow", 5); - multimap.put(nullKey(), 2); - Multimap<String, Integer> multimap2 = create(); - multimap2.put("foo", 1); - multimap2.put("bar", 3); - multimap2.put(nullKey(), nullValue()); - multimap.putAll(multimap2); - assertTrue(multimap.containsEntry("foo", 2)); - assertTrue(multimap.containsEntry("cow", 5)); - assertTrue(multimap.containsEntry("foo", 1)); - assertTrue(multimap.containsEntry("bar", 3)); - assertTrue(multimap.containsEntry(nullKey(), nullValue())); - assertTrue(multimap.containsEntry(nullKey(), 2)); - assertSize(6); - } - - public void testPutAllReturn_emptyCollection() { - assertFalse(multimap.putAll("foo", new ArrayList<Integer>())); - assertFalse(multimap.putAll(create())); - } - - public void testPutAllReturn_nonEmptyCollection() { - assertTrue(multimap.putAll("foo", asList(1, 2, 3))); - assertTrue(multimap.putAll("foo", asList(4, 5, 6))); - assertFalse(multimap.putAll(create())); - - Multimap<String, Integer> other = create(); - other.putAll("bar", asList(7, 8, 9)); - assertTrue(multimap.putAll(other)); - } - - private void checkRemovedCollection(Collection<Integer> collection) { - if (removedCollectionsAreModifiable()) { - collection.add(9876); - collection.remove(9876); - assertFalse(collection.contains(9876)); - } else { - try { - collection.add(9876); - fail(); - } catch (UnsupportedOperationException expected) { - } - } - } - - public void testReplaceValues() { - multimap.put("foo", 1); - multimap.put("bar", 3); - Collection<Integer> values = asList(2, nullValue()); - Collection<Integer> oldValues = multimap.replaceValues("foo", values); - assertTrue(multimap.containsEntry("foo", 2)); - assertTrue(multimap.containsEntry("foo", nullValue())); - assertTrue(multimap.containsEntry("bar", 3)); - assertSize(3); - assertTrue(oldValues.contains(1)); - assertEquals(1, oldValues.size()); - checkRemovedCollection(oldValues); - } - - public void testReplaceValuesEmpty() { - multimap.put("foo", 1); - multimap.put("bar", 3); - Collection<Integer> values = asList(); - Collection<Integer> oldValues = multimap.replaceValues("foo", values); - assertFalse(multimap.containsKey("foo")); - assertTrue(multimap.containsEntry("bar", 3)); - assertSize(1); - assertTrue(oldValues.contains(1)); - assertEquals(1, oldValues.size()); - checkRemovedCollection(oldValues); - } - - public void testReplaceValuesNull() { - multimap.put(nullKey(), 1); - multimap.put("bar", 3); - Collection<Integer> values = asList(2, nullValue()); - Collection<Integer> oldValues = multimap.replaceValues(nullKey(), values); - assertTrue(multimap.containsEntry(nullKey(), 2)); - assertTrue(multimap.containsEntry(nullKey(), nullValue())); - assertTrue(multimap.containsEntry("bar", 3)); - assertSize(3); - assertTrue(oldValues.contains(1)); - assertEquals(1, oldValues.size()); - checkRemovedCollection(oldValues); - } - - public void testReplaceValuesNotPresent() { - multimap.put("bar", 3); - Collection<Integer> values = asList(2, 4); - Collection<Integer> oldValues = multimap.replaceValues("foo", values); - assertTrue(multimap.containsEntry("foo", 2)); - assertTrue(multimap.containsEntry("foo", 4)); - assertTrue(multimap.containsEntry("bar", 3)); - assertSize(3); - assertNotNull(oldValues); - assertTrue(oldValues.isEmpty()); - checkRemovedCollection(oldValues); - } - - public void testReplaceValuesDuplicates() { - Collection<Integer> values = Lists.newArrayList(1, 2, 3, 2, 1); - multimap.put("bar", 3); - Collection<Integer> oldValues = multimap.replaceValues("bar", values); - Collection<Integer> replacedValues = multimap.get("bar"); - assertSize(multimap.size()); - assertEquals(replacedValues.size(), multimap.size()); - assertEquals(1, oldValues.size()); - assertTrue(oldValues.contains(3)); - checkRemovedCollection(oldValues); - } - - public void testRemove() { - multimap.put("foo", 1); - multimap.put("foo", 3); - - assertTrue(multimap.remove("foo", 1)); - assertFalse(multimap.containsEntry("foo", 1)); - assertTrue(multimap.containsEntry("foo", 3)); - assertSize(1); - - assertFalse(multimap.remove("bar", 3)); - assertTrue(multimap.containsEntry("foo", 3)); - assertSize(1); - - assertFalse(multimap.remove("foo", 2)); - assertTrue(multimap.containsEntry("foo", 3)); - assertSize(1); - - assertTrue(multimap.remove("foo", 3)); - assertFalse(multimap.containsKey("foo")); - assertSize(0); - } - - public void testRemoveNull() { - multimap.put(nullKey(), 1); - multimap.put(nullKey(), 3); - multimap.put(nullKey(), nullValue()); - - assertTrue(multimap.remove(nullKey(), 1)); - assertFalse(multimap.containsEntry(nullKey(), 1)); - assertTrue(multimap.containsEntry(nullKey(), 3)); - assertTrue(multimap.containsEntry(nullKey(), nullValue())); - assertSize(2); - - assertTrue(multimap.remove(nullKey(), nullValue())); - assertFalse(multimap.containsEntry(nullKey(), 1)); - assertTrue(multimap.containsEntry(nullKey(), 3)); - assertFalse(multimap.containsEntry(nullKey(), nullValue())); - assertSize(1); - } - - public void testRemoveAll() { - multimap.put("foo", 1); - multimap.put("foo", 3); - Collection<Integer> removed = multimap.removeAll("foo"); - assertFalse(multimap.containsKey("foo")); - assertSize(0); - assertTrue(removed.contains(1)); - assertTrue(removed.contains(3)); - assertEquals(2, removed.size()); - checkRemovedCollection(removed); - } - - public void testRemoveAllNull() { - multimap.put(nullKey(), 1); - multimap.put(nullKey(), nullValue()); - Collection<Integer> removed = multimap.removeAll(nullKey()); - assertFalse(multimap.containsKey(nullKey())); - assertSize(0); - assertTrue(removed.contains(1)); - assertTrue(removed.contains(nullValue())); - assertEquals(2, removed.size()); - checkRemovedCollection(removed); - } - - public void testRemoveAllNotPresent() { - multimap.put("foo", 1); - multimap.put("foo", 3); - Collection<Integer> removed = multimap.removeAll("bar"); - assertSize(2); - assertNotNull(removed); - assertTrue(removed.isEmpty()); - checkRemovedCollection(removed); - } - - public void testClear() { - multimap.put("foo", 1); - multimap.put("bar", 3); - multimap.clear(); - assertEquals(0, multimap.keySet().size()); - assertSize(0); - } - - public void testKeySet() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Set<String> keys = multimap.keySet(); - assertEquals(2, keys.size()); - assertTrue(keys.contains("foo")); - assertTrue(keys.contains(nullKey())); - assertTrue(keys.containsAll(Lists.newArrayList("foo", nullKey()))); - assertFalse(keys.containsAll(Lists.newArrayList("foo", "bar"))); - } - - public void testValues() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Collection<Integer> values = multimap.values(); - assertEquals(3, values.size()); - assertTrue(values.contains(1)); - assertTrue(values.contains(3)); - assertTrue(values.contains(nullValue())); - assertFalse(values.contains(5)); - } - - public void testValuesToArray() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Collection<Integer> values = multimap.values(); - assertThat(values.toArray()).has().allOf(1, 3, nullValue()); - assertThat(values.toArray(new Integer[3])).has().allOf(1, 3, nullValue()); - } - - public void testValuesClear() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Collection<Integer> values = multimap.values(); - values.clear(); - assertTrue(multimap.isEmpty()); - assertTrue(values.isEmpty()); - assertFalse(multimap.containsEntry("foo", 1)); - } - - public void testValuesRemoveAllNullFromEmpty() { - try { - multimap.values().removeAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException expected) {} - } - - public void testValuesRetainAllNullFromEmpty() { - try { - multimap.values().retainAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException expected) {} - } - - // the entries collection is more thoroughly tested in MultimapCollectionTest - @SuppressWarnings("unchecked") // varargs - public void testEntries() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Collection<Entry<String, Integer>> entries = multimap.entries(); - assertThat(entries).has().allOf( - Maps.immutableEntry("foo", 1), - Maps.immutableEntry("foo", nullValue()), - Maps.immutableEntry(nullKey(), 3)); - } - - public void testNoSuchElementException() { - Iterator<Entry<String, Integer>> entries = - multimap.entries().iterator(); - try { - entries.next(); - fail(); - } catch (NoSuchElementException expected) {} - } - - public void testAsMap() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Map<String, Collection<Integer>> map = multimap.asMap(); - - assertEquals(2, map.size()); - assertThat(map.get("foo")).has().allOf(1, nullValue()); - assertThat(map.get(nullKey())).has().item(3); - assertNull(map.get("bar")); - assertTrue(map.containsKey("foo")); - assertTrue(map.containsKey(nullKey())); - assertFalse(multimap.containsKey("bar")); - - assertThat(map.remove("foo")).has().allOf(1, nullValue()); - assertFalse(multimap.containsKey("foo")); - assertEquals(1, multimap.size()); - assertNull(map.remove("bar")); - multimap.get(nullKey()).add(5); - assertTrue(multimap.containsEntry(nullKey(), 5)); - assertEquals(2, multimap.size()); - multimap.get(nullKey()).clear(); - assertTrue(multimap.isEmpty()); - assertEquals(0, multimap.size()); - - try { - map.put("bar", asList(4, 8)); - fail("Expected UnsupportedOperationException"); - } catch (UnsupportedOperationException expected) {} - - multimap.put("bar", 5); - assertSize(1); - map.clear(); - assertSize(0); - } - - public void testAsMapEntries() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Collection<Entry<String, Collection<Integer>>> entries = - multimap.asMap().entrySet(); - assertEquals(2, entries.size()); - - assertTrue(entries.contains( - Maps.immutableEntry("foo", multimap.get("foo")))); - assertFalse(entries.contains( - Maps.immutableEntry("bar", multimap.get("foo")))); - assertFalse(entries.contains( - Maps.immutableEntry("bar", null))); - assertFalse(entries.contains( - Maps.immutableEntry("foo", null))); - assertFalse(entries.contains( - Maps.immutableEntry("foo", asList(1, 4)))); - assertFalse(entries.contains("foo")); - - Iterator<Entry<String, Collection<Integer>>> iterator = - entries.iterator(); - for (int i = 0; i < 2; i++) { - assertTrue(iterator.hasNext()); - Entry<String, Collection<Integer>> entry = iterator.next(); - if ("foo".equals(entry.getKey())) { - assertEquals(2, entry.getValue().size()); - assertTrue(entry.getValue().contains(1)); - assertTrue(entry.getValue().contains(nullValue())); - } else { - assertEquals(nullKey(), entry.getKey()); - assertEquals(1, entry.getValue().size()); - assertTrue(entry.getValue().contains(3)); - } - } - assertFalse(iterator.hasNext()); - } - - public void testAsMapEntriesToArray() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Collection<Entry<String, Collection<Integer>>> entries = - multimap.asMap().entrySet(); - - assertThat(entries.toArray()).has().allOf( - Maps.immutableEntry("foo", multimap.get("foo")), - Maps.immutableEntry(nullKey(), multimap.get(nullKey()))); - assertThat(entries.toArray(new Entry[2])).has().allOf( - Maps.immutableEntry("foo", multimap.get("foo")), - Maps.immutableEntry(nullKey(), multimap.get(nullKey()))); - } - - public void testAsMapValuesToArray() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Collection<Collection<Integer>> values = - multimap.asMap().values(); - - assertThat(values.toArray()).has().allOf( - multimap.get("foo"), multimap.get(nullKey())); - assertThat(values.toArray(new Collection[2])).has().allOf( - multimap.get("foo"), multimap.get(nullKey())); - } - - public void testAsMapKeySetToArray() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Set<String> keySet = multimap.asMap().keySet(); - - assertThat(keySet.toArray()).has().allOf("foo", nullKey()); - assertThat(keySet.toArray(new String[2])).has().allOf("foo", nullKey()); - } - - public void testAsMapToString() { - multimap.put("foo", 1); - assertEquals("{foo=[1]}", multimap.asMap().toString()); - } - - public void testKeys() { - multimap.put("foo", 1); - multimap.put("foo", 5); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Multiset<String> multiset = multimap.keys(); - assertEquals(3, multiset.count("foo")); - assertEquals(1, multiset.count(nullKey())); - assertThat(multiset.elementSet()).has().allOf("foo", nullKey()); - assertEquals(2, multiset.entrySet().size()); - assertEquals(4, multiset.size()); - - Set<Multiset.Entry<String>> entries = multimap.keys().entrySet(); - assertTrue(entries.contains(Multisets.immutableEntry("foo", 3))); - assertFalse(entries.contains(Multisets.immutableEntry("foo", 2))); - assertFalse(entries.contains(Maps.immutableEntry("foo", 3))); - - Multiset<String> foo3null1 = - HashMultiset.create(asList("foo", "foo", nullKey(), "foo")); - assertEquals(foo3null1, multiset); - assertEquals(multiset, foo3null1); - assertFalse(multiset.equals( - HashMultiset.create(asList("foo", "foo", nullKey(), nullKey())))); - assertEquals(foo3null1.hashCode(), multiset.hashCode()); - assertEquals(foo3null1.entrySet(), multiset.entrySet()); - assertEquals(multiset.entrySet(), foo3null1.entrySet()); - assertEquals(foo3null1.entrySet().hashCode(), - multiset.entrySet().hashCode()); - - assertEquals(0, multiset.remove("bar", 1)); - assertEquals(1, multiset.remove(nullKey(), 4)); - assertFalse(multimap.containsKey(nullKey())); - assertSize(3); - assertEquals("foo", entries.iterator().next().getElement()); - - assertEquals(3, multiset.remove("foo", 1)); - assertTrue(multimap.containsKey("foo")); - assertSize(2); - assertEquals(2, multiset.setCount("foo", 0)); - assertEquals(0, multiset.setCount("bar", 0)); - } - - public void testKeysToArray() { - multimap.put("foo", 1); - multimap.put("foo", 5); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - assertThat(multimap.keys().toArray()).has().allOf( - "foo", "foo", "foo", nullKey()); - assertThat(multimap.keys().toArray(new String[3])).has().allOf( - "foo", "foo", "foo", nullKey()); - } - - public void testKeysAdd() { - multimap.put("foo", 1); - Multiset<String> multiset = multimap.keys(); - - try { - multiset.add("bar"); - fail(); - } catch (UnsupportedOperationException expected) {} - - try { - multiset.add("bar", 2); - fail(); - } catch (UnsupportedOperationException expected) {} - } - - public void testKeysContainsAll() { - multimap.put("foo", 1); - multimap.put("foo", 5); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Multiset<String> multiset = multimap.keys(); - - assertTrue(multiset.containsAll(asList("foo", nullKey()))); - assertFalse(multiset.containsAll(asList("foo", "bar"))); - } - - public void testKeysClear() { - multimap.put("foo", 1); - multimap.put("foo", 5); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Multiset<String> multiset = multimap.keys(); - - multiset.clear(); - assertTrue(multiset.isEmpty()); - assertTrue(multimap.isEmpty()); - assertSize(0); - assertFalse(multimap.containsKey("foo")); - assertFalse(multimap.containsKey(nullKey())); - } - - public void testKeysToString() { - multimap.put("foo", 7); - multimap.put("foo", 8); - assertEquals("[foo x 2]", multimap.keys().toString()); - } - - public void testKeysEntrySetIterator() { - multimap.put("foo", 7); - multimap.put("foo", 8); - Iterator<Multiset.Entry<String>> iterator - = multimap.keys().entrySet().iterator(); - assertTrue(iterator.hasNext()); - assertEquals(Multisets.immutableEntry("foo", 2), iterator.next()); - iterator.remove(); - assertFalse(iterator.hasNext()); - assertSize(0); - } - - public void testKeysEntrySetToString() { - multimap.put("foo", 7); - multimap.put("foo", 8); - assertEquals("[foo x 2]", multimap.keys().entrySet().toString()); - } - - public void testKeysEntrySetRemove() { - multimap.putAll("foo", asList(1, 2, 3)); - multimap.putAll("bar", asList(4, 5)); - Set<Multiset.Entry<String>> entries = multimap.keys().entrySet(); - assertTrue(entries.remove(Multisets.immutableEntry("bar", 2))); - assertEquals("[foo x 3]", multimap.keys().entrySet().toString()); - - // doesn't exist in entries, should have no effect - assertFalse(entries.remove(Multisets.immutableEntry("foo", 2))); - assertEquals("[foo x 3]", multimap.keys().entrySet().toString()); - assertEquals("Multimap size after keys().entrySet().remove(entry)", - 3, multimap.size()); - } - - public void testEqualsTrue() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - assertEquals(multimap, multimap); - - Multimap<String, Integer> multimap2 = create(); - multimap2.put(nullKey(), 3); - multimap2.put("foo", 1); - multimap2.put("foo", nullValue()); - - assertEquals(multimap, multimap2); - assertEquals(multimap.hashCode(), multimap2.hashCode()); - } - - public void testEqualsFalse() { - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("bar", 3); - - Multimap<String, Integer> multimap2 = create(); - multimap2.put("bar", 3); - multimap2.put("bar", 1); - assertFalse(multimap.equals(multimap2)); - - multimap2.put("foo", 3); - assertFalse(multimap.equals(multimap2)); - - assertFalse(multimap.equals(nullValue())); - assertFalse(multimap.equals("foo")); - } - - public void testValuesIterator() { - multimap.put("foo", 1); - multimap.put("foo", 2); - multimap.put(nullKey(), 4); - int sum = 0; - for (int i : multimap.values()) { - sum += i; - } - assertEquals(7, sum); - } - - public void testValuesIteratorEmpty() { - int sum = 0; - for (int i : multimap.values()) { - sum += i; - } - assertEquals(0, sum); - } - - public void testGetAddQuery() { - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("bar", 4); - Collection<Integer> values = multimap.get("foo"); - multimap.put("foo", 5); - multimap.put("bar", 6); - - /* Verify that values includes effect of put. */ - assertEquals(3, values.size()); - assertTrue(values.contains(1)); - assertTrue(values.contains(5)); - assertFalse(values.contains(6)); - assertThat(values).has().allOf(1, 3, 5); - assertTrue(values.containsAll(asList(3, 5))); - assertFalse(values.isEmpty()); - assertEquals(multimap.get("foo"), values); - assertEquals(multimap.get("foo").hashCode(), values.hashCode()); - assertEquals(multimap.get("foo").toString(), values.toString()); - } - - public void testGetAddAll() { - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.get("foo").addAll(asList(5, 7)); - multimap.get("bar").addAll(asList(6, 8)); - multimap.get("cow").addAll(Arrays.<Integer>asList()); - assertSize(6); - assertThat(multimap.get("foo")).has().allOf(1, 3, 5, 7); - assertThat(multimap.get("bar")).has().allOf(6, 8); - assertThat(multimap.get("cow")).isEmpty(); - } - - public void testGetRemoveAddQuery() { - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("bar", 4); - Collection<Integer> values = multimap.get("foo"); - Iterator<Integer> iterator = values.iterator(); - multimap.remove("foo", 1); - multimap.remove("foo", 3); - - /* Verify that values includes effect of remove */ - assertEquals(0, values.size()); - assertFalse(values.contains(1)); - assertFalse(values.contains(6)); - assertTrue(values.isEmpty()); - assertEquals(multimap.get("foo"), values); - assertEquals(multimap.get("foo").hashCode(), values.hashCode()); - assertEquals(multimap.get("foo").toString(), values.toString()); - - multimap.put("foo", 5); - - /* Verify that values includes effect of put. */ - assertEquals(1, values.size()); - assertFalse(values.contains(1)); - assertTrue(values.contains(5)); - assertFalse(values.contains(6)); - assertEquals(5, values.iterator().next().intValue()); - assertFalse(values.isEmpty()); - assertEquals(multimap.get("foo"), values); - assertEquals(multimap.get("foo").hashCode(), values.hashCode()); - assertEquals(multimap.get("foo").toString(), values.toString()); - - try { - iterator.hasNext(); - } catch (ConcurrentModificationException expected) {} - } - - public void testModifyCollectionFromGet() { - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("bar", 4); - Collection<Integer> values = multimap.get("foo"); - - assertTrue(values.add(5)); - assertSize(4); - assertEquals(3, multimap.get("foo").size()); - assertTrue(multimap.containsEntry("foo", 5)); - - values.clear(); - assertSize(1); - assertFalse(multimap.containsKey("foo")); - - assertTrue(values.addAll(asList(7, 9))); - assertSize(3); - assertEquals(2, multimap.get("foo").size()); - assertTrue(multimap.containsEntry("foo", 7)); - assertTrue(multimap.containsEntry("foo", 9)); - assertFalse(values.addAll(Collections.<Integer>emptyList())); - assertSize(3); - - assertTrue(values.remove(7)); - assertSize(2); - assertEquals(1, multimap.get("foo").size()); - assertFalse(multimap.containsEntry("foo", 7)); - assertTrue(multimap.containsEntry("foo", 9)); - assertFalse(values.remove(77)); - assertSize(2); - - assertTrue(values.add(11)); - assertTrue(values.add(13)); - assertTrue(values.add(15)); - assertTrue(values.add(17)); - - assertTrue(values.removeAll(asList(11, 15))); - assertSize(4); - assertThat(multimap.get("foo")).has().allOf(9, 13, 17); - assertFalse(values.removeAll(asList(21, 25))); - assertSize(4); - - assertTrue(values.retainAll(asList(13, 17, 19))); - assertSize(3); - assertThat(multimap.get("foo")).has().allOf(13, 17); - assertFalse(values.retainAll(asList(13, 17, 19))); - assertSize(3); - - values.remove(13); - values.remove(17); - assertTrue(multimap.get("foo").isEmpty()); - assertSize(1); - assertFalse(multimap.containsKey("foo")); - } - - public void testGetIterator() { - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("foo", 5); - multimap.put("bar", 4); - Collection<Integer> values = multimap.get("foo"); - - Iterator<Integer> iterator = values.iterator(); - assertTrue(iterator.hasNext()); - Integer v1 = iterator.next(); - assertTrue(iterator.hasNext()); - Integer v2 = iterator.next(); - iterator.remove(); - assertTrue(iterator.hasNext()); - Integer v3 = iterator.next(); - assertFalse(iterator.hasNext()); - - assertThat(asList(v1, v2, v3)).has().allOf(1, 3, 5); - assertSize(3); - assertTrue(multimap.containsEntry("foo", v1)); - assertFalse(multimap.containsEntry("foo", v2)); - assertTrue(multimap.containsEntry("foo", v3)); - - iterator = values.iterator(); - assertTrue(iterator.hasNext()); - Integer n1 = iterator.next(); - iterator.remove(); - assertTrue(iterator.hasNext()); - Integer n3 = iterator.next(); - iterator.remove(); - assertFalse(iterator.hasNext()); - - assertThat(asList(n1, n3)).has().allOf(v1, v3); - assertSize(1); - assertFalse(multimap.containsKey("foo")); - } - - public void testGetClear() { - multimap.put("foo", 1); - multimap.put("bar", 3); - Collection<Integer> values = multimap.get("foo"); - multimap.clear(); - assertTrue(values.isEmpty()); - } - - public void testGetPutAllCollection() { - Collection<Integer> values = multimap.get("foo"); - Collection<Integer> collection = Lists.newArrayList(1, 3); - multimap.putAll("foo", collection); - assertThat(values).has().allOf(1, 3); - } - - public void testGetPutAllMultimap() { - multimap.put("foo", 2); - multimap.put("cow", 5); - multimap.put(nullKey(), 2); - Collection<Integer> valuesFoo = multimap.get("foo"); - Collection<Integer> valuesBar = multimap.get("bar"); - Collection<Integer> valuesCow = multimap.get("cow"); - Collection<Integer> valuesNull = multimap.get(nullKey()); - Multimap<String, Integer> multimap2 = create(); - multimap2.put("foo", 1); - multimap2.put("bar", 3); - multimap2.put(nullKey(), nullValue()); - multimap.putAll(multimap2); - - assertThat(valuesFoo).has().allOf(1, 2); - assertThat(valuesBar).has().item(3); - assertThat(valuesCow).has().item(5); - assertThat(valuesNull).has().allOf(nullValue(), 2); - } - - public void testGetRemove() { - multimap.put("foo", 1); - multimap.put("foo", 3); - Collection<Integer> values = multimap.get("foo"); - multimap.remove("foo", 1); - assertThat(values).has().item(3); - } - - public void testGetRemoveAll() { - multimap.put("foo", 1); - multimap.put("foo", 3); - Collection<Integer> values = multimap.get("foo"); - multimap.removeAll("foo"); - assertTrue(values.isEmpty()); - } - - public void testGetReplaceValues() { - multimap.put("foo", 1); - multimap.put("foo", 3); - Collection<Integer> values = multimap.get("foo"); - multimap.replaceValues("foo", asList(1, 5)); - assertThat(values).has().allOf(1, 5); - - multimap.replaceValues("foo", new ArrayList<Integer>()); - assertTrue(multimap.isEmpty()); - assertSize(0); - assertTrue(values.isEmpty()); - } - - public void testEntriesUpdate() { - multimap.put("foo", 1); - Collection<Entry<String, Integer>> entries = multimap.entries(); - Iterator<Entry<String, Integer>> iterator = entries.iterator(); - - assertTrue(iterator.hasNext()); - Entry<String, Integer> entry = iterator.next(); - assertEquals("foo", entry.getKey()); - assertEquals(1, entry.getValue().intValue()); - iterator.remove(); - assertFalse(iterator.hasNext()); - assertTrue(multimap.isEmpty()); - assertSize(0); - - try { - entries.add(Maps.immutableEntry("bar", 2)); - fail("UnsupportedOperationException expected"); - } catch (UnsupportedOperationException expected) {} - assertSize(0); - assertFalse(multimap.containsEntry("bar", 2)); - - multimap.put("bar", 2); - assertSize(1); - assertTrue(entries.contains(Maps.immutableEntry("bar", 2))); - - entries.clear(); - assertTrue(multimap.isEmpty()); - assertSize(0); - } - - public void testEntriesRemove() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Collection<Entry<String, Integer>> entries = multimap.entries(); - - assertTrue(entries.remove(Maps.immutableEntry("foo", nullValue()))); - assertSize(2); - assertFalse(multimap.containsEntry("foo", nullValue())); - - assertFalse(entries.remove(Maps.immutableEntry("foo", 3))); - assertFalse(entries.remove(3.5)); - assertSize(2); - } - - @SuppressWarnings("unchecked") - public void testEntriesRemoveAll() { - multimap.put("foo", 1); - multimap.put("foo", 2); - multimap.put("bar", 3); - - assertFalse(multimap.entries().removeAll( - Collections.singleton(Maps.immutableEntry("foo", 3)))); - assertSize(3); - - assertTrue(multimap.entries().removeAll(asList( - Maps.immutableEntry("foo", 3), Maps.immutableEntry("bar", 3)))); - assertSize(2); - assertFalse(multimap.containsKey("bar")); - } - - public void testEntriesRemoveAllNullFromEmpty() { - try { - multimap.entries().removeAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException expected) {} - } - - @SuppressWarnings("unchecked") - public void testEntriesRetainAll() { - multimap.put("foo", 1); - multimap.put("foo", 2); - multimap.put("bar", 3); - - assertFalse(multimap.entries().retainAll(asList( - Maps.immutableEntry("foo", 1), Maps.immutableEntry("foo", 2), - Maps.immutableEntry("foo", 3), Maps.immutableEntry("bar", 3)))); - assertSize(3); - - assertTrue(multimap.entries().retainAll(asList( - Maps.immutableEntry("foo", 3), Maps.immutableEntry("bar", 3)))); - assertSize(1); - assertTrue(multimap.containsEntry("bar", 3)); - } - - public void testEntriesRetainAllNullFromEmpty() { - try { - multimap.entries().retainAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException expected) {} - } - - public void testEntriesIterator() { - multimap.put("foo", 3); - Iterator<Entry<String, Integer>> iterator - = multimap.entries().iterator(); - assertTrue(iterator.hasNext()); - assertEquals(Maps.immutableEntry("foo", 3), iterator.next()); - iterator.remove(); - assertFalse(iterator.hasNext()); - assertSize(0); - } - - public void testEntriesToString() { - multimap.put("foo", 3); - Collection<Entry<String, Integer>> entries = multimap.entries(); - assertEquals("[foo=3]", entries.toString()); - } - - public void testEntriesToArray() { - multimap.put("foo", 3); - Collection<Entry<String, Integer>> entries = multimap.entries(); - Entry<?, ?>[] array = new Entry<?, ?>[3]; - assertSame(array, entries.toArray(array)); - assertEquals(Maps.immutableEntry("foo", 3), array[0]); - assertNull(array[1]); - } - - /** - * Test calling setValue() on an entry returned by multimap.entries(). - */ - public void testEntrySetValue() { - multimap.put("foo", 1); - multimap.put("bar", 1); - Collection<Entry<String, Integer>> entries = multimap.entries(); - Iterator<Entry<String, Integer>> iterator = entries.iterator(); - Entry<String, Integer> entrya = iterator.next(); - Entry<String, Integer> entryb = iterator.next(); - try { - entrya.setValue(3); - fail(); - } catch (UnsupportedOperationException expected) {} - assertTrue(multimap.containsEntry("foo", 1)); - assertTrue(multimap.containsEntry("bar", 1)); - assertFalse(multimap.containsEntry("foo", 2)); - assertFalse(multimap.containsEntry("bar", 2)); - assertEquals(1, (int) entrya.getValue()); - assertEquals(1, (int) entryb.getValue()); - } - - /** Verify that the entries remain valid after iterating past them. */ - public void testEntriesCopy() { - multimap.put("foo", 1); - multimap.put("foo", 2); - multimap.put("bar", 3); - - Set<Entry<String, Integer>> copy = Sets.newHashSet(multimap.entries()); - assertEquals(3, copy.size()); - assertTrue(copy.contains(Maps.immutableEntry("foo", 1))); - assertTrue(copy.contains(Maps.immutableEntry("foo", 2))); - assertTrue(copy.contains(Maps.immutableEntry("bar", 3))); - assertFalse(copy.contains(Maps.immutableEntry("bar", 1))); - - multimap.removeAll("foo"); - assertEquals(3, copy.size()); - assertTrue(copy.contains(Maps.immutableEntry("foo", 1))); - assertTrue(copy.contains(Maps.immutableEntry("foo", 2))); - assertTrue(copy.contains(Maps.immutableEntry("bar", 3))); - assertFalse(copy.contains(Maps.immutableEntry("bar", 1))); - } - - public void testKeySetRemove() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Set<String> keys = multimap.keySet(); - assertTrue(keys.remove("foo")); - assertFalse(keys.remove("bar")); - assertSize(1); - assertFalse(multimap.containsKey("foo")); - assertTrue(multimap.containsEntry(nullKey(), 3)); - } - - public void testKeySetRemoveAllNullFromEmpty() { - try { - multimap.keySet().removeAll(null); - fail(); - } catch (NullPointerException expected) {} - } - - public void testKeySetRetainAllNullFromEmpty() { - try { - multimap.keySet().retainAll(null); - // Returning successfully is not ideal, but tolerated. - } catch (NullPointerException expected) {} - } - - public void testKeySetIterator() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - - Iterator<String> iterator = multimap.keySet().iterator(); - while (iterator.hasNext()) { - String key = iterator.next(); - if ("foo".equals(key)) { - iterator.remove(); - } - } - assertSize(1); - assertFalse(multimap.containsKey("foo")); - assertTrue(multimap.containsEntry(nullKey(), 3)); - - iterator = multimap.keySet().iterator(); - assertEquals(nullKey(), iterator.next()); - iterator.remove(); - assertTrue(multimap.isEmpty()); - assertSize(0); - } - - public void testKeySetClear() { - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - - multimap.keySet().clear(); - assertTrue(multimap.isEmpty()); - assertSize(0); - } - - public void testValuesIteratorRemove() { - multimap.put("foo", 1); - multimap.put("foo", 2); - multimap.put(nullKey(), 4); - - Iterator<Integer> iterator = multimap.values().iterator(); - while (iterator.hasNext()) { - int value = iterator.next(); - if ((value % 2) == 0) { - iterator.remove(); - } - } - - assertSize(1); - assertTrue(multimap.containsEntry("foo", 1)); - } - - public void testAsMapEntriesUpdate() { - multimap.put("foo", 1); - multimap.put("foo", 3); - Collection<Entry<String, Collection<Integer>>> entries = - multimap.asMap().entrySet(); - Entry<String, Collection<Integer>> entry = entries.iterator().next(); - Collection<Integer> values = entry.getValue(); - - multimap.put("foo", 5); - assertEquals(3, values.size()); - assertTrue(values.contains(5)); - - values.add(7); - assertSize(4); - assertTrue(multimap.containsValue(7)); - - multimap.put("bar", 4); - assertEquals(2, entries.size()); - assertSize(5); - - assertTrue(entries.remove(entry)); - assertSize(1); - assertFalse(multimap.containsKey("foo")); - assertTrue(multimap.containsKey("bar")); - assertFalse(entries.remove("foo")); - assertFalse(entries.remove( - Maps.immutableEntry("foo", Collections.singleton(2)))); - assertSize(1); - - Iterator<Entry<String, Collection<Integer>>> iterator = - entries.iterator(); - assertTrue(iterator.hasNext()); - iterator.next(); - iterator.remove(); - assertFalse(iterator.hasNext()); - assertSize(0); - assertTrue(multimap.isEmpty()); - - multimap.put("bar", 8); - assertSize(1); - entries.clear(); - assertSize(0); - } - - public void testToStringNull() { - multimap.put("foo", 3); - multimap.put("foo", -1); - multimap.put(nullKey(), nullValue()); - multimap.put("bar", 1); - multimap.put("foo", 2); - multimap.put(nullKey(), 0); - multimap.put("bar", 2); - multimap.put("bar", nullValue()); - multimap.put("foo", nullValue()); - multimap.put("foo", 4); - multimap.put(nullKey(), -1); - multimap.put("bar", 3); - multimap.put("bar", 1); - multimap.put("foo", 1); - - // This test is brittle. The original test was meant to validate the - // contents of the string itself, but key and value ordering tend - // to change under unpredictable circumstances. Instead, we're just ensuring - // that the string not return null and, implicitly, not throw an exception. - assertNotNull(multimap.toString()); - } - - @GwtIncompatible("SerializableTester") - public void testSerializable() { - multimap = createSample(); - assertEquals(multimap, SerializableTester.reserialize(multimap)); - } - - public void testEmptyToString() { - Multimap<String, Integer> map = create(); - assertEquals("{}", map.toString()); - assertEquals("[]", map.entries().toString()); - } - - public void testEmptyGetToString() { - Multimap<String, Integer> map = create(); - map.get("foo"); // shouldn't have any side-effect - assertEquals("{}", map.toString()); - assertEquals("[]", map.entries().toString()); - } - - public void testGetRemoveToString() { - Multimap<String, Integer> map = create(); - map.put("bar", 1); - map.put("foo", 2); - map.put("bar", 3); - map.get("foo").remove(2); - map.get("bar").remove(1); - assertEquals("{bar=[3]}", map.toString()); - assertEquals("[bar=3]", map.entries().toString()); - } - - public void testRemoveToString() { - Multimap<String, Integer> map = create(); - map.put("foo", 1); - map.put("foo", 2); - map.remove("foo", 1); - assertEquals("[foo=2]", map.entries().toString()); - } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } - - // Hack for JDK5 type inference. - private static <T> ListSubject<? extends ListSubject<?, T, List<T>>, T, List<T>> assertThat( - T[] collection) { - return ASSERT.<T, List<T>>that(collection); - } -} diff --git a/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java b/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java deleted file mode 100644 index 3ca8175..0000000 --- a/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static java.util.Arrays.asList; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; -import com.google.common.collect.Multiset.Entry; -import com.google.common.collect.testing.google.UnmodifiableCollectionTests; -import com.google.common.testing.SerializableTester; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Set; - -/** - * Common tests for a {@link Multiset}. - * - * @author Kevin Bourrillion - */ -@GwtCompatible(emulated = true) -public abstract class AbstractMultisetTest extends AbstractCollectionTest { - - @Override protected abstract <E> Multiset<E> create(); - - protected Multiset<String> ms; - - // public for GWT - @Override public void setUp() throws Exception { - super.setUp(); - c = ms = create(); - } - - /** - * Validates that multiset size returned by {@code size()} is the same as the - * size generated by summing the counts of all multiset entries. - */ - protected void assertSize(Multiset<String> multiset) { - long size = 0; - for (Multiset.Entry<String> entry : multiset.entrySet()) { - size += entry.getCount(); - } - assertEquals((int) Math.min(size, Integer.MAX_VALUE), multiset.size()); - } - - protected void assertSize() { - assertSize(ms); - } - - @Override protected void assertContents(String... expected) { - super.assertContents(expected); - assertSize(); - } - - public void testCountZero() { - assertEquals(0, ms.count("a")); - assertSize(); - } - - public void testCountOne() { - ms.add("a"); - assertEquals(1, ms.count("a")); - assertSize(); - } - - public void testCountTwo() { - ms.add("a"); - ms.add("a"); - assertEquals(2, ms.count("a")); - assertSize(); - } - - public void testCountAfterRemoval() { - ms.add("a"); - ms.remove("a"); - assertEquals(0, ms.count("a")); - assertSize(); - } - - public void testCountNull() { - assertEquals(0, ms.count(null)); - } - - public void testCountWrongType() { - assertEquals(0, ms.count(new WrongType())); - } - - static class WrongType {} - - public void testAddNoneToNone() { - assertEquals(0, ms.add("a", 0)); - assertContents(); - } - - public void testAddNoneToSome() { - ms.add("a"); - assertEquals(1, ms.add("a", 0)); - assertContents("a"); - } - - public void testAddSeveralAtOnce() { - assertEquals(0, ms.add("a", 3)); - assertContents("a", "a", "a"); - } - - public void testAddSomeToSome() { - ms.add("a", 2); - assertEquals(2, ms.add("a", 3)); - assertContents("a", "a", "a", "a", "a"); - } - - @Override public void testAddSeveralTimes() { - assertTrue(ms.add("a")); - assertTrue(ms.add("b")); - assertTrue(ms.add("a")); - assertTrue(ms.add("b")); - assertContents("a", "b", "a", "b"); - } - - public void testAddNegative() { - try { - ms.add("a", -1); - fail(); - } catch (IllegalArgumentException expected) { - } - assertSize(); - } - - @Override public void testEqualsNo() { - ms.add("a"); - ms.add("b"); - ms.add("b"); - - Multiset<String> ms2 = create(); - ms2.add("a", 2); - ms2.add("b"); - - assertFalse(ms.equals(ms2)); - assertSize(); - } - - public void testAddTooMany() { - ms.add("a", Integer.MAX_VALUE); // so far so good - ms.add("b", Integer.MAX_VALUE); // so far so good - try { - ms.add("a"); - fail(); - } catch (IllegalArgumentException expected) { - } - assertSize(); - } - - public void testAddAllEmptySet() { - c = ms = createSample(); - assertFalse(ms.addAll(Collections.<String>emptySet())); - assertEquals(createSample(), ms); - assertSize(); - } - - public void testAddAllEmptyMultiset() { - c = ms = createSample(); - Multiset<String> empty = create(); - assertFalse(ms.addAll(empty)); - assertEquals(createSample(), ms); - assertSize(); - } - - public void testAddAllSet() { - c = ms = createSample(); - Set<String> more = ImmutableSet.of("c", "d", "e"); - assertTrue(ms.addAll(more)); - assertContents("a", "b", "b", "c", "c", "d", "d", "d", "d", "e"); - } - - public void testAddAllMultiset() { - c = ms = createSample(); - Multiset<String> more = HashMultiset.create( - asList("c", "c", "d", "d", "e")); - assertTrue(ms.addAll(more)); - assertContents("a", "b", "b", "c", "c", "c", "d", "d", "d", "d", "d", "e"); - } - - public void testRemoveNoneFromNone() { - assertEquals(0, ms.remove("a", 0)); - assertContents(); - } - - public void testRemoveNoneFromSome() { - ms.add("a"); - assertEquals(1, ms.remove("a", 0)); - assertContents("a"); - } - - public void testRemoveOneFromNone() { - assertEquals(0, ms.remove("a", 1)); - assertContents(); - } - - public void testRemoveOneFromOne() { - ms.add("a"); - assertEquals(1, ms.remove("a", 1)); - assertContents(); - } - - public void testRemoveSomeFromSome() { - ms.add("a", 5); - assertEquals(5, ms.remove("a", 3)); - assertContents("a", "a"); - } - - public void testRemoveTooMany() { - ms.add("a", 3); - assertEquals(3, ms.remove("a", 5)); - assertContents(); - } - - public void testRemoveNegative() { - try { - ms.remove("a", -1); - fail(); - } catch (IllegalArgumentException expected) { - } - assertSize(); - } - - public void testContainsSeveral() { - ms.add("a", 3); - assertTrue(ms.contains(new String("a"))); - assertSize(); - } - - public void testContainsAllNo() { - ms.add("a", 2); - ms.add("b", 3); - assertFalse(ms.containsAll(asList("a", "c"))); - assertSize(); - } - - public void testContainsAllYes() { - ms.add("a", 2); - ms.add("b", 3); - ms.add("c", 4); - assertTrue(ms.containsAll(asList("a", "c"))); - assertSize(); - } - - public void testRemoveAllOfOne() { - ms.add("a", 2); - ms.add("b"); - assertTrue(ms.removeAll(asList("a", "c"))); - assertContents("b"); - } - - public void testRemoveAllOfDisjoint() { - ms.add("a", 2); - ms.add("b"); - assertFalse(ms.removeAll(asList("c", "d"))); - assertContents("a", "a", "b"); - } - - public void testRemoveAllOfEverything() { - ms.add("a", 2); - ms.add("b"); - assertTrue(ms.removeAll(asList("a", "b"))); - assertContents(); - } - - public void testRetainAllOfOne() { - ms.add("a", 2); - ms.add("b"); - assertTrue(ms.retainAll(asList("a", "c"))); - assertContents("a", "a"); - } - - public void testRetainAllOfDisjoint() { - ms.add("a", 2); - ms.add("b"); - assertTrue(ms.retainAll(asList("c", "d"))); - assertContents(); - } - - public void testRetainAllOfEverything() { - ms.add("a", 2); - ms.add("b"); - assertFalse(ms.retainAll(asList("a", "b"))); - assertContents("a", "a", "b"); - } - - public void testContainsAllVacuousViaElementSet() { - assertTrue(ms.elementSet().containsAll(Collections.emptySet())); - } - - public void testContainsAllNoViaElementSet() { - ms.add("a", 2); - ms.add("b", 3); - assertFalse(ms.elementSet().containsAll(asList("a", "c"))); - assertSize(); - } - - public void testContainsAllYesViaElementSet() { - ms.add("a", 2); - ms.add("b", 3); - ms.add("c", 4); - assertTrue(ms.elementSet().containsAll(asList("a", "c"))); - assertSize(); - } - - public void testRemoveAllVacuousViaElementSet() { - assertFalse(ms.elementSet().removeAll(Collections.emptySet())); - assertSize(); - } - - public void testRemoveAllOfOneViaElementSet() { - ms.add("a", 2); - ms.add("b"); - assertTrue(ms.elementSet().removeAll(asList("a", "c"))); - assertContents("b"); - } - - public void testRemoveAllOfDisjointViaElementSet() { - ms.add("a", 2); - ms.add("b"); - assertFalse(ms.elementSet().removeAll(asList("c", "d"))); - assertContents("a", "a", "b"); - } - - public void testRemoveAllOfEverythingViaElementSet() { - ms.add("a", 2); - ms.add("b"); - assertTrue(ms.elementSet().removeAll(asList("a", "b"))); - assertContents(); - } - - public void testRetainAllVacuousViaElementSet() { - assertFalse(ms.elementSet().retainAll(asList("a"))); - assertContents(); - } - - public void testRetainAllOfNothingViaElementSet() { - ms.add("a"); - assertTrue(ms.elementSet().retainAll(Collections.emptySet())); - assertContents(); - } - - public void testRetainAllOfOneViaElementSet() { - ms.add("a", 2); - ms.add("b"); - assertTrue(ms.elementSet().retainAll(asList("a", "c"))); - assertContents("a", "a"); - } - - public void testRetainAllOfDisjointViaElementSet() { - ms.add("a", 2); - ms.add("b"); - assertTrue(ms.elementSet().retainAll(asList("c", "d"))); - assertContents(); - } - - public void testRetainAllOfEverythingViaElementSet() { - ms.add("a", 2); - ms.add("b"); - assertFalse(ms.elementSet().retainAll(asList("a", "b"))); - assertContents("a", "a", "b"); - } - - public void testElementSetBasic() { - ms.add("a", 3); - ms.add("b", 2); - ms.add("c", 1); - HashSet<String> expected = Sets.newHashSet("a", "b", "c"); - Set<String> actual = ms.elementSet(); - assertEquals(expected, actual); - assertEquals(actual, expected); - assertSize(); - } - - public void testElementSetIsNotACopy() { - ms.add("a", 1); - ms.add("b", 2); - Set<String> elementSet = ms.elementSet(); - ms.add("c", 3); - ms.setCount("b", 0); - assertEquals(Sets.newHashSet("a", "c"), elementSet); - assertSize(); - } - - public void testRemoveFromElementSetYes() { - ms.add("a", 1); - ms.add("b", 2); - Set<String> elementSet = ms.elementSet(); - assertTrue(elementSet.remove("b")); - assertContents("a"); - } - - public void testRemoveFromElementSetNo() { - ms.add("a", 1); - Set<String> elementSet = ms.elementSet(); - assertFalse(elementSet.remove("b")); - assertContents("a"); - } - - public void testRemoveFromElementSetNull() { - assertEquals(false, ms.elementSet().remove(null)); - } - - public void testRemoveFromElementSetWrongType() { - assertEquals(false, ms.elementSet().remove(new WrongType())); - } - - public void testCantAddToElementSet() { - try { - ms.elementSet().add("a"); - fail(); - } catch (UnsupportedOperationException expected) { - } - assertSize(); - } - - public void testClearViaElementSet() { - ms = createSample(); - ms.elementSet().clear(); - assertContents(); - } - - public void testClearViaEntrySet() { - ms = createSample(); - ms.entrySet().clear(); - assertContents(); - } - - public void testEntrySet() { - ms = createSample(); - for (Multiset.Entry<String> entry : ms.entrySet()) { - assertEquals(entry, entry); - String element = entry.getElement(); - if (element.equals("a")) { - assertEquals(1, entry.getCount()); - } else if (element.equals("b")) { - assertEquals(2, entry.getCount()); - } else if (element.equals("c")) { - assertEquals(1, entry.getCount()); - } else if (element.equals("d")) { - assertEquals(3, entry.getCount()); - } else { - fail(); - } - } - assertSize(); - } - - public void testEntrySetEmpty() { - assertEquals(Collections.emptySet(), ms.entrySet()); - } - - public void testReallyBig() { - ms.add("a", Integer.MAX_VALUE - 1); - assertEquals(Integer.MAX_VALUE - 1, ms.size()); - ms.add("b", 3); - - // See Collection.size() contract - assertEquals(Integer.MAX_VALUE, ms.size()); - - // Make sure we didn't forget our size - ms.remove("a", 4); - assertEquals(Integer.MAX_VALUE - 2, ms.size()); - assertSize(); - } - - public void testToStringNull() { - ms.add("a", 3); - ms.add("c", 1); - ms.add("b", 2); - ms.add(null, 4); - - // This test is brittle. The original test was meant to validate the - // contents of the string itself, but key ordering tended to change - // under unpredictable circumstances. Instead, we're just ensuring - // that the string not return null, and implicitly, not throw an exception. - assertNotNull(ms.toString()); - assertSize(); - } - - @GwtIncompatible("SerializableTester") - public void testSerializable() { - ms = createSample(); - assertEquals(ms, SerializableTester.reserialize(ms)); - assertSize(); - } - - public void testIteratorRemove() { - ms.add("a"); - ms.add("b"); - ms.add("c"); - Iterator<String> iterator = ms.iterator(); - String element1 = iterator.next(); - iterator.remove(); - String element2 = iterator.next(); - assertFalse(ms.contains(element1)); - assertTrue(ms.contains(element2)); - assertSize(); - } - - public void testIteratorRemoveRepeated() { - ms.add("a", 3); - ms.add("b", 1); - ms.add("c", 2); - Iterator<String> iterator = ms.iterator(); - for (int i = 0; i < 6; i++) { - assertTrue(iterator.hasNext()); - iterator.next(); - iterator.remove(); - } - assertFalse(iterator.hasNext()); - assertTrue(ms.isEmpty()); - assertSize(); - } - - public void testIteratorRemoveTooSoon() { - ms.add("a"); - ms.add("b"); - ms.add("c"); - Iterator<String> iterator = ms.iterator(); - try { - iterator.remove(); - fail(); - } catch (IllegalStateException expected) {} - assertSize(); - } - - public void testIteratorRemoveTwiceConsecutive() { - ms.add("a"); - ms.add("b"); - ms.add("c"); - Iterator<String> iterator = ms.iterator(); - iterator.next(); - iterator.remove(); - try { - iterator.remove(); - fail(); - } catch (IllegalStateException expected) {} - assertSize(); - } - - public void testIteratorNoSuchElementException() { - ms.add("a"); - ms.add("b"); - ms.add("c"); - Iterator<String> iterator = ms.iterator(); - iterator.next(); - iterator.next(); - iterator.next(); - try { - iterator.next(); - fail(); - } catch (NoSuchElementException expected) {} - assertSize(); - } - - public void testEntryAfterRemove() { - ms.add("a", 8); - Multiset.Entry<String> entry = ms.entrySet().iterator().next(); - assertEquals(8, entry.getCount()); - ms.remove("a"); - assertEquals(7, entry.getCount()); - ms.remove("a", 4); - assertEquals(3, entry.getCount()); - ms.elementSet().remove("a"); - assertEquals(0, entry.getCount()); - ms.add("a", 5); - assertEquals(5, entry.getCount()); - } - - public void testEntryAfterClear() { - ms.add("a", 3); - Multiset.Entry<String> entry = ms.entrySet().iterator().next(); - ms.clear(); - assertEquals(0, entry.getCount()); - ms.add("a", 5); - assertEquals(5, entry.getCount()); - } - - public void testEntryAfterEntrySetClear() { - ms.add("a", 3); - Multiset.Entry<String> entry = ms.entrySet().iterator().next(); - ms.entrySet().clear(); - assertEquals(0, entry.getCount()); - ms.add("a", 5); - assertEquals(5, entry.getCount()); - } - - public void testEntryAfterEntrySetIteratorRemove() { - ms.add("a", 3); - Iterator<Multiset.Entry<String>> iterator = ms.entrySet().iterator(); - Multiset.Entry<String> entry = iterator.next(); - iterator.remove(); - assertEquals(0, entry.getCount()); - try { - iterator.remove(); - fail(); - } catch (IllegalStateException expected) {} - ms.add("a", 5); - assertEquals(5, entry.getCount()); - } - - public void testEntryAfterElementSetIteratorRemove() { - ms.add("a", 3); - Multiset.Entry<String> entry = ms.entrySet().iterator().next(); - Iterator<String> iterator = ms.elementSet().iterator(); - iterator.next(); - iterator.remove(); - assertEquals(0, entry.getCount()); - ms.add("a", 5); - assertEquals(5, entry.getCount()); - } - - public void testEntrySetContains() { - ms.add("a", 3); - Set<Entry<String>> es = ms.entrySet(); - assertTrue(es.contains(Multisets.immutableEntry("a", 3))); - assertFalse(es.contains(null)); - assertFalse(es.contains(Maps.immutableEntry("a", 3))); - assertFalse(es.contains(Multisets.immutableEntry("a", 2))); - assertFalse(es.contains(Multisets.immutableEntry("b", 3))); - assertFalse(es.contains(Multisets.immutableEntry("b", 0))); - } - - public void testEntrySetRemove() { - ms.add("a", 3); - Set<Entry<String>> es = ms.entrySet(); - assertFalse(es.remove(null)); - assertFalse(es.remove(Maps.immutableEntry("a", 3))); - assertFalse(es.remove(Multisets.immutableEntry("a", 2))); - assertFalse(es.remove(Multisets.immutableEntry("b", 3))); - assertFalse(es.remove(Multisets.immutableEntry("b", 0))); - assertEquals(3, ms.count("a")); - assertTrue(es.remove(Multisets.immutableEntry("a", 3))); - assertEquals(0, ms.count("a")); - } - - public void testEntrySetToArray() { - ms.add("a", 3); - Set<Multiset.Entry<String>> es = ms.entrySet(); - Entry<?>[] array = new Entry<?>[3]; - assertSame(array, es.toArray(array)); - assertEquals(Multisets.immutableEntry("a", 3), array[0]); - assertNull(array[1]); - } - - public void testUnmodifiableMultiset() { - ms.add("a", 3); - ms.add("b"); - ms.add("c", 2); - Multiset<Object> unmodifiable = Multisets.<Object>unmodifiableMultiset(ms); - UnmodifiableCollectionTests.assertMultisetIsUnmodifiable(unmodifiable, "a"); - } - - @Override protected Multiset<String> createSample() { - Multiset<String> ms = create(); - ms.add("a", 1); - ms.add("b", 2); - ms.add("c", 1); - ms.add("d", 3); - return ms; - } -} diff --git a/guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java b/guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java index f12c498..803ea5a 100644 --- a/guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java +++ b/guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java @@ -23,12 +23,12 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.IteratorTester; -import java.util.Iterator; -import java.util.NoSuchElementException; - import junit.framework.AssertionFailedError; import junit.framework.TestCase; +import java.util.Iterator; +import java.util.NoSuchElementException; + /** Tests for {@link AbstractSequentialIterator}. */ @GwtCompatible(emulated = true) public class AbstractSequentialIteratorTest extends TestCase { @@ -50,7 +50,7 @@ public class AbstractSequentialIteratorTest extends TestCase { return newDoubler(2, 32); } }; - ASSERT.<Integer, Iterable<Integer>>that(doubled).iteratesOverSequence(2, 4, 8, 16, 32); + ASSERT.that(doubled).iteratesOverSequence(2, 4, 8, 16, 32); } public void testSampleCode() { @@ -58,7 +58,6 @@ public class AbstractSequentialIteratorTest extends TestCase { @Override public Iterator<Integer> iterator() { Iterator<Integer> powersOfTwo = new AbstractSequentialIterator<Integer>(1) { - @Override protected Integer computeNext(Integer previous) { return (previous == 1 << 30) ? null : previous * 2; } @@ -66,10 +65,9 @@ public class AbstractSequentialIteratorTest extends TestCase { return powersOfTwo; } }; - ASSERT.<Integer, Iterable<Integer>>that(actual).iteratesOverSequence(1, 2, 4, 8, 16, 32, 64, - 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, - 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, - 536870912, 1073741824); + ASSERT.that(actual).iteratesOverSequence(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, + 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, + 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824); } public void testEmpty() { @@ -78,11 +76,13 @@ public class AbstractSequentialIteratorTest extends TestCase { try { empty.next(); fail(); - } catch (NoSuchElementException expected) {} + } catch (NoSuchElementException expected) { + } try { empty.remove(); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } } public void testBroken() { @@ -92,11 +92,13 @@ public class AbstractSequentialIteratorTest extends TestCase { try { broken.next(); fail(); - } catch (MyException expected) {} + } catch (MyException expected) { + } try { broken.next(); fail(); - } catch (MyException expected) {} + } catch (MyException expected) { + } } private static Iterator<Integer> newDoubler(int first, final int last) { diff --git a/guava-tests/test/com/google/common/collect/AbstractSetMultimapTest.java b/guava-tests/test/com/google/common/collect/AbstractSetMultimapTest.java deleted file mode 100644 index e2593a2..0000000 --- a/guava-tests/test/com/google/common/collect/AbstractSetMultimapTest.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static java.util.Arrays.asList; - -import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -/** - * Tests for {@code SetMultimap} implementations. - * - * @author Jared Levy - */ -@GwtCompatible -public abstract class AbstractSetMultimapTest extends AbstractMultimapTest { - - public void testDuplicates() { - Multimap<String, Integer> multimap = getMultimap(); - assertTrue(multimap.put("foo", 1)); - assertTrue(multimap.put("foo", 3)); - assertTrue(multimap.put("bar", 3)); - assertFalse(multimap.put("foo", 1)); - assertSize(3); - assertTrue(multimap.containsEntry("foo", 1)); - assertTrue(multimap.remove("foo", 1)); - assertSize(2); - assertFalse(multimap.containsEntry("foo", 1)); - } - - public void testGetEquals() { - Multimap<String, Integer> multimap = getMultimap(); - multimap.put("foo", 1); - multimap.put("foo", 3); - assertEquals(ImmutableSet.of(1, 3), multimap.get("foo")); - } - - public void testAsMapEquals() { - Multimap<String, Integer> multimap = getMultimap(); - multimap.put("foo", 1); - multimap.put("foo", nullValue()); - multimap.put(nullKey(), 3); - Map<String, Collection<Integer>> map = multimap.asMap(); - - Map<String, Collection<Integer>> equalMap = Maps.newHashMap(); - equalMap.put("foo", Sets.newHashSet(1, nullValue())); - equalMap.put(nullKey(), Sets.newHashSet(3)); - assertEquals(map, equalMap); - assertEquals(equalMap, map); - assertEquals(equalMap.hashCode(), multimap.hashCode()); - - Map<String, Collection<Integer>> unequalMap = Maps.newHashMap(); - equalMap.put("foo", Sets.newHashSet(3, nullValue())); - equalMap.put(nullKey(), Sets.newHashSet(1)); - assertFalse(map.equals(unequalMap)); - assertFalse(unequalMap.equals(map)); - } - - public void testAsMapEntriesEquals() { - Multimap<String, Integer> multimap = getMultimap(); - multimap.put("foo", 1); - multimap.put("foo", 3); - Set<Map.Entry<String, Collection<Integer>>> set - = multimap.asMap().entrySet(); - - Iterator<Map.Entry<String, Collection<Integer>>> i = set.iterator(); - Map.Entry<String, Collection<Integer>> expected = - Maps.immutableEntry( - "foo", (Collection<Integer>) ImmutableSet.of(1, 3)); - Map.Entry<String, Collection<Integer>> entry = i.next(); - assertEquals(expected, entry); - assertFalse(i.hasNext()); - - assertTrue(Collections.singleton(expected).equals(set)); - assertTrue(set.equals(Collections.singleton(expected))); - - Map.Entry<?, ?>[] array = new Map.Entry<?, ?>[3]; - array[1] = Maps.immutableEntry("another", "entry"); - assertSame(array, set.toArray(array)); - assertEquals(entry, array[0]); - assertNull(array[1]); - } - - @SuppressWarnings("unchecked") - public void testAsMapValues() { - Multimap<String, Integer> multimap = create(); - Collection<Collection<Integer>> asMapValues = multimap.asMap().values(); - multimap.put("foo", 1); - multimap.put("foo", 3); - - Collection<?>[] array = new Collection<?>[3]; - array[1] = Collections.emptyList(); - assertSame(array, asMapValues.toArray(array)); - assertEquals(Sets.newHashSet(1, 3), array[0]); - assertNull(array[1]); - - multimap.put("bar", 3); - assertTrue(asMapValues.containsAll( - asList(Sets.newHashSet(1, 3), Sets.newHashSet(3)))); - assertFalse(asMapValues.containsAll( - asList(Sets.newHashSet(1, 3), Sets.newHashSet(1)))); - assertFalse(asMapValues.remove(ImmutableSet.of(1, 2))); - assertEquals(3, multimap.size()); - assertTrue(asMapValues.remove(ImmutableSet.of(1, 3))); - assertEquals(1, multimap.size()); - } - - public void testPutReturn() { - Multimap<String, Integer> multimap = getMultimap(); - assertTrue(multimap.put("foo", 1)); - assertFalse(multimap.put("foo", 1)); - assertTrue(multimap.put("foo", 3)); - assertTrue(multimap.put("bar", 5)); - } - - public void testPutAllReturn_existingElements() { - Multimap<String, Integer> multimap = create(); - assertTrue(multimap.putAll("foo", asList(1, 2, 3))); - assertFalse(multimap.put("foo", 1)); - assertFalse(multimap.putAll("foo", asList(1, 2, 3))); - assertFalse(multimap.putAll("foo", asList(1, 3))); - assertTrue(multimap.putAll("foo", asList(1, 2, 4))); - - Multimap<String, Integer> other = create(); - other.putAll("foo", asList(1, 2)); - assertFalse(multimap.putAll(other)); - - other.putAll("bar", asList(1, 2)); - assertTrue(multimap.putAll(other)); - assertTrue(other.putAll(multimap)); - assertTrue(other.equals(multimap)); - } - - @SuppressWarnings("unchecked") - public void testEntriesEquals() { - Multimap<String, Integer> multimap = getMultimap(); - multimap.put("foo", 1); - multimap.put("foo", 3); - multimap.put("bar", 3); - Collection<Map.Entry<String, Integer>> entries = multimap.entries(); - - Set<Map.Entry<String, Integer>> same = Sets.newHashSet( - Maps.immutableEntry("foo", 3), - Maps.immutableEntry("bar", 3), - Maps.immutableEntry("foo", 1)); - assertEquals(entries, same); - assertEquals(same, entries); - assertEquals(entries.hashCode(), same.hashCode()); - - assertFalse(entries.equals(null)); - assertFalse(entries.equals("foo")); - - Set<Map.Entry<String, Integer>> different3 = Sets.newHashSet( - Maps.immutableEntry("foo", 3), - Maps.immutableEntry("bar", 3), - Maps.immutableEntry("bar", 1)); - assertFalse(entries.equals(different3)); - assertFalse(different3.equals(entries)); - - Set<Map.Entry<String, Integer>> different4 = Sets.newHashSet( - Maps.immutableEntry("foo", 3), - Maps.immutableEntry("bar", 3), - Maps.immutableEntry("bar", 1), - Maps.immutableEntry("foo", 1)); - assertFalse(entries.equals(different4)); - assertFalse(different4.equals(entries)); - } -} diff --git a/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java b/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java index 943c662..1265e31 100644 --- a/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java +++ b/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java @@ -24,12 +24,8 @@ import com.google.common.base.Objects; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; -import java.util.Collection; - import junit.framework.TestCase; -import org.truth0.subjects.CollectionSubject; - /** * Test cases for {@link Table} read operations. * @@ -187,13 +183,7 @@ public abstract class AbstractTableReadTest extends TestCase { public void testColumnSetPartialOverlap() { table = create( "foo", 1, 'a', "bar", 1, 'b', "foo", 2, 'c', "bar", 3, 'd'); - assertThat(table.columnKeySet()).has().allOf(1, 2, 3); - } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); + ASSERT.that(table.columnKeySet()).has().exactly(1, 2, 3); } @GwtIncompatible("NullPointerTester") diff --git a/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java b/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java index 3d87f84..676e175 100644 --- a/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java @@ -27,24 +27,22 @@ import com.google.common.collect.testing.features.MapFeature; import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringListMultimapGenerator; -import java.util.Collection; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.ConcurrentModificationException; import java.util.List; import java.util.Map.Entry; import java.util.RandomAccess; -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.truth0.subjects.CollectionSubject; - /** * Unit tests for {@code ArrayListMultimap}. * * @author Jared Levy */ @GwtCompatible(emulated = true) -public class ArrayListMultimapTest extends AbstractListMultimapTest { +public class ArrayListMultimapTest extends TestCase { @GwtIncompatible("suite") public static Test suite() { @@ -63,8 +61,10 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionFeature.SERIALIZABLE, CollectionSize.ANY) .createTestSuite()); @@ -72,7 +72,7 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest { return suite; } - @Override protected ListMultimap<String, Integer> create() { + protected ListMultimap<String, Integer> create() { return ArrayListMultimap.create(); } @@ -119,9 +119,9 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest { ListMultimap<String, Integer> multimap = create(); multimap.putAll("foo", asList(1, 2, 3, 4, 5)); List<Integer> list = multimap.get("foo"); - assertThat(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder(); + ASSERT.that(multimap.get("foo")).has().exactly(1, 2, 3, 4, 5).inOrder(); List<Integer> sublist = list.subList(0, 5); - assertThat(sublist).has().allOf(1, 2, 3, 4, 5).inOrder(); + ASSERT.that(sublist).has().exactly(1, 2, 3, 4, 5).inOrder(); sublist.clear(); assertTrue(sublist.isEmpty()); @@ -134,7 +134,10 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest { } public void testCreateFromMultimap() { - Multimap<String, Integer> multimap = createSample(); + Multimap<String, Integer> multimap = create(); + multimap.put("foo", 1); + multimap.put("foo", 3); + multimap.put("bar", 2); ArrayListMultimap<String, Integer> copy = ArrayListMultimap.create(multimap); assertEquals(multimap, copy); @@ -187,13 +190,7 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest { multimap.put("bar", 3); multimap.trimToSize(); assertEquals(3, multimap.size()); - assertThat(multimap.get("foo")).has().allOf(1, 2).inOrder(); - assertThat(multimap.get("bar")).has().item(3); - } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); + ASSERT.that(multimap.get("foo")).has().exactly(1, 2).inOrder(); + ASSERT.that(multimap.get("bar")).has().item(3); } } diff --git a/guava-tests/test/com/google/common/collect/ArrayTableTest.java b/guava-tests/test/com/google/common/collect/ArrayTableTest.java index 30a1657..29100ce 100644 --- a/guava-tests/test/com/google/common/collect/ArrayTableTest.java +++ b/guava-tests/test/com/google/common/collect/ArrayTableTest.java @@ -17,13 +17,13 @@ package com.google.common.collect; import static java.util.Arrays.asList; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Objects; import com.google.common.collect.Table.Cell; import com.google.common.testing.EqualsTester; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; @@ -286,13 +286,13 @@ public class ArrayTableTest extends AbstractTableTest { public void testRowKeyList() { ArrayTable<String, Integer, Character> table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); - FluentAsserts.assertThat(table.rowKeyList()).has().allOf("foo", "bar", "cat").inOrder(); + ASSERT.that(table.rowKeyList()).has().exactly("foo", "bar", "cat").inOrder(); } public void testColumnKeyList() { ArrayTable<String, Integer, Character> table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); - FluentAsserts.assertThat(table.columnKeyList()).has().allOf(1, 2, 3).inOrder(); + ASSERT.that(table.columnKeyList()).has().exactly(1, 2, 3).inOrder(); } public void testGetMissingKeys() { @@ -400,9 +400,9 @@ public class ArrayTableTest extends AbstractTableTest { = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); Character[][] array = table.toArray(Character.class); assertEquals(3, array.length); - FluentAsserts.assertThat(array[0]).has().allOf('a', null, 'c').inOrder(); - FluentAsserts.assertThat(array[1]).has().allOf('b', null, null).inOrder(); - FluentAsserts.assertThat(array[2]).has().allOf(null, null, null).inOrder(); + ASSERT.that(array[0]).has().exactly('a', null, 'c').inOrder(); + ASSERT.that(array[1]).has().exactly('b', null, null).inOrder(); + ASSERT.that(array[2]).has().exactly(null, null, null).inOrder(); table.set(0, 2, 'd'); assertEquals((Character) 'c', array[0][2]); array[0][2] = 'e'; diff --git a/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java b/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java index 10a2bde..f7fc520 100644 --- a/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java +++ b/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Map; +import java.util.Random; import java.util.Set; import java.util.SortedMap; import java.util.TreeSet; @@ -287,4 +288,20 @@ final class BenchmarkHelpers { public enum Value { INSTANCE; } + + public enum ListSizeDistribution { + UNIFORM_0_TO_2(0, 2), UNIFORM_0_TO_9(0, 9), ALWAYS_0(0, 0), ALWAYS_10(10, 10); + + final int min; + final int max; + + private ListSizeDistribution(int min, int max) { + this.min = min; + this.max = max; + } + + public int chooseSize(Random random) { + return random.nextInt(max - min + 1) + min; + } + } } diff --git a/guava-tests/test/com/google/common/collect/Collections2Test.java b/guava-tests/test/com/google/common/collect/Collections2Test.java index 1a54975..ed21ec6 100644 --- a/guava-tests/test/com/google/common/collect/Collections2Test.java +++ b/guava-tests/test/com/google/common/collect/Collections2Test.java @@ -19,7 +19,6 @@ package com.google.common.collect; import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newLinkedList; -import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod; import static java.util.Arrays.asList; import static java.util.Collections.nCopies; import static org.truth0.Truth.ASSERT; @@ -34,16 +33,16 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.testing.NullPointerTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Tests for {@link Collections2}. * @@ -93,18 +92,18 @@ public class Collections2Test extends TestCase { @Override public Collection<String> create(String[] elements) { List<String> unfiltered = newArrayList(); unfiltered.add("yyy"); - unfiltered.addAll(asList(elements)); + Collections.addAll(unfiltered, elements); unfiltered.add("zzz"); return Collections2.filter(unfiltered, NOT_YYY_ZZZ); } }) .named("Collections2.filter") .withFeatures( - CollectionFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ADD, + CollectionFeature.SUPPORTS_REMOVE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite(); } @@ -114,17 +113,17 @@ public class Collections2Test extends TestCase { new TestStringCollectionGenerator() { @Override public Collection<String> create(String[] elements) { List<String> unfiltered = newArrayList(); - unfiltered.addAll(asList(elements)); + Collections.addAll(unfiltered, elements); return Collections2.filter(unfiltered, NOT_YYY_ZZZ); } }) .named("Collections2.filter") .withFeatures( - CollectionFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ADD, + CollectionFeature.SUPPORTS_REMOVE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite(); } @@ -135,18 +134,18 @@ public class Collections2Test extends TestCase { @Override public Collection<String> create(String[] elements) { List<String> unfiltered = newLinkedList(); unfiltered.add("yyy"); - unfiltered.addAll(asList(elements)); + Collections.addAll(unfiltered, elements); unfiltered.add("zzz"); return Collections2.filter(unfiltered, NOT_YYY_ZZZ); } }) .named("Collections2.filter") .withFeatures( - CollectionFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ADD, + CollectionFeature.SUPPORTS_REMOVE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite(); } @@ -164,11 +163,11 @@ public class Collections2Test extends TestCase { }) .named("Collections2.filter, no nulls") .withFeatures( - CollectionFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ADD, + CollectionFeature.SUPPORTS_REMOVE, CollectionFeature.ALLOWS_NULL_QUERIES, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite(); } @@ -188,11 +187,11 @@ public class Collections2Test extends TestCase { }) .named("Collections2.filter, filtered input") .withFeatures( - CollectionFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ADD, + CollectionFeature.SUPPORTS_REMOVE, CollectionFeature.KNOWN_ORDER, CollectionFeature.ALLOWS_NULL_QUERIES, CollectionSize.ANY) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite(); } @@ -219,7 +218,7 @@ public class Collections2Test extends TestCase { }) .named("Collections2.transform") .withFeatures( - CollectionFeature.SUPPORTS_REMOVE, + CollectionFeature.REMOVE_OPERATIONS, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY) @@ -238,8 +237,7 @@ public class Collections2Test extends TestCase { Collections2.orderedPermutations(list); assertEquals(1, permutationSet.size()); - ASSERT.<List<Integer>, Collection<List<Integer>>> - that(permutationSet).has().item(list); + ASSERT.that(permutationSet).has().item(list); Iterator<List<Integer>> permutations = permutationSet.iterator(); diff --git a/guava-tests/test/com/google/common/collect/ComparisonChainTest.java b/guava-tests/test/com/google/common/collect/ComparisonChainTest.java index 0a75056..e24ed46 100644 --- a/guava-tests/test/com/google/common/collect/ComparisonChainTest.java +++ b/guava-tests/test/com/google/common/collect/ComparisonChainTest.java @@ -100,12 +100,4 @@ public class ComparisonChainTest extends TestCase { assertTrue(ComparisonChain.start().compareTrueFirst(false, true).result() > 0); assertTrue(ComparisonChain.start().compareTrueFirst(false, false).result() == 0); } - - @SuppressWarnings("deprecation") // test of a deprecated method - public void testCompareBooleans() { - assertTrue(ComparisonChain.start().compare(true, true).result() == 0); - assertTrue(ComparisonChain.start().compare(true, false).result() > 0); - assertTrue(ComparisonChain.start().compare(false, true).result() < 0); - assertTrue(ComparisonChain.start().compare(false, false).result() == 0); - } } diff --git a/guava-tests/test/com/google/common/collect/ComputingConcurrentHashMapTest.java b/guava-tests/test/com/google/common/collect/ComputingConcurrentHashMapTest.java index 5fa1949..479bdf4 100644 --- a/guava-tests/test/com/google/common/collect/ComputingConcurrentHashMapTest.java +++ b/guava-tests/test/com/google/common/collect/ComputingConcurrentHashMapTest.java @@ -25,6 +25,7 @@ import static com.google.common.collect.MapMakerInternalMapTest.checkEvictionQue import static com.google.common.collect.MapMakerInternalMapTest.checkExpirationTimes; import com.google.common.base.Function; +import com.google.common.base.Functions; import com.google.common.collect.MapMaker.ComputingMapAdapter; import com.google.common.collect.MapMaker.RemovalCause; import com.google.common.collect.MapMakerInternalMap.ReferenceEntry; @@ -34,6 +35,8 @@ import com.google.common.collect.MapMakerInternalMapTest.DummyValueReference; import com.google.common.collect.MapMakerInternalMapTest.QueuingRemovalListener; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Iterator; import java.util.List; import java.util.Random; @@ -43,8 +46,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReferenceArray; -import junit.framework.TestCase; - /** * @author Charles Fry */ @@ -71,12 +72,7 @@ public class ComputingConcurrentHashMapTest extends TestCase { // constructor tests public void testComputingFunction() { - Function<Object, Object> computingFunction = new Function<Object, Object>() { - @Override - public Object apply(Object from) { - return from; - } - }; + Function<Object, Object> computingFunction = Functions.identity(); ComputingConcurrentHashMap<Object, Object> map = makeComputingMap(createMapMaker(), computingFunction); assertSame(computingFunction, map.computingFunction); diff --git a/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java b/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java index 7d48434..467d793 100644 --- a/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java +++ b/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java @@ -18,7 +18,6 @@ package com.google.common.collect; import static com.google.common.collect.MapMakerInternalMap.Strength.STRONG; import static com.google.common.collect.MapMakerInternalMap.Strength.WEAK; -import static com.google.common.collect.testing.IteratorFeature.SUPPORTS_REMOVE; import static com.google.common.testing.SerializableTester.reserializeAndAssert; import static java.util.Arrays.asList; import static org.easymock.EasyMock.eq; @@ -28,25 +27,24 @@ import static org.easymock.EasyMock.isA; import com.google.common.base.Equivalence; import com.google.common.collect.MapMaker.RemovalListener; import com.google.common.collect.MapMaker.RemovalNotification; -import com.google.common.collect.Multiset.Entry; -import com.google.common.collect.testing.IteratorTester; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringMultisetGenerator; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.easymock.EasyMock; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + /** * Test case for {@link ConcurrentHashMultiset}. * @@ -57,7 +55,7 @@ public class ConcurrentHashMultisetTest extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(); - suite.addTest(MultisetTestSuiteBuilder.using(concurrentMultisetGenerator()) + suite.addTest(MultisetTestSuiteBuilder.using(concurrentHashMultisetGenerator()) .withFeatures(CollectionSize.ANY, CollectionFeature.GENERAL_PURPOSE, CollectionFeature.SERIALIZABLE, @@ -68,7 +66,7 @@ public class ConcurrentHashMultisetTest extends TestCase { return suite; } - private static TestStringMultisetGenerator concurrentMultisetGenerator() { + private static TestStringMultisetGenerator concurrentHashMultisetGenerator() { return new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { return ConcurrentHashMultiset.create(asList(elements)); @@ -249,6 +247,28 @@ public class ConcurrentHashMultisetTest extends TestCase { verify(); } + public void testRemoveExactly() { + ConcurrentHashMultiset<String> cms = ConcurrentHashMultiset.create(); + cms.add("a", 2); + cms.add("b", 3); + + try { + cms.removeExactly("a", -2); + } catch (IllegalArgumentException expected) {} + + assertTrue(cms.removeExactly("a", 0)); + assertEquals(2, cms.count("a")); + assertTrue(cms.removeExactly("c", 0)); + assertEquals(0, cms.count("c")); + + assertFalse(cms.removeExactly("a", 4)); + assertEquals(2, cms.count("a")); + assertTrue(cms.removeExactly("a", 2)); + assertEquals(0, cms.count("a")); + assertTrue(cms.removeExactly("b", 2)); + assertEquals(1, cms.count("b")); + } + public void testIteratorRemove_actualMap() { // Override to avoid using mocks. multiset = ConcurrentHashMultiset.create(); @@ -267,58 +287,6 @@ public class ConcurrentHashMultisetTest extends TestCase { assertEquals(3, mutations); } - public void testIterator() { - // multiset.iterator - List<String> expected = asList("a", "a", "b", "b", "b"); - new IteratorTester<String>( - 5, asList(SUPPORTS_REMOVE), expected, IteratorTester.KnownOrder.UNKNOWN_ORDER) { - - ConcurrentHashMultiset<String> multiset; - - @Override protected Iterator<String> newTargetIterator() { - multiset = ConcurrentHashMultiset.create(); - multiset.add("a", 2); - multiset.add("b", 3); - return multiset.iterator(); - } - - @Override protected void verify(List<String> elements) { - super.verify(elements); - assertEquals(ImmutableMultiset.copyOf(elements), multiset); - } - }.test(); - } - - public void testEntryIterator() { - // multiset.entryIterator - List<Entry<String>> expected = asList( - Multisets.immutableEntry("a", 1), - Multisets.immutableEntry("b", 2), - Multisets.immutableEntry("c", 3), - Multisets.immutableEntry("d", 4), - Multisets.immutableEntry("e", 5)); - new IteratorTester<Entry<String>>( - 5, asList(SUPPORTS_REMOVE), expected, IteratorTester.KnownOrder.UNKNOWN_ORDER) { - - ConcurrentHashMultiset<String> multiset; - - @Override protected Iterator<Entry<String>> newTargetIterator() { - multiset = ConcurrentHashMultiset.create(); - multiset.add("a", 1); - multiset.add("b", 2); - multiset.add("c", 3); - multiset.add("d", 4); - multiset.add("e", 5); - return multiset.entryIterator(); - } - - @Override protected void verify(List<Entry<String>> elements) { - super.verify(elements); - assertEquals(ImmutableSet.copyOf(elements), ImmutableSet.copyOf(multiset.entryIterator())); - } - }.test(); - } - public void testSetCount_basic() { int initialCount = 20; int countToSet = 40; @@ -547,10 +515,15 @@ public class ConcurrentHashMultisetTest extends TestCase { }; @SuppressWarnings("deprecation") // TODO(kevinb): what to do? - GenericMapMaker<String, Number> mapMaker = new MapMaker() + MapMaker mapMaker = new MapMaker() .concurrencyLevel(1) - .maximumSize(1) - .removalListener(removalListener); + .maximumSize(1); + /* + * Cleverly ignore the return type now that ConcurrentHashMultiset accepts only MapMaker and not + * the deprecated GenericMapMaker. We know that a RemovalListener<String, Number> is a type that + * will work with ConcurrentHashMultiset. + */ + mapMaker.removalListener(removalListener); ConcurrentHashMultiset<String> multiset = ConcurrentHashMultiset.create(mapMaker); diff --git a/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java b/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java index 3fd3e9d..d5e1202 100644 --- a/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java +++ b/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java @@ -22,17 +22,18 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.MapConstraintsTest.TestKeyException; import com.google.common.collect.MapConstraintsTest.TestValueException; +import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; import com.google.common.collect.testing.google.BiMapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringBiMapGenerator; -import java.util.Map.Entry; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.Map.Entry; + /** * Tests for {@link MapConstraints#constrainedBiMap}. * @@ -54,8 +55,10 @@ public class ConstrainedBiMapTest extends TestCase { .named("Maps.constrainedBiMap[HashBiMap]") .withFeatures( CollectionSize.ANY, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, MapFeature.REJECTS_DUPLICATES_AT_CREATION) .createTestSuite()); diff --git a/guava-tests/test/com/google/common/collect/ConstrainedMapTest.java b/guava-tests/test/com/google/common/collect/ConstrainedMapTest.java new file mode 100644 index 0000000..f5260bb --- /dev/null +++ b/guava-tests/test/com/google/common/collect/ConstrainedMapTest.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; +import com.google.common.collect.MapConstraintsTest.TestKeyException; +import com.google.common.collect.MapConstraintsTest.TestValueException; +import com.google.common.collect.testing.MapTestSuiteBuilder; +import com.google.common.collect.testing.TestStringMapGenerator; +import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.features.MapFeature; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +/** + * Tests for {@link MapConstraints#constrainedMap}. + * + * @author Jared Levy + * @author Louis Wasserman + */ +@GwtCompatible(emulated = true) +public class ConstrainedMapTest extends TestCase { + + private static final String TEST_KEY = "42"; + private static final String TEST_VALUE = "test"; + private static final MapConstraint<String, String> TEST_CONSTRAINT = new TestConstraint(); + + @GwtIncompatible("suite") + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTest(MapTestSuiteBuilder + .using(new ConstrainedMapGenerator()) + .named("Maps.constrainedMap[HashMap]") + .withFeatures( + CollectionSize.ANY, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, + MapFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE) + .createTestSuite()); + suite.addTestSuite(ConstrainedMapTest.class); + return suite; + } + + public void testPutWithForbiddenKeyForbiddenValue() { + Map<String, String> map = MapConstraints.constrainedMap( + new HashMap<String, String>(), + TEST_CONSTRAINT); + try { + map.put(TEST_KEY, TEST_VALUE); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + // success + } + } + + public void testPutWithForbiddenKeyAllowedValue() { + Map<String, String> map = MapConstraints.constrainedMap( + new HashMap<String, String>(), + TEST_CONSTRAINT); + try { + map.put(TEST_KEY, "allowed"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + // success + } + } + + public void testPutWithAllowedKeyForbiddenValue() { + Map<String, String> map = MapConstraints.constrainedMap( + new HashMap<String, String>(), + TEST_CONSTRAINT); + try { + map.put("allowed", TEST_VALUE); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + // success + } + } + + public static final class ConstrainedMapGenerator extends TestStringMapGenerator { + @Override + protected Map<String, String> create(Entry<String, String>[] entries) { + Map<String, String> map = MapConstraints.constrainedMap( + new HashMap<String, String>(), + TEST_CONSTRAINT); + for (Entry<String, String> entry : entries) { + map.put(entry.getKey(), entry.getValue()); + } + return map; + } + } + + private static final class TestConstraint implements MapConstraint<String, String> { + @Override + public void checkKeyValue(String key, String value) { + if (TEST_KEY.equals(key)) { + throw new TestKeyException(); + } + if (TEST_VALUE.equals(value)) { + throw new TestValueException(); + } + } + + private static final long serialVersionUID = 0; + } +} diff --git a/guava-tests/test/com/google/common/collect/ConstrainedSetMultimapTest.java b/guava-tests/test/com/google/common/collect/ConstrainedSetMultimapTest.java index 2931cf7..2a558c6 100644 --- a/guava-tests/test/com/google/common/collect/ConstrainedSetMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/ConstrainedSetMultimapTest.java @@ -16,25 +16,59 @@ package com.google.common.collect; -import com.google.common.annotations.GwtCompatible; -import com.google.common.annotations.GwtIncompatible; +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.features.MapFeature; +import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder; +import com.google.common.collect.testing.google.TestStringSetMultimapGenerator; + +import junit.framework.Test; +import junit.framework.TestCase; + +import java.io.Serializable; +import java.util.Map.Entry; /** - * Tests for {@link MapConstraints#constrainedSetMultimap}. + * Tests for {@link MapConstraints#constrainedSetMultimap} not accounted for in + * {@link MapConstraintsTest}. * * @author Jared Levy */ -@GwtCompatible(emulated = true) -public class ConstrainedSetMultimapTest extends AbstractSetMultimapTest { - - @Override protected SetMultimap<String, Integer> create() { - return MapConstraints.<String, Integer>constrainedSetMultimap( - HashMultimap.<String, Integer>create(), - MapConstraintsTest.TEST_CONSTRAINT); +public class ConstrainedSetMultimapTest extends TestCase { + private enum Constraint implements Serializable, MapConstraint<String, String> { + INSTANCE; + + @Override + public void checkKeyValue(String key, String value) { + checkArgument(!"test".equals(key)); + checkArgument(!"test".equals(value)); + } + } + + public static Test suite() { + return SetMultimapTestSuiteBuilder.using( + new TestStringSetMultimapGenerator() { + + @Override + protected SetMultimap<String, String> create(Entry<String, String>[] entries) { + SetMultimap<String, String> multimap = HashMultimap.create(); + for (Entry<String, String> entry : entries) { + multimap.put(entry.getKey(), entry.getValue()); + } + return MapConstraints.constrainedSetMultimap(multimap, Constraint.INSTANCE); + } + }) + .named("MapConstraints.constrainedSetMultimap") + .withFeatures( + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, + MapFeature.GENERAL_PURPOSE, + CollectionSize.ANY, + CollectionFeature.SERIALIZABLE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE) + .createTestSuite(); } - - // an override of a GwtIncompatible method - @GwtIncompatible("SerializableTester") - // not serializable - @Override public void testSerializable() {} } diff --git a/guava-tests/test/com/google/common/collect/ConstraintsTest.java b/guava-tests/test/com/google/common/collect/ConstraintsTest.java index 66d058f..08a2866 100644 --- a/guava-tests/test/com/google/common/collect/ConstraintsTest.java +++ b/guava-tests/test/com/google/common/collect/ConstraintsTest.java @@ -17,12 +17,14 @@ package com.google.common.collect; import static java.util.Arrays.asList; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.util.AbstractCollection; import java.util.Collection; import java.util.Collections; @@ -33,8 +35,6 @@ import java.util.RandomAccess; import java.util.Set; import java.util.SortedSet; -import junit.framework.TestCase; - /** * Tests for {@code Constraints}. * @@ -80,9 +80,10 @@ public class ConstraintsTest extends TestCase { constrained.add("qux"); constrained.addAll(asList("cat", "dog")); /* equals and hashCode aren't defined for Collection */ - FluentAsserts.assertThat(collection).has().allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder(); - FluentAsserts.assertThat(constrained).has() - .allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder(); + ASSERT.that(collection).has() + .exactly("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder(); + ASSERT.that(constrained).has() + .exactly("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder(); } public void testConstrainedCollectionIllegal() { @@ -97,8 +98,8 @@ public class ConstraintsTest extends TestCase { constrained.addAll(asList("baz", TEST_ELEMENT)); fail("TestElementException expected"); } catch (TestElementException expected) {} - FluentAsserts.assertThat(constrained).has().allOf("foo", "bar").inOrder(); - FluentAsserts.assertThat(collection).has().allOf("foo", "bar").inOrder(); + ASSERT.that(constrained).has().exactly("foo", "bar").inOrder(); + ASSERT.that(collection).has().exactly("foo", "bar").inOrder(); } public void testConstrainedSetLegal() { @@ -111,9 +112,9 @@ public class ConstraintsTest extends TestCase { assertTrue(constrained.equals(set)); assertEquals(set.toString(), constrained.toString()); assertEquals(set.hashCode(), constrained.hashCode()); - FluentAsserts.assertThat(set).has().allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder(); - FluentAsserts.assertThat(constrained).has() - .allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder(); + ASSERT.that(set).has().exactly("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder(); + ASSERT.that(constrained).has() + .exactly("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder(); } public void testConstrainedSetIllegal() { @@ -127,8 +128,8 @@ public class ConstraintsTest extends TestCase { constrained.addAll(asList("baz", TEST_ELEMENT)); fail("TestElementException expected"); } catch (TestElementException expected) {} - FluentAsserts.assertThat(constrained).has().allOf("foo", "bar").inOrder(); - FluentAsserts.assertThat(set).has().allOf("foo", "bar").inOrder(); + ASSERT.that(constrained).has().exactly("foo", "bar").inOrder(); + ASSERT.that(set).has().exactly("foo", "bar").inOrder(); } public void testConstrainedSortedSetLegal() { @@ -142,9 +143,9 @@ public class ConstraintsTest extends TestCase { assertTrue(constrained.equals(sortedSet)); assertEquals(sortedSet.toString(), constrained.toString()); assertEquals(sortedSet.hashCode(), constrained.hashCode()); - FluentAsserts.assertThat(sortedSet).has().allOf("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT).inOrder(); - FluentAsserts.assertThat(constrained).has() - .allOf("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT).inOrder(); + ASSERT.that(sortedSet).has().exactly("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT).inOrder(); + ASSERT.that(constrained).has() + .exactly("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT).inOrder(); assertNull(constrained.comparator()); assertEquals("bar", constrained.first()); assertEquals(TEST_ELEMENT, constrained.last()); @@ -174,8 +175,8 @@ public class ConstraintsTest extends TestCase { constrained.addAll(asList("baz", TEST_ELEMENT)); fail("TestElementException expected"); } catch (TestElementException expected) {} - FluentAsserts.assertThat(constrained).has().allOf("bar", "foo").inOrder(); - FluentAsserts.assertThat(sortedSet).has().allOf("bar", "foo").inOrder(); + ASSERT.that(constrained).has().exactly("bar", "foo").inOrder(); + ASSERT.that(sortedSet).has().exactly("bar", "foo").inOrder(); } public void testConstrainedListLegal() { @@ -192,17 +193,17 @@ public class ConstraintsTest extends TestCase { assertTrue(constrained.equals(list)); assertEquals(list.toString(), constrained.toString()); assertEquals(list.hashCode(), constrained.hashCode()); - FluentAsserts.assertThat(list).has().allOf( + ASSERT.that(list).has().exactly( "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder(); - FluentAsserts.assertThat(constrained).has().allOf( + ASSERT.that(constrained).has().exactly( "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder(); ListIterator<String> iterator = constrained.listIterator(); iterator.next(); iterator.set("sun"); constrained.listIterator(2).add("sky"); - FluentAsserts.assertThat(list).has().allOf( + ASSERT.that(list).has().exactly( "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder(); - FluentAsserts.assertThat(constrained).has().allOf( + ASSERT.that(constrained).has().exactly( "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder(); assertTrue(constrained instanceof RandomAccess); } @@ -260,8 +261,8 @@ public class ConstraintsTest extends TestCase { constrained.addAll(1, asList("baz", TEST_ELEMENT)); fail("TestElementException expected"); } catch (TestElementException expected) {} - FluentAsserts.assertThat(constrained).has().allOf("foo", "bar").inOrder(); - FluentAsserts.assertThat(list).has().allOf("foo", "bar").inOrder(); + ASSERT.that(constrained).has().exactly("foo", "bar").inOrder(); + ASSERT.that(list).has().exactly("foo", "bar").inOrder(); } public void testConstrainedMultisetLegal() { @@ -276,15 +277,15 @@ public class ConstraintsTest extends TestCase { assertTrue(constrained.equals(multiset)); assertEquals(multiset.toString(), constrained.toString()); assertEquals(multiset.hashCode(), constrained.hashCode()); - FluentAsserts.assertThat(multiset).has().allOf( + ASSERT.that(multiset).has().exactly( "foo", "bar", TEST_ELEMENT, "qux", "cat", "dog", "cow", "cow"); - FluentAsserts.assertThat(constrained).has().allOf( + ASSERT.that(constrained).has().exactly( "foo", "bar", TEST_ELEMENT, "qux", "cat", "dog", "cow", "cow"); assertEquals(1, constrained.count("foo")); assertEquals(1, constrained.remove("foo", 3)); assertEquals(2, constrained.setCount("cow", 0)); - FluentAsserts.assertThat(multiset).has().allOf("bar", TEST_ELEMENT, "qux", "cat", "dog"); - FluentAsserts.assertThat(constrained).has().allOf("bar", TEST_ELEMENT, "qux", "cat", "dog"); + ASSERT.that(multiset).has().exactly("bar", TEST_ELEMENT, "qux", "cat", "dog"); + ASSERT.that(constrained).has().exactly("bar", TEST_ELEMENT, "qux", "cat", "dog"); } public void testConstrainedMultisetIllegal() { @@ -303,8 +304,8 @@ public class ConstraintsTest extends TestCase { constrained.addAll(asList("baz", TEST_ELEMENT)); fail("TestElementException expected"); } catch (TestElementException expected) {} - FluentAsserts.assertThat(constrained).has().allOf("foo", "bar"); - FluentAsserts.assertThat(multiset).has().allOf("foo", "bar"); + ASSERT.that(constrained).has().exactly("foo", "bar"); + ASSERT.that(multiset).has().exactly("foo", "bar"); } public void testNefariousAddAll() { @@ -313,8 +314,8 @@ public class ConstraintsTest extends TestCase { list, TEST_CONSTRAINT); Collection<String> onceIterable = onceIterableCollection("baz"); constrained.addAll(onceIterable); - FluentAsserts.assertThat(constrained).has().allOf("foo", "bar", "baz").inOrder(); - FluentAsserts.assertThat(list).has().allOf("foo", "bar", "baz").inOrder(); + ASSERT.that(constrained).has().exactly("foo", "bar", "baz").inOrder(); + ASSERT.that(list).has().exactly("foo", "bar", "baz").inOrder(); } /** diff --git a/guava-tests/test/com/google/common/collect/ContiguousSetTest.java b/guava-tests/test/com/google/common/collect/ContiguousSetTest.java index 69e7596..1d26941 100644 --- a/guava-tests/test/com/google/common/collect/ContiguousSetTest.java +++ b/guava-tests/test/com/google/common/collect/ContiguousSetTest.java @@ -21,17 +21,15 @@ import static com.google.common.collect.BoundType.OPEN; import static com.google.common.collect.DiscreteDomain.integers; import static com.google.common.testing.SerializableTester.reserialize; import static com.google.common.testing.SerializableTester.reserializeAndAssert; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.testing.EqualsTester; +import junit.framework.Test; import junit.framework.TestCase; -import org.truth0.Truth; -import org.truth0.subjects.CollectionSubject; - -import java.util.Collection; import java.util.Set; /** @@ -107,18 +105,43 @@ public class ContiguousSetTest extends TestCase { assertEquals(enormous, enormousReserialized); } + public void testCreate_noMin() { + Range<Integer> range = Range.lessThan(0); + try { + ContiguousSet.create(range, RangeTest.UNBOUNDED_DOMAIN); + fail(); + } catch (IllegalArgumentException expected) {} + } + + public void testCreate_noMax() { + Range<Integer> range = Range.greaterThan(0); + try { + ContiguousSet.create(range, RangeTest.UNBOUNDED_DOMAIN); + fail(); + } catch (IllegalArgumentException expected) {} + } + + public void testCreate_empty() { + assertEquals(ImmutableSet.of(), ContiguousSet.create(Range.closedOpen(1, 1), integers())); + assertEquals(ImmutableSet.of(), ContiguousSet.create(Range.openClosed(5, 5), integers())); + assertEquals(ImmutableSet.of(), + ContiguousSet.create(Range.lessThan(Integer.MIN_VALUE), integers())); + assertEquals(ImmutableSet.of(), + ContiguousSet.create(Range.greaterThan(Integer.MAX_VALUE), integers())); + } + public void testHeadSet() { ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); ASSERT.that(set.headSet(1)).isEmpty(); ASSERT.that(set.headSet(2)).has().item(1); - ASSERT.that(set.headSet(3)).has().allOf(1, 2).inOrder(); - ASSERT.that(set.headSet(4)).has().allOf(1, 2, 3).inOrder(); - ASSERT.that(set.headSet(Integer.MAX_VALUE)).has().allOf(1, 2, 3).inOrder(); + ASSERT.that(set.headSet(3)).has().exactly(1, 2).inOrder(); + ASSERT.that(set.headSet(4)).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(set.headSet(Integer.MAX_VALUE)).has().exactly(1, 2, 3).inOrder(); ASSERT.that(set.headSet(1, true)).has().item(1); - ASSERT.that(set.headSet(2, true)).has().allOf(1, 2).inOrder(); - ASSERT.that(set.headSet(3, true)).has().allOf(1, 2, 3).inOrder(); - ASSERT.that(set.headSet(4, true)).has().allOf(1, 2, 3).inOrder(); - ASSERT.that(set.headSet(Integer.MAX_VALUE, true)).has().allOf(1, 2, 3).inOrder(); + ASSERT.that(set.headSet(2, true)).has().exactly(1, 2).inOrder(); + ASSERT.that(set.headSet(3, true)).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(set.headSet(4, true)).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(set.headSet(Integer.MAX_VALUE, true)).has().exactly(1, 2, 3).inOrder(); } public void testHeadSet_tooSmall() { @@ -127,12 +150,12 @@ public class ContiguousSetTest extends TestCase { public void testTailSet() { ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); - ASSERT.that(set.tailSet(Integer.MIN_VALUE)).has().allOf(1, 2, 3).inOrder(); - ASSERT.that(set.tailSet(1)).has().allOf(1, 2, 3).inOrder(); - ASSERT.that(set.tailSet(2)).has().allOf(2, 3).inOrder(); + ASSERT.that(set.tailSet(Integer.MIN_VALUE)).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(set.tailSet(1)).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(set.tailSet(2)).has().exactly(2, 3).inOrder(); ASSERT.that(set.tailSet(3)).has().item(3); - ASSERT.that(set.tailSet(Integer.MIN_VALUE, false)).has().allOf(1, 2, 3).inOrder(); - ASSERT.that(set.tailSet(1, false)).has().allOf(2, 3).inOrder(); + ASSERT.that(set.tailSet(Integer.MIN_VALUE, false)).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(set.tailSet(1, false)).has().exactly(2, 3).inOrder(); ASSERT.that(set.tailSet(2, false)).has().item(3); ASSERT.that(set.tailSet(3, false)).isEmpty(); } @@ -143,18 +166,18 @@ public class ContiguousSetTest extends TestCase { public void testSubSet() { ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers()); - ASSERT.that(set.subSet(1, 4)).has().allOf(1, 2, 3).inOrder(); - ASSERT.that(set.subSet(2, 4)).has().allOf(2, 3).inOrder(); + ASSERT.that(set.subSet(1, 4)).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(set.subSet(2, 4)).has().exactly(2, 3).inOrder(); ASSERT.that(set.subSet(3, 4)).has().item(3); ASSERT.that(set.subSet(3, 3)).isEmpty(); ASSERT.that(set.subSet(2, 3)).has().item(2); - ASSERT.that(set.subSet(1, 3)).has().allOf(1, 2).inOrder(); + ASSERT.that(set.subSet(1, 3)).has().exactly(1, 2).inOrder(); ASSERT.that(set.subSet(1, 2)).has().item(1); ASSERT.that(set.subSet(2, 2)).isEmpty(); - ASSERT.that(set.subSet(Integer.MIN_VALUE, Integer.MAX_VALUE)).has().allOf(1, 2, 3).inOrder(); - ASSERT.that(set.subSet(1, true, 3, true)).has().allOf(1, 2, 3).inOrder(); - ASSERT.that(set.subSet(1, false, 3, true)).has().allOf(2, 3).inOrder(); - ASSERT.that(set.subSet(1, true, 3, false)).has().allOf(1, 2).inOrder(); + ASSERT.that(set.subSet(Integer.MIN_VALUE, Integer.MAX_VALUE)).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(set.subSet(1, true, 3, true)).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(set.subSet(1, false, 3, true)).has().exactly(2, 3).inOrder(); + ASSERT.that(set.subSet(1, true, 3, false)).has().exactly(1, 2).inOrder(); ASSERT.that(set.subSet(1, false, 3, false)).has().item(2); } @@ -280,12 +303,4 @@ public class ContiguousSetTest extends TestCase { assertEquals(ImmutableSet.of(1, 2, 3), set.intersection(ContiguousSet.create(Range.open(-1, 4), integers()))); } - - // Hack for JDK5 type inference. - private static class ASSERT { - static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> that( - Collection<T> collection) { - return Truth.ASSERT.<T, Collection<T>>that(collection); - } - } } diff --git a/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java b/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java index fdf2acd..8e36167 100644 --- a/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java +++ b/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java @@ -32,5 +32,6 @@ public class DiscreteDomainTest extends TestCase { public void testSerialization() { reserializeAndAssert(DiscreteDomain.integers()); reserializeAndAssert(DiscreteDomain.longs()); + reserializeAndAssert(DiscreteDomain.bigIntegers()); } } diff --git a/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java b/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java index d1bd97a..580ee30 100644 --- a/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java +++ b/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java @@ -118,9 +118,4 @@ public class EmptyImmutableTableTest extends AbstractImmutableTableTest { public void testValues() { assertTrue(INSTANCE.values().isEmpty()); } - - public void testReadResolve() { - assertSame(EmptyImmutableTable.INSTANCE, EmptyImmutableTable.INSTANCE.readResolve()); - } - } diff --git a/guava-tests/test/com/google/common/collect/EnumBiMapTest.java b/guava-tests/test/com/google/common/collect/EnumBiMapTest.java index 14c1f0f..4d2a89d 100644 --- a/guava-tests/test/com/google/common/collect/EnumBiMapTest.java +++ b/guava-tests/test/com/google/common/collect/EnumBiMapTest.java @@ -32,7 +32,10 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; -import java.util.Collection; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -40,12 +43,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.truth0.subjects.CollectionSubject; - /** * Tests for {@code EnumBiMap}. * @@ -108,6 +105,7 @@ public class EnumBiMapTest extends TestCase { .named("EnumBiMap") .withFeatures(CollectionSize.ANY, CollectionFeature.SERIALIZABLE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, MapFeature.GENERAL_PURPOSE, CollectionFeature.KNOWN_ORDER) .createTestSuite()); @@ -198,17 +196,17 @@ public class EnumBiMapTest extends TestCase { EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map); // forward map ordered by currency - assertThat(bimap.keySet()) - .has().allOf(Currency.DOLLAR, Currency.FRANC, Currency.PESO).inOrder(); + ASSERT.that(bimap.keySet()) + .has().exactly(Currency.DOLLAR, Currency.FRANC, Currency.PESO).inOrder(); // forward map ordered by currency (even for country values) - assertThat(bimap.values()) - .has().allOf(Country.CANADA, Country.SWITZERLAND, Country.CHILE).inOrder(); + ASSERT.that(bimap.values()) + .has().exactly(Country.CANADA, Country.SWITZERLAND, Country.CHILE).inOrder(); // backward map ordered by country - assertThat(bimap.inverse().keySet()) - .has().allOf(Country.CANADA, Country.CHILE, Country.SWITZERLAND).inOrder(); + ASSERT.that(bimap.inverse().keySet()) + .has().exactly(Country.CANADA, Country.CHILE, Country.SWITZERLAND).inOrder(); // backward map ordered by country (even for currency values) - assertThat(bimap.inverse().values()) - .has().allOf(Currency.DOLLAR, Currency.PESO, Currency.FRANC).inOrder(); + ASSERT.that(bimap.inverse().values()) + .has().exactly(Currency.DOLLAR, Currency.PESO, Currency.FRANC).inOrder(); } public void testKeySetIteratorRemove() { @@ -225,17 +223,17 @@ public class EnumBiMapTest extends TestCase { iter.remove(); // forward map ordered by currency - assertThat(bimap.keySet()) - .has().allOf(Currency.FRANC, Currency.PESO).inOrder(); + ASSERT.that(bimap.keySet()) + .has().exactly(Currency.FRANC, Currency.PESO).inOrder(); // forward map ordered by currency (even for country values) - assertThat(bimap.values()) - .has().allOf(Country.SWITZERLAND, Country.CHILE).inOrder(); + ASSERT.that(bimap.values()) + .has().exactly(Country.SWITZERLAND, Country.CHILE).inOrder(); // backward map ordered by country - assertThat(bimap.inverse().keySet()) - .has().allOf(Country.CHILE, Country.SWITZERLAND).inOrder(); + ASSERT.that(bimap.inverse().keySet()) + .has().exactly(Country.CHILE, Country.SWITZERLAND).inOrder(); // backward map ordered by country (even for currency values) - assertThat(bimap.inverse().values()) - .has().allOf(Currency.PESO, Currency.FRANC).inOrder(); + ASSERT.that(bimap.inverse().values()) + .has().exactly(Currency.PESO, Currency.FRANC).inOrder(); } public void testValuesIteratorRemove() { @@ -253,17 +251,17 @@ public class EnumBiMapTest extends TestCase { iter.remove(); // forward map ordered by currency - assertThat(bimap.keySet()) - .has().allOf(Currency.DOLLAR, Currency.PESO).inOrder(); + ASSERT.that(bimap.keySet()) + .has().exactly(Currency.DOLLAR, Currency.PESO).inOrder(); // forward map ordered by currency (even for country values) - assertThat(bimap.values()) - .has().allOf(Country.CANADA, Country.CHILE).inOrder(); + ASSERT.that(bimap.values()) + .has().exactly(Country.CANADA, Country.CHILE).inOrder(); // backward map ordered by country - assertThat(bimap.inverse().keySet()) - .has().allOf(Country.CANADA, Country.CHILE).inOrder(); + ASSERT.that(bimap.inverse().keySet()) + .has().exactly(Country.CANADA, Country.CHILE).inOrder(); // backward map ordered by country (even for currency values) - assertThat(bimap.inverse().values()) - .has().allOf(Currency.DOLLAR, Currency.PESO).inOrder(); + ASSERT.that(bimap.inverse().values()) + .has().exactly(Currency.DOLLAR, Currency.PESO).inOrder(); } public void testEntrySet() { @@ -302,11 +300,5 @@ public class EnumBiMapTest extends TestCase { .testEquals(); } - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } - /* Remaining behavior tested by AbstractBiMapTest. */ } diff --git a/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java b/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java index 3e7f559..ba8e659 100644 --- a/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java +++ b/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java @@ -27,16 +27,16 @@ import com.google.common.collect.testing.google.TestBiMapGenerator; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Tests for {@code EnumHashBiMap}. * @@ -98,6 +98,7 @@ public class EnumHashBiMapTest extends TestCase { .named("EnumHashBiMap") .withFeatures(CollectionSize.ANY, CollectionFeature.SERIALIZABLE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, MapFeature.ALLOWS_NULL_VALUES, MapFeature.GENERAL_PURPOSE, CollectionFeature.KNOWN_ORDER) diff --git a/guava-tests/test/com/google/common/collect/EnumMultisetTest.java b/guava-tests/test/com/google/common/collect/EnumMultisetTest.java index 30faaf8..457dbe6 100644 --- a/guava-tests/test/com/google/common/collect/EnumMultisetTest.java +++ b/guava-tests/test/com/google/common/collect/EnumMultisetTest.java @@ -23,20 +23,21 @@ import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.AnEnum; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.google.MultisetFeature; import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; import com.google.common.collect.testing.google.TestEnumMultisetGenerator; import com.google.common.testing.ClassSanityTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; -import java.util.Collection; -import java.util.EnumSet; -import java.util.Set; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.Collection; +import java.util.EnumSet; +import java.util.Set; + /** * Tests for an {@link EnumMultiset}. * @@ -52,7 +53,9 @@ public class EnumMultisetTest extends TestCase { .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, CollectionFeature.GENERAL_PURPOSE, - CollectionFeature.ALLOWS_NULL_QUERIES) + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, + CollectionFeature.ALLOWS_NULL_QUERIES, + MultisetFeature.ENTRIES_ARE_VIEWS) .named("EnumMultiset") .createTestSuite()); suite.addTestSuite(EnumMultisetTest.class); @@ -69,10 +72,14 @@ public class EnumMultisetTest extends TestCase { }; } - private static enum Color { + private enum Color { BLUE, RED, YELLOW, GREEN, WHITE } + private enum Gender { + MALE, FEMALE + } + public void testClassCreate() { Multiset<Color> ms = EnumMultiset.create(Color.class); ms.add(Color.RED); @@ -106,7 +113,7 @@ public class EnumMultisetTest extends TestCase { public void testCreateEmptyWithoutClassFails() { try { - Multiset<Color> ms = EnumMultiset.create(ImmutableList.<Color> of()); + EnumMultiset.create(ImmutableList.<Color> of()); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } @@ -138,14 +145,21 @@ public class EnumMultisetTest extends TestCase { assertEquals(3, uniqueEntries.size()); } + // Wrapper of EnumMultiset factory methods, because we need to skip create(Class). + // create(Enum1.class) is equal to create(Enum2.class) but testEquals() expects otherwise. + // For the same reason, we need to skip create(Iterable, Class). + private static class EnumMultisetFactory { + public static <E extends Enum<E>> EnumMultiset<E> create(Iterable<E> elements) { + return EnumMultiset.create(elements); + } + } + @GwtIncompatible("reflection") public void testEquals() throws Exception { new ClassSanityTester() - .setSampleInstances(Class.class, ImmutableList.of(Color.class)) - .setSampleInstances(Enum.class, ImmutableList.copyOf(Color.values())) - .setSampleInstances(Iterable.class, - ImmutableList.of(ImmutableList.of(Color.RED), ImmutableList.of(Color.GREEN))) - .forAllPublicStaticMethods(EnumMultiset.class) + .setDistinctValues(Class.class, Color.class, Gender.class) + .setDistinctValues(Enum.class, Color.BLUE, Color.RED) + .forAllPublicStaticMethods(EnumMultisetFactory.class) .testEquals(); } @@ -153,7 +167,7 @@ public class EnumMultisetTest extends TestCase { public void testNulls() throws Exception { new NullPointerTester() .setDefault(Class.class, Color.class) - .setDefault(Iterable.class, ImmutableList.copyOf(Color.values())) + .setDefault(Iterable.class, EnumSet.allOf(Color.class)) .testAllPublicStaticMethods(EnumMultiset.class); } } diff --git a/guava-tests/test/com/google/common/collect/EvictingQueueTest.java b/guava-tests/test/com/google/common/collect/EvictingQueueTest.java new file mode 100644 index 0000000..9567dee --- /dev/null +++ b/guava-tests/test/com/google/common/collect/EvictingQueueTest.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import static java.util.Arrays.asList; + +import com.google.common.testing.NullPointerTester; +import com.google.common.testing.SerializableTester; + +import junit.framework.TestCase; + +import java.util.NoSuchElementException; + +/** + * Tests for {@link EvictingQueue}. + * + * @author Kurt Alfred Kluever + */ +public class EvictingQueueTest extends TestCase { + + public void testCreateWithNegativeSize() throws Exception { + try { + EvictingQueue.create(-1); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testCreateWithZeroSize() throws Exception { + EvictingQueue<String> queue = EvictingQueue.create(0); + assertEquals(0, queue.size()); + + assertTrue(queue.add("hi")); + assertEquals(0, queue.size()); + + assertTrue(queue.offer("hi")); + assertEquals(0, queue.size()); + + assertFalse(queue.remove("hi")); + assertEquals(0, queue.size()); + + try { + queue.element(); + fail(); + } catch (NoSuchElementException expected) {} + + assertNull(queue.peek()); + assertNull(queue.poll()); + try { + queue.remove(); + fail(); + } catch (NoSuchElementException expected) {} + } + + public void testRemainingCapacity_maxSize0() { + EvictingQueue<String> queue = EvictingQueue.create(0); + assertEquals(0, queue.remainingCapacity()); + } + + public void testRemainingCapacity_maxSize1() { + EvictingQueue<String> queue = EvictingQueue.create(1); + assertEquals(1, queue.remainingCapacity()); + queue.add("hi"); + assertEquals(0, queue.remainingCapacity()); + } + + public void testRemainingCapacity_maxSize3() { + EvictingQueue<String> queue = EvictingQueue.create(3); + assertEquals(3, queue.remainingCapacity()); + queue.add("hi"); + assertEquals(2, queue.remainingCapacity()); + queue.add("hi"); + assertEquals(1, queue.remainingCapacity()); + queue.add("hi"); + assertEquals(0, queue.remainingCapacity()); + } + + public void testEvictingAfterOne() throws Exception { + EvictingQueue<String> queue = EvictingQueue.create(1); + assertEquals(0, queue.size()); + assertEquals(1, queue.remainingCapacity()); + + assertTrue(queue.add("hi")); + assertEquals("hi", queue.element()); + assertEquals("hi", queue.peek()); + assertEquals(1, queue.size()); + assertEquals(0, queue.remainingCapacity()); + + assertTrue(queue.add("there")); + assertEquals("there", queue.element()); + assertEquals("there", queue.peek()); + assertEquals(1, queue.size()); + assertEquals(0, queue.remainingCapacity()); + + assertEquals("there", queue.remove()); + assertEquals(0, queue.size()); + assertEquals(1, queue.remainingCapacity()); + } + + public void testEvictingAfterThree() throws Exception { + EvictingQueue<String> queue = EvictingQueue.create(3); + assertEquals(0, queue.size()); + assertEquals(3, queue.remainingCapacity()); + + assertTrue(queue.add("one")); + assertTrue(queue.add("two")); + assertTrue(queue.add("three")); + assertEquals("one", queue.element()); + assertEquals("one", queue.peek()); + assertEquals(3, queue.size()); + assertEquals(0, queue.remainingCapacity()); + + assertTrue(queue.add("four")); + assertEquals("two", queue.element()); + assertEquals("two", queue.peek()); + assertEquals(3, queue.size()); + assertEquals(0, queue.remainingCapacity()); + + assertEquals("two", queue.remove()); + assertEquals(2, queue.size()); + assertEquals(1, queue.remainingCapacity()); + } + + public void testAddAll() throws Exception { + EvictingQueue<String> queue = EvictingQueue.create(3); + assertEquals(0, queue.size()); + assertEquals(3, queue.remainingCapacity()); + + assertTrue(queue.addAll(asList("one", "two", "three"))); + assertEquals("one", queue.element()); + assertEquals("one", queue.peek()); + assertEquals(3, queue.size()); + assertEquals(0, queue.remainingCapacity()); + + assertTrue(queue.addAll(asList("four"))); + assertEquals("two", queue.element()); + assertEquals("two", queue.peek()); + assertEquals(3, queue.size()); + assertEquals(0, queue.remainingCapacity()); + + assertEquals("two", queue.remove()); + assertEquals(2, queue.size()); + assertEquals(1, queue.remainingCapacity()); + } + + public void testNullPointerExceptions() { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicStaticMethods(EvictingQueue.class); + tester.testAllPublicConstructors(EvictingQueue.class); + EvictingQueue<String> queue = EvictingQueue.create(5); + // The queue must be non-empty so it throws a NPE correctly + queue.add("one"); + tester.testAllPublicInstanceMethods(queue); + } + + public void testSerialization() { + EvictingQueue<String> original = EvictingQueue.create(5); + original.add("one"); + original.add("two"); + original.add("three"); + + EvictingQueue<String> copy = SerializableTester.reserialize(original); + assertEquals(copy.maxSize, original.maxSize); + assertEquals("one", copy.remove()); + assertEquals("two", copy.remove()); + assertEquals("three", copy.remove()); + assertTrue(copy.isEmpty()); + } +} diff --git a/guava-tests/test/com/google/common/collect/FauxveridesTest.java b/guava-tests/test/com/google/common/collect/FauxveridesTest.java index 7d61f84..c1d861c 100644 --- a/guava-tests/test/com/google/common/collect/FauxveridesTest.java +++ b/guava-tests/test/com/google/common/collect/FauxveridesTest.java @@ -26,6 +26,8 @@ import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Objects; +import junit.framework.TestCase; + import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -35,8 +37,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import junit.framework.TestCase; - /** * Tests that all {@code public static} methods "inherited" from superclasses * are "overridden" in each immutable-collection class. This ensures, for diff --git a/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java b/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java index bd530f8..20fb592 100644 --- a/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java +++ b/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java @@ -16,15 +16,14 @@ package com.google.common.collect; +import static org.truth0.Truth.ASSERT; + import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.testing.EqualsTester; import junit.framework.TestCase; -import org.truth0.Truth; -import org.truth0.subjects.CollectionSubject; - import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -101,7 +100,7 @@ public class FilteredCollectionsTest extends TestCase { target.add(4); C addThenFilter = filter(createUnfiltered(target), EVEN); - ASSERT.that(filterThenAdd).has().allFrom(addThenFilter); + ASSERT.that(filterThenAdd).has().exactlyAs(addThenFilter); } } @@ -157,7 +156,7 @@ public class FilteredCollectionsTest extends TestCase { } catch (IllegalArgumentException expected) { } - ASSERT.that(filteredToModify).has().allFrom(filtered); + ASSERT.that(filteredToModify).has().exactlyAs(filtered); } } @@ -191,7 +190,7 @@ public class FilteredCollectionsTest extends TestCase { Predicates.not(Predicates.and(EVEN, PRIME_DIGIT))); filtered2.clear(); - ASSERT.that(unfiltered).has().allFrom(inverseFiltered); + ASSERT.that(unfiltered).has().exactlyAs(inverseFiltered); } } } @@ -342,12 +341,4 @@ public class FilteredCollectionsTest extends TestCase { /** No-op test so that the class has at least one method, making Maven's test runner happy. */ public void testNoop() { } - - // Hack for JDK5 type inference. - private static class ASSERT { - static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> that( - Collection<T> collection) { - return Truth.ASSERT.<T, Collection<T>>that(collection); - } - } } diff --git a/guava-tests/test/com/google/common/collect/FilteredMultimapTest.java b/guava-tests/test/com/google/common/collect/FilteredMultimapTest.java index e87f0b0..22e6ea6 100644 --- a/guava-tests/test/com/google/common/collect/FilteredMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/FilteredMultimapTest.java @@ -19,6 +19,8 @@ package com.google.common.collect; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Predicate; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Map; import java.util.Map.Entry; @@ -29,7 +31,7 @@ import java.util.Map.Entry; * @author Jared Levy */ @GwtIncompatible("nottested") -public class FilteredMultimapTest extends AbstractMultimapTest { +public class FilteredMultimapTest extends TestCase { private static final Predicate<Map.Entry<String, Integer>> ENTRY_PREDICATE = new Predicate<Map.Entry<String, Integer>>() { @@ -38,26 +40,13 @@ public class FilteredMultimapTest extends AbstractMultimapTest { } }; - @Override protected Multimap<String, Integer> create() { + protected Multimap<String, Integer> create() { Multimap<String, Integer> unfiltered = HashMultimap.create(); unfiltered.put("foo", 55556); unfiltered.put("badkey", 1); return Multimaps.filterEntries(unfiltered, ENTRY_PREDICATE); } - // iterators don't support remove() - // TODO(jlevy): Test logic that doesn't involve iterator.remove() - @Override public void testKeysEntrySetIterator() {} - @Override public void testGetIterator() {} - @Override public void testEntriesUpdate() {} - @Override public void testEntriesIterator() {} - @Override public void testKeySetIterator() {} - @Override public void testValuesIteratorRemove() {} - @Override public void testAsMapEntriesUpdate() {} - - // not serializable - @Override public void testSerializable() {} - private static final Predicate<String> KEY_PREDICATE = new Predicate<String>() { @Override public boolean apply(String key) { diff --git a/guava-tests/test/com/google/common/collect/FluentIterableTest.java b/guava-tests/test/com/google/common/collect/FluentIterableTest.java index 1ac520c..4925861 100644 --- a/guava-tests/test/com/google/common/collect/FluentIterableTest.java +++ b/guava-tests/test/com/google/common/collect/FluentIterableTest.java @@ -30,6 +30,9 @@ import com.google.common.collect.testing.IteratorFeature; import com.google.common.collect.testing.IteratorTester; import com.google.common.testing.NullPointerTester; +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -40,11 +43,6 @@ import java.util.SortedSet; import javax.annotation.Nullable; -import junit.framework.TestCase; - -import org.truth0.subjects.CollectionSubject; -import org.truth0.subjects.IterableSubject; - /** * Unit test for {@link FluentIterable}. * @@ -87,10 +85,8 @@ public class FluentIterableTest extends TestCase { public void testSize_collectionDoesntIterate() { List<Integer> nums = asList(1, 2, 3, 4, 5); List<Integer> collection = new ArrayList<Integer>(nums) { - @Override - public Iterator<Integer> iterator() { - fail("Don't iterate me!"); - return null; + @Override public Iterator<Integer> iterator() { + throw new AssertionFailedError("Don't iterate me!"); } }; assertEquals(5, FluentIterable.from(collection).size()); @@ -173,8 +169,8 @@ public class FluentIterableTest extends TestCase { */ public void testFilter() { - FluentIterable<String> filtered = FluentIterable.from(asList("foo", "bar")).filter( - Predicates.equalTo("foo")); + FluentIterable<String> filtered = + FluentIterable.from(asList("foo", "bar")).filter(Predicates.equalTo("foo")); List<String> expected = Collections.singletonList("foo"); List<String> actual = Lists.newArrayList(filtered); @@ -184,18 +180,16 @@ public class FluentIterableTest extends TestCase { } private static class TypeA {} - private interface TypeB {} - private static class HasBoth extends TypeA implements TypeB {} @GwtIncompatible("Iterables.filter(Iterable, Class)") public void testFilterByType() throws Exception { HasBoth hasBoth = new HasBoth(); - FluentIterable<TypeA> alist = FluentIterable.from(asList(new TypeA(), new TypeA(), hasBoth, - new TypeA())); + FluentIterable<TypeA> alist = + FluentIterable.from(asList(new TypeA(), new TypeA(), hasBoth, new TypeA())); Iterable<TypeB> blist = alist.filter(TypeB.class); - assertThat(blist).iteratesOverSequence(hasBoth); + ASSERT.that(blist).iteratesOverSequence(hasBoth); } public void testAnyMatch() { @@ -239,7 +233,8 @@ public class FluentIterableTest extends TestCase { public void testTransformWith() { List<String> input = asList("1", "2", "3"); - Iterable<Integer> iterable = FluentIterable.from(input).transform(new IntegerValueOfFunction()); + Iterable<Integer> iterable = + FluentIterable.from(input).transform(new IntegerValueOfFunction()); assertEquals(asList(1, 2, 3), Lists.newArrayList(iterable)); assertCanIterateAgain(iterable); @@ -248,7 +243,8 @@ public class FluentIterableTest extends TestCase { public void testTransformWith_poorlyBehavedTransform() { List<String> input = asList("1", null, "3"); - Iterable<Integer> iterable = FluentIterable.from(input).transform(new IntegerValueOfFunction()); + Iterable<Integer> iterable = + FluentIterable.from(input).transform(new IntegerValueOfFunction()); Iterator<Integer> resultIterator = iterable.iterator(); resultIterator.next(); @@ -256,7 +252,8 @@ public class FluentIterableTest extends TestCase { try { resultIterator.next(); fail("Transforming null to int should throw NumberFormatException"); - } catch (NumberFormatException expected) {} + } catch (NumberFormatException expected) { + } } private static final class StringValueOfFunction implements Function<Integer, String> { @@ -273,8 +270,8 @@ public class FluentIterableTest extends TestCase { assertEquals(asList("1", "2", "null", "3"), Lists.newArrayList(result)); } - private static final class RepeatedStringValueOfFunction implements - Function<Integer, List<String>> { + private static final class RepeatedStringValueOfFunction + implements Function<Integer, List<String>> { @Override public List<String> apply(Integer from) { String value = String.valueOf(from); @@ -284,8 +281,8 @@ public class FluentIterableTest extends TestCase { public void testTransformAndConcat() { List<Integer> input = asList(1, 2, 3); - Iterable<String> result = FluentIterable.from(input).transformAndConcat( - new RepeatedStringValueOfFunction()); + Iterable<String> result = + FluentIterable.from(input).transformAndConcat(new RepeatedStringValueOfFunction()); assertEquals(asList("1", "1", "2", "2", "3", "3"), Lists.newArrayList(result)); } @@ -313,7 +310,8 @@ public class FluentIterableTest extends TestCase { try { FluentIterable.from(list).first(); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testFirst_emptyList() { @@ -351,7 +349,8 @@ public class FluentIterableTest extends TestCase { try { FluentIterable.from(list).last(); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testLast_emptyList() { @@ -405,7 +404,8 @@ public class FluentIterableTest extends TestCase { public void testSkip_skipNone() { Collection<String> set = ImmutableSet.of("a", "b"); - assertEquals(Lists.newArrayList("a", "b"), Lists.newArrayList(FluentIterable.from(set).skip(0))); + assertEquals(Lists.newArrayList("a", "b"), + Lists.newArrayList(FluentIterable.from(set).skip(0))); } public void testSkip_skipNoneList() { @@ -417,8 +417,7 @@ public class FluentIterableTest extends TestCase { public void testSkip_iterator() throws Exception { new IteratorTester<Integer>(5, IteratorFeature.MODIFIABLE, Lists.newArrayList(2, 3), IteratorTester.KnownOrder.KNOWN_ORDER) { - @Override - protected Iterator<Integer> newTargetIterator() { + @Override protected Iterator<Integer> newTargetIterator() { Collection<Integer> collection = Sets.newLinkedHashSet(); Collections.addAll(collection, 1, 2, 3); return FluentIterable.from(collection).skip(1).iterator(); @@ -429,8 +428,7 @@ public class FluentIterableTest extends TestCase { public void testSkip_iteratorList() throws Exception { new IteratorTester<Integer>(5, IteratorFeature.MODIFIABLE, Lists.newArrayList(2, 3), IteratorTester.KnownOrder.KNOWN_ORDER) { - @Override - protected Iterator<Integer> newTargetIterator() { + @Override protected Iterator<Integer> newTargetIterator() { return FluentIterable.from(Lists.newArrayList(1, 2, 3)).skip(1).iterator(); } }.test(); @@ -452,7 +450,7 @@ public class FluentIterableTest extends TestCase { FluentIterable<String> tail = FluentIterable.from(set).skip(1); set.remove("b"); set.addAll(Lists.newArrayList("X", "Y", "Z")); - assertThat(tail).iteratesOverSequence("c", "X", "Y", "Z"); + ASSERT.that(tail).iteratesOverSequence("c", "X", "Y", "Z"); } public void testSkip_structurallyModifiedSkipSomeList() throws Exception { @@ -460,7 +458,7 @@ public class FluentIterableTest extends TestCase { FluentIterable<String> tail = FluentIterable.from(list).skip(1); list.subList(1, 3).clear(); list.addAll(0, Lists.newArrayList("X", "Y", "Z")); - assertThat(tail).iteratesOverSequence("Y", "Z", "a"); + ASSERT.that(tail).iteratesOverSequence("Y", "Z", "a"); } public void testSkip_structurallyModifiedSkipAll() throws Exception { @@ -476,14 +474,16 @@ public class FluentIterableTest extends TestCase { List<String> list = Lists.newArrayList("a", "b", "c"); FluentIterable<String> tail = FluentIterable.from(list).skip(2); list.subList(0, 2).clear(); - assertThat(tail).isEmpty(); + ASSERT.that(tail).isEmpty(); } + @SuppressWarnings("ReturnValueIgnored") public void testSkip_illegalArgument() { try { FluentIterable.from(asList("a", "b", "c")).skip(-1); fail("Skipping negative number of elements should throw IllegalArgumentException."); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } } public void testLimit() { @@ -495,11 +495,13 @@ public class FluentIterableTest extends TestCase { assertEquals("[foo, bar]", limited.toString()); } + @SuppressWarnings("ReturnValueIgnored") public void testLimit_illegalArgument() { try { FluentIterable.from(Lists.newArrayList("a", "b", "c")).limit(-1); fail("Passing negative number to limit(...) method should throw IllegalArgumentException"); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } } public void testIsEmpty() { @@ -526,11 +528,11 @@ public class FluentIterableTest extends TestCase { } public void testToSet() { - assertThat(fluent(1, 2, 3, 4).toSet()).has().allOf(1, 2, 3, 4).inOrder(); + ASSERT.that(fluent(1, 2, 3, 4).toSet()).has().exactly(1, 2, 3, 4).inOrder(); } public void testToSet_removeDuplicates() { - assertThat(fluent(1, 2, 1, 2).toSet()).has().allOf(1, 2).inOrder(); + ASSERT.that(fluent(1, 2, 1, 2).toSet()).has().exactly(1, 2).inOrder(); } public void testToSet_empty() { @@ -538,19 +540,20 @@ public class FluentIterableTest extends TestCase { } public void testToSortedSet() { - assertThat(fluent(1, 4, 2, 3).toSortedSet(Ordering.<Integer>natural().reverse())).has() - .allOf(4, 3, 2, 1).inOrder(); + ASSERT.that(fluent(1, 4, 2, 3).toSortedSet(Ordering.<Integer>natural().reverse())) + .has().exactly(4, 3, 2, 1).inOrder(); } public void testToSortedSet_removeDuplicates() { - assertThat(fluent(1, 4, 1, 3).toSortedSet(Ordering.<Integer>natural().reverse())).has() - .allOf(4, 3, 1).inOrder(); + ASSERT.that(fluent(1, 4, 1, 3).toSortedSet(Ordering.<Integer>natural().reverse())) + .has().exactly(4, 3, 1).inOrder(); } public void testToMap() { - assertThat(fluent(1, 2, 3).toMap(Functions.toStringFunction()).entrySet()) - .has() - .allOf(Maps.immutableEntry(1, "1"), Maps.immutableEntry(2, "2"), + ASSERT.that(fluent(1, 2, 3).toMap(Functions.toStringFunction()).entrySet()) + .has().exactly( + Maps.immutableEntry(1, "1"), + Maps.immutableEntry(2, "2"), Maps.immutableEntry(3, "3")).inOrder(); } @@ -558,26 +561,33 @@ public class FluentIterableTest extends TestCase { try { fluent(1, null, 2).toMap(Functions.constant("foo")); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testToMap_nullValue() { try { fluent(1, 2, 3).toMap(Functions.constant(null)); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testIndex() { - ImmutableListMultimap<Integer, String> expected = ImmutableListMultimap - .<Integer, String>builder().putAll(3, "one", "two").put(5, "three").put(4, "four").build(); - ImmutableListMultimap<Integer, String> index = FluentIterable.from( - asList("one", "two", "three", "four")).index(new Function<String, Integer>() { - @Override - public Integer apply(String input) { - return input.length(); - } - }); + ImmutableListMultimap<Integer, String> expected = + ImmutableListMultimap.<Integer, String>builder() + .putAll(3, "one", "two") + .put(5, "three") + .put(4, "four") + .build(); + ImmutableListMultimap<Integer, String> index = + FluentIterable.from(asList("one", "two", "three", "four")).index( + new Function<String, Integer>() { + @Override + public Integer apply(String input) { + return input.length(); + } + }); assertEquals(expected, index); } @@ -585,25 +595,29 @@ public class FluentIterableTest extends TestCase { try { fluent(1, 2, 3).index(Functions.constant(null)); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testIndex_nullValue() { try { fluent(1, null, 2).index(Functions.constant("foo")); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testUniqueIndex() { - ImmutableMap<Integer, String> expected = ImmutableMap.of(3, "two", 5, "three", 4, "four"); - ImmutableMap<Integer, String> index = FluentIterable.from(asList("two", "three", "four")) - .uniqueIndex(new Function<String, Integer>() { - @Override - public Integer apply(String input) { - return input.length(); - } - }); + ImmutableMap<Integer, String> expected = + ImmutableMap.of(3, "two", 5, "three", 4, "four"); + ImmutableMap<Integer, String> index = + FluentIterable.from(asList("two", "three", "four")).uniqueIndex( + new Function<String, Integer>() { + @Override + public Integer apply(String input) { + return input.length(); + } + }); assertEquals(expected, index); } @@ -617,14 +631,16 @@ public class FluentIterableTest extends TestCase { } }); fail(); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } } public void testUniqueIndex_nullKey() { try { fluent(1, 2, 3).uniqueIndex(Functions.constant(null)); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testUniqueIndex_nullValue() { @@ -636,20 +652,23 @@ public class FluentIterableTest extends TestCase { } }); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testCopyInto_List() { - assertThat(fluent(1, 3, 5).copyInto(Lists.newArrayList(1, 2))).has().allOf(1, 2, 1, 3, 5) - .inOrder(); + ASSERT.that(fluent(1, 3, 5).copyInto(Lists.newArrayList(1, 2))) + .has().exactly(1, 2, 1, 3, 5).inOrder(); } public void testCopyInto_Set() { - assertThat(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2))).has().allOf(1, 2, 3, 5); + ASSERT.that(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2))) + .has().exactly(1, 2, 3, 5); } public void testCopyInto_SetAllDuplicates() { - assertThat(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2, 3, 5))).has().allOf(1, 2, 3, 5); + ASSERT.that(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2, 3, 5))) + .has().exactly(1, 2, 3, 5); } public void testCopyInto_NonCollection() { @@ -663,31 +682,36 @@ public class FluentIterableTest extends TestCase { } }; - assertThat(FluentIterable.from(iterable).copyInto(list)).has().allOf(1, 2, 3, 9, 8, 7) - .inOrder(); + ASSERT.that(FluentIterable.from(iterable).copyInto(list)) + .has().exactly(1, 2, 3, 9, 8, 7).inOrder(); } public void testGet() { - assertEquals("a", FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(0)); - assertEquals("b", FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(1)); - assertEquals("c", FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(2)); + assertEquals("a", FluentIterable + .from(Lists.newArrayList("a", "b", "c")).get(0)); + assertEquals("b", FluentIterable + .from(Lists.newArrayList("a", "b", "c")).get(1)); + assertEquals("c", FluentIterable + .from(Lists.newArrayList("a", "b", "c")).get(2)); } public void testGet_outOfBounds() { try { FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(-1); fail(); - } catch (IndexOutOfBoundsException expected) {} + } catch (IndexOutOfBoundsException expected) { + } try { FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(3); fail(); - } catch (IndexOutOfBoundsException expected) {} + } catch (IndexOutOfBoundsException expected) { + } } private static void assertCanIterateAgain(Iterable<?> iterable) { - for (@SuppressWarnings("unused") - Object obj : iterable) {} + for (@SuppressWarnings("unused") Object obj : iterable) { + } } private static FluentIterable<Integer> fluent(Integer... elements) { @@ -703,16 +727,4 @@ public class FluentIterableTest extends TestCase { } }; } - - // Hack for JDK5 type inference. - private static <T> IterableSubject<? extends IterableSubject<?, T, Iterable<T>>, T, Iterable<T>> assertThat( - Iterable<T> collection) { - return ASSERT.<T, Iterable<T>>that(collection); - } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java b/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java index c485e49..bf45998 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java @@ -24,12 +24,12 @@ import com.google.common.collect.testing.TestStringCollectionGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; -import java.util.Collection; -import java.util.Collections; - import junit.framework.Test; import junit.framework.TestSuite; +import java.util.Collection; +import java.util.Collections; + /** * Tests for {@link ForwardingCollection}. * diff --git a/guava-tests/test/com/google/common/collect/ForwardingConcurrentMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingConcurrentMapTest.java index 3ca7caf..1c85e83 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingConcurrentMapTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingConcurrentMapTest.java @@ -16,11 +16,11 @@ package com.google.common.collect; +import junit.framework.TestCase; + import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import junit.framework.TestCase; - /** * Tests for {@link ForwardingConcurrentMap}. * diff --git a/guava-tests/test/com/google/common/collect/ForwardingListTest.java b/guava-tests/test/com/google/common/collect/ForwardingListTest.java index ad43117..a6a71b4 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingListTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingListTest.java @@ -22,6 +22,9 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; +import junit.framework.Test; +import junit.framework.TestSuite; + import java.util.Collection; import java.util.Collections; import java.util.Iterator; @@ -29,9 +32,6 @@ import java.util.List; import java.util.ListIterator; import java.util.RandomAccess; -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Tests for {@code ForwardingList}. * diff --git a/guava-tests/test/com/google/common/collect/ForwardingMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingMapTest.java index 4ff6577..06c4975 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingMapTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingMapTest.java @@ -28,6 +28,9 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; +import junit.framework.Test; +import junit.framework.TestSuite; + import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.HashMap; @@ -36,9 +39,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Unit test for {@link ForwardingMap}. * @@ -132,8 +132,9 @@ public class ForwardingMapTest extends ForwardingTestCase { }).named("ForwardingMap[LinkedHashMap] with standard implementations") .withFeatures(CollectionSize.ANY, MapFeature.ALLOWS_NULL_VALUES, - MapFeature.ALLOWS_NULL_KEYS, MapFeature.GENERAL_PURPOSE, - CollectionFeature.KNOWN_ORDER) + MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_ANY_NULL_QUERIES, + MapFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionFeature.KNOWN_ORDER) .createTestSuite()); suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() { @@ -149,7 +150,8 @@ public class ForwardingMapTest extends ForwardingTestCase { }).named("ForwardingMap[ImmutableMap] with standard implementations") .withFeatures( CollectionSize.ANY, MapFeature.REJECTS_DUPLICATES_AT_CREATION, - MapFeature.ALLOWS_NULL_QUERIES, CollectionFeature.KNOWN_ORDER) + MapFeature.ALLOWS_ANY_NULL_QUERIES, + CollectionFeature.KNOWN_ORDER) .createTestSuite()); return suite; diff --git a/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java b/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java index cba0485..0cf4e4a 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java @@ -23,15 +23,15 @@ import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringMultisetGenerator; +import junit.framework.Test; +import junit.framework.TestSuite; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Tests for {@link ForwardingMultiset}. * @@ -259,7 +259,7 @@ public class ForwardingMultisetTest extends ForwardingTestCase { } }).named("standardElementSet tripwire").withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, - CollectionFeature.SUPPORTS_REMOVE).createTestSuite()); + CollectionFeature.REMOVE_OPERATIONS).createTestSuite()); return suite; } diff --git a/guava-tests/test/com/google/common/collect/ForwardingObjectTest.java b/guava-tests/test/com/google/common/collect/ForwardingObjectTest.java index 8bba579..cddb2ba 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingObjectTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingObjectTest.java @@ -16,10 +16,10 @@ package com.google.common.collect; -import java.util.Set; - import junit.framework.TestCase; +import java.util.Set; + /** * Tests for {@code ForwardingObject}. * diff --git a/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java b/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java index a130723..6c3a2b6 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java @@ -23,13 +23,13 @@ import com.google.common.collect.testing.TestStringQueueGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; +import junit.framework.Test; +import junit.framework.TestSuite; + import java.util.Collection; import java.util.Collections; import java.util.Queue; -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Tests for {@code ForwardingQueue}. * diff --git a/guava-tests/test/com/google/common/collect/ForwardingSetTest.java b/guava-tests/test/com/google/common/collect/ForwardingSetTest.java index aed9a4e..c4b7b3c 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingSetTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingSetTest.java @@ -24,14 +24,14 @@ import com.google.common.collect.testing.TestStringSetGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; +import junit.framework.Test; +import junit.framework.TestSuite; + import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Tests for {@code ForwardingSet}. * diff --git a/guava-tests/test/com/google/common/collect/ForwardingSortedMapImplementsMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingSortedMapImplementsMapTest.java index f67849c..8a4d12b 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingSortedMapImplementsMapTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingSortedMapImplementsMapTest.java @@ -83,14 +83,7 @@ public class ForwardingSortedMapImplementsMapTest } catch (ClassCastException tolerated) { } } - - @Override public void testEntrySetContainsEntryIncompatibleComparableKey() { - try { - super.testEntrySetContainsEntryIncompatibleComparableKey(); - } catch (ClassCastException tolerated) { - } - } - + @Override public void testEntrySetRemoveAllNullFromEmpty() { try { super.testEntrySetRemoveAllNullFromEmpty(); diff --git a/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java index ef553b9..e2cf067 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java @@ -130,7 +130,8 @@ public class ForwardingSortedMapTest extends ForwardingMapTest { }).named("ForwardingSortedMap[SafeTreeMap] with no comparator and standard " + "implementations").withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES, - MapFeature.GENERAL_PURPOSE).createTestSuite()); + MapFeature.GENERAL_PURPOSE, CollectionFeature.SUPPORTS_ITERATOR_REMOVE) + .createTestSuite()); suite.addTest(MapTestSuiteBuilder.using(new TestStringSortedMapGenerator() { private final Comparator<String> comparator = NullsBeforeTwo.INSTANCE; @@ -146,8 +147,9 @@ public class ForwardingSortedMapTest extends ForwardingMapTest { }).named("ForwardingSortedMap[SafeTreeMap] with natural comparator and " + "standard implementations").withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES, - MapFeature.ALLOWS_NULL_KEYS, MapFeature.GENERAL_PURPOSE) - .createTestSuite()); + MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_ANY_NULL_QUERIES, + MapFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE).createTestSuite()); suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() { @Override protected SortedMap<String, String> create( Entry<String, String>[] entries) { @@ -162,7 +164,7 @@ public class ForwardingSortedMapTest extends ForwardingMapTest { }).named("ForwardingSortedMap[ImmutableSortedMap] with standard " + "implementations").withFeatures( CollectionSize.ANY, MapFeature.REJECTS_DUPLICATES_AT_CREATION, - MapFeature.ALLOWS_NULL_QUERIES) + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); return suite; diff --git a/guava-tests/test/com/google/common/collect/ForwardingSortedMultisetTest.java b/guava-tests/test/com/google/common/collect/ForwardingSortedMultisetTest.java new file mode 100644 index 0000000..092fe0d --- /dev/null +++ b/guava-tests/test/com/google/common/collect/ForwardingSortedMultisetTest.java @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2011 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import static com.google.common.collect.BoundType.CLOSED; +import static com.google.common.collect.BoundType.OPEN; + +import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder; +import com.google.common.collect.testing.google.TestStringMultisetGenerator; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; + +import javax.annotation.Nullable; + +/** + * Tests for {@link ForwardingSortedMultiset}. + * + * @author Louis Wasserman + */ +public class ForwardingSortedMultisetTest extends ForwardingMultisetTest { + static class StandardImplForwardingSortedMultiset<E> extends ForwardingSortedMultiset<E> { + private final SortedMultiset<E> backingMultiset; + + StandardImplForwardingSortedMultiset(SortedMultiset<E> backingMultiset) { + this.backingMultiset = backingMultiset; + } + + @Override + protected SortedMultiset<E> delegate() { + return backingMultiset; + } + + @Override + public SortedMultiset<E> descendingMultiset() { + return new StandardDescendingMultiset() { + + @Override + Iterator<Entry<E>> entryIterator() { + return backingMultiset + .descendingMultiset() + .entrySet() + .iterator(); + } + }; + } + + @Override + public SortedSet<E> elementSet() { + return new StandardElementSet(); + } + + @Override + public Entry<E> firstEntry() { + return standardFirstEntry(); + } + + @Override + public Entry<E> lastEntry() { + return standardLastEntry(); + } + + @Override + public Entry<E> pollFirstEntry() { + return standardPollFirstEntry(); + } + + @Override + public Entry<E> pollLastEntry() { + return standardPollLastEntry(); + } + + @Override + public SortedMultiset<E> subMultiset( + E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType) { + return standardSubMultiset(lowerBound, lowerBoundType, upperBound, upperBoundType); + } + + @Override + public int count(@Nullable Object element) { + return standardCount(element); + } + + @Override + public boolean equals(@Nullable Object object) { + return standardEquals(object); + } + + @Override + public int hashCode() { + return standardHashCode(); + } + + @Override + public boolean add(E element) { + return standardAdd(element); + } + + @Override + public boolean addAll(Collection<? extends E> collection) { + return standardAddAll(collection); + } + + @Override + public void clear() { + standardClear(); + } + + @Override + public boolean contains(@Nullable Object object) { + return standardContains(object); + } + + @Override + public boolean containsAll(Collection<?> collection) { + return standardContainsAll(collection); + } + + @Override + public boolean isEmpty() { + return standardIsEmpty(); + } + + @Override + public Iterator<E> iterator() { + return standardIterator(); + } + + @Override + public boolean remove(@Nullable Object object) { + return standardRemove(object); + } + + @Override + public boolean removeAll(Collection<?> collection) { + return standardRemoveAll(collection); + } + + @Override + public boolean retainAll(Collection<?> collection) { + return standardRetainAll(collection); + } + + @Override + public int size() { + return standardSize(); + } + + @Override + public Object[] toArray() { + return standardToArray(); + } + + @Override + public <T> T[] toArray(T[] array) { + return standardToArray(array); + } + } + + public static Test suite() { + TestSuite suite = new TestSuite(); + + suite.addTestSuite(ForwardingSortedMultisetTest.class); + suite.addTest(SortedMultisetTestSuiteBuilder + .using(new TestStringMultisetGenerator() { + @Override + protected Multiset<String> create(String[] elements) { + return new StandardImplForwardingSortedMultiset<String>( + TreeMultiset.create(Arrays.asList(elements))); + } + + @Override + public List<String> order(List<String> insertionOrder) { + return Ordering.natural().sortedCopy(insertionOrder); + } + }) + .named("ForwardingSortedMultiset with standard impls") + .withFeatures( + CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, CollectionFeature.GENERAL_PURPOSE, + CollectionFeature.ALLOWS_NULL_QUERIES) + .createTestSuite()); + + return suite; + } + + @Override + public void setUp() throws Exception { + super.setUp(); + /* + * Class parameters must be raw, so we can't create a proxy with generic type arguments. The + * created proxy only records calls and returns null, so the type is irrelevant at runtime. + */ + @SuppressWarnings("unchecked") + final SortedMultiset<String> sortedMultiset = createProxyInstance(SortedMultiset.class); + forward = new ForwardingSortedMultiset<String>() { + @Override + protected SortedMultiset<String> delegate() { + return sortedMultiset; + } + }; + } + + public void testComparator() { + forward().comparator(); + assertEquals("[comparator]", getCalls()); + } + + public void testFirstEntry() { + forward().firstEntry(); + assertEquals("[firstEntry]", getCalls()); + } + + public void testLastEntry() { + forward().lastEntry(); + assertEquals("[lastEntry]", getCalls()); + } + + public void testPollFirstEntry() { + forward().pollFirstEntry(); + assertEquals("[pollFirstEntry]", getCalls()); + } + + public void testPollLastEntry() { + forward().pollLastEntry(); + assertEquals("[pollLastEntry]", getCalls()); + } + + public void testDescendingMultiset() { + forward().descendingMultiset(); + assertEquals("[descendingMultiset]", getCalls()); + } + + public void testHeadMultiset() { + forward().headMultiset("abcd", CLOSED); + assertEquals("[headMultiset(Object,BoundType)]", getCalls()); + } + + public void testSubMultiset() { + forward().subMultiset("abcd", CLOSED, "dcba", OPEN); + assertEquals("[subMultiset(Object,BoundType,Object,BoundType)]", getCalls()); + } + + public void testTailMultiset() { + forward().tailMultiset("last", OPEN); + assertEquals("[tailMultiset(Object,BoundType)]", getCalls()); + } + + @Override + protected SortedMultiset<String> forward() { + return (SortedMultiset<String>) super.forward(); + } +} diff --git a/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java b/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java index 094fa41..3f51db3 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java +++ b/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java @@ -22,15 +22,15 @@ import com.google.common.collect.testing.TestStringSetGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; +import junit.framework.Test; +import junit.framework.TestSuite; + import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.SortedSet; -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Tests for {@code ForwardingSortedSet}. * diff --git a/guava-tests/test/com/google/common/collect/ForwardingTestCase.java b/guava-tests/test/com/google/common/collect/ForwardingTestCase.java index 4f22958..15f89e5 100644 --- a/guava-tests/test/com/google/common/collect/ForwardingTestCase.java +++ b/guava-tests/test/com/google/common/collect/ForwardingTestCase.java @@ -19,6 +19,8 @@ package com.google.common.collect; import com.google.common.base.Function; import com.google.common.base.Joiner; +import junit.framework.TestCase; + import java.lang.reflect.Array; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; @@ -32,8 +34,6 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import junit.framework.TestCase; - /** * Base test case for testing the variety of forwarding classes. * @@ -111,7 +111,7 @@ public abstract class ForwardingTestCase extends TestCase { return 0; } else if ((returnType == Set.class) || (returnType == Collection.class)) { return Collections.emptySet(); - } else if (returnType == Iterator.class){ + } else if (returnType == Iterator.class) { return Iterators.emptyModifiableIterator(); } else if (returnType.isArray()) { return Array.newInstance(returnType.getComponentType(), 0); @@ -140,7 +140,7 @@ public abstract class ForwardingTestCase extends TestCase { } } catch (Throwable cause) { throw new InvocationTargetException(cause, - method.toString() + " with args: " + Arrays.toString(parameters)); + method + " with args: " + Arrays.toString(parameters)); } } } diff --git a/guava-tests/test/com/google/common/collect/GeneralRangeTest.java b/guava-tests/test/com/google/common/collect/GeneralRangeTest.java index c21d6da..46f2e75 100644 --- a/guava-tests/test/com/google/common/collect/GeneralRangeTest.java +++ b/guava-tests/test/com/google/common/collect/GeneralRangeTest.java @@ -22,11 +22,11 @@ import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Objects; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.List; -import junit.framework.TestCase; - /** * Tests for {@code GeneralRange}. * diff --git a/guava-tests/test/com/google/common/collect/HashBiMapTest.java b/guava-tests/test/com/google/common/collect/HashBiMapTest.java index 10223bb..b547bc1 100644 --- a/guava-tests/test/com/google/common/collect/HashBiMapTest.java +++ b/guava-tests/test/com/google/common/collect/HashBiMapTest.java @@ -24,15 +24,15 @@ import com.google.common.collect.testing.features.MapFeature; import com.google.common.collect.testing.google.BiMapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringBiMapGenerator; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Tests for {@link HashBiMap}. * @@ -59,8 +59,10 @@ public class HashBiMapTest extends TestCase { .named("HashBiMap") .withFeatures(CollectionSize.ANY, CollectionFeature.SERIALIZABLE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE) .createTestSuite()); suite.addTestSuite(HashBiMapTest.class); diff --git a/guava-tests/test/com/google/common/collect/HashMultimapTest.java b/guava-tests/test/com/google/common/collect/HashMultimapTest.java index d4f4a59..d7a1f39 100644 --- a/guava-tests/test/com/google/common/collect/HashMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/HashMultimapTest.java @@ -24,18 +24,19 @@ import com.google.common.collect.testing.features.MapFeature; import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringSetMultimapGenerator; -import java.util.Map.Entry; - import junit.framework.Test; +import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.Map.Entry; + /** * Unit tests for {@link HashMultimap}. * * @author Jared Levy */ @GwtCompatible(emulated = true) -public class HashMultimapTest extends AbstractSetMultimapTest { +public class HashMultimapTest extends TestCase { @GwtIncompatible("suite") public static Test suite() { @@ -54,8 +55,10 @@ public class HashMultimapTest extends AbstractSetMultimapTest { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionFeature.SERIALIZABLE, CollectionSize.ANY) .createTestSuite()); @@ -63,10 +66,6 @@ public class HashMultimapTest extends AbstractSetMultimapTest { return suite; } - @Override protected Multimap<String, Integer> create() { - return HashMultimap.create(); - } - /* * The behavior of toString() is tested by TreeMultimap, which shares a * lot of code with HashMultimap and has deterministic iteration order. @@ -81,7 +80,10 @@ public class HashMultimapTest extends AbstractSetMultimapTest { } public void testCreateFromMultimap() { - Multimap<String, Integer> multimap = createSample(); + HashMultimap<String, Integer> multimap = HashMultimap.create(); + multimap.put("foo", 1); + multimap.put("bar", 2); + multimap.put("foo", 3); HashMultimap<String, Integer> copy = HashMultimap.create(multimap); assertEquals(multimap, copy); assertEquals(2, copy.expectedValuesPerKey); diff --git a/guava-tests/test/com/google/common/collect/HashMultisetTest.java b/guava-tests/test/com/google/common/collect/HashMultisetTest.java index cdac03b..4da9513 100644 --- a/guava-tests/test/com/google/common/collect/HashMultisetTest.java +++ b/guava-tests/test/com/google/common/collect/HashMultisetTest.java @@ -22,16 +22,18 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.google.MultisetFeature; import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringMultisetGenerator; import com.google.common.testing.SerializableTester; -import java.io.Serializable; -import java.util.Arrays; - import junit.framework.Test; +import junit.framework.TestCase; import junit.framework.TestSuite; +import java.io.Serializable; +import java.util.Arrays; + /** * Unit test for {@link HashMultiset}. * @@ -39,16 +41,18 @@ import junit.framework.TestSuite; * @author Jared Levy */ @GwtCompatible(emulated = true) -public class HashMultisetTest extends AbstractMultisetTest { +public class HashMultisetTest extends TestCase { @GwtIncompatible("suite") public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(MultisetTestSuiteBuilder.using(hashMultisetGenerator()) .withFeatures(CollectionSize.ANY, + CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.SERIALIZABLE, - CollectionFeature.GENERAL_PURPOSE) + CollectionFeature.GENERAL_PURPOSE, + MultisetFeature.ENTRIES_ARE_VIEWS) .named("HashMultiset") .createTestSuite()); suite.addTestSuite(HashMultisetTest.class); @@ -63,10 +67,6 @@ public class HashMultisetTest extends AbstractMultisetTest { }; } - @Override protected <E> Multiset<E> create() { - return HashMultiset.create(); - } - public void testCreate() { Multiset<String> multiset = HashMultiset.create(); multiset.add("foo", 2); @@ -123,39 +123,4 @@ public class HashMultisetTest extends AbstractMultisetTest { * which shares a lot of code with HashMultiset and has deterministic * iteration order. */ - - @Override - @GwtIncompatible( - "http://code.google.com/p/google-web-toolkit/issues/detail?id=3421") - public void testEntryAfterRemove() { - super.testEntryAfterRemove(); - } - - @Override - @GwtIncompatible( - "http://code.google.com/p/google-web-toolkit/issues/detail?id=3421") - public void testEntryAfterClear() { - super.testEntryAfterClear(); - } - - @Override - @GwtIncompatible( - "http://code.google.com/p/google-web-toolkit/issues/detail?id=3421") - public void testEntryAfterEntrySetClear() { - super.testEntryAfterEntrySetClear(); - } - - @Override - @GwtIncompatible( - "http://code.google.com/p/google-web-toolkit/issues/detail?id=3421") - public void testEntryAfterEntrySetIteratorRemove() { - super.testEntryAfterEntrySetIteratorRemove(); - } - - @Override - @GwtIncompatible( - "http://code.google.com/p/google-web-toolkit/issues/detail?id=3421") - public void testEntryAfterElementSetIteratorRemove() { - super.testEntryAfterElementSetIteratorRemove(); - } } diff --git a/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java index 5527026..3c7111a 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java @@ -26,21 +26,22 @@ import com.google.common.collect.testing.MapInterfaceTest; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; +import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapCopyOfGenerator; import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapGenerator; import com.google.common.collect.testing.google.BiMapInverseTester; import com.google.common.collect.testing.google.BiMapTestSuiteBuilder; import com.google.common.testing.SerializableTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Tests for {@link ImmutableBiMap}. * @@ -60,43 +61,57 @@ public class ImmutableBiMapTest extends TestCase { suite.addTestSuite(CreationTests.class); suite.addTestSuite(BiMapSpecificTests.class); - suite.addTest(BiMapTestSuiteBuilder - .using(new ImmutableBiMapGenerator()) + suite.addTest(BiMapTestSuiteBuilder.using(new ImmutableBiMapGenerator()) .named("ImmutableBiMap") - .withFeatures(CollectionSize.ANY, CollectionFeature.SERIALIZABLE, - CollectionFeature.KNOWN_ORDER, MapFeature.REJECTS_DUPLICATES_AT_CREATION, - MapFeature.ALLOWS_NULL_QUERIES) - .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods()).createTestSuite()); + .withFeatures(CollectionSize.ANY, + CollectionFeature.SERIALIZABLE, + CollectionFeature.KNOWN_ORDER, + MapFeature.REJECTS_DUPLICATES_AT_CREATION, + MapFeature.ALLOWS_ANY_NULL_QUERIES) + .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods()) + .createTestSuite()); + suite.addTest(BiMapTestSuiteBuilder.using(new ImmutableBiMapCopyOfGenerator()) + .named("ImmutableBiMap.copyOf") + .withFeatures(CollectionSize.ANY, + CollectionFeature.SERIALIZABLE, + CollectionFeature.KNOWN_ORDER, + MapFeature.ALLOWS_ANY_NULL_QUERIES) + .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods()) + .createTestSuite()); return suite; } - public static abstract class AbstractMapTests<K, V> extends MapInterfaceTest<K, V> { + public static abstract class AbstractMapTests<K, V> + extends MapInterfaceTest<K, V> { public AbstractMapTests() { super(false, false, false, false, false); } - @Override - protected Map<K, V> makeEmptyMap() { + @Override protected Map<K, V> makeEmptyMap() { throw new UnsupportedOperationException(); } private static final Joiner joiner = Joiner.on(", "); - @Override - protected void assertMoreInvariants(Map<K, V> map) { + @Override protected void assertMoreInvariants(Map<K, V> map) { BiMap<K, V> bimap = (BiMap<K, V>) map; for (Entry<K, V> entry : map.entrySet()) { - assertEquals(entry.getKey() + "=" + entry.getValue(), entry.toString()); + assertEquals(entry.getKey() + "=" + entry.getValue(), + entry.toString()); assertEquals(entry.getKey(), bimap.inverse().get(entry.getValue())); } - assertEquals("{" + joiner.join(map.entrySet()) + "}", map.toString()); - assertEquals("[" + joiner.join(map.entrySet()) + "]", map.entrySet().toString()); - assertEquals("[" + joiner.join(map.keySet()) + "]", map.keySet().toString()); - assertEquals("[" + joiner.join(map.values()) + "]", map.values().toString()); + assertEquals("{" + joiner.join(map.entrySet()) + "}", + map.toString()); + assertEquals("[" + joiner.join(map.entrySet()) + "]", + map.entrySet().toString()); + assertEquals("[" + joiner.join(map.keySet()) + "]", + map.keySet().toString()); + assertEquals("[" + joiner.join(map.values()) + "]", + map.values().toString()); assertEquals(Sets.newHashSet(map.entrySet()), map.entrySet()); assertEquals(Sets.newHashSet(map.keySet()), map.keySet()); @@ -104,73 +119,78 @@ public class ImmutableBiMapTest extends TestCase { } public static class MapTests extends AbstractMapTests<String, Integer> { - @Override - protected Map<String, Integer> makeEmptyMap() { + @Override protected Map<String, Integer> makeEmptyMap() { return ImmutableBiMap.of(); } - @Override - protected Map<String, Integer> makePopulatedMap() { + @Override protected Map<String, Integer> makePopulatedMap() { return ImmutableBiMap.of("one", 1, "two", 2, "three", 3); } - @Override - protected String getKeyNotInPopulatedMap() { + @Override protected String getKeyNotInPopulatedMap() { return "minus one"; } - @Override - protected Integer getValueNotInPopulatedMap() { + @Override protected Integer getValueNotInPopulatedMap() { return -1; } } - public static class InverseMapTests extends AbstractMapTests<String, Integer> { - @Override - protected Map<String, Integer> makeEmptyMap() { + public static class InverseMapTests + extends AbstractMapTests<String, Integer> { + @Override protected Map<String, Integer> makeEmptyMap() { return ImmutableBiMap.of(); } - @Override - protected Map<String, Integer> makePopulatedMap() { + @Override protected Map<String, Integer> makePopulatedMap() { return ImmutableBiMap.of(1, "one", 2, "two", 3, "three").inverse(); } - @Override - protected String getKeyNotInPopulatedMap() { + @Override protected String getKeyNotInPopulatedMap() { return "minus one"; } - @Override - protected Integer getValueNotInPopulatedMap() { + @Override protected Integer getValueNotInPopulatedMap() { return -1; } } public static class CreationTests extends TestCase { public void testEmptyBuilder() { - ImmutableBiMap<String, Integer> map = new Builder<String, Integer>().build(); + ImmutableBiMap<String, Integer> map + = new Builder<String, Integer>().build(); assertEquals(Collections.<String, Integer>emptyMap(), map); assertEquals(Collections.<Integer, String>emptyMap(), map.inverse()); assertSame(ImmutableBiMap.of(), map); } public void testSingletonBuilder() { - ImmutableBiMap<String, Integer> map = new Builder<String, Integer>().put("one", 1).build(); + ImmutableBiMap<String, Integer> map = new Builder<String, Integer>() + .put("one", 1) + .build(); assertMapEquals(map, "one", 1); assertMapEquals(map.inverse(), 1, "one"); } public void testBuilder() { - ImmutableBiMap<String, Integer> map = ImmutableBiMap.<String, Integer>builder().put("one", 1) - .put("two", 2).put("three", 3).put("four", 4).put("five", 5).build(); - assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); - assertMapEquals(map.inverse(), 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); + ImmutableBiMap<String, Integer> map + = ImmutableBiMap.<String, Integer>builder() + .put("one", 1) + .put("two", 2) + .put("three", 3) + .put("four", 4) + .put("five", 5) + .build(); + assertMapEquals(map, + "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); + assertMapEquals(map.inverse(), + 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); } public void testBuilderPutAllWithEmptyMap() { - ImmutableBiMap<String, Integer> map = new Builder<String, Integer>().putAll( - Collections.<String, Integer>emptyMap()).build(); + ImmutableBiMap<String, Integer> map = new Builder<String, Integer>() + .putAll(Collections.<String, Integer>emptyMap()) + .build(); assertEquals(Collections.<String, Integer>emptyMap(), map); } @@ -183,21 +203,32 @@ public class ImmutableBiMapTest extends TestCase { moreToPut.put("four", 4); moreToPut.put("five", 5); - ImmutableBiMap<String, Integer> map = new Builder<String, Integer>().putAll(toPut) - .putAll(moreToPut).build(); - assertMapEquals(map, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); - assertMapEquals(map.inverse(), 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); + ImmutableBiMap<String, Integer> map = new Builder<String, Integer>() + .putAll(toPut) + .putAll(moreToPut) + .build(); + assertMapEquals(map, + "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); + assertMapEquals(map.inverse(), + 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); } public void testBuilderReuse() { Builder<String, Integer> builder = new Builder<String, Integer>(); - ImmutableBiMap<String, Integer> mapOne = builder.put("one", 1).put("two", 2).build(); - ImmutableBiMap<String, Integer> mapTwo = builder.put("three", 3).put("four", 4).build(); + ImmutableBiMap<String, Integer> mapOne = builder + .put("one", 1) + .put("two", 2) + .build(); + ImmutableBiMap<String, Integer> mapTwo = builder + .put("three", 3) + .put("four", 4) + .build(); assertMapEquals(mapOne, "one", 1, "two", 2); assertMapEquals(mapOne.inverse(), 1, "one", 2, "two"); assertMapEquals(mapTwo, "one", 1, "two", 2, "three", 3, "four", 4); - assertMapEquals(mapTwo.inverse(), 1, "one", 2, "two", 3, "three", 4, "four"); + assertMapEquals(mapTwo.inverse(), + 1, "one", 2, "two", 3, "three", 4, "four"); } public void testBuilderPutNullKey() { @@ -205,7 +236,8 @@ public class ImmutableBiMapTest extends TestCase { try { builder.put(null, 1); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testBuilderPutNullValue() { @@ -213,7 +245,8 @@ public class ImmutableBiMapTest extends TestCase { try { builder.put("one", null); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testBuilderPutNullKeyViaPutAll() { @@ -221,7 +254,8 @@ public class ImmutableBiMapTest extends TestCase { try { builder.putAll(Collections.<String, Integer>singletonMap(null, 1)); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testBuilderPutNullValueViaPutAll() { @@ -229,11 +263,14 @@ public class ImmutableBiMapTest extends TestCase { try { builder.putAll(Collections.<String, Integer>singletonMap("one", null)); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testPuttingTheSameKeyTwiceThrowsOnBuild() { - Builder<String, Integer> builder = new Builder<String, Integer>().put("one", 1).put("one", 1); // throwing on this line would be even better + Builder<String, Integer> builder = new Builder<String, Integer>() + .put("one", 1) + .put("one", 1); // throwing on this line would be even better try { builder.build(); @@ -244,46 +281,67 @@ public class ImmutableBiMapTest extends TestCase { } public void testOf() { - assertMapEquals(ImmutableBiMap.of("one", 1), "one", 1); - assertMapEquals(ImmutableBiMap.of("one", 1).inverse(), 1, "one"); - assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2), "one", 1, "two", 2); - assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2).inverse(), 1, "one", 2, "two"); - assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2, "three", 3), "one", 1, "two", 2, - "three", 3); - assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2, "three", 3).inverse(), 1, "one", 2, - "two", 3, "three"); - assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4), "one", 1, - "two", 2, "three", 3, "four", 4); - assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4).inverse(), 1, - "one", 2, "two", 3, "three", 4, "four"); - assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4, "five", 5), + assertMapEquals( + ImmutableBiMap.of("one", 1), + "one", 1); + assertMapEquals( + ImmutableBiMap.of("one", 1).inverse(), + 1, "one"); + assertMapEquals( + ImmutableBiMap.of("one", 1, "two", 2), + "one", 1, "two", 2); + assertMapEquals( + ImmutableBiMap.of("one", 1, "two", 2).inverse(), + 1, "one", 2, "two"); + assertMapEquals( + ImmutableBiMap.of("one", 1, "two", 2, "three", 3), + "one", 1, "two", 2, "three", 3); + assertMapEquals( + ImmutableBiMap.of("one", 1, "two", 2, "three", 3).inverse(), + 1, "one", 2, "two", 3, "three"); + assertMapEquals( + ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4), + "one", 1, "two", 2, "three", 3, "four", 4); + assertMapEquals( + ImmutableBiMap.of( + "one", 1, "two", 2, "three", 3, "four", 4).inverse(), + 1, "one", 2, "two", 3, "three", 4, "four"); + assertMapEquals( + ImmutableBiMap.of( + "one", 1, "two", 2, "three", 3, "four", 4, "five", 5), "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); - assertMapEquals(ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4, "five", 5) - .inverse(), 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); + assertMapEquals( + ImmutableBiMap.of( + "one", 1, "two", 2, "three", 3, "four", 4, "five", 5).inverse(), + 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); } public void testOfNullKey() { try { ImmutableBiMap.of(null, 1); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } try { ImmutableBiMap.of("one", 1, null, 2); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testOfNullValue() { try { ImmutableBiMap.of("one", null); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } try { ImmutableBiMap.of("one", 1, "two", null); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testOfWithDuplicateKey() { @@ -296,16 +354,16 @@ public class ImmutableBiMapTest extends TestCase { } public void testCopyOfEmptyMap() { - ImmutableBiMap<String, Integer> copy = ImmutableBiMap.copyOf(Collections - .<String, Integer>emptyMap()); + ImmutableBiMap<String, Integer> copy + = ImmutableBiMap.copyOf(Collections.<String, Integer>emptyMap()); assertEquals(Collections.<String, Integer>emptyMap(), copy); assertSame(copy, ImmutableBiMap.copyOf(copy)); assertSame(ImmutableBiMap.of(), copy); } public void testCopyOfSingletonMap() { - ImmutableBiMap<String, Integer> copy = ImmutableBiMap.copyOf(Collections.singletonMap("one", - 1)); + ImmutableBiMap<String, Integer> copy + = ImmutableBiMap.copyOf(Collections.singletonMap("one", 1)); assertMapEquals(copy, "one", 1); assertSame(copy, ImmutableBiMap.copyOf(copy)); } @@ -331,23 +389,35 @@ public class ImmutableBiMapTest extends TestCase { Map<String, Integer> hashMap = Maps.newLinkedHashMap(); hashMap.put("one", 1); hashMap.put("two", 2); - ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, - "two", 2)); + ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf( + ImmutableMap.of("one", 1, "two", 2)); assertMapEquals(bimap, "one", 1, "two", 2); assertMapEquals(bimap.inverse(), 1, "one", 2, "two"); } public void testFromImmutableMap() { - ImmutableBiMap<String, Integer> bimap = ImmutableBiMap - .copyOf(new ImmutableMap.Builder<String, Integer>().put("one", 1).put("two", 2) - .put("three", 3).put("four", 4).put("five", 5).build()); - assertMapEquals(bimap, "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); - assertMapEquals(bimap.inverse(), 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); + ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf( + new ImmutableMap.Builder<String, Integer>() + .put("one", 1) + .put("two", 2) + .put("three", 3) + .put("four", 4) + .put("five", 5) + .build()); + assertMapEquals(bimap, + "one", 1, "two", 2, "three", 3, "four", 4, "five", 5); + assertMapEquals(bimap.inverse(), + 1, "one", 2, "two", 3, "three", 4, "four", 5, "five"); } public void testDuplicateValues() { - ImmutableMap<String, Integer> map = new ImmutableMap.Builder<String, Integer>().put("one", 1) - .put("two", 2).put("uno", 1).put("dos", 2).build(); + ImmutableMap<String, Integer> map + = new ImmutableMap.Builder<String, Integer>() + .put("one", 1) + .put("two", 2) + .put("uno", 1) + .put("dos", 2) + .build(); try { ImmutableBiMap.copyOf(map); @@ -362,8 +432,8 @@ public class ImmutableBiMapTest extends TestCase { @SuppressWarnings("deprecation") public void testForcePut() { - ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, - "two", 2)); + ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf( + ImmutableMap.of("one", 1, "two", 2)); try { bimap.forcePut("three", 3); fail(); @@ -371,24 +441,24 @@ public class ImmutableBiMapTest extends TestCase { } public void testKeySet() { - ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, - "two", 2, "three", 3, "four", 4)); + ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf( + ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4)); Set<String> keys = bimap.keySet(); assertEquals(Sets.newHashSet("one", "two", "three", "four"), keys); - ASSERT.<String, Set<String>>that(keys).has().allOf("one", "two", "three", "four").inOrder(); + ASSERT.that(keys).has().exactly("one", "two", "three", "four").inOrder(); } public void testValues() { - ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, - "two", 2, "three", 3, "four", 4)); + ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf( + ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4)); Set<Integer> values = bimap.values(); assertEquals(Sets.newHashSet(1, 2, 3, 4), values); - ASSERT.<Integer, Set<Integer>>that(values).has().allOf(1, 2, 3, 4).inOrder(); + ASSERT.that(values).has().exactly(1, 2, 3, 4).inOrder(); } public void testDoubleInverse() { - ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, - "two", 2)); + ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf( + ImmutableMap.of("one", 1, "two", 2)); assertSame(bimap, bimap.inverse().inverse()); } @@ -400,9 +470,10 @@ public class ImmutableBiMapTest extends TestCase { @GwtIncompatible("SerializableTester") public void testSerialization() { - ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(ImmutableMap.of("one", 1, - "two", 2)); - ImmutableBiMap<String, Integer> copy = SerializableTester.reserializeAndAssert(bimap); + ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf( + ImmutableMap.of("one", 1, "two", 2)); + ImmutableBiMap<String, Integer> copy = + SerializableTester.reserializeAndAssert(bimap); assertEquals(Integer.valueOf(1), copy.get("one")); assertEquals("one", copy.inverse().get(1)); assertSame(copy, copy.inverse().inverse()); @@ -412,14 +483,16 @@ public class ImmutableBiMapTest extends TestCase { public void testInverseSerialization() { ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf( ImmutableMap.of(1, "one", 2, "two")).inverse(); - ImmutableBiMap<String, Integer> copy = SerializableTester.reserializeAndAssert(bimap); + ImmutableBiMap<String, Integer> copy = + SerializableTester.reserializeAndAssert(bimap); assertEquals(Integer.valueOf(1), copy.get("one")); assertEquals("one", copy.inverse().get(1)); assertSame(copy, copy.inverse().inverse()); } } - private static <K, V> void assertMapEquals(Map<K, V> map, Object... alternatingKeysAndValues) { + private static <K, V> void assertMapEquals(Map<K, V> map, + Object... alternatingKeysAndValues) { int i = 0; for (Entry<K, V> entry : map.entrySet()) { assertEquals(alternatingKeysAndValues[i++], entry.getKey()); diff --git a/guava-tests/test/com/google/common/collect/ImmutableClassToInstanceMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableClassToInstanceMapTest.java index f0d1124..74ca804 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableClassToInstanceMapTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableClassToInstanceMapTest.java @@ -23,15 +23,15 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Unit test for {@link ImmutableClassToInstanceMap}. * @@ -64,7 +64,8 @@ public class ImmutableClassToInstanceMapTest extends TestCase { MapFeature.RESTRICTS_KEYS, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY, - MapFeature.ALLOWS_NULL_QUERIES) + MapFeature.ALLOWS_ANY_NULL_QUERIES, + CollectionFeature.SERIALIZABLE) .createTestSuite()); return suite; diff --git a/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java index b44a2dc..3bcb17a 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java @@ -19,6 +19,7 @@ package com.google.common.collect; import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.AnEnum; import com.google.common.collect.testing.Helpers; import com.google.common.collect.testing.MapTestSuiteBuilder; @@ -26,22 +27,19 @@ import com.google.common.collect.testing.TestEnumMapGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; -import java.util.Collection; -import java.util.Map; -import java.util.Map.Entry; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.truth0.subjects.CollectionSubject; +import java.util.Map; +import java.util.Map.Entry; /** * Tests for {@code ImmutableEnumMap}. * * @author Louis Wasserman */ -@GwtCompatible +@GwtCompatible(emulated = true) public class ImmutableEnumMapTest extends TestCase { public static class ImmutableEnumMapGenerator extends TestEnumMapGenerator { @Override @@ -54,6 +52,7 @@ public class ImmutableEnumMapTest extends TestCase { } } + @GwtIncompatible("suite") public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(MapTestSuiteBuilder.using(new ImmutableEnumMapGenerator()) @@ -75,15 +74,9 @@ public class ImmutableEnumMapTest extends TestCase { ImmutableMap<AnEnum, String> map = Maps.immutableEnumMap( ImmutableMap.of(AnEnum.C, "c", AnEnum.A, "a", AnEnum.E, "e")); - assertThat(map.entrySet()).has().allOf( + ASSERT.that(map.entrySet()).has().exactly( Helpers.mapEntry(AnEnum.A, "a"), Helpers.mapEntry(AnEnum.C, "c"), Helpers.mapEntry(AnEnum.E, "e")).inOrder(); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java b/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java index 4e4f700..3e680f1 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java @@ -16,6 +16,8 @@ package com.google.common.collect; +import static org.truth0.Truth.ASSERT; + import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.ImmutableListMultimap.Builder; @@ -26,18 +28,17 @@ import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringListMultimapGenerator; import com.google.common.collect.testing.google.UnmodifiableCollectionTests; import com.google.common.testing.EqualsTester; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.SerializableTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Map.Entry; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Tests for {@link ImmutableListMultimap}. * @@ -62,7 +63,7 @@ public class ImmutableListMultimapTest extends TestCase { suite.addTest(ListMultimapTestSuiteBuilder.using(new ImmutableListMultimapGenerator()) .named("ImmutableListMultimap") .withFeatures( - MapFeature.ALLOWS_NULL_QUERIES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, CollectionFeature.SERIALIZABLE, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY) @@ -262,10 +263,10 @@ public class ImmutableListMultimapTest extends TestCase { builder.put("a", 2); builder.put("b", 6); ImmutableListMultimap<String, Integer> multimap = builder.build(); - FluentAsserts.assertThat(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder(); - FluentAsserts.assertThat(multimap.values()).has().allOf(2, 4, 3, 6, 5, 2).inOrder(); - FluentAsserts.assertThat(multimap.get("a")).has().allOf(5, 2).inOrder(); - FluentAsserts.assertThat(multimap.get("b")).has().allOf(3, 6).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("d", "c", "b", "a").inOrder(); + ASSERT.that(multimap.values()).has().exactly(2, 4, 3, 6, 5, 2).inOrder(); + ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); + ASSERT.that(multimap.get("b")).has().exactly(3, 6).inOrder(); } public void testBuilderOrderKeysByDuplicates() { @@ -284,10 +285,10 @@ public class ImmutableListMultimapTest extends TestCase { builder.put("a", 2); builder.put("bb", 6); ImmutableListMultimap<String, Integer> multimap = builder.build(); - FluentAsserts.assertThat(multimap.keySet()).has().allOf("d", "a", "bb", "cc").inOrder(); - FluentAsserts.assertThat(multimap.values()).has().allOf(2, 5, 2, 3, 6, 4).inOrder(); - FluentAsserts.assertThat(multimap.get("a")).has().allOf(5, 2).inOrder(); - FluentAsserts.assertThat(multimap.get("bb")).has().allOf(3, 6).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("d", "a", "bb", "cc").inOrder(); + ASSERT.that(multimap.values()).has().exactly(2, 5, 2, 3, 6, 4).inOrder(); + ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); + ASSERT.that(multimap.get("bb")).has().exactly(3, 6).inOrder(); } public void testBuilderOrderValuesBy() { @@ -301,10 +302,10 @@ public class ImmutableListMultimapTest extends TestCase { builder.put("a", 2); builder.put("b", 6); ImmutableListMultimap<String, Integer> multimap = builder.build(); - FluentAsserts.assertThat(multimap.keySet()).has().allOf("b", "d", "a", "c").inOrder(); - FluentAsserts.assertThat(multimap.values()).has().allOf(6, 3, 2, 5, 2, 4).inOrder(); - FluentAsserts.assertThat(multimap.get("a")).has().allOf(5, 2).inOrder(); - FluentAsserts.assertThat(multimap.get("b")).has().allOf(6, 3).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("b", "d", "a", "c").inOrder(); + ASSERT.that(multimap.values()).has().exactly(6, 3, 2, 5, 2, 4).inOrder(); + ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); + ASSERT.that(multimap.get("b")).has().exactly(6, 3).inOrder(); } public void testBuilderOrderKeysAndValuesBy() { @@ -319,10 +320,10 @@ public class ImmutableListMultimapTest extends TestCase { builder.put("a", 2); builder.put("b", 6); ImmutableListMultimap<String, Integer> multimap = builder.build(); - FluentAsserts.assertThat(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder(); - FluentAsserts.assertThat(multimap.values()).has().allOf(2, 4, 6, 3, 5, 2).inOrder(); - FluentAsserts.assertThat(multimap.get("a")).has().allOf(5, 2).inOrder(); - FluentAsserts.assertThat(multimap.get("b")).has().allOf(6, 3).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("d", "c", "b", "a").inOrder(); + ASSERT.that(multimap.values()).has().exactly(2, 4, 6, 3, 5, 2).inOrder(); + ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); + ASSERT.that(multimap.get("b")).has().exactly(6, 3).inOrder(); } public void testCopyOf() { diff --git a/guava-tests/test/com/google/common/collect/ImmutableListTest.java b/guava-tests/test/com/google/common/collect/ImmutableListTest.java index ae600d1..57c64d2 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableListTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableListTest.java @@ -41,6 +41,10 @@ import com.google.common.collect.testing.testers.ListHashCodeTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -52,10 +56,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Unit test for {@link ImmutableList}. * @@ -262,7 +262,7 @@ public class ImmutableListTest extends TestCase { try { ImmutableList.copyOf((String[]) null); fail(); - } catch(NullPointerException expected) { + } catch (NullPointerException expected) { } } @@ -338,7 +338,7 @@ public class ImmutableListTest extends TestCase { try { ImmutableList.copyOf((Iterator<String>) null); fail(); - } catch(NullPointerException expected) { + } catch (NullPointerException expected) { } } @@ -450,8 +450,9 @@ public class ImmutableListTest extends TestCase { assertTrue(concurrentlyMutatedList.getAllStates() .contains(copyOfIterable)); - // Check that it's a RegularImmutableList iff it is nonempty: - assertEquals(copyOfIterable.size() == 0, copyOfIterable.isEmpty()); + // Check that we didn't end up with a RegularImmutableList of size 1. + assertEquals(copyOfIterable.size() == 1, + copyOfIterable instanceof SingletonImmutableList); } private static void runConcurrentlyMutatedTest(WrapWithIterable wrap) { @@ -536,7 +537,7 @@ public class ImmutableListTest extends TestCase { void perform(List<Integer> list); } - static final ListFrobber add(final int element) { + static ListFrobber add(final int element) { return new ListFrobber() { @Override public void perform(List<Integer> list) { @@ -545,7 +546,7 @@ public class ImmutableListTest extends TestCase { }; } - static final ListFrobber remove() { + static ListFrobber remove() { return new ListFrobber() { @Override public void perform(List<Integer> list) { @@ -554,7 +555,7 @@ public class ImmutableListTest extends TestCase { }; } - static final ListFrobber nop() { + static ListFrobber nop() { return new ListFrobber() { @Override public void perform(List<Integer> list) { diff --git a/guava-tests/test/com/google/common/collect/ImmutableMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableMapTest.java index 8ed1e85..e79ab50 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableMapTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableMapTest.java @@ -35,6 +35,7 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfEnumMapGenerator; +import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfGenerator; import com.google.common.collect.testing.google.MapGenerators.ImmutableMapEntryListGenerator; import com.google.common.collect.testing.google.MapGenerators.ImmutableMapGenerator; import com.google.common.collect.testing.google.MapGenerators.ImmutableMapKeyListGenerator; @@ -44,6 +45,10 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.io.Serializable; import java.util.Collection; import java.util.Collections; @@ -52,10 +57,6 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Tests for {@link ImmutableMap}. * @@ -80,6 +81,15 @@ public class ImmutableMapTest extends TestCase { .named("ImmutableMap") .createTestSuite()); + suite.addTest(MapTestSuiteBuilder.using(new ImmutableMapCopyOfGenerator()) + .withFeatures( + CollectionSize.ANY, + CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS, + CollectionFeature.KNOWN_ORDER, + CollectionFeature.ALLOWS_NULL_QUERIES) + .named("ImmutableMap.copyOf") + .createTestSuite()); + suite.addTest(MapTestSuiteBuilder.using(new ImmutableMapCopyOfEnumMapGenerator()) .withFeatures( CollectionSize.ANY, @@ -373,6 +383,57 @@ public class ImmutableMapTest extends TestCase { assertMapEquals(mapTwo, "one", 1, "two", 2, "three", 3, "four", 4); } + public void testBuilderPutNullKeyFailsAtomically() { + Builder<String, Integer> builder = new Builder<String, Integer>(); + try { + builder.put(null, 1); + fail(); + } catch (NullPointerException expected) {} + builder.put("foo", 2); + assertMapEquals(builder.build(), "foo", 2); + } + + public void testBuilderPutImmutableEntryWithNullKeyFailsAtomically() { + Builder<String, Integer> builder = new Builder<String, Integer>(); + try { + builder.put(Maps.immutableEntry((String) null, 1)); + fail(); + } catch (NullPointerException expected) {} + builder.put("foo", 2); + assertMapEquals(builder.build(), "foo", 2); + } + + // for GWT compatibility + static class SimpleEntry<K, V> extends AbstractMapEntry<K, V> { + public K key; + public V value; + + SimpleEntry(K key, V value) { + this.key = key; + this.value = value; + } + + @Override + public K getKey() { + return key; + } + + @Override + public V getValue() { + return value; + } + } + + public void testBuilderPutMutableEntryWithNullKeyFailsAtomically() { + Builder<String, Integer> builder = new Builder<String, Integer>(); + try { + builder.put(new SimpleEntry<String, Integer>(null, 1)); + fail(); + } catch (NullPointerException expected) {} + builder.put("foo", 2); + assertMapEquals(builder.build(), "foo", 2); + } + public void testBuilderPutNullKey() { Builder<String, Integer> builder = new Builder<String, Integer>(); try { @@ -418,7 +479,6 @@ public class ImmutableMapTest extends TestCase { builder.build(); fail(); } catch (IllegalArgumentException expected) { - assertEquals("duplicate key: one", expected.getMessage()); } } @@ -473,7 +533,6 @@ public class ImmutableMapTest extends TestCase { ImmutableMap.of("one", 1, "one", 1); fail(); } catch (IllegalArgumentException expected) { - assertEquals("duplicate key: one", expected.getMessage()); } } @@ -526,6 +585,7 @@ public class ImmutableMapTest extends TestCase { ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1); ImmutableSetMultimap<String, Integer> multimap1 = map.asMultimap(); ImmutableSetMultimap<String, Integer> multimap2 = map.asMultimap(); + assertEquals(1, multimap1.asMap().size()); assertSame(multimap1, multimap2); } diff --git a/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java b/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java index d5a8e66..d02359c 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java @@ -23,11 +23,11 @@ import com.google.common.collect.testing.SampleElements.Unhashables; import com.google.common.collect.testing.UnhashableObject; import com.google.common.testing.EqualsTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Map.Entry; -import junit.framework.TestCase; - /** * Tests for {@link ImmutableMultimap}. * diff --git a/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java b/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java index 8df9d07..5e94ac3 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java @@ -36,6 +36,10 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -43,12 +47,6 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.truth0.subjects.CollectionSubject; - /** * Tests for {@link ImmutableMultiset}. * @@ -454,7 +452,7 @@ public class ImmutableMultisetTest extends TestCase { public void testSerialization_multiple() { Collection<String> c = ImmutableMultiset.of("a", "b", "a"); Collection<String> copy = SerializableTester.reserializeAndAssert(c); - assertThat(copy).has().allOf("a", "a", "b").inOrder(); + ASSERT.that(copy).has().exactly("a", "a", "b").inOrder(); } @GwtIncompatible("SerializableTester") @@ -462,7 +460,7 @@ public class ImmutableMultisetTest extends TestCase { Multiset<String> c = ImmutableMultiset.of("a", "b", "a"); Collection<String> copy = LenientSerializableTester.reserializeAndAssertLenient(c.elementSet()); - assertThat(copy).has().allOf("a", "b").inOrder(); + ASSERT.that(copy).has().exactly("a", "b").inOrder(); } @GwtIncompatible("SerializableTester") @@ -475,13 +473,13 @@ public class ImmutableMultisetTest extends TestCase { Collection<String> c = ImmutableMultiset.of("a", "b", "a"); assertEquals(c, ImmutableMultiset.of("a", "b", "a")); assertEquals(c, ImmutableMultiset.of("a", "a", "b")); - assertThat(c).isNotEqualTo(ImmutableMultiset.of("a", "b")); - assertThat(c).isNotEqualTo(ImmutableMultiset.of("a", "b", "c", "d")); + ASSERT.that(c).isNotEqualTo(ImmutableMultiset.of("a", "b")); + ASSERT.that(c).isNotEqualTo(ImmutableMultiset.of("a", "b", "c", "d")); } public void testIterationOrder() { Collection<String> c = ImmutableMultiset.of("a", "b", "a"); - assertThat(c).has().allOf("a", "a", "b").inOrder(); + ASSERT.that(c).has().exactly("a", "a", "b").inOrder(); } public void testMultisetWrites() { @@ -513,10 +511,4 @@ public class ImmutableMultisetTest extends TestCase { .addEqualityGroup(ImmutableMultiset.of(1, 2, 1), ImmutableMultiset.of(2, 1, 1)) .testEquals(); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java b/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java index 39dd3aa..6621483 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java @@ -30,16 +30,14 @@ import com.google.common.collect.testing.google.UnmodifiableCollectionTests; import com.google.common.testing.EqualsTester; import com.google.common.testing.SerializableTester; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Map.Entry; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.truth0.subjects.CollectionSubject; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Map.Entry; /** * Tests for {@link ImmutableSetMultimap}. @@ -64,7 +62,7 @@ public class ImmutableSetMultimapTest extends TestCase { }) .named("ImmutableSetMultimap") .withFeatures( - MapFeature.ALLOWS_NULL_QUERIES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, CollectionFeature.KNOWN_ORDER, CollectionFeature.SERIALIZABLE, CollectionSize.ANY) @@ -251,10 +249,10 @@ public class ImmutableSetMultimapTest extends TestCase { builder.put("a", 2); builder.put("b", 6); ImmutableSetMultimap<String, Integer> multimap = builder.build(); - assertThat(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder(); - assertThat(multimap.values()).has().allOf(2, 4, 3, 6, 5, 2).inOrder(); - assertThat(multimap.get("a")).has().allOf(5, 2).inOrder(); - assertThat(multimap.get("b")).has().allOf(3, 6).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("d", "c", "b", "a").inOrder(); + ASSERT.that(multimap.values()).has().exactly(2, 4, 3, 6, 5, 2).inOrder(); + ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); + ASSERT.that(multimap.get("b")).has().exactly(3, 6).inOrder(); assertFalse(multimap.get("a") instanceof ImmutableSortedSet); assertFalse(multimap.get("x") instanceof ImmutableSortedSet); assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet); @@ -276,10 +274,10 @@ public class ImmutableSetMultimapTest extends TestCase { builder.put("a", 2); builder.put("bb", 6); ImmutableSetMultimap<String, Integer> multimap = builder.build(); - assertThat(multimap.keySet()).has().allOf("d", "a", "bb", "cc").inOrder(); - assertThat(multimap.values()).has().allOf(2, 5, 2, 3, 6, 4).inOrder(); - assertThat(multimap.get("a")).has().allOf(5, 2).inOrder(); - assertThat(multimap.get("bb")).has().allOf(3, 6).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("d", "a", "bb", "cc").inOrder(); + ASSERT.that(multimap.values()).has().exactly(2, 5, 2, 3, 6, 4).inOrder(); + ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); + ASSERT.that(multimap.get("bb")).has().exactly(3, 6).inOrder(); assertFalse(multimap.get("a") instanceof ImmutableSortedSet); assertFalse(multimap.get("x") instanceof ImmutableSortedSet); assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet); @@ -296,10 +294,10 @@ public class ImmutableSetMultimapTest extends TestCase { builder.put("a", 2); builder.put("b", 6); ImmutableSetMultimap<String, Integer> multimap = builder.build(); - assertThat(multimap.keySet()).has().allOf("b", "d", "a", "c").inOrder(); - assertThat(multimap.values()).has().allOf(6, 3, 2, 5, 2, 4).inOrder(); - assertThat(multimap.get("a")).has().allOf(5, 2).inOrder(); - assertThat(multimap.get("b")).has().allOf(6, 3).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("b", "d", "a", "c").inOrder(); + ASSERT.that(multimap.values()).has().exactly(6, 3, 2, 5, 2, 4).inOrder(); + ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); + ASSERT.that(multimap.get("b")).has().exactly(6, 3).inOrder(); assertTrue(multimap.get("a") instanceof ImmutableSortedSet); assertEquals(Collections.reverseOrder(), ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator()); @@ -323,10 +321,10 @@ public class ImmutableSetMultimapTest extends TestCase { builder.put("a", 2); builder.put("b", 6); ImmutableSetMultimap<String, Integer> multimap = builder.build(); - assertThat(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder(); - assertThat(multimap.values()).has().allOf(2, 4, 6, 3, 5, 2).inOrder(); - assertThat(multimap.get("a")).has().allOf(5, 2).inOrder(); - assertThat(multimap.get("b")).has().allOf(6, 3).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("d", "c", "b", "a").inOrder(); + ASSERT.that(multimap.values()).has().exactly(2, 4, 6, 3, 5, 2).inOrder(); + ASSERT.that(multimap.get("a")).has().exactly(5, 2).inOrder(); + ASSERT.that(multimap.get("b")).has().exactly(6, 3).inOrder(); assertTrue(multimap.get("a") instanceof ImmutableSortedSet); assertEquals(Collections.reverseOrder(), ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator()); @@ -528,14 +526,26 @@ public class ImmutableSetMultimapTest extends TestCase { assertSame(multimap, SerializableTester.reserialize(multimap)); } + @GwtIncompatible("SerializableTester") + public void testSortedSerialization() { + Multimap<String, Integer> multimap = new ImmutableSetMultimap.Builder<String, Integer>() + .orderKeysBy(Ordering.natural().reverse()) + .orderValuesBy(Ordering.usingToString()) + .put("a", 2) + .put("a", 10) + .put("b", 1) + .build(); + multimap = SerializableTester.reserialize(multimap); + ASSERT.that(multimap.keySet()).has().exactly("b", "a").inOrder(); + ASSERT.that(multimap.get("a")).has().exactly(10, 2).inOrder(); + assertEquals(Ordering.usingToString(), + ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator()); + assertEquals(Ordering.usingToString(), + ((ImmutableSortedSet<Integer>) multimap.get("z")).comparator()); + } + private ImmutableSetMultimap<String, Integer> createMultimap() { return ImmutableSetMultimap.<String, Integer>builder() .put("foo", 1).put("bar", 2).put("foo", 3).build(); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/ImmutableSetTest.java b/guava-tests/test/com/google/common/collect/ImmutableSetTest.java index 1460ad2..fb561d6 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableSetTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableSetTest.java @@ -16,6 +16,8 @@ package com.google.common.collect; +import static org.truth0.Truth.ASSERT; + import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.ImmutableSet.Builder; @@ -28,16 +30,15 @@ import com.google.common.collect.testing.google.SetGenerators.ImmutableSetAsList import com.google.common.collect.testing.google.SetGenerators.ImmutableSetCopyOfGenerator; import com.google.common.collect.testing.google.SetGenerators.ImmutableSetWithBadHashesGenerator; import com.google.common.testing.EqualsTester; -import com.google.common.testing.FluentAsserts; + +import junit.framework.Test; +import junit.framework.TestSuite; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Unit test for {@link ImmutableSet}. * @@ -152,7 +153,7 @@ public class ImmutableSetTest extends AbstractImmutableSetTest { // now we'll get the varargs overload ImmutableSet<String> set = ImmutableSet.of( "a", "b", "c", "c", "c", "c", "b", "b", "a", "a", "c", "c", "c", "a"); - FluentAsserts.assertThat(set).has().allOf("a", "b", "c").inOrder(); + ASSERT.that(set).has().exactly("a", "b", "c").inOrder(); } public void testCreation_arrayOfArray() { diff --git a/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java index 7a80c3c..3350722 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java @@ -36,11 +36,7 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.truth0.Truth; -import org.truth0.subjects.CollectionSubject; - import java.io.Serializable; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; @@ -413,8 +409,6 @@ public class ImmutableSortedMapTest extends TestCase { builder.build(); fail(); } catch (IllegalArgumentException expected) { - assertEquals("Duplicate keys in mappings one=1 and one=2", - expected.getMessage()); } } @@ -471,8 +465,6 @@ public class ImmutableSortedMapTest extends TestCase { ImmutableSortedMap.of("one", 1, "one", 1); fail(); } catch (IllegalArgumentException expected) { - assertEquals("Duplicate keys in mappings one=1 and one=1", - expected.getMessage()); } } @@ -545,7 +537,7 @@ public class ImmutableSortedMapTest extends TestCase { public void testCopyOfSortedExplicit() { Comparator<String> comparator = Ordering.natural().reverse(); - SortedMap<String, Integer> original = Maps.<String, String, Integer>newTreeMap(comparator); + SortedMap<String, Integer> original = Maps.newTreeMap(comparator); original.put("one", 1); original.put("two", 2); original.put("three", 3); @@ -587,8 +579,6 @@ public class ImmutableSortedMapTest extends TestCase { ImmutableSortedMap.copyOf(original); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { - assertEquals("Duplicate keys in mappings 11=eleven and 12=twelve", - expected.getMessage()); } } @@ -706,7 +696,7 @@ public class ImmutableSortedMapTest extends TestCase { public void testHeadMapInclusive() { Map<String, Integer> map = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).headMap("three", true); - ASSERT.that(map.entrySet()).has().allOf( + ASSERT.that(map.entrySet()).has().exactly( Maps.immutableEntry("one", 1), Maps.immutableEntry("three", 3)).inOrder(); } @@ -715,14 +705,14 @@ public class ImmutableSortedMapTest extends TestCase { public void testHeadMapExclusive() { Map<String, Integer> map = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).headMap("three", false); - ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("one", 1)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly(Maps.immutableEntry("one", 1)).inOrder(); } @SuppressWarnings("unchecked") // varargs public void testTailMapInclusive() { Map<String, Integer> map = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).tailMap("three", true); - ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("three", 3), + ASSERT.that(map.entrySet()).has().exactly(Maps.immutableEntry("three", 3), Maps.immutableEntry("two", 2)).inOrder(); } @@ -730,21 +720,21 @@ public class ImmutableSortedMapTest extends TestCase { public void testTailMapExclusive() { Map<String, Integer> map = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).tailMap("three", false); - ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("two", 2)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly(Maps.immutableEntry("two", 2)).inOrder(); } @SuppressWarnings("unchecked") // varargs public void testSubMapExclusiveExclusive() { Map<String, Integer> map = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", false, "two", false); - ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("three", 3)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly(Maps.immutableEntry("three", 3)).inOrder(); } @SuppressWarnings("unchecked") // varargs public void testSubMapInclusiveExclusive() { Map<String, Integer> map = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", true, "two", false); - ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("one", 1), + ASSERT.that(map.entrySet()).has().exactly(Maps.immutableEntry("one", 1), Maps.immutableEntry("three", 3)).inOrder(); } @@ -752,7 +742,7 @@ public class ImmutableSortedMapTest extends TestCase { public void testSubMapExclusiveInclusive() { Map<String, Integer> map = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", false, "two", true); - ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("three", 3), + ASSERT.that(map.entrySet()).has().exactly(Maps.immutableEntry("three", 3), Maps.immutableEntry("two", 2)).inOrder(); } @@ -760,7 +750,7 @@ public class ImmutableSortedMapTest extends TestCase { public void testSubMapInclusiveInclusive() { Map<String, Integer> map = ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", true, "two", true); - ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("one", 1), + ASSERT.that(map.entrySet()).has().exactly(Maps.immutableEntry("one", 1), Maps.immutableEntry("three", 3), Maps.immutableEntry("two", 2)).inOrder(); } @@ -788,12 +778,4 @@ public class ImmutableSortedMapTest extends TestCase { ImmutableSortedMap.Builder<SuperComparableExample, Object> reverse = ImmutableSortedMap.reverseOrder(); } - - // Hack for JDK5 type inference. - private static class ASSERT { - static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> that( - Collection<T> collection) { - return Truth.ASSERT.<T, Collection<T>>that(collection); - } - } } diff --git a/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java b/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java index e05fcbe..e82a719 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java @@ -31,20 +31,21 @@ import com.google.common.collect.testing.google.UnmodifiableCollectionTests; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.easymock.EasyMock; + +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.easymock.EasyMock; -import org.truth0.subjects.CollectionSubject; - /** * Tests for {@link ImmutableSortedMultiset}. * @@ -421,13 +422,13 @@ public class ImmutableSortedMultisetTest extends TestCase { public void testSerialization_multiple() { Collection<String> c = ImmutableSortedMultiset.of("a", "b", "a"); Collection<String> copy = SerializableTester.reserializeAndAssert(c); - assertThat(copy).has().allOf("a", "a", "b").inOrder(); + ASSERT.that(copy).has().exactly("a", "a", "b").inOrder(); } public void testSerialization_elementSet() { Multiset<String> c = ImmutableSortedMultiset.of("a", "b", "a"); Collection<String> copy = SerializableTester.reserializeAndAssert(c.elementSet()); - assertThat(copy).has().allOf("a", "b").inOrder(); + ASSERT.that(copy).has().exactly("a", "b").inOrder(); } public void testSerialization_entrySet() { @@ -439,13 +440,13 @@ public class ImmutableSortedMultisetTest extends TestCase { Collection<String> c = ImmutableSortedMultiset.of("a", "b", "a"); assertEquals(c, ImmutableSortedMultiset.of("a", "b", "a")); assertEquals(c, ImmutableSortedMultiset.of("a", "a", "b")); - assertThat(c).isNotEqualTo(ImmutableSortedMultiset.of("a", "b")); - assertThat(c).isNotEqualTo(ImmutableSortedMultiset.of("a", "b", "c", "d")); + ASSERT.that(c).isNotEqualTo(ImmutableSortedMultiset.of("a", "b")); + ASSERT.that(c).isNotEqualTo(ImmutableSortedMultiset.of("a", "b", "c", "d")); } public void testIterationOrder() { Collection<String> c = ImmutableSortedMultiset.of("a", "b", "a"); - assertThat(c).has().allOf("a", "a", "b").inOrder(); + ASSERT.that(c).has().exactly("a", "a", "b").inOrder(); } public void testMultisetWrites() { @@ -465,31 +466,64 @@ public class ImmutableSortedMultisetTest extends TestCase { } public void testCopyOfDefensiveCopy() { + // Depending on JDK version, either toArray() or toArray(T[]) may be called... use this class + // rather than mocking to ensure that one of those methods is called. + class TestArrayList<E> extends ArrayList<E> { + boolean toArrayCalled = false; + + @Override + public Object[] toArray() { + toArrayCalled = true; + return super.toArray(); + } + + @Override + public <T> T[] toArray(T[] a) { + toArrayCalled = true; + return super.toArray(a); + } + } + // Test that toArray() is used to make a defensive copy in copyOf(), so concurrently modified // synchronized collections can be safely copied. - @SuppressWarnings("unchecked") - Collection<String> toCopy = EasyMock.createMock(Collection.class); - EasyMock.expect(toCopy.toArray()).andReturn(new Object[0]); - EasyMock.replay(toCopy); + TestArrayList<String> toCopy = new TestArrayList<String>(); ImmutableSortedMultiset<String> multiset = ImmutableSortedMultiset.copyOf(Ordering.natural(), toCopy); - EasyMock.verify(toCopy); + assertTrue(toCopy.toArrayCalled); } @SuppressWarnings("unchecked") public void testCopyOfSortedDefensiveCopy() { + // Depending on JDK version, either toArray() or toArray(T[]) may be called... use this class + // rather than mocking to ensure that one of those methods is called. + class TestHashSet<E> extends HashSet<E> { + boolean toArrayCalled = false; + + @Override + public Object[] toArray() { + toArrayCalled = true; + return super.toArray(); + } + + @Override + public <T> T[] toArray(T[] a) { + toArrayCalled = true; + return super.toArray(a); + } + } + // Test that toArray() is used to make a defensive copy in copyOf(), so concurrently modified // synchronized collections can be safely copied. SortedMultiset<String> toCopy = EasyMock.createMock(SortedMultiset.class); - Set<Entry<String>> entrySet = EasyMock.createMock(Set.class); + TestHashSet<Entry<String>> entrySet = new TestHashSet<Entry<String>>(); EasyMock.expect((Comparator<Comparable>) toCopy.comparator()) .andReturn(Ordering.natural()); EasyMock.expect(toCopy.entrySet()).andReturn(entrySet); - EasyMock.expect(entrySet.toArray()).andReturn(new Object[0]); - EasyMock.replay(toCopy, entrySet); + EasyMock.replay(toCopy); ImmutableSortedMultiset<String> multiset = ImmutableSortedMultiset.copyOfSorted(toCopy); - EasyMock.verify(toCopy, entrySet); + EasyMock.verify(toCopy); + assertTrue(entrySet.toArrayCalled); } private static class IntegerDiv10 implements Comparable<IntegerDiv10> { @@ -521,10 +555,4 @@ public class ImmutableSortedMultisetTest extends TestCase { assertTrue(copy.contains(eleven)); assertTrue(copy.contains(twelve)); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java b/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java index 6a37ba5..e8d4a31 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java @@ -17,6 +17,7 @@ package com.google.common.collect; import static java.util.Arrays.asList; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -30,11 +31,8 @@ import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSet import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetDescendingGenerator; import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitComparator; import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitSuperclassComparatorGenerator; -import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetHeadsetGenerator; import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetReversedOrderGenerator; import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetAsListGenerator; -import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetGenerator; -import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetTailsetGenerator; import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetUnhashableGenerator; import com.google.common.collect.testing.testers.SetHashCodeTester; import com.google.common.testing.NullPointerTester; @@ -42,8 +40,6 @@ import com.google.common.testing.SerializableTester; import junit.framework.Test; import junit.framework.TestSuite; -import org.truth0.Truth; -import org.truth0.subjects.CollectionSubject; import java.util.Arrays; import java.util.Collection; @@ -76,30 +72,6 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { .createTestSuite()); suite.addTest(SortedSetTestSuiteBuilder.using( - new ImmutableSortedSetHeadsetGenerator()) - .named(ImmutableSortedSetTest.class.getName() + ", headset") - .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, - CollectionFeature.SERIALIZABLE, - CollectionFeature.ALLOWS_NULL_QUERIES) - .createTestSuite()); - - suite.addTest(SortedSetTestSuiteBuilder.using( - new ImmutableSortedSetTailsetGenerator()) - .named(ImmutableSortedSetTest.class.getName() + ", tailset") - .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, - CollectionFeature.SERIALIZABLE, - CollectionFeature.ALLOWS_NULL_QUERIES) - .createTestSuite()); - - suite.addTest(SortedSetTestSuiteBuilder.using( - new ImmutableSortedSetSubsetGenerator()) - .named(ImmutableSortedSetTest.class.getName() + ", subset") - .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, - CollectionFeature.SERIALIZABLE, - CollectionFeature.ALLOWS_NULL_QUERIES) - .createTestSuite()); - - suite.addTest(SortedSetTestSuiteBuilder.using( new ImmutableSortedSetExplicitComparator()) .named(ImmutableSortedSetTest.class.getName() + ", explicit comparator, vararg") @@ -334,7 +306,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testOf_ordering() { SortedSet<String> set = of("e", "a", "f", "b", "d", "c"); - ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); } /* @@ -383,7 +355,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testOf_ordering_dupes() { SortedSet<String> set = of("e", "a", "e", "f", "b", "b", "d", "a", "c"); - ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); } public void testOf_comparator() { @@ -394,8 +366,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testOf_headSet() { SortedSet<String> set = of("e", "f", "b", "d", "c"); assertTrue(set.headSet("e") instanceof ImmutableSortedSet); - ASSERT.that(set.headSet("e")).has().allOf("b", "c", "d").inOrder(); - ASSERT.that(set.headSet("g")).has().allOf("b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set.headSet("e")).has().exactly("b", "c", "d").inOrder(); + ASSERT.that(set.headSet("g")).has().exactly("b", "c", "d", "e", "f").inOrder(); assertSame(of(), set.headSet("a")); assertSame(of(), set.headSet("b")); } @@ -403,16 +375,16 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testOf_tailSet() { SortedSet<String> set = of("e", "f", "b", "d", "c"); assertTrue(set.tailSet("e") instanceof ImmutableSortedSet); - ASSERT.that(set.tailSet("e")).has().allOf("e", "f").inOrder(); - ASSERT.that(set.tailSet("a")).has().allOf("b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set.tailSet("e")).has().exactly("e", "f").inOrder(); + ASSERT.that(set.tailSet("a")).has().exactly("b", "c", "d", "e", "f").inOrder(); assertSame(of(), set.tailSet("g")); } public void testOf_subSet() { SortedSet<String> set = of("e", "f", "b", "d", "c"); assertTrue(set.subSet("c", "e") instanceof ImmutableSortedSet); - ASSERT.that(set.subSet("c", "e")).has().allOf("c", "d").inOrder(); - ASSERT.that(set.subSet("a", "g")).has().allOf("b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set.subSet("c", "e")).has().exactly("c", "d").inOrder(); + ASSERT.that(set.subSet("a", "g")).has().exactly("b", "c", "d", "e", "f").inOrder(); assertSame(of(), set.subSet("a", "b")); assertSame(of(), set.subSet("g", "h")); assertSame(of(), set.subSet("c", "c")); @@ -452,14 +424,14 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testExplicit_ordering() { SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add( "in", "the", "quick", "jumped", "over", "a").build(); - ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + ASSERT.that(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); } public void testExplicit_ordering_dupes() { SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add( "in", "the", "quick", "brown", "fox", "jumped", "over", "a", "lazy", "dog").build(); - ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + ASSERT.that(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); } public void testExplicit_contains() { @@ -489,9 +461,9 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { "in", "the", "quick", "jumped", "over", "a").build(); assertTrue(set.headSet("a") instanceof ImmutableSortedSet); assertTrue(set.headSet("fish") instanceof ImmutableSortedSet); - ASSERT.that(set.headSet("fish")).has().allOf("a", "in", "the").inOrder(); + ASSERT.that(set.headSet("fish")).has().exactly("a", "in", "the").inOrder(); ASSERT.that(set.headSet("california")).has() - .allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + .exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); assertTrue(set.headSet("a").isEmpty()); assertTrue(set.headSet("").isEmpty()); } @@ -501,9 +473,9 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { "in", "the", "quick", "jumped", "over", "a").build(); assertTrue(set.tailSet("california") instanceof ImmutableSortedSet); assertTrue(set.tailSet("fish") instanceof ImmutableSortedSet); - ASSERT.that(set.tailSet("fish")).has().allOf("over", "quick", "jumped").inOrder(); + ASSERT.that(set.tailSet("fish")).has().exactly("over", "quick", "jumped").inOrder(); ASSERT.that( - set.tailSet("a")).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + set.tailSet("a")).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); assertTrue(set.tailSet("california").isEmpty()); } @@ -512,9 +484,9 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { "in", "the", "quick", "jumped", "over", "a").build(); assertTrue(set.subSet("the", "quick") instanceof ImmutableSortedSet); assertTrue(set.subSet("", "b") instanceof ImmutableSortedSet); - ASSERT.that(set.subSet("the", "quick")).has().allOf("the", "over").inOrder(); + ASSERT.that(set.subSet("the", "quick")).has().exactly("the", "over").inOrder(); ASSERT.that(set.subSet("a", "california")) - .has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + .has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); assertTrue(set.subSet("", "b").isEmpty()); assertTrue(set.subSet("vermont", "california").isEmpty()); assertTrue(set.subSet("aaa", "zzz").isEmpty()); @@ -558,13 +530,13 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testCopyOf_ordering() { SortedSet<String> set = copyOf(asList("e", "a", "f", "b", "d", "c")); - ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); } public void testCopyOf_ordering_dupes() { SortedSet<String> set = copyOf(asList("e", "a", "e", "f", "b", "b", "d", "a", "c")); - ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); } public void testCopyOf_subSet() { @@ -595,13 +567,13 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testCopyOf_iterator_ordering() { SortedSet<String> set = copyOf(asIterator("e", "a", "f", "b", "d", "c")); - ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); } public void testCopyOf_iterator_ordering_dupes() { SortedSet<String> set = copyOf(asIterator("e", "a", "e", "f", "b", "b", "d", "a", "c")); - ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); } public void testCopyOf_iterator_comparator() { @@ -612,7 +584,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testCopyOf_sortedSet_ordering() { SortedSet<String> set = copyOf(Sets.newTreeSet(asList("e", "a", "f", "b", "d", "c"))); - ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); } public void testCopyOf_sortedSet_comparator() { @@ -624,7 +596,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { SortedSet<String> set = ImmutableSortedSet.copyOf(STRING_LENGTH, asList( "in", "the", "quick", "jumped", "over", "a")); - ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + ASSERT.that(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); } public void testCopyOfExplicit_ordering_dupes() { @@ -632,7 +604,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { ImmutableSortedSet.copyOf(STRING_LENGTH, asList( "in", "the", "quick", "brown", "fox", "jumped", "over", "a", "lazy", "dog")); - ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + ASSERT.that(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); } public void testCopyOfExplicit_comparator() { @@ -646,7 +618,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { SortedSet<String> set = ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator( "in", "the", "quick", "jumped", "over", "a")); - ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + ASSERT.that(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); } public void testCopyOfExplicit_iterator_ordering_dupes() { @@ -654,7 +626,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator( "in", "the", "quick", "brown", "fox", "jumped", "over", "a", "lazy", "dog")); - ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + ASSERT.that(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); } public void testCopyOfExplicit_iterator_comparator() { @@ -668,14 +640,14 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH); Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a"); SortedSet<String> set = copyOf(input); - ASSERT.that(set).has().allOf("a", "in", "jumped", "over", "quick", "the").inOrder(); + ASSERT.that(set).has().exactly("a", "in", "jumped", "over", "quick", "the").inOrder(); } public void testCopyOfSorted_natural_ordering() { SortedSet<String> input = Sets.newTreeSet( asList("in", "the", "quick", "jumped", "over", "a")); SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input); - ASSERT.that(set).has().allOf("a", "in", "jumped", "over", "quick", "the").inOrder(); + ASSERT.that(set).has().exactly("a", "in", "jumped", "over", "quick", "the").inOrder(); } public void testCopyOfSorted_natural_comparator() { @@ -689,7 +661,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH); Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a"); SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input); - ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder(); + ASSERT.that(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder(); assertSame(STRING_LENGTH, set.comparator()); } @@ -776,7 +748,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { @GwtIncompatible("SerializableTester") public void testDifferentComparator_serialization() { - Comparator<Comparable<?>> comparator = Collections.reverseOrder(); + // don't use Collections.reverseOrder(); it didn't reserialize to the same instance in JDK5 + Comparator<Comparable<?>> comparator = Ordering.natural().reverse(); SortedSet<String> set = new ImmutableSortedSet.Builder<String>(comparator) .add("a", "b", "c").build(); SortedSet<String> copy = SerializableTester.reserializeAndAssert(set); @@ -787,7 +760,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testReverseOrder() { SortedSet<String> set = ImmutableSortedSet.<String>reverseOrder() .add("a", "b", "c").build(); - ASSERT.that(set).has().allOf("c", "b", "a").inOrder(); + ASSERT.that(set).has().exactly("c", "b", "a").inOrder(); assertEquals(Ordering.natural().reverse(), set.comparator()); } @@ -802,13 +775,13 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { public void testSupertypeComparator() { SortedSet<Integer> set = new ImmutableSortedSet.Builder<Integer>(TO_STRING) .add(3, 12, 101, 44).build(); - ASSERT.that(set).has().allOf(101, 12, 3, 44).inOrder(); + ASSERT.that(set).has().exactly(101, 12, 3, 44).inOrder(); } public void testSupertypeComparatorSubtypeElements() { SortedSet<Number> set = new ImmutableSortedSet.Builder<Number>(TO_STRING) .add(3, 12, 101, 44).build(); - ASSERT.that(set).has().allOf(101, 12, 3, 44).inOrder(); + ASSERT.that(set).has().exactly(101, 12, 3, 44).inOrder(); } @Override <E extends Comparable<E>> ImmutableSortedSet.Builder<E> builder() { @@ -929,7 +902,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { assertEquals(-1, list.lastIndexOf("chicken")); } - private static final <E> Iterator<E> asIterator(E... elements) { + private static <E> Iterator<E> asIterator(E... elements) { return asList(elements).iterator(); } @@ -950,7 +923,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { Arrays.sort(strings); for (int i = 0; i < strings.length; i++) { ASSERT.that(set.headSet(strings[i], true)) - .has().allFrom(sortedNumberNames(0, i + 1)).inOrder(); + .has().exactlyAs(sortedNumberNames(0, i + 1)).inOrder(); } } @@ -959,7 +932,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings); Arrays.sort(strings); for (int i = 0; i < strings.length; i++) { - ASSERT.that(set.headSet(strings[i], false)).has().allFrom(sortedNumberNames(0, i)).inOrder(); + ASSERT.that(set.headSet(strings[i], false)).has().exactlyAs( + sortedNumberNames(0, i)).inOrder(); } } @@ -968,7 +942,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings); Arrays.sort(strings); for (int i = 0; i < strings.length; i++) { - ASSERT.that(set.tailSet(strings[i], true)).has().allFrom( + ASSERT.that(set.tailSet(strings[i], true)).has().exactlyAs( sortedNumberNames(i, strings.length)).inOrder(); } } @@ -978,7 +952,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings); Arrays.sort(strings); for (int i = 0; i < strings.length; i++) { - ASSERT.that(set.tailSet(strings[i], false)).has().allFrom( + ASSERT.that(set.tailSet(strings[i], false)).has().exactlyAs( sortedNumberNames(i + 1, strings.length)).inOrder(); } } @@ -990,7 +964,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { for (int i = 0; i < strings.length; i++) { for (int j = i; j < strings.length; j++) { ASSERT.that(set.subSet(strings[i], false, strings[j], false)) - .has().allFrom(sortedNumberNames(Math.min(i + 1, j), j)).inOrder(); + .has().exactlyAs(sortedNumberNames(Math.min(i + 1, j), j)).inOrder(); } } } @@ -1002,7 +976,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { for (int i = 0; i < strings.length; i++) { for (int j = i; j < strings.length; j++) { ASSERT.that(set.subSet(strings[i], true, strings[j], false)) - .has().allFrom(sortedNumberNames(i, j)).inOrder(); + .has().exactlyAs(sortedNumberNames(i, j)).inOrder(); } } } @@ -1014,7 +988,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { for (int i = 0; i < strings.length; i++) { for (int j = i; j < strings.length; j++) { ASSERT.that(set.subSet(strings[i], false, strings[j], true)) - .has().allFrom(sortedNumberNames(i + 1, j + 1)).inOrder(); + .has().exactlyAs(sortedNumberNames(i + 1, j + 1)).inOrder(); } } } @@ -1026,7 +1000,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { for (int i = 0; i < strings.length; i++) { for (int j = i; j < strings.length; j++) { ASSERT.that(set.subSet(strings[i], true, strings[j], true)) - .has().allFrom(sortedNumberNames(i, j + 1)).inOrder(); + .has().exactlyAs(sortedNumberNames(i, j + 1)).inOrder(); } } } @@ -1059,13 +1033,4 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest { ImmutableSortedSet.Builder<SuperComparableExample> natural = ImmutableSortedSet.naturalOrder(); ImmutableSortedSet.Builder<SuperComparableExample> reverse = ImmutableSortedSet.reverseOrder(); } - - // Hack for JDK5 type inference. - private static class ASSERT { - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> that( - Collection<T> collection) { - return Truth.ASSERT.<T, Collection<T>>that(collection); - } - } - } diff --git a/guava-tests/test/com/google/common/collect/ImmutableTableTest.java b/guava-tests/test/com/google/common/collect/ImmutableTableTest.java index ad0aa76..36931fe 100644 --- a/guava-tests/test/com/google/common/collect/ImmutableTableTest.java +++ b/guava-tests/test/com/google/common/collect/ImmutableTableTest.java @@ -19,10 +19,7 @@ package com.google.common.collect; import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; - -import java.util.Collection; - -import org.truth0.subjects.CollectionSubject; +import com.google.common.annotations.GwtIncompatible; /** * Tests common methods in {@link ImmutableTable} @@ -188,9 +185,9 @@ public class ImmutableTableTest extends AbstractTableReadTest { validateTableCopies(table); // Even though rowKeySet, columnKeySet, and cellSet have the same // iteration ordering, row has an inconsistent ordering. - assertThat(table.row('b').keySet()).has().allOf(1, 2).inOrder(); - assertThat(ImmutableTable.copyOf(table).row('b').keySet()) - .has().allOf(2, 1).inOrder(); + ASSERT.that(table.row('b').keySet()).has().exactly(1, 2).inOrder(); + ASSERT.that(ImmutableTable.copyOf(table).row('b').keySet()) + .has().exactly(2, 1).inOrder(); } public void testCopyOfSparse() { @@ -231,10 +228,10 @@ public class ImmutableTableTest extends AbstractTableReadTest { = builder.orderRowsBy(Ordering.natural()) .orderColumnsBy(Ordering.natural()) .putAll(table).build(); - assertThat(copy.rowKeySet()).has().allOf('a', 'b').inOrder(); - assertThat(copy.columnKeySet()).has().allOf(1, 2).inOrder(); - assertThat(copy.values()).has().allOf("baz", "bar", "foo").inOrder(); - assertThat(copy.row('b').keySet()).has().allOf(1, 2).inOrder(); + ASSERT.that(copy.rowKeySet()).has().exactly('a', 'b').inOrder(); + ASSERT.that(copy.columnKeySet()).has().exactly(1, 2).inOrder(); + ASSERT.that(copy.values()).has().exactly("baz", "bar", "foo").inOrder(); + ASSERT.that(copy.row('b').keySet()).has().exactly(1, 2).inOrder(); } public void testBuilder_orderRowsAndColumnsBy_sparse() { @@ -252,12 +249,12 @@ public class ImmutableTableTest extends AbstractTableReadTest { builder.put('r', 4, "foo"); builder.put('x', 5, "bar"); Table<Character, Integer, String> table = builder.build(); - assertThat(table.rowKeySet()).has().allOf('b', 'c', 'e', 'r', 'x').inOrder(); - assertThat(table.columnKeySet()).has().allOf(0, 1, 2, 3, 4, 5, 7).inOrder(); - assertThat(table.values()).has().allOf("cat", "axe", "baz", "tub", + ASSERT.that(table.rowKeySet()).has().exactly('b', 'c', 'e', 'r', 'x').inOrder(); + ASSERT.that(table.columnKeySet()).has().exactly(0, 1, 2, 3, 4, 5, 7).inOrder(); + ASSERT.that(table.values()).has().exactly("cat", "axe", "baz", "tub", "dog", "bar", "foo", "foo", "bar").inOrder(); - assertThat(table.row('c').keySet()).has().allOf(0, 3).inOrder(); - assertThat(table.column(5).keySet()).has().allOf('e', 'x').inOrder(); + ASSERT.that(table.row('c').keySet()).has().exactly(0, 3).inOrder(); + ASSERT.that(table.column(5).keySet()).has().exactly('e', 'x').inOrder(); } public void testBuilder_orderRowsAndColumnsBy_dense() { @@ -274,12 +271,12 @@ public class ImmutableTableTest extends AbstractTableReadTest { builder.put('a', 2, "bar"); builder.put('a', 1, "baz"); Table<Character, Integer, String> table = builder.build(); - assertThat(table.rowKeySet()).has().allOf('a', 'b', 'c').inOrder(); - assertThat(table.columnKeySet()).has().allOf(1, 2, 3).inOrder(); - assertThat(table.values()).has().allOf("baz", "bar", "foo", "dog", + ASSERT.that(table.rowKeySet()).has().exactly('a', 'b', 'c').inOrder(); + ASSERT.that(table.columnKeySet()).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(table.values()).has().exactly("baz", "bar", "foo", "dog", "cat", "baz", "bar", "foo").inOrder(); - assertThat(table.row('c').keySet()).has().allOf(1, 2, 3).inOrder(); - assertThat(table.column(1).keySet()).has().allOf('a', 'b', 'c').inOrder(); + ASSERT.that(table.row('c').keySet()).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(table.column(1).keySet()).has().exactly('a', 'b', 'c').inOrder(); } public void testBuilder_orderRowsBy_sparse() { @@ -296,8 +293,8 @@ public class ImmutableTableTest extends AbstractTableReadTest { builder.put('r', 4, "foo"); builder.put('x', 5, "bar"); Table<Character, Integer, String> table = builder.build(); - assertThat(table.rowKeySet()).has().allOf('b', 'c', 'e', 'r', 'x').inOrder(); - assertThat(table.column(5).keySet()).has().allOf('e', 'x').inOrder(); + ASSERT.that(table.rowKeySet()).has().exactly('b', 'c', 'e', 'r', 'x').inOrder(); + ASSERT.that(table.column(5).keySet()).has().exactly('e', 'x').inOrder(); } public void testBuilder_orderRowsBy_dense() { @@ -313,8 +310,8 @@ public class ImmutableTableTest extends AbstractTableReadTest { builder.put('a', 2, "bar"); builder.put('a', 1, "baz"); Table<Character, Integer, String> table = builder.build(); - assertThat(table.rowKeySet()).has().allOf('a', 'b', 'c').inOrder(); - assertThat(table.column(1).keySet()).has().allOf('a', 'b', 'c').inOrder(); + ASSERT.that(table.rowKeySet()).has().exactly('a', 'b', 'c').inOrder(); + ASSERT.that(table.column(1).keySet()).has().exactly('a', 'b', 'c').inOrder(); } public void testBuilder_orderColumnsBy_sparse() { @@ -331,8 +328,8 @@ public class ImmutableTableTest extends AbstractTableReadTest { builder.put('r', 4, "foo"); builder.put('x', 5, "bar"); Table<Character, Integer, String> table = builder.build(); - assertThat(table.columnKeySet()).has().allOf(0, 1, 2, 3, 4, 5, 7).inOrder(); - assertThat(table.row('c').keySet()).has().allOf(0, 3).inOrder(); + ASSERT.that(table.columnKeySet()).has().exactly(0, 1, 2, 3, 4, 5, 7).inOrder(); + ASSERT.that(table.row('c').keySet()).has().exactly(0, 3).inOrder(); } public void testBuilder_orderColumnsBy_dense() { @@ -348,13 +345,18 @@ public class ImmutableTableTest extends AbstractTableReadTest { builder.put('a', 2, "bar"); builder.put('a', 1, "baz"); Table<Character, Integer, String> table = builder.build(); - assertThat(table.columnKeySet()).has().allOf(1, 2, 3).inOrder(); - assertThat(table.row('c').keySet()).has().allOf(1, 2, 3).inOrder(); + ASSERT.that(table.columnKeySet()).has().exactly(1, 2, 3).inOrder(); + ASSERT.that(table.row('c').keySet()).has().exactly(1, 2, 3).inOrder(); } - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); + @GwtIncompatible("Mind-bogglingly slow in GWT") + public void testOverflowCondition() { + // See https://code.google.com/p/guava-libraries/issues/detail?id=1322 for details. + ImmutableTable.Builder<Integer, Integer, String> builder = ImmutableTable.builder(); + for (int i = 1; i < 0x10000; i++) { + builder.put(i, 0, "foo"); + builder.put(0, i, "bar"); + } + assertTrue(builder.build() instanceof SparseImmutableTable); } } diff --git a/guava-tests/test/com/google/common/collect/InternersTest.java b/guava-tests/test/com/google/common/collect/InternersTest.java index d7a776e..49ea67c 100644 --- a/guava-tests/test/com/google/common/collect/InternersTest.java +++ b/guava-tests/test/com/google/common/collect/InternersTest.java @@ -20,10 +20,10 @@ import com.google.common.base.Function; import com.google.common.testing.GcFinalization; import com.google.common.testing.NullPointerTester; -import java.lang.ref.WeakReference; - import junit.framework.TestCase; +import java.lang.ref.WeakReference; + /** * Unit test for {@link Interners}. * diff --git a/guava-tests/test/com/google/common/collect/IterablesTest.java b/guava-tests/test/com/google/common/collect/IterablesTest.java index 7854127..a16beac 100644 --- a/guava-tests/test/com/google/common/collect/IterablesTest.java +++ b/guava-tests/test/com/google/common/collect/IterablesTest.java @@ -23,6 +23,7 @@ import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE; import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -32,9 +33,11 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.testing.IteratorTester; import com.google.common.testing.ClassSanityTester; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -49,8 +52,6 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; -import junit.framework.TestCase; - /** * Unit test for {@code Iterables}. * @@ -85,8 +86,7 @@ public class IterablesTest extends TestCase { List<Integer> nums = asList(1, 2, 3, 4, 5); List<Integer> collection = new ArrayList<Integer>(nums) { @Override public Iterator<Integer> iterator() { - fail("Don't iterate me!"); - return null; + throw new AssertionFailedError("Don't iterate me!"); } }; assertEquals(5, Iterables.size(collection)); @@ -283,7 +283,7 @@ public class IterablesTest extends TestCase { Iterable<TypeA> alist = Lists .newArrayList(new TypeA(), new TypeA(), hasBoth, new TypeA()); Iterable<TypeB> blist = Iterables.filter(alist, TypeB.class); - FluentAsserts.assertThat(blist).iteratesOverSequence(hasBoth); + ASSERT.that(blist).iteratesOverSequence(hasBoth); } public void testTransform() { @@ -411,7 +411,7 @@ public class IterablesTest extends TestCase { int n = 4; Iterable<Integer> repeated = Iterables.concat(Collections.nCopies(n, iterable)); - FluentAsserts.assertThat(repeated).iteratesOverSequence( + ASSERT.that(repeated).iteratesOverSequence( 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3); } @@ -510,7 +510,7 @@ public class IterablesTest extends TestCase { List<String> freshlyAdded = newArrayList("freshly", "added"); boolean changed = Iterables.addAll(alreadyThere, freshlyAdded); - FluentAsserts.assertThat(alreadyThere).has().allOf( + ASSERT.that(alreadyThere).has().exactly( "already", "there", "freshly", "added").inOrder(); assertTrue(changed); } @@ -621,6 +621,38 @@ public class IterablesTest extends TestCase { assertEquals(newArrayList("a", "b"), newArrayList(skip(list, 0))); } + public void testSkip_removal() { + Collection<String> set = Sets.newHashSet("a", "b"); + Iterator<String> iterator = skip(set, 2).iterator(); + try { + iterator.next(); + } catch (NoSuchElementException suppressed) { + // We want remove() to fail even after a failed call to next(). + } + try { + iterator.remove(); + fail("Expected IllegalStateException"); + } catch (IllegalStateException expected) {} + } + + public void testSkip_allOfMutableList_modifiable() { + List<String> list = newArrayList("a", "b"); + Iterator<String> iterator = skip(list, 2).iterator(); + try { + iterator.remove(); + fail("Expected IllegalStateException"); + } catch (IllegalStateException expected) {} + } + + public void testSkip_allOfImmutableList_modifiable() { + List<String> list = ImmutableList.of("a", "b"); + Iterator<String> iterator = skip(list, 2).iterator(); + try { + iterator.remove(); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) {} + } + @GwtIncompatible("slow (~35s)") public void testSkip_iterator() { new IteratorTester<Integer>(5, MODIFIABLE, newArrayList(2, 3), @@ -656,7 +688,7 @@ public class IterablesTest extends TestCase { Iterable<String> tail = skip(set, 1); set.remove("b"); set.addAll(newArrayList("A", "B", "C")); - FluentAsserts.assertThat(tail).iteratesOverSequence("c", "A", "B", "C"); + ASSERT.that(tail).iteratesOverSequence("c", "A", "B", "C"); } public void testSkip_structurallyModifiedSkipSomeList() throws Exception { @@ -664,7 +696,7 @@ public class IterablesTest extends TestCase { Iterable<String> tail = skip(list, 1); list.subList(1, 3).clear(); list.addAll(0, newArrayList("A", "B", "C")); - FluentAsserts.assertThat(tail).iteratesOverSequence("B", "C", "a"); + ASSERT.that(tail).iteratesOverSequence("B", "C", "a"); } public void testSkip_structurallyModifiedSkipAll() throws Exception { @@ -870,14 +902,6 @@ public class IterablesTest extends TestCase { } } - public void testGetLast_withDefault_not_empty_sortedSet() { - // TODO: verify that this is the best testing strategy. - SortedSet<String> diesOnIteratorSortedSet = new DiesOnIteratorTreeSet(); - diesOnIteratorSortedSet.add("bar"); - - assertEquals("bar", Iterables.getLast(diesOnIteratorSortedSet, "qux")); - } - public void testGetLast_emptySortedSet() { SortedSet<String> sortedSet = ImmutableSortedSet.of(); try { @@ -1100,18 +1124,19 @@ public class IterablesTest extends TestCase { // Test & Verify Iterable<String> consumingIterable = Iterables.consumingIterable(list); + assertEquals("Iterables.consumingIterable(...)", consumingIterable.toString()); Iterator<String> consumingIterator = consumingIterable.iterator(); - FluentAsserts.assertThat(list).has().allOf("a", "b").inOrder(); + ASSERT.that(list).has().exactly("a", "b").inOrder(); assertTrue(consumingIterator.hasNext()); - FluentAsserts.assertThat(list).has().allOf("a", "b").inOrder(); + ASSERT.that(list).has().exactly("a", "b").inOrder(); assertEquals("a", consumingIterator.next()); - FluentAsserts.assertThat(list).has().item("b"); + ASSERT.that(list).has().item("b"); assertTrue(consumingIterator.hasNext()); assertEquals("b", consumingIterator.next()); - FluentAsserts.assertThat(list).isEmpty(); + ASSERT.that(list).isEmpty(); assertFalse(consumingIterator.hasNext()); } diff --git a/guava-tests/test/com/google/common/collect/IteratorsTest.java b/guava-tests/test/com/google/common/collect/IteratorsTest.java index 6b6d03f..2f9d83a 100644 --- a/guava-tests/test/com/google/common/collect/IteratorsTest.java +++ b/guava-tests/test/com/google/common/collect/IteratorsTest.java @@ -40,6 +40,11 @@ import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; import com.google.common.testing.NullPointerTester; +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -53,12 +58,6 @@ import java.util.RandomAccess; import java.util.Set; import java.util.Vector; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.truth0.subjects.CollectionSubject; - /** * Unit test for {@code Iterators}. * @@ -123,6 +122,21 @@ public class IteratorsTest extends TestCase { } } + public void testEmptyModifiableIterator() { + Iterator<String> iterator = Iterators.emptyModifiableIterator(); + assertFalse(iterator.hasNext()); + try { + iterator.next(); + fail("Expected NoSuchElementException"); + } catch (NoSuchElementException expected) { + } + try { + iterator.remove(); + fail("Expected IllegalStateException"); + } catch (IllegalStateException expected) { + } + } + public void testSize0() { Iterator<String> iterator = Iterators.emptyIterator(); assertEquals(0, Iterators.size(iterator)); @@ -292,8 +306,7 @@ public class IteratorsTest extends TestCase { new Predicate<String>() { @Override public boolean apply(String s) { - fail("Should never be evaluated"); - return false; + throw new AssertionFailedError("Should never be evaluated"); } }); @@ -302,7 +315,7 @@ public class IteratorsTest extends TestCase { assertEquals(expected, actual); } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testFilterUsingIteratorTester() { final List<Integer> list = asList(1, 2, 3, 4, 5); final Predicate<Integer> isEven = new Predicate<Integer>() { @@ -626,7 +639,7 @@ public class IteratorsTest extends TestCase { } catch (NoSuchElementException expected) {} } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testCycleUsingIteratorTester() { new IteratorTester<Integer>(5, UNMODIFIABLE, asList(1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2), IteratorTester.KnownOrder.KNOWN_ORDER) { @@ -752,7 +765,7 @@ public class IteratorsTest extends TestCase { boolean changed = Iterators.addAll(alreadyThere, Iterators.<String>emptyIterator()); - assertThat(alreadyThere).has().allOf("already", "there").inOrder(); + ASSERT.that(alreadyThere).has().exactly("already", "there").inOrder(); assertFalse(changed); } @@ -762,7 +775,7 @@ public class IteratorsTest extends TestCase { boolean changed = Iterators.addAll(alreadyThere, freshlyAdded.iterator()); - assertThat(alreadyThere).has().allOf("already", "there", "freshly", "added"); + ASSERT.that(alreadyThere).has().exactly("already", "there", "freshly", "added"); assertTrue(changed); } @@ -772,7 +785,7 @@ public class IteratorsTest extends TestCase { List<String> oneMore = Lists.newArrayList("there"); boolean changed = Iterators.addAll(alreadyThere, oneMore.iterator()); - assertThat(alreadyThere).has().allOf("already", "there").inOrder(); + ASSERT.that(alreadyThere).has().exactly("already", "there").inOrder(); assertFalse(changed); } @@ -1061,7 +1074,7 @@ public class IteratorsTest extends TestCase { } catch (IndexOutOfBoundsException expected) {} } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testForArrayUsingTester() { new IteratorTester<Integer>(6, UNMODIFIABLE, asList(1, 2, 3), IteratorTester.KnownOrder.KNOWN_ORDER) { @@ -1071,7 +1084,7 @@ public class IteratorsTest extends TestCase { }.test(); } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testForArrayWithOffsetUsingTester() { new IteratorTester<Integer>(6, UNMODIFIABLE, asList(1, 2, 3), IteratorTester.KnownOrder.KNOWN_ORDER) { @@ -1508,16 +1521,18 @@ public class IteratorsTest extends TestCase { Iterator<String> consumingIterator = Iterators.consumingIterator(list.iterator()); - assertThat(list).has().allOf("a", "b").inOrder(); + assertEquals("Iterators.consumingIterator(...)", consumingIterator.toString()); + + ASSERT.that(list).has().exactly("a", "b").inOrder(); assertTrue(consumingIterator.hasNext()); - assertThat(list).has().allOf("a", "b").inOrder(); + ASSERT.that(list).has().exactly("a", "b").inOrder(); assertEquals("a", consumingIterator.next()); - assertThat(list).has().item("b"); + ASSERT.that(list).has().item("b"); assertTrue(consumingIterator.hasNext()); assertEquals("b", consumingIterator.next()); - assertThat(list).isEmpty(); + ASSERT.that(list).isEmpty(); assertFalse(consumingIterator.hasNext()); } @@ -1582,10 +1597,4 @@ public class IteratorsTest extends TestCase { assertSame(peek, Iterators.peekingIterator(peek)); assertSame(peek, Iterators.peekingIterator((Iterator<String>) peek)); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java b/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java index 5c0bdd3..c905370 100644 --- a/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java @@ -32,8 +32,14 @@ import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringSetMultimapGenerator; +import com.google.common.testing.EqualsTester; import com.google.common.testing.SerializableTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -41,18 +47,13 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.truth0.subjects.CollectionSubject; - /** * Unit tests for {@code LinkedHashMultimap}. * * @author Jared Levy */ @GwtCompatible(emulated = true) -public class LinkedHashMultimapTest extends AbstractSetMultimapTest { +public class LinkedHashMultimapTest extends TestCase { @GwtIncompatible("suite") public static Test suite() { @@ -71,8 +72,10 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionFeature.KNOWN_ORDER, CollectionFeature.SERIALIZABLE, CollectionSize.ANY) @@ -81,10 +84,6 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { return suite; } - @Override protected Multimap<String, Integer> create() { - return LinkedHashMultimap.create(); - } - public void testValueSetHashTableExpansion() { LinkedHashMultimap<String, Integer> multimap = LinkedHashMultimap.create(); for (int z = 1; z <= 100; z++) { @@ -100,7 +99,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { } private Multimap<String, Integer> initializeMultimap5() { - Multimap<String, Integer> multimap = getMultimap(); + Multimap<String, Integer> multimap = LinkedHashMultimap.create(); multimap.put("foo", 5); multimap.put("bar", 4); multimap.put("foo", 3); @@ -110,8 +109,14 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { } public void testToString() { + Multimap<String, Integer> multimap = LinkedHashMultimap.create(); + multimap.put("foo", 3); + multimap.put("bar", 1); + multimap.putAll("foo", Arrays.asList(-1, 2, 4)); + multimap.putAll("bar", Arrays.asList(2, 3)); + multimap.put("foo", 1); assertEquals("{foo=[3, -1, 2, 4, 1], bar=[1, 2, 3]}", - createSample().toString()); + multimap.toString()); } public void testOrderingReadOnly() { @@ -146,8 +151,8 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { multimap.put("c", 4); multimap.remove("a", 1); multimap = SerializableTester.reserializeAndAssert(multimap); - assertThat(multimap.keySet()).has().allOf("a", "b", "c").inOrder(); - assertThat(multimap.entries()).has().allOf( + ASSERT.that(multimap.keySet()).has().exactly("a", "b", "c").inOrder(); + ASSERT.that(multimap.entries()).has().exactly( mapEntry("b", 2), mapEntry("a", 3), mapEntry("c", 4)).inOrder(); @@ -155,12 +160,12 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { } private void assertOrderingReadOnly(Multimap<String, Integer> multimap) { - assertThat(multimap.get("foo")).has().allOf(5, 3).inOrder(); - assertThat(multimap.get("bar")).has().allOf(4, 1).inOrder(); - assertThat(multimap.get("cow")).has().item(2); + ASSERT.that(multimap.get("foo")).has().exactly(5, 3).inOrder(); + ASSERT.that(multimap.get("bar")).has().exactly(4, 1).inOrder(); + ASSERT.that(multimap.get("cow")).has().item(2); - assertThat(multimap.keySet()).has().allOf("foo", "bar", "cow").inOrder(); - assertThat(multimap.values()).has().allOf(5, 4, 3, 2, 1).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("foo", "bar", "cow").inOrder(); + ASSERT.that(multimap.values()).has().exactly(5, 4, 3, 2, 1).inOrder(); Iterator<Map.Entry<String, Integer>> entryIterator = multimap.entries().iterator(); @@ -174,32 +179,32 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { multimap.asMap().entrySet().iterator(); Map.Entry<String, Collection<Integer>> entry = collectionIterator.next(); assertEquals("foo", entry.getKey()); - assertThat(entry.getValue()).has().allOf(5, 3).inOrder(); + ASSERT.that(entry.getValue()).has().exactly(5, 3).inOrder(); entry = collectionIterator.next(); assertEquals("bar", entry.getKey()); - assertThat(entry.getValue()).has().allOf(4, 1).inOrder(); + ASSERT.that(entry.getValue()).has().exactly(4, 1).inOrder(); entry = collectionIterator.next(); assertEquals("cow", entry.getKey()); - assertThat(entry.getValue()).has().item(2); + ASSERT.that(entry.getValue()).has().item(2); } public void testOrderingUpdates() { Multimap<String, Integer> multimap = initializeMultimap5(); - assertThat(multimap.replaceValues("foo", asList(6, 7))).has().allOf(5, 3).inOrder(); - assertThat(multimap.keySet()).has().allOf("foo", "bar", "cow").inOrder(); - assertThat(multimap.removeAll("foo")).has().allOf(6, 7).inOrder(); - assertThat(multimap.keySet()).has().allOf("bar", "cow").inOrder(); + ASSERT.that(multimap.replaceValues("foo", asList(6, 7))).has().exactly(5, 3).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("foo", "bar", "cow").inOrder(); + ASSERT.that(multimap.removeAll("foo")).has().exactly(6, 7).inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("bar", "cow").inOrder(); assertTrue(multimap.remove("bar", 4)); - assertThat(multimap.keySet()).has().allOf("bar", "cow").inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("bar", "cow").inOrder(); assertTrue(multimap.remove("bar", 1)); - assertThat(multimap.keySet()).has().item("cow"); + ASSERT.that(multimap.keySet()).has().item("cow"); multimap.put("bar", 9); - assertThat(multimap.keySet()).has().allOf("cow", "bar").inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("cow", "bar").inOrder(); } public void testToStringNullExact() { - Multimap<String, Integer> multimap = getMultimap(); + Multimap<String, Integer> multimap = LinkedHashMultimap.create(); multimap.put("foo", 3); multimap.put("foo", -1); @@ -241,10 +246,16 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { } public void testCreateFromMultimap() { - Multimap<String, Integer> multimap = createSample(); + Multimap<String, Integer> multimap = LinkedHashMultimap.create(); + multimap.put("a", 1); + multimap.put("b", 2); + multimap.put("a", 3); + multimap.put("c", 4); LinkedHashMultimap<String, Integer> copy = LinkedHashMultimap.create(multimap); - assertEquals(multimap, copy); + new EqualsTester() + .addEqualityGroup(multimap, copy) + .testEquals(); } public void testCreateFromSizes() { @@ -268,7 +279,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { } catch (IllegalArgumentException expected) {} } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testGetIteration() { new IteratorTester<Integer>(6, MODIFIABLE, newLinkedHashSet(asList(2, 3, 4, 7, 8)), @@ -276,7 +287,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { private Multimap<String, Integer> multimap; @Override protected Iterator<Integer> newTargetIterator() { - multimap = create(); + multimap = LinkedHashMultimap.create(); multimap.putAll("foo", asList(2, 3, 4)); multimap.putAll("bar", asList(5, 6)); multimap.putAll("foo", asList(7, 8)); @@ -289,7 +300,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { }.test(); } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testEntriesIteration() { @SuppressWarnings("unchecked") Set<Entry<String, Integer>> set = Sets.newLinkedHashSet(asList( @@ -304,7 +315,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { private Multimap<String, Integer> multimap; @Override protected Iterator<Entry<String, Integer>> newTargetIterator() { - multimap = create(); + multimap = LinkedHashMultimap.create(); multimap.putAll("foo", asList(2, 3)); multimap.putAll("bar", asList(4, 5)); multimap.putAll("foo", asList(6)); @@ -317,14 +328,14 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { }.test(); } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testKeysIteration() { new IteratorTester<String>(6, MODIFIABLE, newArrayList("foo", "foo", "bar", "bar", "foo"), IteratorTester.KnownOrder.KNOWN_ORDER) { private Multimap<String, Integer> multimap; @Override protected Iterator<String> newTargetIterator() { - multimap = create(); + multimap = LinkedHashMultimap.create(); multimap.putAll("foo", asList(2, 3)); multimap.putAll("bar", asList(4, 5)); multimap.putAll("foo", asList(6)); @@ -337,14 +348,14 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { }.test(); } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testValuesIteration() { new IteratorTester<Integer>(6, MODIFIABLE, newArrayList(2, 3, 4, 5, 6), IteratorTester.KnownOrder.KNOWN_ORDER) { private Multimap<String, Integer> multimap; @Override protected Iterator<Integer> newTargetIterator() { - multimap = create(); + multimap = LinkedHashMultimap.create(); multimap.putAll("foo", asList(2, 3)); multimap.putAll("bar", asList(4, 5)); multimap.putAll("foo", asList(6)); @@ -357,7 +368,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { }.test(); } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testKeySetIteration() { new IteratorTester<String>(6, MODIFIABLE, newLinkedHashSet(asList("foo", "bar", "baz", "dog", "cat")), @@ -365,7 +376,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { private Multimap<String, Integer> multimap; @Override protected Iterator<String> newTargetIterator() { - multimap = create(); + multimap = LinkedHashMultimap.create(); multimap.putAll("foo", asList(2, 3)); multimap.putAll("bar", asList(4, 5)); multimap.putAll("foo", asList(6)); @@ -382,7 +393,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { }.test(); } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testAsSetIteration() { @SuppressWarnings("unchecked") Set<Entry<String, Collection<Integer>>> set = newLinkedHashSet(asList( @@ -403,7 +414,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { @Override protected Iterator<Entry<String, Collection<Integer>>> newTargetIterator() { - multimap = create(); + multimap = LinkedHashMultimap.create(); multimap.putAll("foo", asList(2, 3)); multimap.putAll("bar", asList(4, 5)); multimap.putAll("foo", asList(6)); @@ -420,10 +431,4 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest { } }.test(); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java b/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java index f89a72b..db8859a 100644 --- a/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java +++ b/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java @@ -16,29 +16,23 @@ package com.google.common.collect; -import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE; import static java.util.Arrays.asList; import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; -import com.google.common.collect.testing.IteratorTester; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.google.MultisetFeature; import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringMultisetGenerator; -import java.util.Arrays; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.List; - import junit.framework.Test; +import junit.framework.TestCase; import junit.framework.TestSuite; -import org.truth0.subjects.CollectionSubject; +import java.util.Arrays; +import java.util.List; /** * Unit test for {@link LinkedHashMultiset}. @@ -46,7 +40,7 @@ import org.truth0.subjects.CollectionSubject; * @author Kevin Bourrillion */ @GwtCompatible(emulated = true) -public class LinkedHashMultisetTest extends AbstractMultisetTest { +public class LinkedHashMultisetTest extends TestCase { @GwtIncompatible("suite") public static Test suite() { @@ -55,9 +49,11 @@ public class LinkedHashMultisetTest extends AbstractMultisetTest { .named("LinkedHashMultiset") .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, + CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.SERIALIZABLE, - CollectionFeature.GENERAL_PURPOSE) + CollectionFeature.GENERAL_PURPOSE, + MultisetFeature.ENTRIES_ARE_VIEWS) .createTestSuite()); suite.addTestSuite(LinkedHashMultisetTest.class); return suite; @@ -85,10 +81,6 @@ public class LinkedHashMultisetTest extends AbstractMultisetTest { }; } - @Override protected <E> Multiset<E> create() { - return LinkedHashMultiset.create(); - } - public void testCreate() { Multiset<String> multiset = LinkedHashMultiset.create(); multiset.add("foo", 2); @@ -115,36 +107,8 @@ public class LinkedHashMultisetTest extends AbstractMultisetTest { assertEquals("[foo x 2, bar]", multiset.toString()); } - @GwtIncompatible("unreasonable slow") - public void testIteratorBashing() { - ms = createSample(); - IteratorTester<String> tester = - new IteratorTester<String>(6, MODIFIABLE, newArrayList(ms), - IteratorTester.KnownOrder.KNOWN_ORDER) { - @Override protected Iterator<String> newTargetIterator() { - return createSample().iterator(); - } - }; - tester.test(); - } - - @GwtIncompatible("slow (~30s)") - public void testElementSetIteratorBashing() { - IteratorTester<String> tester = - new IteratorTester<String>(5, MODIFIABLE, newArrayList("a", "c", "b"), - IteratorTester.KnownOrder.KNOWN_ORDER) { - @Override protected Iterator<String> newTargetIterator() { - Multiset<String> multiset = create(); - multiset.add("a", 3); - multiset.add("c", 1); - multiset.add("b", 2); - return multiset.elementSet().iterator(); - } - }; - tester.test(); - } - public void testToString() { + Multiset<String> ms = LinkedHashMultiset.create(); ms.add("a", 3); ms.add("c", 1); ms.add("b", 2); @@ -153,38 +117,17 @@ public class LinkedHashMultisetTest extends AbstractMultisetTest { } public void testLosesPlaceInLine() throws Exception { + Multiset<String> ms = LinkedHashMultiset.create(); ms.add("a"); ms.add("b", 2); ms.add("c"); - assertThat(ms.elementSet()).has().allOf("a", "b", "c").inOrder(); + ASSERT.that(ms.elementSet()).has().exactly("a", "b", "c").inOrder(); ms.remove("b"); - assertThat(ms.elementSet()).has().allOf("a", "b", "c").inOrder(); + ASSERT.that(ms.elementSet()).has().exactly("a", "b", "c").inOrder(); ms.add("b"); - assertThat(ms.elementSet()).has().allOf("a", "b", "c").inOrder(); + ASSERT.that(ms.elementSet()).has().exactly("a", "b", "c").inOrder(); ms.remove("b", 2); ms.add("b"); - assertThat(ms.elementSet()).has().allOf("a", "c", "b").inOrder(); - } - - public void testIteratorRemoveConcurrentModification() { - ms.add("a"); - ms.add("b"); - Iterator<String> iterator = ms.iterator(); - iterator.next(); - ms.remove("a"); - assertEquals(1, ms.size()); - assertTrue(ms.contains("b")); - try { - iterator.remove(); - fail(); - } catch (ConcurrentModificationException expected) {} - assertEquals(1, ms.size()); - assertTrue(ms.contains("b")); - } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); + ASSERT.that(ms.elementSet()).has().exactly("a", "c", "b").inOrder(); } } diff --git a/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java b/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java index 00dea79..fc4ff60 100644 --- a/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java @@ -36,6 +36,10 @@ import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringListMultimapGenerator; import com.google.common.testing.EqualsTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -47,18 +51,13 @@ import java.util.Map.Entry; import java.util.RandomAccess; import java.util.Set; -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.truth0.subjects.CollectionSubject; - /** * Tests for {@code LinkedListMultimap}. * * @author Mike Bostock */ @GwtCompatible(emulated = true) -public class LinkedListMultimapTest extends AbstractListMultimapTest { +public class LinkedListMultimapTest extends TestCase { @GwtIncompatible("suite") public static Test suite() { @@ -77,7 +76,9 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionFeature.SERIALIZABLE, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY) @@ -86,7 +87,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { return suite; } - @Override protected LinkedListMultimap<String, Integer> create() { + protected LinkedListMultimap<String, Integer> create() { return LinkedListMultimap.create(); } @@ -128,10 +129,14 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { } public void testCreateFromMultimap() { - Multimap<String, Integer> multimap = createSample(); + Multimap<String, Integer> multimap = LinkedListMultimap.create(); + multimap.put("foo", 1); + multimap.put("bar", 3); + multimap.put("foo", 2); LinkedListMultimap<String, Integer> copy = LinkedListMultimap.create(multimap); assertEquals(multimap, copy); + ASSERT.that(copy.entries()).has().exactlyAs(multimap.entries()).inOrder(); } public void testCreateFromSize() { @@ -150,13 +155,6 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { } catch (IllegalArgumentException expected) {} } - /* "Linked" prefix avoids collision with AbstractMultimapTest. */ - - public void testLinkedToString() { - assertEquals("{foo=[3, -1, 2, 4, 1], bar=[1, 2, 3, 1]}", - createSample().toString()); - } - public void testLinkedGetAdd() { LinkedListMultimap<String, Integer> map = create(); map.put("bar", 1); @@ -232,10 +230,10 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { List<Integer> foos = map.get("foo"); Collection<Integer> values = map.values(); assertEquals(asList(1, 2), foos); - assertThat(values).has().allOf(1, 2, 3).inOrder(); + ASSERT.that(values).has().exactly(1, 2, 3).inOrder(); map.clear(); assertEquals(Collections.emptyList(), foos); - assertThat(values).isEmpty(); + ASSERT.that(values).isEmpty(); assertEquals("[]", map.entries().toString()); assertEquals("{}", map.toString()); } @@ -259,7 +257,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { map.put("bar", 4); assertEquals("[bar=1, foo=2, bar=3, bar=4]", map.entries().toString()); - assertThat(map.keys()).has().allOf("bar", "foo", "bar", "bar").inOrder(); + ASSERT.that(map.keys()).has().exactly("bar", "foo", "bar", "bar").inOrder(); map.keys().remove("bar"); // bar is no longer the first key! assertEquals("{foo=[2], bar=[3, 4]}", map.toString()); } @@ -305,7 +303,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { = map.asMap().entrySet().iterator(); Map.Entry<String, Collection<Integer>> entry = entries.next(); assertEquals("bar", entry.getKey()); - assertThat(entry.getValue()).has().allOf(1, 3).inOrder(); + ASSERT.that(entry.getValue()).has().exactly(1, 3).inOrder(); try { entry.setValue(Arrays.<Integer>asList()); fail("UnsupportedOperationException expected"); @@ -313,32 +311,11 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { entries.remove(); // clear entry = entries.next(); assertEquals("foo", entry.getKey()); - assertThat(entry.getValue()).has().item(2); + ASSERT.that(entry.getValue()).has().item(2); assertFalse(entries.hasNext()); assertEquals("{foo=[2]}", map.toString()); } - /** - * Test calling setValue() on an entry returned by multimap.entries(). - */ - @Override public void testEntrySetValue() { - ListMultimap<String, Integer> multimap = create(); - multimap.put("foo", 1); - multimap.put("bar", 3); - Collection<Map.Entry<String, Integer>> entries = multimap.entries(); - Iterator<Map.Entry<String, Integer>> iterator = entries.iterator(); - Map.Entry<String, Integer> entrya = iterator.next(); - Map.Entry<String, Integer> entryb = iterator.next(); - - int oldValue = entrya.setValue(2); - assertEquals(1, oldValue); - assertFalse(multimap.containsEntry("foo", 1)); - assertTrue(multimap.containsEntry("foo", 2)); - assertTrue(multimap.containsEntry("bar", 3)); - assertEquals(2, (int) entrya.getValue()); - assertEquals(3, (int) entryb.getValue()); - } - public void testEntriesAfterMultimapUpdate() { ListMultimap<String, Integer> multimap = create(); multimap.put("foo", 2); @@ -364,7 +341,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { } @SuppressWarnings("unchecked") - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testEntriesIteration() { List<Entry<String, Integer>> addItems = ImmutableList.of( Maps.immutableEntry("foo", 99), @@ -397,7 +374,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { } } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testKeysIteration() { new IteratorTester<String>(6, MODIFIABLE, newArrayList("foo", "foo", "bar", "bar", "foo"), IteratorTester.KnownOrder.KNOWN_ORDER) { @@ -417,7 +394,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { }.test(); } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testValuesIteration() { List<Integer> addItems = ImmutableList.of(99, 88, 77); @@ -443,7 +420,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { } } - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testKeySetIteration() { new IteratorTester<String>(6, MODIFIABLE, newLinkedHashSet(asList( "foo", "bar", "baz", "dog", "cat")), @@ -469,7 +446,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { } @SuppressWarnings("unchecked") - @GwtIncompatible("unreasonable slow") + @GwtIncompatible("unreasonably slow") public void testAsSetIteration() { Set<Entry<String, Collection<Integer>>> set = Sets.newLinkedHashSet(asList( Maps.immutableEntry("foo", @@ -516,10 +493,4 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest { LinkedListMultimap.create(1)) .testEquals(); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/ListsTest.java b/guava-tests/test/com/google/common/collect/ListsTest.java index 8409838..31731f2 100644 --- a/guava-tests/test/com/google/common/collect/ListsTest.java +++ b/guava-tests/test/com/google/common/collect/ListsTest.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -33,10 +34,15 @@ import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; import com.google.common.collect.testing.google.ListGenerators.CharactersOfCharSequenceGenerator; import com.google.common.collect.testing.google.ListGenerators.CharactersOfStringGenerator; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.easymock.EasyMock; + import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; @@ -49,12 +55,6 @@ import java.util.NoSuchElementException; import java.util.RandomAccess; import java.util.concurrent.CopyOnWriteArrayList; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.easymock.EasyMock; - /** * Unit test for {@code Lists}. * @@ -418,7 +418,7 @@ public class ListsTest extends TestCase { } private void checkFooBarBazList(List<String> list) { - FluentAsserts.assertThat(list).has().allOf("foo", "bar", "baz").inOrder(); + ASSERT.that(list).has().exactly("foo", "bar", "baz").inOrder(); assertEquals(3, list.size()); assertIndexIsOutOfBounds(list, -1); assertEquals("foo", list.get(0)); @@ -429,7 +429,7 @@ public class ListsTest extends TestCase { public void testAsList1Small() { List<String> list = Lists.asList("foo", new String[0]); - FluentAsserts.assertThat(list).has().item("foo"); + ASSERT.that(list).has().item("foo"); assertEquals(1, list.size()); assertIndexIsOutOfBounds(list, -1); assertEquals("foo", list.get(0)); @@ -460,7 +460,7 @@ public class ListsTest extends TestCase { @GwtIncompatible("SerializableTester") public void testAsList2Small() { List<String> list = Lists.asList("foo", "bar", new String[0]); - FluentAsserts.assertThat(list).has().allOf("foo", "bar").inOrder(); + ASSERT.that(list).has().exactly("foo", "bar").inOrder(); assertEquals(2, list.size()); assertIndexIsOutOfBounds(list, -1); assertEquals("foo", list.get(0)); @@ -532,24 +532,24 @@ public class ListsTest extends TestCase { @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_binary1x1() { - FluentAsserts.assertThat(Lists.cartesianProduct(list(1), list(2))).has().item(list(1, 2)); + ASSERT.that(Lists.cartesianProduct(list(1), list(2))).has().item(list(1, 2)); } @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_binary1x2() { - FluentAsserts.assertThat(Lists.cartesianProduct(list(1), list(2, 3))) - .has().allOf(list(1, 2), list(1, 3)).inOrder(); + ASSERT.that(Lists.cartesianProduct(list(1), list(2, 3))) + .has().exactly(list(1, 2), list(1, 3)).inOrder(); } @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_binary2x2() { - FluentAsserts.assertThat(Lists.cartesianProduct(list(1, 2), list(3, 4))) - .has().allOf(list(1, 3), list(1, 4), list(2, 3), list(2, 4)).inOrder(); + ASSERT.that(Lists.cartesianProduct(list(1, 2), list(3, 4))) + .has().exactly(list(1, 3), list(1, 4), list(2, 3), list(2, 4)).inOrder(); } @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_2x2x2() { - FluentAsserts.assertThat(Lists.cartesianProduct(list(0, 1), list(0, 1), list(0, 1))).has().allOf( + ASSERT.that(Lists.cartesianProduct(list(0, 1), list(0, 1), list(0, 1))).has().exactly( list(0, 0, 0), list(0, 0, 1), list(0, 1, 0), list(0, 1, 1), list(1, 0, 0), list(1, 0, 1), list(1, 1, 0), list(1, 1, 1)).inOrder(); } @@ -574,7 +574,8 @@ public class ListsTest extends TestCase { List<Object> exp3 = list((Object) 2, "3"); List<Object> exp4 = list((Object) 2, "4"); - FluentAsserts.assertThat(Lists.<Object>cartesianProduct(x, y)).has().allOf(exp1, exp2, exp3, exp4).inOrder(); + ASSERT.that(Lists.<Object>cartesianProduct(x, y)) + .has().exactly(exp1, exp2, exp3, exp4).inOrder(); } @SuppressWarnings("unchecked") // varargs! @@ -680,6 +681,20 @@ public class ListsTest extends TestCase { assertTransformListIterator(list); } + public void testTransformPreservesIOOBEsThrownByFunction() { + try { + Lists.transform(ImmutableList.of("foo", "bar"), new Function<String, String>() { + @Override + public String apply(String input) { + throw new IndexOutOfBoundsException(); + } + }).toArray(); + fail(); + } catch (IndexOutOfBoundsException expected) { + // success + } + } + private static void assertTransformListIterator(List<String> list) { ListIterator<String> iterator = list.listIterator(1); assertEquals(1, iterator.nextIndex()); @@ -887,6 +902,4 @@ public class ListsTest extends TestCase { public void testPartitionSize_2() { assertEquals(2, Lists.partition(Collections.nCopies(0x40000001, 1), 0x40000000).size()); } - - // These tests are quick and basic and don't actually show unmodifiability... } diff --git a/guava-tests/test/com/google/common/collect/MapConstraintsTest.java b/guava-tests/test/com/google/common/collect/MapConstraintsTest.java index d253a4e..3f9fa66 100644 --- a/guava-tests/test/com/google/common/collect/MapConstraintsTest.java +++ b/guava-tests/test/com/google/common/collect/MapConstraintsTest.java @@ -24,6 +24,8 @@ import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Supplier; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.io.Serializable; import java.util.AbstractMap; import java.util.Arrays; @@ -40,10 +42,6 @@ import java.util.RandomAccess; import java.util.Set; import java.util.SortedSet; -import junit.framework.TestCase; - -import org.truth0.subjects.CollectionSubject; - /** * Tests for {@code MapConstraints}. * @@ -65,9 +63,11 @@ public class MapConstraintsTest extends TestCase { private static final long serialVersionUID = 0; } - static final MapConstraint<String, Integer> TEST_CONSTRAINT = new TestConstraint(); + static final MapConstraint<String, Integer> TEST_CONSTRAINT + = new TestConstraint(); - private static final class TestConstraint implements MapConstraint<String, Integer>, Serializable { + private static final class TestConstraint + implements MapConstraint<String, Integer>, Serializable { @Override public void checkKeyValue(String key, Integer value) { if (TEST_KEY.equals(key)) { @@ -77,7 +77,6 @@ public class MapConstraintsTest extends TestCase { throw new TestValueException(); } } - private static final long serialVersionUID = 0; } @@ -101,7 +100,8 @@ public class MapConstraintsTest extends TestCase { public void testConstrainedMapLegal() { Map<String, Integer> map = Maps.newLinkedHashMap(); - Map<String, Integer> constrained = MapConstraints.constrainedMap(map, TEST_CONSTRAINT); + Map<String, Integer> constrained = MapConstraints.constrainedMap( + map, TEST_CONSTRAINT); map.put(TEST_KEY, TEST_VALUE); constrained.put("foo", 1); map.putAll(ImmutableMap.of("bar", 2)); @@ -110,19 +110,22 @@ public class MapConstraintsTest extends TestCase { assertTrue(constrained.equals(map)); assertEquals(map.entrySet(), constrained.entrySet()); assertEquals(map.keySet(), constrained.keySet()); - assertEquals(HashMultiset.create(map.values()), HashMultiset.create(constrained.values())); + assertEquals(HashMultiset.create(map.values()), + HashMultiset.create(constrained.values())); assertFalse(map.values() instanceof Serializable); assertEquals(map.toString(), constrained.toString()); assertEquals(map.hashCode(), constrained.hashCode()); - assertThat(map.entrySet()) - .has() - .allOf(Maps.immutableEntry(TEST_KEY, TEST_VALUE), Maps.immutableEntry("foo", 1), - Maps.immutableEntry("bar", 2), Maps.immutableEntry("baz", 3)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly( + Maps.immutableEntry(TEST_KEY, TEST_VALUE), + Maps.immutableEntry("foo", 1), + Maps.immutableEntry("bar", 2), + Maps.immutableEntry("baz", 3)).inOrder(); } public void testConstrainedMapIllegal() { Map<String, Integer> map = Maps.newLinkedHashMap(); - Map<String, Integer> constrained = MapConstraints.constrainedMap(map, TEST_CONSTRAINT); + Map<String, Integer> constrained = MapConstraints.constrainedMap( + map, TEST_CONSTRAINT); try { constrained.put(TEST_KEY, TEST_VALUE); fail("TestKeyException expected"); @@ -145,8 +148,10 @@ public class MapConstraintsTest extends TestCase { public void testConstrainedBiMapLegal() { BiMap<String, Integer> map = new AbstractBiMap<String, Integer>( - Maps.<String, Integer>newLinkedHashMap(), Maps.<Integer, String>newLinkedHashMap()) {}; - BiMap<String, Integer> constrained = MapConstraints.constrainedBiMap(map, TEST_CONSTRAINT); + Maps.<String, Integer>newLinkedHashMap(), + Maps.<Integer, String>newLinkedHashMap()) {}; + BiMap<String, Integer> constrained = MapConstraints.constrainedBiMap( + map, TEST_CONSTRAINT); map.put(TEST_KEY, TEST_VALUE); constrained.put("foo", 1); map.putAll(ImmutableMap.of("bar", 2)); @@ -158,16 +163,19 @@ public class MapConstraintsTest extends TestCase { assertEquals(map.values(), constrained.values()); assertEquals(map.toString(), constrained.toString()); assertEquals(map.hashCode(), constrained.hashCode()); - assertThat(map.entrySet()) - .has() - .allOf(Maps.immutableEntry(TEST_KEY, TEST_VALUE), Maps.immutableEntry("foo", 1), - Maps.immutableEntry("bar", 2), Maps.immutableEntry("baz", 3)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly( + Maps.immutableEntry(TEST_KEY, TEST_VALUE), + Maps.immutableEntry("foo", 1), + Maps.immutableEntry("bar", 2), + Maps.immutableEntry("baz", 3)).inOrder(); } public void testConstrainedBiMapIllegal() { BiMap<String, Integer> map = new AbstractBiMap<String, Integer>( - Maps.<String, Integer>newLinkedHashMap(), Maps.<Integer, String>newLinkedHashMap()) {}; - BiMap<String, Integer> constrained = MapConstraints.constrainedBiMap(map, TEST_CONSTRAINT); + Maps.<String, Integer>newLinkedHashMap(), + Maps.<Integer, String>newLinkedHashMap()) {}; + BiMap<String, Integer> constrained = MapConstraints.constrainedBiMap( + map, TEST_CONSTRAINT); try { constrained.put(TEST_KEY, TEST_VALUE); fail("TestKeyException expected"); @@ -202,8 +210,8 @@ public class MapConstraintsTest extends TestCase { public void testConstrainedMultimapLegal() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); + Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap( + multimap, TEST_CONSTRAINT); multimap.put(TEST_KEY, TEST_VALUE); constrained.put("foo", 1); multimap.get("bar").add(2); @@ -212,15 +220,19 @@ public class MapConstraintsTest extends TestCase { constrained.get("zig").addAll(Arrays.asList(5)); multimap.putAll("zag", Arrays.asList(6)); constrained.putAll("bee", Arrays.asList(7)); - multimap.putAll(new ImmutableMultimap.Builder<String, Integer>().put("bim", 8).build()); - constrained.putAll(new ImmutableMultimap.Builder<String, Integer>().put("bop", 9).build()); - multimap.putAll(new ImmutableMultimap.Builder<String, Integer>().put("dig", 10).build()); - constrained.putAll(new ImmutableMultimap.Builder<String, Integer>().put("dag", 11).build()); + multimap.putAll(new ImmutableMultimap.Builder<String, Integer>() + .put("bim", 8).build()); + constrained.putAll(new ImmutableMultimap.Builder<String, Integer>() + .put("bop", 9).build()); + multimap.putAll(new ImmutableMultimap.Builder<String, Integer>() + .put("dig", 10).build()); + constrained.putAll(new ImmutableMultimap.Builder<String, Integer>() + .put("dag", 11).build()); assertTrue(multimap.equals(constrained)); assertTrue(constrained.equals(multimap)); - assertThat(ImmutableList.copyOf(multimap.entries())).is( - ImmutableList.copyOf(constrained.entries())); - assertThat(constrained.asMap().get("foo")).has().item(1); + ASSERT.that(ImmutableList.copyOf(multimap.entries())) + .is(ImmutableList.copyOf(constrained.entries())); + ASSERT.that(constrained.asMap().get("foo")).has().item(1); assertNull(constrained.asMap().get("missing")); assertEquals(multimap.asMap(), constrained.asMap()); assertEquals(multimap.values(), constrained.values()); @@ -228,57 +240,74 @@ public class MapConstraintsTest extends TestCase { assertEquals(multimap.keySet(), constrained.keySet()); assertEquals(multimap.toString(), constrained.toString()); assertEquals(multimap.hashCode(), constrained.hashCode()); - assertThat(multimap.entries()) - .has() - .allOf(Maps.immutableEntry(TEST_KEY, TEST_VALUE), Maps.immutableEntry("foo", 1), - Maps.immutableEntry("bar", 2), Maps.immutableEntry("baz", 3), - Maps.immutableEntry("qux", 4), Maps.immutableEntry("zig", 5), - Maps.immutableEntry("zag", 6), Maps.immutableEntry("bee", 7), - Maps.immutableEntry("bim", 8), Maps.immutableEntry("bop", 9), - Maps.immutableEntry("dig", 10), Maps.immutableEntry("dag", 11)).inOrder(); + ASSERT.that(multimap.entries()).has().exactly( + Maps.immutableEntry(TEST_KEY, TEST_VALUE), + Maps.immutableEntry("foo", 1), + Maps.immutableEntry("bar", 2), + Maps.immutableEntry("baz", 3), + Maps.immutableEntry("qux", 4), + Maps.immutableEntry("zig", 5), + Maps.immutableEntry("zag", 6), + Maps.immutableEntry("bee", 7), + Maps.immutableEntry("bim", 8), + Maps.immutableEntry("bop", 9), + Maps.immutableEntry("dig", 10), + Maps.immutableEntry("dag", 11)).inOrder(); assertFalse(constrained.asMap().values() instanceof Serializable); - Iterator<Collection<Integer>> iterator = constrained.asMap().values().iterator(); + Iterator<Collection<Integer>> iterator = + constrained.asMap().values().iterator(); iterator.next(); iterator.next().add(12); assertTrue(multimap.containsEntry("foo", 12)); } public void testConstrainedTypePreservingList() { - ListMultimap<String, Integer> multimap = MapConstraints.constrainedListMultimap( - LinkedListMultimap.<String, Integer>create(), TEST_CONSTRAINT); + ListMultimap<String, Integer> multimap + = MapConstraints.constrainedListMultimap( + LinkedListMultimap.<String, Integer>create(), + TEST_CONSTRAINT); multimap.put("foo", 1); - Map.Entry<String, Collection<Integer>> entry = multimap.asMap().entrySet().iterator().next(); + Map.Entry<String, Collection<Integer>> entry + = multimap.asMap().entrySet().iterator().next(); assertTrue(entry.getValue() instanceof List); assertFalse(multimap.entries() instanceof Set); assertFalse(multimap.get("foo") instanceof RandomAccess); } public void testConstrainedTypePreservingRandomAccessList() { - ListMultimap<String, Integer> multimap = MapConstraints.constrainedListMultimap( - ArrayListMultimap.<String, Integer>create(), TEST_CONSTRAINT); + ListMultimap<String, Integer> multimap + = MapConstraints.constrainedListMultimap( + ArrayListMultimap.<String, Integer>create(), + TEST_CONSTRAINT); multimap.put("foo", 1); - Map.Entry<String, Collection<Integer>> entry = multimap.asMap().entrySet().iterator().next(); + Map.Entry<String, Collection<Integer>> entry + = multimap.asMap().entrySet().iterator().next(); assertTrue(entry.getValue() instanceof List); assertFalse(multimap.entries() instanceof Set); assertTrue(multimap.get("foo") instanceof RandomAccess); } public void testConstrainedTypePreservingSet() { - SetMultimap<String, Integer> multimap = MapConstraints.constrainedSetMultimap( - LinkedHashMultimap.<String, Integer>create(), TEST_CONSTRAINT); + SetMultimap<String, Integer> multimap + = MapConstraints.constrainedSetMultimap( + LinkedHashMultimap.<String, Integer>create(), + TEST_CONSTRAINT); multimap.put("foo", 1); - Map.Entry<String, Collection<Integer>> entry = multimap.asMap().entrySet().iterator().next(); + Map.Entry<String, Collection<Integer>> entry + = multimap.asMap().entrySet().iterator().next(); assertTrue(entry.getValue() instanceof Set); } public void testConstrainedTypePreservingSortedSet() { Comparator<Integer> comparator = Collections.reverseOrder(); - SortedSetMultimap<String, Integer> delegate = TreeMultimap.create(Ordering.<String>natural(), - comparator); - SortedSetMultimap<String, Integer> multimap = MapConstraints.constrainedSortedSetMultimap( - delegate, TEST_CONSTRAINT); + SortedSetMultimap<String, Integer> delegate + = TreeMultimap.create(Ordering.<String>natural(), comparator); + SortedSetMultimap<String, Integer> multimap + = MapConstraints.constrainedSortedSetMultimap(delegate, + TEST_CONSTRAINT); multimap.put("foo", 1); - Map.Entry<String, Collection<Integer>> entry = multimap.asMap().entrySet().iterator().next(); + Map.Entry<String, Collection<Integer>> entry + = multimap.asMap().entrySet().iterator().next(); assertTrue(entry.getValue() instanceof SortedSet); assertSame(comparator, multimap.valueComparator()); assertSame(comparator, multimap.get("foo").comparator()); @@ -287,8 +316,8 @@ public class MapConstraintsTest extends TestCase { @SuppressWarnings("unchecked") public void testConstrainedMultimapIllegal() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); + Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap( + multimap, TEST_CONSTRAINT); try { constrained.put(TEST_KEY, 1); fail("TestKeyException expected"); @@ -338,18 +367,18 @@ public class MapConstraintsTest extends TestCase { fail("TestKeyException expected"); } catch (TestKeyException expected) {} try { - constrained.putAll(new ImmutableMultimap.Builder<String, Integer>().put(TEST_KEY, 2) - .put("foo", 1).build()); + constrained.putAll(new ImmutableMultimap.Builder<String, Integer>() + .put(TEST_KEY, 2).put("foo", 1).build()); fail("TestKeyException expected"); } catch (TestKeyException expected) {} try { - constrained.putAll(new ImmutableMultimap.Builder<String, Integer>().put("bar", TEST_VALUE) - .put("foo", 1).build()); + constrained.putAll(new ImmutableMultimap.Builder<String, Integer>() + .put("bar", TEST_VALUE).put("foo", 1).build()); fail("TestValueException expected"); } catch (TestValueException expected) {} try { - constrained.putAll(new ImmutableMultimap.Builder<String, Integer>().put(TEST_KEY, TEST_VALUE) - .put("foo", 1).build()); + constrained.putAll(new ImmutableMultimap.Builder<String, Integer>() + .put(TEST_KEY, TEST_VALUE).put("foo", 1).build()); fail("TestKeyException expected"); } catch (TestKeyException expected) {} try { @@ -357,8 +386,9 @@ public class MapConstraintsTest extends TestCase { fail("UnsupportedOperationException expected"); } catch (UnsupportedOperationException expected) {} try { - constrained.entries().addAll( - Arrays.asList(Maps.immutableEntry("foo", 1), Maps.immutableEntry(TEST_KEY, 2))); + constrained.entries().addAll(Arrays.asList( + Maps.immutableEntry("foo", 1), + Maps.immutableEntry(TEST_KEY, 2))); fail("UnsupportedOperationException expected"); } catch (UnsupportedOperationException expected) {} assertTrue(multimap.isEmpty()); @@ -373,11 +403,12 @@ public class MapConstraintsTest extends TestCase { fail("TestValueException expected"); } catch (TestValueException expected) {} try { - ((Collection<Integer>) constrained.asMap().values().toArray()[0]).add(TEST_VALUE); + ((Collection<Integer>) constrained.asMap().values().toArray()[0]) + .add(TEST_VALUE); fail("TestValueException expected"); } catch (TestValueException expected) {} - assertThat(ImmutableList.copyOf(multimap.entries())).is( - ImmutableList.copyOf(constrained.entries())); + ASSERT.that(ImmutableList.copyOf(multimap.entries())) + .is(ImmutableList.copyOf(constrained.entries())); assertEquals(multimap.asMap(), constrained.asMap()); assertEquals(multimap.values(), constrained.values()); assertEquals(multimap.keys(), constrained.keys()); @@ -396,8 +427,8 @@ public class MapConstraintsTest extends TestCase { public void testConstrainedMultimapQueue() { Multimap<String, Integer> multimap = Multimaps.newMultimap( new HashMap<String, Collection<Integer>>(), new QueueSupplier()); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); + Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap( + multimap, TEST_CONSTRAINT); constrained.put("foo", 1); assertTrue(constrained.get("foo").contains(1)); assertTrue(multimap.get("foo").contains(1)); @@ -423,10 +454,12 @@ public class MapConstraintsTest extends TestCase { public void testMapEntrySetToArray() { Map<String, Integer> map = Maps.newLinkedHashMap(); - Map<String, Integer> constrained = MapConstraints.constrainedMap(map, TEST_CONSTRAINT); + Map<String, Integer> constrained + = MapConstraints.constrainedMap(map, TEST_CONSTRAINT); map.put("foo", 1); @SuppressWarnings("unchecked") - Map.Entry<String, Integer> entry = (Map.Entry) constrained.entrySet().toArray()[0]; + Map.Entry<String, Integer> entry + = (Map.Entry) constrained.entrySet().toArray()[0]; try { entry.setValue(TEST_VALUE); fail("TestValueException expected"); @@ -436,9 +469,11 @@ public class MapConstraintsTest extends TestCase { public void testMapEntrySetContainsNefariousEntry() { Map<String, Integer> map = Maps.newTreeMap(); - Map<String, Integer> constrained = MapConstraints.constrainedMap(map, TEST_CONSTRAINT); + Map<String, Integer> constrained + = MapConstraints.constrainedMap(map, TEST_CONSTRAINT); map.put("foo", 1); - Map.Entry<String, Integer> nefariousEntry = nefariousMapEntry(TEST_KEY, TEST_VALUE); + Map.Entry<String, Integer> nefariousEntry + = nefariousMapEntry(TEST_KEY, TEST_VALUE); Set<Map.Entry<String, Integer>> entries = constrained.entrySet(); assertFalse(entries.contains(nefariousEntry)); assertFalse(map.containsValue(TEST_VALUE)); @@ -448,12 +483,13 @@ public class MapConstraintsTest extends TestCase { public void testMultimapAsMapEntriesToArray() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); + Multimap<String, Integer> constrained + = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT); multimap.put("foo", 1); @SuppressWarnings("unchecked") - Map.Entry<String, Collection<Integer>> entry = (Map.Entry<String, Collection<Integer>>) constrained - .asMap().entrySet().toArray()[0]; + Map.Entry<String, Collection<Integer>> entry + = (Map.Entry<String, Collection<Integer>>) + constrained.asMap().entrySet().toArray()[0]; try { entry.setValue(Collections.<Integer>emptySet()); fail("UnsupportedOperationException expected"); @@ -467,11 +503,12 @@ public class MapConstraintsTest extends TestCase { public void testMultimapAsMapValuesToArray() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); + Multimap<String, Integer> constrained + = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT); multimap.put("foo", 1); @SuppressWarnings("unchecked") - Collection<Integer> collection = (Collection<Integer>) constrained.asMap().values().toArray()[0]; + Collection<Integer> collection + = (Collection<Integer>) constrained.asMap().values().toArray()[0]; try { collection.add(TEST_VALUE); fail("TestValueException expected"); @@ -481,10 +518,11 @@ public class MapConstraintsTest extends TestCase { public void testMultimapEntriesContainsNefariousEntry() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); + Multimap<String, Integer> constrained + = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT); multimap.put("foo", 1); - Map.Entry<String, Integer> nefariousEntry = nefariousMapEntry(TEST_KEY, TEST_VALUE); + Map.Entry<String, Integer> nefariousEntry + = nefariousMapEntry(TEST_KEY, TEST_VALUE); Collection<Map.Entry<String, Integer>> entries = constrained.entries(); assertFalse(entries.contains(nefariousEntry)); assertFalse(multimap.containsValue(TEST_VALUE)); @@ -494,10 +532,11 @@ public class MapConstraintsTest extends TestCase { public void testMultimapEntriesRemoveNefariousEntry() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); + Multimap<String, Integer> constrained + = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT); multimap.put("foo", 1); - Map.Entry<String, Integer> nefariousEntry = nefariousMapEntry(TEST_KEY, TEST_VALUE); + Map.Entry<String, Integer> nefariousEntry + = nefariousMapEntry(TEST_KEY, TEST_VALUE); Collection<Map.Entry<String, Integer>> entries = constrained.entries(); assertFalse(entries.remove(nefariousEntry)); assertFalse(multimap.containsValue(TEST_VALUE)); @@ -507,12 +546,13 @@ public class MapConstraintsTest extends TestCase { public void testMultimapAsMapEntriesContainsNefariousEntry() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); + Multimap<String, Integer> constrained + = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT); multimap.put("foo", 1); - Map.Entry<String, ? extends Collection<Integer>> nefariousEntry = nefariousMapEntry(TEST_KEY, - Collections.singleton(TEST_VALUE)); - Set<Map.Entry<String, Collection<Integer>>> entries = constrained.asMap().entrySet(); + Map.Entry<String, ? extends Collection<Integer>> nefariousEntry + = nefariousMapEntry(TEST_KEY, Collections.singleton(TEST_VALUE)); + Set<Map.Entry<String, Collection<Integer>>> entries + = constrained.asMap().entrySet(); assertFalse(entries.contains(nefariousEntry)); assertFalse(multimap.containsValue(TEST_VALUE)); assertFalse(entries.containsAll(Collections.singleton(nefariousEntry))); @@ -521,12 +561,13 @@ public class MapConstraintsTest extends TestCase { public void testMultimapAsMapEntriesRemoveNefariousEntry() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); + Multimap<String, Integer> constrained + = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT); multimap.put("foo", 1); - Map.Entry<String, ? extends Collection<Integer>> nefariousEntry = nefariousMapEntry(TEST_KEY, - Collections.singleton(TEST_VALUE)); - Set<Map.Entry<String, Collection<Integer>>> entries = constrained.asMap().entrySet(); + Map.Entry<String, ? extends Collection<Integer>> nefariousEntry + = nefariousMapEntry(TEST_KEY, Collections.singleton(TEST_VALUE)); + Set<Map.Entry<String, Collection<Integer>>> entries + = constrained.asMap().entrySet(); assertFalse(entries.remove(nefariousEntry)); assertFalse(multimap.containsValue(TEST_VALUE)); assertFalse(entries.removeAll(Collections.singleton(nefariousEntry))); @@ -535,7 +576,8 @@ public class MapConstraintsTest extends TestCase { public void testNefariousMapPutAll() { Map<String, Integer> map = Maps.newLinkedHashMap(); - Map<String, Integer> constrained = MapConstraints.constrainedMap(map, TEST_CONSTRAINT); + Map<String, Integer> constrained = MapConstraints.constrainedMap( + map, TEST_CONSTRAINT); Map<String, Integer> onceIterable = onceIterableMap("foo", 1); constrained.putAll(onceIterable); assertEquals((Integer) 1, constrained.get("foo")); @@ -543,27 +585,30 @@ public class MapConstraintsTest extends TestCase { public void testNefariousMultimapPutAllIterable() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); - Collection<Integer> onceIterable = ConstraintsTest.onceIterableCollection(1); + Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap( + multimap, TEST_CONSTRAINT); + Collection<Integer> onceIterable + = ConstraintsTest.onceIterableCollection(1); constrained.putAll("foo", onceIterable); assertEquals(ImmutableList.of(1), constrained.get("foo")); } public void testNefariousMultimapPutAllMultimap() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); - Multimap<String, Integer> onceIterable = Multimaps.forMap(onceIterableMap("foo", 1)); + Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap( + multimap, TEST_CONSTRAINT); + Multimap<String, Integer> onceIterable + = Multimaps.forMap(onceIterableMap("foo", 1)); constrained.putAll(onceIterable); assertEquals(ImmutableList.of(1), constrained.get("foo")); } public void testNefariousMultimapGetAddAll() { Multimap<String, Integer> multimap = LinkedListMultimap.create(); - Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(multimap, - TEST_CONSTRAINT); - Collection<Integer> onceIterable = ConstraintsTest.onceIterableCollection(1); + Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap( + multimap, TEST_CONSTRAINT); + Collection<Integer> onceIterable + = ConstraintsTest.onceIterableCollection(1); constrained.get("foo").addAll(onceIterable); assertEquals(ImmutableList.of(1), constrained.get("foo")); } @@ -581,40 +626,29 @@ public class MapConstraintsTest extends TestCase { final Map.Entry<K, V> entry = Maps.immutableEntry(key, value); return new AbstractMap<K, V>() { boolean iteratorCalled; - - @Override - public int size() { + @Override public int size() { /* * We could make the map empty, but that seems more likely to trigger * special cases (so maybe we should test both empty and nonempty...). */ return 1; } - - @Override - public Set<Entry<K, V>> entrySet() { + @Override public Set<Entry<K, V>> entrySet() { return new ForwardingSet<Entry<K, V>>() { - @Override - protected Set<Entry<K, V>> delegate() { + @Override protected Set<Entry<K, V>> delegate() { return Collections.singleton(entry); } - - @Override - public Iterator<Entry<K, V>> iterator() { + @Override public Iterator<Entry<K, V>> iterator() { assertFalse("Expected only one call to iterator()", iteratorCalled); iteratorCalled = true; return super.iterator(); } }; } - - @Override - public Set<K> keySet() { + @Override public Set<K> keySet() { throw new UnsupportedOperationException(); } - - @Override - public Collection<V> values() { + @Override public Collection<V> values() { throw new UnsupportedOperationException(); } }; @@ -623,12 +657,7 @@ public class MapConstraintsTest extends TestCase { @GwtIncompatible("SerializableTester") public void testSerialization() { // TODO: Test serialization of constrained collections. - assertSame(MapConstraints.notNull(), SerializableTester.reserialize(MapConstraints.notNull())); - } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); + assertSame(MapConstraints.notNull(), + SerializableTester.reserialize(MapConstraints.notNull())); } } diff --git a/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java b/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java index 56dcf08..c8c4d47 100644 --- a/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java +++ b/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java @@ -35,6 +35,8 @@ import com.google.common.collect.MapMakerInternalMap.Strength; import com.google.common.collect.MapMakerInternalMap.ValueReference; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.util.Iterator; @@ -47,8 +49,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReferenceArray; -import junit.framework.TestCase; - /** * @author Charles Fry */ diff --git a/guava-tests/test/com/google/common/collect/MapMakerTest.java b/guava-tests/test/com/google/common/collect/MapMakerTest.java index 7a5aa5d..27e34b9 100644 --- a/guava-tests/test/com/google/common/collect/MapMakerTest.java +++ b/guava-tests/test/com/google/common/collect/MapMakerTest.java @@ -17,38 +17,46 @@ package com.google.common.collect; import static com.google.common.util.concurrent.Uninterruptibles.awaitUninterruptibly; +import static java.util.concurrent.TimeUnit.SECONDS; +import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Function; import com.google.common.collect.MapMaker.RemovalNotification; import com.google.common.collect.MapMakerInternalMapTest.QueuingRemovalListener; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; -import junit.framework.TestCase; - /** * @author Charles Fry */ +@GwtCompatible(emulated = true) public class MapMakerTest extends TestCase { + @GwtIncompatible("NullPointerTester") public void testNullParameters() throws Exception { NullPointerTester tester = new NullPointerTester(); tester.testAllPublicInstanceMethods(new MapMaker()); } + @GwtIncompatible("threads") + public void testRemovalNotification_clear() throws InterruptedException { // If a clear() happens while a computation is pending, we should not get a removal // notification. final CountDownLatch computingLatch = new CountDownLatch(1); - Function<String, String> computingFunction = new DelayingIdentityLoader(computingLatch); + Function<String, String> computingFunction = new DelayingIdentityLoader<String>(computingLatch); QueuingRemovalListener<String, String> listener = new QueuingRemovalListener<String, String>(); @SuppressWarnings("deprecation") // test of deprecated code @@ -98,6 +106,7 @@ public class MapMakerTest extends TestCase { * removal listener), or else is not affected by the {@code clear()} (and therefore exists in the * map afterward). */ + @GwtIncompatible("threads") public void testRemovalNotification_clear_basher() throws InterruptedException { // If a clear() happens close to the end of computation, one of two things should happen: @@ -170,6 +179,7 @@ public class MapMakerTest extends TestCase { assertTrue(Sets.intersection(map.keySet(), removalNotifications.keySet()).isEmpty()); } + @GwtIncompatible("threads") static final class DelayingIdentityLoader<T> implements Function<T, T> { private final CountDownLatch delayLatch; @@ -182,4 +192,145 @@ public class MapMakerTest extends TestCase { return key; } } + + /* + * TODO(cpovirk): eliminate duplication between these tests and those in LegacyMapMakerTests and + * anywhere else + */ + + /** Tests for the builder. */ + public static class MakerTest extends TestCase { + public void testInitialCapacity_negative() { + MapMaker maker = new MapMaker(); + try { + maker.initialCapacity(-1); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + // TODO(cpovirk): enable when ready + public void xtestInitialCapacity_setTwice() { + MapMaker maker = new MapMaker().initialCapacity(16); + try { + // even to the same value is not allowed + maker.initialCapacity(16); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + @SuppressWarnings("deprecation") // test of deprecated method + public void testExpiration_setTwice() { + MapMaker maker = new MapMaker().expireAfterWrite(1 * 60 * 60, SECONDS); + try { + // even to the same value is not allowed + maker.expireAfterWrite(1 * 60 * 60, SECONDS); + fail(); + } catch (IllegalStateException expected) { + } + } + + public void testMaximumSize_setTwice() { + MapMaker maker = new MapMaker().maximumSize(16); + try { + // even to the same value is not allowed + maker.maximumSize(16); + fail(); + } catch (IllegalStateException expected) { + } + } + + public void testReturnsPlainConcurrentHashMapWhenPossible() { + Map<?, ?> map = new MapMaker() + .initialCapacity(5) + .makeMap(); + assertTrue(map instanceof ConcurrentHashMap); + } + } + + /** Tests of the built map with maximumSize. */ + public static class MaximumSizeTest extends TestCase { + public void testPut_sizeIsZero() { + ConcurrentMap<Object, Object> map = + new MapMaker().maximumSize(0).makeMap(); + assertEquals(0, map.size()); + map.put(new Object(), new Object()); + assertEquals(0, map.size()); + } + + public void testSizeBasedEviction() { + int numKeys = 10; + int mapSize = 5; + ConcurrentMap<Object, Object> map = + new MapMaker().maximumSize(mapSize).makeMap(); + for (int i = 0; i < numKeys; i++) { + map.put(i, i); + } + assertEquals(mapSize, map.size()); + for (int i = numKeys - mapSize; i < mapSize; i++) { + assertTrue(map.containsKey(i)); + } + } + } + + /** Tests for recursive computation. */ + public static class RecursiveComputationTest extends TestCase { + Function<Integer, String> recursiveComputer + = new Function<Integer, String>() { + @Override + public String apply(Integer key) { + if (key > 0) { + return key + ", " + recursiveMap.get(key - 1); + } else { + return "0"; + } + } + }; + + ConcurrentMap<Integer, String> recursiveMap = new MapMaker() + .makeComputingMap(recursiveComputer); + + public void testRecursiveComputation() { + assertEquals("3, 2, 1, 0", recursiveMap.get(3)); + } + } + + /** + * Tests for computing functionality. + */ + public static class ComputingTest extends TestCase { + public void testComputerThatReturnsNull() { + ConcurrentMap<Integer, String> map = new MapMaker() + .makeComputingMap(new Function<Integer, String>() { + @Override + public String apply(Integer key) { + return null; + } + }); + try { + map.get(1); + fail(); + } catch (NullPointerException e) { /* expected */ } + } + + public void testRuntimeException() { + final RuntimeException e = new RuntimeException(); + + ConcurrentMap<Object, Object> map = new MapMaker().makeComputingMap( + new Function<Object, Object>() { + @Override + public Object apply(Object from) { + throw e; + } + }); + + try { + map.get(new Object()); + fail(); + } catch (ComputationException ce) { + assertSame(e, ce.getCause()); + } + } + } } diff --git a/guava-tests/test/com/google/common/collect/MapsCollectionTest.java b/guava-tests/test/com/google/common/collect/MapsCollectionTest.java index 16b2572..a6f4b04 100644 --- a/guava-tests/test/com/google/common/collect/MapsCollectionTest.java +++ b/guava-tests/test/com/google/common/collect/MapsCollectionTest.java @@ -19,8 +19,10 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.testing.Helpers.mapEntry; +import com.google.common.base.Charsets; import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.collect.Maps.EntryTransformer; import com.google.common.collect.testing.Helpers; import com.google.common.collect.testing.MapTestSuiteBuilder; import com.google.common.collect.testing.SafeTreeMap; @@ -29,14 +31,18 @@ import com.google.common.collect.testing.SortedMapTestSuiteBuilder; import com.google.common.collect.testing.TestMapGenerator; import com.google.common.collect.testing.TestStringMapGenerator; import com.google.common.collect.testing.TestStringSortedMapGenerator; +import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; -import com.google.common.collect.testing.google.BiMapRemoveTester; import com.google.common.collect.testing.google.BiMapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringBiMapGenerator; -import com.google.common.collect.testing.testers.CollectionIteratorTester; -import com.google.common.testing.SerializableTester; +import com.google.common.io.BaseEncoding; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import java.io.UnsupportedEncodingException; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -48,10 +54,6 @@ import java.util.SortedSet; import javax.annotation.Nullable; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Test suites for wrappers in {@code Maps}. * @@ -78,26 +80,9 @@ public class MapsCollectionTest extends TestCase { CollectionSize.ANY, MapFeature.ALLOWS_NULL_VALUES, MapFeature.ALLOWS_NULL_KEYS, - MapFeature.REJECTS_DUPLICATES_AT_CREATION) - .createTestSuite()); - suite.addTest(BiMapTestSuiteBuilder - .using(new TestStringBiMapGenerator() { - @Override - protected BiMap<String, String> create(Entry<String, String>[] entries) { - BiMap<String, String> bimap = HashBiMap.create(entries.length); - for (Entry<String, String> entry : entries) { - checkArgument(!bimap.containsKey(entry.getKey())); - bimap.put(entry.getKey(), entry.getValue()); - } - return SerializableTester.reserialize(Maps.unmodifiableBiMap(bimap)); - } - }) - .named("unmodifiableBiMap[HashBiMap], reserialized") - .withFeatures( - CollectionSize.ANY, - MapFeature.ALLOWS_NULL_VALUES, - MapFeature.ALLOWS_NULL_KEYS, - MapFeature.REJECTS_DUPLICATES_AT_CREATION) + MapFeature.ALLOWS_ANY_NULL_QUERIES, + MapFeature.REJECTS_DUPLICATES_AT_CREATION, + CollectionFeature.SERIALIZABLE) .createTestSuite()); suite.addTest(MapTestSuiteBuilder .using(new TestMapGenerator<String, Integer>() { @@ -151,9 +136,10 @@ public class MapsCollectionTest extends TestCase { }) .named("Maps.asMap[Set, Function]") .withFeatures(CollectionSize.ANY, - MapFeature.SUPPORTS_REMOVE) + MapFeature.SUPPORTS_REMOVE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE) .createTestSuite()); - suite.addTest(MapTestSuiteBuilder + suite.addTest(SortedMapTestSuiteBuilder .using(new TestMapGenerator<String, Integer>() { @Override public String[] createKeyArray(int length) { @@ -211,9 +197,11 @@ public class MapsCollectionTest extends TestCase { }) .named("Maps.asMap[SortedSet, Function]") .withFeatures(CollectionSize.ANY, - MapFeature.SUPPORTS_REMOVE) + MapFeature.SUPPORTS_REMOVE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE) .createTestSuite()); suite.addTest(filterSuite()); + suite.addTest(transformSuite()); return suite; } @@ -240,9 +228,9 @@ public class MapsCollectionTest extends TestCase { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() { @Override @@ -257,9 +245,9 @@ public class MapsCollectionTest extends TestCase { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() { @Override @@ -274,9 +262,9 @@ public class MapsCollectionTest extends TestCase { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() { @Override @@ -292,9 +280,9 @@ public class MapsCollectionTest extends TestCase { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod()) .createTestSuite()); return suite; } @@ -316,8 +304,6 @@ public class MapsCollectionTest extends TestCase { MapFeature.ALLOWS_NULL_VALUES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - BiMapRemoveTester.getKeySetIteratorRemoveMethod()) .createTestSuite()); suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() { @Override @@ -332,10 +318,9 @@ public class MapsCollectionTest extends TestCase { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - BiMapRemoveTester.getKeySetIteratorRemoveMethod()) .createTestSuite()); suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() { @Override @@ -350,10 +335,9 @@ public class MapsCollectionTest extends TestCase { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - BiMapRemoveTester.getKeySetIteratorRemoveMethod()) .createTestSuite()); return suite; } @@ -374,7 +358,6 @@ public class MapsCollectionTest extends TestCase { MapFeature.ALLOWS_NULL_VALUES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() { @Override @@ -390,7 +373,6 @@ public class MapsCollectionTest extends TestCase { MapFeature.ALLOWS_NULL_VALUES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() { @Override @@ -406,7 +388,6 @@ public class MapsCollectionTest extends TestCase { MapFeature.ALLOWS_NULL_VALUES, MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) - .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); return suite; } @@ -489,4 +470,120 @@ public class MapsCollectionTest extends TestCase { return delegate; } } + + private static String encode(String str) { + try { + return BaseEncoding.base64().encode(str.getBytes(Charsets.UTF_8.name())); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } + } + + private static final Function<String, String> DECODE_FUNCTION = new Function<String, String>() { + @Override + public String apply(String input) { + try { + return new String(BaseEncoding.base64().decode(input), Charsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); + } + } + }; + + private static final EntryTransformer<String, String, String> DECODE_ENTRY_TRANSFORMER = + new EntryTransformer<String, String, String>() { + @Override + public String transformEntry(String key, String value) { + return DECODE_FUNCTION.apply(value); + } + }; + + static TestSuite transformSuite() { + TestSuite suite = new TestSuite("Maps.transform"); + suite.addTest(transformMapSuite()); + suite.addTest(transformSortedMapSuite()); + return suite; + } + + static TestSuite transformMapSuite() { + TestSuite suite = new TestSuite("TransformMap"); + suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() { + @Override + protected Map<String, String> create(Entry<String, String>[] entries) { + Map<String, String> map = Maps.newLinkedHashMap(); + for (Entry<String, String> entry : entries) { + map.put(entry.getKey(), encode(entry.getValue())); + } + return Maps.transformValues(map, DECODE_FUNCTION); + } + }) + .named("Maps.transformValues[Map, Function]") + .withFeatures( + CollectionSize.ANY, + CollectionFeature.KNOWN_ORDER, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_ANY_NULL_QUERIES, + MapFeature.SUPPORTS_REMOVE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE) + .createTestSuite()); + suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() { + @Override + protected Map<String, String> create(Entry<String, String>[] entries) { + Map<String, String> map = Maps.newLinkedHashMap(); + for (Entry<String, String> entry : entries) { + map.put(entry.getKey(), encode(entry.getValue())); + } + return Maps.transformEntries(map, DECODE_ENTRY_TRANSFORMER); + } + }) + .named("Maps.transformEntries[Map, EntryTransformer]") + .withFeatures( + CollectionSize.ANY, + CollectionFeature.KNOWN_ORDER, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_ANY_NULL_QUERIES, + MapFeature.SUPPORTS_REMOVE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE) + .createTestSuite()); + return suite; + } + + static TestSuite transformSortedMapSuite() { + TestSuite suite = new TestSuite("TransformSortedMap"); + suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() { + @Override + protected SortedMap<String, String> create(Entry<String, String>[] entries) { + SortedMap<String, String> map = new NonNavigableSortedMap(); + for (Entry<String, String> entry : entries) { + map.put(entry.getKey(), encode(entry.getValue())); + } + return Maps.transformValues(map, DECODE_FUNCTION); + } + }) + .named("Maps.transformValues[SortedMap, Function]") + .withFeatures( + CollectionSize.ANY, + CollectionFeature.KNOWN_ORDER, + MapFeature.SUPPORTS_REMOVE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE) + .createTestSuite()); + suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() { + @Override + protected SortedMap<String, String> create(Entry<String, String>[] entries) { + SortedMap<String, String> map = new NonNavigableSortedMap(); + for (Entry<String, String> entry : entries) { + map.put(entry.getKey(), encode(entry.getValue())); + } + return Maps.transformEntries(map, DECODE_ENTRY_TRANSFORMER); + } + }) + .named("Maps.transformEntries[SortedMap, EntryTransformer]") + .withFeatures( + CollectionSize.ANY, + CollectionFeature.KNOWN_ORDER, + MapFeature.SUPPORTS_REMOVE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE) + .createTestSuite()); + return suite; + } } diff --git a/guava-tests/test/com/google/common/collect/MapsTest.java b/guava-tests/test/com/google/common/collect/MapsTest.java index 45790cd..2eddd09 100644 --- a/guava-tests/test/com/google/common/collect/MapsTest.java +++ b/guava-tests/test/com/google/common/collect/MapsTest.java @@ -19,9 +19,12 @@ package com.google.common.collect; import static com.google.common.collect.Maps.transformEntries; import static com.google.common.collect.Maps.transformValues; import static com.google.common.collect.testing.Helpers.mapEntry; +import static java.util.Arrays.asList; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; +import com.google.common.base.Converter; import com.google.common.base.Equivalence; import com.google.common.base.Function; import com.google.common.base.Functions; @@ -32,12 +35,10 @@ import com.google.common.collect.Maps.ValueDifferenceImpl; import com.google.common.collect.SetsTest.Derived; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; +import com.google.common.testing.SerializableTester; import junit.framework.TestCase; -import org.truth0.Truth; -import org.truth0.subjects.CollectionSubject; - import java.io.IOException; import java.io.StringBufferInputStream; import java.lang.reflect.Field; @@ -71,7 +72,8 @@ import java.util.concurrent.ConcurrentMap; @GwtCompatible(emulated = true) public class MapsTest extends TestCase { - private static final Comparator<Integer> SOME_COMPARATOR = Collections.reverseOrder(); + private static final Comparator<Integer> SOME_COMPARATOR = + Collections.reverseOrder(); public void testHashMap() { HashMap<Integer, Integer> map = Maps.newHashMap(); @@ -92,8 +94,8 @@ public class MapsTest extends TestCase { original.put("a", 1); original.put("b", 2); original.put("c", 3); - HashMap<Object, Object> map = Maps - .newHashMap((Map<? extends Object, ? extends Object>) original); + HashMap<Object, Object> map = + Maps.newHashMap((Map<? extends Object, ? extends Object>) original); assertEquals(original, map); } @@ -101,26 +103,39 @@ public class MapsTest extends TestCase { try { Maps.capacity(-1); fail("Negative expected size must result in IllegalArgumentException"); - } catch (IllegalArgumentException ex) {} + } catch (IllegalArgumentException ex) { + } } /** * Tests that nHMWES makes hash maps large enough that adding the expected * number of elements won't cause a rehash. * + * As of jdk7u40, HashMap has an empty-map optimization. The argument to + * new HashMap(int) is noted, but the initial table is a zero-length array. + * * This test may fail miserably on non-OpenJDK environments... */ @GwtIncompatible("reflection") - public void notestNewHashMapWithExpectedSize_wontGrow() throws Exception { - for (int size = 0; size < 200; size++) { + public void testNewHashMapWithExpectedSize_wontGrow() throws Exception { + // before jdk7u40: creates one-bucket table + // after jdk7u40: creates empty table + assertTrue(bucketsOf(Maps.newHashMapWithExpectedSize(0)) <= 1); + + for (int size = 1; size < 200; size++) { HashMap<Integer, Void> map1 = Maps.newHashMapWithExpectedSize(size); - int startSize = sizeOf(map1); + // Only start measuring table size after the first element inserted, to + // deal with empty-map optimization. + map1.put(0, null); + + int initialBuckets = bucketsOf(map1); - for (int i = 0; i < size; i++) { + for (int i = 1; i < size; i++) { map1.put(i, null); } - assertEquals("table size after adding " + size + "elements", startSize, sizeOf(map1)); + assertEquals("table size after adding " + size + " elements", + initialBuckets, bucketsOf(map1)); /* * Something slightly different happens when the entries are added all at @@ -128,12 +143,13 @@ public class MapsTest extends TestCase { */ HashMap<Integer, Void> map2 = Maps.newHashMapWithExpectedSize(size); map2.putAll(map1); - assertEquals("table size after adding " + size + "elements", startSize, sizeOf(map2)); + assertEquals("table size after adding " + size + "elements", + initialBuckets, bucketsOf(map2)); } } @GwtIncompatible("reflection") - private static int sizeOf(HashMap<?, ?> hashMap) throws Exception { + private static int bucketsOf(HashMap<?, ?> hashMap) throws Exception { Field tableField = HashMap.class.getDeclaredField("table"); tableField.setAccessible(true); Object[] table = (Object[]) tableField.get(hashMap); @@ -141,11 +157,16 @@ public class MapsTest extends TestCase { } public void testCapacityForLargeSizes() { - int[] largeExpectedSizes = new int[] { Integer.MAX_VALUE / 2 - 1, Integer.MAX_VALUE / 2, - Integer.MAX_VALUE / 2 + 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE }; + int[] largeExpectedSizes = new int[] { + Integer.MAX_VALUE / 2 - 1, + Integer.MAX_VALUE / 2, + Integer.MAX_VALUE / 2 + 1, + Integer.MAX_VALUE - 1, + Integer.MAX_VALUE}; for (int expectedSize : largeExpectedSizes) { int capacity = Maps.capacity(expectedSize); - assertTrue("capacity (" + capacity + ") must be >= expectedSize (" + expectedSize + ")", + assertTrue( + "capacity (" + capacity + ") must be >= expectedSize (" + expectedSize + ")", capacity >= expectedSize); } } @@ -157,14 +178,12 @@ public class MapsTest extends TestCase { @SuppressWarnings("serial") public void testLinkedHashMapWithInitialMap() { - Map<String, String> map = new LinkedHashMap<String, String>() { - { - put("Hello", "World"); - put("first", "second"); - put("polygene", "lubricants"); - put("alpha", "betical"); - } - }; + Map<String, String> map = new LinkedHashMap<String, String>() {{ + put("Hello", "World"); + put("first", "second"); + put("polygene", "lubricants"); + put("alpha", "betical"); + }}; LinkedHashMap<String, String> copy = Maps.newLinkedHashMap(map); @@ -196,7 +215,8 @@ public class MapsTest extends TestCase { original.put("a", 1); original.put("b", 2); original.put("c", 3); - HashMap<Object, Object> map = Maps.<Object, Object>newLinkedHashMap(original); + HashMap<Object, Object> map + = Maps.<Object, Object>newLinkedHashMap(original); assertEquals(original, map); } @@ -221,8 +241,9 @@ public class MapsTest extends TestCase { assertEquals(Collections.emptyMap(), map); map.put(new Derived("foo"), 1); map.put(new Derived("bar"), 2); - ASSERT.that(map.keySet()).has().allOf(new Derived("bar"), new Derived("foo")).inOrder(); - ASSERT.that(map.values()).has().allOf(2, 1).inOrder(); + ASSERT.that(map.keySet()).has().exactly( + new Derived("bar"), new Derived("foo")).inOrder(); + ASSERT.that(map.values()).has().exactly(2, 1).inOrder(); assertNull(map.comparator()); } @@ -231,14 +252,14 @@ public class MapsTest extends TestCase { assertEquals(Collections.emptyMap(), map); map.put(new LegacyComparable("foo"), 1); map.put(new LegacyComparable("bar"), 2); - ASSERT.that(map.keySet()).has().allOf(new LegacyComparable("bar"), new LegacyComparable("foo")) - .inOrder(); - ASSERT.that(map.values()).has().allOf(2, 1).inOrder(); + ASSERT.that(map.keySet()).has().exactly( + new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder(); + ASSERT.that(map.values()).has().exactly(2, 1).inOrder(); assertNull(map.comparator()); } public void testTreeMapWithComparator() { - TreeMap<Integer, Integer> map = Maps.<Integer, Integer, Integer>newTreeMap(SOME_COMPARATOR); + TreeMap<Integer, Integer> map = Maps.newTreeMap(SOME_COMPARATOR); assertEquals(Collections.emptyMap(), map); assertSame(SOME_COMPARATOR, map.comparator()); } @@ -253,9 +274,7 @@ public class MapsTest extends TestCase { assertSame(copy.comparator(), map.comparator()); } - public enum SomeEnum { - SOME_INSTANCE - } + public enum SomeEnum { SOME_INSTANCE } public void testEnumMap() { EnumMap<SomeEnum, Integer> map = Maps.newEnumMap(SomeEnum.class); @@ -268,7 +287,8 @@ public class MapsTest extends TestCase { try { Maps.<SomeEnum, Long>newEnumMap((Class<MapsTest.SomeEnum>) null); fail("no exception thrown"); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testEnumMapWithInitialEnumMap() { @@ -321,8 +341,10 @@ public class MapsTest extends TestCase { new NullPointerTester().testAllPublicStaticMethods(Maps.class); } - private static final Map<Integer, Integer> EMPTY = Collections.emptyMap(); - private static final Map<Integer, Integer> SINGLETON = Collections.singletonMap(1, 2); + private static final Map<Integer, Integer> EMPTY + = Collections.emptyMap(); + private static final Map<Integer, Integer> SINGLETON + = Collections.singletonMap(1, 2); public void testMapDifferenceEmptyEmpty() { MapDifference<Integer, Integer> diff = Maps.difference(EMPTY, EMPTY); @@ -355,17 +377,20 @@ public class MapsTest extends TestCase { } public void testMapDifferenceTypical() { - Map<Integer, String> left = ImmutableMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e"); - Map<Integer, String> right = ImmutableMap.of(1, "a", 3, "f", 5, "g", 6, "z"); + Map<Integer, String> left = ImmutableMap.of( + 1, "a", 2, "b", 3, "c", 4, "d", 5, "e"); + Map<Integer, String> right = ImmutableMap.of( + 1, "a", 3, "f", 5, "g", 6, "z"); MapDifference<Integer, String> diff1 = Maps.difference(left, right); assertFalse(diff1.areEqual()); assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft()); assertEquals(ImmutableMap.of(6, "z"), diff1.entriesOnlyOnRight()); assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon()); - assertEquals( - ImmutableMap.of(3, ValueDifferenceImpl.create("c", "f"), 5, - ValueDifferenceImpl.create("e", "g")), diff1.entriesDiffering()); + assertEquals(ImmutableMap.of(3, + ValueDifferenceImpl.create("c", "f"), 5, + ValueDifferenceImpl.create("e", "g")), + diff1.entriesDiffering()); assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=z}: " + "value differences={3=(c, f), 5=(e, g)}", diff1.toString()); @@ -374,65 +399,78 @@ public class MapsTest extends TestCase { assertEquals(ImmutableMap.of(6, "z"), diff2.entriesOnlyOnLeft()); assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight()); assertEquals(ImmutableMap.of(1, "a"), diff2.entriesInCommon()); - assertEquals( - ImmutableMap.of(3, ValueDifferenceImpl.create("f", "c"), 5, - ValueDifferenceImpl.create("g", "e")), diff2.entriesDiffering()); + assertEquals(ImmutableMap.of(3, + ValueDifferenceImpl.create("f", "c"), 5, + ValueDifferenceImpl.create("g", "e")), + diff2.entriesDiffering()); assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: " + "value differences={3=(f, c), 5=(g, e)}", diff2.toString()); } public void testMapDifferenceEquals() { - Map<Integer, String> left = ImmutableMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e"); - Map<Integer, String> right = ImmutableMap.of(1, "a", 3, "f", 5, "g", 6, "z"); - Map<Integer, String> right2 = ImmutableMap.of(1, "a", 3, "h", 5, "g", 6, "z"); + Map<Integer, String> left = ImmutableMap.of( + 1, "a", 2, "b", 3, "c", 4, "d", 5, "e"); + Map<Integer, String> right = ImmutableMap.of( + 1, "a", 3, "f", 5, "g", 6, "z"); + Map<Integer, String> right2 = ImmutableMap.of( + 1, "a", 3, "h", 5, "g", 6, "z"); MapDifference<Integer, String> original = Maps.difference(left, right); MapDifference<Integer, String> same = Maps.difference(left, right); MapDifference<Integer, String> reverse = Maps.difference(right, left); MapDifference<Integer, String> diff2 = Maps.difference(left, right2); - new EqualsTester().addEqualityGroup(original, same).addEqualityGroup(reverse) - .addEqualityGroup(diff2).testEquals(); + new EqualsTester() + .addEqualityGroup(original, same) + .addEqualityGroup(reverse) + .addEqualityGroup(diff2) + .testEquals(); } public void testMapDifferencePredicateTypical() { - Map<Integer, String> left = ImmutableMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e"); - Map<Integer, String> right = ImmutableMap.of(1, "A", 3, "F", 5, "G", 6, "Z"); + Map<Integer, String> left = ImmutableMap.of( + 1, "a", 2, "b", 3, "c", 4, "d", 5, "e"); + Map<Integer, String> right = ImmutableMap.of( + 1, "A", 3, "F", 5, "G", 6, "Z"); // TODO(kevinb): replace with Ascii.caseInsensitiveEquivalence() when it // exists Equivalence<String> caseInsensitiveEquivalence = Equivalence.equals().onResultOf( new Function<String, String>() { - @Override - public String apply(String input) { + @Override public String apply(String input) { return input.toLowerCase(); } }); - MapDifference<Integer, String> diff1 = Maps.difference(left, right, caseInsensitiveEquivalence); + MapDifference<Integer, String> diff1 = Maps.difference(left, right, + caseInsensitiveEquivalence); assertFalse(diff1.areEqual()); assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff1.entriesOnlyOnLeft()); assertEquals(ImmutableMap.of(6, "Z"), diff1.entriesOnlyOnRight()); assertEquals(ImmutableMap.of(1, "a"), diff1.entriesInCommon()); - assertEquals( - ImmutableMap.of(3, ValueDifferenceImpl.create("c", "F"), 5, - ValueDifferenceImpl.create("e", "G")), diff1.entriesDiffering()); + assertEquals(ImmutableMap.of(3, + ValueDifferenceImpl.create("c", "F"), 5, + ValueDifferenceImpl.create("e", "G")), + diff1.entriesDiffering()); assertEquals("not equal: only on left={2=b, 4=d}: only on right={6=Z}: " + "value differences={3=(c, F), 5=(e, G)}", diff1.toString()); - MapDifference<Integer, String> diff2 = Maps.difference(right, left, caseInsensitiveEquivalence); + MapDifference<Integer, String> diff2 = Maps.difference(right, left, + caseInsensitiveEquivalence); assertFalse(diff2.areEqual()); assertEquals(ImmutableMap.of(6, "Z"), diff2.entriesOnlyOnLeft()); assertEquals(ImmutableMap.of(2, "b", 4, "d"), diff2.entriesOnlyOnRight()); assertEquals(ImmutableMap.of(1, "A"), diff2.entriesInCommon()); - assertEquals( - ImmutableMap.of(3, ValueDifferenceImpl.create("F", "c"), 5, - ValueDifferenceImpl.create("G", "e")), diff2.entriesDiffering()); + assertEquals(ImmutableMap.of(3, + ValueDifferenceImpl.create("F", "c"), 5, + ValueDifferenceImpl.create("G", "e")), + diff2.entriesDiffering()); assertEquals("not equal: only on left={6=Z}: only on right={2=b, 4=d}: " + "value differences={3=(F, c), 5=(G, e)}", diff2.toString()); } private static final SortedMap<Integer, Integer> SORTED_EMPTY = Maps.newTreeMap(); - private static final SortedMap<Integer, Integer> SORTED_SINGLETON = ImmutableSortedMap.of(1, 2); + private static final SortedMap<Integer, Integer> SORTED_SINGLETON = + ImmutableSortedMap.of(1, 2); public void testMapDifferenceOfSortedMapIsSorted() { Map<Integer, Integer> map = SORTED_SINGLETON; @@ -441,7 +479,8 @@ public class MapsTest extends TestCase { } public void testSortedMapDifferenceEmptyEmpty() { - SortedMapDifference<Integer, Integer> diff = Maps.difference(SORTED_EMPTY, SORTED_EMPTY); + SortedMapDifference<Integer, Integer> diff = + Maps.difference(SORTED_EMPTY, SORTED_EMPTY); assertTrue(diff.areEqual()); assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft()); assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight()); @@ -451,7 +490,8 @@ public class MapsTest extends TestCase { } public void testSortedMapDifferenceEmptySingleton() { - SortedMapDifference<Integer, Integer> diff = Maps.difference(SORTED_EMPTY, SORTED_SINGLETON); + SortedMapDifference<Integer, Integer> diff = + Maps.difference(SORTED_EMPTY, SORTED_SINGLETON); assertFalse(diff.areEqual()); assertEquals(SORTED_EMPTY, diff.entriesOnlyOnLeft()); assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnRight()); @@ -461,7 +501,8 @@ public class MapsTest extends TestCase { } public void testSortedMapDifferenceSingletonEmpty() { - SortedMapDifference<Integer, Integer> diff = Maps.difference(SORTED_SINGLETON, SORTED_EMPTY); + SortedMapDifference<Integer, Integer> diff = + Maps.difference(SORTED_SINGLETON, SORTED_EMPTY); assertFalse(diff.areEqual()); assertEquals(SORTED_SINGLETON, diff.entriesOnlyOnLeft()); assertEquals(SORTED_EMPTY, diff.entriesOnlyOnRight()); @@ -471,87 +512,112 @@ public class MapsTest extends TestCase { } public void testSortedMapDifferenceTypical() { - SortedMap<Integer, String> left = ImmutableSortedMap.<Integer, String>reverseOrder() - .put(1, "a").put(2, "b").put(3, "c").put(4, "d").put(5, "e").build(); + SortedMap<Integer, String> left = + ImmutableSortedMap.<Integer, String>reverseOrder() + .put(1, "a").put(2, "b").put(3, "c").put(4, "d").put(5, "e") + .build(); - SortedMap<Integer, String> right = ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z"); + SortedMap<Integer, String> right = + ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z"); - SortedMapDifference<Integer, String> diff1 = Maps.difference(left, right); + SortedMapDifference<Integer, String> diff1 = + Maps.difference(left, right); assertFalse(diff1.areEqual()); - ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has() - .allOf(Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b")).inOrder(); - ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(Maps.immutableEntry(6, "z")); - ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(Maps.immutableEntry(1, "a")); - ASSERT.that(diff1.entriesDiffering().entrySet()) - .has() - .allOf(Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")), - Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f"))).inOrder(); + ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has().exactly( + Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b")).inOrder(); + ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item( + Maps.immutableEntry(6, "z")); + ASSERT.that(diff1.entriesInCommon().entrySet()).has().item( + Maps.immutableEntry(1, "a")); + ASSERT.that(diff1.entriesDiffering().entrySet()).has().exactly( + Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")), + Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f"))).inOrder(); assertEquals("not equal: only on left={4=d, 2=b}: only on right={6=z}: " + "value differences={5=(e, g), 3=(c, f)}", diff1.toString()); - SortedMapDifference<Integer, String> diff2 = Maps.difference(right, left); + SortedMapDifference<Integer, String> diff2 = + Maps.difference(right, left); assertFalse(diff2.areEqual()); - ASSERT.that(diff2.entriesOnlyOnLeft().entrySet()).has().item(Maps.immutableEntry(6, "z")); - ASSERT.that(diff2.entriesOnlyOnRight().entrySet()).has() - .allOf(Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder(); - ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(Maps.immutableEntry(1, "a")); - assertEquals( - ImmutableMap.of(3, ValueDifferenceImpl.create("f", "c"), 5, - ValueDifferenceImpl.create("g", "e")), diff2.entriesDiffering()); + ASSERT.that(diff2.entriesOnlyOnLeft().entrySet()).has().item( + Maps.immutableEntry(6, "z")); + ASSERT.that(diff2.entriesOnlyOnRight().entrySet()).has().exactly( + Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder(); + ASSERT.that(diff1.entriesInCommon().entrySet()).has().item( + Maps.immutableEntry(1, "a")); + assertEquals(ImmutableMap.of( + 3, ValueDifferenceImpl.create("f", "c"), + 5, ValueDifferenceImpl.create("g", "e")), + diff2.entriesDiffering()); assertEquals("not equal: only on left={6=z}: only on right={2=b, 4=d}: " + "value differences={3=(f, c), 5=(g, e)}", diff2.toString()); } public void testSortedMapDifferenceImmutable() { - SortedMap<Integer, String> left = Maps.newTreeMap(ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", - 4, "d", 5, "e")); - SortedMap<Integer, String> right = Maps.newTreeMap(ImmutableSortedMap.of(1, "a", 3, "f", 5, - "g", 6, "z")); + SortedMap<Integer, String> left = Maps.newTreeMap( + ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e")); + SortedMap<Integer, String> right = + Maps.newTreeMap(ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z")); - SortedMapDifference<Integer, String> diff1 = Maps.difference(left, right); + SortedMapDifference<Integer, String> diff1 = + Maps.difference(left, right); left.put(6, "z"); assertFalse(diff1.areEqual()); - ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has() - .allOf(Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder(); - ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(Maps.immutableEntry(6, "z")); - ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(Maps.immutableEntry(1, "a")); - ASSERT.that(diff1.entriesDiffering().entrySet()) - .has() - .allOf(Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")), - Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g"))).inOrder(); + ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has().exactly( + Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder(); + ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item( + Maps.immutableEntry(6, "z")); + ASSERT.that(diff1.entriesInCommon().entrySet()).has().item( + Maps.immutableEntry(1, "a")); + ASSERT.that(diff1.entriesDiffering().entrySet()).has().exactly( + Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")), + Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g"))).inOrder(); try { diff1.entriesInCommon().put(7, "x"); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } try { diff1.entriesOnlyOnLeft().put(7, "x"); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } try { diff1.entriesOnlyOnRight().put(7, "x"); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } } public void testSortedMapDifferenceEquals() { - SortedMap<Integer, String> left = ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e"); - SortedMap<Integer, String> right = ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z"); - SortedMap<Integer, String> right2 = ImmutableSortedMap.of(1, "a", 3, "h", 5, "g", 6, "z"); - SortedMapDifference<Integer, String> original = Maps.difference(left, right); - SortedMapDifference<Integer, String> same = Maps.difference(left, right); - SortedMapDifference<Integer, String> reverse = Maps.difference(right, left); - SortedMapDifference<Integer, String> diff2 = Maps.difference(left, right2); - - new EqualsTester().addEqualityGroup(original, same).addEqualityGroup(reverse) - .addEqualityGroup(diff2).testEquals(); - } - - private static final Function<String, Integer> LENGTH_FUNCTION = new Function<String, Integer>() { - @Override - public Integer apply(String input) { - return input.length(); - } - }; + SortedMap<Integer, String> left = + ImmutableSortedMap.of(1, "a", 2, "b", 3, "c", 4, "d", 5, "e"); + SortedMap<Integer, String> right = + ImmutableSortedMap.of(1, "a", 3, "f", 5, "g", 6, "z"); + SortedMap<Integer, String> right2 = + ImmutableSortedMap.of(1, "a", 3, "h", 5, "g", 6, "z"); + SortedMapDifference<Integer, String> original = + Maps.difference(left, right); + SortedMapDifference<Integer, String> same = + Maps.difference(left, right); + SortedMapDifference<Integer, String> reverse = + Maps.difference(right, left); + SortedMapDifference<Integer, String> diff2 = + Maps.difference(left, right2); + + new EqualsTester() + .addEqualityGroup(original, same) + .addEqualityGroup(reverse) + .addEqualityGroup(diff2) + .testEquals(); + } + + private static final Function<String, Integer> LENGTH_FUNCTION = + new Function<String, Integer>() { + @Override + public Integer apply(String input) { + return input.length(); + } + }; public void testAsMap() { Set<String> strings = ImmutableSet.of("one", "two", "three"); @@ -559,8 +625,10 @@ public class MapsTest extends TestCase { assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map); assertEquals(Integer.valueOf(5), map.get("three")); assertNull(map.get("five")); - ASSERT.that(map.entrySet()).has() - .allOf(mapEntry("one", 3), mapEntry("two", 3), mapEntry("three", 5)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly( + mapEntry("one", 3), + mapEntry("two", 3), + mapEntry("three", 5)).inOrder(); } public void testAsMapReadsThrough() { @@ -580,7 +648,7 @@ public class MapsTest extends TestCase { Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION); assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map); assertEquals(Integer.valueOf(3), map.remove("two")); - ASSERT.that(strings).has().allOf("one", "three").inOrder(); + ASSERT.that(strings).has().exactly("one", "three").inOrder(); } public void testAsMapEmpty() { @@ -591,7 +659,8 @@ public class MapsTest extends TestCase { assertNull(map.get("five")); } - private static class NonNavigableSortedSet extends ForwardingSortedSet<String> { + private static class NonNavigableSortedSet + extends ForwardingSortedSet<String> { private final SortedSet<String> delegate = Sets.newTreeSet(); @Override @@ -612,12 +681,16 @@ public class MapsTest extends TestCase { assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map); assertEquals(Integer.valueOf(5), map.get("three")); assertNull(map.get("five")); - ASSERT.that(map.entrySet()).has() - .allOf(mapEntry("one", 3), mapEntry("three", 5), mapEntry("two", 3)).inOrder(); - ASSERT.that(map.tailMap("onea").entrySet()).has() - .allOf(mapEntry("three", 5), mapEntry("two", 3)).inOrder(); - ASSERT.that(map.subMap("one", "two").entrySet()).has() - .allOf(mapEntry("one", 3), mapEntry("three", 5)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly( + mapEntry("one", 3), + mapEntry("three", 5), + mapEntry("two", 3)).inOrder(); + ASSERT.that(map.tailMap("onea").entrySet()).has().exactly( + mapEntry("three", 5), + mapEntry("two", 3)).inOrder(); + ASSERT.that(map.subMap("one", "two").entrySet()).has().exactly( + mapEntry("one", 3), + mapEntry("three", 5)).inOrder(); } public void testAsMapSortedReadsThrough() { @@ -628,16 +701,24 @@ public class MapsTest extends TestCase { assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map); assertNull(map.get("four")); strings.add("four"); - assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4), map); + assertEquals( + ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4), + map); assertEquals(Integer.valueOf(4), map.get("four")); SortedMap<String, Integer> headMap = map.headMap("two"); - assertEquals(ImmutableSortedMap.of("four", 4, "one", 3, "three", 5), headMap); + assertEquals( + ImmutableSortedMap.of("four", 4, "one", 3, "three", 5), + headMap); strings.add("five"); strings.remove("one"); - assertEquals(ImmutableSortedMap.of("five", 4, "four", 4, "three", 5), headMap); - ASSERT.that(map.entrySet()).has() - .allOf(mapEntry("five", 4), mapEntry("four", 4), mapEntry("three", 5), mapEntry("two", 3)) - .inOrder(); + assertEquals( + ImmutableSortedMap.of("five", 4, "four", 4, "three", 5), + headMap); + ASSERT.that(map.entrySet()).has().exactly( + mapEntry("five", 4), + mapEntry("four", 4), + mapEntry("three", 5), + mapEntry("two", 3)).inOrder(); } public void testAsMapSortedWritesThrough() { @@ -646,27 +727,32 @@ public class MapsTest extends TestCase { SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION); assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map); assertEquals(Integer.valueOf(3), map.remove("two")); - ASSERT.that(strings).has().allOf("one", "three").inOrder(); + ASSERT.that(strings).has().exactly("one", "three").inOrder(); } public void testAsMapSortedSubViewKeySetsDoNotSupportAdd() { - SortedMap<String, Integer> map = Maps.asMap(new NonNavigableSortedSet(), LENGTH_FUNCTION); + SortedMap<String, Integer> map = Maps.asMap( + new NonNavigableSortedSet(), LENGTH_FUNCTION); try { map.subMap("a", "z").keySet().add("a"); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } try { map.tailMap("a").keySet().add("a"); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } try { map.headMap("r").keySet().add("a"); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } try { map.headMap("r").tailMap("m").keySet().add("a"); fail(); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } } public void testAsMapSortedEmpty() { @@ -681,24 +767,30 @@ public class MapsTest extends TestCase { Iterable<String> strings = ImmutableList.of("one", "two", "three"); ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION); assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map); - ASSERT.that(map.entrySet()).has() - .allOf(mapEntry("one", 3), mapEntry("two", 3), mapEntry("three", 5)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly( + mapEntry("one", 3), + mapEntry("two", 3), + mapEntry("three", 5)).inOrder(); } public void testToMapIterator() { Iterator<String> strings = ImmutableList.of("one", "two", "three").iterator(); ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION); assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map); - ASSERT.that(map.entrySet()).has() - .allOf(mapEntry("one", 3), mapEntry("two", 3), mapEntry("three", 5)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly( + mapEntry("one", 3), + mapEntry("two", 3), + mapEntry("three", 5)).inOrder(); } public void testToMapWithDuplicateKeys() { Iterable<String> strings = ImmutableList.of("one", "two", "three", "two", "one"); ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION); assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map); - ASSERT.that(map.entrySet()).has() - .allOf(mapEntry("one", 3), mapEntry("two", 3), mapEntry("three", 5)).inOrder(); + ASSERT.that(map.entrySet()).has().exactly( + mapEntry("one", 3), + mapEntry("two", 3), + mapEntry("three", 5)).inOrder(); } public void testToMapWithNullKeys() { @@ -706,7 +798,8 @@ public class MapsTest extends TestCase { try { Maps.toMap(strings, Functions.constant("foo")); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testToMapWithNullValues() { @@ -714,31 +807,40 @@ public class MapsTest extends TestCase { try { Maps.toMap(strings, Functions.constant(null)); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } - private static final BiMap<Integer, String> INT_TO_STRING_MAP = new ImmutableBiMap.Builder<Integer, String>() - .put(1, "one").put(2, "two").put(3, "three").build(); + private static final BiMap<Integer, String> INT_TO_STRING_MAP = + new ImmutableBiMap.Builder<Integer, String>() + .put(1, "one") + .put(2, "two") + .put(3, "three") + .build(); public void testUniqueIndexCollection() { - ImmutableMap<Integer, String> outputMap = Maps.uniqueIndex(INT_TO_STRING_MAP.values(), - Functions.forMap(INT_TO_STRING_MAP.inverse())); + ImmutableMap<Integer, String> outputMap = + Maps.uniqueIndex(INT_TO_STRING_MAP.values(), + Functions.forMap(INT_TO_STRING_MAP.inverse())); assertEquals(INT_TO_STRING_MAP, outputMap); } public void testUniqueIndexIterable() { - ImmutableMap<Integer, String> outputMap = Maps.uniqueIndex(new Iterable<String>() { - @Override - public Iterator<String> iterator() { - return INT_TO_STRING_MAP.values().iterator(); - } - }, Functions.forMap(INT_TO_STRING_MAP.inverse())); + ImmutableMap<Integer, String> outputMap = + Maps.uniqueIndex(new Iterable<String>() { + @Override + public Iterator<String> iterator() { + return INT_TO_STRING_MAP.values().iterator(); + } + }, + Functions.forMap(INT_TO_STRING_MAP.inverse())); assertEquals(INT_TO_STRING_MAP, outputMap); } public void testUniqueIndexIterator() { - ImmutableMap<Integer, String> outputMap = Maps.uniqueIndex(INT_TO_STRING_MAP.values() - .iterator(), Functions.forMap(INT_TO_STRING_MAP.inverse())); + ImmutableMap<Integer, String> outputMap = + Maps.uniqueIndex(INT_TO_STRING_MAP.values().iterator(), + Functions.forMap(INT_TO_STRING_MAP.inverse())); assertEquals(INT_TO_STRING_MAP, outputMap); } @@ -747,7 +849,8 @@ public class MapsTest extends TestCase { try { Maps.uniqueIndex(ImmutableSet.of("one", "uno"), Functions.constant(1)); fail(); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } } /** Null values are not allowed. */ @@ -756,7 +859,8 @@ public class MapsTest extends TestCase { try { Maps.uniqueIndex(listWithNull, Functions.constant(1)); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } /** Null keys aren't allowed either. */ @@ -765,12 +869,12 @@ public class MapsTest extends TestCase { try { Maps.uniqueIndex(oneStringList, Functions.constant(null)); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } @GwtIncompatible("Maps.fromProperties") - @SuppressWarnings("deprecation") - // StringBufferInputStream + @SuppressWarnings("deprecation") // StringBufferInputStream public void testFromProperties() throws IOException { Properties testProp = new Properties(); @@ -815,17 +919,17 @@ public class MapsTest extends TestCase { assertTrue(result.size() > 2); assertEquals("", result.get("test")); assertEquals("hidden", result.get("java.version")); - assertNotSame(System.getProperty("java.version"), result.get("java.version")); + assertNotSame(System.getProperty("java.version"), + result.get("java.version")); } @GwtIncompatible("Maps.fromProperties") - @SuppressWarnings("serial") - // never serialized + @SuppressWarnings("serial") // never serialized public void testFromPropertiesNullKey() { Properties properties = new Properties() { - @Override - public Enumeration<?> propertyNames() { - return Iterators.asEnumeration(Arrays.asList(null, "first", "second").iterator()); + @Override public Enumeration<?> propertyNames() { + return Iterators.asEnumeration( + Arrays.asList(null, "first", "second").iterator()); } }; properties.setProperty("first", "true"); @@ -838,14 +942,12 @@ public class MapsTest extends TestCase { } @GwtIncompatible("Maps.fromProperties") - @SuppressWarnings("serial") - // never serialized + @SuppressWarnings("serial") // never serialized public void testFromPropertiesNonStringKeys() { Properties properties = new Properties() { - @Override - public Enumeration<?> propertyNames() { - return Iterators.asEnumeration(Arrays.<Object>asList(Integer.valueOf(123), "first") - .iterator()); + @Override public Enumeration<?> propertyNames() { + return Iterators.asEnumeration( + Arrays.<Object>asList(Integer.valueOf(123), "first").iterator()); } }; @@ -863,33 +965,117 @@ public class MapsTest extends TestCase { * possible to access the raw (modifiable) map entry via a nefarious equals * method. */ - public static <K, V> Map.Entry<K, V> nefariousEntry(final K key, final V value) { + public static <K, V> Map.Entry<K, V> nefariousEntry( + final K key, final V value) { return new AbstractMapEntry<K, V>() { - @Override - public K getKey() { - return key; - } + @Override public K getKey() { + return key; + } + @Override public V getValue() { + return value; + } + @Override public V setValue(V value) { + throw new UnsupportedOperationException(); + } + @SuppressWarnings("unchecked") + @Override public boolean equals(Object o) { + if (o instanceof Map.Entry) { + Map.Entry<K, V> e = (Map.Entry<K, V>) o; + e.setValue(value); // muhahaha! + } + return super.equals(o); + } + }; + } - @Override - public V getValue() { - return value; - } + public void testAsConverter_nominal() throws Exception { + ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of( + "one", 1, + "two", 2); + Converter<String, Integer> converter = Maps.asConverter(biMap); + for (Entry<String, Integer> entry : biMap.entrySet()) { + assertSame(entry.getValue(), converter.convert(entry.getKey())); + } + } - @Override - public V setValue(V value) { - throw new UnsupportedOperationException(); - } + public void testAsConverter_inverse() throws Exception { + ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of( + "one", 1, + "two", 2); + Converter<String, Integer> converter = Maps.asConverter(biMap); + for (Entry<String, Integer> entry : biMap.entrySet()) { + assertSame(entry.getKey(), converter.reverse().convert(entry.getValue())); + } + } - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object o) { - if (o instanceof Map.Entry) { - Map.Entry<K, V> e = (Map.Entry<K, V>) o; - e.setValue(value); // muhahaha! - } - return super.equals(o); - } - }; + public void testAsConverter_noMapping() throws Exception { + ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of( + "one", 1, + "two", 2); + Converter<String, Integer> converter = Maps.asConverter(biMap); + try { + converter.convert("three"); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testAsConverter_nullConversions() throws Exception { + ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of( + "one", 1, + "two", 2); + Converter<String, Integer> converter = Maps.asConverter(biMap); + assertNull(converter.convert(null)); + assertNull(converter.reverse().convert(null)); + } + + public void testAsConverter_isAView() throws Exception { + BiMap<String, Integer> biMap = HashBiMap.create(); + biMap.put("one", 1); + biMap.put("two", 2); + Converter<String, Integer> converter = Maps.asConverter(biMap); + + assertSame(1, converter.convert("one")); + assertSame(2, converter.convert("two")); + try { + converter.convert("three"); + fail(); + } catch (IllegalArgumentException expected) { + } + + biMap.put("three", 3); + + assertSame(1, converter.convert("one")); + assertSame(2, converter.convert("two")); + assertSame(3, converter.convert("three")); + } + + public void testAsConverter_withNullMapping() throws Exception { + BiMap<String, Integer> biMap = HashBiMap.create(); + biMap.put("one", 1); + biMap.put("two", 2); + biMap.put("three", null); + try { + Maps.asConverter(biMap).convert("three"); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testAsConverter_toString() { + ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of( + "one", 1, + "two", 2); + Converter<String, Integer> converter = Maps.asConverter(biMap); + assertEquals("Maps.asConverter({one=1, two=2})", converter.toString()); + } + + public void testAsConverter_serialization() { + ImmutableBiMap<String, Integer> biMap = ImmutableBiMap.of( + "one", 1, + "two", 2); + Converter<String, Integer> converter = Maps.asConverter(biMap); + SerializableTester.reserializeAndAssert(converter); } public void testUnmodifiableBiMap() { @@ -949,7 +1135,8 @@ public class MapsTest extends TestCase { fail("UnsupportedOperationException expected"); } catch (UnsupportedOperationException expected) {} @SuppressWarnings("unchecked") - Map.Entry<Integer, String> entry2 = (Map.Entry<Integer, String>) entries.toArray()[0]; + Map.Entry<Integer, String> entry2 + = (Map.Entry<Integer, String>) entries.toArray()[0]; try { entry2.setValue("four"); fail("UnsupportedOperationException expected"); @@ -969,7 +1156,8 @@ public class MapsTest extends TestCase { } public void testImmutableEntryNull() { - Map.Entry<String, Integer> e = Maps.immutableEntry((String) null, (Integer) null); + Map.Entry<String, Integer> e + = Maps.immutableEntry((String) null, (Integer) null); assertNull(e.getKey()); assertNull(e.getValue()); try { @@ -991,33 +1179,36 @@ public class MapsTest extends TestCase { assertEquals(ImmutableSet.of(1, 2, 3), sync.inverse().keySet()); } - private static final Predicate<String> NOT_LENGTH_3 = new Predicate<String>() { - @Override - public boolean apply(String input) { - return input == null || input.length() != 3; - } - }; + private static final Predicate<String> NOT_LENGTH_3 + = new Predicate<String>() { + @Override + public boolean apply(String input) { + return input == null || input.length() != 3; + } + }; - private static final Predicate<Integer> EVEN = new Predicate<Integer>() { - @Override - public boolean apply(Integer input) { - return input == null || input % 2 == 0; - } - }; + private static final Predicate<Integer> EVEN + = new Predicate<Integer>() { + @Override + public boolean apply(Integer input) { + return input == null || input % 2 == 0; + } + }; - private static final Predicate<Entry<String, Integer>> CORRECT_LENGTH = new Predicate<Entry<String, Integer>>() { - @Override - public boolean apply(Entry<String, Integer> input) { - return input.getKey().length() == input.getValue(); - } - }; + private static final Predicate<Entry<String, Integer>> CORRECT_LENGTH + = new Predicate<Entry<String, Integer>>() { + @Override + public boolean apply(Entry<String, Integer> input) { + return input.getKey().length() == input.getValue(); + } + }; private static final Function<Integer, Double> SQRT_FUNCTION = new Function<Integer, Double>() { - @Override - public Double apply(Integer in) { - return Math.sqrt(in); - } - }; + @Override + public Double apply(Integer in) { + return Math.sqrt(in); + } + }; public static class FilteredMapTest extends TestCase { Map<String, Integer> createUnfiltered() { @@ -1123,7 +1314,8 @@ public class MapsTest extends TestCase { unfiltered.put("three", 3); unfiltered.put("four", 4); Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN); - assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4), unfiltered); + assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4), + unfiltered); assertEquals(ImmutableMap.of("two", 2, "four", 4), filtered); filtered.clear(); @@ -1136,7 +1328,8 @@ public class MapsTest extends TestCase { unfiltered.put("cat", 3); unfiltered.put("dog", 2); unfiltered.put("horse", 5); - Map<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH); + Map<String, Integer> filtered + = Maps.filterEntries(unfiltered, CORRECT_LENGTH); assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered); filtered.put("chicken", 7); @@ -1154,7 +1347,8 @@ public class MapsTest extends TestCase { unfiltered.put("cat", 3); unfiltered.put("dog", 2); unfiltered.put("horse", 5); - Map<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH); + Map<String, Integer> filtered + = Maps.filterEntries(unfiltered, CORRECT_LENGTH); assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered); filtered.put("chicken", 7); @@ -1173,7 +1367,8 @@ public class MapsTest extends TestCase { unfiltered.put("dog", 2); unfiltered.put("horse", 5); Predicate<Object> predicate = Predicates.alwaysFalse(); - Map<String, Integer> filtered = Maps.filterEntries(unfiltered, predicate); + Map<String, Integer> filtered + = Maps.filterEntries(unfiltered, predicate); assertTrue(filtered.isEmpty()); } @@ -1185,10 +1380,12 @@ public class MapsTest extends TestCase { Predicate<Entry<?, ?>> predicate = new Predicate<Entry<?, ?>>() { @Override public boolean apply(Entry<?, ?> input) { - return "cat".equals(input.getKey()) || Integer.valueOf(2) == input.getValue(); + return "cat".equals(input.getKey()) + || Integer.valueOf(2) == input.getValue(); } }; - Map<String, Integer> filtered = Maps.filterEntries(unfiltered, predicate); + Map<String, Integer> filtered + = Maps.filterEntries(unfiltered, predicate); assertEquals(ImmutableMap.of("cat", 3, "dog", 2), filtered); } } @@ -1201,17 +1398,20 @@ public class MapsTest extends TestCase { public void testFilterKeysIdentifiesSortedMap() { SortedMap<String, Integer> map = createUnfiltered(); - assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3) instanceof SortedMap); + assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3) + instanceof SortedMap); } public void testFilterValuesIdentifiesSortedMap() { SortedMap<String, Integer> map = createUnfiltered(); - assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN) instanceof SortedMap); + assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN) + instanceof SortedMap); } public void testFilterEntriesIdentifiesSortedMap() { SortedMap<String, Integer> map = createUnfiltered(); - assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH) instanceof SortedMap); + assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH) + instanceof SortedMap); } public void testFirstAndLastKeyFilteredMap() { @@ -1254,17 +1454,20 @@ public class MapsTest extends TestCase { public void testFilterKeysIdentifiesBiMap() { BiMap<String, Integer> map = createUnfiltered(); - assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3) instanceof BiMap); + assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3) + instanceof BiMap); } public void testFilterValuesIdentifiesBiMap() { BiMap<String, Integer> map = createUnfiltered(); - assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN) instanceof BiMap); + assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN) + instanceof BiMap); } public void testFilterEntriesIdentifiesBiMap() { BiMap<String, Integer> map = createUnfiltered(); - assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH) instanceof BiMap); + assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH) + instanceof BiMap); } } @@ -1276,7 +1479,8 @@ public class MapsTest extends TestCase { } public void testTransformValuesSecretlySorted() { - Map<String, Integer> map = sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9)); + Map<String, Integer> map = + sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9)); Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION); assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed); @@ -1285,12 +1489,13 @@ public class MapsTest extends TestCase { public void testTransformEntries() { Map<String, String> map = ImmutableMap.of("a", "4", "b", "9"); - EntryTransformer<String, String, String> concat = new EntryTransformer<String, String, String>() { - @Override - public String transformEntry(String key, String value) { - return key + value; - } - }; + EntryTransformer<String, String, String> concat = + new EntryTransformer<String, String, String>() { + @Override + public String transformEntry(String key, String value) { + return key + value; + } + }; Map<String, String> transformed = transformEntries(map, concat); assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed); @@ -1298,18 +1503,20 @@ public class MapsTest extends TestCase { public void testTransformEntriesSecretlySorted() { Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9"); - EntryTransformer<String, String, String> concat = new EntryTransformer<String, String, String>() { - @Override - public String transformEntry(String key, String value) { - return key + value; - } - }; + EntryTransformer<String, String, String> concat = + new EntryTransformer<String, String, String>() { + @Override + public String transformEntry(String key, String value) { + return key + value; + } + }; Map<String, String> transformed = transformEntries(map, concat); assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed); assertTrue(transformed instanceof SortedMap); } + @SuppressWarnings("unused") public void testTransformEntriesGenerics() { Map<Object, Object> map1 = ImmutableMap.<Object, Object>of(1, 2); Map<Object, Number> map2 = ImmutableMap.<Object, Number>of(1, 2); @@ -1322,12 +1529,13 @@ public class MapsTest extends TestCase { Map<Integer, Integer> map9 = ImmutableMap.<Integer, Integer>of(1, 2); Map<? extends Number, ? extends Number> map0 = ImmutableMap.of(1, 2); - EntryTransformer<Number, Number, Double> transformer = new EntryTransformer<Number, Number, Double>() { - @Override - public Double transformEntry(Number key, Number value) { - return key.doubleValue() + value.doubleValue(); - } - }; + EntryTransformer<Number, Number, Double> transformer = + new EntryTransformer<Number, Number, Double>() { + @Override + public Double transformEntry(Number key, Number value) { + return key.doubleValue() + value.doubleValue(); + } + }; Map<Object, Double> objectKeyed; Map<Number, Double> numberKeyed; @@ -1366,30 +1574,34 @@ public class MapsTest extends TestCase { } public void testTransformEntriesExample() { - Map<String, Boolean> options = ImmutableMap.of("verbose", true, "sort", false); - EntryTransformer<String, Boolean, String> flagPrefixer = new EntryTransformer<String, Boolean, String>() { - @Override - public String transformEntry(String key, Boolean value) { - return value ? key : "no" + key; - } - }; + Map<String, Boolean> options = + ImmutableMap.of("verbose", true, "sort", false); + EntryTransformer<String, Boolean, String> flagPrefixer = + new EntryTransformer<String, Boolean, String>() { + @Override + public String transformEntry(String key, Boolean value) { + return value ? key : "no" + key; + } + }; Map<String, String> transformed = transformEntries(options, flagPrefixer); assertEquals("{verbose=verbose, sort=nosort}", transformed.toString()); } // Logically this would accept a NavigableMap, but that won't work under GWT. - private static <K, V> SortedMap<K, V> sortedNotNavigable(final SortedMap<K, V> map) { + private static <K, V> SortedMap<K, V> sortedNotNavigable( + final SortedMap<K, V> map) { return new ForwardingSortedMap<K, V>() { - @Override - protected SortedMap<K, V> delegate() { + @Override protected SortedMap<K, V> delegate() { return map; } }; } public void testSortedMapTransformValues() { - SortedMap<String, Integer> map = sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9)); - SortedMap<String, Double> transformed = transformValues(map, SQRT_FUNCTION); + SortedMap<String, Integer> map = + sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9)); + SortedMap<String, Double> transformed = + transformValues(map, SQRT_FUNCTION); /* * We'd like to sanity check that we didn't get a NavigableMap out, but we @@ -1399,13 +1611,15 @@ public class MapsTest extends TestCase { } public void testSortedMapTransformEntries() { - SortedMap<String, String> map = sortedNotNavigable(ImmutableSortedMap.of("a", "4", "b", "9")); - EntryTransformer<String, String, String> concat = new EntryTransformer<String, String, String>() { - @Override - public String transformEntry(String key, String value) { - return key + value; - } - }; + SortedMap<String, String> map = + sortedNotNavigable(ImmutableSortedMap.of("a", "4", "b", "9")); + EntryTransformer<String, String, String> concat = + new EntryTransformer<String, String, String>() { + @Override + public String transformEntry(String key, String value) { + return key + value; + } + }; SortedMap<String, String> transformed = transformEntries(map, concat); /* @@ -1414,12 +1628,4 @@ public class MapsTest extends TestCase { */ assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed); } - - // Hack for JDK5 type inference. - private static class ASSERT { - static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> that( - Collection<T> collection) { - return Truth.ASSERT.<T, Collection<T>>that(collection); - } - } } diff --git a/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java b/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java index f9d8677..00679cc 100644 --- a/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java +++ b/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java @@ -54,7 +54,6 @@ public class MapsTransformValuesTest extends MapInterfaceTest<String, String> { super(false, true, false, true, true); } - @Override protected Map<String, String> makeEmptyMap() { return Maps.transformValues(Maps.<String, String>newHashMap(), Functions.<String>identity()); diff --git a/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java b/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java index 69e6711..c6461c8 100644 --- a/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java +++ b/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java @@ -16,11 +16,14 @@ package com.google.common.collect; +import static org.truth0.Truth.ASSERT; + import com.google.common.collect.testing.IteratorFeature; import com.google.common.collect.testing.IteratorTester; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -35,8 +38,6 @@ import java.util.Random; import java.util.SortedMap; import java.util.concurrent.atomic.AtomicInteger; -import junit.framework.TestCase; - /** * Unit test for {@link MinMaxPriorityQueue}. * @@ -354,7 +355,7 @@ public class MinMaxPriorityQueueTest extends TestCase { } } assertTrue(q.isIntact()); - FluentAsserts.assertThat(result).has().allOf(1, 15, 13, 8, 14); + ASSERT.that(result).has().exactly(1, 15, 13, 8, 14); } /** @@ -522,11 +523,9 @@ public class MinMaxPriorityQueueTest extends TestCase { @Override protected void verify(List<T> elements) { assertEquals(Sets.newHashSet(elements), Sets.newHashSet(mmHeap.iterator())); - assertTrue("Invalid MinMaxHeap: " + mmHeap.toString(), - mmHeap.isIntact()); + assertTrue("Invalid MinMaxHeap: " + mmHeap, mmHeap.isIntact()); } }; - tester.ignoreSunJavaBug6529795(); tester.test(); } @@ -719,23 +718,23 @@ public class MinMaxPriorityQueueTest extends TestCase { List<Integer> contents = Lists.newArrayList(expected); List<Integer> elements = Lists.newArrayListWithCapacity(size); while (!q.isEmpty()) { - FluentAsserts.assertThat(q).has().allFrom(contents); + ASSERT.that(q).has().exactlyAs(contents); Integer next = q.pollFirst(); contents.remove(next); - FluentAsserts.assertThat(q).has().allFrom(contents); + ASSERT.that(q).has().exactlyAs(contents); for (int i = 0; i <= size; i++) { q.add(i); contents.add(i); - FluentAsserts.assertThat(q).has().allFrom(contents); + ASSERT.that(q).has().exactlyAs(contents); q.add(next); contents.add(next); - FluentAsserts.assertThat(q).has().allFrom(contents); + ASSERT.that(q).has().exactlyAs(contents); q.remove(i); assertTrue(contents.remove(Integer.valueOf(i))); - FluentAsserts.assertThat(q).has().allFrom(contents); + ASSERT.that(q).has().exactlyAs(contents); assertEquals(next, q.poll()); contents.remove(next); - FluentAsserts.assertThat(q).has().allFrom(contents); + ASSERT.that(q).has().exactlyAs(contents); } elements.add(next); } diff --git a/guava-tests/test/com/google/common/collect/MultimapBuilderTest.java b/guava-tests/test/com/google/common/collect/MultimapBuilderTest.java new file mode 100644 index 0000000..1dd3fa9 --- /dev/null +++ b/guava-tests/test/com/google/common/collect/MultimapBuilderTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; +import com.google.common.collect.MultimapBuilder.MultimapBuilderWithKeys; +import com.google.common.testing.SerializableTester; + +import junit.framework.TestCase; + +import java.math.RoundingMode; +import java.util.SortedMap; +import java.util.SortedSet; + +/** + * Tests for {@link MultimapBuilder}. + * + * @author Louis Wasserman + */ +@GwtCompatible(emulated = true) +public class MultimapBuilderTest extends TestCase { + + @GwtIncompatible("doesn't build without explicit type parameters on build() methods") + public void testGenerics() { + ListMultimap<String, Integer> a = MultimapBuilder.hashKeys().arrayListValues().build(); + SortedSetMultimap<String, Integer> b = MultimapBuilder.linkedHashKeys().treeSetValues().build(); + SetMultimap<String, Integer> c = + MultimapBuilder.treeKeys(String.CASE_INSENSITIVE_ORDER).hashSetValues().build(); + } + + public void testGenerics_gwtCompatible() { + ListMultimap<String, Integer> a = + MultimapBuilder.hashKeys().arrayListValues().<String, Integer>build(); + SortedSetMultimap<String, Integer> b = + MultimapBuilder.linkedHashKeys().treeSetValues().<String, Integer>build(); + SetMultimap<String, Integer> c = MultimapBuilder.treeKeys(String.CASE_INSENSITIVE_ORDER) + .hashSetValues().<String, Integer>build(); + } + + @GwtIncompatible("doesn't build without explicit type parameters on build() methods") + public void testTreeKeys() { + ListMultimap<String, Integer> multimap = MultimapBuilder.treeKeys().arrayListValues().build(); + assertTrue(multimap.keySet() instanceof SortedSet); + assertTrue(multimap.asMap() instanceof SortedMap); + } + + public void testTreeKeys_gwtCompatible() { + ListMultimap<String, Integer> multimap = + MultimapBuilder.treeKeys().arrayListValues().<String, Integer>build(); + assertTrue(multimap.keySet() instanceof SortedSet); + assertTrue(multimap.asMap() instanceof SortedMap); + } + + public void testSerialization() { + for (MultimapBuilderWithKeys<?> builderWithKeys : ImmutableList.of( + MultimapBuilder.hashKeys(), MultimapBuilder.linkedHashKeys(), MultimapBuilder.treeKeys(), + MultimapBuilder.enumKeys(RoundingMode.class))) { + for (MultimapBuilder<?, ?> builder : ImmutableList.of( + builderWithKeys.arrayListValues(), + builderWithKeys.linkedListValues(), + builderWithKeys.hashSetValues(), + builderWithKeys.linkedHashSetValues(), + builderWithKeys.treeSetValues(), + builderWithKeys.enumSetValues(RoundingMode.class))) { + SerializableTester.reserializeAndAssert(builder.build()); + } + } + } +} diff --git a/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java b/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java index 989878a..9e70754 100644 --- a/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java +++ b/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java @@ -21,8 +21,9 @@ import static com.google.common.collect.testing.Helpers.mapEntry; import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES; import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE; import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods; +import static com.google.common.collect.testing.google.MultisetCountTester.getCountDuplicateInitializingMethods; import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods; -import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods; +import static com.google.common.collect.testing.google.MultisetRemoveTester.getRemoveDuplicateInitializingMethods; import static java.lang.reflect.Proxy.newProxyInstance; import com.google.common.annotations.GwtIncompatible; @@ -42,15 +43,19 @@ import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.Feature; import com.google.common.collect.testing.features.MapFeature; import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder; +import com.google.common.collect.testing.google.MultimapFeature; import com.google.common.collect.testing.google.MultimapTestSuiteBuilder; -import com.google.common.collect.testing.google.MultisetIteratorTester; import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; -import com.google.common.collect.testing.google.MultisetWritesTester; +import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder; import com.google.common.collect.testing.google.TestListMultimapGenerator; import com.google.common.collect.testing.google.TestMultimapGenerator; +import com.google.common.collect.testing.google.TestSetMultimapGenerator; import com.google.common.collect.testing.google.TestStringListMultimapGenerator; import com.google.common.collect.testing.google.TestStringMultisetGenerator; -import com.google.common.collect.testing.testers.CollectionIteratorTester; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @@ -61,10 +66,6 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - /** * Run collection tests on wrappers from {@link Multimaps}. * @@ -73,35 +74,18 @@ import junit.framework.TestSuite; @GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version public class MultimapsCollectionTest extends TestCase { - static final Feature<?>[] COLLECTION_FEATURES_ORDER = { - CollectionSize.ANY, - CollectionFeature.ALLOWS_NULL_VALUES, - CollectionFeature.KNOWN_ORDER, - CollectionFeature.GENERAL_PURPOSE - }; - static final Feature<?>[] COLLECTION_FEATURES_REMOVE = { - CollectionSize.ANY, - CollectionFeature.ALLOWS_NULL_VALUES, - CollectionFeature.SUPPORTS_REMOVE - }; - - static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = { - CollectionSize.ANY, - CollectionFeature.ALLOWS_NULL_VALUES, - CollectionFeature.KNOWN_ORDER, - CollectionFeature.SUPPORTS_REMOVE - }; - private static final Feature<?>[] FOR_MAP_FEATURES_ONE = { CollectionSize.ONE, ALLOWS_NULL_VALUES, SUPPORTS_REMOVE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE }; private static final Feature<?>[] FOR_MAP_FEATURES_ANY = { CollectionSize.ANY, ALLOWS_NULL_VALUES, SUPPORTS_REMOVE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, MultisetTestSuiteBuilder.NoRecurse.NO_ENTRY_SET, // Cannot create entries with count > 1 }; @@ -252,6 +236,9 @@ public class MultimapsCollectionTest extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(); + suite.addTest(transformSuite()); + suite.addTest(filterSuite()); + suite.addTest(ListMultimapTestSuiteBuilder.using(new TestStringListMultimapGenerator() { @Override protected ListMultimap<String, String> create(Entry<String, String>[] entries) { @@ -267,11 +254,12 @@ public class MultimapsCollectionTest extends TestCase { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionSize.ANY) .createTestSuite()); - suite.addTest(transformSuite()); suite.addTest(SetTestSuiteBuilder.using( new TestStringSetGenerator() { @@ -312,9 +300,10 @@ public class MultimapsCollectionTest extends TestCase { }) .named("Multimaps.forMap.keys") .withFeatures(FOR_MAP_FEATURES_ANY) - .suppressing(getReadsDuplicateInitializingMethods()) + .suppressing(getCountDuplicateInitializingMethods()) .suppressing(getSetCountDuplicateInitializingMethods()) .suppressing(getIteratorDuplicateInitializingMethods()) + .suppressing(getRemoveDuplicateInitializingMethods()) .createTestSuite()); // TODO: use collection testers on Multimaps.forMap.entries @@ -418,7 +407,9 @@ public class MultimapsCollectionTest extends TestCase { .withFeatures( CollectionSize.ANY, MapFeature.SUPPORTS_REMOVE, - MapFeature.ALLOWS_NULL_KEYS) + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); suite.addTest(MultimapTestSuiteBuilder.using( new TransformedMultimapGenerator<Multimap<String,String>>() { @@ -431,7 +422,9 @@ public class MultimapsCollectionTest extends TestCase { .withFeatures( CollectionSize.ANY, MapFeature.SUPPORTS_REMOVE, - MapFeature.ALLOWS_NULL_KEYS) + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); suite.addTest(ListMultimapTestSuiteBuilder.using(new TransformedListMultimapGenerator() { @Override @@ -443,7 +436,9 @@ public class MultimapsCollectionTest extends TestCase { .withFeatures( CollectionSize.ANY, MapFeature.SUPPORTS_REMOVE, - MapFeature.ALLOWS_NULL_KEYS) + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); suite.addTest(ListMultimapTestSuiteBuilder.using(new TransformedListMultimapGenerator() { @Override @@ -456,18 +451,18 @@ public class MultimapsCollectionTest extends TestCase { .withFeatures( CollectionSize.ANY, MapFeature.SUPPORTS_REMOVE, - MapFeature.ALLOWS_NULL_KEYS) + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); // TODO: use collection testers on Multimaps.forMap.entries - - suite.addTest(filterSuite()); return suite; } - static abstract class TestFilteredMultimapGenerator - implements TestMultimapGenerator<String, Integer, Multimap<String, Integer>> { + static abstract class TestFilteredMultimapGenerator<M extends Multimap<String, Integer>> + implements TestMultimapGenerator<String, Integer, M> { @Override public SampleElements<Entry<String, Integer>> samples() { @@ -479,19 +474,6 @@ public class MultimapsCollectionTest extends TestCase { mapEntry("five", 82)); } - abstract Multimap<String, Integer> filter(Multimap<String, Integer> multimap); - - @Override - public Multimap<String, Integer> create(Object... elements) { - Multimap<String, Integer> multimap = LinkedHashMultimap.create(); - for (Object o : elements) { - @SuppressWarnings("unchecked") - Entry<String, Integer> entry = (Entry<String, Integer>) o; - multimap.put(entry.getKey(), entry.getValue()); - } - return filter(multimap); - } - @SuppressWarnings("unchecked") @Override public Entry<String, Integer>[] createArray(int length) { @@ -522,18 +504,80 @@ public class MultimapsCollectionTest extends TestCase { public SampleElements<Integer> sampleValues() { return new SampleElements<Integer>(114, 37, 42, 19, 82); } + } + + static abstract class FilteredSetMultimapGenerator + extends TestFilteredMultimapGenerator<SetMultimap<String, Integer>> + implements TestSetMultimapGenerator<String, Integer> { + + + abstract SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap); + + @Override + public SetMultimap<String, Integer> create(Object... elements) { + SetMultimap<String, Integer> multimap = LinkedHashMultimap.create(); + for (Object o : elements) { + @SuppressWarnings("unchecked") + Entry<String, Integer> entry = (Entry<String, Integer>) o; + multimap.put(entry.getKey(), entry.getValue()); + } + return filter(multimap); + } @Override public Collection<Integer> createCollection(Iterable<? extends Integer> values) { return Sets.newLinkedHashSet(values); } } + + static abstract class FilteredListMultimapGenerator + extends TestFilteredMultimapGenerator<ListMultimap<String, Integer>> + implements TestListMultimapGenerator<String, Integer> { + + @Override + public ListMultimap<String, Integer> create(Object... elements) { + ListMultimap<String, Integer> multimap = LinkedListMultimap.create(); + for (Object o : elements) { + @SuppressWarnings("unchecked") + Entry<String, Integer> entry = (Entry<String, Integer>) o; + multimap.put(entry.getKey(), entry.getValue()); + } + return filter(multimap); + } + + abstract ListMultimap<String, Integer> filter(ListMultimap<String, Integer> multimap); + + @Override + public Collection<Integer> createCollection(Iterable<? extends Integer> values) { + return Lists.newArrayList(values); + } + } - private static Test filterSuite() { + private static Test filterSuite() { TestSuite suite = new TestSuite("Multimaps.filter*"); - suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() { + suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { + @Override + SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { + multimap.put("foo", 17); + multimap.put("bar", 32); + multimap.put("foo", 16); + return Multimaps.filterKeys(multimap, + Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar")))); + } + }) + .named("Multimaps.filterKeys[SetMultimap, Predicate]") + .withFeatures( + CollectionSize.ANY, + MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE, + MapFeature.GENERAL_PURPOSE, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES) + .createTestSuite()); + + suite.addTest(ListMultimapTestSuiteBuilder.using(new FilteredListMultimapGenerator() { @Override - Multimap<String, Integer> filter(Multimap<String, Integer> multimap) { + ListMultimap<String, Integer> filter(ListMultimap<String, Integer> multimap) { multimap.put("foo", 17); multimap.put("bar", 32); multimap.put("foo", 16); @@ -541,19 +585,37 @@ public class MultimapsCollectionTest extends TestCase { Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar")))); } }) - .named("Multimaps.filterKeys[Multimap, Predicate]") + .named("Multimaps.filterKeys[ListMultimap, Predicate]") + .withFeatures( + CollectionSize.ANY, + MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE, + MapFeature.GENERAL_PURPOSE, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES) + .createTestSuite()); + suite.addTest(ListMultimapTestSuiteBuilder.using(new FilteredListMultimapGenerator() { + @Override + ListMultimap<String, Integer> filter(ListMultimap<String, Integer> multimap) { + multimap.put("foo", 17); + multimap.put("bar", 32); + multimap.put("foo", 16); + multimap = Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("foo"))); + return Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("bar"))); + } + }) + .named("Multimaps.filterKeys[Multimaps.filterKeys[ListMultimap], Predicate]") .withFeatures( CollectionSize.ANY, + MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE, MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_KEYS, - MapFeature.ALLOWS_NULL_VALUES) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetWritesTester.getEntrySetIteratorMethod()) + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); - suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() { + suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { @Override - Multimap<String, Integer> filter(Multimap<String, Integer> multimap) { + SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { multimap.put("one", 314); multimap.put("two", 159); multimap.put("one", 265); @@ -561,19 +623,17 @@ public class MultimapsCollectionTest extends TestCase { Predicates.not(Predicates.in(ImmutableSet.of(314, 159, 265)))); } }) - .named("Multimaps.filterValues[Multimap, Predicate]") + .named("Multimaps.filterValues[SetMultimap, Predicate]") .withFeatures( CollectionSize.ANY, MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_KEYS, - MapFeature.ALLOWS_NULL_VALUES) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetWritesTester.getEntrySetIteratorMethod()) + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); - suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() { + suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { @Override - Multimap<String, Integer> filter(Multimap<String, Integer> multimap) { + SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { ImmutableSetMultimap<String, Integer> badEntries = ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358); multimap.putAll(badEntries); @@ -581,19 +641,17 @@ public class MultimapsCollectionTest extends TestCase { Predicates.not(Predicates.in(badEntries.entries()))); } }) - .named("Multimaps.filterEntries[Multimap, Predicate]") + .named("Multimaps.filterEntries[SetMultimap, Predicate]") .withFeatures( CollectionSize.ANY, MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_KEYS, - MapFeature.ALLOWS_NULL_VALUES) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetWritesTester.getEntrySetIteratorMethod()) + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); - suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() { + suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { @Override - Multimap<String, Integer> filter(Multimap<String, Integer> multimap) { + SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { ImmutableSetMultimap<String, Integer> badEntries = ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358); multimap.putAll(badEntries); @@ -603,19 +661,17 @@ public class MultimapsCollectionTest extends TestCase { Predicates.not(Predicates.in(badEntries.entries()))); } }) - .named("Multimaps.filterEntries[Maps.filterKeys[Multimap]]") + .named("Multimaps.filterEntries[Multimaps.filterKeys[SetMultimap]]") .withFeatures( CollectionSize.ANY, MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_KEYS, - MapFeature.ALLOWS_NULL_VALUES) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetWritesTester.getEntrySetIteratorMethod()) + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); - suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() { + suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { @Override - Multimap<String, Integer> filter(Multimap<String, Integer> multimap) { + SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { ImmutableSetMultimap<String, Integer> badEntries = ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358); multimap.putAll(badEntries); @@ -625,19 +681,17 @@ public class MultimapsCollectionTest extends TestCase { Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar")))); } }) - .named("Multimaps.filterKeys[Maps.filterEntries[Multimap]]") + .named("Multimaps.filterKeys[Multimaps.filterEntries[SetMultimap]]") .withFeatures( CollectionSize.ANY, MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_KEYS, - MapFeature.ALLOWS_NULL_VALUES) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetWritesTester.getEntrySetIteratorMethod()) + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); - suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() { + suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { @Override - Multimap<String, Integer> filter(Multimap<String, Integer> multimap) { + SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { ImmutableSetMultimap<String, Integer> badEntries = ImmutableSetMultimap.of("foo", 314, "bar", 358); multimap.putAll(badEntries); @@ -646,15 +700,14 @@ public class MultimapsCollectionTest extends TestCase { return multimap; } }) - .named("Multimaps.filterKeys[Maps.filterKeys[Multimap]]") + .named("Multimaps.filterKeys[Multimaps.filterKeys[SetMultimap]]") .withFeatures( CollectionSize.ANY, + MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE, MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_KEYS, - MapFeature.ALLOWS_NULL_VALUES) - .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(), - MultisetWritesTester.getEntrySetIteratorMethod()) + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); return suite; } diff --git a/guava-tests/test/com/google/common/collect/MultimapsTest.java b/guava-tests/test/com/google/common/collect/MultimapsTest.java index b8a36e9..c99681a 100644 --- a/guava-tests/test/com/google/common/collect/MultimapsTest.java +++ b/guava-tests/test/com/google/common/collect/MultimapsTest.java @@ -22,24 +22,28 @@ import static com.google.common.collect.Sets.newHashSet; import static com.google.common.collect.testing.Helpers.nefariousMapEntry; import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE; import static java.util.Arrays.asList; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Function; import com.google.common.base.Functions; +import com.google.common.base.Predicates; import com.google.common.base.Supplier; import com.google.common.collect.Maps.EntryTransformer; import com.google.common.collect.testing.IteratorTester; import com.google.common.collect.testing.google.UnmodifiableCollectionTests; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.io.Serializable; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; @@ -61,7 +65,7 @@ import javax.annotation.Nullable; * @author Jared Levy */ @GwtCompatible(emulated = true) -public class MultimapsTest extends AbstractMultimapTest { +public class MultimapsTest extends TestCase { private static final Comparator<Integer> INT_COMPARATOR = Ordering.<Integer>natural().reverse().nullsFirst(); @@ -74,11 +78,6 @@ public class MultimapsTest extends AbstractMultimapTest { } }; - @Override protected Multimap<String, Integer> create() { - return Multimaps.synchronizedSetMultimap( - HashMultimap.<String, Integer>create()); - } - @SuppressWarnings("deprecation") public void testUnmodifiableListMultimapShortCircuit() { ListMultimap<String, Integer> mod = ArrayListMultimap.create(); @@ -298,11 +297,10 @@ public class MultimapsTest extends AbstractMultimapTest { assertEquals(multimap.hashCode(), unmodifiable.hashCode()); assertEquals(multimap, unmodifiable); - FluentAsserts.assertThat(unmodifiable.asMap().get("bar")).has().allOf(5, -1); + ASSERT.that(unmodifiable.asMap().get("bar")).has().exactly(5, -1); assertNull(unmodifiable.asMap().get("missing")); assertFalse(unmodifiable.entries() instanceof Serializable); - assertFalse(unmodifiable.asMap().values() instanceof Serializable); } /** @@ -379,6 +377,32 @@ public class MultimapsTest extends AbstractMultimapTest { assertEquals(expected, multimap); } + public void testAsMap_multimap() { + Multimap<String, Integer> multimap = Multimaps.newMultimap( + new HashMap<String, Collection<Integer>>(), new QueueSupplier()); + Map<String, Collection<Integer>> map = Multimaps.asMap(multimap); + assertSame(multimap.asMap(), map); + } + + public void testAsMap_listMultimap() { + ListMultimap<String, Integer> listMultimap = ArrayListMultimap.create(); + Map<String, List<Integer>> map = Multimaps.asMap(listMultimap); + assertSame(listMultimap.asMap(), map); + } + + public void testAsMap_setMultimap() { + SetMultimap<String, Integer> setMultimap = LinkedHashMultimap.create(); + Map<String, Set<Integer>> map = Multimaps.asMap(setMultimap); + assertSame(setMultimap.asMap(), map); + } + + public void testAsMap_sortedSetMultimap() { + SortedSetMultimap<String, Integer> sortedSetMultimap = + TreeMultimap.create(); + Map<String, SortedSet<Integer>> map = Multimaps.asMap(sortedSetMultimap); + assertSame(sortedSetMultimap.asMap(), map); + } + public void testForMap() { Map<String, Integer> map = Maps.newHashMap(); map.put("foo", 1); @@ -430,11 +454,11 @@ public class MultimapsTest extends AbstractMultimapTest { assertFalse(map.containsKey("bar")); assertEquals(map.keySet(), multimapView.keySet()); assertEquals(map.keySet(), multimapView.keys().elementSet()); - FluentAsserts.assertThat(multimapView.keys()).has().item("foo"); - FluentAsserts.assertThat(multimapView.values()).has().item(1); - FluentAsserts.assertThat(multimapView.entries()).has().item( + ASSERT.that(multimapView.keys()).has().item("foo"); + ASSERT.that(multimapView.values()).has().item(1); + ASSERT.that(multimapView.entries()).has().item( Maps.immutableEntry("foo", 1)); - FluentAsserts.assertThat(multimapView.asMap().entrySet()).has().item( + ASSERT.that(multimapView.asMap().entrySet()).has().item( Maps.immutableEntry( "foo", (Collection<Integer>) Collections.singleton(1))); multimapView.clear(); @@ -525,13 +549,12 @@ public class MultimapsTest extends AbstractMultimapTest { } }; - tester.ignoreSunJavaBug6529795(); tester.test(); } private enum Color {BLUE, RED, YELLOW, GREEN} - private static abstract class CountingSupplier<E> + private abstract static class CountingSupplier<E> implements Supplier<E>, Serializable { int count; @@ -592,7 +615,7 @@ public class MultimapsTest extends AbstractMultimapTest { } catch (IllegalArgumentException expected) { // expected } - FluentAsserts.assertThat(multimap.entries()).has().allOf( + ASSERT.that(multimap.entries()).has().exactly( Maps.immutableEntry(Color.RED, 1), Maps.immutableEntry(Color.BLUE, 2)); } @@ -815,7 +838,7 @@ public class MultimapsTest extends AbstractMultimapTest { } }; Multimap<String, Integer> transformed = Multimaps.transformValues(multimap, square); - FluentAsserts.assertThat(transformed.entries()).has().allOf(immutableEntry("a", 4), + ASSERT.that(transformed.entries()).has().exactly(immutableEntry("a", 4), immutableEntry("a", 16), immutableEntry("b", 9), immutableEntry("b", 9), immutableEntry("c", 36)).inOrder(); } @@ -833,7 +856,7 @@ public class MultimapsTest extends AbstractMultimapTest { }); Entry<String, String> entry = multimap.entries().iterator().next(); entry.setValue("bbb"); - FluentAsserts.assertThat(transformed.entries()).has().allOf(immutableEntry("a", 3)).inOrder(); + ASSERT.that(transformed.entries()).has().exactly(immutableEntry("a", 3)).inOrder(); } @GwtIncompatible(value = "untested") @@ -848,7 +871,7 @@ public class MultimapsTest extends AbstractMultimapTest { }; ListMultimap<String, Integer> transformed = Multimaps.transformValues(multimap, square); - FluentAsserts.assertThat(transformed.entries()).has().allOf(immutableEntry("a", 4), + ASSERT.that(transformed.entries()).has().exactly(immutableEntry("a", 4), immutableEntry("a", 16), immutableEntry("b", 9), immutableEntry("b", 9), immutableEntry("c", 36)).inOrder(); } @@ -866,7 +889,7 @@ public class MultimapsTest extends AbstractMultimapTest { }; Multimap<String, String> transformed = Multimaps.transformEntries(multimap, transformer); - FluentAsserts.assertThat(transformed.entries()).has().allOf(immutableEntry("a", "a"), + ASSERT.that(transformed.entries()).has().exactly(immutableEntry("a", "a"), immutableEntry("a", "a"), immutableEntry("b", "nob")).inOrder(); } @@ -904,6 +927,83 @@ public class MultimapsTest extends AbstractMultimapTest { } private static void foo(Object o) {} + + public void testFilteredKeysSetMultimapReplaceValues() { + SetMultimap<String, Integer> multimap = LinkedHashMultimap.create(); + multimap.put("foo", 1); + multimap.put("bar", 2); + multimap.put("baz", 3); + multimap.put("bar", 4); + + SetMultimap<String, Integer> filtered = Multimaps.filterKeys( + multimap, Predicates.in(ImmutableSet.of("foo", "bar"))); + + assertEquals( + ImmutableSet.of(), + filtered.replaceValues("baz", ImmutableSet.<Integer>of())); + + try { + filtered.replaceValues("baz", ImmutableSet.of(5)); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + public void testFilteredKeysSetMultimapGetBadValue() { + SetMultimap<String, Integer> multimap = LinkedHashMultimap.create(); + multimap.put("foo", 1); + multimap.put("bar", 2); + multimap.put("baz", 3); + multimap.put("bar", 4); + + SetMultimap<String, Integer> filtered = Multimaps.filterKeys( + multimap, Predicates.in(ImmutableSet.of("foo", "bar"))); + Set<Integer> bazSet = filtered.get("baz"); + ASSERT.that(bazSet).isEmpty(); + try { + bazSet.add(5); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + try { + bazSet.addAll(ImmutableSet.of(6, 7)); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + public void testFilteredKeysListMultimapGetBadValue() { + ListMultimap<String, Integer> multimap = ArrayListMultimap.create(); + multimap.put("foo", 1); + multimap.put("bar", 2); + multimap.put("baz", 3); + multimap.put("bar", 4); + + ListMultimap<String, Integer> filtered = Multimaps.filterKeys( + multimap, Predicates.in(ImmutableSet.of("foo", "bar"))); + List<Integer> bazList = filtered.get("baz"); + ASSERT.that(bazList).isEmpty(); + try { + bazList.add(5); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + try { + bazList.add(0, 6); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + try { + bazList.addAll(ImmutableList.of(7, 8)); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + try { + bazList.addAll(0, ImmutableList.of(9, 10)); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } @GwtIncompatible("NullPointerTester") public void testNullPointers() { diff --git a/guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java b/guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java index c5d776c..54cd61e 100644 --- a/guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java +++ b/guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java @@ -24,22 +24,18 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; -import com.google.common.collect.testing.google.MultisetIteratorTester; import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; -import com.google.common.collect.testing.google.MultisetWritesTester; import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringMultisetGenerator; -import com.google.common.collect.testing.testers.CollectionIteratorTester; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * Collection tests on wrappers from {@link Multisets}. * @@ -94,11 +90,9 @@ public class MultisetsCollectionTest extends TestCase { .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.KNOWN_ORDER, - CollectionFeature.GENERAL_PURPOSE) + CollectionFeature.SUPPORTS_ADD, + CollectionFeature.SUPPORTS_REMOVE) .named("Multiset.filter[Multiset, Predicate]") - .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod(), - MultisetIteratorTester.getIteratorKnownOrderRemoveSupportedMethod(), - MultisetWritesTester.getEntrySetIteratorMethod()) .createTestSuite()); return suite; @@ -240,7 +234,7 @@ public class MultisetsCollectionTest extends TestCase { @Override protected Multiset<String> create(String[] elements) { Multiset<String> multiset = LinkedHashMultiset.create(); - multiset.addAll(Arrays.asList(elements)); + Collections.addAll(multiset, elements); multiset.addAll(ELEMENTS_TO_FILTER_OUT); return Multisets.filter(multiset, PREDICATE); } diff --git a/guava-tests/test/com/google/common/collect/MultisetsImmutableEntryTest.java b/guava-tests/test/com/google/common/collect/MultisetsImmutableEntryTest.java index 05dddbb..4d4aadc 100644 --- a/guava-tests/test/com/google/common/collect/MultisetsImmutableEntryTest.java +++ b/guava-tests/test/com/google/common/collect/MultisetsImmutableEntryTest.java @@ -19,10 +19,10 @@ package com.google.common.collect; import com.google.common.annotations.GwtCompatible; import com.google.common.collect.Multiset.Entry; -import java.util.Collections; - import junit.framework.TestCase; +import java.util.Collections; + /** * Tests for {@link Multisets#immutableEntry}. * diff --git a/guava-tests/test/com/google/common/collect/MultisetsTest.java b/guava-tests/test/com/google/common/collect/MultisetsTest.java index 0723fab..69cf56a 100644 --- a/guava-tests/test/com/google/common/collect/MultisetsTest.java +++ b/guava-tests/test/com/google/common/collect/MultisetsTest.java @@ -21,15 +21,12 @@ import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.DerivedComparable; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import junit.framework.TestCase; /** * Tests for {@link Multisets}. @@ -48,7 +45,7 @@ public class MultisetsTest extends TestCase { assertTrue(set.isEmpty()); set.add(new DerivedComparable("foo"), 2); set.add(new DerivedComparable("bar"), 3); - FluentAsserts.assertThat(set).has().allOf( + ASSERT.that(set).has().exactly( new DerivedComparable("bar"), new DerivedComparable("bar"), new DerivedComparable("bar"), new DerivedComparable("foo"), new DerivedComparable("foo")).inOrder(); } @@ -58,7 +55,7 @@ public class MultisetsTest extends TestCase { assertTrue(set.isEmpty()); set.add(new LegacyComparable("foo"), 2); set.add(new LegacyComparable("bar"), 3); - FluentAsserts.assertThat(set).has().allOf(new LegacyComparable("bar"), + ASSERT.that(set).has().exactly(new LegacyComparable("bar"), new LegacyComparable("bar"), new LegacyComparable("bar"), new LegacyComparable("foo"), new LegacyComparable("foo")).inOrder(); } @@ -68,7 +65,7 @@ public class MultisetsTest extends TestCase { = TreeMultiset.create(Collections.reverseOrder()); multiset.add("bar", 3); multiset.add("foo", 2); - FluentAsserts.assertThat(multiset).has().allOf("foo", "foo", "bar", "bar", "bar").inOrder(); + ASSERT.that(multiset).has().exactly("foo", "foo", "bar", "bar", "bar").inOrder(); } public void testRetainOccurrencesEmpty() { @@ -76,7 +73,7 @@ public class MultisetsTest extends TestCase { Multiset<String> toRetain = HashMultiset.create(Arrays.asList("a", "b", "a")); assertFalse(Multisets.retainOccurrences(multiset, toRetain)); - FluentAsserts.assertThat(multiset).isEmpty(); + ASSERT.that(multiset).isEmpty(); } public void testRemoveOccurrencesEmpty() { @@ -91,7 +88,7 @@ public class MultisetsTest extends TestCase { Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); Multiset<String> ms2 = HashMultiset.create( Arrays.asList("a", "b", "b", "c")); - FluentAsserts.assertThat(Multisets.union(ms1, ms2)).has().allOf("a", "a", "b", "b", "c"); + ASSERT.that(Multisets.union(ms1, ms2)).has().exactly("a", "a", "b", "b", "c"); } public void testUnionEqualMultisets() { @@ -115,50 +112,50 @@ public class MultisetsTest extends TestCase { public void testIntersectEmptyNonempty() { Multiset<String> ms1 = HashMultiset.create(); Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a")); - FluentAsserts.assertThat(Multisets.intersection(ms1, ms2)).isEmpty(); + ASSERT.that(Multisets.intersection(ms1, ms2)).isEmpty(); } public void testIntersectNonemptyEmpty() { Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); Multiset<String> ms2 = HashMultiset.create(); - FluentAsserts.assertThat(Multisets.intersection(ms1, ms2)).isEmpty(); + ASSERT.that(Multisets.intersection(ms1, ms2)).isEmpty(); } public void testSum() { Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b", "c")); - FluentAsserts.assertThat(Multisets.sum(ms1, ms2)).has().allOf("a", "a", "b", "b", "c"); + ASSERT.that(Multisets.sum(ms1, ms2)).has().exactly("a", "a", "b", "b", "c"); } public void testSumEmptyNonempty() { Multiset<String> ms1 = HashMultiset.create(); Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a")); - FluentAsserts.assertThat(Multisets.sum(ms1, ms2)).has().allOf("a", "b", "a"); + ASSERT.that(Multisets.sum(ms1, ms2)).has().exactly("a", "b", "a"); } public void testSumNonemptyEmpty() { Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); Multiset<String> ms2 = HashMultiset.create(); - FluentAsserts.assertThat(Multisets.sum(ms1, ms2)).has().allOf("a", "b", "a"); + ASSERT.that(Multisets.sum(ms1, ms2)).has().exactly("a", "b", "a"); } public void testDifferenceWithNoRemovedElements() { Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a")); - FluentAsserts.assertThat(Multisets.difference(ms1, ms2)).has().allOf("a", "b"); + ASSERT.that(Multisets.difference(ms1, ms2)).has().exactly("a", "b"); } public void testDifferenceWithRemovedElement() { Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b")); - FluentAsserts.assertThat(Multisets.difference(ms1, ms2)).has().allOf("a", "a"); + ASSERT.that(Multisets.difference(ms1, ms2)).has().exactly("a", "a"); } public void testDifferenceWithMoreElementsInSecondMultiset() { Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a")); Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "b", "b")); Multiset<String> diff = Multisets.difference(ms1, ms2); - FluentAsserts.assertThat(diff).has().item("a"); + ASSERT.that(diff).has().item("a"); assertEquals(0, diff.count("b")); assertEquals(1, diff.count("a")); assertFalse(diff.contains("b")); @@ -208,7 +205,7 @@ public class MultisetsTest extends TestCase { Multiset<String> toRetain = HashMultiset.create(Arrays.asList("a", "b", "b")); assertTrue(Multisets.retainOccurrences(multiset, toRetain)); - FluentAsserts.assertThat(multiset).has().allOf("a", "b").inOrder(); + ASSERT.that(multiset).has().exactly("a", "b").inOrder(); } public void testRemoveEmptyOccurrences() { @@ -216,7 +213,7 @@ public class MultisetsTest extends TestCase { TreeMultiset.create(Arrays.asList("a", "b", "a")); Multiset<String> toRemove = HashMultiset.create(); assertFalse(Multisets.removeOccurrences(multiset, toRemove)); - FluentAsserts.assertThat(multiset).has().allOf("a", "a", "b").inOrder(); + ASSERT.that(multiset).has().exactly("a", "a", "b").inOrder(); } public void testRemoveOccurrences() { @@ -225,7 +222,7 @@ public class MultisetsTest extends TestCase { Multiset<String> toRemove = HashMultiset.create(Arrays.asList("a", "b", "b")); assertTrue(Multisets.removeOccurrences(multiset, toRemove)); - FluentAsserts.assertThat(multiset).has().allOf("a", "c").inOrder(); + ASSERT.that(multiset).has().exactly("a", "c").inOrder(); } @SuppressWarnings("deprecation") @@ -245,11 +242,11 @@ public class MultisetsTest extends TestCase { ImmutableMultiset<String> sortedMultiset = Multisets.copyHighestCountFirst(multiset); - FluentAsserts.assertThat(sortedMultiset.entrySet()).has().allOf( + ASSERT.that(sortedMultiset.entrySet()).has().exactly( Multisets.immutableEntry("a", 3), Multisets.immutableEntry("c", 2), Multisets.immutableEntry("b", 1)).inOrder(); - FluentAsserts.assertThat(sortedMultiset).has().allOf( + ASSERT.that(sortedMultiset).has().exactly( "a", "a", "a", @@ -257,7 +254,7 @@ public class MultisetsTest extends TestCase { "c", "b").inOrder(); - FluentAsserts.assertThat(Multisets.copyHighestCountFirst(ImmutableMultiset.of())).isEmpty(); + ASSERT.that(Multisets.copyHighestCountFirst(ImmutableMultiset.of())).isEmpty(); } @GwtIncompatible("NullPointerTester") diff --git a/guava-tests/test/com/google/common/collect/MutableClassToInstanceMapTest.java b/guava-tests/test/com/google/common/collect/MutableClassToInstanceMapTest.java index 6a8df70..10b5cf7 100644 --- a/guava-tests/test/com/google/common/collect/MutableClassToInstanceMapTest.java +++ b/guava-tests/test/com/google/common/collect/MutableClassToInstanceMapTest.java @@ -18,18 +18,19 @@ package com.google.common.collect; import com.google.common.collect.ImmutableClassToInstanceMapTest.TestClassToInstanceMapGenerator; import com.google.common.collect.testing.MapTestSuiteBuilder; +import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; import com.google.common.collect.testing.testers.MapPutTester; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.Map.Entry; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Map.Entry; + /** * Unit test of {@link MutableClassToInstanceMap}. * @@ -72,7 +73,8 @@ public class MutableClassToInstanceMapTest extends TestCase { MapFeature.RESTRICTS_KEYS, MapFeature.ALLOWS_NULL_VALUES, CollectionSize.ANY, - MapFeature.ALLOWS_NULL_QUERIES) + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, + MapFeature.ALLOWS_ANY_NULL_QUERIES) .suppressing(remapTest) .createTestSuite()); diff --git a/guava-tests/test/com/google/common/collect/NewCustomTableTest.java b/guava-tests/test/com/google/common/collect/NewCustomTableTest.java index d6dedf8..c172826 100644 --- a/guava-tests/test/com/google/common/collect/NewCustomTableTest.java +++ b/guava-tests/test/com/google/common/collect/NewCustomTableTest.java @@ -21,12 +21,9 @@ import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.base.Supplier; -import java.util.Collection; import java.util.Map; import java.util.TreeMap; -import org.truth0.subjects.CollectionSubject; - /** * Test cases for {@link Tables#newCustomTable}. * @@ -54,17 +51,11 @@ public class NewCustomTableTest extends AbstractTableTest { public void testRowKeySetOrdering() { table = create("foo", 3, 'a', "bar", 1, 'b', "foo", 2, 'c'); - assertThat(table.rowKeySet()).has().allOf("foo", "bar").inOrder(); + ASSERT.that(table.rowKeySet()).has().exactly("foo", "bar").inOrder(); } public void testRowOrdering() { table = create("foo", 3, 'a', "bar", 1, 'b', "foo", 2, 'c'); - assertThat(table.row("foo").keySet()).has().allOf(2, 3).inOrder(); - } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); + ASSERT.that(table.row("foo").keySet()).has().exactly(2, 3).inOrder(); } } diff --git a/guava-tests/test/com/google/common/collect/ObjectArraysTest.java b/guava-tests/test/com/google/common/collect/ObjectArraysTest.java index ad10dfe..4c2cd85 100644 --- a/guava-tests/test/com/google/common/collect/ObjectArraysTest.java +++ b/guava-tests/test/com/google/common/collect/ObjectArraysTest.java @@ -16,17 +16,18 @@ package com.google.common.collect; +import static org.truth0.Truth.ASSERT; + import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.io.Serializable; import java.util.Arrays; import java.util.List; -import junit.framework.TestCase; - /** * Unit test for {@code ObjectArrays}. * @@ -97,7 +98,7 @@ public class ObjectArraysTest extends TestCase { String[] result = ObjectArrays.concat( new String[0], new String[] { "a", "b" }, String.class); assertEquals(String[].class, result.getClass()); - FluentAsserts.assertThat(result).has().allOf("a", "b").inOrder(); + ASSERT.that(result).has().exactly("a", "b").inOrder(); } @GwtIncompatible("ObjectArrays.concat(Object[], Object[], Class)") @@ -105,7 +106,7 @@ public class ObjectArraysTest extends TestCase { String[] result = ObjectArrays.concat( new String[] { "a", "b" }, new String[0], String.class); assertEquals(String[].class, result.getClass()); - FluentAsserts.assertThat(result).has().allOf("a", "b").inOrder(); + ASSERT.that(result).has().exactly("a", "b").inOrder(); } @GwtIncompatible("ObjectArrays.concat(Object[], Object[], Class)") @@ -113,7 +114,7 @@ public class ObjectArraysTest extends TestCase { String[] result = ObjectArrays.concat( new String[] { "a", "b" }, new String[] { "c", "d" }, String.class); assertEquals(String[].class, result.getClass()); - FluentAsserts.assertThat(result).has().allOf("a", "b", "c", "d").inOrder(); + ASSERT.that(result).has().exactly("a", "b", "c", "d").inOrder(); } @GwtIncompatible("ObjectArrays.concat(Object[], Object[], Class)") @@ -151,8 +152,8 @@ public class ObjectArraysTest extends TestCase { private void doTestToArrayImpl2(List<Integer> list, Integer[] array1, boolean expectModify) { - Integer[] starting = Platform.clone(array1); - Integer[] array2 = Platform.clone(array1); + Integer[] starting = ObjectArrays.arraysCopyOf(array1, array1.length); + Integer[] array2 = ObjectArrays.arraysCopyOf(array1, array1.length); Object[] reference = list.toArray(array1); Object[] target = ObjectArrays.toArrayImpl(list, array2); @@ -169,32 +170,32 @@ public class ObjectArraysTest extends TestCase { public void testPrependZeroElements() { String[] result = ObjectArrays.concat("foo", new String[] {}); - FluentAsserts.assertThat(result).has().item("foo"); + ASSERT.that(result).has().item("foo"); } public void testPrependOneElement() { String[] result = ObjectArrays.concat("foo", new String[] { "bar" }); - FluentAsserts.assertThat(result).has().allOf("foo", "bar").inOrder(); + ASSERT.that(result).has().exactly("foo", "bar").inOrder(); } public void testPrependTwoElements() { String[] result = ObjectArrays.concat("foo", new String[] { "bar", "baz" }); - FluentAsserts.assertThat(result).has().allOf("foo", "bar", "baz").inOrder(); + ASSERT.that(result).has().exactly("foo", "bar", "baz").inOrder(); } public void testAppendZeroElements() { String[] result = ObjectArrays.concat(new String[] {}, "foo"); - FluentAsserts.assertThat(result).has().item("foo"); + ASSERT.that(result).has().item("foo"); } public void testAppendOneElement() { String[] result = ObjectArrays.concat(new String[] { "foo" }, "bar"); - FluentAsserts.assertThat(result).has().allOf("foo", "bar").inOrder(); + ASSERT.that(result).has().exactly("foo", "bar").inOrder(); } public void testAppendTwoElements() { String[] result = ObjectArrays.concat(new String[] { "foo", "bar" }, "baz"); - FluentAsserts.assertThat(result).has().allOf("foo", "bar", "baz").inOrder(); + ASSERT.that(result).has().exactly("foo", "bar", "baz").inOrder(); } public void testEmptyArrayToEmpty() { @@ -218,20 +219,6 @@ public class ObjectArraysTest extends TestCase { ObjectArrays.newArray(new String[] { "a", "b", "c", "d", "e" }, 10)); } - public void testCloneEmptyArray() { - checkArrayEquals(new String[0], Platform.clone(new String[0])); - } - - public void testCloneSingletonArray() { - checkArrayEquals( - new String[] { "a" }, Platform.clone(new String[] { "a" })); - } - - public void testCloneMultipleElementArray() { - checkArrayEquals( - new String[] { "a", "b", "c" }, Platform.clone(new String[] { "a", "b", "c" })); - } - private static void checkArrayEquals(Object[] expected, Object[] actual) { assertTrue("expected(" + expected.getClass() + "): " + Arrays.toString(expected) + " actual(" + actual.getClass() + "): " + Arrays.toString(actual), diff --git a/guava-tests/test/com/google/common/collect/OrderingTest.java b/guava-tests/test/com/google/common/collect/OrderingTest.java index ad2203e..4af99d5 100644 --- a/guava-tests/test/com/google/common/collect/OrderingTest.java +++ b/guava-tests/test/com/google/common/collect/OrderingTest.java @@ -21,6 +21,7 @@ import static com.google.common.collect.Lists.newArrayList; import static com.google.common.testing.SerializableTester.reserialize; import static com.google.common.testing.SerializableTester.reserializeAndAssert; import static java.util.Arrays.asList; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -29,10 +30,12 @@ import com.google.common.base.Functions; import com.google.common.collect.Ordering.ArbitraryOrdering; import com.google.common.collect.Ordering.IncomparableValueException; import com.google.common.collect.testing.Helpers; +import com.google.common.primitives.Ints; import com.google.common.testing.EqualsTester; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Collections; import java.util.Comparator; @@ -43,8 +46,6 @@ import java.util.RandomAccess; import javax.annotation.Nullable; -import junit.framework.TestCase; - /** * Unit tests for {@code Ordering}. * @@ -156,7 +157,7 @@ public class OrderingTest extends TestCase { = Ordering.explicit(2, 8, 6, 1, 7, 5, 3, 4, 0, 9); List<Integer> list = Arrays.asList(0, 3, 5, 6, 7, 8, 9); Collections.sort(list, c); - FluentAsserts.assertThat(list).has().allOf(8, 6, 7, 5, 3, 0, 9).inOrder(); + ASSERT.that(list).has().exactly(8, 6, 7, 5, 3, 0, 9).inOrder(); reserializeAndAssert(c); } @@ -831,25 +832,29 @@ public class OrderingTest extends TestCase { // should periodically try increasing this, but it makes the test run long private static final int RECURSE_DEPTH = 2; - + public void testCombinationsExhaustively_startingFromNatural() { testExhaustively(Ordering.<String>natural(), "a", "b", "d"); } - + + @GwtIncompatible("too slow") public void testCombinationsExhaustively_startingFromExplicit() { testExhaustively(Ordering.explicit("a", "b", "c", "d"), "a", "b", "d"); } - + + @GwtIncompatible("too slow") public void testCombinationsExhaustively_startingFromUsingToString() { testExhaustively(Ordering.usingToString(), 1, 12, 2); } + @GwtIncompatible("too slow") public void testCombinationsExhaustively_startingFromFromComparator() { testExhaustively(Ordering.from(String.CASE_INSENSITIVE_ORDER), "A", "b", "C", "d"); } - + + @GwtIncompatible("too slow") public void testCombinationsExhaustively_startingFromArbitrary() { Ordering<Object> arbitrary = Ordering.arbitrary(); Object[] array = {1, "foo", new Object()}; @@ -1084,7 +1089,7 @@ public class OrderingTest extends TestCase { // order of 't'. @Override public int compareTo(Composite<T> that) { - return rank < that.rank ? -1 : rank > that.rank ? 1 : 0; + return Ints.compare(rank, that.rank); } static <T> Function<Composite<T>, T> getValueFunction() { diff --git a/guava-tests/test/com/google/common/collect/PeekingIteratorTest.java b/guava-tests/test/com/google/common/collect/PeekingIteratorTest.java index 755e340..85cf9dd 100644 --- a/guava-tests/test/com/google/common/collect/PeekingIteratorTest.java +++ b/guava-tests/test/com/google/common/collect/PeekingIteratorTest.java @@ -25,14 +25,14 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.IteratorTester; +import junit.framework.TestCase; + import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; -import junit.framework.TestCase; - /** * Unit test for {@link PeekingIterator}. * diff --git a/guava-tests/test/com/google/common/collect/QueuesTest.java b/guava-tests/test/com/google/common/collect/QueuesTest.java index 874592d..bffcb39 100644 --- a/guava-tests/test/com/google/common/collect/QueuesTest.java +++ b/guava-tests/test/com/google/common/collect/QueuesTest.java @@ -193,7 +193,6 @@ public class QueuesTest extends TestCase { private void testDrainUninterruptibly_doesNotThrow(final BlockingQueue<Object> q) { final Thread mainThread = Thread.currentThread(); threadPool.submit(new Runnable() { - @Override public void run() { new Producer(q, 50).run(); new Interrupter(mainThread).run(); diff --git a/guava-tests/test/com/google/common/collect/RangeTest.java b/guava-tests/test/com/google/common/collect/RangeTest.java index d866048..2e32593 100644 --- a/guava-tests/test/com/google/common/collect/RangeTest.java +++ b/guava-tests/test/com/google/common/collect/RangeTest.java @@ -27,13 +27,13 @@ import com.google.common.base.Predicate; import com.google.common.collect.testing.Helpers; import com.google.common.testing.EqualsTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.NoSuchElementException; -import junit.framework.TestCase; - /** * Unit test for {@link Range}. * @@ -536,7 +536,7 @@ public class RangeTest extends TestCase { = Range.closed(LegacyComparable.X, LegacyComparable.Y); } - private static final DiscreteDomain<Integer> UNBOUNDED_DOMAIN = + static final DiscreteDomain<Integer> UNBOUNDED_DOMAIN = new DiscreteDomain<Integer>() { @Override public Integer next(Integer value) { return integers().next(value); @@ -551,29 +551,6 @@ public class RangeTest extends TestCase { } }; - public void testAsSet_noMin() { - Range<Integer> range = Range.lessThan(0); - try { - range.asSet(UNBOUNDED_DOMAIN); - fail(); - } catch (IllegalArgumentException expected) {} - } - - public void testAsSet_noMax() { - Range<Integer> range = Range.greaterThan(0); - try { - range.asSet(UNBOUNDED_DOMAIN); - fail(); - } catch (IllegalArgumentException expected) {} - } - - public void testAsSet_empty() { - assertEquals(ImmutableSet.of(), Range.closedOpen(1, 1).asSet(integers())); - assertEquals(ImmutableSet.of(), Range.openClosed(5, 5).asSet(integers())); - assertEquals(ImmutableSet.of(), Range.lessThan(Integer.MIN_VALUE).asSet(integers())); - assertEquals(ImmutableSet.of(), Range.greaterThan(Integer.MAX_VALUE).asSet(integers())); - } - public void testCanonical() { assertEquals(Range.closedOpen(1, 5), Range.closed(1, 4).canonical(integers())); diff --git a/guava-tests/test/com/google/common/collect/RangesTest.java b/guava-tests/test/com/google/common/collect/RangesTest.java deleted file mode 100644 index ee249c0..0000000 --- a/guava-tests/test/com/google/common/collect/RangesTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.collect; - -import static com.google.common.collect.BoundType.CLOSED; -import static com.google.common.collect.BoundType.OPEN; - -import com.google.common.annotations.GwtCompatible; -import com.google.common.testing.EqualsTester; - -import java.util.Arrays; -import java.util.List; -import java.util.NoSuchElementException; - -import junit.framework.TestCase; - -/** - * @author Gregory Kick - */ -@GwtCompatible -@SuppressWarnings("deprecation") // since Ranges is deprecated -public class RangesTest extends TestCase { - public void testSingleton() { - assertEquals(Ranges.closed(0, 0), Ranges.singleton(0)); - assertEquals(Ranges.closed(9, 9), Ranges.singleton(9)); - } - - public void testEncloseAll() { - assertEquals(Ranges.closed(0, 0), Ranges.encloseAll(Arrays.asList(0))); - assertEquals(Ranges.closed(-3, 5), Ranges.encloseAll(Arrays.asList(5, -3))); - assertEquals(Ranges.closed(-3, 5), Ranges.encloseAll(Arrays.asList(1, 2, 2, 2, 5, -3, 0, -1))); - } - - public void testEncloseAll_empty() { - try { - Ranges.encloseAll(ImmutableSet.<Integer>of()); - fail(); - } catch (NoSuchElementException expected) {} - } - - public void testEncloseAll_nullValue() { - List<Integer> nullFirst = Lists.newArrayList(null, 0); - try { - Ranges.encloseAll(nullFirst); - fail(); - } catch (NullPointerException expected) {} - List<Integer> nullNotFirst = Lists.newArrayList(0, null); - try { - Ranges.encloseAll(nullNotFirst); - fail(); - } catch (NullPointerException expected) {} - } - - public void testEquivalentFactories() { - new EqualsTester() - .addEqualityGroup(Ranges.all()) - .addEqualityGroup( - Ranges.atLeast(1), - Ranges.downTo(1, CLOSED)) - .addEqualityGroup( - Ranges.greaterThan(1), - Ranges.downTo(1, OPEN)) - .addEqualityGroup( - Ranges.atMost(7), - Ranges.upTo(7, CLOSED)) - .addEqualityGroup( - Ranges.lessThan(7), - Ranges.upTo(7, OPEN)) - .addEqualityGroup( - Ranges.open(1, 7), - Ranges.range(1, OPEN, 7, OPEN)) - .addEqualityGroup( - Ranges.openClosed(1, 7), - Ranges.range(1, OPEN, 7, CLOSED)) - .addEqualityGroup( - Ranges.closed(1, 7), - Ranges.range(1, CLOSED, 7, CLOSED)) - .addEqualityGroup( - Ranges.closedOpen(1, 7), - Ranges.range(1, CLOSED, 7, OPEN)) - .testEquals(); - } -} diff --git a/guava-tests/test/com/google/common/collect/RegularImmutableAsListTest.java b/guava-tests/test/com/google/common/collect/RegularImmutableAsListTest.java new file mode 100644 index 0000000..8d9c2ec --- /dev/null +++ b/guava-tests/test/com/google/common/collect/RegularImmutableAsListTest.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.collect; + +import com.google.common.annotations.GwtCompatible; + +import junit.framework.TestCase; + +/** + * Tests for {@link RegularImmutableAsList}. + * + * @author Louis Wasserman + */ +@GwtCompatible +public class RegularImmutableAsListTest extends TestCase { + /** + * RegularImmutableAsList should assume its input is null-free without checking, because it only + * gets invoked from other immutable collections. + */ + public void testDoesntCheckForNull() { + ImmutableSet<Integer> set = ImmutableSet.of(1, 2, 3); + new RegularImmutableAsList<Integer>(set, new Object[] {null, null, null}); + // shouldn't throw! + } +} diff --git a/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java b/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java index 9eced5b..b76942b 100644 --- a/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java +++ b/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java @@ -16,11 +16,10 @@ package com.google.common.collect; +import static org.truth0.Truth.ASSERT; + import com.google.common.annotations.GwtCompatible; -import com.google.common.collect.RegularImmutableTable.DenseImmutableTable; -import com.google.common.collect.RegularImmutableTable.SparseImmutableTable; import com.google.common.collect.Table.Cell; -import com.google.common.testing.FluentAsserts; /** * @author Gregory Kick @@ -63,8 +62,8 @@ public class RegularImmutableTableTest extends AbstractImmutableTableTest { public void testValues() { for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) { - FluentAsserts.assertThat(testInstance.values()) - .has().allOf("foo", "bar", "baz") + ASSERT.that(testInstance.values()) + .has().exactly("foo", "bar", "baz") .inOrder(); } } diff --git a/guava-tests/test/com/google/common/collect/SetOperationsTest.java b/guava-tests/test/com/google/common/collect/SetOperationsTest.java index 4375951..474d9f7 100644 --- a/guava-tests/test/com/google/common/collect/SetOperationsTest.java +++ b/guava-tests/test/com/google/common/collect/SetOperationsTest.java @@ -26,13 +26,13 @@ import com.google.common.collect.testing.TestStringSetGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; -import java.util.HashSet; -import java.util.Set; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.HashSet; +import java.util.Set; + /** * Unit tests for {@link Sets#union}, {@link Sets#intersection} and * {@link Sets#difference}. diff --git a/guava-tests/test/com/google/common/collect/SetsTest.java b/guava-tests/test/com/google/common/collect/SetsTest.java index 7b3d1c2..e726f63 100644 --- a/guava-tests/test/com/google/common/collect/SetsTest.java +++ b/guava-tests/test/com/google/common/collect/SetsTest.java @@ -19,6 +19,7 @@ package com.google.common.collect; import static com.google.common.collect.Iterables.unmodifiableIterable; import static com.google.common.collect.Sets.newEnumSet; import static com.google.common.collect.Sets.newHashSet; +import static com.google.common.collect.Sets.newLinkedHashSet; import static com.google.common.collect.Sets.powerSet; import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE; import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod; @@ -84,80 +85,100 @@ import javax.annotation.Nullable; @GwtCompatible(emulated = true) public class SetsTest extends TestCase { - private static final IteratorTester.KnownOrder KNOWN_ORDER = IteratorTester.KnownOrder.KNOWN_ORDER; + private static final IteratorTester.KnownOrder KNOWN_ORDER = + IteratorTester.KnownOrder.KNOWN_ORDER; - private static final Collection<Integer> EMPTY_COLLECTION = Arrays.<Integer>asList(); + private static final Collection<Integer> EMPTY_COLLECTION + = Arrays.<Integer>asList(); - private static final Collection<Integer> SOME_COLLECTION = Arrays.asList(0, 1, 1); + private static final Collection<Integer> SOME_COLLECTION + = Arrays.asList(0, 1, 1); - private static final Iterable<Integer> SOME_ITERABLE = new Iterable<Integer>() { - @Override - public Iterator<Integer> iterator() { - return SOME_COLLECTION.iterator(); - } - }; + private static final Iterable<Integer> SOME_ITERABLE + = new Iterable<Integer>() { + @Override + public Iterator<Integer> iterator() { + return SOME_COLLECTION.iterator(); + } + }; - private static final List<Integer> LONGER_LIST = Arrays.asList(8, 6, 7, 5, 3, 0, 9); + private static final List<Integer> LONGER_LIST + = Arrays.asList(8, 6, 7, 5, 3, 0, 9); - private static final Comparator<Integer> SOME_COMPARATOR = Collections.reverseOrder(); + private static final Comparator<Integer> SOME_COMPARATOR + = Collections.reverseOrder(); @GwtIncompatible("suite") public static Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(SetsTest.class); - suite.addTest(SetTestSuiteBuilder - .using(new TestStringSetGenerator() { - @Override - protected Set<String> create(String[] elements) { + suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { + @Override protected Set<String> create(String[] elements) { + return Sets.newConcurrentHashSet(Arrays.asList(elements)); + } + }) + .named("Sets.newConcurrentHashSet") + .withFeatures(CollectionSize.ANY, SetFeature.GENERAL_PURPOSE) + .createTestSuite()); + + suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { + @Override protected Set<String> create(String[] elements) { int size = elements.length; // Remove last element, if size > 1 - Set<String> set1 = (size > 1) ? Sets.newHashSet(Arrays.asList(elements).subList(0, - size - 1)) : Sets.newHashSet(elements); + Set<String> set1 = (size > 1) + ? Sets.newHashSet( + Arrays.asList(elements).subList(0, size - 1)) + : Sets.newHashSet(elements); // Remove first element, if size > 0 - Set<String> set2 = (size > 0) ? Sets.newHashSet(Arrays.asList(elements) - .subList(1, size)) : Sets.<String>newHashSet(); + Set<String> set2 = (size > 0) + ? Sets.newHashSet( + Arrays.asList(elements).subList(1, size)) + : Sets.<String>newHashSet(); return Sets.union(set1, set2); } - }).named("Sets.union") + }) + .named("Sets.union") .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { - @Override - protected Set<String> create(String[] elements) { - Set<String> set1 = Sets.newHashSet(elements); - set1.add(samples().e3); - Set<String> set2 = Sets.newHashSet(elements); - set2.add(samples().e4); - return Sets.intersection(set1, set2); - } - }).named("Sets.intersection") - .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES).createTestSuite()); + @Override protected Set<String> create(String[] elements) { + Set<String> set1 = Sets.newHashSet(elements); + set1.add(samples().e3); + Set<String> set2 = Sets.newHashSet(elements); + set2.add(samples().e4); + return Sets.intersection(set1, set2); + } + }) + .named("Sets.intersection") + .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES) + .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { - @Override - protected Set<String> create(String[] elements) { - Set<String> set1 = Sets.newHashSet(elements); - set1.add(samples().e3); - Set<String> set2 = Sets.newHashSet(samples().e3); - return Sets.difference(set1, set2); - } - }).named("Sets.difference") - .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES).createTestSuite()); + @Override protected Set<String> create(String[] elements) { + Set<String> set1 = Sets.newHashSet(elements); + set1.add(samples().e3); + Set<String> set2 = Sets.newHashSet(samples().e3); + return Sets.difference(set1, set2); + } + }) + .named("Sets.difference") + .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES) + .createTestSuite()); - suite.addTest(SetTestSuiteBuilder - .using(new TestEnumSetGenerator() { - @Override - protected Set<AnEnum> create(AnEnum[] elements) { + suite.addTest(SetTestSuiteBuilder.using(new TestEnumSetGenerator() { + @Override protected Set<AnEnum> create(AnEnum[] elements) { AnEnum[] otherElements = new AnEnum[elements.length - 1]; - System.arraycopy(elements, 1, otherElements, 0, otherElements.length); + System.arraycopy( + elements, 1, otherElements, 0, otherElements.length); return Sets.immutableEnumSet(elements[0], otherElements); } }) .named("Sets.immutableEnumSet") .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL, - CollectionFeature.ALLOWS_NULL_QUERIES).createTestSuite()); + CollectionFeature.ALLOWS_NULL_QUERIES) + .createTestSuite()); suite.addTest(testsForFilter()); suite.addTest(testsForFilterNoNulls()); @@ -168,30 +189,31 @@ public class SetsTest extends TestCase { @GwtIncompatible("suite") private static Test testsForFilter() { - return SetTestSuiteBuilder - .using(new TestStringSetGenerator() { - @Override - public Set<String> create(String[] elements) { + return SetTestSuiteBuilder.using(new TestStringSetGenerator() { + @Override public Set<String> create(String[] elements) { Set<String> unfiltered = Sets.newLinkedHashSet(); unfiltered.add("yyy"); - unfiltered.addAll(Arrays.asList(elements)); + Collections.addAll(unfiltered, elements); unfiltered.add("zzz"); return Sets.filter(unfiltered, Collections2Test.NOT_YYY_ZZZ); } }) .named("Sets.filter") - .withFeatures(SetFeature.GENERAL_PURPOSE, CollectionFeature.ALLOWS_NULL_VALUES, - CollectionFeature.KNOWN_ORDER, CollectionSize.ANY) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()).createTestSuite(); + .withFeatures( + CollectionFeature.SUPPORTS_ADD, + CollectionFeature.SUPPORTS_REMOVE, + CollectionFeature.ALLOWS_NULL_VALUES, + CollectionFeature.KNOWN_ORDER, + CollectionSize.ANY) + .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) + .createTestSuite(); } @GwtIncompatible("suite") private static Test testsForFilterNoNulls() { TestSuite suite = new TestSuite(); - suite.addTest(SetTestSuiteBuilder - .using(new TestStringSetGenerator() { - @Override - public Set<String> create(String[] elements) { + suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { + @Override public Set<String> create(String[] elements) { Set<String> unfiltered = Sets.newLinkedHashSet(); unfiltered.add("yyy"); unfiltered.addAll(ImmutableList.copyOf(elements)); @@ -202,40 +224,43 @@ public class SetsTest extends TestCase { .named("Sets.filter, no nulls") .withFeatures(SetFeature.GENERAL_PURPOSE, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()).createTestSuite()); + .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) + .createTestSuite()); return suite; } @GwtIncompatible("suite") private static Test testsForFilterFiltered() { - return SetTestSuiteBuilder - .using(new TestStringSetGenerator() { - @Override - public Set<String> create(String[] elements) { + return SetTestSuiteBuilder.using(new TestStringSetGenerator() { + @Override public Set<String> create(String[] elements) { Set<String> unfiltered = Sets.newLinkedHashSet(); unfiltered.add("yyy"); unfiltered.addAll(ImmutableList.copyOf(elements)); unfiltered.add("zzz"); unfiltered.add("abc"); - return Sets.filter(Sets.filter(unfiltered, Collections2Test.LENGTH_1), + return Sets.filter( + Sets.filter(unfiltered, Collections2Test.LENGTH_1), Collections2Test.NOT_YYY_ZZZ); } }) .named("Sets.filter, filtered input") - .withFeatures(SetFeature.GENERAL_PURPOSE, CollectionFeature.KNOWN_ORDER, - CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()).createTestSuite(); + .withFeatures( + CollectionFeature.SUPPORTS_ADD, + CollectionFeature.SUPPORTS_REMOVE, + CollectionFeature.KNOWN_ORDER, + CollectionSize.ANY, + CollectionFeature.ALLOWS_NULL_QUERIES) + .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) + .createTestSuite(); } - private enum SomeEnum { - A, B, C, D - } + private enum SomeEnum { A, B, C, D } public void testImmutableEnumSet() { Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B); - ASSERT.<SomeEnum, Set<SomeEnum>>that(units).has().allOf(SomeEnum.B, SomeEnum.D).inOrder(); + ASSERT.that(units).has().exactly(SomeEnum.B, SomeEnum.D).inOrder(); try { units.remove(SomeEnum.B); fail("ImmutableEnumSet should throw an exception on remove()"); @@ -250,30 +275,35 @@ public class SetsTest extends TestCase { public void testImmutableEnumSet_serialized() { Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B); - ASSERT.<SomeEnum, Set<SomeEnum>>that(units).has().allOf(SomeEnum.B, SomeEnum.D).inOrder(); + ASSERT.that(units).has().exactly(SomeEnum.B, SomeEnum.D).inOrder(); Set<SomeEnum> copy = SerializableTester.reserializeAndAssert(units); assertTrue(copy instanceof ImmutableEnumSet); } public void testImmutableEnumSet_fromIterable() { - ImmutableSet<SomeEnum> none = Sets.immutableEnumSet(MinimalIterable.<SomeEnum>of()); - ASSERT.<SomeEnum, ImmutableSet<SomeEnum>>that(none).isEmpty(); + ImmutableSet<SomeEnum> none + = Sets.immutableEnumSet(MinimalIterable.<SomeEnum>of()); + ASSERT.that(none).isEmpty(); - ImmutableSet<SomeEnum> one = Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.B)); - ASSERT.<SomeEnum, ImmutableSet<SomeEnum>>that(one).has().item(SomeEnum.B); + ImmutableSet<SomeEnum> one + = Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.B)); + ASSERT.that(one).has().item(SomeEnum.B); - ImmutableSet<SomeEnum> two = Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.D, SomeEnum.B)); - ASSERT.<SomeEnum, ImmutableSet<SomeEnum>>that(two).has().allOf(SomeEnum.B, SomeEnum.D) - .inOrder(); + ImmutableSet<SomeEnum> two + = Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.D, SomeEnum.B)); + ASSERT.that(two).has().exactly(SomeEnum.B, SomeEnum.D).inOrder(); } @GwtIncompatible("java serialization not supported in GWT.") - public void testImmutableEnumSet_deserializationMakesDefensiveCopy() throws Exception { - ImmutableSet<SomeEnum> original = Sets.immutableEnumSet(SomeEnum.A, SomeEnum.B); + public void testImmutableEnumSet_deserializationMakesDefensiveCopy() + throws Exception { + ImmutableSet<SomeEnum> original = + Sets.immutableEnumSet(SomeEnum.A, SomeEnum.B); int handleOffset = 6; byte[] serializedForm = serializeWithBackReference(original, handleOffset); - ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(serializedForm)); + ObjectInputStream in = + new ObjectInputStream(new ByteArrayInputStream(serializedForm)); ImmutableSet<?> deserialized = (ImmutableSet<?>) in.readObject(); EnumSet<?> delegate = (EnumSet<?>) in.readObject(); @@ -284,8 +314,8 @@ public class SetsTest extends TestCase { } @GwtIncompatible("java serialization not supported in GWT.") - private static byte[] serializeWithBackReference(Object original, int handleOffset) - throws IOException { + private static byte[] serializeWithBackReference( + Object original, int handleOffset) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); @@ -311,7 +341,8 @@ public class SetsTest extends TestCase { } public void testNewEnumSet_empty() { - EnumSet<SomeEnum> copy = newEnumSet(Collections.<SomeEnum>emptySet(), SomeEnum.class); + EnumSet<SomeEnum> copy = + newEnumSet(Collections.<SomeEnum>emptySet(), SomeEnum.class); assertEquals(EnumSet.noneOf(SomeEnum.class), copy); } @@ -365,6 +396,16 @@ public class SetsTest extends TestCase { verifySetContents(set, SOME_COLLECTION); } + public void testNewConcurrentHashSetEmpty() { + Set<Integer> set = Sets.newConcurrentHashSet(); + verifySetContents(set, EMPTY_COLLECTION); + } + + public void testNewConcurrentHashSetFromCollection() { + Set<Integer> set = Sets.newConcurrentHashSet(SOME_COLLECTION); + verifySetContents(set, SOME_COLLECTION); + } + public void testNewLinkedHashSetEmpty() { LinkedHashSet<Integer> set = Sets.newLinkedHashSet(); verifyLinkedHashSetContents(set, EMPTY_COLLECTION); @@ -376,7 +417,8 @@ public class SetsTest extends TestCase { } public void testNewLinkedHashSetFromIterable() { - LinkedHashSet<Integer> set = Sets.newLinkedHashSet(new Iterable<Integer>() { + LinkedHashSet<Integer> set = Sets.newLinkedHashSet(new Iterable<Integer>() + { @Override public Iterator<Integer> iterator() { return LONGER_LIST.iterator(); @@ -405,8 +447,7 @@ public class SetsTest extends TestCase { assertTrue(set.isEmpty()); set.add(new Derived("foo")); set.add(new Derived("bar")); - ASSERT.<Derived, TreeSet<Derived>>that(set).has().allOf(new Derived("bar"), new Derived("foo")) - .inOrder(); + ASSERT.that(set).has().exactly(new Derived("bar"), new Derived("foo")).inOrder(); } public void testNewTreeSetEmptyNonGeneric() { @@ -414,8 +455,8 @@ public class SetsTest extends TestCase { assertTrue(set.isEmpty()); set.add(new LegacyComparable("foo")); set.add(new LegacyComparable("bar")); - ASSERT.<LegacyComparable, TreeSet<LegacyComparable>>that(set).has() - .allOf(new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder(); + ASSERT.that(set).has() + .exactly(new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder(); } public void testNewTreeSetFromCollection() { @@ -429,18 +470,19 @@ public class SetsTest extends TestCase { } public void testNewTreeSetFromIterableDerived() { - Iterable<Derived> iterable = Arrays.asList(new Derived("foo"), new Derived("bar")); + Iterable<Derived> iterable = + Arrays.asList(new Derived("foo"), new Derived("bar")); TreeSet<Derived> set = Sets.newTreeSet(iterable); - ASSERT.<Derived, TreeSet<Derived>>that(set).has().allOf(new Derived("bar"), new Derived("foo")) - .inOrder(); + ASSERT.that(set).has().exactly( + new Derived("bar"), new Derived("foo")).inOrder(); } public void testNewTreeSetFromIterableNonGeneric() { - Iterable<LegacyComparable> iterable = Arrays.asList(new LegacyComparable("foo"), - new LegacyComparable("bar")); + Iterable<LegacyComparable> iterable = + Arrays.asList(new LegacyComparable("foo"), new LegacyComparable("bar")); TreeSet<LegacyComparable> set = Sets.newTreeSet(iterable); - ASSERT.<LegacyComparable, TreeSet<LegacyComparable>>that(set).has() - .allOf(new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder(); + ASSERT.that(set).has().exactly( + new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder(); } public void testNewTreeSetEmptyWithComparator() { @@ -523,7 +565,8 @@ public class SetsTest extends TestCase { @GwtIncompatible("NullPointerTester") public void testNullPointerExceptions() { - new NullPointerTester().setDefault(Enum.class, SomeEnum.A) + new NullPointerTester() + .setDefault(Enum.class, SomeEnum.A) .setDefault(Class.class, SomeEnum.class) // for newEnumSet .testAllPublicStaticMethods(Sets.class); } @@ -536,10 +579,11 @@ public class SetsTest extends TestCase { @GwtIncompatible("SerializableTester") public void testNewSetFromMapSerialization() { - Set<Integer> set = Sets.newSetFromMap(new LinkedHashMap<Integer, Boolean>()); + Set<Integer> set = + Sets.newSetFromMap(new LinkedHashMap<Integer, Boolean>()); set.addAll(SOME_COLLECTION); Set<Integer> copy = SerializableTester.reserializeAndAssert(set); - ASSERT.<Integer, Set<Integer>>that(copy).has().allOf(0, 1).inOrder(); + ASSERT.that(copy).has().exactly(0, 1).inOrder(); } public void testNewSetFromMapIllegal() { @@ -557,39 +601,33 @@ public class SetsTest extends TestCase { /** * The 0-ary cartesian product is a single empty list. */ - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_zeroary() { - ASSERT.<List<Object>, Set<List<Object>>>that(Sets.cartesianProduct()).has().allOf(list()); + ASSERT.that(Sets.cartesianProduct()).has().exactly(list()); } /** * A unary cartesian product is one list of size 1 for each element in the * input set. */ - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_unary() { - ASSERT.<List<Integer>, Collection<List<Integer>>>that(Sets.cartesianProduct(set(1, 2))).has() - .allOf(list(1), list(2)); + ASSERT.that(Sets.cartesianProduct(set(1, 2))).has().exactly(list(1), list(2)); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_binary0x0() { Set<Integer> mt = emptySet(); assertEmpty(Sets.cartesianProduct(mt, mt)); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_binary0x1() { Set<Integer> mt = emptySet(); assertEmpty(Sets.cartesianProduct(mt, set(1))); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_binary1x0() { Set<Integer> mt = emptySet(); assertEmpty(Sets.cartesianProduct(set(1), mt)); @@ -601,41 +639,31 @@ public class SetsTest extends TestCase { assertFalse(set.iterator().hasNext()); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_binary1x1() { - ASSERT.<List<Integer>, Collection<List<Integer>>>that(Sets.cartesianProduct(set(1), set(2))) - .has().item(list(1, 2)); + ASSERT.that(Sets.cartesianProduct(set(1), set(2))).has().item(list(1, 2)); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_binary1x2() { - ASSERT.<List<Integer>, Collection<List<Integer>>>that(Sets.cartesianProduct(set(1), set(2, 3))) - .has().allOf(list(1, 2), list(1, 3)).inOrder(); + ASSERT.that(Sets.cartesianProduct(set(1), set(2, 3))) + .has().exactly(list(1, 2), list(1, 3)).inOrder(); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_binary2x2() { - ASSERT - .<List<Integer>, Collection<List<Integer>>>that(Sets.cartesianProduct(set(1, 2), set(3, 4))) - .has().allOf(list(1, 3), list(1, 4), list(2, 3), list(2, 4)).inOrder(); + ASSERT.that(Sets.cartesianProduct(set(1, 2), set(3, 4))) + .has().exactly(list(1, 3), list(1, 4), list(2, 3), list(2, 4)).inOrder(); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_2x2x2() { - ASSERT - .<List<Integer>, Collection<List<Integer>>>that( - Sets.cartesianProduct(set(0, 1), set(0, 1), set(0, 1))) - .has() - .allOf(list(0, 0, 0), list(0, 0, 1), list(0, 1, 0), list(0, 1, 1), list(1, 0, 0), - list(1, 0, 1), list(1, 1, 0), list(1, 1, 1)).inOrder(); + ASSERT.that(Sets.cartesianProduct(set(0, 1), set(0, 1), set(0, 1))).has().exactly( + list(0, 0, 0), list(0, 0, 1), list(0, 1, 0), list(0, 1, 1), + list(1, 0, 0), list(1, 0, 1), list(1, 1, 0), list(1, 1, 1)).inOrder(); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_contains() { Set<List<Integer>> actual = Sets.cartesianProduct(set(1, 2), set(3, 4)); assertTrue(actual.contains(list(1, 3))); @@ -645,8 +673,7 @@ public class SetsTest extends TestCase { assertFalse(actual.contains(list(3, 1))); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_unrelatedTypes() { Set<Integer> x = set(1, 2); Set<String> y = set("3", "4"); @@ -656,22 +683,20 @@ public class SetsTest extends TestCase { List<Object> exp3 = list((Object) 2, "3"); List<Object> exp4 = list((Object) 2, "4"); - ASSERT.<List<Object>, Set<List<Object>>>that(Sets.<Object>cartesianProduct(x, y)).has() - .allOf(exp1, exp2, exp3, exp4).inOrder(); + ASSERT.that(Sets.<Object>cartesianProduct(x, y)) + .has().exactly(exp1, exp2, exp3, exp4).inOrder(); } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProductTooBig() { - Set<Integer> set = Range.closed(0, 10000).asSet(DiscreteDomain.integers()); + Set<Integer> set = ContiguousSet.create(Range.closed(0, 10000), DiscreteDomain.integers()); try { Sets.cartesianProduct(set, set, set, set, set); fail("Expected IAE"); } catch (IllegalArgumentException expected) {} } - @SuppressWarnings("unchecked") - // varargs! + @SuppressWarnings("unchecked") // varargs! public void testCartesianProduct_hashCode() { // Run through the same cartesian products we tested above @@ -690,11 +715,12 @@ public class SetsTest extends TestCase { checkHashCode(Sets.cartesianProduct(set(num), set(1))); checkHashCode(Sets.cartesianProduct(set(1), set(2, num))); checkHashCode(Sets.cartesianProduct(set(1, num), set(2, num - 1))); - checkHashCode(Sets.cartesianProduct(set(1, num), set(2, num - 1), set(3, num + 1))); + checkHashCode(Sets.cartesianProduct( + set(1, num), set(2, num - 1), set(3, num + 1))); // a bigger one - checkHashCode(Sets.cartesianProduct(set(1, num, num + 1), set(2), set(3, num + 2), - set(4, 5, 6, 7, 8))); + checkHashCode(Sets.cartesianProduct( + set(1, num, num + 1), set(2), set(3, num + 2), set(4, 5, 6, 7, 8))); } public void testPowerSetEmpty() { @@ -725,8 +751,11 @@ public class SetsTest extends TestCase { almostPowerSet.remove(ImmutableSet.of(1, 2, 3)); almostPowerSet.add(ImmutableSet.of(1, 2, 4)); - new EqualsTester().addEqualityGroup(expected, powerSet) - .addEqualityGroup(ImmutableSet.of(1, 2, 3)).addEqualityGroup(almostPowerSet).testEquals(); + new EqualsTester() + .addEqualityGroup(expected, powerSet) + .addEqualityGroup(ImmutableSet.of(1, 2, 3)) + .addEqualityGroup(almostPowerSet) + .testEquals(); for (Set<Integer> subset : expected) { assertTrue(powerSet.contains(subset)); @@ -754,14 +783,15 @@ public class SetsTest extends TestCase { try { i.next(); fail(); - } catch (NoSuchElementException expected) {} + } catch (NoSuchElementException expected) { + } } @GwtIncompatible("too slow for GWT") public void testPowerSetIteration_iteratorTester() { ImmutableSet<Integer> elements = ImmutableSet.of(1, 2); - Set<Set<Integer>> expected = newHashSet(); + Set<Set<Integer>> expected = newLinkedHashSet(); expected.add(ImmutableSet.<Integer>of()); expected.add(ImmutableSet.of(1)); expected.add(ImmutableSet.of(2)); @@ -769,8 +799,7 @@ public class SetsTest extends TestCase { final Set<Set<Integer>> powerSet = powerSet(elements); new IteratorTester<Set<Integer>>(6, UNMODIFIABLE, expected, KNOWN_ORDER) { - @Override - protected Iterator<Set<Integer>> newTargetIterator() { + @Override protected Iterator<Set<Integer>> newTargetIterator() { return powerSet.iterator(); } }.test(); @@ -779,7 +808,7 @@ public class SetsTest extends TestCase { public void testPowerSetIteration_iteratorTester_fast() { ImmutableSet<Integer> elements = ImmutableSet.of(1, 2); - Set<Set<Integer>> expected = newHashSet(); + Set<Set<Integer>> expected = newLinkedHashSet(); expected.add(ImmutableSet.<Integer>of()); expected.add(ImmutableSet.of(1)); expected.add(ImmutableSet.of(2)); @@ -787,8 +816,7 @@ public class SetsTest extends TestCase { final Set<Set<Integer>> powerSet = powerSet(elements); new IteratorTester<Set<Integer>>(4, UNMODIFIABLE, expected, KNOWN_ORDER) { - @Override - protected Iterator<Set<Integer>> newTargetIterator() { + @Override protected Iterator<Set<Integer>> newTargetIterator() { return powerSet.iterator(); } }.test(); @@ -800,33 +828,41 @@ public class SetsTest extends TestCase { assertPowerSetSize(4, 'a', 'b'); assertPowerSetSize(8, 'a', 'b', 'c'); assertPowerSetSize(16, 'a', 'b', 'd', 'e'); - assertPowerSetSize(1 << 30, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4'); + assertPowerSetSize(1 << 30, + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', + '3', '4'); } public void testPowerSetCreationErrors() { try { - powerSet(newHashSet('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5')); + powerSet(newHashSet('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '1', '2', '3', '4', '5')); fail(); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } try { powerSet(singleton(null)); fail(); - } catch (NullPointerException expected) {} + } catch (NullPointerException expected) { + } } public void testPowerSetEqualsAndHashCode_verifyAgainstHashSet() { - ImmutableList<Integer> allElements = ImmutableList.of(4233352, 3284593, 3794208, 3849533, - 4013967, 2902658, 1886275, 2131109, 985872, 1843868); + ImmutableList<Integer> allElements = ImmutableList.of(4233352, 3284593, + 3794208, 3849533, 4013967, 2902658, 1886275, 2131109, 985872, 1843868); for (int i = 0; i < allElements.size(); i++) { Set<Integer> elements = newHashSet(allElements.subList(0, i)); Set<Set<Integer>> powerSet1 = powerSet(elements); Set<Set<Integer>> powerSet2 = powerSet(elements); - new EqualsTester().addEqualityGroup(powerSet1, powerSet2, toHashSets(powerSet1)) - .addEqualityGroup(ImmutableSet.of()).addEqualityGroup(ImmutableSet.of(9999999)) - .addEqualityGroup("notASet").testEquals(); + new EqualsTester() + .addEqualityGroup(powerSet1, powerSet2, toHashSets(powerSet1)) + .addEqualityGroup(ImmutableSet.of()) + .addEqualityGroup(ImmutableSet.of(9999999)) + .addEqualityGroup("notASet") + .testEquals(); assertEquals(toHashSets(powerSet1).hashCode(), powerSet1.hashCode()); } } @@ -836,12 +872,12 @@ public class SetsTest extends TestCase { * is correct under our {@code hashCode} implementation. */ public void testPowerSetHashCode_inputHashCodeTimesTooFarValueIsZero() { - Set<Object> sumToEighthMaxIntElements = newHashSet(objectWithHashCode(1 << 29), - objectWithHashCode(0)); + Set<Object> sumToEighthMaxIntElements = + newHashSet(objectWithHashCode(1 << 29), objectWithHashCode(0)); assertPowerSetHashCode(1 << 30, sumToEighthMaxIntElements); - Set<Object> sumToQuarterMaxIntElements = newHashSet(objectWithHashCode(1 << 30), - objectWithHashCode(0)); + Set<Object> sumToQuarterMaxIntElements = + newHashSet(objectWithHashCode(1 << 30), objectWithHashCode(0)); assertPowerSetHashCode(1 << 31, sumToQuarterMaxIntElements); } @@ -851,11 +887,14 @@ public class SetsTest extends TestCase { Set<Set<Set<Object>>> two = powerSet(one); Set<Set<Set<Set<Object>>>> four = powerSet(two); Set<Set<Set<Set<Set<Object>>>>> sixteen = powerSet(four); - Set<Set<Set<Set<Set<Set<Object>>>>>> sixtyFiveThousandish = powerSet(sixteen); + Set<Set<Set<Set<Set<Set<Object>>>>>> sixtyFiveThousandish = + powerSet(sixteen); assertEquals(1 << 16, sixtyFiveThousandish.size()); - assertTrue(powerSet(makeSetOfZeroToTwentyNine()).contains(makeSetOfZeroToTwentyNine())); - assertFalse(powerSet(makeSetOfZeroToTwentyNine()).contains(ImmutableSet.of(30))); + assertTrue(powerSet(makeSetOfZeroToTwentyNine()) + .contains(makeSetOfZeroToTwentyNine())); + assertFalse(powerSet(makeSetOfZeroToTwentyNine()) + .contains(ImmutableSet.of(30))); } private static Set<Integer> makeSetOfZeroToTwentyNine() { @@ -877,8 +916,7 @@ public class SetsTest extends TestCase { private static Object objectWithHashCode(final int hashCode) { return new Object() { - @Override - public int hashCode() { + @Override public int hashCode() { return hashCode; } }; @@ -910,9 +948,10 @@ public class SetsTest extends TestCase { * collection. Also verifies that the ordering in the set is the same * as the ordering of the given contents. */ - private static <E> void verifyLinkedHashSetContents(LinkedHashSet<E> set, Collection<E> contents) { - assertEquals("LinkedHashSet should have preserved order for iteration", new ArrayList<E>(set), - new ArrayList<E>(contents)); + private static <E> void verifyLinkedHashSetContents( + LinkedHashSet<E> set, Collection<E> contents) { + assertEquals("LinkedHashSet should have preserved order for iteration", + new ArrayList<E>(set), new ArrayList<E>(contents)); verifySetContents(set, contents); } @@ -922,7 +961,8 @@ public class SetsTest extends TestCase { * given iterable. Also verifies that the comparator is the same as the * given comparator. */ - private static <E> void verifySortedSetContents(SortedSet<E> set, Iterable<E> iterable, + private static <E> void verifySortedSetContents( + SortedSet<E> set, Iterable<E> iterable, @Nullable Comparator<E> comparator) { assertSame(comparator, set.comparator()); verifySetContents(set, iterable); @@ -955,13 +995,11 @@ public class SetsTest extends TestCase { this.s = s; } - @Override - public int hashCode() { // delegate to 's' + @Override public int hashCode() { // delegate to 's' return s.hashCode(); } - @Override - public boolean equals(Object other) { + @Override public boolean equals(Object other) { if (other == null) { return false; } else if (other instanceof Base) { @@ -994,21 +1032,24 @@ public class SetsTest extends TestCase { try { unmod.add(4); fail("UnsupportedOperationException expected"); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } try { unmod.remove(4); fail("UnsupportedOperationException expected"); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } try { unmod.addAll(Collections.singleton(4)); fail("UnsupportedOperationException expected"); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } try { Iterator<Integer> iterator = unmod.iterator(); iterator.next(); iterator.remove(); fail("UnsupportedOperationException expected"); - } catch (UnsupportedOperationException expected) {} + } catch (UnsupportedOperationException expected) { + } } - } diff --git a/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java b/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java index 60eaec8..cd6b6bf 100644 --- a/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java +++ b/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java @@ -17,8 +17,18 @@ package com.google.common.collect; import static com.google.common.base.Preconditions.checkArgument; import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; +import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; +import com.google.common.collect.testing.google.TestStringMultisetGenerator; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; import java.io.Serializable; +import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -32,11 +42,25 @@ import javax.annotation.Nullable; * @author Louis Wasserman */ @SuppressWarnings("serial") // No serialization is used in this test -@GwtCompatible -public class SimpleAbstractMultisetTest extends AbstractMultisetTest { - - @Override protected <E> Multiset<E> create() { - return new SimpleAbstractMultiset<E>(); +@GwtCompatible(emulated = true) +public class SimpleAbstractMultisetTest extends TestCase { + @GwtIncompatible("suite") + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTestSuite(SimpleAbstractMultisetTest.class); + suite.addTest(MultisetTestSuiteBuilder.using(new TestStringMultisetGenerator() { + @Override + protected Multiset<String> create(String[] elements) { + Multiset<String> ms = new NoRemoveMultiset<String>(); + Collections.addAll(ms, elements); + return ms; + } + }) + .named("NoRemoveMultiset") + .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, + CollectionFeature.SUPPORTS_ADD) + .createTestSuite()); + return suite; } public void testFastAddAllMultiset() { @@ -85,7 +109,7 @@ public class SimpleAbstractMultisetTest extends AbstractMultisetTest { @Override Iterator<Entry<E>> entryIterator() { final Iterator<Map.Entry<E, Integer>> backingEntries = backingMap.entrySet().iterator(); - return new Iterator<Multiset.Entry<E>>() { + return new UnmodifiableIterator<Multiset.Entry<E>>() { @Override public boolean hasNext() { return backingEntries.hasNext(); @@ -107,11 +131,6 @@ public class SimpleAbstractMultisetTest extends AbstractMultisetTest { } }; } - - @Override - public void remove() { - backingEntries.remove(); - } }; } @@ -120,20 +139,4 @@ public class SimpleAbstractMultisetTest extends AbstractMultisetTest { return backingMap.size(); } } - - private static class SimpleAbstractMultiset<E> extends NoRemoveMultiset<E> { - @SuppressWarnings("unchecked") - @Override public int remove(@Nullable Object element, int occurrences) { - checkArgument(occurrences >= 0); - Integer count = backingMap.get(element); - if (count == null) { - return 0; - } else if (count > occurrences) { - backingMap.put((E) element, count - occurrences); - return count; - } else { - return backingMap.remove(element); - } - } - } } diff --git a/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java b/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java index a07b199..8fba129 100644 --- a/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java +++ b/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java @@ -16,11 +16,12 @@ package com.google.common.collect; +import static org.truth0.Truth.ASSERT; + import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Objects; import com.google.common.testing.EqualsTester; -import com.google.common.testing.FluentAsserts; /** * Tests {@link SingletonImmutableTable}. @@ -70,7 +71,7 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest { public void testEqualsObject() { new EqualsTester() .addEqualityGroup(testTable, HashBasedTable.create(testTable)) - .addEqualityGroup(EmptyImmutableTable.INSTANCE, HashBasedTable.create()) + .addEqualityGroup(ImmutableTable.of(), HashBasedTable.create()) .addEqualityGroup(HashBasedTable.create(ImmutableTable.of('A', 2, ""))) .testEquals(); } @@ -125,7 +126,7 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest { } public void testValues() { - FluentAsserts.assertThat(testTable.values()).has().item("blah"); + ASSERT.that(testTable.values()).has().item("blah"); } @Override Iterable<ImmutableTable<Character, Integer, String>> getTestInstances() { diff --git a/guava-tests/test/com/google/common/collect/SortedIterablesTest.java b/guava-tests/test/com/google/common/collect/SortedIterablesTest.java index b4340ea..d3a50f8 100644 --- a/guava-tests/test/com/google/common/collect/SortedIterablesTest.java +++ b/guava-tests/test/com/google/common/collect/SortedIterablesTest.java @@ -16,10 +16,10 @@ package com.google.common.collect; import com.google.common.annotations.GwtCompatible; -import java.util.SortedSet; - import junit.framework.TestCase; +import java.util.SortedSet; + /** * Unit tests for {@code SortedIterables}. * diff --git a/guava-tests/test/com/google/common/collect/SortedListsTest.java b/guava-tests/test/com/google/common/collect/SortedListsTest.java index 96535cb..02b259a 100644 --- a/guava-tests/test/com/google/common/collect/SortedListsTest.java +++ b/guava-tests/test/com/google/common/collect/SortedListsTest.java @@ -20,10 +20,10 @@ import com.google.common.collect.SortedLists.KeyAbsentBehavior; import com.google.common.collect.SortedLists.KeyPresentBehavior; import com.google.common.testing.NullPointerTester; -import java.util.List; - import junit.framework.TestCase; +import java.util.List; + /** * Tests for SortedLists. * diff --git a/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java b/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java index e7fa996..878f414 100644 --- a/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java +++ b/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java @@ -27,11 +27,11 @@ import com.google.common.collect.testing.google.BiMapInverseTester; import com.google.common.collect.testing.google.BiMapTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringBiMapGenerator; +import junit.framework.TestSuite; + import java.util.Map.Entry; import java.util.Set; -import junit.framework.TestSuite; - /** * Tests for {@code Synchronized#biMap}. * @@ -44,16 +44,20 @@ public class SynchronizedBiMapTest extends SynchronizedMapTest { suite.addTest(BiMapTestSuiteBuilder.using(new SynchTestingBiMapGenerator()) .named("Synchronized.biMap[TestBiMap]") .withFeatures(CollectionSize.ANY, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, MapFeature.REJECTS_DUPLICATES_AT_CREATION) .createTestSuite()); suite.addTest(BiMapTestSuiteBuilder.using(new SynchronizedHashBiMapGenerator()) .named("synchronizedBiMap[HashBiMap]") .withFeatures(CollectionSize.ANY, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, MapFeature.REJECTS_DUPLICATES_AT_CREATION, CollectionFeature.SERIALIZABLE) diff --git a/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java b/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java index b7b2077..4df3e5f 100644 --- a/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java +++ b/guava-tests/test/com/google/common/collect/SynchronizedMapTest.java @@ -22,14 +22,14 @@ import com.google.common.collect.Synchronized.SynchronizedCollection; import com.google.common.collect.Synchronized.SynchronizedSet; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; -import junit.framework.TestCase; - /** * Tests for {@code Synchronized#map}. * diff --git a/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java b/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java index fb42524..2b85d7d 100644 --- a/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java +++ b/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java @@ -18,36 +18,65 @@ package com.google.common.collect; import static org.truth0.Truth.ASSERT; +import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.features.MapFeature; +import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder; +import com.google.common.collect.testing.google.TestStringSetMultimapGenerator; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.io.Serializable; import java.util.Arrays; import java.util.Collection; import java.util.Map; +import java.util.Map.Entry; import java.util.RandomAccess; import java.util.Set; import javax.annotation.Nullable; -import org.truth0.subjects.CollectionSubject; - /** * Tests for {@code Synchronized#multimap}. * * @author Mike Bostock */ -public class SynchronizedMultimapTest extends AbstractSetMultimapTest { - - @Override protected Multimap<String, Integer> create() { - TestMultimap<String, Integer> inner = new TestMultimap<String, Integer>(); - Multimap<String, Integer> outer = Synchronized.multimap(inner, inner.mutex); - return outer; +public class SynchronizedMultimapTest extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTestSuite(SynchronizedMultimapTest.class); + suite.addTest(SetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() { + @Override + protected SetMultimap<String, String> create(Entry<String, String>[] entries) { + TestMultimap<String, String> inner = new TestMultimap<String, String>(); + SetMultimap<String, String> outer = Synchronized.setMultimap(inner, inner.mutex); + for (Entry<String, String> entry : entries) { + outer.put(entry.getKey(), entry.getValue()); + } + return outer; + } + }) + .named("Synchronized.setMultimap") + .withFeatures(MapFeature.GENERAL_PURPOSE, + CollectionSize.ANY, + CollectionFeature.SERIALIZABLE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, + MapFeature.ALLOWS_NULL_KEYS, + MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES) + .createTestSuite()); + return suite; } - private static final class TestMultimap<K, V> extends ForwardingMultimap<K, V> + private static final class TestMultimap<K, V> extends ForwardingSetMultimap<K, V> implements Serializable { - final Multimap<K, V> delegate = HashMultimap.create(); + final SetMultimap<K, V> delegate = HashMultimap.create(); public final Object mutex = new Integer(1); // something Serializable - @Override protected Multimap<K, V> delegate() { + @Override protected SetMultimap<K, V> delegate() { return delegate; } @@ -92,7 +121,7 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest { return super.containsEntry(key, value); } - @Override public Collection<V> get(@Nullable K key) { + @Override public Set<V> get(@Nullable K key) { assertTrue(Thread.holdsLock(mutex)); /* TODO: verify that the Collection is also synchronized? */ return super.get(key); @@ -114,7 +143,7 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest { return super.putAll(map); } - @Override public Collection<V> replaceValues(@Nullable K key, + @Override public Set<V> replaceValues(@Nullable K key, Iterable<? extends V> values) { assertTrue(Thread.holdsLock(mutex)); return super.replaceValues(key, values); @@ -126,7 +155,7 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest { return super.remove(key, value); } - @Override public Collection<V> removeAll(@Nullable Object key) { + @Override public Set<V> removeAll(@Nullable Object key) { assertTrue(Thread.holdsLock(mutex)); return super.removeAll(key); } @@ -154,7 +183,7 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest { return super.values(); } - @Override public Collection<Map.Entry<K, V>> entries() { + @Override public Set<Map.Entry<K, V>> entries() { assertTrue(Thread.holdsLock(mutex)); /* TODO: verify that the Collection is also synchronized? */ return super.entries(); @@ -175,11 +204,11 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest { ArrayListMultimap.<String, Integer>create()); multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1)); multimap.putAll("bar", Arrays.asList(1, 2, 3, 1)); - assertThat(multimap.removeAll("foo")).has().allOf(3, -1, 2, 4, 1).inOrder(); + ASSERT.that(multimap.removeAll("foo")).has().exactly(3, -1, 2, 4, 1).inOrder(); assertFalse(multimap.containsKey("foo")); - assertThat(multimap.replaceValues("bar", Arrays.asList(6, 5))) - .has().allOf(1, 2, 3, 1).inOrder(); - assertThat(multimap.get("bar")).has().allOf(6, 5).inOrder(); + ASSERT.that(multimap.replaceValues("bar", Arrays.asList(6, 5))) + .has().exactly(1, 2, 3, 1).inOrder(); + ASSERT.that(multimap.get("bar")).has().exactly(6, 5).inOrder(); } public void testSynchronizedSortedSetMultimap() { @@ -188,11 +217,11 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest { TreeMultimap.<String, Integer>create()); multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1)); multimap.putAll("bar", Arrays.asList(1, 2, 3, 1)); - assertThat(multimap.removeAll("foo")).has().allOf(-1, 1, 2, 3, 4).inOrder(); + ASSERT.that(multimap.removeAll("foo")).has().exactly(-1, 1, 2, 3, 4).inOrder(); assertFalse(multimap.containsKey("foo")); - assertThat(multimap.replaceValues("bar", Arrays.asList(6, 5))) - .has().allOf(1, 2, 3).inOrder(); - assertThat(multimap.get("bar")).has().allOf(5, 6).inOrder(); + ASSERT.that(multimap.replaceValues("bar", Arrays.asList(6, 5))) + .has().exactly(1, 2, 3).inOrder(); + ASSERT.that(multimap.get("bar")).has().exactly(5, 6).inOrder(); } public void testSynchronizedArrayListMultimapRandomAccess() { @@ -214,10 +243,4 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest { assertFalse(multimap.get("foo") instanceof RandomAccess); assertFalse(multimap.get("bar") instanceof RandomAccess); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java b/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java index 7916725..4cce708 100644 --- a/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java +++ b/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java @@ -16,12 +16,12 @@ package com.google.common.collect; +import junit.framework.TestCase; + import java.util.Collection; import java.util.Iterator; import java.util.Queue; -import junit.framework.TestCase; - /** * Tests for {@link Synchronized#queue} and {@link Queues#synchronizedQueue}. * diff --git a/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java b/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java index b14da0a..0c4274e 100644 --- a/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java +++ b/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java @@ -18,10 +18,17 @@ package com.google.common.collect; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.testing.SerializableTester; +import com.google.common.collect.testing.SetTestSuiteBuilder; +import com.google.common.collect.testing.TestStringSetGenerator; +import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.CollectionSize; + +import junit.framework.Test; +import junit.framework.TestCase; import java.io.Serializable; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -32,21 +39,26 @@ import javax.annotation.Nullable; * * @author Mike Bostock */ -public class SynchronizedSetTest extends AbstractCollectionTest { - public final Object mutex = new Integer(1); // something Serializable - - @Override protected <E> Set<E> create() { - TestSet<E> inner = new TestSet<E>(new HashSet<E>(), mutex); - Set<E> outer = Synchronized.set(inner, inner.mutex); - return outer; - } - - @Override public void testNullPointerExceptions() { - /* Skip this test, as SynchronizedSet is not a public class. */ - } - - public void testSerialization() { - SerializableTester.reserializeAndAssert(create()); +public class SynchronizedSetTest extends TestCase { + + public static final Object MUTEX = new Integer(1); // something Serializable + + public static Test suite() { + return SetTestSuiteBuilder.using(new TestStringSetGenerator() { + @Override + protected Set<String> create(String[] elements) { + TestSet<String> inner = new TestSet<String>(new HashSet<String>(), MUTEX); + Set<String> outer = Synchronized.set(inner, inner.mutex); + Collections.addAll(outer, elements); + return outer; + } + }) + .named("Synchronized.set") + .withFeatures(CollectionFeature.GENERAL_PURPOSE, + CollectionFeature.ALLOWS_NULL_VALUES, + CollectionSize.ANY, + CollectionFeature.SERIALIZABLE) + .createTestSuite(); } static class TestSet<E> extends ForwardingSet<E> implements Serializable { diff --git a/guava-tests/test/com/google/common/collect/TableCollectionTest.java b/guava-tests/test/com/google/common/collect/TableCollectionTest.java index e52e033..38d9337 100644 --- a/guava-tests/test/com/google/common/collect/TableCollectionTest.java +++ b/guava-tests/test/com/google/common/collect/TableCollectionTest.java @@ -17,8 +17,6 @@ package com.google.common.collect; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod; -import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -29,13 +27,19 @@ import com.google.common.collect.testing.CollectionTestSuiteBuilder; import com.google.common.collect.testing.MapInterfaceTest; import com.google.common.collect.testing.SampleElements; import com.google.common.collect.testing.SetTestSuiteBuilder; +import com.google.common.collect.testing.SortedSetTestSuiteBuilder; import com.google.common.collect.testing.TestSetGenerator; import com.google.common.collect.testing.TestStringCollectionGenerator; import com.google.common.collect.testing.TestStringSetGenerator; +import com.google.common.collect.testing.TestStringSortedSetGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.Feature; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -43,10 +47,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import java.util.SortedSet; /** * Collection tests for {@link Table} implementations. @@ -142,11 +143,12 @@ public class TableCollectionTest extends TestCase { }) .named("HashBasedTable.rowKeySet") .withFeatures(COLLECTION_FEATURES_REMOVE) + .withFeatures(CollectionFeature.SUPPORTS_ITERATOR_REMOVE) .createTestSuite()); - suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { - @Override protected Set<String> create(String[] elements) { - Table<String, Integer, Character> table = TreeBasedTable.create(); + suite.addTest(SortedSetTestSuiteBuilder.using(new TestStringSortedSetGenerator() { + @Override protected SortedSet<String> create(String[] elements) { + TreeBasedTable<String, Integer, Character> table = TreeBasedTable.create(); populateForRowKeySet(table, elements); return table.rowKeySet(); } @@ -158,61 +160,7 @@ public class TableCollectionTest extends TestCase { }) .named("TreeBasedTable.rowKeySet") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) - .createTestSuite()); - - suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { - @Override protected Set<String> create(String[] elements) { - TreeBasedTable<String, Integer, Character> table - = TreeBasedTable.create(); - populateForRowKeySet(table, elements); - table.put("z", 1, 'a'); - return table.rowKeySet().headSet("x"); - } - - @Override public List<String> order(List<String> insertionOrder) { - Collections.sort(insertionOrder); - return insertionOrder; - } - }) - .named("TreeBasedTable.rowKeySet.headSet") - .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) - .createTestSuite()); - - suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { - @Override protected Set<String> create(String[] elements) { - TreeBasedTable<String, Integer, Character> table - = TreeBasedTable.create(); - populateForRowKeySet(table, elements); - table.put("\0", 1, 'a'); - return table.rowKeySet().tailSet("a"); - } - - @Override public List<String> order(List<String> insertionOrder) { - Collections.sort(insertionOrder); - return insertionOrder; - } - }) - .named("TreeBasedTable.rowKeySet.tailSet") - .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) - .createTestSuite()); - - suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { - @Override protected Set<String> create(String[] elements) { - TreeBasedTable<String, Integer, Character> table - = TreeBasedTable.create(); - populateForRowKeySet(table, elements); - table.put("\0", 1, 'a'); - table.put("z", 1, 'a'); - return table.rowKeySet().subSet("a", "x"); - } - - @Override public List<String> order(List<String> insertionOrder) { - Collections.sort(insertionOrder); - return insertionOrder; - } - }) - .named("TreeBasedTable.rowKeySet.subSet") - .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) + .withFeatures(CollectionFeature.SUPPORTS_ITERATOR_REMOVE) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @@ -267,7 +215,6 @@ public class TableCollectionTest extends TestCase { }) .named("HashBasedTable.columnKeySet") .withFeatures(COLLECTION_FEATURES_REMOVE) - .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @@ -284,7 +231,6 @@ public class TableCollectionTest extends TestCase { }) .named("TreeBasedTable.columnKeySet") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @@ -296,7 +242,6 @@ public class TableCollectionTest extends TestCase { }) .named("unmodifiableTable[HashBasedTable].columnKeySet") .withFeatures(COLLECTION_FEATURES) - .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @@ -313,7 +258,6 @@ public class TableCollectionTest extends TestCase { }) .named("unmodifiableRowSortedTable[TreeBasedTable].columnKeySet") .withFeatures(COLLECTION_FEATURES_ORDER) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( @@ -347,6 +291,7 @@ public class TableCollectionTest extends TestCase { }) .named("HashBasedTable.values") .withFeatures(COLLECTION_FEATURES_REMOVE) + .withFeatures(CollectionFeature.SUPPORTS_ITERATOR_REMOVE) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( @@ -361,6 +306,7 @@ public class TableCollectionTest extends TestCase { }) .named("TreeBasedTable.values") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) + .withFeatures(CollectionFeature.SUPPORTS_ITERATOR_REMOVE) .createTestSuite()); final Function<String, String> removeFirstCharacter @@ -382,6 +328,7 @@ public class TableCollectionTest extends TestCase { }) .named("TransformValues.values") .withFeatures(COLLECTION_FEATURES_REMOVE) + .withFeatures(CollectionFeature.SUPPORTS_ITERATOR_REMOVE) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( @@ -458,7 +405,7 @@ public class TableCollectionTest extends TestCase { } }) .named("HashBasedTable.cellSet") - .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE, + .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS, CollectionFeature.ALLOWS_NULL_QUERIES) .createTestSuite()); @@ -468,7 +415,7 @@ public class TableCollectionTest extends TestCase { } }) .named("TreeBasedTable.cellSet") - .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE, + .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS, CollectionFeature.ALLOWS_NULL_QUERIES) .createTestSuite()); @@ -480,7 +427,7 @@ public class TableCollectionTest extends TestCase { } }) .named("TransposedTable.cellSet") - .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE, + .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS, CollectionFeature.ALLOWS_NULL_QUERIES) .createTestSuite()); @@ -503,7 +450,7 @@ public class TableCollectionTest extends TestCase { }) .named("TransformValues.cellSet") .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES, - CollectionFeature.SUPPORTS_REMOVE) + CollectionFeature.REMOVE_OPERATIONS) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() { @@ -574,7 +521,6 @@ public class TableCollectionTest extends TestCase { }) .named("HashBasedTable.column.keySet") .withFeatures(COLLECTION_FEATURES_REMOVE) - .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @@ -590,7 +536,6 @@ public class TableCollectionTest extends TestCase { }) .named("TreeBasedTable.column.keySet") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @@ -602,7 +547,6 @@ public class TableCollectionTest extends TestCase { }) .named("TransformValues.column.keySet") .withFeatures(COLLECTION_FEATURES_REMOVE) - .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @@ -614,7 +558,6 @@ public class TableCollectionTest extends TestCase { }) .named("unmodifiableTable[HashBasedTable].column.keySet") .withFeatures(COLLECTION_FEATURES) - .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @@ -630,7 +573,6 @@ public class TableCollectionTest extends TestCase { }) .named("unmodifiableRowSortedTable[TreeBasedTable].column.keySet") .withFeatures(COLLECTION_FEATURES_ORDER) - .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); return suite; diff --git a/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java b/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java index 1ea040c..2be612b 100644 --- a/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java +++ b/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java @@ -41,9 +41,10 @@ public class TablesTransformValuesTest extends AbstractTableTest { Object... data) { Table<String, Integer, String> table = HashBasedTable.create(); checkArgument(data.length % 3 == 0); - for (int i = 0; i < data.length; i+= 3) { - String value = (data[i+2] == null) ? null : data[i+2].toString() + "transformed"; - table.put((String) data[i], (Integer) data[i+1], value); + for (int i = 0; i < data.length; i += 3) { + String value = + (data[i + 2] == null) ? null : (data[i + 2] + "transformed"); + table.put((String) data[i], (Integer) data[i + 1], value); } return Tables.transformValues(table, FIRST_CHARACTER); } diff --git a/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java b/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java index d0be710..1e12b17 100644 --- a/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java +++ b/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java @@ -23,11 +23,14 @@ import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.SortedMapInterfaceTest; import com.google.common.collect.testing.SortedMapTestSuiteBuilder; import com.google.common.collect.testing.TestStringSortedMapGenerator; +import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; import com.google.common.testing.SerializableTester; -import java.util.Collection; +import junit.framework.Test; +import junit.framework.TestSuite; + import java.util.Collections; import java.util.Comparator; import java.util.Map; @@ -35,11 +38,6 @@ import java.util.Map.Entry; import java.util.Set; import java.util.SortedMap; -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.truth0.subjects.CollectionSubject; - /** * Test cases for {@link TreeBasedTable}. * @@ -67,7 +65,10 @@ public class TreeBasedTableTest extends AbstractTableTest { } return table.row("b"); } - }).withFeatures(MapFeature.GENERAL_PURPOSE, CollectionSize.ANY) + }).withFeatures( + MapFeature.GENERAL_PURPOSE, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, + CollectionSize.ANY) .named("RowMapTestSuite").createTestSuite()); return suite; } @@ -153,8 +154,8 @@ public class TreeBasedTableTest extends AbstractTableTest { table.put("foo", 12, 'b'); table.put("bar", 5, 'c'); table.put("cat", 8, 'd'); - assertThat(table.rowKeySet()).has().allOf("foo", "cat", "bar").inOrder(); - assertThat(table.row("foo").keySet()).has().allOf(12, 3).inOrder(); + ASSERT.that(table.rowKeySet()).has().exactly("foo", "cat", "bar").inOrder(); + ASSERT.that(table.row("foo").keySet()).has().exactly(12, 3).inOrder(); } public void testCreateCopy() { @@ -165,8 +166,8 @@ public class TreeBasedTableTest extends AbstractTableTest { original.put("bar", 5, 'c'); original.put("cat", 8, 'd'); table = TreeBasedTable.create(original); - assertThat(table.rowKeySet()).has().allOf("foo", "cat", "bar").inOrder(); - assertThat(table.row("foo").keySet()).has().allOf(12, 3).inOrder(); + ASSERT.that(table.rowKeySet()).has().exactly("foo", "cat", "bar").inOrder(); + ASSERT.that(table.row("foo").keySet()).has().exactly(12, 3).inOrder(); assertEquals(original, table); } @@ -448,10 +449,4 @@ public class TreeBasedTableTest extends AbstractTableTest { assertEquals(ImmutableMap.of(5, 'x'), row); assertEquals(ImmutableMap.of(5, 'x'), subRow); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java b/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java index 4ebaeaf..68b4fd9 100644 --- a/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java +++ b/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java @@ -22,21 +22,22 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + +import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.Map; import java.util.SortedSet; -import org.truth0.subjects.CollectionSubject; - /** * Unit tests for {@code TreeMultimap} with explicit comparators. * * @author Jared Levy */ @GwtCompatible(emulated = true) -public class TreeMultimapExplicitTest extends AbstractSetMultimapTest { +public class TreeMultimapExplicitTest extends TestCase { /** * Compare strings lengths, and if the lengths are equal compare the strings. @@ -67,7 +68,7 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest { private static final Comparator<Integer> DECREASING_INT_COMPARATOR = Ordering.<Integer>natural().reverse().nullsFirst(); - @Override protected Multimap<String, Integer> create() { + private SetMultimap<String, Integer> create() { return TreeMultimap.create( StringLength.COMPARATOR, DECREASING_INT_COMPARATOR); } @@ -98,21 +99,27 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest { tree.put("google", 6); tree.put("tree", 0); tree.put("tree", 3); - assertThat(tree.keySet()).has().allOf("tree", "google").inOrder(); - assertThat(tree.get("google")).has().allOf(6, 2).inOrder(); + ASSERT.that(tree.keySet()).has().exactly("tree", "google").inOrder(); + ASSERT.that(tree.get("google")).has().exactly(6, 2).inOrder(); TreeMultimap<String, Integer> copy = TreeMultimap.create(tree); assertEquals(tree, copy); - assertThat(copy.keySet()).has().allOf("google", "tree").inOrder(); - assertThat(copy.get("google")).has().allOf(2, 6).inOrder(); + ASSERT.that(copy.keySet()).has().exactly("google", "tree").inOrder(); + ASSERT.that(copy.get("google")).has().exactly(2, 6).inOrder(); assertEquals(Ordering.natural(), copy.keyComparator()); assertEquals(Ordering.natural(), copy.valueComparator()); assertEquals(Ordering.natural(), copy.get("google").comparator()); } public void testToString() { + Multimap<String, Integer> multimap = create(); + multimap.put("foo", 3); + multimap.put("bar", 1); + multimap.putAll("foo", Arrays.asList(-1, 2, 4)); + multimap.putAll("bar", Arrays.asList(2, 3)); + multimap.put("foo", 1); assertEquals("{bar=[3, 2, 1], foo=[4, 3, 2, 1, -1]}", - createSample().toString()); + multimap.toString()); } public void testGetComparator() { @@ -123,14 +130,14 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest { public void testOrderedGet() { TreeMultimap<String, Integer> multimap = createPopulate(); - assertThat(multimap.get(null)).has().allOf(7, 3, 1).inOrder(); - assertThat(multimap.get("google")).has().allOf(6, 2).inOrder(); - assertThat(multimap.get("tree")).has().allOf(null, 0).inOrder(); + ASSERT.that(multimap.get(null)).has().exactly(7, 3, 1).inOrder(); + ASSERT.that(multimap.get("google")).has().exactly(6, 2).inOrder(); + ASSERT.that(multimap.get("tree")).has().exactly(null, 0).inOrder(); } public void testOrderedKeySet() { TreeMultimap<String, Integer> multimap = createPopulate(); - assertThat(multimap.keySet()).has().allOf(null, "tree", "google").inOrder(); + ASSERT.that(multimap.keySet()).has().exactly(null, "tree", "google").inOrder(); } public void testOrderedAsMapEntries() { @@ -139,18 +146,18 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest { multimap.asMap().entrySet().iterator(); Map.Entry<String, Collection<Integer>> entry = iterator.next(); assertEquals(null, entry.getKey()); - assertThat(entry.getValue()).has().allOf(7, 3, 1); + ASSERT.that(entry.getValue()).has().exactly(7, 3, 1); entry = iterator.next(); assertEquals("tree", entry.getKey()); - assertThat(entry.getValue()).has().allOf(null, 0); + ASSERT.that(entry.getValue()).has().exactly(null, 0); entry = iterator.next(); assertEquals("google", entry.getKey()); - assertThat(entry.getValue()).has().allOf(6, 2); + ASSERT.that(entry.getValue()).has().exactly(6, 2); } public void testOrderedEntries() { TreeMultimap<String, Integer> multimap = createPopulate(); - assertThat(multimap.entries()).has().allOf( + ASSERT.that(multimap.entries()).has().exactly( Maps.immutableEntry((String) null, 7), Maps.immutableEntry((String) null, 3), Maps.immutableEntry((String) null, 1), @@ -162,7 +169,7 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest { public void testOrderedValues() { TreeMultimap<String, Integer> multimap = createPopulate(); - assertThat(multimap.values()).has().allOf(7, 3, 1, null, 0, 6, 2).inOrder(); + ASSERT.that(multimap.values()).has().exactly(7, 3, 1, null, 0, 6, 2).inOrder(); } public void testComparator() { @@ -173,7 +180,12 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest { } public void testMultimapComparators() { - Multimap<String, Integer> multimap = createSample(); + Multimap<String, Integer> multimap = create(); + multimap.put("foo", 3); + multimap.put("bar", 1); + multimap.putAll("foo", Arrays.asList(-1, 2, 4)); + multimap.putAll("bar", Arrays.asList(2, 3)); + multimap.put("foo", 1); TreeMultimap<String, Integer> copy = TreeMultimap.create(StringLength.COMPARATOR, DECREASING_INT_COMPARATOR); copy.putAll(multimap); @@ -199,15 +211,9 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest { TreeMultimap<String, Integer> multimap = createPopulate(); TreeMultimap<String, Integer> copy = SerializableTester.reserializeAndAssert(multimap); - assertThat(copy.values()).has().allOf(7, 3, 1, null, 0, 6, 2).inOrder(); - assertThat(copy.keySet()).has().allOf(null, "tree", "google").inOrder(); + ASSERT.that(copy.values()).has().exactly(7, 3, 1, null, 0, 6, 2).inOrder(); + ASSERT.that(copy.keySet()).has().exactly(null, "tree", "google").inOrder(); assertEquals(multimap.keyComparator(), copy.keyComparator()); assertEquals(multimap.valueComparator(), copy.valueComparator()); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java b/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java index 799478c..f1f52f6 100644 --- a/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java +++ b/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java @@ -16,6 +16,7 @@ package com.google.common.collect; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; @@ -28,12 +29,11 @@ import com.google.common.collect.testing.google.TestStringSetMultimapGenerator; import com.google.common.testing.SerializableTester; import junit.framework.Test; +import junit.framework.TestCase; import junit.framework.TestSuite; -import org.truth0.Truth; -import org.truth0.subjects.CollectionSubject; - import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; @@ -50,7 +50,7 @@ import java.util.SortedSet; * @author Jared Levy */ @GwtCompatible(emulated = true) -public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { +public class TreeMultimapNaturalTest extends TestCase { @GwtIncompatible("suite") public static Test suite() { @@ -84,8 +84,10 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { .withFeatures( MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES, + MapFeature.ALLOWS_ANY_NULL_QUERIES, MapFeature.GENERAL_PURPOSE, MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionFeature.KNOWN_ORDER, CollectionFeature.SERIALIZABLE, CollectionSize.ANY) @@ -94,19 +96,10 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { return suite; } - @Override protected Multimap<String, Integer> create() { + protected SetMultimap<String, Integer> create() { return TreeMultimap.create(); } - /* Null keys and values aren't supported. */ - @Override protected String nullKey() { - return "null"; - } - - @Override protected Integer nullValue() { - return 42; - } - /** * Create and populate a {@code TreeMultimap} with the natural ordering of * keys and values. @@ -124,20 +117,23 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { } public void testToString() { + SetMultimap<String, Integer> multimap = create(); + multimap.putAll("bar", Arrays.asList(3, 1, 2)); + multimap.putAll("foo", Arrays.asList(2, 3, 1, -1, 4)); assertEquals("{bar=[1, 2, 3], foo=[-1, 1, 2, 3, 4]}", - createSample().toString()); + multimap.toString()); } public void testOrderedGet() { TreeMultimap<String, Integer> multimap = createPopulate(); - ASSERT.that(multimap.get("foo")).has().allOf(1, 3, 7).inOrder(); - ASSERT.that(multimap.get("google")).has().allOf(2, 6).inOrder(); - ASSERT.that(multimap.get("tree")).has().allOf(0, 4).inOrder(); + ASSERT.that(multimap.get("foo")).has().exactly(1, 3, 7).inOrder(); + ASSERT.that(multimap.get("google")).has().exactly(2, 6).inOrder(); + ASSERT.that(multimap.get("tree")).has().exactly(0, 4).inOrder(); } public void testOrderedKeySet() { TreeMultimap<String, Integer> multimap = createPopulate(); - ASSERT.that(multimap.keySet()).has().allOf("foo", "google", "tree").inOrder(); + ASSERT.that(multimap.keySet()).has().exactly("foo", "google", "tree").inOrder(); } public void testOrderedAsMapEntries() { @@ -146,18 +142,18 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { multimap.asMap().entrySet().iterator(); Map.Entry<String, Collection<Integer>> entry = iterator.next(); assertEquals("foo", entry.getKey()); - ASSERT.that(entry.getValue()).has().allOf(1, 3, 7); + ASSERT.that(entry.getValue()).has().exactly(1, 3, 7); entry = iterator.next(); assertEquals("google", entry.getKey()); - ASSERT.that(entry.getValue()).has().allOf(2, 6); + ASSERT.that(entry.getValue()).has().exactly(2, 6); entry = iterator.next(); assertEquals("tree", entry.getKey()); - ASSERT.that(entry.getValue()).has().allOf(0, 4); + ASSERT.that(entry.getValue()).has().exactly(0, 4); } public void testOrderedEntries() { TreeMultimap<String, Integer> multimap = createPopulate(); - ASSERT.that(multimap.entries()).has().allOf( + ASSERT.that(multimap.entries()).has().exactly( Maps.immutableEntry("foo", 1), Maps.immutableEntry("foo", 3), Maps.immutableEntry("foo", 7), @@ -169,12 +165,14 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { public void testOrderedValues() { TreeMultimap<String, Integer> multimap = createPopulate(); - ASSERT.that(multimap.values()).has().allOf( + ASSERT.that(multimap.values()).has().exactly( 1, 3, 7, 2, 6, 0, 4).inOrder(); } public void testMultimapConstructor() { - Multimap<String, Integer> multimap = createSample(); + SetMultimap<String, Integer> multimap = create(); + multimap.putAll("bar", Arrays.asList(3, 1, 2)); + multimap.putAll("foo", Arrays.asList(2, 3, 1, -1, 4)); TreeMultimap<String, Integer> copy = TreeMultimap.create(multimap); assertEquals(multimap, copy); } @@ -250,8 +248,8 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { TreeMultimap<String, Integer> multimap = createPopulate(); TreeMultimap<String, Integer> copy = SerializableTester.reserializeAndAssert(multimap); - ASSERT.that(copy.values()).has().allOf(1, 3, 7, 2, 6, 0, 4).inOrder(); - ASSERT.that(copy.keySet()).has().allOf("foo", "google", "tree").inOrder(); + ASSERT.that(copy.values()).has().exactly(1, 3, 7, 2, 6, 0, 4).inOrder(); + ASSERT.that(copy.keySet()).has().exactly("foo", "google", "tree").inOrder(); assertEquals(multimap.keyComparator(), copy.keyComparator()); assertEquals(multimap.valueComparator(), copy.valueComparator()); } @@ -266,9 +264,9 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { multimap.put(new DerivedComparable("bar"), new DerivedComparable("b")); multimap.put(new DerivedComparable("bar"), new DerivedComparable("a")); multimap.put(new DerivedComparable("bar"), new DerivedComparable("r")); - ASSERT.that(multimap.keySet()).has().allOf( + ASSERT.that(multimap.keySet()).has().exactly( new DerivedComparable("bar"), new DerivedComparable("foo")).inOrder(); - ASSERT.that(multimap.values()).has().allOf( + ASSERT.that(multimap.values()).has().exactly( new DerivedComparable("a"), new DerivedComparable("b"), new DerivedComparable("r"), new DerivedComparable("f"), new DerivedComparable("o")).inOrder(); assertEquals(Ordering.natural(), multimap.keyComparator()); @@ -287,9 +285,9 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { multimap.put(new LegacyComparable("bar"), new LegacyComparable("b")); multimap.put(new LegacyComparable("bar"), new LegacyComparable("a")); multimap.put(new LegacyComparable("bar"), new LegacyComparable("r")); - ASSERT.that(multimap.keySet()).has().allOf( + ASSERT.that(multimap.keySet()).has().exactly( new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder(); - ASSERT.that(multimap.values()).has().allOf( + ASSERT.that(multimap.values()).has().exactly( new LegacyComparable("a"), new LegacyComparable("b"), new LegacyComparable("r"), @@ -362,13 +360,4 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest { } fail("No bridge method found"); } - - // Hack for JDK5 type inference. - private static class ASSERT { - static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> that( - Collection<T> collection) { - return Truth.ASSERT.<T, Collection<T>>that(collection); - } - } - } diff --git a/guava-tests/test/com/google/common/collect/TreeMultisetTest.java b/guava-tests/test/com/google/common/collect/TreeMultisetTest.java index c68fcb2..8cb98ab 100644 --- a/guava-tests/test/com/google/common/collect/TreeMultisetTest.java +++ b/guava-tests/test/com/google/common/collect/TreeMultisetTest.java @@ -17,32 +17,28 @@ package com.google.common.collect; import static com.google.common.collect.BoundType.CLOSED; -import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE; import static java.util.Collections.sort; import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.Helpers.NullsBeforeB; -import com.google.common.collect.testing.IteratorTester; import com.google.common.collect.testing.SortedSetTestSuiteBuilder; import com.google.common.collect.testing.TestStringSetGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.google.MultisetFeature; import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder; import com.google.common.collect.testing.google.TestStringMultisetGenerator; import junit.framework.Test; +import junit.framework.TestCase; import junit.framework.TestSuite; -import org.truth0.subjects.CollectionSubject; import java.lang.reflect.Method; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; -import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.SortedSet; @@ -53,7 +49,7 @@ import java.util.SortedSet; * @author Neal Kanodia */ @GwtCompatible(emulated = true) -public class TreeMultisetTest extends AbstractMultisetTest { +public class TreeMultisetTest extends TestCase { @GwtIncompatible("suite") public static Test suite() { @@ -73,7 +69,8 @@ public class TreeMultisetTest extends AbstractMultisetTest { .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, CollectionFeature.GENERAL_PURPOSE, CollectionFeature.SERIALIZABLE, - CollectionFeature.ALLOWS_NULL_QUERIES) + CollectionFeature.ALLOWS_NULL_QUERIES, + MultisetFeature.ENTRIES_ARE_VIEWS) .named("TreeMultiset, Ordering.natural") .createTestSuite()); suite.addTest(SortedMultisetTestSuiteBuilder @@ -81,7 +78,7 @@ public class TreeMultisetTest extends AbstractMultisetTest { @Override protected Multiset<String> create(String[] elements) { Multiset<String> result = TreeMultiset.create(NullsBeforeB.INSTANCE); - result.addAll(Arrays.asList(elements)); + Collections.addAll(result, elements); return result; } @@ -94,7 +91,8 @@ public class TreeMultisetTest extends AbstractMultisetTest { .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, CollectionFeature.GENERAL_PURPOSE, CollectionFeature.SERIALIZABLE, - CollectionFeature.ALLOWS_NULL_VALUES) + CollectionFeature.ALLOWS_NULL_VALUES, + MultisetFeature.ENTRIES_ARE_VIEWS) .named("TreeMultiset, NullsBeforeB") .createTestSuite()); suite.addTest(SortedSetTestSuiteBuilder.using(new TestStringSetGenerator() { @@ -111,18 +109,13 @@ public class TreeMultisetTest extends AbstractMultisetTest { .named("TreeMultiset[Ordering.natural].elementSet") .withFeatures( CollectionSize.ANY, - CollectionFeature.SUPPORTS_REMOVE, + CollectionFeature.REMOVE_OPERATIONS, CollectionFeature.ALLOWS_NULL_QUERIES) .createTestSuite()); suite.addTestSuite(TreeMultisetTest.class); return suite; } - @SuppressWarnings("unchecked") - @Override protected <E> Multiset<E> create() { - return (Multiset) TreeMultiset.create(); - } - public void testCreate() { TreeMultiset<String> multiset = TreeMultiset.create(); multiset.add("foo", 2); @@ -151,6 +144,7 @@ public class TreeMultisetTest extends AbstractMultisetTest { } public void testToString() { + Multiset<String> ms = TreeMultiset.create(); ms.add("a", 3); ms.add("c", 1); ms.add("b", 2); @@ -158,54 +152,6 @@ public class TreeMultisetTest extends AbstractMultisetTest { assertEquals("[a x 3, b x 2, c]", ms.toString()); } - @GwtIncompatible("unreasonable slow") - public void testIteratorBashing() { - IteratorTester<String> tester = - new IteratorTester<String>(createSample().size() + 2, MODIFIABLE, - newArrayList(createSample()), - IteratorTester.KnownOrder.KNOWN_ORDER) { - private Multiset<String> targetMultiset; - - @Override protected Iterator<String> newTargetIterator() { - targetMultiset = createSample(); - return targetMultiset.iterator(); - } - - @Override protected void verify(List<String> elements) { - assertEquals(elements, Lists.newArrayList(targetMultiset)); - } - }; - - /* This next line added as a stopgap until JDK6 bug is fixed. */ - tester.ignoreSunJavaBug6529795(); - - tester.test(); - } - - @GwtIncompatible("slow (~30s)") - public void testElementSetIteratorBashing() { - IteratorTester<String> tester = new IteratorTester<String>(5, MODIFIABLE, - newArrayList("a", "b", "c"), IteratorTester.KnownOrder.KNOWN_ORDER) { - private Set<String> targetSet; - @Override protected Iterator<String> newTargetIterator() { - Multiset<String> multiset = create(); - multiset.add("a", 3); - multiset.add("c", 1); - multiset.add("b", 2); - targetSet = multiset.elementSet(); - return targetSet.iterator(); - } - @Override protected void verify(List<String> elements) { - assertEquals(elements, Lists.newArrayList(targetSet)); - } - }; - - /* This next line added as a stopgap until JDK6 bug is fixed. */ - tester.ignoreSunJavaBug6529795(); - - tester.test(); - } - public void testElementSetSortedSetMethods() { TreeMultiset<String> ms = TreeMultiset.create(); ms.add("c", 1); @@ -217,9 +163,9 @@ public class TreeMultisetTest extends AbstractMultisetTest { assertEquals("c", elementSet.last()); assertEquals(Ordering.natural(), elementSet.comparator()); - assertThat(elementSet.headSet("b")).has().allOf("a").inOrder(); - assertThat(elementSet.tailSet("b")).has().allOf("b", "c").inOrder(); - assertThat(elementSet.subSet("a", "c")).has().allOf("a", "b").inOrder(); + ASSERT.that(elementSet.headSet("b")).has().exactly("a").inOrder(); + ASSERT.that(elementSet.tailSet("b")).has().exactly("b", "c").inOrder(); + ASSERT.that(elementSet.subSet("a", "c")).has().exactly("a", "b").inOrder(); } public void testElementSetSubsetRemove() { @@ -232,18 +178,18 @@ public class TreeMultisetTest extends AbstractMultisetTest { ms.add("f", 2); SortedSet<String> elementSet = ms.elementSet(); - assertThat(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(elementSet).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); SortedSet<String> subset = elementSet.subSet("b", "f"); - assertThat(subset).has().allOf("b", "c", "d", "e").inOrder(); + ASSERT.that(subset).has().exactly("b", "c", "d", "e").inOrder(); assertTrue(subset.remove("c")); - assertThat(elementSet).has().allOf("a", "b", "d", "e", "f").inOrder(); - assertThat(subset).has().allOf("b", "d", "e").inOrder(); + ASSERT.that(elementSet).has().exactly("a", "b", "d", "e", "f").inOrder(); + ASSERT.that(subset).has().exactly("b", "d", "e").inOrder(); assertEquals(10, ms.size()); assertFalse(subset.remove("a")); - assertThat(elementSet).has().allOf("a", "b", "d", "e", "f").inOrder(); - assertThat(subset).has().allOf("b", "d", "e").inOrder(); + ASSERT.that(elementSet).has().exactly("a", "b", "d", "e", "f").inOrder(); + ASSERT.that(subset).has().exactly("b", "d", "e").inOrder(); assertEquals(10, ms.size()); } @@ -257,13 +203,13 @@ public class TreeMultisetTest extends AbstractMultisetTest { ms.add("f", 2); SortedSet<String> elementSet = ms.elementSet(); - assertThat(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(elementSet).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); SortedSet<String> subset = elementSet.subSet("b", "f"); - assertThat(subset).has().allOf("b", "c", "d", "e").inOrder(); + ASSERT.that(subset).has().exactly("b", "c", "d", "e").inOrder(); assertTrue(subset.removeAll(Arrays.asList("a", "c"))); - assertThat(elementSet).has().allOf("a", "b", "d", "e", "f").inOrder(); - assertThat(subset).has().allOf("b", "d", "e").inOrder(); + ASSERT.that(elementSet).has().exactly("a", "b", "d", "e", "f").inOrder(); + ASSERT.that(subset).has().exactly("b", "d", "e").inOrder(); assertEquals(10, ms.size()); } @@ -277,13 +223,13 @@ public class TreeMultisetTest extends AbstractMultisetTest { ms.add("f", 2); SortedSet<String> elementSet = ms.elementSet(); - assertThat(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(elementSet).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); SortedSet<String> subset = elementSet.subSet("b", "f"); - assertThat(subset).has().allOf("b", "c", "d", "e").inOrder(); + ASSERT.that(subset).has().exactly("b", "c", "d", "e").inOrder(); assertTrue(subset.retainAll(Arrays.asList("a", "c"))); - assertThat(elementSet).has().allOf("a", "c", "f").inOrder(); - assertThat(subset).has().allOf("c").inOrder(); + ASSERT.that(elementSet).has().exactly("a", "c", "f").inOrder(); + ASSERT.that(subset).has().exactly("c").inOrder(); assertEquals(5, ms.size()); } @@ -297,13 +243,13 @@ public class TreeMultisetTest extends AbstractMultisetTest { ms.add("f", 2); SortedSet<String> elementSet = ms.elementSet(); - assertThat(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder(); + ASSERT.that(elementSet).has().exactly("a", "b", "c", "d", "e", "f").inOrder(); SortedSet<String> subset = elementSet.subSet("b", "f"); - assertThat(subset).has().allOf("b", "c", "d", "e").inOrder(); + ASSERT.that(subset).has().exactly("b", "c", "d", "e").inOrder(); subset.clear(); - assertThat(elementSet).has().allOf("a", "f").inOrder(); - assertThat(subset).isEmpty(); + ASSERT.that(elementSet).has().exactly("a", "f").inOrder(); + ASSERT.that(subset).isEmpty(); assertEquals(3, ms.size()); } @@ -322,7 +268,7 @@ public class TreeMultisetTest extends AbstractMultisetTest { ms.add("b"); ms.add("d"); - assertThat(ms).has().allOf("d", "c", "b", "b", "a").inOrder(); + ASSERT.that(ms).has().exactly("d", "c", "b", "b", "a").inOrder(); SortedSet<String> elementSet = ms.elementSet(); assertEquals("d", elementSet.first()); @@ -340,7 +286,7 @@ public class TreeMultisetTest extends AbstractMultisetTest { ms.add("b"); ms.add(null, 2); - assertThat(ms).has().allOf(null, null, null, "a", "b", "b").inOrder(); + ASSERT.that(ms).has().exactly(null, null, null, "a", "b", "b").inOrder(); assertEquals(3, ms.count(null)); SortedSet<String> elementSet = ms.elementSet(); @@ -406,11 +352,6 @@ public class TreeMultisetTest extends AbstractMultisetTest { assertEquals(Integer.MAX_VALUE, ms.tailMultiset("a", CLOSED).size()); } - @Override public void testToStringNull() { - c = ms = TreeMultiset.create(Ordering.natural().nullsFirst()); - super.testToStringNull(); - } - @GwtIncompatible("reflection") public void testElementSetBridgeMethods() { for (Method m : TreeMultiset.class.getMethods()) { @@ -420,10 +361,4 @@ public class TreeMultisetTest extends AbstractMultisetTest { } fail("No bridge method found"); } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/collect/TreeTraverserTest.java b/guava-tests/test/com/google/common/collect/TreeTraverserTest.java new file mode 100644 index 0000000..37c9859 --- /dev/null +++ b/guava-tests/test/com/google/common/collect/TreeTraverserTest.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2011 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations + * under the License. + */ + +package com.google.common.collect; + +import static org.truth0.Truth.ASSERT; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; +import com.google.common.base.Optional; +import com.google.common.testing.NullPointerTester; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Nullable; + +/** + * Tests for {@code TreeTraverser}. + * + * @author Louis Wasserman + */ +@GwtCompatible(emulated = true) +public class TreeTraverserTest extends TestCase { + private static final class Tree { + final char value; + final List<Tree> children; + + public Tree(char value, Tree... children) { + this.value = value; + this.children = Arrays.asList(children); + } + } + + private static final class BinaryTree { + final char value; + @Nullable + final BinaryTree left; + @Nullable + final BinaryTree right; + + private BinaryTree(char value, BinaryTree left, BinaryTree right) { + this.value = value; + this.left = left; + this.right = right; + } + } + + private static final TreeTraverser<Tree> ADAPTER = new TreeTraverser<Tree>() { + @Override + public Iterable<Tree> children(Tree node) { + return node.children; + } + }; + + private static final BinaryTreeTraverser<BinaryTree> BIN_ADAPTER = + new BinaryTreeTraverser<BinaryTree>() { + + @Override + public Optional<BinaryTree> leftChild(BinaryTree node) { + return Optional.fromNullable(node.left); + } + + @Override + public Optional<BinaryTree> rightChild(BinaryTree node) { + return Optional.fromNullable(node.right); + } + }; + + // h + // / | \ + // / e \ + // d g + // /|\ | + // / | \ f + // a b c + static final Tree a = new Tree('a'); + static final Tree b = new Tree('b'); + static final Tree c = new Tree('c'); + static final Tree d = new Tree('d', a, b, c); + static final Tree e = new Tree('e'); + static final Tree f = new Tree('f'); + static final Tree g = new Tree('g', f); + static final Tree h = new Tree('h', d, e, g); + + // d + // / \ + // b e + // / \ \ + // a c f + // / + // g + static final BinaryTree ba = new BinaryTree('a', null, null); + static final BinaryTree bc = new BinaryTree('c', null, null); + static final BinaryTree bb = new BinaryTree('b', ba, bc); + static final BinaryTree bg = new BinaryTree('g', null, null); + static final BinaryTree bf = new BinaryTree('f', bg, null); + static final BinaryTree be = new BinaryTree('e', null, bf); + static final BinaryTree bd = new BinaryTree('d', bb, be); + + static String iterationOrder(Iterable<Tree> iterable) { + StringBuilder builder = new StringBuilder(); + for (Tree t : iterable) { + builder.append(t.value); + } + return builder.toString(); + } + + static String binaryIterationOrder(Iterable<BinaryTree> iterable) { + StringBuilder builder = new StringBuilder(); + for (BinaryTree t : iterable) { + builder.append(t.value); + } + return builder.toString(); + } + + public void testPreOrder() { + ASSERT.that(iterationOrder(ADAPTER.preOrderTraversal(h))).is("hdabcegf"); + ASSERT.that(binaryIterationOrder(BIN_ADAPTER.preOrderTraversal(bd))).is("dbacefg"); + } + + public void testPostOrder() { + ASSERT.that(iterationOrder(ADAPTER.postOrderTraversal(h))).is("abcdefgh"); + ASSERT.that(binaryIterationOrder(BIN_ADAPTER.postOrderTraversal(bd))).is("acbgfed"); + } + + public void testBreadthOrder() { + ASSERT.that(iterationOrder(ADAPTER.breadthFirstTraversal(h))).is("hdegabcf"); + ASSERT.that(binaryIterationOrder(BIN_ADAPTER.breadthFirstTraversal(bd))).is("dbeacfg"); + } + + public void testInOrder() { + ASSERT.that(binaryIterationOrder(BIN_ADAPTER.inOrderTraversal(bd))).is("abcdegf"); + } + + @GwtIncompatible("NullPointerTester") + public void testNulls() { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicInstanceMethods(ADAPTER); + tester.testAllPublicInstanceMethods(BIN_ADAPTER); + } +} diff --git a/guava-tests/test/com/google/common/collect/UnmodifiableIteratorTest.java b/guava-tests/test/com/google/common/collect/UnmodifiableIteratorTest.java index fab3408..8cc7f32 100644 --- a/guava-tests/test/com/google/common/collect/UnmodifiableIteratorTest.java +++ b/guava-tests/test/com/google/common/collect/UnmodifiableIteratorTest.java @@ -18,11 +18,11 @@ package com.google.common.collect; import com.google.common.annotations.GwtCompatible; +import junit.framework.TestCase; + import java.util.Iterator; import java.util.NoSuchElementException; -import junit.framework.TestCase; - /** * Tests for {@link UnmodifiableIterator}. * diff --git a/guava-tests/test/com/google/common/collect/UnmodifiableListIteratorTest.java b/guava-tests/test/com/google/common/collect/UnmodifiableListIteratorTest.java index 11a7456..5cb01ef 100644 --- a/guava-tests/test/com/google/common/collect/UnmodifiableListIteratorTest.java +++ b/guava-tests/test/com/google/common/collect/UnmodifiableListIteratorTest.java @@ -18,12 +18,12 @@ package com.google.common.collect; import com.google.common.annotations.GwtCompatible; +import junit.framework.TestCase; + import java.util.Iterator; import java.util.ListIterator; import java.util.NoSuchElementException; -import junit.framework.TestCase; - /** * Tests for UnmodifiableListIterator. * @@ -91,8 +91,9 @@ public class UnmodifiableListIteratorTest extends TestCase { return i; } @Override public String previous() { - if(!hasPrevious()) + if (!hasPrevious()) { throw new NoSuchElementException(); + } return array[--i]; } @Override public int previousIndex() { diff --git a/guava-tests/test/com/google/common/collect/WellBehavedMapTest.java b/guava-tests/test/com/google/common/collect/WellBehavedMapTest.java index 24d27f7..d20e998 100644 --- a/guava-tests/test/com/google/common/collect/WellBehavedMapTest.java +++ b/guava-tests/test/com/google/common/collect/WellBehavedMapTest.java @@ -18,12 +18,12 @@ package com.google.common.collect; import com.google.common.annotations.GwtCompatible; +import junit.framework.TestCase; + import java.util.EnumMap; import java.util.Map; import java.util.Set; -import junit.framework.TestCase; - @GwtCompatible public class WellBehavedMapTest extends TestCase { enum Foo { diff --git a/guava-tests/test/com/google/common/escape/ArrayBasedCharEscaperTest.java b/guava-tests/test/com/google/common/escape/ArrayBasedCharEscaperTest.java new file mode 100644 index 0000000..76ae23c --- /dev/null +++ b/guava-tests/test/com/google/common/escape/ArrayBasedCharEscaperTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.escape; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.collect.ImmutableMap; +import com.google.common.escape.testing.EscaperAsserts; + +import junit.framework.TestCase; + +import java.io.IOException; +import java.util.Map; + +/** + * @author David Beaumont + */ +@GwtCompatible +public class ArrayBasedCharEscaperTest extends TestCase { + private static final Map<Character, String> NO_REPLACEMENTS = + ImmutableMap.of(); + private static final Map<Character, String> SIMPLE_REPLACEMENTS = + ImmutableMap.of( + '\n', "<newline>", + '\t', "<tab>", + '&', "<and>"); + + public void testSafeRange() throws IOException { + // Basic escaping of unsafe chars (wrap them in {,}'s) + CharEscaper wrappingEscaper = + new ArrayBasedCharEscaper(NO_REPLACEMENTS, 'A', 'Z') { + @Override protected char[] escapeUnsafe(char c) { + return ("{" + c + "}").toCharArray(); + } + }; + EscaperAsserts.assertBasic(wrappingEscaper); + // '[' and '@' lie either side of [A-Z]. + assertEquals("{[}FOO{@}BAR{]}", wrappingEscaper.escape("[FOO@BAR]")); + } + + public void testSafeRange_maxLessThanMin() throws IOException { + // Basic escaping of unsafe chars (wrap them in {,}'s) + CharEscaper wrappingEscaper = + new ArrayBasedCharEscaper(NO_REPLACEMENTS, 'Z', 'A') { + @Override protected char[] escapeUnsafe(char c) { + return ("{" + c + "}").toCharArray(); + } + }; + EscaperAsserts.assertBasic(wrappingEscaper); + // escape everything. + assertEquals("{[}{F}{O}{O}{]}", wrappingEscaper.escape("[FOO]")); + } + + public void testDeleteUnsafeChars() throws IOException { + CharEscaper deletingEscaper = + new ArrayBasedCharEscaper(NO_REPLACEMENTS, ' ', '~') { + private final char[] noChars = new char[0]; + @Override protected char[] escapeUnsafe(char c) { + return noChars; + } + }; + EscaperAsserts.assertBasic(deletingEscaper); + assertEquals("Everything outside the printable ASCII range is deleted.", + deletingEscaper.escape("\tEverything\0 outside the\uD800\uDC00 " + + "printable ASCII \uFFFFrange is \u007Fdeleted.\n")); + } + + public void testReplacementPriority() throws IOException { + CharEscaper replacingEscaper = + new ArrayBasedCharEscaper(SIMPLE_REPLACEMENTS, ' ', '~') { + private final char[] unknown = new char[] { '?' }; + @Override protected char[] escapeUnsafe(char c) { + return unknown; + } + }; + EscaperAsserts.assertBasic(replacingEscaper); + + // Replacements are applied first regardless of whether the character is in + // the safe range or not ('&' is a safe char while '\t' and '\n' are not). + assertEquals("<tab>Fish <and>? Chips?<newline>", + replacingEscaper.escape("\tFish &\0 Chips\r\n")); + } +} diff --git a/guava-tests/test/com/google/common/escape/ArrayBasedEscaperMapTest.java b/guava-tests/test/com/google/common/escape/ArrayBasedEscaperMapTest.java new file mode 100644 index 0000000..3d0d3d9 --- /dev/null +++ b/guava-tests/test/com/google/common/escape/ArrayBasedEscaperMapTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.escape; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.collect.ImmutableMap; + +import junit.framework.TestCase; + +import java.util.Map; + +/** + * @author David Beaumont + */ +@GwtCompatible +public class ArrayBasedEscaperMapTest extends TestCase { + public void testNullMap() { + try { + ArrayBasedEscaperMap.create(null); + fail("expected exception did not occur"); + } catch (NullPointerException e) { + // pass + } + } + + public void testEmptyMap() { + Map<Character, String> map = ImmutableMap.of(); + ArrayBasedEscaperMap fem = ArrayBasedEscaperMap.create(map); + // Non-null array of zero length. + assertEquals(0, fem.getReplacementArray().length); + } + + public void testMapLength() { + Map<Character, String> map = ImmutableMap.of( + 'a', "first", + 'z', "last"); + ArrayBasedEscaperMap fem = ArrayBasedEscaperMap.create(map); + // Array length is highest character value + 1 + assertEquals('z' + 1, fem.getReplacementArray().length); + } + + public void testMapping() { + Map<Character, String> map = ImmutableMap.of( + '\0', "zero", + 'a', "first", + 'b', "second", + 'z', "last", + '\uFFFF', "biggest"); + ArrayBasedEscaperMap fem = ArrayBasedEscaperMap.create(map); + char[][] replacementArray = fem.getReplacementArray(); + // Array length is highest character value + 1 + assertEquals(65536, replacementArray.length); + // The final element should always be non null. + assertNotNull(replacementArray[replacementArray.length - 1]); + // Exhaustively check all mappings (an int index avoids wrapping). + for (int n = 0; n < replacementArray.length; ++n) { + char c = (char) n; + if (replacementArray[n] != null) { + assertEquals(map.get(c), new String(replacementArray[n])); + } else { + assertFalse(map.containsKey(c)); + } + } + } +} diff --git a/guava-tests/test/com/google/common/escape/ArrayBasedUnicodeEscaperTest.java b/guava-tests/test/com/google/common/escape/ArrayBasedUnicodeEscaperTest.java new file mode 100644 index 0000000..6ecac91 --- /dev/null +++ b/guava-tests/test/com/google/common/escape/ArrayBasedUnicodeEscaperTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.escape; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.collect.ImmutableMap; +import com.google.common.escape.testing.EscaperAsserts; + +import junit.framework.TestCase; + +import java.io.IOException; +import java.util.Map; + +/** + * @author David Beaumont + */ +@GwtCompatible +public class ArrayBasedUnicodeEscaperTest extends TestCase { + private static final Map<Character, String> NO_REPLACEMENTS = + ImmutableMap.of(); + private static final Map<Character, String> SIMPLE_REPLACEMENTS = + ImmutableMap.of( + '\n', "<newline>", + '\t', "<tab>", + '&', "<and>"); + private static final char[] NO_CHARS = new char[0]; + + public void testReplacements() throws IOException { + // In reality this is not a very sensible escaper to have (if you are only + // escaping elements from a map you would use a ArrayBasedCharEscaper). + UnicodeEscaper escaper = new ArrayBasedUnicodeEscaper(SIMPLE_REPLACEMENTS, + Character.MIN_VALUE, Character.MAX_CODE_POINT, null) { + @Override protected char[] escapeUnsafe(int c) { + return NO_CHARS; + } + }; + EscaperAsserts.assertBasic(escaper); + assertEquals("<tab>Fish <and> Chips<newline>", + escaper.escape("\tFish & Chips\n")); + + // Verify that everything else is left unescaped. + String safeChars = "\0\u0100\uD800\uDC00\uFFFF"; + assertEquals(safeChars, escaper.escape(safeChars)); + + // Ensure that Unicode escapers behave correctly wrt badly formed input. + String badUnicode = "\uDC00\uD800"; + try { + escaper.escape(badUnicode); + fail("should fail for bad Unicode"); + } catch (IllegalArgumentException e) { + // Pass + } + } + + public void testSafeRange() throws IOException { + // Basic escaping of unsafe chars (wrap them in {,}'s) + UnicodeEscaper wrappingEscaper = + new ArrayBasedUnicodeEscaper(NO_REPLACEMENTS, 'A', 'Z', null) { + @Override protected char[] escapeUnsafe(int c) { + return ("{" + (char) c + "}").toCharArray(); + } + }; + EscaperAsserts.assertBasic(wrappingEscaper); + // '[' and '@' lie either side of [A-Z]. + assertEquals("{[}FOO{@}BAR{]}", wrappingEscaper.escape("[FOO@BAR]")); + } + + public void testDeleteUnsafeChars() throws IOException { + UnicodeEscaper deletingEscaper = + new ArrayBasedUnicodeEscaper(NO_REPLACEMENTS, ' ', '~', null) { + @Override protected char[] escapeUnsafe(int c) { + return NO_CHARS; + } + }; + EscaperAsserts.assertBasic(deletingEscaper); + assertEquals("Everything outside the printable ASCII range is deleted.", + deletingEscaper.escape("\tEverything\0 outside the\uD800\uDC00 " + + "printable ASCII \uFFFFrange is \u007Fdeleted.\n")); + } + + public void testReplacementPriority() throws IOException { + UnicodeEscaper replacingEscaper = + new ArrayBasedUnicodeEscaper(SIMPLE_REPLACEMENTS, ' ', '~', null) { + private final char[] unknown = new char[] { '?' }; + @Override protected char[] escapeUnsafe(int c) { + return unknown; + } + }; + EscaperAsserts.assertBasic(replacingEscaper); + + // Replacements are applied first regardless of whether the character is in + // the safe range or not ('&' is a safe char while '\t' and '\n' are not). + assertEquals("<tab>Fish <and>? Chips?<newline>", + replacingEscaper.escape("\tFish &\0 Chips\r\n")); + } + + public void testCodePointsFromSurrogatePairs() throws IOException { + UnicodeEscaper surrogateEscaper = + new ArrayBasedUnicodeEscaper(NO_REPLACEMENTS, 0, 0x20000, null) { + private final char[] escaped = new char[] { 'X' }; + @Override protected char[] escapeUnsafe(int c) { + return escaped; + } + }; + EscaperAsserts.assertBasic(surrogateEscaper); + + // A surrogate pair defining a code point within the safe range. + String safeInput = "\uD800\uDC00"; // 0x10000 + assertEquals(safeInput, surrogateEscaper.escape(safeInput)); + + // A surrogate pair defining a code point outside the safe range (but both + // of the surrogate characters lie within the safe range). It is important + // not to accidentally treat this as a sequence of safe characters. + String unsafeInput = "\uDBFF\uDFFF"; // 0x10FFFF + assertEquals("X", surrogateEscaper.escape(unsafeInput)); + } +} diff --git a/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetWithChmTest.java b/guava-tests/test/com/google/common/escape/CharEscaperBuilderTest.java index c573ab1..c564f67 100644 --- a/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetWithChmTest.java +++ b/guava-tests/test/com/google/common/escape/CharEscaperBuilderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Guava Authors + * Copyright (C) 2012 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,18 +14,17 @@ * limitations under the License. */ -package com.google.common.collect; +package com.google.common.escape; -/** - * Unit test for {@link ConcurrentHashMultiset} behavior when backed by the - * standard {@link java.util.concurrent.ConcurrentHashMap}. - * - * @author Kevin Bourrillion - * @author Jared Levy - */ -public class ConcurrentHashMultisetWithChmTest - extends AbstractConcurrentHashMultisetTest { - @Override protected <E> Multiset<E> create() { - return ConcurrentHashMultiset.create(); +import junit.framework.TestCase; + +public class CharEscaperBuilderTest extends TestCase { + + public void testAddEscapes() { + char[] cs = {'a', 'b', 'c'}; + CharEscaperBuilder builder = new CharEscaperBuilder().addEscapes(cs, "Z"); + Escaper escaper = builder.toEscaper(); + assertEquals("ZZZdef", escaper.escape("abcdef")); } + } diff --git a/guava-tests/test/com/google/common/escape/EscapersTest.java b/guava-tests/test/com/google/common/escape/EscapersTest.java new file mode 100644 index 0000000..c8df0a2 --- /dev/null +++ b/guava-tests/test/com/google/common/escape/EscapersTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.escape; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.collect.ImmutableMap; +import com.google.common.escape.testing.EscaperAsserts; + +import junit.framework.TestCase; + +import java.io.IOException; + +/** + * @author David Beaumont + */ +@GwtCompatible +public class EscapersTest extends TestCase { + public void testNullEscaper() throws IOException { + Escaper escaper = Escapers.nullEscaper(); + EscaperAsserts.assertBasic(escaper); + String s = "\0\n\t\\az09~\uD800\uDC00\uFFFF"; + assertEquals("null escaper should have no effect", s, escaper.escape(s)); + } + + public void testBuilderInitialStateNoReplacement() { + // Unsafe characters aren't modified by default (unsafeReplacement == null). + Escaper escaper = Escapers.builder().setSafeRange('a', 'z').build(); + assertEquals("The Quick Brown Fox", escaper.escape("The Quick Brown Fox")); + } + + public void testBuilderInitialStateNoneUnsafe() { + // No characters are unsafe by default (safeMin == 0, safeMax == 0xFFFF). + Escaper escaper = Escapers.builder().setUnsafeReplacement("X").build(); + assertEquals("\0\uFFFF", escaper.escape("\0\uFFFF")); + } + + public void testBuilderRetainsState() { + // Setting a safe range and unsafe replacement works as expected. + Escapers.Builder builder = Escapers.builder(); + builder.setSafeRange('a', 'z'); + builder.setUnsafeReplacement("X"); + assertEquals("XheXXuickXXrownXXoxX", + builder.build().escape("The Quick Brown Fox!")); + // Explicit replacements take priority over unsafe characters. + builder.addEscape(' ', "_"); + builder.addEscape('!', "_"); + assertEquals("Xhe_Xuick_Xrown_Xox_", + builder.build().escape("The Quick Brown Fox!")); + // Explicit replacements take priority over safe characters. + builder.setSafeRange(' ', '~'); + assertEquals("The_Quick_Brown_Fox_", + builder.build().escape("The Quick Brown Fox!")); + } + + public void testBuilderCreatesIndependentEscapers() { + // Setup a simple builder and create the first escaper. + Escapers.Builder builder = Escapers.builder(); + builder.setSafeRange('a', 'z'); + builder.setUnsafeReplacement("X"); + builder.addEscape(' ', "_"); + Escaper first = builder.build(); + // Modify one of the existing mappings before creating a new escaper. + builder.addEscape(' ', "-"); + builder.addEscape('!', "$"); + Escaper second = builder.build(); + // This should have no effect on existing escapers. + builder.addEscape(' ', "*"); + + // Test both escapers after modifying the builder. + assertEquals("Xhe_Xuick_Xrown_XoxX", first.escape("The Quick Brown Fox!")); + assertEquals("Xhe-Xuick-Xrown-Xox$", second.escape("The Quick Brown Fox!")); + } + + public void testAsUnicodeEscaper() throws IOException { + CharEscaper charEscaper = createSimpleCharEscaper( + ImmutableMap.<Character, char[]>builder() + .put('x', "<hello>".toCharArray()) + .put('\uD800', "<hi>".toCharArray()) + .put('\uDC00', "<lo>".toCharArray()) + .build()); + UnicodeEscaper unicodeEscaper = Escapers.asUnicodeEscaper(charEscaper); + EscaperAsserts.assertBasic(unicodeEscaper); + assertEquals("<hello><hi><lo>", charEscaper.escape("x\uD800\uDC00")); + assertEquals("<hello><hi><lo>", unicodeEscaper.escape("x\uD800\uDC00")); + + // Test that wrapped escapers acquire good Unicode semantics. + assertEquals("<hi><hello><lo>", charEscaper.escape("\uD800x\uDC00")); + try { + unicodeEscaper.escape("\uD800x\uDC00"); + fail("should have failed for bad Unicode input"); + } catch (IllegalArgumentException e) { + // pass + } + assertEquals("<lo><hi>", charEscaper.escape("\uDC00\uD800")); + try { + unicodeEscaper.escape("\uDC00\uD800"); + fail("should have failed for bad Unicode input"); + } catch (IllegalArgumentException e) { + // pass + } + } + + // A trival non-optimized escaper for testing. + private CharEscaper createSimpleCharEscaper( + final ImmutableMap<Character, char[]> replacementMap) { + return new CharEscaper() { + @Override protected char[] escape(char c) { + return replacementMap.get(c); + } + }; + } + + // A trival non-optimized escaper for testing. + private UnicodeEscaper createSimpleUnicodeEscaper( + final ImmutableMap<Integer, char[]> replacementMap) { + return new UnicodeEscaper() { + @Override protected char[] escape(int cp) { + return replacementMap.get(cp); + } + }; + } +} diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java b/guava-tests/test/com/google/common/escape/PackageSanityTests.java index e18b00e..c2af8b7 100644 --- a/guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java +++ b/guava-tests/test/com/google/common/escape/PackageSanityTests.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package com.google.common.util.concurrent; +package com.google.common.escape; -import junit.framework.TestCase; +import com.google.common.testing.AbstractPackageSanityTests; /** - * Unit tests for {@link ForwardingService} + * Basic sanity tests for the entire package. + * + * @author Ben Yu */ -public class ForwardingServiceTest extends TestCase { - public void testForwarding() { - ForwardingObjectTester.testForwardingObject(ForwardingService.class); - } -} + +public class PackageSanityTests extends AbstractPackageSanityTests {} diff --git a/guava-tests/test/com/google/common/escape/UnicodeEscaperTest.java b/guava-tests/test/com/google/common/escape/UnicodeEscaperTest.java new file mode 100644 index 0000000..36eccdf --- /dev/null +++ b/guava-tests/test/com/google/common/escape/UnicodeEscaperTest.java @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.escape; + +import com.google.common.annotations.GwtCompatible; + +import junit.framework.TestCase; + +/** + * Tests for {@link UnicodeEscaper}. + * + * @author David Beaumont + */ +@GwtCompatible +public class UnicodeEscaperTest extends TestCase { + + private static final String SMALLEST_SURROGATE = + "" + Character.MIN_HIGH_SURROGATE + Character.MIN_LOW_SURROGATE; + private static final String LARGEST_SURROGATE = + "" + Character.MAX_HIGH_SURROGATE + Character.MAX_LOW_SURROGATE; + + private static final String TEST_STRING = + "\0abyz\u0080\u0100\u0800\u1000ABYZ\uffff" + + SMALLEST_SURROGATE + "0189" + LARGEST_SURROGATE; + + // Escapes nothing + private static final UnicodeEscaper NOP_ESCAPER = new UnicodeEscaper() { + @Override + protected char[] escape(int c) { + return null; + } + }; + + // Escapes everything except [a-zA-Z0-9] + private static final UnicodeEscaper SIMPLE_ESCAPER = new UnicodeEscaper() { + @Override + protected char[] escape(int cp) { + return ('a' <= cp && cp <= 'z') || + ('A' <= cp && cp <= 'Z') || + ('0' <= cp && cp <= '9') ? null : + ("[" + String.valueOf(cp) + "]").toCharArray(); + } + }; + + public void testNopEscaper() { + UnicodeEscaper e = NOP_ESCAPER; + assertEquals(TEST_STRING, escapeAsString(e, TEST_STRING)); + } + + public void testSimpleEscaper() { + UnicodeEscaper e = SIMPLE_ESCAPER; + String expected = + "[0]abyz[128][256][2048][4096]ABYZ[65535]" + + "[" + Character.MIN_SUPPLEMENTARY_CODE_POINT + "]" + + "0189[" + Character.MAX_CODE_POINT + "]"; + assertEquals(expected, escapeAsString(e, TEST_STRING)); + } + + public void testGrowBuffer() { // need to grow past an initial 1024 byte buffer + StringBuffer input = new StringBuffer(); + StringBuffer expected = new StringBuffer(); + for (int i = 256; i < 1024; i++) { + input.append((char) i); + expected.append("[" + i + "]"); + } + assertEquals(expected.toString(), SIMPLE_ESCAPER.escape(input.toString())); + } + + public void testSurrogatePairs() { + UnicodeEscaper e = SIMPLE_ESCAPER; + + // Build up a range of surrogate pair characters to test + final int min = Character.MIN_SUPPLEMENTARY_CODE_POINT; + final int max = Character.MAX_CODE_POINT; + final int range = max - min; + final int s1 = min + (1 * range) / 4; + final int s2 = min + (2 * range) / 4; + final int s3 = min + (3 * range) / 4; + final char[] dst = new char[12]; + + // Put surrogate pairs at odd indices so they can be split easily + dst[0] = 'x'; + Character.toChars(min, dst, 1); + Character.toChars(s1, dst, 3); + Character.toChars(s2, dst, 5); + Character.toChars(s3, dst, 7); + Character.toChars(max, dst, 9); + dst[11] = 'x'; + String test = new String(dst); + + // Get the expected result string + String expected = + "x[" + min + "][" + s1 + "][" + s2 + "][" + s3 + "][" + max + "]x"; + assertEquals(expected, escapeAsString(e, test)); + } + + public void testTrailingHighSurrogate() { + String test = "abc" + Character.MIN_HIGH_SURROGATE; + try { + escapeAsString(NOP_ESCAPER, test); + fail("Trailing high surrogate should cause exception"); + } catch (IllegalArgumentException expected) { + // Pass + } + try { + escapeAsString(SIMPLE_ESCAPER, test); + fail("Trailing high surrogate should cause exception"); + } catch (IllegalArgumentException expected) { + // Pass + } + } + + public void testNullInput() { + UnicodeEscaper e = SIMPLE_ESCAPER; + try { + e.escape((String) null); + fail("Null string should cause exception"); + } catch (NullPointerException expected) { + // Pass + } + } + + public void testBadStrings() { + UnicodeEscaper e = SIMPLE_ESCAPER; + String[] BAD_STRINGS = { + String.valueOf(Character.MIN_LOW_SURROGATE), + Character.MIN_LOW_SURROGATE + "xyz", + "abc" + Character.MIN_LOW_SURROGATE, + "abc" + Character.MIN_LOW_SURROGATE + "xyz", + String.valueOf(Character.MAX_LOW_SURROGATE), + Character.MAX_LOW_SURROGATE + "xyz", + "abc" + Character.MAX_LOW_SURROGATE, + "abc" + Character.MAX_LOW_SURROGATE + "xyz", + }; + for (String s : BAD_STRINGS) { + try { + escapeAsString(e, s); + fail("Isolated low surrogate should cause exception [" + s + "]"); + } catch (IllegalArgumentException expected) { + // Pass + } + } + } + + public void testFalsePositivesForNextEscapedIndex() { + UnicodeEscaper e = new UnicodeEscaper() { + // Canonical escaper method that only escapes lower case ASCII letters. + @Override + protected char[] escape(int cp) { + return ('a' <= cp && cp <= 'z') ? + new char[] { Character.toUpperCase((char) cp) } : null; + } + // Inefficient implementation that defines all letters as escapable. + @Override + protected int nextEscapeIndex(CharSequence csq, int index, int end) { + while (index < end && !Character.isLetter(csq.charAt(index))) { + index++; + } + return index; + } + }; + assertEquals("\0HELLO \uD800\uDC00 WORLD!\n", + e.escape("\0HeLLo \uD800\uDC00 WorlD!\n")); + } + + public void testCodePointAt_IndexOutOfBoundsException() { + try { + UnicodeEscaper.codePointAt("Testing...", 4, 2); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + } + + private String escapeAsString(Escaper e, String s) { + return e.escape(s); + } +} diff --git a/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java b/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java index 01b9a42..1a0d555 100644 --- a/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java +++ b/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java @@ -18,11 +18,11 @@ package com.google.common.eventbus; import com.google.common.collect.Lists; +import junit.framework.TestCase; + import java.util.List; import java.util.concurrent.Executor; -import junit.framework.TestCase; - /** * Test case for {@link AsyncEventBus}. * diff --git a/guava-tests/test/com/google/common/eventbus/EventBusTest.java b/guava-tests/test/com/google/common/eventbus/EventBusTest.java index 74f72c8..30fa0da 100644 --- a/guava-tests/test/com/google/common/eventbus/EventBusTest.java +++ b/guava-tests/test/com/google/common/eventbus/EventBusTest.java @@ -19,6 +19,8 @@ package com.google.common.eventbus; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import junit.framework.TestCase; + import java.util.Collection; import java.util.List; import java.util.Set; @@ -26,8 +28,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import junit.framework.TestCase; - /** * Test case for {@link EventBus}. * @@ -120,6 +120,57 @@ public class EventBusTest extends TestCase { COMP_EVENT, compEvents.get(1)); } + public void testSubscriberThrowsException() throws Exception{ + final RecordingSubscriberExceptionHandler handler = + new RecordingSubscriberExceptionHandler(); + final EventBus eventBus = new EventBus(handler); + final RuntimeException exception = + new RuntimeException("but culottes have a tendancy to ride up!"); + final Object subscriber = new Object() { + @Subscribe + public void throwExceptionOn(String message) { + throw exception; + } + }; + eventBus.register(subscriber); + eventBus.post(EVENT); + + assertEquals("Cause should be available.", + exception, handler.exception); + assertEquals("EventBus should be available.", + eventBus, handler.context.getEventBus()); + assertEquals("Event should be available.", + EVENT, + handler.context.getEvent()); + assertEquals("Subscriber should be available.", + subscriber, handler.context.getSubscriber()); + assertEquals("Method should be available.", + subscriber.getClass().getMethod("throwExceptionOn", String.class), + handler.context.getSubscriberMethod()); + } + + public void testSubscriberThrowsExceptionHandlerThrowsException() throws Exception{ + final EventBus eventBus = new EventBus(new SubscriberExceptionHandler() { + @Override + public void handleException(Throwable exception, + SubscriberExceptionContext context) { + throw new RuntimeException(); + } + }); + final Object subscriber = new Object() { + @Subscribe + public void throwExceptionOn(String message) { + throw new RuntimeException(); + } + }; + eventBus.register(subscriber); + try { + eventBus.post(EVENT); + } catch (RuntimeException e) { + fail("Exception should not be thrown."); + } + } + public void testDeadEventForwarding() { GhostCatcher catcher = new GhostCatcher(); bus.register(catcher); @@ -240,6 +291,24 @@ public class EventBusTest extends TestCase { } /** + * Records a thrown exception information. + */ + private static final class RecordingSubscriberExceptionHandler + implements SubscriberExceptionHandler { + + public SubscriberExceptionContext context; + public Throwable exception; + + @Override + public void handleException(Throwable exception, + SubscriberExceptionContext context) { + this.exception = exception; + this.context = context; + + } + } + + /** * Runnable which registers a StringCatcher on an event bus and adds it to a * list. */ diff --git a/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java b/guava-tests/test/com/google/common/eventbus/EventSubscriberTest.java index cb85a57..b0a332a 100644 --- a/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java +++ b/guava-tests/test/com/google/common/eventbus/EventSubscriberTest.java @@ -18,17 +18,17 @@ package com.google.common.eventbus; import com.google.common.testing.EqualsTester; +import junit.framework.TestCase; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import junit.framework.TestCase; - /** - * Test case for {@link EventHandler}. + * Test case for {@link EventSubscriber}. * * @author Cliff Biffle */ -public class EventHandlerTest extends TestCase { +public class EventSubscriberTest extends TestCase { private static final Object FIXTURE_ARGUMENT = new Object(); @@ -50,22 +50,22 @@ public class EventHandlerTest extends TestCase { public void testBasicMethodCall() throws Exception { Method method = getRecordingMethod(); - EventHandler handler = new EventHandler(this, method); + EventSubscriber subscriber = new EventSubscriber(this, method); - handler.handleEvent(FIXTURE_ARGUMENT); + subscriber.handleEvent(FIXTURE_ARGUMENT); - assertTrue("Handler must call provided method.", methodCalled); - assertTrue("Handler argument must be *exactly* the provided object.", + assertTrue("Subscriber must call provided method.", methodCalled); + assertTrue("Subscriber argument must be *exactly* the provided object.", methodArgument == FIXTURE_ARGUMENT); } public void testExceptionWrapping() { Method method = getExceptionThrowingMethod(); - EventHandler handler = new EventHandler(this, method); + EventSubscriber subscriber = new EventSubscriber(this, method); try { - handler.handleEvent(new Object()); - fail("Handlers whose methods throw must throw InvocationTargetException"); + subscriber.handleEvent(new Object()); + fail("Subscribers whose methods throw must throw InvocationTargetException"); } catch (InvocationTargetException e) { assertTrue("Expected exception must be wrapped.", e.getCause() instanceof IntentionalException); @@ -74,11 +74,11 @@ public class EventHandlerTest extends TestCase { public void testErrorPassthrough() throws InvocationTargetException { Method method = getErrorThrowingMethod(); - EventHandler handler = new EventHandler(this, method); + EventSubscriber subscriber = new EventSubscriber(this, method); try { - handler.handleEvent(new Object()); - fail("Handlers whose methods throw Errors must rethrow them"); + subscriber.handleEvent(new Object()); + fail("Subscribers whose methods throw Errors must rethrow them"); } catch (JudgmentError e) { // Expected. } @@ -89,9 +89,9 @@ public class EventHandlerTest extends TestCase { Method concat = String.class.getMethod("concat", String.class); new EqualsTester() .addEqualityGroup( - new EventHandler("foo", charAt), new EventHandler("foo", charAt)) - .addEqualityGroup(new EventHandler("bar", charAt)) - .addEqualityGroup(new EventHandler("foo", concat)) + new EventSubscriber("foo", charAt), new EventSubscriber("foo", charAt)) + .addEqualityGroup(new EventSubscriber("bar", charAt)) + .addEqualityGroup(new EventSubscriber("foo", concat)) .testEquals(); } @@ -112,7 +112,7 @@ public class EventHandlerTest extends TestCase { throw new IllegalStateException("This test needs access to reflection."); } catch (NoSuchMethodException e) { throw new AssertionError( - "Someone changed EventHandlerTest#recordingMethod's visibility, " + + "Someone changed EventSubscriberTest#recordingMethod's visibility, " + "signature, or removed it entirely. (Must be public.)"); } return method; @@ -135,7 +135,7 @@ public class EventHandlerTest extends TestCase { throw new IllegalStateException("This test needs access to reflection."); } catch (NoSuchMethodException e) { throw new AssertionError( - "Someone changed EventHandlerTest#exceptionThrowingMethod's " + + "Someone changed EventSubscriberTest#exceptionThrowingMethod's " + "visibility, signature, or removed it entirely. (Must be public.)"); } return method; @@ -158,7 +158,7 @@ public class EventHandlerTest extends TestCase { throw new IllegalStateException("This test needs access to reflection."); } catch (NoSuchMethodException e) { throw new AssertionError( - "Someone changed EventHandlerTest#errorThrowingMethod's " + + "Someone changed EventSubscriberTest#errorThrowingMethod's " + "visibility, signature, or removed it entirely. (Must be public.)"); } return method; @@ -166,15 +166,13 @@ public class EventHandlerTest extends TestCase { /** * Records the provided object in {@link #methodArgument} and sets - * {@link #methodCalled}. This method is called reflectively by EventHandler + * {@link #methodCalled}. This method is called reflectively by EventSubscriber * during tests, and must remain public. * * @param arg argument to record. */ public void recordingMethod(Object arg) { - if (methodCalled == true) { - throw new IllegalStateException("Method called more than once."); - } + assertFalse(methodCalled); methodCalled = true; methodArgument = arg; } diff --git a/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java b/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java index 5024370..5f984b0 100644 --- a/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java +++ b/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java @@ -31,21 +31,21 @@ import javax.annotation.Nullable; public class PackageSanityTests extends AbstractPackageSanityTests { public PackageSanityTests() throws Exception { - setDefault(EventHandler.class, new DummyHandler().toEventHandler()); - setDefault(Method.class, DummyHandler.handlerMethod()); + setDefault(EventSubscriber.class, new DummySubscriber().toEventSubscriber()); + setDefault(Method.class, DummySubscriber.subscriberMethod()); } - private static class DummyHandler { + private static class DummySubscriber { @SuppressWarnings("unused") // Used by reflection public void handle(@Nullable Object anything) {} - EventHandler toEventHandler() throws Exception { - return new EventHandler(this, handlerMethod()); + EventSubscriber toEventSubscriber() throws Exception { + return new EventSubscriber(this, subscriberMethod()); } - private static Method handlerMethod() throws NoSuchMethodException { - return DummyHandler.class.getMethod("handle", Object.class); + private static Method subscriberMethod() throws NoSuchMethodException { + return DummySubscriber.class.getMethod("handle", Object.class); } } } diff --git a/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java b/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java index aac7868..f39f5f8 100644 --- a/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java +++ b/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java @@ -18,10 +18,10 @@ package com.google.common.eventbus; import com.google.common.collect.Lists; -import java.util.List; - import junit.framework.TestCase; +import java.util.List; + /** * Validate that {@link EventBus} behaves carefully when listeners publish * their own events. diff --git a/guava-tests/test/com/google/common/eventbus/StringCatcher.java b/guava-tests/test/com/google/common/eventbus/StringCatcher.java index ac61c03..e57397a 100644 --- a/guava-tests/test/com/google/common/eventbus/StringCatcher.java +++ b/guava-tests/test/com/google/common/eventbus/StringCatcher.java @@ -18,14 +18,14 @@ package com.google.common.eventbus; import com.google.common.collect.Lists; +import junit.framework.Assert; + import java.util.List; import javax.annotation.Nullable; -import junit.framework.Assert; - /** - * A simple EventHandler mock that records Strings. + * A simple EventSubscriber mock that records Strings. * * For testing fun, also includes a landmine method that EventBus tests are * required <em>not</em> to call ({@link #methodWithoutAnnotation(String)}). diff --git a/guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java b/guava-tests/test/com/google/common/eventbus/outside/AnnotatedSubscriberFinderTests.java index 393e771..922b956 100644 --- a/guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java +++ b/guava-tests/test/com/google/common/eventbus/outside/AnnotatedSubscriberFinderTests.java @@ -22,52 +22,49 @@ import com.google.common.collect.Lists; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; -import java.util.Collection; -import java.util.List; - import junit.framework.TestCase; -import org.truth0.subjects.CollectionSubject; +import java.util.List; /** - * Test that EventBus finds the correct handlers. + * Test that EventBus finds the correct subscribers. * * This test must be outside the c.g.c.eventbus package to test correctly. * @author Louis Wasserman */ -public class AnnotatedHandlerFinderTests { +public class AnnotatedSubscriberFinderTests { private static final Object EVENT = new Object(); abstract static class AbstractEventBusTest<H> extends TestCase { - abstract H createHandler(); + abstract H createSubscriber(); - private H handler; + private H subscriber; - H getHandler() { - return handler; + H getSubscriber() { + return subscriber; } @Override protected void setUp() throws Exception { - handler = createHandler(); + subscriber = createSubscriber(); EventBus bus = new EventBus(); - bus.register(handler); + bus.register(subscriber); bus.post(EVENT); } @Override protected void tearDown() throws Exception { - handler = null; + subscriber = null; } } /* * We break the tests up based on whether they are annotated or abstract in the superclass. */ - public static class BaseHandlerFinderTest extends - AbstractEventBusTest<BaseHandlerFinderTest.Handler> { - static class Handler { + public static class BaseSubscriberFinderTest extends + AbstractEventBusTest<BaseSubscriberFinderTest.Subscriber> { + static class Subscriber { final List<Object> nonSubscriberEvents = Lists.newArrayList(); final List<Object> subscriberEvents = Lists.newArrayList(); @@ -82,16 +79,16 @@ public class AnnotatedHandlerFinderTests { } public void testNonSubscriber() { - assertThat(getHandler().nonSubscriberEvents).isEmpty(); + ASSERT.that(getSubscriber().nonSubscriberEvents).isEmpty(); } public void testSubscriber() { - assertThat(getHandler().subscriberEvents).has().item(EVENT); + ASSERT.that(getSubscriber().subscriberEvents).has().item(EVENT); } @Override - Handler createHandler() { - return new Handler(); + Subscriber createSubscriber() { + return new Subscriber(); } } @@ -122,15 +119,15 @@ public class AnnotatedHandlerFinderTests { } public void testOverriddenAndAnnotatedInSubclass() { - assertThat(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT); } public void testOverriddenNotAnnotatedInSubclass() { - assertThat(getHandler().overriddenInSubclassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().overriddenInSubclassEvents).has().item(EVENT); } @Override - SubClass createHandler() { + SubClass createSubscriber() { return new SubClass(); } } @@ -202,31 +199,33 @@ public class AnnotatedHandlerFinderTests { } public void testNotOverriddenInSubclass() { - assertThat(getHandler().notOverriddenInSubclassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().notOverriddenInSubclassEvents).has().item(EVENT); } public void testOverriddenNotAnnotatedInSubclass() { - assertThat(getHandler().overriddenNotAnnotatedInSubclassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().overriddenNotAnnotatedInSubclassEvents).has().item(EVENT); } public void testDifferentlyOverriddenNotAnnotatedInSubclass() { - assertThat(getHandler().differentlyOverriddenNotAnnotatedInSubclassGoodEvents) + ASSERT + .that(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassGoodEvents) .has().item(EVENT); - assertThat(getHandler().differentlyOverriddenNotAnnotatedInSubclassBadEvents).isEmpty(); + ASSERT.that(getSubscriber().differentlyOverriddenNotAnnotatedInSubclassBadEvents).isEmpty(); } public void testOverriddenAndAnnotatedInSubclass() { - assertThat(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT); } public void testDifferentlyOverriddenAndAnnotatedInSubclass() { - assertThat(getHandler().differentlyOverriddenAnnotatedInSubclassGoodEvents) + ASSERT + .that(getSubscriber().differentlyOverriddenAnnotatedInSubclassGoodEvents) .has().item(EVENT); - assertThat(getHandler().differentlyOverriddenAnnotatedInSubclassBadEvents).isEmpty(); + ASSERT.that(getSubscriber().differentlyOverriddenAnnotatedInSubclassBadEvents).isEmpty(); } @Override - SubClass createHandler() { + SubClass createSubscriber() { return new SubClass(); } } @@ -256,15 +255,15 @@ public class AnnotatedHandlerFinderTests { } public void testOverriddenAndAnnotatedInSubclass() { - assertThat(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT); } public void testOverriddenInSubclassNowhereAnnotated() { - assertThat(getHandler().overriddenInSubclassNowhereAnnotatedEvents).isEmpty(); + ASSERT.that(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty(); } @Override - SubClass createHandler() { + SubClass createSubscriber() { return new SubClass(); } } @@ -303,25 +302,25 @@ public class AnnotatedHandlerFinderTests { } public void testNeitherOverriddenNorAnnotated() { - assertThat(getHandler().neitherOverriddenNorAnnotatedEvents).isEmpty(); + ASSERT.that(getSubscriber().neitherOverriddenNorAnnotatedEvents).isEmpty(); } public void testOverriddenInSubclassNowhereAnnotated() { - assertThat(getHandler().overriddenInSubclassNowhereAnnotatedEvents).isEmpty(); + ASSERT.that(getSubscriber().overriddenInSubclassNowhereAnnotatedEvents).isEmpty(); } public void testOverriddenAndAnnotatedInSubclass() { - assertThat(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT); } @Override - SubClass createHandler() { + SubClass createSubscriber() { return new SubClass(); } } public static class DeepInterfaceTest extends - AbstractEventBusTest<DeepInterfaceTest.HandlerClass> { + AbstractEventBusTest<DeepInterfaceTest.SubscriberClass> { interface Interface1 { @Subscribe void annotatedIn1(Object o); @@ -358,7 +357,7 @@ public class AnnotatedHandlerFinderTests { void annotatedIn2(Object o); } - static class HandlerClass implements Interface2 { + static class SubscriberClass implements Interface2 { final List<Object> annotatedIn1Events = Lists.newArrayList(); final List<Object> annotatedIn1And2Events = Lists.newArrayList(); final List<Object> annotatedIn1And2AndClassEvents = Lists.newArrayList(); @@ -413,46 +412,40 @@ public class AnnotatedHandlerFinderTests { } public void testAnnotatedIn1() { - assertThat(getHandler().annotatedIn1Events).has().item(EVENT); + ASSERT.that(getSubscriber().annotatedIn1Events).has().item(EVENT); } public void testAnnotatedIn2() { - assertThat(getHandler().annotatedIn2Events).has().item(EVENT); + ASSERT.that(getSubscriber().annotatedIn2Events).has().item(EVENT); } public void testAnnotatedIn1And2() { - assertThat(getHandler().annotatedIn1And2Events).has().item(EVENT); + ASSERT.that(getSubscriber().annotatedIn1And2Events).has().item(EVENT); } public void testAnnotatedIn1And2AndClass() { - assertThat(getHandler().annotatedIn1And2AndClassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().annotatedIn1And2AndClassEvents).has().item(EVENT); } public void testDeclaredIn1AnnotatedIn2() { - assertThat(getHandler().declaredIn1AnnotatedIn2Events).has().item(EVENT); + ASSERT.that(getSubscriber().declaredIn1AnnotatedIn2Events).has().item(EVENT); } public void testDeclaredIn1AnnotatedInClass() { - assertThat(getHandler().declaredIn1AnnotatedInClassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().declaredIn1AnnotatedInClassEvents).has().item(EVENT); } public void testDeclaredIn2AnnotatedInClass() { - assertThat(getHandler().declaredIn2AnnotatedInClassEvents).has().item(EVENT); + ASSERT.that(getSubscriber().declaredIn2AnnotatedInClassEvents).has().item(EVENT); } public void testNowhereAnnotated() { - (getHandler().nowhereAnnotatedEvents).isEmpty(); + ASSERT.that(getSubscriber().nowhereAnnotatedEvents).isEmpty(); } @Override - HandlerClass createHandler() { - return new HandlerClass(); + SubscriberClass createSubscriber() { + return new SubscriberClass(); } } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java b/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java index 9e0b626..d23e021 100644 --- a/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java +++ b/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java @@ -19,11 +19,11 @@ package com.google.common.eventbus.outside; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; +import junit.framework.TestCase; + import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import junit.framework.TestCase; - /** * Test cases for {@code EventBus} that must not be in the same package. * diff --git a/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java b/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java index abfca73..ee47a1b 100644 --- a/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java +++ b/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java @@ -135,7 +135,7 @@ public class AbstractByteHasherTest extends TestCase { @Override public HashCode hash() { - return HashCodes.fromBytesNoCopy(bytes()); + return HashCode.fromBytesNoCopy(bytes()); } } } diff --git a/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java b/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java index 264901d..e8a262e 100644 --- a/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java +++ b/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java @@ -22,6 +22,8 @@ import com.google.common.jdk5backport.Arrays; import junit.framework.TestCase; +import junit.framework.TestCase; + import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.nio.charset.Charset; @@ -87,7 +89,7 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase { for (int i = 0; i < s.length(); i++) { h1.putChar(s.charAt(i)); } - h2.putString(s); + h2.putUnencodedChars(s); assertEquals(h1.hash(), h2.hash()); } @@ -103,7 +105,7 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase { final ByteArrayOutputStream out = new ByteArrayOutputStream(); @Override HashCode makeHash() { - return HashCodes.fromBytes(out.toByteArray()); + return HashCode.fromBytes(out.toByteArray()); } @Override @@ -131,12 +133,12 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase { @Override public HashCode hashBytes(byte[] input) { - return HashCodes.fromBytes(input); + return HashCode.fromBytes(input); } @Override public HashCode hashBytes(byte[] input, int off, int len) { - return HashCodes.fromBytes(Arrays.copyOfRange(input, off, off + len)); + return HashCode.fromBytes(Arrays.copyOfRange(input, off, off + len)); } @Override diff --git a/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java b/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java index 8030cda..d4f2d2e 100644 --- a/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java +++ b/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java @@ -200,7 +200,7 @@ public class AbstractStreamingHasherTest extends TestCase { } @Override HashCode makeHash() { - return HashCodes.fromBytes(out.toByteArray()); + return HashCode.fromBytes(out.toByteArray()); } @Override protected void process(ByteBuffer bb) { @@ -251,7 +251,7 @@ public class AbstractStreamingHasherTest extends TestCase { private static class Control extends AbstractNonStreamingHashFunction { @Override public HashCode hashBytes(byte[] input) { - return HashCodes.fromBytes(input); + return HashCode.fromBytes(input); } @Override diff --git a/guava-tests/test/com/google/common/hash/BloomFilterTest.java b/guava-tests/test/com/google/common/hash/BloomFilterTest.java index c6a755a..be8c614 100644 --- a/guava-tests/test/com/google/common/hash/BloomFilterTest.java +++ b/guava-tests/test/com/google/common/hash/BloomFilterTest.java @@ -16,28 +16,46 @@ package com.google.common.hash; +import static com.google.common.hash.BloomFilterStrategies.BitArray; + import com.google.common.collect.ImmutableSet; +import com.google.common.math.LongMath; import com.google.common.primitives.Ints; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + +import java.math.RoundingMode; import java.util.Random; import javax.annotation.Nullable; -import junit.framework.TestCase; - /** * Tests for SimpleGenericBloomFilter and derived BloomFilter views. * * @author Dimitris Andreou */ public class BloomFilterTest extends TestCase { + public void testLargeBloomFilterDoesntOverflow() { + long numBits = Integer.MAX_VALUE; + numBits++; - public void testCreateAndCheckBloomFilterWithKnownFalsePositives() { + BitArray bitArray = new BitArray(numBits); + assertTrue( + "BitArray.bitSize() must return a positive number, but was " + bitArray.bitSize(), + bitArray.bitSize() > 0); + + // Ideally we would also test the bitSize() overflow of this BF, but it runs out of heap space + // BloomFilter.create(Funnels.unencodedCharsFunnel(), 244412641, 1e-11); + } + + public void testCreateAndCheckMitz32BloomFilterWithKnownFalsePositives() { int numInsertions = 1000000; - BloomFilter<CharSequence> bf = BloomFilter.create(Funnels.stringFunnel(), numInsertions); + BloomFilter<CharSequence> bf = BloomFilter.create( + Funnels.unencodedCharsFunnel(), numInsertions, 0.03, + BloomFilterStrategies.MURMUR128_MITZ_32); // Insert "numInsertions" even numbers into the BF. for (int i = 0; i < numInsertions * 2; i += 2) { @@ -74,6 +92,47 @@ public class BloomFilterTest extends TestCase { assertEquals(actualFpp, expectedFpp, 0.00015); } + public void testCreateAndCheckBloomFilterWithKnownFalsePositives64() { + int numInsertions = 1000000; + BloomFilter<CharSequence> bf = BloomFilter.create( + Funnels.unencodedCharsFunnel(), numInsertions, 0.03, + BloomFilterStrategies.MURMUR128_MITZ_64); + + // Insert "numInsertions" even numbers into the BF. + for (int i = 0; i < numInsertions * 2; i += 2) { + bf.put(Integer.toString(i)); + } + + // Assert that the BF "might" have all of the even numbers. + for (int i = 0; i < numInsertions * 2; i += 2) { + assertTrue(bf.mightContain(Integer.toString(i))); + } + + // Now we check for known false positives using a set of known false positives. + // (These are all of the false positives under 900.) + ImmutableSet<Integer> falsePositives = ImmutableSet.of( + 15, 25, 287, 319, 381, 399, 421, 465, 529, 697, 767, 857); + for (int i = 1; i < 900; i += 2) { + if (!falsePositives.contains(i)) { + assertFalse("BF should not contain " + i, bf.mightContain(Integer.toString(i))); + } + } + + // Check that there are exactly 30104 false positives for this BF. + int knownNumberOfFalsePositives = 30104; + int numFpp = 0; + for (int i = 1; i < numInsertions * 2; i += 2) { + if (bf.mightContain(Integer.toString(i))) { + numFpp++; + } + } + assertEquals(knownNumberOfFalsePositives, numFpp); + double actualFpp = (double) knownNumberOfFalsePositives / numInsertions; + double expectedFpp = bf.expectedFpp(); + // The normal order of (expected, actual) is reversed here on purpose. + assertEquals(actualFpp, expectedFpp, 0.00033); + } + /** * Sanity checking with many combinations of false positive rates and expected insertions */ @@ -87,19 +146,19 @@ public class BloomFilterTest extends TestCase { public void testPreconditions() { try { - BloomFilter.create(Funnels.stringFunnel(), -1); + BloomFilter.create(Funnels.unencodedCharsFunnel(), -1); fail(); } catch (IllegalArgumentException expected) {} try { - BloomFilter.create(Funnels.stringFunnel(), -1, 0.03); + BloomFilter.create(Funnels.unencodedCharsFunnel(), -1, 0.03); fail(); } catch (IllegalArgumentException expected) {} try { - BloomFilter.create(Funnels.stringFunnel(), 1, 0.0); + BloomFilter.create(Funnels.unencodedCharsFunnel(), 1, 0.0); fail(); } catch (IllegalArgumentException expected) {} try { - BloomFilter.create(Funnels.stringFunnel(), 1, 1.0); + BloomFilter.create(Funnels.unencodedCharsFunnel(), 1, 1.0); fail(); } catch (IllegalArgumentException expected) {} } @@ -108,14 +167,14 @@ public class BloomFilterTest extends TestCase { try { int n = 1000; double p = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000001; - BloomFilter.create(Funnels.stringFunnel(), n, p); + BloomFilter.create(Funnels.unencodedCharsFunnel(), n, p); fail(); } catch (IllegalArgumentException expected) {} } public void testNullPointers() { NullPointerTester tester = new NullPointerTester(); - tester.testAllPublicInstanceMethods(BloomFilter.create(Funnels.stringFunnel(), 100)); + tester.testAllPublicInstanceMethods(BloomFilter.create(Funnels.unencodedCharsFunnel(), 100)); tester.testAllPublicStaticMethods(BloomFilter.class); } @@ -169,7 +228,7 @@ public class BloomFilterTest extends TestCase { } public void testCopy() { - BloomFilter<CharSequence> original = BloomFilter.create(Funnels.stringFunnel(), 100); + BloomFilter<CharSequence> original = BloomFilter.create(Funnels.unencodedCharsFunnel(), 100); BloomFilter<CharSequence> copy = original.copy(); assertNotSame(original, copy); assertEquals(original, copy); @@ -189,25 +248,36 @@ public class BloomFilterTest extends TestCase { } } + public void testBitSize() { + double fpp = 0.03; + for (int i = 1; i < 10000; i++) { + long numBits = BloomFilter.optimalNumOfBits(i, fpp); + int arraySize = Ints.checkedCast(LongMath.divide(numBits, 64, RoundingMode.CEILING)); + assertEquals( + arraySize * Long.SIZE, + BloomFilter.create(Funnels.unencodedCharsFunnel(), i, fpp).bitSize()); + } + } + public void testEquals_empty() { new EqualsTester() .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 100, 0.01)) .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 100, 0.02)) .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 200, 0.01)) .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 200, 0.02)) - .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 100, 0.01)) - .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 100, 0.02)) - .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 200, 0.01)) - .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 200, 0.02)) + .addEqualityGroup(BloomFilter.create(Funnels.unencodedCharsFunnel(), 100, 0.01)) + .addEqualityGroup(BloomFilter.create(Funnels.unencodedCharsFunnel(), 100, 0.02)) + .addEqualityGroup(BloomFilter.create(Funnels.unencodedCharsFunnel(), 200, 0.01)) + .addEqualityGroup(BloomFilter.create(Funnels.unencodedCharsFunnel(), 200, 0.02)) .testEquals(); } public void testEquals() { - BloomFilter<CharSequence> bf1 = BloomFilter.create(Funnels.stringFunnel(), 100); + BloomFilter<CharSequence> bf1 = BloomFilter.create(Funnels.unencodedCharsFunnel(), 100); bf1.put("1"); bf1.put("2"); - BloomFilter<CharSequence> bf2 = BloomFilter.create(Funnels.stringFunnel(), 100); + BloomFilter<CharSequence> bf2 = BloomFilter.create(Funnels.unencodedCharsFunnel(), 100); bf2.put("1"); bf2.put("2"); @@ -250,7 +320,7 @@ public class BloomFilterTest extends TestCase { public void testPutReturnValue() { for (int i = 0; i < 10; i++) { - BloomFilter<CharSequence> bf = BloomFilter.create(Funnels.stringFunnel(), 100); + BloomFilter<CharSequence> bf = BloomFilter.create(Funnels.unencodedCharsFunnel(), 100); for (int j = 0; j < 10; j++) { String value = new Object().toString(); boolean mightContain = bf.mightContain(value); @@ -260,6 +330,57 @@ public class BloomFilterTest extends TestCase { } } + public void testPutAll() { + int element1 = 1; + int element2 = 2; + + BloomFilter<Integer> bf1 = BloomFilter.create(Funnels.integerFunnel(), 100); + bf1.put(element1); + assertTrue(bf1.mightContain(element1)); + assertFalse(bf1.mightContain(element2)); + + BloomFilter<Integer> bf2 = BloomFilter.create(Funnels.integerFunnel(), 100); + bf2.put(element2); + assertFalse(bf2.mightContain(element1)); + assertTrue(bf2.mightContain(element2)); + + assertTrue(bf1.isCompatible(bf2)); + bf1.putAll(bf2); + assertTrue(bf1.mightContain(element1)); + assertTrue(bf1.mightContain(element2)); + assertFalse(bf2.mightContain(element1)); + assertTrue(bf2.mightContain(element2)); + } + + public void testPutAllDifferentSizes() { + BloomFilter<Integer> bf1 = BloomFilter.create(Funnels.integerFunnel(), 1); + BloomFilter<Integer> bf2 = BloomFilter.create(Funnels.integerFunnel(), 10); + + try { + assertFalse(bf1.isCompatible(bf2)); + bf1.putAll(bf2); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + assertFalse(bf2.isCompatible(bf1)); + bf2.putAll(bf1); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testPutAllWithSelf() { + BloomFilter<Integer> bf1 = BloomFilter.create(Funnels.integerFunnel(), 1); + try { + assertFalse(bf1.isCompatible(bf1)); + bf1.putAll(bf1); + fail(); + } catch (IllegalArgumentException expected) { + } + } + public void testJavaSerialization() { BloomFilter<byte[]> bf = BloomFilter.create(Funnels.byteArrayFunnel(), 100); for (int i = 0; i < 10; i++) { @@ -280,7 +401,27 @@ public class BloomFilterTest extends TestCase { * Only appending a new constant is allowed. */ public void testBloomFilterStrategies() { - assertEquals(1, BloomFilterStrategies.values().length); + assertEquals(2, BloomFilterStrategies.values().length); assertEquals(BloomFilterStrategies.MURMUR128_MITZ_32, BloomFilterStrategies.values()[0]); + assertEquals(BloomFilterStrategies.MURMUR128_MITZ_64, BloomFilterStrategies.values()[1]); + } + + public void testGetDefaultStrategyFromSystemProperty() { + // clear the property to test the case when the property is not set (the default) + System.clearProperty(BloomFilter.USE_MITZ32_PROPERTY); + assertEquals(BloomFilterStrategies.MURMUR128_MITZ_64, + BloomFilter.getDefaultStrategyFromSystemProperty()); + + System.setProperty(BloomFilter.USE_MITZ32_PROPERTY, "true"); + assertEquals(BloomFilterStrategies.MURMUR128_MITZ_32, + BloomFilter.getDefaultStrategyFromSystemProperty()); + + System.setProperty(BloomFilter.USE_MITZ32_PROPERTY, "TRUE"); + assertEquals(BloomFilterStrategies.MURMUR128_MITZ_32, + BloomFilter.getDefaultStrategyFromSystemProperty()); + + System.setProperty(BloomFilter.USE_MITZ32_PROPERTY, "false"); + assertEquals(BloomFilterStrategies.MURMUR128_MITZ_64, + BloomFilter.getDefaultStrategyFromSystemProperty()); } } diff --git a/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java b/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java index ad83b2b..5b29c46 100644 --- a/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java +++ b/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java @@ -19,10 +19,10 @@ import static com.google.common.hash.Hashing.ChecksumType.CRC_32; import com.google.common.base.Supplier; -import java.util.zip.Checksum; - import junit.framework.TestCase; +import java.util.zip.Checksum; + /** * Tests for ChecksumHashFunction. * diff --git a/guava-tests/test/com/google/common/hash/FunnelsTest.java b/guava-tests/test/com/google/common/hash/FunnelsTest.java index 7a71157..f94e7b1 100644 --- a/guava-tests/test/com/google/common/hash/FunnelsTest.java +++ b/guava-tests/test/com/google/common/hash/FunnelsTest.java @@ -16,15 +16,23 @@ package com.google.common.hash; +import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import com.google.common.base.Charsets; import com.google.common.hash.AbstractStreamingHashFunction.AbstractStreamingHasher; +import com.google.common.testing.EqualsTester; +import com.google.common.testing.SerializableTester; + +import junit.framework.TestCase; + +import org.mockito.InOrder; import java.io.OutputStream; import java.nio.ByteBuffer; - -import junit.framework.TestCase; +import java.nio.charset.Charset; +import java.util.Arrays; /** * Tests for HashExtractors. @@ -33,9 +41,9 @@ import junit.framework.TestCase; */ public class FunnelsTest extends TestCase { public void testForBytes() { - PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class); - Funnels.byteArrayFunnel().funnel(new byte[] { 4, 3, 2, 1 }, bytePrimitiveSink); - verify(bytePrimitiveSink).putBytes(new byte[] { 4, 3, 2, 1 }); + PrimitiveSink primitiveSink = mock(PrimitiveSink.class); + Funnels.byteArrayFunnel().funnel(new byte[] { 4, 3, 2, 1 }, primitiveSink); + verify(primitiveSink).putBytes(new byte[] { 4, 3, 2, 1 }); } public void testForBytes_null() { @@ -43,20 +51,34 @@ public class FunnelsTest extends TestCase { } public void testForStrings() { - PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class); - Funnels.stringFunnel().funnel("test", bytePrimitiveSink); - verify(bytePrimitiveSink).putString("test"); + PrimitiveSink primitiveSink = mock(PrimitiveSink.class); + Funnels.unencodedCharsFunnel().funnel("test", primitiveSink); + verify(primitiveSink).putUnencodedChars("test"); } public void testForStrings_null() { - assertNullsThrowException(Funnels.stringFunnel()); + assertNullsThrowException(Funnels.unencodedCharsFunnel()); + } + + public void testForStringsCharset() { + for (Charset charset : Charset.availableCharsets().values()) { + PrimitiveSink primitiveSink = mock(PrimitiveSink.class); + Funnels.stringFunnel(charset).funnel("test", primitiveSink); + verify(primitiveSink).putString("test", charset); + } + } + + public void testForStringsCharset_null() { + for (Charset charset : Charset.availableCharsets().values()) { + assertNullsThrowException(Funnels.stringFunnel(charset)); + } } public void testForInts() { Integer value = 1234; - PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class); - Funnels.integerFunnel().funnel(value, bytePrimitiveSink); - verify(bytePrimitiveSink).putInt(1234); + PrimitiveSink primitiveSink = mock(PrimitiveSink.class); + Funnels.integerFunnel().funnel(value, primitiveSink); + verify(primitiveSink).putInt(1234); } public void testForInts_null() { @@ -65,17 +87,30 @@ public class FunnelsTest extends TestCase { public void testForLongs() { Long value = 1234L; - PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class); - Funnels.longFunnel().funnel(value, bytePrimitiveSink); - verify(bytePrimitiveSink).putLong(1234); + PrimitiveSink primitiveSink = mock(PrimitiveSink.class); + Funnels.longFunnel().funnel(value, primitiveSink); + verify(primitiveSink).putLong(1234); } public void testForLongs_null() { assertNullsThrowException(Funnels.longFunnel()); } + public void testSequential() { + @SuppressWarnings("unchecked") + Funnel<Object> elementFunnel = mock(Funnel.class); + PrimitiveSink primitiveSink = mock(PrimitiveSink.class); + Funnel<Iterable<? extends Object>> sequential = Funnels.sequentialFunnel(elementFunnel); + sequential.funnel(Arrays.asList("foo", "bar", "baz", "quux"), primitiveSink); + InOrder inOrder = inOrder(elementFunnel); + inOrder.verify(elementFunnel).funnel("foo", primitiveSink); + inOrder.verify(elementFunnel).funnel("bar", primitiveSink); + inOrder.verify(elementFunnel).funnel("baz", primitiveSink); + inOrder.verify(elementFunnel).funnel("quux", primitiveSink); + } + private static void assertNullsThrowException(Funnel<?> funnel) { - PrimitiveSink bytePrimitiveSink = new AbstractStreamingHasher(4, 4) { + PrimitiveSink primitiveSink = new AbstractStreamingHasher(4, 4) { @Override HashCode makeHash() { throw new UnsupportedOperationException(); } @Override protected void process(ByteBuffer bb) { @@ -85,11 +120,11 @@ public class FunnelsTest extends TestCase { } }; try { - funnel.funnel(null, bytePrimitiveSink); + funnel.funnel(null, primitiveSink); fail(); } catch (NullPointerException ok) {} } - + public void testAsOutputStream() throws Exception { PrimitiveSink sink = mock(PrimitiveSink.class); OutputStream out = Funnels.asOutputStream(sink); @@ -101,4 +136,40 @@ public class FunnelsTest extends TestCase { verify(sink).putBytes(bytes); verify(sink).putBytes(bytes, 1, 2); } + + public void testSerialization() { + assertSame( + Funnels.byteArrayFunnel(), + SerializableTester.reserialize(Funnels.byteArrayFunnel())); + assertSame( + Funnels.integerFunnel(), + SerializableTester.reserialize(Funnels.integerFunnel())); + assertSame( + Funnels.longFunnel(), + SerializableTester.reserialize(Funnels.longFunnel())); + assertSame( + Funnels.unencodedCharsFunnel(), + SerializableTester.reserialize(Funnels.unencodedCharsFunnel())); + assertEquals( + Funnels.sequentialFunnel(Funnels.integerFunnel()), + SerializableTester.reserialize(Funnels.sequentialFunnel(Funnels.integerFunnel()))); + assertEquals( + Funnels.stringFunnel(Charsets.US_ASCII), + SerializableTester.reserialize(Funnels.stringFunnel(Charsets.US_ASCII))); + } + + public void testEquals() { + new EqualsTester() + .addEqualityGroup(Funnels.byteArrayFunnel()) + .addEqualityGroup(Funnels.integerFunnel()) + .addEqualityGroup(Funnels.longFunnel()) + .addEqualityGroup(Funnels.unencodedCharsFunnel()) + .addEqualityGroup(Funnels.stringFunnel(Charsets.UTF_8)) + .addEqualityGroup(Funnels.stringFunnel(Charsets.US_ASCII)) + .addEqualityGroup(Funnels.sequentialFunnel(Funnels.integerFunnel()), + SerializableTester.reserialize(Funnels.sequentialFunnel( + Funnels.integerFunnel()))) + .addEqualityGroup(Funnels.sequentialFunnel(Funnels.longFunnel())) + .testEquals(); + } } diff --git a/guava-tests/test/com/google/common/hash/HashCodeTest.java b/guava-tests/test/com/google/common/hash/HashCodeTest.java new file mode 100644 index 0000000..121d983 --- /dev/null +++ b/guava-tests/test/com/google/common/hash/HashCodeTest.java @@ -0,0 +1,395 @@ +/* + * Copyright (C) 2011 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.hash; + +import static com.google.common.io.BaseEncoding.base16; + +import com.google.common.collect.ImmutableList; +import com.google.common.io.BaseEncoding; +import com.google.common.jdk5backport.Arrays; +import com.google.common.testing.ClassSanityTester; + +import junit.framework.TestCase; + +/** + * Unit tests for {@link HashCode}. + * + * @author Dimitris Andreou + * @author Kurt Alfred Kluever + */ +public class HashCodeTest extends TestCase { + // note: asInt(), asLong() are in little endian + private static final ImmutableList<ExpectedHashCode> expectedHashCodes = ImmutableList.of( + new ExpectedHashCode(new byte[] { + (byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x89, + (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01}, + 0x89abcdef, 0x0123456789abcdefL, "efcdab8967452301"), + + new ExpectedHashCode(new byte[] { + (byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x89, + (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01, // up to here, same bytes as above + (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08}, + 0x89abcdef, 0x0123456789abcdefL, // asInt/asLong as above, due to equal eight first bytes + "efcdab89674523010102030405060708"), + + new ExpectedHashCode(new byte[] { (byte) 0xdf, (byte) 0x9b, (byte) 0x57, (byte) 0x13 }, + 0x13579bdf, null, "df9b5713"), + + new ExpectedHashCode(new byte[] { + (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00}, + 0x0000abcd, null, "cdab0000"), + + new ExpectedHashCode(new byte[] { + (byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}, + 0x00abcdef, 0x0000000000abcdefL, "efcdab0000000000") + ); + + // expectedHashCodes must contain at least one hash code with 4 bytes + public void testFromInt() { + for (ExpectedHashCode expected : expectedHashCodes) { + if (expected.bytes.length == 4) { + HashCode fromInt = HashCode.fromInt(expected.asInt); + assertExpectedHashCode(expected, fromInt); + } + } + } + + // expectedHashCodes must contain at least one hash code with 8 bytes + public void testFromLong() { + for (ExpectedHashCode expected : expectedHashCodes) { + if (expected.bytes.length == 8) { + HashCode fromLong = HashCode.fromLong(expected.asLong); + assertExpectedHashCode(expected, fromLong); + } + } + } + + public void testFromBytes() { + for (ExpectedHashCode expected : expectedHashCodes) { + HashCode fromBytes = HashCode.fromBytes(expected.bytes); + assertExpectedHashCode(expected, fromBytes); + } + } + + public void testFromBytes_copyOccurs() { + byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 }; + HashCode hashCode = HashCode.fromBytes(bytes); + int expectedInt = 0x0000abcd; + String expectedToString = "cdab0000"; + + assertEquals(expectedInt, hashCode.asInt()); + assertEquals(expectedToString, hashCode.toString()); + + bytes[0] = (byte) 0x00; + + assertEquals(expectedInt, hashCode.asInt()); + assertEquals(expectedToString, hashCode.toString()); + } + + public void testFromBytesNoCopy_noCopyOccurs() { + byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 }; + HashCode hashCode = HashCode.fromBytesNoCopy(bytes); + + assertEquals(0x0000abcd, hashCode.asInt()); + assertEquals("cdab0000", hashCode.toString()); + + bytes[0] = (byte) 0x00; + + assertEquals(0x0000ab00, hashCode.asInt()); + assertEquals("00ab0000", hashCode.toString()); + } + + public void testGetBytesInternal_noCloneOccurs() { + byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 }; + HashCode hashCode = HashCode.fromBytes(bytes); + + assertEquals(0x0000abcd, hashCode.asInt()); + assertEquals("cdab0000", hashCode.toString()); + + hashCode.getBytesInternal()[0] = (byte) 0x00; + + assertEquals(0x0000ab00, hashCode.asInt()); + assertEquals("00ab0000", hashCode.toString()); + } + + public void testPadToLong() { + assertEquals(0x1111111111111111L, HashCode.fromLong(0x1111111111111111L).padToLong()); + assertEquals(0x9999999999999999L, HashCode.fromLong(0x9999999999999999L).padToLong()); + assertEquals(0x0000000011111111L, HashCode.fromInt(0x11111111).padToLong()); + assertEquals(0x0000000099999999L, HashCode.fromInt(0x99999999).padToLong()); + } + + public void testPadToLongWith4Bytes() { + assertEquals(0x0000000099999999L, HashCode.fromBytesNoCopy(byteArrayWith9s(4)).padToLong()); + } + + public void testPadToLongWith6Bytes() { + assertEquals(0x0000999999999999L, HashCode.fromBytesNoCopy(byteArrayWith9s(6)).padToLong()); + } + + public void testPadToLongWith8Bytes() { + assertEquals(0x9999999999999999L, HashCode.fromBytesNoCopy(byteArrayWith9s(8)).padToLong()); + } + + private static byte[] byteArrayWith9s(int size) { + byte[] bytez = new byte[size]; + Arrays.fill(bytez, (byte) 0x99); + return bytez; + } + + public void testToString() { + byte[] data = new byte[] { 127, -128, 5, -1, 14 }; + assertEquals("7f8005ff0e", HashCode.fromBytes(data).toString()); + assertEquals("7f8005ff0e", base16().lowerCase().encode(data)); + } + + public void testHashCode_nulls() throws Exception { + sanityTester().testNulls(); + } + + public void testHashCode_equalsAndSerializable() throws Exception { + sanityTester().testEqualsAndSerializable(); + } + + public void testRoundTripHashCodeUsingBaseEncoding() { + HashCode hash1 = Hashing.sha1().hashString("foo"); + HashCode hash2 = + HashCode.fromBytes(BaseEncoding.base16().lowerCase().decode(hash1.toString())); + assertEquals(hash1, hash2); + } + + public void testObjectHashCode() { + HashCode hashCode42 = HashCode.fromInt(42); + assertEquals(42, hashCode42.hashCode()); + } + + // See https://code.google.com/p/guava-libraries/issues/detail?id=1494 + public void testObjectHashCodeWithSameLowOrderBytes() { + // These will have the same first 4 bytes (all 0). + byte[] bytesA = new byte[5]; + byte[] bytesB = new byte[5]; + + // Change only the last (5th) byte + bytesA[4] = (byte) 0xbe; + bytesB[4] = (byte) 0xef; + + HashCode hashCodeA = HashCode.fromBytes(bytesA); + HashCode hashCodeB = HashCode.fromBytes(bytesB); + + // They aren't equal... + assertFalse(hashCodeA.equals(hashCodeB)); + + // But they still have the same Object#hashCode() value. + // Technically not a violation of the equals/hashCode contract, but...? + assertEquals(hashCodeA.hashCode(), hashCodeB.hashCode()); + } + + public void testRoundTripHashCodeUsingFromString() { + HashCode hash1 = Hashing.sha1().hashString("foo"); + HashCode hash2 = HashCode.fromString(hash1.toString()); + assertEquals(hash1, hash2); + } + + public void testRoundTrip() { + for (ExpectedHashCode expected : expectedHashCodes) { + String string = HashCodes.fromBytes(expected.bytes).toString(); + assertEquals(expected.toString, string); + assertEquals( + expected.toString, + HashCodes.fromBytes( + BaseEncoding.base16().lowerCase().decode(string)).toString()); + } + } + + public void testFromStringFailsWithInvalidHexChar() { + try { + HashCode.fromString("7f8005ff0z"); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testFromStringFailsWithUpperCaseString() { + String string = Hashing.sha1().hashString("foo").toString().toUpperCase(); + try { + HashCode.fromString(string); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testFromStringFailsWithShortInputs() { + try { + HashCode.fromString(""); + fail(); + } catch (IllegalArgumentException expected) { + } + try { + HashCode.fromString("7"); + fail(); + } catch (IllegalArgumentException expected) { + } + HashCode.fromString("7f"); + } + + public void testFromStringFailsWithOddLengthInput() { + try { + HashCode.fromString("7f8"); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testIntWriteBytesTo() { + byte[] dest = new byte[4]; + HashCodes.fromInt(42).writeBytesTo(dest, 0, 4); + assertTrue(Arrays.equals( + HashCodes.fromInt(42).asBytes(), + dest)); + } + + public void testLongWriteBytesTo() { + byte[] dest = new byte[8]; + HashCodes.fromLong(42).writeBytesTo(dest, 0, 8); + assertTrue(Arrays.equals( + HashCodes.fromLong(42).asBytes(), + dest)); + } + + private static final HashCode HASH_ABCD = + HashCode.fromBytes(new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd }); + + public void testWriteBytesTo() { + byte[] dest = new byte[4]; + HASH_ABCD.writeBytesTo(dest, 0, 4); + assertTrue(Arrays.equals( + new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd }, + dest)); + } + + public void testWriteBytesToOversizedArray() { + byte[] dest = new byte[5]; + HASH_ABCD.writeBytesTo(dest, 0, 4); + assertTrue(Arrays.equals( + new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0x00 }, + dest)); + } + + public void testWriteBytesToOversizedArrayLongMaxLength() { + byte[] dest = new byte[5]; + HASH_ABCD.writeBytesTo(dest, 0, 5); + assertTrue(Arrays.equals( + new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0x00 }, + dest)); + } + + public void testWriteBytesToOversizedArrayShortMaxLength() { + byte[] dest = new byte[5]; + HASH_ABCD.writeBytesTo(dest, 0, 3); + assertTrue(Arrays.equals( + new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0x00, (byte) 0x00 }, + dest)); + } + + public void testWriteBytesToUndersizedArray() { + byte[] dest = new byte[3]; + try { + HASH_ABCD.writeBytesTo(dest, 0, 4); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + } + + public void testWriteBytesToUndersizedArrayLongMaxLength() { + byte[] dest = new byte[3]; + try { + HASH_ABCD.writeBytesTo(dest, 0, 5); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + } + + public void testWriteBytesToUndersizedArrayShortMaxLength() { + byte[] dest = new byte[3]; + HASH_ABCD.writeBytesTo(dest, 0, 2); + assertTrue(Arrays.equals( + new byte[] { (byte) 0xaa, (byte) 0xbb, (byte) 0x00 }, + dest)); + } + + private static ClassSanityTester.FactoryMethodReturnValueTester sanityTester() { + return new ClassSanityTester() + .setDefault(byte[].class, new byte[] {1, 2, 3, 4}) + .setDistinctValues(byte[].class, new byte[] {1, 2, 3, 4}, new byte[] {5, 6, 7, 8}) + .setDistinctValues(String.class, "7f8005ff0e", "7f8005ff0f") + .forAllPublicStaticMethods(HashCode.class); + } + + private static void assertExpectedHashCode(ExpectedHashCode expectedHashCode, HashCode hash) { + assertTrue(Arrays.equals(expectedHashCode.bytes, hash.asBytes())); + byte[] bb = new byte[hash.bits() / 8]; + hash.writeBytesTo(bb, 0, bb.length); + assertTrue(Arrays.equals(expectedHashCode.bytes, bb)); + assertEquals(expectedHashCode.asInt, hash.asInt()); + if (expectedHashCode.asLong == null) { + try { + hash.asLong(); + fail(); + } catch (IllegalStateException expected) {} + } else { + assertEquals(expectedHashCode.asLong.longValue(), hash.asLong()); + } + assertEquals(expectedHashCode.toString, hash.toString()); + assertSideEffectFree(hash); + assertReadableBytes(hash); + } + + private static void assertSideEffectFree(HashCode hash) { + byte[] original = hash.asBytes(); + byte[] mutated = hash.asBytes(); + mutated[0]++; + assertTrue(Arrays.equals(original, hash.asBytes())); + } + + private static void assertReadableBytes(HashCode hashCode) { + assertTrue(hashCode.bits() >= 32); // sanity + byte[] hashBytes = hashCode.asBytes(); + int totalBytes = hashCode.bits() / 8; + + for (int bytes = 0; bytes < totalBytes; bytes++) { + byte[] bb = new byte[bytes]; + hashCode.writeBytesTo(bb, 0, bb.length); + + assertTrue(Arrays.equals(Arrays.copyOf(hashBytes, bytes), bb)); + } + } + + private static class ExpectedHashCode { + final byte[] bytes; + final int asInt; + final Long asLong; // null means that asLong should throw an exception + final String toString; + ExpectedHashCode(byte[] bytes, int asInt, Long asLong, String toString) { + this.bytes = bytes; + this.asInt = asInt; + this.asLong = asLong; + this.toString = toString; + } + } +} diff --git a/guava-tests/test/com/google/common/hash/HashCodesTest.java b/guava-tests/test/com/google/common/hash/HashCodesTest.java deleted file mode 100644 index 0b9709a..0000000 --- a/guava-tests/test/com/google/common/hash/HashCodesTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.hash; - -import static com.google.common.jdk5backport.Arrays.copyOf; - -import com.google.common.collect.ImmutableList; -import com.google.common.testing.ClassSanityTester; - -import junit.framework.TestCase; - -import java.util.Arrays; - -/** - * Tests for HashCodes, especially making sure that their endianness promises (big-endian) - * are upheld. - * - * @author Dimitris Andreou - */ -public class HashCodesTest extends TestCase { - // note: asInt(), asLong() are in little endian - private static final ImmutableList<ExpectedHashCode> expectedHashCodes = ImmutableList.of( - new ExpectedHashCode(new byte[] { - (byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x89, - (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01}, - 0x89abcdef, 0x0123456789abcdefL, "efcdab8967452301"), - - new ExpectedHashCode(new byte[] { - (byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x89, - (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01, // up to here, same bytes as above - (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08}, - 0x89abcdef, 0x0123456789abcdefL, // asInt/asLong as above, due to equal eight first bytes - "efcdab89674523010102030405060708"), - - new ExpectedHashCode(new byte[] { (byte) 0xdf, (byte) 0x9b, (byte) 0x57, (byte) 0x13 }, - 0x13579bdf, null, "df9b5713"), - - new ExpectedHashCode(new byte[] { - (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00}, - 0x0000abcd, null, "cdab0000"), - - new ExpectedHashCode(new byte[] { - (byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}, - 0x00abcdef, 0x0000000000abcdefL, "efcdab0000000000") - ); - - // expectedHashCodes must contain at least one hash code with 4 bytes - public void testFromInt() { - for (ExpectedHashCode expected : expectedHashCodes) { - if (expected.bytes.length == 4) { - HashCode fromInt = HashCodes.fromInt(expected.asInt); - assertExpectedHashCode(expected, fromInt); - } - } - } - - // expectedHashCodes must contain at least one hash code with 8 bytes - public void testFromLong() { - for (ExpectedHashCode expected : expectedHashCodes) { - if (expected.bytes.length == 8) { - HashCode fromLong = HashCodes.fromLong(expected.asLong); - assertExpectedHashCode(expected, fromLong); - } - } - } - - public void testFromBytes() { - for (ExpectedHashCode expected : expectedHashCodes) { - HashCode fromBytes = HashCodes.fromBytes(expected.bytes); - assertExpectedHashCode(expected, fromBytes); - } - } - - public void testFromBytes_copyOccurs() { - byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 }; - HashCode hashCode = HashCodes.fromBytes(bytes); - int expectedInt = 0x0000abcd; - String expectedToString = "cdab0000"; - - assertEquals(expectedInt, hashCode.asInt()); - assertEquals(expectedToString, hashCode.toString()); - - bytes[0] = (byte) 0x00; - - assertEquals(expectedInt, hashCode.asInt()); - assertEquals(expectedToString, hashCode.toString()); - } - - public void testFromBytesNoCopy_noCopyOccurs() { - byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 }; - HashCode hashCode = HashCodes.fromBytesNoCopy(bytes); - - assertEquals(0x0000abcd, hashCode.asInt()); - assertEquals("cdab0000", hashCode.toString()); - - bytes[0] = (byte) 0x00; - - assertEquals(0x0000ab00, hashCode.asInt()); - assertEquals("00ab0000", hashCode.toString()); - } - - public void testPadToLong() { - assertEquals(0x1111111111111111L, HashCodes.fromLong(0x1111111111111111L).padToLong()); - assertEquals(0x9999999999999999L, HashCodes.fromLong(0x9999999999999999L).padToLong()); - assertEquals(0x0000000011111111L, HashCodes.fromInt(0x11111111).padToLong()); - assertEquals(0x0000000099999999L, HashCodes.fromInt(0x99999999).padToLong()); - - byte[] longBytes = {(byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99, - (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99}; - byte[] intBytes = {(byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99}; - assertEquals(0x9999999999999999L, HashCodes.fromBytesNoCopy(longBytes).padToLong()); - assertEquals(0x0000000099999999L, HashCodes.fromBytesNoCopy(intBytes).padToLong()); - } - - public void testHashCodes_nulls() throws Exception { - sanityTester().testNulls(); - } - - public void testHashCodes_equalsAndSerializable() throws Exception { - sanityTester().testEqualsAndSerializable(); - } - - private static ClassSanityTester.FactoryMethodReturnValueTester sanityTester() { - return new ClassSanityTester() - .setDefault(byte[].class, new byte[] {1, 2, 3, 4}) - .setSampleInstances(byte[].class, - ImmutableList.of(new byte[] {1, 2, 3, 4}, new byte[] {5, 6, 7, 8})) - .forAllPublicStaticMethods(HashCodes.class); - } - - private static void assertExpectedHashCode(ExpectedHashCode expected, HashCode hash) { - assertTrue(Arrays.equals(expected.bytes, hash.asBytes())); - byte[] bb = new byte[hash.bits() / 8]; - hash.writeBytesTo(bb, 0, bb.length); - assertTrue(Arrays.equals(expected.bytes, bb)); - assertEquals(expected.asInt, hash.asInt()); - if (expected.asLong == null) { - try { - hash.asLong(); - fail(); - } catch (IllegalStateException ok) {} - } else { - assertEquals(expected.asLong.longValue(), hash.asLong()); - } - assertEquals(expected.toString, hash.toString()); - assertSideEffectFree(hash); - assertReadableBytes(hash); - } - - private static void assertSideEffectFree(HashCode hash) { - byte[] original = hash.asBytes(); - byte[] mutated = hash.asBytes(); - mutated[0]++; - assertTrue(Arrays.equals(original, hash.asBytes())); - } - - private static void assertReadableBytes(HashCode hashCode) { - assertTrue(hashCode.bits() >= 32); // sanity - byte[] hashBytes = hashCode.asBytes(); - int totalBytes = hashCode.bits() / 8; - - for (int bytes = 0; bytes < totalBytes; bytes++) { - byte[] bb = new byte[bytes]; - hashCode.writeBytesTo(bb, 0, bb.length); - - assertTrue(Arrays.equals(copyOf(hashBytes, bytes), bb)); - } - } - - private static class ExpectedHashCode { - final byte[] bytes; - final int asInt; - final Long asLong; // null means that asLong should throw an exception - final String toString; - ExpectedHashCode(byte[] bytes, int asInt, Long asLong, String toString) { - this.bytes = bytes; - this.asInt = asInt; - this.asLong = asLong; - this.toString = toString; - } - } -} diff --git a/guava-tests/test/com/google/common/hash/HashFunctionEnum.java b/guava-tests/test/com/google/common/hash/HashFunctionEnum.java new file mode 100644 index 0000000..7a2d390 --- /dev/null +++ b/guava-tests/test/com/google/common/hash/HashFunctionEnum.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.hash; + +/** + * An enum that contains all of the known hash functions. + * + * @author Kurt Alfred Kluever + */ +enum HashFunctionEnum { + ADLER32(Hashing.adler32()), + CRC32(Hashing.crc32()), + GOOD_FAST_HASH_32(Hashing.goodFastHash(32)), + GOOD_FAST_HASH_64(Hashing.goodFastHash(64)), + GOOD_FAST_HASH_128(Hashing.goodFastHash(128)), + GOOD_FAST_HASH_256(Hashing.goodFastHash(256)), + MD5(Hashing.md5()), + MURMUR3_128(Hashing.murmur3_128()), + MURMUR3_32(Hashing.murmur3_32()), + SHA1(Hashing.sha1()), + SHA256(Hashing.sha256()), + SHA512(Hashing.sha512()), + SIP_HASH24(Hashing.sipHash24()), + + // Hash functions found in //javatests for comparing against current implementation of CityHash. + // These can probably be removed sooner or later. + ; + + private final HashFunction hashFunction; + + private HashFunctionEnum(HashFunction hashFunction) { + this.hashFunction = hashFunction; + } + + HashFunction getHashFunction() { + return hashFunction; + } +} diff --git a/guava-tests/test/com/google/common/hash/HashTestUtils.java b/guava-tests/test/com/google/common/hash/HashTestUtils.java index c1dc7cd..5427513 100644 --- a/guava-tests/test/com/google/common/hash/HashTestUtils.java +++ b/guava-tests/test/com/google/common/hash/HashTestUtils.java @@ -19,7 +19,6 @@ package com.google.common.hash; import static org.junit.Assert.assertEquals; import com.google.common.base.Charsets; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.google.common.jdk5backport.Arrays; @@ -181,7 +180,7 @@ final class HashTestUtils { } String s = new String(value); for (PrimitiveSink sink : sinks) { - sink.putString(s); + sink.putUnencodedChars(s); } } }, @@ -189,7 +188,7 @@ final class HashTestUtils { @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) { String s = new String(new char[] { randomLowSurrogate(random) }); for (PrimitiveSink sink : sinks) { - sink.putString(s); + sink.putUnencodedChars(s); } } }, @@ -197,7 +196,7 @@ final class HashTestUtils { @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) { String s = new String(new char[] { randomHighSurrogate(random) }); for (PrimitiveSink sink : sinks) { - sink.putString(s); + sink.putUnencodedChars(s); } } }, @@ -206,7 +205,7 @@ final class HashTestUtils { String s = new String(new char[] { randomLowSurrogate(random), randomHighSurrogate(random)}); for (PrimitiveSink sink : sinks) { - sink.putString(s); + sink.putUnencodedChars(s); } } }, @@ -215,7 +214,7 @@ final class HashTestUtils { String s = new String(new char[] { randomHighSurrogate(random), randomLowSurrogate(random)}); for (PrimitiveSink sink : sinks) { - sink.putString(s); + sink.putUnencodedChars(s); } } }; @@ -260,8 +259,8 @@ final class HashTestUtils { // flip input bit for key2 int key2 = key1 ^ (1 << i); // get hashes - int hash1 = function.newHasher().putInt(key1).hash().asInt(); - int hash2 = function.newHasher().putInt(key2).hash().asInt(); + int hash1 = function.hashInt(key1).asInt(); + int hash2 = function.hashInt(key2).asInt(); // test whether the hash values have same output bits same |= ~(hash1 ^ hash2); // test whether the hash values have different output bits @@ -299,8 +298,8 @@ final class HashTestUtils { // flip input bit for key2 int key2 = key1 ^ (1 << i); // compute hash values - int hash1 = function.newHasher().putInt(key1).hash().asInt(); - int hash2 = function.newHasher().putInt(key2).hash().asInt(); + int hash1 = function.hashInt(key1).asInt(); + int hash2 = function.hashInt(key2).asInt(); for (int k = 0; k < hashBits; k++) { if ((hash1 & (1 << k)) == (hash2 & (1 << k))) { same[k] += 1; @@ -338,15 +337,15 @@ final class HashTestUtils { int maxCount = 20; // the probability of error here is miniscule boolean diff = false; - while (diff == false) { + while (!diff) { int delta = (1 << i) | (1 << j); int key1 = rand.nextInt(); // apply delta int key2 = key1 ^ delta; // get hashes - int hash1 = function.newHasher().putInt(key1).hash().asInt(); - int hash2 = function.newHasher().putInt(key2).hash().asInt(); + int hash1 = function.hashInt(key1).asInt(); + int hash2 = function.hashInt(key2).asInt(); // this 2-bit candidate delta is not a characteristic // if deltas are different @@ -389,8 +388,8 @@ final class HashTestUtils { // flip input bit for key2 int key2 = key1 ^ delta; // compute hash values - int hash1 = function.newHasher().putInt(key1).hash().asInt(); - int hash2 = function.newHasher().putInt(key2).hash().asInt(); + int hash1 = function.hashInt(key1).asInt(); + int hash2 = function.hashInt(key2).asInt(); for (int k = 0; k < hashBits; k++) { if ((hash1 & (1 << k)) == (hash2 & (1 << k))) { same[k] += 1; @@ -511,7 +510,7 @@ final class HashTestUtils { hashFunction.newHasher().putLong(l).hash()); } - private static final ImmutableList<Charset> CHARSETS = ImmutableList.of( + private static final ImmutableSet<Charset> CHARSETS = ImmutableSet.of( Charsets.ISO_8859_1, Charsets.US_ASCII, Charsets.UTF_16, @@ -523,12 +522,14 @@ final class HashTestUtils { // Test that only data and data-order is important, not the individual operations. new EqualsTester() .addEqualityGroup( - hashFunction.newHasher().putString("abc").hash(), - hashFunction.newHasher().putString("ab").putString("c").hash(), - hashFunction.newHasher().putString("a").putString("bc").hash(), - hashFunction.newHasher().putString("a").putString("b").putString("c").hash(), - hashFunction.newHasher().putChar('a').putString("bc").hash(), - hashFunction.newHasher().putString("ab").putChar('c').hash(), + hashFunction.hashUnencodedChars("abc"), + hashFunction.newHasher().putUnencodedChars("abc").hash(), + hashFunction.newHasher().putUnencodedChars("ab").putUnencodedChars("c").hash(), + hashFunction.newHasher().putUnencodedChars("a").putUnencodedChars("bc").hash(), + hashFunction.newHasher().putUnencodedChars("a").putUnencodedChars("b") + .putUnencodedChars("c").hash(), + hashFunction.newHasher().putChar('a').putUnencodedChars("bc").hash(), + hashFunction.newHasher().putUnencodedChars("ab").putChar('c').hash(), hashFunction.newHasher().putChar('a').putChar('b').putChar('c').hash()) .testEquals(); @@ -536,13 +537,8 @@ final class HashTestUtils { byte[] bytes = new byte[size]; random.nextBytes(bytes); String string = new String(bytes); - assertEquals(hashFunction.hashString(string), - hashFunction.newHasher().putString(string).hash()); - // These assertions causes failures when testing with mvn. See b/6657789 - // assertEquals(hashFunction.hashString(string), - // hashFunction.hashString(string, Charsets.UTF_16LE)); - // assertEquals(hashFunction.hashString(string), - // hashFunction.newHasher().putString(string, Charsets.UTF_16LE).hash()); + assertEquals(hashFunction.hashUnencodedChars(string), + hashFunction.newHasher().putUnencodedChars(string).hash()); for (Charset charset : CHARSETS) { assertEquals(hashFunction.hashString(string, charset), hashFunction.newHasher().putString(string, charset).hash()); @@ -550,9 +546,9 @@ final class HashTestUtils { } /** - * This verifies that putString(String) and hashString(String) are equivalent, even for - * funny strings composed by (possibly unmatched, and mostly illegal) surrogate characters. - * (But doesn't test that they do the right thing - just their consistency). + * This verifies that putUnencodedChars(String) and hashUnencodedChars(String) are equivalent, + * even for funny strings composed by (possibly unmatched, and mostly illegal) surrogate + * characters. (But doesn't test that they do the right thing - just their consistency). */ private static void assertHashStringWithSurrogatesEquivalence( HashFunction hashFunction, Random random) { @@ -562,8 +558,8 @@ final class HashTestUtils { chars[i] = random.nextBoolean() ? randomLowSurrogate(random) : randomHighSurrogate(random); } String string = new String(chars); - assertEquals(hashFunction.hashString(string), - hashFunction.newHasher().putString(string).hash()); + assertEquals(hashFunction.hashUnencodedChars(string), + hashFunction.newHasher().putUnencodedChars(string).hash()); } static char randomLowSurrogate(Random random) { diff --git a/guava-tests/test/com/google/common/hash/HashingInputStreamTest.java b/guava-tests/test/com/google/common/hash/HashingInputStreamTest.java new file mode 100644 index 0000000..f6709ce --- /dev/null +++ b/guava-tests/test/com/google/common/hash/HashingInputStreamTest.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.hash; + +import static org.easymock.EasyMock.aryEq; +import static org.easymock.EasyMock.eq; + +import com.google.common.testing.NullPointerTester; + +import junit.framework.TestCase; + +import org.easymock.EasyMock; + +import java.io.ByteArrayInputStream; + +/** + * Tests for {@link HashingInputStream}. + * + * @author Qian Huang + */ +public class HashingInputStreamTest extends TestCase { + private Hasher hasher; + private HashFunction hashFunction; + private static final byte[] testBytes = new byte[] {'y', 'a', 'm', 's'}; + private ByteArrayInputStream buffer; + + @Override protected void setUp() throws Exception { + super.setUp(); + hasher = EasyMock.createMock(Hasher.class); + hashFunction = EasyMock.createMock(HashFunction.class); + buffer = new ByteArrayInputStream(testBytes); + + EasyMock.expect(hashFunction.newHasher()).andReturn(hasher).once(); + EasyMock.replay(hashFunction); + } + + public void testRead_putSingleByte() throws Exception { + EasyMock.expect(hasher.putByte((byte) 'y')).andReturn(hasher).once(); + EasyMock.replay(hasher); + HashingInputStream in = new HashingInputStream(hashFunction, buffer); + + int b = in.read(); + assertEquals('y', b); + + EasyMock.verify(hashFunction); + EasyMock.verify(hasher); + } + + public void testRead_putByteArray() throws Exception { + EasyMock.expect(hasher.putBytes(aryEq(testBytes), eq(0), eq(testBytes.length))) + .andReturn(hasher).once(); + EasyMock.replay(hasher); + HashingInputStream in = new HashingInputStream(hashFunction, buffer); + + byte[] buf = new byte[4]; + int numOfByteRead = in.read(buf, 0, buf.length); + assertEquals(4, numOfByteRead); + for (int i = 0; i < testBytes.length; i++) { + assertEquals(testBytes[i], buf[i]); + } + + EasyMock.verify(hashFunction); + EasyMock.verify(hasher); + } + + public void testRead_putByteArrayAtPos() throws Exception { + EasyMock.expect(hasher.putBytes(aryEq(new byte[] {'y', 'a', 'm'}), eq(0), eq(3))) + .andReturn(hasher).once(); + EasyMock.replay(hasher); + HashingInputStream in = new HashingInputStream(hashFunction, buffer); + + byte[] buf = new byte[3]; + int numOfByteRead = in.read(buf, 0, 3); + assertEquals(3, numOfByteRead); + for (int i = 0; i < numOfByteRead; i++) { + assertEquals(testBytes[i], buf[i]); + } + + EasyMock.verify(hashFunction); + EasyMock.verify(hasher); + } + + public void testRead_putByteArrayOutOfBound() throws Exception { + byte[] buf = new byte[100]; + byte[] expectedBytes = buf.clone(); + System.arraycopy(testBytes, 0, expectedBytes, 0, testBytes.length); + + EasyMock.expect(hasher.putBytes(aryEq(expectedBytes), eq(0), eq(4))) + .andReturn(hasher).once(); + EasyMock.replay(hasher); + HashingInputStream in = new HashingInputStream(hashFunction, buffer); + + int numOfByteRead = in.read(buf, 0, 100); + assertEquals(4, numOfByteRead); + for (int i = 0; i < numOfByteRead; i++) { + assertEquals(testBytes[i], buf[i]); + } + + EasyMock.verify(hashFunction); + EasyMock.verify(hasher); + } + + public void testHash_hashesCorrectly() throws Exception { + HashCode expectedHash = Hashing.md5().hashBytes(testBytes); + HashingInputStream in = new HashingInputStream(Hashing.md5(), buffer); + + byte[] buf = new byte[4]; + int numOfByteRead = in.read(buf, 0, buf.length); + assertEquals(4, numOfByteRead); + + assertEquals(expectedHash, in.hash()); + } + + public void testHash_hashesCorrectlyReadOutOfBound() throws Exception { + HashCode expectedHash = Hashing.md5().hashBytes(testBytes); + HashingInputStream in = new HashingInputStream(Hashing.md5(), buffer); + + byte[] buf = new byte[100]; + int numOfByteRead = in.read(buf, 0, buf.length); + assertEquals(-1, in.read()); // additional read + assertEquals(4, numOfByteRead); + + assertEquals(expectedHash, in.hash()); + } + + public void testHash_hashesCorrectlyForSkipping() throws Exception { + HashCode expectedHash = Hashing.md5().hashBytes(new byte[] {'m', 's'}); + HashingInputStream in = new HashingInputStream(Hashing.md5(), buffer); + + long numOfByteSkipped = in.skip(2); + assertEquals(2, numOfByteSkipped); + + byte[] buf = new byte[4]; + int numOfByteRead = in.read(buf, 0, buf.length); + assertEquals(2, numOfByteRead); + + assertEquals(expectedHash, in.hash()); + } + + public void testChecksForNull() throws Exception { + NullPointerTester tester = new NullPointerTester(); + + tester.testAllPublicInstanceMethods(new HashingInputStream(Hashing.md5(), buffer)); + tester.testAllPublicStaticMethods(HashingInputStream.class); + tester.testAllPublicConstructors(HashingInputStream.class); + } +} diff --git a/guava-tests/test/com/google/common/hash/HashingOutputStreamTest.java b/guava-tests/test/com/google/common/hash/HashingOutputStreamTest.java new file mode 100644 index 0000000..425ee85 --- /dev/null +++ b/guava-tests/test/com/google/common/hash/HashingOutputStreamTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2011 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.hash; + +import com.google.common.testing.NullPointerTester; + +import junit.framework.TestCase; + +import org.easymock.EasyMock; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for {@link HashingOutputStream}. + * + * @author Nick Piepmeier + */ +public class HashingOutputStreamTest extends TestCase { + private Hasher hasher; + private HashFunction hashFunction; + private final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + @Override protected void setUp() throws Exception { + super.setUp(); + hasher = EasyMock.createMock(Hasher.class); + hashFunction = EasyMock.createMock(HashFunction.class); + + EasyMock.expect(hashFunction.newHasher()).andReturn(hasher).once(); + EasyMock.replay(hashFunction); + } + + public void testWrite_putSingleByte() throws Exception { + int b = 'q'; + EasyMock.expect(hasher.putByte((byte) b)).andReturn(hasher).once(); + EasyMock.replay(hasher); + HashingOutputStream out = new HashingOutputStream(hashFunction, buffer); + + out.write(b); + + EasyMock.verify(hashFunction); + EasyMock.verify(hasher); + } + + public void testWrite_putByteArray() throws Exception { + byte[] buf = new byte[] {'y', 'a', 'm', 's'}; + EasyMock.expect(hasher.putBytes(buf, 0, buf.length)).andReturn(hasher).once(); + EasyMock.replay(hasher); + HashingOutputStream out = new HashingOutputStream(hashFunction, buffer); + + out.write(buf); + + EasyMock.verify(hashFunction); + EasyMock.verify(hasher); + } + + public void testWrite_putByteArrayAtPos() throws Exception { + byte[] buf = new byte[] {'y', 'a', 'm', 's'}; + EasyMock.expect(hasher.putBytes(buf, 0, 3)).andReturn(hasher).once(); + EasyMock.replay(hasher); + HashingOutputStream out = new HashingOutputStream(hashFunction, buffer); + + out.write(buf, 0, 3); + + EasyMock.verify(hashFunction); + EasyMock.verify(hasher); + } + + public void testHash_hashesCorrectly() throws Exception { + byte[] buf = new byte[] {'y', 'a', 'm', 's'}; + HashCode expectedHash = Hashing.md5().hashBytes(buf); + HashingOutputStream out = new HashingOutputStream(Hashing.md5(), buffer); + + out.write(buf); + + assertEquals(expectedHash, out.hash()); + } + + public void testChecksForNull() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicInstanceMethods( + new HashingOutputStream(Hashing.md5(), new ByteArrayOutputStream())); + tester.testAllPublicStaticMethods(HashingOutputStream.class); + tester.testAllPublicConstructors(HashingOutputStream.class); + } +} diff --git a/guava-tests/test/com/google/common/hash/HashingTest.java b/guava-tests/test/com/google/common/hash/HashingTest.java index 6518d4c..2f369f2 100644 --- a/guava-tests/test/com/google/common/hash/HashingTest.java +++ b/guava-tests/test/com/google/common/hash/HashingTest.java @@ -17,22 +17,27 @@ package com.google.common.hash; import static com.google.common.hash.Hashing.ConcatenatedHashFunction; +import static com.google.common.hash.Hashing.goodFastHash; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableTable; import com.google.common.collect.Lists; import com.google.common.collect.Table.Cell; +import com.google.common.primitives.Ints; +import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.common.util.concurrent.AtomicLongMap; +import junit.framework.TestCase; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.nio.ByteBuffer; import java.util.Collections; import java.util.List; import java.util.Random; -import junit.framework.TestCase; - /** * Unit tests for {@link Hashing}. * @@ -100,6 +105,16 @@ public class HashingTest extends TestCase { assertEquals("Hashing.murmur3_32(0)", Hashing.murmur3_32().toString()); } + public void testSipHash24() { + HashTestUtils.check2BitAvalanche(Hashing.sipHash24(), 250, 0.14); + HashTestUtils.checkAvalanche(Hashing.sipHash24(), 250, 0.10); + HashTestUtils.checkNo2BitCharacteristics(Hashing.sipHash24()); + HashTestUtils.checkNoFunnels(Hashing.sipHash24()); + HashTestUtils.assertInvariants(Hashing.sipHash24()); + assertEquals("Hashing.sipHash24(506097522914230528, 1084818905618843912)", + Hashing.sipHash24().toString()); + } + public void testGoodFastHash() { for (int i = 1; i < 200; i += 17) { HashFunction hasher = Hashing.goodFastHash(i); @@ -199,9 +214,9 @@ public class HashingTest extends TestCase { } public void testConsistentHash_ofHashCode() { - checkSameResult(HashCodes.fromLong(1), 1); - checkSameResult(HashCodes.fromLong(0x9999999999999999L), 0x9999999999999999L); - checkSameResult(HashCodes.fromInt(0x99999999), 0x0000000099999999L); + checkSameResult(HashCode.fromLong(1), 1); + checkSameResult(HashCode.fromLong(0x9999999999999999L), 0x9999999999999999L); + checkSameResult(HashCode.fromInt(0x99999999), 0x0000000099999999L); } public void checkSameResult(HashCode hashCode, long equivLong) { @@ -209,18 +224,22 @@ public class HashingTest extends TestCase { } /** - * Tests that the linear congruential generator is actually compatible with the c++ - * implementation. - * - * This test was added to help refactoring, it is not a strict requirement, it can be removed if - * functionality changes in the future. + * Check a few "golden" values to see that implementations across languages + * are equivalent. */ public void testConsistentHash_linearCongruentialGeneratorCompatibility() { - assertEquals(55, Hashing.consistentHash(1, 100)); - assertEquals(62, Hashing.consistentHash(2, 100)); - assertEquals(8, Hashing.consistentHash(3, 100)); - assertEquals(45, Hashing.consistentHash(4, 100)); - assertEquals(59, Hashing.consistentHash(5, 100)); + int[] golden100 = + { 0, 55, 62, 8, 45, 59, 86, 97, 82, 59, + 73, 37, 17, 56, 86, 21, 90, 37, 38, 83 }; + for (int i = 0; i < golden100.length; i++) { + assertEquals(golden100[i], Hashing.consistentHash(i, 100)); + } + assertEquals(6, Hashing.consistentHash(10863919174838991L, 11)); + assertEquals(3, Hashing.consistentHash(2016238256797177309L, 11)); + assertEquals(5, Hashing.consistentHash(1673758223894951030L, 11)); + assertEquals(80343, Hashing.consistentHash(2, 100001)); + assertEquals(22152, Hashing.consistentHash(2201, 100001)); + assertEquals(15018, Hashing.consistentHash(2202, 100001)); } private static final double MAX_PERCENT_SPREAD = 0.5; @@ -236,19 +255,19 @@ public class HashingTest extends TestCase { public void testCombineOrdered_differentBitLengths() { try { - Hashing.combineOrdered(ImmutableList.of(HashCodes.fromInt(32), HashCodes.fromLong(32L))); + Hashing.combineOrdered(ImmutableList.of(HashCode.fromInt(32), HashCode.fromLong(32L))); fail(); } catch (IllegalArgumentException expected) { } } public void testCombineOrdered() { - HashCode hash31 = HashCodes.fromInt(31); - HashCode hash32 = HashCodes.fromInt(32); + HashCode hash31 = HashCode.fromInt(31); + HashCode hash32 = HashCode.fromInt(32); assertEquals(hash32, Hashing.combineOrdered(ImmutableList.of(hash32))); - assertEquals(HashCodes.fromBytes(new byte[] { (byte) 0x80, 0, 0, 0 }), + assertEquals(HashCode.fromBytes(new byte[] { (byte) 0x80, 0, 0, 0 }), Hashing.combineOrdered(ImmutableList.of(hash32, hash32))); - assertEquals(HashCodes.fromBytes(new byte[] { (byte) 0xa0, 0, 0, 0 }), + assertEquals(HashCode.fromBytes(new byte[] { (byte) 0xa0, 0, 0, 0 }), Hashing.combineOrdered(ImmutableList.of(hash32, hash32, hash32))); assertFalse( Hashing.combineOrdered(ImmutableList.of(hash31, hash32)).equals( @@ -259,7 +278,7 @@ public class HashingTest extends TestCase { Random random = new Random(7); List<HashCode> hashCodes = Lists.newArrayList(); for (int i = 0; i < 10; i++) { - hashCodes.add(HashCodes.fromLong(random.nextLong())); + hashCodes.add(HashCode.fromLong(random.nextLong())); } HashCode hashCode1 = Hashing.combineOrdered(hashCodes); Collections.shuffle(hashCodes, random); @@ -278,18 +297,18 @@ public class HashingTest extends TestCase { public void testCombineUnordered_differentBitLengths() { try { - Hashing.combineUnordered(ImmutableList.of(HashCodes.fromInt(32), HashCodes.fromLong(32L))); + Hashing.combineUnordered(ImmutableList.of(HashCode.fromInt(32), HashCode.fromLong(32L))); fail(); } catch (IllegalArgumentException expected) { } } public void testCombineUnordered() { - HashCode hash31 = HashCodes.fromInt(31); - HashCode hash32 = HashCodes.fromInt(32); + HashCode hash31 = HashCode.fromInt(31); + HashCode hash32 = HashCode.fromInt(32); assertEquals(hash32, Hashing.combineUnordered(ImmutableList.of(hash32))); - assertEquals(HashCodes.fromInt(64), Hashing.combineUnordered(ImmutableList.of(hash32, hash32))); - assertEquals(HashCodes.fromInt(96), + assertEquals(HashCode.fromInt(64), Hashing.combineUnordered(ImmutableList.of(hash32, hash32))); + assertEquals(HashCode.fromInt(96), Hashing.combineUnordered(ImmutableList.of(hash32, hash32, hash32))); assertEquals( Hashing.combineUnordered(ImmutableList.of(hash31, hash32)), @@ -297,10 +316,10 @@ public class HashingTest extends TestCase { } public void testCombineUnordered_randomHashCodes() { - Random random = new Random(); + Random random = new Random(RANDOM_SEED); List<HashCode> hashCodes = Lists.newArrayList(); for (int i = 0; i < 10; i++) { - hashCodes.add(HashCodes.fromLong(random.nextLong())); + hashCodes.add(HashCode.fromLong(random.nextLong())); } HashCode hashCode1 = Hashing.combineUnordered(hashCodes); Collections.shuffle(hashCodes); @@ -309,6 +328,15 @@ public class HashingTest extends TestCase { assertEquals(hashCode1, hashCode2); } + public void testConcatenatedHashFunction_equals() { + assertEquals( + new ConcatenatedHashFunction(Hashing.md5()), + new ConcatenatedHashFunction(Hashing.md5())); + assertEquals( + new ConcatenatedHashFunction(Hashing.md5(), Hashing.murmur3_32()), + new ConcatenatedHashFunction(Hashing.md5(), Hashing.murmur3_32())); + } + public void testConcatenatedHashFunction_bits() { assertEquals(Hashing.md5().bits(), new ConcatenatedHashFunction(Hashing.md5()).bits()); @@ -327,10 +355,30 @@ public class HashingTest extends TestCase { buffer.put(md5Hash); buffer.put(murmur3Hash); - assertEquals(HashCodes.fromBytes(combined), + assertEquals(HashCode.fromBytes(combined), new ConcatenatedHashFunction(Hashing.md5(), Hashing.murmur3_32()).hashLong(42L)); } + public void testHashIntReverseBytesVsHashBytesIntsToByteArray() { + int input = 42; + assertEquals( + Hashing.md5().hashBytes(Ints.toByteArray(input)), + Hashing.md5().hashInt(Integer.reverseBytes(input))); + } + + public void testHashIntVsForLoop() { + int input = 42; + HashCode expected = Hashing.md5().hashInt(input); + + Hasher hasher = Hashing.md5().newHasher(); + for (int i = 0; i < 32; i += 8) { + hasher.putByte((byte) (input >> i)); + } + HashCode actual = hasher.hash(); + + assertEquals(expected, actual); + } + private static final String EMPTY_STRING = ""; private static final String TQBFJOTLD = "The quick brown fox jumps over the lazy dog"; private static final String TQBFJOTLDP = "The quick brown fox jumps over the lazy dog."; @@ -367,8 +415,26 @@ public class HashingTest extends TestCase { .put(Hashing.sha512(), TQBFJOTLDP, "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb" + "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed") + .put(Hashing.crc32(), EMPTY_STRING, "00000000") + .put(Hashing.crc32(), TQBFJOTLD, "39a34f41") + .put(Hashing.crc32(), TQBFJOTLDP, "e9259051") + .put(Hashing.sipHash24(), EMPTY_STRING, "310e0edd47db6f72") + .put(Hashing.sipHash24(), TQBFJOTLD, "e46f1fdc05612752") + .put(Hashing.sipHash24(), TQBFJOTLDP, "9b602581fce4d4f8") .build(); + public void testAllHashFunctionsHaveKnownHashes() throws Exception { + for (Method method : Hashing.class.getDeclaredMethods()) { + if (method.getReturnType().equals(HashFunction.class) // must return HashFunction + && Modifier.isPublic(method.getModifiers()) // only the public methods + && method.getParameterTypes().length == 0) { // only the seed-less grapes^W hash functions + HashFunction hashFunction = (HashFunction) method.invoke(Hashing.class); + assertTrue("There should be at least 3 entries in KNOWN_HASHES for " + hashFunction, + KNOWN_HASHES.row(hashFunction).size() >= 3); + } + } + } + public void testKnownUtf8Hashing() { for (Cell<HashFunction, String, String> cell : KNOWN_HASHES.cellSet()) { HashFunction func = cell.getRowKey(); @@ -383,7 +449,99 @@ public class HashingTest extends TestCase { public void testNullPointers() { NullPointerTester tester = new NullPointerTester() - .setDefault(HashCode.class, HashCodes.fromInt(0)); + .setDefault(HashCode.class, HashCode.fromLong(0)); tester.testAllPublicStaticMethods(Hashing.class); } + + public void testSeedlessHashFunctionEquals() throws Exception { + assertSeedlessHashFunctionEquals(Hashing.class); + } + + public void testSeededHashFunctionEquals() throws Exception { + assertSeededHashFunctionEquals(Hashing.class); + } + + /** + * Tests equality of {@link Hashing#goodFastHash} instances. This test must be separate from + * {@link #testSeededHashFunctionEquals} because the parameter to {@code goodFastHash} is a size, + * not a seed, and because that size is rounded up. Thus, {@code goodFastHash} instances with + * different parameters can be equal. That fact is a problem for {@code + * testSeededHashFunctionEquals}. + */ + public void testGoodFastHashEquals() throws Exception { + HashFunction hashFunction1a = goodFastHash(1); + HashFunction hashFunction1b = goodFastHash(32); + HashFunction hashFunction2a = goodFastHash(33); + HashFunction hashFunction2b = goodFastHash(128); + HashFunction hashFunction3a = goodFastHash(129); + HashFunction hashFunction3b = goodFastHash(256); + HashFunction hashFunction4a = goodFastHash(257); + HashFunction hashFunction4b = goodFastHash(384); + + new EqualsTester() + .addEqualityGroup(hashFunction1a, hashFunction1b) + .addEqualityGroup(hashFunction2a, hashFunction2b) + .addEqualityGroup(hashFunction3a, hashFunction3b) + .addEqualityGroup(hashFunction4a, hashFunction4b) + .testEquals(); + + assertEquals(hashFunction1a.toString(), hashFunction1b.toString()); + assertEquals(hashFunction2a.toString(), hashFunction2b.toString()); + assertEquals(hashFunction3a.toString(), hashFunction3b.toString()); + assertEquals(hashFunction4a.toString(), hashFunction4b.toString()); + } + + static void assertSeedlessHashFunctionEquals(Class<?> clazz) throws Exception { + for (Method method : clazz.getDeclaredMethods()) { + if (method.getReturnType().equals(HashFunction.class) // must return HashFunction + && Modifier.isPublic(method.getModifiers()) // only the public methods + && method.getParameterTypes().length == 0) { // only the seed-less hash functions + HashFunction hashFunction1a = (HashFunction) method.invoke(clazz); + HashFunction hashFunction1b = (HashFunction) method.invoke(clazz); + + new EqualsTester() + .addEqualityGroup(hashFunction1a, hashFunction1b) + .testEquals(); + + // Make sure we're returning not only equal instances, but constants. + assertSame(hashFunction1a, hashFunction1b); + + assertEquals(hashFunction1a.toString(), hashFunction1b.toString()); + } + } + } + + static void assertSeededHashFunctionEquals(Class<?> clazz) throws Exception { + Random random = new Random(RANDOM_SEED); + for (Method method : clazz.getDeclaredMethods()) { + if (method.getReturnType().equals(HashFunction.class) // must return HashFunction + && Modifier.isPublic(method.getModifiers()) // only the public methods + && method.getParameterTypes().length != 0 // only the seeded hash functions + && !method.getName().equals("goodFastHash")) { // tested in testGoodFastHashEquals + Object[] params1 = new Object[method.getParameterTypes().length]; + Object[] params2 = new Object[method.getParameterTypes().length]; + for (int i = 0; i < params1.length; i++) { + if (method.getParameterTypes()[i] == int.class) { + params1[i] = random.nextInt(); + params2[i] = random.nextInt(); + } else if (method.getParameterTypes()[i] == long.class) { + params1[i] = random.nextLong(); + params2[i] = random.nextLong(); + } else { + fail("Unable to create a random parameter for " + method.getParameterTypes()[i]); + } + } + HashFunction hashFunction1a = (HashFunction) method.invoke(clazz, params1); + HashFunction hashFunction1b = (HashFunction) method.invoke(clazz, params1); + HashFunction hashFunction2 = (HashFunction) method.invoke(clazz, params2); + + new EqualsTester() + .addEqualityGroup(hashFunction1a, hashFunction1b) + .addEqualityGroup(hashFunction2) + .testEquals(); + + assertEquals(hashFunction1a.toString(), hashFunction1b.toString()); + } + } + } } diff --git a/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java b/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java index 7433332..2a625d6 100644 --- a/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java +++ b/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java @@ -16,6 +16,8 @@ package com.google.common.hash; +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.jdk5backport.Arrays; @@ -23,7 +25,6 @@ import junit.framework.TestCase; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; - /** * Tests for the MessageDigestHashFunction. * @@ -31,17 +32,59 @@ import java.security.NoSuchAlgorithmException; */ public class MessageDigestHashFunctionTest extends TestCase { private static final ImmutableSet<String> INPUTS = ImmutableSet.of("", "Z", "foobar"); - private static final ImmutableSet<String> ALGORITHMS = ImmutableSet.of( - "MD5", "SHA1", "SHA-1", "SHA-256", "SHA-512"); + + // From "How Provider Implementations Are Requested and Supplied" from + // http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html + // - Some providers may choose to also include alias names. + // - For example, the "SHA-1" algorithm might be referred to as "SHA1". + // - The algorithm name is not case-sensitive. + private static final ImmutableMap<String, HashFunction> ALGORITHMS = + new ImmutableMap.Builder<String, HashFunction>() + .put("MD5", Hashing.md5()) + .put("SHA", Hashing.sha1()) // Not the official name, but still works + .put("SHA1", Hashing.sha1()) // Not the official name, but still works + .put("sHa-1", Hashing.sha1()) // Not the official name, but still works + .put("SHA-1", Hashing.sha1()) + .put("SHA-256", Hashing.sha256()) + .put("SHA-512", Hashing.sha512()) + .build(); public void testHashing() { for (String stringToTest : INPUTS) { - for (String algorithmToTest : ALGORITHMS) { + for (String algorithmToTest : ALGORITHMS.keySet()) { assertMessageDigestHashing(HashTestUtils.ascii(stringToTest), algorithmToTest); } } } + public void testPutAfterHash() { + Hasher sha1 = Hashing.sha1().newHasher(); + + assertEquals("2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", + sha1.putString("The quick brown fox jumps over the lazy dog", Charsets.UTF_8) + .hash() + .toString()); + try { + sha1.putInt(42); + fail(); + } catch (IllegalStateException expected) { + } + } + + public void testHashTwice() { + Hasher sha1 = Hashing.sha1().newHasher(); + + assertEquals("2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", + sha1.putString("The quick brown fox jumps over the lazy dog", Charsets.UTF_8) + .hash() + .toString()); + try { + sha1.hash(); + fail(); + } catch (IllegalStateException expected) { + } + } + public void testToString() { assertEquals("Hashing.md5()", Hashing.md5().toString()); assertEquals("Hashing.sha1()", Hashing.sha1().toString()); @@ -53,11 +96,11 @@ public class MessageDigestHashFunctionTest extends TestCase { try { MessageDigest digest = MessageDigest.getInstance(algorithmName); assertEquals( - HashCodes.fromBytes(digest.digest(input)), - new MessageDigestHashFunction(algorithmName, algorithmName).hashBytes(input)); + HashCode.fromBytes(digest.digest(input)), + ALGORITHMS.get(algorithmName).hashBytes(input)); for (int bytes = 4; bytes <= digest.getDigestLength(); bytes++) { assertEquals( - HashCodes.fromBytes(Arrays.copyOf(digest.digest(input), bytes)), + HashCode.fromBytes(Arrays.copyOf(digest.digest(input), bytes)), new MessageDigestHashFunction(algorithmName, bytes, algorithmName).hashBytes(input)); } try { @@ -70,5 +113,4 @@ public class MessageDigestHashFunctionTest extends TestCase { throw new AssertionError(nsae); } } - } diff --git a/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java b/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java index b733885..70483f7 100644 --- a/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java +++ b/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java @@ -21,11 +21,11 @@ import static com.google.common.hash.Hashing.murmur3_128; import com.google.common.base.Charsets; import com.google.common.hash.HashTestUtils.HashFn; +import junit.framework.TestCase; + import java.nio.ByteBuffer; import java.nio.ByteOrder; -import junit.framework.TestCase; - /** * Tests for {@link Murmur3_128HashFunction}. */ @@ -63,7 +63,7 @@ public class Murmur3Hash128Test extends TestCase { for (long x : longs) { bb.putLong(x); } - return HashCodes.fromBytes(bb.array()); + return HashCode.fromBytes(bb.array()); } public void testParanoid() { diff --git a/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java b/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java index b6a6d8e..fde6ab0 100644 --- a/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java +++ b/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java @@ -43,16 +43,17 @@ public class Murmur3Hash32Test extends TestCase { } public void testKnownStringInputs() { - assertHash(0, murmur3_32().hashString("")); - assertHash(679745764, murmur3_32().hashString("k")); - assertHash(1510782915, murmur3_32().hashString("hell")); - assertHash(-675079799, murmur3_32().hashString("hello")); - assertHash(1935035788, murmur3_32().hashString("http://www.google.com/")); - assertHash(-528633700, murmur3_32().hashString("The quick brown fox jumps over the lazy dog")); + assertHash(0, murmur3_32().hashUnencodedChars("")); + assertHash(679745764, murmur3_32().hashUnencodedChars("k")); + assertHash(1510782915, murmur3_32().hashUnencodedChars("hell")); + assertHash(-675079799, murmur3_32().hashUnencodedChars("hello")); + assertHash(1935035788, murmur3_32().hashUnencodedChars("http://www.google.com/")); + assertHash(-528633700, + murmur3_32().hashUnencodedChars("The quick brown fox jumps over the lazy dog")); } private static void assertHash(int expected, HashCode actual) { - assertEquals(HashCodes.fromInt(expected), actual); + assertEquals(HashCode.fromInt(expected), actual); } public void testParanoid() { diff --git a/guava-tests/test/com/google/common/hash/PackageSanityTests.java b/guava-tests/test/com/google/common/hash/PackageSanityTests.java index a752a33..cbfd1e2 100644 --- a/guava-tests/test/com/google/common/hash/PackageSanityTests.java +++ b/guava-tests/test/com/google/common/hash/PackageSanityTests.java @@ -28,7 +28,7 @@ import com.google.common.testing.AbstractPackageSanityTests; public class PackageSanityTests extends AbstractPackageSanityTests { public PackageSanityTests() { setDefault(BitArray.class, new BitArray(1)); - setDefault(HashCode.class, HashCodes.fromInt(1)); + setDefault(HashCode.class, HashCode.fromInt(1)); setDefault(String.class, "MD5"); setDefault(int.class, 32); } diff --git a/guava-tests/test/com/google/common/hash/SipHashFunctionTest.java b/guava-tests/test/com/google/common/hash/SipHashFunctionTest.java new file mode 100644 index 0000000..8824b23 --- /dev/null +++ b/guava-tests/test/com/google/common/hash/SipHashFunctionTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.hash; + +import static com.google.common.base.Charsets.UTF_8; + +import com.google.common.collect.ImmutableSet; + +import junit.framework.TestCase; + +/** + * Unit tests for {@link SipHashFunction}. + * + * @author Kurt Alfred Kluever + */ +public class SipHashFunctionTest extends TestCase { + + // From https://131002.net/siphash/siphash24.c + // k = 00 01 02 ... + private static final long K0 = 0x0706050403020100L; + private static final long K1 = 0x0f0e0d0c0b0a0908L; + private static final HashFunction SIP_WITH_KEY = Hashing.sipHash24(K0, K1); + private static final HashFunction SIP_WITHOUT_KEY = Hashing.sipHash24(); + + // These constants were originally ported from https://www.131002.net/siphash/siphash24.c. See: + // https://github.com/nahi/siphash-java-inline/blob/master/src/test/java/SipHashInlineTest.java + private static final long[] EXPECTED = new long[] { + 0x726fdb47dd0e0e31L, + 0x74f839c593dc67fdL, + 0x0d6c8009d9a94f5aL, + 0x85676696d7fb7e2dL, + 0xcf2794e0277187b7L, + 0x18765564cd99a68dL, + 0xcbc9466e58fee3ceL, + 0xab0200f58b01d137L, + 0x93f5f5799a932462L, + 0x9e0082df0ba9e4b0L, + 0x7a5dbbc594ddb9f3L, + 0xf4b32f46226bada7L, + 0x751e8fbc860ee5fbL, + 0x14ea5627c0843d90L, + 0xf723ca908e7af2eeL, + 0xa129ca6149be45e5L, + 0x3f2acc7f57c29bdbL, + 0x699ae9f52cbe4794L, + 0x4bc1b3f0968dd39cL, + 0xbb6dc91da77961bdL, + 0xbed65cf21aa2ee98L, + 0xd0f2cbb02e3b67c7L, + 0x93536795e3a33e88L, + 0xa80c038ccd5ccec8L, + 0xb8ad50c6f649af94L, + 0xbce192de8a85b8eaL, + 0x17d835b85bbb15f3L, + 0x2f2e6163076bcfadL, + 0xde4daaaca71dc9a5L, + 0xa6a2506687956571L, + 0xad87a3535c49ef28L, + 0x32d892fad841c342L, + 0x7127512f72f27cceL, + 0xa7f32346f95978e3L, + 0x12e0b01abb051238L, + 0x15e034d40fa197aeL, + 0x314dffbe0815a3b4L, + 0x027990f029623981L, + 0xcadcd4e59ef40c4dL, + 0x9abfd8766a33735cL, + 0x0e3ea96b5304a7d0L, + 0xad0c42d6fc585992L, + 0x187306c89bc215a9L, + 0xd4a60abcf3792b95L, + 0xf935451de4f21df2L, + 0xa9538f0419755787L, + 0xdb9acddff56ca510L, + 0xd06c98cd5c0975ebL, + 0xe612a3cb9ecba951L, + 0xc766e62cfcadaf96L, + 0xee64435a9752fe72L, + 0xa192d576b245165aL, + 0x0a8787bf8ecb74b2L, + 0x81b3e73d20b49b6fL, + 0x7fa8220ba3b2eceaL, + 0x245731c13ca42499L, + 0xb78dbfaf3a8d83bdL, + 0xea1ad565322a1a0bL, + 0x60e61c23a3795013L, + 0x6606d7e446282b93L, + 0x6ca4ecb15c5f91e1L, + 0x9f626da15c9625f3L, + 0xe51b38608ef25f57L, + 0x958a324ceb064572L + }; + + public void testVectors() { + for (int i = 0; i < EXPECTED.length; ++i) { + byte[] msg = new byte[i]; + for (int j = 0; j < i; ++j) { + msg[j] = (byte) j; + } + assertSip(msg, EXPECTED[i]); + } + } + + // This test data comes from "SipHash: a fast short-input PRF", "Appendix A: Test values". + // It can be downloaded here: https://131002.net/siphash/siphash.pdf + public void test15ByteStringFromSipHashPaper() { + byte[] message = new byte[] { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e }; + long k0 = 0x0706050403020100L; + long k1 = 0x0f0e0d0c0b0a0908L; + + assertEquals(0xa129ca6149be45e5L, Hashing.sipHash24(k0, k1).hashBytes(message).asLong()); + } + + // From https://github.com/BrandonHaynes/siphash-csharp/blob/master/tests/Tests.cs + public void testKnownValues() { + assertSip(new byte[] { }, 0x726fdb47dd0e0e31L); + assertSip(new byte[] { 0x61 }, 0x2ba3e8e9a71148caL); + assertSip(new byte[1000000], 0x28205108397aa742L); + assertSip("12345678", 0x02130609caea37ebL); + assertSip("abcdef", 0x2a6e77e733c7c05dL); + assertSip("SipHash", 0x8325093242a96f60L); + } + + // Test for common pitfall regarding sign extension. + // For example: (long) data[i++] | (long) data[i++] << 8 | ... + // If data[i] == (byte) 0x80, the first cast will sign-extend it to 0xffffffffffffff80, + // masking the remaining seven bytes. + // To test this, we give an input where bit 7 is not cleared. For example: + // (1) 00 01 02 03 04 05 06 07 80 + // (2) 00 01 02 03 04 05 06 07 81 + // (3) 00 01 02 03 04 05 06 07 ff (or anything in between) + // A fault implementation will generate collisions for these inputs. + public void testCollisionsDueToIncorrectSignExtension() { + byte[] col1 = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, (byte) 0x80 }; + byte[] col2 = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, (byte) 0x81 }; + byte[] col3 = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, (byte) 0xff }; + + ImmutableSet<HashCode> hashCodes = ImmutableSet.of( + SIP_WITH_KEY.hashBytes(col1), + SIP_WITH_KEY.hashBytes(col2), + SIP_WITH_KEY.hashBytes(col3)); + assertEquals(3, hashCodes.size()); + } + + public void testToString() { + assertEquals("Hashing.sipHash24(" + K0 + ", " + K1 + ")", SIP_WITH_KEY.toString()); + assertEquals("Hashing.sipHash24(" + K0 + ", " + K1 + ")", SIP_WITHOUT_KEY.toString()); + assertEquals("Hashing.sipHash24(20, 13)", Hashing.sipHash24(20, 13).toString()); + } + + private static void assertSip(String input, long expected) { + assertEquals(expected, SIP_WITH_KEY.hashString(input, UTF_8).asLong()); + assertEquals(expected, SIP_WITH_KEY.newHasher().putString(input, UTF_8).hash().asLong()); + assertEquals(expected, SIP_WITHOUT_KEY.hashString(input, UTF_8).asLong()); + assertEquals(expected, SIP_WITHOUT_KEY.newHasher().putString(input, UTF_8).hash().asLong()); + } + + private static void assertSip(byte[] input, long expected) { + assertEquals(expected, SIP_WITH_KEY.hashBytes(input).asLong()); + assertEquals(expected, SIP_WITH_KEY.newHasher().putBytes(input).hash().asLong()); + assertEquals(expected, SIP_WITHOUT_KEY.hashBytes(input).asLong()); + assertEquals(expected, SIP_WITHOUT_KEY.newHasher().putBytes(input).hash().asLong()); + } +} diff --git a/guava-tests/test/com/google/common/html/HtmlEscapersTest.java b/guava-tests/test/com/google/common/html/HtmlEscapersTest.java new file mode 100644 index 0000000..43bd8e9 --- /dev/null +++ b/guava-tests/test/com/google/common/html/HtmlEscapersTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.html; + +import static com.google.common.html.HtmlEscapers.htmlEscaper; + +import com.google.common.annotations.GwtCompatible; + +import junit.framework.TestCase; + +/** + * Tests for the {@link HtmlEscapers} class. + * + * @author David Beaumont + */ +@GwtCompatible +public class HtmlEscapersTest extends TestCase { + + public void testHtmlEscaper() throws Exception { + assertEquals("xxx", htmlEscaper().escape("xxx")); + assertEquals(""test"", htmlEscaper().escape("\"test\"")); + assertEquals("'test'", htmlEscaper().escape("\'test'")); + assertEquals("test & test & test", htmlEscaper().escape("test & test & test")); + assertEquals("test << 1", htmlEscaper().escape("test << 1")); + assertEquals("test >> 1", htmlEscaper().escape("test >> 1")); + assertEquals("<tab>", htmlEscaper().escape("<tab>")); + + // Test simple escape of '&'. + assertEquals("foo&bar", htmlEscaper().escape("foo&bar")); + + // If the string contains no escapes, it should return the arg. + // Note: assert<b>Same</b> for this implementation. + String s = "blah blah farhvergnugen"; + assertSame(s, htmlEscaper().escape(s)); + + // Tests escapes at begin and end of string. + assertEquals("<p>", htmlEscaper().escape("<p>")); + + // Test all escapes. + assertEquals("a"b<c>d&", htmlEscaper().escape("a\"b<c>d&")); + + // Test two escapes in a row. + assertEquals("foo&&bar", htmlEscaper().escape("foo&&bar")); + + // Test many non-escaped characters. + s = "!@#$%^*()_+=-/?\\|]}[{,.;:" + + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "1234567890"; + assertSame(s, htmlEscaper().escape(s)); + } +} diff --git a/guava-tests/test/com/google/common/io/BaseEncodingTest.java b/guava-tests/test/com/google/common/io/BaseEncodingTest.java index a8ffc49..9580185 100644 --- a/guava-tests/test/com/google/common/io/BaseEncodingTest.java +++ b/guava-tests/test/com/google/common/io/BaseEncodingTest.java @@ -25,6 +25,9 @@ import com.google.common.base.Ascii; import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; +import com.google.common.io.BaseEncoding.DecodingException; + +import junit.framework.TestCase; import java.io.IOException; import java.io.InputStream; @@ -33,8 +36,6 @@ import java.io.StringReader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; -import junit.framework.TestCase; - /** * Tests for {@code BaseEncoding}. * @@ -42,7 +43,7 @@ import junit.framework.TestCase; */ @GwtCompatible(emulated = true) public class BaseEncodingTest extends TestCase { - public void assertEquals(byte[] expected, byte[] actual) { + public static void assertEquals(byte[] expected, byte[] actual) { assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; i++) { assertEquals(expected[i], actual[i]); @@ -302,16 +303,18 @@ public class BaseEncodingTest extends TestCase { } public void testBase16UpperCaseIsNoOp() { - assertSame(base16().upperCase(), base16().upperCase()); + assertSame(base16(), base16().upperCase()); } - private void testEncodingWithCasing(BaseEncoding encoding, String decoded, String encoded) { + private static void testEncodingWithCasing( + BaseEncoding encoding, String decoded, String encoded) { testEncodingWithSeparators(encoding, decoded, encoded); testEncodingWithSeparators(encoding.upperCase(), decoded, Ascii.toUpperCase(encoded)); testEncodingWithSeparators(encoding.lowerCase(), decoded, Ascii.toLowerCase(encoded)); } - private void testEncodingWithSeparators(BaseEncoding encoding, String decoded, String encoded) { + private static void testEncodingWithSeparators( + BaseEncoding encoding, String decoded, String encoded) { testEncoding(encoding, decoded, encoded); // test separators work @@ -323,14 +326,15 @@ public class BaseEncodingTest extends TestCase { } } - private void testEncoding(BaseEncoding encoding, String decoded, String encoded) { + private static void testEncoding(BaseEncoding encoding, String decoded, String encoded) { testEncodes(encoding, decoded, encoded); testDecodes(encoding, encoded, decoded); } - private void testEncodes(BaseEncoding encoding, String decoded, String encoded) { + private static void testEncodes(BaseEncoding encoding, String decoded, String encoded) { byte[] bytes; try { + // GWT does not support String.getBytes(Charset) bytes = decoded.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { throw new AssertionError(); @@ -338,9 +342,10 @@ public class BaseEncodingTest extends TestCase { assertEquals(encoded, encoding.encode(bytes)); } - private void testDecodes(BaseEncoding encoding, String encoded, String decoded) { + private static void testDecodes(BaseEncoding encoding, String encoded, String decoded) { byte[] bytes; try { + // GWT does not support String.getBytes(Charset) bytes = decoded.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { throw new AssertionError(); @@ -348,17 +353,23 @@ public class BaseEncodingTest extends TestCase { assertEquals(bytes, encoding.decode(encoded)); } - private void assertFailsToDecode(BaseEncoding encoding, String cannotDecode) { + private static void assertFailsToDecode(BaseEncoding encoding, String cannotDecode) { try { encoding.decode(cannotDecode); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { // success } + try { + encoding.decodeChecked(cannotDecode); + fail("Expected DecodingException"); + } catch (DecodingException expected) { + // success + } } @GwtIncompatible("Reader/Writer") - private void testStreamingEncodingWithCasing( + private static void testStreamingEncodingWithCasing( BaseEncoding encoding, String decoded, String encoded) throws IOException { testStreamingEncodingWithSeparators(encoding, decoded, encoded); testStreamingEncodingWithSeparators(encoding.upperCase(), decoded, Ascii.toUpperCase(encoded)); @@ -366,7 +377,7 @@ public class BaseEncodingTest extends TestCase { } @GwtIncompatible("Reader/Writer") - private void testStreamingEncodingWithSeparators( + private static void testStreamingEncodingWithSeparators( BaseEncoding encoding, String decoded, String encoded) throws IOException { testStreamingEncoding(encoding, decoded, encoded); @@ -380,17 +391,18 @@ public class BaseEncodingTest extends TestCase { } @GwtIncompatible("Reader/Writer") - private void testStreamingEncoding(BaseEncoding encoding, String decoded, String encoded) + private static void testStreamingEncoding(BaseEncoding encoding, String decoded, String encoded) throws IOException { testStreamingEncodes(encoding, decoded, encoded); testStreamingDecodes(encoding, encoded, decoded); } @GwtIncompatible("Writer") - private void testStreamingEncodes(BaseEncoding encoding, String decoded, String encoded) + private static void testStreamingEncodes(BaseEncoding encoding, String decoded, String encoded) throws IOException { byte[] bytes; try { + // GWT does not support String.getBytes(Charset) bytes = decoded.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { throw new AssertionError(); @@ -403,10 +415,11 @@ public class BaseEncodingTest extends TestCase { } @GwtIncompatible("Reader") - private void testStreamingDecodes(BaseEncoding encoding, String encoded, String decoded) + private static void testStreamingDecodes(BaseEncoding encoding, String encoded, String decoded) throws IOException { byte[] bytes; try { + // GWT does not support String.getBytes(Charset) bytes = decoded.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { throw new AssertionError(); @@ -418,12 +431,12 @@ public class BaseEncodingTest extends TestCase { assertEquals(-1, decodingStream.read()); decodingStream.close(); } - + public void testToString() { assertEquals("BaseEncoding.base64().withPadChar(=)", BaseEncoding.base64().toString()); - assertEquals("BaseEncoding.base32Hex().omitPadding()", + assertEquals("BaseEncoding.base32Hex().omitPadding()", BaseEncoding.base32Hex().omitPadding().toString()); - assertEquals("BaseEncoding.base32().lowerCase().withPadChar($)", + assertEquals("BaseEncoding.base32().lowerCase().withPadChar($)", BaseEncoding.base32().lowerCase().withPadChar('$').toString()); assertEquals("BaseEncoding.base16().withSeparator(\"\n\", 10)", BaseEncoding.base16().withSeparator("\n", 10).toString()); diff --git a/guava-tests/test/com/google/common/io/ByteSinkTest.java b/guava-tests/test/com/google/common/io/ByteSinkTest.java index adb659c..fa04fac 100644 --- a/guava-tests/test/com/google/common/io/ByteSinkTest.java +++ b/guava-tests/test/com/google/common/io/ByteSinkTest.java @@ -22,9 +22,9 @@ import static com.google.common.io.TestOption.READ_THROWS; import static com.google.common.io.TestOption.WRITE_THROWS; import static org.junit.Assert.assertArrayEquals; -import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.OutputStream; import java.util.EnumSet; /** @@ -44,7 +44,7 @@ public class ByteSinkTest extends IoTestCase { } public void testOpenBufferedStream() throws IOException { - BufferedOutputStream out = sink.openBufferedStream(); + OutputStream out = sink.openBufferedStream(); assertTrue(sink.wasStreamOpened()); assertFalse(sink.wasStreamClosed()); diff --git a/guava-tests/test/com/google/common/io/ByteSinkTester.java b/guava-tests/test/com/google/common/io/ByteSinkTester.java index d514d35..5222a18 100644 --- a/guava-tests/test/com/google/common/io/ByteSinkTester.java +++ b/guava-tests/test/com/google/common/io/ByteSinkTester.java @@ -16,16 +16,15 @@ package com.google.common.io; +import static com.google.common.io.SourceSinkFactory.ByteSinkFactory; +import static com.google.common.io.SourceSinkFactory.CharSinkFactory; import static org.junit.Assert.assertArrayEquals; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableList; -import com.google.common.io.SourceSinkFactory.ByteSinkFactory; -import com.google.common.io.SourceSinkFactory.CharSinkFactory; import junit.framework.TestSuite; -import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; @@ -103,7 +102,7 @@ public class ByteSinkTester extends SourceSinkTester<ByteSink, byte[], ByteSinkF } public void testOpenBufferedStream() throws IOException { - BufferedOutputStream out = sink.openBufferedStream(); + OutputStream out = sink.openBufferedStream(); try { ByteStreams.copy(new ByteArrayInputStream(data), out); } finally { diff --git a/guava-tests/test/com/google/common/io/ByteSourceTest.java b/guava-tests/test/com/google/common/io/ByteSourceTest.java index 3c682bb..c40fcdd 100644 --- a/guava-tests/test/com/google/common/io/ByteSourceTest.java +++ b/guava-tests/test/com/google/common/io/ByteSourceTest.java @@ -17,6 +17,7 @@ package com.google.common.io; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.io.TestOption.AVAILABLE_ALWAYS_ZERO; import static com.google.common.io.TestOption.CLOSE_THROWS; import static com.google.common.io.TestOption.OPEN_THROWS; import static com.google.common.io.TestOption.READ_THROWS; @@ -25,12 +26,18 @@ import static com.google.common.io.TestOption.WRITE_THROWS; import static org.junit.Assert.assertArrayEquals; import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import com.google.common.hash.Hashing; +import com.google.common.testing.TestLogHandler; + +import junit.framework.TestSuite; -import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.util.EnumSet; @@ -41,6 +48,16 @@ import java.util.EnumSet; */ public class ByteSourceTest extends IoTestCase { + public static TestSuite suite() { + TestSuite suite = new TestSuite(); + suite.addTest(ByteSourceTester.tests("ByteSource.wrap[byte[]]", + SourceSinkFactories.byteArraySourceFactory(), true)); + suite.addTest(ByteSourceTester.tests("ByteSource.empty[]", + SourceSinkFactories.emptyByteSourceFactory(), true)); + suite.addTestSuite(ByteSourceTest.class); + return suite; + } + private static final byte[] bytes = newPreFilledByteArray(10000); private TestByteSource source; @@ -51,7 +68,7 @@ public class ByteSourceTest extends IoTestCase { } public void testOpenBufferedStream() throws IOException { - BufferedInputStream in = source.openBufferedStream(); + InputStream in = source.openBufferedStream(); assertTrue(source.wasStreamOpened()); assertFalse(source.wasStreamClosed()); @@ -70,6 +87,9 @@ public class ByteSourceTest extends IoTestCase { // test that we can get the size even if skip() isn't supported assertEquals(bytes.length, new TestByteSource(bytes, SKIP_THROWS).size()); + + // test that we can get the size even if available() always returns zero + assertEquals(bytes.length, new TestByteSource(bytes, AVAILABLE_ALWAYS_ZERO).size()); } public void testCopyTo_outputStream() throws IOException { @@ -98,6 +118,51 @@ public class ByteSourceTest extends IoTestCase { assertTrue(source.wasStreamOpened() && source.wasStreamClosed()); } + public void testRead_withProcessor() throws IOException { + final byte[] processedBytes = new byte[bytes.length]; + ByteProcessor<byte[]> processor = new ByteProcessor<byte[]>() { + int pos; + + @Override + public boolean processBytes(byte[] buf, int off, int len) throws IOException { + System.arraycopy(buf, off, processedBytes, pos, len); + pos += len; + return true; + } + + @Override + public byte[] getResult() { + return processedBytes; + } + }; + + source.read(processor); + assertTrue(source.wasStreamOpened() && source.wasStreamClosed()); + + assertArrayEquals(bytes, processedBytes); + } + + public void testRead_withProcessor_stopsOnFalse() throws IOException { + ByteProcessor<Void> processor = new ByteProcessor<Void>() { + boolean firstCall = true; + + @Override + public boolean processBytes(byte[] buf, int off, int len) throws IOException { + assertTrue("consume() called twice", firstCall); + firstCall = false; + return false; + } + + @Override + public Void getResult() { + return null; + } + }; + + source.read(processor); + assertTrue(source.wasStreamOpened() && source.wasStreamClosed()); + } + public void testHash() throws IOException { ByteSource byteSource = new TestByteSource("hamburger\n".getBytes(Charsets.US_ASCII.name())); @@ -212,4 +277,151 @@ public class ByteSourceTest extends IoTestCase { } assertTrue(okSource.wasStreamClosed()); } + + public void testConcat() throws IOException { + ByteSource b1 = ByteSource.wrap(new byte[] {0, 1, 2, 3}); + ByteSource b2 = ByteSource.wrap(new byte[0]); + ByteSource b3 = ByteSource.wrap(new byte[] {4, 5}); + + byte[] expected = {0, 1, 2, 3, 4, 5}; + + assertArrayEquals(expected, + ByteSource.concat(ImmutableList.of(b1, b2, b3)).read()); + assertArrayEquals(expected, + ByteSource.concat(b1, b2, b3).read()); + assertArrayEquals(expected, + ByteSource.concat(ImmutableList.of(b1, b2, b3).iterator()).read()); + assertEquals(expected.length, ByteSource.concat(b1, b2, b3).size()); + assertFalse(ByteSource.concat(b1, b2, b3).isEmpty()); + + ByteSource emptyConcat = ByteSource.concat(ByteSource.empty(), ByteSource.empty()); + assertTrue(emptyConcat.isEmpty()); + assertEquals(0, emptyConcat.size()); + } + + public void testConcat_infiniteIterable() throws IOException { + ByteSource source = ByteSource.wrap(new byte[] {0, 1, 2, 3}); + Iterable<ByteSource> cycle = Iterables.cycle(ImmutableList.of(source)); + ByteSource concatenated = ByteSource.concat(cycle); + + byte[] expected = {0, 1, 2, 3, 0, 1, 2, 3}; + assertArrayEquals(expected, concatenated.slice(0, 8).read()); + } + + private static final ByteSource BROKEN_CLOSE_SOURCE + = new TestByteSource(new byte[10], CLOSE_THROWS); + private static final ByteSource BROKEN_OPEN_SOURCE + = new TestByteSource(new byte[10], OPEN_THROWS); + private static final ByteSource BROKEN_READ_SOURCE + = new TestByteSource(new byte[10], READ_THROWS); + private static final ByteSink BROKEN_CLOSE_SINK + = new TestByteSink(CLOSE_THROWS); + private static final ByteSink BROKEN_OPEN_SINK + = new TestByteSink(OPEN_THROWS); + private static final ByteSink BROKEN_WRITE_SINK + = new TestByteSink(WRITE_THROWS); + + private static final ImmutableSet<ByteSource> BROKEN_SOURCES + = ImmutableSet.of(BROKEN_CLOSE_SOURCE, BROKEN_OPEN_SOURCE, BROKEN_READ_SOURCE); + private static final ImmutableSet<ByteSink> BROKEN_SINKS + = ImmutableSet.of(BROKEN_CLOSE_SINK, BROKEN_OPEN_SINK, BROKEN_WRITE_SINK); + + public void testCopyExceptions() { + if (!Closer.SuppressingSuppressor.isAvailable()) { + // test that exceptions are logged + + TestLogHandler logHandler = new TestLogHandler(); + Closeables.logger.addHandler(logHandler); + try { + for (ByteSource in : BROKEN_SOURCES) { + runFailureTest(in, newNormalByteSink()); + assertTrue(logHandler.getStoredLogRecords().isEmpty()); + + runFailureTest(in, BROKEN_CLOSE_SINK); + assertEquals((in == BROKEN_OPEN_SOURCE) ? 0 : 1, getAndResetRecords(logHandler)); + } + + for (ByteSink out : BROKEN_SINKS) { + runFailureTest(newNormalByteSource(), out); + assertTrue(logHandler.getStoredLogRecords().isEmpty()); + + runFailureTest(BROKEN_CLOSE_SOURCE, out); + assertEquals(1, getAndResetRecords(logHandler)); + } + + for (ByteSource in : BROKEN_SOURCES) { + for (ByteSink out : BROKEN_SINKS) { + runFailureTest(in, out); + assertTrue(getAndResetRecords(logHandler) <= 1); + } + } + } finally { + Closeables.logger.removeHandler(logHandler); + } + } else { + // test that exceptions are suppressed + + for (ByteSource in : BROKEN_SOURCES) { + int suppressed = runSuppressionFailureTest(in, newNormalByteSink()); + assertEquals(0, suppressed); + + suppressed = runSuppressionFailureTest(in, BROKEN_CLOSE_SINK); + assertEquals((in == BROKEN_OPEN_SOURCE) ? 0 : 1, suppressed); + } + + for (ByteSink out : BROKEN_SINKS) { + int suppressed = runSuppressionFailureTest(newNormalByteSource(), out); + assertEquals(0, suppressed); + + suppressed = runSuppressionFailureTest(BROKEN_CLOSE_SOURCE, out); + assertEquals(1, suppressed); + } + + for (ByteSource in : BROKEN_SOURCES) { + for (ByteSink out : BROKEN_SINKS) { + int suppressed = runSuppressionFailureTest(in, out); + assertTrue(suppressed <= 1); + } + } + } + } + + private static int getAndResetRecords(TestLogHandler logHandler) { + int records = logHandler.getStoredLogRecords().size(); + logHandler.clear(); + return records; + } + + private static void runFailureTest(ByteSource in, ByteSink out) { + try { + in.copyTo(out); + fail(); + } catch (IOException expected) { + } + } + + /** + * @return the number of exceptions that were suppressed on the expected thrown exception + */ + private static int runSuppressionFailureTest(ByteSource in, ByteSink out) { + try { + in.copyTo(out); + fail(); + } catch (IOException expected) { + return CloserTest.getSuppressed(expected).length; + } + throw new AssertionError(); // can't happen + } + + private static ByteSource newNormalByteSource() { + return ByteSource.wrap(new byte[10]); + } + + private static ByteSink newNormalByteSink() { + return new ByteSink() { + @Override public OutputStream openStream() { + return new ByteArrayOutputStream(); + } + }; + } } diff --git a/guava-tests/test/com/google/common/io/ByteSourceTester.java b/guava-tests/test/com/google/common/io/ByteSourceTester.java index ca59205..789cb8f 100644 --- a/guava-tests/test/com/google/common/io/ByteSourceTester.java +++ b/guava-tests/test/com/google/common/io/ByteSourceTester.java @@ -16,18 +16,17 @@ package com.google.common.io; +import static com.google.common.io.SourceSinkFactory.ByteSourceFactory; +import static com.google.common.io.SourceSinkFactory.CharSourceFactory; import static org.junit.Assert.assertArrayEquals; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableList; import com.google.common.hash.HashCode; import com.google.common.hash.Hashing; -import com.google.common.io.SourceSinkFactory.ByteSourceFactory; -import com.google.common.io.SourceSinkFactory.CharSourceFactory; import junit.framework.TestSuite; -import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -93,8 +92,9 @@ public class ByteSourceTester extends SourceSinkTester<ByteSource, byte[], ByteS // test a random slice() of the ByteSource Random random = new Random(); byte[] expected = factory.getExpected(bytes); - int off = random.nextInt(expected.length); - int len = random.nextInt(expected.length - off); + // if expected.length == 0, off has to be 0 but length doesn't matter--result will be empty + int off = expected.length == 0 ? 0 : random.nextInt(expected.length); + int len = expected.length == 0 ? 4 : random.nextInt(expected.length - off); ByteSourceFactory sliced = SourceSinkFactories.asSlicedByteSourceFactory(factory, off, len); suite.addTest(suiteForBytes(sliced, bytes, name + ".slice[int, int]", desc, false)); @@ -126,7 +126,7 @@ public class ByteSourceTester extends SourceSinkTester<ByteSource, byte[], ByteS } public void testOpenBufferedStream() throws IOException { - BufferedInputStream in = source.openBufferedStream(); + InputStream in = source.openBufferedStream(); try { byte[] readBytes = ByteStreams.toByteArray(in); assertExpectedBytes(readBytes); @@ -158,6 +158,10 @@ public class ByteSourceTester extends SourceSinkTester<ByteSource, byte[], ByteS assertExpectedBytes(out.toByteArray()); } + public void testIsEmpty() throws IOException { + assertEquals(expected.length == 0, source.isEmpty()); + } + public void testSize() throws IOException { assertEquals(expected.length, source.size()); } @@ -172,6 +176,25 @@ public class ByteSourceTester extends SourceSinkTester<ByteSource, byte[], ByteS })); } + public void testRead_usingByteProcessor() throws IOException { + byte[] readBytes = source.read(new ByteProcessor<byte[]>() { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + + @Override + public boolean processBytes(byte[] buf, int off, int len) throws IOException { + out.write(buf, off, len); + return true; + } + + @Override + public byte[] getResult() { + return out.toByteArray(); + } + }); + + assertExpectedBytes(readBytes); + } + public void testHash() throws IOException { HashCode expectedHash = Hashing.md5().hashBytes(expected); assertEquals(expectedHash, source.hash(Hashing.md5())); diff --git a/guava-tests/test/com/google/common/io/ByteStreamsTest.java b/guava-tests/test/com/google/common/io/ByteStreamsTest.java index f040daf..96a4ab0 100644 --- a/guava-tests/test/com/google/common/io/ByteStreamsTest.java +++ b/guava-tests/test/com/google/common/io/ByteStreamsTest.java @@ -17,23 +17,13 @@ package com.google.common.io; import static com.google.common.base.Charsets.UTF_16; -import static com.google.common.io.ByteStreams.copy; -import static com.google.common.io.ByteStreams.newInputStreamSupplier; - import com.google.common.base.Charsets; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; -import com.google.common.hash.Hashing; import com.google.common.jdk5backport.Arrays; -import com.google.common.testing.TestLogHandler; - -import junit.framework.TestSuite; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.FilterInputStream; -import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -41,7 +31,6 @@ import java.io.UnsupportedEncodingException; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; -import java.util.Random; import java.util.zip.CRC32; import java.util.zip.Checksum; @@ -52,424 +41,6 @@ import java.util.zip.Checksum; */ public class ByteStreamsTest extends IoTestCase { - public static TestSuite suite() { - TestSuite suite = new TestSuite(); - suite.addTest(ByteSourceTester.tests("ByteStreams.asByteSource[byte[]]", - SourceSinkFactories.byteArraySourceFactory(), true)); - suite.addTestSuite(ByteStreamsTest.class); - return suite; - } - - /** Provides an InputStream that throws an IOException on every read. */ - static final InputSupplier<InputStream> BROKEN_READ - = new InputSupplier<InputStream>() { - @Override - public InputStream getInput() { - return new InputStream() { - @Override public int read() throws IOException { - throw new IOException("broken read"); - } - }; - } - }; - - /** Provides an OutputStream that throws an IOException on every write. */ - static final OutputSupplier<OutputStream> BROKEN_WRITE - = new OutputSupplier<OutputStream>() { - @Override - public OutputStream getOutput() { - return new OutputStream() { - @Override public void write(int b) throws IOException { - throw new IOException("broken write"); - } - }; - } - }; - - /** Provides an InputStream that throws an IOException on close. */ - static final InputSupplier<InputStream> BROKEN_CLOSE_INPUT = - new InputSupplier<InputStream>() { - @Override - public InputStream getInput() { - return new FilterInputStream(new ByteArrayInputStream(new byte[10])) { - @Override public void close() throws IOException { - throw new IOException("broken close input"); - } - }; - } - }; - - /** Provides an OutputStream that throws an IOException on every close. */ - static final OutputSupplier<OutputStream> BROKEN_CLOSE_OUTPUT = - new OutputSupplier<OutputStream>() { - @Override - public OutputStream getOutput() { - return new FilterOutputStream(new ByteArrayOutputStream()) { - @Override public void close() throws IOException { - throw new IOException("broken close output"); - } - }; - } - }; - - /** Throws an IOException from getInput. */ - static final InputSupplier<InputStream> BROKEN_GET_INPUT = - new InputSupplier<InputStream>() { - @Override - public InputStream getInput() throws IOException { - throw new IOException("broken get input"); - } - }; - - /** Throws an IOException from getOutput. */ - static final OutputSupplier<OutputStream> BROKEN_GET_OUTPUT = - new OutputSupplier<OutputStream>() { - @Override - public OutputStream getOutput() throws IOException { - throw new IOException("broken get output"); - } - }; - - private static final ImmutableSet<InputSupplier<InputStream>> BROKEN_INPUTS = - ImmutableSet.of(BROKEN_CLOSE_INPUT, BROKEN_GET_INPUT, BROKEN_READ); - private static final ImmutableSet<OutputSupplier<OutputStream>> BROKEN_OUTPUTS - = ImmutableSet.of(BROKEN_CLOSE_OUTPUT, BROKEN_GET_OUTPUT, BROKEN_WRITE); - - public void testByteSuppliers() throws IOException { - byte[] range = newPreFilledByteArray(200); - assertEquals(range, - ByteStreams.toByteArray(ByteStreams.newInputStreamSupplier(range))); - - byte[] subRange = ByteStreams.toByteArray( - ByteStreams.newInputStreamSupplier(range, 100, 50)); - assertEquals(50, subRange.length); - assertEquals(100, subRange[0]); - assertEquals((byte) 149, subRange[subRange.length - 1]); - } - - public void testEqual() throws IOException { - equalHelper(false, 0, 1); - equalHelper(false, 400, 10000); - equalHelper(false, 0x2000, 0x2001); - equalHelper(false, new byte[]{ 0 }, new byte[]{ 1 }); - - byte[] mutate = newPreFilledByteArray(10000); - mutate[9000] = 0; - equalHelper(false, mutate, newPreFilledByteArray(10000)); - - equalHelper(true, 0, 0); - equalHelper(true, 1, 1); - equalHelper(true, 400, 400); - - final byte[] tenK = newPreFilledByteArray(10000); - equalHelper(true, tenK, tenK); - assertTrue(ByteStreams.equal(ByteStreams.newInputStreamSupplier(tenK), - new InputSupplier<InputStream>() { - @Override - public InputStream getInput() { - return new RandomAmountInputStream(new ByteArrayInputStream(tenK), - new Random(301)); - } - })); - } - - private static void equalHelper(boolean expect, int size1, int size2) - throws IOException { - equalHelper(expect, newPreFilledByteArray(size1), - newPreFilledByteArray(size2)); - } - - private static void equalHelper(boolean expect, byte[] a, byte[] b) - throws IOException { - assertEquals(expect, ByteStreams.equal( - ByteStreams.newInputStreamSupplier(a), - ByteStreams.newInputStreamSupplier(b))); - } - - public void testAlwaysCloses() throws IOException { - byte[] range = newPreFilledByteArray(100); - CheckCloseSupplier.Input<InputStream> okRead - = newCheckInput(ByteStreams.newInputStreamSupplier(range)); - CheckCloseSupplier.Output<OutputStream> okWrite - = newCheckOutput(new OutputSupplier<OutputStream>() { - @Override - public OutputStream getOutput() { - return new ByteArrayOutputStream(); - } - }); - - CheckCloseSupplier.Input<InputStream> brokenRead - = newCheckInput(BROKEN_READ); - CheckCloseSupplier.Output<OutputStream> brokenWrite - = newCheckOutput(BROKEN_WRITE); - - // copy, both suppliers - ByteStreams.copy(okRead, okWrite); - assertTrue(okRead.areClosed()); - assertTrue(okWrite.areClosed()); - - try { - ByteStreams.copy(okRead, brokenWrite); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken write", e.getMessage()); - } - assertTrue(okRead.areClosed()); - assertTrue(brokenWrite.areClosed()); - - try { - ByteStreams.copy(brokenRead, okWrite); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - assertTrue(okWrite.areClosed()); - - try { - ByteStreams.copy(brokenRead, brokenWrite); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - assertTrue(brokenWrite.areClosed()); - - // copy, input supplier - OutputStream out = okWrite.getOutput(); - ByteStreams.copy(okRead, out); - assertTrue(okRead.areClosed()); - assertFalse(okWrite.areClosed()); - out.close(); - - out = brokenWrite.getOutput(); - try { - ByteStreams.copy(okRead, out); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken write", e.getMessage()); - } - assertTrue(okRead.areClosed()); - assertFalse(brokenWrite.areClosed()); - out.close(); - - out = okWrite.getOutput(); - try { - ByteStreams.copy(brokenRead, out); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - assertFalse(okWrite.areClosed()); - out.close(); - - out = brokenWrite.getOutput(); - try { - ByteStreams.copy(brokenRead, out); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - assertFalse(brokenWrite.areClosed()); - out.close(); - - // copy, output supplier - InputStream in = okRead.getInput(); - ByteStreams.copy(in, okWrite); - assertFalse(okRead.areClosed()); - assertTrue(okWrite.areClosed()); - in.close(); - - in = okRead.getInput(); - try { - ByteStreams.copy(in, brokenWrite); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken write", e.getMessage()); - } - assertFalse(okRead.areClosed()); - assertTrue(brokenWrite.areClosed()); - in.close(); - - in = brokenRead.getInput(); - try { - ByteStreams.copy(in, okWrite); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken read", e.getMessage()); - } - assertFalse(brokenRead.areClosed()); - assertTrue(okWrite.areClosed()); - in.close(); - - in = brokenRead.getInput(); - try { - ByteStreams.copy(in, brokenWrite); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken read", e.getMessage()); - } - assertFalse(brokenRead.areClosed()); - assertTrue(brokenWrite.areClosed()); - in.close(); - - // toByteArray - assertEquals(range, ByteStreams.toByteArray(okRead)); - assertTrue(okRead.areClosed()); - - try { - ByteStreams.toByteArray(brokenRead); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - - // equal - try { - ByteStreams.equal(brokenRead, okRead); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - - try { - ByteStreams.equal(okRead, brokenRead); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - - // write - try { - ByteStreams.write(new byte[10], brokenWrite); - fail("expected exception"); - } catch (IOException e) { - assertEquals("broken write", e.getMessage()); - } - assertTrue(brokenWrite.areClosed()); - } - - public void testCopySuppliersExceptions() { - if (!Closer.SuppressingSuppressor.isAvailable()) { - // test that exceptions are logged - - TestLogHandler logHandler = new TestLogHandler(); - Closeables.logger.addHandler(logHandler); - try { - for (InputSupplier<InputStream> in : BROKEN_INPUTS) { - runFailureTest(in, newByteArrayOutputStreamSupplier()); - assertTrue(logHandler.getStoredLogRecords().isEmpty()); - - runFailureTest(in, BROKEN_CLOSE_OUTPUT); - assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, getAndResetRecords(logHandler)); - } - - for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) { - runFailureTest(newInputStreamSupplier(new byte[10]), out); - assertTrue(logHandler.getStoredLogRecords().isEmpty()); - - runFailureTest(BROKEN_CLOSE_INPUT, out); - assertEquals(1, getAndResetRecords(logHandler)); - } - - for (InputSupplier<InputStream> in : BROKEN_INPUTS) { - for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) { - runFailureTest(in, out); - assertTrue(getAndResetRecords(logHandler) <= 1); - } - } - } finally { - Closeables.logger.removeHandler(logHandler); - } - } else { - // test that exceptions are suppressed - - for (InputSupplier<InputStream> in : BROKEN_INPUTS) { - int suppressed = runSuppressionFailureTest(in, newByteArrayOutputStreamSupplier()); - assertEquals(0, suppressed); - - suppressed = runSuppressionFailureTest(in, BROKEN_CLOSE_OUTPUT); - assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, suppressed); - } - - for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) { - int suppressed = runSuppressionFailureTest(newInputStreamSupplier(new byte[10]), out); - assertEquals(0, suppressed); - - suppressed = runSuppressionFailureTest(BROKEN_CLOSE_INPUT, out); - assertEquals(1, suppressed); - } - - for (InputSupplier<InputStream> in : BROKEN_INPUTS) { - for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) { - int suppressed = runSuppressionFailureTest(in, out); - assertTrue(suppressed <= 1); - } - } - } - } - - private static int getAndResetRecords(TestLogHandler logHandler) { - int records = logHandler.getStoredLogRecords().size(); - logHandler.clear(); - return records; - } - - private static void runFailureTest( - InputSupplier<? extends InputStream> in, OutputSupplier<OutputStream> out) { - try { - copy(in, out); - fail(); - } catch (IOException expected) { - } - } - - /** - * @return the number of exceptions that were suppressed on the expected thrown exception - */ - private static int runSuppressionFailureTest( - InputSupplier<? extends InputStream> in, OutputSupplier<OutputStream> out) { - try { - copy(in, out); - fail(); - } catch (IOException expected) { - return CloserTest.getSuppressed(expected).length; - } - throw new AssertionError(); // can't happen - } - - private static OutputSupplier<OutputStream> newByteArrayOutputStreamSupplier() { - return new OutputSupplier<OutputStream>() { - @Override public OutputStream getOutput() { - return new ByteArrayOutputStream(); - } - }; - } - - public void testWriteBytes() throws IOException { - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] expected = newPreFilledByteArray(100); - ByteStreams.write(expected, new OutputSupplier<OutputStream>() { - @Override public OutputStream getOutput() { - return out; - } - }); - assertEquals(expected, out.toByteArray()); - } - - public void testCopy() throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] expected = newPreFilledByteArray(100); - long num = ByteStreams.copy(new ByteArrayInputStream(expected), out); - assertEquals(100, num); - assertEquals(expected, out.toByteArray()); - } - public void testCopyChannel() throws IOException { byte[] expected = newPreFilledByteArray(100); ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -568,7 +139,7 @@ public class ByteStreamsTest extends IoTestCase { ByteArrayDataInput in = ByteStreams.newDataInput(b); try { in.readInt(); - fail(); + fail("expected exception"); } catch (IllegalStateException expected) { } } @@ -579,7 +150,7 @@ public class ByteStreamsTest extends IoTestCase { assertEquals(0x76543210, in.readInt()); try { in.readInt(); - fail(); + fail("expected exception"); } catch (IllegalStateException expected) { } } @@ -590,18 +161,18 @@ public class ByteStreamsTest extends IoTestCase { in.readFully(actual); assertEquals(bytes, actual); } - + public void testNewDataInput_readFullyAndThenSome() { ByteArrayDataInput in = ByteStreams.newDataInput(bytes); byte[] actual = new byte[bytes.length * 2]; try { in.readFully(actual); - fail(); + fail("expected exception"); } catch (IllegalStateException ex) { assertTrue(ex.getCause() instanceof EOFException); } } - + public void testNewDataInput_readFullyWithOffset() { ByteArrayDataInput in = ByteStreams.newDataInput(bytes); byte[] actual = new byte[4]; @@ -611,7 +182,7 @@ public class ByteStreamsTest extends IoTestCase { assertEquals(bytes[0], actual[2]); assertEquals(bytes[1], actual[3]); } - + public void testNewDataInput_readLine() throws UnsupportedEncodingException { ByteArrayDataInput in = ByteStreams.newDataInput( "This is a line\r\nThis too\rand this\nand also this".getBytes(Charsets.UTF_8.name())); @@ -627,7 +198,7 @@ public class ByteStreamsTest extends IoTestCase { assertEquals(Float.intBitsToFloat(0x12345678), in.readFloat(), 0.0); assertEquals(Float.intBitsToFloat(0x76543210), in.readFloat(), 0.0); } - + public void testNewDataInput_readDouble() { byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10}; ByteArrayDataInput in = ByteStreams.newDataInput(data); @@ -649,7 +220,7 @@ public class ByteStreamsTest extends IoTestCase { assertEquals('e', in.readChar()); assertEquals('d', in.readChar()); } - + public void testNewDataInput_readUnsignedShort() { byte[] data = {0, 0, 0, 1, (byte) 0xFF, (byte) 0xFF, 0x12, 0x34}; ByteArrayDataInput in = ByteStreams.newDataInput(data); @@ -658,7 +229,7 @@ public class ByteStreamsTest extends IoTestCase { assertEquals(65535, in.readUnsignedShort()); assertEquals(0x1234, in.readUnsignedShort()); } - + public void testNewDataInput_readLong() { byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10}; ByteArrayDataInput in = ByteStreams.newDataInput(data); @@ -669,7 +240,7 @@ public class ByteStreamsTest extends IoTestCase { ByteArrayDataInput in = ByteStreams.newDataInput(bytes); assertTrue(in.readBoolean()); } - + public void testNewDataInput_readByte() { ByteArrayDataInput in = ByteStreams.newDataInput(bytes); for (int i = 0; i < bytes.length; i++) { @@ -677,7 +248,7 @@ public class ByteStreamsTest extends IoTestCase { } try { in.readByte(); - fail(); + fail("expected exception"); } catch (IllegalStateException ex) { assertTrue(ex.getCause() instanceof EOFException); } @@ -690,7 +261,7 @@ public class ByteStreamsTest extends IoTestCase { } try { in.readUnsignedByte(); - fail(); + fail("expected exception"); } catch (IllegalStateException ex) { assertTrue(ex.getCause() instanceof EOFException); } @@ -701,18 +272,21 @@ public class ByteStreamsTest extends IoTestCase { assertEquals(0x56787654, in.readInt()); try { in.readInt(); - fail(); + fail("expected exception"); } catch (IllegalStateException expected) { } } public void testNewDataInput_skip() { ByteArrayDataInput in = ByteStreams.newDataInput(new byte[2]); - in.skipBytes(2); - try { - in.skipBytes(1); - } catch (IllegalStateException expected) { - } + assertEquals(2, in.skipBytes(2)); + assertEquals(0, in.skipBytes(1)); + } + + public void testNewDataInput_BAIS() { + ByteArrayInputStream bais = new ByteArrayInputStream(new byte[] {0x12, 0x34, 0x56, 0x78}); + ByteArrayDataInput in = ByteStreams.newDataInput(bais); + assertEquals(0x12345678, in.readInt()); } public void testNewDataOutput_empty() { @@ -827,131 +401,42 @@ public class ByteStreamsTest extends IoTestCase { assertEquals(0L, checksum.getValue()); } - public void testHash() throws IOException { - InputSupplier<ByteArrayInputStream> asciiBytes = - ByteStreams.newInputStreamSupplier(ASCII.getBytes(Charsets.US_ASCII.name())); - InputSupplier<ByteArrayInputStream> i18nBytes = - ByteStreams.newInputStreamSupplier(I18N.getBytes(Charsets.UTF_8.name())); - - String init = "d41d8cd98f00b204e9800998ecf8427e"; - assertEquals(init, Hashing.md5().newHasher().hash().toString()); - - String asciiHash = "e5df5a39f2b8cb71b24e1d8038f93131"; - assertEquals(asciiHash, ByteStreams.hash(asciiBytes, Hashing.md5()).toString()); - - String i18nHash = "7fa826962ce2079c8334cd4ebf33aea4"; - assertEquals(i18nHash, ByteStreams.hash(i18nBytes, Hashing.md5()).toString()); + public void testNewDataOutput_BAOS() { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteArrayDataOutput out = ByteStreams.newDataOutput(baos); + out.writeInt(0x12345678); + assertEquals(4, baos.size()); + assertEquals(new byte[] {0x12, 0x34, 0x56, 0x78}, baos.toByteArray()); } - public void testLength() throws IOException { - lengthHelper(Long.MAX_VALUE); - lengthHelper(7); - lengthHelper(1); - lengthHelper(0); - - assertEquals(0, ByteStreams.length( - ByteStreams.newInputStreamSupplier(new byte[0]))); + public void testToByteArray_withSize_givenCorrectSize() throws IOException { + InputStream in = newTestStream(100); + byte[] b = ByteStreams.toByteArray(in, 100); + assertEquals(100, b.length); } - private static void lengthHelper(final long skipLimit) throws IOException { - assertEquals(100, ByteStreams.length(new InputSupplier<InputStream>() { - @Override - public InputStream getInput() { - return new SlowSkipper(new ByteArrayInputStream(new byte[100]), - skipLimit); - } - })); + public void testToByteArray_withSize_givenSmallerSize() throws IOException { + InputStream in = newTestStream(100); + byte[] b = ByteStreams.toByteArray(in, 80); + assertEquals(100, b.length); } - public void testSlice() throws IOException { - // Test preconditions - InputSupplier<? extends InputStream> supplier - = ByteStreams.newInputStreamSupplier(newPreFilledByteArray(100)); - try { - ByteStreams.slice(supplier, -1, 10); - fail("expected exception"); - } catch (IllegalArgumentException expected) { - } - - try { - ByteStreams.slice(supplier, 0, -1); - fail("expected exception"); - } catch (IllegalArgumentException expected) { - } - - try { - ByteStreams.slice(null, 0, 10); - fail("expected exception"); - } catch (NullPointerException expected) { - } - - sliceHelper(0, 0, 0, 0); - sliceHelper(0, 0, 1, 0); - sliceHelper(100, 0, 10, 10); - sliceHelper(100, 0, 100, 100); - sliceHelper(100, 5, 10, 10); - sliceHelper(100, 5, 100, 95); - sliceHelper(100, 100, 0, 0); - sliceHelper(100, 100, 10, 0); - - try { - sliceHelper(100, 101, 10, 0); - fail("expected exception"); - } catch (EOFException expected) { - } + public void testToByteArray_withSize_givenLargerSize() throws IOException { + InputStream in = newTestStream(100); + byte[] b = ByteStreams.toByteArray(in, 120); + assertEquals(100, b.length); } - /** - * @param input the size of the input stream - * @param offset the first argument to {@link ByteStreams#slice} - * @param length the second argument to {@link ByteStreams#slice} - * @param expectRead the number of bytes we expect to read - */ - private static void sliceHelper( - int input, int offset, long length, int expectRead) throws IOException { - Preconditions.checkArgument(expectRead == (int) - Math.max(0, Math.min(input, offset + length) - offset)); - InputSupplier<? extends InputStream> supplier - = ByteStreams.newInputStreamSupplier(newPreFilledByteArray(input)); - assertEquals( - newPreFilledByteArray(offset, expectRead), - ByteStreams.toByteArray(ByteStreams.slice(supplier, offset, length))); + public void testToByteArray_withSize_givenSizeZero() throws IOException { + InputStream in = newTestStream(100); + byte[] b = ByteStreams.toByteArray(in, 0); + assertEquals(100, b.length); } private static InputStream newTestStream(int n) { return new ByteArrayInputStream(newPreFilledByteArray(n)); } - private static CheckCloseSupplier.Input<InputStream> newCheckInput( - InputSupplier<? extends InputStream> delegate) { - return new CheckCloseSupplier.Input<InputStream>(delegate) { - @Override protected InputStream wrap(InputStream object, - final Callback callback) { - return new FilterInputStream(object) { - @Override public void close() throws IOException { - callback.delegateClosed(); - super.close(); - } - }; - } - }; - } - - private static CheckCloseSupplier.Output<OutputStream> newCheckOutput( - OutputSupplier<? extends OutputStream> delegate) { - return new CheckCloseSupplier.Output<OutputStream>(delegate) { - @Override protected OutputStream wrap(OutputStream object, - final Callback callback) { - return new FilterOutputStream(object) { - @Override public void close() throws IOException { - callback.delegateClosed(); - super.close(); - } - }; - } - }; - } - /** Stream that will skip a maximum number of bytes at a time. */ private static class SlowSkipper extends FilterInputStream { private final long max; @@ -970,13 +455,6 @@ public class ByteStreamsTest extends IoTestCase { final byte[] array = newPreFilledByteArray(1000); assertEquals(array, ByteStreams.readBytes( new ByteArrayInputStream(array), new TestByteProcessor())); - assertEquals(array, ByteStreams.readBytes( - new InputSupplier<InputStream>() { - @Override - public InputStream getInput() { - return new ByteArrayInputStream(array); - } - }, new TestByteProcessor())); } private class TestByteProcessor implements ByteProcessor<byte[]> { @@ -998,7 +476,7 @@ public class ByteStreamsTest extends IoTestCase { public void testByteProcessorStopEarly() throws IOException { byte[] array = newPreFilledByteArray(6000); assertEquals((Integer) 42, - ByteStreams.readBytes(ByteStreams.newInputStreamSupplier(array), + ByteStreams.readBytes(new ByteArrayInputStream(array), new ByteProcessor<Integer>() { @Override public boolean processBytes(byte[] buf, int off, int len) { @@ -1095,7 +573,7 @@ public class ByteStreamsTest extends IoTestCase { lin.skip(3); assertEquals(0, lin.available()); } - + public void testLimit_markNotSet() { byte[] big = newPreFilledByteArray(5); InputStream bin = new ByteArrayInputStream(big); @@ -1108,7 +586,7 @@ public class ByteStreamsTest extends IoTestCase { assertEquals("Mark not set", expected.getMessage()); } } - + public void testLimit_markNotSupported() { InputStream lin = ByteStreams.limit(new UnmarkableInputStream(), 2); diff --git a/guava-tests/test/com/google/common/io/CharSequenceReaderTest.java b/guava-tests/test/com/google/common/io/CharSequenceReaderTest.java new file mode 100644 index 0000000..6e2bb9f --- /dev/null +++ b/guava-tests/test/com/google/common/io/CharSequenceReaderTest.java @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.io; + +import junit.framework.TestCase; + +import java.io.IOException; +import java.nio.CharBuffer; + +/** + * Tests for {@link CharSequenceReader}. + * + * @author Colin Decker + */ +public class CharSequenceReaderTest extends TestCase { + + public void testReadEmptyString() throws IOException { + assertReadsCorrectly(""); + } + + public void testReadsStringsCorrectly() throws IOException { + assertReadsCorrectly("abc"); + assertReadsCorrectly("abcde"); + assertReadsCorrectly("abcdefghijkl"); + assertReadsCorrectly("" + + "abcdefghijklmnopqrstuvwxyz\n" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r" + + "0123456789\r\n" + + "!@#$%^&*()-=_+\t[]{};':\",./<>?\\| "); + } + + public void testMarkAndReset() throws IOException { + String string = "abcdefghijklmnopqrstuvwxyz"; + CharSequenceReader reader = new CharSequenceReader(string); + assertTrue(reader.markSupported()); + + assertEquals(string, readFully(reader)); + assertFullyRead(reader); + + // reset and read again + reader.reset(); + assertEquals(string, readFully(reader)); + assertFullyRead(reader); + + // reset, skip, mark, then read the rest + reader.reset(); + assertEquals(5, reader.skip(5)); + reader.mark(Integer.MAX_VALUE); + assertEquals(string.substring(5), readFully(reader)); + assertFullyRead(reader); + + // reset to the mark and then read the rest + reader.reset(); + assertEquals(string.substring(5), readFully(reader)); + assertFullyRead(reader); + } + + public void testIllegalArguments() throws IOException { + CharSequenceReader reader = new CharSequenceReader("12345"); + + char[] buf = new char[10]; + try { + reader.read(buf, 0, 11); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + try { + reader.read(buf, 10, 1); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + try { + reader.read(buf, 11, 0); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + try { + reader.read(buf, -1, 5); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + try { + reader.read(buf, 5, -1); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + try { + reader.read(buf, 0, 11); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + try { + reader.skip(-1); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + reader.mark(-1); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testMethodsThrowWhenClosed() throws IOException { + CharSequenceReader reader = new CharSequenceReader(""); + reader.close(); + + try { + reader.read(); + fail(); + } catch (IOException expected) { + } + + try { + reader.read(new char[10]); + fail(); + } catch (IOException expected) { + } + + try { + reader.read(new char[10], 0, 10); + fail(); + } catch (IOException expected) { + } + + try { + reader.read(CharBuffer.allocate(10)); + fail(); + } catch (IOException expected) { + } + + try { + reader.skip(10); + fail(); + } catch (IOException expected) { + } + + try { + reader.ready(); + fail(); + } catch (IOException expected) { + } + + try { + reader.mark(10); + fail(); + } catch (IOException expected) { + } + + try { + reader.reset(); + fail(); + } catch (IOException expected) { + } + } + + /** + * Creates a CharSequenceReader wrapping the given CharSequence and tests that the reader produces + * the same sequence when read using each type of read method it provides. + */ + private static void assertReadsCorrectly(CharSequence charSequence) throws IOException { + String expected = charSequence.toString(); + + // read char by char + CharSequenceReader reader = new CharSequenceReader(charSequence); + for (int i = 0; i < expected.length(); i++) { + assertEquals(expected.charAt(i), reader.read()); + } + assertFullyRead(reader); + + // read all to one array + reader = new CharSequenceReader(charSequence); + char[] buf = new char[expected.length()]; + assertEquals(expected.length() == 0 ? -1 : expected.length(), reader.read(buf)); + assertEquals(expected, new String(buf)); + assertFullyRead(reader); + + // read in chunks to fixed array + reader = new CharSequenceReader(charSequence); + buf = new char[5]; + StringBuilder builder = new StringBuilder(); + int read; + while ((read = reader.read(buf, 0, buf.length)) != -1) { + builder.append(buf, 0, read); + } + assertEquals(expected, builder.toString()); + assertFullyRead(reader); + + // read all to one CharBuffer + reader = new CharSequenceReader(charSequence); + CharBuffer buf2 = CharBuffer.allocate(expected.length()); + assertEquals(expected.length() == 0 ? -1 : expected.length(), reader.read(buf2)); + buf2.flip(); + assertEquals(expected, buf2.toString()); + assertFullyRead(reader); + + // read in chunks to fixed CharBuffer + reader = new CharSequenceReader(charSequence); + buf2 = CharBuffer.allocate(5); + builder = new StringBuilder(); + while (reader.read(buf2) != -1) { + buf2.flip(); + builder.append(buf2); + buf2.clear(); + } + assertEquals(expected, builder.toString()); + assertFullyRead(reader); + + // skip fully + reader = new CharSequenceReader(charSequence); + assertEquals(expected.length(), reader.skip(Long.MAX_VALUE)); + assertFullyRead(reader); + + // skip 5 and read the rest + if (expected.length() > 5) { + reader = new CharSequenceReader(charSequence); + assertEquals(5, reader.skip(5)); + + buf = new char[expected.length() - 5]; + assertEquals(buf.length, reader.read(buf, 0, buf.length)); + assertEquals(expected.substring(5), new String(buf)); + assertFullyRead(reader); + } + } + + private static void assertFullyRead(CharSequenceReader reader) throws IOException { + assertEquals(-1, reader.read()); + assertEquals(-1, reader.read(new char[10], 0, 10)); + assertEquals(-1, reader.read(CharBuffer.allocate(10))); + assertEquals(0, reader.skip(10)); + } + + private static String readFully(CharSequenceReader reader) throws IOException { + StringBuilder builder = new StringBuilder(); + int read; + while ((read = reader.read()) != -1) { + builder.append((char) read); + } + return builder.toString(); + } +} diff --git a/guava-tests/test/com/google/common/io/CharSinkTest.java b/guava-tests/test/com/google/common/io/CharSinkTest.java index 9fd88d3..c98d474 100644 --- a/guava-tests/test/com/google/common/io/CharSinkTest.java +++ b/guava-tests/test/com/google/common/io/CharSinkTest.java @@ -23,9 +23,9 @@ import static com.google.common.io.TestOption.WRITE_THROWS; import com.google.common.collect.ImmutableList; -import java.io.BufferedWriter; import java.io.IOException; import java.io.StringReader; +import java.io.Writer; import java.util.EnumSet; /** @@ -45,7 +45,7 @@ public class CharSinkTest extends IoTestCase { } public void testOpenBufferedStream() throws IOException { - BufferedWriter writer = sink.openBufferedStream(); + Writer writer = sink.openBufferedStream(); assertTrue(sink.wasStreamOpened()); assertFalse(sink.wasStreamClosed()); diff --git a/guava-tests/test/com/google/common/io/CharSinkTester.java b/guava-tests/test/com/google/common/io/CharSinkTester.java index 31edaa5..9ad4175 100644 --- a/guava-tests/test/com/google/common/io/CharSinkTester.java +++ b/guava-tests/test/com/google/common/io/CharSinkTester.java @@ -16,18 +16,18 @@ package com.google.common.io; +import static com.google.common.io.SourceSinkFactory.CharSinkFactory; + import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; -import com.google.common.io.SourceSinkFactory.CharSinkFactory; -import java.io.BufferedWriter; +import junit.framework.TestSuite; + import java.io.IOException; import java.io.Writer; import java.lang.reflect.Method; import java.util.Map; -import junit.framework.TestSuite; - /** * A generator of {@code TestSuite} instances for testing {@code CharSink} implementations. * Generates tests of a all methods on a {@code CharSink} given various inputs written to it. @@ -87,7 +87,7 @@ public class CharSinkTester extends SourceSinkTester<CharSink, String, CharSinkF } public void testOpenBufferedStream() throws IOException { - BufferedWriter writer = sink.openBufferedStream(); + Writer writer = sink.openBufferedStream(); try { writer.write(data); } finally { diff --git a/guava-tests/test/com/google/common/io/CharSourceTest.java b/guava-tests/test/com/google/common/io/CharSourceTest.java index 6474d5a..4fa5b86 100644 --- a/guava-tests/test/com/google/common/io/CharSourceTest.java +++ b/guava-tests/test/com/google/common/io/CharSourceTest.java @@ -22,11 +22,20 @@ import static com.google.common.io.TestOption.READ_THROWS; import static com.google.common.io.TestOption.WRITE_THROWS; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.testing.TestLogHandler; + +import junit.framework.TestSuite; import java.io.BufferedReader; import java.io.IOException; +import java.io.Reader; import java.io.StringWriter; +import java.io.Writer; import java.util.EnumSet; +import java.util.List; /** * Tests for the default implementations of {@code CharSource} methods. @@ -35,6 +44,16 @@ import java.util.EnumSet; */ public class CharSourceTest extends IoTestCase { + public static TestSuite suite() { + TestSuite suite = new TestSuite(); + suite.addTest(CharSourceTester.tests("CharSource.wrap[CharSequence]", + SourceSinkFactories.stringCharSourceFactory())); + suite.addTest(CharSourceTester.tests("CharSource.empty[]", + SourceSinkFactories.emptyCharSourceFactory())); + suite.addTestSuite(CharStreamsTest.class); + return suite; + } + private static final String STRING = ASCII + I18N; private static final String LINES = "foo\nbar\r\nbaz\rsomething"; @@ -101,6 +120,46 @@ public class CharSourceTest extends IoTestCase { assertTrue(lines.wasStreamOpened() && lines.wasStreamClosed()); } + public void testReadLines_withProcessor() throws IOException { + TestCharSource lines = new TestCharSource(LINES); + List<String> list = lines.readLines(new LineProcessor<List<String>>() { + List<String> list = Lists.newArrayList(); + + @Override + public boolean processLine(String line) throws IOException { + list.add(line); + return true; + } + + @Override + public List<String> getResult() { + return list; + } + }); + assertEquals(ImmutableList.of("foo", "bar", "baz", "something"), list); + assertTrue(lines.wasStreamOpened() && lines.wasStreamClosed()); + } + + public void testReadLines_withProcessor_stopsOnFalse() throws IOException { + TestCharSource lines = new TestCharSource(LINES); + List<String> list = lines.readLines(new LineProcessor<List<String>>() { + List<String> list = Lists.newArrayList(); + + @Override + public boolean processLine(String line) throws IOException { + list.add(line); + return false; + } + + @Override + public List<String> getResult() { + return list; + } + }); + assertEquals(ImmutableList.of("foo"), list); + assertTrue(lines.wasStreamOpened() && lines.wasStreamClosed()); + } + public void testCopyToAppendable_doesNotCloseIfWriter() throws IOException { TestWriter writer = new TestWriter(); assertFalse(writer.closed()); @@ -142,4 +201,151 @@ public class CharSourceTest extends IoTestCase { } assertTrue(okSource.wasStreamClosed()); } + + public void testConcat() throws IOException { + CharSource c1 = CharSource.wrap("abc"); + CharSource c2 = CharSource.wrap(""); + CharSource c3 = CharSource.wrap("de"); + + String expected = "abcde"; + + assertEquals(expected, + CharSource.concat(ImmutableList.of(c1, c2, c3)).read()); + assertEquals(expected, + CharSource.concat(c1, c2, c3).read()); + assertEquals(expected, + CharSource.concat(ImmutableList.of(c1, c2, c3).iterator()).read()); + assertFalse(CharSource.concat(c1, c2, c3).isEmpty()); + + CharSource emptyConcat = CharSource.concat(CharSource.empty(), CharSource.empty()); + assertTrue(emptyConcat.isEmpty()); + } + + public void testConcat_infiniteIterable() throws IOException { + CharSource source = CharSource.wrap("abcd"); + Iterable<CharSource> cycle = Iterables.cycle(ImmutableList.of(source)); + CharSource concatenated = CharSource.concat(cycle); + + String expected = "abcdabcd"; + + // read the first 8 chars manually, since there's no equivalent to ByteSource.slice + // TODO(user): Add CharSource.slice? + StringBuilder builder = new StringBuilder(); + Reader reader = concatenated.openStream(); // no need to worry about closing + for (int i = 0; i < 8; i++) { + builder.append((char) reader.read()); + } + assertEquals(expected, builder.toString()); + } + + static final CharSource BROKEN_READ_SOURCE = new TestCharSource("ABC", READ_THROWS); + static final CharSource BROKEN_CLOSE_SOURCE = new TestCharSource("ABC", CLOSE_THROWS); + static final CharSource BROKEN_OPEN_SOURCE = new TestCharSource("ABC", OPEN_THROWS); + static final CharSink BROKEN_WRITE_SINK = new TestCharSink(WRITE_THROWS); + static final CharSink BROKEN_CLOSE_SINK = new TestCharSink(CLOSE_THROWS); + static final CharSink BROKEN_OPEN_SINK = new TestCharSink(OPEN_THROWS); + + private static final ImmutableSet<CharSource> BROKEN_SOURCES + = ImmutableSet.of(BROKEN_CLOSE_SOURCE, BROKEN_OPEN_SOURCE, BROKEN_READ_SOURCE); + private static final ImmutableSet<CharSink> BROKEN_SINKS + = ImmutableSet.of(BROKEN_CLOSE_SINK, BROKEN_OPEN_SINK, BROKEN_WRITE_SINK); + + public void testCopyExceptions() { + if (!Closer.SuppressingSuppressor.isAvailable()) { + // test that exceptions are logged + + TestLogHandler logHandler = new TestLogHandler(); + Closeables.logger.addHandler(logHandler); + try { + for (CharSource in : BROKEN_SOURCES) { + runFailureTest(in, newNormalCharSink()); + assertTrue(logHandler.getStoredLogRecords().isEmpty()); + + runFailureTest(in, BROKEN_CLOSE_SINK); + assertEquals((in == BROKEN_OPEN_SOURCE) ? 0 : 1, getAndResetRecords(logHandler)); + } + + for (CharSink out : BROKEN_SINKS) { + runFailureTest(newNormalCharSource(), out); + assertTrue(logHandler.getStoredLogRecords().isEmpty()); + + runFailureTest(BROKEN_CLOSE_SOURCE, out); + assertEquals(1, getAndResetRecords(logHandler)); + } + + for (CharSource in : BROKEN_SOURCES) { + for (CharSink out : BROKEN_SINKS) { + runFailureTest(in, out); + assertTrue(getAndResetRecords(logHandler) <= 1); + } + } + } finally { + Closeables.logger.removeHandler(logHandler); + } + } else { + // test that exceptions are suppressed + + for (CharSource in : BROKEN_SOURCES) { + int suppressed = runSuppressionFailureTest(in, newNormalCharSink()); + assertEquals(0, suppressed); + + suppressed = runSuppressionFailureTest(in, BROKEN_CLOSE_SINK); + assertEquals((in == BROKEN_OPEN_SOURCE) ? 0 : 1, suppressed); + } + + for (CharSink out : BROKEN_SINKS) { + int suppressed = runSuppressionFailureTest(newNormalCharSource(), out); + assertEquals(0, suppressed); + + suppressed = runSuppressionFailureTest(BROKEN_CLOSE_SOURCE, out); + assertEquals(1, suppressed); + } + + for (CharSource in : BROKEN_SOURCES) { + for (CharSink out : BROKEN_SINKS) { + int suppressed = runSuppressionFailureTest(in, out); + assertTrue(suppressed <= 1); + } + } + } + } + + private static int getAndResetRecords(TestLogHandler logHandler) { + int records = logHandler.getStoredLogRecords().size(); + logHandler.clear(); + return records; + } + + private static void runFailureTest(CharSource in, CharSink out) { + try { + in.copyTo(out); + fail(); + } catch (IOException expected) { + } + } + + /** + * @return the number of exceptions that were suppressed on the expected thrown exception + */ + private static int runSuppressionFailureTest(CharSource in, CharSink out) { + try { + in.copyTo(out); + fail(); + } catch (IOException expected) { + return CloserTest.getSuppressed(expected).length; + } + throw new AssertionError(); // can't happen + } + + private static CharSource newNormalCharSource() { + return CharSource.wrap("ABC"); + } + + private static CharSink newNormalCharSink() { + return new CharSink() { + @Override public Writer openStream() { + return new StringWriter(); + } + }; + } } diff --git a/guava-tests/test/com/google/common/io/CharSourceTester.java b/guava-tests/test/com/google/common/io/CharSourceTester.java index 6d5367d..8d5bc79 100644 --- a/guava-tests/test/com/google/common/io/CharSourceTester.java +++ b/guava-tests/test/com/google/common/io/CharSourceTester.java @@ -16,8 +16,12 @@ package com.google.common.io; +import static com.google.common.io.SourceSinkFactory.CharSourceFactory; + import com.google.common.collect.ImmutableList; -import com.google.common.io.SourceSinkFactory.CharSourceFactory; +import com.google.common.collect.Lists; + +import junit.framework.TestSuite; import java.io.BufferedReader; import java.io.IOException; @@ -27,8 +31,6 @@ import java.lang.reflect.Method; import java.util.List; import java.util.Map; -import junit.framework.TestSuite; - /** * A generator of {@code TestSuite} instances for testing {@code CharSource} implementations. * Generates tests of a all methods on a {@code CharSource} given various inputs the source is @@ -136,6 +138,52 @@ public class CharSourceTester extends SourceSinkTester<CharSource, String, CharS assertExpectedLines(source.readLines()); } + public void testIsEmpty() throws IOException { + assertEquals(expected.length() == 0, source.isEmpty()); + } + + public void testReadLines_withProcessor() throws IOException { + List<String> list = source.readLines(new LineProcessor<List<String>>() { + List<String> list = Lists.newArrayList(); + + @Override + public boolean processLine(String line) throws IOException { + list.add(line); + return true; + } + + @Override + public List<String> getResult() { + return list; + } + }); + + assertExpectedLines(list); + } + + public void testReadLines_withProcessor_stopsOnFalse() throws IOException { + List<String> list = source.readLines(new LineProcessor<List<String>>() { + List<String> list = Lists.newArrayList(); + + @Override + public boolean processLine(String line) throws IOException { + list.add(line); + return false; + } + + @Override + public List<String> getResult() { + return list; + } + }); + + if (expectedLines.isEmpty()) { + assertTrue(list.isEmpty()); + } else { + assertEquals(expectedLines.subList(0, 1), list); + } + } + private void assertExpectedString(String string) { assertEquals(expected, string); } diff --git a/guava-tests/test/com/google/common/io/CharStreamsTest.java b/guava-tests/test/com/google/common/io/CharStreamsTest.java index a3506cd..f47ce8a 100644 --- a/guava-tests/test/com/google/common/io/CharStreamsTest.java +++ b/guava-tests/test/com/google/common/io/CharStreamsTest.java @@ -16,30 +16,18 @@ package com.google.common.io; -import static com.google.common.base.Charsets.UTF_8; -import static com.google.common.io.CharStreams.copy; -import static com.google.common.io.CharStreams.newReaderSupplier; - -import com.google.common.base.Charsets; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.testing.TestLogHandler; -import java.io.ByteArrayInputStream; import java.io.EOFException; import java.io.FilterReader; -import java.io.FilterWriter; import java.io.IOException; -import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.util.List; -import junit.framework.TestSuite; - /** * Unit test for {@link CharStreams}. * @@ -47,44 +35,11 @@ import junit.framework.TestSuite; */ public class CharStreamsTest extends IoTestCase { - public static TestSuite suite() { - TestSuite suite = new TestSuite(); - suite.addTest(CharSourceTester.tests("CharStreams.asCharSource[String]", - SourceSinkFactories.stringCharSourceFactory())); - suite.addTestSuite(CharStreamsTest.class); - return suite; - } - private static final String TEXT = "The quick brown fox jumped over the lazy dog."; - static final InputSupplier<? extends Reader> BROKEN_READ - = CharStreams.newReaderSupplier(ByteStreamsTest.BROKEN_READ, UTF_8); - - static final OutputSupplier<? extends Writer> BROKEN_WRITE - = CharStreams.newWriterSupplier(ByteStreamsTest.BROKEN_WRITE, UTF_8); - - static final InputSupplier<? extends Reader> BROKEN_CLOSE_INPUT - = CharStreams.newReaderSupplier(ByteStreamsTest.BROKEN_CLOSE_INPUT, UTF_8); - - static final OutputSupplier<? extends Writer> BROKEN_CLOSE_OUTPUT - = CharStreams.newWriterSupplier(ByteStreamsTest.BROKEN_CLOSE_OUTPUT, UTF_8); - - static final InputSupplier<? extends Reader> BROKEN_GET_INPUT - = CharStreams.newReaderSupplier(ByteStreamsTest.BROKEN_GET_INPUT, UTF_8); - - static final OutputSupplier<? extends Writer> BROKEN_GET_OUTPUT - = CharStreams.newWriterSupplier(ByteStreamsTest.BROKEN_GET_OUTPUT, UTF_8); - - private static final ImmutableSet<InputSupplier<? extends Reader>> BROKEN_INPUTS = - ImmutableSet.of(BROKEN_CLOSE_INPUT, BROKEN_GET_INPUT, BROKEN_READ); - private static final ImmutableSet<OutputSupplier<? extends Writer>> BROKEN_OUTPUTS - = ImmutableSet.of(BROKEN_CLOSE_OUTPUT, BROKEN_GET_OUTPUT, BROKEN_WRITE); - public void testToString() throws IOException { assertEquals(TEXT, CharStreams.toString(new StringReader(TEXT))); - assertEquals(TEXT, - CharStreams.toString(CharStreams.newReaderSupplier(TEXT))); } public void testSkipFully_blockingRead() throws IOException { @@ -92,29 +47,29 @@ public class CharStreamsTest extends IoTestCase { CharStreams.skipFully(reader, 6); assertEquals(-1, reader.read()); } - + private static class NonSkippingReader extends StringReader { NonSkippingReader(String s) { super(s); } - + @Override public long skip(long n) { return 0; } } - - public void testReadLines_fromReadable() throws IOException { - byte[] bytes = "a\nb\nc".getBytes(Charsets.UTF_8.name()); + + public void testReadLines() throws IOException { List<String> lines = CharStreams.readLines( - new InputStreamReader(new ByteArrayInputStream(bytes), Charsets.UTF_8)); + new StringReader("a\nb\nc")); assertEquals(ImmutableList.of("a", "b", "c"), lines); } public void testReadLines_withLineProcessor() throws IOException { - InputSupplier<StringReader> r = CharStreams.newReaderSupplier("a\nb\nc"); + String text = "a\nb\nc"; // Test a LineProcessor that always returns false. + Reader r = new StringReader(text); LineProcessor<Integer> alwaysFalse = new LineProcessor<Integer>() { int seen; @Override @@ -131,6 +86,7 @@ public class CharStreamsTest extends IoTestCase { CharStreams.readLines(r, alwaysFalse).intValue()); // Test a LineProcessor that always returns true. + r = new StringReader(text); LineProcessor<Integer> alwaysTrue = new LineProcessor<Integer>() { int seen; @Override @@ -147,6 +103,7 @@ public class CharStreamsTest extends IoTestCase { CharStreams.readLines(r, alwaysTrue).intValue()); // Test a LineProcessor that is conditional. + r = new StringReader(text); final StringBuilder sb = new StringBuilder(); LineProcessor<Integer> conditional = new LineProcessor<Integer>() { int seen; @@ -165,168 +122,6 @@ public class CharStreamsTest extends IoTestCase { assertEquals("ab", sb.toString()); } - public void testAlwaysCloses() throws IOException { - CheckCloseSupplier.Input<Reader> okRead - = newCheckReader(CharStreams.newReaderSupplier(TEXT)); - CheckCloseSupplier.Output<Writer> okWrite - = newCheckWriter(new OutputSupplier<Writer>() { - @Override - public Writer getOutput() { - return new StringWriter(); - } - }); - CheckCloseSupplier.Input<Reader> brokenRead = newCheckReader(BROKEN_READ); - CheckCloseSupplier.Output<Writer> brokenWrite - = newCheckWriter(BROKEN_WRITE); - - CharStreams.copy(okRead, okWrite); - assertTrue(okRead.areClosed()); - assertTrue(okWrite.areClosed()); - - try { - CharStreams.copy(okRead, brokenWrite); - fail("expected exception"); - } catch (Exception e) { - assertEquals("broken write", e.getMessage()); - } - assertTrue(okRead.areClosed()); - assertTrue(brokenWrite.areClosed()); - - try { - CharStreams.copy(brokenRead, okWrite); - fail("expected exception"); - } catch (Exception e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - assertTrue(okWrite.areClosed()); - - try { - CharStreams.copy(brokenRead, brokenWrite); - fail("expected exception"); - } catch (Exception e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - assertTrue(brokenWrite.areClosed()); - - assertEquals(TEXT, CharStreams.toString(okRead)); - assertTrue(okRead.areClosed()); - - try { - CharStreams.toString(brokenRead); - fail("expected exception"); - } catch (Exception e) { - assertEquals("broken read", e.getMessage()); - } - assertTrue(brokenRead.areClosed()); - - try { - CharStreams.write("hello world", brokenWrite); - fail("expected exception"); - } catch (Exception e) { - assertEquals("broken write", e.getMessage()); - } - assertTrue(brokenWrite.areClosed()); - } - - public void testCopySuppliersExceptions() { - if (!Closer.SuppressingSuppressor.isAvailable()) { - // test that exceptions are logged - - TestLogHandler logHandler = new TestLogHandler(); - Closeables.logger.addHandler(logHandler); - try { - for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) { - runFailureTest(in, newStringWriterSupplier()); - assertTrue(logHandler.getStoredLogRecords().isEmpty()); - - runFailureTest(in, BROKEN_CLOSE_OUTPUT); - assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, getAndResetRecords(logHandler)); - } - - for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) { - runFailureTest(newReaderSupplier("ABC"), out); - assertTrue(logHandler.getStoredLogRecords().isEmpty()); - - runFailureTest(BROKEN_CLOSE_INPUT, out); - assertEquals(1, getAndResetRecords(logHandler)); - } - - for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) { - for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) { - runFailureTest(in, out); - assertTrue(getAndResetRecords(logHandler) <= 1); - } - } - } finally { - Closeables.logger.removeHandler(logHandler); - } - } else { - // test that exceptions are suppressed - - for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) { - int suppressed = runSuppressionFailureTest(in, newStringWriterSupplier()); - assertEquals(0, suppressed); - - suppressed = runSuppressionFailureTest(in, BROKEN_CLOSE_OUTPUT); - assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, suppressed); - } - - for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) { - int suppressed = runSuppressionFailureTest(newReaderSupplier("ABC"), out); - assertEquals(0, suppressed); - - suppressed = runSuppressionFailureTest(BROKEN_CLOSE_INPUT, out); - assertEquals(1, suppressed); - } - - for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) { - for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) { - int suppressed = runSuppressionFailureTest(in, out); - assertTrue(suppressed <= 1); - } - } - } - } - - private static int getAndResetRecords(TestLogHandler logHandler) { - int records = logHandler.getStoredLogRecords().size(); - logHandler.clear(); - return records; - } - - private static void runFailureTest( - InputSupplier<? extends Reader> in, OutputSupplier<? extends Writer> out) { - try { - copy(in, out); - fail(); - } catch (IOException expected) { - } - } - - /** - * @return the number of exceptions that were suppressed on the expected thrown exception - */ - private static int runSuppressionFailureTest( - InputSupplier<? extends Reader> in, OutputSupplier<? extends Writer> out) { - try { - copy(in, out); - fail(); - } catch (IOException expected) { - return CloserTest.getSuppressed(expected).length; - } - throw new AssertionError(); // can't happen - } - - private static OutputSupplier<Writer> newStringWriterSupplier() { - return new OutputSupplier<Writer>() { - @Override public Writer getOutput() { - return new StringWriter(); - } - }; - } - public void testSkipFully_EOF() throws IOException { Reader reader = new StringReader("abcde"); try { @@ -363,17 +158,6 @@ public class CharStreamsTest extends IoTestCase { assertSame(secretlyAWriter, result); } - public void testWriteString() throws IOException { - final StringWriter sw = new StringWriter(); - String expected = "foo"; - CharStreams.write(expected, new OutputSupplier<Writer>() { - @Override public Writer getOutput() { - return sw; - } - }); - assertEquals(expected, sw.toString()); - } - public void testCopy() throws IOException { StringBuilder builder = new StringBuilder(); long copied = CharStreams.copy(new StringReader(ASCII), builder); @@ -406,32 +190,16 @@ public class CharStreamsTest extends IoTestCase { assertEquals(string.length(), copied); } - private static CheckCloseSupplier.Input<Reader> newCheckReader( - InputSupplier<? extends Reader> delegate) { - return new CheckCloseSupplier.Input<Reader>(delegate) { - @Override protected Reader wrap(Reader object, final Callback callback) { - return new FilterReader(object) { - @Override public void close() throws IOException { - callback.delegateClosed(); - super.close(); - } - }; - } - }; - } - - private static CheckCloseSupplier.Output<Writer> newCheckWriter( - OutputSupplier<? extends Writer> delegate) { - return new CheckCloseSupplier.Output<Writer>(delegate) { - @Override protected Writer wrap(Writer object, final Callback callback) { - return new FilterWriter(object) { - @Override public void close() throws IOException { - callback.delegateClosed(); - super.close(); - } - }; - } - }; + public void testNullWriter() throws Exception { + // create a null writer + Writer nullWriter = CharStreams.nullWriter(); + // write to the writer + nullWriter.write('n'); + String test = "Test string for NullWriter"; + nullWriter.write(test); + nullWriter.write(test, 2, 10); + // nothing really to assert? + assertSame(CharStreams.nullWriter(), CharStreams.nullWriter()); } /** diff --git a/guava-tests/test/com/google/common/io/CheckCloseSupplier.java b/guava-tests/test/com/google/common/io/CheckCloseSupplier.java deleted file mode 100644 index 12711f7..0000000 --- a/guava-tests/test/com/google/common/io/CheckCloseSupplier.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.io; - -import com.google.common.collect.Sets; - -import java.io.IOException; -import java.util.Set; - -/** - * The purpose of the CheckCloseSupplier is to report when all closeable objects - * supplied by the delegate supplier are closed. To do this, the factory method - * returns a decorated version of the {@code delegate} supplied in the - * constructor. The decoration mechanism is left up to the subclass via the - * abstract {@link #wrap} method. - * - * <p>The decorated object returned from {@link #wrap} should ideally override - * its {@code close} method to not only call {@code super.close()} but to also - * call {@code callback.delegateClosed()}. - * - * @author Chris Nokleberg - */ -abstract class CheckCloseSupplier<T> { - private final Set<Callback> open = Sets.newHashSet(); - - abstract static class Input<T> extends CheckCloseSupplier<T> - implements InputSupplier<T> { - private final InputSupplier<? extends T> delegate; - - public Input(InputSupplier<? extends T> delegate) { - this.delegate = delegate; - } - - @Override public T getInput() throws IOException { - return wrap(delegate.getInput(), newCallback()); - } - } - - abstract static class Output<T> extends CheckCloseSupplier<T> - implements OutputSupplier<T> { - private final OutputSupplier<? extends T> delegate; - - public Output(OutputSupplier<? extends T> delegate) { - this.delegate = delegate; - } - - @Override public T getOutput() throws IOException { - return wrap(delegate.getOutput(), newCallback()); - } - } - - public final class Callback { - public void delegateClosed() { - open.remove(this); - } - } - - protected Callback newCallback() { - Callback callback = new Callback(); - open.add(callback); - return callback; - } - - /** - * Subclasses should wrap the given object and call - * {@link Callback#delegateClosed} when the close method of the delegate is - * called, to inform the supplier that the underlying - * {@code Closeable} is not longer open. - * - * @param object the object to wrap. - * @param callback the object that the wrapper should call to signal that the - */ - protected abstract T wrap(T object, Callback callback); - - /** Returns true if all the closeables have been closed closed */ - public boolean areClosed() { - return open.isEmpty(); - } -} diff --git a/guava-tests/test/com/google/common/io/CloseablesTest.java b/guava-tests/test/com/google/common/io/CloseablesTest.java index fe7e684..a4cd1bb 100644 --- a/guava-tests/test/com/google/common/io/CloseablesTest.java +++ b/guava-tests/test/com/google/common/io/CloseablesTest.java @@ -22,10 +22,13 @@ import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.reset; import static org.easymock.EasyMock.verify; +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; import java.io.Closeable; import java.io.IOException; - -import junit.framework.TestCase; +import java.io.InputStream; +import java.io.Reader; /** * Unit tests for {@link Closeables}. @@ -72,10 +75,31 @@ public class CloseablesTest extends TestCase { Closeables.closeQuietly(mockCloseable); } + public void testCloseQuietly_inputStreamWithEatenException() throws IOException { + TestInputStream in = new TestInputStream( + new ByteArrayInputStream(new byte[1]), TestOption.CLOSE_THROWS); + Closeables.closeQuietly(in); + assertTrue(in.closed()); + } + + public void testCloseQuietly_readerWithEatenException() throws IOException { + TestReader in = new TestReader(TestOption.CLOSE_THROWS); + Closeables.closeQuietly(in); + assertTrue(in.closed()); + } + public void testCloseNull() throws IOException { Closeables.close(null, true); Closeables.close(null, false); - Closeables.closeQuietly(null); + Closeables.closeQuietly((Closeable) null); + } + + public void testCloseQuietlyNull_inputStream() { + Closeables.closeQuietly((InputStream) null); + } + + public void testCloseQuietlyNull_reader() { + Closeables.closeQuietly((Reader) null); } @Override protected void setUp() throws Exception { diff --git a/guava-tests/test/com/google/common/io/CloserTest.java b/guava-tests/test/com/google/common/io/CloserTest.java index 09e4541..9481ca5 100644 --- a/guava-tests/test/com/google/common/io/CloserTest.java +++ b/guava-tests/test/com/google/common/io/CloserTest.java @@ -25,6 +25,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.testing.TestLogHandler; +import junit.framework.TestCase; + import java.io.Closeable; import java.io.IOException; import java.lang.reflect.Method; @@ -33,8 +35,6 @@ import java.util.logging.LogRecord; import javax.annotation.Nullable; -import junit.framework.TestCase; - /** * Tests for {@link Closer}. * @@ -354,6 +354,12 @@ public class CloserTest extends TestCase { assertEquals(ImmutableSet.of(c1Exception, c2Exception), suppressed); } + public void testNullCloseable() throws IOException { + Closer closer = Closer.create(); + closer.register(null); + closer.close(); + } + static Throwable[] getSuppressed(Throwable throwable) { try { Method getSuppressed = Throwable.class.getDeclaredMethod("getSuppressed"); diff --git a/guava-tests/test/com/google/common/io/FileBackedOutputStreamTest.java b/guava-tests/test/com/google/common/io/FileBackedOutputStreamTest.java index ce698e4..af3032f 100644 --- a/guava-tests/test/com/google/common/io/FileBackedOutputStreamTest.java +++ b/guava-tests/test/com/google/common/io/FileBackedOutputStreamTest.java @@ -20,7 +20,6 @@ import com.google.common.testing.GcFinalization; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; @@ -79,15 +78,14 @@ public class FileBackedOutputStreamTest extends IoTestCase { boolean resetOnFinalize) throws IOException { byte[] data = newPreFilledByteArray(dataSize); FileBackedOutputStream out = new FileBackedOutputStream(fileThreshold, resetOnFinalize); - InputSupplier<InputStream> supplier = out.getSupplier(); + ByteSource source = out.asByteSource(); int chunk1 = Math.min(dataSize, fileThreshold); int chunk2 = dataSize - chunk1; // Write just enough to not trip the threshold if (chunk1 > 0) { write(out, data, 0, chunk1, singleByte); - assertTrue(ByteStreams.equal( - ByteStreams.newInputStreamSupplier(data, 0, chunk1), supplier)); + assertTrue(ByteSource.wrap(data).slice(0, chunk1).contentEquals(source)); } File file = out.getFile(); assertNull(file); @@ -101,8 +99,8 @@ public class FileBackedOutputStreamTest extends IoTestCase { } out.close(); - // Check that supplier returns the right data - assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier))); + // Check that source returns the right data + assertTrue(Arrays.equals(data, source.read())); // Make sure that reset deleted the file out.reset(); @@ -129,10 +127,10 @@ public class FileBackedOutputStreamTest extends IoTestCase { public void testWriteErrorAfterClose() throws Exception { byte[] data = newPreFilledByteArray(100); FileBackedOutputStream out = new FileBackedOutputStream(50); - InputSupplier<InputStream> supplier = out.getSupplier(); + ByteSource source = out.asByteSource(); out.write(data); - assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier))); + assertTrue(Arrays.equals(data, source.read())); out.close(); try { @@ -143,23 +141,23 @@ public class FileBackedOutputStreamTest extends IoTestCase { } // Verify that write had no effect - assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier))); + assertTrue(Arrays.equals(data, source.read())); out.reset(); } public void testReset() throws Exception { byte[] data = newPreFilledByteArray(100); FileBackedOutputStream out = new FileBackedOutputStream(Integer.MAX_VALUE); - InputSupplier<InputStream> supplier = out.getSupplier(); + ByteSource source = out.asByteSource(); out.write(data); - assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier))); + assertTrue(Arrays.equals(data, source.read())); out.reset(); - assertTrue(Arrays.equals(new byte[0], ByteStreams.toByteArray(supplier))); + assertTrue(Arrays.equals(new byte[0], source.read())); out.write(data); - assertTrue(Arrays.equals(data, ByteStreams.toByteArray(supplier))); + assertTrue(Arrays.equals(data, source.read())); out.close(); } diff --git a/guava-tests/test/com/google/common/io/FileTreeTraverserTest.java b/guava-tests/test/com/google/common/io/FileTreeTraverserTest.java new file mode 100644 index 0000000..706dcfc --- /dev/null +++ b/guava-tests/test/com/google/common/io/FileTreeTraverserTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.io; + +import com.google.common.collect.ImmutableSet; + +import junit.framework.TestCase; + +import java.io.File; +import java.io.IOException; + +/** + * Tests for {@link Files#fileTreeViewer}. + * + * @author Colin Decker + */ + +public class FileTreeTraverserTest extends TestCase { + + private File dir; + + @Override + public void setUp() throws IOException { + dir = Files.createTempDir(); + } + + @Override + public void tearDown() throws IOException { + File[] files = dir.listFiles(); + if (files == null) { + return; + } + + // we aren't creating any files in subdirs + for (File file : files) { + file.delete(); + } + + dir.delete(); + } + + public void testFileTreeViewer_emptyDir() throws IOException { + assertDirChildren(); + } + + public void testFileTreeViewer_singleFile() throws IOException { + File file = newFile("test"); + assertDirChildren(file); + } + + public void testFileTreeViewer_singleDir() throws IOException { + File file = newDir("test"); + assertDirChildren(file); + } + + public void testFileTreeViewer_multipleFiles() throws IOException { + File a = newFile("a"); + File b = newDir("b"); + File c = newFile("c"); + File d = newDir("d"); + assertDirChildren(a, b, c, d); + } + + private File newDir(String name) throws IOException { + File file = new File(dir, name); + file.mkdir(); + return file; + } + + private File newFile(String name) throws IOException { + File file = new File(dir, name); + file.createNewFile(); + return file; + } + + private void assertDirChildren(File... files) { + assertEquals(ImmutableSet.copyOf(files), + ImmutableSet.copyOf(Files.fileTreeTraverser().children(dir))); + } +} diff --git a/guava-tests/test/com/google/common/io/FilesSimplifyPathTest.java b/guava-tests/test/com/google/common/io/FilesSimplifyPathTest.java index 27e8623..212ad61 100644 --- a/guava-tests/test/com/google/common/io/FilesSimplifyPathTest.java +++ b/guava-tests/test/com/google/common/io/FilesSimplifyPathTest.java @@ -22,12 +22,12 @@ import static com.google.common.io.Files.simplifyPath; import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; +import junit.framework.TestCase; + import java.io.IOException; import java.net.URL; import java.util.Iterator; -import junit.framework.TestCase; - /** * Unit tests for {@link Files#simplifyPath}. * diff --git a/guava-tests/test/com/google/common/io/FilesTest.java b/guava-tests/test/com/google/common/io/FilesTest.java new file mode 100644 index 0000000..f8eb3d0 --- /dev/null +++ b/guava-tests/test/com/google/common/io/FilesTest.java @@ -0,0 +1,821 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.io; + +import static com.google.common.io.Files.createTempDir; +import static com.google.common.io.Files.touch; +import static org.truth0.Truth.ASSERT; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableList; +import com.google.common.hash.Hashing; +import com.google.common.primitives.Bytes; + +import junit.framework.TestSuite; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel.MapMode; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +/** + * Unit test for {@link Files}. + * + * @author Chris Nokleberg + */ +public class FilesTest extends IoTestCase { + + public static TestSuite suite() { + TestSuite suite = new TestSuite(); + suite.addTest(ByteSourceTester.tests("Files.asByteSource[File]", + SourceSinkFactories.fileByteSourceFactory(), true)); + suite.addTest(ByteSinkTester.tests("Files.asByteSink[File]", + SourceSinkFactories.fileByteSinkFactory())); + suite.addTest(ByteSinkTester.tests("Files.asByteSink[File, APPEND]", + SourceSinkFactories.appendingFileByteSinkFactory())); + suite.addTest(CharSourceTester.tests("Files.asCharSource[File, Charset]", + SourceSinkFactories.fileCharSourceFactory())); + suite.addTest(CharSinkTester.tests("Files.asCharSink[File, Charset]", + SourceSinkFactories.fileCharSinkFactory())); + suite.addTest(CharSinkTester.tests("Files.asCharSink[File, Charset, APPEND]", + SourceSinkFactories.appendingFileCharSinkFactory())); + suite.addTestSuite(FilesTest.class); + return suite; + } + + public void testToByteArray() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + File i18nFile = getTestFile("i18n.txt"); + assertTrue(Arrays.equals(ASCII.getBytes(Charsets.US_ASCII.name()), + Files.toByteArray(asciiFile))); + assertTrue(Arrays.equals(I18N.getBytes(Charsets.UTF_8.name()), + Files.toByteArray(i18nFile))); + assertTrue(Arrays.equals(I18N.getBytes(Charsets.UTF_8.name()), + Files.asByteSource(i18nFile).read())); + } + + public void testReadFile_withCorrectSize() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + + Closer closer = Closer.create(); + try { + InputStream in = closer.register(new FileInputStream(asciiFile)); + byte[] bytes = Files.readFile(in, asciiFile.length()); + assertTrue(Arrays.equals(ASCII.getBytes(Charsets.US_ASCII.name()), bytes)); + } catch (Throwable e) { + throw closer.rethrow(e); + } finally { + closer.close(); + } + } + + public void testReadFile_withSmallerSize() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + + Closer closer = Closer.create(); + try { + InputStream in = closer.register(new FileInputStream(asciiFile)); + byte[] bytes = Files.readFile(in, 10); + assertTrue(Arrays.equals(ASCII.getBytes(Charsets.US_ASCII.name()), bytes)); + } catch (Throwable e) { + throw closer.rethrow(e); + } finally { + closer.close(); + } + } + + public void testReadFile_withLargerSize() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + + Closer closer = Closer.create(); + try { + InputStream in = closer.register(new FileInputStream(asciiFile)); + byte[] bytes = Files.readFile(in, 500); + assertTrue(Arrays.equals(ASCII.getBytes(Charsets.US_ASCII.name()), bytes)); + } catch (Throwable e) { + throw closer.rethrow(e); + } finally { + closer.close(); + } + } + + public void testReadFile_withSizeZero() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + + Closer closer = Closer.create(); + try { + InputStream in = closer.register(new FileInputStream(asciiFile)); + byte[] bytes = Files.readFile(in, 0); + assertTrue(Arrays.equals(ASCII.getBytes(Charsets.US_ASCII.name()), bytes)); + } catch (Throwable e) { + throw closer.rethrow(e); + } finally { + closer.close(); + } + } + + /** + * A {@link File} that provides a specialized value for {link File#length()}. + */ + private static class BadLengthFile extends File { + + private final long badLength; + + public BadLengthFile(File delegate, long badLength) { + super(delegate.getPath()); + this.badLength = badLength; + } + + @Override + public long length() { + return badLength; + } + + private static final long serialVersionUID = 0; + } + + public void testToString() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + File i18nFile = getTestFile("i18n.txt"); + assertEquals(ASCII, Files.toString(asciiFile, Charsets.US_ASCII)); + assertEquals(I18N, Files.toString(i18nFile, Charsets.UTF_8)); + ASSERT.that(Files.toString(i18nFile, Charsets.US_ASCII)) + .isNotEqualTo(I18N); + } + + public void testCopyCharacters() throws IOException { + File i18nFile = getTestFile("i18n.txt"); + File temp = createTempFile(); + Files.copy(i18nFile, Charsets.UTF_8, + Files.asCharSink(temp, Charsets.UTF_8)); + assertEquals(I18N, Files.toString(temp, Charsets.UTF_8)); + + Files.copy(Files.asCharSource(i18nFile, Charsets.UTF_8), temp, + Charsets.UTF_8); + assertEquals(I18N, Files.toString(temp, Charsets.UTF_8)); + + Files.copy(i18nFile, Charsets.UTF_8, + Files.asCharSink(temp, Charsets.UTF_16LE)); + assertEquals(I18N, Files.toString(temp, Charsets.UTF_16LE)); + } + + public void testWriteString() throws IOException { + File temp = createTempFile(); + Files.write(I18N, temp, Charsets.UTF_16LE); + assertEquals(I18N, Files.toString(temp, Charsets.UTF_16LE)); + } + + public void testWriteBytes() throws IOException { + File temp = createTempFile(); + byte[] data = newPreFilledByteArray(2000); + Files.write(data, temp); + assertTrue(Arrays.equals(data, Files.toByteArray(temp))); + + try { + Files.write(null, temp); + fail("expected exception"); + } catch (NullPointerException expected) { + } + } + + public void testAppendString() throws IOException { + File temp = createTempFile(); + Files.append(I18N, temp, Charsets.UTF_16LE); + assertEquals(I18N, Files.toString(temp, Charsets.UTF_16LE)); + Files.append(I18N, temp, Charsets.UTF_16LE); + assertEquals(I18N + I18N, Files.toString(temp, Charsets.UTF_16LE)); + Files.append(I18N, temp, Charsets.UTF_16LE); + assertEquals(I18N + I18N + I18N, Files.toString(temp, Charsets.UTF_16LE)); + } + + public void testCopyToOutputStream() throws IOException { + File i18nFile = getTestFile("i18n.txt"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Files.copy(i18nFile, out); + assertEquals(I18N, out.toString("UTF-8")); + } + + public void testCopyToAppendable() throws IOException { + File i18nFile = getTestFile("i18n.txt"); + StringBuilder sb = new StringBuilder(); + Files.copy(i18nFile, Charsets.UTF_8, sb); + assertEquals(I18N, sb.toString()); + } + + public void testCopyToByteSink() throws IOException { + File i18nFile = getTestFile("i18n.txt"); + File temp = createTempFile(); + Files.copy(i18nFile, Files.asByteSink(temp)); + assertEquals(I18N, Files.toString(temp, Charsets.UTF_8)); + } + + public void testCopyFromByteSource() throws IOException { + File i18nFile = getTestFile("i18n.txt"); + File temp = createTempFile(); + Files.copy(Files.asByteSource(i18nFile), temp); + assertEquals(I18N, Files.toString(temp, Charsets.UTF_8)); + } + + public void testCopyFile() throws IOException { + File i18nFile = getTestFile("i18n.txt"); + File temp = createTempFile(); + Files.copy(i18nFile, temp); + assertEquals(I18N, Files.toString(temp, Charsets.UTF_8)); + } + + public void testCopyEqualFiles() throws IOException { + File temp1 = createTempFile(); + File temp2 = file(temp1.getPath()); + assertEquals(temp1, temp2); + Files.write(ASCII, temp1, Charsets.UTF_8); + try { + Files.copy(temp1, temp2); + fail("Expected an IAE to be thrown but wasn't"); + } catch (IllegalArgumentException expected) { + } + assertEquals(ASCII, Files.toString(temp1, Charsets.UTF_8)); + } + + public void testCopySameFile() throws IOException { + File temp = createTempFile(); + Files.write(ASCII, temp, Charsets.UTF_8); + try { + Files.copy(temp, temp); + fail("Expected an IAE to be thrown but wasn't"); + } catch (IllegalArgumentException expected) { + } + assertEquals(ASCII, Files.toString(temp, Charsets.UTF_8)); + } + + public void testCopyIdenticalFiles() throws IOException { + File temp1 = createTempFile(); + Files.write(ASCII, temp1, Charsets.UTF_8); + File temp2 = createTempFile(); + Files.write(ASCII, temp2, Charsets.UTF_8); + Files.copy(temp1, temp2); + assertEquals(ASCII, Files.toString(temp1, Charsets.UTF_8)); + } + + public void testEqual() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + File i18nFile = getTestFile("i18n.txt"); + assertFalse(Files.equal(asciiFile, i18nFile)); + assertTrue(Files.equal(asciiFile, asciiFile)); + + File temp = createTempFile(); + Files.copy(asciiFile, temp); + assertTrue(Files.equal(asciiFile, temp)); + + Files.copy(i18nFile, temp); + assertTrue(Files.equal(i18nFile, temp)); + + Files.copy(asciiFile, temp); + RandomAccessFile rf = new RandomAccessFile(temp, "rw"); + rf.writeByte(0); + rf.close(); + assertEquals(asciiFile.length(), temp.length()); + assertFalse(Files.equal(asciiFile, temp)); + + assertTrue(Files.asByteSource(asciiFile) + .contentEquals(Files.asByteSource(asciiFile))); + + // 0-length files have special treatment (/proc, etc.) + assertTrue(Files.equal(asciiFile, new BadLengthFile(asciiFile, 0))); + } + + public void testNewReader() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + try { + Files.newReader(asciiFile, null); + fail("expected exception"); + } catch (NullPointerException expected) { + } + + try { + Files.newReader(null, Charsets.UTF_8); + fail("expected exception"); + } catch (NullPointerException expected) { + } + + BufferedReader r = Files.newReader(asciiFile, Charsets.US_ASCII); + try { + assertEquals(ASCII, r.readLine()); + } finally { + r.close(); + } + } + + public void testNewWriter() throws IOException { + File temp = createTempFile(); + try { + Files.newWriter(temp, null); + fail("expected exception"); + } catch (NullPointerException expected) { + } + + try { + Files.newWriter(null, Charsets.UTF_8); + fail("expected exception"); + } catch (NullPointerException expected) { + } + + BufferedWriter w = Files.newWriter(temp, Charsets.UTF_8); + try { + w.write(I18N); + } finally { + w.close(); + } + + File i18nFile = getTestFile("i18n.txt"); + assertTrue(Files.equal(i18nFile, temp)); + } + + public void testTouch() throws IOException { + File temp = createTempFile(); + assertTrue(temp.exists()); + assertTrue(temp.delete()); + assertFalse(temp.exists()); + Files.touch(temp); + assertTrue(temp.exists()); + Files.touch(temp); + assertTrue(temp.exists()); + + try { + Files.touch(new File(temp.getPath()) { + @Override + public boolean setLastModified(long t) { + return false; + } + + private static final long serialVersionUID = 0; + }); + fail("expected exception"); + } catch (IOException expected) { + } + } + + public void testTouchTime() throws IOException { + File temp = createTempFile(); + assertTrue(temp.exists()); + temp.setLastModified(0); + assertEquals(0, temp.lastModified()); + Files.touch(temp); + ASSERT.that(temp.lastModified()).isNotEqualTo(0); + } + + public void testCreateParentDirs_root() throws IOException { + File file = root(); + assertNull(file.getParentFile()); + assertNull(file.getCanonicalFile().getParentFile()); + Files.createParentDirs(file); + } + + public void testCreateParentDirs_relativePath() throws IOException { + File file = file("nonexistent.file"); + assertNull(file.getParentFile()); + assertNotNull(file.getCanonicalFile().getParentFile()); + Files.createParentDirs(file); + } + + public void testCreateParentDirs_noParentsNeeded() throws IOException { + File file = file(getTempDir(), "nonexistent.file"); + assertTrue(file.getParentFile().exists()); + Files.createParentDirs(file); + } + + public void testCreateParentDirs_oneParentNeeded() throws IOException { + File file = file(getTempDir(), "parent", "nonexistent.file"); + File parent = file.getParentFile(); + assertFalse(parent.exists()); + try { + Files.createParentDirs(file); + assertTrue(parent.exists()); + } finally { + assertTrue(parent.delete()); + } + } + + public void testCreateParentDirs_multipleParentsNeeded() throws IOException { + File file = file(getTempDir(), "grandparent", "parent", "nonexistent.file"); + File parent = file.getParentFile(); + File grandparent = parent.getParentFile(); + assertFalse(grandparent.exists()); + Files.createParentDirs(file); + assertTrue(parent.exists()); + } + + public void testCreateParentDirs_nonDirectoryParentExists() throws IOException { + File parent = getTestFile("ascii.txt"); + assertTrue(parent.isFile()); + File file = file(parent, "foo"); + try { + Files.createParentDirs(file); + fail(); + } catch (IOException expected) { + } + } + + public void testCreateTempDir() { + File temp = Files.createTempDir(); + assertTrue(temp.exists()); + assertTrue(temp.isDirectory()); + assertEquals(0, temp.listFiles().length); + assertTrue(temp.delete()); + } + + public void testMove() throws IOException { + File i18nFile = getTestFile("i18n.txt"); + File temp1 = createTempFile(); + File temp2 = createTempFile(); + + Files.copy(i18nFile, temp1); + moveHelper(true, temp1, temp2); + assertTrue(Files.equal(temp2, i18nFile)); + } + + public void testMoveViaCopy() throws IOException { + File i18nFile = getTestFile("i18n.txt"); + File temp1 = createTempFile(); + File temp2 = createTempFile(); + + Files.copy(i18nFile, temp1); + moveHelper(true, new UnmovableFile(temp1, false, true), temp2); + assertTrue(Files.equal(temp2, i18nFile)); + } + + public void testMoveFailures() throws IOException { + File temp1 = createTempFile(); + File temp2 = createTempFile(); + + moveHelper(false, new UnmovableFile(temp1, false, false), temp2); + moveHelper(false, new UnmovableFile(temp1, false, false), + new UnmovableFile(temp2, true, false)); + + try { + File asciiFile = getTestFile("ascii.txt"); + moveHelper(false, asciiFile, asciiFile); + fail("expected exception"); + } catch (IllegalArgumentException expected) { + } + } + + private void moveHelper(boolean success, File from, File to) + throws IOException { + try { + Files.move(from, to); + if (success) { + assertFalse(from.exists()); + assertTrue(to.exists()); + } else { + fail("expected exception"); + } + } catch (IOException possiblyExpected) { + if (success) { + throw possiblyExpected; + } + } + } + + private static class UnmovableFile extends File { + + private final boolean canRename; + private final boolean canDelete; + + public UnmovableFile(File file, boolean canRename, boolean canDelete) { + super(file.getPath()); + this.canRename = canRename; + this.canDelete = canDelete; + } + + @Override + public boolean renameTo(File to) { + return canRename && super.renameTo(to); + } + + @Override + public boolean delete() { + return canDelete && super.delete(); + } + + private static final long serialVersionUID = 0; + } + + public void testLineReading() throws IOException { + File temp = createTempFile(); + assertNull(Files.readFirstLine(temp, Charsets.UTF_8)); + assertTrue(Files.readLines(temp, Charsets.UTF_8).isEmpty()); + + PrintWriter w = new PrintWriter(Files.newWriter(temp, Charsets.UTF_8)); + w.println("hello"); + w.println(""); + w.println(" world "); + w.println(""); + w.close(); + + assertEquals("hello", Files.readFirstLine(temp, Charsets.UTF_8)); + assertEquals(ImmutableList.of("hello", "", " world ", ""), + Files.readLines(temp, Charsets.UTF_8)); + + assertTrue(temp.delete()); + } + + public void testReadLines_withLineProcessor() throws IOException { + File temp = createTempFile(); + LineProcessor<List<String>> collect = new LineProcessor<List<String>>() { + List<String> collector = new ArrayList<String>(); + + @Override + public boolean processLine(String line) { + collector.add(line); + return true; + } + + @Override + public List<String> getResult() { + return collector; + } + }; + ASSERT.that(Files.readLines(temp, Charsets.UTF_8, collect)).isEmpty(); + + PrintWriter w = new PrintWriter(Files.newWriter(temp, Charsets.UTF_8)); + w.println("hello"); + w.println(""); + w.println(" world "); + w.println(""); + w.close(); + Files.readLines(temp, Charsets.UTF_8, collect); + ASSERT.that(collect.getResult()) + .has().exactly("hello", "", " world ", "").inOrder(); + + LineProcessor<List<String>> collectNonEmptyLines = + new LineProcessor<List<String>>() { + List<String> collector = new ArrayList<String>(); + + @Override + public boolean processLine(String line) { + if (line.length() > 0) { + collector.add(line); + } + return true; + } + + @Override + public List<String> getResult() { + return collector; + } + }; + Files.readLines(temp, Charsets.UTF_8, collectNonEmptyLines); + ASSERT.that(collectNonEmptyLines.getResult()).has().exactly( + "hello", " world ").inOrder(); + + assertTrue(temp.delete()); + } + + public void testHash() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + File i18nFile = getTestFile("i18n.txt"); + + String init = "d41d8cd98f00b204e9800998ecf8427e"; + assertEquals(init, Hashing.md5().newHasher().hash().toString()); + + String asciiHash = "e5df5a39f2b8cb71b24e1d8038f93131"; + assertEquals(asciiHash, Files.hash(asciiFile, Hashing.md5()).toString()); + + String i18nHash = "7fa826962ce2079c8334cd4ebf33aea4"; + assertEquals(i18nHash, Files.hash(i18nFile, Hashing.md5()).toString()); + } + + public void testMap() throws IOException { + // Test data + int size = 1024; + byte[] bytes = newPreFilledByteArray(size); + + // Setup + File file = createTempFile(); + Files.write(bytes, file); + + // Test + MappedByteBuffer actual = Files.map(file); + + // Verify + ByteBuffer expected = ByteBuffer.wrap(bytes); + assertTrue("ByteBuffers should be equal.", expected.equals(actual)); + } + + public void testMap_noSuchFile() throws IOException { + // Setup + File file = createTempFile(); + boolean deleted = file.delete(); + assertTrue(deleted); + + // Test + try { + Files.map(file); + fail("Should have thrown FileNotFoundException."); + } catch (FileNotFoundException expected) { + } + } + + public void testMap_readWrite() throws IOException { + // Test data + int size = 1024; + byte[] expectedBytes = new byte[size]; + byte[] bytes = newPreFilledByteArray(1024); + + // Setup + File file = createTempFile(); + Files.write(bytes, file); + + Random random = new Random(); + random.nextBytes(expectedBytes); + + // Test + MappedByteBuffer map = Files.map(file, MapMode.READ_WRITE); + map.put(expectedBytes); + + // Verify + byte[] actualBytes = Files.toByteArray(file); + assertTrue(Arrays.equals(expectedBytes, actualBytes)); + } + + public void testMap_readWrite_creates() throws IOException { + // Test data + int size = 1024; + byte[] expectedBytes = newPreFilledByteArray(1024); + + // Setup + File file = createTempFile(); + boolean deleted = file.delete(); + assertTrue(deleted); + assertFalse(file.exists()); + + // Test + MappedByteBuffer map = Files.map(file, MapMode.READ_WRITE, size); + map.put(expectedBytes); + + // Verify + assertTrue(file.exists()); + assertTrue(file.isFile()); + assertEquals(size, file.length()); + byte[] actualBytes = Files.toByteArray(file); + assertTrue(Arrays.equals(expectedBytes, actualBytes)); + } + + public void testMap_readWrite_max_value_plus_1() throws IOException { + // Setup + File file = createTempFile(); + // Test + try { + Files.map(file, MapMode.READ_WRITE, (long) Integer.MAX_VALUE + 1); + fail("Should throw when size exceeds Integer.MAX_VALUE"); + } catch (IllegalArgumentException expected) { + } + } + + public void testGetFileExtension() { + assertEquals("txt", Files.getFileExtension(".txt")); + assertEquals("txt", Files.getFileExtension("blah.txt")); + assertEquals("txt", Files.getFileExtension("blah..txt")); + assertEquals("txt", Files.getFileExtension(".blah.txt")); + assertEquals("txt", Files.getFileExtension("/tmp/blah.txt")); + assertEquals("gz", Files.getFileExtension("blah.tar.gz")); + assertEquals("", Files.getFileExtension("/")); + assertEquals("", Files.getFileExtension(".")); + assertEquals("", Files.getFileExtension("..")); + assertEquals("", Files.getFileExtension("...")); + assertEquals("", Files.getFileExtension("blah")); + assertEquals("", Files.getFileExtension("blah.")); + assertEquals("", Files.getFileExtension(".blah.")); + assertEquals("", Files.getFileExtension("/foo.bar/blah")); + assertEquals("", Files.getFileExtension("/foo/.bar/blah")); + } + + public void testGetNameWithoutExtension() { + assertEquals("", Files.getNameWithoutExtension(".txt")); + assertEquals("blah", Files.getNameWithoutExtension("blah.txt")); + assertEquals("blah.", Files.getNameWithoutExtension("blah..txt")); + assertEquals(".blah", Files.getNameWithoutExtension(".blah.txt")); + assertEquals("blah", Files.getNameWithoutExtension("/tmp/blah.txt")); + assertEquals("blah.tar", Files.getNameWithoutExtension("blah.tar.gz")); + assertEquals("", Files.getNameWithoutExtension("/")); + assertEquals("", Files.getNameWithoutExtension(".")); + assertEquals(".", Files.getNameWithoutExtension("..")); + assertEquals("..", Files.getNameWithoutExtension("...")); + assertEquals("blah", Files.getNameWithoutExtension("blah")); + assertEquals("blah", Files.getNameWithoutExtension("blah.")); + assertEquals(".blah", Files.getNameWithoutExtension(".blah.")); + assertEquals("blah", Files.getNameWithoutExtension("/foo.bar/blah")); + assertEquals("blah", Files.getNameWithoutExtension("/foo/.bar/blah")); + } + + public void testReadBytes() throws IOException { + ByteProcessor<byte[]> processor = new ByteProcessor<byte[]>() { + private final ByteArrayOutputStream out = new ByteArrayOutputStream(); + + @Override + public boolean processBytes(byte[] buffer, int offset, int length) throws IOException { + if (length >= 0) { + out.write(buffer, offset, length); + } + return true; + } + + @Override + public byte[] getResult() { + return out.toByteArray(); + } + }; + + File asciiFile = getTestFile("ascii.txt"); + byte[] result = Files.readBytes(asciiFile, processor); + assertEquals(Bytes.asList(Files.toByteArray(asciiFile)), Bytes.asList(result)); + } + + public void testReadBytes_returnFalse() throws IOException { + ByteProcessor<byte[]> processor = new ByteProcessor<byte[]>() { + private final ByteArrayOutputStream out = new ByteArrayOutputStream(); + + @Override + public boolean processBytes(byte[] buffer, int offset, int length) throws IOException { + if (length > 0) { + out.write(buffer, offset, 1); + return false; + } else { + return true; + } + } + + @Override + public byte[] getResult() { + return out.toByteArray(); + } + }; + + File asciiFile = getTestFile("ascii.txt"); + byte[] result = Files.readBytes(asciiFile, processor); + assertEquals(1, result.length); + } + + public void testPredicates() throws IOException { + File asciiFile = getTestFile("ascii.txt"); + File dir = asciiFile.getParentFile(); + assertTrue(Files.isDirectory().apply(dir)); + assertFalse(Files.isFile().apply(dir)); + + assertFalse(Files.isDirectory().apply(asciiFile)); + assertTrue(Files.isFile().apply(asciiFile)); + } + + /** + * Returns a root path for the file system. + */ + private static File root() { + return File.listRoots()[0]; + } + + /** + * Returns a {@code File} object for the given path parts. + */ + private static File file(String first, String... more) { + return file(new File(first), more); + } + + /** + * Returns a {@code File} object for the given path parts. + */ + private static File file(File first, String... more) { + // not very efficient, but should definitely be correct + File file = first; + for (String name : more) { + file = new File(file, name); + } + return file; + } +} diff --git a/guava-tests/test/com/google/common/io/FlushablesTest.java b/guava-tests/test/com/google/common/io/FlushablesTest.java index 94652da..34a3155 100644 --- a/guava-tests/test/com/google/common/io/FlushablesTest.java +++ b/guava-tests/test/com/google/common/io/FlushablesTest.java @@ -22,11 +22,11 @@ import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.reset; import static org.easymock.EasyMock.verify; +import junit.framework.TestCase; + import java.io.Flushable; import java.io.IOException; -import junit.framework.TestCase; - /** * Unit tests for {@link Flushables}. * diff --git a/guava-tests/test/com/google/common/io/IoTestCase.java b/guava-tests/test/com/google/common/io/IoTestCase.java index 1d16cdb..435a4dd 100644 --- a/guava-tests/test/com/google/common/io/IoTestCase.java +++ b/guava-tests/test/com/google/common/io/IoTestCase.java @@ -16,15 +16,30 @@ package com.google.common.io; +import com.google.common.collect.Sets; + import junit.framework.TestCase; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + /** * Base test case class for I/O tests. * * @author Chris Nokleberg + * @author Colin Decker */ public abstract class IoTestCase extends TestCase { + private static final Logger logger = Logger.getLogger(IoTestCase.class.getName()); + static final String I18N = "\u00CE\u00F1\u0163\u00E9\u0072\u00F1\u00E5\u0163\u00EE\u00F6" + "\u00F1\u00E5\u013C\u00EE\u017E\u00E5\u0163\u00EE\u00F6\u00F1"; @@ -33,20 +48,152 @@ public abstract class IoTestCase extends TestCase { = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; - /** Returns a byte array of length size that has values 0 .. size - 1. */ - protected static byte[] newPreFilledByteArray(int size) { + private File testDir; + private File tempDir; + + private final Set<File> filesToDelete = Sets.newHashSet(); + + @Override + protected void tearDown() { + for (File file : filesToDelete) { + if (file.exists()) { + delete(file); + } + } + filesToDelete.clear(); + } + + private File getTestDir() throws IOException { + if (testDir != null) { + return testDir; + } + + URL testFileUrl = IoTestCase.class.getResource("testdata/i18n.txt"); + if (testFileUrl == null) { + throw new RuntimeException("unable to locate testdata directory"); + } + + if (testFileUrl.getProtocol().equals("file")) { + try { + File testFile = new File(testFileUrl.toURI()); + testDir = testFile.getParentFile(); // the testdata directory + } catch (Exception ignore) { + // probably URISyntaxException or IllegalArgumentException + // fall back to copying URLs to files in the testDir == null block below + } + } + + if (testDir == null) { + // testdata resources aren't file:// urls, so create a directory to store them in and then + // copy the resources to the filesystem as needed + testDir = createTempDir(); + } + + return testDir; + } + + /** + * Returns the file with the given name under the testdata directory. + */ + protected final File getTestFile(String name) throws IOException { + File file = new File(getTestDir(), name); + if (!file.exists()) { + URL resourceUrl = IoTestCase.class.getResource("testdata/" + name); + if (resourceUrl == null) { + return null; + } + copy(resourceUrl, file); + } + + return file; + } + + /** + * Creates a new temp dir for testing. The returned directory and all contents of it will be + * deleted in the tear-down for this test. + */ + protected final File createTempDir() throws IOException { + File tempFile = File.createTempFile("IoTestCase", ""); + if (!tempFile.delete() || !tempFile.mkdir()) { + throw new IOException("failed to create temp dir"); + } + filesToDelete.add(tempFile); + return tempFile; + } + + /** + * Gets a temp dir for testing. The returned directory and all contents of it will be deleted in + * the tear-down for this test. Subsequent invocations of this method will return the same + * directory. + */ + protected final File getTempDir() throws IOException { + if (tempDir == null) { + tempDir = createTempDir(); + } + + return tempDir; + } + + /** + * Creates a new temp file in the temp directory returned by {@link #getTempDir()}. The file will + * be deleted in the tear-down for this test. + */ + protected final File createTempFile() throws IOException { + return File.createTempFile("test", null, getTempDir()); + } + + /** + * Returns a byte array of length size that has values 0 .. size - 1. + */ + static byte[] newPreFilledByteArray(int size) { return newPreFilledByteArray(0, size); } /** - * Returns a byte array of length size that has values - * offset .. offset + size - 1. + * Returns a byte array of length size that has values offset .. offset + size - 1. */ - protected static byte[] newPreFilledByteArray(int offset, int size) { + static byte[] newPreFilledByteArray(int offset, int size) { byte[] array = new byte[size]; for (int i = 0; i < size; i++) { array[i] = (byte) (offset + i); } return array; } + + private static void copy(URL url, File file) throws IOException { + InputStream in = url.openStream(); + try { + OutputStream out = new FileOutputStream(file); + try { + byte[] buf = new byte[4096]; + for (int read = in.read(buf); read != -1; read = in.read(buf)) { + out.write(buf, 0, read); + } + } finally { + out.close(); + } + } finally { + in.close(); + } + } + + private boolean delete(File file) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + if (files != null) { + for (File f : files) { + if (!delete(f)) { + return false; + } + } + } + } + + if (!file.delete()) { + logger.log(Level.WARNING, "couldn't delete file: {0}", new Object[] {file}); + return false; + } + + return true; + } } diff --git a/guava-tests/test/com/google/common/io/LimitInputStreamTest.java b/guava-tests/test/com/google/common/io/LimitInputStreamTest.java deleted file mode 100644 index 30d8850..0000000 --- a/guava-tests/test/com/google/common/io/LimitInputStreamTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.io; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * @author Charles Fry - */ -public class LimitInputStreamTest extends IoTestCase { - - public void testLimit() throws Exception { - byte[] big = newPreFilledByteArray(5); - InputStream bin = new ByteArrayInputStream(big); - InputStream lin = new LimitInputStream(bin, 2); - - // also test available - lin.mark(2); - assertEquals(2, lin.available()); - int read = lin.read(); - assertEquals(big[0], read); - assertEquals(1, lin.available()); - read = lin.read(); - assertEquals(big[1], read); - assertEquals(0, lin.available()); - read = lin.read(); - assertEquals(-1, read); - - lin.reset(); - byte[] small = new byte[5]; - read = lin.read(small); - assertEquals(2, read); - assertEquals(big[0], small[0]); - assertEquals(big[1], small[1]); - - lin.reset(); - read = lin.read(small, 2, 3); - assertEquals(2, read); - assertEquals(big[0], small[2]); - assertEquals(big[1], small[3]); - } - - public void testMark() throws Exception { - byte[] big = newPreFilledByteArray(5); - InputStream bin = new ByteArrayInputStream(big); - InputStream lin = new LimitInputStream(bin, 2); - - int read = lin.read(); - assertEquals(big[0], read); - lin.mark(2); - - read = lin.read(); - assertEquals(big[1], read); - read = lin.read(); - assertEquals(-1, read); - - lin.reset(); - read = lin.read(); - assertEquals(big[1], read); - read = lin.read(); - assertEquals(-1, read); - } - - public void testSkip() throws Exception { - byte[] big = newPreFilledByteArray(5); - InputStream bin = new ByteArrayInputStream(big); - InputStream lin = new LimitInputStream(bin, 2); - - // also test available - lin.mark(2); - assertEquals(2, lin.available()); - lin.skip(1); - assertEquals(1, lin.available()); - - lin.reset(); - assertEquals(2, lin.available()); - lin.skip(3); - assertEquals(0, lin.available()); - } - - - public void testMarkNotSet() { - byte[] big = newPreFilledByteArray(5); - InputStream bin = new ByteArrayInputStream(big); - InputStream lin = new LimitInputStream(bin, 2); - - try { - lin.reset(); - fail(); - } catch (IOException expected) { - assertEquals("Mark not set", expected.getMessage()); - } - } - - public void testMarkNotSupported() { - InputStream lin = new LimitInputStream(new UnmarkableInputStream(), 2); - - try { - lin.reset(); - fail(); - } catch (IOException expected) { - assertEquals("Mark not supported", expected.getMessage()); - } - } - - private static class UnmarkableInputStream extends InputStream { - @Override - public int read() throws IOException { - return 0; - } - - @Override - public boolean markSupported() { - return false; - } - } -} diff --git a/guava-tests/test/com/google/common/io/LittleEndianDataInputStreamTest.java b/guava-tests/test/com/google/common/io/LittleEndianDataInputStreamTest.java index c7d1927..d794ad6 100644 --- a/guava-tests/test/com/google/common/io/LittleEndianDataInputStreamTest.java +++ b/guava-tests/test/com/google/common/io/LittleEndianDataInputStreamTest.java @@ -18,6 +18,8 @@ package com.google.common.io; import com.google.common.primitives.Bytes; +import junit.framework.TestCase; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInput; @@ -25,8 +27,6 @@ import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; -import junit.framework.TestCase; - /** * Test class for {@link LittleEndianDataInputStream}. * diff --git a/guava-tests/test/com/google/common/io/MultiInputStreamTest.java b/guava-tests/test/com/google/common/io/MultiInputStreamTest.java index 06ad254..a14338a 100644 --- a/guava-tests/test/com/google/common/io/MultiInputStreamTest.java +++ b/guava-tests/test/com/google/common/io/MultiInputStreamTest.java @@ -46,15 +46,15 @@ public class MultiInputStreamTest extends IoTestCase { } public void testOnlyOneOpen() throws Exception { - final InputSupplier<InputStream> supplier = newByteSupplier(0, 50); + final ByteSource source = newByteSource(0, 50); final int[] counter = new int[1]; - InputSupplier<InputStream> checker = new InputSupplier<InputStream>() { + ByteSource checker = new ByteSource() { @Override - public InputStream getInput() throws IOException { + public InputStream openStream() throws IOException { if (counter[0]++ != 0) { - throw new IllegalStateException("More than one supplier open"); + throw new IllegalStateException("More than one source open"); } - return new FilterInputStream(supplier.getInput()) { + return new FilterInputStream(source.openStream()) { @Override public void close() throws IOException { super.close(); counter[0]--; @@ -62,29 +62,26 @@ public class MultiInputStreamTest extends IoTestCase { }; } }; - @SuppressWarnings("unchecked") - byte[] result = ByteStreams.toByteArray( - ByteStreams.join(checker, checker, checker)); + byte[] result = ByteSource.concat(checker, checker, checker).read(); assertEquals(150, result.length); } private void joinHelper(Integer... spans) throws Exception { - List<InputSupplier<InputStream>> suppliers = Lists.newArrayList(); + List<ByteSource> sources = Lists.newArrayList(); int start = 0; for (Integer span : spans) { - suppliers.add(newByteSupplier(start, span)); + sources.add(newByteSource(start, span)); start += span; } - InputSupplier<InputStream> joined = ByteStreams.join(suppliers); - assertTrue(ByteStreams.equal(newByteSupplier(0, start), joined)); + ByteSource joined = ByteSource.concat(sources); + assertTrue(newByteSource(0, start).contentEquals(joined)); } public void testReadSingleByte() throws Exception { - InputSupplier<InputStream> supplier = newByteSupplier(0, 10); - @SuppressWarnings("unchecked") - InputSupplier<InputStream> joined = ByteStreams.join(supplier, supplier); - assertEquals(20, ByteStreams.length(joined)); - InputStream in = joined.getInput(); + ByteSource source = newByteSource(0, 10); + ByteSource joined = ByteSource.concat(source, source); + assertEquals(20, joined.size()); + InputStream in = joined.openStream(); assertFalse(in.markSupported()); assertEquals(10, in.available()); int total = 0; @@ -97,9 +94,9 @@ public class MultiInputStreamTest extends IoTestCase { public void testSkip() throws Exception { MultiInputStream multi = new MultiInputStream( - Collections.singleton(new InputSupplier<InputStream>() { + Collections.singleton(new ByteSource() { @Override - public InputStream getInput() { + public InputStream openStream() { return new ByteArrayInputStream(newPreFilledByteArray(0, 50)) { @Override public long skip(long n) { return 0; @@ -114,10 +111,10 @@ public class MultiInputStreamTest extends IoTestCase { assertEquals(20, multi.read()); } - private static InputSupplier<InputStream> newByteSupplier(final int start, final int size) { - return new InputSupplier<InputStream>() { + private static ByteSource newByteSource(final int start, final int size) { + return new ByteSource() { @Override - public InputStream getInput() { + public InputStream openStream() { return new ByteArrayInputStream(newPreFilledByteArray(start, size)); } }; diff --git a/guava-tests/test/com/google/common/io/MultiReaderTest.java b/guava-tests/test/com/google/common/io/MultiReaderTest.java index a1ff385..26a5d44 100644 --- a/guava-tests/test/com/google/common/io/MultiReaderTest.java +++ b/guava-tests/test/com/google/common/io/MultiReaderTest.java @@ -18,13 +18,13 @@ package com.google.common.io; import com.google.common.collect.ImmutableList; +import junit.framework.TestCase; + import java.io.FilterReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; -import junit.framework.TestCase; - /** * @author ricebin */ @@ -32,15 +32,15 @@ public class MultiReaderTest extends TestCase { public void testOnlyOneOpen() throws Exception { String testString = "abcdefgh"; - final InputSupplier<Reader> supplier = newReader(testString); + final CharSource source = newCharSource(testString); final int[] counter = new int[1]; - InputSupplier<Reader> reader = new InputSupplier<Reader>() { + CharSource reader = new CharSource() { @Override - public Reader getInput() throws IOException { + public Reader openStream() throws IOException { if (counter[0]++ != 0) { - throw new IllegalStateException("More than one supplier open"); + throw new IllegalStateException("More than one source open"); } - return new FilterReader(supplier.getInput()) { + return new FilterReader(source.openStream()) { @Override public void close() throws IOException { super.close(); counter[0]--; @@ -48,16 +48,15 @@ public class MultiReaderTest extends TestCase { }; } }; - @SuppressWarnings("unchecked") - Reader joinedReader = CharStreams.join(reader, reader, reader).getInput(); + Reader joinedReader = CharSource.concat(reader, reader, reader).openStream(); String result = CharStreams.toString(joinedReader); assertEquals(testString.length() * 3, result.length()); } public void testReady() throws Exception { - InputSupplier<Reader> supplier = newReader("a"); - Iterable<? extends InputSupplier<? extends Reader>> list = ImmutableList.of(supplier, supplier); - Reader joinedReader = CharStreams.join(list).getInput(); + CharSource source = newCharSource("a"); + Iterable<? extends CharSource> list = ImmutableList.of(source, source); + Reader joinedReader = CharSource.concat(list).openStream(); assertTrue(joinedReader.ready()); assertEquals('a', joinedReader.read()); @@ -68,19 +67,18 @@ public class MultiReaderTest extends TestCase { public void testSimple() throws Exception { String testString = "abcdefgh"; - InputSupplier<Reader> supplier = newReader(testString); - @SuppressWarnings("unchecked") - Reader joinedReader = CharStreams.join(supplier, supplier).getInput(); + CharSource source = newCharSource(testString); + Reader joinedReader = CharSource.concat(source, source).openStream(); String expectedString = testString + testString; assertEquals(expectedString, CharStreams.toString(joinedReader)); } - private static InputSupplier<Reader> newReader(final String text) { - return new InputSupplier<Reader>() { + private static CharSource newCharSource(final String text) { + return new CharSource() { @Override - public Reader getInput() { + public Reader openStream() { return new StringReader(text); } }; @@ -89,9 +87,8 @@ public class MultiReaderTest extends TestCase { public void testSkip() throws Exception { String begin = "abcde"; String end = "fghij"; - @SuppressWarnings("unchecked") Reader joinedReader = - CharStreams.join(newReader(begin), newReader(end)).getInput(); + CharSource.concat(newCharSource(begin), newCharSource(end)).openStream(); String expected = begin + end; assertEquals(expected.charAt(0), joinedReader.read()); @@ -105,9 +102,9 @@ public class MultiReaderTest extends TestCase { } public void testSkipZero() throws Exception { - InputSupplier<Reader> supplier = newReader("a"); - Iterable<? extends InputSupplier<? extends Reader>> list = ImmutableList.of(supplier, supplier); - Reader joinedReader = CharStreams.join(list).getInput(); + CharSource source = newCharSource("a"); + Iterable<CharSource> list = ImmutableList.of(source, source); + Reader joinedReader = CharSource.concat(list).openStream(); assertEquals(0, joinedReader.skip(0)); assertEquals('a', joinedReader.read()); diff --git a/guava-tests/test/com/google/common/io/NullOutputStreamTest.java b/guava-tests/test/com/google/common/io/NullOutputStreamTest.java deleted file mode 100644 index edbdfc9..0000000 --- a/guava-tests/test/com/google/common/io/NullOutputStreamTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2002 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.io; - -import junit.framework.TestCase; - -/** - * Unit tests for {@link NullOutputStream}. - * - * @author Spencer Kimball - */ -public class NullOutputStreamTest extends TestCase { - - public void testBasicOperation() throws Exception { - // create a null output stream - NullOutputStream nos = new NullOutputStream(); - assertNotNull(nos); - // write to the output stream - nos.write('n'); - String test = "Test string for NullOutputStream"; - nos.write(test.getBytes()); - nos.write(test.getBytes(), 2, 10); - } -} diff --git a/guava-tests/test/com/google/common/io/PackageSanityTests.java b/guava-tests/test/com/google/common/io/PackageSanityTests.java index a620b30..66d3bca 100644 --- a/guava-tests/test/com/google/common/io/PackageSanityTests.java +++ b/guava-tests/test/com/google/common/io/PackageSanityTests.java @@ -19,6 +19,7 @@ package com.google.common.io; import com.google.common.testing.AbstractPackageSanityTests; import java.lang.reflect.Method; +import java.nio.channels.FileChannel.MapMode; /** * Basic sanity tests for the entire package. @@ -32,5 +33,6 @@ public class PackageSanityTests extends AbstractPackageSanityTests { setDefault(int.class, 32); setDefault(String.class, "abcd"); setDefault(Method.class, AbstractPackageSanityTests.class.getDeclaredMethods()[0]); + setDefault(MapMode.class, MapMode.READ_ONLY); } } diff --git a/guava-tests/test/com/google/common/io/PatternFilenameFilterTest.java b/guava-tests/test/com/google/common/io/PatternFilenameFilterTest.java index 148999d..6a89011 100644 --- a/guava-tests/test/com/google/common/io/PatternFilenameFilterTest.java +++ b/guava-tests/test/com/google/common/io/PatternFilenameFilterTest.java @@ -16,12 +16,12 @@ package com.google.common.io; +import junit.framework.TestCase; + import java.io.File; import java.io.FilenameFilter; import java.util.regex.PatternSyntaxException; -import junit.framework.TestCase; - /** * Unit test for {@link PatternFilenameFilter}. * diff --git a/guava-tests/test/com/google/common/io/ResourcesTest.java b/guava-tests/test/com/google/common/io/ResourcesTest.java index b84a4bc..dac1d80 100644 --- a/guava-tests/test/com/google/common/io/ResourcesTest.java +++ b/guava-tests/test/com/google/common/io/ResourcesTest.java @@ -17,22 +17,25 @@ package com.google.common.io; import static com.google.common.base.CharMatcher.WHITESPACE; +import static org.truth0.Truth.ASSERT; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableList; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; +import junit.framework.TestSuite; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; +import java.io.File; import java.io.IOException; +import java.io.PrintWriter; import java.net.URL; +import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; -import junit.framework.TestSuite; - /** * Unit test for {@link Resources}. * @@ -50,17 +53,10 @@ public class ResourcesTest extends IoTestCase { return suite; } - public void testUrlSupplier() throws IOException { - byte[] data = ByteStreams.toByteArray( - Resources.newInputStreamSupplier(classfile(Resources.class))); - assertEquals(0xCAFEBABE, - new DataInputStream(new ByteArrayInputStream(data)).readInt()); - } - public void testToString() throws IOException { URL resource = getClass().getResource("testdata/i18n.txt"); assertEquals(I18N, Resources.toString(resource, Charsets.UTF_8)); - FluentAsserts.assertThat(Resources.toString(resource, Charsets.US_ASCII)) + ASSERT.that(Resources.toString(resource, Charsets.US_ASCII)) .isNotEqualTo(I18N); } @@ -137,6 +133,56 @@ public class ResourcesTest extends IoTestCase { assertNotNull(Resources.getResource(getClass(), "testdata/i18n.txt")); } + public void testGetResource_contextClassLoader() throws IOException { + // Check that we can find a resource if it is visible to the context class + // loader, even if it is not visible to the loader of the Resources class. + + File tempFile = createTempFile(); + PrintWriter writer = new PrintWriter(tempFile, "UTF-8"); + writer.println("rud a chur ar an méar fhada"); + writer.close(); + + // First check that we can't find it without setting the context loader. + // This is a sanity check that the test doesn't spuriously pass because + // the resource is visible to the system class loader. + try { + Resources.getResource(tempFile.getName()); + fail("Should get IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + + // Now set the context loader to one that should find the resource. + URL baseUrl = tempFile.getParentFile().toURI().toURL(); + URLClassLoader loader = new URLClassLoader(new URL[] {baseUrl}); + ClassLoader oldContextLoader = + Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(loader); + URL url = Resources.getResource(tempFile.getName()); + String text = Resources.toString(url, Charsets.UTF_8); + assertEquals("rud a chur ar an méar fhada\n", text); + } finally { + Thread.currentThread().setContextClassLoader(oldContextLoader); + } + } + + public void testGetResource_contextClassLoaderNull() { + ClassLoader oldContextLoader = + Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(null); + assertNotNull( + Resources.getResource("com/google/common/io/testdata/i18n.txt")); + try { + Resources.getResource("no such resource"); + fail("Should get IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } finally { + Thread.currentThread().setContextClassLoader(oldContextLoader); + } + } + public void testNulls() { new NullPointerTester() .setDefault(URL.class, classfile(ResourcesTest.class)) diff --git a/guava-tests/test/com/google/common/io/SourceSinkFactories.java b/guava-tests/test/com/google/common/io/SourceSinkFactories.java index 892a48e..56c73e2 100644 --- a/guava-tests/test/com/google/common/io/SourceSinkFactories.java +++ b/guava-tests/test/com/google/common/io/SourceSinkFactories.java @@ -17,12 +17,12 @@ package com.google.common.io; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.io.SourceSinkFactory.ByteSinkFactory; +import static com.google.common.io.SourceSinkFactory.ByteSourceFactory; +import static com.google.common.io.SourceSinkFactory.CharSinkFactory; +import static com.google.common.io.SourceSinkFactory.CharSourceFactory; import com.google.common.base.Charsets; -import com.google.common.io.SourceSinkFactory.ByteSinkFactory; -import com.google.common.io.SourceSinkFactory.ByteSourceFactory; -import com.google.common.io.SourceSinkFactory.CharSinkFactory; -import com.google.common.io.SourceSinkFactory.CharSourceFactory; import com.google.common.jdk5backport.Arrays; import java.io.ByteArrayOutputStream; @@ -59,6 +59,14 @@ public class SourceSinkFactories { return new ByteArraySourceFactory(); } + public static ByteSourceFactory emptyByteSourceFactory() { + return new EmptyByteSourceFactory(); + } + + public static CharSourceFactory emptyCharSourceFactory() { + return new EmptyCharSourceFactory(); + } + public static ByteSourceFactory fileByteSourceFactory() { return new FileByteSourceFactory(); } @@ -108,7 +116,12 @@ public class SourceSinkFactories { @Override public String getExpected(String data) { - return checkNotNull(data); + try { + return new String(factory.getExpected(data.getBytes(Charsets.UTF_8.name())), + Charsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(); + } } @Override @@ -163,7 +176,8 @@ public class SourceSinkFactories { @Override public byte[] getExpected(byte[] bytes) { - return Arrays.copyOfRange(factory.getExpected(bytes), off, off + len); + byte[] baseExpected = factory.getExpected(bytes); + return Arrays.copyOfRange(baseExpected, off, Math.min(baseExpected.length, off + len)); } @Override @@ -177,7 +191,7 @@ public class SourceSinkFactories { @Override public CharSource createSource(String data) throws IOException { - return CharStreams.asCharSource(data); + return CharSource.wrap(data); } @Override @@ -194,7 +208,7 @@ public class SourceSinkFactories { @Override public ByteSource createSource(byte[] bytes) throws IOException { - return ByteStreams.asByteSource(bytes); + return ByteSource.wrap(bytes); } @Override @@ -207,6 +221,40 @@ public class SourceSinkFactories { } } + private static class EmptyCharSourceFactory implements CharSourceFactory { + + @Override + public CharSource createSource(String data) throws IOException { + return CharSource.empty(); + } + + @Override + public String getExpected(String data) { + return ""; + } + + @Override + public void tearDown() throws IOException { + } + } + + private static class EmptyByteSourceFactory implements ByteSourceFactory { + + @Override + public ByteSource createSource(byte[] bytes) throws IOException { + return ByteSource.empty(); + } + + @Override + public byte[] getExpected(byte[] bytes) { + return new byte[0]; + } + + @Override + public void tearDown() throws IOException { + } + } + private abstract static class FileFactory { private static final Logger logger = Logger.getLogger(FileFactory.class.getName()); @@ -222,6 +270,7 @@ public class SourceSinkFactories { protected File getFile() { return fileThreadLocal.get(); } + public final void tearDown() throws IOException { if (!fileThreadLocal.get().delete()) { logger.warning("Unable to delete file: " + fileThreadLocal.get()); diff --git a/guava-tests/test/com/google/common/io/SourceSinkTester.java b/guava-tests/test/com/google/common/io/SourceSinkTester.java index 3eb5e57..ff3167b 100644 --- a/guava-tests/test/com/google/common/io/SourceSinkTester.java +++ b/guava-tests/test/com/google/common/io/SourceSinkTester.java @@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; +import junit.framework.TestCase; + import java.io.IOException; import java.io.Reader; import java.io.StringReader; @@ -29,8 +31,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.List; -import junit.framework.TestCase; - /** * @param <S> the source or sink type * @param <T> the data type (byte[] or String) diff --git a/guava-tests/test/com/google/common/io/TestInputStream.java b/guava-tests/test/com/google/common/io/TestInputStream.java index 51aec6d..09cf990 100644 --- a/guava-tests/test/com/google/common/io/TestInputStream.java +++ b/guava-tests/test/com/google/common/io/TestInputStream.java @@ -73,6 +73,12 @@ public class TestInputStream extends FilterInputStream { } @Override + public int available() throws IOException { + throwIf(closed); + return options.contains(TestOption.AVAILABLE_ALWAYS_ZERO) ? 0 : in.available(); + } + + @Override public void close() throws IOException { closed = true; throwIf(CLOSE_THROWS); diff --git a/guava-tests/test/com/google/common/io/TestOption.java b/guava-tests/test/com/google/common/io/TestOption.java index 89d7a77..5ebd1f1 100644 --- a/guava-tests/test/com/google/common/io/TestOption.java +++ b/guava-tests/test/com/google/common/io/TestOption.java @@ -26,5 +26,6 @@ public enum TestOption { SKIP_THROWS, READ_THROWS, WRITE_THROWS, - CLOSE_THROWS + CLOSE_THROWS, + AVAILABLE_ALWAYS_ZERO } diff --git a/guava-tests/test/com/google/common/io/testdata/ascii.txt b/guava-tests/test/com/google/common/io/testdata/ascii.txt new file mode 100644 index 0000000..d86e6b0 --- /dev/null +++ b/guava-tests/test/com/google/common/io/testdata/ascii.txt @@ -0,0 +1 @@ + !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
\ No newline at end of file diff --git a/guava-tests/test/com/google/common/math/BigIntegerMathTest.java b/guava-tests/test/com/google/common/math/BigIntegerMathTest.java index eb34b02..7e1aa77 100644 --- a/guava-tests/test/com/google/common/math/BigIntegerMathTest.java +++ b/guava-tests/test/com/google/common/math/BigIntegerMathTest.java @@ -38,12 +38,12 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; -import junit.framework.TestCase; - /** * Tests for BigIntegerMath. * diff --git a/guava-tests/test/com/google/common/math/DoubleMathTest.java b/guava-tests/test/com/google/common/math/DoubleMathTest.java index bedabed..1231142 100644 --- a/guava-tests/test/com/google/common/math/DoubleMathTest.java +++ b/guava-tests/test/com/google/common/math/DoubleMathTest.java @@ -33,6 +33,8 @@ import static java.math.RoundingMode.UNNECESSARY; import static java.math.RoundingMode.UP; import static java.util.Arrays.asList; +import com.google.common.annotations.GwtCompatible; +import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.primitives.Doubles; @@ -51,6 +53,7 @@ import java.util.List; * * @author Louis Wasserman */ +@GwtCompatible(emulated = true) public class DoubleMathTest extends TestCase { private static final BigDecimal MAX_INT_AS_BIG_DECIMAL = BigDecimal.valueOf(Integer.MAX_VALUE); @@ -62,10 +65,10 @@ public class DoubleMathTest extends TestCase { private static final double MIN_NORMAL = 2.2250738585072014E-308; // Doubles.MIN_NORMAL from 1.6 public void testConstantsMaxFactorial() { - BigInteger MAX_DOUBLE_VALUE = BigDecimal.valueOf(Double.MAX_VALUE).toBigInteger(); - assertTrue(BigIntegerMath.factorial(DoubleMath.MAX_FACTORIAL).compareTo(MAX_DOUBLE_VALUE) <= 0); + BigInteger maxDoubleValue = BigDecimal.valueOf(Double.MAX_VALUE).toBigInteger(); + assertTrue(BigIntegerMath.factorial(DoubleMath.MAX_FACTORIAL).compareTo(maxDoubleValue) <= 0); assertTrue( - BigIntegerMath.factorial(DoubleMath.MAX_FACTORIAL + 1).compareTo(MAX_DOUBLE_VALUE) > 0); + BigIntegerMath.factorial(DoubleMath.MAX_FACTORIAL + 1).compareTo(maxDoubleValue) > 0); } public void testConstantsEverySixteenthFactorial() { @@ -75,6 +78,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)") public void testRoundIntegralDoubleToInt() { for (double d : INTEGRAL_DOUBLE_CANDIDATES) { for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) { @@ -92,6 +96,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)") public void testRoundFractionalDoubleToInt() { for (double d : FRACTIONAL_DOUBLE_CANDIDATES) { for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) { @@ -109,6 +114,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)") public void testRoundExactIntegralDoubleToInt() { for (double d : INTEGRAL_DOUBLE_CANDIDATES) { BigDecimal expected = new BigDecimal(d).setScale(0, UNNECESSARY); @@ -124,6 +130,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)") public void testRoundExactFractionalDoubleToIntFails() { for (double d : FRACTIONAL_DOUBLE_CANDIDATES) { try { @@ -133,6 +140,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)") public void testRoundNaNToIntAlwaysFails() { for (RoundingMode mode : ALL_ROUNDING_MODES) { try { @@ -142,6 +150,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToInt(double, RoundingMode)") public void testRoundInfiniteToIntAlwaysFails() { for (RoundingMode mode : ALL_ROUNDING_MODES) { try { @@ -155,6 +164,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)") public void testRoundIntegralDoubleToLong() { for (double d : INTEGRAL_DOUBLE_CANDIDATES) { for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) { @@ -172,6 +182,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)") public void testRoundFractionalDoubleToLong() { for (double d : FRACTIONAL_DOUBLE_CANDIDATES) { for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) { @@ -189,6 +200,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)") public void testRoundExactIntegralDoubleToLong() { for (double d : INTEGRAL_DOUBLE_CANDIDATES) { // every mode except UNNECESSARY @@ -205,6 +217,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)") public void testRoundExactFractionalDoubleToLongFails() { for (double d : FRACTIONAL_DOUBLE_CANDIDATES) { try { @@ -214,6 +227,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)") public void testRoundNaNToLongAlwaysFails() { for (RoundingMode mode : ALL_ROUNDING_MODES) { try { @@ -223,6 +237,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToLong(double, RoundingMode)") public void testRoundInfiniteToLongAlwaysFails() { for (RoundingMode mode : ALL_ROUNDING_MODES) { try { @@ -236,6 +251,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)") public void testRoundIntegralDoubleToBigInteger() { for (double d : INTEGRAL_DOUBLE_CANDIDATES) { for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) { @@ -245,6 +261,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)") public void testRoundFractionalDoubleToBigInteger() { for (double d : FRACTIONAL_DOUBLE_CANDIDATES) { for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) { @@ -254,6 +271,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)") public void testRoundExactIntegralDoubleToBigInteger() { for (double d : INTEGRAL_DOUBLE_CANDIDATES) { BigDecimal expected = new BigDecimal(d).setScale(0, UNNECESSARY); @@ -261,6 +279,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)") public void testRoundExactFractionalDoubleToBigIntegerFails() { for (double d : FRACTIONAL_DOUBLE_CANDIDATES) { try { @@ -270,6 +289,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)") public void testRoundNaNToBigIntegerAlwaysFails() { for (RoundingMode mode : ALL_ROUNDING_MODES) { try { @@ -279,6 +299,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)") public void testRoundInfiniteToBigIntegerAlwaysFails() { for (RoundingMode mode : ALL_ROUNDING_MODES) { try { @@ -292,6 +313,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.roundToBigInteger(double, RoundingMode)") public void testRoundLog2Floor() { for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) { int log2 = DoubleMath.log2(d, FLOOR); @@ -300,6 +322,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.log2(double, RoundingMode), StrictMath") public void testRoundLog2Ceiling() { for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) { int log2 = DoubleMath.log2(d, CEILING); @@ -309,6 +332,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.log2(double, RoundingMode), StrictMath") public void testRoundLog2Down() { for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) { int log2 = DoubleMath.log2(d, DOWN); @@ -324,6 +348,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.log2(double, RoundingMode), StrictMath") public void testRoundLog2Up() { for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) { int log2 = DoubleMath.log2(d, UP); @@ -339,7 +364,7 @@ public class DoubleMathTest extends TestCase { } } - + @GwtIncompatible("DoubleMath.log2(double, RoundingMode)") public void testRoundLog2ThrowsOnZerosInfinitiesAndNaN() { for (RoundingMode mode : ALL_ROUNDING_MODES) { for (double d : @@ -347,28 +372,31 @@ public class DoubleMathTest extends TestCase { try { DoubleMath.log2(d, mode); fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException e) {} + } catch (IllegalArgumentException expected) {} } } } + @GwtIncompatible("DoubleMath.log2(double, RoundingMode)") public void testRoundLog2ThrowsOnNegative() { for (RoundingMode mode : ALL_ROUNDING_MODES) { for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) { try { DoubleMath.log2(-d, mode); fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException e) {} + } catch (IllegalArgumentException expected) {} } } } + @GwtIncompatible("DoubleMath.isPowerOfTwo, DoubleMath.log2(double, RoundingMode), StrictMath") public void testIsPowerOfTwoYes() { for (int i = -1074; i <= 1023; i++) { assertTrue(DoubleMath.isPowerOfTwo(StrictMath.pow(2.0, i))); } } + @GwtIncompatible("DoubleMath.isPowerOfTwo, DoubleMath.log2(double, RoundingMode), StrictMath") public void testIsPowerOfTwo() { for (double x : ALL_DOUBLE_CANDIDATES) { boolean expected = x > 0 && !Double.isInfinite(x) && !Double.isNaN(x) @@ -377,7 +405,6 @@ public class DoubleMathTest extends TestCase { } } - public void testLog2SemiMonotonic() { for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) { assertTrue(DoubleMath.log2(d + 0.01) >= DoubleMath.log2(d)); @@ -401,18 +428,22 @@ public class DoubleMathTest extends TestCase { assertTrue(Double.isNaN(DoubleMath.log2(Double.NaN))); } + + @GwtIncompatible("DoubleMath.isMathematicalInteger") public void testIsMathematicalIntegerIntegral() { for (double d : INTEGRAL_DOUBLE_CANDIDATES) { assertTrue(DoubleMath.isMathematicalInteger(d)); } } + @GwtIncompatible("DoubleMath.isMathematicalInteger") public void testIsMathematicalIntegerFractional() { for (double d : FRACTIONAL_DOUBLE_CANDIDATES) { assertFalse(DoubleMath.isMathematicalInteger(d)); } } + @GwtIncompatible("DoubleMath.isMathematicalInteger") public void testIsMathematicalIntegerNotFinite() { for (double d : Arrays.asList(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN)) { @@ -420,6 +451,7 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("Math.ulp") public void testFactorial() { for (int i = 0; i <= DoubleMath.MAX_FACTORIAL; i++) { double actual = BigIntegerMath.factorial(i).doubleValue(); @@ -553,6 +585,110 @@ public class DoubleMathTest extends TestCase { } } + @GwtIncompatible("DoubleMath.mean") + public void testMean_doubleVarargs() { + assertEquals(-1.375, DoubleMath.mean(1.1, -2.2, 4.4, -8.8), 1.0e-10); + assertEquals(1.1, DoubleMath.mean(1.1), 1.0e-10); + try { + DoubleMath.mean(Double.NaN); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + try { + DoubleMath.mean(Double.POSITIVE_INFINITY); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + @GwtIncompatible("DoubleMath.mean") + public void testMean_intVarargs() { + assertEquals(-13.75, DoubleMath.mean(11, -22, 44, -88), 1.0e-10); + assertEquals(11.0, DoubleMath.mean(11), 1.0e-10); + } + + @GwtIncompatible("DoubleMath.mean") + public void testMean_longVarargs() { + assertEquals(-13.75, DoubleMath.mean(11L, -22L, 44L, -88L), 1.0e-10); + assertEquals(11.0, DoubleMath.mean(11L), 1.0e-10); + } + + @GwtIncompatible("DoubleMath.mean") + public void testMean_emptyVarargs() { + try { + DoubleMath.mean(); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + @GwtIncompatible("DoubleMath.mean") + public void testMean_doubleIterable() { + assertEquals(-1.375, DoubleMath.mean(ImmutableList.of(1.1, -2.2, 4.4, -8.8)), 1.0e-10); + assertEquals(1.1, DoubleMath.mean(ImmutableList.of(1.1)), 1.0e-10); + try { + DoubleMath.mean(ImmutableList.<Double>of()); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + try { + DoubleMath.mean(ImmutableList.of(Double.NaN)); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + try { + DoubleMath.mean(ImmutableList.of(Double.POSITIVE_INFINITY)); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + @GwtIncompatible("DoubleMath.mean") + public void testMean_intIterable() { + assertEquals(-13.75, DoubleMath.mean(ImmutableList.of(11, -22, 44, -88)), 1.0e-10); + assertEquals(11, DoubleMath.mean(ImmutableList.of(11)), 1.0e-10); + try { + DoubleMath.mean(ImmutableList.<Integer>of()); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + @GwtIncompatible("DoubleMath.mean") + public void testMean_longIterable() { + assertEquals(-13.75, DoubleMath.mean(ImmutableList.of(11L, -22L, 44L, -88L)), 1.0e-10); + assertEquals(11, DoubleMath.mean(ImmutableList.of(11L)), 1.0e-10); + try { + DoubleMath.mean(ImmutableList.<Long>of()); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + @GwtIncompatible("DoubleMath.mean") + public void testMean_intIterator() { + assertEquals(-13.75, DoubleMath.mean(ImmutableList.of(11, -22, 44, -88).iterator()), 1.0e-10); + assertEquals(11, DoubleMath.mean(ImmutableList.of(11).iterator()), 1.0e-10); + try { + DoubleMath.mean(ImmutableList.<Integer>of().iterator()); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + @GwtIncompatible("DoubleMath.mean") + public void testMean_longIterator() { + assertEquals(-13.75, DoubleMath.mean(ImmutableList.of(11L, -22L, 44L, -88L).iterator()), + 1.0e-10); + assertEquals(11, DoubleMath.mean(ImmutableList.of(11L).iterator()), 1.0e-10); + try { + DoubleMath.mean(ImmutableList.<Long>of().iterator()); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + + @GwtIncompatible("NullPointerTester") public void testNullPointers() { NullPointerTester tester = new NullPointerTester(); tester.setDefault(double.class, 3.0); diff --git a/guava-tests/test/com/google/common/math/DoubleUtilsTest.java b/guava-tests/test/com/google/common/math/DoubleUtilsTest.java index 7920674..65952aa 100644 --- a/guava-tests/test/com/google/common/math/DoubleUtilsTest.java +++ b/guava-tests/test/com/google/common/math/DoubleUtilsTest.java @@ -20,11 +20,12 @@ import static com.google.common.math.MathTesting.ALL_BIGINTEGER_CANDIDATES; import static com.google.common.math.MathTesting.FINITE_DOUBLE_CANDIDATES; import static com.google.common.math.MathTesting.POSITIVE_FINITE_DOUBLE_CANDIDATES; -import java.math.BigInteger; - import junit.framework.TestCase; + import sun.misc.FpUtils; +import java.math.BigInteger; + /** * Tests for {@link DoubleUtils}. * diff --git a/guava-tests/test/com/google/common/math/IntMathTest.java b/guava-tests/test/com/google/common/math/IntMathTest.java index e837dfc..aba46c3 100644 --- a/guava-tests/test/com/google/common/math/IntMathTest.java +++ b/guava-tests/test/com/google/common/math/IntMathTest.java @@ -32,12 +32,12 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; -import junit.framework.TestCase; - /** * Tests for {@link IntMath}. * @@ -95,6 +95,18 @@ public class IntMathTest extends TestCase { public void testPowersSqrtMaxInt() { assertEquals(IntMath.sqrt(Integer.MAX_VALUE, FLOOR), IntMath.FLOOR_SQRT_MAX_INT); } + + public void testLessThanBranchFree() { + for (int x : ALL_INTEGER_CANDIDATES) { + for (int y : ALL_INTEGER_CANDIDATES) { + if (LongMath.fitsInInt((long) x - y)) { + int expected = (x < y) ? 1 : 0; + int actual = IntMath.lessThanBranchFree(x, y); + assertEquals(expected, actual); + } + } + } + } @GwtIncompatible("java.math.BigInteger") public void testIsPowerOfTwo() { diff --git a/guava-tests/test/com/google/common/math/LongMathTest.java b/guava-tests/test/com/google/common/math/LongMathTest.java index 161aa58..d3ac668 100644 --- a/guava-tests/test/com/google/common/math/LongMathTest.java +++ b/guava-tests/test/com/google/common/math/LongMathTest.java @@ -34,12 +34,12 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; -import junit.framework.TestCase; - /** * Tests for LongMath. * @@ -137,6 +137,19 @@ public class LongMathTest extends TestCase { } catch (ArithmeticException expected) {} } + public void testLessThanBranchFree() { + for (long x : ALL_LONG_CANDIDATES) { + for (long y : ALL_LONG_CANDIDATES) { + BigInteger difference = BigInteger.valueOf(x).subtract(BigInteger.valueOf(y)); + if (fitsInLong(difference)) { + int expected = (x < y) ? 1 : 0; + int actual = LongMath.lessThanBranchFree(x, y); + assertEquals(expected, actual); + } + } + } + } + // Throws an ArithmeticException if "the simple implementation" of binomial coefficients overflows @GwtIncompatible("TODO") private long simpleBinomial(int n, int k) { @@ -285,11 +298,11 @@ public class LongMathTest extends TestCase { @GwtIncompatible("TODO") public void testSqrtExactMatchesFloorOrThrows() { for (long x : POSITIVE_LONG_CANDIDATES) { - long logFloor = LongMath.sqrt(x, FLOOR); + long sqrtFloor = LongMath.sqrt(x, FLOOR); // We only expect an exception if x was not a perfect square. - boolean isPerfectSquare = (logFloor * logFloor == x); + boolean isPerfectSquare = (sqrtFloor * sqrtFloor == x); try { - assertEquals(logFloor, LongMath.sqrt(x, UNNECESSARY)); + assertEquals(sqrtFloor, LongMath.sqrt(x, UNNECESSARY)); assertTrue(isPerfectSquare); } catch (ArithmeticException e) { assertFalse(isPerfectSquare); @@ -587,6 +600,20 @@ public class LongMathTest extends TestCase { } } + @GwtIncompatible("far too slow") + public void testSqrtOfPerfectSquareAsDoubleIsPerfect() { + // This takes just over a minute on my machine. + for (long n = 0; n <= LongMath.FLOOR_SQRT_MAX_LONG; n++) { + long actual = (long) Math.sqrt(n * n); + assertTrue(actual == n); + } + } + + public void testSqrtOfLongIsAtMostFloorSqrtMaxLong() { + long sqrtMaxLong = (long) Math.sqrt(Long.MAX_VALUE); + assertTrue(sqrtMaxLong <= LongMath.FLOOR_SQRT_MAX_LONG); + } + @GwtIncompatible("java.math.BigInteger") public void testMean() { // Odd-sized ranges have an obvious mean diff --git a/guava-tests/test/com/google/common/math/MathPreconditionsTest.java b/guava-tests/test/com/google/common/math/MathPreconditionsTest.java index 1ba7065..b776ee1 100644 --- a/guava-tests/test/com/google/common/math/MathPreconditionsTest.java +++ b/guava-tests/test/com/google/common/math/MathPreconditionsTest.java @@ -18,10 +18,10 @@ package com.google.common.math; import com.google.common.annotations.GwtCompatible; -import java.math.BigInteger; - import junit.framework.TestCase; +import java.math.BigInteger; + /** * Unit tests for {@link MathPreconditions}. * diff --git a/guava-tests/test/com/google/common/math/PackageSanityTests.java b/guava-tests/test/com/google/common/math/PackageSanityTests.java index 4914af1..1fc7cc7 100644 --- a/guava-tests/test/com/google/common/math/PackageSanityTests.java +++ b/guava-tests/test/com/google/common/math/PackageSanityTests.java @@ -24,4 +24,8 @@ import com.google.common.testing.AbstractPackageSanityTests; * @author Ben Yu */ -public class PackageSanityTests extends AbstractPackageSanityTests {} +public class PackageSanityTests extends AbstractPackageSanityTests { + public PackageSanityTests() { + publicApiOnly(); + } +} diff --git a/guava-tests/test/com/google/common/net/HostAndPortTest.java b/guava-tests/test/com/google/common/net/HostAndPortTest.java index 476a63b..d431702 100644 --- a/guava-tests/test/com/google/common/net/HostAndPortTest.java +++ b/guava-tests/test/com/google/common/net/HostAndPortTest.java @@ -16,6 +16,7 @@ package com.google.common.net; +import com.google.common.annotations.GwtCompatible; import com.google.common.testing.SerializableTester; import junit.framework.TestCase; @@ -25,6 +26,7 @@ import junit.framework.TestCase; * * @author Paul Marks */ +@GwtCompatible public class HostAndPortTest extends TestCase { public void testFromStringWellFormed() { @@ -163,6 +165,28 @@ public class HostAndPortTest extends TestCase { } } + public void testFromHost() { + HostAndPort hp = HostAndPort.fromHost("gmail.com"); + assertEquals("gmail.com", hp.getHostText()); + assertFalse(hp.hasPort()); + + hp = HostAndPort.fromHost("[::1]"); + assertEquals("::1", hp.getHostText()); + assertFalse(hp.hasPort()); + + try { + HostAndPort.fromHost("gmail.com:80"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + + try { + HostAndPort.fromHost("[gmail.com]"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + public void testGetPortOrDefault() { assertEquals(80, HostAndPort.fromString("host:80").getPortOrDefault(123)); assertEquals(123, HostAndPort.fromString("host").getPortOrDefault(123)); diff --git a/guava-tests/test/com/google/common/net/HostSpecifierTest.java b/guava-tests/test/com/google/common/net/HostSpecifierTest.java index af55dd6..12c7631 100644 --- a/guava-tests/test/com/google/common/net/HostSpecifierTest.java +++ b/guava-tests/test/com/google/common/net/HostSpecifierTest.java @@ -20,11 +20,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.text.ParseException; import java.util.List; -import junit.framework.TestCase; - /** * {@link TestCase} for {@link HostSpecifier}. This is a relatively * cursory test, as HostSpecifier is a thin wrapper around diff --git a/guava-tests/test/com/google/common/net/HttpHeadersTest.java b/guava-tests/test/com/google/common/net/HttpHeadersTest.java index 7977587..282f41f 100644 --- a/guava-tests/test/com/google/common/net/HttpHeadersTest.java +++ b/guava-tests/test/com/google/common/net/HttpHeadersTest.java @@ -19,49 +19,67 @@ package com.google.common.net; import com.google.common.base.Ascii; import com.google.common.base.Joiner; import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import junit.framework.TestCase; + import java.lang.reflect.Field; import java.util.List; -import junit.framework.TestCase; - /** * Tests for the HttpHeaders class. * * @author Kurt Alfred Kluever */ public class HttpHeadersTest extends TestCase { + public void testConstantNameMatchesString() throws Exception { - for (Field field : HttpHeaders.class.getDeclaredFields()) { + // Special case some of the weird HTTP Header names... + ImmutableBiMap<String, String> specialCases = ImmutableBiMap.of("ETAG", "ETag"); + ImmutableSet<String> uppercaseAcronyms = ImmutableSet.of( + "ID", "DNT", "IP", "MD5", "P3P", "TE", "UID", "URL", "WWW", "XSS"); + assertConstantNameMatchesString(HttpHeaders.class, specialCases, uppercaseAcronyms); + } + + // Visible for other tests to use + static void assertConstantNameMatchesString(Class<?> clazz, + ImmutableBiMap<String, String> specialCases, ImmutableSet<String> uppercaseAcronyms) + throws IllegalAccessException { + for (Field field : relevantFields(clazz)) { + assertEquals(upperToHttpHeaderName(field.getName(), specialCases, uppercaseAcronyms), + field.get(null)); + } + } + + // Visible for other tests to use + static ImmutableSet<Field> relevantFields(Class<?> cls) { + ImmutableSet.Builder<Field> builder = ImmutableSet.builder(); + for (Field field : cls.getDeclaredFields()) { /* * Coverage mode generates synthetic fields. If we ever add private * fields, they will cause similar problems, and we may want to switch * this check to isAccessible(). */ if (!field.isSynthetic()) { - assertEquals(upperToHttpHeaderName(field.getName()), field.get(null)); + builder.add(field); } } + return builder.build(); } - private static final ImmutableSet<String> UPPERCASE_ACRONYMS = ImmutableSet.of( - "ID", "DNT", "GFE", "GSE", "IP", "MD5", "P3P", "TE", "UID", "URL", - "WWW", "XSS"); - private static final Splitter SPLITTER = Splitter.on('_'); private static final Joiner JOINER = Joiner.on('-'); - private static String upperToHttpHeaderName(String constantName) { - // Special case some of the weird HTTP Header names... - if (constantName.equals("ETAG")) { - return "ETag"; + private static String upperToHttpHeaderName(String constantName, + ImmutableBiMap<String, String> specialCases, ImmutableSet<String> uppercaseAcronyms) { + if (specialCases.containsKey(constantName)) { + return specialCases.get(constantName); } - List<String> parts = Lists.newArrayList(); for (String part : SPLITTER.split(constantName)) { - if (!UPPERCASE_ACRONYMS.contains(part)) { + if (!uppercaseAcronyms.contains(part)) { part = part.charAt(0) + Ascii.toLowerCase(part.substring(1)); } parts.add(part); diff --git a/guava-tests/test/com/google/common/net/InetAddressesTest.java b/guava-tests/test/com/google/common/net/InetAddressesTest.java index 0872d29..90d3285 100644 --- a/guava-tests/test/com/google/common/net/InetAddressesTest.java +++ b/guava-tests/test/com/google/common/net/InetAddressesTest.java @@ -18,13 +18,13 @@ package com.google.common.net; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; -import junit.framework.TestCase; - /** * Tests for {@link InetAddresses}. * diff --git a/guava-tests/test/com/google/common/net/InternetDomainNameTest.java b/guava-tests/test/com/google/common/net/InternetDomainNameTest.java index cf09b14..a63c147 100644 --- a/guava-tests/test/com/google/common/net/InternetDomainNameTest.java +++ b/guava-tests/test/com/google/common/net/InternetDomainNameTest.java @@ -18,15 +18,13 @@ package com.google.common.net; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; +import com.google.common.base.Ascii; import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; -import java.util.List; -import java.util.Locale; - import junit.framework.TestCase; /** @@ -58,7 +56,7 @@ public final class InternetDomainNameTest extends TestCase { private static final String ALMOST_TOO_LONG = Strings.repeat("aaaaa.", 40) + "1234567890.c"; - private static final List<String> VALID_NAME = ImmutableList.of( + private static final ImmutableSet<String> VALID_NAME = ImmutableSet.of( "foo.com", "f-_-o.cOM", "f--1.com", @@ -76,7 +74,7 @@ public final class InternetDomainNameTest extends TestCase { ALMOST_TOO_MANY_LEVELS, ALMOST_TOO_LONG); - private static final List<String> INVALID_NAME = ImmutableList.of( + private static final ImmutableSet<String> INVALID_NAME = ImmutableSet.of( "", " ", "127.0.0.1", @@ -99,11 +97,11 @@ public final class InternetDomainNameTest extends TestCase { ALMOST_TOO_MANY_LEVELS + "com", ALMOST_TOO_LONG + ".c"); - private static final List<String> PS = ImmutableList.of( + private static final ImmutableSet<String> PS = ImmutableSet.of( "com", "co.uk", - "foo.ar", - "xxxxxx.ar", + "foo.bd", + "xxxxxx.bd", "org.mK", "us", "uk\uFF61com.", // Alternate dot character @@ -112,87 +110,88 @@ public final class InternetDomainNameTest extends TestCase { "xn--jrpeland-54a.no" // IDNA (punycode) encoding of above ); - private static final List<String> NO_PS = ImmutableList.of( + private static final ImmutableSet<String> NO_PS = ImmutableSet.of( "www", "foo.google", "x.y.z"); - private static final List<String> NON_PS = ImmutableList.of( + private static final ImmutableSet<String> NON_PS = ImmutableSet.of( "foo.bar.com", "foo.ca", "foo.bar.ca", "foo.bar.co.il", "state.CA.us", "www.state.pa.us", "pvt.k12.ca.us", "www.google.com", "www4.yahoo.co.uk", "home.netscape.com", "web.MIT.edu", "foo.eDu.au", "utenti.blah.IT", "dominio.com.co"); - private static final List<String> TOP_PRIVATE_DOMAIN = ImmutableList.of( - "google.com", "foo.Co.uk", "foo.ca.us."); + private static final ImmutableSet<String> TOP_PRIVATE_DOMAIN = + ImmutableSet.of("google.com", "foo.Co.uk", "foo.ca.us."); - private static final List<String> UNDER_PRIVATE_DOMAIN = ImmutableList.of( - "foo.bar.google.com", "a.b.co.uk", "x.y.ca.us"); + private static final ImmutableSet<String> UNDER_PRIVATE_DOMAIN = + ImmutableSet.of("foo.bar.google.com", "a.b.co.uk", "x.y.ca.us"); - private static final List<String> VALID_IP_ADDRS = ImmutableList.of( + private static final ImmutableSet<String> VALID_IP_ADDRS = ImmutableSet.of( "1.2.3.4", "127.0.0.1", "::1", "2001:db8::1"); - private static final List<String> INVALID_IP_ADDRS = ImmutableList.of( + private static final ImmutableSet<String> INVALID_IP_ADDRS = ImmutableSet.of( "", "1", "1.2.3", "...", "1.2.3.4.5", "400.500.600.700", ":", ":::1", "2001:db8:"); - private static final List<String> SOMEWHERE_UNDER_PS = ImmutableList.of( - "foo.bar.google.com", - "a.b.c.1.2.3.ca.us", - "site.jp", - "uomi-online.kir.jp", - "jprs.co.jp", - "site.quick.jp", - "site.tenki.jp", - "site.or.jp", - "site.gr.jp", - "site.ne.jp", - "site.ac.jp", - "site.ad.jp", - "site.ed.jp", - "site.geo.jp", - "site.go.jp", - "site.lg.jp", - "1.fm", - "site.cc", - "site.ee", - "site.fi", - "site.fm", - "site.gr", - "www.leguide.ma", - "site.ma", - "some.org.mk", - "site.mk", - "site.tv", - "site.us", - "www.odev.us", - "www.GOOGLE.com", - "www.com", - "google.com", - "www7.google.co.uk", - "google.Co.uK", - "jobs.kt.com.", - "home.netscape.com", - "web.stanford.edu", - "stanford.edu", - "state.ca.us", - "www.state.ca.us", - "state.ca.us", - "pvt.k12.ca.us", - "www.rave.ca.", - "cnn.ca", - "ledger-enquirer.com", - "it-trace.ch", - "cool.dk", - "cool.co.uk", - "cool.de", - "cool.es", - "cool\uFF61fr", // Alternate dot character - "cool.nl", - "members.blah.nl.", - "cool.se", - "utenti.blah.it", - "kt.co", - "a\u7f51\u7edcA.\u7f51\u7edc.Cn" // "a网络A.网络.Cn" - ); + private static final ImmutableSet<String> SOMEWHERE_UNDER_PS = + ImmutableSet.of( + "foo.bar.google.com", + "a.b.c.1.2.3.ca.us", + "site.jp", + "uomi-online.kir.jp", + "jprs.co.jp", + "site.quick.jp", + "site.tenki.jp", + "site.or.jp", + "site.gr.jp", + "site.ne.jp", + "site.ac.jp", + "site.ad.jp", + "site.ed.jp", + "site.geo.jp", + "site.go.jp", + "site.lg.jp", + "1.fm", + "site.cc", + "site.ee", + "site.fi", + "site.fm", + "site.gr", + "www.leguide.ma", + "site.ma", + "some.org.mk", + "site.mk", + "site.tv", + "site.us", + "www.odev.us", + "www.GOOGLE.com", + "www.com", + "google.com", + "www7.google.co.uk", + "google.Co.uK", + "jobs.kt.com.", + "home.netscape.com", + "web.stanford.edu", + "stanford.edu", + "state.ca.us", + "www.state.ca.us", + "state.ca.us", + "pvt.k12.ca.us", + "www.rave.ca.", + "cnn.ca", + "ledger-enquirer.com", + "it-trace.ch", + "cool.dk", + "cool.co.uk", + "cool.de", + "cool.es", + "cool\uFF61fr", // Alternate dot character + "cool.nl", + "members.blah.nl.", + "cool.se", + "utenti.blah.it", + "kt.co", + "a\u7f51\u7edcA.\u7f51\u7edc.Cn" // "a网络A.网络.Cn" + ); public void testValid() { for (String name : VALID_NAME) { @@ -271,13 +270,13 @@ public final class InternetDomainNameTest extends TestCase { public void testParent() { assertEquals( "com", - InternetDomainName.from("google.com").parent().name()); + InternetDomainName.from("google.com").parent().toString()); assertEquals( "uk", - InternetDomainName.from("co.uk").parent().name()); + InternetDomainName.from("co.uk").parent().toString()); assertEquals( "google.com", - InternetDomainName.from("www.google.com").parent().name()); + InternetDomainName.from("www.google.com").parent().toString()); try { InternetDomainName.from("com").parent(); @@ -289,7 +288,7 @@ public final class InternetDomainNameTest extends TestCase { public void testChild() { InternetDomainName domain = InternetDomainName.from("foo.com"); - assertEquals("www.foo.com", domain.child("www").name()); + assertEquals("www.foo.com", domain.child("www").toString()); try { domain.child("www."); @@ -302,7 +301,7 @@ public final class InternetDomainNameTest extends TestCase { public void testParentChild() { InternetDomainName origin = InternetDomainName.from("foo.com"); InternetDomainName parent = origin.parent(); - assertEquals("com", parent.name()); + assertEquals("com", parent.toString()); // These would throw an exception if leniency were not preserved during parent() and child() // calls. @@ -319,7 +318,8 @@ public final class InternetDomainNameTest extends TestCase { } public void testInvalidTopPrivateDomain() { - List<String> badCookieDomains = ImmutableList.of("co.uk", "foo", "com"); + ImmutableSet<String> badCookieDomains = + ImmutableSet.of("co.uk", "foo", "com"); for (String domain : badCookieDomains) { try { @@ -345,10 +345,7 @@ public final class InternetDomainNameTest extends TestCase { } } - // TODO(hhchan): Resurrect this test after removing the reference to - // String.toLowerCase(Locale) - @GwtIncompatible("String.toLowerCase(Locale)") - public void testName() { + public void testToString() { for (String inputName : SOMEWHERE_UNDER_PS) { InternetDomainName domain = InternetDomainName.from(inputName); @@ -358,34 +355,34 @@ public final class InternetDomainNameTest extends TestCase { * used in other tests. */ - String expectedName = inputName.toLowerCase(Locale.ENGLISH); + String expectedName = Ascii.toLowerCase(inputName); expectedName = expectedName.replaceAll("[\u3002\uFF0E\uFF61]", "."); if (expectedName.endsWith(".")) { expectedName = expectedName.substring(0, expectedName.length() - 1); } - assertEquals(expectedName, domain.name()); + assertEquals(expectedName, domain.toString()); } } public void testExclusion() { InternetDomainName domain = InternetDomainName.from("foo.nic.uk"); assertTrue(domain.hasPublicSuffix()); - assertEquals("uk", domain.publicSuffix().name()); + assertEquals("uk", domain.publicSuffix().toString()); // Behold the weirdness! assertFalse(domain.publicSuffix().isPublicSuffix()); } public void testMultipleUnders() { - // PSL has both *.uk and *.police.uk; the latter should win. + // PSL has both *.uk and *.sch.uk; the latter should win. // See http://code.google.com/p/guava-libraries/issues/detail?id=1176 - InternetDomainName domain = InternetDomainName.from("www.essex.police.uk"); + InternetDomainName domain = InternetDomainName.from("www.essex.sch.uk"); assertTrue(domain.hasPublicSuffix()); - assertEquals("essex.police.uk", domain.publicSuffix().name()); - assertEquals("www.essex.police.uk", domain.topPrivateDomain().name()); + assertEquals("essex.sch.uk", domain.publicSuffix().toString()); + assertEquals("www.essex.sch.uk", domain.topPrivateDomain().toString()); } public void testEquality() { diff --git a/guava-tests/test/com/google/common/net/MediaTypeTest.java b/guava-tests/test/com/google/common/net/MediaTypeTest.java index 06422cd..12efed6 100644 --- a/guava-tests/test/com/google/common/net/MediaTypeTest.java +++ b/guava-tests/test/com/google/common/net/MediaTypeTest.java @@ -45,13 +45,13 @@ import com.google.common.collect.ImmutableMultimap; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.lang.reflect.Field; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; -import junit.framework.TestCase; - /** * Tests for {@link MediaType}. * diff --git a/guava-tests/test/com/google/common/net/PercentEscaperTest.java b/guava-tests/test/com/google/common/net/PercentEscaperTest.java new file mode 100644 index 0000000..65425d3 --- /dev/null +++ b/guava-tests/test/com/google/common/net/PercentEscaperTest.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.net; + +import static com.google.common.escape.testing.EscaperAsserts.assertEscaping; +import static com.google.common.escape.testing.EscaperAsserts.assertUnescaped; +import static com.google.common.escape.testing.EscaperAsserts.assertUnicodeEscaping; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.base.Preconditions; +import com.google.common.escape.UnicodeEscaper; + +import junit.framework.TestCase; + +/** + * Tests for {@link PercentEscaper}. + * + * @author David Beaumont + */ +@GwtCompatible +public class PercentEscaperTest extends TestCase { + + /** Tests that the simple escaper treats 0-9, a-z and A-Z as safe */ + public void testSimpleEscaper() { + UnicodeEscaper e = new PercentEscaper("", false); + for (char c = 0; c < 128; c++) { + if ((c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z')) { + assertUnescaped(e, c); + } else { + assertEscaping(e, escapeAscii(c), c); + } + } + + // Testing mutlibyte escape sequences + assertEscaping(e, "%00", '\u0000'); // nul + assertEscaping(e, "%7F", '\u007f'); // del + assertEscaping(e, "%C2%80", '\u0080'); // xx-00010,x-000000 + assertEscaping(e, "%DF%BF", '\u07ff'); // xx-11111,x-111111 + assertEscaping(e, "%E0%A0%80", '\u0800'); // xxx-0000,x-100000,x-00,0000 + assertEscaping(e, "%EF%BF%BF", '\uffff'); // xxx-1111,x-111111,x-11,1111 + assertUnicodeEscaping(e, "%F0%90%80%80", '\uD800', '\uDC00'); + assertUnicodeEscaping(e, "%F4%8F%BF%BF", '\uDBFF', '\uDFFF'); + + // simple string tests + assertEquals("", e.escape("")); + assertEquals("safestring", e.escape("safestring")); + assertEquals("embedded%00null", e.escape("embedded\0null")); + assertEquals("max%EF%BF%BFchar", e.escape("max\uffffchar")); + } + + /** Tests the various ways that the space character can be handled */ + public void testPlusForSpace() { + UnicodeEscaper basicEscaper = new PercentEscaper("", false); + UnicodeEscaper plusForSpaceEscaper = new PercentEscaper("", true); + UnicodeEscaper spaceEscaper = new PercentEscaper(" ", false); + + assertEquals("string%20with%20spaces", + basicEscaper.escape("string with spaces")); + assertEquals("string+with+spaces", + plusForSpaceEscaper.escape("string with spaces")); + assertEquals("string with spaces", + spaceEscaper.escape("string with spaces")); + } + + /** Tests that if we add extra 'safe' characters they remain unescaped */ + public void testCustomEscaper() { + UnicodeEscaper e = new PercentEscaper("+*/-", false); + for (char c = 0; c < 128; c++) { + if ((c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + "+*/-".indexOf(c) >= 0) { + assertUnescaped(e, c); + } else { + assertEscaping(e, escapeAscii(c), c); + } + } + } + + /** Tests that if specify '%' as safe the result is an idempotent escaper. */ + public void testCustomEscaper_withpercent() { + UnicodeEscaper e = new PercentEscaper("%", false); + assertEquals("foo%7Cbar", e.escape("foo|bar")); + assertEquals("foo%7Cbar", e.escape("foo%7Cbar")); // idempotent + } + + /** + * Test that giving a null 'safeChars' string causes a + * {@link NullPointerException}. + */ + public void testBadArguments_null() { + try { + new PercentEscaper(null, false); + fail("Expected null pointer exception for null parameter"); + } catch (NullPointerException expected) { + // pass + } + } + + /** + * Tests that specifying any alphanumeric characters as 'safe' causes an + * {@link IllegalArgumentException}. + */ + public void testBadArguments_badchars() { + String msg = "Alphanumeric characters are always 'safe' " + + "and should not be explicitly specified"; + try { + new PercentEscaper("-+#abc.!", false); + fail(msg); + } catch (IllegalArgumentException expected) { + assertEquals(msg, expected.getMessage()); + } + } + + /** + * Tests that if space is a safe character you cannot also specify + * 'plusForSpace' (throws {@link IllegalArgumentException}). + */ + public void testBadArguments_plusforspace() { + try { + new PercentEscaper(" ", false); + } catch (IllegalArgumentException e) { + fail("Space can be a 'safe' character if plusForSpace is false"); + } + String msg = + "plusForSpace cannot be specified when space is a 'safe' character"; + try { + new PercentEscaper(" ", true); + fail(msg); + } catch (IllegalArgumentException expected) { + assertEquals(msg, expected.getMessage()); + } + } + + /** Helper to manually escape a 7-bit ascii character */ + private String escapeAscii(char c) { + Preconditions.checkArgument(c < 128); + String hex = "0123456789ABCDEF"; + return "%" + hex.charAt((c >> 4) & 0xf) + hex.charAt(c & 0xf); + } +} diff --git a/guava-tests/test/com/google/common/net/UrlEscapersTest.java b/guava-tests/test/com/google/common/net/UrlEscapersTest.java new file mode 100644 index 0000000..76a02c6 --- /dev/null +++ b/guava-tests/test/com/google/common/net/UrlEscapersTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.net; + +import static com.google.common.escape.testing.EscaperAsserts.assertEscaping; +import static com.google.common.escape.testing.EscaperAsserts.assertUnescaped; +import static com.google.common.escape.testing.EscaperAsserts.assertUnicodeEscaping; +import static com.google.common.net.UrlEscapers.urlFormParameterEscaper; +import static com.google.common.net.UrlEscapers.urlFragmentEscaper; +import static com.google.common.net.UrlEscapers.urlPathSegmentEscaper; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.escape.UnicodeEscaper; + +import junit.framework.TestCase; + +/** + * Tests for the {@link UrlEscapers} class. + * + * @author David Beaumont + */ +@GwtCompatible +public class UrlEscapersTest extends TestCase { + /** + * Helper to assert common expected behaviour of uri escapers. You should call + * assertBasicUrlEscaper() unless the escaper explicitly does not escape '%'. + */ + static void assertBasicUrlEscaperExceptPercent(UnicodeEscaper e) { + // URL escapers should throw null pointer exceptions for null input + try { + e.escape((String) null); + fail("Escaping null string should throw exception"); + } catch (NullPointerException x) { + // pass + } + + // All URL escapers should leave 0-9, A-Z, a-z unescaped + assertUnescaped(e, 'a'); + assertUnescaped(e, 'z'); + assertUnescaped(e, 'A'); + assertUnescaped(e, 'Z'); + assertUnescaped(e, '0'); + assertUnescaped(e, '9'); + + // Unreserved characters used in java.net.URLEncoder + assertUnescaped(e, '-'); + assertUnescaped(e, '_'); + assertUnescaped(e, '.'); + assertUnescaped(e, '*'); + + assertEscaping(e, "%00", '\u0000'); // nul + assertEscaping(e, "%7F", '\u007f'); // del + assertEscaping(e, "%C2%80", '\u0080'); // xx-00010,x-000000 + assertEscaping(e, "%DF%BF", '\u07ff'); // xx-11111,x-111111 + assertEscaping(e, "%E0%A0%80", '\u0800'); // xxx-0000,x-100000,x-00,0000 + assertEscaping(e, "%EF%BF%BF", '\uffff'); // xxx-1111,x-111111,x-11,1111 + assertUnicodeEscaping(e, "%F0%90%80%80", '\uD800', '\uDC00'); + assertUnicodeEscaping(e, "%F4%8F%BF%BF", '\uDBFF', '\uDFFF'); + + assertEquals("", e.escape("")); + assertEquals("safestring", e.escape("safestring")); + assertEquals("embedded%00null", e.escape("embedded\0null")); + assertEquals("max%EF%BF%BFchar", e.escape("max\uffffchar")); + } + + // Helper to assert common expected behaviour of uri escapers. + static void assertBasicUrlEscaper(UnicodeEscaper e) { + assertBasicUrlEscaperExceptPercent(e); + // The escape character must always be escaped + assertEscaping(e, "%25", '%'); + } + + public void testUrlFormParameterEscaper() { + UnicodeEscaper e = (UnicodeEscaper) urlFormParameterEscaper(); + // Verify that these are the same escaper (as documented) + assertSame(e, urlFormParameterEscaper()); + assertBasicUrlEscaper(e); + + /* + * Specified as safe by RFC 2396 but not by java.net.URLEncoder. These tests will start failing + * when the escaper is made compliant with RFC 2396, but that's a good thing (just change them + * to assertUnescaped). + */ + assertEscaping(e, "%21", '!'); + assertEscaping(e, "%28", '('); + assertEscaping(e, "%29", ')'); + assertEscaping(e, "%7E", '~'); + assertEscaping(e, "%27", '\''); + + // Plus for spaces + assertEscaping(e, "+", ' '); + assertEscaping(e, "%2B", '+'); + + assertEquals("safe+with+spaces", e.escape("safe with spaces")); + assertEquals("foo%40bar.com", e.escape("foo@bar.com")); + } + + public void testUrlPathSegmentEscaper() { + UnicodeEscaper e = (UnicodeEscaper) urlPathSegmentEscaper(); + assertPathEscaper(e); + assertUnescaped(e, '+'); + } + + static void assertPathEscaper(UnicodeEscaper e) { + assertBasicUrlEscaper(e); + + assertUnescaped(e, '!'); + assertUnescaped(e, '\''); + assertUnescaped(e, '('); + assertUnescaped(e, ')'); + assertUnescaped(e, '~'); + assertUnescaped(e, ':'); + assertUnescaped(e, '@'); + + // Don't use plus for spaces + assertEscaping(e, "%20", ' '); + + assertEquals("safe%20with%20spaces", e.escape("safe with spaces")); + assertEquals("foo@bar.com", e.escape("foo@bar.com")); + } + + public void testUrlFragmentEscaper() { + UnicodeEscaper e = (UnicodeEscaper) urlFragmentEscaper(); + assertUnescaped(e, '+'); + assertUnescaped(e, '/'); + assertUnescaped(e, '?'); + + assertPathEscaper(e); + } +} diff --git a/guava-tests/test/com/google/common/primitives/BooleansTest.java b/guava-tests/test/com/google/common/primitives/BooleansTest.java index e7a29b2..e7610ff 100644 --- a/guava-tests/test/com/google/common/primitives/BooleansTest.java +++ b/guava-tests/test/com/google/common/primitives/BooleansTest.java @@ -22,14 +22,14 @@ import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; -import junit.framework.TestCase; - /** * Unit test for {@link Booleans}. * @@ -288,6 +288,14 @@ public class BooleansTest extends TestCase { } } + public void testCountTrue() { + assertEquals(0, Booleans.countTrue()); + assertEquals(0, Booleans.countTrue(false)); + assertEquals(1, Booleans.countTrue(true)); + assertEquals(3, Booleans.countTrue(false, true, false, true, false, true)); + assertEquals(1, Booleans.countTrue(false, false, true, false, false)); + } + @GwtIncompatible("NullPointerTester") public void testNulls() { new NullPointerTester().testAllPublicStaticMethods(Booleans.class); diff --git a/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java index 694e5fb..585c4c8 100644 --- a/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java +++ b/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java @@ -28,12 +28,12 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; -import java.util.List; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.List; + /** * Test suite covering {@link Bytes#asList(byte[])}. * diff --git a/guava-tests/test/com/google/common/primitives/BytesTest.java b/guava-tests/test/com/google/common/primitives/BytesTest.java index 8640f37..e268427 100644 --- a/guava-tests/test/com/google/common/primitives/BytesTest.java +++ b/guava-tests/test/com/google/common/primitives/BytesTest.java @@ -21,13 +21,13 @@ import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; -import junit.framework.TestCase; - /** * Unit test for {@link Bytes}. * diff --git a/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java index 2f27c0d..c2eae49 100644 --- a/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java +++ b/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java @@ -28,12 +28,12 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; -import java.util.List; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.List; + /** * Test suite covering {@link Chars#asList(char[])}. * diff --git a/guava-tests/test/com/google/common/primitives/CharsTest.java b/guava-tests/test/com/google/common/primitives/CharsTest.java index 2fef960..e6d7439 100644 --- a/guava-tests/test/com/google/common/primitives/CharsTest.java +++ b/guava-tests/test/com/google/common/primitives/CharsTest.java @@ -22,14 +22,14 @@ import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; -import junit.framework.TestCase; - /** * Unit test for {@link Chars}. * diff --git a/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java index b7272b0..a20f7f5 100644 --- a/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java +++ b/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java @@ -28,12 +28,12 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; -import java.util.List; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.List; + /** * Test suite covering {@link Doubles#asList(double[])}. * diff --git a/guava-tests/test/com/google/common/primitives/DoublesTest.java b/guava-tests/test/com/google/common/primitives/DoublesTest.java index bc7aa29..9f04471 100644 --- a/guava-tests/test/com/google/common/primitives/DoublesTest.java +++ b/guava-tests/test/com/google/common/primitives/DoublesTest.java @@ -17,12 +17,13 @@ package com.google.common.primitives; import static java.lang.Double.NaN; +import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; +import com.google.common.base.Converter; import com.google.common.collect.ImmutableList; import com.google.common.collect.testing.Helpers; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; @@ -299,6 +300,11 @@ public class DoublesTest extends TestCase { assertSame(comparator, SerializableTester.reserialize(comparator)); } + @GwtIncompatible("SerializableTester") + public void testStringConverterSerialization() { + SerializableTester.reserializeAndAssert(Doubles.stringConverter()); + } + public void testToArray() { // need explicit type parameter to avoid javac warning!? List<Double> none = Arrays.<Double>asList(); @@ -364,7 +370,7 @@ public class DoublesTest extends TestCase { list.set(0, (double) 2); assertTrue(Arrays.equals(new double[] {(double) 2, (double) 1}, array)); array[1] = (double) 3; - FluentAsserts.assertThat(list).has().allOf((double) 2, (double) 3).inOrder(); + ASSERT.that(list).has().exactly((double) 2, (double) 3).inOrder(); } public void testAsList_toArray_roundTrip() { @@ -498,4 +504,45 @@ public class DoublesTest extends TestCase { public void testNulls() { new NullPointerTester().testAllPublicStaticMethods(Doubles.class); } + + public void testStringConverter_convert() { + Converter<String, Double> converter = Doubles.stringConverter(); + assertEquals((Double) 1.0, converter.convert("1.0")); + assertEquals((Double) 0.0, converter.convert("0.0")); + assertEquals((Double) (-1.0), converter.convert("-1.0")); + assertEquals((Double) 1.0, converter.convert("1")); + assertEquals((Double) 0.0, converter.convert("0")); + assertEquals((Double) (-1.0), converter.convert("-1")); + assertEquals((Double) 1e6, converter.convert("1e6")); + assertEquals((Double) 1e-6, converter.convert("1e-6")); + } + + public void testStringConverter_convertError() { + try { + Doubles.stringConverter().convert("notanumber"); + fail(); + } catch (NumberFormatException expected) { + } + } + + public void testStringConverter_nullConversions() { + assertNull(Doubles.stringConverter().convert(null)); + assertNull(Doubles.stringConverter().reverse().convert(null)); + } + + @GwtIncompatible("Double.toString returns different value in GWT.") + public void testStringConverter_reverse() { + Converter<String, Double> converter = Doubles.stringConverter(); + assertEquals("1.0", converter.reverse().convert(1.0)); + assertEquals("0.0", converter.reverse().convert(0.0)); + assertEquals("-1.0", converter.reverse().convert(-1.0)); + assertEquals("1000000.0", converter.reverse().convert(1e6)); + assertEquals("1.0E-6", converter.reverse().convert(1e-6)); + } + + @GwtIncompatible("NullPointerTester") + public void testStringConverter_nullPointerTester() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicInstanceMethods(Doubles.stringConverter()); + } } diff --git a/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java index 836c55b..06dd93b 100644 --- a/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java +++ b/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java @@ -28,12 +28,12 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; -import java.util.List; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.List; + /** * Test suite covering {@link Floats#asList(float[])})}. * diff --git a/guava-tests/test/com/google/common/primitives/FloatsTest.java b/guava-tests/test/com/google/common/primitives/FloatsTest.java index cc5e8c0..2b0c441 100644 --- a/guava-tests/test/com/google/common/primitives/FloatsTest.java +++ b/guava-tests/test/com/google/common/primitives/FloatsTest.java @@ -21,6 +21,7 @@ import static org.truth0.Truth.ASSERT; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; +import com.google.common.base.Converter; import com.google.common.collect.ImmutableList; import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; @@ -290,6 +291,11 @@ public class FloatsTest extends TestCase { assertSame(comparator, SerializableTester.reserialize(comparator)); } + @GwtIncompatible("SerializableTester") + public void testStringConverterSerialization() { + SerializableTester.reserializeAndAssert(Floats.stringConverter()); + } + public void testToArray() { // need explicit type parameter to avoid javac warning!? List<Float> none = Arrays.<Float>asList(); @@ -355,7 +361,7 @@ public class FloatsTest extends TestCase { list.set(0, (float) 2); assertTrue(Arrays.equals(new float[] {(float) 2, (float) 1}, array)); array[1] = (float) 3; - ASSERT.<Float, List<Float>>that(list).has().allOf((float) 2, (float) 3).inOrder(); + ASSERT.that(list).has().exactly((float) 2, (float) 3).inOrder(); } public void testAsList_toArray_roundTrip() { @@ -484,4 +490,46 @@ public class FloatsTest extends TestCase { public void testNulls() { new NullPointerTester().testAllPublicStaticMethods(Floats.class); } + + @GwtIncompatible("Float.toString returns different value in GWT.") + public void testStringConverter_convert() { + Converter<String, Float> converter = Floats.stringConverter(); + assertEquals((Float) 1.0f, converter.convert("1.0")); + assertEquals((Float) 0.0f, converter.convert("0.0")); + assertEquals((Float) (-1.0f), converter.convert("-1.0")); + assertEquals((Float) 1.0f, converter.convert("1")); + assertEquals((Float) 0.0f, converter.convert("0")); + assertEquals((Float) (-1.0f), converter.convert("-1")); + assertEquals((Float) 1e6f, converter.convert("1e6")); + assertEquals((Float) 1e-6f, converter.convert("1e-6")); + } + + public void testStringConverter_convertError() { + try { + Floats.stringConverter().convert("notanumber"); + fail(); + } catch (NumberFormatException expected) { + } + } + + public void testStringConverter_nullConversions() { + assertNull(Floats.stringConverter().convert(null)); + assertNull(Floats.stringConverter().reverse().convert(null)); + } + + @GwtIncompatible("Float.toString returns different value in GWT.") + public void testStringConverter_reverse() { + Converter<String, Float> converter = Floats.stringConverter(); + assertEquals("1.0", converter.reverse().convert(1.0f)); + assertEquals("0.0", converter.reverse().convert(0.0f)); + assertEquals("-1.0", converter.reverse().convert(-1.0f)); + assertEquals("1000000.0", converter.reverse().convert(1e6f)); + assertEquals("1.0E-6", converter.reverse().convert(1e-6f)); + } + + @GwtIncompatible("NullPointerTester") + public void testStringConverter_nullPointerTester() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicInstanceMethods(Floats.stringConverter()); + } } diff --git a/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java index 865241c..efdbbb2 100644 --- a/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java +++ b/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java @@ -28,12 +28,12 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; -import java.util.List; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.List; + /** * Test suite covering {@link Ints#asList(int[])}. * diff --git a/guava-tests/test/com/google/common/primitives/IntsTest.java b/guava-tests/test/com/google/common/primitives/IntsTest.java index 4ca959a..a475739 100644 --- a/guava-tests/test/com/google/common/primitives/IntsTest.java +++ b/guava-tests/test/com/google/common/primitives/IntsTest.java @@ -18,10 +18,13 @@ package com.google.common.primitives; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; +import com.google.common.base.Converter; import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -29,8 +32,6 @@ import java.util.Comparator; import java.util.List; import java.util.Random; -import junit.framework.TestCase; - /** * Unit test for {@link Ints}. * @@ -315,6 +316,11 @@ public class IntsTest extends TestCase { assertSame(comparator, SerializableTester.reserialize(comparator)); } + @GwtIncompatible("SerializableTester") + public void testStringConverterSerialization() { + SerializableTester.reserializeAndAssert(Ints.stringConverter()); + } + public void testToArray() { // need explicit type parameter to avoid javac warning!? List<Integer> none = Arrays.<Integer>asList(); @@ -415,6 +421,48 @@ public class IntsTest extends TestCase { new NullPointerTester().testAllPublicStaticMethods(Ints.class); } + public void testStringConverter_convert() { + Converter<String, Integer> converter = Ints.stringConverter(); + assertEquals((Integer) 1, converter.convert("1")); + assertEquals((Integer) 0, converter.convert("0")); + assertEquals((Integer) (-1), converter.convert("-1")); + assertEquals((Integer) 255, converter.convert("0xff")); + assertEquals((Integer) 255, converter.convert("0xFF")); + assertEquals((Integer) (-255), converter.convert("-0xFF")); + assertEquals((Integer) 255, converter.convert("#0000FF")); + assertEquals((Integer) 438, converter.convert("0666")); + } + + public void testStringConverter_convertError() { + try { + Ints.stringConverter().convert("notanumber"); + fail(); + } catch (NumberFormatException expected) { + } + } + + public void testStringConverter_nullConversions() { + assertNull(Ints.stringConverter().convert(null)); + assertNull(Ints.stringConverter().reverse().convert(null)); + } + + public void testStringConverter_reverse() { + Converter<String, Integer> converter = Ints.stringConverter(); + assertEquals("1", converter.reverse().convert(1)); + assertEquals("0", converter.reverse().convert(0)); + assertEquals("-1", converter.reverse().convert(-1)); + assertEquals("255", converter.reverse().convert(0xff)); + assertEquals("255", converter.reverse().convert(0xFF)); + assertEquals("-255", converter.reverse().convert(-0xFF)); + assertEquals("438", converter.reverse().convert(0666)); + } + + @GwtIncompatible("NullPointerTester") + public void testStringConverter_nullPointerTester() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicInstanceMethods(Ints.stringConverter()); + } + @GwtIncompatible("AndroidInteger") public void testTryParse() { tryParseAndAssertEquals(0, "0"); @@ -433,6 +481,7 @@ public class IntsTest extends TestCase { Ints.tryParse(Long.toString(((long) GREATEST) + 1))); assertNull("Min integer - 1", Ints.tryParse(Long.toString(((long) LEAST) - 1))); + assertNull(Ints.tryParse("\u0662\u06f3")); } /** diff --git a/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java index 4530318..c5049c4 100644 --- a/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java +++ b/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java @@ -28,12 +28,12 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; -import java.util.List; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.List; + /** * Test suite covering {@link Longs#asList(long[])}. * diff --git a/guava-tests/test/com/google/common/primitives/LongsTest.java b/guava-tests/test/com/google/common/primitives/LongsTest.java index 69bcb5a..6f490d7 100644 --- a/guava-tests/test/com/google/common/primitives/LongsTest.java +++ b/guava-tests/test/com/google/common/primitives/LongsTest.java @@ -21,10 +21,13 @@ import static java.lang.Long.MIN_VALUE; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; +import com.google.common.base.Converter; import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.math.BigInteger; import java.util.Arrays; import java.util.Collection; @@ -33,8 +36,6 @@ import java.util.Comparator; import java.util.List; import java.util.Random; -import junit.framework.TestCase; - /** * Unit test for {@link Longs}. * @@ -298,6 +299,11 @@ public class LongsTest extends TestCase { assertSame(comparator, SerializableTester.reserialize(comparator)); } + @GwtIncompatible("SerializableTester") + public void testStringConverterSerialization() { + SerializableTester.reserializeAndAssert(Longs.stringConverter()); + } + public void testToArray() { // need explicit type parameter to avoid javac warning!? List<Long> none = Arrays.<Long>asList(); @@ -398,6 +404,48 @@ public class LongsTest extends TestCase { new NullPointerTester().testAllPublicStaticMethods(Longs.class); } + public void testStringConverter_convert() { + Converter<String, Long> converter = Longs.stringConverter(); + assertEquals((Long) 1L, converter.convert("1")); + assertEquals((Long) 0L, converter.convert("0")); + assertEquals((Long) (-1L), converter.convert("-1")); + assertEquals((Long) 255L, converter.convert("0xff")); + assertEquals((Long) 255L, converter.convert("0xFF")); + assertEquals((Long) (-255L), converter.convert("-0xFF")); + assertEquals((Long) 255L, converter.convert("#0000FF")); + assertEquals((Long) 438L, converter.convert("0666")); + } + + public void testStringConverter_convertError() { + try { + Longs.stringConverter().convert("notanumber"); + fail(); + } catch (NumberFormatException expected) { + } + } + + public void testStringConverter_nullConversions() { + assertNull(Longs.stringConverter().convert(null)); + assertNull(Longs.stringConverter().reverse().convert(null)); + } + + public void testStringConverter_reverse() { + Converter<String, Long> converter = Longs.stringConverter(); + assertEquals("1", converter.reverse().convert(1L)); + assertEquals("0", converter.reverse().convert(0L)); + assertEquals("-1", converter.reverse().convert(-1L)); + assertEquals("255", converter.reverse().convert(0xffL)); + assertEquals("255", converter.reverse().convert(0xFFL)); + assertEquals("-255", converter.reverse().convert(-0xFFL)); + assertEquals("438", converter.reverse().convert(0666L)); + } + + @GwtIncompatible("NullPointerTester") + public void testStringConverter_nullPointerTester() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicInstanceMethods(Longs.stringConverter()); + } + @GwtIncompatible("AndroidInteger") public void testTryParse() { tryParseAndAssertEquals(0L, "0"); @@ -416,6 +464,7 @@ public class LongsTest extends TestCase { Longs.tryParse(BigInteger.valueOf(MAX_VALUE).add(BigInteger.ONE).toString())); assertNull("Min integer - 1", Longs.tryParse(BigInteger.valueOf(MIN_VALUE).subtract(BigInteger.ONE).toString())); + assertNull(Longs.tryParse("\u0662\u06f3")); } /** diff --git a/guava-tests/test/com/google/common/primitives/PrimitivesTest.java b/guava-tests/test/com/google/common/primitives/PrimitivesTest.java index 347de03..b3ef33c 100644 --- a/guava-tests/test/com/google/common/primitives/PrimitivesTest.java +++ b/guava-tests/test/com/google/common/primitives/PrimitivesTest.java @@ -19,10 +19,10 @@ package com.google.common.primitives; import com.google.common.collect.ImmutableSet; import com.google.common.testing.NullPointerTester; -import java.util.Set; - import junit.framework.TestCase; +import java.util.Set; + /** * Unit test for {@link Primitives}. * diff --git a/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java index c06d286..78086e4 100644 --- a/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java +++ b/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java @@ -28,12 +28,12 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.ListFeature; -import java.util.List; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.List; + /** * Test suite covering {@link Shorts#asList(short[])}. * diff --git a/guava-tests/test/com/google/common/primitives/ShortsTest.java b/guava-tests/test/com/google/common/primitives/ShortsTest.java index ad3ca25..f9b9412 100644 --- a/guava-tests/test/com/google/common/primitives/ShortsTest.java +++ b/guava-tests/test/com/google/common/primitives/ShortsTest.java @@ -18,10 +18,13 @@ package com.google.common.primitives; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; +import com.google.common.base.Converter; import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -29,8 +32,6 @@ import java.util.Comparator; import java.util.List; import java.util.Random; -import junit.framework.TestCase; - /** * Unit test for {@link Shorts}. * @@ -322,6 +323,11 @@ public class ShortsTest extends TestCase { assertSame(comparator, SerializableTester.reserialize(comparator)); } + @GwtIncompatible("SerializableTester") + public void testStringConverterSerialization() { + SerializableTester.reserializeAndAssert(Shorts.stringConverter()); + } + public void testToArray() { // need explicit type parameter to avoid javac warning!? List<Short> none = Arrays.<Short>asList(); @@ -421,4 +427,46 @@ public class ShortsTest extends TestCase { public void testNulls() { new NullPointerTester().testAllPublicStaticMethods(Shorts.class); } + + public void testStringConverter_convert() { + Converter<String, Short> converter = Shorts.stringConverter(); + assertEquals((Short) (short) 1, converter.convert("1")); + assertEquals((Short) (short) 0, converter.convert("0")); + assertEquals((Short) (short) (-1), converter.convert("-1")); + assertEquals((Short) (short) 255, converter.convert("0xff")); + assertEquals((Short) (short) 255, converter.convert("0xFF")); + assertEquals((Short) (short) (-255), converter.convert("-0xFF")); + assertEquals((Short) (short) 255, converter.convert("#0000FF")); + assertEquals((Short) (short) 438, converter.convert("0666")); + } + + public void testStringConverter_convertError() { + try { + Shorts.stringConverter().convert("notanumber"); + fail(); + } catch (NumberFormatException expected) { + } + } + + public void testStringConverter_nullConversions() { + assertNull(Shorts.stringConverter().convert(null)); + assertNull(Shorts.stringConverter().reverse().convert(null)); + } + + public void testStringConverter_reverse() { + Converter<String, Short> converter = Shorts.stringConverter(); + assertEquals("1", converter.reverse().convert((short) 1)); + assertEquals("0", converter.reverse().convert((short) 0)); + assertEquals("-1", converter.reverse().convert((short) -1)); + assertEquals("255", converter.reverse().convert((short) 0xff)); + assertEquals("255", converter.reverse().convert((short) 0xFF)); + assertEquals("-255", converter.reverse().convert((short) -0xFF)); + assertEquals("438", converter.reverse().convert((short) 0666)); + } + + @GwtIncompatible("NullPointerTester") + public void testStringConverter_nullPointerTester() throws Exception { + NullPointerTester tester = new NullPointerTester(); + tester.testAllPublicInstanceMethods(Shorts.stringConverter()); + } } diff --git a/guava-tests/test/com/google/common/primitives/SignedBytesTest.java b/guava-tests/test/com/google/common/primitives/SignedBytesTest.java index 5a38bee..8e205fe 100644 --- a/guava-tests/test/com/google/common/primitives/SignedBytesTest.java +++ b/guava-tests/test/com/google/common/primitives/SignedBytesTest.java @@ -22,12 +22,12 @@ import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Comparator; import java.util.List; -import junit.framework.TestCase; - /** * Unit test for {@link SignedBytes}. * diff --git a/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java b/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java index 4faa247..575eb7e 100644 --- a/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java +++ b/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java @@ -20,12 +20,12 @@ import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Comparator; import java.util.List; -import junit.framework.TestCase; - /** * Unit test for {@link UnsignedBytes}. * @@ -226,9 +226,9 @@ public class UnsignedBytesTest extends TestCase { public void testLexicographicalComparatorDefaultChoice() { Comparator<byte[]> defaultComparator = UnsignedBytes.lexicographicalComparator(); - Comparator<byte[]> pureJavaComparator = - UnsignedBytes.LexicographicalComparatorHolder.PureJavaComparator.INSTANCE; - assertSame(defaultComparator, pureJavaComparator); + Comparator<byte[]> unsafeComparator = + UnsignedBytes.LexicographicalComparatorHolder.UnsafeComparator.INSTANCE; + assertSame(defaultComparator, unsafeComparator); } public void testLexicographicalComparator() { @@ -253,6 +253,23 @@ public class UnsignedBytesTest extends TestCase { Helpers.testComparator(javaImpl, ordered); assertSame(javaImpl, SerializableTester.reserialize(javaImpl)); } + + @SuppressWarnings("unchecked") + public void testLexicographicalComparatorLongInputs() { + for (Comparator<byte[]> comparator : Arrays.asList( + UnsignedBytes.lexicographicalComparator(), + UnsignedBytes.lexicographicalComparatorJavaImpl())) { + for (int i = 0; i < 32; i++) { + byte[] left = new byte[32]; + byte[] right = new byte[32]; + + assertTrue(comparator.compare(left, right) == 0); + left[i] = 1; + assertTrue(comparator.compare(left, right) > 0); + assertTrue(comparator.compare(right, left) < 0); + } + } + } public void testNulls() { new NullPointerTester().testAllPublicStaticMethods(UnsignedBytes.class); diff --git a/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java b/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java index 22a26ef..e053f0b 100644 --- a/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java +++ b/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java @@ -21,10 +21,10 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; -import java.math.BigInteger; - import junit.framework.TestCase; +import java.math.BigInteger; + /** * Tests for {@code UnsignedInteger}. * @@ -200,7 +200,8 @@ public class UnsignedIntegerTest extends TestCase { public void testDivideByZeroThrows() { for (int a : TEST_INTS) { try { - UnsignedInteger.fromIntBits(a).divide(UnsignedInteger.ZERO); + UnsignedInteger ignored = + UnsignedInteger.fromIntBits(a).dividedBy(UnsignedInteger.ZERO); fail("Expected ArithmeticException"); } catch (ArithmeticException expected) {} } diff --git a/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java b/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java index 8c76ef6..d1fd13c 100644 --- a/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java +++ b/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java @@ -19,13 +19,13 @@ import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Random; -import junit.framework.TestCase; - /** * Tests for UnsignedInts * diff --git a/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java b/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java index cc7cca4..1df86cb 100644 --- a/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java +++ b/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java @@ -21,10 +21,10 @@ import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; -import java.math.BigInteger; - import junit.framework.TestCase; +import java.math.BigInteger; + /** * Tests for {@code UnsignedLong}. * diff --git a/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java b/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java index cbd7dae..7abee87 100644 --- a/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java +++ b/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java @@ -21,14 +21,14 @@ import com.google.common.annotations.GwtIncompatible; import com.google.common.collect.testing.Helpers; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.math.BigInteger; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Random; -import junit.framework.TestCase; - /** * Tests for UnsignedLongs * @@ -98,10 +98,10 @@ public class UnsignedLongsTest extends TestCase { new long[] {}, new long[] {LEAST}, new long[] {LEAST, LEAST}, - new long[] {LEAST, 1}, - new long[] {1}, - new long[] {1, LEAST}, - new long[] {GREATEST, GREATEST - 1}, + new long[] {LEAST, (long) 1}, + new long[] {(long) 1}, + new long[] {(long) 1, LEAST}, + new long[] {GREATEST, GREATEST - (long) 1}, new long[] {GREATEST, GREATEST}, new long[] {GREATEST, GREATEST, GREATEST}); diff --git a/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java b/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java index 8c19250..b53af57 100644 --- a/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java +++ b/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java @@ -20,13 +20,15 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableList; import com.google.common.testing.EqualsTester; +import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + +import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.List; -import junit.framework.TestCase; - /** * Tests for {@link AbstractInvocationHandler}. * @@ -47,14 +49,29 @@ public class AbstractInvocationHandlerTest extends TestCase { assertEquals(Proxy.getInvocationHandler(proxy).toString(), proxy.toString()); } + interface A {} + interface B{} + public void testEquals() { + class AB implements A, B {} + class BA implements B, A {} + AB ab = new AB(); + BA ba = new BA(); new EqualsTester() .addEqualityGroup(newDelegatingList(LIST1)) // Actually, this violates List#equals contract. // But whatever, no one is going to proxy List (hopefully). .addEqualityGroup(newDelegatingList(LIST1)) .addEqualityGroup(newDelegatingList(LIST2)) - .addEqualityGroup(newDelegatingListWithEquals(LIST1), newDelegatingListWithEquals(LIST1)) + .addEqualityGroup( + newProxyWithEqualsForInterfaces(List.class, Runnable.class), + newProxyWithEqualsForInterfaces(List.class, Runnable.class)) + .addEqualityGroup( + newProxyWithEqualsForInterfaces(Runnable.class, List.class)) + .addEqualityGroup( + newDelegatingListWithEquals(LIST1), + newDelegatingListWithEquals(LIST1), + SerializableTester.reserialize(newDelegatingListWithEquals(LIST1))) .addEqualityGroup( newDelegatingListWithEquals(LIST2), newProxyWithSubHandler1(LIST2), // Makes sure type of handler doesn't affect equality @@ -88,7 +105,14 @@ public class AbstractInvocationHandlerTest extends TestCase { return Reflection.newProxy(List.class, new SubHandler2(delegate)); } - private static class DelegatingInvocationHandler extends AbstractInvocationHandler { + private static Object newProxyWithEqualsForInterfaces( + Class<?>... interfaces) { + return Proxy.newProxyInstance(AbstractInvocationHandlerTest.class.getClassLoader(), + interfaces, new DelegatingInvocationHandlerWithEquals("a string")); + } + + private static class DelegatingInvocationHandler extends AbstractInvocationHandler + implements Serializable { final Object delegate; DelegatingInvocationHandler(Object delegate) { @@ -123,6 +147,10 @@ public class AbstractInvocationHandlerTest extends TestCase { @Override public int hashCode() { return delegate.hashCode(); } + + @Override public String toString() { + return "another arbitrary string"; + } } private static class SubHandler1 extends DelegatingInvocationHandlerWithEquals { diff --git a/guava-tests/test/com/google/common/reflect/ClassPathTest.java b/guava-tests/test/com/google/common/reflect/ClassPathTest.java index ccf7508..bd63635 100644 --- a/guava-tests/test/com/google/common/reflect/ClassPathTest.java +++ b/guava-tests/test/com/google/common/reflect/ClassPathTest.java @@ -20,9 +20,10 @@ import static org.truth0.Truth.ASSERT; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.common.io.Closer; +import com.google.common.io.Resources; import com.google.common.reflect.ClassPath.ClassInfo; import com.google.common.reflect.ClassPath.ResourceInfo; import com.google.common.reflect.subpackage.ClassInSubPackage; @@ -34,16 +35,20 @@ import org.junit.Test; import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; -import java.util.Collection; import java.util.Map; import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; import java.util.jar.Manifest; +import java.util.zip.ZipEntry; /** * Functional tests of {@link ClassPath}. @@ -55,29 +60,58 @@ public class ClassPathTest extends TestCase { Map<String, ResourceInfo> byToString = Maps.newHashMap(); ClassPath classpath = ClassPath.from(getClass().getClassLoader()); for (ResourceInfo resource : classpath.getResources()) { + ASSERT.that(resource.getResourceName()).isNotEqualTo(JarFile.MANIFEST_NAME); + ASSERT.that(resource.toString()).isNotEqualTo(JarFile.MANIFEST_NAME); byName.put(resource.getResourceName(), resource); byToString.put(resource.toString(), resource); // TODO: This will fail on maven resources in the classes directory on a mac. // assertNotNull(resource.url()); } String testResourceName = "com/google/common/reflect/test.txt"; - ASSERT.<String, Collection<String>>that(byName.keySet()).has().allOf( + ASSERT.that(byName.keySet()).has().allOf( "com/google/common/reflect/ClassPath.class", "com/google/common/reflect/ClassPathTest.class", "com/google/common/reflect/ClassPathTest$Nested.class", testResourceName); - assertFalse(byName.keySet().contains("META-INF/MANIFEST.MF")); - ASSERT.<String, Collection<String>>that(byToString.keySet()).has().allOf( + ASSERT.that(byToString.keySet()).has().allOf( "com.google.common.reflect.ClassPath", "com.google.common.reflect.ClassPathTest", - "com/google/common/reflect/ClassPathTest$Nested.class", + "com.google.common.reflect.ClassPathTest$Nested", testResourceName); - assertFalse(byToString.keySet().contains("META-INF/MANIFEST.MF")); assertEquals(getClass().getClassLoader().getResource(testResourceName), byName.get("com/google/common/reflect/test.txt").url()); } - public void testGetClasses() throws Exception { + public void testGetAllClasses() throws Exception { + Set<String> names = Sets.newHashSet(); + Set<String> strings = Sets.newHashSet(); + Set<Class<?>> classes = Sets.newHashSet(); + Set<String> packageNames = Sets.newHashSet(); + Set<String> simpleNames = Sets.newHashSet(); + ClassPath classpath = ClassPath.from(getClass().getClassLoader()); + for (ClassInfo classInfo : classpath.getAllClasses()) { + if (!classInfo.getPackageName().equals(ClassPathTest.class.getPackage().getName())) { + continue; + } + names.add(classInfo.getName()); + strings.add(classInfo.toString()); + classes.add(classInfo.load()); + packageNames.add(classInfo.getPackageName()); + simpleNames.add(classInfo.getSimpleName()); + } + class LocalClass {} + Class<?> anonymousClass = new Object() {}.getClass(); + ASSERT.that(names).has().allOf(anonymousClass.getName(), LocalClass.class.getName(), + ClassPath.class.getName(), ClassPathTest.class.getName()); + ASSERT.that(strings).has().allOf(anonymousClass.getName(), LocalClass.class.getName(), + ClassPath.class.getName(), ClassPathTest.class.getName()); + ASSERT.that(classes).has().allOf(anonymousClass, LocalClass.class, ClassPath.class, + ClassPathTest.class); + ASSERT.that(packageNames).has().exactly(ClassPath.class.getPackage().getName()); + ASSERT.that(simpleNames).has().allOf("", "Local", "ClassPath", "ClassPathTest"); + } + + public void testGetTopLevelClasses() throws Exception { Set<String> names = Sets.newHashSet(); Set<String> strings = Sets.newHashSet(); Set<Class<?>> classes = Sets.newHashSet(); @@ -92,25 +126,28 @@ public class ClassPathTest extends TestCase { packageNames.add(classInfo.getPackageName()); simpleNames.add(classInfo.getSimpleName()); } - ASSERT.<String, Collection<String>>that(names).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName()); - ASSERT.<String, Collection<String>>that(strings).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName()); - ASSERT.<Class<?>, Collection<Class<?>>>that(classes).has().allOf(ClassPath.class, ClassPathTest.class); - ASSERT.<String, Collection<String>>that(packageNames).has().item(ClassPath.class.getPackage().getName()); - ASSERT.<String, Collection<String>>that(simpleNames).has().allOf("ClassPath", "ClassPathTest"); + ASSERT.that(names).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName()); + ASSERT.that(strings).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName()); + ASSERT.that(classes).has().allOf(ClassPath.class, ClassPathTest.class); + ASSERT.that(packageNames).has().item(ClassPath.class.getPackage().getName()); + ASSERT.that(simpleNames).has().allOf("ClassPath", "ClassPathTest"); assertFalse(classes.contains(ClassInSubPackage.class)); } - public void testGetClassesRecursive() throws Exception { + public void testGetTopLevelClassesRecursive() throws Exception { Set<Class<?>> classes = Sets.newHashSet(); ClassPath classpath = ClassPath.from(ClassPathTest.class.getClassLoader()); for (ClassInfo classInfo : classpath.getTopLevelClassesRecursive(ClassPathTest.class.getPackage().getName())) { + if (classInfo.getName().contains("ClassPathTest")) { + System.err.println(""); + } classes.add(classInfo.load()); } - ASSERT.<Class<?>, Collection<Class<?>>>that(classes).has().allOf(ClassPathTest.class, ClassInSubPackage.class); + ASSERT.that(classes).has().allOf(ClassPathTest.class, ClassInSubPackage.class); } - public void testGetClasses_diamond() throws Exception { + public void testGetTopLevelClasses_diamond() throws Exception { ClassLoader parent = ClassPathTest.class.getClassLoader(); ClassLoader sub1 = new ClassLoader(parent) {}; ClassLoader sub2 = new ClassLoader(parent) {}; @@ -131,7 +168,7 @@ public class ClassPathTest extends TestCase { } public void testClassPathEntries_emptyURLClassLoader_noParent() { - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathEntries(new URLClassLoader(new URL[0], null)).keySet()) + ASSERT.that(ClassPath.getClassPathEntries(new URLClassLoader(new URL[0], null)).keySet()) .isEmpty(); } @@ -151,7 +188,7 @@ public class ClassPathTest extends TestCase { URLClassLoader child = new URLClassLoader(new URL[] {url2}, parent) {}; ImmutableMap<URI, ClassLoader> classPathEntries = ClassPath.getClassPathEntries(child); assertEquals(ImmutableMap.of(url1.toURI(), parent, url2.toURI(), child), classPathEntries); - ASSERT.<URI, Collection<URI>>that(classPathEntries.keySet()).has().allOf(url1.toURI(), url2.toURI()).inOrder(); + ASSERT.that(classPathEntries.keySet()).has().exactly(url1.toURI(), url2.toURI()).inOrder(); } public void testClassPathEntries_duplicateUri_parentWins() throws Exception { @@ -162,7 +199,7 @@ public class ClassPathTest extends TestCase { } public void testClassPathEntries_notURLClassLoader_noParent() { - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathEntries(new ClassLoader(null) {}).keySet()).isEmpty(); + ASSERT.that(ClassPath.getClassPathEntries(new ClassLoader(null) {}).keySet()).isEmpty(); } public void testClassPathEntries_notURLClassLoader_withParent() throws Exception { @@ -192,56 +229,69 @@ public class ClassPathTest extends TestCase { ClassPath.getClassPathEntries(new ClassLoader(parent) {})); } - public void testBrowseFromFile_fileNotExists() throws IOException { + public void testScan_classPathCycle() throws IOException { + File jarFile = File.createTempFile("with_circular_class_path", ".jar"); + try { + writeSelfReferencingJarFile(jarFile, "test.txt"); + ClassPath.Scanner scanner = new ClassPath.Scanner(); + scanner.scan(jarFile.toURI(), ClassPathTest.class.getClassLoader()); + assertEquals(1, scanner.getResources().size()); + } finally { + jarFile.delete(); + } + } + + public void testScanFromFile_fileNotExists() throws IOException { ClassLoader classLoader = ClassPathTest.class.getClassLoader(); - ImmutableSet.Builder<ResourceInfo> resources = ImmutableSet.builder(); - ClassPath.browseFrom(new File("no/such/file/anywhere"), classLoader, resources); - ASSERT.<ResourceInfo, Collection<ResourceInfo>>that(resources.build()).isEmpty(); + ClassPath.Scanner scanner = new ClassPath.Scanner(); + scanner.scanFrom(new File("no/such/file/anywhere"), classLoader); + ASSERT.that(scanner.getResources()).isEmpty(); } - public void testBrowseFromFile_notJarFile() throws IOException { + public void testScanFromFile_notJarFile() throws IOException { ClassLoader classLoader = ClassPathTest.class.getClassLoader(); - ImmutableSet.Builder<ResourceInfo> resources = ImmutableSet.builder(); File notJar = File.createTempFile("not_a_jar", "txt"); + ClassPath.Scanner scanner = new ClassPath.Scanner(); try { - ClassPath.browseFrom(notJar, classLoader, resources); + scanner.scanFrom(notJar, classLoader); } finally { notJar.delete(); } - ASSERT.<ResourceInfo, Collection<ResourceInfo>>that(resources.build()).isEmpty(); + ASSERT.that(scanner.getResources()).isEmpty(); } public void testGetClassPathEntry() throws URISyntaxException { assertEquals(URI.create("file:/usr/test/dep.jar"), - ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "file:/usr/test/dep.jar")); + ClassPath.Scanner.getClassPathEntry( + new File("/home/build/outer.jar"), "file:/usr/test/dep.jar")); assertEquals(URI.create("file:/home/build/a.jar"), - ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "a.jar")); + ClassPath.Scanner.getClassPathEntry(new File("/home/build/outer.jar"), "a.jar")); assertEquals(URI.create("file:/home/build/x/y/z"), - ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z")); + ClassPath.Scanner.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z")); assertEquals(URI.create("file:/home/build/x/y/z.jar"), - ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z.jar")); + ClassPath.Scanner.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z.jar")); } public void testGetClassPathFromManifest_nullManifest() { - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(new File("some.jar"), null)).isEmpty(); + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(new File("some.jar"), null)).isEmpty(); } public void testGetClassPathFromManifest_noClassPath() throws IOException { File jarFile = new File("base.jar"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest(""))) + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest(""))) .isEmpty(); } public void testGetClassPathFromManifest_emptyClassPath() throws IOException { File jarFile = new File("base.jar"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifestClasspath(""))) + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifestClasspath(""))) .isEmpty(); } public void testGetClassPathFromManifest_badClassPath() throws IOException { File jarFile = new File("base.jar"); Manifest manifest = manifestClasspath("an_invalid^path"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest)) + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) .isEmpty(); } @@ -249,45 +299,45 @@ public class ClassPathTest extends TestCase { File jarFile = new File("base/some.jar"); // with/relative/directory is the Class-Path value in the mf file. Manifest manifest = manifestClasspath("with/relative/dir"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest)) - .has().allOf(new File("base/with/relative/dir").toURI()).inOrder(); + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) + .has().exactly(new File("base/with/relative/dir").toURI()).inOrder(); } public void testGetClassPathFromManifest_relativeJar() throws IOException { File jarFile = new File("base/some.jar"); // with/relative/directory is the Class-Path value in the mf file. Manifest manifest = manifestClasspath("with/relative.jar"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest)) - .has().allOf(new File("base/with/relative.jar").toURI()).inOrder(); + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) + .has().exactly(new File("base/with/relative.jar").toURI()).inOrder(); } public void testGetClassPathFromManifest_jarInCurrentDirectory() throws IOException { File jarFile = new File("base/some.jar"); // with/relative/directory is the Class-Path value in the mf file. Manifest manifest = manifestClasspath("current.jar"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest)) - .has().allOf(new File("base/current.jar").toURI()).inOrder(); + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) + .has().exactly(new File("base/current.jar").toURI()).inOrder(); } public void testGetClassPathFromManifest_absoluteDirectory() throws IOException { File jarFile = new File("base/some.jar"); Manifest manifest = manifestClasspath("file:/with/absolute/dir"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest)) - .has().allOf(new File("/with/absolute/dir").toURI()).inOrder(); + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) + .has().exactly(new File("/with/absolute/dir").toURI()).inOrder(); } public void testGetClassPathFromManifest_absoluteJar() throws IOException { File jarFile = new File("base/some.jar"); Manifest manifest = manifestClasspath("file:/with/absolute.jar"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest)) - .has().allOf(new File("/with/absolute.jar").toURI()).inOrder(); + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) + .has().exactly(new File("/with/absolute.jar").toURI()).inOrder(); } public void testGetClassPathFromManifest_multiplePaths() throws IOException { File jarFile = new File("base/some.jar"); Manifest manifest = manifestClasspath("file:/with/absolute.jar relative.jar relative/dir"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest)) - .has().allOf( + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) + .has().exactly( new File("/with/absolute.jar").toURI(), new File("base/relative.jar").toURI(), new File("base/relative/dir").toURI()) @@ -297,15 +347,15 @@ public class ClassPathTest extends TestCase { public void testGetClassPathFromManifest_leadingBlanks() throws IOException { File jarFile = new File("base/some.jar"); Manifest manifest = manifestClasspath(" relative.jar"); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest)) - .has().allOf(new File("base/relative.jar").toURI()).inOrder(); + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) + .has().exactly(new File("base/relative.jar").toURI()).inOrder(); } public void testGetClassPathFromManifest_trailingBlanks() throws IOException { File jarFile = new File("base/some.jar"); Manifest manifest = manifestClasspath("relative.jar "); - ASSERT.<URI, Collection<URI>>that(ClassPath.getClassPathFromManifest(jarFile, manifest)) - .has().allOf(new File("base/relative.jar").toURI()).inOrder(); + ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) + .has().exactly(new File("base/relative.jar").toURI()).inOrder(); } public void testGetClassName() { @@ -315,7 +365,7 @@ public class ClassPathTest extends TestCase { public void testResourceInfo_of() { assertEquals(ClassInfo.class, resourceInfo(ClassPathTest.class).getClass()); assertEquals(ClassInfo.class, resourceInfo(ClassPath.class).getClass()); - assertEquals(ResourceInfo.class, resourceInfo(Nested.class).getClass()); + assertEquals(ClassInfo.class, resourceInfo(Nested.class).getClass()); } public void testGetSimpleName() { @@ -323,6 +373,17 @@ public class ClassPathTest extends TestCase { new ClassInfo("Foo.class", getClass().getClassLoader()).getSimpleName()); assertEquals("Foo", new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getSimpleName()); + assertEquals("Foo", + new ClassInfo("a/b/Bar$Foo.class", getClass().getClassLoader()).getSimpleName()); + assertEquals("", + new ClassInfo("a/b/Bar$1.class", getClass().getClassLoader()).getSimpleName()); + assertEquals("Foo", + new ClassInfo("a/b/Bar$Foo.class", getClass().getClassLoader()).getSimpleName()); + assertEquals("", + new ClassInfo("a/b/Bar$1.class", getClass().getClassLoader()).getSimpleName()); + assertEquals("Local", + new ClassInfo("a/b/Bar$1Local.class", getClass().getClassLoader()).getSimpleName()); + } public void testGetPackageName() { @@ -366,6 +427,29 @@ public class ClassPathTest extends TestCase { return manifest("Class-Path: " + classpath + "\n"); } + private static void writeSelfReferencingJarFile(File jarFile, String... entries) + throws IOException { + Manifest manifest = new Manifest(); + // Without version, the manifest is silently ignored. Ugh! + manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); + manifest.getMainAttributes().put(Attributes.Name.CLASS_PATH, jarFile.getName()); + + Closer closer = Closer.create(); + try { + FileOutputStream fileOut = closer.register(new FileOutputStream(jarFile)); + JarOutputStream jarOut = closer.register(new JarOutputStream(fileOut)); + for (String entry : entries) { + jarOut.putNextEntry(new ZipEntry(entry)); + Resources.copy(ClassPathTest.class.getResource(entry), jarOut); + jarOut.closeEntry(); + } + } catch (Throwable e) { + throw closer.rethrow(e); + } finally { + closer.close(); + } + } + private static Manifest manifest(String content) throws IOException { InputStream in = new ByteArrayInputStream(content.getBytes(Charsets.US_ASCII.name())); Manifest manifest = new Manifest(); diff --git a/guava-tests/test/com/google/common/reflect/ElementTest.java b/guava-tests/test/com/google/common/reflect/ElementTest.java index 89790ae..a34693a 100644 --- a/guava-tests/test/com/google/common/reflect/ElementTest.java +++ b/guava-tests/test/com/google/common/reflect/ElementTest.java @@ -19,12 +19,12 @@ package com.google.common.reflect; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Constructor; -import junit.framework.TestCase; - /** * Unit tests of {@link Element}. * diff --git a/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java b/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java index b32042f..d3937da 100644 --- a/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java +++ b/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java @@ -27,14 +27,14 @@ import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + /** * Unit test for {@link ImmutableTypeToInstanceMap}. * @@ -68,7 +68,7 @@ public class ImmutableTypeToInstanceMapTest extends TestCase { MapFeature.RESTRICTS_KEYS, CollectionFeature.KNOWN_ORDER, CollectionSize.ANY, - MapFeature.ALLOWS_NULL_QUERIES) + MapFeature.ALLOWS_ANY_NULL_QUERIES) .createTestSuite()); return suite; @@ -100,7 +100,7 @@ public class ImmutableTypeToInstanceMapTest extends TestCase { assertEquals(ImmutableList.of(1), map.getInstance(type)); } - public void testGenericArrayType() { + public void testGeneriArrayType() { @SuppressWarnings("unchecked") // Trying to test generic array ImmutableList<Integer>[] array = new ImmutableList[] {ImmutableList.of(1)}; TypeToken<ImmutableList<Integer>[]> type = new TypeToken<ImmutableList<Integer>[]>() {}; @@ -109,8 +109,7 @@ public class ImmutableTypeToInstanceMapTest extends TestCase { .put(type, array) .build(); assertEquals(1, map.size()); - ASSERT.<ImmutableList<Integer>, List<ImmutableList<Integer>>> - that(map.getInstance(type)).has().allOf(array[0]).inOrder(); + ASSERT.that(map.getInstance(type)).has().exactly(array[0]).inOrder(); } public void testWildcardType() { diff --git a/guava-tests/test/com/google/common/reflect/InvokableTest.java b/guava-tests/test/com/google/common/reflect/InvokableTest.java index 29f7373..b8875fd 100644 --- a/guava-tests/test/com/google/common/reflect/InvokableTest.java +++ b/guava-tests/test/com/google/common/reflect/InvokableTest.java @@ -21,17 +21,18 @@ import com.google.common.collect.Iterables; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.TypeVariable; import java.util.Collections; import javax.annotation.Nullable; -import junit.framework.TestCase; - /** * Unit tests for {@link Invokable}. * @@ -44,6 +45,26 @@ public class InvokableTest extends TestCase { Prepender.constructor().getReturnType().getType()); } + private static class WithConstructorAndTypeParameter<T> { + @SuppressWarnings("unused") // by reflection + <X> WithConstructorAndTypeParameter() {} + } + + public void testConstructor_returnType_hasTypeParameter() throws Exception { + @SuppressWarnings("rawtypes") // Foo.class for Foo<T> is always raw type + Class<WithConstructorAndTypeParameter> type = WithConstructorAndTypeParameter.class; + @SuppressWarnings("rawtypes") // Foo.class + Constructor<WithConstructorAndTypeParameter> constructor = type.getDeclaredConstructor(); + Invokable<?, ?> factory = Invokable.from(constructor); + assertEquals(2, factory.getTypeParameters().length); + assertEquals(type.getTypeParameters()[0], factory.getTypeParameters()[0]); + assertEquals(constructor.getTypeParameters()[0], factory.getTypeParameters()[1]); + ParameterizedType returnType = (ParameterizedType) factory.getReturnType().getType(); + assertEquals(type, returnType.getRawType()); + assertEquals(ImmutableList.copyOf(type.getTypeParameters()), + ImmutableList.copyOf(returnType.getActualTypeArguments())); + } + public void testConstructor_exceptionTypes() throws Exception { assertEquals(ImmutableList.of(TypeToken.of(NullPointerException.class)), Prepender.constructor(String.class, int.class).getExceptionTypes()); @@ -300,13 +321,13 @@ public class InvokableTest extends TestCase { class NestedInner {} } - public void testInnerClassDefaultConstructor() throws Exception { + public void testInnerClassDefaultConstructor() { Constructor<?> constructor = InnerWithDefaultConstructor.class.getDeclaredConstructors() [0]; assertEquals(0, Invokable.from(constructor).getParameters().size()); } - public void testNestedInnerClassDefaultConstructor() throws Exception { + public void testNestedInnerClassDefaultConstructor() { Constructor<?> constructor = InnerWithDefaultConstructor.NestedInner.class.getDeclaredConstructors() [0]; assertEquals(0, Invokable.from(constructor).getParameters().size()); @@ -317,7 +338,7 @@ public class InvokableTest extends TestCase { public InnerWithOneParameterConstructor(String s) {} } - public void testInnerClassWithOneParameterConstructor() throws Exception { + public void testInnerClassWithOneParameterConstructor() { Constructor<?> constructor = InnerWithOneParameterConstructor.class.getDeclaredConstructors()[0]; Invokable<?, ?> invokable = Invokable.from(constructor); @@ -330,7 +351,7 @@ public class InvokableTest extends TestCase { InnerWithAnnotatedConstructorParameter(@Nullable String s) {} } - public void testInnerClassWithAnnotatedConstructorParameter() throws Exception { + public void testInnerClassWithAnnotatedConstructorParameter() { Constructor<?> constructor = InnerWithAnnotatedConstructorParameter.class.getDeclaredConstructors() [0]; Invokable<?, ?> invokable = Invokable.from(constructor); @@ -343,7 +364,7 @@ public class InvokableTest extends TestCase { InnerWithGenericConstructorParameter(Iterable<String> it, String s) {} } - public void testInnerClassWithGenericConstructorParameter() throws Exception { + public void testInnerClassWithGenericConstructorParameter() { Constructor<?> constructor = InnerWithGenericConstructorParameter.class.getDeclaredConstructors() [0]; Invokable<?, ?> invokable = Invokable.from(constructor); @@ -354,7 +375,7 @@ public class InvokableTest extends TestCase { invokable.getParameters().get(1).getType()); } - public void testAnonymousClassDefaultConstructor() throws Exception { + public void testAnonymousClassDefaultConstructor() { final int i = 1; final String s = "hello world"; Class<?> anonymous = new Runnable() { @@ -362,23 +383,21 @@ public class InvokableTest extends TestCase { System.out.println(s + i); } }.getClass(); - Constructor<?> constructor = - anonymous.getDeclaredConstructors() [0]; + Constructor<?> constructor = anonymous.getDeclaredConstructors() [0]; assertEquals(0, Invokable.from(constructor).getParameters().size()); } - public void testAnonymousClassWithTwoParametersConstructor() throws Exception { + public void testAnonymousClassWithTwoParametersConstructor() { abstract class Base { @SuppressWarnings("unused") // called by reflection Base(String s, int i) {} } Class<?> anonymous = new Base("test", 0) {}.getClass(); - Constructor<?> constructor = - anonymous.getDeclaredConstructors() [0]; + Constructor<?> constructor = anonymous.getDeclaredConstructors() [0]; assertEquals(2, Invokable.from(constructor).getParameters().size()); } - public void testLocalClassDefaultConstructor() throws Exception { + public void testLocalClassDefaultConstructor() { final int i = 1; final String s = "hello world"; class LocalWithDefaultConstructor implements Runnable { @@ -386,8 +405,7 @@ public class InvokableTest extends TestCase { System.out.println(s + i); } } - Constructor<?> constructor = - LocalWithDefaultConstructor.class.getDeclaredConstructors() [0]; + Constructor<?> constructor = LocalWithDefaultConstructor.class.getDeclaredConstructors() [0]; assertEquals(0, Invokable.from(constructor).getParameters().size()); } @@ -395,7 +413,7 @@ public class InvokableTest extends TestCase { doTestStaticAnonymousClassDefaultConstructor(); } - private static void doTestStaticAnonymousClassDefaultConstructor() throws Exception { + private static void doTestStaticAnonymousClassDefaultConstructor() { final int i = 1; final String s = "hello world"; Class<?> anonymous = new Runnable() { @@ -403,11 +421,72 @@ public class InvokableTest extends TestCase { System.out.println(s + i); } }.getClass(); - Constructor<?> constructor = - anonymous.getDeclaredConstructors() [0]; + Constructor<?> constructor = anonymous.getDeclaredConstructors() [0]; assertEquals(0, Invokable.from(constructor).getParameters().size()); } + public void testAnonymousClassInConstructor() { + new AnonymousClassInConstructor(); + } + + private static class AnonymousClassInConstructor { + AnonymousClassInConstructor() { + final int i = 1; + final String s = "hello world"; + Class<?> anonymous = new Runnable() { + @Override public void run() { + System.out.println(s + i); + } + }.getClass(); + Constructor<?> constructor = anonymous.getDeclaredConstructors() [0]; + assertEquals(0, Invokable.from(constructor).getParameters().size()); + } + } + + public void testLocalClassInInstanceInitializer() { + new LocalClassInInstanceInitializer(); + } + + private static class LocalClassInInstanceInitializer { + { + class Local {} + Constructor<?> constructor = Local.class.getDeclaredConstructors() [0]; + assertEquals(0, Invokable.from(constructor).getParameters().size()); + } + } + + public void testLocalClassInStaticInitializer() { + new LocalClassInStaticInitializer(); + } + + private static class LocalClassInStaticInitializer { + static { + class Local {} + Constructor<?> constructor = Local.class.getDeclaredConstructors() [0]; + assertEquals(0, Invokable.from(constructor).getParameters().size()); + } + } + + public void testLocalClassWithSeeminglyHiddenThisInStaticInitializer_BUG() { + new LocalClassWithSeeminglyHiddenThisInStaticInitializer(); + } + + /** + * This class demonstrates a bug in getParameters() when the local class is inside static + * initializer. + */ + private static class LocalClassWithSeeminglyHiddenThisInStaticInitializer { + static { + class Local { + @SuppressWarnings("unused") // through reflection + Local(LocalClassWithSeeminglyHiddenThisInStaticInitializer outer) {} + } + Constructor<?> constructor = Local.class.getDeclaredConstructors() [0]; + int miscalculated = 0; + assertEquals(miscalculated, Invokable.from(constructor).getParameters().size()); + } + } + public void testLocalClassWithOneParameterConstructor() throws Exception { final int i = 1; final String s = "hello world"; diff --git a/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java b/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java index 7b44ee8..f2bd5b0 100644 --- a/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java +++ b/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java @@ -21,20 +21,20 @@ import static org.truth0.Truth.ASSERT; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.testing.MapTestSuiteBuilder; +import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; import com.google.common.collect.testing.testers.MapPutTester; import com.google.common.reflect.ImmutableTypeToInstanceMapTest.TestTypeToInstanceMapGenerator; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Map.Entry; + /** * Unit test of {@link MutableTypeToInstanceMap}. * @@ -77,8 +77,9 @@ public class MutableTypeToInstanceMapTest extends TestCase { MapFeature.SUPPORTS_REMOVE, MapFeature.RESTRICTS_KEYS, MapFeature.ALLOWS_NULL_VALUES, + CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionSize.ANY, - MapFeature.ALLOWS_NULL_QUERIES) + MapFeature.ALLOWS_ANY_NULL_QUERIES) .suppressing(remapTest) .createTestSuite()); @@ -105,6 +106,40 @@ public class MutableTypeToInstanceMapTest extends TestCase { } catch (UnsupportedOperationException expected) {} } + public void testEntrySetMutationThrows() { + map.putInstance(String.class, "test"); + assertEquals(TypeToken.of(String.class), map.entrySet().iterator().next().getKey()); + assertEquals("test", map.entrySet().iterator().next().getValue()); + try { + map.entrySet().iterator().next().setValue(1); + fail(); + } catch (UnsupportedOperationException expected) {} + } + + public void testEntrySetToArrayMutationThrows() { + map.putInstance(String.class, "test"); + @SuppressWarnings("unchecked") // Should get a CCE later if cast is wrong + Entry<Object, Object> entry = (Entry<Object, Object>) map.entrySet().toArray()[0]; + assertEquals(TypeToken.of(String.class), entry.getKey()); + assertEquals("test", entry.getValue()); + try { + entry.setValue(1); + fail(); + } catch (UnsupportedOperationException expected) {} + } + + public void testEntrySetToTypedArrayMutationThrows() { + map.putInstance(String.class, "test"); + @SuppressWarnings("unchecked") // Should get a CCE later if cast is wrong + Entry<Object, Object> entry = map.entrySet().toArray(new Entry[0])[0]; + assertEquals(TypeToken.of(String.class), entry.getKey()); + assertEquals("test", entry.getValue()); + try { + entry.setValue(1); + fail(); + } catch (UnsupportedOperationException expected) {} + } + public void testPutAndGetInstance() { assertNull(map.putInstance(Integer.class, new Integer(5))); @@ -165,8 +200,7 @@ public class MutableTypeToInstanceMapTest extends TestCase { TypeToken<ImmutableList<Integer>[]> type = new TypeToken<ImmutableList<Integer>[]>() {}; map.putInstance(type, array); assertEquals(1, map.size()); - ASSERT.<ImmutableList<Integer>, List<ImmutableList<Integer>>> - that(map.getInstance(type)).has().allOf(array[0]).inOrder(); + ASSERT.that(map.getInstance(type)).has().exactly(array[0]).inOrder(); } public void testWildcardType() { diff --git a/guava-tests/test/com/google/common/reflect/ParameterTest.java b/guava-tests/test/com/google/common/reflect/ParameterTest.java index cba38d9..88d04b7 100644 --- a/guava-tests/test/com/google/common/reflect/ParameterTest.java +++ b/guava-tests/test/com/google/common/reflect/ParameterTest.java @@ -19,10 +19,10 @@ package com.google.common.reflect; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; -import java.lang.reflect.Method; - import junit.framework.TestCase; +import java.lang.reflect.Method; + /** * Tests for {@link Parameter}. * diff --git a/guava-tests/test/com/google/common/reflect/ReflectionTest.java b/guava-tests/test/com/google/common/reflect/ReflectionTest.java index 8056c3e..2923b47 100644 --- a/guava-tests/test/com/google/common/reflect/ReflectionTest.java +++ b/guava-tests/test/com/google/common/reflect/ReflectionTest.java @@ -18,12 +18,12 @@ package com.google.common.reflect; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Map; -import junit.framework.TestCase; - /** Tests for {@link Reflection} */ public class ReflectionTest extends TestCase { diff --git a/guava-tests/test/com/google/common/reflect/TypeParameterTest.java b/guava-tests/test/com/google/common/reflect/TypeParameterTest.java index 3800aef..9ac8a4a 100644 --- a/guava-tests/test/com/google/common/reflect/TypeParameterTest.java +++ b/guava-tests/test/com/google/common/reflect/TypeParameterTest.java @@ -24,8 +24,6 @@ import junit.framework.TestCase; import java.lang.reflect.Method; import java.lang.reflect.TypeVariable; -import junit.framework.TestCase; - /** * Unit test for {@link TypeParameter}. * diff --git a/guava-tests/test/com/google/common/reflect/TypeResolverTest.java b/guava-tests/test/com/google/common/reflect/TypeResolverTest.java index 2925d39..84b1b5e 100644 --- a/guava-tests/test/com/google/common/reflect/TypeResolverTest.java +++ b/guava-tests/test/com/google/common/reflect/TypeResolverTest.java @@ -16,13 +16,13 @@ package com.google.common.reflect; +import junit.framework.TestCase; + import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; -import junit.framework.TestCase; - /** * Unit tests of {@link TypeResolver}. * diff --git a/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java b/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java index 6c00fb1..2c7e050 100644 --- a/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java +++ b/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java @@ -21,6 +21,8 @@ import static org.truth0.Truth.ASSERT; import com.google.common.base.Predicate; import com.google.common.base.Supplier; +import junit.framework.TestCase; + import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -30,8 +32,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import junit.framework.TestCase; - /** * Unit test for {@link TypeToken} and {@link TypeResolver}. * @@ -124,7 +124,7 @@ public class TypeTokenResolutionTest extends TestCase { parameterized.parameterizedType()); assertEquals(TypeTokenResolutionTest.class, resolved.getOwnerType()); assertEquals(Bar.class, resolved.getRawType()); - ASSERT.<Type, List<Type>>that(resolved.getActualTypeArguments()).has().item(String.class); + ASSERT.that(resolved.getActualTypeArguments()).has().item(String.class); } private interface StringListPredicate extends Predicate<List<String>> {} @@ -544,4 +544,20 @@ public class TypeTokenResolutionTest extends TestCase { throw new RuntimeException(e); } } + + public void testTwoStageResolution() { + class ForTwoStageResolution<A extends Number> { + <B extends A> void verifyTwoStageResolution() { + @SuppressWarnings({"unchecked", "rawtypes"}) + Type type = new TypeToken<B>(getClass()) {} + // B's bound may have already resolved to something. + // Make sure it can still further resolve when given a context. + .where(new TypeParameter<B>() {}, (Class) Integer.class) + .getType(); + assertEquals(Integer.class, type); + } + } + new ForTwoStageResolution<Integer>().verifyTwoStageResolution(); + new ForTwoStageResolution<Integer>() {}.verifyTwoStageResolution(); + } } diff --git a/guava-tests/test/com/google/common/reflect/TypeTokenTest.java b/guava-tests/test/com/google/common/reflect/TypeTokenTest.java index e86b35b..a4a869c 100644 --- a/guava-tests/test/com/google/common/reflect/TypeTokenTest.java +++ b/guava-tests/test/com/google/common/reflect/TypeTokenTest.java @@ -23,11 +23,15 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; +import com.google.common.primitives.Primitives; import com.google.common.testing.EqualsTester; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + +import org.truth0.subjects.CollectionSubject; + import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.GenericArrayType; @@ -36,13 +40,10 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; -import junit.framework.TestCase; - -import org.truth0.subjects.CollectionSubject; - /** * Test cases for {@link TypeToken}. * @@ -78,6 +79,7 @@ public class TypeTokenTest extends TestCase { assertEquals(StringList.class.getGenericInterfaces()[0], token.getType()); } + @SuppressWarnings("rawtypes") // Trying to test TypeToken.of(List.class) public void testGetClass() { TypeToken<List> token = TypeToken.of(List.class); assertEquals(new TypeToken<List>() {}, token); @@ -159,39 +161,39 @@ public class TypeTokenTest extends TestCase { public void testGetTypes_noSuperclass() { TypeToken<Object>.TypeSet types = new TypeToken<Object>() {}.getTypes(); - assertThat(types).has().item(TypeToken.of(Object.class)); - assertThat(types.rawTypes()).has().item(Object.class); - assertThat(types.interfaces()).isEmpty(); - assertThat(types.interfaces().rawTypes()).isEmpty(); - assertThat(types.classes()).has().item(TypeToken.of(Object.class)); - assertThat(types.classes().rawTypes()).has().item(Object.class); + ASSERT.that(types).has().item(TypeToken.of(Object.class)); + ASSERT.that(types.rawTypes()).has().item(Object.class); + ASSERT.that(types.interfaces()).isEmpty(); + ASSERT.that(types.interfaces().rawTypes()).isEmpty(); + ASSERT.that(types.classes()).has().item(TypeToken.of(Object.class)); + ASSERT.that(types.classes().rawTypes()).has().item(Object.class); } public void testGetTypes_fromInterface() { TypeToken<Interface1>.TypeSet types = new TypeToken<Interface1>() {}.getTypes(); - assertThat(types).has().item(TypeToken.of(Interface1.class)); - assertThat(types.rawTypes()).has().item(Interface1.class); - assertThat(types.interfaces()).has().item(TypeToken.of(Interface1.class)); - assertThat(types.interfaces().rawTypes()).has().item(Interface1.class); - assertThat(types.classes()).isEmpty(); - assertThat(types.classes().rawTypes()).isEmpty(); + ASSERT.that(types).has().item(TypeToken.of(Interface1.class)); + ASSERT.that(types.rawTypes()).has().item(Interface1.class); + ASSERT.that(types.interfaces()).has().item(TypeToken.of(Interface1.class)); + ASSERT.that(types.interfaces().rawTypes()).has().item(Interface1.class); + ASSERT.that(types.classes()).isEmpty(); + ASSERT.that(types.classes().rawTypes()).isEmpty(); } public void testGetTypes_fromPrimitive() { TypeToken<Integer>.TypeSet types = TypeToken.of(int.class).getTypes(); - assertThat(types).has().item(TypeToken.of(int.class)); - assertThat(types.rawTypes()).has().item(int.class); - assertThat(types.interfaces()).isEmpty(); - assertThat(types.interfaces().rawTypes()).isEmpty(); - assertThat(types.classes()).has().item(TypeToken.of(int.class)); - assertThat(types.classes().rawTypes()).has().item(int.class); + ASSERT.that(types).has().item(TypeToken.of(int.class)); + ASSERT.that(types.rawTypes()).has().item(int.class); + ASSERT.that(types.interfaces()).isEmpty(); + ASSERT.that(types.interfaces().rawTypes()).isEmpty(); + ASSERT.that(types.classes()).has().item(TypeToken.of(int.class)); + ASSERT.that(types.classes().rawTypes()).has().item(int.class); } public void testGetTypes_withInterfacesAndSuperclasses() { abstract class Class2 extends Class1 implements Interface12 {} abstract class Class3<T> extends Class2 implements Interface3<T> {} TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes(); - assertThat(types).has().allOf( + assertThat(types).has().exactly( new TypeToken<Class3<String>>() {}, new TypeToken<Interface3<String>>() {}, new TypeToken<Iterable<String>>() {}, @@ -201,13 +203,13 @@ public class TypeTokenTest extends TestCase { TypeToken.of(Interface2.class), TypeToken.of(Class1.class), TypeToken.of(Object.class)); - assertThat(types.interfaces()).has().allOf( + assertThat(types.interfaces()).has().exactly( new TypeToken<Interface3<String>>() {}, TypeToken.of(Interface12.class), TypeToken.of(Interface1.class), TypeToken.of(Interface2.class), new TypeToken<Iterable<String>>() {}); - assertThat(types.classes()).has().allOf( + assertThat(types.classes()).has().exactly( new TypeToken<Class3<String>>() {}, TypeToken.of(Class2.class), TypeToken.of(Class1.class), @@ -219,7 +221,7 @@ public class TypeTokenTest extends TestCase { abstract class Class2 extends Class1 implements Interface12 {} abstract class Class3<T> extends Class2 implements Interface3<T> {} TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes(); - assertThat(types.rawTypes()).has().allOf( + assertThat(types.rawTypes()).has().exactly( Class3.class, Interface3.class, Iterable.class, Class2.class, @@ -228,13 +230,13 @@ public class TypeTokenTest extends TestCase { Interface2.class, Class1.class, Object.class); - assertThat(types.interfaces().rawTypes()).has().allOf( + assertThat(types.interfaces().rawTypes()).has().exactly( Interface3.class, Interface12.class, Interface1.class, Interface2.class, Iterable.class); - assertThat(types.classes().rawTypes()).has().allOf( + assertThat(types.classes().rawTypes()).has().exactly( Class3.class, Class2.class, Class1.class, @@ -242,11 +244,39 @@ public class TypeTokenTest extends TestCase { assertSubtypeFirst(types); } + public <A extends Class1 & Interface1, B extends A> + void testGetTypes_ignoresTypeVariablesByDefault() { + TypeToken<?>.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes(); + assertThat(types).has().exactly( + TypeToken.of(Interface1.class), TypeToken.of(Class1.class), + TypeToken.of(Object.class)); + assertSubtypeFirst(types); + assertThat(types.interfaces()) + .has().exactly(TypeToken.of(Interface1.class)) + .inOrder(); + assertThat(types.classes()) + .has().exactly(TypeToken.of(Class1.class), TypeToken.of(Object.class)) + .inOrder(); + } + + public <A extends Class1 & Interface1, B extends A> + void testGetTypes_rawTypes_ignoresTypeVariablesByDefault() { + TypeToken<?>.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes(); + assertThat(types.rawTypes()) + .has().exactly(Interface1.class, Class1.class, Object.class); + assertThat(types.interfaces().rawTypes()) + .has().exactly(Interface1.class) + .inOrder(); + assertThat(types.classes().rawTypes()) + .has().exactly(Class1.class, Object.class) + .inOrder(); + } + public <A extends Interface1 & Interface2 & Interface3<String>> void testGetTypes_manyBounds() { - TypeToken.TypeSet types = TypeToken.of(new TypeCapture<A>() {}.capture()).getTypes(); - assertThat(types.rawTypes()).has().allOf( - Interface1.class, Interface2.class, Interface3.class, Iterable.class); + TypeToken<?>.TypeSet types = TypeToken.of(new TypeCapture<A>() {}.capture()).getTypes(); + assertThat(types.rawTypes()) + .has().exactly(Interface1.class, Interface2.class, Interface3.class, Iterable.class); } private static void assertSubtypeFirst(TypeToken<?>.TypeSet types) { @@ -436,76 +466,75 @@ public class TypeTokenTest extends TestCase { } public <T> void testGetGenericInterfaces_typeVariable_unbounded() { - assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()) - .isEmpty(); + ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()).isEmpty(); assertHasArrayInterfaces(new TypeToken<T[]>() {}); } public <T extends NoInterface> void testGetGenericInterfaces_typeVariable_boundIsClass() { - assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()) - .isEmpty(); + ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()).isEmpty(); assertHasArrayInterfaces(new TypeToken<T[]>() {}); } public <T extends NoInterface&Iterable<String>> void testGetGenericInterfaces_typeVariable_boundsAreClassWithInterface() { assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()) - .iteratesOverSequence(new TypeToken<Iterable<String>>() {}); + .has().exactly(new TypeToken<Iterable<String>>() {}); + assertHasArrayInterfaces(new TypeToken<T[]>() {}); + } + + public <T extends CharSequence&Iterable<String>> + void testGetGenericInterfaces_typeVariable_boundsAreInterfaces() { + assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()) + .has().exactly(TypeToken.of(CharSequence.class), new TypeToken<Iterable<String>>() {}); assertHasArrayInterfaces(new TypeToken<T[]>() {}); } public <T extends CharSequence&Iterable<T>> void testGetGenericInterfaces_typeVariable_boundsAreFBoundedInterfaces() { assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()) - .iteratesOverSequence(TypeToken.of(CharSequence.class), new TypeToken<Iterable<T>>() {}); + .has().exactly(TypeToken.of(CharSequence.class), new TypeToken<Iterable<T>>() {}); assertHasArrayInterfaces(new TypeToken<T[]>() {}); } public <T extends Base&Iterable<T>> void testGetGenericInterfaces_typeVariable_boundsAreClassWithFBoundedInterface() { assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()) - .iteratesOverSequence(new TypeToken<Iterable<T>>() {}); + .has().exactly(new TypeToken<Iterable<T>>() {}); assertHasArrayInterfaces(new TypeToken<T[]>() {}); } public <T extends NoInterface, T1 extends T, T2 extends T1> void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndClass() { - assertThat(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces()) - .isEmpty(); + ASSERT.that(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces()).isEmpty(); assertHasArrayInterfaces(new TypeToken<T2[]>() {}); } public <T extends Iterable<T>, T1 extends T, T2 extends T1> void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndInterface() { assertThat(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces()) - .iteratesOverSequence(TypeToken.of(new TypeCapture<T1>() {}.capture())); + .has().exactly(TypeToken.of(new TypeCapture<T1>() {}.capture())); assertHasArrayInterfaces(new TypeToken<T2[]>() {}); } public void testGetGenericInterfaces_wildcard_lowerBounded() { - assertThat(TypeToken.of(Types.supertypeOf(String.class)).getGenericInterfaces()) - .isEmpty(); - assertThat(TypeToken.of(Types.supertypeOf(String[].class)).getGenericInterfaces()) - .isEmpty(); + ASSERT.that(TypeToken.of(Types.supertypeOf(String.class)).getGenericInterfaces()).isEmpty(); + ASSERT.that(TypeToken.of(Types.supertypeOf(String[].class)).getGenericInterfaces()).isEmpty(); } public void testGetGenericInterfaces_wildcard_boundIsClass() { - assertThat(TypeToken.of(Types.subtypeOf(Object.class)).getGenericInterfaces()) - .isEmpty(); - assertThat(TypeToken.of(Types.subtypeOf(Object[].class)).getGenericInterfaces()) - .isEmpty(); + ASSERT.that(TypeToken.of(Types.subtypeOf(Object.class)).getGenericInterfaces()).isEmpty(); + ASSERT.that(TypeToken.of(Types.subtypeOf(Object[].class)).getGenericInterfaces()).isEmpty(); } public void testGetGenericInterfaces_wildcard_boundIsInterface() { TypeToken<Iterable<String>> interfaceType = new TypeToken<Iterable<String>>() {}; assertThat(TypeToken.of(Types.subtypeOf(interfaceType.getType())).getGenericInterfaces()) - .iteratesOverSequence(interfaceType); + .has().exactly(interfaceType); assertHasArrayInterfaces(new TypeToken<Iterable<String>[]>() {}); } public void testGetGenericInterfaces_noInterface() { - assertThat(new TypeToken<NoInterface>() {}.getGenericInterfaces()) - .isEmpty(); + ASSERT.that(new TypeToken<NoInterface>() {}.getGenericInterfaces()).isEmpty(); assertHasArrayInterfaces(new TypeToken<NoInterface[]>() {}); } @@ -545,6 +574,7 @@ public class TypeTokenTest extends TestCase { private static class ConcreteSI extends Fourth<String, Integer> {} public void testAssignableClassToClass() { + @SuppressWarnings("rawtypes") // To test TypeToken<List> TypeToken<List> tokL = new TypeToken<List>() {}; assertTrue(tokL.isAssignableFrom(List.class)); assertTrue(tokL.isAssignableFrom(ArrayList.class)); @@ -612,26 +642,31 @@ public class TypeTokenTest extends TestCase { } public void testAssignableParameterizedTypeToClass() { + @SuppressWarnings("rawtypes") // Trying to test raw class TypeToken<List> tokL = new TypeToken<List>() {}; assertTrue(tokL.isAssignableFrom(StringList.class)); assertTrue(tokL.isAssignableFrom( StringList.class.getGenericInterfaces()[0])); + @SuppressWarnings("rawtypes") // Trying to test raw class TypeToken<Second> tokS = new TypeToken<Second>() {}; assertTrue(tokS.isAssignableFrom(Second.class)); assertTrue(tokS.isAssignableFrom(Third.class.getGenericSuperclass())); } public void testAssignableArrayToClass() throws Exception { + @SuppressWarnings("rawtypes") // Trying to test raw class TypeToken<List[]> tokL = new TypeToken<List[]>() {}; assertTrue(tokL.isAssignableFrom(List[].class)); assertFalse(tokL.isAssignableFrom(List.class)); + @SuppressWarnings("rawtypes") // Trying to test raw class TypeToken<Second[]> tokS = new TypeToken<Second[]>() {}; assertTrue(tokS.isAssignableFrom(Second[].class)); assertTrue(tokS.isAssignableFrom(Third[].class)); } + @SuppressWarnings("rawtypes") // Trying to test raw class public void testAssignableTokenToClass() { TypeToken<List> tokL = new TypeToken<List>() {}; assertTrue(tokL.isAssignableFrom(new TypeToken<List>() {})); @@ -881,6 +916,20 @@ public class TypeTokenTest extends TestCase { assertFalse(TypeToken.of(Types.supertypeOf(Object[].class)).isArray()); } + public <T extends Integer> void testPrimitiveWrappingAndUnwrapping() { + for (Class<?> type : Primitives.allPrimitiveTypes()) { + assertIsPrimitive(TypeToken.of(type)); + } + for (Class<?> type : Primitives.allWrapperTypes()) { + assertIsWrapper(TypeToken.of(type)); + } + assertNotPrimitiveNorWrapper(TypeToken.of(String.class)); + assertNotPrimitiveNorWrapper(TypeToken.of(Object[].class)); + assertNotPrimitiveNorWrapper(TypeToken.of(Types.subtypeOf(Object.class))); + assertNotPrimitiveNorWrapper(new TypeToken<List<String>>() {}); + assertNotPrimitiveNorWrapper(TypeToken.of(new TypeCapture<T>() {}.capture())); + } + public void testGetComponentType_arrayClasses() { assertEquals(Object.class, TypeToken.of(Object[].class).getComponentType().getType()); assertEquals(Object[].class, TypeToken.of(Object[][].class).getComponentType().getType()); @@ -936,6 +985,7 @@ public class TypeTokenTest extends TestCase { public void testToGenericType() { assertEquals(TypeToken.of(String.class), TypeToken.toGenericType(String.class)); assertEquals(new TypeToken<int[]>() {}, TypeToken.toGenericType(int[].class)); + @SuppressWarnings("rawtypes") // Iterable.class TypeToken<? extends Iterable> genericType = TypeToken.toGenericType(Iterable.class); assertEquals(Iterable.class, genericType.getRawType()); assertEquals(Types.newParameterizedType(Iterable.class, Iterable.class.getTypeParameters()[0]), @@ -1001,7 +1051,7 @@ public class TypeTokenTest extends TestCase { new TypeToken<List>() {}.getSupertype(Iterable.class).getType()); } - @SuppressWarnings("rawtypes") // purpose is to test raw type + @SuppressWarnings({"rawtypes", "unchecked"}) // purpose is to test raw type public void testGetSupertype_notSupertype() { try { new TypeToken<List<String>>() {}.getSupertype((Class) String.class); @@ -1154,7 +1204,7 @@ public class TypeTokenTest extends TestCase { TypeToken<?> matrixType = type.resolveType( Holder.class.getDeclaredField("matrix").getGenericType()); assertEquals(List[].class, matrixType.getRawType()); - FluentAsserts.assertThat(matrixType.getType()) + ASSERT.that(matrixType.getType()) .isNotEqualTo(new TypeToken<List<?>[]>() {}.getType()); } @@ -1191,10 +1241,10 @@ public class TypeTokenTest extends TestCase { public <T extends Number & List<String>> void testMethod_returnType_resolvedAgainstTypeBound() throws NoSuchMethodException { Method getMethod = List.class.getMethod("get", int.class); - Invokable<T, String> Invokable = new TypeToken<T>(getClass()) {} + Invokable<T, String> invokable = new TypeToken<T>(getClass()) {} .method(getMethod) .returning(String.class); - assertEquals(TypeToken.of(String.class), Invokable.getReturnType()); + assertEquals(TypeToken.of(String.class), invokable.getReturnType()); } public <T extends List<String>> void testMethod_parameterTypes() @@ -1207,6 +1257,19 @@ public class TypeTokenTest extends TestCase { assertEquals(TypeToken.of(String.class), params.get(1).getType()); } + public void testMethod_equals() throws NoSuchMethodException { + Method getMethod = List.class.getMethod("get", int.class); + Method setMethod = List.class.getMethod("set", int.class, Object.class); + new EqualsTester() + .addEqualityGroup(Invokable.from(getMethod), Invokable.from(getMethod)) + .addEqualityGroup(Invokable.from(setMethod)) + .addEqualityGroup(new TypeToken<List<Integer>>() {}.method(getMethod)) + .addEqualityGroup(new TypeToken<List<String>>() {}.method(getMethod)) + .addEqualityGroup(new TypeToken<List<Integer>>() {}.method(setMethod)) + .addEqualityGroup(new TypeToken<List<String>>() {}.method(setMethod)) + .testEquals(); + } + private interface Loser<E extends Throwable> { void lose() throws E; } @@ -1215,7 +1278,7 @@ public class TypeTokenTest extends TestCase { throws NoSuchMethodException { Method failMethod = Loser.class.getMethod("lose"); Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.method(failMethod); - assertThat(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class)); + ASSERT.that(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class)); } public void testConstructor_getOwnerType() throws NoSuchMethodException { @@ -1243,6 +1306,19 @@ public class TypeTokenTest extends TestCase { } catch (IllegalArgumentException expected) {} } + public void testConstructor_equals() throws NoSuchMethodException { + Constructor<?> defaultConstructor = ArrayList.class.getConstructor(); + Constructor<?> oneArgConstructor = ArrayList.class.getConstructor(int.class); + new EqualsTester() + .addEqualityGroup(Invokable.from(defaultConstructor), Invokable.from(defaultConstructor)) + .addEqualityGroup(Invokable.from(oneArgConstructor)) + .addEqualityGroup(new TypeToken<ArrayList<Integer>>() {}.constructor(defaultConstructor)) + .addEqualityGroup(new TypeToken<ArrayList<String>>() {}.constructor(defaultConstructor)) + .addEqualityGroup(new TypeToken<ArrayList<Integer>>() {}.constructor(oneArgConstructor)) + .addEqualityGroup(new TypeToken<ArrayList<String>>() {}.constructor(oneArgConstructor)) + .testEquals(); + } + private static class Container<T> { @SuppressWarnings("unused") public Container(T data) {} @@ -1268,7 +1344,80 @@ public class TypeTokenTest extends TestCase { @SuppressWarnings("rawtypes") // Reflection API skew Constructor<CannotConstruct> constructor = CannotConstruct.class.getConstructor(); Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.constructor(constructor); - assertThat(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class)); + ASSERT.that(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class)); + } + + public void testRejectTypeVariable_class() { + assertNoTypeVariable(String.class); + assertNoTypeVariable(String[].class); + assertNoTypeVariable(int[].class); + } + + public void testRejectTypeVariable_parameterizedType() { + assertNoTypeVariable(new TypeCapture<Iterable<String>>() {}.capture()); + } + + public void testRejectTypeVariable_wildcardType() { + assertNoTypeVariable( + new TypeCapture<Iterable<? extends String>>() {}.capture()); + assertNoTypeVariable( + new TypeCapture<Iterable<? super String>>() {}.capture()); + } + + public void testRejectTypeVariable_genericArrayType() { + assertNoTypeVariable( + new TypeCapture<Iterable<? extends String>[]>() {}.capture()); + } + + public <T> void testRejectTypeVariable_withTypeVariable() { + assertHasTypeVariable(new TypeCapture<T>() {}.capture()); + assertHasTypeVariable(new TypeCapture<T[]>() {}.capture()); + assertHasTypeVariable(new TypeCapture<Iterable<T>>() {}.capture()); + assertHasTypeVariable(new TypeCapture<Map<String, T>>() {}.capture()); + assertHasTypeVariable( + new TypeCapture<Map<String, ? extends T>>() {}.capture()); + assertHasTypeVariable( + new TypeCapture<Map<String, ? super T[]>>() {}.capture()); + } + + private static class From<K> { + class To<V> { + Type type() { + return new TypeToken<To<V>>(getClass()) {}.getType(); + } + } + } + + public <T> void testRejectTypeVariable_withOwnerType() { + // Neither has subclass + assertHasTypeVariable(new From<Integer>().new To<String>().type()); + assertHasTypeVariable(new From<T>().new To<String>().type()); + assertHasTypeVariable(new From<Integer>().new To<T>().type()); + + // Owner is subclassed + assertHasTypeVariable(new From<Integer>() {}.new To<String>().type()); + assertHasTypeVariable(new From<T>() {}.new To<String>().type()); + + // Inner is subclassed + assertNoTypeVariable(new From<Integer>().new To<String>() {}.type()); + assertHasTypeVariable(new From<Integer>().new To<T>() {}.type()); + assertHasTypeVariable(new From<T>().new To<String>() {}.type()); + + // both subclassed + assertHasTypeVariable(new From<T>() {}.new To<String>() {}.type()); + assertNoTypeVariable(new From<Integer>() {}.new To<String>() {}.type()); + assertHasTypeVariable(new From<Integer>() {}.new To<T>() {}.type()); + } + + private static void assertHasTypeVariable(Type type) { + try { + TypeToken.of(type).rejectTypeVariables(); + fail("Should contain TypeVariable"); + } catch (IllegalArgumentException expected) {} + } + + private static void assertNoTypeVariable(Type type) { + TypeToken.of(type).rejectTypeVariables(); } private abstract static class RawTypeConsistencyTester<T extends Enum<T> & CharSequence> { @@ -1368,7 +1517,6 @@ public class TypeTokenTest extends TestCase { private abstract class SubOuter extends BaseOuter { private abstract class SubInner extends BaseInner {} } - } // For Guava bug http://code.google.com/p/guava-libraries/issues/detail?id=1025 @@ -1482,13 +1630,36 @@ public class TypeTokenTest extends TestCase { return builder.build(); } + private static void assertIsPrimitive(TypeToken<?> type) { + assertTrue(type.isPrimitive()); + assertNotWrapper(type); + assertEquals(TypeToken.of(Primitives.wrap((Class<?>) type.getType())), type.wrap()); + } + + private static void assertNotPrimitive(TypeToken<?> type) { + assertFalse(type.isPrimitive()); + assertSame(type, type.wrap()); + } + + private static void assertIsWrapper(TypeToken<?> type) { + assertNotPrimitive(type); + assertEquals(TypeToken.of(Primitives.unwrap((Class<?>) type.getType())), type.unwrap()); + } + + private static void assertNotWrapper(TypeToken<?> type) { + assertSame(type, type.unwrap()); + } + + private static void assertNotPrimitiveNorWrapper(TypeToken<?> type) { + assertNotPrimitive(type); + assertNotWrapper(type); + } + private interface BaseInterface {} private static class Base implements BaseInterface {} private static class Sub extends Base {} - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); + private static CollectionSubject<?, Object, ?> assertThat(Collection<?> actual) { + return ASSERT.that(Collections.<Object>unmodifiableCollection(actual)); } } diff --git a/guava-tests/test/com/google/common/reflect/TypeVisitorTest.java b/guava-tests/test/com/google/common/reflect/TypeVisitorTest.java new file mode 100644 index 0000000..133bd08 --- /dev/null +++ b/guava-tests/test/com/google/common/reflect/TypeVisitorTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.reflect; + +import junit.framework.TestCase; + +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.lang.reflect.WildcardType; +import java.util.ArrayList; +import java.util.EnumSet; + +/** + * Tests of {@link TypeVisitor}. + * + * @author Ben Yu + */ +public class TypeVisitorTest extends TestCase { + + public void testVisitNull() { + new BaseTypeVisitor().visit( + ((ParameterizedType) ArrayList.class.getGenericSuperclass()).getOwnerType()); + } + + public void testVisitClass() { + assertVisited(String.class); + new BaseTypeVisitor() { + @Override void visitClass(Class<?> t) {} + }.visit(String.class); + } + + public <T> void testVisitTypeVariable() { + Type type = new TypeCapture<T>() {}.capture(); + assertVisited(type); + new BaseTypeVisitor() { + @Override void visitTypeVariable(TypeVariable<?> t) {} + }.visit(type); + } + + public void testVisitWildcardType() { + WildcardType type = Types.subtypeOf(String.class); + assertVisited(type); + new BaseTypeVisitor() { + @Override void visitWildcardType(WildcardType t) {} + }.visit(type); + } + + public <T> void testVisitGenericArrayType() { + Type type = new TypeCapture<T[]>() {}.capture(); + assertVisited(type); + new BaseTypeVisitor() { + @Override void visitGenericArrayType(GenericArrayType t) {} + }.visit(type); + } + + public <T> void testVisitParameterizedType() { + Type type = new TypeCapture<Iterable<T>>() {}.capture(); + assertVisited(type); + new BaseTypeVisitor() { + @Override void visitParameterizedType(ParameterizedType t) {} + }.visit(type); + } + + public <E extends Enum<E>> void testVisitRecursiveTypeBounds() { + Type type = new TypeCapture<EnumSet<E>>() {}.capture(); + assertVisited(type); + new BaseTypeVisitor() { + @Override void visitParameterizedType(ParameterizedType t) { + visit(t.getActualTypeArguments()); + } + @Override void visitTypeVariable(TypeVariable<?> t) { + visit(t.getBounds()); + } + }.visit(type); + } + + private static void assertVisited(Type type) { + TypeVisitor visitor = new BaseTypeVisitor(); + try { + visitor.visit(type); + fail("Type not visited"); + } catch (UnsupportedOperationException expected) {} + try { + visitor.visit(new Type[] {type}); + fail("Type not visited"); + } catch (UnsupportedOperationException expected) {} + } + + private static class BaseTypeVisitor extends TypeVisitor { + @Override void visitTypeVariable(TypeVariable<?> t) { + throw new UnsupportedOperationException(); + } + + @Override void visitWildcardType(WildcardType t) { + throw new UnsupportedOperationException(); + } + + @Override void visitParameterizedType(ParameterizedType t) { + throw new UnsupportedOperationException(); + } + + @Override void visitClass(Class<?> t) { + throw new UnsupportedOperationException(); + } + + @Override void visitGenericArrayType(GenericArrayType t) { + throw new UnsupportedOperationException(); + } + } +} diff --git a/guava-tests/test/com/google/common/reflect/TypesTest.java b/guava-tests/test/com/google/common/reflect/TypesTest.java index 9e0a93f..a41b6a9 100644 --- a/guava-tests/test/com/google/common/reflect/TypesTest.java +++ b/guava-tests/test/com/google/common/reflect/TypesTest.java @@ -17,13 +17,16 @@ package com.google.common.reflect; import static java.util.Arrays.asList; +import static org.truth0.Truth.ASSERT; +import com.google.common.collect.Lists; import com.google.common.testing.EqualsTester; -import com.google.common.testing.FluentAsserts; import com.google.common.testing.NullPointerTester; import com.google.common.testing.NullPointerTester.Visibility; import com.google.common.testing.SerializableTester; +import junit.framework.TestCase; + import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.ParameterizedType; @@ -35,8 +38,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import junit.framework.TestCase; - /** * Tests for {@link Types}. * @@ -65,7 +66,7 @@ public class TypesTest extends TestCase { assertEquals(jvmType.toString(), ourType.toString()); assertEquals(jvmType.hashCode(), ourType.hashCode()); assertEquals(HashMap.class, ourType.getRawType()); - FluentAsserts.assertThat(ourType.getActualTypeArguments()) + ASSERT.that(ourType.getActualTypeArguments()) .iteratesOverSequence(jvmType.getActualTypeArguments()); assertEquals(Arrays.asList( String.class, @@ -106,7 +107,7 @@ public class TypesTest extends TestCase { assertEquals(jvmType.toString(), ourType.toString()); assertEquals(Map.class, ourType.getOwnerType()); assertEquals(Map.Entry.class, ourType.getRawType()); - FluentAsserts.assertThat(ourType.getActualTypeArguments()) + ASSERT.that(ourType.getActualTypeArguments()) .iteratesOverSequence(jvmType.getActualTypeArguments()); } @@ -267,10 +268,10 @@ public class TypesTest extends TestCase { WildcardType expected, WildcardType actual) { assertEquals(expected.toString(), actual.toString()); assertEquals(actual.toString(), expected.hashCode(), actual.hashCode()); - FluentAsserts.assertThat(actual.getLowerBounds()) - .has().allFrom(asList(expected.getLowerBounds())).inOrder(); - FluentAsserts.assertThat(actual.getUpperBounds()) - .has().allFrom(asList(expected.getUpperBounds())).inOrder(); + ASSERT.that(actual.getLowerBounds()) + .has().exactlyAs(asList(expected.getLowerBounds())).inOrder(); + ASSERT.that(actual.getUpperBounds()) + .has().exactlyAs(asList(expected.getUpperBounds())).inOrder(); } private static class WithTypeVariable { @@ -311,43 +312,61 @@ public class TypesTest extends TestCase { assertEqualTypeVariable(objectBoundJvmType, objectBound); assertEqualTypeVariable(upperBoundJvmType, upperBound); - new EqualsTester() + new TypeVariableEqualsTester() .addEqualityGroup(noBoundJvmType, noBound) .addEqualityGroup(objectBoundJvmType, objectBound) - .addEqualityGroup( - upperBoundJvmType, upperBound, - withBounds(upperBoundJvmType, CharSequence.class)) // bounds ignored + .addEqualityGroup(upperBoundJvmType, upperBound) .testEquals(); } public void testNewTypeVariable_primitiveTypeBound() { try { - Types.newTypeVariable(List.class, "E", int.class); + Types.newArtificialTypeVariable(List.class, "E", int.class); fail(); } catch (IllegalArgumentException expected) {} } public void testNewTypeVariable_serializable() throws Exception { try { - SerializableTester.reserialize(Types.newTypeVariable(List.class, "E")); + SerializableTester.reserialize(Types.newArtificialTypeVariable(List.class, "E")); fail(); } catch (RuntimeException expected) {} } private static <D extends GenericDeclaration> TypeVariable<D> withBounds( TypeVariable<D> typeVariable, Type... bounds) { - return Types.newTypeVariable( + return Types.newArtificialTypeVariable( typeVariable.getGenericDeclaration(), typeVariable.getName(), bounds); } + private static class TypeVariableEqualsTester { + private final EqualsTester tester = new EqualsTester(); + + TypeVariableEqualsTester addEqualityGroup(Type jvmType, Type... types) { + if (Types.NativeTypeVariableEquals.NATIVE_TYPE_VARIABLE_ONLY) { + tester.addEqualityGroup(jvmType); + tester.addEqualityGroup((Object[]) types); + } else { + tester.addEqualityGroup(Lists.asList(jvmType, types).toArray()); + } + return this; + } + + void testEquals() { + tester.testEquals(); + } + } + private static void assertEqualTypeVariable( TypeVariable<?> expected, TypeVariable<?> actual) { assertEquals(expected.toString(), actual.toString()); assertEquals(expected.getName(), actual.getName()); assertEquals( expected.getGenericDeclaration(), actual.getGenericDeclaration()); - assertEquals(actual.toString(), expected.hashCode(), actual.hashCode()); - FluentAsserts.assertThat(actual.getBounds()).has().allFrom(asList(expected.getBounds())).inOrder(); + if (!Types.NativeTypeVariableEquals.NATIVE_TYPE_VARIABLE_ONLY) { + assertEquals(actual.toString(), expected.hashCode(), actual.hashCode()); + } + ASSERT.that(actual.getBounds()).has().exactlyAs(asList(expected.getBounds())).inOrder(); } /** @@ -374,40 +393,7 @@ public class TypesTest extends TestCase { Types.newParameterizedType( Map.class, String.class, Integer.class, Long.class); fail(); - } catch(IllegalArgumentException expected) {} - } - - public void testContainsTypeVariable_class() { - assertFalse(Types.containsTypeVariable(String.class)); - assertFalse(Types.containsTypeVariable(String[].class)); - assertFalse(Types.containsTypeVariable(int[].class)); - } - - public void testContainsTypeVariable_parameterizedType() { - assertFalse(Types.containsTypeVariable(new TypeCapture<Iterable<String>>() {}.capture())); - } - - public void testContainsTypeVariable_wildcardType() { - assertFalse(Types.containsTypeVariable( - new TypeCapture<Iterable<? extends String>>() {}.capture())); - assertFalse(Types.containsTypeVariable( - new TypeCapture<Iterable<? super String>>() {}.capture())); - } - - public void testContainsTypeVariable_genericArrayType() { - assertFalse(Types.containsTypeVariable( - new TypeCapture<Iterable<? extends String>[]>() {}.capture())); - } - - public <T> void testContainsTypeVariable_withTypeVariable() { - assertTrue(Types.containsTypeVariable(new TypeCapture<T>() {}.capture())); - assertTrue(Types.containsTypeVariable(new TypeCapture<T[]>() {}.capture())); - assertTrue(Types.containsTypeVariable(new TypeCapture<Iterable<T>>() {}.capture())); - assertTrue(Types.containsTypeVariable(new TypeCapture<Map<String, T>>() {}.capture())); - assertTrue(Types.containsTypeVariable( - new TypeCapture<Map<String, ? extends T>>() {}.capture())); - assertTrue(Types.containsTypeVariable( - new TypeCapture<Map<String, ? super T[]>>() {}.capture())); + } catch (IllegalArgumentException expected) {} } public void testToString() { diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractChainedListenableFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractChainedListenableFutureTest.java index cda5a9a..ff1a81f 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AbstractChainedListenableFutureTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AbstractChainedListenableFutureTest.java @@ -18,11 +18,11 @@ package com.google.common.util.concurrent; import com.google.common.util.concurrent.testing.MockFutureListener; +import junit.framework.TestCase; + import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import junit.framework.TestCase; - /** * Unit tests for any listenable future that chains other listenable futures. * Unit tests need only override buildChainingFuture and getSuccessfulResult, @@ -64,13 +64,7 @@ public abstract class AbstractChainedListenableFutureTest<T> extends TestCase { public void testFutureGetThrowsWrappedError() throws Exception { Error error = new Error(); - try { - inputFuture.setException(error); - fail("Expected an Error to be thrown"); // COV_NF_LINE - } catch (Error expected) { - assertSame(error, expected); - } - + inputFuture.setException(error); // Verify that get throws an ExecutionException, caused by an Error, when // the callback is called. listener.assertException(error); diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java index e9f9e67..b30d531 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java @@ -16,22 +16,19 @@ package com.google.common.util.concurrent; -import com.google.common.base.Throwables; import com.google.common.testing.TearDown; import com.google.common.testing.TearDownStack; +import junit.framework.TestCase; + import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import junit.framework.TestCase; - /** * Unit test for {@link AbstractExecutionThreadService}. * @@ -45,7 +42,7 @@ public class AbstractExecutionThreadServiceTest extends TestCase { private Thread executionThread; private Throwable thrownByExecutionThread; - private final Executor executor = new Executor() { + private final Executor exceptionCatchingExecutor = new Executor() { @Override public void execute(Runnable command) { executionThread = new Thread(command); @@ -67,43 +64,32 @@ public class AbstractExecutionThreadServiceTest extends TestCase { WaitOnRunService service = new WaitOnRunService(); assertFalse(service.startUpCalled); - service.start().get(); + service.startAsync().awaitRunning(); assertTrue(service.startUpCalled); assertEquals(Service.State.RUNNING, service.state()); enterRun.await(); // to avoid stopping the service until run() is invoked - service.stop().get(); + service.stopAsync().awaitTerminated(); assertTrue(service.shutDownCalled); assertEquals(Service.State.TERMINATED, service.state()); executionThread.join(); assertNull(thrownByExecutionThread); } - public void testServiceStartStopIdempotence() throws Exception { + public void testServiceStopIdempotence() throws Exception { WaitOnRunService service = new WaitOnRunService(); - service.start(); - service.start(); - service.startAndWait(); - assertEquals(Service.State.RUNNING, service.state()); - service.startAndWait(); - assertEquals(Service.State.RUNNING, service.state()); - + service.startAsync().awaitRunning(); enterRun.await(); // to avoid stopping the service until run() is invoked - service.stop(); - service.stop(); - service.stopAndWait(); + service.stopAsync(); + service.stopAsync(); + service.stopAsync().awaitTerminated(); assertEquals(Service.State.TERMINATED, service.state()); - service.stopAndWait(); + service.stopAsync().awaitTerminated(); assertEquals(Service.State.TERMINATED, service.state()); - assertEquals(Service.State.RUNNING, service.start().get()); - assertEquals(Service.State.RUNNING, service.startAndWait()); - assertEquals(Service.State.TERMINATED, service.stop().get()); - assertEquals(Service.State.TERMINATED, service.stopAndWait()); - executionThread.join(); assertNull(thrownByExecutionThread); } @@ -112,7 +98,7 @@ public class AbstractExecutionThreadServiceTest extends TestCase { WaitOnRunService service = new WaitOnRunService(); service.expectedShutdownState = Service.State.RUNNING; - service.start().get(); + service.startAsync().awaitRunning(); assertTrue(service.startUpCalled); assertEquals(Service.State.RUNNING, service.state()); @@ -123,7 +109,7 @@ public class AbstractExecutionThreadServiceTest extends TestCase { assertEquals(Service.State.TERMINATED, service.state()); assertNull(thrownByExecutionThread); - service.stop().get(); // no-op + service.stopAsync().awaitTerminated(); // no-op assertEquals(Service.State.TERMINATED, service.state()); assertTrue(service.shutDownCalled); } @@ -153,7 +139,7 @@ public class AbstractExecutionThreadServiceTest extends TestCase { try { exitRun.await(); } catch (InterruptedException e) { - throw Throwables.propagate(e); + throw new RuntimeException(e); } } @@ -170,7 +156,7 @@ public class AbstractExecutionThreadServiceTest extends TestCase { } @Override protected Executor executor() { - return executor; + return exceptionCatchingExecutor; } } @@ -178,11 +164,11 @@ public class AbstractExecutionThreadServiceTest extends TestCase { ThrowOnStartUpService service = new ThrowOnStartUpService(); assertFalse(service.startUpCalled); - Future<Service.State> startupFuture = service.start(); + service.startAsync(); try { - startupFuture.get(); + service.awaitRunning(); fail(); - } catch (ExecutionException expected) { + } catch (IllegalStateException expected) { assertEquals("kaboom!", expected.getCause().getMessage()); } executionThread.join(); @@ -205,16 +191,21 @@ public class AbstractExecutionThreadServiceTest extends TestCase { } @Override protected Executor executor() { - return executor; + return exceptionCatchingExecutor; } } public void testServiceThrowOnRun() throws Exception { ThrowOnRunService service = new ThrowOnRunService(); - service.start().get(); - - executionThread.join(); + service.startAsync(); + try { + service.awaitTerminated(); + fail(); + } catch (IllegalStateException expected) { + executionThread.join(); + assertEquals(thrownByExecutionThread, expected.getCause()); + } assertTrue(service.shutDownCalled); assertEquals(Service.State.FAILED, service.state()); assertEquals("kaboom!", thrownByExecutionThread.getMessage()); @@ -224,8 +215,14 @@ public class AbstractExecutionThreadServiceTest extends TestCase { ThrowOnRunService service = new ThrowOnRunService(); service.throwOnShutDown = true; - service.start().get(); - executionThread.join(); + service.startAsync(); + try { + service.awaitTerminated(); + fail(); + } catch (IllegalStateException expected) { + executionThread.join(); + assertEquals(thrownByExecutionThread, expected.getCause()); + } assertTrue(service.shutDownCalled); assertEquals(Service.State.FAILED, service.state()); @@ -248,17 +245,17 @@ public class AbstractExecutionThreadServiceTest extends TestCase { } @Override protected Executor executor() { - return executor; + return exceptionCatchingExecutor; } } public void testServiceThrowOnShutDown() throws Exception { ThrowOnShutDown service = new ThrowOnShutDown(); - service.start().get(); + service.startAsync().awaitRunning(); assertEquals(Service.State.RUNNING, service.state()); - service.stop(); + service.stopAsync(); enterRun.countDown(); executionThread.join(); @@ -271,7 +268,7 @@ public class AbstractExecutionThreadServiceTest extends TestCase { try { enterRun.await(); } catch (InterruptedException e) { - throw Throwables.propagate(e); + throw new RuntimeException(e); } } @@ -280,7 +277,7 @@ public class AbstractExecutionThreadServiceTest extends TestCase { } @Override protected Executor executor() { - return executor; + return exceptionCatchingExecutor; } } @@ -288,7 +285,7 @@ public class AbstractExecutionThreadServiceTest extends TestCase { TimeoutOnStartUp service = new TimeoutOnStartUp(); try { - service.start().get(1, TimeUnit.MILLISECONDS); + service.startAsync().awaitRunning(1, TimeUnit.MILLISECONDS); fail(); } catch (TimeoutException e) { assertTrue(e.getMessage().contains(Service.State.STARTING.toString())); @@ -316,10 +313,10 @@ public class AbstractExecutionThreadServiceTest extends TestCase { started.await(); } }; - service.start(); - ListenableFuture<Service.State> stopped = service.stop(); + service.startAsync(); + service.stopAsync(); started.countDown(); - assertEquals(Service.State.TERMINATED, stopped.get()); + service.awaitTerminated(); assertEquals(Service.State.TERMINATED, service.state()); assertEquals(1, service.startupCalled); assertEquals(0, service.runCalled); @@ -328,19 +325,18 @@ public class AbstractExecutionThreadServiceTest extends TestCase { public void testStop_noStart() { FakeService service = new FakeService(); - assertEquals(Service.State.TERMINATED, service.stopAndWait()); + service.stopAsync().awaitTerminated(); assertEquals(Service.State.TERMINATED, service.state()); assertEquals(0, service.startupCalled); assertEquals(0, service.runCalled); assertEquals(0, service.shutdownCalled); } - public void testDefaultService() { - AbstractExecutionThreadService service = new AbstractExecutionThreadService() { - @Override protected void run() throws Exception {} - }; - assertEquals(Service.State.RUNNING, service.startAndWait()); - assertEquals(Service.State.TERMINATED, service.stopAndWait()); + public void testDefaultService() throws InterruptedException { + WaitOnRunService service = new WaitOnRunService(); + service.startAsync().awaitRunning(); + enterRun.await(); + service.stopAsync().awaitTerminated(); } private class FakeService extends AbstractExecutionThreadService implements TearDown { diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java index cdb25f5..4024a8e 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java @@ -16,7 +16,10 @@ package com.google.common.util.concurrent; -import com.google.common.testing.FluentAsserts; +import static org.truth0.Truth.ASSERT; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; @@ -24,9 +27,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - /** * Tests for {@link AbstractFuture}. * @@ -153,11 +153,11 @@ public class AbstractFutureTest extends TestCase { int index = findStackFrame( e, getClass().getName(), "getExpectingExecutionException"); - FluentAsserts.assertThat(index).isNotEqualTo(0); + ASSERT.that(index).isNotEqualTo(0); // Above our method should be the call to get(). Don't assert on the class // because it could be some superclass. - FluentAsserts.assertThat(e.getStackTrace()[index - 1].getMethodName()).isEqualTo("get"); + ASSERT.that(e.getStackTrace()[index - 1].getMethodName()).isEqualTo("get"); } private static int findStackFrame( diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java index 0c3b2ab..eb159df 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java @@ -19,18 +19,14 @@ package com.google.common.util.concurrent; import static org.truth0.Truth.ASSERT; import com.google.common.collect.Lists; -import com.google.common.testing.FluentAsserts; -import java.util.Collection; +import junit.framework.TestCase; + import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import junit.framework.TestCase; - -import org.truth0.subjects.CollectionSubject; - /** * Tests for {@link AbstractIdleService}. * @@ -51,9 +47,9 @@ public class AbstractIdleServiceTest extends TestCase { public void testServiceStartStop() throws Exception { AbstractIdleService service = new DefaultService(); - assertEquals(Service.State.RUNNING, service.startAndWait()); + service.startAsync().awaitRunning(); assertEquals(Service.State.RUNNING, service.state()); - assertEquals(Service.State.TERMINATED, service.stopAndWait()); + service.stopAsync().awaitTerminated(); assertEquals(Service.State.TERMINATED, service.state()); } @@ -65,7 +61,7 @@ public class AbstractIdleServiceTest extends TestCase { } }; try { - service.startAndWait(); + service.startAsync().awaitRunning(); fail(); } catch (RuntimeException e) { assertSame(exception, e.getCause()); @@ -80,9 +76,9 @@ public class AbstractIdleServiceTest extends TestCase { throw exception; } }; - service.startAndWait(); + service.startAsync().awaitRunning(); try { - service.stopAndWait(); + service.stopAsync().awaitTerminated(); fail(); } catch (RuntimeException e) { assertSame(exception, e.getCause()); @@ -94,10 +90,10 @@ public class AbstractIdleServiceTest extends TestCase { public void testStart() { TestService service = new TestService(); assertEquals(0, service.startUpCalled); - service.startAndWait(); + service.startAsync().awaitRunning(); assertEquals(1, service.startUpCalled); assertEquals(Service.State.RUNNING, service.state()); - assertThat(service.transitionStates).has().allOf(Service.State.STARTING).inOrder(); + ASSERT.that(service.transitionStates).has().exactly(Service.State.STARTING).inOrder(); } public void testStart_failed() { @@ -110,36 +106,36 @@ public class AbstractIdleServiceTest extends TestCase { }; assertEquals(0, service.startUpCalled); try { - service.startAndWait(); + service.startAsync().awaitRunning(); fail(); } catch (RuntimeException e) { assertSame(exception, e.getCause()); } assertEquals(1, service.startUpCalled); assertEquals(Service.State.FAILED, service.state()); - assertThat(service.transitionStates).has().allOf(Service.State.STARTING).inOrder(); + ASSERT.that(service.transitionStates).has().exactly(Service.State.STARTING).inOrder(); } public void testStop_withoutStart() { TestService service = new TestService(); - service.stopAndWait(); + service.stopAsync().awaitTerminated(); assertEquals(0, service.startUpCalled); assertEquals(0, service.shutDownCalled); assertEquals(Service.State.TERMINATED, service.state()); - assertThat(service.transitionStates).isEmpty(); + ASSERT.that(service.transitionStates).isEmpty(); } public void testStop_afterStart() { TestService service = new TestService(); - service.startAndWait(); + service.startAsync().awaitRunning(); assertEquals(1, service.startUpCalled); assertEquals(0, service.shutDownCalled); - service.stopAndWait(); + service.stopAsync().awaitTerminated(); assertEquals(1, service.startUpCalled); assertEquals(1, service.shutDownCalled); assertEquals(Service.State.TERMINATED, service.state()); - assertThat(service.transitionStates) - .has().allOf(Service.State.STARTING, Service.State.STOPPING).inOrder(); + ASSERT.that(service.transitionStates) + .has().exactly(Service.State.STARTING, Service.State.STOPPING).inOrder(); } public void testStop_failed() { @@ -150,11 +146,11 @@ public class AbstractIdleServiceTest extends TestCase { throw exception; } }; - service.startAndWait(); + service.startAsync().awaitRunning(); assertEquals(1, service.startUpCalled); assertEquals(0, service.shutDownCalled); try { - service.stopAndWait(); + service.stopAsync().awaitTerminated(); fail(); } catch (RuntimeException e) { assertSame(exception, e.getCause()); @@ -162,16 +158,16 @@ public class AbstractIdleServiceTest extends TestCase { assertEquals(1, service.startUpCalled); assertEquals(1, service.shutDownCalled); assertEquals(Service.State.FAILED, service.state()); - assertThat(service.transitionStates) - .has().allOf(Service.State.STARTING, Service.State.STOPPING).inOrder(); + ASSERT.that(service.transitionStates) + .has().exactly(Service.State.STARTING, Service.State.STOPPING).inOrder(); } public void testServiceToString() { AbstractIdleService service = new TestService(); assertEquals("TestService [NEW]", service.toString()); - service.startAndWait(); + service.startAsync().awaitRunning(); assertEquals("TestService [RUNNING]", service.toString()); - service.stopAndWait(); + service.stopAsync().awaitTerminated(); assertEquals("TestService [TERMINATED]", service.toString()); } @@ -185,10 +181,10 @@ public class AbstractIdleServiceTest extends TestCase { } }; try { - service.start().get(1, TimeUnit.MILLISECONDS); + service.startAsync().awaitRunning(1, TimeUnit.MILLISECONDS); fail("Expected timeout"); } catch (TimeoutException e) { - FluentAsserts.assertThat(e.getMessage()).contains(Service.State.STARTING.toString()); + ASSERT.that(e.getMessage()).contains(Service.State.STARTING.toString()); } } @@ -216,10 +212,4 @@ public class AbstractIdleServiceTest extends TestCase { return MoreExecutors.sameThreadExecutor(); } } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractListeningExecutorServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractListeningExecutorServiceTest.java index f7bbf43..df96535 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AbstractListeningExecutorServiceTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AbstractListeningExecutorServiceTest.java @@ -1,652 +1,112 @@ /* - * This file is a modified version of - * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck/AbstractExecutorServiceTest.java?revision=1.30 - * which contained the following notice: + * Copyright (C) 2011 The Guava Authors * - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - * Other contributors include Andrew Wright, Jeffrey Hayes, - * Pat Fisher, Mike Judd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.google.common.util.concurrent; -import static java.util.concurrent.TimeUnit.MILLISECONDS; +import com.google.common.collect.ImmutableList; + +import junit.framework.TestCase; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -public class AbstractListeningExecutorServiceTest extends JSR166TestCase { - /** - * A no-frills implementation of AbstractListeningExecutorService, designed - * to test the submit methods only. - */ - static class DirectExecutorService - extends AbstractListeningExecutorService { - @Override - public void execute(Runnable r) { r.run(); } - @Override - public void shutdown() { shutdown = true; } - @Override - public List<Runnable> shutdownNow() { - shutdown = true; - return Collections.emptyList(); - } - @Override - public boolean isShutdown() { return shutdown; } - @Override - public boolean isTerminated() { return isShutdown(); } - @Override - public boolean awaitTermination(long timeout, TimeUnit unit) { - return isShutdown(); - } - private volatile boolean shutdown = false; - } - - /** - * execute(runnable) runs it to completion - */ - public void testExecuteRunnable() throws Exception { - ExecutorService e = new DirectExecutorService(); - TrackedShortRunnable task = new TrackedShortRunnable(); - assertFalse(task.done); - Future<?> future = e.submit(task); - future.get(); - assertTrue(task.done); - } - - /** - * Completed submit(callable) returns result - */ - public void testSubmitCallable() throws Exception { - ExecutorService e = new DirectExecutorService(); - Future<String> future = e.submit(new StringTask()); - String result = future.get(); - assertSame(TEST_STRING, result); - } - - /** - * Completed submit(runnable) returns successfully - */ - public void testSubmitRunnable() throws Exception { - ExecutorService e = new DirectExecutorService(); - Future<?> future = e.submit(new NoOpRunnable()); - future.get(); - assertTrue(future.isDone()); - } - - /** - * Completed submit(runnable, result) returns result - */ - public void testSubmitRunnable2() throws Exception { - ExecutorService e = new DirectExecutorService(); - Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING); - String result = future.get(); - assertSame(TEST_STRING, result); - } - - /** - * A submitted privileged action runs to completion - */ - public void testSubmitPrivilegedAction() throws Exception { - Runnable r = new CheckedRunnable() { - @Override - public void realRun() throws Exception { - ExecutorService e = new DirectExecutorService(); - Future future = e.submit(Executors.callable( - new PrivilegedAction() { - @Override - public Object run() { - return TEST_STRING; - }})); - - assertSame(TEST_STRING, future.get()); - }}; - - runWithPermissions(r, - new RuntimePermission("getClassLoader"), - new RuntimePermission("setContextClassLoader"), - new RuntimePermission("modifyThread")); - } - - /** - * A submitted privileged exception action runs to completion - */ - public void testSubmitPrivilegedExceptionAction() throws Exception { - Runnable r = new CheckedRunnable() { - @Override - public void realRun() throws Exception { - ExecutorService e = new DirectExecutorService(); - Future future = e.submit(Executors.callable( - new PrivilegedExceptionAction() { - @Override - public Object run() { - return TEST_STRING; - }})); - - assertSame(TEST_STRING, future.get()); - }}; - - runWithPermissions(r); - } - - /** - * A submitted failed privileged exception action reports exception - */ - public void testSubmitFailedPrivilegedExceptionAction() throws Exception { - Runnable r = new CheckedRunnable() { - @Override - public void realRun() throws Exception { - ExecutorService e = new DirectExecutorService(); - Future future = e.submit(Executors.callable( - new PrivilegedExceptionAction() { - @Override - public Object run() throws Exception { - throw new IndexOutOfBoundsException(); - }})); - - try { - future.get(); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() - instanceof IndexOutOfBoundsException); - }}}; - - runWithPermissions(r); - } - - /** - * execute(null runnable) throws NPE - */ - public void testExecuteNullRunnable() { - try { - ExecutorService e = new DirectExecutorService(); - e.submit((Runnable) null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * submit(null callable) throws NPE - */ - public void testSubmitNullCallable() { - try { - ExecutorService e = new DirectExecutorService(); - e.submit((Callable<?>) null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * submit(callable).get() throws InterruptedException if interrupted - */ - - public void testInterruptedSubmit() throws InterruptedException { - final CountDownLatch submitted = new CountDownLatch(1); - final CountDownLatch quittingTime = new CountDownLatch(1); - final ExecutorService p - = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, - new ArrayBlockingQueue<Runnable>(10)); - final Callable<Void> awaiter = new CheckedCallable<Void>() { - @Override - public Void realCall() throws InterruptedException { - quittingTime.await(); - return null; - }}; - try { - Thread t = new Thread(new CheckedInterruptedRunnable() { - @Override - public void realRun() throws Exception { - Future<Void> future = p.submit(awaiter); - submitted.countDown(); - future.get(); - }}); - t.start(); - submitted.await(); - t.interrupt(); - t.join(); - } finally { - quittingTime.countDown(); - joinPool(p); - } - } - - /** - * get of submit(callable) throws ExecutionException if callable - * throws exception - */ - - public void testSubmitEE() throws InterruptedException { - ThreadPoolExecutor p = - new ThreadPoolExecutor(1, 1, - 60, TimeUnit.SECONDS, - new ArrayBlockingQueue<Runnable>(10)); - - Callable<Object> c = new Callable<Object>() { - @Override - public Object call() { - throw new ArithmeticException("/ by zero"); - }}; - - try { - p.submit(c).get(); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof ArithmeticException); - } - joinPool(p); - } - - /** - * invokeAny(null) throws NPE - */ - public void testInvokeAny1() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAny(null); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } - } - - /** - * invokeAny(empty collection) throws IAE - */ - public void testInvokeAny2() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAny(new ArrayList<Callable<String>>()); - shouldThrow(); - } catch (IllegalArgumentException success) { - } finally { - joinPool(e); - } - } - - /** - * invokeAny(c) throws NPE if c has null elements - */ - public void testInvokeAny3() throws Exception { - ExecutorService e = new DirectExecutorService(); - List<Callable<Integer>> l = new ArrayList<Callable<Integer>>(); - l.add(new Callable<Integer>() { - @Override - public Integer call() { - throw new ArithmeticException("/ by zero"); - }}); - l.add(null); - try { - e.invokeAny(l); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } - } - - /** - * invokeAny(c) throws ExecutionException if no task in c completes - */ - public void testInvokeAny4() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new NPETask()); - try { - e.invokeAny(l); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof NullPointerException); - } finally { - joinPool(e); - } - } - - /** - * invokeAny(c) returns result of some task in c if at least one completes - */ - public void testInvokeAny5() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new StringTask()); - l.add(new StringTask()); - String result = e.invokeAny(l); - assertSame(TEST_STRING, result); - } finally { - joinPool(e); - } - } - - /** - * invokeAll(null) throws NPE - */ - public void testInvokeAll1() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAll(null); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } - } - - /** - * invokeAll(empty collection) returns empty collection - */ - public void testInvokeAll2() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { - List<Future<String>> r = - e.invokeAll(new ArrayList<Callable<String>>()); - assertTrue(r.isEmpty()); - } finally { - joinPool(e); - } - } - - /** - * invokeAll(c) throws NPE if c has null elements - */ - public void testInvokeAll3() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new StringTask()); - l.add(null); - try { - e.invokeAll(l); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } - } +/** + * Tests for {@link AbstractListeningExecutorService}. + * + * @author Colin Decker + */ +public class AbstractListeningExecutorServiceTest extends TestCase { - /** - * get of returned element of invokeAll(c) throws exception on failed task + public void testSubmit() throws Exception { + /* + * Mostly just tests that ListenableFutureTasks are created and run; tests for + * ListenableFutureTask should ensure that listeners are called correctly. */ - public void testInvokeAll4() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new NPETask()); - List<Future<String>> futures = e.invokeAll(l); - assertEquals(1, futures.size()); - try { - futures.get(0).get(); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof NullPointerException); - } - } finally { - joinPool(e); - } - } - /** - * invokeAll(c) returns results of all completed tasks in c - */ - public void testInvokeAll5() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new StringTask()); - l.add(new StringTask()); - List<Future<String>> futures = e.invokeAll(l); - assertEquals(2, futures.size()); - for (Future<String> future : futures) - assertSame(TEST_STRING, future.get()); - } finally { - joinPool(e); - } - } + TestListeningExecutorService e = new TestListeningExecutorService(); - /** - * timed invokeAny(null) throws NPE - */ - public void testTimedInvokeAny1() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } - } + TestRunnable runnable = new TestRunnable(); + ListenableFuture<?> runnableFuture = e.submit(runnable); + assertTrue(runnableFuture instanceof ListenableFutureTask); + assertTrue(runnableFuture.isDone()); + assertTrue(runnable.run); - /** - * timed invokeAny(null time unit) throws NPE - */ - public void testTimedInvokeAnyNullTimeUnit() throws Exception { - ExecutorService e = new DirectExecutorService(); - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new StringTask()); - try { - e.invokeAny(l, MEDIUM_DELAY_MS, null); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } - } + ListenableFuture<String> callableFuture = e.submit(new TestCallable()); + assertTrue(callableFuture instanceof ListenableFutureTask); + assertTrue(callableFuture.isDone()); + assertEquals("foo", callableFuture.get()); - /** - * timed invokeAny(empty collection) throws IAE - */ - public void testTimedInvokeAny2() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAny(new ArrayList<Callable<String>>(), - MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (IllegalArgumentException success) { - } finally { - joinPool(e); - } - } + TestRunnable runnable2 = new TestRunnable(); + ListenableFuture<Integer> runnableFuture2 = e.submit(runnable2, 3); + assertTrue(runnableFuture2 instanceof ListenableFutureTask); + assertTrue(runnableFuture2.isDone()); + assertTrue(runnable2.run); + assertEquals((Integer) 3, runnableFuture2.get()); + } - /** - * timed invokeAny(c) throws NPE if c has null elements - */ - public void testTimedInvokeAny3() throws Exception { - ExecutorService e = new DirectExecutorService(); - List<Callable<Integer>> l = new ArrayList<Callable<Integer>>(); - l.add(new Callable<Integer>() { - @Override - public Integer call() { - throw new ArithmeticException("/ by zero"); - }}); - l.add(null); - try { - e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } - } + private static class TestRunnable implements Runnable { + boolean run = false; - /** - * timed invokeAny(c) throws ExecutionException if no task completes - */ - public void testTimedInvokeAny4() throws Exception { - ExecutorService e = new DirectExecutorService(); - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new NPETask()); - try { - e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof NullPointerException); - } finally { - joinPool(e); - } + @Override + public void run() { + run = true; } + } - /** - * timed invokeAny(c) returns result of some task in c - */ - public void testTimedInvokeAny5() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new StringTask()); - l.add(new StringTask()); - String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); - assertSame(TEST_STRING, result); - } finally { - joinPool(e); - } + private static class TestCallable implements Callable<String> { + @Override + public String call() { + return "foo"; } + } - /** - * timed invokeAll(null) throws NPE - */ - public void testTimedInvokeAll1() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } - } + /** + * Simple same thread listening executor service that doesn't handle shutdown. + */ + private static class TestListeningExecutorService extends AbstractListeningExecutorService { - /** - * timed invokeAll(null time unit) throws NPE - */ - public void testTimedInvokeAllNullTimeUnit() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new StringTask()); - try { - e.invokeAll(l, MEDIUM_DELAY_MS, null); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } + @Override + public void execute(Runnable runnable) { + assertTrue(runnable instanceof ListenableFutureTask); + runnable.run(); } - /** - * timed invokeAll(empty collection) returns empty collection - */ - public void testTimedInvokeAll2() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { - List<Future<String>> r = e.invokeAll( - new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, - MILLISECONDS); - assertTrue(r.isEmpty()); - } finally { - joinPool(e); - } + @Override + public void shutdown() { } - /** - * timed invokeAll(c) throws NPE if c has null elements - */ - public void testTimedInvokeAll3() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new StringTask()); - l.add(null); - try { - e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); - } + @Override + public List<Runnable> shutdownNow() { + return ImmutableList.of(); } - /** - * get of returned element of invokeAll(c) throws exception on failed task - */ - public void testTimedInvokeAll4() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new NPETask()); - List<Future<String>> futures = - e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); - assertEquals(1, futures.size()); - try { - futures.get(0).get(); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof NullPointerException); - } - } finally { - joinPool(e); - } + @Override + public boolean isShutdown() { + return false; } - /** - * timed invokeAll(c) returns results of all completed tasks in c - */ - public void testTimedInvokeAll5() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new StringTask()); - l.add(new StringTask()); - List<Future<String>> futures = - e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); - assertEquals(2, futures.size()); - for (Future<String> future : futures) - assertSame(TEST_STRING, future.get()); - } finally { - joinPool(e); - } + @Override + public boolean isTerminated() { + return false; } - /** - * timed invokeAll cancels tasks not completed by timeout - */ - public void testTimedInvokeAll6() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { - List<Callable<String>> l = new ArrayList<Callable<String>>(); - l.add(new StringTask()); - l.add(Executors.callable( - possiblyInterruptedRunnable(2 * SHORT_DELAY_MS), TEST_STRING)); - l.add(new StringTask()); - List<Future<String>> futures = - e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS); - assertEquals(3, futures.size()); - Iterator<Future<String>> it = futures.iterator(); - Future<String> f1 = it.next(); - Future<String> f2 = it.next(); - Future<String> f3 = it.next(); - assertTrue(f1.isDone()); - assertFalse(f1.isCancelled()); - assertTrue(f2.isDone()); - assertFalse(f2.isCancelled()); - assertTrue(f3.isDone()); - assertTrue(f3.isCancelled()); - } finally { - joinPool(e); - } + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) { + return false; } - + } } diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java index 10418b1..59ed10e 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java @@ -19,6 +19,8 @@ package com.google.common.util.concurrent; import com.google.common.util.concurrent.AbstractScheduledService.Scheduler; import com.google.common.util.concurrent.Service.State; +import junit.framework.TestCase; + import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutionException; @@ -31,8 +33,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import junit.framework.TestCase; - /** * Unit test for {@link AbstractScheduledService}. * @@ -58,9 +58,9 @@ public class AbstractScheduledServiceTest extends TestCase { public void testServiceStartStop() throws Exception { NullService service = new NullService(); - service.startAndWait(); + service.startAsync().awaitRunning(); assertFalse(future.isDone()); - service.stopAndWait(); + service.stopAsync().awaitTerminated(); assertTrue(future.isCancelled()); } @@ -73,7 +73,7 @@ public class AbstractScheduledServiceTest extends TestCase { public void testFailOnExceptionFromRun() throws Exception { TestService service = new TestService(); service.runException = new Exception(); - service.startAndWait(); + service.startAsync().awaitRunning(); service.runFirstBarrier.await(); service.runSecondBarrier.await(); try { @@ -91,9 +91,9 @@ public class AbstractScheduledServiceTest extends TestCase { TestService service = new TestService(); service.startUpException = new Exception(); try { - service.startAndWait(); + service.startAsync().awaitRunning(); fail(); - } catch (UncheckedExecutionException e) { + } catch (IllegalStateException e) { assertEquals(service.startUpException, e.getCause()); } assertEquals(0, service.numberOfTimesRunCalled.get()); @@ -103,14 +103,14 @@ public class AbstractScheduledServiceTest extends TestCase { public void testFailOnExceptionFromShutDown() throws Exception { TestService service = new TestService(); service.shutDownException = new Exception(); - service.startAndWait(); + service.startAsync().awaitRunning(); service.runFirstBarrier.await(); - ListenableFuture<Service.State> stopHandle = service.stop(); + service.stopAsync(); service.runSecondBarrier.await(); try { - stopHandle.get(); + service.awaitTerminated(); fail(); - } catch (ExecutionException e) { + } catch (IllegalStateException e) { assertEquals(service.shutDownException, e.getCause()); } assertEquals(Service.State.FAILED, service.state()); @@ -118,21 +118,21 @@ public class AbstractScheduledServiceTest extends TestCase { public void testRunOneIterationCalledMultipleTimes() throws Exception { TestService service = new TestService(); - service.startAndWait(); + service.startAsync().awaitRunning(); for (int i = 1; i < 10; i++) { service.runFirstBarrier.await(); assertEquals(i, service.numberOfTimesRunCalled.get()); service.runSecondBarrier.await(); } service.runFirstBarrier.await(); - service.stop(); + service.stopAsync(); service.runSecondBarrier.await(); - service.stopAndWait(); + service.stopAsync().awaitTerminated(); } public void testExecutorOnlyCalledOnce() throws Exception { TestService service = new TestService(); - service.startAndWait(); + service.startAsync().awaitRunning(); // It should be called once during startup. assertEquals(1, service.numberOfTimesExecutorCalled.get()); for (int i = 1; i < 10; i++) { @@ -141,9 +141,9 @@ public class AbstractScheduledServiceTest extends TestCase { service.runSecondBarrier.await(); } service.runFirstBarrier.await(); - service.stop(); + service.stopAsync(); service.runSecondBarrier.await(); - service.stopAndWait(); + service.stopAsync().awaitTerminated(); // Only called once overall. assertEquals(1, service.numberOfTimesExecutorCalled.get()); } @@ -159,13 +159,9 @@ public class AbstractScheduledServiceTest extends TestCase { executorService = super.executor(); // Add a listener that will be executed after the listener that shuts down the executor. addListener(new Listener() { - @Override public void starting() {} - @Override public void running() {} - @Override public void stopping(State from) {} @Override public void terminated(State from) { terminationLatch.countDown(); } - @Override public void failed(State from, Throwable failure) {} }, MoreExecutors.sameThreadExecutor()); } return executorService; @@ -175,10 +171,10 @@ public class AbstractScheduledServiceTest extends TestCase { return Scheduler.newFixedDelaySchedule(0, 1, TimeUnit.MILLISECONDS); }}; - service.start(); + service.startAsync(); assertFalse(service.executor().isShutdown()); - service.startAndWait(); - service.stop(); + service.awaitRunning(); + service.stopAsync(); terminationLatch.await(); assertTrue(service.executor().isShutdown()); assertTrue(service.executor().awaitTermination(100, TimeUnit.MILLISECONDS)); @@ -199,11 +195,6 @@ public class AbstractScheduledServiceTest extends TestCase { executorService = super.executor(); // Add a listener that will be executed after the listener that shuts down the executor. addListener(new Listener() { - @Override public void starting() {} - @Override public void running() {} - @Override public void stopping(State from) {} - @Override public void terminated(State from) { - } @Override public void failed(State from, Throwable failure) { failureLatch.countDown(); } @@ -217,11 +208,9 @@ public class AbstractScheduledServiceTest extends TestCase { }}; try { - service.startAndWait(); + service.startAsync().awaitRunning(); fail("Expected service to fail during startup"); - } catch (UncheckedExecutionException e) { - // expected - } + } catch (IllegalStateException expected) {} failureLatch.await(); assertTrue(service.executor().isShutdown()); assertTrue(service.executor().awaitTermination(100, TimeUnit.MILLISECONDS)); @@ -229,7 +218,7 @@ public class AbstractScheduledServiceTest extends TestCase { public void testSchedulerOnlyCalledOnce() throws Exception { TestService service = new TestService(); - service.startAndWait(); + service.startAsync().awaitRunning(); // It should be called once during startup. assertEquals(1, service.numberOfTimesSchedulerCalled.get()); for (int i = 1; i < 10; i++) { @@ -238,9 +227,9 @@ public class AbstractScheduledServiceTest extends TestCase { service.runSecondBarrier.await(); } service.runFirstBarrier.await(); - service.stop(); + service.stopAsync(); service.runSecondBarrier.await(); - service.stopAndWait(); + service.awaitTerminated(); // Only called once overall. assertEquals(1, service.numberOfTimesSchedulerCalled.get()); } @@ -391,12 +380,12 @@ public class AbstractScheduledServiceTest extends TestCase { public void testCustomSchedulerServiceStop() throws Exception { TestAbstractScheduledCustomService service = new TestAbstractScheduledCustomService(); - service.startAndWait(); + service.startAsync().awaitRunning(); service.firstBarrier.await(); assertEquals(1, service.numIterations.get()); - service.stop(); + service.stopAsync(); service.secondBarrier.await(); - service.stopAndWait(); + service.awaitTerminated(); // Sleep for a while just to ensure that our task wasn't called again. Thread.sleep(unit.toMillis(3 * delay)); assertEquals(1, service.numIterations.get()); @@ -416,14 +405,14 @@ public class AbstractScheduledServiceTest extends TestCase { } }; service.useBarriers = false; - service.startAndWait(); + service.startAsync().awaitRunning(); Thread.sleep(50); service.useBarriers = true; service.firstBarrier.await(); int numIterations = service.numIterations.get(); - service.stop(); + service.stopAsync(); service.secondBarrier.await(); - service.stopAndWait(); + service.awaitTerminated(); assertEquals(numIterations, service.numIterations.get()); } @@ -461,7 +450,7 @@ public class AbstractScheduledServiceTest extends TestCase { public void testCustomSchedulerFailure() throws Exception { TestFailingCustomScheduledService service = new TestFailingCustomScheduledService(); - service.startAndWait(); + service.startAsync().awaitRunning(); for (int i = 1; i < 4; i++) { service.firstBarrier.await(); assertEquals(i, service.numIterations.get()); @@ -469,9 +458,9 @@ public class AbstractScheduledServiceTest extends TestCase { } Thread.sleep(1000); try { - service.stop().get(100, TimeUnit.SECONDS); + service.stopAsync().awaitTerminated(100, TimeUnit.SECONDS); fail(); - } catch (ExecutionException e) { + } catch (IllegalStateException e) { assertEquals(State.FAILED, service.state()); } } diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java index 7dcbf39..5ebd205 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java @@ -25,16 +25,17 @@ import com.google.common.collect.Lists; import com.google.common.util.concurrent.Service.Listener; import com.google.common.util.concurrent.Service.State; +import junit.framework.TestCase; + import java.lang.Thread.UncaughtExceptionHandler; import java.util.List; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import javax.annotation.concurrent.GuardedBy; -import junit.framework.TestCase; - /** * Unit test for {@link AbstractService}. * @@ -42,6 +43,7 @@ import junit.framework.TestCase; */ public class AbstractServiceTest extends TestCase { + private static final long LONG_TIMEOUT_MILLIS = 2500; private Thread executionThread; private Throwable thrownByExecutionThread; @@ -53,12 +55,12 @@ public class AbstractServiceTest extends TestCase { assertFalse(service.isRunning()); assertFalse(service.running); - service.start(); + service.startAsync(); assertEquals(State.RUNNING, service.state()); assertTrue(service.isRunning()); assertTrue(service.running); - service.stop(); + service.stopAsync(); assertEquals(State.TERMINATED, service.state()); assertFalse(service.isRunning()); assertFalse(service.running); @@ -74,22 +76,31 @@ public class AbstractServiceTest extends TestCase { public void testNoOpServiceStartAndWaitStopAndWait() throws Exception { NoOpService service = new NoOpService(); - service.start().get(); + service.startAsync().awaitRunning(); assertEquals(State.RUNNING, service.state()); - service.stop().get(); + service.stopAsync().awaitTerminated(); assertEquals(State.TERMINATED, service.state()); } - public void testNoOpServiceStartStopIdempotence() throws Exception { + public void testNoOpServiceStartAsyncAndAwaitStopAsyncAndAwait() throws Exception { + NoOpService service = new NoOpService(); + + service.startAsync().awaitRunning(); + assertEquals(State.RUNNING, service.state()); + + service.stopAsync().awaitTerminated(); + assertEquals(State.TERMINATED, service.state()); + } + + public void testNoOpServiceStopIdempotence() throws Exception { NoOpService service = new NoOpService(); RecordingListener listener = RecordingListener.record(service); - service.start(); - service.start(); + service.startAsync().awaitRunning(); assertEquals(State.RUNNING, service.state()); - service.stop(); - service.stop(); + service.stopAsync(); + service.stopAsync(); assertEquals(State.TERMINATED, service.state()); assertEquals( ImmutableList.of( @@ -100,27 +111,24 @@ public class AbstractServiceTest extends TestCase { listener.getStateHistory()); } - public void testNoOpServiceStartStopIdempotenceAfterWait() throws Exception { + public void testNoOpServiceStopIdempotenceAfterWait() throws Exception { NoOpService service = new NoOpService(); - service.start().get(); - service.start(); - assertEquals(State.RUNNING, service.state()); + service.startAsync().awaitRunning(); - service.stop().get(); - service.stop(); + service.stopAsync().awaitTerminated(); + service.stopAsync(); assertEquals(State.TERMINATED, service.state()); } - public void testNoOpServiceStartStopIdempotenceDoubleWait() throws Exception { + public void testNoOpServiceStopIdempotenceDoubleWait() throws Exception { NoOpService service = new NoOpService(); - service.start().get(); - service.start().get(); + service.startAsync().awaitRunning(); assertEquals(State.RUNNING, service.state()); - service.stop().get(); - service.stop().get(); + service.stopAsync().awaitTerminated(); + service.stopAsync().awaitTerminated(); assertEquals(State.TERMINATED, service.state()); } @@ -130,10 +138,10 @@ public class AbstractServiceTest extends TestCase { currentThread().interrupt(); try { - service.startAndWait(); + service.startAsync().awaitRunning(); assertEquals(State.RUNNING, service.state()); - service.stopAndWait(); + service.stopAsync().awaitTerminated(); assertEquals(State.TERMINATED, service.state()); assertTrue(currentThread().isInterrupted()); @@ -162,7 +170,7 @@ public class AbstractServiceTest extends TestCase { ManualSwitchedService service = new ManualSwitchedService(); RecordingListener listener = RecordingListener.record(service); - service.start(); + service.startAsync(); assertEquals(State.STARTING, service.state()); assertFalse(service.isRunning()); assertTrue(service.doStartCalled); @@ -171,7 +179,7 @@ public class AbstractServiceTest extends TestCase { assertEquals(State.RUNNING, service.state()); assertTrue(service.isRunning()); - service.stop(); + service.stopAsync(); assertEquals(State.STOPPING, service.state()); assertFalse(service.isRunning()); assertTrue(service.doStopCalled); @@ -193,7 +201,7 @@ public class AbstractServiceTest extends TestCase { ManualSwitchedService service = new ManualSwitchedService(); RecordingListener listener = RecordingListener.record(service); - service.start(); + service.startAsync(); service.notifyStarted(); service.notifyStopped(); assertEquals(State.TERMINATED, service.state()); @@ -212,12 +220,12 @@ public class AbstractServiceTest extends TestCase { ManualSwitchedService service = new ManualSwitchedService(); RecordingListener listener = RecordingListener.record(service); - service.start(); + service.startAsync(); assertEquals(State.STARTING, service.state()); assertFalse(service.isRunning()); assertTrue(service.doStartCalled); - service.stop(); + service.stopAsync(); assertEquals(State.STOPPING, service.state()); assertFalse(service.isRunning()); assertFalse(service.doStopCalled); @@ -238,11 +246,32 @@ public class AbstractServiceTest extends TestCase { listener.getStateHistory()); } + /** + * This tests for a bug where if {@link Service#stopAsync()} was called while the service was + * {@link State#STARTING} more than once, the {@link Listener#stopping(State)} callback would get + * called multiple times. + */ + public void testManualServiceStopMultipleTimesWhileStarting() throws Exception { + ManualSwitchedService service = new ManualSwitchedService(); + final AtomicInteger stopppingCount = new AtomicInteger(); + service.addListener(new Listener() { + @Override public void stopping(State from) { + stopppingCount.incrementAndGet(); + } + }, MoreExecutors.sameThreadExecutor()); + + service.startAsync(); + service.stopAsync(); + assertEquals(1, stopppingCount.get()); + service.stopAsync(); + assertEquals(1, stopppingCount.get()); + } + public void testManualServiceStopWhileNew() throws Exception { ManualSwitchedService service = new ManualSwitchedService(); RecordingListener listener = RecordingListener.record(service); - service.stop(); + service.stopAsync(); assertEquals(State.TERMINATED, service.state()); assertFalse(service.isRunning()); assertFalse(service.doStartCalled); @@ -253,7 +282,7 @@ public class AbstractServiceTest extends TestCase { public void testManualServiceFailWhileStarting() throws Exception { ManualSwitchedService service = new ManualSwitchedService(); RecordingListener listener = RecordingListener.record(service); - service.start(); + service.startAsync(); service.notifyFailed(EXCEPTION); assertEquals(ImmutableList.of(State.STARTING, State.FAILED), listener.getStateHistory()); } @@ -261,7 +290,7 @@ public class AbstractServiceTest extends TestCase { public void testManualServiceFailWhileRunning() throws Exception { ManualSwitchedService service = new ManualSwitchedService(); RecordingListener listener = RecordingListener.record(service); - service.start(); + service.startAsync(); service.notifyStarted(); service.notifyFailed(EXCEPTION); assertEquals(ImmutableList.of(State.STARTING, State.RUNNING, State.FAILED), @@ -271,9 +300,9 @@ public class AbstractServiceTest extends TestCase { public void testManualServiceFailWhileStopping() throws Exception { ManualSwitchedService service = new ManualSwitchedService(); RecordingListener listener = RecordingListener.record(service); - service.start(); + service.startAsync(); service.notifyStarted(); - service.stop(); + service.stopAsync(); service.notifyFailed(EXCEPTION); assertEquals(ImmutableList.of(State.STARTING, State.RUNNING, State.STOPPING, State.FAILED), listener.getStateHistory()); @@ -282,7 +311,7 @@ public class AbstractServiceTest extends TestCase { public void testManualServiceUnrequestedStop() { ManualSwitchedService service = new ManualSwitchedService(); - service.start(); + service.startAsync(); service.notifyStarted(); assertEquals(State.RUNNING, service.state()); @@ -297,7 +326,7 @@ public class AbstractServiceTest extends TestCase { /** * The user of this service should call {@link #notifyStarted} and {@link - * #notifyStopped} after calling {@link #start} and {@link #stop}. + * #notifyStopped} after calling {@link #startAsync} and {@link #stopAsync}. */ private static class ManualSwitchedService extends AbstractService { boolean doStartCalled = false; @@ -314,15 +343,55 @@ public class AbstractServiceTest extends TestCase { } } + public void testAwaitTerminated() throws Exception { + final NoOpService service = new NoOpService(); + Thread waiter = new Thread() { + @Override public void run() { + service.awaitTerminated(); + } + }; + waiter.start(); + service.startAsync().awaitRunning(); + assertEquals(State.RUNNING, service.state()); + service.stopAsync(); + waiter.join(LONG_TIMEOUT_MILLIS); // ensure that the await in the other thread is triggered + assertFalse(waiter.isAlive()); + } + + public void testAwaitTerminated_FailedService() throws Exception { + final ManualSwitchedService service = new ManualSwitchedService(); + final AtomicReference<Throwable> exception = Atomics.newReference(); + Thread waiter = new Thread() { + @Override public void run() { + try { + service.awaitTerminated(); + fail("Expected an IllegalStateException"); + } catch (Throwable t) { + exception.set(t); + } + } + }; + waiter.start(); + service.startAsync(); + service.notifyStarted(); + assertEquals(State.RUNNING, service.state()); + service.notifyFailed(EXCEPTION); + assertEquals(State.FAILED, service.state()); + waiter.join(LONG_TIMEOUT_MILLIS); + assertFalse(waiter.isAlive()); + assertTrue(exception.get() instanceof IllegalStateException); + assertEquals(EXCEPTION, exception.get().getCause()); + } + public void testThreadedServiceStartAndWaitStopAndWait() throws Throwable { ThreadedService service = new ThreadedService(); RecordingListener listener = RecordingListener.record(service); - service.start().get(); + service.startAsync().awaitRunning(); assertEquals(State.RUNNING, service.state()); service.awaitRunChecks(); - service.stopAndWait(); + service.stopAsync().awaitTerminated(); assertEquals(State.TERMINATED, service.state()); throwIfSet(thrownByExecutionThread); @@ -335,34 +404,32 @@ public class AbstractServiceTest extends TestCase { listener.getStateHistory()); } - public void testThreadedServiceStartStopIdempotence() throws Throwable { + public void testThreadedServiceStopIdempotence() throws Throwable { ThreadedService service = new ThreadedService(); - service.start(); - service.start().get(); + service.startAsync().awaitRunning(); assertEquals(State.RUNNING, service.state()); service.awaitRunChecks(); - service.stop(); - service.stop().get(); + service.stopAsync(); + service.stopAsync().awaitTerminated(); assertEquals(State.TERMINATED, service.state()); throwIfSet(thrownByExecutionThread); } - public void testThreadedServiceStartStopIdempotenceAfterWait() + public void testThreadedServiceStopIdempotenceAfterWait() throws Throwable { ThreadedService service = new ThreadedService(); - service.start().get(); - service.start(); + service.startAsync().awaitRunning(); assertEquals(State.RUNNING, service.state()); service.awaitRunChecks(); - service.stop().get(); - service.stop(); + service.stopAsync().awaitTerminated(); + service.stopAsync(); assertEquals(State.TERMINATED, service.state()); executionThread.join(); @@ -370,18 +437,17 @@ public class AbstractServiceTest extends TestCase { throwIfSet(thrownByExecutionThread); } - public void testThreadedServiceStartStopIdempotenceDoubleWait() + public void testThreadedServiceStopIdempotenceDoubleWait() throws Throwable { ThreadedService service = new ThreadedService(); - service.start().get(); - service.start().get(); + service.startAsync().awaitRunning(); assertEquals(State.RUNNING, service.state()); service.awaitRunChecks(); - service.stop().get(); - service.stop().get(); + service.stopAsync().awaitTerminated(); + service.stopAsync().awaitTerminated(); assertEquals(State.TERMINATED, service.state()); throwIfSet(thrownByExecutionThread); @@ -390,13 +456,14 @@ public class AbstractServiceTest extends TestCase { public void testManualServiceFailureIdempotence() { ManualSwitchedService service = new ManualSwitchedService(); RecordingListener.record(service); - service.start(); + service.startAsync(); service.notifyFailed(new Exception("1")); service.notifyFailed(new Exception("2")); + assertEquals("1", service.failureCause().getMessage()); try { - service.startAndWait(); + service.awaitRunning(); fail(); - } catch (UncheckedExecutionException e) { + } catch (IllegalStateException e) { assertEquals("1", e.getCause().getMessage()); } } @@ -463,13 +530,13 @@ public class AbstractServiceTest extends TestCase { NoOpService service = new NoOpService(); RecordingListener listener = RecordingListener.record(service); - Future<State> stopResult = service.stop(); + service.stopAsync(); assertEquals(State.TERMINATED, service.state()); - assertEquals(State.TERMINATED, stopResult.get()); - Future<State> startResult = service.start(); - assertEquals(State.TERMINATED, service.state()); - assertEquals(State.TERMINATED, startResult.get()); + try { + service.startAsync(); + fail(); + } catch (IllegalStateException expected) {} assertEquals(State.TERMINATED, Iterables.getOnlyElement(listener.getStateHistory())); } @@ -478,9 +545,10 @@ public class AbstractServiceTest extends TestCase { RecordingListener listener = RecordingListener.record(service); try { - service.startAndWait(); + service.startAsync().awaitRunning(); fail(); - } catch (UncheckedExecutionException e) { + } catch (IllegalStateException e) { + assertEquals(EXCEPTION, service.failureCause()); assertEquals(EXCEPTION, e.getCause()); } assertEquals( @@ -494,11 +562,12 @@ public class AbstractServiceTest extends TestCase { StopFailingService service = new StopFailingService(); RecordingListener listener = RecordingListener.record(service); - service.startAndWait(); + service.startAsync().awaitRunning(); try { - service.stopAndWait(); + service.stopAsync().awaitTerminated(); fail(); - } catch (UncheckedExecutionException e) { + } catch (IllegalStateException e) { + assertEquals(EXCEPTION, service.failureCause()); assertEquals(EXCEPTION, e.getCause()); } assertEquals( @@ -510,16 +579,17 @@ public class AbstractServiceTest extends TestCase { listener.getStateHistory()); } - public void testFailingServiceStopAndWait_runFailinging() throws Exception { + public void testFailingServiceStopAndWait_runFailing() throws Exception { RunFailingService service = new RunFailingService(); RecordingListener listener = RecordingListener.record(service); - service.startAndWait(); + service.startAsync(); try { - service.stopAndWait(); + service.awaitRunning(); fail(); - } catch (UncheckedExecutionException e) { - assertEquals(EXCEPTION, e.getCause().getCause()); + } catch (IllegalStateException e) { + assertEquals(EXCEPTION, service.failureCause()); + assertEquals(EXCEPTION, e.getCause()); } assertEquals( ImmutableList.of( @@ -534,9 +604,10 @@ public class AbstractServiceTest extends TestCase { RecordingListener listener = RecordingListener.record(service); try { - service.startAndWait(); + service.startAsync().awaitRunning(); fail(); - } catch (UncheckedExecutionException e) { + } catch (IllegalStateException e) { + assertEquals(service.exception, service.failureCause()); assertEquals(service.exception, e.getCause()); } assertEquals( @@ -550,11 +621,12 @@ public class AbstractServiceTest extends TestCase { StopThrowingService service = new StopThrowingService(); RecordingListener listener = RecordingListener.record(service); - service.startAndWait(); + service.startAsync().awaitRunning(); try { - service.stopAndWait(); + service.stopAsync().awaitTerminated(); fail(); - } catch (UncheckedExecutionException e) { + } catch (IllegalStateException e) { + assertEquals(service.exception, service.failureCause()); assertEquals(service.exception, e.getCause()); } assertEquals( @@ -570,12 +642,13 @@ public class AbstractServiceTest extends TestCase { RunThrowingService service = new RunThrowingService(); RecordingListener listener = RecordingListener.record(service); - service.startAndWait(); + service.startAsync(); try { - service.stopAndWait(); + service.awaitTerminated(); fail(); - } catch (UncheckedExecutionException e) { - assertEquals(service.exception, e.getCause().getCause()); + } catch (IllegalStateException e) { + assertEquals(service.exception, service.failureCause()); + assertEquals(service.exception, e.getCause()); } assertEquals( ImmutableList.of( @@ -593,7 +666,7 @@ public class AbstractServiceTest extends TestCase { } catch (IllegalStateException e) { // expected } - service.startAndWait(); + service.startAsync().awaitRunning(); try { service.failureCause(); fail(); @@ -601,9 +674,9 @@ public class AbstractServiceTest extends TestCase { // expected } try { - service.stopAndWait(); + service.stopAsync().awaitTerminated(); fail(); - } catch (UncheckedExecutionException e) { + } catch (IllegalStateException e) { assertEquals(EXCEPTION, service.failureCause()); assertEquals(EXCEPTION, e.getCause()); } @@ -611,60 +684,58 @@ public class AbstractServiceTest extends TestCase { public void testAddListenerAfterFailureDoesntCauseDeadlock() throws InterruptedException { final StartFailingService service = new StartFailingService(); - service.start(); + service.startAsync(); assertEquals(State.FAILED, service.state()); service.addListener(new RecordingListener(service), MoreExecutors.sameThreadExecutor()); Thread thread = new Thread() { @Override public void run() { - // Internally start() grabs a lock, this could be any such method on AbstractService. - service.start(); + // Internally stopAsync() grabs a lock, this could be any such method on AbstractService. + service.stopAsync(); } }; thread.start(); - thread.join(100); + thread.join(LONG_TIMEOUT_MILLIS); assertFalse(thread + " is deadlocked", thread.isAlive()); } public void testListenerDoesntDeadlockOnStartAndWaitFromRunning() throws Exception { final NoOpThreadedService service = new NoOpThreadedService(); service.addListener(new Listener() { - @Override public void starting() { } @Override public void running() { - service.startAndWait(); + service.awaitRunning(); } - @Override public void stopping(State from) { } - @Override public void terminated(State from) { } - @Override public void failed(State from, Throwable failure) { } }, MoreExecutors.sameThreadExecutor()); - service.start().get(10, TimeUnit.MILLISECONDS); - service.stop(); + service.startAsync().awaitRunning(LONG_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + service.stopAsync(); } public void testListenerDoesntDeadlockOnStopAndWaitFromTerminated() throws Exception { final NoOpThreadedService service = new NoOpThreadedService(); service.addListener(new Listener() { - @Override public void starting() { } - @Override public void running() { } - @Override public void stopping(State from) { } @Override public void terminated(State from) { - service.stopAndWait(); + service.stopAsync().awaitTerminated(); } - @Override public void failed(State from, Throwable failure) { } }, MoreExecutors.sameThreadExecutor()); - service.startAndWait(); + service.startAsync().awaitRunning(); Thread thread = new Thread() { @Override public void run() { - service.stopAndWait(); + service.stopAsync().awaitTerminated(); } }; thread.start(); - thread.join(100); + thread.join(LONG_TIMEOUT_MILLIS); assertFalse(thread + " is deadlocked", thread.isAlive()); } private static class NoOpThreadedService extends AbstractExecutionThreadService { - @Override protected void run() throws Exception {} + final CountDownLatch latch = new CountDownLatch(1); + @Override protected void run() throws Exception { + latch.await(); + } + @Override protected void triggerShutdown() { + latch.countDown(); + } } private static class StartFailingService extends AbstractService { @@ -738,7 +809,7 @@ public class AbstractServiceTest extends TestCase { } } - private static class RecordingListener implements Listener { + private static class RecordingListener extends Listener { static RecordingListener record(Service service) { RecordingListener listener = new RecordingListener(service); service.addListener(listener, MoreExecutors.sameThreadExecutor()); @@ -771,8 +842,7 @@ public class AbstractServiceTest extends TestCase { @Override public synchronized void running() { assertEquals(State.STARTING, Iterables.getOnlyElement(stateHistory)); stateHistory.add(State.RUNNING); - assertTrue(service.start().isDone()); - assertEquals(State.RUNNING, service.startAndWait()); + service.awaitRunning(); assertNotSame(State.STARTING, service.state()); } @@ -780,8 +850,14 @@ public class AbstractServiceTest extends TestCase { assertEquals(from, Iterables.getLast(stateHistory)); stateHistory.add(State.STOPPING); if (from == State.STARTING) { - assertTrue(service.start().isDone()); - assertEquals(State.STOPPING, service.startAndWait()); + try { + service.awaitRunning(); + fail(); + } catch (IllegalStateException expected) { + assertNull(expected.getCause()); + assertTrue(expected.getMessage().equals( + "Expected the service to be RUNNING, but was STOPPING")); + } } assertNotSame(from, service.state()); } @@ -790,12 +866,16 @@ public class AbstractServiceTest extends TestCase { assertEquals(from, Iterables.getLast(stateHistory, State.NEW)); stateHistory.add(State.TERMINATED); assertEquals(State.TERMINATED, service.state()); - assertTrue(service.start().isDone()); if (from == State.NEW) { - assertEquals(State.TERMINATED, service.startAndWait()); + try { + service.awaitRunning(); + fail(); + } catch (IllegalStateException expected) { + assertNull(expected.getCause()); + assertTrue(expected.getMessage().equals( + "Expected the service to be RUNNING, but was TERMINATED")); + } } - assertTrue(service.stop().isDone()); - assertEquals(State.TERMINATED, service.stopAndWait()); completionLatch.countDown(); } @@ -803,23 +883,20 @@ public class AbstractServiceTest extends TestCase { assertEquals(from, Iterables.getLast(stateHistory)); stateHistory.add(State.FAILED); assertEquals(State.FAILED, service.state()); + assertEquals(failure, service.failureCause()); if (from == State.STARTING) { try { - service.startAndWait(); + service.awaitRunning(); fail(); - } catch (UncheckedExecutionException e) { + } catch (IllegalStateException e) { assertEquals(failure, e.getCause()); } } try { - service.stopAndWait(); + service.awaitTerminated(); fail(); - } catch (UncheckedExecutionException e) { - if (from == State.STOPPING) { - assertEquals(failure, e.getCause()); - } else { - assertEquals(failure, e.getCause().getCause()); - } + } catch (IllegalStateException e) { + assertEquals(failure, e.getCause()); } completionLatch.countDown(); } @@ -851,8 +928,8 @@ public class AbstractServiceTest extends TestCase { public void testNotifyFailedWhenTerminated() { NoOpService service = new NoOpService(); - service.startAndWait(); - service.stopAndWait(); + service.startAsync().awaitRunning(); + service.stopAsync().awaitTerminated(); try { service.notifyFailed(new Exception()); fail(); diff --git a/guava-tests/test/com/google/common/util/concurrent/AsyncSettableFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/AsyncSettableFutureTest.java new file mode 100644 index 0000000..1ffd307 --- /dev/null +++ b/guava-tests/test/com/google/common/util/concurrent/AsyncSettableFutureTest.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.util.concurrent; + +import junit.framework.TestCase; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Tests that {@code AsyncSettableFuture} is a valid {@link ListenableFuture} + * that behaves itself as expected. + */ + +public class AsyncSettableFutureTest extends TestCase { + + private static class Foo {} + private static class FooChild extends Foo {} + + /** Tests the initial state of the future. */ + public void testCreate() throws Exception { + AsyncSettableFuture<Integer> future = AsyncSettableFuture.create(); + assertFalse(future.isSet()); + assertFalse(future.isDone()); + assertFalse(future.isCancelled()); + } + + public void testSetValue() throws Exception { + AsyncSettableFuture<Integer> future = AsyncSettableFuture.create(); + assertTrue(future.setValue(42)); + assertTrue(future.isSet()); + // Later attempts to set the future should return false. + assertFalse(future.setValue(23)); + assertFalse(future.setException(new Exception("bar"))); + assertFalse(future.setFuture(SettableFuture.<Integer>create())); + // Check that the future has been set properly. + assertTrue(future.isDone()); + assertFalse(future.isCancelled()); + assertEquals(42, (int) future.get()); + } + + public void testSetException() throws Exception { + AsyncSettableFuture<Object> future = AsyncSettableFuture.create(); + Exception e = new Exception("foobarbaz"); + assertTrue(future.setException(e)); + assertTrue(future.isSet()); + // Later attempts to set the future should return false. + assertFalse(future.setValue(23)); + assertFalse(future.setException(new Exception("quux"))); + assertFalse(future.setFuture(SettableFuture.create())); + // Check that the future has been set properly. + assertTrue(future.isDone()); + assertFalse(future.isCancelled()); + try { + future.get(); + fail("Expected ExecutionException"); + } catch (ExecutionException ee) { + assertSame(e, ee.getCause()); + } + } + + public void testSetFuture() throws Exception { + AsyncSettableFuture<String> future = AsyncSettableFuture.create(); + SettableFuture<String> nested = SettableFuture.create(); + assertTrue(future.setFuture(nested)); + assertTrue(future.isSet()); + // Later attempts to set the future should return false. + assertFalse(future.setValue("x")); + assertFalse(future.setException(new Exception("bar"))); + assertFalse(future.setFuture(SettableFuture.<String>create())); + // Check that the future has been set properly. + assertFalse(future.isDone()); + assertFalse(future.isCancelled()); + try { + future.get(0, TimeUnit.MILLISECONDS); + fail("Expected TimeoutException"); + } catch (TimeoutException expected) { /* expected */ } + nested.set("foo"); + assertTrue(future.isDone()); + assertFalse(future.isCancelled()); + assertEquals("foo", future.get()); + } + + public void testSetFuture_genericsHierarchy() throws Exception { + AsyncSettableFuture<Foo> future = AsyncSettableFuture.create(); + SettableFuture<FooChild> nested = SettableFuture.create(); + assertTrue(future.setFuture(nested)); + assertTrue(future.isSet()); + // Later attempts to set the future should return false. + assertFalse(future.setValue(new Foo())); + assertFalse(future.setException(new Exception("bar"))); + assertFalse(future.setFuture(SettableFuture.<Foo>create())); + // Check that the future has been set properly. + assertFalse(future.isDone()); + assertFalse(future.isCancelled()); + try { + future.get(0, TimeUnit.MILLISECONDS); + fail("Expected TimeoutException"); + } catch (TimeoutException expected) { /* expected */ } + FooChild value = new FooChild(); + nested.set(value); + assertTrue(future.isDone()); + assertFalse(future.isCancelled()); + assertSame(value, future.get()); + } + + public void testCancel_innerCancelsAsync() throws Exception { + AsyncSettableFuture<Object> async = AsyncSettableFuture.create(); + SettableFuture<Object> inner = SettableFuture.create(); + async.setFuture(inner); + inner.cancel(true); + assertTrue(async.isCancelled()); + try { + async.get(); + fail("Expected CancellationException"); + } catch (CancellationException expected) { /* expected */ } + } + + public void testCancel_resultCancelsInner_interrupted() throws Exception { + AsyncSettableFuture<Object> async = AsyncSettableFuture.create(); + MyFuture<Object> inner = new MyFuture<Object>(); + async.setFuture(inner); + async.cancel(true); + assertTrue(inner.isCancelled()); + assertTrue(inner.myWasInterrupted()); + try { + inner.get(); + fail("Expected CancellationException"); + } catch (CancellationException expected) { /* expected */ } + } + + public void testCancel_resultCancelsInner() throws Exception { + AsyncSettableFuture<Object> async = AsyncSettableFuture.create(); + MyFuture<Object> inner = new MyFuture<Object>(); + async.setFuture(inner); + async.cancel(false); + assertTrue(inner.isCancelled()); + assertFalse(inner.myWasInterrupted()); + try { + inner.get(); + fail("Expected CancellationException"); + } catch (CancellationException expected) { /* expected */ } + } + + public void testCancel_beforeSet() throws Exception { + AsyncSettableFuture<Object> async = AsyncSettableFuture.create(); + async.cancel(true); + assertFalse(async.setValue(42)); + } + + public void testCancel_multipleBeforeSetFuture_noInterruptFirst() throws Exception { + AsyncSettableFuture<Object> async = AsyncSettableFuture.create(); + async.cancel(false); + async.cancel(true); + MyFuture<Object> inner = new MyFuture<Object>(); + assertFalse(async.setFuture(inner)); + assertTrue(inner.isCancelled()); + assertFalse(inner.myWasInterrupted()); + } + + public void testCancel_multipleBeforeSetFuture_interruptFirst() throws Exception { + AsyncSettableFuture<Object> async = AsyncSettableFuture.create(); + async.cancel(true); + async.cancel(false); + MyFuture<Object> inner = new MyFuture<Object>(); + assertFalse(async.setFuture(inner)); + assertTrue(inner.isCancelled()); + assertTrue(inner.myWasInterrupted()); + } + + private static class MyFuture<V> extends AbstractFuture<V> { + boolean myWasInterrupted() { + // we need a new method since wasInterrupted is final, so we can't increase its visibility. + return wasInterrupted(); + } + } +} diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java index d2abf04..7ad3a4a 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java @@ -13,6 +13,8 @@ package com.google.common.util.concurrent; +import junit.framework.*; + import java.util.Arrays; /** @@ -23,8 +25,8 @@ public class AtomicDoubleArrayTest extends JSR166TestCase { private static final double[] VALUES = { Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, - Long.MIN_VALUE, - Integer.MIN_VALUE, + (double) Long.MIN_VALUE, + (double) Integer.MIN_VALUE, -Math.PI, -1.0, -Double.MIN_VALUE, @@ -33,8 +35,8 @@ public class AtomicDoubleArrayTest extends JSR166TestCase { Double.MIN_VALUE, 1.0, Math.PI, - Integer.MAX_VALUE, - Long.MAX_VALUE, + (double) Integer.MAX_VALUE, + (double) Long.MAX_VALUE, Double.MAX_VALUE, Double.POSITIVE_INFINITY, Double.NaN, @@ -200,7 +202,6 @@ public class AtomicDoubleArrayTest extends JSR166TestCase { final AtomicDoubleArray a = new AtomicDoubleArray(1); a.set(0, 1.0); Thread t = newStartedThread(new CheckedRunnable() { - @Override public void realRun() { while (!a.compareAndSet(0, 2.0, 3.0)) { Thread.yield(); @@ -288,7 +289,6 @@ public class AtomicDoubleArrayTest extends JSR166TestCase { final AtomicDoubleArray aa; volatile long counts; Counter(AtomicDoubleArray a) { aa = a; } - @Override public void realRun() { for (;;) { boolean done = true; @@ -317,7 +317,7 @@ public class AtomicDoubleArrayTest extends JSR166TestCase { public void testCountingInMultipleThreads() throws InterruptedException { final AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); for (int i = 0; i < SIZE; i++) { - aa.set(i, COUNTDOWN); + aa.set(i, (double) COUNTDOWN); } Counter c1 = new Counter(aa); Counter c2 = new Counter(aa); @@ -334,7 +334,7 @@ public class AtomicDoubleArrayTest extends JSR166TestCase { public void testSerialization() throws Exception { AtomicDoubleArray x = new AtomicDoubleArray(SIZE); for (int i = 0; i < SIZE; i++) { - x.set(i, -i); + x.set(i, (double) -i); } AtomicDoubleArray y = serialClone(x); assertTrue(x != y); diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleTest.java index c2bb85b..a45ed2c 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleTest.java @@ -13,6 +13,7 @@ package com.google.common.util.concurrent; +import junit.framework.*; /** * Unit test for {@link AtomicDouble}. @@ -22,8 +23,8 @@ public class AtomicDoubleTest extends JSR166TestCase { private static final double[] VALUES = { Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, - Long.MIN_VALUE, - Integer.MIN_VALUE, + (double) Long.MIN_VALUE, + (double) Integer.MIN_VALUE, -Math.PI, -1.0, -Double.MIN_VALUE, @@ -32,8 +33,8 @@ public class AtomicDoubleTest extends JSR166TestCase { Double.MIN_VALUE, 1.0, Math.PI, - Integer.MAX_VALUE, - Long.MAX_VALUE, + (double) Integer.MAX_VALUE, + (double) Long.MAX_VALUE, Double.MAX_VALUE, Double.POSITIVE_INFINITY, Double.NaN, @@ -117,7 +118,6 @@ public class AtomicDoubleTest extends JSR166TestCase { public void testCompareAndSetInMultipleThreads() throws Exception { final AtomicDouble at = new AtomicDouble(1.0); Thread t = newStartedThread(new CheckedRunnable() { - @Override public void realRun() { while (!at.compareAndSet(2.0, 3.0)) { Thread.yield(); @@ -195,9 +195,10 @@ public class AtomicDoubleTest extends JSR166TestCase { public void testSerialization() throws Exception { AtomicDouble a = new AtomicDouble(); AtomicDouble b = serialClone(a); - assertTrue(a != b); + assertNotSame(a, b); a.set(-22.0); AtomicDouble c = serialClone(a); + assertNotSame(b, c); assertBitEquals(-22.0, a.get()); assertBitEquals(0.0, b.get()); assertBitEquals(-22.0, c.get()); diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java index c1a3c68..8746e33 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java @@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.util.Map; import java.util.Random; import java.util.Set; @@ -30,8 +32,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import junit.framework.TestCase; - /** * Tests for {@link AtomicLongMap}. * diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java index d34db8b..5a19625 100644 --- a/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java @@ -18,10 +18,10 @@ package com.google.common.util.concurrent; import com.google.common.testing.NullPointerTester; -import java.util.concurrent.atomic.AtomicReferenceArray; - import junit.framework.TestCase; +import java.util.concurrent.atomic.AtomicReferenceArray; + /** * Unit test for {@link Atomics}. * diff --git a/guava-tests/test/com/google/common/util/concurrent/CallablesTest.java b/guava-tests/test/com/google/common/util/concurrent/CallablesTest.java index 41307a7..885b73c 100644 --- a/guava-tests/test/com/google/common/util/concurrent/CallablesTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/CallablesTest.java @@ -16,10 +16,14 @@ package com.google.common.util.concurrent; -import java.util.concurrent.Callable; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import junit.framework.TestCase; +import java.security.Permission; +import java.util.concurrent.Callable; + /** * Unit tests for {@link Callables}. * @@ -36,4 +40,59 @@ public class CallablesTest extends TestCase { // Expect the same value on subsequent calls assertSame(value, callable.call()); } + + public void testRenaming() throws Exception { + String oldName = Thread.currentThread().getName(); + final Supplier<String> newName = Suppliers.ofInstance("MyCrazyThreadName"); + Callable<Void> callable = new Callable<Void>() { + @Override public Void call() throws Exception { + assertEquals(Thread.currentThread().getName(), newName.get()); + return null; + } + }; + Callables.threadRenaming(callable, newName).call(); + assertEquals(oldName, Thread.currentThread().getName()); + } + + public void testRenaming_exceptionalReturn() throws Exception { + String oldName = Thread.currentThread().getName(); + final Supplier<String> newName = Suppliers.ofInstance("MyCrazyThreadName"); + class MyException extends Exception {} + Callable<Void> callable = new Callable<Void>() { + @Override public Void call() throws Exception { + assertEquals(Thread.currentThread().getName(), newName.get()); + throw new MyException(); + } + }; + try { + Callables.threadRenaming(callable, newName).call(); + fail(); + } catch (MyException expected) {} + assertEquals(oldName, Thread.currentThread().getName()); + } + + public void testRenaming_noPermissions() throws Exception { + System.setSecurityManager(new SecurityManager() { + @Override public void checkAccess(Thread t) { + throw new SecurityException(); + } + @Override public void checkPermission(Permission perm) { + // Do nothing so we can clear the security manager at the end + } + }); + try { + final String oldName = Thread.currentThread().getName(); + Supplier<String> newName = Suppliers.ofInstance("MyCrazyThreadName"); + Callable<Void> callable = new Callable<Void>() { + @Override public Void call() throws Exception { + assertEquals(Thread.currentThread().getName(), oldName); + return null; + } + }; + Callables.threadRenaming(callable, newName).call(); + assertEquals(oldName, Thread.currentThread().getName()); + } finally { + System.setSecurityManager(null); + } + } } diff --git a/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java b/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java index 19f95d3..4340c60 100644 --- a/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java @@ -19,6 +19,9 @@ package com.google.common.util.concurrent; import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor; import com.google.common.testing.NullPointerTester; +import com.google.common.util.concurrent.ExecutionList; + +import junit.framework.TestCase; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; @@ -26,8 +29,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import junit.framework.TestCase; - /** * Unit tests for {@link ExecutionList}. * @@ -105,6 +106,22 @@ public class ExecutionListTest extends TestCase { assertTrue(countDownLatch.await(1L, TimeUnit.SECONDS)); } + public void testOrdering() throws Exception { + final AtomicInteger integer = new AtomicInteger(); + for (int i = 0; i < 10; i++) { + final int expectedCount = i; + list.add( + new Runnable() { + @Override public void run() { + integer.compareAndSet(expectedCount, expectedCount + 1); + } + }, + MoreExecutors.sameThreadExecutor()); + } + list.execute(); + assertEquals(10, integer.get()); + } + private class MockRunnable implements Runnable { CountDownLatch countDownLatch; @@ -132,7 +149,4 @@ public class ExecutionListTest extends TestCase { throw new RuntimeException(); } }; - private static final Runnable DO_NOTHING = new Runnable() { - @Override public void run() {} - }; } diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java index 1c5af0b..edc48a9 100644 --- a/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java +++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java @@ -22,11 +22,11 @@ import com.google.common.collect.ForwardingObject; import com.google.common.collect.Iterables; import com.google.common.testing.ForwardingWrapperTester; +import org.easymock.EasyMock; + import java.lang.reflect.Method; import java.util.Arrays; -import org.easymock.EasyMock; - /** * Tester for typical subclass of {@link ForwardingObject} by using EasyMock partial mocks. * diff --git a/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java b/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java index e4f63ba..87367b2 100644 --- a/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java @@ -36,14 +36,20 @@ import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.testing.ClassSanityTester; -import com.google.common.testing.FluentAsserts; +import com.google.common.testing.TestLogHandler; import com.google.common.util.concurrent.ForwardingFuture.SimpleForwardingFuture; +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.easymock.EasyMock; +import org.easymock.IMocksControl; + import java.io.IOException; import java.util.Arrays; -import java.util.Collection; import java.util.List; import java.util.Set; import java.util.concurrent.Callable; @@ -58,16 +64,10 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.logging.Handler; import java.util.logging.LogRecord; +import java.util.logging.Logger; import javax.annotation.Nullable; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - -import org.easymock.EasyMock; -import org.easymock.IMocksControl; -import org.truth0.subjects.CollectionSubject; - /** * Unit tests for {@link Futures}. * @@ -76,6 +76,10 @@ import org.truth0.subjects.CollectionSubject; * @author Nishant Thakkar */ public class FuturesTest extends TestCase { + private static final Logger combinedFutureLogger = Logger.getLogger( + "com.google.common.util.concurrent.Futures$CombinedFuture"); + private final TestLogHandler combinedFutureLogHandler = new TestLogHandler(); + private static final String DATA1 = "data"; private static final String DATA2 = "more data"; private static final String DATA3 = "most data"; @@ -84,7 +88,7 @@ public class FuturesTest extends TestCase { @Override protected void setUp() throws Exception { super.setUp(); - + combinedFutureLogger.addHandler(combinedFutureLogHandler); mocksControl = EasyMock.createControl(); } @@ -96,7 +100,7 @@ public class FuturesTest extends TestCase { * it's hard to imagine that anything will break in practice.) */ Thread.interrupted(); - + combinedFutureLogger.removeHandler(combinedFutureLogHandler); super.tearDown(); } @@ -203,15 +207,14 @@ public class FuturesTest extends TestCase { private static class Bar {} private static class BarChild extends Bar {} - public void testTransform_ListenableFuture_genericsNull() throws Exception { + public void testTransform_genericsNull() throws Exception { ListenableFuture<?> nullFuture = Futures.immediateFuture(null); ListenableFuture<?> transformedFuture = Futures.transform(nullFuture, Functions.constant(null)); assertNull(transformedFuture.get()); } - public void testTransform_ListenableFuture_genericsHierarchy() - throws Exception { + public void testTransform_genericsHierarchy() throws Exception { ListenableFuture<FooChild> future = Futures.immediateFuture(null); final BarChild barChild = new BarChild(); Function<Foo, BarChild> function = new Function<Foo, BarChild>() { @@ -223,12 +226,11 @@ public class FuturesTest extends TestCase { assertSame(barChild, bar); } - public void testTransform_ListenableFuture_cancelPropagatesToInput() throws Exception { + public void testTransform_cancelPropagatesToInput() throws Exception { SettableFuture<Foo> input = SettableFuture.create(); AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() { @Override public ListenableFuture<Bar> apply(Foo unused) { - fail("Unexpeted call to apply."); - return null; + throw new AssertionFailedError("Unexpeted call to apply."); } }; assertTrue(Futures.transform(input, function).cancel(false)); @@ -236,13 +238,11 @@ public class FuturesTest extends TestCase { assertFalse(input.wasInterrupted()); } - public void testTransform_ListenableFuture_interruptPropagatesToInput() - throws Exception { + public void testTransform_interruptPropagatesToInput() throws Exception { SettableFuture<Foo> input = SettableFuture.create(); AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() { @Override public ListenableFuture<Bar> apply(Foo unused) { - fail("Unexpeted call to apply."); - return null; + throw new AssertionFailedError("Unexpeted call to apply."); } }; assertTrue(Futures.transform(input, function).cancel(true)); @@ -250,8 +250,7 @@ public class FuturesTest extends TestCase { assertTrue(input.wasInterrupted()); } - public void testTransform_ListenableFuture_cancelPropagatesToAsyncOutput() - throws Exception { + public void testTransform_cancelPropagatesToAsyncOutput() throws Exception { ListenableFuture<Foo> immediate = Futures.immediateFuture(new Foo()); final SettableFuture<Bar> secondary = SettableFuture.create(); AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() { @@ -264,7 +263,7 @@ public class FuturesTest extends TestCase { assertFalse(secondary.wasInterrupted()); } - public void testTransform_ListenableFuture_interruptPropagatesToAsyncOutput() + public void testTransform_interruptPropagatesToAsyncOutput() throws Exception { ListenableFuture<Foo> immediate = Futures.immediateFuture(new Foo()); final SettableFuture<Bar> secondary = SettableFuture.create(); @@ -279,11 +278,10 @@ public class FuturesTest extends TestCase { } /** - * {@link ListenableFuture} variant of - * {@link #testTransformValueRemainsMemoized_Future()}. + * Tests that the function is invoked only once, even if it throws an + * exception. */ - public void testTransformValueRemainsMemoized_ListenableFuture() - throws Exception { + public void testTransformValueRemainsMemoized() throws Exception { class Holder { int value = 2; } @@ -331,29 +329,26 @@ public class FuturesTest extends TestCase { static class MyRuntimeException extends RuntimeException {} /** - * {@link ListenableFuture} variant of - * {@link #testTransformExceptionRemainsMemoized_Future()}. + * Test that the function is invoked only once, even if it throws an + * exception. Also, test that that function's result is wrapped in an + * ExecutionException. */ - public void testTransformExceptionRemainsMemoized_ListenableFuture() - throws Throwable { - SettableFuture<Integer> input = SettableFuture.create(); - + public void testTransformExceptionRemainsMemoized() throws Throwable { + // We need to test with two input futures since ExecutionList.execute + // doesn't catch Errors and we cannot depend on the order that our + // transformations run. (So it is possible that the Error being thrown + // could prevent our second transformations from running). + SettableFuture<Integer> exceptionInput = SettableFuture.create(); ListenableFuture<Integer> exceptionComposedFuture = - Futures.transform(input, newOneTimeExceptionThrower()); - ListenableFuture<Integer> errorComposedFuture = - Futures.transform(input, newOneTimeErrorThrower()); + Futures.transform(exceptionInput, newOneTimeExceptionThrower()); + exceptionInput.set(0); + runGetIdempotencyTest(exceptionComposedFuture, MyRuntimeException.class); - try { - input.set(0); - fail(); - } catch (MyError expected) { - /* - * The ListenableFuture variant rethrows errors from execute() as well - * as assigning them to the output of the future. - */ - } + SettableFuture<Integer> errorInput = SettableFuture.create(); + ListenableFuture<Integer> errorComposedFuture = + Futures.transform(errorInput, newOneTimeErrorThrower()); + errorInput.set(0); - runGetIdempotencyTest(exceptionComposedFuture, MyRuntimeException.class); runGetIdempotencyTest(errorComposedFuture, MyError.class); /* @@ -361,14 +356,11 @@ public class FuturesTest extends TestCase { * slightly different in that case. */ exceptionComposedFuture = - Futures.transform(input, newOneTimeExceptionThrower()); + Futures.transform(exceptionInput, newOneTimeExceptionThrower()); runGetIdempotencyTest(exceptionComposedFuture, MyRuntimeException.class); - try { - Futures.transform(input, newOneTimeErrorThrower()); - fail(); - } catch (MyError expected) { - } + runGetIdempotencyTest(Futures.transform(errorInput, newOneTimeErrorThrower()), MyError.class); + runGetIdempotencyTest(errorComposedFuture, MyError.class); } private static void runGetIdempotencyTest(Future<Integer> transformedFuture, @@ -385,20 +377,6 @@ public class FuturesTest extends TestCase { } } - private static <I, O> Function<I, O> newOneTimeValueReturner(final O output) { - return new Function<I, O>() { - int calls = 0; - - @Override - public O apply(I arg0) { - if (++calls > 1) { - fail(); - } - return output; - } - }; - } - private static Function<Integer, Integer> newOneTimeExceptionThrower() { return new Function<Integer, Integer>() { int calls = 0; @@ -543,19 +521,19 @@ public class FuturesTest extends TestCase { @SuppressWarnings("unchecked") public void testWithFallback_fallbackGeneratesError() throws Exception { - Error error = new Error("deliberate"); - FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class); - RuntimeException raisedException = new RuntimeException(); - expect(fallback.create(raisedException)).andThrow(error); - ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException); - mocksControl.replay(); + final Error error = new Error("deliberate"); + FutureFallback<Integer> fallback = new FutureFallback<Integer>() { + @Override public ListenableFuture<Integer> create(Throwable t) throws Exception { + throw error; + } + }; + ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(new RuntimeException()); try { - Futures.withFallback(failingFuture, fallback); + Futures.withFallback(failingFuture, fallback).get(); fail("An Exception should have been thrown!"); - } catch (Error expected) { - assertSame(error, expected); + } catch (ExecutionException expected) { + assertSame(error, expected.getCause()); } - mocksControl.verify(); } public void testWithFallback_fallbackReturnsRuntimeException() throws Exception { @@ -694,7 +672,7 @@ public class FuturesTest extends TestCase { } catch (TimeoutException expected) {} } - public void testTransform_asyncFunction_error() { + public void testTransform_asyncFunction_error() throws InterruptedException { final Error error = new Error("deliberate"); AsyncFunction<String, Integer> function = new AsyncFunction<String, Integer>() { @Override public ListenableFuture<Integer> apply(String input) { @@ -702,14 +680,14 @@ public class FuturesTest extends TestCase { } }; SettableFuture<String> inputFuture = SettableFuture.create(); - Futures.transform(inputFuture, function); + ListenableFuture<Integer> outputFuture = Futures.transform(inputFuture, function); + inputFuture.set("value"); try { - inputFuture.set("value"); - } catch (Error expected) { - assertSame(error, expected); - return; + outputFuture.get(); + fail("should have thrown error"); + } catch (ExecutionException e) { + assertSame(error, e.getCause()); } - fail("should have thrown error"); } public void testTransform_asyncFunction_cancelledWhileApplyingFunction() @@ -843,7 +821,7 @@ public class FuturesTest extends TestCase { assertTrue(listener.wasCalled()); List<String> results = compound.get(); - assertThat(results).has().allOf(DATA1, DATA2, DATA3).inOrder(); + ASSERT.that(results).has().exactly(DATA1, DATA2, DATA3).inOrder(); } public void testAllAsList_emptyList() throws Exception { @@ -925,19 +903,13 @@ public class FuturesTest extends TestCase { ListenableFuture<String> future2 = Futures.immediateFuture("results"); ListenableFuture<List<String>> compound = Futures.allAsList(ImmutableList.of(future1, future2)); + future1.setException(error); try { - future1.setException(error); - } catch (Error expected) { - assertSame(error, expected); - try { - compound.get(); - } catch (ExecutionException ee) { - assertSame(error, ee.getCause()); - return; - } + compound.get(); fail("Expected error not set in compound future."); + } catch (ExecutionException ee) { + assertSame(error, ee.getCause()); } - fail("Expected error not thrown"); } public void testAllAsList_cancelled() throws Exception { @@ -1024,7 +996,55 @@ public class FuturesTest extends TestCase { assertTrue(listener.wasCalled()); List<String> results = compound.get(); - assertThat(results).has().allOf(DATA1, DATA2, DATA3).inOrder(); + ASSERT.that(results).has().exactly(DATA1, DATA2, DATA3).inOrder(); + } + + /** + * A single non-error failure is not logged because it is reported via the output future. + */ + @SuppressWarnings("unchecked") + public void testAllAsList_logging_exception() throws Exception { + try { + Futures.allAsList(immediateFailedFuture(new MyException())).get(); + fail(); + } catch (ExecutionException e) { + assertTrue(e.getCause() instanceof MyException); + assertEquals("Nothing should be logged", 0, + combinedFutureLogHandler.getStoredLogRecords().size()); + } + } + + /** + * Ensure that errors are always logged. + */ + @SuppressWarnings("unchecked") + public void testAllAsList_logging_error() throws Exception { + try { + Futures.allAsList(immediateFailedFuture(new MyError())).get(); + fail(); + } catch (ExecutionException e) { + assertTrue(e.getCause() instanceof MyError); + List<LogRecord> logged = combinedFutureLogHandler.getStoredLogRecords(); + assertEquals(1, logged.size()); // errors are always logged + assertTrue(logged.get(0).getThrown() instanceof MyError); + } + } + + /** + * All as list will log extra exceptions that occur after failure. + */ + @SuppressWarnings("unchecked") + public void testAllAsList_logging_multipleExceptions() throws Exception { + try { + Futures.allAsList(immediateFailedFuture(new MyException()), + immediateFailedFuture(new MyException())).get(); + fail(); + } catch (ExecutionException e) { + assertTrue(e.getCause() instanceof MyException); + List<LogRecord> logged = combinedFutureLogHandler.getStoredLogRecords(); + assertEquals(1, logged.size()); // the second failure is logged + assertTrue(logged.get(0).getThrown() instanceof MyException); + } } private static String createCombinedResult(Integer i, Boolean b) { @@ -1444,7 +1464,7 @@ public class FuturesTest extends TestCase { assertTrue(listener.wasCalled()); List<String> results = compound.get(); - assertThat(results).has().allOf(DATA1, DATA2, DATA3).inOrder(); + ASSERT.that(results).has().exactly(DATA1, DATA2, DATA3).inOrder(); } public void testSuccessfulAsList_emptyList() throws Exception { @@ -1487,7 +1507,7 @@ public class FuturesTest extends TestCase { assertTrue(listener.wasCalled()); List<String> results = compound.get(); - assertThat(results).has().allOf(null, DATA2).inOrder(); + ASSERT.that(results).has().exactly(null, DATA2).inOrder(); } public void testSuccessfulAsList_totalFailure() throws Exception { @@ -1508,7 +1528,7 @@ public class FuturesTest extends TestCase { assertTrue(listener.wasCalled()); List<String> results = compound.get(); - assertThat(results).has().allOf(null, null).inOrder(); + ASSERT.that(results).has().exactly(null, null).inOrder(); } public void testSuccessfulAsList_cancelled() throws Exception { @@ -1529,7 +1549,7 @@ public class FuturesTest extends TestCase { assertTrue(listener.wasCalled()); List<String> results = compound.get(); - assertThat(results).has().allOf(null, DATA2).inOrder(); + ASSERT.that(results).has().exactly(null, DATA2).inOrder(); } public void testSuccessfulAsList_resultCancelled() throws Exception { @@ -1655,7 +1675,86 @@ public class FuturesTest extends TestCase { assertTrue(listener.wasCalled()); List<String> results = compound.get(); - assertThat(results).has().allOf(null, null, DATA3).inOrder(); + ASSERT.that(results).has().exactly(null, null, DATA3).inOrder(); + } + + /** Non-Error exceptions are never logged. */ + @SuppressWarnings("unchecked") + public void testSuccessfulAsList_logging_exception() throws Exception { + assertEquals(Lists.newArrayList((Object) null), + Futures.successfulAsList( + immediateFailedFuture(new MyException())).get()); + assertEquals("Nothing should be logged", 0, + combinedFutureLogHandler.getStoredLogRecords().size()); + + // Not even if there are a bunch of failures. + assertEquals(Lists.newArrayList(null, null, null), + Futures.successfulAsList( + immediateFailedFuture(new MyException()), + immediateFailedFuture(new MyException()), + immediateFailedFuture(new MyException())).get()); + assertEquals("Nothing should be logged", 0, + combinedFutureLogHandler.getStoredLogRecords().size()); + } + + /** + * Ensure that errors are always logged. + */ + @SuppressWarnings("unchecked") + public void testSuccessfulAsList_logging_error() throws Exception { + assertEquals(Lists.newArrayList((Object) null), + Futures.successfulAsList( + immediateFailedFuture(new MyError())).get()); + List<LogRecord> logged = combinedFutureLogHandler.getStoredLogRecords(); + assertEquals(1, logged.size()); // errors are always logged + assertTrue(logged.get(0).getThrown() instanceof MyError); + } + + public void testNonCancellationPropagating_successful() throws Exception { + SettableFuture<Foo> input = SettableFuture.create(); + ListenableFuture<Foo> wrapper = Futures.nonCancellationPropagating(input); + Foo foo = new Foo(); + + assertFalse(wrapper.isDone()); + input.set(foo); + assertTrue(wrapper.isDone()); + assertSame(foo, wrapper.get()); + } + + public void testNonCancellationPropagating_failure() throws Exception { + SettableFuture<Foo> input = SettableFuture.create(); + ListenableFuture<Foo> wrapper = Futures.nonCancellationPropagating(input); + Throwable failure = new Throwable("thrown"); + + assertFalse(wrapper.isDone()); + input.setException(failure); + assertTrue(wrapper.isDone()); + try { + wrapper.get(); + fail("Expected ExecutionException"); + } catch (ExecutionException e) { + assertSame(failure, e.getCause()); + } + } + + public void testNonCancellationPropagating_delegateCancelled() throws Exception { + SettableFuture<Foo> input = SettableFuture.create(); + ListenableFuture<Foo> wrapper = Futures.nonCancellationPropagating(input); + + assertFalse(wrapper.isDone()); + assertTrue(input.cancel(false)); + assertTrue(wrapper.isCancelled()); + } + + public void testNonCancellationPropagating_doesNotPropagate() throws Exception { + SettableFuture<Foo> input = SettableFuture.create(); + ListenableFuture<Foo> wrapper = Futures.nonCancellationPropagating(input); + + assertTrue(wrapper.cancel(true)); + assertTrue(wrapper.isCancelled()); + assertTrue(wrapper.isDone()); + assertFalse(input.isCancelled()); + assertFalse(input.isDone()); } private static class TestException extends Exception { @@ -2238,11 +2337,133 @@ public class FuturesTest extends TestCase { ExceptionWithoutThrowableConstructor.class); fail(); } catch (ExceptionWithoutThrowableConstructor expected) { - FluentAsserts.assertThat(expected.getMessage()).contains("mymessage"); + ASSERT.that(expected.getMessage()).contains("mymessage"); assertEquals(CHECKED_EXCEPTION, expected.getCause()); } } + public void testCompletionOrder() throws Exception { + SettableFuture<Long> future1 = SettableFuture.create(); + SettableFuture<Long> future2 = SettableFuture.create(); + SettableFuture<Long> future3 = SettableFuture.create(); + SettableFuture<Long> future4 = SettableFuture.create(); + SettableFuture<Long> future5 = SettableFuture.create(); + + ImmutableList<ListenableFuture<Long>> futures = Futures.inCompletionOrder( + ImmutableList.<ListenableFuture<Long>>of(future1, future2, future3, future4, future5)); + future2.set(1L); + future5.set(2L); + future1.set(3L); + future3.set(4L); + future4.set(5L); + + long expected = 1L; + for (ListenableFuture<Long> future : futures) { + assertEquals((Long) expected, future.get()); + expected++; + } + } + + public void testCompletionOrderExceptionThrown() throws Exception { + SettableFuture<Long> future1 = SettableFuture.create(); + SettableFuture<Long> future2 = SettableFuture.create(); + SettableFuture<Long> future3 = SettableFuture.create(); + SettableFuture<Long> future4 = SettableFuture.create(); + SettableFuture<Long> future5 = SettableFuture.create(); + + ImmutableList<ListenableFuture<Long>> futures = Futures.inCompletionOrder( + ImmutableList.<ListenableFuture<Long>>of(future1, future2, future3, future4, future5)); + future2.set(1L); + future5.setException(new IllegalStateException("2L")); + future1.set(3L); + future3.set(4L); + future4.set(5L); + + long expected = 1L; + for (ListenableFuture<Long> future : futures) { + if (expected != 2) { + assertEquals((Long) expected, future.get()); + } else { + try { + future.get(); + fail(); + } catch (ExecutionException e) { + // Expected + assertEquals("2L", e.getCause().getMessage()); + } + } + expected++; + } + } + + public void testCompletionOrderFutureCancelled() throws Exception { + SettableFuture<Long> future1 = SettableFuture.create(); + SettableFuture<Long> future2 = SettableFuture.create(); + SettableFuture<Long> future3 = SettableFuture.create(); + SettableFuture<Long> future4 = SettableFuture.create(); + SettableFuture<Long> future5 = SettableFuture.create(); + + ImmutableList<ListenableFuture<Long>> futures = Futures.inCompletionOrder( + ImmutableList.<ListenableFuture<Long>>of(future1, future2, future3, future4, future5)); + future2.set(1L); + future5.set(2L); + future1.set(3L); + future3.cancel(true); + future4.set(5L); + + long expected = 1L; + for (ListenableFuture<Long> future : futures) { + if (expected != 4) { + assertEquals((Long) expected, future.get()); + } else { + try { + future.get(); + fail(); + } catch (CancellationException e) { + // Expected + } + } + expected++; + } + } + + public void testCancellingADelegateDoesNotPropagate() throws Exception { + SettableFuture<Long> future1 = SettableFuture.create(); + SettableFuture<Long> future2 = SettableFuture.create(); + + ImmutableList<ListenableFuture<Long>> delegates = Futures.inCompletionOrder( + ImmutableList.<ListenableFuture<Long>>of(future1, future2)); + + future1.set(1L); + // Cannot cancel a complete delegate + assertFalse(delegates.get(0).cancel(true)); + // Cancel the delegate before the input future is done + assertTrue(delegates.get(1).cancel(true)); + // Setting the future still works since cancellation didn't propagate + assertTrue(future2.set(2L)); + // Second check to ensure the input future was not cancelled + assertEquals((Long) 2L, future2.get()); + } + + // Mostly an example of how it would look like to use a list of mixed types + public void testCompletionOrderMixedBagOTypes() throws Exception { + SettableFuture<Long> future1 = SettableFuture.create(); + SettableFuture<String> future2 = SettableFuture.create(); + SettableFuture<Integer> future3 = SettableFuture.create(); + + ImmutableList<? extends ListenableFuture<?>> inputs = + ImmutableList.<ListenableFuture<?>>of(future1, future2, future3); + ImmutableList<ListenableFuture<Object>> futures = Futures.inCompletionOrder(inputs); + future2.set("1L"); + future1.set(2L); + future3.set(3); + + ImmutableList<?> expected = ImmutableList.of("1L", 2L, 3); + for (int i = 0; i < expected.size(); i++) { + assertEquals(expected.get(i), futures.get(i).get()); + } + } + public static final class TwoArgConstructorException extends Exception { public TwoArgConstructorException(String message, Throwable cause) { super(message, cause); @@ -2361,10 +2582,4 @@ public class FuturesTest extends TestCase { failure.initCause(cause); throw failure; } - - // Hack for JDK5 type inference. - private static <T> CollectionSubject<? extends CollectionSubject<?, T, Collection<T>>, T, Collection<T>> assertThat( - Collection<T> collection) { - return ASSERT.<T, Collection<T>>that(collection); - } } diff --git a/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java b/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java index 914a1f7..23fc1e8 100644 --- a/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java +++ b/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java @@ -18,6 +18,8 @@ package com.google.common.util.concurrent; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; +import junit.framework.*; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; @@ -33,22 +35,10 @@ import java.util.Arrays; import java.util.Date; import java.util.NoSuchElementException; import java.util.PropertyPermission; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.CyclicBarrier; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.Semaphore; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeoutException; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - /** * Base class for JSR166 Junit TCK tests. Defines some constants, * utility methods and classes, as well as a simple framework for @@ -143,7 +133,6 @@ abstract class JSR166TestCase extends TestCase { private static final long profileThreshold = Long.getLong("jsr166.profileThreshold", 100); - @Override protected void runTest() throws Throwable { if (profileTests) runTestProfiled(); @@ -322,7 +311,6 @@ abstract class JSR166TestCase extends TestCase { threadFailure.compareAndSet(null, t); } - @Override public void setUp() { setDelays(); } @@ -336,7 +324,6 @@ abstract class JSR166TestCase extends TestCase { * * Triggers test case failure if interrupt status is set in the main thread. */ - @Override public void tearDown() throws Exception { Throwable t = threadFailure.getAndSet(null); if (t != null) { @@ -686,19 +673,15 @@ abstract class JSR166TestCase extends TestCase { } void addPermission(Permission perm) { perms.add(perm); } void clearPermissions() { perms = new Permissions(); } - @Override public PermissionCollection getPermissions(CodeSource cs) { return perms; } - @Override public PermissionCollection getPermissions(ProtectionDomain pd) { return perms; } - @Override public boolean implies(ProtectionDomain pd, Permission p) { return perms.implies(p); } - @Override public void refresh() {} } @@ -817,7 +800,6 @@ abstract class JSR166TestCase extends TestCase { public abstract class CheckedRunnable implements Runnable { protected abstract void realRun() throws Throwable; - @Override public final void run() { try { realRun(); @@ -836,7 +818,6 @@ abstract class JSR166TestCase extends TestCase { this.exceptionClass = exceptionClass; } - @Override public final void run() { try { realRun(); @@ -857,7 +838,6 @@ abstract class JSR166TestCase extends TestCase { this.exceptionClass = exceptionClass; } - @Override public final void run() { try { realRun(); @@ -872,7 +852,6 @@ abstract class JSR166TestCase extends TestCase { public abstract class CheckedInterruptedRunnable implements Runnable { protected abstract void realRun() throws Throwable; - @Override public final void run() { try { realRun(); @@ -888,7 +867,6 @@ abstract class JSR166TestCase extends TestCase { public abstract class CheckedCallable<T> implements Callable<T> { protected abstract T realCall() throws Throwable; - @Override public final T call() { try { return realCall(); @@ -903,7 +881,6 @@ abstract class JSR166TestCase extends TestCase { implements Callable<T> { protected abstract T realCall() throws Throwable; - @Override public final T call() { try { T result = realCall(); @@ -919,25 +896,21 @@ abstract class JSR166TestCase extends TestCase { } public static class NoOpRunnable implements Runnable { - @Override public void run() {} } public static class NoOpCallable implements Callable { - @Override public Object call() { return Boolean.TRUE; } } public static final String TEST_STRING = "a test string"; public static class StringTask implements Callable<String> { - @Override public String call() { return TEST_STRING; } } public Callable<String> latchAwaitingStringTask(final CountDownLatch latch) { return new CheckedCallable<String>() { - @Override protected String realCall() { try { latch.await(); @@ -948,7 +921,6 @@ abstract class JSR166TestCase extends TestCase { public Runnable awaiter(final CountDownLatch latch) { return new CheckedRunnable() { - @Override public void realRun() throws InterruptedException { await(latch); }}; @@ -990,38 +962,32 @@ abstract class JSR166TestCase extends TestCase { // } public static class NPETask implements Callable<String> { - @Override public String call() { throw new NullPointerException(); } } public static class CallableOne implements Callable<Integer> { - @Override public Integer call() { return one; } } public class ShortRunnable extends CheckedRunnable { - @Override protected void realRun() throws Throwable { delay(SHORT_DELAY_MS); } } public class ShortInterruptedRunnable extends CheckedInterruptedRunnable { - @Override protected void realRun() throws InterruptedException { delay(SHORT_DELAY_MS); } } public class SmallRunnable extends CheckedRunnable { - @Override protected void realRun() throws Throwable { delay(SMALL_DELAY_MS); } } public class SmallPossiblyInterruptedRunnable extends CheckedRunnable { - @Override protected void realRun() { try { delay(SMALL_DELAY_MS); @@ -1030,7 +996,6 @@ abstract class JSR166TestCase extends TestCase { } public class SmallCallable extends CheckedCallable { - @Override protected Object realCall() throws InterruptedException { delay(SMALL_DELAY_MS); return Boolean.TRUE; @@ -1038,14 +1003,12 @@ abstract class JSR166TestCase extends TestCase { } public class MediumRunnable extends CheckedRunnable { - @Override protected void realRun() throws Throwable { delay(MEDIUM_DELAY_MS); } } public class MediumInterruptedRunnable extends CheckedInterruptedRunnable { - @Override protected void realRun() throws InterruptedException { delay(MEDIUM_DELAY_MS); } @@ -1053,7 +1016,6 @@ abstract class JSR166TestCase extends TestCase { public Runnable possiblyInterruptedRunnable(final long timeoutMillis) { return new CheckedRunnable() { - @Override protected void realRun() { try { delay(timeoutMillis); @@ -1062,7 +1024,6 @@ abstract class JSR166TestCase extends TestCase { } public class MediumPossiblyInterruptedRunnable extends CheckedRunnable { - @Override protected void realRun() { try { delay(MEDIUM_DELAY_MS); @@ -1071,7 +1032,6 @@ abstract class JSR166TestCase extends TestCase { } public class LongPossiblyInterruptedRunnable extends CheckedRunnable { - @Override protected void realRun() { try { delay(LONG_DELAY_MS); @@ -1083,7 +1043,6 @@ abstract class JSR166TestCase extends TestCase { * For use as ThreadFactory in constructors */ public static class SimpleThreadFactory implements ThreadFactory { - @Override public Thread newThread(Runnable r) { return new Thread(r); } @@ -1096,9 +1055,7 @@ abstract class JSR166TestCase extends TestCase { public static TrackedRunnable trackedRunnable(final long timeoutMillis) { return new TrackedRunnable() { private volatile boolean done = false; - @Override public boolean isDone() { return done; } - @Override public void run() { try { delay(timeoutMillis); @@ -1110,7 +1067,6 @@ abstract class JSR166TestCase extends TestCase { public static class TrackedShortRunnable implements Runnable { public volatile boolean done = false; - @Override public void run() { try { delay(SHORT_DELAY_MS); @@ -1121,7 +1077,6 @@ abstract class JSR166TestCase extends TestCase { public static class TrackedSmallRunnable implements Runnable { public volatile boolean done = false; - @Override public void run() { try { delay(SMALL_DELAY_MS); @@ -1132,7 +1087,6 @@ abstract class JSR166TestCase extends TestCase { public static class TrackedMediumRunnable implements Runnable { public volatile boolean done = false; - @Override public void run() { try { delay(MEDIUM_DELAY_MS); @@ -1143,7 +1097,6 @@ abstract class JSR166TestCase extends TestCase { public static class TrackedLongRunnable implements Runnable { public volatile boolean done = false; - @Override public void run() { try { delay(LONG_DELAY_MS); @@ -1154,7 +1107,6 @@ abstract class JSR166TestCase extends TestCase { public static class TrackedNoOpRunnable implements Runnable { public volatile boolean done = false; - @Override public void run() { done = true; } @@ -1162,7 +1114,6 @@ abstract class JSR166TestCase extends TestCase { public static class TrackedCallable implements Callable { public volatile boolean done = false; - @Override public Object call() { try { delay(SMALL_DELAY_MS); @@ -1207,7 +1158,6 @@ abstract class JSR166TestCase extends TestCase { * For use as RejectedExecutionHandler in constructors */ public static class NoOpREHandler implements RejectedExecutionHandler { - @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {} } @@ -1219,7 +1169,6 @@ abstract class JSR166TestCase extends TestCase { public class CheckedBarrier extends CyclicBarrier { public CheckedBarrier(int parties) { super(parties); } - @Override public int await() { try { return super.await(2 * LONG_DELAY_MS, MILLISECONDS); diff --git a/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java b/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java index aacb608..5042d83 100644 --- a/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java @@ -27,14 +27,16 @@ import com.google.common.testing.ClassSanityTester; import com.google.common.util.concurrent.FuturesTest.ExecutorSpy; import com.google.common.util.concurrent.FuturesTest.SingleCallListener; +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - /** * Unit tests for {@link JdkFutureAdapters}. * @@ -103,6 +105,45 @@ public class JdkFutureAdaptersTest extends TestCase { assertTrue(listenableFuture.isDone()); } + public void testListenInPoolThreadCustomExecutorInterrupted() + throws Exception { + final CountDownLatch submitSuccessful = new CountDownLatch(1); + ExecutorService executorService = new ThreadPoolExecutor( + 0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, + new SynchronousQueue<Runnable>(), + new ThreadFactoryBuilder().setDaemon(true).build()) { + @Override + protected void beforeExecute(Thread t, Runnable r) { + submitSuccessful.countDown(); + } + }; + NonListenableSettableFuture<String> abstractFuture = + NonListenableSettableFuture.create(); + ListenableFuture<String> listenableFuture = + listenInPoolThread(abstractFuture, executorService); + + SingleCallListener singleCallListener = new SingleCallListener(); + singleCallListener.expectCall(); + + assertFalse(singleCallListener.wasCalled()); + assertFalse(listenableFuture.isDone()); + + listenableFuture.addListener(singleCallListener, sameThreadExecutor()); + /* + * Don't shut down until the listenInPoolThread task has been accepted to + * run. We want to see what happens when it's interrupted, not when it's + * rejected. + */ + submitSuccessful.await(); + executorService.shutdownNow(); + abstractFuture.set(DATA1); + assertEquals(DATA1, listenableFuture.get()); + singleCallListener.waitForCall(); + + assertTrue(singleCallListener.wasCalled()); + assertTrue(listenableFuture.isDone()); + } + /** * A Future that doesn't implement ListenableFuture, useful for testing * listenInPoolThread. diff --git a/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTaskTest.java b/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTaskTest.java index 0c96508..479e569 100644 --- a/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTaskTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTaskTest.java @@ -16,6 +16,8 @@ package com.google.common.util.concurrent; +import junit.framework.TestCase; + import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; @@ -23,8 +25,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import junit.framework.TestCase; - /** * Test case for {@link ListenableFutureTask}. * diff --git a/guava-tests/test/com/google/common/util/concurrent/ListenerCallQueueTest.java b/guava-tests/test/com/google/common/util/concurrent/ListenerCallQueueTest.java new file mode 100644 index 0000000..651eb96 --- /dev/null +++ b/guava-tests/test/com/google/common/util/concurrent/ListenerCallQueueTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2014 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.util.concurrent; + +import com.google.common.util.concurrent.ListenerCallQueue.Callback; + +import junit.framework.TestCase; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Tests for {@link ListenerCallQueue}. + */ +public class ListenerCallQueueTest extends TestCase { + + private static final Callback<Object> THROWING_CALLBACK = new Callback<Object>("throwing()") { + @Override public void call(Object object) { + throw new RuntimeException(); + } + }; + + public void testAddAndExecute() { + Object listenerInstance = new Object(); + ListenerCallQueue<Object> queue = + new ListenerCallQueue<Object>(listenerInstance, MoreExecutors.sameThreadExecutor()); + + AtomicInteger counter = new AtomicInteger(); + queue.add(incrementingCallback(counter, 1)); + queue.add(incrementingCallback(counter, 2)); + queue.add(incrementingCallback(counter, 3)); + queue.add(incrementingCallback(counter, 4)); + assertEquals(0, counter.get()); + queue.execute(); + assertEquals(4, counter.get()); + } + + public void testAddAndExecute_withExceptions() { + Object listenerInstance = new Object(); + ListenerCallQueue<Object> queue = + new ListenerCallQueue<Object>(listenerInstance, MoreExecutors.sameThreadExecutor()); + + AtomicInteger counter = new AtomicInteger(); + queue.add(incrementingCallback(counter, 1)); + queue.add(THROWING_CALLBACK); + queue.add(incrementingCallback(counter, 2)); + queue.add(THROWING_CALLBACK); + queue.add(incrementingCallback(counter, 3)); + queue.add(THROWING_CALLBACK); + queue.add(incrementingCallback(counter, 4)); + queue.add(THROWING_CALLBACK); + assertEquals(0, counter.get()); + queue.execute(); + assertEquals(4, counter.get()); + } + + public void testAddAndExecute_multithreaded() throws InterruptedException { + ExecutorService service = Executors.newFixedThreadPool(4); + try { + ListenerCallQueue<Object> queue = + new ListenerCallQueue<Object>(new Object(), service); + + final CountDownLatch latch = new CountDownLatch(1); + AtomicInteger counter = new AtomicInteger(); + queue.add(incrementingCallback(counter, 1)); + queue.add(incrementingCallback(counter, 2)); + queue.add(incrementingCallback(counter, 3)); + queue.add(incrementingCallback(counter, 4)); + queue.add(countDownCallback(latch)); + assertEquals(0, counter.get()); + queue.execute(); + latch.await(); + assertEquals(4, counter.get()); + } finally { + service.shutdown(); + } + } + + public void testAddAndExecute_multithreaded_withThrowingRunnable() throws InterruptedException { + ExecutorService service = Executors.newFixedThreadPool(4); + try { + ListenerCallQueue<Object> queue = + new ListenerCallQueue<Object>(new Object(), service); + + final CountDownLatch latch = new CountDownLatch(1); + AtomicInteger counter = new AtomicInteger(); + queue.add(incrementingCallback(counter, 1)); + queue.add(THROWING_CALLBACK); + queue.add(incrementingCallback(counter, 2)); + queue.add(THROWING_CALLBACK); + queue.add(incrementingCallback(counter, 3)); + queue.add(THROWING_CALLBACK); + queue.add(incrementingCallback(counter, 4)); + queue.add(THROWING_CALLBACK); + queue.add(countDownCallback(latch)); + assertEquals(0, counter.get()); + queue.execute(); + latch.await(); + assertEquals(4, counter.get()); + } finally { + service.shutdown(); + } + } + + private Callback<Object> incrementingCallback(final AtomicInteger counter, final int expected) { + return new Callback<Object>("incrementing") { + @Override void call(Object listener) { + assertEquals(expected, counter.incrementAndGet()); + } + }; + } + + private Callback<Object> countDownCallback(final CountDownLatch latch) { + return new Callback<Object>("countDown") { + @Override void call(Object listener) { + latch.countDown(); + } + }; + } +} diff --git a/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java b/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java index 2aad6b3..3b0af7f 100644 --- a/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java @@ -31,24 +31,34 @@ package com.google.common.util.concurrent; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.util.concurrent.MoreExecutors.invokeAnyImpl; import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator; +import static com.google.common.util.concurrent.MoreExecutors.renamingDecorator; import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor; +import static com.google.common.util.concurrent.MoreExecutors.shutdownAndAwaitTermination; +import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.truth0.Truth.ASSERT; +import com.google.common.base.Suppliers; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.testing.ClassSanityTester; -import com.google.common.testing.FluentAsserts; import com.google.common.util.concurrent.MoreExecutors.Application; +import org.mockito.InOrder; +import org.mockito.Mockito; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; @@ -56,15 +66,14 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import org.mockito.InOrder; -import org.mockito.Mockito; - /** * Tests for MoreExecutors. * @@ -104,8 +113,8 @@ public class MoreExecutorsTest extends JSR166TestCase { Future<?> future = executor.submit(incrementTask); assertTrue(future.isDone()); assertEquals(1, threadLocalCount.get().intValue()); - } catch (Throwable Throwable) { - throwableFromOtherThread.set(Throwable); + } catch (Throwable t) { + throwableFromOtherThread.set(t); } } }); @@ -187,8 +196,8 @@ public class MoreExecutorsTest extends JSR166TestCase { assertTrue(future.isDone()); assertTrue(executor.isShutdown()); assertTrue(executor.isTerminated()); - } catch (Throwable Throwable) { - throwableFromOtherThread.set(Throwable); + } catch (Throwable t) { + throwableFromOtherThread.set(t); } }}); @@ -249,6 +258,14 @@ public class MoreExecutorsTest extends JSR166TestCase { } catch (RejectedExecutionException expected) {} } + public <T> void testListeningExecutorServiceInvokeAllJavadocCodeCompiles() + throws Exception { + ListeningExecutorService executor = MoreExecutors.sameThreadExecutor(); + List<Callable<T>> tasks = ImmutableList.of(); + @SuppressWarnings("unchecked") // guaranteed by invokeAll contract + List<ListenableFuture<T>> futures = (List) executor.invokeAll(tasks); + } + public void testListeningDecorator() throws Exception { ListeningExecutorService service = listeningDecorator(MoreExecutors.sameThreadExecutor()); @@ -258,10 +275,10 @@ public class MoreExecutorsTest extends JSR166TestCase { List<Future<String>> results; results = service.invokeAll(callables); - FluentAsserts.assertThat(getOnlyElement(results)).isA(ListenableFutureTask.class); + ASSERT.that(getOnlyElement(results)).isA(ListenableFutureTask.class); results = service.invokeAll(callables, 1, SECONDS); - FluentAsserts.assertThat(getOnlyElement(results)).isA(ListenableFutureTask.class); + ASSERT.that(getOnlyElement(results)).isA(ListenableFutureTask.class); /* * TODO(cpovirk): move ForwardingTestCase somewhere common, and use it to @@ -269,6 +286,132 @@ public class MoreExecutorsTest extends JSR166TestCase { */ } + public void testListeningDecorator_noWrapExecuteTask() { + ExecutorService delegate = mock(ExecutorService.class); + ListeningExecutorService service = listeningDecorator(delegate); + Runnable task = new Runnable() { + @Override + public void run() {} + }; + service.execute(task); + verify(delegate).execute(task); + } + + public void testListeningDecorator_scheduleSuccess() throws Exception { + final CountDownLatch completed = new CountDownLatch(1); + ScheduledThreadPoolExecutor delegate = new ScheduledThreadPoolExecutor(1) { + @Override + protected void afterExecute(Runnable r, Throwable t) { + completed.countDown(); + } + }; + ListeningScheduledExecutorService service = listeningDecorator(delegate); + ListenableFuture<?> future = + service.schedule(Callables.returning(null), 1, TimeUnit.MILLISECONDS); + + /* + * Wait not just until the Future's value is set (as in future.get()) but + * also until ListeningScheduledExecutorService's wrapper task is done + * executing listeners, as detected by yielding control to afterExecute. + */ + completed.await(); + assertTrue(future.isDone()); + assertListenerRunImmediately(future); + assertEquals(0, delegate.getQueue().size()); + } + + public void testListeningDecorator_scheduleFailure() throws Exception { + ScheduledThreadPoolExecutor delegate = new ScheduledThreadPoolExecutor(1); + ListeningScheduledExecutorService service = listeningDecorator(delegate); + RuntimeException ex = new RuntimeException(); + ListenableFuture<?> future = + service.schedule(new ThrowingRunnable(0, ex), 1, TimeUnit.MILLISECONDS); + assertExecutionException(future, ex); + assertEquals(0, delegate.getQueue().size()); + } + + public void testListeningDecorator_schedulePeriodic() throws Exception { + ScheduledThreadPoolExecutor delegate = new ScheduledThreadPoolExecutor(1); + ListeningScheduledExecutorService service = listeningDecorator(delegate); + RuntimeException ex = new RuntimeException(); + + ListenableFuture<?> future; + + ThrowingRunnable runnable = new ThrowingRunnable(5, ex); + future = service.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.MILLISECONDS); + assertExecutionException(future, ex); + assertEquals(5, runnable.count); + assertEquals(0, delegate.getQueue().size()); + + runnable = new ThrowingRunnable(5, ex); + future = service.scheduleWithFixedDelay(runnable, 1, 1, TimeUnit.MILLISECONDS); + assertExecutionException(future, ex); + assertEquals(5, runnable.count); + assertEquals(0, delegate.getQueue().size()); + } + + public void testListeningDecorator_cancelled() throws Exception { + ScheduledThreadPoolExecutor delegate = new ScheduledThreadPoolExecutor(1); + BlockingQueue<?> delegateQueue = delegate.getQueue(); + ListeningScheduledExecutorService service = listeningDecorator(delegate); + ListenableFuture<?> future; + ScheduledFuture<?> delegateFuture; + + Runnable runnable = new Runnable() { + @Override public void run() {} + }; + + future = service.schedule(runnable, 5 * 60, TimeUnit.SECONDS); + future.cancel(true); + assertTrue(future.isCancelled()); + delegateFuture = (ScheduledFuture<?>) delegateQueue.element(); + assertTrue(delegateFuture.isCancelled()); + + delegateQueue.clear(); + + future = service.scheduleAtFixedRate(runnable, 5 * 60, 5 * 60, TimeUnit.SECONDS); + future.cancel(true); + assertTrue(future.isCancelled()); + delegateFuture = (ScheduledFuture<?>) delegateQueue.element(); + assertTrue(delegateFuture.isCancelled()); + + delegateQueue.clear(); + + future = service.scheduleWithFixedDelay(runnable, 5 * 60, 5 * 60, TimeUnit.SECONDS); + future.cancel(true); + assertTrue(future.isCancelled()); + delegateFuture = (ScheduledFuture<?>) delegateQueue.element(); + assertTrue(delegateFuture.isCancelled()); + } + + private static final class ThrowingRunnable implements Runnable { + final int throwAfterCount; + final RuntimeException thrown; + int count; + + ThrowingRunnable(int throwAfterCount, RuntimeException thrown) { + this.throwAfterCount = throwAfterCount; + this.thrown = thrown; + } + + @Override + public void run() { + if (++count >= throwAfterCount) { + throw thrown; + } + } + } + + private static void assertExecutionException(Future<?> future, Exception expectedCause) + throws Exception { + try { + future.get(); + fail("Expected ExecutionException"); + } catch (ExecutionException e) { + assertSame(expectedCause, e.getCause()); + } + } + /** * invokeAny(null) throws NPE */ @@ -447,8 +590,20 @@ public class MoreExecutorsTest extends JSR166TestCase { assertEquals(factory.getClass(), Executors.defaultThreadFactory().getClass()); } + public void testThreadRenaming() { + Executor renamingExecutor = renamingDecorator(sameThreadExecutor(), + Suppliers.ofInstance("FooBar")); + String oldName = Thread.currentThread().getName(); + renamingExecutor.execute(new Runnable() { + @Override public void run() { + assertEquals("FooBar", Thread.currentThread().getName()); + }}); + assertEquals(oldName, Thread.currentThread().getName()); + } + public void testExecutors_nullCheck() throws Exception { new ClassSanityTester() + .setDefault(RateLimiter.class, RateLimiter.create(1.0)) .forAllPublicStaticMethods(MoreExecutors.class) .thatReturn(Executor.class) .testNulls(); @@ -470,4 +625,69 @@ public class MoreExecutorsTest extends JSR166TestCase { } } } + + /* Half of a 1-second timeout in nanoseconds */ + private static final long HALF_SECOND_NANOS = NANOSECONDS.convert(1L, SECONDS) / 2; + + public void testShutdownAndAwaitTermination_immediateShutdown() throws Exception { + ExecutorService service = Executors.newSingleThreadExecutor(); + assertTrue(shutdownAndAwaitTermination(service, 1L, SECONDS)); + assertTrue(service.isTerminated()); + } + + public void testShutdownAndAwaitTermination_immediateShutdownInternal() throws Exception { + ExecutorService service = mock(ExecutorService.class); + when(service.awaitTermination(HALF_SECOND_NANOS, NANOSECONDS)).thenReturn(true); + when(service.isTerminated()).thenReturn(true); + assertTrue(shutdownAndAwaitTermination(service, 1L, SECONDS)); + verify(service).shutdown(); + verify(service).awaitTermination(HALF_SECOND_NANOS, NANOSECONDS); + } + + public void testShutdownAndAwaitTermination_forcedShutDownInternal() throws Exception { + ExecutorService service = mock(ExecutorService.class); + when(service.awaitTermination(HALF_SECOND_NANOS, NANOSECONDS)) + .thenReturn(false).thenReturn(true); + when(service.isTerminated()).thenReturn(true); + assertTrue(shutdownAndAwaitTermination(service, 1L, SECONDS)); + verify(service).shutdown(); + verify(service, times(2)).awaitTermination(HALF_SECOND_NANOS, NANOSECONDS); + verify(service).shutdownNow(); + } + + public void testShutdownAndAwaitTermination_nonTerminationInternal() throws Exception { + ExecutorService service = mock(ExecutorService.class); + when(service.awaitTermination(HALF_SECOND_NANOS, NANOSECONDS)) + .thenReturn(false).thenReturn(false); + assertFalse(shutdownAndAwaitTermination(service, 1L, SECONDS)); + verify(service).shutdown(); + verify(service, times(2)).awaitTermination(HALF_SECOND_NANOS, NANOSECONDS); + verify(service).shutdownNow(); + } + + public void testShutdownAndAwaitTermination_interruptedInternal() throws Exception { + final ExecutorService service = mock(ExecutorService.class); + when(service.awaitTermination(HALF_SECOND_NANOS, NANOSECONDS)) + .thenThrow(new InterruptedException()); + + final AtomicBoolean terminated = new AtomicBoolean(); + // we need to keep this in a flag because t.isInterrupted() returns false after t.join() + final AtomicBoolean interrupted = new AtomicBoolean(); + // we need to use another thread because it will be interrupted and thus using + // the current one, owned by JUnit, would make the test fail + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + terminated.set(shutdownAndAwaitTermination(service, 1L, SECONDS)); + interrupted.set(Thread.currentThread().isInterrupted()); + } + }); + thread.start(); + thread.join(); + verify(service).shutdown(); + verify(service).awaitTermination(HALF_SECOND_NANOS, NANOSECONDS); + verify(service).shutdownNow(); + assertTrue(interrupted.get()); + assertFalse(terminated.get()); + } } diff --git a/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java b/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java index d4da81a..d79b7b9 100644 --- a/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java +++ b/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java @@ -24,4 +24,8 @@ import com.google.common.testing.AbstractPackageSanityTests; * @author Ben Yu */ -public class PackageSanityTests extends AbstractPackageSanityTests {} +public class PackageSanityTests extends AbstractPackageSanityTests { + public PackageSanityTests() { + setDefault(RateLimiter.class, RateLimiter.create(1.0)); + } +} diff --git a/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java b/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java index 762310c..93fff44 100644 --- a/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java @@ -20,19 +20,21 @@ import com.google.common.collect.Lists; import com.google.common.testing.NullPointerTester; import com.google.common.testing.NullPointerTester.Visibility; +import junit.framework.TestCase; + import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; -import junit.framework.TestCase; - /** * Tests for RateLimiter. * * @author Dimitris Andreou */ public class RateLimiterTest extends TestCase { + private static final double EPSILON = 1e-8; + /** * The ticker gathers events and presents them as strings. * R0.6 means a delay of 0.6 seconds caused by the (R)ateLimiter @@ -79,6 +81,15 @@ public class RateLimiterTest extends TestCase { assertEvents("R0.00", "U0.20", "R0.00", "R0.20"); } + public void testSimpleAcquireReturnValues() { + RateLimiter limiter = RateLimiter.create(ticker, 5.0); + assertEquals(0.0, limiter.acquire(), EPSILON); // R0.00 + ticker.sleepMillis(200); // U0.20, we are ready for the next request... + assertEquals(0.0, limiter.acquire(), EPSILON); // R0.00, ...which is granted immediately + assertEquals(0.2, limiter.acquire(), EPSILON); // R0.20 + assertEvents("R0.00", "U0.20", "R0.00", "R0.20"); + } + public void testOneSecondBurst() { RateLimiter limiter = RateLimiter.create(ticker, 5.0); ticker.sleepMillis(1000); // max capacity reached @@ -153,7 +164,7 @@ public class RateLimiterTest extends TestCase { } public void testBursty() { - RateLimiter limiter = RateLimiter.createBursty(ticker, 1.0, 10); + RateLimiter limiter = RateLimiter.createWithCapacity(ticker, 1.0, 10, TimeUnit.SECONDS); ticker.sleepMillis(10000); // reach full capacity limiter.acquire(11); // all these are served in a burst (10 + 1 by borrowing from the future) limiter.acquire(1); // out of capacity, we have to wait @@ -321,7 +332,7 @@ public class RateLimiterTest extends TestCase { } private void assertEvents(String... events) { - assertEquals(Arrays.asList(events).toString(), ticker.readEventsAndClear()); + assertEquals(Arrays.toString(events), ticker.readEventsAndClear()); } private static class FakeTicker extends RateLimiter.SleepingTicker { diff --git a/guava-tests/test/com/google/common/net/TestPlatform.java b/guava-tests/test/com/google/common/util/concurrent/RunnablesTest.java index 39301d5..b18a451 100644 --- a/guava-tests/test/com/google/common/net/TestPlatform.java +++ b/guava-tests/test/com/google/common/util/concurrent/RunnablesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Guava Authors + * Copyright (C) 2013 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,13 +14,20 @@ * limitations under the License. */ -package com.google.common.net; +package com.google.common.util.concurrent; import com.google.common.annotations.GwtCompatible; +import junit.framework.TestCase; + /** - * @author Hayward Chan + * Unit tests for {@link Runnables}. + * + * @author Olivier Pernet */ -@GwtCompatible(emulated = true) -class TestPlatform { +@GwtCompatible +public class RunnablesTest extends TestCase { + public void testDoNothingRunnableIsSingleton() { + assertSame(Runnables.doNothing(), Runnables.doNothing()); + } } diff --git a/guava-tests/test/com/google/common/util/concurrent/SerializingExecutorTest.java b/guava-tests/test/com/google/common/util/concurrent/SerializingExecutorTest.java new file mode 100644 index 0000000..01efd24 --- /dev/null +++ b/guava-tests/test/com/google/common/util/concurrent/SerializingExecutorTest.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.util.concurrent; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import junit.framework.TestCase; + +import java.util.List; +import java.util.Queue; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Tests {@link SerializingExecutor}. + * + * @author JJ Furman + */ +public class SerializingExecutorTest extends TestCase { + private static class FakeExecutor implements Executor { + Queue<Runnable> tasks = Lists.newLinkedList(); + @Override public void execute(Runnable command) { + tasks.add(command); + } + + boolean hasNext() { + return !tasks.isEmpty(); + } + + void runNext() { + assertTrue("expected at least one task to run", hasNext()); + tasks.remove().run(); + } + + } + private FakeExecutor fakePool; + private SerializingExecutor e; + + @Override + public void setUp() { + fakePool = new FakeExecutor(); + e = new SerializingExecutor(fakePool); + } + + public void testSerializingNullExecutor_fails() { + try { + new SerializingExecutor(null); + fail("Should have failed with NullPointerException."); + } catch (NullPointerException expected) { + } + } + + public void testBasics() { + final AtomicInteger totalCalls = new AtomicInteger(); + Runnable intCounter = new Runnable() { + @Override + public void run() { + totalCalls.incrementAndGet(); + } + }; + + assertFalse(fakePool.hasNext()); + e.execute(intCounter); + assertTrue(fakePool.hasNext()); + e.execute(intCounter); + assertEquals(0, totalCalls.get()); + fakePool.runNext(); // run just 1 sub task... + assertEquals(2, totalCalls.get()); + assertFalse(fakePool.hasNext()); + + // Check that execute can be safely repeated + e.execute(intCounter); + e.execute(intCounter); + e.execute(intCounter); + assertEquals(2, totalCalls.get()); + fakePool.runNext(); + assertEquals(5, totalCalls.get()); + assertFalse(fakePool.hasNext()); + } + + public void testOrdering() { + final List<Integer> callOrder = Lists.newArrayList(); + + class FakeOp implements Runnable { + final int op; + + FakeOp(int op) { + this.op = op; + } + + @Override + public void run() { + callOrder.add(op); + } + } + + e.execute(new FakeOp(0)); + e.execute(new FakeOp(1)); + e.execute(new FakeOp(2)); + fakePool.runNext(); + + assertEquals(ImmutableList.of(0, 1, 2), callOrder); + } + + public void testExceptions() { + + final AtomicInteger numCalls = new AtomicInteger(); + + Runnable runMe = new Runnable() { + @Override + public void run() { + numCalls.incrementAndGet(); + throw new RuntimeException("FAKE EXCEPTION!"); + } + }; + + e.execute(runMe); + e.execute(runMe); + fakePool.runNext(); + + assertEquals(2, numCalls.get()); + } + + public void testDelegateRejection() { + final AtomicInteger numCalls = new AtomicInteger(); + final AtomicBoolean reject = new AtomicBoolean(true); + final SerializingExecutor executor = new SerializingExecutor( + new Executor() { + @Override public void execute(Runnable r) { + if (reject.get()) { + throw new RejectedExecutionException(); + } + r.run(); + } + }); + Runnable task = new Runnable() { + @Override + public void run() { + numCalls.incrementAndGet(); + } + }; + try { + executor.execute(task); + fail(); + } catch (RejectedExecutionException expected) {} + assertEquals(0, numCalls.get()); + reject.set(false); + executor.execute(task); + assertEquals(2, numCalls.get()); + } + + public void testTaskThrowsError() throws Exception { + class MyError extends Error {} + final CyclicBarrier barrier = new CyclicBarrier(2); + // we need to make sure the error gets thrown on a different thread. + ExecutorService service = Executors.newSingleThreadExecutor(); + try { + final SerializingExecutor executor = new SerializingExecutor(service); + Runnable errorTask = new Runnable() { + @Override + public void run() { + throw new MyError(); + } + }; + Runnable barrierTask = new Runnable() { + @Override + public void run() { + try { + barrier.await(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }; + executor.execute(errorTask); + service.execute(barrierTask); // submit directly to the service + // the barrier task runs after the error task so we know that the error has been observed by + // SerializingExecutor by the time the barrier is satified + barrier.await(10, TimeUnit.SECONDS); + executor.execute(barrierTask); + // timeout means the second task wasn't even tried + barrier.await(10, TimeUnit.SECONDS); + } finally { + service.shutdown(); + } + } +} diff --git a/guava-tests/test/com/google/common/util/concurrent/ServiceManagerTest.java b/guava-tests/test/com/google/common/util/concurrent/ServiceManagerTest.java new file mode 100644 index 0000000..147ed64 --- /dev/null +++ b/guava-tests/test/com/google/common/util/concurrent/ServiceManagerTest.java @@ -0,0 +1,561 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.common.util.concurrent; + +import static java.util.Arrays.asList; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.testing.NullPointerTester; +import com.google.common.testing.TestLogHandler; +import com.google.common.util.concurrent.ServiceManager.Listener; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Formatter; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +/** + * Tests for {@link ServiceManager}. + * + * @author Luke Sandberg + * @author Chris Nokleberg + */ +public class ServiceManagerTest extends TestCase { + + private static class NoOpService extends AbstractService { + @Override protected void doStart() { + notifyStarted(); + } + + @Override protected void doStop() { + notifyStopped(); + } + } + + /* + * A NoOp service that will delay the startup and shutdown notification for a configurable amount + * of time. + */ + private static class NoOpDelayedSerivce extends NoOpService { + private long delay; + + public NoOpDelayedSerivce(long delay) { + this.delay = delay; + } + + @Override protected void doStart() { + new Thread() { + @Override public void run() { + Uninterruptibles.sleepUninterruptibly(delay, TimeUnit.MILLISECONDS); + notifyStarted(); + } + }.start(); + } + + @Override protected void doStop() { + new Thread() { + @Override public void run() { + Uninterruptibles.sleepUninterruptibly(delay, TimeUnit.MILLISECONDS); + notifyStopped(); + } + }.start(); + } + } + + private static class FailStartService extends NoOpService { + @Override protected void doStart() { + notifyFailed(new IllegalStateException("failed")); + } + } + + private static class FailRunService extends NoOpService { + @Override protected void doStart() { + super.doStart(); + notifyFailed(new IllegalStateException("failed")); + } + } + + private static class FailStopService extends NoOpService { + @Override protected void doStop() { + notifyFailed(new IllegalStateException("failed")); + } + } + + public void testServiceStartupTimes() { + Service a = new NoOpDelayedSerivce(150); + Service b = new NoOpDelayedSerivce(353); + ServiceManager serviceManager = new ServiceManager(asList(a, b)); + serviceManager.startAsync().awaitHealthy(); + ImmutableMap<Service, Long> startupTimes = serviceManager.startupTimes(); + assertEquals(2, startupTimes.size()); + assertTrue(startupTimes.get(a) >= 150); + assertTrue(startupTimes.get(b) >= 353); + } + + public void testServiceStartStop() { + Service a = new NoOpService(); + Service b = new NoOpService(); + ServiceManager manager = new ServiceManager(asList(a, b)); + RecordingListener listener = new RecordingListener(); + manager.addListener(listener); + assertState(manager, Service.State.NEW, a, b); + assertFalse(manager.isHealthy()); + manager.startAsync().awaitHealthy(); + assertState(manager, Service.State.RUNNING, a, b); + assertTrue(manager.isHealthy()); + assertTrue(listener.healthyCalled); + assertFalse(listener.stoppedCalled); + assertTrue(listener.failedServices.isEmpty()); + manager.stopAsync().awaitStopped(); + assertState(manager, Service.State.TERMINATED, a, b); + assertFalse(manager.isHealthy()); + assertTrue(listener.stoppedCalled); + assertTrue(listener.failedServices.isEmpty()); + } + + public void testFailStart() throws Exception { + Service a = new NoOpService(); + Service b = new FailStartService(); + Service c = new NoOpService(); + Service d = new FailStartService(); + Service e = new NoOpService(); + ServiceManager manager = new ServiceManager(asList(a, b, c, d, e)); + RecordingListener listener = new RecordingListener(); + manager.addListener(listener); + assertState(manager, Service.State.NEW, a, b, c, d, e); + try { + manager.startAsync().awaitHealthy(); + fail(); + } catch (IllegalStateException expected) { + } + assertFalse(listener.healthyCalled); + assertState(manager, Service.State.RUNNING, a, c, e); + assertEquals(ImmutableSet.of(b, d), listener.failedServices); + assertState(manager, Service.State.FAILED, b, d); + assertFalse(manager.isHealthy()); + + manager.stopAsync().awaitStopped(); + assertFalse(manager.isHealthy()); + assertFalse(listener.healthyCalled); + assertTrue(listener.stoppedCalled); + } + + public void testFailRun() throws Exception { + Service a = new NoOpService(); + Service b = new FailRunService(); + ServiceManager manager = new ServiceManager(asList(a, b)); + RecordingListener listener = new RecordingListener(); + manager.addListener(listener); + assertState(manager, Service.State.NEW, a, b); + try { + manager.startAsync().awaitHealthy(); + fail(); + } catch (IllegalStateException expected) { + } + assertTrue(listener.healthyCalled); + assertEquals(ImmutableSet.of(b), listener.failedServices); + + manager.stopAsync().awaitStopped(); + assertState(manager, Service.State.FAILED, b); + assertState(manager, Service.State.TERMINATED, a); + + assertTrue(listener.stoppedCalled); + } + + public void testFailStop() throws Exception { + Service a = new NoOpService(); + Service b = new FailStopService(); + Service c = new NoOpService(); + ServiceManager manager = new ServiceManager(asList(a, b, c)); + RecordingListener listener = new RecordingListener(); + manager.addListener(listener); + + manager.startAsync().awaitHealthy(); + assertTrue(listener.healthyCalled); + assertFalse(listener.stoppedCalled); + manager.stopAsync().awaitStopped(); + + assertTrue(listener.stoppedCalled); + assertEquals(ImmutableSet.of(b), listener.failedServices); + assertState(manager, Service.State.FAILED, b); + assertState(manager, Service.State.TERMINATED, a, c); + } + + public void testToString() throws Exception { + Service a = new NoOpService(); + Service b = new FailStartService(); + ServiceManager manager = new ServiceManager(asList(a, b)); + String toString = manager.toString(); + assertTrue(toString.contains("NoOpService")); + assertTrue(toString.contains("FailStartService")); + } + + public void testTimeouts() throws Exception { + Service a = new NoOpDelayedSerivce(50); + ServiceManager manager = new ServiceManager(asList(a)); + manager.startAsync(); + try { + manager.awaitHealthy(1, TimeUnit.MILLISECONDS); + fail(); + } catch (TimeoutException expected) { + } + manager.awaitHealthy(100, TimeUnit.MILLISECONDS); // no exception thrown + + manager.stopAsync(); + try { + manager.awaitStopped(1, TimeUnit.MILLISECONDS); + fail(); + } catch (TimeoutException expected) { + } + manager.awaitStopped(100, TimeUnit.MILLISECONDS); // no exception thrown + } + + /** + * This covers a case where if the last service to stop failed then the stopped callback would + * never be called. + */ + public void testSingleFailedServiceCallsStopped() { + Service a = new FailStartService(); + ServiceManager manager = new ServiceManager(asList(a)); + RecordingListener listener = new RecordingListener(); + manager.addListener(listener); + try { + manager.startAsync().awaitHealthy(); + fail(); + } catch (IllegalStateException expected) { + } + assertTrue(listener.stoppedCalled); + } + + /** + * This covers a bug where listener.healthy would get called when a single service failed during + * startup (it occurred in more complicated cases also). + */ + public void testFailStart_singleServiceCallsHealthy() { + Service a = new FailStartService(); + ServiceManager manager = new ServiceManager(asList(a)); + RecordingListener listener = new RecordingListener(); + manager.addListener(listener); + try { + manager.startAsync().awaitHealthy(); + fail(); + } catch (IllegalStateException expected) { + } + assertFalse(listener.healthyCalled); + } + + /** + * This covers a bug where if a listener was installed that would stop the manager if any service + * fails and something failed during startup before service.start was called on all the services, + * then awaitStopped would deadlock due to an IllegalStateException that was thrown when trying to + * stop the timer(!). + */ + public void testFailStart_stopOthers() throws TimeoutException { + Service a = new FailStartService(); + Service b = new NoOpService(); + final ServiceManager manager = new ServiceManager(asList(a, b)); + manager.addListener(new Listener() { + @Override public void failure(Service service) { + manager.stopAsync(); + }}); + manager.startAsync(); + manager.awaitStopped(10, TimeUnit.MILLISECONDS); + } + + private static void assertState( + ServiceManager manager, Service.State state, Service... services) { + Collection<Service> managerServices = manager.servicesByState().get(state); + for (Service service : services) { + assertEquals(service.toString(), state, service.state()); + assertEquals(service.toString(), service.isRunning(), state == Service.State.RUNNING); + assertTrue(managerServices + " should contain " + service, managerServices.contains(service)); + } + } + + /** + * This is for covering a case where the ServiceManager would behave strangely if constructed + * with no service under management. Listeners would never fire because the ServiceManager was + * healthy and stopped at the same time. This test ensures that listeners fire and isHealthy + * makes sense. + */ + public void testEmptyServiceManager() { + Logger logger = Logger.getLogger(ServiceManager.class.getName()); + logger.setLevel(Level.FINEST); + TestLogHandler logHandler = new TestLogHandler(); + logger.addHandler(logHandler); + ServiceManager manager = new ServiceManager(Arrays.<Service>asList()); + RecordingListener listener = new RecordingListener(); + manager.addListener(listener, MoreExecutors.sameThreadExecutor()); + manager.startAsync().awaitHealthy(); + assertTrue(manager.isHealthy()); + assertTrue(listener.healthyCalled); + assertFalse(listener.stoppedCalled); + assertTrue(listener.failedServices.isEmpty()); + manager.stopAsync().awaitStopped(); + assertFalse(manager.isHealthy()); + assertTrue(listener.stoppedCalled); + assertTrue(listener.failedServices.isEmpty()); + // check that our NoOpService is not directly observable via any of the inspection methods or + // via logging. + assertEquals("ServiceManager{services=[]}", manager.toString()); + assertTrue(manager.servicesByState().isEmpty()); + assertTrue(manager.startupTimes().isEmpty()); + Formatter logFormatter = new Formatter() { + @Override public String format(LogRecord record) { + return formatMessage(record); + } + }; + for (LogRecord record : logHandler.getStoredLogRecords()) { + assertFalse(logFormatter.format(record).contains("NoOpService")); + } + } + + /** + * Tests that a ServiceManager can be fully shut down if one of its failure listeners is slow or + * even permanently blocked. + */ + + public void testListenerDeadlock() throws InterruptedException { + final CountDownLatch failEnter = new CountDownLatch(1); + final CountDownLatch failLeave = new CountDownLatch(1); + final CountDownLatch afterStarted = new CountDownLatch(1); + Service failRunService = new AbstractService() { + @Override protected void doStart() { + new Thread() { + @Override public void run() { + notifyStarted(); + // We need to wait for the main thread to leave the ServiceManager.startAsync call to + // ensure that the thread running the failure callbacks is not the main thread. + Uninterruptibles.awaitUninterruptibly(afterStarted); + notifyFailed(new Exception("boom")); + } + }.start(); + } + @Override protected void doStop() { + notifyStopped(); + } + }; + final ServiceManager manager = new ServiceManager( + Arrays.asList(failRunService, new NoOpService())); + manager.addListener(new ServiceManager.Listener() { + @Override public void failure(Service service) { + failEnter.countDown(); + // block until after the service manager is shutdown + Uninterruptibles.awaitUninterruptibly(failLeave); + } + }, MoreExecutors.sameThreadExecutor()); + manager.startAsync(); + afterStarted.countDown(); + // We do not call awaitHealthy because, due to races, that method may throw an exception. But + // we really just want to wait for the thread to be in the failure callback so we wait for that + // explicitly instead. + failEnter.await(); + assertFalse("State should be updated before calling listeners", manager.isHealthy()); + // now we want to stop the services. + Thread stoppingThread = new Thread() { + @Override public void run() { + manager.stopAsync().awaitStopped(); + } + }; + stoppingThread.start(); + // this should be super fast since the only non stopped service is a NoOpService + stoppingThread.join(1000); + assertFalse("stopAsync has deadlocked!.", stoppingThread.isAlive()); + failLeave.countDown(); // release the background thread + } + + /** + * Catches a bug where when constructing a service manager failed, later interactions with the + * service could cause IllegalStateExceptions inside the partially constructed ServiceManager. + * This ISE wouldn't actually bubble up but would get logged by ExecutionQueue. This obfuscated + * the original error (which was not constructing ServiceManager correctly). + */ + public void testPartiallyConstructedManager() { + Logger logger = Logger.getLogger("global"); + logger.setLevel(Level.FINEST); + TestLogHandler logHandler = new TestLogHandler(); + logger.addHandler(logHandler); + NoOpService service = new NoOpService(); + service.startAsync(); + try { + new ServiceManager(Arrays.asList(service)); + fail(); + } catch (IllegalArgumentException expected) {} + service.stopAsync(); + // Nothing was logged! + assertEquals(0, logHandler.getStoredLogRecords().size()); + } + + public void testPartiallyConstructedManager_transitionAfterAddListenerBeforeStateIsReady() { + // The implementation of this test is pretty sensitive to the implementation :( but we want to + // ensure that if weird things happen during construction then we get exceptions. + final NoOpService service1 = new NoOpService(); + // This service will start service1 when addListener is called. This simulates service1 being + // started asynchronously. + Service service2 = new Service() { + final NoOpService delegate = new NoOpService(); + @Override public final void addListener(Listener listener, Executor executor) { + service1.startAsync(); + delegate.addListener(listener, executor); + } + // Delegates from here on down + @Override public final Service startAsync() { + return delegate.startAsync(); + } + + @Override public final Service stopAsync() { + return delegate.stopAsync(); + } + + @Override public final ListenableFuture<State> start() { + return delegate.start(); + } + + @Override public final ListenableFuture<State> stop() { + return delegate.stop(); + } + + @Override public State startAndWait() { + return delegate.startAndWait(); + } + + @Override public State stopAndWait() { + return delegate.stopAndWait(); + } + + @Override public final void awaitRunning() { + delegate.awaitRunning(); + } + + @Override public final void awaitRunning(long timeout, TimeUnit unit) + throws TimeoutException { + delegate.awaitRunning(timeout, unit); + } + + @Override public final void awaitTerminated() { + delegate.awaitTerminated(); + } + + @Override public final void awaitTerminated(long timeout, TimeUnit unit) + throws TimeoutException { + delegate.awaitTerminated(timeout, unit); + } + + @Override public final boolean isRunning() { + return delegate.isRunning(); + } + + @Override public final State state() { + return delegate.state(); + } + + @Override public final Throwable failureCause() { + return delegate.failureCause(); + } + }; + try { + new ServiceManager(Arrays.asList(service1, service2)); + fail(); + } catch (IllegalArgumentException expected) { + assertTrue(expected.getMessage().contains("started transitioning asynchronously")); + } + } + + /** + * This test is for a case where two Service.Listener callbacks for the same service would call + * transitionService in the wrong order due to a race. Due to the fact that it is a race this + * test isn't guaranteed to expose the issue, but it is at least likely to become flaky if the + * race sneaks back in, and in this case flaky means something is definitely wrong. + * + * <p>Before the bug was fixed this test would fail at least 30% of the time. + */ + + public void testTransitionRace() throws TimeoutException { + for (int k = 0; k < 1000; k++) { + List<Service> services = Lists.newArrayList(); + for (int i = 0; i < 5; i++) { + services.add(new SnappyShutdownService(i)); + } + ServiceManager manager = new ServiceManager(services); + manager.startAsync().awaitHealthy(); + manager.stopAsync().awaitStopped(1, TimeUnit.SECONDS); + } + } + + /** + * This service will shutdown very quickly after stopAsync is called and uses a background thread + * so that we know that the stopping() listeners will execute on a different thread than the + * terminated() listeners. + */ + private static class SnappyShutdownService extends AbstractExecutionThreadService { + final int index; + final CountDownLatch latch = new CountDownLatch(1); + + SnappyShutdownService(int index) { + this.index = index; + } + + @Override protected void run() throws Exception { + latch.await(); + } + + @Override protected void triggerShutdown() { + latch.countDown(); + } + + @Override protected String serviceName() { + return this.getClass().getSimpleName() + "[" + index + "]"; + } + } + + public void testNulls() { + ServiceManager manager = new ServiceManager(Arrays.<Service>asList()); + new NullPointerTester() + .setDefault(ServiceManager.Listener.class, new RecordingListener()) + .testAllPublicInstanceMethods(manager); + } + + private static final class RecordingListener extends ServiceManager.Listener { + volatile boolean healthyCalled; + volatile boolean stoppedCalled; + final Set<Service> failedServices = Sets.newConcurrentHashSet(); + + @Override public void healthy() { + healthyCalled = true; + } + + @Override public void stopped() { + stoppedCalled = true; + } + + @Override public void failure(Service service) { + failedServices.add(service); + } + } +} diff --git a/guava-tests/test/com/google/common/util/concurrent/ServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/ServiceTest.java new file mode 100644 index 0000000..e8ff37f --- /dev/null +++ b/guava-tests/test/com/google/common/util/concurrent/ServiceTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.util.concurrent; + +import static com.google.common.util.concurrent.Service.State.FAILED; +import static com.google.common.util.concurrent.Service.State.NEW; +import static com.google.common.util.concurrent.Service.State.RUNNING; +import static com.google.common.util.concurrent.Service.State.STARTING; +import static com.google.common.util.concurrent.Service.State.STOPPING; +import static com.google.common.util.concurrent.Service.State.TERMINATED; + +import junit.framework.TestCase; + +/** + * Unit tests for {@link Service} + */ +public class ServiceTest extends TestCase { + + /** Assert on the comparison ordering of the State enum since we guarantee it. */ + public void testStateOrdering() { + // List every valid (direct) state transition. + assertLessThan(NEW, STARTING); + assertLessThan(NEW, TERMINATED); + + assertLessThan(STARTING, RUNNING); + assertLessThan(STARTING, STOPPING); + assertLessThan(STARTING, FAILED); + + assertLessThan(RUNNING, STOPPING); + assertLessThan(RUNNING, FAILED); + + assertLessThan(STOPPING, FAILED); + assertLessThan(STOPPING, TERMINATED); + } + + private static <T extends Comparable<? super T>> void assertLessThan(T a, T b) { + if (a.compareTo(b) >= 0) { + fail(String.format("Expected %s to be less than %s", a, b)); + } + } +} diff --git a/guava-tests/test/com/google/common/util/concurrent/SettableFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/SettableFutureTest.java index f727690..47f71c0 100644 --- a/guava-tests/test/com/google/common/util/concurrent/SettableFutureTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/SettableFutureTest.java @@ -16,11 +16,11 @@ package com.google.common.util.concurrent; +import junit.framework.TestCase; + import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import junit.framework.TestCase; - /** * Test cases for {@link SettableFuture}. * diff --git a/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java b/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java index d4fd396..3651934 100644 --- a/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java @@ -16,13 +16,13 @@ package com.google.common.util.concurrent; +import junit.framework.TestCase; + import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import junit.framework.TestCase; - /** * Unit test for {@link SimpleTimeLimiter}. * diff --git a/guava-tests/test/com/google/common/util/concurrent/StripedTest.java b/guava-tests/test/com/google/common/util/concurrent/StripedTest.java index 7aa127c..ba93d7b 100644 --- a/guava-tests/test/com/google/common/util/concurrent/StripedTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/StripedTest.java @@ -19,6 +19,7 @@ package com.google.common.util.concurrent; import static com.google.common.collect.Iterables.concat; import com.google.common.base.Functions; +import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -27,13 +28,17 @@ import com.google.common.collect.Sets; import com.google.common.testing.GcFinalization; import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.lang.ref.WeakReference; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.Semaphore; import java.util.concurrent.locks.Lock; - -import junit.framework.TestCase; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Tests for Striped. @@ -51,14 +56,40 @@ public class StripedTest extends TestCase { Striped.semaphore(256, 1)); } + private static final Supplier<ReadWriteLock> READ_WRITE_LOCK_SUPPLIER = + new Supplier<ReadWriteLock>() { + @Override public ReadWriteLock get() { + return new ReentrantReadWriteLock(); + } + }; + + private static final Supplier<Lock> LOCK_SUPPLER = new Supplier<Lock>() { + @Override public Lock get() { + return new ReentrantLock(); + } + }; + + private static final Supplier<Semaphore> SEMAPHORE_SUPPLER = new Supplier<Semaphore>() { + @Override public Semaphore get() { + return new Semaphore(1, false); + } + }; + private static List<Striped<?>> weakImplementations() { - return ImmutableList.of( - Striped.lazyWeakReadWriteLock(50), - Striped.lazyWeakReadWriteLock(64), - Striped.lazyWeakLock(50), - Striped.lazyWeakLock(64), - Striped.lazyWeakSemaphore(50, 1), - Striped.lazyWeakSemaphore(64, 1)); + return ImmutableList.<Striped<?>>builder() + .add(new Striped.SmallLazyStriped<ReadWriteLock>(50, READ_WRITE_LOCK_SUPPLIER)) + .add(new Striped.SmallLazyStriped<ReadWriteLock>(64, READ_WRITE_LOCK_SUPPLIER)) + .add(new Striped.LargeLazyStriped<ReadWriteLock>(50, READ_WRITE_LOCK_SUPPLIER)) + .add(new Striped.LargeLazyStriped<ReadWriteLock>(64, READ_WRITE_LOCK_SUPPLIER)) + .add(new Striped.SmallLazyStriped<Lock>(50, LOCK_SUPPLER)) + .add(new Striped.SmallLazyStriped<Lock>(64, LOCK_SUPPLER)) + .add(new Striped.LargeLazyStriped<Lock>(50, LOCK_SUPPLER)) + .add(new Striped.LargeLazyStriped<Lock>(64, LOCK_SUPPLER)) + .add(new Striped.SmallLazyStriped<Semaphore>(50, SEMAPHORE_SUPPLER)) + .add(new Striped.SmallLazyStriped<Semaphore>(64, SEMAPHORE_SUPPLER)) + .add(new Striped.LargeLazyStriped<Semaphore>(50, SEMAPHORE_SUPPLER)) + .add(new Striped.LargeLazyStriped<Semaphore>(64, SEMAPHORE_SUPPLER)) + .build(); } private static Iterable<Striped<?>> allImplementations() { @@ -162,4 +193,16 @@ public class StripedTest extends TestCase { fail(); } catch (RuntimeException expected) {} } + + public void testMaxSize() { + for (Striped<?> striped : ImmutableList.of( + Striped.lazyWeakLock(Integer.MAX_VALUE), + Striped.lazyWeakSemaphore(Integer.MAX_VALUE, Integer.MAX_VALUE), + Striped.lazyWeakReadWriteLock(Integer.MAX_VALUE))) { + for (int i = 0; i < 3; i++) { + // doesn't throw exception + striped.getAt(Integer.MAX_VALUE - i); + } + } + } } diff --git a/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java b/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java index 73153f5..d26ba63 100644 --- a/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java @@ -16,15 +16,16 @@ package com.google.common.util.concurrent; -import com.google.common.testing.FluentAsserts; +import static org.truth0.Truth.ASSERT; + import com.google.common.testing.NullPointerTester; +import junit.framework.TestCase; + import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; -import junit.framework.TestCase; - /** * Tests for ThreadFactoryBuilder. * @@ -82,7 +83,7 @@ public class ThreadFactoryBuilderTest extends TestCase { ThreadFactory threadFactory2 = builder.build(); Thread thread3 = threadFactory2.newThread(monitoredRunnable); checkThreadPoolName(thread3, 1); - FluentAsserts.assertThat( + ASSERT.that( thread2.getName().substring(0, thread.getName().lastIndexOf('-'))) .isNotEqualTo( thread3.getName().substring(0, thread.getName().lastIndexOf('-'))); diff --git a/guava-tests/test/com/google/common/util/concurrent/UncaughtExceptionHandlersTest.java b/guava-tests/test/com/google/common/util/concurrent/UncaughtExceptionHandlersTest.java index 79539ec..5105c58 100644 --- a/guava-tests/test/com/google/common/util/concurrent/UncaughtExceptionHandlersTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/UncaughtExceptionHandlersTest.java @@ -24,8 +24,6 @@ import com.google.common.util.concurrent.UncaughtExceptionHandlers.Exiter; import junit.framework.TestCase; -import org.junit.Test; - /** * @author Gregory Kick */ @@ -38,7 +36,7 @@ public class UncaughtExceptionHandlersTest extends TestCase { runtimeMock = createMock(Runtime.class); } - @Test public void testExiter() { + public void testExiter() { runtimeMock.exit(1); replay(runtimeMock); new Exiter(runtimeMock).uncaughtException(new Thread(), new Exception()); diff --git a/guava-tests/test/com/google/common/util/concurrent/WrappingExecutorServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/WrappingExecutorServiceTest.java new file mode 100644 index 0000000..48e605d --- /dev/null +++ b/guava-tests/test/com/google/common/util/concurrent/WrappingExecutorServiceTest.java @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2011 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.util.concurrent; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + +import junit.framework.TestCase; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Test for {@link WrappingExecutorService} + * + * @author Chris Nokleberg + */ +public class WrappingExecutorServiceTest extends TestCase { + private static final String RESULT_VALUE = "ran"; + private static final Runnable DO_NOTHING = new Runnable() { + @Override + public void run() { + } + }; + + // Uninteresting delegations + public void testDelegations() throws InterruptedException { + MockExecutor mock = new MockExecutor(); + TestExecutor testExecutor = new TestExecutor(mock); + assertFalse(testExecutor.awaitTermination(10, TimeUnit.MILLISECONDS)); + mock.assertLastMethodCalled("awaitTermination"); + assertFalse(testExecutor.isTerminated()); + mock.assertLastMethodCalled("isTerminated"); + assertFalse(testExecutor.isShutdown()); + mock.assertLastMethodCalled("isShutdown"); + testExecutor.shutdown(); + mock.assertLastMethodCalled("shutdown"); + List<Runnable> list = testExecutor.shutdownNow(); + mock.assertLastMethodCalled("shutdownNow"); + assertEquals(ImmutableList.of(), list); + } + + public void testExecute() { + MockExecutor mock = new MockExecutor(); + TestExecutor testExecutor = new TestExecutor(mock); + testExecutor.execute(DO_NOTHING); + mock.assertLastMethodCalled("execute"); + } + + public void testSubmit() throws InterruptedException, ExecutionException { + { + MockExecutor mock = new MockExecutor(); + TestExecutor testExecutor = new TestExecutor(mock); + Future<?> f = testExecutor.submit(DO_NOTHING); + mock.assertLastMethodCalled("submit"); + f.get(); + } + { + MockExecutor mock = new MockExecutor(); + TestExecutor testExecutor = new TestExecutor(mock); + Future<String> f = testExecutor.submit(DO_NOTHING, RESULT_VALUE); + mock.assertLastMethodCalled("submit"); + assertEquals(RESULT_VALUE, f.get()); + } + { + MockExecutor mock = new MockExecutor(); + TestExecutor testExecutor = new TestExecutor(mock); + Callable<String> task = Callables.returning(RESULT_VALUE); + Future<String> f = testExecutor.submit(task); + mock.assertLastMethodCalled("submit"); + assertEquals(RESULT_VALUE, f.get()); + } + } + + public void testInvokeAll() throws InterruptedException, ExecutionException { + List<Callable<String>> tasks = createTasks(3); + { + MockExecutor mock = new MockExecutor(); + TestExecutor testExecutor = new TestExecutor(mock); + List<Future<String>> futures = testExecutor.invokeAll(tasks); + mock.assertLastMethodCalled("invokeAll"); + checkResults(futures); + } + { + MockExecutor mock = new MockExecutor(); + TimeUnit unit = TimeUnit.SECONDS; + long timeout = 5; + TestExecutor testExecutor = new TestExecutor(mock); + List<Future<String>> futures = testExecutor.invokeAll(tasks, timeout, unit); + mock.assertMethodWithTimeout("invokeAll", timeout, unit); + checkResults(futures); + } + } + + public void testInvokeAny() throws InterruptedException, ExecutionException, TimeoutException { + List<Callable<String>> tasks = createTasks(3); + { + MockExecutor mock = new MockExecutor(); + TestExecutor testExecutor = new TestExecutor(mock); + String s = testExecutor.invokeAny(tasks); + assertEquals("ran0", s); + mock.assertLastMethodCalled("invokeAny"); + } + { + MockExecutor mock = new MockExecutor(); + TimeUnit unit = TimeUnit.SECONDS; + long timeout = 5; + TestExecutor testExecutor = new TestExecutor(mock); + String s = testExecutor.invokeAny(tasks, timeout, unit); + assertEquals(RESULT_VALUE + "0", s); + mock.assertMethodWithTimeout("invokeAny", timeout, unit); + } + } + + private static void checkResults(List<Future<String>> futures) + throws InterruptedException, ExecutionException { + for (int i = 0; i < futures.size(); i++) { + assertEquals(RESULT_VALUE + i, futures.get(i).get()); + } + } + + private static List<Callable<String>> createTasks(int n) { + List<Callable<String>> callables = Lists.newArrayList(); + for (int i = 0; i < n; i++) { + callables.add(Callables.returning(RESULT_VALUE + i)); + } + return callables; + } + + private static final class WrappedCallable<T> implements Callable<T> { + private final Callable<T> delegate; + + public WrappedCallable(Callable<T> delegate) { + this.delegate = delegate; + } + + @Override + public T call() throws Exception { + return delegate.call(); + } + } + + private static final class WrappedRunnable implements Runnable { + private final Runnable delegate; + + public WrappedRunnable(Runnable delegate) { + this.delegate = delegate; + } + + @Override + public void run() { + delegate.run(); + } + } + + private static final class TestExecutor extends WrappingExecutorService { + public TestExecutor(MockExecutor mock) { + super(mock); + } + + @Override + protected <T> Callable<T> wrapTask(Callable<T> callable) { + return new WrappedCallable<T>(callable); + } + + @Override protected Runnable wrapTask(Runnable command) { + return new WrappedRunnable(command); + } + } + + // TODO: If this test can ever depend on EasyMock or the like, use it instead. + private static final class MockExecutor implements ExecutorService { + private String lastMethodCalled = ""; + private long lastTimeoutInMillis = -1; + private ExecutorService inline = MoreExecutors.sameThreadExecutor(); + + public void assertLastMethodCalled(String method) { + assertEquals(method, lastMethodCalled); + } + + public void assertMethodWithTimeout(String method, long timeout, TimeUnit unit) { + assertLastMethodCalled(method + "Timeout"); + assertEquals(unit.toMillis(timeout), lastTimeoutInMillis); + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) { + lastMethodCalled = "awaitTermination"; + return false; + } + + @Override + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) + throws InterruptedException { + lastMethodCalled = "invokeAll"; + assertTaskWrapped(tasks); + return inline.invokeAll(tasks); + } + + @Override + public <T> List<Future<T>> invokeAll( + Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) + throws InterruptedException { + assertTaskWrapped(tasks); + lastMethodCalled = "invokeAllTimeout"; + lastTimeoutInMillis = unit.toMillis(timeout); + return inline.invokeAll(tasks, timeout, unit); + } + + // Define the invokeAny methods to invoke the first task + @Override + public <T> T invokeAny(Collection<? extends Callable<T>> tasks) + throws ExecutionException, InterruptedException { + assertTaskWrapped(tasks); + lastMethodCalled = "invokeAny"; + return inline.submit(Iterables.get(tasks, 0)).get(); + } + + @Override + public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) + throws ExecutionException, InterruptedException, TimeoutException { + assertTaskWrapped(tasks); + lastMethodCalled = "invokeAnyTimeout"; + lastTimeoutInMillis = unit.toMillis(timeout); + return inline.submit(Iterables.get(tasks, 0)).get(timeout, unit); + } + + @Override + public boolean isShutdown() { + lastMethodCalled = "isShutdown"; + return false; + } + + @Override + public boolean isTerminated() { + lastMethodCalled = "isTerminated"; + return false; + } + + @Override + public void shutdown() { + lastMethodCalled = "shutdown"; + } + + @Override + public List<Runnable> shutdownNow() { + lastMethodCalled = "shutdownNow"; + return ImmutableList.of(); + } + + @Override + public <T> Future<T> submit(Callable<T> task) { + lastMethodCalled = "submit"; + assertTrue(task instanceof WrappedCallable); + return inline.submit(task); + } + + @Override + public Future<?> submit(Runnable task) { + lastMethodCalled = "submit"; + assertTrue(task instanceof WrappedRunnable); + return inline.submit(task); + } + + @Override + public <T> Future<T> submit(Runnable task, T result) { + lastMethodCalled = "submit"; + assertTrue(task instanceof WrappedRunnable); + return inline.submit(task, result); + } + + @Override + public void execute(Runnable command) { + lastMethodCalled = "execute"; + assertTrue(command instanceof WrappedRunnable); + inline.execute(command); + } + + private static <T> void assertTaskWrapped( + Collection<? extends Callable<T>> tasks) { + Predicate<Object> p = Predicates.instanceOf(WrappedCallable.class); + assertTrue(Iterables.all(tasks, p)); + } + + } +} diff --git a/guava-tests/test/com/google/common/util/concurrent/WrappingScheduledExecutorServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/WrappingScheduledExecutorServiceTest.java new file mode 100644 index 0000000..479fa8c --- /dev/null +++ b/guava-tests/test/com/google/common/util/concurrent/WrappingScheduledExecutorServiceTest.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.util.concurrent; + +import junit.framework.TestCase; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Test for {@link WrappingScheduledExecutorService} + * + * @author Luke Sandberg + */ +public class WrappingScheduledExecutorServiceTest extends TestCase { + private static final Runnable DO_NOTHING = new Runnable() { + @Override + public void run() { + } + }; + + public void testSchedule() { + MockExecutor mock = new MockExecutor(); + TestExecutor testExecutor = new TestExecutor(mock); + + testExecutor.schedule(DO_NOTHING, 10, TimeUnit.SECONDS); + mock.assertLastMethodCalled("scheduleRunnable", 10, TimeUnit.SECONDS); + + testExecutor.schedule(Executors.callable(DO_NOTHING), 5, TimeUnit.SECONDS); + mock.assertLastMethodCalled("scheduleCallable", 5, TimeUnit.SECONDS); + } + + public void testSchedule_repeating() { + MockExecutor mock = new MockExecutor(); + TestExecutor testExecutor = new TestExecutor(mock); + testExecutor.scheduleWithFixedDelay(DO_NOTHING, 100, 10, TimeUnit.SECONDS); + mock.assertLastMethodCalled("scheduleWithFixedDelay", 100, 10, TimeUnit.SECONDS); + + testExecutor.scheduleAtFixedRate(DO_NOTHING, 3, 7, TimeUnit.SECONDS); + mock.assertLastMethodCalled("scheduleAtFixedRate", 3, 7, TimeUnit.SECONDS); + } + + private static final class WrappedCallable<T> implements Callable<T> { + private final Callable<T> delegate; + + public WrappedCallable(Callable<T> delegate) { + this.delegate = delegate; + } + + @Override + public T call() throws Exception { + return delegate.call(); + } + } + + private static final class WrappedRunnable implements Runnable { + private final Runnable delegate; + + public WrappedRunnable(Runnable delegate) { + this.delegate = delegate; + } + + @Override + public void run() { + delegate.run(); + } + } + + private static final class TestExecutor extends WrappingScheduledExecutorService { + public TestExecutor(MockExecutor mock) { + super(mock); + } + + @Override + protected <T> Callable<T> wrapTask(Callable<T> callable) { + return new WrappedCallable<T>(callable); + } + + @Override protected Runnable wrapTask(Runnable command) { + return new WrappedRunnable(command); + } + } + + private static final class MockExecutor implements ScheduledExecutorService { + String lastMethodCalled = ""; + long lastInitialDelay; + long lastDelay; + TimeUnit lastUnit; + + void assertLastMethodCalled(String method, long delay, TimeUnit unit) { + assertEquals(method, lastMethodCalled); + assertEquals(delay, lastDelay); + assertEquals(unit, lastUnit); + } + + void assertLastMethodCalled(String method, long initialDelay, long delay, TimeUnit unit) { + assertEquals(method, lastMethodCalled); + assertEquals(initialDelay, lastInitialDelay); + assertEquals(delay, lastDelay); + assertEquals(unit, lastUnit); + } + + @Override public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { + assertTrue(command instanceof WrappedRunnable); + lastMethodCalled = "scheduleRunnable"; + lastDelay = delay; + lastUnit = unit; + return null; + } + + @Override public <V> ScheduledFuture<V> schedule( + Callable<V> callable, long delay, TimeUnit unit) { + assertTrue(callable instanceof WrappedCallable); + lastMethodCalled = "scheduleCallable"; + lastDelay = delay; + lastUnit = unit; + return null; + } + + @Override public ScheduledFuture<?> scheduleAtFixedRate( + Runnable command, long initialDelay, long period, TimeUnit unit) { + assertTrue(command instanceof WrappedRunnable); + lastMethodCalled = "scheduleAtFixedRate"; + lastInitialDelay = initialDelay; + lastDelay = period; + lastUnit = unit; + return null; + } + + @Override public ScheduledFuture<?> scheduleWithFixedDelay( + Runnable command, long initialDelay, long delay, TimeUnit unit) { + assertTrue(command instanceof WrappedRunnable); + lastMethodCalled = "scheduleWithFixedDelay"; + lastInitialDelay = initialDelay; + lastDelay = delay; + lastUnit = unit; + return null; + } + + // No need to test these methods as they are handled by WrappingExecutorServiceTest + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) + throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public <T> List<Future<T>> invokeAll( + Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) + throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public <T> T invokeAny(Collection<? extends Callable<T>> tasks) + throws ExecutionException, InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) + throws ExecutionException, InterruptedException, TimeoutException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isShutdown() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isTerminated() { + throw new UnsupportedOperationException(); + } + + @Override + public void shutdown() { + throw new UnsupportedOperationException(); + } + + @Override + public List<Runnable> shutdownNow() { + throw new UnsupportedOperationException(); + } + + @Override + public <T> Future<T> submit(Callable<T> task) { + throw new UnsupportedOperationException(); + } + + @Override + public Future<?> submit(Runnable task) { + throw new UnsupportedOperationException(); + } + + @Override + public <T> Future<T> submit(Runnable task, T result) { + throw new UnsupportedOperationException(); + } + + @Override + public void execute(Runnable command) { + throw new UnsupportedOperationException(); + } + + } +} diff --git a/guava-tests/test/com/google/common/xml/XmlEscapersTest.java b/guava-tests/test/com/google/common/xml/XmlEscapersTest.java new file mode 100644 index 0000000..5052962 --- /dev/null +++ b/guava-tests/test/com/google/common/xml/XmlEscapersTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.xml; + +import static com.google.common.escape.testing.EscaperAsserts.assertEscaping; +import static com.google.common.escape.testing.EscaperAsserts.assertUnescaped; + +import com.google.common.annotations.GwtCompatible; +import com.google.common.escape.CharEscaper; + +import junit.framework.TestCase; + +/** + * Tests for the {@link XmlEscapers} class. + * + * @author Alex Matevossian + * @author David Beaumont + */ +@GwtCompatible +public class XmlEscapersTest extends TestCase { + + public void testXmlContentEscaper() throws Exception { + CharEscaper xmlContentEscaper = (CharEscaper) XmlEscapers.xmlContentEscaper(); + assertBasicXmlEscaper(xmlContentEscaper, false, false); + // Test quotes are not escaped. + assertEquals("\"test\"", xmlContentEscaper.escape("\"test\"")); + assertEquals("'test'", xmlContentEscaper.escape("'test'")); + } + + public void testXmlAttributeEscaper() throws Exception { + CharEscaper xmlAttributeEscaper = (CharEscaper) XmlEscapers.xmlAttributeEscaper(); + assertBasicXmlEscaper(xmlAttributeEscaper, true, true); + // Test quotes are escaped. + assertEquals(""test"", xmlAttributeEscaper.escape("\"test\"")); + assertEquals("'test'", xmlAttributeEscaper.escape("\'test'")); + // Test all escapes + assertEquals("a"b<c>d&e"f'", + xmlAttributeEscaper.escape("a\"b<c>d&e\"f'")); + // Test '\t', '\n' and '\r' are escaped. + assertEquals("a	b
c
d", xmlAttributeEscaper.escape("a\tb\nc\rd")); + } + + // Helper to assert common properties of xml escapers. + private void assertBasicXmlEscaper(CharEscaper xmlEscaper, + boolean shouldEscapeQuotes, boolean shouldEscapeWhitespaceChars) { + // Simple examples (smoke tests) + assertEquals("xxx", xmlEscaper.escape("xxx")); + assertEquals("test & test & test", + xmlEscaper.escape("test & test & test")); + assertEquals("test << 1", xmlEscaper.escape("test << 1")); + assertEquals("test >> 1", xmlEscaper.escape("test >> 1")); + assertEquals("<tab>", xmlEscaper.escape("<tab>")); + + // Test all non-escaped ASCII characters. + String s = "!@#$%^*()_+=-/?\\|]}[{,.;:" + + "abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "1234567890"; + assertEquals(s, xmlEscaper.escape(s)); + + // Test ASCII control characters. + for (char ch = 0; ch < 0x20; ch++) { + if (ch == '\t' || ch == '\n' || ch == '\r') { + // Only these whitespace chars are permitted in XML, + if (shouldEscapeWhitespaceChars) { + assertEscaping(xmlEscaper, "&#x" + Integer.toHexString(ch).toUpperCase() + ";", ch); + } else { + assertUnescaped(xmlEscaper, ch); + } + } else { + // and everything else is replaced with FFFD. + assertEscaping(xmlEscaper, "\uFFFD", ch); + } + } + + // Test _all_ allowed characters (including surrogate values). + for (char ch = 0x20; ch <= 0xFFFD; ch++) { + // There are a small number of cases to consider, so just do it manually. + if (ch == '&') { + assertEscaping(xmlEscaper, "&", ch); + } else if (ch == '<') { + assertEscaping(xmlEscaper, "<", ch); + } else if (ch == '>') { + assertEscaping(xmlEscaper, ">", ch); + } else if (shouldEscapeQuotes && ch == '\'') { + assertEscaping(xmlEscaper, "'", ch); + } else if (shouldEscapeQuotes && ch == '"') { + assertEscaping(xmlEscaper, """, ch); + } else { + String input = String.valueOf(ch); + String escaped = xmlEscaper.escape(input); + assertEquals( + "char 0x" + Integer.toString(ch, 16) + " should not be escaped", + input, escaped); + } + } + + // Test that 0xFFFE and 0xFFFF are replaced with 0xFFFD + assertEscaping(xmlEscaper, "\uFFFD", '\uFFFE'); + assertEscaping(xmlEscaper, "\uFFFD", '\uFFFF'); + + assertEquals("0xFFFE is forbidden and should be replaced during escaping", + "[\uFFFD]", xmlEscaper.escape("[\ufffe]")); + assertEquals("0xFFFF is forbidden and should be replaced during escaping", + "[\uFFFD]", xmlEscaper.escape("[\uffff]")); + } +} |