001package org.apache.maven.doxia.module.apt; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.IOException; 023import java.io.Reader; 024import java.io.StringWriter; 025import java.io.Writer; 026import java.util.Iterator; 027 028import org.apache.maven.doxia.parser.AbstractParserTest; 029import org.apache.maven.doxia.parser.Parser; 030import org.apache.maven.doxia.parser.ParseException; 031 032import org.apache.maven.doxia.sink.Sink; 033import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; 034import org.apache.maven.doxia.sink.impl.SinkEventElement; 035import org.apache.maven.doxia.sink.impl.SinkEventTestingSink; 036import org.codehaus.plexus.util.IOUtil; 037 038/** 039 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a> 040 * @version $Id$ 041 */ 042public class AptParserTest 043 extends AbstractParserTest 044{ 045 046 private AptParser parser; 047 048 @Override 049 protected void setUp() 050 throws Exception 051 { 052 super.setUp(); 053 054 parser = (AptParser) lookup( Parser.ROLE, "apt" ); 055 } 056 057 /** {@inheritDoc} */ 058 protected Parser createParser() 059 { 060 return parser; 061 } 062 063 protected String parseFileToAptSink( String file ) 064 throws ParseException 065 { 066 StringWriter output = null; 067 Reader reader = null; 068 try 069 { 070 output = new StringWriter(); 071 reader = getTestReader( file ); 072 073 Sink sink = new AptSink( output ); 074 createParser().parse( reader, sink ); 075 } 076 finally 077 { 078 IOUtil.close( output ); 079 IOUtil.close( reader ); 080 } 081 082 return output.toString(); 083 } 084 085 /** @throws Exception */ 086 public void testLineBreak() 087 throws Exception 088 { 089 String linebreak = parseFileToAptSink( "test/linebreak" ); 090 091 assertTrue( linebreak.indexOf( "Line\\" + EOL + "break." ) != -1 ); 092 } 093 094 /** @throws Exception */ 095 public void testSnippetMacro() 096 throws Exception 097 { 098 String macro = parseFileToAptSink( "test/macro" ); 099 100 assertTrue( macro.indexOf( "<modelVersion\\>4.0.0\\</modelVersion\\>" ) != -1 ); 101 } 102 103 /** @throws Exception */ 104 public void testCommentsBeforeTitle() 105 throws Exception 106 { 107 String comments = parseFileToAptSink( "test/comments" ); 108 109 assertEquals( 0, comments.indexOf( "~~ comments before title" + EOL + "~~ like a license header, for example" 110 + EOL + " -----" + EOL + " Test DOXIA-379" ) ); 111 } 112 113 /** @throws Exception */ 114 public void testSnippet() 115 throws Exception 116 { 117 // DOXIA-259 118 119 Reader reader = null; 120 SinkEventTestingSink sink = new SinkEventTestingSink(); 121 122 try 123 { 124 reader = getTestReader( "test/snippet" ); 125 126 createParser().parse( reader, sink ); 127 } 128 finally 129 { 130 IOUtil.close( reader ); 131 } 132 133 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 134 135 assertEquals( it, "head", "head_", "body", "list", "listItem", "text", "verbatim", "text", "verbatim_", 136 "paragraph", "text", "paragraph_", "listItem_", "listItem", "text", "verbatim", "text", 137 "verbatim_", "paragraph", "text", "paragraph_", "listItem_", "list_", "body_" ); 138 } 139 140 141 /** @throws Exception */ 142 public void testSnippetTrailingSpace() 143 throws Exception 144 { 145 // DOXIA-425 146 String text = "%{snippet|id=myid|file=pom.xml} " + EOL; 147 148 SinkEventTestingSink sink = new SinkEventTestingSink(); 149 150 parser.parse( text, sink ); 151 152 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 153 154 assertEquals( it, "head", "head_", "body", "verbatim", "text", "verbatim_", "body_" ); 155 } 156 157 /** @throws Exception */ 158 public void testTocMacro() 159 throws Exception 160 { 161 String toc = parseFileToAptSink( "test/toc" ); 162 163 // No section, only subsection 1 and 2 164 assertTrue( toc.indexOf( "* {{{SubSection_1.1}SubSection 1.1}}" ) != -1 ); 165 assertTrue( toc.indexOf( "* {{{SubSection_1.1.2.1.1}SubSection 1.1.2.1.1}}" ) == -1 ); 166 } 167 168 /** 169 * Parses the test document test.apt and re-emits 170 * it into parser/test.apt. 171 * 172 * @throws java.io.IOException if the test file cannot be read. 173 * @throws org.apache.maven.doxia.parser.ParseException if the test file cannot be parsed. 174 */ 175 public void testTestDocument() 176 throws IOException, ParseException 177 { 178 Writer writer = null; 179 Reader reader = null; 180 try 181 { 182 writer = getTestWriter( "test" ); 183 reader = getTestReader( "test" ); 184 185 Sink sink = new AptSink( writer ); 186 187 createParser().parse( reader, sink ); 188 } 189 finally 190 { 191 IOUtil.close( writer ); 192 IOUtil.close( reader ); 193 } 194 } 195 196 /** @throws Exception */ 197 public void testBoxedVerbatim() 198 throws Exception 199 { 200 String text = "+--" + EOL + "boxed verbatim" + EOL + "+--" + EOL 201 + "---" + EOL + "un-boxed verbatim" + EOL + "---" + EOL; 202 203 SinkEventTestingSink sink = new SinkEventTestingSink(); 204 205 parser.parse( text, sink ); 206 207 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 208 209 assertStartsWith( it, "head", "head_", "body" ); 210 assertEquals( it.next(), "verbatim", SinkEventAttributeSet.BOXED ); 211 assertStartsWith( it, "text", "verbatim_" ); 212 213 assertEquals( it.next(), "verbatim", new Object[] { null } ); 214 assertEquals( it, "text", "verbatim_", "body_" ); 215 } 216 217 /** @throws Exception */ 218 public void testMultiLinesInTableCells() 219 throws Exception 220 { 221 String text = "*----------*--------------+----------------:" + EOL + 222 " cell 1, | cell 1,2 | cell 1,3" + EOL + 223 " 1 | | " + EOL + 224 "*----------*--------------+----------------:" + EOL + 225 " cell 2,1 | cell 2, | cell 2,3" + EOL + 226 " | 2 |" + EOL + 227 "*----------*--------------+----------------:" + EOL + 228 " cell 3,1 | cell 3,2 | cell 3," + EOL + 229 " | | 3" + EOL + 230 "*----------*--------------+----------------:" + EOL; 231 232 SinkEventTestingSink sink = new SinkEventTestingSink(); 233 234 parser.parse( text, sink ); 235 236 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 237 238 assertStartsWith( it, "head", "head_", "body", "table", "tableRows", "tableRow", "tableCell" ); 239 assertEquals( it.next(), "text", "cell 1, 1" ); 240 241 assertStartsWith( it, "tableCell_", "tableCell" ); 242 assertEquals( it.next(), "text", "cell 1,2" ); 243 244 assertStartsWith( it, "tableCell_", "tableCell" ); 245 assertEquals( it.next(), "text", "cell 1,3" ); 246 247 assertStartsWith( it, "tableCell_", "tableRow_", "tableRow", "tableCell" ); 248 assertEquals( it.next(), "text", "cell 2,1" ); 249 250 assertStartsWith( it, "tableCell_", "tableCell" ); 251 assertEquals( it.next(), "text", "cell 2, 2" ); 252 253 assertStartsWith( it, "tableCell_", "tableCell" ); 254 assertEquals( it.next(), "text", "cell 2,3" ); 255 256 assertStartsWith( it, "tableCell_", "tableRow_", "tableRow", "tableCell" ); 257 assertEquals( it.next(), "text", "cell 3,1" ); 258 259 assertStartsWith( it, "tableCell_", "tableCell" ); 260 assertEquals( it.next(), "text", "cell 3,2" ); 261 262 assertStartsWith( it, "tableCell_", "tableCell" ); 263 assertEquals( it.next(), "text", "cell 3, 3" ); 264 265 assertEquals( it, "tableCell_", "tableRow_", "tableRows_", "table_", "body_" ); 266 } 267 268 /** @throws Exception */ 269 public void testLineBreakInTableCells() 270 throws Exception 271 { 272 String text = "*----------*--------------+----------------:" + EOL + 273 " cell 1,\\ | cell 1,2 | cell 1,3" + EOL + 274 " 1 | | " + EOL + 275 "*----------*--------------+----------------:" + EOL + 276 " cell 2,1 | cell 2,\\ | cell 2,3" + EOL + 277 " | 2 |" + EOL + 278 "*----------*--------------+----------------:" + EOL + 279 " cell 3,1 | cell 3,2 | cell 3,\\" + EOL + 280 " | | 3" + EOL + 281 "*----------*--------------+----------------:" + EOL; 282 283 SinkEventTestingSink sink = new SinkEventTestingSink(); 284 285 parser.parse( text, sink ); 286 287 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 288 289 assertStartsWith( it, "head", "head_", "body", "table", "tableRows", "tableRow", "tableCell" ); 290 assertEquals( it.next(), "text", "cell 1,\u00A0" ); 291 292 assertEquals( it.next().getName(), "lineBreak" ); 293 assertEquals( it.next(), "text", "1" ); 294 295 assertStartsWith( it, "tableCell_", "tableCell" ); 296 assertEquals( it.next(), "text", "cell 1,2" ); 297 298 assertStartsWith( it, "tableCell_", "tableCell" ); 299 assertEquals( it.next(), "text", "cell 1,3" ); 300 301 assertStartsWith( it, "tableCell_", "tableRow_", "tableRow", "tableCell" ); 302 assertEquals( it.next(), "text", "cell 2,1" ); 303 304 assertStartsWith( it, "tableCell_", "tableCell" ); 305 assertEquals( it.next(), "text", "cell 2,\u00A0" ); 306 307 assertEquals( it.next().getName(), "lineBreak" ); 308 assertEquals( it.next(), "text", "2" ); 309 310 assertStartsWith( it, "tableCell_", "tableCell" ); 311 assertEquals( it.next(), "text", "cell 2,3" ); 312 313 assertStartsWith( it, "tableCell_", "tableRow_", "tableRow", "tableCell" ); 314 assertEquals( it.next(), "text", "cell 3,1" ); 315 316 assertStartsWith( it, "tableCell_", "tableCell" ); 317 assertEquals( it.next(), "text", "cell 3,2" ); 318 319 assertStartsWith( it, "tableCell_", "tableCell" ); 320 assertEquals( it.next(), "text", "cell 3,\u00A0" ); 321 322 assertEquals( it.next().getName(), "lineBreak" ); 323 assertEquals( it.next(), "text", "3" ); 324 325 assertEquals( it, "tableCell_", "tableRow_", "tableRows_", "table_", "body_" ); 326 } 327 328 /** @throws Exception */ 329 public void testDOXIA38() 330 throws Exception 331 { 332 String text = 333 "*----------*--------------*---------------*" + EOL + 334 "| Centered | Centered | Centered |" + EOL + 335 "*----------*--------------+---------------:" + EOL + 336 "| Centered | Left-aligned | Right-aligned |" + EOL + 337 "*----------*--------------+---------------:"; 338 339 SinkEventTestingSink sink = new SinkEventTestingSink(); 340 341 parser.parse( text, sink ); 342 343 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 344 345 assertStartsWith( it, "head", "head_", "body", "table", "tableRows", "tableRow" ); 346 assertAttributeEquals( it.next(), "tableCell", SinkEventAttributeSet.ALIGN, "center" ); 347 assertEquals( it.next(), "text", "Centered" ); 348 assertEquals( it.next().getName(), "tableCell_" ); 349 350 assertAttributeEquals( it.next(), "tableCell", SinkEventAttributeSet.ALIGN, "center" ); 351 assertEquals( it.next(), "text", "Centered" ); 352 assertEquals( it.next().getName(), "tableCell_" ); 353 354 assertAttributeEquals( it.next(), "tableCell", SinkEventAttributeSet.ALIGN, "center" ); 355 assertEquals( it.next(), "text", "Centered" ); 356 assertStartsWith( it, "tableCell_", "tableRow_", "tableRow" ); 357 358 assertAttributeEquals( it.next(), "tableCell", SinkEventAttributeSet.ALIGN, "center" ); 359 assertEquals( it.next(), "text", "Centered" ); 360 assertEquals( it.next().getName(), "tableCell_" ); 361 362 assertAttributeEquals( it.next(), "tableCell", SinkEventAttributeSet.ALIGN, "left" ); 363 assertEquals( it.next(), "text", "Left-aligned" ); 364 assertEquals( it.next().getName(), "tableCell_" ); 365 366 assertAttributeEquals( it.next(), "tableCell", SinkEventAttributeSet.ALIGN, "right" ); 367 assertEquals( it.next(), "text", "Right-aligned" ); 368 assertEquals( it, "tableCell_", "tableRow_", "tableRows_", "table_", "body_" ); 369 } 370 371 /** @throws Exception */ 372 public void testSpecialCharactersInTables() 373 throws Exception 374 { 375 // DOXIA-323, DOXIA-433 376 String text = 377 " \\~ \\= \\- \\+ \\* \\[ \\] \\< \\> \\{ \\} \\\\ \\u2713" + EOL 378 + EOL 379 + "*--------------------------------------------------+---------------+" + EOL 380 + "| \\~ \\= \\- \\+ \\* \\[ \\] \\< \\> \\{ \\} \\\\ \\u2713 | special chars |" + EOL 381 + "*--------------------------------------------------+---------------+"; 382 383 SinkEventTestingSink sink = new SinkEventTestingSink(); 384 parser.parse( text, sink ); 385 386 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 387 388 assertStartsWith( it, "head", "head_", "body", "paragraph" ); 389 assertEquals( it.next(), "text", "~ = - + * [ ] < > { } \\ \u2713" ); 390 391 assertStartsWith( it, "paragraph_", "table", "tableRows", "tableRow", "tableCell" ); 392 assertEquals( it.next(), "text", "~ = - + * [ ] < > { } \\ \u2713" ); 393 394 assertEquals( it, "tableCell_", "tableCell", "text", "tableCell_", "tableRow_", "tableRows_", "table_", "body_" ); 395 } 396 397 /** @throws Exception */ 398 public void testSpacesAndBracketsInAnchors() 399 throws Exception 400 { 401 final String text = " {Anchor with spaces (and brackets)}" + EOL 402 + " Link to {{Anchor with spaces (and brackets)}}" + EOL 403 + " {{{http://fake.api#method(with, args)}method(with, args)}}" + EOL; 404 405 final SinkEventTestingSink sink = new SinkEventTestingSink(); 406 407 parser.parse( text, sink ); 408 409 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 410 411 assertStartsWith( it, "head", "head_", "body", "paragraph" ); 412 assertEquals( it.next(), "anchor", "Anchor_with_spaces_and_brackets" ); 413 414 assertEquals( it.next(), "text", "Anchor with spaces (and brackets)" ); 415 416 assertStartsWith( it, "anchor_", "text" ); 417 assertEquals( it.next(), "link", "#Anchor_with_spaces_and_brackets" ); 418 419 assertEquals( it.next(), "text", "Anchor with spaces (and brackets)" ); 420 421 assertStartsWith( it, "link_", "text" ); 422 assertEquals( it.next(), "link", "http://fake.api#method(with, args)" ); 423 424 assertEquals( it.next(), "text", "method(with, args)" ); 425 426 assertEquals( it, "link_", "paragraph_", "body_" ); 427 } 428 429 /** @throws Exception */ 430 public void testSectionTitleAnchors() 431 throws Exception 432 { 433 // DOXIA-420 434 String text = "Enhancements to the APT format" + EOL + EOL 435 + "{Title with anchor}" + EOL; 436 437 SinkEventTestingSink sink = new SinkEventTestingSink(); 438 439 parser.parse( text, sink ); 440 441 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 442 443 assertEquals( it, "head", "head_", "body", "section1", "sectionTitle1", "text", "sectionTitle1_", "section1_", 444 "section1", "sectionTitle1", "anchor", "text", "anchor_", "sectionTitle1_", "section1_", "body_" ); 445 } 446 447 /** 448 * @throws Exception 449 */ 450 public void testTableHeaders() throws Exception 451 { 452 // DOXIA-404 453 String text = "*-----------+-----------+" + EOL + 454 "|| Header 1 || Header 2 |" + EOL + 455 "*-----------+-----------+" + EOL + 456 " Cell 1 | Cell 2 |" + EOL + 457 "*-----------+-----------+" + EOL + 458 " Cell 3 | Cell 4 |" + EOL + 459 "*-----------+-----------+" + EOL; 460 461 SinkEventTestingSink sink = new SinkEventTestingSink(); 462 463 parser.parse( text, sink ); 464 465 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 466 467 assertStartsWith( it, "head", "head_", "body", "table", "tableRows" ); 468 assertStartsWith( it, "tableRow", "tableHeaderCell", "text", "tableHeaderCell_", "tableHeaderCell", "text", 469 "tableHeaderCell_", "tableRow_" ); 470 assertStartsWith( it, "tableRow", "tableCell", "text", "tableCell_", "tableCell", "text", "tableCell_", 471 "tableRow_" ); 472 assertStartsWith( it, "tableRow", "tableCell", "text", "tableCell_", "tableCell", "text", "tableCell_", 473 "tableRow_" ); 474 assertEquals( it, "tableRows_", "table_", "body_" ); 475 } 476 477 public void testEscapedPipeInTableCell() throws Exception 478 { 479 // DOXIA-479 480 String text="*---+---+" + EOL + 481 "| cell \\| pipe | next cell " + EOL + 482 "*---+---+" + EOL; 483 484 SinkEventTestingSink sink = new SinkEventTestingSink(); 485 486 parser.parse( text, sink ); 487 488 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 489 assertStartsWith( it, "head", "head_", "body", "table", "tableRows", "tableRow", "tableCell" ); 490 assertEquals( it.next(), "text", "cell | pipe" ); 491 assertStartsWith( it, "tableCell_", "tableCell" ); 492 assertEquals( it.next(), "text", "next cell" ); 493 assertEquals( it, "tableCell_", "tableRow_", "tableRows_", "table_", "body_" ); 494 } 495 496 public void testLiteralAnchor() 497 throws Exception 498 { 499 // DOXIA-397 500 String text = 501 "{{{../apidocs/groovyx/net/http/ParserRegistry.html##parseText(org.apache.http.HttpResponse)}ParserRegistry}}"; 502 503 SinkEventTestingSink sink = new SinkEventTestingSink(); 504 505 parser.parse( text, sink ); 506 507 Iterator<SinkEventElement> it = sink.getEventList().iterator(); 508 assertStartsWith( it, "head", "head_", "body", "section1", "sectionTitle1" ); 509 assertEquals( it.next(), "link", 510 "../apidocs/groovyx/net/http/ParserRegistry.html#parseText(org.apache.http.HttpResponse)" ); 511 assertEquals( it.next(), "text", "ParserRegistry" ); 512 assertEquals( it, "link_", "sectionTitle1_", "section1_", "body_" ); 513 } 514 515 /** {@inheritDoc} */ 516 protected String outputExtension() 517 { 518 return "apt"; 519 } 520}