source: josm/trunk/test/unit/org/openstreetmap/josm/testutils/JOSMTestRules.java@ 10373

Last change on this file since 10373 was 10373, checked in by Don-vip, 8 years ago

fix #12949 - Use test rule instead of JOSMFixture to speed up tests (patch by michael2402) - gsoc-core

File size: 6.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.testutils;
3
4import java.io.File;
5import java.io.IOException;
6
7import org.junit.rules.TemporaryFolder;
8import org.junit.rules.TestRule;
9import org.junit.rules.Timeout;
10import org.junit.runner.Description;
11import org.junit.runners.model.InitializationError;
12import org.junit.runners.model.Statement;
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.gui.layer.MainLayerManager;
15import org.openstreetmap.josm.gui.util.GuiHelper;
16import org.openstreetmap.josm.io.OsmApi;
17import org.openstreetmap.josm.io.OsmApiInitializationException;
18import org.openstreetmap.josm.io.OsmTransferCanceledException;
19import org.openstreetmap.josm.tools.I18n;
20
21/**
22 * This class runs a test in an environment that resembles the one used by the JOSM main application.
23 * <p>
24 * The environment is reset before every test. You can specify the components to which you need access using the methods of this class.
25 * For example, invoking {@link #preferences()} gives you access to the (default) preferences.
26 *
27 * @author Michael Zangl
28 */
29public class JOSMTestRules implements TestRule {
30 //We should make this the default when running from ant: Timeout.seconds(10);
31 private Timeout timeout = null;
32 private TemporaryFolder josmHome;
33 private boolean usePreferences = false;
34 private APIType useAPI = APIType.NONE;
35 private String i18n = null;
36 private boolean platform;
37
38 /**
39 * Disable the default timeout for this test. Use with care.
40 * @return this instance, for easy chaining
41 */
42 public JOSMTestRules noTimeout() {
43 timeout = null;
44 return this;
45 }
46
47 /**
48 * Set a timeout for all tests in this class. Local method timeouts may only reduce this timeout.
49 * @param millis The timeout duration in milliseconds.
50 * @return this instance, for easy chaining
51 */
52 public JOSMTestRules timeout(int millis) {
53 timeout = Timeout.millis(millis);
54 return this;
55 }
56
57 /**
58 * Enable the use of default preferences.
59 * @return this instance, for easy chaining
60 */
61 public JOSMTestRules preferences() {
62 josmHome();
63 usePreferences = true;
64 return this;
65 }
66
67 /**
68 * Set JOSM home to a valid, empty directory.
69 * @return this instance, for easy chaining
70 */
71 private JOSMTestRules josmHome() {
72 josmHome = new TemporaryFolder();
73 return this;
74 }
75
76 /**
77 * Enables the i18n module for this test in english.
78 * @return this instance, for easy chaining
79 */
80 public JOSMTestRules i18n() {
81 return i18n("en");
82 }
83
84 /**
85 * Enables the i18n module for this test.
86 * @param language The language to use.
87 * @return this instance, for easy chaining
88 */
89 public JOSMTestRules i18n(String language) {
90 i18n = language;
91 return this;
92 }
93
94 /**
95 * Enable {@link Main#platform} global variable.
96 * @return this instance, for easy chaining
97 */
98 public JOSMTestRules platform() {
99 platform = true;
100 return this;
101 }
102
103 /**
104 * Enable the dev.openstreetmap.org API for this test.
105 * @return this instance, for easy chaining
106 */
107 public JOSMTestRules devAPI() {
108 preferences();
109 useAPI = APIType.DEV;
110 return this;
111 }
112
113 /**
114 * Use the {@link FakeOsmApi} for testing.
115 * @return this instance, for easy chaining
116 */
117 public JOSMTestRules fakeAPI() {
118 useAPI = APIType.FAKE;
119 return this;
120 }
121
122 @Override
123 public Statement apply(final Statement base, Description description) {
124 Statement statement = new Statement() {
125 @Override
126 public void evaluate() throws Throwable {
127 before();
128 try {
129 base.evaluate();
130 } finally {
131 after();
132 }
133 }
134 };
135 if (timeout != null) {
136 statement = timeout.apply(statement, description);
137 }
138 if (josmHome != null) {
139 statement = josmHome.apply(statement, description);
140 }
141 return statement;
142 }
143
144 /**
145 * Set up before running a test
146 * @throws InitializationError If an error occured while creating the required environment.
147 */
148 protected void before() throws InitializationError {
149 // Tests are running headless by default.
150 System.setProperty("java.awt.headless", "true");
151
152 // Set up i18n
153 if (i18n != null) {
154 I18n.set(i18n);
155 }
156
157 // Add JOSM home
158 if (josmHome != null) {
159 try {
160 File home = josmHome.newFolder();
161 System.setProperty("josm.home", home.getAbsolutePath());
162 } catch (IOException e) {
163 throw new InitializationError(e);
164 }
165 }
166
167 // Add preferences
168 if (usePreferences) {
169 Main.initApplicationPreferences();
170 Main.pref.enableSaveOnPut(false);
171 // No pref init -> that would only create the preferences file.
172 // We force the use of a wrong API server, just in case anyone attempts an upload
173 Main.pref.put("osm-server.url", "http://invalid");
174 }
175
176 // Set API
177 if (useAPI == APIType.DEV) {
178 Main.pref.put("osm-server.url", "http://api06.dev.openstreetmap.org/api");
179 } else if (useAPI == APIType.FAKE) {
180 FakeOsmApi api = FakeOsmApi.getInstance();
181 Main.pref.put("osm-server.url", api.getServerUrl());
182 }
183
184 // Initialize API
185 if (useAPI != APIType.NONE) {
186 try {
187 OsmApi.getOsmApi().initialize(null);
188 } catch (OsmTransferCanceledException | OsmApiInitializationException e) {
189 throw new InitializationError(e);
190 }
191 }
192
193 // Set Platform
194 if (platform) {
195 Main.determinePlatformHook();
196 }
197 }
198
199 /**
200 * Clean up after running a test
201 */
202 protected void after() {
203 // Sync AWT Thread
204 GuiHelper.runInEDTAndWait(new Runnable() {
205 @Override
206 public void run() {
207 }
208 });
209 // Remove all layers
210 MainLayerManager lm = Main.getLayerManager();
211 while (!lm.getLayers().isEmpty()) {
212 lm.removeLayer(lm.getLayers().get(0));
213 }
214
215 // TODO: Remove global listeners and other global state.
216
217 Main.pref = null;
218 Main.platform = null;
219 // Parts of JOSM uses weak references - destroy them.
220 System.gc();
221 }
222
223 enum APIType {
224 NONE, FAKE, DEV
225 }
226}
Note: See TracBrowser for help on using the repository browser.