/* * Copyright 2005-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.wamblee.reflection; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.derby.impl.sql.execute.OnceResultSet; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.wamblee.reflection.ObjectTraversal.ObjectVisitor; import static junit.framework.TestCase.*; public class ObjectTraversalTest { @Mock private ObjectVisitor visitor; private ObjectTraversal traversal; @Before public void setUp() { MockitoAnnotations.initMocks(this); traversal = new ObjectTraversal(visitor); when(visitor.mustVisit(any(Class.class))).thenReturn(true); when(visitor.mustVisit(any(Field.class))).thenReturn(true); when(visitor.mustVisit(any(Method.class))).thenReturn(true); when(visitor.visitPlainObject(any())).thenReturn(true); when(visitor.visitArray(any())).thenReturn(true); when(visitor.visitList(any(List.class))).thenReturn(true); when(visitor.visitMap(any(Map.class))).thenReturn(true); when(visitor.visitSet(any(Set.class))).thenReturn(true); } public static class X1 { } public static class X2 { private X1 x; } @Test public void testTraverseFields() throws Exception { X2 x2 = new X2(); X1 x1 = new X1(); x2.x = x1; traversal.accept(x2); verify(visitor).mustVisit(X2.class); verify(visitor).mustVisit(X1.class); verify(visitor).mustVisit(eq(X2.class.getDeclaredField("x"))); verify(visitor).visitPlainObject(same(x2)); verify(visitor).visitPlainObject(same(x1)); verifyNoMoreInteractions(visitor); } public static class TraversalNonTraversedFields { private int x; private Object y = new Object(); } @Test public void testNonTraversedFields() throws Exception { TraversalNonTraversedFields obj =new TraversalNonTraversedFields(); traversal.accept(obj); verify(visitor).mustVisit(TraversalNonTraversedFields.class); verify(visitor).mustVisit(eq(TraversalNonTraversedFields.class.getDeclaredField("x"))); verify(visitor).mustVisit(eq(TraversalNonTraversedFields.class.getDeclaredField("y"))); verify(visitor).visitPlainObject(same(obj)); } public static class X3 { } public static class X4 { public X3 getX3() { return new X3(); } } @Test public void testTraverseMethods() throws Exception { X4 x4 = new X4(); traversal.accept(x4); verify(visitor).mustVisit(X4.class); verify(visitor).mustVisit(X3.class); verify(visitor).mustVisit(eq(X4.class.getDeclaredMethod("getX3"))); verify(visitor).visitPlainObject(same(x4)); verify(visitor).visitPlainObject(isA(X3.class)); verifyNoMoreInteractions(visitor); } @Test public void testTraverseList() { List list = new ArrayList(); list.add(new X1()); list.add(new X3()); traversal.accept(list); verify(visitor).visitList(same(list)); verify(visitor).visitPlainObject(isA(X1.class)); verify(visitor).visitPlainObject(isA(X3.class)); } @Test public void testTraverseMap() { Map map = new HashMap(); map.put("x1", new X1()); map.put("x3", new X3()); traversal.accept(map); verify(visitor).visitMap(same(map)); verify(visitor).visitPlainObject(isA(X1.class)); verify(visitor).visitPlainObject(isA(X3.class)); } @Test public void testTraverseSet() { Set set = new HashSet(); set.add(new X1()); set.add(new X3()); traversal.accept(set); verify(visitor).visitSet(same(set)); verify(visitor).visitPlainObject(isA(X1.class)); verify(visitor).visitPlainObject(isA(X3.class)); } @Test public void testTraverseArray() { Object[] obj = new Object[2]; obj[0] = new X1(); obj[1] = new X3(); traversal.accept(obj); verify(visitor).visitArray(same(obj)); verify(visitor).visitPlainObject(isA(X1.class)); verify(visitor).visitPlainObject(isA(X3.class)); } @Test public void testExcludeClasses() { X2 x2 = new X2(); x2.x = new X1(); when(visitor.mustVisit(X1.class)).thenReturn(false); traversal.accept(x2); verify(visitor).visitPlainObject(same(x2)); verify(visitor, never()).visitPlainObject(same(x2.x)); } @Test public void testExcludeFields() { X2 x2 = new X2(); x2.x = new X1(); when(visitor.mustVisit(any(Field.class))).thenReturn(false); traversal.accept(x2); verify(visitor).visitPlainObject(same(x2)); verify(visitor, never()).visitPlainObject(same(x2.x)); } @Test public void testExcludeMethods() { X4 x4 = new X4(); when(visitor.mustVisit(any(Method.class))).thenReturn(false); traversal.accept(x4); verify(visitor).visitPlainObject(same(x4)); verify(visitor, never()).visitPlainObject(isA(X3.class)); } public static class X5 { private X6 x6; } public static class X6 { private X5 x5; } @Test public void testCyclic() { X6 x6 = new X6(); X5 x5 = new X5(); x6.x5 = x5; x5.x6 = x6; traversal.accept(x6); verify(visitor).visitPlainObject(same(x6)); verify(visitor).visitPlainObject(same(x5)); } @Test public void testCyclicList() { List list = new ArrayList(); list.add(list); traversal.accept(list); verify(visitor, times(1)).visitList(same(list)); } @Test public void testCyclicMap() { Map map = new HashMap(); map.put("x", map); traversal.accept(map); verify(visitor, times(1)).visitMap(same(map)); } @Test public void testCyclicSet() { Set set = new HashSet(); set.add(set); traversal.accept(set); verify(visitor, times(1)).visitSet(same(set)); } @Test public void testCyclicArray() { Object[] obj = new Object[1]; obj[0] = obj; traversal.accept(obj); verify(visitor, times(1)).visitArray(same(obj)); } @Test public void testVisitNull() { traversal.accept(null); } @Test public void testExcludeFieldByReturningFalseInVisit() { X2 x2 = new X2(); x2.x = new X1(); when(visitor.visitPlainObject(any())).thenReturn(false); traversal.accept(x2); verify(visitor).visitPlainObject(same(x2)); verify(visitor, never()).visitPlainObject(same(x2.x)); } @Test public void testTraverseListExcludeElements() { List list = new ArrayList(); list.add(new X1()); list.add(new X3()); when(visitor.visitList(any(List.class))).thenReturn(false); traversal.accept(list); verify(visitor).visitList(same(list)); verify(visitor, never()).visitPlainObject(any()); } @Test public void testTraverseMapExcludeElements() { Map map = new HashMap(); map.put("x1", new X1()); map.put("x3", new X3()); when(visitor.visitMap(any(Map.class))).thenReturn(false); traversal.accept(map); verify(visitor).visitMap(same(map)); verify(visitor, never()).visitPlainObject(any()); } @Test public void testTraverseSetExcludeElements() { Set set = new HashSet(); set.add(new X1()); set.add(new X3()); when(visitor.visitSet(any(Set.class))).thenReturn(false); traversal.accept(set); verify(visitor).visitSet(same(set)); verify(visitor, never()).visitPlainObject(any()); } @Test public void testTraverseArrayExcludeElements() { Object[] obj = new Object[2]; obj[0] = new X1(); obj[1] = new X3(); when(visitor.visitArray(any())).thenReturn(false); traversal.accept(obj); verify(visitor).visitArray(same(obj)); verify(visitor, never()).visitPlainObject(any()); } }