blob: d051e91491aac7da461d5da6408d65a64ab2e71f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2016 Tasktop Technologies
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* David Green - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.wikitext.confluence.internal;
import static org.junit.Assert.assertEquals;
import java.io.StringWriter;
import org.eclipse.mylyn.wikitext.parser.Attributes;
import org.eclipse.mylyn.wikitext.parser.DocumentBuilder;
import org.eclipse.mylyn.wikitext.parser.DocumentBuilder.BlockType;
import org.eclipse.mylyn.wikitext.parser.DocumentBuilder.SpanType;
import org.eclipse.mylyn.wikitext.parser.ImageAttributes;
import org.eclipse.mylyn.wikitext.parser.LinkAttributes;
import org.junit.Test;
/**
* @author David Green
* @see ConfluenceDocumentBuilder
*/
public class ConfluenceDocumentBuilderTest {
private final StringWriter out = new StringWriter();
private final DocumentBuilder builder = new ConfluenceDocumentBuilder(out);
@Test
public void paragraph() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text\n\nmore text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("text more text\n\n", markup);
}
@Test
public void paragraphWithCssClass() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes(null, "test", null, null));
builder.characters("text\n\nmore text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("text more text\n\n", markup);
}
@Test
public void paragraphWithCssStyle() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes(null, null, "x-test: foo;", null));
builder.characters("text\n\nmore text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("text more text\n\n", markup);
}
@Test
public void paragraphWithId() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes("123", null, null, null));
builder.characters("text\n\nmore text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("text more text\n\n", markup);
}
@Test
public void paragraphWithIdAndClass() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes("123", "test", null, null));
builder.characters("text\n\nmore text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("text more text\n\n", markup);
}
@Test
public void paragraphWithLink() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text\n\nmore text ");
final LinkAttributes attributes = new LinkAttributes();
attributes.setHref("http://example.com/foo+bar/baz.gif");
builder.beginSpan(SpanType.LINK, attributes);
builder.characters("baz");
builder.endSpan();
builder.characters(" test");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("text more text [baz | http://example.com/foo+bar/baz.gif] test\n\n", markup);
}
@Test
public void blockCode() {
builder.beginDocument();
builder.beginBlock(BlockType.CODE, new Attributes());
builder.characters("text\n\nmore text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("{code}text\n\nmore text{code}\n\n\n", markup);
}
@Test
public void codeBlockWithLineBreaks() {
builder.beginDocument();
builder.beginBlock(BlockType.CODE, new Attributes());
builder.characters("line 1");
builder.lineBreak();
builder.characters("line 2");
builder.lineBreak();
builder.lineBreak();
builder.characters("line 3");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("{code}line 1\nline 2\n\nline 3{code}\n\n\n", markup);
}
@Test
public void codeBlockCurlyBraceContent() {
assertCodeBlock("{code}{something}{code}\n\n", "{something}");
}
@Test
public void codeBlockSquareBraceContent() {
assertCodeBlock("{code}[something]{code}\n\n", "[something]");
}
@Test
public void preformattedBlockWithLineBreaks() {
builder.beginDocument();
builder.beginBlock(BlockType.PREFORMATTED, new Attributes());
builder.characters("line 1");
builder.lineBreak();
builder.characters("line 2");
builder.lineBreak();
builder.lineBreak();
builder.characters("line 3");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("{noformat}line 1\nline 2\n\nline 3{noformat}\n\n", markup);
}
@Test
public void preformattedBlockWithCurlyBraceContent() {
builder.beginDocument();
builder.beginBlock(BlockType.PREFORMATTED, new Attributes());
builder.characters("{somecontent}");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("{noformat}{somecontent}{noformat}\n\n", markup);
}
@Test
public void paragraphFollowingExtendedBlockCode() {
builder.beginDocument();
builder.beginBlock(BlockType.CODE, new Attributes());
builder.characters("text\n\nmore text");
builder.endBlock();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text");
builder.endBlock();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text2");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("{code}text\n\nmore text{code}\n\n\ntext\n\ntext2\n\n", markup);
}
@Test
public void heading1() {
builder.beginDocument();
builder.beginHeading(1, new Attributes());
builder.characters("text\n\nmore text");
builder.endHeading();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("h1. text more text\n\ntext\n\n", markup);
}
@Test
public void headingWithLineBreaks() {
builder.beginDocument();
builder.beginHeading(1, new Attributes());
builder.characters("line 1 of heading");
builder.lineBreak();
builder.characters("line 2 of heading");
builder.endHeading();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("h1. line 1 of heading\\\\line 2 of heading\n\ntext\n\n", markup);
}
@Test
public void heading1_WithNestedMarkup() {
builder.beginDocument();
builder.beginHeading(1, new Attributes());
builder.characters("text ");
builder.beginSpan(SpanType.EMPHASIS, new Attributes());
builder.characters("emphasized");
builder.endSpan();
builder.endHeading();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("h1. text _emphasized_\n\ntext\n\n", markup);
}
@Test
public void implicitParagrah() {
builder.beginDocument();
builder.characters("text1");
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text2");
builder.endBlock();
builder.characters("text3");
builder.endDocument();
String markup = out.toString();
assertEquals("text1\n\ntext2\n\ntext3\n\n", markup);
}
@Test
public void boldSpanNoWhitespace_spanAtLineStart() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("text2");
builder.endSpan();
builder.characters("text3");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("*text2* text3\n\n", markup);
}
@Test
public void boldSpanNoWhitespace_spanAtLineEnd() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text3");
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("text2");
builder.endSpan();
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("text3 *text2*\n\n", markup);
}
@Test
public void boldSpanNoWhitespace_spanMidLine() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text3");
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("text2");
builder.endSpan();
builder.characters("text4");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("text3 *text2* text4\n\n", markup);
}
@Test
public void boldSpanNoWhitespace_adjacentSpans() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("text2");
builder.endSpan();
builder.beginSpan(SpanType.ITALIC, new Attributes());
builder.characters("text3");
builder.endSpan();
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("*text2*_text3_\n\n", markup);
}
@Test
public void spanWithAdjacentWhitespace() {
builder.beginDocument();
builder.characters("prefix ");
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("bolded");
builder.endBlock();
builder.characters(" suffix");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("prefix *bolded* suffix\n\n", markup);
}
@Test
public void boldSpanWithAdjacentPunctuation() {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("text2");
builder.endSpan();
builder.characters("!");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("*text2*!\n\n", markup);
}
@Test
public void emptySpan() {
builder.beginDocument();
builder.characters("prefix ");
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.endBlock();
builder.characters(" suffix");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("prefix suffix\n\n", markup);
}
@Test
public void monospaceSpan() {
builder.beginDocument();
builder.characters("prefix ");
builder.beginSpan(SpanType.MONOSPACE, new Attributes());
builder.characters("test");
builder.endSpan();
builder.characters(" suffix");
builder.endDocument();
String markup = out.toString();
assertEquals("prefix {{test}} suffix\n\n", markup);
}
@Test
public void monospaceSpanWithCurlyBraceContent() {
builder.beginDocument();
builder.characters("prefix ");
builder.beginSpan(SpanType.MONOSPACE, new Attributes());
builder.characters("{test}");
builder.endSpan();
builder.characters(" suffix");
builder.endDocument();
String markup = out.toString();
assertEquals("prefix {{\\{test}}} suffix\n\n", markup);
}
@Test
public void linkSpan() {
builder.beginDocument();
builder.characters("prefix ");
LinkAttributes attributes = new LinkAttributes();
attributes.setHref("http://example.com/target");
builder.beginSpan(SpanType.LINK, attributes);
builder.characters("test");
builder.endSpan();
builder.characters(" suffix");
builder.endDocument();
String markup = out.toString();
assertEquals("prefix [test | http://example.com/target] suffix\n\n", markup);
}
@Test
public void linkSpanWithAdjacentSpans() {
builder.beginDocument();
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("bold");
builder.endSpan();
LinkAttributes attributes = new LinkAttributes();
attributes.setHref("http://example.com/target");
builder.beginSpan(SpanType.LINK, attributes);
builder.characters("test");
builder.endSpan();
builder.beginSpan(SpanType.ITALIC, new Attributes());
builder.characters("italic");
builder.endSpan();
builder.endDocument();
String markup = out.toString();
assertEquals("*bold*[test | http://example.com/target]_italic_\n\n", markup);
}
@Test
public void linkSpanWithTitle() {
builder.beginDocument();
builder.characters("prefix ");
LinkAttributes attributes = new LinkAttributes();
attributes.setHref("http://example.com/target");
attributes.setTitle("Title Words");
builder.beginSpan(SpanType.LINK, attributes);
builder.characters("test");
builder.endSpan();
builder.characters(" suffix");
builder.endDocument();
String markup = out.toString();
assertEquals("prefix [test | http://example.com/target | Title Words] suffix\n\n", markup);
}
@Test
public void linkSpanNoText() {
builder.beginDocument();
builder.characters("prefix ");
LinkAttributes attributes = new LinkAttributes();
attributes.setHref("http://example.com/target");
builder.beginSpan(SpanType.LINK, attributes);
builder.endSpan();
builder.characters(" suffix");
builder.endDocument();
String markup = out.toString();
assertEquals("prefix [http://example.com/target] suffix\n\n", markup);
}
@Test
public void linkSpanWithSpecialCharacters() {
builder.beginDocument();
LinkAttributes attributes = new LinkAttributes();
attributes.setHref("http://example.com/target");
attributes.setTitle("Title Words");
builder.beginSpan(SpanType.LINK, attributes);
builder.characters("[This][Is] a test");
builder.endSpan();
builder.endDocument();
assertEquals("[\\[This\\]\\[Is\\] a test | http://example.com/target | Title Words]\n\n", out.toString());
}
@Test
public void linkAlternate() {
builder.beginDocument();
builder.characters("prefix ");
builder.link("#test", "Test 123");
builder.characters(" suffix");
builder.endDocument();
String markup = out.toString();
assertEquals("prefix [Test 123 | #test] suffix\n\n", markup);
}
@Test
public void linkSpanNoHref() {
builder.beginDocument();
builder.characters("prefix ");
LinkAttributes attributes = new LinkAttributes();
builder.beginSpan(SpanType.LINK, attributes);
builder.endSpan();
builder.characters(" suffix");
builder.endDocument();
String markup = out.toString();
assertEquals("prefix [] suffix\n\n", markup);
}
@Test
public void linkSpanWithSurroundingItalics() {
builder.beginDocument();
builder.beginSpan(SpanType.ITALIC, new Attributes());
builder.characters("prefix ");
LinkAttributes attributes = new LinkAttributes();
attributes.setHref("http://example.com/target");
builder.beginSpan(SpanType.LINK, attributes);
builder.characters("text");
builder.endSpan();
builder.endSpan();
builder.endDocument();
assertEquals("_prefix [text | http://example.com/target]_\n\n", out.toString());
}
@Test
public void tableWithEmptyCells() {
assertTableRow("| |content| |\n\n", BlockType.TABLE_CELL_NORMAL);
}
@Test
public void tableWithEmptyHeaderCells() {
assertTableRow("|| ||content|| |\n\n", BlockType.TABLE_CELL_HEADER);
}
@Test
public void tableWithCellsContainingBulletedList() {
assertTableRow("|| ||* first\n* second|| |\n\n", BlockType.TABLE_CELL_HEADER, this::emitMultiItemBulletedList);
}
@Test
public void tableWithCellsContainingNumericList() {
assertTableRow("| |# first\n# second| |\n\n", BlockType.TABLE_CELL_NORMAL, this::emitMultiItemNumericList);
}
@Test
public void tableWithLineBreaks() {
assertTableRow("| |abc\\\\ \\\\def| |\n\n", BlockType.TABLE_CELL_NORMAL, () -> {
builder.characters("abc");
builder.lineBreak();
builder.lineBreak();
builder.characters("def");
});
}
@Test
public void tableWithWhitespaceAndNewlinesInContent() {
assertTableRow("| |abc def| |\n\n", BlockType.TABLE_CELL_NORMAL, () -> {
builder.characters(" \n\nabc\n\ndef");
});
}
@Test
public void tableWithParagraphs() {
assertTableRow("| |abc\ndef| |\n\n", BlockType.TABLE_CELL_NORMAL, () -> {
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("abc");
builder.endBlock();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.endBlock();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("def");
builder.endBlock();
});
}
@Test
public void tableWithNestedList() {
assertTableRow("| |* first\n" + //
"* second| |\n\n", //
BlockType.TABLE_CELL_NORMAL, () -> {
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
emitListItemHavingParagraphAndContent("first");
emitListItemHavingParagraphAndContent("second");
builder.endBlock();
});
}
@Test
public void divAfterImplicitParagraph() {
builder.beginDocument();
builder.characters("test");
builder.beginBlock(BlockType.DIV, new Attributes());
builder.characters("more ");
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("text");
builder.endSpan();
builder.endBlock();
builder.beginBlock(BlockType.NUMERIC_LIST, new Attributes());
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters("text2");
builder.endSpan();
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("test\n\nmore *text*\n\n# text2\n", markup);
}
@Test
public void divWithinTableCell() {
builder.beginDocument();
builder.beginBlock(BlockType.TABLE, new Attributes());
builder.beginBlock(BlockType.TABLE_ROW, new Attributes());
builder.beginBlock(BlockType.TABLE_CELL_NORMAL, new Attributes());
builder.characters("first");
builder.endBlock();
builder.beginBlock(BlockType.TABLE_CELL_NORMAL, new Attributes());
builder.beginBlock(BlockType.DIV, new Attributes());
builder.characters("content");
builder.endBlock(); // div
builder.beginBlock(BlockType.DIV, new Attributes());
builder.characters("content2");
builder.endBlock(); // div
builder.endBlock(); // cell
builder.endBlock(); // row
builder.endBlock(); // table
builder.endDocument();
String markup = out.toString();
assertEquals("|first|content content2|\n\n", markup);
}
@Test
public void italics() {
builder.beginDocument();
builder.characters("prefix ");
builder.beginSpan(SpanType.ITALIC, new Attributes());
builder.characters("italic phrase");
builder.endBlock();
builder.characters(" suffix");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("prefix _italic phrase_ suffix\n\n", markup);
}
@Test
public void mark() {
builder.beginDocument();
builder.characters("prefix ");
builder.beginSpan(SpanType.MARK, new Attributes());
builder.characters("italic phrase");
builder.endBlock();
builder.characters(" suffix");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("prefix _italic phrase_ suffix\n\n", markup);
}
@Test
public void emptyBoldSpan() {
builder.beginDocument();
builder.characters("first ");
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.endSpan();
builder.characters("second");
builder.endDocument();
String markup = out.toString();
assertEquals("first second\n\n", markup);
}
@Test
public void paragraphWithSingleNewline() {
builder.beginDocument();
builder.characters("first");
builder.lineBreak();
builder.characters("second");
builder.endDocument();
String markup = out.toString();
assertEquals("first\nsecond\n\n", markup);
}
@Test
public void paragraphWithMultipleNewlines() {
builder.beginDocument();
builder.characters("first");
builder.lineBreak();
builder.lineBreak();
builder.lineBreak();
builder.characters("second");
builder.endDocument();
String markup = out.toString();
assertEquals("first\n\\\\ \\\\second\n\n", markup);
}
@Test
public void paragraphWithCurlyBraceContent() {
assertParagraphWithContent("\\{something}\n\n", "{something}");
}
@Test
public void paragraphWithSquareBraceContent() {
assertParagraphWithContent("\\[something\\]\n\n", "[something]");
}
@Test
public void paragraphWithSlashContent() {
assertParagraphWithContent("here is \ a slash\n\n", "here is \\ a slash");
}
@Test
public void listItemWithSingleNewline() {
builder.beginDocument();
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters("first");
builder.lineBreak();
builder.characters("second");
builder.endBlock(); // list item
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters("another");
builder.endBlock(); // list item
builder.endBlock(); // list
builder.endDocument();
String markup = out.toString();
assertEquals("* first\\\\second\n* another\n", markup);
}
@Test
public void listItemWithMultipleNewlines() {
builder.beginDocument();
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters("first");
builder.lineBreak();
builder.lineBreak();
builder.characters("second");
builder.endBlock(); // list item
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters("another");
builder.endBlock(); // list item
builder.endBlock(); // list
builder.endDocument();
String markup = out.toString();
assertEquals("* first\\\\ \\\\second\n* another\n", markup);
}
@Test
public void listWithMultipleItems() {
builder.beginDocument();
emitMultiItemBulletedList();
builder.endDocument();
String markup = out.toString();
assertEquals("* first\n* second\n", markup);
}
@Test
public void listItemWithSingleParagraph() {
builder.beginDocument();
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
emitListItemHavingParagraphAndContent("first");
builder.endBlock(); // list
builder.endDocument();
assertEquals("* first\n", out.toString());
}
@Test
public void listItemWithMultipleParagraphs() {
builder.beginDocument();
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("first");
builder.endBlock(); // paragraph
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("second");
builder.endBlock(); // paragraph
builder.endBlock(); // list item
builder.endBlock(); // list
builder.endDocument();
assertEquals("* first\nsecond\n", out.toString());
}
@Test
public void listItemWithMultipleMixedParagraphs() {
builder.beginDocument();
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters("first");
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("second");
builder.endBlock(); // paragraph
builder.characters("third");
builder.endBlock(); // list item
builder.endBlock(); // list
builder.endDocument();
assertEquals("* first\nsecond\nthird\n", out.toString());
}
private void emitMultiItemBulletedList() {
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
emitListItem("first");
emitListItem("second");
builder.endBlock();
}
private void emitMultiItemNumericList() {
builder.beginBlock(BlockType.NUMERIC_LIST, new Attributes());
emitListItem("first");
emitListItem("second");
builder.endBlock();
}
private void emitListItem(String text) {
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters(text);
builder.endBlock(); // list item
}
@Test
public void listWithNestedSublist() {
builder.beginDocument();
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters("first");
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
emitListItem("first.1");
emitListItem("first.2");
builder.endBlock(); // list
builder.endBlock(); // list item
emitListItem("second");
builder.endBlock(); // list
builder.endDocument();
String markup = out.toString();
assertEquals("* first\n** first.1\n** first.2\n* second\n", markup);
}
@Test
public void listWithNestedSublist2() {
builder.beginDocument();
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
emitListItem("first");
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters("second");
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
emitListItem("second.1");
builder.endBlock(); // list
builder.endBlock(); // list item
builder.endBlock(); // list
builder.beginBlock(BlockType.NUMERIC_LIST, new Attributes());
emitListItem("third");
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.characters("fourth");
builder.beginBlock(BlockType.NUMERIC_LIST, new Attributes());
emitListItem("fourth.1");
builder.endBlock(); // list
builder.endBlock(); // list item
builder.endBlock(); // list
builder.endDocument();
String markup = out.toString();
assertEquals("* first\n* second\n** second.1\n\n# third\n# fourth\n## fourth.1\n", markup);
}
@Test
public void listWithNestedListsWihoutListItem() {
builder.beginDocument();
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
emitListItemHavingParagraphAndContent("content 1");
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
emitListItemHavingParagraphAndContent("content 2");
builder.endBlock(); // list
builder.endBlock(); // list
builder.endBlock(); // list
builder.endDocument();
assertEquals("* content 1\n" + //
"*** content 2\n", out.toString());
}
@Test
public void preformattedWithMultipleNewlines() {
builder.beginDocument();
builder.beginBlock(BlockType.PREFORMATTED, new Attributes());
builder.characters("first");
builder.lineBreak();
builder.lineBreak();
builder.characters("second");
builder.endBlock(); // pre
builder.endDocument();
String markup = out.toString();
assertEquals("{noformat}first\n\nsecond{noformat}\n\n", markup);
}
@Test
public void implicitParagrahWithSpan() {
builder.beginDocument();
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("text1");
builder.endSpan();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters("text2");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("*text1*\n\ntext2\n\n", markup);
}
@Test
public void spanOpensImplicitParagraph() {
builder.beginDocument();
builder.beginBlock(BlockType.CODE, new Attributes());
builder.characters("// some code");
builder.endBlock();
builder.beginSpan(SpanType.DELETED, new Attributes());
builder.characters("redacted");
builder.endSpan();
builder.characters(" text");
builder.endDocument();
String markup = out.toString();
assertEquals("{code}// some code{code}\n\n-redacted- text\n\n", markup);
}
@Test
public void blockQuote() {
builder.beginDocument();
builder.beginBlock(BlockType.QUOTE, new Attributes());
builder.characters("block text");
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("{quote}block text{quote}\n\n", markup);
}
@Test
public void blockQuoteContainingMarkup() {
builder.beginDocument();
builder.beginBlock(BlockType.QUOTE, new Attributes());
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.characters("bold");
builder.endSpan();
builder.characters("text");
builder.beginSpan(SpanType.ITALIC, new Attributes());
builder.characters("italic");
builder.endSpan();
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals("{quote}*bold* text _italic_{quote}\n\n", markup);
}
@Test
public void citationAfterBlockQuote() {
builder.beginDocument();
builder.beginBlock(BlockType.QUOTE, new Attributes());
builder.beginSpan(SpanType.CITATION, new Attributes());
builder.characters("citation");
builder.endSpan();
builder.endBlock();
builder.beginSpan(SpanType.CITATION, new Attributes());
builder.characters("citation");
builder.endSpan();
builder.endDocument();
String markup = out.toString();
assertEquals("{quote}??citation??{quote}\n\n??citation??\n\n", markup);
}
@Test
public void imageLink() {
builder.beginDocument();
builder.characters("a ");
builder.imageLink(new LinkAttributes(), new ImageAttributes(), "#foo", "fooImage.png");
builder.characters(" test");
builder.endDocument();
String markup = out.toString();
assertEquals("a !fooImage.png!:#foo test\n\n", markup);
}
@Test
public void image() {
builder.beginDocument();
builder.characters("a ");
builder.image(new ImageAttributes(), "fooImage.png");
builder.characters(" test");
builder.endDocument();
String markup = out.toString();
assertEquals("a !fooImage.png! test\n\n", markup);
}
@Test
public void imageNoUrl() {
builder.beginDocument();
builder.characters("a ");
builder.image(new ImageAttributes(), null);
builder.characters(" test");
builder.endDocument();
String markup = out.toString();
assertEquals("a test\n\n", markup);
}
@Test
public void spanSuperscript() {
assertSpan("begin ^span text^ end\n\n", SpanType.SUPERSCRIPT);
}
@Test
public void spanSubscript() {
assertSpan("begin ~span text~ end\n\n", SpanType.SUBSCRIPT);
}
@Test
public void spanBold() {
assertSpan("begin *span text* end\n\n", SpanType.BOLD);
}
@Test
public void spanCitation() {
assertSpan("begin ??span text?? end\n\n", SpanType.CITATION);
}
@Test
public void spanCode() {
assertSpan("begin @span text@ end\n\n", SpanType.CODE);
}
@Test
public void spanDeleted() {
assertSpan("begin -span text- end\n\n", SpanType.DELETED);
}
@Test
public void spanEmphasis() {
assertSpan("begin _span text_ end\n\n", SpanType.EMPHASIS);
}
@Test
public void spanInserted() {
assertSpan("begin +span text+ end\n\n", SpanType.INSERTED);
}
@Test
public void spanItalic() {
assertSpan("begin _span text_ end\n\n", SpanType.ITALIC);
}
@Test
public void spanMonospace() {
assertSpan("begin {{span text}} end\n\n", SpanType.MONOSPACE);
}
@Test
public void spanQuote() {
assertSpan("beginspan textend\n\n", SpanType.QUOTE);
}
@Test
public void spanSpan() {
assertSpan("beginspan textend\n\n", SpanType.SPAN);
}
@Test
public void spanStrong() {
assertSpan("begin *span text* end\n\n", SpanType.STRONG);
}
@Test
public void spanUnderlined() {
assertSpan("begin +span text+ end\n\n", SpanType.UNDERLINED);
}
@Test
public void nestedBoldItalic() {
assertNestedSpan("begin *_span_* end\n\n", SpanType.BOLD, SpanType.ITALIC);
}
@Test
public void nestedItalicBold() {
assertNestedSpan("begin _*span*_ end\n\n", SpanType.ITALIC, SpanType.BOLD);
}
@Test
public void nestedDeletedSuperscript() {
assertNestedSpan("begin -^span^- end\n\n", SpanType.DELETED, SpanType.SUPERSCRIPT);
}
@Test
public void nestedSuperscriptDeleted() {
assertNestedSpan("begin ^-span-^ end\n\n", SpanType.SUPERSCRIPT, SpanType.DELETED);
}
@Test
public void nestedUnderlineSubscript() {
assertNestedSpan("begin +~span~+ end\n\n", SpanType.UNDERLINED, SpanType.SUBSCRIPT);
}
@Test
public void nestedSubscriptUnderline() {
assertNestedSpan("begin ~+span+~ end\n\n", SpanType.SUBSCRIPT, SpanType.UNDERLINED);
}
@Test
public void nestedMonospaceCitation() {
assertNestedSpan("begin {{??span??}} end\n\n", SpanType.MONOSPACE, SpanType.CITATION);
}
@Test
public void nestedCitationMonospace() {
assertNestedSpan("begin ??{{span}}?? end\n\n", SpanType.CITATION, SpanType.MONOSPACE);
}
@Test
public void nestedLinkCode() {
assertNestedSpan("begin %@span@% end\n\n", SpanType.LINK, SpanType.CODE);
}
@Test
public void nestedCodeLink() {
assertNestedSpan("begin @%span%@ end\n\n", SpanType.CODE, SpanType.LINK);
}
@Test
public void adjacentBoldItalic() {
assertAdjacentSpan("begin *left*_right_ end\n\n", SpanType.BOLD, SpanType.ITALIC);
}
@Test
public void adjacentItalicBold() {
assertAdjacentSpan("begin _left_*right* end\n\n", SpanType.ITALIC, SpanType.BOLD);
}
@Test
public void adjacentDeletedSuperscript() {
assertAdjacentSpan("begin -left-^right^ end\n\n", SpanType.DELETED, SpanType.SUPERSCRIPT);
}
@Test
public void adjacentSuperscriptDeleted() {
assertAdjacentSpan("begin ^left^-right- end\n\n", SpanType.SUPERSCRIPT, SpanType.DELETED);
}
@Test
public void adjacentUnderlineSubscript() {
assertAdjacentSpan("begin +left+~right~ end\n\n", SpanType.UNDERLINED, SpanType.SUBSCRIPT);
}
@Test
public void adjacentSubscriptUnderline() {
assertAdjacentSpan("begin ~left~+right+ end\n\n", SpanType.SUBSCRIPT, SpanType.UNDERLINED);
}
@Test
public void adjacentMonospaceCitation() {
assertAdjacentSpan("begin {{left}}??right?? end\n\n", SpanType.MONOSPACE, SpanType.CITATION);
}
@Test
public void adjacentCitationMonospace() {
assertAdjacentSpan("begin ??left??{{right}} end\n\n", SpanType.CITATION, SpanType.MONOSPACE);
}
@Test
public void adjacentLinkCode() {
assertAdjacentSpan("begin %left%@right@ end\n\n", SpanType.LINK, SpanType.CODE);
}
@Test
public void adjacentCodeLink() {
assertAdjacentSpan("begin @left@%right% end\n\n", SpanType.CODE, SpanType.LINK);
}
@Test
public void italicBoldItalic() {
builder.beginDocument();
builder.beginSpan(SpanType.ITALIC, new Attributes());
builder.characters("italic");
builder.endSpan();
builder.beginSpan(SpanType.BOLD, new Attributes());
builder.beginSpan(SpanType.ITALIC, new Attributes());
builder.characters("bolditalic");
builder.endSpan();
builder.endSpan();
builder.endDocument();
String markup = out.toString();
assertEquals("_italic_*_bolditalic_*\n\n", markup);
}
private void assertSpan(String expected, SpanType spanType) {
builder.beginDocument();
builder.characters("begin");
builder.beginSpan(spanType, new Attributes());
builder.characters("span text");
builder.endSpan();
builder.characters("end");
builder.endDocument();
String markup = out.toString();
assertEquals(expected, markup);
}
private void assertNestedSpan(String expected, SpanType outerSpan, SpanType innerSpan) {
builder.beginDocument();
builder.characters("begin");
builder.beginSpan(outerSpan, new Attributes());
builder.beginSpan(innerSpan, new Attributes());
builder.characters("span");
builder.endSpan();
builder.endSpan();
builder.characters("end");
builder.endDocument();
String markup = out.toString();
assertEquals(expected, markup);
}
private void assertAdjacentSpan(String expected, SpanType leftSpan, SpanType rightSpan) {
builder.beginDocument();
builder.characters("begin");
builder.beginSpan(leftSpan, new Attributes());
builder.characters("left");
builder.endSpan();
builder.beginSpan(rightSpan, new Attributes());
builder.characters("right");
builder.endSpan();
builder.characters("end");
builder.endDocument();
String markup = out.toString();
assertEquals(expected, markup);
}
private void assertTableRow(String expectedMarkup, BlockType cellType) {
assertTableRow(expectedMarkup, cellType, () -> builder.characters("content"));
}
private void assertTableRow(String expectedMarkup, BlockType cellType, Runnable cellContentProvider) {
builder.beginDocument();
builder.beginBlock(BlockType.TABLE, new Attributes());
builder.beginBlock(BlockType.TABLE_ROW, new Attributes());
builder.beginBlock(cellType, new Attributes());
builder.endBlock();
builder.beginBlock(cellType, new Attributes());
cellContentProvider.run();
builder.endBlock();
builder.beginBlock(cellType, new Attributes());
builder.endBlock();
builder.endBlock();
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals(expectedMarkup, markup);
}
private void assertParagraphWithContent(String expected, String characters) {
builder.beginDocument();
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters(characters);
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals(expected, markup);
}
private void emitListItemHavingParagraphAndContent(String content) {
builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
builder.beginBlock(BlockType.PARAGRAPH, new Attributes());
builder.characters(content);
builder.endBlock(); // paragraph
builder.endBlock(); // list item
}
private void assertCodeBlock(String expected, String content) {
builder.beginDocument();
builder.beginBlock(BlockType.CODE, new Attributes());
builder.characters(content);
builder.endBlock();
builder.endDocument();
String markup = out.toString();
assertEquals(expected, markup);
}
}