01 /*
02 * Copyright 2008-2012 the original author or authors.
03 *
04 * Licensed under the Apache License, Version 2.0 (the "License");
05 * you may not use this file except in compliance with the License.
06 * You may obtain a copy of the License at
07 *
08 * http://www.apache.org/licenses/LICENSE-2.0
09 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package griffon.test
17
18 import griffon.core.UIThreadManager
19
20 /**
21 * Support class for writing unit tests in Griffon. It mainly provides
22 * access to various mocking options, while making sure that the meta-
23 * class magic does not leak outside of a single test.
24 * It also provides access to the threading facilities exposed by
25 * {@code UIThreadManager}.
26 */
27 class GriffonUnitTestCase extends GroovyTestCase {
28 Map savedMetaClasses
29
30 protected void setUp() {
31 super.setUp()
32 savedMetaClasses = [:]
33 }
34
35 protected void tearDown() {
36 super.tearDown()
37
38 // Restore all the saved meta classes.
39 savedMetaClasses.each { clazz, metaClass ->
40 GroovySystem.metaClassRegistry.removeMetaClass(clazz)
41 GroovySystem.metaClassRegistry.setMetaClass(clazz, metaClass)
42 }
43 }
44
45 /**
46 * Use this method when you plan to perform some meta-programming
47 * on a class. It ensures that any modifications you make will be
48 * cleared at the end of the test.
49 * @param clazz The class to register.
50 */
51 protected void registerMetaClass(Class clazz) {
52 // If the class has already been registered, then there's nothing to do.
53 if (savedMetaClasses.containsKey(clazz)) return
54
55 // Save the class's current meta class.
56 savedMetaClasses[clazz] = clazz.metaClass
57
58 // Create a new EMC for the class and attach it.
59 def emc = new ExpandoMetaClass(clazz, true, true)
60 emc.initialize()
61 GroovySystem.metaClassRegistry.setMetaClass(clazz, emc)
62 }
63
64 /**
65 * Creates a new Griffon mock for the given class. Use it as you
66 * would use MockFor and StubFor.
67 * @param clazz The class to mock.
68 * @param loose If <code>true</code>, the method returns a loose-
69 * expectation mock, otherwise it returns a strict one. The default
70 * is a strict mock.
71 */
72 protected GriffonMock mockFor(Class clazz, boolean loose = false) {
73 registerMetaClass(clazz)
74 return new GriffonMock(clazz, loose)
75 }
76
77 /** Executes code synchronously inside the UI thread */
78 def execSync = UIThreadManager.instance.&executeSync
79 /** Executes code asynchronously inside the UI thread */
80 def execAsync = UIThreadManager.instance.&executeAsync
81 /** Executes code outside the UI thread */
82 def execOutside = UIThreadManager.instance.&executeOutside
83 /** True if the current thread is the UI thread */
84 def isUIThread = UIThreadManager.instance.&isUIThread
85 /** Schedules a block of code as a Future */
86 def execFuture = { Object... args ->
87 UIThreadManager.instance.executeFuture(* args)
88 }
89 }
|