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 }