De-Wikipedia-ization backported from stable
[mediawiki.git] / testsuite / src / com / piclab / wikitest / WikiTest.java
blob7d01c48bd1d6462c6c596e9ea5a06f3f99374361
2 /*
3 * WikiTest is the base class for all the various
4 * individual tests of the installed wiki, which
5 * will be called by WikiSuite.
6 */
8 package com.piclab.wikitest;
9 import com.meterware.httpunit.*;
10 import org.w3c.dom.*;
11 import java.util.regex.*;
13 public class WikiTest {
15 protected WikiSuite m_suite = null;
16 protected long m_start, m_stop;
17 protected boolean m_verboseflag = false;
19 /* All subclasses of WikiTest should override testName()
20 * to return a useful name and runTest() to perform the actual
21 * tests. runTest() should return true on success. You can
22 * also overrise initTest() if you like; it gets run before
23 * the individual test timer is started.
26 public String testName() { return "Error"; }
28 protected int initTest() throws Exception {
29 return 0;
32 protected int runTest() throws Exception {
33 return 0;
37 * This is the primary entry point:
40 public void run( WikiSuite ws ) {
41 m_suite = ws;
42 run();
45 private void run() {
46 int result = 0;
48 /* assert( m_suite != null ); */
50 java.util.logging.Level ll = null;
51 if ( m_verboseflag ) {
52 ll = WikiSuite.setLoggingLevel( java.util.logging.Level.FINE );
55 try {
56 result = initTest();
57 } catch ( Exception e ) {
58 WikiSuite.error( "Exception (" + e + ") initializing test \"" +
59 testName() + "\"" );
60 e.printStackTrace();
61 result = 1;
63 if ( result != 0 ) {
64 WikiSuite.error( "Test \"" + testName() +
65 "\" failed to initialize with code " + result );
66 return;
68 WikiSuite.info( "Started test \"" + testName() + "\"" );
69 m_start = System.currentTimeMillis();
71 try {
72 result = runTest();
73 } catch (Exception e) {
74 WikiSuite.error( "Exception (" + e + ") running test \"" +
75 testName() + "\"" );
76 e.printStackTrace();
77 result = 2;
79 m_stop = System.currentTimeMillis();
80 double time = (double)(m_stop - m_start) / 1000.0;
82 StringBuffer sb = new StringBuffer(100);
83 sb.append( "Test \"" ).append( testName() ).append( "\" " )
84 .append( (result==0) ? "Succeeded" : "Failed " ).append( " (" )
85 .append( WikiSuite.threeDecimals( time ) ).append( " secs)" );
86 WikiSuite.info( sb.toString() );
88 if ( m_verboseflag ) {
89 WikiSuite.setLoggingLevel( ll );
94 * General utility functions
97 public int fail( int code ) {
98 WikiSuite.error( "Test \"" + testName() + "\" failed with code " + code );
99 return code;
102 public void clearCookies() { m_suite.getConv().clearContents(); }
105 * Encapsulate rules for converting a title to URL form; this
106 * should match the equivalent function in the Wiki code.
109 public static String titleToUrl( String title ) {
110 StringBuffer sb = new StringBuffer( title.length() + 20 );
112 if ( "".equals( title ) ) {
113 title = WikiSuite.getMainPage();
116 for (int i=0; i<title.length(); ++i) {
117 char c = title.charAt(i);
118 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
119 sb.append(c);
120 } else if (c >= '0' && c <= '9') {
121 sb.append(c);
122 } else if (c == '.' || c == '-' || c == '*' || c == ':' || c == '/'
123 || c == '(' || c == ')' || c == '_') {
124 sb.append(c);
125 } else if (c == ' ') {
126 sb.append('_');
127 } else {
128 sb.append('%');
129 String hex = "00" + Integer.toHexString((int)c);
130 sb.append(hex.substring(hex.length() - 2));
133 return sb.toString();
136 public static String viewUrl( String title, String query ) {
137 StringBuffer url = new StringBuffer(200);
138 String t = titleToUrl( title );
140 url.append( WikiSuite.getServer() )
141 .append( WikiSuite.getScript() ).append( "?title=" ).append( t )
142 .append( "&" ).append( query );
143 return url.toString();
146 public static String viewUrl( String title ) {
147 StringBuffer url = new StringBuffer(200);
148 String t = titleToUrl( title );
149 String ap = WikiSuite.getArticlePath();
151 int p = ap.indexOf( "$1" );
152 if ( p >= 0 ) {
153 url.append( ap );
154 url.replace( p, p+2, t );
155 } else {
156 url.append( WikiSuite.getServer() )
157 .append( WikiSuite.getScript() ).append( "?title=" ).append( t );
159 return url.toString();
162 public WebResponse getResponse( String url )
163 throws WikiSuiteFailureException {
164 WebResponse r = null;
165 String msg = null;
167 try {
168 r = m_suite.getConv().getResponse( url );
169 } catch (org.xml.sax.SAXException e) {
170 msg = "Error parsing received page \"" + url + "\"";
171 WikiSuite.warning( msg );
172 } catch (java.net.MalformedURLException e) {
173 msg = "Badly formed URL \"" + url + "\"";
174 WikiSuite.fatal( msg );
175 throw new WikiSuiteFailureException( msg );
176 } catch (java.io.IOException e) {
177 WikiSuite.warning( "I/O Error receiving page \"" + url + "\"" );
179 return r;
182 public WebResponse getResponse( WebRequest req ) {
183 WebResponse r = null;
185 try {
186 r = m_suite.getConv().getResponse( req );
187 } catch (org.xml.sax.SAXException e) {
188 WikiSuite.warning( "Error parsing received page." );
189 } catch (java.io.IOException e) {
190 WikiSuite.warning( "I/O Error receiving page." );
192 return r;
195 public void showResponseTitle( WebResponse wr )
196 throws WikiSuiteFailureException {
197 String t = null;
199 try {
200 t = wr.getTitle();
201 if ( "Error".equals( t ) || "Database error".equals( t ) ) {
202 throw new WikiSuiteFailureException( "Got wiki error page." );
204 WikiSuite.fine( "Viewing \"" + t + "\"" );
205 } catch (org.xml.sax.SAXException e) {
206 WikiSuite.error( "Exception (" + e + ")" );
207 throw new WikiSuiteFailureException( "Couldn't parse title." );
211 public WebResponse viewPage( String title )
212 throws WikiSuiteFailureException {
213 WebResponse wr = getResponse( viewUrl( title ) );
214 showResponseTitle( wr );
215 return wr;
218 public WebResponse viewPage( String title, String query )
219 throws WikiSuiteFailureException {
220 StringBuffer url = new StringBuffer( 200 );
221 String t = titleToUrl( title );
223 url.append( m_suite.getServer() )
224 .append( m_suite.getScript() ).append( "?title=" )
225 .append( t ).append( "&" ).append( query );
227 WebResponse wr = getResponse( url.toString() );
228 showResponseTitle( wr );
229 return wr;
232 public WebResponse searchFor( String target, String query )
233 throws WikiSuiteFailureException {
234 StringBuffer url = new StringBuffer( 200 );
235 String t = null;
237 try {
238 t = java.net.URLEncoder.encode( target, "UTF-8" );
239 } catch ( java.io.UnsupportedEncodingException e ) {
240 throw new WikiSuiteFailureException( e.toString() );
242 url.append( m_suite.getServer() )
243 .append( m_suite.getScript() ).append( "?search=" )
244 .append( t );
245 if ( ! "".equals( query ) ) {
246 url.append( "&" ).append( query );
248 return getResponse( url.toString() );
251 public WebResponse searchFor( String target )
252 throws WikiSuiteFailureException {
253 return searchFor( target, null );
256 public WebResponse editPage( String title )
257 throws WikiSuiteFailureException {
258 return viewPage( title, "action=edit" );
261 public static WebForm getFormByName( WebResponse resp, String name )
262 throws WikiSuiteFailureException {
263 String msg = null;
264 WebForm[] forms = null;
266 try {
267 forms = resp.getForms();
268 } catch ( org.xml.sax.SAXException e ) {
269 msg = "Couldn't find form \"" + name + "\"";
270 WikiSuite.error( msg );
271 return null;
273 for (int i=0; i < forms.length; ++i) {
274 Node formNode = forms[i].getDOMSubtree();
275 NamedNodeMap nnm = formNode.getAttributes();
276 Node nameNode = nnm.getNamedItem( "id" );
278 if (nameNode == null) continue;
279 if (nameNode.getNodeValue().equalsIgnoreCase( name )) {
280 return forms[i];
283 return null;
286 public WebResponse loginAs( String name, String password )
287 throws WikiSuiteFailureException {
288 WebResponse wr = null;
289 WebRequest req = null;
291 wr = viewPage( "Special:Userlogin" );
293 WebForm loginform = getFormByName( wr, "userlogin" );
294 req = loginform.getRequest( "wpLoginattempt" );
295 req.setParameter( "wpName", name );
296 req.setParameter( "wpPassword", password );
297 wr = getResponse( req );
299 WikiSuite.fine( "Logged in as " + name );
300 return wr;
303 public WebResponse logout()
304 throws WikiSuiteFailureException {
305 WebResponse wr = viewPage( "Special:Userlogout" );
306 clearCookies();
307 return wr;
310 public WebResponse deletePage( String title )
311 throws WikiSuiteFailureException {
312 WebResponse wr = null;
314 wr = loginAs( "WikiSysop", m_suite.getSysopPass() );
315 wr = viewPage( title, "action=delete" );
317 String rt = null;
318 try {
319 rt = wr.getTitle();
320 } catch ( org.xml.sax.SAXException e ) {
321 WikiSuite.error( "Could not parse response to delete request." );
322 wr = logout();
323 return null;
326 if ( rt.equals( "Internal error" ) ) {
327 wr = logout();
328 return null;
329 /* Can't delete because it doesn't exist: no problem */
332 WebForm delform = getFormByName( wr, "deleteconfirm" );
333 WebRequest req = delform.getRequest( "wpConfirmB" );
335 req.setParameter( "wpReason", "Deletion for testing" );
336 req.setParameter( "wpConfirm", "1" );
338 WebResponse ret = getResponse( req );
339 WikiSuite.fine( "Deleted \"" + title + "\"" );
341 wr = logout();
342 return ret;
345 public WebResponse replacePage( String page, String text )
346 throws WikiSuiteFailureException {
347 WebResponse wr = editPage( page );
349 WebForm editform = getFormByName( wr, "editform" );
350 WebRequest req = editform.getRequest( "wpSave" );
351 req.setParameter( "wpTextbox1", text );
352 return getResponse( req );
355 public WebResponse addText( String page, String text )
356 throws WikiSuiteFailureException {
357 WebResponse wr = editPage( page );
359 WebForm editform = getFormByName( wr, "editform" );
360 WebRequest req = editform.getRequest( "wpSave" );
361 String old = req.getParameter( "wpTextbox1" );
363 req.setParameter( "wpTextbox1", old + "\n" + text );
364 req.setParameter( "wpSummary", "Wikitest addition to " + page );
366 return getResponse( req );
369 public WebRequest openPrefs() throws WikiSuiteFailureException {
370 WebResponse wr = viewPage( "Special:Preferences" );
371 WebForm pform = getFormByName( wr, "preferences" );
372 return pform.getRequest( "wpSaveprefs" );
375 private static Pattern m_startdiv = null, m_enddiv = null;
377 public String getArticle( WebResponse wr )
378 throws WikiSuiteFailureException {
379 String msg = null;
380 String text = null;
381 Matcher m = null;
383 if ( m_startdiv == null ) {
384 m_startdiv = Pattern.compile( "<div\\s[^>]*id\\s*=\\s*.article[^>]*>",
385 Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
386 m_enddiv = Pattern.compile( "</div[^>]*>",
387 Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
389 try {
390 text = wr.getText();
391 } catch ( java.io.IOException e ) {
392 msg = "Error (" + e + ") parsing page.";
393 WikiSuite.error( msg );
394 throw new WikiSuiteFailureException( msg );
396 m = m_startdiv.matcher( text );
397 if (! m.find()) {
398 throw new WikiSuiteFailureException( "Can't find article div start." );
401 text = text.substring( m.end() );
402 m = m_enddiv.matcher( text );
403 if (! m.find()) {
404 throw new WikiSuiteFailureException( "Can't find article div end." );
406 text = text.substring( 0, m.start() );
407 return text;
410 public int checkGoodPatterns( String text, String[] pats ) {
411 Pattern p = null;
412 Matcher m = null;
414 for ( int i = 0; i < pats.length; ++i ) {
415 p = Pattern.compile( pats[i], Pattern.CASE_INSENSITIVE );
416 m = p.matcher( text );
418 if ( ! m.find() ) { return 1 + i; }
420 return 0;
423 public int checkBadPatterns( String text, String[] badpats ) {
424 Pattern p = null;
425 Matcher m = null;
427 for ( int i = 0; i < badpats.length; ++i ) {
428 p = Pattern.compile( badpats[i], Pattern.CASE_INSENSITIVE );
429 m = p.matcher( text );
431 if ( m.find() ) { return 1 + i; }
433 return 0;
437 * The main method of a subclass should be able to just create
438 * an instance of itself and call runSingle() to perform a
439 * standalone test, and we'll handle the commandline and
440 * setting up a suite object, etc. They are of course welcome
441 * to set up a more complex main if they want.
444 public void runSingle( String[] params ) {
446 * Do command line. For now, just verbose flag.
448 for ( int i = 0; i < params.length; ++i ) {
449 if ( "-v".equals( params[i].substring( 0, 2 ) ) ) {
450 m_verboseflag = true;
453 run( new WikiSuite() );
456 public static void main( String params ) {
457 System.out.println( "WikiTest is not a runnable class." );