// Copyright 2010 Google Inc. // // 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.android.stardroid.test.util; import com.google.android.stardroid.base.Lists; import com.google.android.stardroid.test.util.ImmutableEqualsTester.TestableBuilder; import java.util.Arrays; import junit.framework.AssertionFailedError; import junit.framework.TestCase; /** * Unit tests for the {@link ImmutableEqualsTester} class. * * @author Brent Bryan */ public class ImmutableEqualsTesterTest extends TestCase { /** * A test object with trivial semantics that we'll use to test the * {@link ImmutableEqualsTester}. */ public static class MyObject { private final int id; private final String name; public MyObject(int id, Foo foo) { this(id, "" + foo); } public MyObject(int id, SubFoo subFoo) { this(id, "" + subFoo); } public MyObject(int id, String name) { this.id = id; this.name = name; } public MyObject(int id, String... strings) { this(id, Arrays.asList(strings).toString()); } @Override public boolean equals(Object o) { if (o instanceof MyObject) { MyObject that = (MyObject) o; return this.id == that.id && ((this.name == null && that.name == null) || this.name != null && this.name.equals(that.name)); } return false; } @Override public int hashCode() { return Arrays.hashCode(new Object[] {id, name}); } @Override public String toString() { return String.format("Id: %d Name: %s", id, name); } } /** A marker class used for testing. */ static class Foo { @Override public String toString() { return "foo" + hashCode(); } } /** A marker class which is a subclass of {@link Foo} used for testing. */ static class SubFoo extends Foo { @Override public String toString() { return "subfoo" + hashCode(); } } public void testIsArgOfType() { assertTrue(TestableBuilder.isArgOfType((byte)2, Byte.TYPE)); assertTrue(TestableBuilder.isArgOfType((short)2, Short.TYPE)); assertTrue(TestableBuilder.isArgOfType(4, Integer.TYPE)); assertTrue(TestableBuilder.isArgOfType(Integer.valueOf(4), Integer.TYPE)); assertTrue(TestableBuilder.isArgOfType(4L, Long.TYPE)); assertTrue(TestableBuilder.isArgOfType(Long.valueOf(4L), Long.TYPE)); assertTrue(TestableBuilder.isArgOfType(4.0f, Float.TYPE)); assertTrue(TestableBuilder.isArgOfType(4.0, Double.TYPE)); assertTrue(TestableBuilder.isArgOfType(true, Boolean.TYPE)); assertTrue(TestableBuilder.isArgOfType('a', Character.TYPE)); assertTrue(TestableBuilder.isArgOfType("Hello", String.class)); assertTrue(TestableBuilder.isArgOfType(new Foo(), Foo.class)); assertTrue(TestableBuilder.isArgOfType(new SubFoo(), Foo.class)); assertTrue(TestableBuilder.isArgOfType(null, String.class)); assertTrue(TestableBuilder.isArgOfType(null, Foo.class)); assertTrue(TestableBuilder.isArgOfType(null, SubFoo.class)); assertFalse(TestableBuilder.isArgOfType(new Foo(), SubFoo.class)); assertFalse(TestableBuilder.isArgOfType(new Foo(), String.class)); assertFalse(TestableBuilder.isArgOfType("Hi", Foo.class)); assertFalse(TestableBuilder.isArgOfType(null, Long.TYPE)); } public void testGetArgs() { Object[] defaultArgs = {"a", "b", "c", "d"}; Object[] altArgs = {"1", "2", "3", "4"}; // Nasty array to List conversion is required as arrays equality is pointer // based, not equality based. assertEquals(Lists.asList("1", "b", "c", "d"), Arrays.asList(TestableBuilder.getArgs(defaultArgs, altArgs, 0))); assertEquals(Lists.asList("a", "2", "c", "d"), Arrays.asList(TestableBuilder.getArgs(defaultArgs, altArgs, 1))); assertEquals(Lists.asList("a", "b", "c", "4"), Arrays.asList(TestableBuilder.getArgs(defaultArgs, altArgs, 3))); } public void testGetArgs_indexOutOfBounds() { Object[] defaultArgs = {"a", "b", "c", "d"}; Object[] altArgs = {"1", "2", "3", "4"}; assertEquals(defaultArgs, TestableBuilder.getArgs(defaultArgs, altArgs, -1)); assertEquals(defaultArgs, TestableBuilder.getArgs(defaultArgs, altArgs, defaultArgs.length)); assertEquals(defaultArgs, TestableBuilder.getArgs(defaultArgs, altArgs, defaultArgs.length + 10)); } public void testEquals() { ImmutableEqualsTester .of(MyObject.class) .defaultArgs(1, "Pittsburgh") .alternativeArgs(2, "Seattle") .testEquals(); } public void testEquals_nullValues() { ImmutableEqualsTester .of(MyObject.class) .defaultArgs(1, null) .alternativeArgs(Integer.valueOf(2), "Seattle") .testEquals(); } public void testEquals_findUniqueConstructor() { ImmutableEqualsTester .of(MyObject.class) .defaultArgs(1, null) .alternativeArgs(2, new Foo()) .testEquals(); } public void testEquals_findVarArgsConstructor() { ImmutableEqualsTester .of(MyObject.class) .defaultArgs(1, new String[] {"a", "b", "c"}) .alternativeArgs(2, new String[] {"1", "2", "3"}) .testEquals(); } private <F> void assertTestEqualsCausesException(String message, TestableBuilder<F> builder) { boolean caughtError = false; try { builder.testEquals(); } catch (AssertionFailedError e) { caughtError = true; } if (!caughtError) { fail(message); } } public void testEquals_defaultArgsConstructorTypesMismatch() { assertTestEqualsCausesException( "Mismatchs between default argument types and constructor types should cause an error.", ImmutableEqualsTester .of(MyObject.class) .defaultArgs(1, new Foo()) .alternativeArgs(2, "Seattle")); } public void testEquals_alternateArgsConstructorTypesMismatch() { assertTestEqualsCausesException( "Mismatchs between alternative argument types and constructor types should cause an error.", ImmutableEqualsTester .of(MyObject.class) .defaultArgs(1, "Pittsburgh") .alternativeArgs(2, new SubFoo())); } public void testEquals_noConstructorForTypes() { assertTestEqualsCausesException( "Lack of a constructor which matches the argument types should cause an error.", ImmutableEqualsTester .of(MyObject.class) .defaultArgs(1, "Pittsburgh", new Foo()) .alternativeArgs(2, "Seattle", new SubFoo())); } public void testEquals_multipleConstructors() { assertTestEqualsCausesException( "Multiple constructors which match the arguments should cause an error.", ImmutableEqualsTester .of(MyObject.class) .defaultArgs(1, null) .alternativeArgs(2, new SubFoo())); } }