Skip to content

Commit

Permalink
Add regression tests from cmark and commonmark.js
Browse files Browse the repository at this point in the history
There were two failing tests, related to:

* Backslash in link destinations (see commonmark/commonmark-spec#493)
* Tabs in ATX/Setext headers

Change the implementation to match the reference implementation.
  • Loading branch information
robinst committed Mar 26, 2018
1 parent c742a0d commit 01d8cc6
Show file tree
Hide file tree
Showing 21 changed files with 377 additions and 83 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
with the exception that 0.x versions can break between minor versions.

## Unreleased
### Changed
- Parse backslash followed by unescapable character the same way as
the reference implementations.
### Fixed
- Fix tab handling in ATX and Setext headings.

## [0.11.0] - 2018-01-17
### Added
- The extension for tables now also renders to plain text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import org.commonmark.testutil.spec.SpecReader;
import org.commonmark.testutil.TestResources;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -30,7 +30,7 @@ public class AndroidSupportTest {

@Before
public void setUp() throws Exception {
spec = SpecReader.readSpec();
spec = TestResources.readAsString(TestResources.getSpec());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.testutil.spec.SpecExample;
import org.commonmark.testutil.spec.SpecReader;
import org.commonmark.testutil.TestResources;
import org.commonmark.testutil.example.Example;
import org.commonmark.testutil.example.ExampleReader;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
Expand All @@ -29,9 +30,9 @@ public BoundsIntegrationTest(String input) {

@Parameterized.Parameters(name = "{0}")
public static List<Object[]> data() {
List<SpecExample> examples = SpecReader.readExamples();
List<Example> examples = ExampleReader.readExamples(TestResources.getSpec());
List<Object[]> data = new ArrayList<>();
for (SpecExample example : examples) {
for (Example example : examples) {
data.add(new Object[]{example.getSource()});
}
return data;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.commonmark.integration;

import org.commonmark.testutil.spec.SpecReader;
import org.commonmark.testutil.TestResources;
import org.commonmark.testutil.example.ExampleReader;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
Expand All @@ -17,8 +18,8 @@
@State(Scope.Benchmark)
public class PegDownBenchmark {

private static final String SPEC = SpecReader.readSpec();
private static final List<String> SPEC_EXAMPLES = SpecReader.readExamplesAsString();
private static final String SPEC = TestResources.readAsString(TestResources.getSpec());
private static final List<String> SPEC_EXAMPLES = ExampleReader.readExampleSources(TestResources.getSpec());
private static final PegDownProcessor PROCESSOR = new PegDownProcessor(Extensions.FENCED_CODE_BLOCKS);

public static void main(String[] args) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.commonmark.ext.front.matter.YamlFrontMatterExtension;
import org.commonmark.renderer.html.HtmlRenderer;
import org.commonmark.parser.Parser;
import org.commonmark.testutil.spec.SpecExample;
import org.commonmark.testutil.example.Example;
import org.commonmark.testutil.SpecTestCase;
import org.junit.Test;

Expand All @@ -30,7 +30,7 @@ public class SpecIntegrationTest extends SpecTestCase {
private static final HtmlRenderer RENDERER = HtmlRenderer.builder().extensions(EXTENSIONS).percentEncodeUrls(true).build();
private static final Map<String, String> OVERRIDDEN_EXAMPLES = getOverriddenExamples();

public SpecIntegrationTest(SpecExample example) {
public SpecIntegrationTest(Example example) {
super(example);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.commonmark.testutil;

import org.commonmark.testutil.spec.SpecExample;
import org.commonmark.testutil.spec.SpecReader;
import org.commonmark.testutil.example.Example;
import org.commonmark.testutil.example.ExampleReader;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
Expand All @@ -13,17 +13,17 @@
@RunWith(Parameterized.class)
public abstract class SpecTestCase extends RenderingTestCase {

protected final SpecExample example;
protected final Example example;

public SpecTestCase(SpecExample example) {
public SpecTestCase(Example example) {
this.example = example;
}

@Parameters(name = "{0}")
public static List<Object[]> data() {
List<SpecExample> examples = SpecReader.readExamples();
List<Example> examples = ExampleReader.readExamples(TestResources.getSpec());
List<Object[]> data = new ArrayList<>();
for (SpecExample example : examples) {
for (Example example : examples) {
data.add(new Object[]{example});
}
return data;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.commonmark.testutil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

public class TestResources {

public static URL getSpec() {
return TestResources.class.getResource("/spec.txt");
}

public static List<URL> getRegressions() {
return Arrays.asList(
TestResources.class.getResource("/cmark-regression.txt"),
TestResources.class.getResource("/commonmark.js-regression.txt")
);
}

public static String readAsString(URL url) {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), Charset.forName("UTF-8")))) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
return sb.toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package org.commonmark.testutil.spec;
package org.commonmark.testutil.example;

public class SpecExample {
public class Example {

private final String filename;
private final String section;
private final int exampleNumber;
private final String source;
private final String html;

public SpecExample(String section, int exampleNumber, String source, String html) {
public Example(String filename, String section, int exampleNumber, String source, String html) {
this.filename = filename;
this.section = section;
this.exampleNumber = exampleNumber;
this.source = source;
Expand All @@ -24,6 +26,6 @@ public String getHtml() {

@Override
public String toString() {
return "Section \"" + section + "\" example " + exampleNumber;
return "File \"" + filename + "\" section \"" + section + "\" example " + exampleNumber;
}
}
Original file line number Diff line number Diff line change
@@ -1,73 +1,54 @@
package org.commonmark.testutil.spec;
package org.commonmark.testutil.example;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SpecReader {
/**
* Reader for files containing examples of CommonMark source and the expected HTML rendering (e.g. spec.txt).
*/
public class ExampleReader {

private static final Pattern SECTION_PATTERN = Pattern.compile("#{1,6} *(.*)");

private final InputStream inputStream;
private final String filename;

private State state = State.BEFORE;
private String section;
private StringBuilder source;
private StringBuilder html;
private int exampleNumber = 0;

private List<SpecExample> examples = new ArrayList<>();
private List<Example> examples = new ArrayList<>();

private SpecReader(InputStream stream) {
private ExampleReader(InputStream stream, String filename) {
this.inputStream = stream;
this.filename = filename;
}

public static List<SpecExample> readExamples() {
try (InputStream stream = getSpecInputStream()) {
return new SpecReader(stream).read();
public static List<Example> readExamples(URL url) {
try (InputStream stream = url.openStream()) {
return new ExampleReader(stream, new File(url.getPath()).getName()).read();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static List<String> readExamplesAsString() {
List<SpecExample> examples = SpecReader.readExamples();
public static List<String> readExampleSources(URL url) {
List<Example> examples = ExampleReader.readExamples(url);
List<String> result = new ArrayList<>();
for (SpecExample example : examples) {
for (Example example : examples) {
result.add(example.getSource());
}
return result;
}

public static String readSpec() {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(getSpecInputStream(), Charset.forName("UTF-8")))) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
return sb.toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static InputStream getSpecInputStream() {
InputStream stream = SpecReader.class.getResourceAsStream("/spec.txt");
if (stream == null) {
throw new IllegalStateException("Could not load spec.txt classpath resource");
}
return stream;
}

private List<SpecExample> read() throws IOException {
private List<Example> read() throws IOException {
resetContents();

try (BufferedReader reader = new BufferedReader(
Expand Down Expand Up @@ -106,7 +87,7 @@ private void processLine(String line) {
case HTML:
if (line.equals("````````````````````````````````")) {
state = State.BEFORE;
examples.add(new SpecExample(section, exampleNumber,
examples.add(new Example(filename, section, exampleNumber,
source.toString(), html.toString()));
resetContents();
} else {
Expand Down
7 changes: 7 additions & 0 deletions commonmark-test-util/src/main/resources/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
These files are copied from the CommonMark repositories, namely:

https://github.com/commonmark/CommonMark/blob/master/spec.txt
https://github.com/commonmark/cmark/blob/master/test/regression.txt
https://github.com/commonmark/commonmark.js/blob/master/test/regression.txt

They are licensed as stated in those repositories.
95 changes: 95 additions & 0 deletions commonmark-test-util/src/main/resources/cmark-regression.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
### Regression tests

Issue #113: EOL character weirdness on Windows
(Important: first line ends with CR + CR + LF)

```````````````````````````````` example
line1

line2
.
<p>line1</p>
<p>line2</p>
````````````````````````````````

Issue #114: cmark skipping first character in line
(Important: the blank lines around "Repeatedly" contain a tab.)

```````````````````````````````` example
By taking it apart

- alternative solutions
Repeatedly solving
- how techniques
.
<p>By taking it apart</p>
<ul>
<li>alternative solutions</li>
</ul>
<p>Repeatedly solving</p>
<ul>
<li>how techniques</li>
</ul>
````````````````````````````````

Issue jgm/CommonMark#430: h2..h6 not recognized as block tags.

```````````````````````````````` example
<h1>lorem</h1>

<h2>lorem</h2>

<h3>lorem</h3>

<h4>lorem</h4>

<h5>lorem</h5>

<h6>lorem</h6>
.
<h1>lorem</h1>
<h2>lorem</h2>
<h3>lorem</h3>
<h4>lorem</h4>
<h5>lorem</h5>
<h6>lorem</h6>
````````````````````````````````

Issue jgm/commonmark.js#109 - tabs after setext header line


```````````````````````````````` example
hi
--→
.
<h2>hi</h2>
````````````````````````````````

Issue #177 - incorrect emphasis parsing

```````````````````````````````` example
a***b* c*
.
<p>a*<em><em>b</em> c</em></p>
````````````````````````````````

Issue #193 - unescaped left angle brackets in link destination

```````````````````````````````` example
[a]

[a]: <te<st>
.
<p><a href="%3Cte%3Cst%3E">a</a></p>
````````````````````````````````

Issue #192 - escaped spaces in link destination


```````````````````````````````` example
[a](te\ st)
.
<p>[a](te\ st)</p>
````````````````````````````````
Loading

0 comments on commit 01d8cc6

Please sign in to comment.