/*****************************************************************************
* Copyright (C) PicoContainer Organization. All rights reserved. *
* ------------------------------------------------------------------------- *
* The software in this package is published under the terms of the BSD *
* style license a copy of which has been included with this distribution in *
* the LICENSE.txt file. *
* *
* Original code by Joerg Schaible *
*****************************************************************************/
package tests.jfun.yan.tck;
import junit.framework.Assert;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import jfun.yan.*;
import jfun.yan.containers.DefaultContainer;
import jfun.yan.factory.GlobalScope;
import jfun.yan.factory.ThreadLocalScope;
import jfun.yan.util.AmbiguityException;
import jfun.yan.util.ReflectionUtil;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* Test suite for a ComponentAdapter implementation.
* @author Jörg Schaible
* @since 1.1
*/
public abstract class BaseComponentTestCase
extends TestCase {
public static void main(String[] args){
tests.jfun.yan.Utils.runTest(suite());
}
private static TestSuite suite(){
return new TestSuite(BaseComponentTestCase.class);
}
public static int SERIALIZABLE = 1;
public static int VERIFYING = 2;
public static int INSTANTIATING = 4;
public static int RESOLVING = 8;
protected int getComponentAdapterNature() {
return SERIALIZABLE | VERIFYING | INSTANTIATING | RESOLVING;
}
/*
protected ComponentAdapterFactory createDefaultComponentAdapterFactory() {
return new DefaultComponentAdapterFactory();
}
*/
// ============================================
// Default
// ============================================
/**
* Prepare the test <em>verifyWithoutDependencyWorks</em>.
* @param picoContainer container, may probably not be used.
* @return a ComponentAdapter of the type to test for a component without dependencies. Registration in the pico is not
* necessary.
*/
protected abstract Component prepDEF_verifyWithoutDependencyWorks(Container picoContainer);
final public void testDEF_verifyWithoutDependencyWorks() {
final Container yan = new DefaultContainer();
final Component component = prepDEF_verifyWithoutDependencyWorks(yan);
//assertSame(getComponentAdapterType(), component.getClass());
//component.verify(yan.getDependency(component.getType(), yan));
verify(component, yan);
}
/**
* Prepare the test <em>verifyDoesNotInstantiate</em>.
* @param yan container, may probably not be used.
* @return a Component of the type to test for a component that may throw on instantiation. Registration in the pico
* is not necessary.
*/
protected abstract Component prepDEF_verifyDoesNotInstantiate(Container yan);
final public void testDEF_verifyDoesNotInstantiate() {
final Container yan = new DefaultContainer();
final Component component = prepDEF_verifyDoesNotInstantiate(yan);
//assertSame(getComponentAdapterType(), component.getClass());
final Component notInstantiatablecomponentAdapter =
new NotInstantiatableComponentAdapter(component);
final Container wrappedPicoContainer = wrapComponentInstances(
NotInstantiatableComponentAdapter.class, yan, null);
verify(notInstantiatablecomponentAdapter, wrappedPicoContainer);
/*.verify(
wrappedPicoContainer.getDependency
(notInstantiatablecomponentAdapter.getType()));*/
}
// ============================================
// Serializable
// ============================================
/**
* Prepare the test <em>isSerializable</em>. Overload this function, if the Component supports
* serialization.
* @param yan container, may probably not be used.
* @return a Component of the type to test. Registration in the pico is not necessary.
*/
protected Component prepSER_isSerializable(Container yan) {
throw new AssertionFailedError("You have to overwrite this method for a useful test");
}
public static final class TestTransient implements java.io.Serializable{
private transient final String s = new String("abc");
public String getS() {
return s;
}
}
public static void testTransient()
throws Exception{
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
final ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
final TestTransient tt = new TestTransient();
assertEquals("abc", tt.getS());
outputStream.writeObject(tt);
final ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
final TestTransient tt2 = (TestTransient)inputStream.readObject();
assertNull(tt2.getS());
}
private void testSerializable(Component component, Container yan)
throws IOException, ClassNotFoundException{
//assertSame(getComponentAdapterType(), component.getClass());
final Object instance = create(component, yan);
assertNotNull(instance);
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
final ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(component);
outputStream.close();
final ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
final Component serializedComponentAdapter = (Component) inputStream.readObject();
inputStream.close();
//if(!java.lang.reflect.Proxy.isProxyClass(component.getType()))
assertEquals(component.getType(), serializedComponentAdapter.getType());
final Object instanceAfterSerialization = create(serializedComponentAdapter, yan);
assertNotNull(instanceAfterSerialization);
//if(!java.lang.reflect.Proxy.isProxyClass(component.getType()))
assertSame(instance.getClass(), instanceAfterSerialization.getClass());
//else
// assertEquals(instance.getClass().getInterfaces().length, instanceAfterSerialization.getClass().getInterfaces().length);
}
final public void testSER_isSerializable()
throws IOException, ClassNotFoundException {
/*
if ((getComponentAdapterNature() & SERIALIZABLE) > 0) {
final Container yan = new DefaultContainer();
final Component component = prepSER_isSerializable(yan);
//assertSame(getComponentAdapterType(), component.getClass());
final Object instance = create(component, yan);
assertNotNull(instance);
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
final ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(component);
outputStream.close();
final ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
final Component serializedComponentAdapter = (Component) inputStream.readObject();
inputStream.close();
assertEquals(component.getType(), serializedComponentAdapter.getType());
final Object instanceAfterSerialization = create(serializedComponentAdapter, yan);
assertNotNull(instanceAfterSerialization);
assertSame(instance.getClass(), instanceAfterSerialization.getClass());
}*/
final Container yan = new DefaultContainer();
testSerializable(prepSER_isSerializable(yan), yan);
testSerializable(Components.value("hello"), yan);
testSerializable(Components.ctor(ArrayList.class, null), yan);
testSerializable(Components.ctor(ArrayList.class, null), yan);
testSerializable(Components.method(this, "greet").withArgument(0, Components.value("Tom")).singleton().proxy(), yan);
testSerializable(Components.method(this, "greet").withArgument(0, Components.value("Tom")).singleton(new GlobalScope()).proxy(), yan);
testSerializable(Components.method(this, "greet").withArgument(0, Components.value("Tom")).singleton(new ThreadLocalScope()).proxy(), yan);
}
public static String greet(String name){
return "hello " +name;
}
/**
* Prepare the test <em>isXStreamSerializable</em>. Overload this function, if the Component supports
* serialization.
* @param yan container, may probably not be used.
* @return a Component of the type to test. Registration in the pico is not necessary.
*/
protected Component prepSER_isXStreamSerializable(Container yan) {
throw new AssertionFailedError("You have to overwrite this method for a useful test");
}
// ============================================
// Verifying
// ============================================
/**
* Prepare the test <em>verificationFailsWithUnsatisfiedDependency</em>. Overload this function, if the
* Component's verification can fail e.g. due to an unresolved dependency.
* @param yan container, may probably not be used.
* @return a Component of the type to test, that fails for the verification, e.g. because of a compoennt with missing
* dependencies. Registration in the pico is not necessary.
*/
protected Component prepVER_verificationFails(Container yan) {
throw new AssertionFailedError("You have to overwrite this method for a useful test");
}
final public void testVER_verificationFails() {
if ((getComponentAdapterNature() & VERIFYING) > 0) {
final Container yan = new DefaultContainer();
final Component component = prepVER_verificationFails(yan);
//assertSame(getComponentAdapterType(), component.getClass());
try {
yan.verifyComponent(component);
fail("YanException expected");
} catch (YanException e) {
} catch (Exception e) {
fail("YanException expected");
}
try {
create(component, yan);//component.create(yan.getDependency(component.getType()));
fail("PicoInitializationException or YanException expected");
} catch (ComponentInstantiationException e) {
} catch (YanException e) {
} catch (Exception e) {
fail("PicoInitializationException or YanException expected");
}
}
}
// ============================================
// Instantiating
// ============================================
/**
* Prepare the test <em>createsNewInstances</em>. Overload this function, if the Component is instantiating. It
* should create a new instance with every call.
* @param yan container, may probably not be used.
* @return a Component of the type to test. Registration in the pico is not necessary.
*/
protected Component prepINS_createsNewInstances(Container yan) {
throw new AssertionFailedError("You have to overwrite this method for a useful test");
}
private static Object create(Component cc, ComponentMap c){
return cc.create(c.getDependencyOfType(cc.getType(),c));
}
private static Class verify(Component cc, ComponentMap c){
return cc.verify(c.getDependencyOfType(cc.getType(),c));
}
final public void testINS_createsNewInstances() {
if ((getComponentAdapterNature() & INSTANTIATING) > 0) {
final Container yan = new DefaultContainer();
final Component component = prepINS_createsNewInstances(yan);
//assertSame(getComponentAdapterType(), component.getClass());
final Object instance = create(component, yan);
assertNotNull(instance);
assertNotSame(instance, create(component, yan));
assertSame(instance.getClass(), create(component, yan).getClass());
}
}
/**
* Prepare the test <em>errorIsRethrown</em>. Overload this function, if the Component is instantiating.
* @param yan container, may probably not be used.
* @return a Component of the type to test with a component that fails with an {@link Error}at instantiation.
* Registration in the pico is not necessary.
*/
protected abstract Component prepINS_errorIsRethrown(Container yan);
final public void testINS_errorIsRethrown() {
if ((getComponentAdapterNature() & INSTANTIATING) > 0) {
final Container yan = new DefaultContainer();
//assertSame(getComponentAdapterType(), component.getClass());
final Component component = prepINS_errorIsRethrown(yan);
try{
create(component, yan);
fail("Thrown Error excpected");
}
catch(Error e){
assertEquals("test", e.getMessage());
}
}
}
/**
* Prepare the test <em>runtimeExceptionIsRethrown</em>. Overload this function, if the Component is
* instantiating.
* @param yan container, may probably not be used.
* @return a Component of the type to test with a component that fails with a {@link RuntimeException}at
* instantiation. Registration in the pico is not necessary.
*/
protected Component prepINS_runtimeExceptionIsRethrown(Container yan) {
throw new AssertionFailedError("You have to overwrite this method for a useful test");
}
final public void testINS_runtimeExceptionIsRethrown() {
if ((getComponentAdapterNature() & INSTANTIATING) > 0) {
final Container yan = new DefaultContainer();
final Component component = prepINS_runtimeExceptionIsRethrown(yan);
//assertSame(getComponentAdapterType(), component.getClass());
try {
create(component, yan);
fail("Thrown RuntimeException excpected");
} catch (final ComponentInstantiationException e) {
assertEquals("test", e.getCause().getMessage());
}
}
}
/**
* Prepare the test <em>normalExceptionIsRethrownInsidePicoInvocationTargetInitializationException</em>. Overload this
* function, if the Component is instantiating.
* @param yan container, may probably not be used.
* @return a Component of the type to test with a component that fails with a
* {@link PicoInvocationTargetInitializationException}at instantiation. Registration in the pico is not necessary.
*/
protected Component prepINS_normalExceptionIsRethrownInsidePicoInvocationTargetInitializationException(
Container yan) {
throw new AssertionFailedError("You have to overwrite this method for a useful test");
}
final public void testINS_normalExceptionIsRethrownInsidePicoInvocationTargetInitializationException() {
if ((getComponentAdapterNature() & INSTANTIATING) > 0) {
final Container yan = new DefaultContainer();
final Component component = prepINS_normalExceptionIsRethrownInsidePicoInvocationTargetInitializationException(yan);
//assertSame(getComponentAdapterType(), component.getClass());
try {
create(component, yan);
fail("Thrown PicoInvocationTargetInitializationException excpected");
} catch (final ComponentInstantiationException e) {
assertTrue(e.getMessage().endsWith("test"));
assertTrue(e.getCause() instanceof Exception);
}
}
}
// ============================================
// Resolving
// ============================================
/**
* Prepare the test <em>dependenciesAreResolved</em>. Overload this function, if the Component is resolves
* dependencies.
* @param yan container, used to register dependencies.
* @return a Component of the type to test with a component that has dependencies. Registration in the pico is not
* necessary.
*/
protected abstract Component prepRES_dependenciesAreResolved(Container yan);
final public void testRES_dependenciesAreResolved() {
if ((getComponentAdapterNature() & RESOLVING) > 0) {
final List dependencies = new LinkedList();
final Object[] wrapperDependencies = new Object[]{dependencies};
final Container yan = new DefaultContainer();
final Component component = prepRES_dependenciesAreResolved(yan);
//assertSame(getComponentAdapterType(), component.getClass());
assertFalse(yan.getComponents().contains(component));
final Container wrappedPicoContainer = wrapComponentInstances(
CollectingComponentAdapter.class, yan, wrapperDependencies);
final Object instance = create(component,wrappedPicoContainer);
assertNotNull(instance);
assertTrue(dependencies.size() > 0);
}
}
/**
* Prepare the test <em>failingVerificationWithCyclicDependencyException</em>. Overload this function, if the
* Component is resolves dependencies.
* @param yan container, used to register dependencies.
* @return a Component of the type to test with a component that has cyclic dependencies. You have to register the
* component itself in the pico.
*/
protected Component prepRES_failingVerificationWithCyclicDependencyException(Container yan) {
throw new AssertionFailedError("You have to overwrite this method for a useful test");
}
/*
final public void testRES_failingVerificationWithCyclicDependencyException() {
if ((getComponentAdapterNature() & RESOLVING) > 0) {
final Set cycleInstances = new HashSet();
final ObjectReference cycleCheck = new SimpleReference();
final Object[] wrapperDependencies = new Object[]{cycleInstances, cycleCheck};
final Container yan = new DefaultContainer();
final Component component = prepRES_failingVerificationWithCyclicDependencyException(yan);
assertSame(getComponentAdapterType(), component.getClass());
assertTrue(yan.getComponentAdapters().contains(component));
final Container wrappedPicoContainer = wrapComponentInstances(
CycleDetectorComponentAdapter.class, yan, wrapperDependencies);
try {
component.verify(wrappedPicoContainer);
fail("Thrown PicoVerificationException excpected");
} catch (final CyclicDependencyException cycle) {
final Class[] dependencies = cycle.getDependencies();
assertSame(dependencies[0], dependencies[dependencies.length - 1]);
}
}
}*/
/**
* Prepare the test <em>failingInstantiationWithCyclicDependencyException</em>. Overload this function, if the
* Component is resolves dependencies.
* @param yan container, used to register dependencies.
* @return a Component of the type to test with a component that has cyclic dependencies. You have to register the
* component itself in the pico.
*/
/*
protected Component prepRES_failingInstantiationWithCyclicDependencyException(
Container yan) {
throw new AssertionFailedError("You have to overwrite this method for a useful test");
}
final public void testRES_failingInstantiationWithCyclicDependencyException() {
if ((getComponentAdapterNature() & RESOLVING) > 0) {
final Set cycleInstances = new HashSet();
final ObjectReference cycleCheck = new SimpleReference();
final Object[] wrapperDependencies = new Object[]{cycleInstances, cycleCheck};
final Container yan = new DefaultContainer();
final Component component = prepRES_failingInstantiationWithCyclicDependencyException(yan);
assertSame(getComponentAdapterType(), component.getClass());
assertTrue(yan.getComponentAdapters().contains(component));
final Container wrappedPicoContainer = wrapComponentInstances(
CycleDetectorComponentAdapter.class, yan, wrapperDependencies);
try {
component.getInstance(wrappedPicoContainer);
fail("Thrown CyclicDependencyException excpected");
} catch (final CyclicDependencyException e) {
final Class[] dependencies = e.getDependencies();
assertSame(dependencies[0], dependencies[dependencies.length - 1]);
}
}
}*/
// ============================================
// Model & Helpers
// ============================================
/*
static class RecordingVisitor
extends AbstractPicoVisitor {
private final List visitedElements = new LinkedList();
public void visitContainer(Container pico) {
visitedElements.add(pico);
}
public void visitComponentAdapter(Component component) {
visitedElements.add(component);
}
public void visitParameter(Parameter parameter) {
visitedElements.add(parameter);
}
List getVisitedElements() {
return visitedElements;
}
}
*/
static public class NotInstantiatableComponentAdapter
extends DelegatingComponent {
public NotInstantiatableComponentAdapter(final Component delegate) {
super(delegate);
}
public Object create(final Dependency pp) {
Assert.fail("Not instantiatable");
return null;
}
}
static public class CollectingComponentAdapter
extends DelegatingComponent {
final List list;
public CollectingComponentAdapter(final Component delegate, final List list) {
super(delegate);
this.list = list;
}
public Object create(final Dependency pp) {
final Object result =
BaseComponentTestCase.create(getDelegateTarget(), pp.getComponentMap());
list.add(result);
return result;
}
}
/*
static public class CycleDetectorComponentAdapter
extends DelegatingComponent {
private final Set set;
private final ObjectReference reference;
public CycleDetectorComponentAdapter(final Component delegate, final Set set, final ObjectReference reference) {
super(delegate);
this.set = set;
this.reference = reference;
}
public Object getInstance(final Container container) {
if (set.contains(this)) {
reference.set(this);
} else {
set.add(this);
}
return super.getInstance(container);
}
}
*/
final protected Container wrapComponentInstances(
final Class decoratingComponentAdapterClass, final Container yan, final Object[] wrapperDependencies) {
assertTrue(DelegatingComponent.class.isAssignableFrom(decoratingComponentAdapterClass));
final Container mutablePicoContainer = new DefaultContainer();
final int size = (wrapperDependencies != null ? wrapperDependencies.length : 0) + 1;
final Collection allComponentAdapters = yan.getComponents();
for (final Iterator iter = allComponentAdapters.iterator(); iter.hasNext();) {
//final Parameter[] parameters = new Parameter[size];
final Creator[] params = new Creator[size];
params[0] = Components.value(iter.next()).guard().singleton();
for (int i = 1; i < params.length; i++) {
Component tmp = Components.value(wrapperDependencies[i - 1]);
switch(i%3){//to test all singleton methods.
case 0:
tmp = tmp.singleton(new GlobalScope());
break;
case 1:
tmp = tmp.singleton(new ThreadLocalScope());
case 2:
tmp = tmp.singleton();
}
params[i] = tmp.guard();
}
Component cc = Components.ctor(decoratingComponentAdapterClass)
.withArguments(params);
final Container instantiatingPicoContainer = new DefaultContainer();
instantiatingPicoContainer.registerComponent("decorator",
cc);
mutablePicoContainer.registerComponent(
(Component) instantiatingPicoContainer.getInstance("decorator"));
}
return mutablePicoContainer;
}
static class Dummy{
public void mtd1(int i){}
public void mtd2(){}
public void mtd2(int i){}
static void static1(){}
public static void static1(int i){}
public static void static2(){}
public static void static2(int i){}
}
public static class PublicDummy{
PublicDummy(int i){}
void mtd1(){}
public void mtd1(int i){}
public void mtd2(){}
public void mtd2(int i){}
static void static1(){}
public static void static1(int i){}
public static void static2(){}
public static void static2(int i){}
public void mtd0(){}
public static void mtd0(int i){}
}
public static class AmbiguousDummy{
public AmbiguousDummy(){}
public AmbiguousDummy(int i){}
}
public void testInvalidComponents(){
try{
Components.ctor(Dummy.class);
fail("should prevent non-public type");
}
catch(IllegalArgumentException e){
assertTrue(e.getMessage().startsWith("constructor not found"));
}
try{
Components.ctor(PublicDummy.class);
fail("should prevent non-public constructor");
}
catch(IllegalArgumentException e){
assertTrue(e.getMessage().startsWith("constructor not found"));
}
try{
Components.ctor(AmbiguousDummy.class);
fail("should prevent ambiguous constructors");
}
catch(IllegalArgumentException e){
assertTrue(e.getMessage().endsWith("more than one qualified constructors"));
}
try{
Components.method(new PublicDummy(3), "mtd2");
}
catch(AmbiguityException e){
assertTrue(e.getMessage().endsWith("has more than one qualified methods named mtd2"));
//System.out.println(e);
}
try{
Components.method(new PublicDummy(3), "mtdx");
}
catch(IllegalArgumentException e){
assertTrue(e.getMessage().startsWith("method"));
assertTrue(e.getMessage().endsWith("not found"));
//System.out.println(e);
}
assertNotNull(Components.static_method(PublicDummy.class, "mtd0"));
try{
Components.method(new PublicDummy(3), "mtd0");
fail("should prevent constructor resolution error");
}
catch(AmbiguityException e){
assertTrue(e.getMessage().endsWith("has more than one qualified methods named mtd0"));
}
try{
Components.ctor(AmbiguousDummy.class, new Class[]{String.class});
fail("should prevent constructor resolution error");
}
catch(IllegalArgumentException e){
assertTrue(e.getMessage().startsWith("constructor not found"));
}
Components.static_method(PublicDummy.class, "static1");
Components.method(new PublicDummy(1), "static1");
Components.method(new PublicDummy(2), "mtd1");
try{
Components.static_method(Dummy.class, "static1", null);
fail("should prevent no-such-method");
}
catch(IllegalArgumentException e){
assertTrue(e.getMessage().endsWith("Dummy.static1() not found."));
}
try{
Components.static_method(PublicDummy.class, "mtd2", null);
fail("should prevent non-static error");
}
catch(IllegalArgumentException e){
//System.out.println(e);
assertTrue(e.getMessage().endsWith("is not static"));
}
try{
Components.static_method(Dummy.class, "mtd1");
fail("should prevent non-static error");
}
catch(IllegalArgumentException e){
//System.out.println(e);
assertTrue(e.getMessage().startsWith("static method named mtd1 "));
assertTrue(e.getMessage().indexOf("cannot be found")>0);
}
}
public void testComponentAsObject(){
final Component c = Components.static_method(java.text.DateFormat.class,
"getDateInstance", null);
assertEquals(c, c);
final HashMap map = new HashMap();
map.put(c, c);
assertSame(c, map.get(c));
assertTrue(c.toString().endsWith("getDateInstance()"));
}
public void testSubsumptionAndCasting(){
Integer seed = new Integer(1);
final Component c0 =
Components.value(seed)
.subsume(Integer.class)
.subsume(int.class);
final Component c1 =
Components.value(null)
.subsume(Integer.class)
.subsume(int.class);
try{
c1.subsume(Number.class)
.subsume(int.class);
fail("should have failed subsumption");
}
catch(IllegalArgumentException e){
assertEquals("java.lang.Number is not a subtype of int", e.getMessage());
}
final Component c2 =
Components.cast(Components.cast(c1.cast(Number.class), Number.class),
Integer.class);
final Component c20 =
Components.cast(Components.cast(c0.subsume(Number.class), Number.class),
Integer.class);
assertSame(seed, c20.create(null));
final Component c3 = Components.cast(c2, int.class);
try{
c3.create(null);
fail("should have failed with ClassCastException");
}
catch(TypeMismatchException e){
assertEquals("int expected, while java.lang.Object encountered.", e.getMessage());
assertEquals(int.class, e.getExpectedType());
assertSame(null, e.getActualType());
}
}
public static class Account implements Comparable{
private String num;
private BigDecimal balance;
private java.util.List activities;
public java.util.List getActivities() {
return activities;
}
public void setActivities(java.util.List activities) {
this.activities = activities;
}
public BigDecimal getBalance() {
return balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public int compareTo(Object o) {
return balance.compareTo((BigDecimal)o);
}
}
public void testProxy()throws Exception{
final Component cc =
Components.bean(Account.class, new String[]{"num", "balance"})
.proxy();
final Component cc2 = cc.proxy(new Class[]{Comparable.class});
final Component cc3 = cc.proxy(new Class[]{});
Component cc4 = cc2.proxy(new Class[]{Comparable.class});
try{
cc4.proxy(new Class[]{Runnable.class});
fail("should have failed with IllegalArgumentException");
}
catch(IllegalArgumentException e){
assertEquals("type java.lang.Runnable is not a super type of any of [interface java.lang.Comparable]",
e.getMessage());
}
}
public static CharSequence getCharSequence(){
return "1";
}
public void testArray(){
final Component c1 = Components.ctor(String.class, null);
final Component c2 = Components.ctor(StringBuffer.class, null);
final Component c3 = Components.method(this, "getCharSequence");
final Component c4 = Components.useKey("xxx");
final Component a1 = Components.array(new Component[]{});
assertEquals(Object[].class, a1.getType());
final Component a2 = Components.array(new Component[]{c1});
assertEquals(String[].class, a2.getType());
final Component a3 = Components.array(new Component[]{c1, c3});
assertEquals(CharSequence[].class, a3.getType());
final Component a4 = Components.array(new Component[]{c1, c3, c2});
assertEquals(CharSequence[].class, a4.getType());
final Component a5 = Components.array(new Component[]{c1, c2});
assertEquals(Object[].class, a5.getType());
final Component a6 = Components.array(new Component[]{c1, c2, c3, c4});
assertEquals(Object[].class, a6.getType());
}
}