1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

App: Release v4.5.15.1709

This commit is contained in:
gnosygnu
2017-09-17 22:39:30 -04:00
parent 4ca98f7333
commit ea3f0ffbcc
896 changed files with 69373 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*; import gplx.xowa.wikis.ttls.*;
public class Xop_subst_tst {
private final Xop_fxt fxt = new Xop_fxt();
@Before public void init() {
fxt.Reset();
fxt.Init_defn_clear();
fxt.Init_defn_add("xo_print", "{{{1}}}");
fxt.Init_defn_add("!", "|");
}
@Test public void Wiki_txt_subst() {fxt.Test_parse_tmpl_str_test("{{{1}}}" , "{{subst:test|a}}" , "a");}
@Test public void Wiki_txt_subst_ws() {fxt.Test_parse_tmpl_str_test("{{{1}}}" , "{{ subst:test|a}}" , "a");}
@Test public void Wiki_txt_safesubst() {fxt.Test_parse_tmpl_str_test("{{{1}}}" , "{{safesubst:test|a}}" , "a");}
@Test public void Tmpl_txt_subst_empty() {fxt.Test_parse_tmpl_str_test("{{subst:}}" , "{{test}}" , "{{subst:}}");}
@Test public void Tmpl_txt_safesubst() {fxt.Test_parse_tmpl_str_test("{{safesubst:xo_print|a}}" , "{{test}}" , "a");}
@Test public void Tmpl_prm_subst() {fxt.Test_parse_tmpl_str_test("{{{{{1|subst:}}}xo_print|a}}" , "{{test}}" , "{{subst:xo_print|a}}");}
@Test public void Tmpl_prm_subst_ws() {fxt.Test_parse_tmpl_str_test("{{{{{1| subst:}}}xo_print|a}}" , "{{test}}" , "{{ subst:xo_print|a}}");}
@Test public void Tmpl_prm_safesubst() {fxt.Test_parse_tmpl_str_test("{{{{{1|safesubst:}}}xo_print|a}}" , "{{test}}" , "a");}
@Test public void Tmpl_prm_safesubst_empty() {fxt.Test_parse_tmpl_str_test("{{{{{|safesubst:}}}xo_print|a}}" , "{{test}}" , "a");}
@Test public void Tmpl_txt_subst_pf() {fxt.Test_parse_tmpl_str_test("{{subst:#expr:0}}" , "{{test}}" , "0");}
@Test public void Tmpl_txt_safesubst_prm() {fxt.Test_parse_tmpl_str_test("{{{{{|safesubst:}}}#if:{{{1|}}}{{{{{|safesubst:}}}!}}c1|c2}}" , "{{test}}" , "c2");}
@Test public void Exc_tmpl_prm_safesubst_ns() {fxt.Test_parse_tmpl_str_test("{{{{{|safesubst}}}:NAMESPACE}}" , "{{test}}" , "");}
@Test public void Unreferenced() { // PURPOSE: if subst, but in tmpl stage, do not actually subst; PAGE:en.w:Unreferenced; DATE:2013-01-31
fxt.Init_defn_clear();
fxt.Init_defn_add("substcheck", "SUBST");
fxt.Init_defn_add("ifsubst", String_.Concat_lines_nl
( "{{ {{{|safesubst:}}}#ifeq:{{ {{{|safesubst:}}}NAMESPACE}}|{{NAMESPACE}}"
, " |{{{no|{{{2|}}}}}}"
, " |{{{yes|{{{1|}}}}}}"
, "}}"
));
fxt.Test_parse_tmpl_str_test("{{ {{{|safesubst:}}}ifsubst |yes|<includeonly>{{subst:substcheck}}</includeonly>}}", "{{test}}", "{{subst:substcheck}}");
}
@Test public void Urlencode_missing_ttl() { // PURPOSE: handle missing ttl inside {{does-template-exist}}; EX: en.d:Kazakhstan; DATE:2014-03-25
fxt.Init_defn_clear();
fxt.Init_defn_add("test", "{{safesubst:urlencode:{{safesubst:Template:{{{1}}}}}}}");
fxt.Test_parse_page_tmpl_str("{{test|xyz}}", "%5B%5BTemplate%3Axyz%5D%5D"); // url-encoded version of [[:Template:xyz]]; NOTE: removed leading ":" from ":Template:" DATE:2016-06-24
}
@Test public void Urlencode_invalid_ttl() { // PURPOSE: handle invalid ttl inside does-template-exist; EX: en.d:peace; DATE:2014-03-31
fxt.Init_defn_clear();
fxt.Init_defn_add("test", "{{safesubst:urlencode:{{safesubst:Template:{{{1}}}}}}}");
fxt.Test_parse_page_tmpl_str("{{test|[xyz]}}", "%7B%7Bsafesubst%3ATemplate%3A%5Bxyz%5D%7D%7D"); // url-encoded version of {{safesubst:Template:xyz}}
}
@Test public void Urlencode_template_ttl() { // PURPOSE: handle template ttl inside does-template-exist; based on above; DATE:2014-03-31
fxt.Init_defn_clear();
fxt.Init_defn_add("test", "{{safesubst:urlencode:{{Template:{{{1}}}}}}}");
fxt.Test_parse_page_tmpl_str("{{test|Template:[xyz]}}", "%7B%7BTemplate%3ATemplate%3A%5Bxyz%5D%7D%7D"); // url-encoded version of {{safesubst:Template:xyz}}
}
@Test public void Nowiki() { // PURPOSE: stack overflow; PAGE:Близкиерузья_(Сезон_2) DATE:2014-10-21
fxt.Init_defn_add("ET", "");
fxt.Init_defn_add("ds", "<includeonly>{{subst:</includeonly><includeonly>ET|<nowiki>{{subst:ds}}</nowiki>}}</includeonly>");
fxt.Test_parse_page_tmpl_str("{{subst:ds}}", ""); // {{subst:ds}} causes stack overflow; {{ds}} does not
}
// NOTE: these are actually not good tests; MW does subst just before save; it doesn't do subst on load; in this case, the tests are testing load (which will noop); they need to test save (which xowa doesn't do)
// @Test public void Tmpl_txt_subst() {fxt.Test_parse_tmpl_str_test("{{subst:xo_print|a}}" , "{{test}}" , "a");}
// @Test public void Tmpl_txt_subst_prm() {fxt.Test_parse_tmpl_str_test("{{subst:xo_print|{{{1}}}}}" , "{{test|a}}" , "a");}
//@Test public void Tmpl_txt_safesubst_prm() {fxt.Test_parse_tmpl_str_test("{{{{{|safesubst:}}}ns:Category}}" , "{{test}}" , "Category");}
//@Test public void Tmpl_txt_subst_immed() {fxt.Test_parse_tmpl_str_test("{{xo_print{{subst:!}}a}}" , "{{test}}" , "a");}
}

View File

@@ -0,0 +1,38 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xop_tkn_print_tst {
private final Xop_fxt fxt = new Xop_fxt();
@Test public void Text() {tst_Print("a ''b'' c [[d]] e");}
@Test public void Prm() {tst_Print("{{{1}}}");}
@Test public void Prm_dflt() {tst_Print("{{{1|a}}}");}
@Test public void Prm_dflt_prm() {tst_Print("{{{1|{{{2}}}}}}");}
@Test public void Tmpl() {tst_Print("{{a}}");}
@Test public void Tmpl_arg() {tst_Print("{{a|1|2}}");}
@Test public void Tmpl_arg_prm() {tst_Print("{{a|1|{{{1}}}}}");}
@Test public void Tmpl_arg_tmpl() {tst_Print("{{a|1|{{b}}}}");}
@Test public void Tmpl_pf() {tst_Print("{{#expr:1}}");}
private void tst_Print(String raw) {
Xop_ctx ctx = fxt.Ctx();
byte[] raw_bry = Bry_.new_u8(raw);
Xot_defn_tmpl defn = fxt.run_Parse_tmpl(Bry_.Empty, raw_bry);
Xot_fmtr_prm raw_fmtr = new Xot_fmtr_prm();
defn.Root().Tmpl_fmt(ctx, raw_bry, raw_fmtr);
raw_fmtr.Print(tst_Print_bb);
Tfds.Eq(raw, tst_Print_bb.To_str_and_clear());
} private Bry_bfr tst_Print_bb = Bry_bfr_.New();
}

View File

@@ -0,0 +1,56 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*; import gplx.core.strings.*;
public class Xot_defn_trace_brief_tst {
Xot_defn_trace_fxt fxt = new Xot_defn_trace_fxt();
@Before public void init() {
fxt.Init_defn_clear();
fxt.Init_defn_add("leaf_a", "{{{1}}}");
fxt.Init_defn_add("leaf_b", "{{{1}}}");
fxt.Ctx().Defn_trace_(new Xot_defn_trace_brief());
}
@Test public void Basic_a_1() {fxt.tst_("{{leaf_a}}" , "0001 leaf_a");}
@Test public void Basic_a_2() {fxt.tst_("{{leaf_a}} {{leaf_a}}" , "0002 leaf_a");}
@Test public void Basic_a_b() {fxt.tst_("{{leaf_a}} {{leaf_b}}" , "0001 leaf_a", "0001 leaf_b");}
}
class Xot_defn_trace_fxt {
private final Xop_fxt fxt = new Xop_fxt();
public Xop_ctx Ctx() {return fxt.Ctx();}
public void Init_defn_clear() {fxt.Init_defn_clear();}
public void Init_defn_add(String name, String raw) {fxt.Init_defn_add(name, raw);}
public void tst_(String raw, String... expd_ary) {
Xop_ctx ctx = fxt.Ctx();
ctx.Defn_trace().Clear();
byte[] src = Bry_.new_u8(raw);
ctx.Page().Ttl_(Xoa_ttl.Parse(fxt.Wiki(), Bry_.new_a7("test")));
Xop_root_tkn root = ctx.Tkn_mkr().Root(src);
fxt.Parser().Parse_page_all_clear(root, ctx, ctx.Tkn_mkr(), src);
ctx.Defn_trace().Print(src, tmp);
String[] actl_ary = String_.Split(tmp.To_str_and_clear(), (char)Byte_ascii.Nl);
Tfds.Eq_ary(expd_ary, actl_ary);
} private Bry_bfr tmp = Bry_bfr_.New();
String[] To_str(Xot_defn_trace_itm_brief[] ary) {
String[] rv = new String[ary.length];
for (int i = 0; i < rv.length; i++) {
Xot_defn_trace_itm_brief itm = ary[i];
sb.Add(String_.new_u8(itm.Name())).Add("|").Add(itm.Count());
rv[i] = sb.To_str_and_clear();
}
return rv;
}
String_bldr sb = String_bldr_.new_();
}

View File

@@ -0,0 +1,47 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xot_defn_trace_dbg_tst {
Xot_defn_trace_fxt fx = new Xot_defn_trace_fxt();
@Before public void init() {
fx.Init_defn_clear();
fx.Init_defn_add("print", "{{{1}}}");
fx.Init_defn_add("concat", "{{{1}}}{{{2}}}");
fx.Init_defn_add("bool_str", "{{#ifeq:{{{1}}}|1|y|n}}");
fx.Init_defn_add("mid_1", "{{print|[ {{concat|{{{1}}}|{{{2}}}}} ]}}");
fx.Ctx().Defn_trace_(Xot_defn_trace_dbg.Instance);
}
@Test public void Tmpl() {
fx.tst_
( "{{print|a|key1=b}}"
, "*source"
, "{{print|a|key1=b}}"
, " *invk"
, " {{print|a|key1=b}}"
, " *lnk: [[Template:print]]"
, " *args"
, " 1: a"
, " 2: b"
, " key1: b"
, " *eval"
, " a"
, "*result"
, "a"
);
}
//@Test public void Basic_b() {fx.tst_("{{mwo_b|2}}" , "[[Test page]]", "00 11 {{mwo_b|1}} -> b");}
}

View File

@@ -0,0 +1,129 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xot_examples_tst {
private final Xop_fxt fxt = new Xop_fxt();
@Before public void init() {
Io_mgr.Instance.InitEngine_mem();
fxt.Reset();
}
@Test public void Arg_0() {Init_tmpl_for(); fxt.Test_parse_tmpl_str("{{For}}" , "For other uses, see [[Test page (disambiguation)]].");}
@Test public void Arg_1() {Init_tmpl_for(); fxt.Test_parse_tmpl_str("{{For|a}}" , "For a, see [[Test page (disambiguation)]].");}
@Test public void Arg_2() {Init_tmpl_for(); fxt.Test_parse_tmpl_str("{{For|a|b}}" , "For a, see [[b]].");}
@Test public void Arg_3() {Init_tmpl_for(); fxt.Test_parse_tmpl_str("{{For|a|b|c}}" , "For a, see [[b]]&#32;and [[c]].");}
@Test public void Arg_4() {Init_tmpl_for(); fxt.Test_parse_tmpl_str("{{For|a|b|c|d}}" , "For a, see [[b]], [[c]], and [[d]].");}
@Test public void Arg_5() {Init_tmpl_for(); fxt.Test_parse_tmpl_str("{{For|a|b|c|d|e}}" , "For a, see [[b]], [[c]], [[d]], and [[e]].");}
@Test public void Arg_1_nil() {Init_tmpl_for(); fxt.Test_parse_tmpl_str("{{For||a|b}}" , "For other uses, see [[a]]&#32;and [[b]].");}
@Test public void Main() {
Init_tmpl_main(); fxt.Test_parse_tmpl_str("{{Main|a}}", "Main article: [[a|a]]");
}
@Test public void About() {
Init_tmpl_about(); fxt.Test_parse_tmpl_str("{{About|abc}}", "This article is about abc.&#32;&#32;For other uses, see [[Test page (disambiguation)]].");
}
@Test public void About_2() { // PAGE:en.w:{{About|the NASA space mission||Messenger (disambiguation)}}
Init_tmpl_about(); fxt.Test_parse_tmpl_str("{{About|a||b{{!}}c}}", "This article is about a.&#32;&#32;For other uses, see [[b|c]].");
}
@Test public void OtherUses() {
Init_tmpl_other_uses(); fxt.Test_parse_tmpl_str("{{Other uses|abc}}", "For other uses, see [[abc]].");
}
@Test public void SeeAlso() {
Init_tmpl_see_also(); fxt.Test_parse_tmpl_str("{{See also|abc}}", "See also: [[abc]]");
}
@Test public void Redirect() {
Init_tmpl_redirect(); fxt.Test_parse_tmpl_str("{{Redirect|abc}}", "\"abc\" redirects here. For other uses, see [[abc (disambiguation)]].");
}
private void Init_tmpl_main() {
fxt.Init_page_create("Template:Main", String_.Concat_lines_nl
( "{{#ifeq:{{SUBJECTSPACE}}|Category|The main {{#ifeq:{{NAMESPACE:{{{1}}}}}||article|page}}{{#if:{{{2|}}}|s}} for this [[Wikipedia:Categorization|category]] {{#if:{{{2|}}}|are|is}}|Main {{#ifeq:{{NAMESPACE:{{{1}}}}}||article|page}}{{#if:{{{2|}}}|s}}:}} [[{{{1|{{PAGENAME}}}}}|{{{l1|{{{1|{{PAGENAME}}}}}}}}]]{{#if:{{{2| }}}"
, " |{{#if:{{{3|}}}|,&#32;|&#32;and&#32;}}[[{{{2}}}|{{{l2|{{{2}}}}}}]]}}{{#if:{{{3|}}}"
, " |{{#if:{{{4|}}}|,&#32;|,&#32;and&#32;}}[[{{{3}}}|{{{l3|{{{3}}}}}}]]}}{{#if:{{{4|}}}"
, " |{{#if:{{{5|}}}|,&#32;|,&#32;and&#32;}}[[{{{4}}}|{{{l4|{{{4}}}}}}]]}}{{#if:{{{5|}}}"
, " |{{#if:{{{6|}}}|,&#32;|,&#32;and&#32;}}[[{{{5}}}|{{{l5|{{{5}}}}}}]]}}{{#if:{{{6|}}}"
, " |{{#if:{{{7|}}}|,&#32;|,&#32;and&#32;}}[[{{{6}}}|{{{l6|{{{6}}}}}}]]}}{{#if:{{{7|}}}"
, " |{{#if:{{{8|}}}|,&#32;|,&#32;and&#32;}}[[{{{7}}}|{{{l7|{{{7}}}}}}]]}}{{#if:{{{8|}}}"
, " |{{#if:{{{9|}}}|,&#32;|,&#32;and&#32;}}[[{{{8}}}|{{{l8|{{{8}}}}}}]]}}{{#if:{{{9|}}}"
, " |{{#if:{{{10|}}}|,&#32;|,&#32;and&#32;}}[[{{{9}}}|{{{l9|{{{9}}}}}}]]}}{{#if:{{{10|}}}"
, " |, and [[{{{10}}}|{{{l10|{{{10}}}}}}]]}}{{#if:{{{11| }}}|&#32; (too many parameters in &#123;&#123;[[Template:main|main]]&#125;&#125;)}}"
));
}
private void Init_tmpl_for() {
fxt.Init_page_create("Template:For", "For {{#if:{{{1|}}}|{{{1}}}|other uses}}, see [[{{{2|{{PAGENAME}} (disambiguation)}}}]]{{#if:{{{3|}}}|{{#if:{{{4|}}}|, [[{{{3}}}]], {{#if:{{{5|}}}|[[{{{4}}}]], and [[{{{5}}}]]|and [[{{{4}}}]]}}|&#32;and [[{{{3}}}]]}}}}.");
}
private void Init_tmpl_other_uses() {
Init_tmpl_about();
fxt.Init_page_create("Template:Other uses", "{{#if:{{{2|}}}|{{about|||{{{1}}}|and|{{{2|}}}|_nocat=1}}|{{about|||{{{1|{{PAGENAME}} (disambiguation)}}}|_nocat=1}}}}");
}
private void Init_tmpl_about() {
fxt.Init_page_create("Template:!", "|");
fxt.Init_page_create("Template:About", String_.Concat_lines_nl
( "{{#if: {{{1|}}}|<!--"
, " -->This {{#ifeq:{{NAMESPACE}}|{{ns:0}}|article|page}} is about {{{1}}}.&#32;&#32;}}<!--"
, "-->For {{#if:{{{2|}}}|{{{2}}}|other uses}}, see {{#if:{{{3|}}}|[[{{{3}}}]]{{#ifeq:{{{4|}}}|and|&#32;and {{#if:{{{5|}}}|[[{{{5}}}]]|[[{{PAGENAME}} (disambiguation)]]}}}}|[[{{PAGENAME}} (disambiguation)]]}}.<!--"
, "-->{{#if:{{{2|}}}|{{#if:{{{4|}}}|<!--"
, " -->{{#ifeq:{{{4|}}}|and||<!-- 'and' is a special word, don't output 'For and, ...'"
, " -->&#32;&#32;For {{#ifeq:{{{4}}}|1|other uses|{{{4}}}}}, see {{#if:{{{5|}}}|[[{{{5}}}]]{{#ifeq:{{{6|}}}|and|&#32;and {{#if:{{{7|}}}|[[{{{7}}}]]|[[{{PAGENAME}} (disambiguation)]]}}}}|[[{{PAGENAME}} (disambiguation)]]}}.}}<!--"
, " -->{{#if:{{{6|}}}|<!--"
, " -->{{#ifeq:{{{6|}}}|and||<!--"
, " -->&#32;&#32;For {{#ifeq:{{{6}}}|1|other uses|{{{6}}}}}, see {{#if:{{{7|}}}|[[{{{7}}}]]{{#ifeq:{{{8|}}}|and|&#32;and {{#if:{{{9|}}}|[[{{{9}}}]]|[[{{PAGENAME}} (disambiguation)]]}}}}|[[{{PAGENAME}} (disambiguation)]]}}.}}<!--"
, " -->{{#if:{{{8|}}}|<!--"
, " -->{{#ifeq:{{{8|}}}|and||<!--"
, " -->&#32;&#32;For {{#ifeq:{{{8}}}|1|other uses|{{{8}}}}}, see {{#if:{{{9|}}}|[[{{{9}}}]]|[[{{PAGENAME}} (disambiguation)]]}}.}}<!--"
, " -->}}<!--"
, " -->}}<!--"
, "-->}}}}<!--"
, "-->{{#if:{{{_nocat|}}}||{{#if:{{{1|}}}{{{2|}}}||{{#if:{{{3|}}}|[[Category:Hatnote templates using unusual parameters|A{{PAGENAME}}]]}}}}{{#ifeq:{{str left|{{{1}}}|3}}|is |[[Category:Hatnote templates using unusual parameters|B{{PAGENAME}}]]}}}}"
));
}
private void Init_tmpl_see_also() {
fxt.Init_page_create("Template:See also", String_.Concat_lines_nl
( "See also: {{#if:{{{1<includeonly>|</includeonly>}}} |<!--then:-->[[{{{1}}}{{#if:{{{label 1|{{{l1|}}}}}}|{{!}}{{{label 1|{{{l1}}}}}}}}]] |<!--else:-->'''Error: [[Template:See also|Template must be given at least one article name]]'''"
, "}}{{#if:{{{2|}}}|{{#if:{{{3|}}}|, |&nbsp;and }} [[{{{2}}}{{#if:{{{label 2|{{{l2|}}}}}}|{{!}}{{{label 2|{{{l2}}}}}}}}]]"
, "}}{{#if:{{{3|}}}|{{#if:{{{4|}}}|, |,&nbsp;and }} [[{{{3}}}{{#if:{{{label 3|{{{l3|}}}}}}|{{!}}{{{label 3|{{{l3}}}}}}}}]]"
, "}}{{#if:{{{4|}}}|{{#if:{{{5|}}}|, |,&nbsp;and }} [[{{{4}}}{{#if:{{{label 4|{{{l4|}}}}}}|{{!}}{{{label 4|{{{l4}}}}}}}}]]"
, "}}{{#if:{{{5|}}}|{{#if:{{{6|}}}|, |,&nbsp;and }} [[{{{5}}}{{#if:{{{label 5|{{{l5|}}}}}}|{{!}}{{{label 5|{{{l5}}}}}}}}]]"
, "}}{{#if:{{{6|}}}|{{#if:{{{7|}}}|, |,&nbsp;and }} [[{{{6}}}{{#if:{{{label 6|{{{l6|}}}}}}|{{!}}{{{label 6|{{{l6}}}}}}}}]]"
, "}}{{#if:{{{7|}}}|{{#if:{{{8|}}}|, |,&nbsp;and }} [[{{{7}}}{{#if:{{{label 7|{{{l7|}}}}}}|{{!}}{{{label 7|{{{l7}}}}}}}}]]"
, "}}{{#if:{{{8|}}}|{{#if:{{{9|}}}|, |,&nbsp;and }} [[{{{8}}}{{#if:{{{label 8|{{{l8|}}}}}}|{{!}}{{{label 8|{{{l8}}}}}}}}]]"
, "}}{{#if:{{{9|}}}|{{#if:{{{10|}}}|, |,&nbsp;and }} [[{{{9}}}{{#if:{{{label 9|{{{l9|}}}}}}|{{!}}{{{label 9|{{{l9}}}}}}}}]]"
, "}}{{#if:{{{10|}}}|{{#if:{{{11|}}}|, |,&nbsp;and }} [[{{{10}}}{{#if:{{{label 10|{{{l10|}}}}}}|{{!}}{{{label 10|{{{l10}}}}}}}}]]"
, "}}{{#if:{{{11|}}}|{{#if:{{{12|}}}|, |,&nbsp;and }} [[{{{11}}}{{#if:{{{label 11|{{{l11|}}}}}}|{{!}}{{{label 11|{{{l11}}}}}}}}]]"
, "}}{{#if:{{{12|}}}|{{#if:{{{13|}}}|, |,&nbsp;and }} [[{{{12}}}{{#if:{{{label 12|{{{l12|}}}}}}|{{!}}{{{label 12|{{{l12}}}}}}}}]]"
, "}}{{#if:{{{13|}}}|{{#if:{{{14|}}}|, |,&nbsp;and }} [[{{{13}}}{{#if:{{{label 13|{{{l13|}}}}}}|{{!}}{{{label 13|{{{l13}}}}}}}}]]"
, "}}{{#if:{{{14|}}}|{{#if:{{{15|}}}|, |,&nbsp;and }} [[{{{14}}}{{#if:{{{label 14|{{{l14||}}}}}}|{{!}}{{{label 14|{{{l14}}}}}}}}]]"
, "}}{{#if:{{{15|}}}|,&nbsp;and [[{{{15}}}{{#if:{{{label 15|{{{l15}}}}}}|{{!}}{{{label 15|{{{l15}}}}}}}}]]"
, "}}{{#if:{{{16|}}}| &mdash; '''<br/>Error: [[Template:See also|Too many links specified (maximum is 15)]]'''"
, "}}"
));
}
private void Init_tmpl_redirect() {
fxt.Init_page_create("Template:Redirect", String_.Concat_lines_nl
( "\"{{{1}}}\" redirects here. For {{#if:{{{2|}}}|{{{2}}}|other uses}}, see {{#if:{{{3|}}}|[[{{{3}}}]]{{#ifeq:{{{4|}}}|and|&#32;and {{#if:{{{5|}}}|[[{{{5}}}]]|[[{{{1}}} (disambiguation)]]}}}}|[[{{{1}}} (disambiguation)]]}}.<!--"
, "-->{{#if:{{{2|}}}|{{#if:{{{4|}}}|<!--"
, " -->{{#ifeq:{{{4|}}}|and||<!-- \"and\" is a special word, don't output \"For and, ...\""
, " -->&#32;&#32;For {{#ifeq:{{{4}}}|1|other uses|{{{4}}}}}, see {{#if:{{{5|}}}|[[{{{5}}}]]{{#ifeq:{{{6|}}}|and|&#32;and {{#if:{{{7|}}}|[[{{{7}}}]]|[[{{{4}}} (disambiguation)]]}}}}|[[{{{4}}} (disambiguation)]]}}.}}<!--"
, " -->{{#if:{{{6|}}}|<!--"
, " -->{{#ifeq:{{{6|}}}|and||<!--"
, " -->&#32;&#32;For {{#ifeq:{{{6}}}|1|other uses|{{{6}}}}}, see {{#if:{{{7|}}}|[[{{{7}}}]]{{#ifeq:{{{8|}}}|and|&#32;and {{#if:{{{9|}}}|[[{{{9}}}]]|[[{{{6}}} (disambiguation)]]}}}}|[[{{{6}}} (disambiguation)]]}}.}}<!--"
, " -->{{#if:{{{8|}}}|<!--"
, " -->{{#ifeq:{{{8|}}}|and||<!--"
, " -->&#32;&#32;For {{#ifeq:{{{8}}}|1|other uses|{{{8}}}}}, see {{#if:{{{9|}}}|[[{{{9}}}]]|[[{{{8}}} (disambiguation)]]}}.}}<!--"
, " -->}}<!--"
, " -->}}<!--"
, "-->}}}}"
));
}
}

View File

@@ -0,0 +1,46 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xot_invk_sandbox_tst {
private final Xop_fxt fxt = new Xop_fxt();
@Before public void init() {
fxt.Reset();
fxt.Init_defn_clear();
fxt.Init_defn_add("concat", "{{{1}}}{{{2}}}");
}
@Test public void Basic() {
fxt.Test_parse_tmpl_str("{{concat|a|b}}", "ab");
}
@Test public void Basic_too_many() { // c gets ignored
fxt.Test_parse_tmpl_str("{{concat|a|b|c}}", "ab");
}
@Test public void Basic_too_few() {
fxt.Test_parse_tmpl_str("{{concat|a}}", "a{{{2}}}");
}
@Test public void Basic_else() {
fxt.Init_defn_add("concat", "{{{1}}}{{{2|?}}}");
fxt.Test_parse_tmpl_str("{{concat|a}}", "a?");
}
@Test public void Eq_2() {
fxt.Init_defn_add("concat", "{{{lkp1}}}");
fxt.Test_parse_tmpl_str("{{concat|lkp1=a=b}}", "a=b");
}
@Test public void Recurse() {fxt.Test_parse_tmpl_str_test("<{{concat|{{{1}}}|{{{2}}}}}>" , "{{test|a|b}}", "<ab>");}
@Test public void Recurse_mix() {fxt.Test_parse_tmpl_str_test("{{concat|.{{{1}}}.|{{{2}}}}}" , "{{test|a|b}}", ".a.b");}
@Test public void Recurse_err() {fxt.Test_parse_tmpl_str_test("{{concat|{{{1}}}|{{{2}}}}}" , "{{test1|a|b}}", "[[:Template:test1]]");} // NOTE: make sure test1 does not match test
@Test public void KeyNewLine() {fxt.Test_parse_tmpl_str_test("{{\n concat|a|b}}" , "{{\n test}}", "ab");}
}

View File

@@ -0,0 +1,438 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*; import gplx.xowa.wikis.ttls.*; import gplx.xowa.wikis.nss.*;
public class Xot_invk_wkr__basic__tst {
private final Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@Test public void Basic() {
fxt.Test_parse_page_tmpl("{{a}}", fxt.tkn_tmpl_invk_w_name(0, 5, 2, 3));
}
@Test public void Arg_many() {
fxt.Test_parse_page_tmpl("{{a|b|c|d}}", fxt.tkn_tmpl_invk_w_name(0, 11, 2, 3)
.Args_(fxt.tkn_arg_val_txt_(4, 5), fxt.tkn_arg_val_txt_(6, 7), fxt.tkn_arg_val_txt_(8, 9)));
}
@Test public void Kv() {
fxt.Test_parse_page_tmpl("{{a|b=c}}", fxt.tkn_tmpl_invk_w_name(0, 9, 2, 3)
.Args_
( fxt.tkn_arg_nde_()
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(4, 5)))
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(6, 7)))
));
}
@Test public void Kv_arg() {
fxt.Test_parse_tmpl("{{a|b={{{1}}}}}", fxt.tkn_tmpl_invk_w_name(0, 15, 2, 3)
.Args_
( fxt.tkn_arg_nde_()
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(4, 5)))
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_tmpl_prm_find_(fxt.tkn_txt_(9, 10))))
));
}
@Test public void Kv_tmpl_compiled() {
fxt.Test_parse_tmpl("{{a|b={{c}}}}", fxt.tkn_tmpl_invk_w_name(0, 13, 2, 3)
.Args_
( fxt.tkn_arg_nde_()
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(4, 5)))
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_tmpl_invk_w_name(6, 11, 8, 9)))
));
}
@Test public void Kv_tmpl_dynamic() {
fxt.Test_parse_tmpl("{{a|b={{c|{{{1}}}}}}}", fxt.tkn_tmpl_invk_w_name(0, 21, 2, 3)
.Args_
( fxt.tkn_arg_nde_()
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(4, 5)))
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_tmpl_invk_w_name(6, 19, 8, 9).Args_(fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_().Subs_(fxt.tkn_tmpl_prm_find_(fxt.tkn_txt_(13, 14))))))
)
));
}
@Test public void Nest() {
fxt.Test_parse_page_tmpl("{{a|b{{c|d}}e}}", fxt.tkn_tmpl_invk_w_name(0, 15, 2, 3).Args_
( fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_
( fxt.tkn_txt_(4, 5)
, fxt.tkn_tmpl_invk_w_name(5, 12, 7, 8).Args_
( fxt.tkn_arg_val_txt_(9, 10)
)
, fxt.tkn_txt_(12, 13)
))
));
}
@Test public void Whitespace() {
fxt.Test_parse_page_tmpl("{{a| b = c }}", fxt.tkn_tmpl_invk_w_name(0, 13, 2, 3).Args_
( fxt.tkn_arg_nde_()
.Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_space_(4, 5).Ignore_y_(), fxt.tkn_txt_(5, 6), fxt.tkn_space_( 6, 7).Ignore_y_()))
.Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_space_(8, 9).Ignore_y_(), fxt.tkn_txt_(9, 10), fxt.tkn_space_(10, 11).Ignore_y_()))
));
}
@Test public void Whitespace_nl() {
fxt.Test_parse_page_tmpl("{{a|b=c\n}}", fxt.tkn_tmpl_invk_w_name(0, 10, 2, 3).Args_
( fxt.tkn_arg_nde_()
.Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(4, 5)))
.Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(6, 7), fxt.tkn_nl_char_(7, 8).Ignore_y_()))
));
}
@Test public void Err_noName() { // WP: [[Russian language]]
fxt.Test_parse_page_tmpl("{{|}}", fxt.tkn_curly_bgn_(0), fxt.tkn_pipe_(2), fxt.tkn_txt_(3, 5));
}
@Test public void Err_noName_nl() {
fxt.Test_parse_page_tmpl("{{\n|}}", fxt.tkn_curly_bgn_(0), fxt.tkn_nl_char_len1_(2), fxt.tkn_pipe_(3), fxt.tkn_txt_(4, 6));
}
@Test public void Err_noName_tab() {
fxt.Test_parse_page_tmpl("{{\t|}}", fxt.tkn_curly_bgn_(0), fxt.tkn_tab_(2), fxt.tkn_pipe_(3), fxt.tkn_txt_(4, 6));
}
@Test public void Err_empty() { // WP: [[Set theory]]
fxt.Test_parse_page_tmpl("{{}}", fxt.tkn_txt_(0, 4));
}
@Test public void DynamicName() {
fxt.Init_defn_clear();
fxt.Init_defn_add("proc_1", "proc_1 called");
fxt.Init_defn_add("proc_2", "proc_2 called");
fxt.Test_parse_tmpl_str_test("{{proc_{{{1}}}}}" , "{{test|1}}" , "proc_1 called");
fxt.Test_parse_tmpl_str_test("{{proc_{{{1}}}}}" , "{{test|2}}" , "proc_2 called");
fxt.Test_parse_tmpl_str_test("{{proc_{{#expr:1}}}}" , "{{test}}" , "proc_1 called");
}
@Test public void Comment() {
fxt.Test_parse_tmpl_str_test("b" , "{{test<!--a-->}}" , "b");
}
@Test public void Err_equal() { // WP:[[E (mathematical constant)]]
fxt.Test_parse_page_tmpl("{{=}}", fxt.tkn_tmpl_invk_(0, 5).Name_tkn_(fxt.tkn_arg_nde_(2, 3).Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_eq_(2)))));
}
@Test public void Err_dangling() { // WP:[[Antoni Salieri]]; {{icon it}\n
fxt.Test_parse_page_tmpl("{{fail} {{pass}}", fxt.tkn_curly_bgn_(0), fxt.tkn_txt_(2, 7), fxt.tkn_space_(7, 8), fxt.tkn_tmpl_invk_w_name(8, 16, 10, 14));
}
@Test public void MultipleColon() {
fxt.Init_defn_clear();
fxt.Init_defn_add("H:IPA", "{{{1}}}");
fxt.Test_parse_tmpl_str_test("{{H:IPA|{{{1}}}}}" , "{{test|a}}" , "a");
}
@Test public void RedundantTemplate() { // {{Template:a}} == {{a}}
fxt.Init_defn_clear();
fxt.Init_defn_add("a", "a");
fxt.Test_parse_tmpl_str_test("{{Template:a}}" , "{{test}}" , "a");
fxt.Init_defn_clear();
}
@Test public void Lnki() { // PURPOSE: pipe inside lnki should not be interpreted for tmpl: WP:[[Template:Quote]]
fxt.Test_parse_tmpl_str_test("{{{1}}}{{{2}}}" , "{{test|[[a|b]]|c}}" , "[[a|b]]c");
}
@Test public void Lnki2() {// PURPOSE: pipe inside lnki inside tmpl should be interpreted WP:[[H:IPA]]
fxt.Test_parse_tmpl_str_test("[[a|{{#switch:{{{1}}}|b=c]]|d=e]]|f]]}}" , "{{test|b}}" , "[[a|c]]");
}
@Test public void Nowiki() { // PURPOSE: nowiki tag should be ignored: en.w:Template:Main
fxt.Test_parse_tmpl_str_test("<div <nowiki>class='a'</nowiki> />" , "{{test}}" , "<div <nowiki>class='a'</nowiki> />");
}
@Test public void Nowiki_if() { // PURPOSE: templates and functions inside nowiki should not be evaluated
fxt.Test_parse_tmpl_str_test("a <nowiki>{{#if:|y|n}}</nowiki> b" , "{{test}}" , "a <nowiki>{{#if:|y|n}}</nowiki> b");
}
@Test public void Nowiki_endtag() { // PURPOSE: <nowiki/> should not match </nowiki>
fxt.Test_parse_page_all_str("<nowiki /> ''b'' <nowiki>c</nowiki>" , " <i>b</i> c");
}
@Test public void Nowiki_xnde_frag() { // PURPOSE: nowiki did not handle xnde frag and literalized; nowiki_xnde_frag; DATE:2013-01-27
fxt.Test_parse_page_all_str("<nowiki><pre></nowiki>{{#expr:1}}<pre>b</pre>" , "&lt;pre&gt;1<pre>b</pre>");
}
@Test public void Nowiki_lnki() { // PURPOSE: nowiki should noop lnkis; DATE:2013-01-27
fxt.Test_parse_page_all_str("<nowiki>[[A]]</nowiki>" , "[[A]]");
}
@Test public void Nowiki_underscore() { // PURPOSE: nowiki did not handle __DISAMBIG__; DATE:2013-07-28
fxt.Test_parse_page_all_str("<nowiki>__DISAMBIG__</nowiki>" , "__DISAMBIG__");
}
@Test public void Nowiki_asterisk() { // PURPOSE: nowiki should noop lists; DATE:2013-08-26
fxt.Test_parse_page_all_str("<nowiki>*a</nowiki>", "*a");
}
@Test public void Nowiki_space() { // PURPOSE: nowiki should noop space (else pre); DATE:2013-09-03
fxt.Init_para_y_();
fxt.Test_parse_page_all_str("a\n<nowiki> </nowiki>b", "<p>a\n b\n</p>\n");
fxt.Init_para_n_();
}
@Test public void LnkiWithPipe_basic() { // PURPOSE: pipe in link should not count towards tmpl: WP:{{H:title|dotted=no|pronunciation:|[[File:Loudspeaker.svg|11px|link=|alt=play]]}}
fxt.Test_parse_tmpl_str_test("{{{1}}}{{{2}}}" , "{{test|[[b=c|d]]}}" , "[[b=c|d]]{{{2}}}");
}
@Test public void LnkiWithPipe_nested() {
fxt.Test_parse_tmpl_str_test("{{{1}}}{{{2}}}" , "{{test|[[b=c|d[[e|f]]g]]}}" , "[[b=c|d[[e|f]]g]]{{{2}}}");
}
@Test public void LnkiWithPipe_unclosed() {
fxt.Test_parse_tmpl_str_test("{{{1}}}{{{2}}}" , "{{test|[[b=c|d}}" , "{{test|[[b=c|d}}");
}
@Test public void Err_tmp_empty() { // PURPOSE: {{{{R from misspelling}} }}
fxt.Test_parse_tmpl_str_test("{{{1}}}" , "{{ {{a}} }}" , "{{[[:Template:a]]}}");
}
@Test public void Mismatch_bgn() { // PURPOSE: handle {{{ }}; WP:Paris Commune; Infobox Former Country
fxt.Init_defn_clear();
fxt.Init_defn_add("!", "|");
fxt.Test_parse_tmpl_str_test("{{#if:|{{{!}}{{!}}}|x}}" , "{{test}}" , "x");
}
@Test public void Mismatch_tblw() { // PURPOSE: handle {{{!}}; WP:Soviet Union
fxt.Init_defn_clear();
fxt.Init_defn_add("!", "|");
fxt.Test_parse_page_all_str("a\n{{{!}}\n|b\n|}", String_.Concat_lines_nl_skip_last
( "a"
, "<table>"
, " <tr>"
, " <td>b"
, " </td>"
, " </tr>"
, "</table>"
, ""
)
);
fxt.Init_defn_clear();
}
@Test public void Lnki_space() {
fxt.Init_defn_clear();
fxt.Init_defn_add("c", "{{{1}}}");
fxt.Test_parse_tmpl_str("{{c|[[a|b ]]}}", "[[a|b ]]");
}
@Test public void Bug_innerTemplate() { // PURPOSE: issue with inner templates not using correct key
fxt.Init_defn_clear();
fxt.Init_defn_add("temp_1", "{{temp_2|key1=val1}}");
fxt.Init_defn_add("temp_2", "{{{key1}}}");
fxt.Test_parse_tmpl_str("{{temp_1}}", "val1");
}
@Test public void Xnde_xtn_preserved() { // PURPOSE: tmpl was dropping .Xtn ndes;
fxt.Init_defn_clear();
fxt.Init_defn_add("test_template", "{{{1}}}");
fxt.Test_parse_page_all_str("{{test_template|a<source>1</source>b}}", "a<div class=\"mw-highlight\"><pre style=\"overflow:auto\">1</pre></div>b"); // was just ab
fxt.Init_defn_clear();
}
@Test public void Recurse() {
fxt.Init_defn_clear();
fxt.Init_defn_add("test_recurse", "bgn:{{test_recurse}}:end");
fxt.Test_parse_page_all_str("{{test_recurse}}", "bgn::end");
fxt.Init_defn_clear();
}
@Test public void Ws_nl() {
fxt.Test_parse_tmpl_str_test("{{{1}}}" , "{{test|\na}}" , "\na");
}
@Test public void Ws_trimmed_key_0() { // PURPOSE: control test for key_1, key_2
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{test_2|{{{1}}}}}");
fxt.Init_defn_add("test_2", "{{{1}}}");
fxt.Test_parse_tmpl_str("{{test_1| a }}", " a ");
fxt.Init_defn_clear();
}
@Test public void Ws_trimmed_key_1() { // PURPOSE: trim prm when passed as key;
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{test_2|key={{{1}}}}}");
fxt.Init_defn_add("test_2", "{{{key}}}");
fxt.Test_parse_tmpl_str("{{test_1| a }}", "a");
fxt.Init_defn_clear();
}
@Test public void Ws_trimmed_key_2() { // PURPOSE: trim prm; note that 1 is key not idx; PAGE:en.w:Coord in Chernobyl disaster, Sahara
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{test_2|1={{{1}}}}}");
fxt.Init_defn_add("test_2", "{{{1}}}");
fxt.Test_parse_tmpl_str("{{test_1| a }}", "a");
fxt.Init_defn_clear();
}
@Test public void Ws_trimmed_key_3() { // PURPOSE: trim entire arg only, not individual prm
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{test_2|1={{{1}}}{{{2}}}}}");
fxt.Init_defn_add("test_2", "{{{1}}}");
fxt.Test_parse_tmpl_str("{{test_1| a | b }}", "a b");
fxt.Init_defn_clear();
}
@Test public void Ws_eval_prm() { // PURPOSE: skip ws in prm_idx; EX:it.w:Portale:Giochi_da_tavolo; it.w:Template:Alternate; DATE:2014-02-09
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", String_.Concat_lines_nl_skip_last
( "{{{ {{#expr: 1}} }}}"
));
fxt.Test_parse_tmpl_str("{{test_1|a}}", "a");
fxt.Init_defn_clear();
}
@Test public void Keyd_arg_is_trimmed() { // PURPOSE: trim entire arg only, not individual prm; PAGE:en.w:William Shakespeare; {{Relatebardtree}}
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{test_2|1={{{{{{1}}}}}}}}");
fxt.Init_defn_add("test_2", "{{{1}}}");
fxt.Test_parse_tmpl_str("{{test_1| b | b = x }}", "x");
fxt.Init_defn_clear();
}
@Test public void Ws_arg() { // PURPOSE: whitespace arg should not throw array index out of bounds; EX.WIKT: wear one's heart on one's sleeve
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{{{{1}}}}}");
fxt.Test_parse_tmpl_str("{{test_1| }}", "");
fxt.Init_defn_clear();
}
@Test public void Xnde_xtn_ref_not_arg() { // PURPOSE: <ref name= should not be interpreted as arg; EX: {{tmp|a<ref name="b"/>}}; arg1 is a<ref name="b"/> not "b"; PAGE:en.w:WWI
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{{1}}}");
fxt.Test_parse_page_tmpl_str("{{test_1|a<ref name=b />}}", "a<ref name=b />");
fxt.Init_defn_clear();
}
@Test public void Multi_bgn_5_end_3_2() {
fxt.Test_parse_tmpl("{{{{{1}}}|a}}", fxt.tkn_tmpl_invk_(0, 13)
.Name_tkn_(fxt.tkn_arg_nde_(2, 9).Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_tmpl_prm_find_(fxt.tkn_txt_(5, 6)))))
.Args_
( fxt.tkn_arg_val_txt_(10, 11)
)
);
}
@Test public void Lnki_has_invk_end() {// PURPOSE: [[A|bcd}}]] should not break enclosing templates; EX.CM:Template:Protect
fxt.Test_parse_page_tmpl_str(String_.Concat_lines_nl_skip_last
( "{{#switch:y"
, " |y=[[A|b}}]]"
, " |#default=n"
, "}}"
), "[[A|b}}]]");
}
@Test public void Lnki_has_prm_end() {// PURPOSE: [[A|bcd}}}]] should not break enclosing templates; EX.CM:Template:Protect
fxt.Test_parse_page_tmpl_str(String_.Concat_lines_nl_skip_last
( "{{#switch:y"
, " |y=[[A|b}}}]]"
, " |#default=n"
, "}}"
), "[[A|b}}}]]");
}
@Test public void Tmpl_overrides_pfunc() { // PURPOSE: {{plural|}} overrides {{plural:}}
fxt.Init_defn_clear();
fxt.Init_defn_add("plural", "{{{1}}}");
fxt.Test_parse_tmpl_str("{{plural|a}}" , "a");
fxt.Test_parse_tmpl_str("{{plural:2|a|b}}" , "b"); // make sure pfunc still works
fxt.Init_defn_clear();
}
@Test public void Tmpl_aliases() { // PURPOSE: handled aliases for Template ns
fxt.Wiki().Ns_mgr().Aliases_add(Xow_ns_.Tid__template, "TemplateAlias");
fxt.Wiki().Ns_mgr().Init();
fxt.Init_defn_clear();
fxt.Init_defn_add("tmpl_key", "tmpl_val");
fxt.Test_parse_tmpl_str("{{TemplateAlias:tmpl_key}}" , "tmpl_val");
fxt.Init_defn_clear();
}
@Test public void Tmpl_aliases_2() { // PURPOSE: handled aliases for other ns; DATE:2013-02-08
fxt.Wiki().Ns_mgr().Aliases_add(Xow_ns_.Tid__project, "WP");
fxt.Wiki().Ns_mgr().Init();
fxt.Init_defn_clear();
fxt.Init_page_create("Project:tmpl_key", "tmpl_val");
fxt.Test_parse_tmpl_str("{{WP:tmpl_key}}" , "tmpl_val");
fxt.Init_defn_clear();
}
@Test public void Template_loop_across_namespaces() {// PURPOSE: {{Institution:Louvre}} results in template loop b/c it calls {{Louvre}}; EX: c:Mona Lisa
fxt.Init_page_create("Template:Test", "test");
fxt.Init_page_create("Category:Test", "{{Test}}");
fxt.Test_parse_page_all_str("{{Category:Test}}", "test");
}
@Test public void Closing_braces_should_not_extend_beyond_lnki() { // PURPOSE: extra }} should not close any frames beyond lnki; EX:w:Template:Cite wikisource; w:John Fletcher (playwright)
fxt.Init_defn_clear();
fxt.Init_defn_add("test_b", "{{{test_b_0|}}}");
fxt.Init_defn_add("test_a", "{{test_b|test_b_0=[[{{{test_a_0}}}}}]]}}"); // NOTE: extra 2 }}; should render literally and not close "{{test_b"
fxt.Test_parse_tmpl_str("{{test_a|test_a_0=1}}" , "[[1}}]]");
fxt.Init_defn_clear();
}
// @Test public void Trim_ws_on_sub_tmpls() { // PURPOSE: ws should be trimmed on eval tkns; EX:w:Lackawanna Cut-Off; {{Lackawanna Cut-Off}}; DELETE: no longer needed; DATE:2014-02-04
// fxt.Init_defn_clear();
// fxt.Init_defn_add("test_b", "\n\nb\n\n");
// fxt.Init_defn_add("test_a", "a{{test_b}}c");
// fxt.Test_parse_tmpl_str("{{test_a}}" , "a\n\nbc");
// fxt.Init_defn_clear();
// }
@Test public void Nowiki_tblw() { // PURPOSE: nowiki does not exclude sections with pipe; will cause tables to fail; EX: de.wikipedia.org/wiki/Hilfe:Vorlagenprogrammierung
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "{|"
, "|-"
, "|<nowiki>{{ #time:M|Jan}}</nowiki>"
, "|}"
), String_.Concat_lines_nl_skip_last
( "<table>"
, " <tr>"
, " <td>{{ #time:M|Jan}}"
, " </td>"
, " </tr>"
, "</table>"
, ""
));
}
@Test public void Template_plus_other_ns() { // PURPOSE.fix: Template:Wikipedia:A was transcluding "Wikipedia:A" instead of "Template:Wikipedia:A"; DATE:2013-04-03
fxt.Init_defn_clear();
fxt.Init_page_create("Template:Wikipedia:A" , "B");
fxt.Test_parse_tmpl_str("{{Template:Wikipedia:A}}" , "B");
fxt.Init_defn_clear();
}
@Test public void Return_nl() { // PURPOSE: allow \n to be returned by tmpl; do not trim; EX: zh.wikipedia.org/wiki/北區_(香港); DATE:2014-02-04
fxt.Init_defn_add("1x", "{{{1}}}");
fxt.Test_parse_tmpl_str("a{{1x|\n}}b", "a\nb");
fxt.Init_defn_clear();
}
@Test public void Ignore_hdr() { // PURPOSE: hdr-like tkns inside tmpl should not be treated as "=" in tmpl_prm; EX: key_1\n==a==; EX:it.b:Wikibooks:Vetrina; DATE:2014-02-09
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{{key_1|null_key_1}}}");
fxt.Test_parse_tmpl_str(String_.Concat_lines_nl_skip_last // == a === should be treated as hdr;
( "{{test_1|key_1"
, "== a =="
, "}}"
)
, "null_key_1"
);
fxt.Test_parse_tmpl_str(String_.Concat_lines_nl_skip_last // = a = should not be treated as hdr;
( "{{test_1|key_1"
, "= a ="
, "}}"
)
, "a ="
);
fxt.Init_defn_clear();
}
@Test public void Ignore_hdr_2() { // PURPOSE: hdr-like logic did not work for "== \n"; PAGE:nl.q:Geert_Wilders; DATE:2014-06-05
fxt.Init_defn_clear();
fxt.Init_defn_add("Hdr_w_space", String_.Concat_lines_nl_skip_last
( "{{#if:{{{key|}}} | "
, "==={{{key}}}=== " // NOTE " " after "==="
, "|}}"
));
fxt.Test_parse_page_tmpl_str(String_.Concat_lines_nl_skip_last
( "{{Hdr_w_space"
, "|key=A"
, "}}"
), "===A==="
);
fxt.Init_defn_clear();
}
@Test public void Ignore_hdr_3() { // PURPOSE: tkn with multiple eq should have be treated as value, not header; PAGE:zh.w:Wikipedia:条目评选; DATE:2014-08-27
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{{key_1|null_key_1}}}");
fxt.Test_parse_page_tmpl_str(String_.Concat_lines_nl_skip_last
( "{{test_1"
, "|key_1===A==" // note that this is not "===A==", but "=","===A=="
, "}}"
), "==A=="
);
fxt.Init_defn_clear();
}
@Test public void Ignore_hdr_4() { // PURPOSE: variation of above; make sure 2nd "==" doesn't trigger another key; DATE:2014-08-27
fxt.Init_defn_clear();
fxt.Init_defn_add("test_1", "{{{key_1|null_key_1}}}");
fxt.Test_parse_page_tmpl_str(String_.Concat_lines_nl_skip_last
( "{{test_1"
, "|key_1===A===B" // = should be at "==A", not "==B"
, "}}"
), "==A===B"
);
fxt.Init_defn_clear();
}
@Test public void Tmpl_case_match() { // PURPOSE: template name should match by case; EX:es.d:eclipse; DATE:2014-02-12
fxt.Init_defn_clear();
fxt.Init_defn_add("CASE_MATCH", "found", Xow_ns_case_.Tid__all);
fxt.Test_parse_tmpl_str("{{case_match}}", "[[:Template:case_match]]"); // Xot_invk_tkn will do 2 searches: "test" and "Test"
fxt.Test_parse_tmpl_str("{{cASE_MATCH}}", "found"); // Xot_invk_tkn will do 2 searches: "tEST" and "TEST"
fxt.Init_defn_clear();
}
@Test public void Kv_same() { // PURPOSE: multiple identical keys should retrieve last, not first; EX: {{A|1=a|1=b}}; PAGE:el.d:ἔχω DATE:2014-07-23
fxt.Init_defn_clear();
fxt.Init_defn_add("tmpl_1", "{{{1}}}");
fxt.Test_parse_tmpl_str_test("{{tmpl_1|1=a|1=b}}" , "{{test}}" , "b"); // duplicate "1"; use last
fxt.Test_parse_tmpl_str_test("{{tmpl_1|a|1=b}}" , "{{test}}" , "b"); // "a" has implicit key of "1"; overwritten by "1=b"; verified against MW
fxt.Test_parse_tmpl_str_test("{{tmpl_1|1=a|b}}" , "{{test}}" , "b"); // "b" has implicit key of "1"; overwritten by "1=b"; verified against MW
}
@Test public void Bang() { // PURPOSE: support new bang keyword; DATE:2014-08-05
fxt.Test_parse_tmpl_str("{{!}}", "|");
}
}

View File

@@ -0,0 +1,45 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*; import gplx.xowa.wikis.ttls.*; import gplx.xowa.wikis.nss.*;
public class Xot_invk_wkr__missing__tst {
@Before public void init() {fxt.Reset();} private final Xop_fxt fxt = new Xop_fxt();
@Test public void Missing() {
fxt.Init_defn_clear();
fxt.Init_defn_add("test_template", "{{[[Template:{{{1}}}|{{{1}}}]]}}");
fxt.Test_parse_tmpl_str("{{test_template|a}}", "{{[[Template:a|a]]}}");
fxt.Init_defn_clear();
}
@Test public void Missing__name_and_args() { // PURPOSE: missing title should return name + args; used to only return name; PAGE:en.w:Flag_of_Greenland; DATE:2016-06-21
fxt.Init_defn_clear();
fxt.Init_defn_add("test_template", "{{ {{{1}}} | a | b }}");
fxt.Test_parse_tmpl_str("{{test_template}}", "{{{{{1}}}| a | b }}"); // NOTE: this should include spaces (" {{{1}}} "), but for now, ignore
fxt.Init_defn_clear();
}
@Test public void Missing__evaluate_optional() { // PURPOSE: missing title should still evaulate optional args; "{{{a|}}}" -> ""; PAGE:en.w:Europe; en.w:Template:Country_data_Guernsey DATE:2016-10-13
fxt.Init_defn_clear();
fxt.Init_defn_add("test_template", "{{ {{{1}}} | {{{a|}}} | b }}");
fxt.Test_parse_tmpl_str("{{test_template}}", "{{{{{1}}}| | b }}"); // NOTE: "| |" not "| {{{a|}}} |"
fxt.Init_defn_clear();
}
@Test public void Missing_foreign() {
Xow_ns ns = fxt.Wiki().Ns_mgr().Ns_template();
byte[] old_ns = ns.Name_db();
ns.Name_bry_(Bry_.new_a7("Template_foreign"));
fxt.Test_parse_tmpl_str("{{Missing}}", "[[:Template_foreign:Missing]]");
ns.Name_bry_(old_ns);
}
}

View File

@@ -0,0 +1,119 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xot_invk_wkr__prepend_nl__tst {
@Before public void init() {fxt.Reset();} private final Xop_fxt fxt = new Xop_fxt();
@Test public void Basic() { // PURPOSE: if {| : ; # *, auto add new_line REF.MW:Parser.php|braceSubstitution
fxt.Init_defn_clear();
fxt.Init_defn_add("test_inner", "# a");
fxt.Test_parse_tmpl_str_test("{{test_inner}}" , "z {{test}}" , "z \n# a");
fxt.Init_defn_clear();
}
@Test public void Skip_if_nl_exists() {
fxt.Init_defn_clear();
fxt.Init_defn_add("test_inner", "# a");
fxt.Test_parse_tmpl_str_test("{{test_inner}}" , "z \n{{test}}" , "z \n# a"); // NOTE: no \n
fxt.Init_defn_clear();
}
@Test public void Skip_if_nl_exists_2() { // PURPOSE: \n inside template args should not print \n\n; PAGE:bn.w:লিওনেল_মেসি |ko.w:도쿄_지하철_히비야_선|DATE:2014-05-27
fxt.Init_defn_clear();
fxt.Init_defn_add("test_list", "# a");
fxt.Init_defn_add("test_print", "{{{1}}}");
fxt.Test_parse_tmpl_str_test(String_.Concat_lines_nl_skip_last
( "{{test_print|"
, "{{test_list}}" // note that there is a "\n" here, but test_list will return "#"; "#" should not be prepended with \n
, "{{test_list}}"
, "}}"
), "{{test}}"
, String_.Concat_lines_nl_skip_last
( "" // NOTE: \n still prints b/c of \n between "{{test_print|" and "{{test_list}}"; should trim ws at start;
, "# a"
, "# a"
));
fxt.Init_defn_clear();
}
@Test public void Pfunc() {// PURPOSE: if {| : ; # *, auto add new_line; parser_function variant; PAGE:en.w:Soviet Union; Infobox former country
fxt.Test_parse_tmpl_str_test("" , "z {{#if:true|#a|n}}" , "z \n#a");
}
@Test public void Bos() { // PURPOSE: function should expand "*a" to "\n*a" even if "*a" is bos; SEE:NOTE_1 PAGE:en.w:Rome and Panoramas; DATE:2014-02-05
fxt.Test_parse_page_tmpl_str("{{#if:x|*a}}", "\n*a");
}
@Test public void Tmpl_arg() { // PURPOSE: tmpl arg should auto-create; PAGE:vi.w:Friedrich_II_của_Phổ; DATE:2014-04-26
fxt.Init_defn_add("cquote" , "*b");
fxt.Init_defn_add("blockquote" , "<blockquote>{{{1}}}</blockquote>");
fxt.Test_html_full_str("a\n{{blockquote|{{cquote}}}}"
, String_.Concat_lines_nl_skip_last
( "a"
, "<blockquote>"
, "<ul>"
, " <li>b"
, " </li>"
, "</ul></blockquote>"
)
);
}
@Test public void Nested_1_n() { // PURPOSE: handled nested templates; PAGE:en.w:Central_Line en.w:Panama_Canal; DATE:2014-08-21
fxt.Init_defn_clear();
fxt.Init_defn_add("Nest_1" , "a{{Nest_1_1}}"); // 0: no \n
fxt.Init_defn_add("Nest_1_1" , "b\n{{Nest_1_1_1}}"); // 1: \n
fxt.Init_defn_add("Nest_1_1_1" , "*c"); // 2: "*" should not prepend \n b/c (1) has \n; used to only check (0)
fxt.Test_parse_tmpl_str_test("{{Nest_1}}", "{{test}}", String_.Concat_lines_nl_skip_last
( "ab" // not prepended
, "*c"
));
}
@Test public void Nested_1_y() { // PURPOSE: handled nested templates; PAGE:en.w:Lackawanna_Cut-Off; DATE:2014-08-21
fxt.Init_defn_clear();
fxt.Init_defn_add("Nest_1" , "a\n{{Nest_1_1}}"); // 0: no \n
fxt.Init_defn_add("Nest_1_1" , "b{{Nest_1_1_1}}"); // 1: char
fxt.Init_defn_add("Nest_1_1_1" , "*c"); // 2: "*" should prepend \n b/c (1) has char; used to check (0) and not prepend
fxt.Test_parse_tmpl_str_test("{{Nest_1}}", "{{test}}", String_.Concat_lines_nl_skip_last
( "a"
, "b" // prepended
, "*c"
));
}
@Test public void Nested_0_n() { // PURPOSE: handled nested templates variation of above; DATE:2014-08-21
fxt.Init_defn_clear();
fxt.Init_defn_add("Nest_1" , "a\n{{Nest_1_1}}"); // 0: \n
fxt.Init_defn_add("Nest_1_1" , "{{Nest_1_1_1}}"); // 1: ""
fxt.Init_defn_add("Nest_1_1_1" , "*b"); // 2: "*" should not prepend \n b/c (1) is empty and (0) has \n
fxt.Test_parse_tmpl_str_test("{{Nest_1}}", "{{test}}", String_.Concat_lines_nl_skip_last
( "a" // not prepended
, "*b"
));
}
@Test public void Nested_0_y() { // PURPOSE: handled nested templates variation of above; DATE:2014-08-21
fxt.Init_defn_clear();
fxt.Init_defn_add("Nest_1" , "a{{Nest_1_1}}"); // 0: no \n
fxt.Init_defn_add("Nest_1_1" , "{{Nest_1_1_1}}"); // 1: ""
fxt.Init_defn_add("Nest_1_1_1" , "*b"); // 2: "*" should prepend \n b/c (1) is empty and (0) has char
fxt.Test_parse_tmpl_str_test("{{Nest_1}}", "{{test}}", String_.Concat_lines_nl_skip_last
( "a" // prepended
, "*b"
));
}
}
/*
NOTE_1: function should expand "*a" to "\n*a" even if "*a" is bos
consider following
Template:Test with text of "#a"
a) "a{{test}}" would return "a\n#a" b/c of rule for auto-adding \n
b) bug was that "{{test}}" would return "#a" b/c "#a" was at bos which would expand to list later
however, needs to be "\n#a" b/c appended to other strings wherein bos would be irrelevant.
Actual situation was very complicated. PAGE:en.w:Rome;
*/

View File

@@ -0,0 +1,47 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xot_invk_wkr__raw_msg__tst {
@Before public void init() {fxt.Reset();} private final Xop_fxt fxt = new Xop_fxt();
@After public void term() {fxt.Init_defn_clear();}
@Test public void Raw() { // PURPOSE: {{raw:A}} is same as {{A}}; EX.WIKT:android; {{raw:ja/script}}
fxt.Init_defn_clear();
fxt.Init_defn_add("Test 1", "{{#if:|y|{{{1}}}}}");
fxt.Test_parse_tmpl_str("{{raw:Test 1|a}}", "a");
fxt.Init_defn_clear();
}
@Test public void Raw_spanish() { // PURPOSE.fix: {{raw}} should not fail; EX:es.s:Carta_a_Silvia; DATE:2014-02-11
fxt.Test_parse_tmpl_str("{{raw}}", "[[:Template:raw]]"); // used to fail; now tries to get Template:Raw which doesn't exist
}
@Test public void Special() { // PURPOSE: {{Special:Whatlinkshere}} is same as [[:Special:Whatlinkshere]]; EX.WIKT:android; isValidPageName
fxt.Test_parse_page_tmpl_str("{{Special:Whatlinkshere}}", "[[:Special:Whatlinkshere]]");
}
@Test public void Special_arg() { // PURPOSE: make sure Special still works with {{{1}}}
fxt.Init_defn_clear();
fxt.Init_defn_add("Test1", "{{Special:Whatlinkshere/{{{1}}}}}");
fxt.Test_parse_tmpl_str("{{Test1|-1}}", "[[:Special:Whatlinkshere/-1]]");
fxt.Init_defn_clear();
}
@Test public void Raw_special() { // PURPOSE: {{raw:A}} is same as {{A}}; EX.WIKT:android; {{raw:ja/script}}
fxt.Test_parse_tmpl_str("{{raw:Special:Whatlinkshere}}", "[[:Special:Whatlinkshere]]");
fxt.Init_defn_clear();
}
@Test public void Msg() {
fxt.Init_defn_add("CURRENTMONTH", "a");
fxt.Test_parse_tmpl_str("{{msg:CURRENTMONTH}}", "a");
}
}

View File

@@ -0,0 +1,54 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xot_invk_wkr__transclude__tst {
@Before public void init() {fxt.Reset();} private final Xop_fxt fxt = new Xop_fxt();
@After public void term() {fxt.Init_defn_clear();}
@Test public void Basic() { // PURPOSE: {{:Template:Test}} is same as {{Template:Test}}; EX.WIKT:android; japanese and {{:Template:ja/script}}
fxt.Init_defn_add("Test_1", "{{#if:|y|n}}"); // NOTE: must be of form "Test 1"; test_1 will fail
fxt.Test_parse_tmpl_str("{{:Template:Test 1}}", "n");
}
@Test public void Arguments() { // PURPOSE: transclusion test with arguments
fxt.Init_page_create("PageToTransclude", "a{{{key}}}c");
fxt.Test_parse_tmpl_str("some text to make this page longer than transclusion {{:PageToTransclude|key=b}}" , "some text to make this page longer than transclusion abc");
}
@Test public void Redirect() { // PURPOSE: StackOverflowError when transcluded sub-page redirects back to root_page; DATE:2014-01-07
fxt.Init_page_create("Root/Leaf", "#REDIRECT [[Root]]");
fxt.Init_page_create("Root", "<gallery>A.png|a{{/Leaf}}b</gallery>"); // NOTE: gallery neeeded for XOWA to fail; MW fails if just {{/Leaf}}
fxt.Test_parse_page("Root", "<gallery>A.png|a{{/Leaf}}b</gallery>");
}
@Test public void Missing__sub_page() { // PURPOSE: transclusion of a missing page should create a link, not print an empty String; EX: it.u:Dipartimento:Design; DATE:2014-02-12
fxt.Page_ttl_("Test_Page");
fxt.Test_parse_tmpl_str("{{/Sub}}", "[[Test_Page/Sub]]");
}
@Test public void Missing__colon_prefix() {// PURPOSE: page with colon_prefix should not add Template: PAGE:en.d:a; DATE:2016-06-24
fxt.Test_parse_tmpl_str("{{:a}}", "[[:a]]"); // ":a", not "Template:A" or "A"
}
@Test public void Colon_by_safesubst() { // SUPPORT: page with colon_prefix should not add Template: PAGE:en.d:a; DATE:2016-06-24
fxt.Init_defn_add("Test_2", "{{safesubst:Template:{{{1}}}}}");
fxt.Test_parse_tmpl_str("{{Test 2|b}}", "[[Template:b]]");
}
@Test public void Colon_w_template() { // SUPPORT: page with colon_prefix should not add Template: PAGE:en.d:a; DATE:2016-06-24
fxt.Init_defn_add("Test_3", "{{:Template:{{{1}}}}}");
fxt.Test_parse_tmpl_str("{{Test 3|b}}", "[[:Template:b]]");
}
@Test public void Toc() { // PURPOSE: __TOC__ in transcluded page should be ignored; PAGE:de.w:Game_of_Thrones DATE:2016-11-21
fxt.Init_page_create("TranscludedToc", "__TOC__\na");
fxt.Parser().Expand_tmpl(Bry_.new_u8("{{:TranscludedToc}}"));
Tfds.Eq(false, fxt.Page().Wtxt().Toc().Flag__toc()); // transcluded page is true, but current page should still be false
}
}

View File

@@ -0,0 +1,55 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xot_prm_tkn_tst {
private final Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@Test public void Idx_1() {fxt.Test_parse_tmpl_str_test("{{{1}}}" , "{{test|a|b}}" , "a");}
@Test public void Idx_2() {fxt.Test_parse_tmpl_str_test("{{{2}}}" , "{{test|a|b}}" , "b");}
@Test public void Idx_3_nil() {fxt.Test_parse_tmpl_str_test("{{{3}}}" , "{{test|a|b}}" , "{{{3}}}");}
@Test public void Idx_3_dflt() {fxt.Test_parse_tmpl_str_test("{{{3|c}}}" , "{{test|a|b}}" , "c");}
@Test public void Idx_3_dflt_len0() {fxt.Test_parse_tmpl_str_test("{{{1|}}}" , "{{test}}" , "");}
@Test public void Idx_1_and_2() {fxt.Test_parse_tmpl_str_test("({{{1}}} {{{2}}})" , "{{test|a|b}}" , "(a b)");}
@Test public void Idx_2_len0() {fxt.Test_parse_tmpl_str_test("{{{1}}}" , "{{test||b}}" , "");}// should not fail
@Test public void Key() {fxt.Test_parse_tmpl_str_test("{{{k1}}}" , "{{test|k1=a|k2=b}}" , "a");}
@Test public void Key_nil() {fxt.Test_parse_tmpl_str_test("{{{k3|c}}}" , "{{test|k1=a|k2=b}}" , "c");}
@Test public void Key_exact() {fxt.Test_parse_tmpl_str_test("{{{k|}}}{{{k2|}}}" , "{{test|k=a}}" , "a");} // only {{{k}}} matched
@Test public void Var() {fxt.Test_parse_tmpl_str_test("{{{1|-{{PAGENAME}}-}}}" , "{{test}}" , "-Test page-");}
@Test public void Newline_bgn() {fxt.Test_parse_tmpl_str_test("{{{1}}} {{{2}}}" , "{{test|a|\nb}}" , "a \nb");}
@Test public void Newline_end() {fxt.Test_parse_tmpl_str_test("{{{1}}} {{{2}}}" , "{{test|a|b\n}}" , "a b\n");}
@Test public void Exc_lkp_nil() {fxt.Test_parse_tmpl_str_test("{{{}}}" , "{{test|a|b}}" , "{{{}}}");}
@Test public void Exc_lkp_and_args1() {fxt.Test_parse_tmpl_str_test("{{{|}}}" , "{{test|a|b}}" , "");}
@Test public void Exc_lkp_nil_args1_txt() {fxt.Test_parse_tmpl_str_test("{{{|a}}}" , "{{test|a|b}}" , "a");}
@Test public void Ws_idx() {fxt.Test_parse_tmpl_str_test("{{{ 1 }}}" , "{{test|a|b}}" , "a");}
@Test public void Ws_idx_nil() {fxt.Test_parse_tmpl_str_test("{{{ 1 }}}" , "{{test}}" , "{{{ 1 }}}");}
@Test public void Ws_key() {fxt.Test_parse_tmpl_str_test("{{{ k1 }}}" , "{{test|k1=a|k2=b}}" , "a");}
@Test public void Ws_dflt() {fxt.Test_parse_tmpl_str_test("{{{1| a }}}" , "{{test}}" , " a ");}
@Test public void Dflt_multiple() {fxt.Test_parse_tmpl_str_test("{{{1|a|b}}}" , "{{test}}" , "a");}
@Test public void Keyd_not_idxd() {fxt.Test_parse_tmpl_str_test("{{{1}}}{{{2}}}" , "{{test|a|key=b}}" , "a{{{2}}}");}
@Test public void Keyd_not_idxd_ints() {fxt.Test_parse_tmpl_str_test("{{{1}}}{{{2}}}" , "{{test|1=a|2=b}}" , "ab");}
@Test public void Recurse_1() {fxt.Test_parse_tmpl_str_test("{{{1{{{2|}}}|}}}" , "{{test|a}}" , "a");} // used in {{See}} to test if argument 2 is last
@Test public void Recurse_2() {fxt.Test_parse_tmpl_str_test("{{{1{{{2|}}}|}}}" , "{{test|a|b}}" , "");}
@Test public void Keyd_int() {fxt.Test_parse_tmpl_str_test("{{{1}}}{{{2}}}" , "{{test|2=a|b}}" , "ba");}
@Test public void Keyd_int2() {fxt.Test_parse_tmpl_str_test("{{{1}}}{{{2}}}" , "{{test|2=a|1=b}}" , "ba");}
@Test public void Keyd_int3() {fxt.Test_parse_tmpl_str_test("{{{12}}}" , "{{test|12=a}}" , "a");}
@Test public void Equal_ignored() {fxt.Test_parse_tmpl_str_test("{{{1|b=c}}}" , "{{test}}" , "b=c");}
@Test public void Unresolved() {fxt.Test_parse_tmpl_str_test("" , "{{{a|b}}}" , "b");}
@Test public void Six_ltr() {fxt.Test_parse_tmpl_str_test("{{{{{{1}}}}}}" , "{{test|a}}" , "{{{a}}}");}
@Test public void Six_num() {fxt.Test_parse_tmpl_str_test("{{{{{{1}}}}}}" , "{{test|1}}" , "1");}
}
/*
*/