001    // Copyright 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.enhance;
016    
017    import static org.easymock.EasyMock.expect;
018    import static org.easymock.EasyMock.expectLastCall;
019    
020    import java.lang.reflect.Modifier;
021    import java.util.Collections;
022    
023    import org.apache.hivemind.ApplicationRuntimeException;
024    import org.apache.hivemind.ErrorLog;
025    import org.apache.hivemind.Location;
026    import org.apache.hivemind.service.MethodSignature;
027    import org.apache.tapestry.BaseComponent;
028    import org.apache.tapestry.BaseComponentTestCase;
029    import org.apache.tapestry.IComponent;
030    import org.apache.tapestry.spec.ContainedComponent;
031    import org.apache.tapestry.spec.IComponentSpecification;
032    import org.apache.tapestry.spec.IContainedComponent;
033    import org.testng.annotations.Test;
034    
035    /**
036     * Tests for {@link org.apache.tapestry.enhance.InjectComponentWorker}.
037     * 
038     * @author Howard M. Lewis Ship
039     * @since 4.0
040     */
041    @Test
042    public class TestInjectComponentWorker extends BaseComponentTestCase
043    {
044        private IComponentSpecification newSpec(String componentId, String propertyName,
045                Location location)
046        {
047            IContainedComponent cc = new ContainedComponent();
048            cc.setPropertyName(propertyName);
049            cc.setLocation(location);
050            
051            IComponentSpecification spec = newSpec();
052    
053            expect(spec.getComponentIds()).andReturn(Collections.singletonList(componentId));
054    
055            expect(spec.getComponent(componentId)).andReturn(cc);
056    
057            return spec;
058        }
059    
060        public void testNoWork()
061        {
062            IComponentSpecification spec = newSpec("fred", null, null);
063            EnhancementOperation op = newMock(EnhancementOperation.class);
064    
065            replay();
066    
067            new InjectComponentWorker().performEnhancement(op, spec);
068    
069            verify();
070        }
071    
072        protected EnhancementOperation newEnhancementOperation()
073        {
074            return newMock(EnhancementOperation.class);
075        }
076    
077        protected void trainGetPropertyType(EnhancementOperation op, String propertyName,
078                Class propertyType)
079        {
080            expect(op.getPropertyType(propertyName)).andReturn(propertyType);
081        }
082    
083        protected void trainGetAccessorMethodName(EnhancementOperation op, String propertyName,
084                String methodName)
085        {
086            expect(op.getAccessorMethodName(propertyName)).andReturn(methodName);
087        }
088    
089        protected void trainGetClassReference(EnhancementOperation op, Class clazz, String reference)
090        {
091            expect(op.getClassReference(clazz)).andReturn(reference);
092        }
093    
094        protected void trainAddInjectedField(EnhancementOperation op, String fieldName,
095                Class fieldType, Object fieldValue, String uniqueFieldName)
096        {
097            expect(op.addInjectedField(fieldName, fieldType, fieldValue)).andReturn(uniqueFieldName);
098        }
099    
100        public void testSuccess()
101        {
102            Location l = newLocation();
103            IComponentSpecification spec = newSpec("fred", "barney", l);
104            EnhancementOperation op = newEnhancementOperation();
105    
106            trainGetPropertyType(op, "barney", IComponent.class);
107    
108            op.claimReadonlyProperty("barney");
109    
110            trainGetClassReference(op, IComponent.class, "_$IComponent$class");
111            trainAddInjectedField(op, "_$barney$location", Location.class, l, "_$$location");
112    
113            op.addField("_$barney", IComponent.class);
114    
115            trainGetAccessorMethodName(op, "barney", "getBarney");
116    
117            op.addMethod(
118                    Modifier.PUBLIC,
119                    new MethodSignature(IComponent.class, "getBarney", null, null),
120                    "return _$barney;",
121                    l);
122    
123            op.extendMethodImplementation(
124                    IComponent.class,
125                    EnhanceUtils.FINISH_LOAD_SIGNATURE,
126                    "_$barney = (org.apache.tapestry.IComponent) "
127                            + "org.apache.tapestry.TapestryUtils#getComponent"
128                            + "(this, \"fred\", _$IComponent$class, _$$location);");
129    
130            replay();
131    
132            new InjectComponentWorker().performEnhancement(op, spec);
133    
134            verify();
135        }
136    
137        public void testFailure()
138        {
139            Location l = newLocation();
140            Throwable ex = new ApplicationRuntimeException(EnhanceMessages.claimedProperty("barney"));
141            
142            EnhancementOperation op = newMock(EnhancementOperation.class);
143    
144            IComponentSpecification spec = newSpec("fred", "barney", l);
145    
146            ErrorLog log = newMock(ErrorLog.class);
147    
148            expect(op.getPropertyType("barney")).andReturn(IComponent.class);
149    
150            op.claimReadonlyProperty("barney");
151            expectLastCall().andThrow(ex);
152    
153            expect(op.getBaseClass()).andReturn(BaseComponent.class);
154    
155            log.error(EnhanceMessages.errorAddingProperty("barney", BaseComponent.class, ex), l, ex);
156    
157            replay();
158    
159            InjectComponentWorker w = new InjectComponentWorker();
160    
161            w.setErrorLog(log);
162    
163            w.performEnhancement(op, spec);
164    
165            verify();
166        }
167    }