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;
009    
010    import static org.junit.Assert.assertEquals;
011    import static org.junit.Assert.assertSame;
012    import static org.junit.Assert.assertTrue;
013    import static org.junit.Assert.fail;
014    import static org.picocontainer.tck.MockFactory.mockeryWithCountingNamingScheme;
015    
016    import org.jmock.Expectations;
017    import org.jmock.Mockery;
018    import org.jmock.Sequence;
019    import org.jmock.integration.junit4.JMock;
020    import org.junit.Test;
021    import org.junit.runner.RunWith;
022    import org.picocontainer.visitors.AbstractPicoVisitor;
023    import org.picocontainer.visitors.VerifyingVisitor;
024    
025    
026    /**
027     * Test general PicoVisitor behaviour.
028     * @author Jörg Schaible
029     * @author Mauro Talevi
030     */
031    @RunWith(JMock.class)
032    public class PicoVisitorTestCase {
033    
034            private Mockery mockery = mockeryWithCountingNamingScheme();
035            
036        @Test public void testVisitorThatMustBeInvokedUsingTraverse() {
037            MutablePicoContainer pico = new DefaultPicoContainer();
038            try {
039                pico.accept(new VerifyingVisitor());
040                fail("PicoVisitorTraversalException expected");
041            } catch (AbstractPicoVisitor.PicoVisitorTraversalException e) {
042                assertTrue(e.getMessage().indexOf(VerifyingVisitor.class.getName()) >= 0);
043            }
044        }
045    
046        public static class UnusualNode {
047            boolean visited;
048    
049            public void accept(PicoVisitor visit) {
050                visited = true;
051            }
052        }
053    
054        @Test public void testUnusualTraverseNode() {
055            UnusualNode node = new UnusualNode();
056            new VerifyingVisitor().traverse(node);
057            assertTrue(node.visited);
058        }
059    
060        @Test public void testIllegalTraverseNode() {
061            try {
062                new VerifyingVisitor().traverse("Gosh!");
063                fail("IllegalArgumentException expected");
064            } catch (IllegalArgumentException e) {
065                assertTrue(e.getMessage().indexOf(String.class.getName()) >= 0);
066            }
067        }
068    
069        @Test public void testThrownRuntimeExceptionIsUnwrapped() {
070            final PicoContainer pico = mockery.mock(PicoContainer.class);
071            final PicoVisitor visitor = new VerifyingVisitor();
072            final Error exception = new Error("junit");
073            mockery.checking(new Expectations() {{
074                one(pico).accept(with(same(visitor)));
075                will(throwException(new PicoCompositionException("message", exception)));
076            }});
077            try {
078                visitor.traverse(pico);
079                fail("PicoCompositionException expected");
080            } catch (RuntimeException e) {
081                assertEquals("message", e.getMessage());
082                assertSame(exception, e.getCause());
083            }
084        }
085    
086        @Test public void testThrownErrorIsUnwrapped() {
087            final PicoContainer pico = mockery.mock(PicoContainer.class);
088            final PicoVisitor visitor = new VerifyingVisitor();
089            final Error error = new InternalError("junit");
090            final Sequence sequence = mockery.sequence("accepting");
091            mockery.checking(new Expectations() {{
092                one(pico).accept(with(same(visitor))); inSequence(sequence);
093                one(pico).accept(with(same(visitor))); inSequence(sequence);
094                will(throwException(error));
095            }});
096            visitor.traverse(pico);
097            try {
098                visitor.traverse(pico);
099                fail("UndeclaredThrowableException expected");
100            } catch(InternalError e) {
101                assertEquals("junit", e.getMessage());
102            }
103        }
104    }