2 * Copyright 2005-2010 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.reflection;
18 import static org.mockito.Matchers.*;
19 import static org.mockito.Mockito.*;
21 import java.lang.reflect.Field;
22 import java.lang.reflect.Method;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
29 import java.util.logging.ConsoleHandler;
30 import java.util.logging.Level;
31 import java.util.logging.Logger;
33 import org.apache.derby.impl.sql.execute.OnceResultSet;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.mockito.Mock;
37 import org.mockito.MockitoAnnotations;
38 import org.wamblee.reflection.ObjectTraversal.ObjectVisitor;
40 import static junit.framework.TestCase.*;
42 public class ObjectTraversalTest {
45 private ObjectVisitor visitor;
47 private ObjectTraversal traversal;
51 MockitoAnnotations.initMocks(this);
52 traversal = new ObjectTraversal(visitor);
54 when(visitor.mustVisit(any(Class.class))).thenReturn(true);
55 when(visitor.mustVisit(any(Field.class))).thenReturn(true);
56 when(visitor.mustVisit(any(Method.class))).thenReturn(true);
58 when(visitor.visitPlainObject(any())).thenReturn(true);
59 when(visitor.visitArray(any())).thenReturn(true);
60 when(visitor.visitList(any(List.class))).thenReturn(true);
61 when(visitor.visitMap(any(Map.class))).thenReturn(true);
62 when(visitor.visitSet(any(Set.class))).thenReturn(true);
64 ObjectTraversal.LOGGER.setLevel(Level.FINEST);
65 ConsoleHandler handler = new ConsoleHandler();
66 handler.setLevel(Level.FINEST);
67 ObjectTraversal.LOGGER.addHandler(handler);
70 public static class X1 {
74 public static class X2 {
79 public void testTraverseFields() throws Exception {
84 verify(visitor).mustVisit(X2.class);
85 verify(visitor).mustVisit(X1.class);
86 verify(visitor).mustVisit(eq(X2.class.getDeclaredField("x")));
87 verify(visitor).visitPlainObject(same(x2));
88 verify(visitor).visitPlainObject(same(x1));
89 verifyNoMoreInteractions(visitor);
92 public static class TraversalNonTraversedFields {
94 private Object y = new Object();
98 public void testNonTraversedFields() throws Exception {
99 TraversalNonTraversedFields obj = new TraversalNonTraversedFields();
100 traversal.accept(obj);
101 verify(visitor).mustVisit(TraversalNonTraversedFields.class);
102 verify(visitor).mustVisit(
103 eq(TraversalNonTraversedFields.class.getDeclaredField("x")));
104 verify(visitor).mustVisit(
105 eq(TraversalNonTraversedFields.class.getDeclaredField("y")));
106 verify(visitor).visitPlainObject(same(obj));
109 public static class X3 {
113 public static class X4 {
120 public void testTraverseMethods() throws Exception {
122 traversal.accept(x4);
123 verify(visitor).mustVisit(X4.class);
124 verify(visitor).mustVisit(X3.class);
125 verify(visitor).mustVisit(eq(X4.class.getDeclaredMethod("getX3")));
126 verify(visitor).visitPlainObject(same(x4));
127 verify(visitor).visitPlainObject(isA(X3.class));
128 verifyNoMoreInteractions(visitor);
132 public void testTraverseList() {
133 List list = new ArrayList();
136 traversal.accept(list);
137 verify(visitor).visitList(same(list));
138 verify(visitor).visitPlainObject(isA(X1.class));
139 verify(visitor).visitPlainObject(isA(X3.class));
143 public void testTraverseMap() {
144 Map<String, Object> map = new HashMap<String, Object>();
145 map.put("x1", new X1());
146 map.put("x3", new X3());
147 traversal.accept(map);
148 verify(visitor).visitMap(same(map));
149 verify(visitor).visitPlainObject(isA(X1.class));
150 verify(visitor).visitPlainObject(isA(X3.class));
154 public void testTraverseSet() {
155 Set set = new HashSet();
158 traversal.accept(set);
159 verify(visitor).visitSet(same(set));
160 verify(visitor).visitPlainObject(isA(X1.class));
161 verify(visitor).visitPlainObject(isA(X3.class));
165 public void testTraverseArray() {
166 Object[] obj = new Object[2];
169 traversal.accept(obj);
170 verify(visitor).visitArray(same(obj));
171 verify(visitor).visitPlainObject(isA(X1.class));
172 verify(visitor).visitPlainObject(isA(X3.class));
176 public void testExcludeClasses() {
179 when(visitor.mustVisit(X1.class)).thenReturn(false);
180 traversal.accept(x2);
181 verify(visitor).visitPlainObject(same(x2));
182 verify(visitor, never()).visitPlainObject(same(x2.x));
186 public void testExcludeFields() {
189 when(visitor.mustVisit(any(Field.class))).thenReturn(false);
190 traversal.accept(x2);
191 verify(visitor).visitPlainObject(same(x2));
192 verify(visitor, never()).visitPlainObject(same(x2.x));
196 public void testExcludeMethods() {
198 when(visitor.mustVisit(any(Method.class))).thenReturn(false);
199 traversal.accept(x4);
200 verify(visitor).visitPlainObject(same(x4));
201 verify(visitor, never()).visitPlainObject(isA(X3.class));
204 public static class X5 {
208 public static class X6 {
213 public void testCyclic() {
218 traversal.accept(x6);
219 verify(visitor).visitPlainObject(same(x6));
220 verify(visitor).visitPlainObject(same(x5));
224 public void testCyclicList() {
225 List list = new ArrayList();
227 traversal.accept(list);
228 verify(visitor, times(1)).visitList(same(list));
232 public void testCyclicMap() {
233 Map map = new HashMap();
235 traversal.accept(map);
236 verify(visitor, times(1)).visitMap(same(map));
240 public void testCyclicSet() {
241 Set set = new HashSet();
243 traversal.accept(set);
244 verify(visitor, times(1)).visitSet(same(set));
248 public void testCyclicArray() {
249 Object[] obj = new Object[1];
251 traversal.accept(obj);
252 verify(visitor, times(1)).visitArray(same(obj));
256 public void testVisitNull() {
257 traversal.accept(null);
261 public void testExcludeFieldByReturningFalseInVisit() {
264 when(visitor.visitPlainObject(any())).thenReturn(false);
265 traversal.accept(x2);
266 verify(visitor).visitPlainObject(same(x2));
267 verify(visitor, never()).visitPlainObject(same(x2.x));
271 public void testTraverseListExcludeElements() {
272 List list = new ArrayList();
275 when(visitor.visitList(any(List.class))).thenReturn(false);
276 traversal.accept(list);
277 verify(visitor).visitList(same(list));
278 verify(visitor, never()).visitPlainObject(any());
282 public void testTraverseMapExcludeElements() {
283 Map<String, Object> map = new HashMap<String, Object>();
284 map.put("x1", new X1());
285 map.put("x3", new X3());
286 when(visitor.visitMap(any(Map.class))).thenReturn(false);
287 traversal.accept(map);
288 verify(visitor).visitMap(same(map));
289 verify(visitor, never()).visitPlainObject(any());
293 public void testTraverseSetExcludeElements() {
294 Set set = new HashSet();
297 when(visitor.visitSet(any(Set.class))).thenReturn(false);
299 traversal.accept(set);
300 verify(visitor).visitSet(same(set));
301 verify(visitor, never()).visitPlainObject(any());
305 public void testTraverseArrayExcludeElements() {
306 Object[] obj = new Object[2];
309 when(visitor.visitArray(any())).thenReturn(false);
311 traversal.accept(obj);
312 verify(visitor).visitArray(same(obj));
313 verify(visitor, never()).visitPlainObject(any());