/* XOWA: the XOWA Offline Wiki Application Copyright (C) 2012-2017 gnosygnu@gmail.com XOWA is licensed under the terms of the General Public License (GPL) Version 3, or alternatively under the terms of the Apache License Version 2.0. You may use XOWA according to either of these licenses as is most appropriate for your project on a case-by-case basis. The terms of each license can be found in the source code repository: GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt */ package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*; import org.junit.*; public class Xomw_prepro_wkr__tst { private final Xomw_prepro_wkr__fxt fxt = new Xomw_prepro_wkr__fxt(); @Test public void Text() { fxt.Test__parse("abc", "<root>abc</root>"); } @Test public void Brack() { fxt.Test__parse("a[[b]]c", "<root>a[[b]]c</root>"); } @Test public void Brack__one() { // COVERS: "Add literal brace(s)" fxt.Test__parse("a[b]c", "<root>a[b]c</root>"); } @Test public void Brack__max() { // COVERS: "The specified maximum exists in the callback array, unless the caller" fxt.Test__parse("a[[[[[b]]]]]c", "<root>a[[[[[b]]]]]c</root>"); } @Test public void Template() { fxt.Test__parse("a{{b}}c", "<root>a<template><title>b</title></template>c</root>"); } @Test public void Template__args__idx() { fxt.Test__parse("a{{b|c|d}}e", "<root>a<template><title>b</title><part><name index=\"1\" /><value>c</value></part><part><name index=\"2\" /><value>d</value></part></template>e</root>"); } @Test public void Template__args__key() { fxt.Test__parse("a{{b|c=d}}e", "<root>a<template><title>b</title><part><name>c</name>=<value>d</value></part></template>e</root>"); } @Test public void Template__line_start() { // COVERS: "The invocation is at the start of the line if lineStart is set in" fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a" , "{{b}}" ), String_.Concat_lines_nl_skip_last ( "<root>a" , "<template lineStart=\"1\"><title>b</title></template></root>" )); } @Test public void Template__max() { // COVERS: "do we still qualify for any callback with remaining count?" fxt.Test__parse("a{{{{{b}}}}}c", "<root>a<template><title><tplarg><title>b</title></tplarg></title></template>c</root>"); } @Test public void Tplarg() { fxt.Test__parse("a{{{b}}}c", "<root>a<tplarg><title>b</title></tplarg>c</root>"); } @Test public void Tplarg__dflt() { fxt.Test__parse("a{{{b|c}}}d", "<root>a<tplarg><title>b</title><part><name index=\"1\" /><value>c</value></part></tplarg>d</root>"); } @Test public void Comment() { fxt.Test__parse("a<!--b-->c", "<root>a<comment><!--b--></comment>c</root>"); } @Test public void Comment__dangling() {// COVERS: "Unclosed comment in input, runs to end" fxt.Test__parse("a<!--b", "<root>a<comment><!--b</comment></root>"); } @Test public void Comment__ws() { // COVERS: "Search backwards for leading whitespace" fxt.Test__parse("a <!--b--> c", "<root>a <comment><!--b--></comment> c</root>"); // NOTE: space is outside comment } @Test public void Comment__many__ws() {// COVERS: "Dump all but the last comment to the accumulator" fxt.Test__parse("a <!--1--> <!--2--> z", "<root>a <comment><!--1--></comment> <comment><!--2--></comment> z</root>"); // NOTE: space is outside comment; } @Test public void Comment__nl__ws() { // COVERS: "Eat the line if possible" fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a" , " <!--1--> " , " <!--2--> " , "z" ), String_.Concat_lines_nl_skip_last ( "<root>a" , "<comment> <!--1--> " // NOTE: space is inside </comment> if flanked by nl; , "</comment><comment> <!--2--> " , "</comment>z</root>" )); } @Test public void Ext() { // COVERS.ALSO: "Note that the attr element contains the whitespace between name and attribute," fxt.Test__parse("a<pre id=\"1\">b</pre>c", "<root>a<ext><name>pre</name><attr> id="1"</attr><inner>b</inner><close></pre></close></ext>c</root>"); } @Test public void Ext__inline() { // COVERS: "if ( $text[$tagEndPos - 1] == '/' ) {" fxt.Test__parse("a<pre/>b" , "<root>a<ext><name>pre</name><attr></attr></ext>b</root>"); fxt.Test__parse("a<pre />b" , "<root>a<ext><name>pre</name><attr> </attr></ext>b</root>"); } @Test public void Ext__end__pass__space() {// COVERS: "\s*" in `preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i",` fxt.Test__parse("a<pre>b</pre >c", "<root>a<ext><name>pre</name><attr></attr><inner>b</inner><close></pre ></close></ext>c</root>"); } @Test public void Ext__end__pass__name() { // COVERS: "\s*" in `preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i",` fxt.Test__parse("a<pre>b</pro></pre>c", "<root>a<ext><name>pre</name><attr></attr><inner>b</pro></inner><close></pre></close></ext>c</root>"); } @Test public void Ext__end__fail__angle() {// COVERS: "\s*" in `preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i",` fxt.Test__parse("a<pre>b</pre c", "<root>a<pre>b</pre c</root>"); } @Test public void Ext__dangling() { // COVERS: "Let it run out to the end of the text." fxt.Test__parse("a<pre>bc", "<root>a<pre>bc</root>"); } @Test public void Ext__dangling__many() { // COVERS: "Cache results, otherwise we have O(N^2) performance for input like <foo><foo><foo>..." fxt.Test__parse("a<pre><pre><pre>bc", "<root>a<pre><pre><pre>bc</root>"); } @Test public void Ext__unclosed() { // COVERS: "Infinite backtrack" fxt.Test__parse("a<pre bcd", "<root>a<pre bcd</root>"); } @Test public void Ext__noinclude() { // COVERS: "<includeonly> and <noinclude> just become <ignore> tags" fxt.Init__for_inclusion_(Bool_.N); fxt.Test__parse("a<includeonly>b<noinclude>c</noinclude>d</includeonly>e", "<root>a<ignore><includeonly>b<noinclude>c</noinclude>d</includeonly></ignore>e</root>"); } @Test public void Heading() { fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a" , "== b1 ==" , "z" ), String_.Concat_lines_nl_skip_last ( "<root>a" , "<h level=\"2\" i=\"1\">== b1 ==</h>" , "z</root>" )); } @Test public void Heading__eos__no_nl() { fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a" , "== b1 ==" ), String_.Concat_lines_nl_skip_last ( "<root>a" , "<h level=\"2\" i=\"1\">== b1 ==</h></root>" )); } @Test public void Heading__bos__implied_nl() { // COVERS: "Is this the start of a heading?" fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "== b1 ==" , "z" ), String_.Concat_lines_nl_skip_last ( "<root><h level=\"2\" i=\"1\">== b1 ==</h>" , "z</root>" )); } @Test public void Heading__dwim__y() { // COVERS: "DWIM: This looks kind of like a name/value separator." fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a{{b|" , "=c=" , "}}d" ), String_.Concat_lines_nl_skip_last ( "<root>a<template><title>b</title><part><name>" , "</name>=<value>c=" , "</value></part></template>d</root>" )); } @Test public void Heading__dwim__n() { // COVERS: "DWIM: This looks kind of like a name/value separator." fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a{{b|" , "==c==" , "}}d" ), String_.Concat_lines_nl_skip_last ( "<root>a<template><title>b</title><part><name index=\"1\" /><value>" , "<h level=\"2\" i=\"1\">==c==</h>" , "</value></part></template>d</root>" )); } @Test public void Heading__comment() { // COVERS: "Comment found at line end" fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a" , "==b== <!--c-->" , "" ), String_.Concat_lines_nl_skip_last ( "<root>a" , "<h level=\"2\" i=\"1\">==b== <comment><!--c--></comment></h>" , "</root>" )); } @Test public void Heading__consecutive__5() { // COVERS: "This is just a single String of equals signs on its own line" fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a" , "=====" , "" ), String_.Concat_lines_nl_skip_last ( "<root>a" , "<h level=\"2\" i=\"1\">=====</h>" , "</root>" )); } @Test public void Heading__consecutive__1() { // COVERS: "Single equals sign on its own line, count=0" fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a" , "=" , "" ), String_.Concat_lines_nl_skip_last ( "<root>a" , "=" , "</root>" )); } @Test public void Heading__unclosed() { // COVERS: "No match, no <h>, just pass down the inner src" fxt.Test__parse(String_.Concat_lines_nl_skip_last ( "a" , "===b" , "" ), String_.Concat_lines_nl_skip_last ( "<root>a" , "===b" , "</root>" )); } @Test public void Inclusion__n() { fxt.Init__for_inclusion_(Bool_.N); fxt.Test__parse("a<onlyinclude>b</onlyinclude>c", "<root>a<ignore><onlyinclude></ignore>b<ignore></onlyinclude></ignore>c</root>"); } @Test public void Inclusion__y() { fxt.Init__for_inclusion_(Bool_.Y); fxt.Test__parse("a<onlyinclude>b</onlyinclude>c", "<root><ignore>a<onlyinclude></ignore>b<ignore></onlyinclude>c</ignore></root>"); } @Test public void Ignored__noinclude() { // COVERS: "Handle ignored tags" fxt.Init__for_inclusion_(Bool_.N); fxt.Test__parse("a<noinclude>b</noinclude>c", "<root>a<ignore><noinclude></ignore>b<ignore></noinclude></ignore>c</root>"); } } class Xomw_prepro_wkr__fxt { private final Xomw_prepro_wkr wkr = new Xomw_prepro_wkr(); private boolean for_inclusion = false; public Xomw_prepro_wkr__fxt() { wkr.Init_by_wiki("pre"); } public void Init__for_inclusion_(boolean v) {for_inclusion = v;} public void Test__parse(String src_str, String expd) { byte[] src_bry = Bry_.new_u8(src_str); byte[] actl = wkr.Preprocess_to_xml(src_bry, for_inclusion); Tfds.Eq_str_lines(expd, String_.new_u8(actl), src_str); } }