1 package org.apache.maven.doxia.module.xdoc;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileFilter;
24 import java.io.FileReader;
25 import java.io.Reader;
26 import java.io.Writer;
27
28 import java.util.Iterator;
29 import java.util.regex.Pattern;
30
31 import org.apache.maven.doxia.parser.AbstractParserTest;
32 import org.apache.maven.doxia.parser.ParseException;
33 import org.apache.maven.doxia.parser.Parser;
34 import org.apache.maven.doxia.sink.Sink;
35 import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
36 import org.apache.maven.doxia.sink.impl.SinkEventElement;
37 import org.apache.maven.doxia.sink.impl.SinkEventTestingSink;
38 import org.codehaus.plexus.util.IOUtil;
39
40
41
42
43
44
45
46 public class XdocParserTest
47 extends AbstractParserTest
48 {
49 private XdocParser parser;
50
51 @Override
52 protected void setUp()
53 throws Exception
54 {
55 super.setUp();
56
57 parser = (XdocParser) lookup( Parser.ROLE, "xdoc" );
58
59
60
61 String tmpDir = System.getProperty( "java.io.tmpdir" );
62
63 final Pattern xsdFilePattern = Pattern.compile( "(xdoc\\-.*|xml)\\.xsd" );
64
65 File[] xsdFiles = new File( tmpDir ).listFiles( new FileFilter()
66 {
67
68 public boolean accept( File pathname )
69 {
70 return pathname.isFile() && xsdFilePattern.matcher( pathname.getName() ).matches();
71 }
72 } );
73
74 for ( File xsdFile : xsdFiles )
75 {
76 xsdFile.delete();
77 }
78
79
80
81
82
83
84
85
86 }
87
88
89 protected String outputExtension()
90 {
91 return "xml";
92 }
93
94
95 protected Parser createParser()
96 {
97 return parser;
98 }
99
100
101 public void testSnippetMacro()
102 throws Exception
103 {
104 Writer output = null;
105 Reader reader = null;
106
107 try
108 {
109 output = getTestWriter( "macro" );
110 reader = getTestReader( "macro" );
111
112 Sink sink = new XdocSink( output );
113 createParser().parse( reader, sink );
114 sink.close();
115 }
116 finally
117 {
118 IOUtil.close( output );
119 IOUtil.close( reader );
120 }
121
122 File f = getTestFile( getBasedir(), outputBaseDir() + getOutputDir() + "macro.xml" );
123 assertTrue( "The file " + f.getAbsolutePath() + " was not created", f.exists() );
124
125 String content;
126 try
127 {
128 reader = new FileReader( f );
129 content = IOUtil.toString( reader );
130 }
131 finally
132 {
133 IOUtil.close( reader );
134 }
135
136 assertTrue( content.indexOf( "<modelVersion>4.0.0</modelVersion>" ) != -1 );
137 }
138
139
140 public void testTocMacro()
141 throws Exception
142 {
143 Writer output = null;
144 Reader reader = null;
145
146 try
147 {
148 output = getTestWriter( "toc" );
149 reader = getTestReader( "toc" );
150
151 Sink sink = new XdocSink( output );
152 createParser().parse( reader, sink );
153 sink.close();
154 }
155 finally
156 {
157 IOUtil.close( output );
158 IOUtil.close( reader );
159 }
160
161 File f = getTestFile( getBasedir(), outputBaseDir() + getOutputDir() + "toc.xml" );
162 assertTrue( "The file " + f.getAbsolutePath() + " was not created", f.exists() );
163
164 String content;
165 try
166 {
167 reader = new FileReader( f );
168 content = IOUtil.toString( reader );
169 }
170 finally
171 {
172 IOUtil.close( reader );
173 }
174
175
176 assertTrue( content.indexOf( "<a href=\"#Section_11\">Section 11</a>" ) != -1 );
177 assertTrue( content.indexOf( "<a href=\"#Section_1211\">Section 1211</a>" ) == -1 );
178 }
179
180 private Iterator<SinkEventElement> parseText( String text )
181 throws ParseException
182 {
183 SinkEventTestingSink sink = new SinkEventTestingSink();
184
185 parser.parse( text, sink );
186
187 return sink.getEventList().iterator();
188 }
189
190
191 public void testHeadEventsList()
192 throws Exception
193 {
194 String text = "<document>"
195 + "<properties><title>title</title>"
196 + "<!-- Test comment: DOXIA-312 -->"
197 + "<author email=\"a@b.c\">John Doe</author></properties>"
198 + "<head>"
199 + "<meta name=\"security\" content=\"low\"/>"
200 + "<base href=\"http://maven.apache.org/\"/>"
201 + "</head>"
202 + "<body></body></document>";
203
204 Iterator<SinkEventElement> it = parseText( text );
205
206 assertStartsWith( it, "head", "title", "text", "title_", "comment", "author", "text", "author_" );
207
208 SinkEventElement unknown = it.next();
209 assertEquals( "unknown", unknown.getName() );
210 assertEquals( "meta", unknown.getArgs()[0] );
211
212 unknown = it.next();
213 assertEquals( "unknown", unknown.getName() );
214 assertEquals( "base", unknown.getArgs()[0] );
215
216 assertEquals( it, "head_", "body", "body_" );
217
218
219 text = "<document>"
220 + "<properties><title>properties title</title></properties>"
221 + "<head><title>head title</title></head>"
222 + "<body></body></document>";
223
224 it = parseText( text );
225
226 assertStartsWith( it, "head", "title" );
227
228 SinkEventElement title = it.next();
229 assertEquals( "text", title.getName() );
230 assertEquals( "properties title", title.getArgs()[0] );
231
232 assertEquals( it, "title_", "head_", "body", "body_" );
233 }
234
235
236 public void testDocumentBodyEventsList()
237 throws Exception
238 {
239 String text = "<document><body></body></document>";
240
241 Iterator<SinkEventElement> it = parseText( text );
242
243 assertEquals( it, "body", "body_" );
244 }
245
246
247 public void testSectionEventsList()
248 throws Exception
249 {
250 String text = "<section name=\"sec 1\"><subsection name=\"sub 1\"></subsection></section>";
251
252 Iterator<SinkEventElement> it = parseText( text );
253
254 assertEquals( it, "section1", "sectionTitle1", "text", "sectionTitle1_", "section2", "sectionTitle2", "text",
255 "sectionTitle2_", "section2_", "section1_" );
256 }
257
258
259 public void testSectionAttributes()
260 throws Exception
261 {
262
263 String text = "<section name=\"section name\" class=\"foo\" id=\"bar\"></section>";
264
265 Iterator<SinkEventElement> it = parseText( text );
266
267 assertStartsWith( it, "anchor", "anchor_" );
268
269 SinkEventElement next = it.next();
270 assertEquals( "section1", next.getName() );
271 SinkEventAttributeSet set = (SinkEventAttributeSet) next.getArgs()[0];
272 assertEquals( 3, set.getAttributeCount() );
273 assertTrue( set.containsAttribute( "name", "section name" ) );
274 assertTrue( set.containsAttribute( "class", "foo" ) );
275 assertTrue( set.containsAttribute( "id", "bar" ) );
276
277 next = it.next();
278 assertEquals( "sectionTitle1", next.getName() );
279 assertNull( (SinkEventAttributeSet) next.getArgs()[0] );
280
281 assertEquals( it, "text", "sectionTitle1_", "section1_" );
282 }
283
284
285 public void testNestedSectionsEventsList()
286 throws Exception
287 {
288
289 String text = "<section name=\"section\"><h6>h6</h6><subsection name=\"subsection\"></subsection></section>";
290
291 Iterator<SinkEventElement> it = parseText( text );
292
293 assertEquals( it, "section1", "sectionTitle1", "text", "sectionTitle1_", "section2", "section3", "section4",
294 "section5", "sectionTitle5", "text", "sectionTitle5_", "section5_", "section4_", "section3_",
295 "section2_", "section2", "sectionTitle2", "text", "sectionTitle2_", "section2_", "section1_" );
296 }
297
298
299 public void testSourceEventsList()
300 throws Exception
301 {
302 String text = "<source><a href=\"what.html\">what</a></source>";
303
304 Iterator<SinkEventElement> it = parseText( text );
305
306 assertEquals( it, "verbatim", "link", "text", "link_", "verbatim_" );
307
308 text = "<source><![CDATA[<a href=\"what.html\">what</a>]]></source>";
309 it = parseText( text );
310
311 assertEquals( it, "verbatim", "text", "verbatim_" );
312
313 text = "<source><![CDATA[<source>what</source>]]></source>";
314 it = parseText( text );
315
316 assertEquals( it, "verbatim", "text", "verbatim_" );
317 }
318
319
320 public void testSourceContainingDTD()
321 throws Exception
322 {
323 String text = "<source><![CDATA[" +
324 "<!DOCTYPE web-app PUBLIC " +
325 "\"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN\"" +
326 " \"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd\">" +
327 "]]></source>";
328
329 Iterator<SinkEventElement> it = parseText( text );
330
331 assertEquals( it, "verbatim", "text", "verbatim_" );
332 }
333
334
335 public void testPreEOL()
336 throws Exception
337 {
338
339 String text = "<source><a href=\"what.html\">what</a>" + EOL
340 + "<a href=\"what.html\">what</a></source>";
341
342 Iterator<SinkEventElement> it = parseText( text );
343
344 assertEquals( it, "verbatim", "link", "text", "link_", "text", "link", "text", "link_", "verbatim_" );
345 }
346
347
348
349
350
351
352 public void testSectionIdAnchor()
353 throws Exception
354 {
355 String text = "<section name=\"test\" id=\"test-id\">This is a test."
356 + "<subsection name=\"sub-test\" id=\"sub-id\">Sub-section</subsection></section>";
357
358 Iterator<SinkEventElement> it = parseText( text );
359
360 assertEquals( it.next(), "anchor", "test-id" );
361
362 assertStartsWith( it, "anchor_", "section1", "sectionTitle1", "text", "sectionTitle1_", "text" );
363
364 assertEquals( it.next(), "anchor", "sub-id" );
365
366 assertEquals( it, "anchor_", "section2", "sectionTitle2", "text", "sectionTitle2_", "text", "section2_",
367 "section1_" );
368 }
369
370
371
372
373
374
375 public void testJavaScript()
376 throws Exception
377 {
378 String text = "<script type=\"text/javascript\"><![CDATA[alert(\"Hello!\");]]></script>";
379
380 Iterator<SinkEventElement> it = parseText( text );
381 assertEquals( it, "unknown", "unknown", "unknown" );
382 }
383
384
385
386
387
388
389 public void testUnknown()
390 throws Exception
391 {
392 String text = "<applet><param name=\"name\" value=\"value\"/><unknown/></applet>";
393
394 Iterator<SinkEventElement> it = parseText( text );
395 assertEquals( it, "unknown", "unknown", "unknown", "unknown", "unknown" );
396 }
397
398
399
400
401 public void testMacroExceptions()
402 {
403 SinkEventTestingSink sink = new SinkEventTestingSink();
404 assertParseException( sink, "<macro/>" );
405 assertParseException( sink, "<macro name=\"\"/>" );
406 assertParseException( sink, "<macro name=\"name\"><param name=\"\" value=\"value\"/></macro>" );
407 assertParseException( sink, "<macro name=\"name\"><param name=\"name\" value=\"\"/></macro>" );
408 assertParseException( sink, "<macro name=\"name\"><param value=\"value\"/></macro>" );
409 assertParseException( sink, "<macro name=\"name\"><param name=\"name\"/></macro>" );
410 assertParseException( sink, "<macro name=\"unknown\"></macro>" );
411 }
412
413 private void assertParseException( Sink sink, String text )
414 {
415 try
416 {
417 parser.parse( text, sink );
418
419 fail( "Should not be parseable: '" + text + "'" );
420 }
421 catch ( ParseException ex )
422 {
423 assertNotNull( ex );
424 }
425 }
426
427
428 public void testEntities()
429 throws Exception
430 {
431 final String text = "<!DOCTYPE test [<!ENTITY foo \"ř\"><!ENTITY tritPos \"𝟭\">]>"
432 + "<section name=\"&&foo;&tritPos;\"><p>&&foo;&tritPos;</p></section>";
433
434 SinkEventTestingSink sink = new SinkEventTestingSink();
435
436 parser.setValidate( false );
437 parser.parse( text, sink );
438
439 Iterator<SinkEventElement> it = sink.getEventList().iterator();
440
441 assertStartsWith( it, "section1", "sectionTitle1" );
442
443 assertEquals( it.next(), "text", "&\u0159\uD835\uDFED" );
444
445 assertStartsWith( it, "sectionTitle1_", "paragraph" );
446
447 assertEquals( it.next(), "text", "&" );
448
449 assertEquals( it.next(), "text", "\u0159" );
450
451 assertEquals( it.next(), "text", "\uD835\uDFED" );
452
453 assertEquals( it, "paragraph_", "section1_" );
454 }
455
456 public void testStyleWithCData() throws Exception
457 {
458
459 final String text = "<style type=\"text/css\">\n" +
460 "<![CDATA[\n" +
461 "h2 {\n" +
462 "font-size: 50px;\n" +
463 "}\n" +
464 "]]>\n" +
465 "</style>";
466
467 SinkEventTestingSink sink = new SinkEventTestingSink();
468
469 parser.setValidate( false );
470 parser.parse( text, sink );
471
472 Iterator<SinkEventElement> it = sink.getEventList().iterator();
473 SinkEventElement styleElm = it.next();
474 assertEquals( "unknown", styleElm.getName() );
475 assertEquals( "style", styleElm.getArgs()[0] );
476 SinkEventElement cdataElm = it.next();
477 assertEquals( "unknown", cdataElm.getName() );
478 assertEquals( "CDATA", cdataElm.getArgs()[0] );
479 SinkEventElement styleElm_ = it.next();
480 assertEquals( "unknown", styleElm_.getName() );
481 assertEquals( "style", styleElm_.getArgs()[0] );
482 assertFalse( it.hasNext() );
483 }
484 }