| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.felix.scr.impl.inject.internal; |
| |
| import java.lang.reflect.Array; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.felix.scr.impl.inject.internal.Annotations; |
| import org.mockito.Mockito; |
| import org.osgi.framework.Bundle; |
| |
| import junit.framework.TestCase; |
| |
| public class AnnotationTest extends TestCase |
| { |
| |
| public void testMapIdentifierToKey() throws Exception |
| { |
| assertEquals("foo", Annotations.mapIdentifierToKey("foo")); |
| assertEquals("foo", Annotations.mapIdentifierToKey("$foo")); |
| assertEquals("foo", Annotations.mapIdentifierToKey("foo$")); |
| assertEquals("$foo", Annotations.mapIdentifierToKey("$$foo")); |
| assertEquals("foobar", Annotations.mapIdentifierToKey("foo$bar")); |
| assertEquals("foo$bar", Annotations.mapIdentifierToKey("foo$$bar")); |
| assertEquals("foo.", Annotations.mapIdentifierToKey("foo_")); |
| assertEquals("foo_", Annotations.mapIdentifierToKey("foo__")); |
| assertEquals(".foo", Annotations.mapIdentifierToKey("_foo")); |
| assertEquals("_foo", Annotations.mapIdentifierToKey("__foo")); |
| assertEquals("foo.bar", Annotations.mapIdentifierToKey("foo_bar")); |
| assertEquals("foo_bar", Annotations.mapIdentifierToKey("foo__bar")); |
| assertEquals("foo$", Annotations.mapIdentifierToKey("foo$$$")); |
| assertEquals("foo_.", Annotations.mapIdentifierToKey("foo___")); |
| assertEquals("foo-.bar", Annotations.mapIdentifierToKey("foo$_$_bar")); |
| assertEquals("six-prop", Annotations.mapIdentifierToKey("six$_$prop")); |
| assertEquals("seven$.prop", Annotations.mapIdentifierToKey("seven$$_$prop")); |
| } |
| |
| public void testMapTypeNameToKey() throws Exception |
| { |
| assertEquals("service.ranking", Annotations.mapTypeNameToKey("ServiceRanking")); |
| assertEquals("some_value", Annotations.mapTypeNameToKey("Some_Value")); |
| assertEquals("osgi.property", Annotations.mapTypeNameToKey("OSGiProperty")); |
| } |
| |
| public enum E1 {a, b, c} |
| public @interface A1 { |
| boolean bool(); |
| byte byt(); |
| char cha(); |
| Class<?> clas(); |
| E1 e1(); |
| double doubl(); |
| float floa(); |
| int integer(); |
| long lon(); |
| short shor(); |
| String string(); |
| } |
| |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| private Bundle mockBundle() throws ClassNotFoundException |
| { |
| Bundle b = Mockito.mock(Bundle.class); |
| Mockito.when(b.loadClass(String.class.getName())).thenReturn((Class) String.class); |
| Mockito.when(b.loadClass(Integer.class.getName())).thenReturn((Class) Integer.class); |
| return b; |
| } |
| |
| public void testA1() throws Exception |
| { |
| Map<String, Object> values = allValues(); |
| |
| Object o = Annotations.toObject( A1.class, values, mockBundle(), false); |
| assertTrue("expected an A1", o instanceof A1); |
| |
| A1 a = (A1) o; |
| checkA1(a); |
| } |
| |
| private void checkA1(A1 a) |
| { |
| assertEquals(true, a.bool()); |
| assertEquals((byte)12, a.byt()); |
| assertEquals('c', a.cha()); |
| assertEquals(String.class, a.clas()); |
| assertEquals(E1.a, a.e1()); |
| assertEquals(3.14d, a.doubl()); |
| assertEquals(500f, a.floa()); |
| assertEquals(3, a.integer()); |
| assertEquals(12345678l, a.lon()); |
| assertEquals((short)3, a.shor()); |
| assertEquals("3", a.string()); |
| } |
| |
| public void testA1FromArray() throws Exception |
| { |
| Map<String, Object> values = arrayValues(); |
| |
| Object o = Annotations.toObject( A1.class, values, mockBundle(), false); |
| assertTrue("expected an A1", o instanceof A1); |
| |
| A1 a = (A1) o; |
| assertEquals(true, a.bool()); |
| assertEquals((byte)12, a.byt()); |
| assertEquals(String.class, a.clas()); |
| assertEquals(E1.a, a.e1()); |
| assertEquals(3.14d, a.doubl()); |
| assertEquals(500f, a.floa()); |
| assertEquals(3, a.integer()); |
| assertEquals(12345678l, a.lon()); |
| assertEquals((short)3, a.shor()); |
| assertEquals(null, a.string()); |
| } |
| |
| private Map<String, Object> allValues() |
| { |
| Map<String, Object> values = new HashMap<>(); |
| values.put("bool", "true"); |
| values.put("byt", 12l); |
| values.put("cha", 'c'); |
| values.put("clas", String.class.getName()); |
| values.put("e1", E1.a.toString()); |
| values.put("doubl", "3.14"); |
| values.put("floa", 500l); |
| values.put("integer", 3.0d); |
| values.put("lon", "12345678"); |
| values.put("shor", 3l); |
| values.put("string", 3); |
| values.put("array", new String[]{"foo", "bar"}); |
| return values; |
| } |
| |
| public void testA1NoValues() throws Exception |
| { |
| Map<String, Object> values = new HashMap<>(); |
| |
| Object o = Annotations.toObject( A1.class, values, mockBundle(), false); |
| assertTrue("expected an A1", o instanceof A1); |
| |
| A1 a = (A1) o; |
| assertEquals(false, a.bool()); |
| assertEquals((byte)0, a.byt()); |
| assertEquals((char)0, a.cha()); |
| assertEquals(null, a.clas()); |
| assertEquals(null, a.e1()); |
| assertEquals(0d, a.doubl()); |
| assertEquals(0f, a.floa()); |
| assertEquals(0, a.integer()); |
| assertEquals(0l, a.lon()); |
| assertEquals((short)0, a.shor()); |
| assertEquals(null, a.string()); |
| } |
| |
| public @interface A2 { |
| boolean bool() default true; |
| byte byt() default 5; |
| char cha() default 'a'; |
| Class<?> clas() default Integer.class; |
| E1 e1() default E1.b; |
| double doubl() default -2; |
| float floa() default -4; |
| int integer() default -5; |
| long lon() default Long.MIN_VALUE; |
| short shor() default -8; |
| String string() default "default"; |
| String[] array() default {}; |
| } |
| |
| public void testA2AllValues() throws Exception |
| { |
| Map<String, Object> values = allValues(); |
| |
| Object o = Annotations.toObject( A2.class, values, mockBundle(), false); |
| assertTrue("expected an A2", o instanceof A2); |
| |
| A2 a = (A2) o; |
| assertEquals(true, a.bool()); |
| assertEquals((byte)12, a.byt()); |
| assertEquals('c', a.cha()); |
| assertEquals(String.class, a.clas()); |
| assertEquals(E1.a, a.e1()); |
| assertEquals(3.14d, a.doubl()); |
| assertEquals(500f, a.floa()); |
| assertEquals(3, a.integer()); |
| assertEquals(12345678l, a.lon()); |
| assertEquals((short)3, a.shor()); |
| assertEquals("3", a.string()); |
| assertArrayEquals(new String[]{"foo", "bar"}, a.array()); |
| } |
| |
| public void testA2DefaultValues() throws Exception |
| { |
| Map<String, Object> values = Collections.emptyMap(); |
| |
| Object o = Annotations.toObject( A2.class, values, mockBundle(), false); |
| assertTrue("expected an A2", o instanceof A2); |
| |
| A2 a = (A2) o; |
| assertEquals(false, a.bool()); |
| assertEquals((byte)0, a.byt()); |
| assertEquals((char)0, a.cha()); |
| assertEquals(null, a.clas()); |
| assertEquals(null, a.e1()); |
| assertEquals(0.0, a.doubl()); |
| assertEquals(0.0f, a.floa()); |
| assertEquals(0, a.integer()); |
| assertEquals(0, a.lon()); |
| assertEquals((short)0, a.shor()); |
| assertEquals(null, a.string()); |
| assertEquals(0, a.array().length); |
| } |
| |
| public @interface A1Arrays { |
| boolean[] bool(); |
| byte[] byt(); |
| char[] cha(); |
| Class<?>[] clas(); |
| E1[] e1(); |
| double[] doubl(); |
| float[] floa(); |
| int[] integer(); |
| long[] lon(); |
| short[] shor(); |
| String[] string(); |
| } |
| |
| public void testA1ArraysNoValues() throws Exception |
| { |
| Map<String, Object> values = new HashMap<>(); |
| |
| Object o = Annotations.toObject( A1Arrays.class, values, mockBundle(), false); |
| assertTrue("expected an A1Arrays", o instanceof A1Arrays); |
| |
| A1Arrays a = (A1Arrays) o; |
| assertEquals(0, a.bool().length); |
| assertEquals(0, a.byt().length); |
| assertEquals(0, a.cha().length); |
| assertEquals(0, a.clas().length); |
| assertEquals(0, a.e1().length); |
| assertEquals(0, a.doubl().length); |
| assertEquals(0, a.floa().length); |
| assertEquals(0, a.integer().length); |
| assertEquals(0, a.lon().length); |
| assertEquals(0, a.shor().length); |
| assertEquals(0, a.string().length); |
| } |
| |
| public void testA1Array() throws Exception |
| { |
| Map<String, Object> values = allValues(); |
| |
| Object o = Annotations.toObject( A1Arrays.class, values, mockBundle(), false); |
| assertTrue("expected an A1Arrays", o instanceof A1Arrays); |
| |
| A1Arrays a = (A1Arrays) o; |
| assertArrayEquals(new boolean[] {true}, a.bool()); |
| assertArrayEquals(new byte[] {(byte)12}, a.byt()); |
| assertArrayEquals(new char[] {'c'}, a.cha()); |
| assertArrayEquals(new Class<?>[] {String.class}, a.clas()); |
| assertArrayEquals(new E1[] {E1.a}, a.e1()); |
| assertArrayEquals(new double[] {3.14d}, a.doubl()); |
| assertArrayEquals(new float[] {500f}, a.floa()); |
| assertArrayEquals(new int[] {3}, a.integer()); |
| assertArrayEquals(new long[] {12345678l}, a.lon()); |
| assertArrayEquals(new short[] {(short)3}, a.shor()); |
| assertArrayEquals(new String[] {"3"}, a.string()); |
| } |
| |
| private void assertArrayEquals(Object a, Object b) |
| { |
| assertTrue(a.getClass().isArray()); |
| assertTrue(b.getClass().isArray()); |
| assertEquals("wrong length", Array.getLength(a), Array.getLength(b)); |
| assertEquals("wrong type", a.getClass().getComponentType(), b.getClass().getComponentType()); |
| for (int i = 0; i < Array.getLength(a); i++) |
| { |
| assertEquals("different value at " + i, Array.get(a, i), Array.get(b, i)); |
| } |
| |
| } |
| |
| private Map<String, Object> arrayValues() |
| { |
| Map<String, Object> values = new HashMap<>(); |
| values.put("bool", new boolean[] {true, false}); |
| values.put("byt", new byte[] {12, 3}); |
| values.put("cha", new char[] {'c', 'h', 'a', 'r'}); |
| values.put("clas", new String[] {String.class.getName(), Integer.class.getName()}); |
| values.put("e1", new String[] {E1.a.name(), E1.b.name()}); |
| values.put("doubl", new double[] {3.14, 2.78, 9}); |
| values.put("floa", new float[] {500, 37.44f}); |
| values.put("integer", new int[] {3, 6, 9}); |
| values.put("lon", new long[] {12345678l, -1}); |
| values.put("shor", new short[] {3, 88}); |
| values.put("string", new String[] {}); |
| return values; |
| } |
| |
| public void testA1ArrayFromArray() throws Exception |
| { |
| Map<String, Object> values = arrayValues(); |
| |
| doA1ArrayTest(values); |
| } |
| |
| public void testA1ArrayFromCollection() throws Exception |
| { |
| Map<String, Object> values = arrayValues(); |
| Map<String, Object> collectionValues = new HashMap<>(); |
| for (Map.Entry<String, Object> entry: values.entrySet()) |
| { |
| collectionValues.put(entry.getKey(), toList(entry.getValue())); |
| } |
| |
| doA1ArrayTest(collectionValues); |
| } |
| |
| private List<?> toList(Object value) |
| { |
| List<Object> result = new ArrayList<>(); |
| for (int i = 0; i < Array.getLength(value); i++) |
| { |
| result.add(Array.get(value, i)); |
| } |
| return result; |
| } |
| |
| private void doA1ArrayTest(Map<String, Object> values) throws ClassNotFoundException |
| { |
| Object o = Annotations.toObject( A1Arrays.class, values, mockBundle(), false); |
| assertTrue("expected an A1Arrays", o instanceof A1Arrays); |
| |
| A1Arrays a = (A1Arrays) o; |
| assertArrayEquals(new boolean[] {true, false}, a.bool()); |
| assertArrayEquals(new byte[] {12, 3}, a.byt()); |
| assertArrayEquals(new char[] {'c', 'h', 'a', 'r'}, a.cha()); |
| assertArrayEquals(new Class<?>[] {String.class, Integer.class}, a.clas()); |
| assertArrayEquals(new E1[] {E1.a, E1.b}, a.e1()); |
| assertArrayEquals(new double[] {3.14, 2.78, 9}, a.doubl()); |
| assertArrayEquals(new float[] {500f, 37.44f}, a.floa()); |
| assertArrayEquals(new int[] {3, 6, 9}, a.integer()); |
| assertArrayEquals(new long[] {12345678l, -1}, a.lon()); |
| assertArrayEquals(new short[] {(short)3, 88}, a.shor()); |
| assertArrayEquals(new String[] {}, a.string()); |
| } |
| |
| public @interface B1 { |
| boolean bool(); |
| byte byt(); |
| Class<?> clas(); |
| E1 e1(); |
| double doubl(); |
| float floa(); |
| int integer(); |
| long lon(); |
| short shor(); |
| String string(); |
| A1 a1(); |
| A1[] a1array(); |
| } |
| |
| public void testB1() throws Exception |
| { |
| Map<String, Object> values = b1Values(); |
| |
| Object o = Annotations.toObject( B1.class, values, mockBundle(), true); |
| assertTrue("expected an B1 " + o, o instanceof B1); |
| B1 b = (B1) o; |
| checkB1(b); |
| } |
| |
| private void checkB1(B1 b) |
| { |
| checkA1(b.a1()); |
| assertEquals(3, b.a1array().length); |
| checkA1(b.a1array()[0]); |
| checkA1(b.a1array()[1]); |
| checkA1(b.a1array()[2]); |
| } |
| |
| private Map<String, Object> b1Values() |
| { |
| Map<String, Object> a1Values = allValues(); |
| Map<String, Object> values = allValues(); |
| nest(values, "a1", 0, a1Values); |
| nest(values, "a1array", 0, a1Values); |
| nest(values, "a1array", 1, a1Values); |
| nest(values, "a1array", 2, a1Values); |
| return values; |
| } |
| |
| private void nest(Map<String, Object> values, String key, int i, |
| Map<String, Object> a1Values) |
| { |
| for (Map.Entry<String, Object> entry: a1Values.entrySet()) |
| { |
| values.put(key + "." + i + "." + entry.getKey(), entry.getValue()); |
| } |
| } |
| |
| public @interface C1 { |
| boolean bool(); |
| byte byt(); |
| Class<?> clas(); |
| E1 e1(); |
| double doubl(); |
| float floa(); |
| int integer(); |
| long lon(); |
| short shor(); |
| String string(); |
| B1 b1(); |
| B1[] b1array(); |
| } |
| |
| public void testC1() throws Exception |
| { |
| Map<String, Object> values = c1Values(); |
| |
| Object o = Annotations.toObject( C1.class, values, mockBundle(), true); |
| assertTrue("expected an B1 " + o, o instanceof C1); |
| C1 c = (C1) o; |
| checkB1(c.b1()); |
| assertEquals(3, c.b1array().length); |
| checkB1(c.b1array()[0]); |
| checkB1(c.b1array()[1]); |
| checkB1(c.b1array()[2]); |
| |
| } |
| |
| private Map<String, Object> c1Values() |
| { |
| Map<String, Object> b1Values = b1Values(); |
| Map<String, Object> values = allValues(); |
| nest(values, "b1", 0, b1Values); |
| nest(values, "b1array", 0, b1Values); |
| nest(values, "b1array", 1, b1Values); |
| nest(values, "b1array", 2, b1Values); |
| return values; |
| } |
| |
| public interface I0 { |
| boolean bool(); |
| byte byt(); |
| Class<?> clas(); |
| E1 e1(); |
| } |
| public interface AI1 extends I0 { |
| double doubl(); |
| float floa(); |
| int integer(); |
| long lon(); |
| short shor(); |
| String string(); |
| } |
| |
| public interface BI1 extends I0 { |
| double doubl(); |
| float floa(); |
| int integer(); |
| long lon(); |
| short shor(); |
| String string(); |
| AI1 a1(); |
| AI1[] a1array(); |
| } |
| |
| public interface CI1 extends I0 { |
| double doubl(); |
| float floa(); |
| int integer(); |
| long lon(); |
| short shor(); |
| String string(); |
| BI1 b1(); |
| BI1[] b1array(); |
| } |
| |
| public void testAI1() throws Exception |
| { |
| Map<String, Object> values = allValues(); |
| |
| Object o = Annotations.toObject( AI1.class, values, mockBundle(), true); |
| assertTrue("expected an AI1", o instanceof AI1); |
| |
| AI1 a = (AI1) o; |
| checkAI1(a); |
| } |
| |
| private void checkAI1(AI1 a) |
| { |
| assertEquals(true, a.bool()); |
| assertEquals((byte)12, a.byt()); |
| assertEquals(String.class, a.clas()); |
| assertEquals(E1.a, a.e1()); |
| assertEquals(3.14d, a.doubl()); |
| assertEquals(500f, a.floa()); |
| assertEquals(3, a.integer()); |
| assertEquals(12345678l, a.lon()); |
| assertEquals((short)3, a.shor()); |
| assertEquals("3", a.string()); |
| } |
| |
| public void testBI1() throws Exception |
| { |
| Map<String, Object> values = b1Values(); |
| |
| Object o = Annotations.toObject( BI1.class, values, mockBundle(), true); |
| assertTrue("expected an B1 " + o, o instanceof BI1); |
| BI1 b = (BI1) o; |
| checkBI1(b); |
| } |
| |
| private void checkBI1(BI1 b) |
| { |
| checkAI1(b.a1()); |
| assertEquals(3, b.a1array().length); |
| checkAI1(b.a1array()[0]); |
| checkAI1(b.a1array()[1]); |
| checkAI1(b.a1array()[2]); |
| } |
| |
| public void testCI1() throws Exception |
| { |
| Map<String, Object> values = c1Values(); |
| |
| Object o = Annotations.toObject( CI1.class, values, mockBundle(), true); |
| assertTrue("expected an B1 " + o, o instanceof CI1); |
| CI1 c = (CI1) o; |
| checkBI1(c.b1()); |
| assertEquals(3, c.b1array().length); |
| checkBI1(c.b1array()[0]); |
| checkBI1(c.b1array()[1]); |
| checkBI1(c.b1array()[2]); |
| |
| } |
| |
| class Odd |
| { |
| private final String content; |
| |
| public Odd(String content) |
| { |
| this.content = content; |
| } |
| |
| public String getContent() |
| { |
| return content; |
| } |
| } |
| |
| class Odder extends Odd |
| { |
| |
| public Odder(String content) |
| { |
| super(content); |
| } |
| |
| } |
| |
| interface OddTest |
| { |
| Odd odd1(); |
| |
| Odd odd2(); |
| |
| Odd odd3(); |
| |
| Odd odder1(); |
| |
| Odd odder2(); |
| |
| Odd odder3(); |
| } |
| |
| public void testOddClasses() throws Exception |
| { |
| Map<String, Object> values = new HashMap<>(); |
| values.put("odd1", new Odd("one")); |
| values.put("odd2", Collections.singletonList(new Odd("two"))); |
| values.put("odd3", new Odd[] {new Odd("three"), new Odd("four")}); |
| values.put("odder1", new Odder("one")); |
| values.put("odder2", Collections.singletonList(new Odder("two"))); |
| values.put("odder3", new Odder[] {new Odder("three"), new Odder("four")}); |
| |
| Object o = Annotations.toObject(OddTest.class, values, mockBundle(), true); |
| assertTrue("expected an OddTest", o instanceof OddTest); |
| OddTest ot = (OddTest)o; |
| assertOdd("one", ot.odd1()); |
| assertOdd("two", ot.odd2()); |
| assertOdd("three", ot.odd3()); |
| assertOdder("one", ot.odder1()); |
| assertOdder("two", ot.odder2()); |
| assertOdder("three", ot.odder3()); |
| } |
| |
| public @interface SETest1 { |
| String value(); |
| } |
| |
| public @interface SETest2 { |
| boolean foo() default true; |
| String value(); |
| } |
| |
| public @interface SETest3 { |
| boolean foo(); |
| String value(); |
| } |
| |
| public @interface SETest4 { |
| boolean foo(); |
| String values(); |
| } |
| |
| public @interface PrefixTest { |
| String PREFIX_ = "org.apache."; |
| |
| boolean foo() default true; |
| String[] values() default {"a"}; |
| String value(); |
| } |
| |
| public @interface SingleElementTest { |
| String PREFIX_ = "org.apache."; |
| |
| String value(); |
| } |
| |
| public void testSingleElementAnnotation() throws Exception |
| { |
| assertFalse(Annotations.isSingleElementAnnotation(Map.class)); |
| assertTrue(Annotations.isSingleElementAnnotation(SETest1.class)); |
| assertTrue(Annotations.isSingleElementAnnotation(SETest2.class)); |
| assertFalse(Annotations.isSingleElementAnnotation(SETest3.class)); |
| assertFalse(Annotations.isSingleElementAnnotation(SETest4.class)); |
| assertTrue(Annotations.isSingleElementAnnotation(SingleElementTest.class)); |
| } |
| |
| public void testGetPrefix() throws Exception |
| { |
| assertNull(Annotations.getPrefix(Map.class)); |
| assertNull(Annotations.getPrefix(SETest1.class)); |
| assertNull(Annotations.getPrefix(SETest2.class)); |
| assertNull(Annotations.getPrefix(SETest3.class)); |
| assertNull(Annotations.getPrefix(SETest4.class)); |
| assertNull(Annotations.getPrefix(A1.class)); |
| assertEquals("org.apache.", Annotations.getPrefix(PrefixTest.class)); |
| } |
| |
| public void testMappingWithPrefix() throws Exception |
| { |
| final Map<String, Object> values = new HashMap<>(); |
| values.put("foo", false); |
| values.put("org.apache.foo", true); |
| values.put("values", "false-values"); |
| values.put("org.apache.values", "true-values"); |
| values.put("value", "false-value"); |
| values.put("org.apache.prefix.test", "true-value"); |
| |
| final PrefixTest o = Annotations.toObject( PrefixTest.class, values, mockBundle(), true); |
| assertEquals("true-value", o.value()); |
| assertEquals(1, o.values().length); |
| assertEquals("true-values", o.values()[0]); |
| assertEquals(true, o.foo()); |
| } |
| |
| public void testMappingWithPrefixSingleValue() throws Exception |
| { |
| final Map<String, Object> values = new HashMap<>(); |
| values.put("value", "false-value"); |
| values.put("org.apache.single.element.test", "true-value"); |
| |
| final SingleElementTest o = Annotations.toObject( SingleElementTest.class, values, mockBundle(), true); |
| assertEquals("true-value", o.value()); |
| } |
| |
| private void assertOdd(String expectedContent, Object actual) { |
| assertTrue("expected an Odd", actual instanceof Odd); |
| assertEquals("Expected Odd contents", expectedContent, ((Odd)actual).getContent()); |
| } |
| private void assertOdder(String expectedContent, Object actual) { |
| assertTrue("expected an Odder", actual instanceof Odder); |
| assertEquals("Expected Odd contents", expectedContent, ((Odder)actual).getContent()); |
| } |
| } |