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 junit.framework.TestCase; 021 import org.apache.commons.proxy.ObjectProvider; 022 import org.apache.commons.proxy.ProxyFactory; 023 import org.apache.commons.proxy.provider.ConstantProvider; 024 025 import java.io.Serializable; 026 027 /** 028 * 029 */ 030 public class TestDuckTypingInvoker extends TestCase 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 testNoMatchingMethod() 045 { 046 final ObjectProvider targetProvider = new ConstantProvider( new LegacyDuck() ); 047 final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider ); 048 final Goose goose = ( Goose ) new ProxyFactory().createInvokerProxy( invoker, new Class[]{ Goose.class } ); 049 try 050 { 051 goose.sayHonk(); 052 fail( "No matching method should be found." ); 053 } 054 catch ( UnsupportedOperationException e ) 055 { 056 // Do nothing, expected behavior! 057 } 058 } 059 060 public void testMismatchingParameterType() 061 { 062 final ObjectProvider targetProvider = new ConstantProvider( new LegacyDuck() ); 063 final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider ); 064 final ParameterizedDuck parameterizedDuck = ( ParameterizedDuck ) new ProxyFactory() 065 .createInvokerProxy( invoker, new Class[]{ ParameterizedDuck.class } ); 066 try 067 { 068 parameterizedDuck.sayQuack("Elmer"); 069 fail( "No matching method should be found." ); 070 } 071 catch ( UnsupportedOperationException e ) 072 { 073 // Do nothing, expected behavior! 074 } 075 } 076 077 public void testTargetHasCompatibleReturnType() 078 { 079 final ObjectProvider targetProvider = new ConstantProvider( new LegacyDuck() ); 080 final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider ); 081 final SerializableDuck duck = ( SerializableDuck ) new ProxyFactory().createInvokerProxy( invoker, new Class[]{ 082 SerializableDuck.class } ); 083 assertEquals("Quack!", duck.sayQuack() ); 084 085 } 086 087 public void testMismatchingReturnType() 088 { 089 final ObjectProvider targetProvider = new ConstantProvider( new LegacyDuck() ); 090 final DuckTypingInvoker invoker = new DuckTypingInvoker( targetProvider ); 091 final VoidReturnDuck voidDuck = ( VoidReturnDuck ) new ProxyFactory().createInvokerProxy( invoker, new Class[]{ 092 VoidReturnDuck.class } ); 093 try 094 { 095 voidDuck.sayQuack(); 096 fail( "No matching method should be found." ); 097 } 098 catch ( UnsupportedOperationException e ) 099 { 100 // Do nothing, expected behavior! 101 } 102 } 103 104 //---------------------------------------------------------------------------------------------------------------------- 105 // Inner Classes 106 //---------------------------------------------------------------------------------------------------------------------- 107 108 public static class LegacyDuck 109 { 110 public String sayQuack() 111 { 112 return "Quack!"; 113 } 114 } 115 116 public interface Duck 117 { 118 public String sayQuack(); 119 } 120 121 public interface SerializableDuck 122 { 123 public Serializable sayQuack(); 124 } 125 126 public interface ParameterizedDuck 127 { 128 public String sayQuack( String recipient ); 129 } 130 131 public interface VoidReturnDuck 132 { 133 public void sayQuack(); 134 } 135 136 public interface Goose 137 { 138 public void sayHonk(); 139 } 140 }