001 // Copyright 2006, 2007, 2008, 2010, 2011 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.tapestry5.ioc.test; 016 017 import static java.lang.Thread.sleep; 018 import static org.easymock.EasyMock.isA; 019 020 import java.io.File; 021 import java.lang.annotation.Annotation; 022 import java.lang.reflect.Method; 023 import java.net.URL; 024 import java.util.Locale; 025 026 import org.apache.tapestry5.ioc.*; 027 import org.apache.tapestry5.ioc.annotations.IntermediateType; 028 import org.apache.tapestry5.ioc.def.*; 029 import org.apache.tapestry5.ioc.services.ClassPropertyAdapter; 030 import org.apache.tapestry5.ioc.services.MasterObjectProvider; 031 import org.apache.tapestry5.ioc.services.PerthreadManager; 032 import org.apache.tapestry5.ioc.services.PropertyAccess; 033 import org.apache.tapestry5.ioc.services.PropertyAdapter; 034 import org.apache.tapestry5.ioc.services.SymbolSource; 035 import org.apache.tapestry5.ioc.services.ThreadLocale; 036 import org.apache.tapestry5.ioc.services.TypeCoercer; 037 import org.slf4j.Logger; 038 039 /** 040 * Add factory and trainer methods for the public interfaces of Tapestry IOC. 041 */ 042 public class IOCTestCase extends TestBase 043 { 044 045 /** 046 * Builds a Registry for the provided modules; caller should shutdown the Registry when done. 047 */ 048 protected final Registry buildRegistry(Class... moduleClasses) 049 { 050 RegistryBuilder builder = new RegistryBuilder(); 051 052 builder.add(moduleClasses); 053 054 return builder.build(); 055 } 056 057 protected final Method findMethod(Class clazz, String methodName) 058 { 059 for (Method method : clazz.getMethods()) 060 { 061 if (method.getName().equals(methodName)) 062 return method; 063 } 064 065 throw new IllegalArgumentException(String.format("Class %s does not provide a method named '%s'.", 066 clazz.getName(), methodName)); 067 } 068 069 protected final Method findMethod(Object subject, String methodName) 070 { 071 return findMethod(subject.getClass(), methodName); 072 } 073 074 protected final Method findMethod(String methodName) 075 { 076 return findMethod(this, methodName); 077 } 078 079 /** 080 * Combines a series of lines by forming a string with a line separator after each line. 081 */ 082 protected final String join(String... lines) 083 { 084 StringBuilder result = new StringBuilder(); 085 086 for (String line : lines) 087 { 088 result.append(line); 089 result.append("\n"); 090 } 091 092 return result.toString(); 093 } 094 095 protected final AnnotationProvider mockAnnotationProvider() 096 { 097 return newMock(AnnotationProvider.class); 098 } 099 100 @SuppressWarnings("unchecked") 101 protected final <T> Configuration<T> mockConfiguration() 102 { 103 return newMock(Configuration.class); 104 } 105 106 protected final ContributionDef mockContributionDef() 107 { 108 return newMock(ContributionDef.class); 109 } 110 111 protected final DecoratorDef mockDecoratorDef() 112 { 113 return newMock(DecoratorDef.class); 114 } 115 116 protected final DecoratorDef2 mockDecoratorDef2() 117 { 118 return newMock(DecoratorDef2.class); 119 } 120 121 protected final AdvisorDef mockAdvisorDef() 122 { 123 return newMock(AdvisorDef.class); 124 } 125 126 protected final AdvisorDef2 mockAdvisorDef2() 127 { 128 return newMock(AdvisorDef2.class); 129 } 130 131 protected final Location mockLocation() 132 { 133 return newMock(Location.class); 134 } 135 136 protected final Logger mockLogger() 137 { 138 return newMock(Logger.class); 139 } 140 141 protected final void stub_isDebugEnabled(Logger logger, boolean enabled) 142 { 143 expect(logger.isDebugEnabled()).andStubReturn(enabled); 144 } 145 146 @SuppressWarnings("unchecked") 147 protected final <K, V> MappedConfiguration<K, V> mockMappedConfiguration() 148 { 149 return newMock(MappedConfiguration.class); 150 } 151 152 protected final MessageFormatter mockMessageFormatter() 153 { 154 return newMock(MessageFormatter.class); 155 } 156 157 protected final Messages mockMessages() 158 { 159 return newMock(Messages.class); 160 } 161 162 protected final ModuleDef mockModuleDef() 163 { 164 return newMock(ModuleDef.class); 165 } 166 167 protected final ModuleDef2 mockModuleDef2() 168 { 169 return newMock(ModuleDef2.class); 170 } 171 172 protected final ObjectCreator mockObjectCreator() 173 { 174 return newMock(ObjectCreator.class); 175 } 176 177 protected final ObjectProvider mockObjectProvider() 178 { 179 return newMock(ObjectProvider.class); 180 } 181 182 @SuppressWarnings("unchecked") 183 protected final <T> OrderedConfiguration<T> mockOrderedConfiguration() 184 { 185 return newMock(OrderedConfiguration.class); 186 } 187 188 protected final Resource mockResource() 189 { 190 return newMock(Resource.class); 191 } 192 193 /** 194 * Frequently used as a placeholder for an arbitrary service (but its nice and simple). 195 */ 196 protected final Runnable mockRunnable() 197 { 198 return newMock(Runnable.class); 199 } 200 201 protected final ServiceBuilderResources mockServiceBuilderResources() 202 { 203 return newMock(ServiceBuilderResources.class); 204 } 205 206 protected final ServiceDecorator mockServiceDecorator() 207 { 208 return newMock(ServiceDecorator.class); 209 } 210 211 protected final ServiceDef mockServiceDef() 212 { 213 return newMock(ServiceDef.class); 214 } 215 216 protected final ObjectLocator mockObjectLocator() 217 { 218 return newMock(ObjectLocator.class); 219 } 220 221 protected final ServiceResources mockServiceResources() 222 { 223 return newMock(ServiceResources.class); 224 } 225 226 protected final SymbolSource mockSymbolSource() 227 { 228 return newMock(SymbolSource.class); 229 } 230 231 protected final ThreadLocale mockThreadLocale() 232 { 233 return newMock(ThreadLocale.class); 234 } 235 236 protected final TypeCoercer mockTypeCoercer() 237 { 238 return newMock(TypeCoercer.class); 239 } 240 241 protected final void stub_contains(Messages messages, boolean contained) 242 { 243 expect(messages.contains(isA(String.class))).andStubReturn(contained); 244 } 245 246 protected <S, T> void train_coerce(TypeCoercer coercer, S input, Class<T> expectedType, T coercedValue) 247 { 248 expect(coercer.coerce(input, expectedType)).andReturn(coercedValue); 249 } 250 251 protected final void train_contains(Messages messages, String key, boolean result) 252 { 253 expect(messages.contains(key)).andReturn(result).atLeastOnce(); 254 } 255 256 protected final void train_createInterceptor(ServiceDecorator decorator, Object coreObject, Object interceptor) 257 { 258 expect(decorator.createInterceptor(coreObject)).andReturn(interceptor); 259 } 260 261 protected final void train_createObject(ObjectCreator creator, Object service) 262 { 263 expect(creator.createObject()).andReturn(service); 264 } 265 266 protected final void train_expandSymbols(SymbolSource source, String input) 267 { 268 train_expandSymbols(source, input, input); 269 } 270 271 protected final void train_expandSymbols(SymbolSource source, String input, String expanded) 272 { 273 expect(source.expandSymbols(input)).andReturn(expanded); 274 } 275 276 protected final void train_forFile(Resource resource, String relativePath, Resource file) 277 { 278 expect(resource.forFile(relativePath)).andReturn(file); 279 } 280 281 protected final void train_forLocale(Resource base, Locale locale, Resource resource) 282 { 283 expect(base.forLocale(locale)).andReturn(resource); 284 } 285 286 /** 287 * Have to put the result before the varargs. 288 */ 289 protected void train_format(MessageFormatter formatter, String result, Object... arguments) 290 { 291 expect(formatter.format(arguments)).andReturn(result); 292 } 293 294 protected final void train_get(Messages messages, String key, String message) 295 { 296 expect(messages.get(key)).andReturn(message).atLeastOnce(); 297 } 298 299 protected final void train_getLocale(ThreadLocale threadLocale, Locale locale) 300 { 301 expect(threadLocale.getLocale()).andReturn(locale); 302 } 303 304 protected final void train_getLogger(LoggerSource source, String serviceId, Logger logger) 305 { 306 expect(source.getLogger(serviceId)).andReturn(logger).atLeastOnce(); 307 } 308 309 protected final void train_getMessageFormatter(Messages messages, String key, MessageFormatter formatter) 310 { 311 expect(messages.getFormatter(key)).andReturn(formatter).atLeastOnce(); 312 } 313 314 protected final void train_getPath(Resource r, String path) 315 { 316 expect(r.getPath()).andReturn(path).atLeastOnce(); 317 } 318 319 protected final <T> void train_getService(ObjectLocator locator, Class<T> serviceInterface, T service) 320 { 321 expect(locator.getService(serviceInterface)).andReturn(service); 322 } 323 324 protected final <T> void train_getService(ObjectLocator locator, String serviceId, Class<T> serviceInterface, 325 T service) 326 { 327 expect(locator.getService(serviceId, serviceInterface)).andReturn(service); 328 } 329 330 protected final void train_getServiceId(ServiceDef def, String serviceId) 331 { 332 expect(def.getServiceId()).andReturn(serviceId).atLeastOnce(); 333 } 334 335 protected final void train_getServiceId(ServiceResources resources, String serviceId) 336 { 337 expect(resources.getServiceId()).andReturn(serviceId).atLeastOnce(); 338 } 339 340 protected final void train_getServiceInterface(ServiceDef def, Class serviceInterface) 341 { 342 expect(def.getServiceInterface()).andReturn(serviceInterface).atLeastOnce(); 343 } 344 345 protected final void train_getServiceInterface(ServiceResources resources, Class serviceInterface) 346 { 347 expect(resources.getServiceInterface()).andReturn(serviceInterface).atLeastOnce(); 348 } 349 350 protected final void train_getLogger(ServiceResources resources, Logger log) 351 { 352 expect(resources.getLogger()).andReturn(log).atLeastOnce(); 353 } 354 355 protected final void train_isDebugEnabled(Logger log, boolean debugEnabled) 356 { 357 expect(log.isDebugEnabled()).andReturn(debugEnabled); 358 } 359 360 protected final void train_isTraceEnabled(Logger log, boolean traceEnabled) 361 { 362 expect(log.isTraceEnabled()).andReturn(traceEnabled); 363 } 364 365 protected final void train_matches(DecoratorDef decoratorDef, ServiceDef serviceDef, boolean matches) 366 { 367 expect(decoratorDef.matches(serviceDef)).andReturn(matches); 368 } 369 370 protected final void train_matches(AdvisorDef advisorDef, ServiceDef serviceDef, boolean matches) 371 { 372 expect(advisorDef.matches(serviceDef)).andReturn(matches); 373 } 374 375 protected final <T> void train_provide(ObjectProvider provider, Class<T> objectType, 376 AnnotationProvider annotationProvider, ObjectLocator locator, T object) 377 { 378 expect(provider.provide(objectType, annotationProvider, locator)).andReturn(object); 379 } 380 381 protected final void train_toURL(Resource resource, URL url) 382 { 383 expect(resource.toURL()).andReturn(url).atLeastOnce(); 384 } 385 386 protected final <T extends Annotation> void train_getAnnotation(AnnotationProvider annotationProvider, 387 Class<T> annotationClass, T annotation) 388 { 389 expect(annotationProvider.getAnnotation(annotationClass)).andReturn(annotation); 390 } 391 392 protected final MasterObjectProvider mockMasterObjectProvider() 393 { 394 return newMock(MasterObjectProvider.class); 395 } 396 397 protected final void train_value(IntermediateType it, Class value) 398 { 399 expect(it.value()).andReturn(value); 400 } 401 402 protected final IntermediateType newIntermediateType() 403 { 404 return newMock(IntermediateType.class); 405 } 406 407 protected final PropertyAdapter mockPropertyAdapter() 408 { 409 return newMock(PropertyAdapter.class); 410 } 411 412 protected final ClassPropertyAdapter mockClassPropertyAdapter() 413 { 414 return newMock(ClassPropertyAdapter.class); 415 } 416 417 protected final PropertyAccess mockPropertyAccess() 418 { 419 return newMock(PropertyAccess.class); 420 } 421 422 protected final <T> void train_autobuild(ObjectLocator locator, Class<T> beanClass, T instance) 423 { 424 expect(locator.autobuild(beanClass)).andReturn(instance); 425 } 426 427 protected final PerthreadManager mockPerthreadManager() 428 { 429 return newMock(PerthreadManager.class); 430 } 431 432 protected final ServiceResources mockServiceResources(OperationTracker tracker) 433 { 434 ServiceResources resources = mockServiceResources(); 435 436 train_getTracker(resources, tracker); 437 438 return resources; 439 } 440 441 protected final void train_getTracker(ServiceResources resources, OperationTracker tracker) 442 { 443 expect(resources.getTracker()).andReturn(tracker).atLeastOnce(); 444 } 445 446 protected final ServiceBuilderResources mockServiceBuilderResources(OperationTracker tracker) 447 { 448 ServiceBuilderResources resources = mockServiceBuilderResources(); 449 450 train_getTracker(resources, tracker); 451 452 return resources; 453 } 454 455 protected final void train_valueForSymbol(SymbolSource symbolSource, String symbolName, String value) 456 { 457 expect(symbolSource.valueForSymbol(symbolName)).andReturn(value).atLeastOnce(); 458 } 459 460 /** 461 * Touches the file, changing the last modified time to the current time. 462 * Does not return until the last modified time for the file actually changes (how long that takes 463 * is JDK, OS and file system dependent). 464 */ 465 protected final void touch(File f) throws Exception 466 { 467 long startModified = f.lastModified(); 468 469 int index = 0; 470 471 while (true) 472 { 473 f.setLastModified(System.currentTimeMillis()); 474 475 long newModified = f.lastModified(); 476 477 if (newModified != startModified) 478 return; 479 480 // Sleep an ever increasing amount, to ensure that the filesystem 481 // catches the change to the file. The Ubuntu CI Server appears 482 // to need longer waits. 483 484 sleep(50 * (2 ^ index++)); 485 } 486 } 487 }