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  import com.lexicalscope.fluentreflection.dynamicproxy.MethodBody;
17  import com.lexicalscope.fluentreflection.dynamicproxy.QueryMethod;
18  
19  public class TestFluentDynamicProxy {
20      @Rule public final ExpectedException exception = ExpectedException.none();
21  
22      static class MyException extends Exception {
23          private static final long serialVersionUID = -4179362193684542734L;
24      }
25  
26      interface ThrowingMethod {
27          void method() throws MyException;
28      }
29  
30      interface TwoMethods {
31          void methodA();
32  
33          void methodB();
34      }
35  
36      interface TwoQueryMethod {
37          int methodA();
38  
39          int methodB();
40      }
41  
42      interface MethodWithArgument {
43          int method(int argument);
44      }
45  
46      @Test public void canProxyMultipleMethods() throws Exception {
47          final List<String> called = new ArrayList<String>();
48  
49          final TwoMethods dynamicProxy = dynamicProxy(new Implementing<TwoMethods>() {
50              {
51                  whenProxying(anything()).execute(new MethodBody() {
52                      @Override public void body() {
53                          called.add(methodName());
54                      }
55                  });
56              }
57          });
58  
59          assertThat(called, org.hamcrest.Matchers.<String>empty());
60  
61          dynamicProxy.methodA();
62  
63          assertThat(called, contains("methodA"));
64  
65          dynamicProxy.methodB();
66  
67          assertThat(called, contains("methodA", "methodB"));
68      }
69  
70      @Test public void canReturnValueFromProxiedMethod() throws Exception {
71  
72          final TwoQueryMethod dynamicProxy = dynamicProxy(new Implementing<TwoQueryMethod>() {
73              {
74                  whenProxying(anything()).execute(new MethodBody() {
75                      @Override public void body() {
76                          returnValue(42);
77                      }
78                  });
79              }
80          });
81  
82          assertThat(dynamicProxy.methodA(), equalTo(42));
83          assertThat(dynamicProxy.methodB(), equalTo(42));
84      }
85  
86      @Test public void canReturnDifferentValuesFromEachProxiedMethod() throws Exception {
87  
88          final TwoQueryMethod dynamicProxy = dynamicProxy(new Implementing<TwoQueryMethod>() {
89              {
90                  whenProxying(hasName("methodA")).execute(new MethodBody() {
91                      @Override public void body() {
92                          returnValue(42);
93                      }
94                  });
95  
96                  whenProxying(hasName("methodB")).execute(new MethodBody() {
97                      @Override public void body() {
98                          returnValue(24);
99                      }
100                 });
101             }
102         });
103 
104         assertThat(dynamicProxy.methodA(), equalTo(42));
105         assertThat(dynamicProxy.methodB(), equalTo(24));
106     }
107 
108     @Test public void canDefineDefaultImplementationForUnmatchedMethods() throws Exception {
109 
110         final TwoQueryMethod dynamicProxy = dynamicProxy(new Implementing<TwoQueryMethod>() {
111             {
112                 whenProxying(hasName("methodA")).execute(new MethodBody() {
113                     @Override public void body() {
114                         returnValue(42);
115                     }
116                 });
117 
118                 whenProxying(anything()).execute(new MethodBody() {
119                     @Override public void body() {
120                         returnValue(24);
121                     }
122                 });
123             }
124         });
125 
126         assertThat(dynamicProxy.methodA(), equalTo(42));
127         assertThat(dynamicProxy.methodB(), equalTo(24));
128     }
129 
130     @Test public void canThrowException() throws Exception {
131         final ThrowingMethod dynamicProxy = dynamicProxy(new Implementing<ThrowingMethod>() {
132             {
133                 whenProxying(anything()).execute(new MethodBody() {
134                     @Override public void body() throws MyException {
135                         throw new MyException();
136                     }
137                 });
138             }
139         });
140 
141         exception.expect(MyException.class);
142         dynamicProxy.method();
143     }
144 
145     @Test public void canGetMethodArguments() throws Exception {
146         final MethodWithArgument dynamicProxy = dynamicProxy(new Implementing<MethodWithArgument>() {
147             {
148                 whenProxying(anything()).execute(new MethodBody() {
149                     @Override public void body() {
150                         returnValue(args()[0]);
151                     }
152                 });
153             }
154         });
155 
156         assertThat(dynamicProxy.method(42), equalTo(42));
157     }
158 
159     @Test public void canGetBindUsingMethodArguments() throws Exception {
160         final MethodWithArgument dynamicProxy = dynamicProxy(new Implementing<MethodWithArgument>() {
161             {
162                 matchingSignature(new QueryMethod() {
163                     @SuppressWarnings("unused") public int body(final int agument)
164                     {
165                         return 42;
166                     }
167                 });
168             }
169         });
170 
171         assertThat(dynamicProxy.method(42), equalTo(42));
172     }
173 }