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

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

fix #13037 - Small fixes for unit tests (patch by michael2402) - gsoc-core

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