From a1807aa84b4eb6fc7172c937dc488624adaf69a3 Mon Sep 17 00:00:00 2001 From: me Date: Wed, 4 Feb 2026 20:26:02 +0500 Subject: [PATCH] add solutions for hw7 (markup) and tests --- .gitea/workflows/markup.yml | 22 +++ java/markup/AbstractMarkup.java | 35 +++++ java/markup/Emphasis.java | 24 +++ java/markup/ListElement.java | 6 + java/markup/ListItem.java | 26 ++++ java/markup/ListItemContent.java | 6 + java/markup/MarkupElement.java | 7 + java/markup/MarkupListTest.java | 248 +++++++++++++++++++++++++++++++ java/markup/MarkupTest.java | 97 ++++++++++++ java/markup/MarkupTester.java | 71 +++++++++ java/markup/OrderedList.java | 29 ++++ java/markup/Paragraph.java | 29 ++++ java/markup/Strong.java | 24 +++ java/markup/Text.java | 24 +++ java/markup/UnorderedList.java | 29 ++++ java/markup/package-info.java | 7 + 16 files changed, 684 insertions(+) create mode 100644 .gitea/workflows/markup.yml create mode 100644 java/markup/AbstractMarkup.java create mode 100644 java/markup/Emphasis.java create mode 100644 java/markup/ListElement.java create mode 100644 java/markup/ListItem.java create mode 100644 java/markup/ListItemContent.java create mode 100644 java/markup/MarkupElement.java create mode 100644 java/markup/MarkupListTest.java create mode 100644 java/markup/MarkupTest.java create mode 100644 java/markup/MarkupTester.java create mode 100644 java/markup/OrderedList.java create mode 100644 java/markup/Paragraph.java create mode 100644 java/markup/Strong.java create mode 100644 java/markup/Text.java create mode 100644 java/markup/UnorderedList.java create mode 100644 java/markup/package-info.java diff --git a/.gitea/workflows/markup.yml b/.gitea/workflows/markup.yml new file mode 100644 index 0000000..ad14395 --- /dev/null +++ b/.gitea/workflows/markup.yml @@ -0,0 +1,22 @@ +name: Markup Tests + +on: + push: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Compile Java + run: | + mkdir -p out + javac -d out $(find java -name "*.java") + + - name: Run Markup tests + run: | + java -ea -cp out markup.MarkupTest Base 3233 3435 3637 3839 4142 4749 diff --git a/java/markup/AbstractMarkup.java b/java/markup/AbstractMarkup.java new file mode 100644 index 0000000..59b7e07 --- /dev/null +++ b/java/markup/AbstractMarkup.java @@ -0,0 +1,35 @@ +package markup; + +import java.util.List; + +public abstract class AbstractMarkup implements MarkupElement { + protected final List elements; + + public AbstractMarkup(List elements) { + this.elements = elements; + } + + protected void toMarkdown(StringBuilder sb, String delimiter) { + sb.append(delimiter); + for (MarkupElement element : elements) { + element.toMarkdown(sb); + } + sb.append(delimiter); + } + + protected void toHtml(StringBuilder sb, String tag) { + sb.append("<").append(tag).append(">"); + for (MarkupElement element : elements) { + element.toHtml(sb); + } + sb.append(""); + } + + protected void toTex(StringBuilder sb, String command) { + sb.append(command).append("{"); + for (MarkupElement element : elements) { + element.toTex(sb); + } + sb.append("}"); + } +} \ No newline at end of file diff --git a/java/markup/Emphasis.java b/java/markup/Emphasis.java new file mode 100644 index 0000000..1b59617 --- /dev/null +++ b/java/markup/Emphasis.java @@ -0,0 +1,24 @@ +package markup; + +import java.util.List; + +public class Emphasis extends AbstractMarkup { + public Emphasis(List elements) { + super(elements); + } + + @Override + public void toMarkdown(StringBuilder sb) { + toMarkdown(sb, "*"); + } + + @Override + public void toHtml(StringBuilder sb) { + toHtml(sb, "em"); + } + + @Override + public void toTex(StringBuilder sb) { + toTex(sb, "\\emph"); + } +} \ No newline at end of file diff --git a/java/markup/ListElement.java b/java/markup/ListElement.java new file mode 100644 index 0000000..f754457 --- /dev/null +++ b/java/markup/ListElement.java @@ -0,0 +1,6 @@ +package markup; + +public interface ListElement { + void toHtml(StringBuilder sb); + void toTex(StringBuilder sb); +} \ No newline at end of file diff --git a/java/markup/ListItem.java b/java/markup/ListItem.java new file mode 100644 index 0000000..b464ddc --- /dev/null +++ b/java/markup/ListItem.java @@ -0,0 +1,26 @@ +package markup; + +import java.util.List; + +public class ListItem { + private final List elements; + + public ListItem(List elements) { + this.elements = elements; + } + + public void toHtml(StringBuilder sb) { + sb.append("
  • "); + for (ListItemContent element : elements) { + element.toHtml(sb); + } + sb.append("
  • "); + } + + public void toTex(StringBuilder sb) { + sb.append("\\item "); + for (ListItemContent element : elements) { + element.toTex(sb); + } + } +} \ No newline at end of file diff --git a/java/markup/ListItemContent.java b/java/markup/ListItemContent.java new file mode 100644 index 0000000..9ef835e --- /dev/null +++ b/java/markup/ListItemContent.java @@ -0,0 +1,6 @@ +package markup; + +public interface ListItemContent { + void toHtml(StringBuilder sb); + void toTex(StringBuilder sb); +} \ No newline at end of file diff --git a/java/markup/MarkupElement.java b/java/markup/MarkupElement.java new file mode 100644 index 0000000..d6f3d48 --- /dev/null +++ b/java/markup/MarkupElement.java @@ -0,0 +1,7 @@ +package markup; + +public interface MarkupElement { + void toMarkdown(StringBuilder sb); + void toHtml(StringBuilder sb); + void toTex(StringBuilder sb); +} \ No newline at end of file diff --git a/java/markup/MarkupListTest.java b/java/markup/MarkupListTest.java new file mode 100644 index 0000000..fbc8b79 --- /dev/null +++ b/java/markup/MarkupListTest.java @@ -0,0 +1,248 @@ +package markup; + +import base.Asserts; +import base.Selector; +import base.TestCounter; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.WildcardType; +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) + */ +public final class MarkupListTest { + public static final Consumer VARIANT = MarkupListTest.variant( + "Tex", Map.ofEntries( + Map.entry("

    ", "\\par{}"), Map.entry("

    ", ""), + Map.entry("", "\\emph{"), Map.entry("", "}"), + Map.entry("", "\\textbf{"), Map.entry("", "}"), + Map.entry("", "\\textst{"), Map.entry("", "}"), + Map.entry("
      ", "\\begin{itemize}"), Map.entry("
    ", "\\end{itemize}"), + Map.entry("
      ", "\\begin{enumerate}"), Map.entry("
    ", "\\end{enumerate}"), + Map.entry("
  • ", "\\item "), Map.entry("
  • ", "") + ) + ); + + + public static final Selector SELECTOR = new Selector(MarkupListTest.class) + .variant("3637", VARIANT) + .variant("3839", VARIANT) + .variant("4142", VARIANT) + .variant("4749", VARIANT) + + ; + + private MarkupListTest() { + } + + public static Consumer variant(final String name, final Map mapping) { + return MarkupTester.variant(MarkupListTest::test, name, mapping); + } + + private static void test(final MarkupTester.Checker checker) { + final Paragraph paragraph0 = new Paragraph(List.of(new Text("hello"))); + final String paragraph0Markup = "

    hello

    "; + + final Paragraph paragraph1 = new Paragraph(List.of( + new Strong(List.of( + new Text("1"), + new Strikeout(List.of( + new Text("2"), + new Emphasis(List.of( + new Text("3"), + new Text("4") + )), + new Text("5") + )), + new Text("6") + )) + )); + final String paragraph1Markup = "

    123456

    "; + + final Paragraph paragraph2 = new Paragraph(List.of(new Strong(List.of( + new Text("sdq"), + new Strikeout(List.of(new Emphasis(List.of(new Text("r"))), new Text("vavc"))), + new Text("zg"))) + )); + final String paragraph2Markup = "

    sdqrvavczg

    "; + + checker.test(paragraph0, paragraph0Markup); + checker.test(paragraph1, paragraph1Markup); + checker.test(paragraph2, paragraph2Markup); + + final ListItem li1 = new ListItem(List.of(new Paragraph(List.of(new Text("1.1"))), new Paragraph(List.of(new Text("1.2"))))); + final String li1Markup = "

    1.1

    1.2

    "; + final ListItem li2 = new ListItem(List.of(new Paragraph(List.of(new Text("2"))))); + final String li2Markup = "

    2

    "; + final ListItem pli1 = new ListItem(List.of(paragraph1)); + final ListItem pli2 = new ListItem(List.of(paragraph2)); + + final ListItem nestedUl = new ListItem(List.of(ul(li1, li2))); + final String nestedUlMarkup = ul(li1Markup, li2Markup); + + checker.test(ul(li1), ul(li1Markup)); + checker.test(ul(li2), ul(li2Markup)); + checker.test(ul(pli1), ul(paragraph1Markup)); + checker.test(ul(pli2), ul(paragraph2Markup)); + checker.test(ul(li1, li2), nestedUlMarkup); + checker.test(ul(pli1, pli2), ul(paragraph1Markup, paragraph2Markup)); + checker.test(ul(nestedUl), ul(nestedUlMarkup)); + + final ListItem nestedOl = new ListItem(List.of(ol(li1, li2))); + final String nestedOlMarkup = ol(li1Markup, li2Markup); + checker.test(ol(li1), ol(li1Markup)); + checker.test(ol(li2), ol(li2Markup)); + checker.test(ol(pli1), ol(paragraph1Markup)); + checker.test(ol(pli2), ol(paragraph2Markup)); + checker.test(ol(li1, li2), nestedOlMarkup); + checker.test(ol(pli1, pli2), ol(paragraph1Markup, paragraph2Markup)); + checker.test(ol(nestedOl), ol(nestedOlMarkup)); + + checker.test(ul(nestedUl, nestedOl), ul(nestedUlMarkup, nestedOlMarkup)); + checker.test(ol(nestedUl, nestedOl), ol(nestedUlMarkup, nestedOlMarkup)); + + checker.test( + ul(nestedUl, nestedOl, pli1, pli2), + ul(nestedUlMarkup, nestedOlMarkup, paragraph1Markup, paragraph2Markup) + ); + checker.test( + ol(nestedUl, nestedOl, pli1, pli2), + ol(nestedUlMarkup, nestedOlMarkup, paragraph1Markup, paragraph2Markup) + ); + + checker.test( + new Paragraph(List.of(new Strikeout(List.of(new Strong(List.of(new Strikeout(List.of(new Emphasis(List.of(new Strikeout(List.of(new Text("е"), new Text("г"), new Text("ц"))), new Strong(List.of(new Text("щэш"), new Text("игепы"), new Text("хм"))), new Strikeout(List.of(new Text("б"), new Text("е"))))), new Strong(List.of(new Strong(List.of(new Text("ю"), new Text("дърб"), new Text("еи"))), new Emphasis(List.of(new Text("зр"), new Text("дуаужш"), new Text("ш"))), new Strong(List.of(new Text("рб"), new Text("щ"))))), new Text("a"))), new Strikeout(List.of(new Text("no"), new Text("ddw"), new Strong(List.of(new Emphasis(List.of(new Text("щ"), new Text("ча"), new Text("эгфш"))), new Strikeout(List.of(new Text("фяи"), new Text("штел"), new Text("н"))), new Strikeout(List.of(new Text("ту"), new Text("ьъг"))))))), new Emphasis(List.of(new Emphasis(List.of(new Text("tc"), new Strong(List.of(new Text("щ"), new Text("э"), new Text("то"))), new Strong(List.of(new Text("а"), new Text("ц"))))), new Emphasis(List.of(new Text("hld"), new Emphasis(List.of(new Text("ыо"), new Text("яще"), new Text("лэ"))), new Text("i"))), new Text("tm"))))), new Emphasis(List.of(new Text("q"), new Emphasis(List.of(new Text("zn"), new Strong(List.of(new Text("mnphd"), new Strong(List.of(new Text("г"), new Text("вй"), new Text("шш"))), new Strong(List.of(new Text("з"), new Text("ввъ"))))), new Strikeout(List.of(new Emphasis(List.of(new Text("у"), new Text("в"), new Text("у"))), new Strikeout(List.of(new Text("лдяр"), new Text("зоъ"), new Text("эн"))), new Strikeout(List.of(new Text("в"), new Text("м"))))))), new Strikeout(List.of(new Text("cqqzbhtn"), new Text("i"), new Strong(List.of(new Text("i"), new Strikeout(List.of(new Text("э"), new Text("як"))), new Text("i"))))))), new Text("ef"))), new Strikeout(List.of(new Strikeout(List.of(new Strong(List.of(new Emphasis(List.of(new Strong(List.of(new Text("шец"), new Text("ю"), new Text("дрк"))), new Strikeout(List.of(new Text("е"), new Text("мь"), new Text("б"))), new Strong(List.of(new Text("еп"), new Text("ряэк"))))), new Strong(List.of(new Text("t"), new Emphasis(List.of(new Text("сы"), new Text("в"), new Text("к"))), new Text("rf"))), new Text("x"))), new Emphasis(List.of(new Emphasis(List.of(new Emphasis(List.of(new Text("юд"), new Text("чх"), new Text("яжюи"))), new Emphasis(List.of(new Text("и"), new Text("п"), new Text("вх"))), new Text("mf"))), new Emphasis(List.of(new Strong(List.of(new Text("шб"), new Text("вс"), new Text("е"))), new Strong(List.of(new Text("т"), new Text("шж"), new Text("ину"))), new Strong(List.of(new Text("ыа"), new Text("ьскю"))))), new Text("x"))), new Strikeout(List.of(new Emphasis(List.of(new Strong(List.of(new Text("в"), new Text("зыйгг"), new Text("о"))), new Strikeout(List.of(new Text("ок"), new Text("уч"), new Text("л"))), new Text("v"))), new Emphasis(List.of(new Strong(List.of(new Text("н"), new Text("ъчжфзтодг"), new Text("кыч"))), new Strikeout(List.of(new Text("вд"), new Text("лпбзс"), new Text("гщ"))), new Emphasis(List.of(new Text("ъ"), new Text("й"))))), new Text("n"))))), new Strong(List.of(new Strong(List.of(new Emphasis(List.of(new Strong(List.of(new Text("ю"), new Text("сдям"), new Text("ш"))), new Strong(List.of(new Text("ц"), new Text("еящж"), new Text("шн"))), new Text("upg"))), new Text("d"), new Strikeout(List.of(new Text("xu"), new Strikeout(List.of(new Text("кл"), new Text("еок"), new Text("с"))), new Strong(List.of(new Text("а"), new Text("ь"))))))), new Strong(List.of(new Strikeout(List.of(new Text("zn"), new Text("syb"), new Strong(List.of(new Text("ъзюкмц"), new Text("ндюз"))))), new Strong(List.of(new Strikeout(List.of(new Text("н"), new Text("с"), new Text("ь"))), new Strikeout(List.of(new Text("зьуес"), new Text("к"), new Text("и"))), new Strong(List.of(new Text("тв"), new Text("у"))))), new Strikeout(List.of(new Strong(List.of(new Text("ы"), new Text("г"), new Text("гм"))), new Strong(List.of(new Text("сыр"), new Text("я"), new Text("т"))), new Emphasis(List.of(new Text("ь"), new Text("махыы"))))))), new Text("k"))), new Text("q"))), new Strikeout(List.of(new Text("b"), new Text("o"), new Emphasis(List.of(new Strong(List.of(new Strikeout(List.of(new Strong(List.of(new Text("х"), new Text("йз"), new Text("ж"))), new Text("udlh"), new Strikeout(List.of(new Text("чъ"), new Text("с"))))), new Strong(List.of(new Strong(List.of(new Text("ю"), new Text("т"), new Text("яъайл"))), new Strong(List.of(new Text("х"), new Text("ри"), new Text("в"))), new Strong(List.of(new Text("щ"), new Text("вт"))))), new Text("m"))), new Text("vzb"), new Strong(List.of(new Text("oi"), new Text("r"), new Text("inpz"))))))))), + "

    егцщэшигепыхмбеюдърбеизрдуаужшшрбщanoddwщчаэгфшфяиштелнтуьъгtcщэтоацhldыоящелэitmqznmnphdгвйшшзввъувулдярзоъэнвмcqqzbhtniiэякiefшецюдркемьбепряэкtсывкrfxюдчхяжюиипвхmfшбвсетшжинуыаьскюxвзыйггоокучлvнъчжфзтодгкычвдлпбзсгщъйnюсдямшцеящжшнupgdxuклеоксаьznsybъзюкмцндюзнсьзьуескитвуыггмсырятьмахыыkqboхйзжudlhчъсютяъайлхривщвтmvzboirinpz

    " + ); + + checker.test( + new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("е"))), new Paragraph(List.of(new Text("х"))))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new Paragraph(List.of(new Text("эш"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("цць"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("м"))))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("ю"))), new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))))), new Paragraph(List.of(new Emphasis(List.of(new Emphasis(List.of(new Text("узр"))), new Text("i"), new Emphasis(List.of(new Text("аужш"))), new Text("ш"))), new Strong(List.of(new Text("c"), new Strikeout(List.of(new Text("щ"))), new Text("a"), new Text("з"))), new Strong(List.of(new Emphasis(List.of(new Text("ь"))), new Text("ddw"), new Text("зщ"), new Text("ча"))), new Emphasis(List.of(new Strong(List.of(new Text("гфш"))), new Strikeout(List.of(new Text("фяи"))), new Text("штел"), new Text("н"))))), new OrderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("юцщ"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("э"))))))))), new ListItem(List.of(new OrderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new Paragraph(List.of(new Text("ж"))))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ыеж"))), new Paragraph(List.of(new Text("ыо"))))), new ListItem(List.of(new Paragraph(List.of(new Text("ще"))), new Paragraph(List.of(new Text("щш"))))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()))))), new OrderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("щосз"))), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("сс"))), new UnorderedList(List.of()))))), new Paragraph(List.of(new Text("yu"), new Text("w"), new Text("ghtry"), new Emphasis(List.of(new Strikeout(List.of(new Text("прф"))), new Emphasis(List.of(new Text("р"))), new Text("я"), new Text("я"))))), new Paragraph(List.of(new Text("w"), new Strong(List.of(new Text("k"), new Emphasis(List.of(new Text("н"))), new Strikeout(List.of(new Text("в"))), new Text("м"))), new Strikeout(List.of(new Text("cqqzbhtn"), new Text("i"), new Text("м"), new Text("ю"))), new Strikeout(List.of(new Strong(List.of(new Text("ш"))), new Strong(List.of(new Text("к"))), new Text("ж"), new Text("б"))))))), new ListItem(List.of(new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("е"))), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("ед"))), new UnorderedList(List.of()))))), new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new Paragraph(List.of(new Text("п"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("э"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("к"))))))), new Paragraph(List.of(new Strong(List.of(new Strong(List.of(new Text("с"))), new Text("x"), new Emphasis(List.of(new Text("йюд"))), new Text("чх"))), new Strikeout(List.of(new Strong(List.of(new Text("жюи"))), new Emphasis(List.of(new Text("и"))), new Strong(List.of(new Text("ьмт"))), new Text("йц"))), new Emphasis(List.of(new Strong(List.of(new Text("шб"))), new Strong(List.of(new Text("еф"))), new Text("ут"), new Text("шж"))), new Emphasis(List.of(new Emphasis(List.of(new Text("ну"))), new Strong(List.of(new Text("ыа"))), new Text("ьскю"), new Text("чз"))))))), new ListItem(List.of(new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new Paragraph(List.of(new Text("ыйгг"))))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()), new Paragraph(List.of(new Text("ф"))))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ч"))))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))))), new Paragraph(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("э"))), new Text("amqcfdzrg"), new Emphasis(List.of(new Text("т"))), new Text("з"))), new Text("b"), new Emphasis(List.of(new Strikeout(List.of(new Text("энфны"))), new Strikeout(List.of(new Text("гщ"))), new Text("ы"), new Text("шя"))), new Text("uvpqzhn"))), new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ящж"))), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("цлл"))))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ъ"))))))), new Paragraph(List.of(new Strong(List.of(new Strong(List.of(new Text("ъ"))), new Strikeout(List.of(new Text("кл"))), new Strikeout(List.of(new Text("счи"))), new Text("ра"))), new Strong(List.of(new Strikeout(List.of(new Text("ь"))), new Text("zn"), new Text("ъ"), new Text("умъъзюкмц"))), new Strikeout(List.of(new Emphasis(List.of(new Text("дюз"))), new Strong(List.of(new Text("эы"))), new Text("и"), new Text("р"))), new Emphasis(List.of(new Strong(List.of(new Text("ьуес"))), new Strikeout(List.of(new Text("йгтв"))), new Text("у"), new Text("еы"))))))))), + "
        1. е

          х

            1. эш

              • цць

                • м

                      1. ю

                                  узрiаужшшcщьddwзщчагфшфяиштелн

                                          1. юцщ

                                                  1. э

                                                      1. ж

                                                        1. ыеж

                                                          ыо

                                                        2. ще

                                                          щш

                                                            1. щосз

                                                                          • сс

                                                                            yuwghtryпрфряя

                                                                            wkнвмcqqzbhtniмюшкжб

                                                                                                        • е

                                                                                                              • ед

                                                                                                                    1. п

                                                                                                                      • э

                                                                                                                              1. к

                                                                                                                              сxйюдчхжюииьмтйцшбефутшжнуыаьскючз

                                                                                                                                  1. ыйгг

                                                                                                                                      • ф

                                                                                                                                        1. ч

                                                                                                                                            эamqcfdzrgтзbэнфныгщышяuvpqzhn

                                                                                                                                                    1. ящж

                                                                                                                                                        1. цлл

                                                                                                                                                          1. ъ

                                                                                                                                                          ъклсчираьznъумъъзюкмцдюзэыирьуесйгтвуеы

                                                                                                                                                        " + ); + + checker.test( + new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("е"))))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("нцйцць"))), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("м"))))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ю"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("щ"))))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))), new Paragraph(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("зр"))), new Text("i"), new Text("и"), new Text("г"), new Text("с"))), new Strong(List.of(new Strong(List.of(new Text("шмрб"))), new Strong(List.of(new Text("ь"))), new Text("з"), new Text("з"), new Text("фь"))), new Text("ddw"), new Strong(List.of(new Emphasis(List.of(new Text("щ"))), new Strong(List.of(new Text("втъп"))), new Text("ш"), new Text("ч"), new Text("фяи"))), new Strong(List.of(new Emphasis(List.of(new Text("тел"))), new Text("н"), new Text("ь"), new Text("ддзюцщ"), new Text("пт"))))), new Paragraph(List.of(new Text("n"), new Text("zi"), new Strong(List.of(new Emphasis(List.of(new Text("ж"))), new Text("t"), new Text("ыеж"), new Text("ч"), new Text("г"))), new Text("kwt"), new Strong(List.of(new Strong(List.of(new Text("э"))), new Text("нх"), new Text("уи"), new Text("о"), new Text("п"))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("ж"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("сс"))))), new ListItem(List.of(new Paragraph(List.of(new Text("т"))))))))), new ListItem(List.of(new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("щу"))))))), new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ир"))))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("зоъ"))), new Paragraph(List.of(new Text("е"))))), new ListItem(List.of(new Paragraph(List.of(new Text("в"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))), new OrderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("сснюпия"))), new Paragraph(List.of(new Text("щ"))))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("э"))), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("м"))), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("е"))), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))))), new ListItem(List.of(new Paragraph(List.of(new Strong(List.of(new Emphasis(List.of(new Text("п"))), new Text("l"), new Text("р"), new Text("п"), new Text("уерсы"))), new Strikeout(List.of(new Strikeout(List.of(new Text("к"))), new Text("rf"), new Text("екйюд"), new Text("чх"), new Text("яжюи"))), new Emphasis(List.of(new Strikeout(List.of(new Text("кьмт"))), new Strikeout(List.of(new Text("рщюереф"))), new Text("ут"), new Text("шж"), new Text("ину"))), new Strong(List.of(new Strong(List.of(new Text("дгб"))), new Emphasis(List.of(new Text("кю"))), new Text("чз"), new Text("мв"), new Text("зыйгг"))), new Strong(List.of(new Strikeout(List.of(new Text("ш"))), new Text("ф"), new Text("я"), new Text("ч"), new Text("ме"))))), new Paragraph(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("э"))), new Text("amqcfdzrg"), new Text("кыч"), new Text("к"), new Text("я"))), new Strikeout(List.of(new Strong(List.of(new Text("нфны"))), new Strikeout(List.of(new Text("гщ"))), new Text("ы"), new Text("шя"), new Text("е"))), new Strong(List.of(new Strong(List.of(new Text("ъю"))), new Emphasis(List.of(new Text("яхе"))), new Text("б"), new Text("бц"), new Text("еящж"))), new Text("cn"), new Emphasis(List.of(new Strong(List.of(new Text("як"))), new Text("въ"), new Text("оде"), new Text("кл"), new Text("еок"))))), new Paragraph(List.of(new Strikeout(List.of(new Strong(List.of(new Text("а"))), new Strong(List.of(new Text("иь"))), new Text("аш"), new Text("ъ"), new Text("умъъзюкмц"))), new Strikeout(List.of(new Emphasis(List.of(new Text("дюз"))), new Strong(List.of(new Text("эы"))), new Text("и"), new Text("р"), new Text("зьуес"))), new Strikeout(List.of(new Strikeout(List.of(new Text("и"))), new Strong(List.of(new Text("тв"))), new Text("у"), new Text("еы"), new Text("г"))), new Text("atsui"), new Strikeout(List.of(new Text("y"), new Text("щз"), new Text("н"), new Text("е"), new Text("э"))))), new Paragraph(List.of(new Emphasis(List.of(new Text("o"), new Text("rz"), new Text("к"), new Text("к"), new Text("б"))), new Emphasis(List.of(new Strong(List.of(new Text("ьх"))), new Emphasis(List.of(new Text("ил"))), new Text("ф"), new Text("пмгр"), new Text("и"))), new Emphasis(List.of(new Text("lhovy"), new Emphasis(List.of(new Text("ъайл"))), new Text("ь"), new Text("э"), new Text("п"))), new Strikeout(List.of(new Strong(List.of(new Text("щщ"))), new Strong(List.of(new Text("х"))), new Text("б"), new Text("е"), new Text("к"))), new Emphasis(List.of(new Strikeout(List.of(new Text("чяя"))), new Text("х"), new Text("я"), new Text("р"), new Text("ю"))))), new Paragraph(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("йл"))), new Emphasis(List.of(new Text("змл"))), new Text("б"), new Text("аж"), new Text("ъ"))), new Strong(List.of(new Strong(List.of(new Text("энян"))), new Emphasis(List.of(new Text("ю"))), new Text("п"), new Text("ымы"), new Text("ешьи"))), new Emphasis(List.of(new Strong(List.of(new Text("к"))), new Strikeout(List.of(new Text("яэ"))), new Text("п"), new Text("юзщ"), new Text("я"))), new Text("w"), new Emphasis(List.of(new Text("se"), new Text("о"), new Text("ъязе"), new Text("гзко"), new Text("ъ"))))))), new ListItem(List.of(new OrderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("ч"))), new Paragraph(List.of(new Text("пз"))))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("й"))))), new ListItem(List.of(new Paragraph(List.of(new Text("лчж"))), new Paragraph(List.of(new Text("чв"))))), new ListItem(List.of(new Paragraph(List.of(new Text("с"))), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("ь"))), new Paragraph(List.of(new Text("ъ"))))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("вп"))), new Paragraph(List.of(new Text("р"))))), new ListItem(List.of(new OrderedList(List.of()))))), new Paragraph(List.of(new Text("ds"), new Emphasis(List.of(new Strikeout(List.of(new Text("дйгып"))), new Emphasis(List.of(new Text("и"))), new Text("сэ"), new Text("е"), new Text("юо"))), new Emphasis(List.of(new Strikeout(List.of(new Text("бвщ"))), new Text("d"), new Text("ъ"), new Text("ит"), new Text("бщ"))), new Emphasis(List.of(new Text("w"), new Strikeout(List.of(new Text("гсщ"))), new Text("ъ"), new Text("срцч"), new Text("хе"))), new Text("m"))), new OrderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("е"))), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("оото"))), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))))), new ListItem(List.of(new Paragraph(List.of(new Emphasis(List.of(new Emphasis(List.of(new Text("я"))), new Strong(List.of(new Text("сшъ"))), new Text("лм"), new Text("ы"), new Text("рц"))), new Emphasis(List.of(new Strikeout(List.of(new Text("я"))), new Strikeout(List.of(new Text("ъ"))), new Text("п"), new Text("дхдэ"), new Text("щэ"))), new Emphasis(List.of(new Text("dtt"), new Emphasis(List.of(new Text("дрм"))), new Text("в"), new Text("яешц"), new Text("йшй"))), new Strong(List.of(new Strong(List.of(new Text("мив"))), new Text("u"), new Text("у"), new Text("к"), new Text("б"))), new Strikeout(List.of(new Text("c"), new Text("э"), new Text("м"), new Text("п"), new Text("о"))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("х"))), new Paragraph(List.of(new Text("й"))))), new ListItem(List.of(new Paragraph(List.of(new Text("эя"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("ф"))))), new ListItem(List.of(new OrderedList(List.of()))))), new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("щ"))))), new ListItem(List.of(new Paragraph(List.of(new Text("чи"))), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("к"))), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("ф"))))))), new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("м"))), new Paragraph(List.of(new Text("щцс"))))), new ListItem(List.of(new Paragraph(List.of(new Text("вус"))), new Paragraph(List.of(new Text("я"))))), new ListItem(List.of(new Paragraph(List.of(new Text("кр"))))), new ListItem(List.of(new UnorderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("я"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("гр"))))), new ListItem(List.of(new Paragraph(List.of(new Text("ж"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()))))))))), + "
                                                                                                                                                            1. е

                                                                                                                                                                    1. нцйцць

                                                                                                                                                                      1. м

                                                                                                                                                                            1. ю

                                                                                                                                                                              • щ

                                                                                                                                                                                    зрiигсшмрбьззфьddwщвтъпшчфяителньддзюцщпт

                                                                                                                                                                                    nziжtыежчгkwtэнхуиоп

                                                                                                                                                                                        1. ж

                                                                                                                                                                                              • сс

                                                                                                                                                                                              • т

                                                                                                                                                                                                              • щу

                                                                                                                                                                                                                1. ир

                                                                                                                                                                                                                    1. зоъ

                                                                                                                                                                                                                      е

                                                                                                                                                                                                                    2. в

                                                                                                                                                                                                                        1. сснюпия

                                                                                                                                                                                                                          щ

                                                                                                                                                                                                                            • э

                                                                                                                                                                                                                                    • м

                                                                                                                                                                                                                                                            1. е

                                                                                                                                                                                                                                                                1. пlрпуерсыкrfекйюдчхяжюикьмтрщюерефутшжинудгбкючзмвзыйггшфячме

                                                                                                                                                                                                                                                                  эamqcfdzrgкычкянфныгщышяеъюяхеббцеящжcnяквъодеклеок

                                                                                                                                                                                                                                                                  аиьашъумъъзюкмцдюзэыирзьуеситвуеыгatsuiyщзнеэ

                                                                                                                                                                                                                                                                  orzккбьхилфпмгриlhovyъайльэпщщхбекчяяхярю

                                                                                                                                                                                                                                                                  йлзмлбажъэнянюпымыешьикяэпюзщяwseоъязегзкоъ

                                                                                                                                                                                                                                                                  1. ч

                                                                                                                                                                                                                                                                    пз

                                                                                                                                                                                                                                                                    1. й

                                                                                                                                                                                                                                                                    2. лчж

                                                                                                                                                                                                                                                                      чв

                                                                                                                                                                                                                                                                    3. с

                                                                                                                                                                                                                                                                        • ь

                                                                                                                                                                                                                                                                          ъ

                                                                                                                                                                                                                                                                                • вп

                                                                                                                                                                                                                                                                                  р

                                                                                                                                                                                                                                                                                  dsдйгыписэеюобвщdъитбщwгсщъсрцчхеm

                                                                                                                                                                                                                                                                                              • е

                                                                                                                                                                                                                                                                                                      • оото

                                                                                                                                                                                                                                                                                                              • ясшълмырцяъпдхдэщэdttдрмвяешцйшймивuукбcэмпо

                                                                                                                                                                                                                                                                                                                    1. х

                                                                                                                                                                                                                                                                                                                      й

                                                                                                                                                                                                                                                                                                                    2. эя

                                                                                                                                                                                                                                                                                                                        • ф

                                                                                                                                                                                                                                                                                                                            1. щ

                                                                                                                                                                                                                                                                                                                            2. чи

                                                                                                                                                                                                                                                                                                                              1. к

                                                                                                                                                                                                                                                                                                                                    1. ф

                                                                                                                                                                                                                                                                                                                                        • м

                                                                                                                                                                                                                                                                                                                                          щцс

                                                                                                                                                                                                                                                                                                                                        • вус

                                                                                                                                                                                                                                                                                                                                          я

                                                                                                                                                                                                                                                                                                                                        • кр

                                                                                                                                                                                                                                                                                                                                            • я

                                                                                                                                                                                                                                                                                                                                              • гр

                                                                                                                                                                                                                                                                                                                                              • ж

                                                                                                                                                                                                                                                                                                                                                  " + ); + + checkTypes(); + } + + private static OrderedList ol(final ListItem... items) { + return new OrderedList(List.of(items)); + } + + private static String ol(final String... items) { + return list("ol", items); + } + + private static UnorderedList ul(final ListItem... items) { + return new UnorderedList(List.of(items)); + } + + private static String ul(final String... items) { + return list("ul", items); + } + + private static String list(final String type, final String[] items) { + return "<" + type + ">" + Stream.of(items).map(item -> "
                                                                                                                                                                                                                                                                                                                                                • " + item + "
                                                                                                                                                                                                                                                                                                                                                • ").collect(Collectors.joining()) + ""; + } + + private static Class loadClass(final String name) { + try { + return Class.forName(name); + } catch (final ClassNotFoundException e) { + throw Asserts.error("Cannot find class %s: %s", name, e); + } + } + + private static Map> loadClasses(final String... names) { + return Arrays.stream(names) + .collect(Collectors.toUnmodifiableMap(Function.identity(), name -> loadClass("markup." + name))); + } + + private static void checkTypes() { + final Map> classes = loadClasses("Text", "Emphasis", "Strikeout", "Strong", "Paragraph", "OrderedList", "UnorderedList", "ListItem"); + final String[] inlineClasses = {"Text", "Emphasis", "Strikeout", "Strong"}; + + checkConstructor(classes, "OrderedList", "ListItem"); + checkConstructor(classes, "UnorderedList", "ListItem"); + checkConstructor(classes, "ListItem", "OrderedList", "UnorderedList", "Paragraph"); + Stream.of("Paragraph", "Emphasis", "Strong", "Strikeout") + .forEach(parent -> checkConstructor(classes, parent, inlineClasses)); + } + + private static void checkConstructor(final Map> classes, final String parent, final String... children) { + new TypeChecker(classes, parent, children).checkConstructor(); + } + + private static class TypeChecker { + private final Map> classes; + private final Set> children; + private final Class parent; + + public TypeChecker(final Map> classes, final String parent, final String[] children) { + this.classes = classes; + this.children = Arrays.stream(children).map(classes::get).collect(Collectors.toUnmodifiableSet()); + this.parent = Objects.requireNonNull(classes.get(parent)); + } + + private void checkClassType(final Class classType) { + final Predicate> isAssignableFrom = classType::isAssignableFrom; + checkType(parent, Predicate.not(isAssignableFrom), "not ", children.stream()); + checkType(parent, isAssignableFrom, "", classes.values().stream().filter(Predicate.not(children::contains))); + } + + private static void checkType(final Class parent, final Predicate> predicate, final String not, final Stream> children) { + children.filter(predicate).findAny().ifPresent(child -> { + throw Asserts.error("%s is %scompatible with child of type %s", parent, not, child); + }); + } + + @SuppressWarnings("ChainOfInstanceofChecks") + private void checkParametrizedType(final ParameterizedType type) { + final Type actualType = type.getActualTypeArguments()[0]; + if (actualType instanceof Class) { + checkClassType((Class) actualType); + } else if (actualType instanceof WildcardType) { + for (final Type boundType : ((WildcardType) actualType).getUpperBounds()) { + if (boundType instanceof Class) { + checkClassType((Class) boundType); + } else { + throw Asserts.error("Unsupported wildcard bound type in %s(List<...>): %s", parent, boundType); + } + } + } else { + throw Asserts.error("Unsupported type argument type in %s(List<...>): %s", parent, actualType); + } + } + + @SuppressWarnings("ChainOfInstanceofChecks") + private void checkConstructor() { + try { + final Type argType = parent.getConstructor(List.class).getGenericParameterTypes()[0]; + if (argType instanceof ParameterizedType) { + checkParametrizedType((ParameterizedType) argType); + } else if (argType instanceof Class) { + throw Asserts.error("Raw List type in %s(List)", parent.getName()); + } else { + throw Asserts.error("Unsupported argument type in %s(List<...>): %s", parent.getName(), argType); + } + } catch (final NoSuchMethodException e) { + throw Asserts.error("Missing %s(List<...>) constructor: %s", parent.getName(), e); + } + } + } + + public static void main(final String... args) { + MarkupTest.main(args); + SELECTOR.main(args); + } +} diff --git a/java/markup/MarkupTest.java b/java/markup/MarkupTest.java new file mode 100644 index 0000000..9574b13 --- /dev/null +++ b/java/markup/MarkupTest.java @@ -0,0 +1,97 @@ +package markup; + +import base.Selector; +import base.TestCounter; + +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +/** + * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) + */ +public final class MarkupTest { + private static final Consumer MARKDOWN = MarkupTest.variant( + "Markdown", Map.of( + "&[", "", "&]", "", + "<", "", ">", "" + ) + ); + + private static final Consumer HTML = MarkupTest.variant( + "Html", Map.of( + "&[", "

                                                                                                                                                                                                                                                                                                                                                  ", "&]", "

                                                                                                                                                                                                                                                                                                                                                  ", + "*<", "", "*>", "", + "__<", "", "__>", "", + "~<", "", "~>", "" + ) + ); + + public static final Selector SELECTOR = new Selector(MarkupTest.class) + .variant("Base", MARKDOWN) + .variant("3637", MARKDOWN) + .variant("3839", MARKDOWN) + .variant("3435", HTML) + .variant("3233", HTML) + .variant("4142", MARKDOWN) + .variant("4749", MARKDOWN) + + ; + + public static Consumer variant(final String name, final Map mapping) { + return MarkupTester.variant(MarkupTest::test, name, mapping); + } + + private MarkupTest() { + } + + public static void test(final MarkupTester.Checker checker) { + test(checker, new Paragraph(List.of(new Text("Hello"))), "Hello"); + test(checker, new Paragraph(List.of(new Emphasis(List.of(new Text("Hello"))))), "*"); + test(checker, new Paragraph(List.of(new Strong(List.of(new Text("Hello"))))), "__"); + test(checker, new Paragraph(List.of(new Strikeout(List.of(new Text("Hello"))))), "~"); + + final Paragraph paragraph = new Paragraph(List.of( + new Strong(List.of( + new Text("1"), + new Strikeout(List.of( + new Text("2"), + new Emphasis(List.of( + new Text("3"), + new Text("4") + )), + new Text("5") + )), + new Text("6") + )) + )); + test(checker, paragraph, "__<1~<2*<34*>5~>6__>"); + test( + checker, + new Paragraph(List.of(new Strong(List.of( + new Text("sdq"), + new Strikeout(List.of(new Emphasis(List.of(new Text("r"))), new Text("vavc"))), + new Text("zg") + )))), + "__vavc~>zg__>" + ); + test( + checker, + new Paragraph(List.of(new Strikeout(List.of(new Strong(List.of(new Strikeout(List.of(new Text("е"), new Text("е"), new Text("г"))), new Text("ftje"), new Strong(List.of(new Text("йцць"), new Text("р"))))), new Strong(List.of(new Strikeout(List.of(new Text("д"), new Text("б"), new Text("е"))), new Strong(List.of(new Text("лъ"), new Text("шщ"))), new Strong(List.of(new Text("б"), new Text("еи"))))), new Emphasis(List.of(new Emphasis(List.of(new Text("м"), new Text("к"))), new Emphasis(List.of(new Text("уаужш"), new Text("ш"))), new Strong(List.of(new Text("рб"), new Text("щ"))))))), new Text("a"), new Strikeout(List.of(new Text("no"), new Text("ddw"), new Strong(List.of(new Emphasis(List.of(new Text("щ"), new Text("ча"))), new Emphasis(List.of(new Text("ъп"), new Text("ш"))), new Text("psk"))))))), + "~<__<~<еег~>ftje__<йццьр__>__>__<~<дбе~>__<лъшщ__>__<беи__>__>*<*<мк*>*<уаужшш*>__<рбщ__>*>~>a~*<ъпш*>psk__>~>" + ); + test( + checker, + new Paragraph(List.of(new Strikeout(List.of(new Strong(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("об"))), new Strikeout(List.of(new Text("ц"))), new Text("зснцйцць"), new Text("р"), new Text("а"))), new Strikeout(List.of(new Strikeout(List.of(new Text("б"))), new Strikeout(List.of(new Text("ялъ"))), new Text("шщ"), new Text("ф"), new Text("м"))), new Emphasis(List.of(new Emphasis(List.of(new Text("узр"))), new Text("i"), new Text("и"), new Text("г"), new Text("с"))), new Strong(List.of(new Strong(List.of(new Text("шмрб"))), new Strong(List.of(new Text("ь"))), new Text("з"), new Text("з"), new Text("фь"))), new Text("ddw"))), new Strong(List.of(new Emphasis(List.of(new Emphasis(List.of(new Text("ввтъп"))), new Strong(List.of(new Text("ш"))), new Text("хте"), new Text("чюе"), new Text("х"))), new Text("g"), new Strikeout(List.of(new Strikeout(List.of(new Text("ддзюцщ"))), new Strong(List.of(new Text("к"))), new Text("йщ"), new Text("э"), new Text("то"))), new Strong(List.of(new Emphasis(List.of(new Text("ж"))), new Text("t"), new Text("ыеж"), new Text("ч"), new Text("г"))), new Text("kwt"))), new Strong(List.of(new Strong(List.of(new Emphasis(List.of(new Text("ш"))), new Strong(List.of(new Text("х"))), new Text("уи"), new Text("о"), new Text("п"))), new Emphasis(List.of(new Text("zn"), new Strong(List.of(new Text("нш"))), new Text("диуьг"), new Text("вй"), new Text("шш"))), new Strong(List.of(new Emphasis(List.of(new Text("ьмша"))), new Emphasis(List.of(new Text("у"))), new Text("в"), new Text("у"), new Text("ир"))), new Emphasis(List.of(new Strikeout(List.of(new Text("я"))), new Strikeout(List.of(new Text("зоъ"))), new Text("эн"), new Text("ъ"), new Text("ьо"))), new Text("cqqzbhtn"))), new Text("i"), new Strong(List.of(new Text("i"), new Strikeout(List.of(new Strong(List.of(new Text("ш"))), new Strong(List.of(new Text("к"))), new Text("ж"), new Text("б"), new Text("ащ"))), new Strikeout(List.of(new Strikeout(List.of(new Text("пян"))), new Emphasis(List.of(new Text("ц"))), new Text("ю"), new Text("дрк"), new Text("лщ"))), new Strong(List.of(new Text("xywa"), new Text("ряэк"), new Text("п"), new Text("э"), new Text("т"))), new Strong(List.of(new Strikeout(List.of(new Text("е"))), new Text("чб"), new Text("зс"), new Text("екйюд"), new Text("чх"))))))), new Strikeout(List.of(new Strong(List.of(new Strong(List.of(new Strong(List.of(new Text("юи"))), new Emphasis(List.of(new Text("и"))), new Text("п"), new Text("вх"), new Text("ф"))), new Strong(List.of(new Strong(List.of(new Text("щюереф"))), new Text("otvic"), new Text("ж"), new Text("уыа"), new Text("ьскю"))), new Text("x"), new Strikeout(List.of(new Emphasis(List.of(new Text("ж"))), new Strikeout(List.of(new Text("зыйгг"))), new Text("о"), new Text("ш"), new Text("ф"))), new Text("zf"))), new Emphasis(List.of(new Text("a"), new Strikeout(List.of(new Emphasis(List.of(new Text("э"))), new Text("amqcfdzrg"), new Text("кыч"), new Text("к"), new Text("я"))), new Strikeout(List.of(new Strong(List.of(new Text("нфны"))), new Strikeout(List.of(new Text("гщ"))), new Text("ы"), new Text("шя"), new Text("е"))), new Strong(List.of(new Strong(List.of(new Text("ъю"))), new Emphasis(List.of(new Text("яхе"))), new Text("б"), new Text("бц"), new Text("еящж"))), new Text("cn"))), new Emphasis(List.of(new Strong(List.of(new Strong(List.of(new Text("л"))), new Text("wl"), new Text("оде"), new Text("кл"), new Text("еок"))), new Strikeout(List.of(new Strikeout(List.of(new Text("яяиь"))), new Strong(List.of(new Text("ик"))), new Text("юью"), new Text("ь"), new Text("э"))), new Emphasis(List.of(new Strikeout(List.of(new Text("жп"))), new Emphasis(List.of(new Text("ц"))), new Text("ндюз"), new Text("ч"), new Text("н"))), new Text("r"), new Strikeout(List.of(new Strikeout(List.of(new Text("зьуес"))), new Text("к"), new Text("и"), new Text("к"), new Text("й"))))), new Strikeout(List.of(new Emphasis(List.of(new Strikeout(List.of(new Text("еы"))), new Emphasis(List.of(new Text("б"))), new Text("сйсыр"), new Text("я"), new Text("т"))), new Emphasis(List.of(new Emphasis(List.of(new Text("з"))), new Strong(List.of(new Text("ахыы"))), new Text("х"), new Text("м"), new Text("п"))), new Strikeout(List.of(new Text("b"), new Text("o"), new Text("шьх"), new Text("йз"), new Text("ж"))), new Text("udlh"), new Strikeout(List.of(new Strikeout(List.of(new Text("п"))), new Text("хъфоз"), new Text("е"), new Text("ыф"), new Text("ю"))))), new Text("z"))), new Text("hy"), new Strong(List.of(new Text("tyv"), new Text("x"), new Strikeout(List.of(new Text("vzb"), new Strong(List.of(new Text("oi"), new Text("r"), new Text("ю"), new Text("с"), new Text("еппзмл"))), new Text("r"), new Emphasis(List.of(new Strikeout(List.of(new Text("игс"))), new Emphasis(List.of(new Text("нян"))), new Text("ю"), new Text("с"), new Text("цлъ"))), new Text("rptq"))), new Emphasis(List.of(new Strong(List.of(new Text("u"), new Strong(List.of(new Text("кще"))), new Text("пхте"), new Text("у"), new Text("з"))), new Text("zbmflu"), new Strikeout(List.of(new Strong(List.of(new Text("л"))), new Emphasis(List.of(new Text("ко"))), new Text("ъ"), new Text("щ"), new Text("жч"))), new Strong(List.of(new Strong(List.of(new Text("ж"))), new Strikeout(List.of(new Text("еъ"))), new Text("в"), new Text("ф"), new Text("йб"))), new Text("kvuf"))), new Strikeout(List.of(new Text("azn"), new Strikeout(List.of(new Strong(List.of(new Text("ъ"))), new Emphasis(List.of(new Text("ре"))), new Text("йч"), new Text("н"), new Text("ир"))), new Emphasis(List.of(new Emphasis(List.of(new Text("с"))), new Strong(List.of(new Text("щ"))), new Text("ъсбчиюзи"), new Text("сэ"), new Text("е"))), new Strikeout(List.of(new Emphasis(List.of(new Text("о"))), new Text("г"), new Text("бвщ"), new Text("пр"), new Text("йвъч"))), new Text("c"))))), new Strong(List.of(new Strikeout(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("жбфц"))), new Strong(List.of(new Text("рцч"))), new Text("хе"), new Text("ж"), new Text("ы"))), new Strikeout(List.of(new Emphasis(List.of(new Text("я"))), new Emphasis(List.of(new Text("мн"))), new Text("яе"), new Text("е"), new Text("дхпг"))), new Emphasis(List.of(new Emphasis(List.of(new Text("нй"))), new Text("gf"), new Text("и"), new Text("хю"), new Text("ця"))), new Strong(List.of(new Emphasis(List.of(new Text("о"))), new Emphasis(List.of(new Text("ъ"))), new Text("лм"), new Text("ы"), new Text("рц"))), new Emphasis(List.of(new Strikeout(List.of(new Text("я"))), new Text("ыл"), new Text("г"), new Text("я"), new Text("эй"))))), new Text("qi"), new Emphasis(List.of(new Text("dtt"), new Emphasis(List.of(new Strong(List.of(new Text("пв"))), new Text("i"), new Text("яешц"), new Text("йшй"), new Text("щмив"))), new Text("u"), new Text("d"), new Strikeout(List.of(new Strikeout(List.of(new Text("о"))), new Text("иов"), new Text("к"), new Text("кои"), new Text("яс"))))), new Strikeout(List.of(new Emphasis(List.of(new Text("j"), new Strong(List.of(new Text("эя"))), new Text("шыф"), new Text("дрн"), new Text("щ"))), new Text("j"), new Strong(List.of(new Emphasis(List.of(new Text("ю"))), new Strikeout(List.of(new Text("чцин"))), new Text("сф"), new Text("з"), new Text("юэи"))), new Emphasis(List.of(new Emphasis(List.of(new Text("цс"))), new Text("ювус"), new Text("ъ"), new Text("щэны"), new Text("б"))), new Emphasis(List.of(new Text("cbogf"), new Text("э"), new Text("ж"), new Text("ш"), new Text("м"))))), new Strikeout(List.of(new Strong(List.of(new Strong(List.of(new Text("ф"))), new Text("w"), new Text("цеъ"), new Text("н"), new Text("ем"))), new Strikeout(List.of(new Strikeout(List.of(new Text("л"))), new Strong(List.of(new Text("э"))), new Text("лд"), new Text("эд"), new Text("л"))), new Emphasis(List.of(new Emphasis(List.of(new Text("уг"))), new Strikeout(List.of(new Text("зп"))), new Text("юб"), new Text("сгы"), new Text("шю"))), new Strikeout(List.of(new Emphasis(List.of(new Text("рйей"))), new Text("с"), new Text("зюй"), new Text("р"), new Text("в"))), new Emphasis(List.of(new Text("p"), new Text("у"), new Text("на"), new Text("б"), new Text("х"))))))))), + "~<__<~<*<об*>~<ц~>зснцйццьра~>~<~<б~>~<ялъ~>шщфм~>*<*<узр*>iигс*>__<__<шмрб__>__<ь__>ззфь__>ddw__>__<*<*<ввтъп*>__<ш__>хтечюех*>g~<~<ддзюцщ~>__<к__>йщэто~>__<*<ж*>tыежчг__>kwt__>__<__<*<ш*>__<х__>уиоп__>*диуьгвйшш*>__<*<ьмша*>*<у*>вуир__>*<~<я~>~<зоъ~>энъьо*>cqqzbhtn__>i____<к__>жбащ~>~<~<пян~>*<ц*>юдрклщ~>____<~<е~>чбзсекйюдчх__>__>~>~<__<__<__<юи__>*<и*>пвхф__>__<__<щюереф__>otvicжуыаьскю__>x~<*<ж*>~<зыйгг~>ошф~>zf__>*amqcfdzrgкычкя~>~<__<нфны__>~<гщ~>ышяе~>__<__<ъю__>*<яхе*>ббцеящж__>cn*>*<__<__<л__>wlодеклеок__>~<~<яяиь~>__<ик__>юьюьэ~>*<~<жп~>*<ц*>ндюзчн*>r~<~<зьуес~>кикй~>*>~<*<~<еы~>*<б*>сйсырят*>*<*<з*>__<ахыы__>хмп*>~udlh~<~<п~>хъфозеыфю~>~>z~>hy__r*<~<игс~>*<нян*>юсцлъ*>rptq~>*<__пхтеуз__>zbmflu~<__<л__>*<ко*>ъщжч~>__<__<ж__>~<еъ~>вфйб__>kvuf*>~*<ре*>йчнир~>*<*<с*>__<щ__>ъсбчиюзисэе*>~<*<о*>гбвщпрйвъч~>c~>__>__<~<~<*<жбфц*>__<рцч__>хежы~>~<*<я*>*<мн*>яеедхпг~>*<*<нй*>gfихюця*>__<*<о*>*<ъ*>лмырц__>*<~<я~>ылгяэй*>~>qi*iяешцйшйщмив*>ud~<~<о~>иовккоияс~>*>~<*шыфдрнщ*>j__<*<ю*>~<чцин~>сфзюэи__>*<*<цс*>ювусъщэныб*>*~>~<__<__<ф__>wцеънем__>~<~<л~>__<э__>лдэдл~>*<*<уг*>~<зп~>юбсгышю*>~<*<рйей*>сзюйрв~>*~>__>" + ); + } + + private static void test(final MarkupTester.Checker checker, final Paragraph paragraph, final String template) { + checker.test(paragraph, String.format("&[%s&]", template)); + } + + public static void main(final String... args) { + SELECTOR.main(args); + } +} diff --git a/java/markup/MarkupTester.java b/java/markup/MarkupTester.java new file mode 100644 index 0000000..4d93d97 --- /dev/null +++ b/java/markup/MarkupTester.java @@ -0,0 +1,71 @@ +package markup; + +import base.Asserts; +import base.BaseChecker; +import base.TestCounter; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +/** + * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) + */ +public final class MarkupTester { + private final Map mapping; + private final String toString; + + private MarkupTester(final Map mapping, final String toString) { + this.mapping = mapping; + this.toString = toString; + } + + public static Consumer variant(final Consumer checker, final String name, final Map mapping) { + return counter -> test(checker).accept(new MarkupTester(mapping, "to" + name), counter); + } + + public static BiConsumer test(final Consumer tester) { + return (checker, counter) -> tester.accept(checker.new Checker(counter)); + } + + @Override + public String toString() { + return toString; + } + + public class Checker extends BaseChecker { + public Checker(final TestCounter counter) { + super(counter); + } + + private MethodHandle findMethod(final T value) { + try { + return MethodHandles.publicLookup().findVirtual(value.getClass(), toString, MethodType.methodType(void.class, StringBuilder.class)); + } catch (final NoSuchMethodException | IllegalAccessException e) { + throw Asserts.error("Cannot find method 'void %s(StringBuilder)' for %s", toString, value.getClass()); + } + } + + public void test(final T value, String expectedTemplate) { + final MethodHandle method = findMethod(value); + for (final Map.Entry entry : mapping.entrySet()) { + expectedTemplate = expectedTemplate.replace(entry.getKey(), entry.getValue()); + } + + final String expected = expectedTemplate; + counter.println("Test " + counter.getTestNo()); + counter.test(() -> { + final StringBuilder sb = new StringBuilder(); + try { + method.invoke(value, sb); + } catch (final Throwable e) { + throw Asserts.error("%s(StringBuilder) for %s thrown exception: %s", toString, value.getClass(), e); + } + Asserts.assertEquals("Result", expected, sb.toString()); + }); + } + } +} diff --git a/java/markup/OrderedList.java b/java/markup/OrderedList.java new file mode 100644 index 0000000..f88b1b4 --- /dev/null +++ b/java/markup/OrderedList.java @@ -0,0 +1,29 @@ +package markup; + +import java.util.List; + +public class OrderedList implements ListItemContent { + private final List items; + + public OrderedList(List items) { + this.items = items; + } + + @Override + public void toHtml(StringBuilder sb) { + sb.append("
                                                                                                                                                                                                                                                                                                                                                    "); + for (ListItem item : items) { + item.toHtml(sb); + } + sb.append("
                                                                                                                                                                                                                                                                                                                                                  "); + } + + @Override + public void toTex(StringBuilder sb) { + sb.append("\\begin{enumerate}"); + for (ListItem item : items) { + item.toTex(sb); + } + sb.append("\\end{enumerate}"); + } +} \ No newline at end of file diff --git a/java/markup/Paragraph.java b/java/markup/Paragraph.java new file mode 100644 index 0000000..8b064e2 --- /dev/null +++ b/java/markup/Paragraph.java @@ -0,0 +1,29 @@ +package markup; + +import java.util.List; + +public class Paragraph extends AbstractMarkup implements ListItemContent { + public Paragraph(List elements) { + super(elements); + } + + @Override + public void toMarkdown(StringBuilder sb) { + for (MarkupElement element : elements) { + element.toMarkdown(sb); + } + } + + @Override + public void toHtml(StringBuilder sb) { + toHtml(sb, "p"); + } + + @Override + public void toTex(StringBuilder sb) { + sb.append("\\par{}"); + for (MarkupElement element : elements) { + element.toTex(sb); + } + } +} \ No newline at end of file diff --git a/java/markup/Strong.java b/java/markup/Strong.java new file mode 100644 index 0000000..a4a7ad3 --- /dev/null +++ b/java/markup/Strong.java @@ -0,0 +1,24 @@ +package markup; + +import java.util.List; + +public class Strong extends AbstractMarkup { + public Strong(List elements) { + super(elements); + } + + @Override + public void toMarkdown(StringBuilder sb) { + toMarkdown(sb, "__"); + } + + @Override + public void toHtml(StringBuilder sb) { + toHtml(sb, "strong"); + } + + @Override + public void toTex(StringBuilder sb) { + toTex(sb, "\\textbf"); + } +} \ No newline at end of file diff --git a/java/markup/Text.java b/java/markup/Text.java new file mode 100644 index 0000000..c0e9442 --- /dev/null +++ b/java/markup/Text.java @@ -0,0 +1,24 @@ +package markup; + +public class Text implements MarkupElement { + private final String text; + + public Text(String text) { + this.text = text; + } + + @Override + public void toMarkdown(StringBuilder sb) { + sb.append(text); + } + + @Override + public void toHtml(StringBuilder sb) { + sb.append(text); + } + + @Override + public void toTex(StringBuilder sb) { + sb.append(text); + } +} \ No newline at end of file diff --git a/java/markup/UnorderedList.java b/java/markup/UnorderedList.java new file mode 100644 index 0000000..c2c9602 --- /dev/null +++ b/java/markup/UnorderedList.java @@ -0,0 +1,29 @@ +package markup; + +import java.util.List; + +public class UnorderedList implements ListItemContent { + private final List items; + + public UnorderedList(List items) { + this.items = items; + } + + @Override + public void toHtml(StringBuilder sb) { + sb.append("
                                                                                                                                                                                                                                                                                                                                                    "); + for (ListItem item : items) { + item.toHtml(sb); + } + sb.append("
                                                                                                                                                                                                                                                                                                                                                  "); + } + + @Override + public void toTex(StringBuilder sb) { + sb.append("\\begin{itemize}"); + for (ListItem item : items) { + item.toTex(sb); + } + sb.append("\\end{itemize}"); + } +} \ No newline at end of file diff --git a/java/markup/package-info.java b/java/markup/package-info.java new file mode 100644 index 0000000..fdef1bc --- /dev/null +++ b/java/markup/package-info.java @@ -0,0 +1,7 @@ +/** + * Tests for Markup homework + * of Introduction to Programming course. + * + * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) + */ +package markup; \ No newline at end of file