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 * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant   *
009 *****************************************************************************/
010package org.picocontainer.injectors;
011
012import org.junit.Before;
013import org.junit.Test;
014import org.picocontainer.ComponentFactory;
015import org.picocontainer.DefaultPicoContainer;
016import org.picocontainer.PicoCompositionException;
017import org.picocontainer.tck.AbstractComponentFactoryTest;
018
019import static junit.framework.Assert.assertNull;
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertFalse;
022import static org.junit.Assert.fail;
023
024/**
025 * @author Jörg Schaible
026 */
027public class SetterInjectionTestCase extends AbstractComponentFactoryTest {
028        
029        @Before
030    public void setUp() throws Exception {
031        picoContainer = new DefaultPicoContainer(createComponentFactory());
032    }
033
034    protected ComponentFactory createComponentFactory() {
035        return new SetterInjection();
036    }
037
038    public static interface Bean {
039    }
040
041    public static class NamedBean implements Bean {
042        private String name;
043
044        public String getName() {
045            return name;
046        }
047
048        public void setName(String name) {
049            this.name = name;
050        }
051    }
052
053    public static class NamedBeanWithPossibleDefault extends NamedBean {
054        private boolean byDefault;
055
056        public NamedBeanWithPossibleDefault() {
057        }
058
059        public NamedBeanWithPossibleDefault(String name) {
060            setName(name);
061            byDefault = true;
062        }
063
064        public boolean getByDefault() {
065            return byDefault;
066        }
067    }
068
069    public static class NoBean extends NamedBean {
070        public NoBean(String name) {
071            setName(name);
072        }
073    }
074
075    @Test public void testContainerUsesStandardConstructor() {
076        picoContainer.addComponent(Bean.class, NamedBeanWithPossibleDefault.class);
077        picoContainer.addComponent("Tom");
078        NamedBeanWithPossibleDefault bean = (NamedBeanWithPossibleDefault) picoContainer.getComponent(Bean.class);
079        assertFalse(bean.getByDefault());
080    }
081
082    @Test public void testContainerUsesOnlyStandardConstructor() {
083        picoContainer.addComponent(Bean.class, NoBean.class);
084        picoContainer.addComponent("Tom");
085        try {
086            picoContainer.getComponent(Bean.class);
087            fail("Instantiation should have failed.");
088        } catch (PicoCompositionException e) {
089        }
090    }
091
092    public static class AnotherNamedBean implements Bean {
093        private String name;
094
095        public String getName() {
096            return name;
097        }
098
099        public void initName(String name) {
100            this.name = name;
101        }
102    }
103
104    @Test public void testAlternatePrefixWorks() {
105        picoContainer = new DefaultPicoContainer(new SetterInjection("init"));
106        picoContainer.addComponent(Bean.class, AnotherNamedBean.class);
107        picoContainer.addComponent("Tom");
108        AnotherNamedBean bean = picoContainer.getComponent(AnotherNamedBean.class);
109        assertEquals("Tom", bean.getName());
110    }
111
112    public static class AnotherNamedBean2 extends AnotherNamedBean {
113        private String name2;
114
115        public String getName2() {
116            return name2;
117        }
118
119        public void initName2(String name) {
120            this.name2 = name;
121        }
122    }
123
124
125    @Test public void testNotMatcherWorks() {
126        picoContainer = new DefaultPicoContainer(new SetterInjection("init", "initName2"));
127        picoContainer.addComponent(Bean.class, AnotherNamedBean2.class);
128        picoContainer.addComponent("Tom");
129        AnotherNamedBean2 bean = picoContainer.getComponent(AnotherNamedBean2.class);
130        assertEquals("Tom", bean.getName());
131        assertNull(bean.getName2());
132    }
133
134    public static class RecursivelyNamedBean implements Bean {
135        private String name;
136        private NamedBean namedBean;
137
138        public String getName() {
139            return name;
140        }
141
142        public void setName(String name) {
143            this.name = name;
144        }
145
146        public void setNamedBean(NamedBean namedBean) {
147            this.namedBean = namedBean;
148        }
149
150        public NamedBean getNamedBean() {
151            return namedBean;
152        }
153    }
154
155    @Test public void testOptionalWorks() {
156        picoContainer = new DefaultPicoContainer(new SetterInjection().withInjectionOptional());
157        picoContainer.addComponent(RecursivelyNamedBean.class, RecursivelyNamedBean.class);
158        picoContainer.addComponent("Tom");
159        RecursivelyNamedBean bean = picoContainer.getComponent(RecursivelyNamedBean.class);
160        assertEquals("Tom", bean.getName());
161        assertNull(bean.getNamedBean());
162    }
163
164
165}