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 * Original code by * 009 *****************************************************************************/ 010 package org.picocontainer.defaults; 011 012 import static org.junit.Assert.assertEquals; 013 import static org.junit.Assert.fail; 014 import static org.picocontainer.tck.MockFactory.mockeryWithCountingNamingScheme; 015 016 import java.lang.reflect.Constructor; 017 import java.util.Collection; 018 import java.util.Vector; 019 020 import org.hamcrest.BaseMatcher; 021 import org.hamcrest.Description; 022 import org.hamcrest.Matcher; 023 import org.jmock.Expectations; 024 import org.jmock.Mockery; 025 import org.jmock.integration.junit4.JMock; 026 import org.junit.Test; 027 import org.junit.runner.RunWith; 028 import org.picocontainer.ComponentAdapter; 029 import org.picocontainer.ComponentMonitor; 030 import org.picocontainer.ComponentMonitorStrategy; 031 import org.picocontainer.DefaultPicoContainer; 032 import org.picocontainer.PicoContainer; 033 import org.picocontainer.injectors.ConstructorInjector; 034 import org.picocontainer.monitors.AbstractComponentMonitor; 035 036 /** 037 * @author Mauro Talevi 038 */ 039 @RunWith(JMock.class) 040 public class AbstractComponentMonitorTestCase { 041 042 private Mockery mockery = mockeryWithCountingNamingScheme(); 043 044 @Test public void testDelegatingMonitorThrowsExpectionWhenConstructionWithNullDelegate(){ 045 try { 046 new AbstractComponentMonitor(null); 047 fail("NPE expected"); 048 } catch (NullPointerException e) { 049 assertEquals("NPE", "monitor", e.getMessage()); 050 } 051 } 052 053 @Test public void testDelegatingMonitorThrowsExpectionWhenChangingToNullMonitor(){ 054 AbstractComponentMonitor dcm = new AbstractComponentMonitor(); 055 try { 056 dcm.changeMonitor(null); 057 fail("NPE expected"); 058 } catch (NullPointerException e) { 059 assertEquals("NPE", "monitor", e.getMessage()); 060 } 061 } 062 063 @Test public void testDelegatingMonitorCanChangeMonitorInDelegateThatDoesSupportMonitorStrategy() { 064 ComponentMonitor monitor = mockMonitorWithNoExpectedMethods(); 065 AbstractComponentMonitor dcm = new AbstractComponentMonitor(mockMonitorThatSupportsStrategy(monitor)); 066 dcm.changeMonitor(monitor); 067 assertEquals(monitor, dcm.currentMonitor()); 068 dcm.instantiating(null, null, null); 069 } 070 071 @Test public void testDelegatingMonitorChangesDelegateThatDoesNotSupportMonitorStrategy() { 072 ComponentMonitor delegate = mockMonitorWithNoExpectedMethods(); 073 AbstractComponentMonitor dcm = new AbstractComponentMonitor(delegate); 074 ComponentMonitor monitor = mockMonitorWithNoExpectedMethods(); 075 assertEquals(delegate, dcm.currentMonitor()); 076 dcm.changeMonitor(monitor); 077 assertEquals(monitor, dcm.currentMonitor()); 078 } 079 080 @Test public void testDelegatingMonitorReturnsDelegateThatDoesNotSupportMonitorStrategy() { 081 ComponentMonitor delegate = mockMonitorWithNoExpectedMethods(); 082 AbstractComponentMonitor dcm = new AbstractComponentMonitor(delegate); 083 assertEquals(delegate, dcm.currentMonitor()); 084 } 085 086 private ComponentMonitor mockMonitorWithNoExpectedMethods() { 087 return mockery.mock(ComponentMonitor.class); 088 } 089 090 private ComponentMonitor mockMonitorThatSupportsStrategy(final ComponentMonitor currentMonitor) { 091 final TestMonitorThatSupportsStrategy monitor = mockery.mock(TestMonitorThatSupportsStrategy.class); 092 mockery.checking(new Expectations(){{ 093 one(monitor).changeMonitor(with(equal(currentMonitor))); 094 one(monitor).currentMonitor(); 095 will(returnValue(currentMonitor)); 096 one(monitor).instantiating(with(any(PicoContainer.class)), with(any(ComponentAdapter.class)), with(any(Constructor.class))); 097 }}); 098 return monitor; 099 } 100 101 @Test public void testMonitoringHappensBeforeAndAfterInstantiation() throws NoSuchMethodException { 102 final Vector ourIntendedInjectee0 = new Vector(); 103 final String ourIntendedInjectee1 = "hullo"; 104 final DefaultPicoContainer parent = new DefaultPicoContainer(); 105 final ComponentMonitor monitor = mockery.mock(ComponentMonitor.class); 106 final DefaultPicoContainer child = new DefaultPicoContainer(new AbstractComponentMonitor(monitor), parent); 107 final Constructor needsACoupleOfThings = NeedsACoupleOfThings.class.getConstructors()[0]; 108 final Matcher<Long> durationIsGreaterThanOrEqualToZero = new BaseMatcher<Long>() { 109 public boolean matches(Object item) { 110 Long duration = (Long)item; 111 return 0 <= duration; 112 } 113 114 public void describeTo(Description description) { 115 description.appendText("The endTime wasn't after the startTime"); 116 } 117 }; 118 final Matcher<Object> isANACOTThatWozCreated = new BaseMatcher<Object>() { 119 public boolean matches(Object item) { 120 return item instanceof NeedsACoupleOfThings; 121 } 122 123 public void describeTo(Description description) { 124 description.appendText("Should have been a NeedsACoupleOfThings"); 125 } 126 }; 127 final Matcher<Object[]> collectionAndStringWereInjected = new BaseMatcher<Object[]>() { 128 public boolean matches(Object item) { 129 Object[] args = (Object[]) item; 130 return args.length == 2 && args[0] == ourIntendedInjectee0 && args[1] == ourIntendedInjectee1; 131 } 132 public void describeTo(Description description) { 133 description.appendText("Should have injected our intended vector and string"); 134 } 135 }; 136 mockery.checking(new Expectations(){{ 137 one(monitor).instantiating(with(same(child)), with(any(ConstructorInjector.class)), with(equal(needsACoupleOfThings))); 138 will(returnValue(needsACoupleOfThings)); 139 one(monitor).instantiated(with(same(child)), with(any(ConstructorInjector.class)), with(equal(needsACoupleOfThings)), with(isANACOTThatWozCreated), with(collectionAndStringWereInjected), with(durationIsGreaterThanOrEqualToZero)); 140 atLeast(2).of(monitor).noComponentFound(with(any(DefaultPicoContainer.class)), with(any(Object.class))); 141 will(returnValue(null)); 142 }}); 143 parent.addComponent(ourIntendedInjectee0); 144 parent.addComponent(ourIntendedInjectee1); 145 child.addComponent(NeedsACoupleOfThings.class); 146 child.getComponent(NeedsACoupleOfThings.class); 147 } 148 149 public static class NeedsACoupleOfThings { 150 public NeedsACoupleOfThings(Collection collection, String string) { 151 } 152 } 153 154 public static interface TestMonitorThatSupportsStrategy extends ComponentMonitor, ComponentMonitorStrategy { 155 } 156 }