1   package com.lexicalscope.fluentreflection.dynamicproxy.endtoend;
2   
3   import static com.lexicalscope.fluentreflection.ReflectionMatchers.hasName;
4   import static com.lexicalscope.fluentreflection.dynamicproxy.FluentProxy.dynamicProxy;
5   import static org.hamcrest.MatcherAssert.assertThat;
6   import static org.hamcrest.Matchers.*;
7   
8   import java.util.ArrayList;
9   import java.util.List;
10  
11  import org.junit.Rule;
12  import org.junit.Test;
13  import org.junit.rules.ExpectedException;
14  
15  import com.lexicalscope.fluentreflection.dynamicproxy.Implementing;
16  
17  public class TestLightweightFluentDynamicProxy {
18      @Rule public final ExpectedException exception = ExpectedException.none();
19  
20      static class MyException extends Exception {
21          private static final long serialVersionUID = -4179362193684542734L;
22      }
23  
24      interface ThrowingMethod {
25          void method() throws MyException;
26      }
27  
28      interface TwoMethods {
29          void methodA();
30  
31          void methodB();
32      }
33  
34      interface TwoQueryMethod {
35          int methodA();
36  
37          int methodB();
38      }
39  
40      interface MethodWithArgument {
41          int method(int argument);
42          String method(String argument);
43      }
44  
45      @Test public void canProxyMultipleMethods() throws Exception {
46          final List<String> called = new ArrayList<String>();
47  
48          final TwoMethods dynamicProxy = dynamicProxy(new Implementing<TwoMethods>() {
49              @SuppressWarnings("unused") public void body() {
50                  called.add(methodName());
51              }
52          });
53  
54          assertThat(called, org.hamcrest.Matchers.<String>empty());
55  
56          dynamicProxy.methodA();
57  
58          assertThat(called, contains("methodA"));
59  
60          dynamicProxy.methodB();
61  
62          assertThat(called, contains("methodA", "methodB"));
63      }
64  
65      @Test public void canReturnValueFromProxiedMethod() throws Exception {
66  
67          final TwoQueryMethod dynamicProxy = dynamicProxy(new Implementing<TwoQueryMethod>() {
68              @SuppressWarnings("unused") public void body() {
69                  returnValue(42);
70              }
71          });
72  
73          assertThat(dynamicProxy.methodA(), equalTo(42));
74          assertThat(dynamicProxy.methodB(), equalTo(42));
75      }
76  
77      @Test public void canReturnDifferentValuesFromEachProxiedMethod() throws Exception {
78  
79          final TwoQueryMethod dynamicProxy = dynamicProxy(new Implementing<TwoQueryMethod>() {
80              @SuppressWarnings("unused") public void bodyA() {
81                  whenProxying(hasName("methodA"));
82                  returnValue(42);
83              }
84  
85              @SuppressWarnings("unused") public void bodyB() {
86                  whenProxying(hasName("methodB"));
87                  returnValue(24);
88              }
89          });
90  
91          assertThat(dynamicProxy.methodA(), equalTo(42));
92          assertThat(dynamicProxy.methodB(), equalTo(24));
93      }
94  
95      @Test public void canDefineDefaultImplementationForUnmatchedMethods() throws Exception {
96  
97          final TwoQueryMethod dynamicProxy = dynamicProxy(new Implementing<TwoQueryMethod>() {
98              @SuppressWarnings("unused") public void bodyA() {
99                  whenProxying(hasName("methodA"));
100                 returnValue(42);
101             }
102 
103             @SuppressWarnings("unused") public void bodyX() {
104                 whenProxyingUnmatched();
105                 returnValue(24);
106             }
107         });
108 
109         assertThat(dynamicProxy.methodA(), equalTo(42));
110         assertThat(dynamicProxy.methodB(), equalTo(24));
111     }
112 
113     @Test public void canThrowException() throws Exception {
114         final ThrowingMethod dynamicProxy = dynamicProxy(new Implementing<ThrowingMethod>() {
115             @SuppressWarnings("unused") public void body() throws MyException {
116                 throw new MyException();
117             }
118         });
119 
120         exception.expect(MyException.class);
121         dynamicProxy.method();
122     }
123 
124     @Test public void canGetMethodArguments() throws Exception {
125         final MethodWithArgument dynamicProxy = dynamicProxy(new Implementing<MethodWithArgument>() {
126             @SuppressWarnings("unused") public void body() {
127                 returnValue(args()[0]);
128             }
129         });
130 
131         assertThat(dynamicProxy.method(42), equalTo(42));
132     }
133 
134     @Test public void canGetBindUsingMethodArguments() throws Exception {
135         final MethodWithArgument dynamicProxy = dynamicProxy(new Implementing<MethodWithArgument>() {
136             @SuppressWarnings("unused") public int body(final int agument)
137             {
138                 return 42;
139             }
140 
141             @SuppressWarnings("unused") public String body(final String agument)
142             {
143                 return "42";
144             }
145         });
146 
147         assertThat(dynamicProxy.method(42), equalTo(42));
148         assertThat(dynamicProxy.method("42"), equalTo("42"));
149     }
150 }