001 // Copyright 2004, 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 org.apache.hivemind.ApplicationRuntimeException; 018 import org.apache.hivemind.Location; 019 import org.apache.hivemind.service.MethodSignature; 020 import org.apache.tapestry.BaseComponentTestCase; 021 import org.apache.tapestry.engine.HomeService; 022 import org.apache.tapestry.engine.IEngineService; 023 import org.apache.tapestry.services.InjectedValueProvider; 024 import org.apache.tapestry.spec.InjectSpecification; 025 import org.apache.tapestry.spec.InjectSpecificationImpl; 026 import static org.easymock.EasyMock.expect; 027 import org.testng.annotations.Test; 028 029 import java.lang.reflect.Modifier; 030 import java.util.HashMap; 031 import java.util.Map; 032 033 /** 034 * Tests for {@link org.apache.tapestry.enhance.InjectObjectWorker}. 035 * 036 * @author Howard M. Lewis Ship 037 * @since 4.0 038 */ 039 @Test 040 public class TestInjectObjectWorker extends BaseComponentTestCase 041 { 042 private InjectSpecification newSpec(String name, String locator, Location location) 043 { 044 InjectSpecification is = new InjectSpecificationImpl(); 045 046 is.setProperty(name); 047 is.setObject(locator); 048 is.setLocation(location); 049 050 return is; 051 } 052 053 public void testNoExistingProperty() 054 { 055 Location l = newLocation(); 056 Object injectedValue = new Object(); 057 058 InjectSpecification spec = newSpec("fred", "service:barney", l); 059 060 EnhancementOperation op = newMock(EnhancementOperation.class); 061 062 InjectedValueProvider p = newMock(InjectedValueProvider.class); 063 064 expect(op.getPropertyType("fred")).andReturn(null); 065 066 op.claimReadonlyProperty("fred"); 067 068 expect(p.obtainValue("service:barney", l)).andReturn(injectedValue); 069 070 // When the same bean is injected multiple times, the field name 071 // returned won't match the field name suggested; make sure the code 072 // generation used the correct field name. 073 074 expect(op.addInjectedField("_$fred", Object.class, injectedValue)).andReturn("_$gnarly"); 075 076 op.addMethod( 077 Modifier.PUBLIC, 078 new MethodSignature(Object.class, "getFred", null, null), 079 "return _$gnarly;", 080 l); 081 082 replay(); 083 084 InjectObjectWorker w = new InjectObjectWorker(); 085 w.setProvider(p); 086 087 w.performEnhancement(op, spec); 088 089 verify(); 090 } 091 092 public void testWithExistingProperty() 093 { 094 Location l = newLocation(); 095 Object injectedValue = new HomeService(); 096 097 InjectSpecification spec = newSpec("wilma", "service:betty", l); 098 099 EnhancementOperation op = newMock(EnhancementOperation.class); 100 101 InjectedValueProvider p = newMock(InjectedValueProvider.class); 102 103 expect(op.getPropertyType("wilma")).andReturn(IEngineService.class); 104 105 op.claimReadonlyProperty("wilma"); 106 107 expect(p.obtainValue("service:betty", l)).andReturn(injectedValue); 108 109 expect(op.addInjectedField("_$wilma", IEngineService.class, injectedValue)).andReturn("_$wilma"); 110 111 op.addMethod(Modifier.PUBLIC, new MethodSignature(IEngineService.class, "getWilma", null, 112 null), "return _$wilma;", l); 113 114 replay(); 115 116 InjectObjectWorker w = new InjectObjectWorker(); 117 w.setProvider(p); 118 119 w.performEnhancement(op, spec); 120 121 verify(); 122 } 123 124 /** 125 * Test what happens when the value to be injected is null (usually indicating an error in the 126 * locator and/or a configuration error inside the HiveMind descriptors). 127 */ 128 129 public void testInjectNull() 130 { 131 Location l = newLocation(); 132 133 InjectSpecification spec = newSpec("fred", "service:barney", l); 134 135 EnhancementOperation op = newMock(EnhancementOperation.class); 136 137 InjectedValueProvider p = newMock(InjectedValueProvider.class); 138 139 expect(op.getPropertyType("fred")).andReturn(null); 140 141 op.claimReadonlyProperty("fred"); 142 143 expect(p.obtainValue("service:barney", l)).andReturn(null); 144 145 replay(); 146 147 InjectObjectWorker w = new InjectObjectWorker(); 148 w.setProvider(p); 149 150 try 151 { 152 w.performEnhancement(op, spec); 153 unreachable(); 154 } 155 catch (ApplicationRuntimeException ex) 156 { 157 assertEquals("Value obtained using locator 'service:barney' is null.", ex.getMessage()); 158 assertSame(l, ex.getLocation()); 159 } 160 161 verify(); 162 } 163 164 public void testInjectedValueWrongType() 165 { 166 Location l = newLocation(); 167 168 InjectSpecification spec = newSpec("fred", "service:barney", l); 169 170 EnhancementOperation op = newMock(EnhancementOperation.class); 171 172 InjectedValueProvider p = newMock(InjectedValueProvider.class); 173 174 expect(op.getPropertyType("fred")).andReturn(IEngineService.class); 175 176 op.claimReadonlyProperty("fred"); 177 178 expect(p.obtainValue("service:barney", l)).andReturn("INJECTED-VALUE"); 179 180 replay(); 181 182 InjectObjectWorker w = new InjectObjectWorker(); 183 w.setProvider(p); 184 185 try 186 { 187 w.performEnhancement(op, spec); 188 unreachable(); 189 190 } 191 catch (ApplicationRuntimeException ex) 192 { 193 assertEquals( 194 "The value obtained using locator 'service:barney' (INJECTED-VALUE) is not compatible with the existing property (of type org.apache.tapestry.engine.IEngineService).", 195 ex.getMessage()); 196 assertSame(l, ex.getLocation()); 197 } 198 199 verify(); 200 } 201 202 public void testInjectMap() 203 { 204 Location l = newLocation(); 205 Map injectedValue = new HashMap(); 206 207 InjectSpecification spec = newSpec("fred", "service:barney", l); 208 209 EnhancementOperation op = newMock(EnhancementOperation.class); 210 211 InjectedValueProvider p = newMock(InjectedValueProvider.class); 212 213 expect(op.getPropertyType("fred")).andReturn(Map.class); 214 215 op.claimReadonlyProperty("fred"); 216 217 expect(p.obtainValue("service:barney", l)).andReturn(new HashMap()); 218 219 expect(op.addInjectedField("_$fred", Map.class, injectedValue)).andReturn("_$fred"); 220 221 op.addMethod(Modifier.PUBLIC, new MethodSignature(Map.class, "getFred", null, 222 null), "return _$fred;", l); 223 224 replay(); 225 226 InjectObjectWorker w = new InjectObjectWorker(); 227 w.setProvider(p); 228 229 w.performEnhancement(op, spec); 230 231 verify(); 232 } 233 }