001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.proxy.invoker;
019
020 import org.apache.commons.proxy.ObjectProvider;
021 import org.apache.commons.proxy.ProxyFactory;
022 import org.apache.commons.proxy.provider.ConstantProvider;
023 import org.apache.commons.proxy.util.AbstractTestCase;
024
025 import java.io.Serializable;
026
027 /**
028 *
029 */
030 public class TestDuckTypingInvoker extends AbstractTestCase
031 {
032 //**********************************************************************************************************************
033 // Other Methods
034 //**********************************************************************************************************************
035
036 public void testExactSignatureMatch()
037 {
038 final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
039 final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
040 final Duck duck = ( Duck ) new ProxyFactory().createInvokerProxy(invoker, new Class[] {Duck.class});
041 assertEquals("Quack!", duck.sayQuack());
042 }
043
044 public void testMismatchingParameterType()
045 {
046 final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
047 final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
048 final ParameterizedDuck parameterizedDuck = ( ParameterizedDuck ) new ProxyFactory()
049 .createInvokerProxy(invoker, new Class[] {ParameterizedDuck.class});
050 try
051 {
052 parameterizedDuck.sayQuack("Elmer");
053 fail("No matching method should be found.");
054 }
055 catch( UnsupportedOperationException e )
056 {
057 // Do nothing, expected behavior!
058 }
059 }
060
061 public void testMismatchingReturnType()
062 {
063 final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
064 final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
065 final VoidReturnDuck voidDuck = ( VoidReturnDuck ) new ProxyFactory().createInvokerProxy(invoker, new Class[] {
066 VoidReturnDuck.class});
067 try
068 {
069 voidDuck.sayQuack();
070 fail("No matching method should be found.");
071 }
072 catch( UnsupportedOperationException e )
073 {
074 // Do nothing, expected behavior!
075 }
076 }
077
078 public void testNoMatchingMethod()
079 {
080 final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
081 final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
082 final Goose goose = ( Goose ) new ProxyFactory().createInvokerProxy(invoker, new Class[] {Goose.class});
083 try
084 {
085 goose.sayHonk();
086 fail("No matching method should be found.");
087 }
088 catch( UnsupportedOperationException e )
089 {
090 // Do nothing, expected behavior!
091 }
092 }
093
094 public void testSerialization()
095 {
096 final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
097 final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
098 assertSerializable(invoker);
099 }
100
101 public void testTargetHasCompatibleReturnType()
102 {
103 final ObjectProvider targetProvider = new ConstantProvider(new LegacyDuck());
104 final DuckTypingInvoker invoker = new DuckTypingInvoker(targetProvider);
105 final SerializableDuck duck = ( SerializableDuck ) new ProxyFactory().createInvokerProxy(invoker, new Class[] {
106 SerializableDuck.class});
107 assertEquals("Quack!", duck.sayQuack());
108 }
109
110 //**********************************************************************************************************************
111 // Inner Classes
112 //**********************************************************************************************************************
113
114 public interface Duck
115 {
116 public String sayQuack();
117 }
118
119 public interface Goose
120 {
121 public void sayHonk();
122 }
123
124 public static class LegacyDuck implements Serializable
125 {
126 public String sayQuack()
127 {
128 return "Quack!";
129 }
130 }
131
132 public interface ParameterizedDuck
133 {
134 public String sayQuack( String recipient );
135 }
136
137 public interface SerializableDuck
138 {
139 public Serializable sayQuack();
140 }
141
142 public interface VoidReturnDuck
143 {
144 public void sayQuack();
145 }
146 }