001 /*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved. *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file. *
007 *****************************************************************************/
008 package org.picocontainer.visitors;
009
010 import static org.junit.Assert.assertEquals;
011 import static org.picocontainer.tck.MockFactory.mockeryWithCountingNamingScheme;
012
013 import java.lang.reflect.Method;
014 import java.util.LinkedList;
015 import java.util.List;
016
017 import org.jmock.Expectations;
018 import org.jmock.Mockery;
019 import org.jmock.Sequence;
020 import org.jmock.integration.junit4.JMock;
021 import org.junit.Before;
022 import org.junit.Test;
023 import org.junit.runner.RunWith;
024 import org.picocontainer.DefaultPicoContainer;
025 import org.picocontainer.MutablePicoContainer;
026 import org.picocontainer.PicoVisitor;
027 import org.picocontainer.behaviors.Caching;
028 import org.picocontainer.testmodel.Touchable;
029
030
031 /**
032 * @author Jörg Schaible
033 * @author Mauro Talevi
034 */
035 @RunWith(JMock.class)
036 public class MethodCallingVisitorTest {
037
038 private Mockery mockery = mockeryWithCountingNamingScheme();
039
040 private Method add;
041 private Method touch;
042
043 @Before
044 public void setUp() throws Exception {
045 add = List.class.getMethod("add", Object.class);
046 touch = Touchable.class.getMethod("touch", (Class[])null);
047 }
048
049 @Test public void testVisitorWillTraverseAndCall() throws Exception {
050 MutablePicoContainer parent = new DefaultPicoContainer(new Caching());
051 MutablePicoContainer child = new DefaultPicoContainer(new Caching());
052 parent.addChildContainer(child);
053 parent.addComponent(List.class, LinkedList.class);
054 child.addComponent(List.class, LinkedList.class);
055 List parentList = parent.getComponent(List.class);
056 List childList = child.getComponent(List.class);
057
058 assertEquals(0, parentList.size());
059 assertEquals(0, childList.size());
060
061 PicoVisitor visitor = new MethodCallingVisitor(add, List.class, new Object[]{Boolean.TRUE});
062 visitor.traverse(parent);
063
064 assertEquals(1, parentList.size());
065 assertEquals(1, childList.size());
066 }
067
068 @Test public void testVisitsInInstantiationOrder() throws Exception {
069 final Touchable touchable1 = mockery.mock(Touchable.class);
070 final Touchable touchable2 = mockery.mock(Touchable.class);
071
072 final Sequence sequence = mockery.sequence("touching");
073 mockery.checking(new Expectations() {{
074 one(touchable1).touch(); inSequence(sequence);
075 one(touchable2).touch(); inSequence(sequence);
076 }});
077
078 MutablePicoContainer parent = new DefaultPicoContainer();
079 MutablePicoContainer child = new DefaultPicoContainer();
080 parent.addChildContainer(child);
081 parent.addComponent(touchable1);
082 child.addComponent(touchable2);
083
084 PicoVisitor visitor = new MethodCallingVisitor(touch, Touchable.class, null);
085 visitor.traverse(parent);
086 }
087
088 @Test public void testVisitsInReverseInstantiationOrder() throws Exception {
089 final Touchable touchable1 = mockery.mock(Touchable.class);
090 final Touchable touchable2 = mockery.mock(Touchable.class);
091
092 final Sequence sequence = mockery.sequence("touching");
093 mockery.checking(new Expectations() {{
094 one(touchable2).touch(); inSequence(sequence);
095 one(touchable1).touch(); inSequence(sequence);
096 }});
097
098 MutablePicoContainer parent = new DefaultPicoContainer();
099 MutablePicoContainer child = new DefaultPicoContainer();
100 parent.addChildContainer(child);
101 parent.addComponent(touchable1);
102 child.addComponent(touchable2);
103
104 PicoVisitor visitor = new MethodCallingVisitor(touch, Touchable.class, null, false);
105 visitor.traverse(parent);
106 }
107 }