Redefine test format

This commit is contained in:
Dimitry Ivanov 2018-12-17 16:18:20 +03:00
parent 448a620399
commit 414a8763f2
25 changed files with 530 additions and 63 deletions

View File

@ -105,6 +105,7 @@ public abstract class TestSpan {
public abstract int length(); public abstract int length();
} }
// important: children should not be included in equals...
public static abstract class Span extends TestSpan { public static abstract class Span extends TestSpan {
@NonNull @NonNull

View File

@ -72,16 +72,18 @@ public abstract class TestSpanMatcher {
@NonNull final Spanned spanned, @NonNull final Spanned spanned,
final int start, final int start,
final int end, final int end,
@NonNull TestSpan.Span expected) { @NonNull final TestSpan.Span expected) {
// when queried multiple spans can be returned (for example if one span // when queried multiple spans can be returned (for example if one span
// wraps another one. so [0 1 [2 3] 4 5] where [] represents start/end of // wraps another one. so [0 1 [2 3] 4 5] where [] represents start/end of
// a span of same type, when queried for spans at 2-3 position, both will be returned // a span of same type, when queried for spans at 2-3 position, both will be returned
final TestSpan.Span actual = Ix.fromArray(spanned.getSpans(start, end, expected.getClass())) final TestSpan.Span actual = Ix.fromArray(spanned.getSpans(start, end, Object.class))
.cast(TestSpan.Span.class)
.filter(new IxPredicate<TestSpan.Span>() { .filter(new IxPredicate<TestSpan.Span>() {
@Override @Override
public boolean test(TestSpan.Span span) { public boolean test(TestSpan.Span span) {
return start == spanned.getSpanStart(span) return expected.name().equals(span.name())
&& start == spanned.getSpanStart(span)
&& end == spanned.getSpanEnd(span); && end == spanned.getSpanEnd(span);
} }
}) })

View File

@ -46,14 +46,12 @@ class TestSpanSpan extends TestSpan.Span {
TestSpanSpan that = (TestSpanSpan) o; TestSpanSpan that = (TestSpanSpan) o;
if (!name.equals(that.name)) return false; if (!name.equals(that.name)) return false;
if (!children.equals(that.children)) return false;
return arguments.equals(that.arguments); return arguments.equals(that.arguments);
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = name.hashCode(); int result = name.hashCode();
result = 31 * result + children.hashCode();
result = 31 * result + arguments.hashCode(); result = 31 * result + arguments.hashCode();
return result; return result;
} }

View File

@ -0,0 +1,70 @@
package ru.noties.markwon.test;
import org.junit.Test;
import java.util.Map;
import ru.noties.markwon.test.TestSpan.Document;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static ru.noties.markwon.test.TestSpan.args;
import static ru.noties.markwon.test.TestSpan.document;
import static ru.noties.markwon.test.TestSpan.span;
import static ru.noties.markwon.test.TestSpan.text;
public class TestSpanTest {
@Test
public void args_not_event_throws() {
try {
args("key");
fail();
} catch (IllegalStateException e) {
assertTrue(e.getMessage(), e.getMessage().contains("Supplied key-values array must contain "));
}
}
@Test
public void args_key_not_string_throws() {
try {
args("key", 1, 2, 3);
fail();
} catch (ClassCastException e) {
assertTrue(true);
}
}
@Test
public void args_correct() {
final Map<String, Object> args = args("key1", true, "key2", 4);
assertEquals(2, args.size());
assertEquals(true, args.get("key1"));
assertEquals(4, args.get("key2"));
}
@Test
public void empty_document() {
final Document document = document();
assertEquals(0, document.children().size());
assertEquals("", document.wholeText());
}
@Test
public void document_single_text_child() {
final Document document = document(text("Text"));
assertEquals(1, document.children().size());
assertEquals("Text", document.wholeText());
}
@Test
public void document_single_span_child() {
final Document document = document(span("span", text("TextInSpan")));
assertEquals(1, document.children().size());
assertTrue(document.children().get(0) instanceof TestSpan.Span);
assertEquals("TextInSpan", document.wholeText());
}
}

View File

@ -0,0 +1,13 @@
apply plugin: 'java-library'
sourceCompatibility = 1.7
targetCompatibility = 1.7
dependencies {
api deps['support-annotations']
deps['test'].with {
implementation it['commons-io']
}
}

View File

@ -0,0 +1,32 @@
package ru.noties.markwon.test;
import android.support.annotation.NonNull;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public abstract class TestUtil {
@NonNull
public static String read(@NonNull String path) {
try {
return IOUtils.resourceToString(path, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@NonNull
public static String read(@NonNull Object who, @NonNull String path) {
try {
return IOUtils.resourceToString(path, StandardCharsets.UTF_8, who.getClass().getClassLoader());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private TestUtil() {
}
}

View File

@ -21,14 +21,20 @@ dependencies {
} }
deps['test'].with { deps['test'].with {
testImplementation project(':markwon-test-span')
testImplementation project(':markwon-test-util')
testImplementation it['junit'] testImplementation it['junit']
testImplementation it['robolectric'] testImplementation it['robolectric']
testImplementation it['mockito']
// to remove after migration
testImplementation it['ix-java'] testImplementation it['ix-java']
testImplementation it['jackson-yaml'] testImplementation it['jackson-yaml']
testImplementation it['jackson-databind'] testImplementation it['jackson-databind']
testImplementation it['gson'] testImplementation it['gson']
testImplementation it['commons-io'] testImplementation it['commons-io']
testImplementation it['mockito']
} }
} }

View File

@ -0,0 +1,60 @@
package ru.noties.markwon.core;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Spanned;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.MarkwonConfiguration;
import ru.noties.markwon.SpannableFactoryDef;
import ru.noties.markwon.test.TestSpan;
import ru.noties.markwon.test.TestSpanMatcher;
import static ru.noties.markwon.test.TestSpan.document;
import static ru.noties.markwon.test.TestSpan.span;
import static ru.noties.markwon.test.TestSpan.text;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class CoreTest {
@Test
public void bold_italic() {
final String input = "**_bold italic_**";
final TestSpan.Document document = document(
span("bold",
span("italic", text("bold italic"))));
final Spanned spanned = (Spanned) Markwon.builder(RuntimeEnvironment.application)
.use(CorePlugin.create())
.use(new AbstractMarkwonPlugin() {
@Override
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
builder.factory(new SpannableFactoryDef() {
@Override
public Object strongEmphasis() {
return span("bold");
}
@Override
public Object emphasis() {
return span("italic");
}
});
}
})
.build()
.toMarkdown(input);
TestSpanMatcher.matches(spanned, document);
}
}

View File

@ -0,0 +1,4 @@
# 2 space indentation
[*.java]
indent_style = space
indent_size = 2

View File

@ -0,0 +1,44 @@
package ru.noties.markwon.core.suite;
import android.support.annotation.NonNull;
import android.text.Spanned;
import org.robolectric.RuntimeEnvironment;
import ru.noties.markwon.AbstractMarkwonPlugin;
import ru.noties.markwon.Markwon;
import ru.noties.markwon.MarkwonConfiguration;
import ru.noties.markwon.core.CorePlugin;
import ru.noties.markwon.test.TestSpan;
import ru.noties.markwon.test.TestSpanMatcher;
import ru.noties.markwon.test.TestUtil;
abstract class BaseSuiteTest {
void matches(@NonNull String input, @NonNull TestSpan.Document document) {
final Spanned spanned = (Spanned) markwon().toMarkdown(input);
TestSpanMatcher.matches(spanned, document);
}
void matchInput(@NonNull String name, @NonNull TestSpan.Document document) {
matches(read(name), document);
}
@NonNull
String read(@NonNull String name) {
return TestUtil.read(this, "tests/" + name);
}
@NonNull
Markwon markwon() {
return Markwon.builder(RuntimeEnvironment.application)
.use(CorePlugin.create())
.use(new AbstractMarkwonPlugin() {
@Override
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
builder.factory(new TestFactory());
}
})
.build();
}
}

View File

@ -0,0 +1,33 @@
package ru.noties.markwon.core.suite;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import ru.noties.markwon.test.TestSpan;
import static ru.noties.markwon.core.suite.TestFactory.BOLD;
import static ru.noties.markwon.core.suite.TestFactory.ITALIC;
import static ru.noties.markwon.test.TestSpan.document;
import static ru.noties.markwon.test.TestSpan.span;
import static ru.noties.markwon.test.TestSpan.text;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class BoldItalic extends BaseSuiteTest {
/*
**_bold italic_**
*/
@Test
public void test() {
final TestSpan.Document document = document(
span(BOLD,
span(ITALIC, text("bold italic"))));
matchInput("bold-italic.md", document);
}
}

View File

@ -0,0 +1,51 @@
package ru.noties.markwon.core.suite;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import ru.noties.markwon.test.TestSpan;
import static ru.noties.markwon.core.suite.TestFactory.CODE;
import static ru.noties.markwon.test.TestSpan.args;
import static ru.noties.markwon.test.TestSpan.document;
import static ru.noties.markwon.test.TestSpan.span;
import static ru.noties.markwon.test.TestSpan.text;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class CodeBlocks extends BaseSuiteTest {
/*
```java
final String s = null;
```
```html
<html></html>
```
```
nothing here
```
*/
@Test
public void test() {
final TestSpan.Document document = document(
span(CODE,
args("multiline", true),
text("\u00a0\nfinal String s = null;\n\u00a0")),
text("\n\n"),
span(CODE,
args("multiline", true),
text("\u00a0\n<html></html>\n\u00a0")),
text("\n\n"),
span(CODE,
args("multiline", true),
text("\u00a0\nnothing here\n\u00a0"))
);
matchInput("code-blocks.md", document);
}
}

View File

@ -0,0 +1,44 @@
package ru.noties.markwon.core.suite;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import ru.noties.markwon.test.TestSpan.Document;
import static ru.noties.markwon.core.suite.TestFactory.BOLD;
import static ru.noties.markwon.core.suite.TestFactory.CODE;
import static ru.noties.markwon.core.suite.TestFactory.ITALIC;
import static ru.noties.markwon.test.TestSpan.args;
import static ru.noties.markwon.test.TestSpan.document;
import static ru.noties.markwon.test.TestSpan.span;
import static ru.noties.markwon.test.TestSpan.text;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class DeeplyNested extends BaseSuiteTest {
/*
**bold *bold italic `bold italic code` bold italic* bold** normal
*/
@Test
public void test() {
final Document document = document(
span(BOLD,
text("bold "),
span(ITALIC,
text("bold italic "),
span(CODE,
args("multiline", false),
text("\u00a0bold italic code\u00a0")),
text(" bold italic")),
text(" bold")),
text(" normal")
);
matchInput("deeply-nested.md", document);
}
}

View File

@ -0,0 +1,46 @@
package ru.noties.markwon.core.suite;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import ru.noties.markwon.test.TestSpan.Document;
import static ru.noties.markwon.core.suite.TestFactory.BOLD;
import static ru.noties.markwon.core.suite.TestFactory.ITALIC;
import static ru.noties.markwon.core.suite.TestFactory.LINK;
import static ru.noties.markwon.test.TestSpan.args;
import static ru.noties.markwon.test.TestSpan.document;
import static ru.noties.markwon.test.TestSpan.span;
import static ru.noties.markwon.test.TestSpan.text;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class First extends BaseSuiteTest {
/*
Here is some [link](https://my.href)
**bold _bold italic_ bold** normal
*/
@Test
public void test() {
final Document document = document(
text("Here is some "),
span(LINK,
args("href", "https://my.href"),
text("link")),
text(" "),
span(BOLD,
text("bold "),
span(ITALIC,
text("bold italic")),
text(" bold")),
text(" normal")
);
matchInput("first.md", document);
}
}

View File

@ -0,0 +1,88 @@
package ru.noties.markwon.core.suite;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import ru.noties.markwon.SpannableFactory;
import ru.noties.markwon.core.MarkwonTheme;
import ru.noties.markwon.core.spans.LinkSpan;
import ru.noties.markwon.image.AsyncDrawableLoader;
import ru.noties.markwon.image.ImageSize;
import ru.noties.markwon.image.ImageSizeResolver;
import static ru.noties.markwon.test.TestSpan.args;
import static ru.noties.markwon.test.TestSpan.span;
class TestFactory implements SpannableFactory {
static final String BOLD = "bold";
static final String ITALIC = "italic";
static final String CODE = "code";
static final String LINK = "link";
@Nullable
@Override
public Object strongEmphasis() {
return span(BOLD);
}
@Nullable
@Override
public Object emphasis() {
return span(ITALIC);
}
@Nullable
@Override
public Object blockQuote(@NonNull MarkwonTheme theme) {
return null;
}
@Nullable
@Override
public Object code(@NonNull MarkwonTheme theme, boolean multiline) {
return span(CODE, args("multiline", multiline));
}
@Nullable
@Override
public Object orderedListItem(@NonNull MarkwonTheme theme, int startNumber) {
return null;
}
@Nullable
@Override
public Object bulletListItem(@NonNull MarkwonTheme theme, int level) {
return null;
}
@Nullable
@Override
public Object thematicBreak(@NonNull MarkwonTheme theme) {
return null;
}
@Nullable
@Override
public Object heading(@NonNull MarkwonTheme theme, int level) {
return null;
}
@Nullable
@Override
public Object paragraph(boolean inTightList) {
return null;
}
@Nullable
@Override
public Object image(@NonNull MarkwonTheme theme, @NonNull String destination, @NonNull AsyncDrawableLoader loader, @NonNull ImageSizeResolver imageSizeResolver, @Nullable ImageSize imageSize, boolean replacementTextIsLink) {
return null;
}
@Nullable
@Override
public Object link(@NonNull MarkwonTheme theme, @NonNull String destination, @NonNull LinkSpan.Resolver resolver) {
return span(LINK, args("href", destination));
}
}

View File

@ -0,0 +1,18 @@
package ru.noties.markwon.core.visitor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static org.junit.Assert.*;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class BlockQuoteNodeVisitorTest {
@Test
public void test() {
fail();
}
}

View File

@ -0,0 +1 @@
**_bold italic_**

View File

@ -1,5 +0,0 @@
input: "**_bold italic_**"
output:
- b:
- i: "bold italic"

View File

@ -0,0 +1,9 @@
```java
final String s = null;
```
```html
<html></html>
```
```
nothing here
```

View File

@ -1,17 +0,0 @@
input: |-
```java
final String s = null;
```
```html
<html></html>
```
```
nothing here
```
output:
- code-block: "final String s = null;"
- "\n\n"
- code-block: "<html></html>"
- "\n\n"
- code-block: "nothing here"

View File

@ -0,0 +1 @@
**bold *bold italic `bold italic code` bold italic* bold** normal

View File

@ -1,12 +0,0 @@
input: |-
**bold *bold italic `bold italic code` bold italic* bold** normal
output:
- b:
- "bold "
- i:
- "bold italic "
- code: "bold italic code"
- " bold italic"
- " bold"
- " normal"

View File

@ -0,0 +1,2 @@
Here is some [link](https://my.href)
**bold _bold italic_ bold** normal

View File

@ -1,23 +0,0 @@
description: Defining test case format
input: |-
Here is some [link](https://my.href)
**bold _bold italic_ bold** normal
config:
use-paragraphs: false
use-html: false
soft-break-adds-new-line: false
html-allow-non-closed-tags: false
output:
- "Here is some "
- a: "link"
href: "https://my.href"
- " "
- b:
- "bold "
- i: "bold italic" #equals to: `- i: - text: "bold italic"`
- " bold"
- " normal"

View File

@ -11,5 +11,6 @@ include ':app',
':markwon-html', ':markwon-html',
':markwon-view', ':markwon-view',
':markwon-test-span', ':markwon-test-span',
':markwon-test-util',
':sample-custom-extension', ':sample-custom-extension',
':sample-latex-math' ':sample-latex-math'