1 package org.codehaus.mojo.javascript;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.File;
20 import java.io.FileWriter;
21 import java.io.IOException;
22 import java.io.Writer;
23 import java.net.URL;
24 import java.util.Arrays;
25 import java.util.Collections;
26
27 import org.apache.maven.plugin.MojoExecutionException;
28 import org.apache.maven.plugin.MojoFailureException;
29 import org.apache.maven.surefire.junit.JUnitTestSet;
30 import org.apache.maven.surefire.report.FileReporter;
31 import org.apache.maven.surefire.report.ReportEntry;
32 import org.apache.maven.surefire.report.Reporter;
33 import org.apache.maven.surefire.report.ReporterManager;
34 import org.apache.maven.surefire.testset.AbstractTestSet;
35 import org.codehaus.plexus.util.DirectoryScanner;
36 import org.codehaus.plexus.util.IOUtil;
37 import org.mortbay.util.MultiException;
38
39 import junit.framework.TestSuite;
40 import net.jsunit.Configuration;
41 import net.jsunit.ConfigurationException;
42 import net.jsunit.JsUnitServer;
43
44
45
46
47
48
49
50
51
52 public class JsUnitMojo
53 extends AbstractJavascriptMojo
54 {
55
56
57
58
59
60
61 private boolean skipTests;
62
63
64
65
66
67
68
69 private boolean testFailureIgnore;
70
71
72
73
74
75
76 private File reportsDirectory;
77
78
79
80
81
82
83 private File workDirectory;
84
85
86
87
88
89
90 private File jsunitTestSourceDirectory;
91
92
93
94
95 private File jasmineTestSourceDirectory;
96
97
98
99
100
101
102 private String[] browsers;
103
104 private String[] DEFAULT_BROWSERS = { "firefox" };
105
106
107
108
109
110
111 private int port;
112
113
114
115
116
117
118 private String[] excludes;
119
120
121
122
123
124
125 private String[] includes;
126
127 private static final String[] DEFAULT_INCLUDES = { "**/*.html", "**/*.htm", "**/*.js" };
128
129
130
131
132
133 private String firefoxPath;
134
135
136
137
138 private String iePath;
139
140
141
142
143
144
145 public void execute()
146 throws MojoExecutionException, MojoFailureException
147 {
148 if(jsunitTestSourceDirectory.equals(jasmineTestSourceDirectory) || !jsunitTestSourceDirectory.exists()) {
149 getLog().info("No JsUnit tests, skipping JsUnit tests execution.");
150 return;
151 }
152
153 if (skipTests)
154 {
155 getLog().warn( "Skipping JsUnit tests." );
156 return;
157 }
158
159 String[] tests = getTestsToRun();
160
161 if ( tests == null || tests.length == 0 )
162 {
163 getLog().info( "no jsunit tests to run." );
164 return;
165 }
166
167 unpackJavascriptDependency( "net.jsunit:jsunit-testRunner", workDirectory );
168
169 if ( browsers == null )
170 {
171 browsers = DEFAULT_BROWSERS;
172 }
173
174 for ( int i = 0; i < browsers.length; i++ )
175 {
176 if ( new File( browsers[i] ).exists() )
177 {
178 continue;
179 }
180 if ( "firefox".equalsIgnoreCase( browsers[i] ) )
181 {
182 browsers[i] = firefoxPath;
183 }
184 if ( "iexplorer".equalsIgnoreCase( browsers[i] ) )
185 {
186 browsers[i] = iePath;
187 }
188 }
189
190 JsUnitServer server = new JsUnitServer();
191 try
192 {
193 runJsUnitTests( server, tests );
194 }
195 catch ( Exception e )
196 {
197 throw new MojoExecutionException( "Failed to run JsUnit tests", e );
198 }
199 finally
200 {
201 try
202 {
203 server.stop();
204 }
205 catch ( InterruptedException e )
206 {
207
208 }
209 }
210 }
211
212 private void runJsUnitTests( JsUnitServer server, String[] tests )
213 throws Exception
214 {
215 setupServer( server );
216
217 Reporter reporter = new FileReporter( reportsDirectory, Boolean.FALSE );
218 ReporterManager reportManager = new ReporterManager( Collections.singletonList( reporter ) );
219 ReportEntry report = new ReportEntry( this, "jsunit", "test Starting" );
220 reportManager.testSetStarting( report );
221
222 for ( int i = 0; i < tests.length; i++ )
223 {
224 String test = tests[i];
225 String path = workDirectory.toURI().getPath();
226 String name = test.substring( 0, test.lastIndexOf( '.' ) );
227 if ( test.toLowerCase().endsWith( ".js" ) )
228 {
229 test = buildMinimalHtml( test );
230 }
231 server.setTestURL( new URL( "file://" + path
232 + "testRunner.html?autoRun=true&submitresults=true" + "&resultid=TEST-" + name
233 + "&testPage=" + path.substring( 1 ) + test ) );
234
235 JsUnitTestCase.setSuite( new TestSuite( JsUnitTestCase.class, name ) );
236 AbstractTestSet testSet = new JUnitTestSet( JsUnitTestCase.class );
237
238 testSet.execute( reportManager, getClass().getClassLoader() );
239 }
240
241 report = new ReportEntry( this, "jsunit", "test Completed" );
242 reportManager.testSetCompleted( report );
243 checkFailure( reportManager );
244 }
245
246
247
248
249
250
251 private String buildMinimalHtml( String test )
252 throws IOException
253 {
254 String name = test.substring( 0, test.lastIndexOf( '.' ) );
255 String html = name + ".html";
256 File file = new File( workDirectory, html );
257 file.getParentFile().mkdirs();
258
259 test = test.replace( '\\', '/' );
260 String basedir = "";
261 int i = 0;
262 while ( ( i = test.indexOf( "/" ) ) > 0 )
263 {
264 test = test.substring( i );
265 basedir += "../";
266 }
267 if ( basedir.trim().length() == 0 )
268 {
269 basedir = ".";
270 }
271
272 Writer w = new FileWriter( file );
273 w.write( "<html>\n" );
274 w.write( "<head>\n" );
275 w.write( "<script type='text/javascript' src='" + basedir
276 + "/app/jsUnitCore.js'></script>\n" );
277 w.write( "<script type='text/javascript' src='" + test + "'></script>\n" );
278 w.write( "</head>\n" );
279 w.write( "<body>\n" );
280 w.write( "</body>\n" );
281 w.write( "</html>\n" );
282
283 IOUtil.close( w );
284 return html;
285 }
286
287 private String[] getTestsToRun()
288 {
289 if ( !jsunitTestSourceDirectory.exists() )
290 {
291 return null;
292 }
293 DirectoryScanner scanner = new DirectoryScanner();
294 scanner.setBasedir(jsunitTestSourceDirectory);
295 scanner.setExcludes( excludes );
296 scanner.addDefaultExcludes();
297 if ( includes == null )
298 {
299 includes = DEFAULT_INCLUDES;
300 }
301 scanner.setIncludes( includes );
302 scanner.scan();
303 String[] tests = scanner.getIncludedFiles();
304 return tests;
305 }
306
307 private void checkFailure( ReporterManager reportManager )
308 throws MojoFailureException
309 {
310 if ( reportManager.getNumErrors() + reportManager.getNumFailures() > 0 )
311 {
312 String msg =
313 "There are test failures.\n\nPlease refer to " + reportsDirectory
314 + " for the individual test results.";
315 if ( testFailureIgnore )
316 {
317 getLog().error( msg );
318 }
319 else
320 {
321 throw new MojoFailureException( msg );
322 }
323 }
324 }
325
326 private void setupServer( JsUnitServer server )
327 throws ConfigurationException, MultiException
328 {
329 System.setProperty( Configuration.URL, "http://localhost:" + port + "/jsunit/" );
330 System.setProperty( Configuration.PORT, String.valueOf( port ) );
331 System.setProperty( Configuration.LOGS_DIRECTORY, reportsDirectory.getAbsolutePath() );
332 server.initialize();
333 server.setResourceBase( workDirectory );
334 server.setLocalBrowserFileNames( Arrays.asList( browsers ) );
335 server.start();
336 JsUnitTestCase.setSharedServer( server );
337 }
338 }