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

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

fix NPE in JOSMTestRules + ignore findbugs warning

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