Map: Compare precision against 4 not 0 [#792]

staging
gnosygnu 4 years ago
parent 72051f4ce9
commit 316c6c6a58

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, 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. or alternatively under the terms of the Apache License Version 2.0.
@ -13,12 +13,16 @@ 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 GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.xtns.mapSources; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; package gplx.xowa.xtns.mapSources;
import org.junit.*;
public class Map_dd2dms_func_tst { import gplx.xowa.Xop_fxt;
@Before public void init() {fxt.Reset();} private final Xop_fxt fxt = new Xop_fxt(); import org.junit.Before;
@Test public void Example() {fxt.Test_parse_tmpl_str_test("{{#dd2dms: 14.58|precision=4}}" , "{{test}}" , "14° 34' 48"");} import org.junit.Test;
@Test public void Plus() {fxt.Test_parse_tmpl_str_test("{{#dd2dms: 14.58|precision=4|plus=pos}}" , "{{test}}" , "14° 34' 48" pos");}
@Test public void Ws() {fxt.Test_parse_tmpl_str_test("{{#dd2dms: 14.58| precision = 4 | plus = pos }}" , "{{test}}" , "14° 34' 48" pos");} public class Map_dd2dms_func_tst {
@Test public void Nested_pfunc() {fxt.Test_parse_tmpl_str_test("{{#dd2dms: 14.58|{{#if:2|precision=2}}}}" , "{{test|3}}" , "14° 34'");} // handle "{{#if:2|precision=2}}" -> "precision=2" @Before public void init() {fxt.Reset();} private final Xop_fxt fxt = new Xop_fxt();
} @Test public void Example() {fxt.Test_parse_tmpl_str_test("{{#dd2dms: 14.58|precision=4}}" , "{{test}}" , "14° 34' 48"");}
@Test public void Plus() {fxt.Test_parse_tmpl_str_test("{{#dd2dms: 14.58|precision=4|plus=pos}}" , "{{test}}" , "14° 34' 48" pos");}
@Test public void Ws() {fxt.Test_parse_tmpl_str_test("{{#dd2dms: 14.58| precision = 4 | plus = pos }}" , "{{test}}" , "14° 34' 48" pos");}
@Test public void Nested_pfunc() {fxt.Test_parse_tmpl_str_test("{{#dd2dms: 14.58|{{#if:2|precision=2}}}}" , "{{test|3}}" , "14° 35'");} // handle "{{#if:2|precision=2}}" -> "precision=2"
}

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, 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. or alternatively under the terms of the Apache License Version 2.0.
@ -13,293 +13,306 @@ 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 GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.xtns.mapSources; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; package gplx.xowa.xtns.mapSources;
import gplx.core.primitives.*; import gplx.core.btries.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; import gplx.Bry_;
class Map_math {// REF.MW:MapSources_math.php import gplx.Bry_bfr;
private int word_idx_nsew; import gplx.Bry_bfr_;
private double[] rv = new double[4]; import gplx.Bry_find_;
private byte dir_id; import gplx.Byte_ascii;
private int prec; import gplx.Double_;
private int step; import gplx.Err_;
public double Dec() {return dec;} private double dec; import gplx.Math_;
public int Error() {return error;} private int error; import gplx.String_;
public double Coord_dec() {return coord_dec;} private double coord_dec; import gplx.core.btries.Btrie_slim_mgr;
public double Coord_deg() {return coord_deg;} private double coord_deg; import gplx.core.primitives.Byte_obj_val;
public double Coord_min() {return coord_min;} private double coord_min; import gplx.xowa.parsers.Xop_ctx;
public double Coord_sec() {return coord_sec;} private double coord_sec; import gplx.xowa.parsers.tmpls.Xot_invk;
public byte[] Coord_dir_ns() {return coord_dir_ns;} private byte[] coord_dir_ns;
public byte[] Coord_dir_ew() {return coord_dir_ew;} private byte[] coord_dir_ew; class Map_math {// REF.MW:MapSources_math.php
public boolean Ctor(byte[] input, int prec, byte[] dir, int until_step) { private int word_idx_nsew;
try { private double[] rv = new double[4];
New_coord(input, dir, prec); private byte dir_id;
if (until_step > 1 && error == 0) private int prec;
Set_coord(); private int step;
} catch (Exception e) { public double Dec() {return dec;} private double dec;
Err_.Noop(e); public int Error() {return error;} private int error;
error = -128; public double Coord_dec() {return coord_dec;} private double coord_dec;
} public double Coord_deg() {return coord_deg;} private double coord_deg;
return error == 0; public double Coord_min() {return coord_min;} private double coord_min;
} public double Coord_sec() {return coord_sec;} private double coord_sec;
public void Fail(Xop_ctx ctx, byte[] src, Xot_invk self, Bry_bfr bfr, byte[] pfunc_name) { public byte[] Coord_dir_ns() {return coord_dir_ns;} private byte[] coord_dir_ns;
String page_str = ctx.Page().Url().To_str(); public byte[] Coord_dir_ew() {return coord_dir_ew;} private byte[] coord_dir_ew;
String pfunc_name_str = String_.new_u8(pfunc_name); public boolean Ctor(byte[] input, int prec, byte[] dir, int until_step) {
String self_str = String_.new_u8(src, self.Src_bgn(), self.Src_end()); try {
switch (error) { New_coord(input, dir, prec);
case -1: // empty coord; EX: {{#deg2dd:|precision=6}}}} PAGE:it.v:Sami; DATE:2014-03-02 if (until_step > 1 && error == 0)
case -2: // words > 4; EX:{{#geoLink: $1 $2 $3 $4 $5 $6|lat=51°2000″19°5550″}}; PAGE:pl.v:Rezerwat_przyrody_Jaksonek DATE:2014-08-14 Set_coord();
case -3: // invalid delim; EX:{{#geoLink: $1 $2 $3 $4 $5 $6|lat=51°3137″|long=20°1317'}}; PAGE:pl.v:Rezerwat_przyrody_Ciosny DATE:2014-08-14 } catch (Exception e) {
ctx.App().Usr_dlg().Log_many("", "", "mapSources failed: page=~{0} pfunc=~{1} err=~{2} src=~{3}", page_str, pfunc_name_str, error, self_str); // don't warn b/c there are many Err_.Noop(e);
break; error = -128;
default: }
ctx.App().Usr_dlg().Warn_many("", "", "mapSources failed: page=~{0} pfunc=~{1} err=~{2} src=~{3}", page_str, pfunc_name_str, error, self_str); return error == 0;
break; }
} public void Fail(Xop_ctx ctx, byte[] src, Xot_invk self, Bry_bfr bfr, byte[] pfunc_name) {
} String page_str = ctx.Page().Url().To_str();
private void New_coord(byte[] input, byte[] dir, int prec) { // REF.MW:newCoord String pfunc_name_str = String_.new_u8(pfunc_name);
this.error = 0; this.word_idx_nsew = -1; String self_str = String_.new_u8(src, self.Src_bgn(), self.Src_end());
coord_dec = coord_deg = coord_min = coord_sec = 0; switch (error) {
rv[0] = rv[1] = rv[2] = 0; rv[3] = 1; case -1: // empty coord; EX: {{#deg2dd:|precision=6}}}} PAGE:it.v:Sami; DATE:2014-03-02
this.dir_id = Parse_dir(dir); case -2: // words > 4; EX:{{#geoLink: $1 $2 $3 $4 $5 $6|lat=51°2000″19°5550″}}; PAGE:pl.v:Rezerwat_przyrody_Jaksonek DATE:2014-08-14
this.prec = Parse_precision(prec); case -3: // invalid delim; EX:{{#geoLink: $1 $2 $3 $4 $5 $6|lat=51°3137″|long=20°1317'}}; PAGE:pl.v:Rezerwat_przyrody_Ciosny DATE:2014-08-14
this.dec = 0; ctx.App().Usr_dlg().Log_many("", "", "mapSources failed: page=~{0} pfunc=~{1} err=~{2} src=~{3}", page_str, pfunc_name_str, error, self_str); // don't warn b/c there are many
this.step = 0; break;
Parse_input(input); default:
} ctx.App().Usr_dlg().Warn_many("", "", "mapSources failed: page=~{0} pfunc=~{1} err=~{2} src=~{3}", page_str, pfunc_name_str, error, self_str);
private void Set_coord() { // REF.MW:setCoord break;
if (step > 1) return; }
if (prec < 9) }
dec = Math_.Round(dec, prec); private void New_coord(byte[] input, byte[] dir, int prec) { // REF.MW:newCoord
int sign = dec < 0 ? -1 : 1; this.error = 0; this.word_idx_nsew = -1;
double angle = Math_.Abs_double(dec); coord_dec = coord_deg = coord_min = coord_sec = 0;
double deg = Math_.Floor(angle); rv[0] = rv[1] = rv[2] = 0; rv[3] = 1;
double min = (angle - deg) * 60; this.dir_id = Parse_dir(dir);
double sec = prec > 0 this.prec = Parse_precision(prec);
? Math_.Round((min - Math_.Floor(min)) * 60, prec - 4) this.dec = 0;
: Math_.Round((min - Math_.Floor(min)) * 60, 0) this.step = 0;
; Parse_input(input);
min = Math_.Floor(min); }
if (sec >= 60) { private void Set_coord() { // REF.MW:setCoord
sec -= 60; if (step > 1) return;
min++; if (prec < 9)
} dec = Math_.Round(dec, prec);
if (prec < 3 && sec >= 30) int sign = dec < 0 ? -1 : 1;
min++; double angle = Math_.Abs_double(dec);
if (prec < 3) double deg = Math_.Floor(angle);
sec = 0; double min = (angle - deg) * 60;
if (min >= 60) { double sec = prec > 4 // 2020-09-03|ISSUE#:792|precision check should be > 4 not > 0;PAGE:en.w:Huntington_Plaza
min -= 60; ? Math_.Round((min - Math_.Floor(min)) * 60, prec - 4)
deg++; : Math_.Round((min - Math_.Floor(min)) * 60, 0)
} ;
if (prec < 1 && min >= 30) { min = Math_.Floor(min);
deg++; if (sec >= 60) {
} sec -= 60;
if (prec < 1) min++;
min = 0; }
coord_dec = Math_.Round(dec, prec); if (prec < 3 && sec >= 30)
coord_deg = deg * sign; min++;
coord_min = min; if (prec < 3)
coord_sec = sec; sec = 0;
if (sign > 0) { if (min >= 60) {
coord_dir_ns = Compass_N; min -= 60;
coord_dir_ew = Compass_E; deg++;
} }
else { if (prec < 1 && min >= 30) {
coord_dir_ns = Compass_S; deg++;
coord_dir_ew = Compass_W; }
} if (prec < 1)
step = 2; min = 0;
} coord_dec = Math_.Round(dec, prec);
public byte[] Get_dms(boolean wikibase, byte[] plus, byte[] minus) { // REF.MW: getDMSString coord_deg = deg * sign;
if (step < 2) Set_coord(); coord_min = min;
double deg = coord_deg; coord_sec = sec;
if ( dec < 0 if (sign > 0) {
&& ( (Bry_.Len_gt_0(plus) || Bry_.Len_gt_0(minus)) coord_dir_ns = Compass_N;
|| wikibase // NOTE: wikibase will always pass in empty plus / minus; still need to suppress "-" sign because letter has already been reversed; EX:"-2 E" -> "2 W" x> "-2 W" DATE:2017-04-02 coord_dir_ew = Compass_E;
) }
) { else {
deg = Math_.Abs_double(deg); coord_dir_ns = Compass_S;
} coord_dir_ew = Compass_W;
tmp_bfr.Add_double(deg).Add(Bry_deg); }
if (prec > 0) { step = 2;
if (!wikibase) // NOTE: do not add space if wikibase, else will fail in Module:en.w:WikidataCoord; PAGE:en.w:Hulme_Arch_Bridge DATE:2017-04-02 }
tmp_bfr.Add_byte_space(); public byte[] Get_dms(boolean wikibase, byte[] plus, byte[] minus) { // REF.MW: getDMSString
tmp_bfr.Add_double(coord_min).Add(wikibase ? Bry_apos_wb : Bry_apos_mw); if (step < 2) Set_coord();
} double deg = coord_deg;
if (prec > 2) { if ( dec < 0
if (!wikibase) // NOTE: do not add space if wikibase, else will fail in Module:en.w:WikidataCoord; PAGE:en.w:Hulme_Arch_Bridge DATE:2017-04-02 && ( (Bry_.Len_gt_0(plus) || Bry_.Len_gt_0(minus))
tmp_bfr.Add_byte_space(); || wikibase // NOTE: wikibase will always pass in empty plus / minus; still need to suppress "-" sign because letter has already been reversed; EX:"-2 E" -> "2 W" x> "-2 W" DATE:2017-04-02
tmp_bfr.Add_double(coord_sec).Add(wikibase ? Bry_quot_wb : Bry_quot_mw); )
} ) {
byte[] letter = null; deg = Math_.Abs_double(deg);
if (dir_id == Dir_lat_id) }
letter = coord_dir_ns; tmp_bfr.Add_double(deg).Add(Bry_deg);
if (dir_id == Dir_long_id) if (prec > 0) {
letter = coord_dir_ew; if (!wikibase) // NOTE: do not add space if wikibase, else will fail in Module:en.w:WikidataCoord; PAGE:en.w:Hulme_Arch_Bridge DATE:2017-04-02
if (dec > 0 && Bry_.Len_gt_0(plus)) tmp_bfr.Add_byte_space();
letter = plus; tmp_bfr.Add_double(coord_min).Add(wikibase ? Bry_apos_wb : Bry_apos_mw);
if (dec < 0 && Bry_.Len_gt_0(minus)) }
letter = minus; if (prec > 2) {
if (letter != null) { if (!wikibase) // NOTE: do not add space if wikibase, else will fail in Module:en.w:WikidataCoord; PAGE:en.w:Hulme_Arch_Bridge DATE:2017-04-02
tmp_bfr.Add_byte_space(); tmp_bfr.Add_byte_space();
tmp_bfr.Add(letter); tmp_bfr.Add_double(coord_sec).Add(wikibase ? Bry_quot_wb : Bry_quot_mw);
} }
return tmp_bfr.To_bry_and_clear(); byte[] letter = null;
} if (dir_id == Dir_lat_id)
private void Parse_input(byte[] src) { // REF.MW: toDec letter = coord_dir_ns;
src = Parse_input_normalize(tmp_bfr, src); if (dir_id == Dir_long_id)
if (src == null) {error = -1; return;} letter = coord_dir_ew;
int src_len = src.length; if (dec > 0 && Bry_.Len_gt_0(plus))
int word_idx = -1, word_bgn = 0, words_len = 0; letter = plus;
int i = 0; if (dec < 0 && Bry_.Len_gt_0(minus))
while (true) { letter = minus;
boolean is_last = i == src_len; if (letter != null) {
byte b = is_last ? Byte_ascii.Space : src[i]; tmp_bfr.Add_byte_space();
switch (b) { tmp_bfr.Add(letter);
case Byte_ascii.Space: }
Parse_input_word(rv, src, ++word_idx, word_bgn, i); return tmp_bfr.To_bry_and_clear();
++words_len; }
i = Bry_find_.Find_fwd_while_space_or_tab(src, i, src_len); private void Parse_input(byte[] src) { // REF.MW: toDec
word_bgn = i; src = Parse_input_normalize(tmp_bfr, src);
break; if (src == null) {error = -1; return;}
} int src_len = src.length;
if (is_last) break; int word_idx = -1, word_bgn = 0, words_len = 0;
i++; int i = 0;
} while (true) {
if (words_len < 1 || words_len > 4) {error = -2; return;} boolean is_last = i == src_len;
if (word_idx_nsew != -1 && word_idx_nsew != words_len - 1) {error = -10; return;} byte b = is_last ? Byte_ascii.Space : src[i];
if (rv[0] >= 0) switch (b) {
dec = (rv[0] + rv[1] / 60 + rv[2] / 3600 ) * rv[3]; case Byte_ascii.Space:
else Parse_input_word(rv, src, ++word_idx, word_bgn, i);
dec = (rv[0] - rv[1] / 60 - rv[2] / 3600 ) * rv[3]; ++words_len;
this.step = 1; i = Bry_find_.Find_fwd_while_space_or_tab(src, i, src_len);
} word_bgn = i;
private boolean Parse_input_word_is_compass(byte v) { break;
switch (v) { }
case Byte_ascii.Ltr_N: if (is_last) break;
case Byte_ascii.Ltr_E: i++;
case Byte_ascii.Ltr_S: }
case Byte_ascii.Ltr_W: if (words_len < 1 || words_len > 4) {error = -2; return;}
return true; if (word_idx_nsew != -1 && word_idx_nsew != words_len - 1) {error = -10; return;}
default: if (rv[0] >= 0)
return false; dec = (rv[0] + rv[1] / 60 + rv[2] / 3600 ) * rv[3];
} else
} dec = (rv[0] - rv[1] / 60 - rv[2] / 3600 ) * rv[3];
private void Parse_input_word(double[] rv, byte[] input, int word_idx, int word_bgn, int word_end) { this.step = 1;
if (word_idx >= Input_units_len) return; }
byte unit_dlm = Input_units[word_idx]; private boolean Parse_input_word_is_compass(byte v) {
int pos = Bry_find_.Find_fwd(input, unit_dlm, word_bgn, word_end); switch (v) {
if (pos != Bry_find_.Not_found) // remove dlms from end of bry; EX: "123'" -> "123" case Byte_ascii.Ltr_N:
word_end = pos; case Byte_ascii.Ltr_E:
if (!Parse_input_word_is_compass(input[word_bgn])) { // if ( is_numeric( $v ) ) { case Byte_ascii.Ltr_S:
double word_val = Bry_.To_double_or(input, word_bgn, word_end, Double_.NaN); case Byte_ascii.Ltr_W:
if (!Double_.IsNaN(word_val)) { return true;
if (word_idx > 2) {error = -4; return;} default:
switch (word_idx) { return false;
case 0: }
if (word_val <= -180 || word_val > 180) {error = -5; return;} }
rv[0] = word_val; private void Parse_input_word(double[] rv, byte[] input, int word_idx, int word_bgn, int word_end) {
break; if (word_idx >= Input_units_len) return;
case 1: byte unit_dlm = Input_units[word_idx];
if (word_val < 0 || word_val >= 60) {error = -6; return;} int pos = Bry_find_.Find_fwd(input, unit_dlm, word_bgn, word_end);
if (rv[0] != (int)(rv[0])) {error = -7; return;} if (pos != Bry_find_.Not_found) // remove dlms from end of bry; EX: "123'" -> "123"
rv[1] = word_val; word_end = pos;
break; if (!Parse_input_word_is_compass(input[word_bgn])) { // if ( is_numeric( $v ) ) {
case 2: double word_val = Bry_.To_double_or(input, word_bgn, word_end, Double_.NaN);
if (word_val < 0 || word_val >= 60) {error = -8; return;} if (!Double_.IsNaN(word_val)) {
if (rv[1] != (int)(rv[1])) {error = -9; return;} if (word_idx > 2) {error = -4; return;}
rv[2] = word_val; switch (word_idx) {
break; case 0:
} if (word_val <= -180 || word_val > 180) {error = -5; return;}
} rv[0] = word_val;
else { break;
error = -3; case 1:
return; if (word_val < 0 || word_val >= 60) {error = -6; return;}
} if (rv[0] != (int)(rv[0])) {error = -7; return;}
} rv[1] = word_val;
else { // 'NSEW' break;
word_idx_nsew = word_idx; case 2:
byte word_byte = input[word_bgn]; if (word_val < 0 || word_val >= 60) {error = -8; return;}
if (rv[0] < 0) {error = -11; return;} if (rv[1] != (int)(rv[1])) {error = -9; return;}
if (word_end - word_bgn != 1) {error = -3; return;} rv[2] = word_val;
switch (dir_id) { break;
case Dir_long_id: }
if (word_byte == Byte_ascii.Ltr_N || word_byte == Byte_ascii.Ltr_S) {error = -12; return;} }
break; else {
case Dir_lat_id: error = -3;
if (word_byte == Byte_ascii.Ltr_E || word_byte == Byte_ascii.Ltr_W) {error = -12; return;} return;
break; }
case Dir_unknown_id: }
if (word_byte == Byte_ascii.Ltr_N || word_byte == Byte_ascii.Ltr_S) this.dir_id = Dir_lat_id; else { // 'NSEW'
else this.dir_id = Dir_long_id; word_idx_nsew = word_idx;
break; byte word_byte = input[word_bgn];
} if (rv[0] < 0) {error = -11; return;}
if (this.dir_id == Dir_lat_id) { if (word_end - word_bgn != 1) {error = -3; return;}
double rv_0 = rv[0]; switch (dir_id) {
if (rv_0 < -90 || rv_0 > 90) {error = -13; return;} case Dir_long_id:
} if (word_byte == Byte_ascii.Ltr_N || word_byte == Byte_ascii.Ltr_S) {error = -12; return;}
if (word_byte == Byte_ascii.Ltr_S || word_byte == Byte_ascii.Ltr_W) break;
rv[3] = -1; case Dir_lat_id:
} if (word_byte == Byte_ascii.Ltr_E || word_byte == Byte_ascii.Ltr_W) {error = -12; return;}
} break;
private static byte Parse_dir(byte[] dir) { case Dir_unknown_id:
if (Bry_.Len_eq_0(dir)) return Dir_unknown_id; if (word_byte == Byte_ascii.Ltr_N || word_byte == Byte_ascii.Ltr_S) this.dir_id = Dir_lat_id;
Object dir_obj = Dir_trie.Match_bgn(dir, 0, dir.length); else this.dir_id = Dir_long_id;
return dir_obj == null ? Dir_unknown_id : ((Byte_obj_val)dir_obj).Val(); break;
} }
private static int Parse_precision(int val) { // REF.MW: MapSourcesMath.php|newCoord if (this.dir_id == Dir_lat_id) {
if (val > -1 && val < 10) return val; double rv_0 = rv[0];
else if (val == -1) return 9; if (rv_0 < -90 || rv_0 > 90) {error = -13; return;}
else return 4; }
} if (word_byte == Byte_ascii.Ltr_S || word_byte == Byte_ascii.Ltr_W)
private Bry_bfr tmp_bfr = Bry_bfr_.Reset(32); rv[3] = -1;
public static byte[] Parse_input_normalize(Bry_bfr bfr, byte[] src) { }
/* }
$w = str_replace( array( '', '', '' ), "'", $input ); private static byte Parse_dir(byte[] dir) {
$w = str_replace( array( "''", '“', '”', '″' ), '"', $w ); if (Bry_.Len_eq_0(dir)) return Dir_unknown_id;
$w = str_replace( '', '-', $w ); Object dir_obj = Dir_trie.Match_bgn(dir, 0, dir.length);
$w = strtoupper( str_replace( array( '_', '/', "\t", "\n", "\r" ), ' ', $w ) ); return dir_obj == null ? Dir_unknown_id : ((Byte_obj_val)dir_obj).Val();
$w = str_replace( array( '°', "'", '"' ), array( '° ', "' ", '" ' ), $w ); }
$w = trim( str_replace( array( 'N', 'S', 'E', 'W' ), array( ' N', ' S', ' E', ' W' ), $w ) ); private static int Parse_precision(int val) { // REF.MW: MapSourcesMath.php|newCoord
*/ if (val > -1 && val < 10) return val;
int src_end = src.length; if (src_end == 0) return null; else if (val == -1) return 9;
src = Trie__normalize__apos.Replace(bfr, src, 0, src_end); // normalize apos separately, since 2 apos can go to quotes; EX: -> "; PAGE:it.v:Morro_d'Oro DATE:2015-12-06 else return 4;
src = Trie__normalize__rest.Replace(bfr, src, 0, src.length); // normalize rest; }
return Bry_.Trim(src); private Bry_bfr tmp_bfr = Bry_bfr_.Reset(32);
} public static byte[] Parse_input_normalize(Bry_bfr bfr, byte[] src) {
private static final byte[] /*
Bry_deg = Bry_.new_u8("°") $w = str_replace( array( '', '', '' ), "'", $input );
, Bry_quot_mw = Bry_.new_a7("&quot;") $w = str_replace( array( "''", '“', '”', '″' ), '"', $w );
, Bry_quot_wb = Bry_.new_a7("&#34;") // REF:en.w:Module:WikidataCoord $w = str_replace( '', '-', $w );
, Bry_apos_mw = Bry_.new_a7("'") $w = strtoupper( str_replace( array( '_', '/', "\t", "\n", "\r" ), ' ', $w ) );
, Bry_apos_wb = Bry_.new_a7("&#39;") // REF:en.w:Module:WikidataCoord $w = str_replace( array( '°', "'", '"' ), array( '° ', "' ", '" ' ), $w );
; $w = trim( str_replace( array( 'N', 'S', 'E', 'W' ), array( ' N', ' S', ' E', ' W' ), $w ) );
private static final byte Dir_unknown_id = 0, Dir_lat_id = 1, Dir_long_id = 2; */
public static final byte[] Dir_lat_bry = Bry_.new_a7("lat"), Dir_long_bry = Bry_.new_a7("long"); int src_end = src.length; if (src_end == 0) return null;
private static final Btrie_slim_mgr Dir_trie = Btrie_slim_mgr.ci_a7() // NOTE:ci.ascii:MW_const.en src = Trie__normalize__apos.Replace(bfr, src, 0, src_end); // normalize apos separately, since 2 apos can go to quotes; EX: -> "; PAGE:it.v:Morro_d'Oro DATE:2015-12-06
.Add_bry_byte(Dir_lat_bry , Dir_lat_id) src = Trie__normalize__rest.Replace(bfr, src, 0, src.length); // normalize rest;
.Add_bry_byte(Dir_long_bry , Dir_long_id) return Bry_.Trim(src);
; }
private static final byte[] private static final byte[]
Compass_N = new byte[] {Byte_ascii.Ltr_N} Bry_deg = Bry_.new_u8("°")
, Compass_E = new byte[] {Byte_ascii.Ltr_E} , Bry_quot_mw = Bry_.new_a7("&quot;")
, Compass_S = new byte[] {Byte_ascii.Ltr_S} , Bry_quot_wb = Bry_.new_a7("&#34;") // REF:en.w:Module:WikidataCoord
, Compass_W = new byte[] {Byte_ascii.Ltr_W} , Bry_apos_mw = Bry_.new_a7("'")
; , Bry_apos_wb = Bry_.new_a7("&#39;") // REF:en.w:Module:WikidataCoord
private static final byte Input_byte_degree = Byte_ascii.Slash; // NOTE: ugly cheat to avoid using multi-byte char; note that all "/" are swapped out to " ", so any remaining "/" was added by the normalizer; EX: "123° 4/5" -> "123/ 4 5" ;
private static final byte[] Input_units = new byte[] {Input_byte_degree, Byte_ascii.Apos, Byte_ascii.Quote, Byte_ascii.Space}; private static final byte Dir_unknown_id = 0, Dir_lat_id = 1, Dir_long_id = 2;
private static final int Input_units_len = Input_units.length; public static final byte[] Dir_lat_bry = Bry_.new_a7("lat"), Dir_long_bry = Bry_.new_a7("long");
private static final Btrie_slim_mgr Trie__normalize__apos = Btrie_slim_mgr.cs() private static final Btrie_slim_mgr Dir_trie = Btrie_slim_mgr.ci_a7() // NOTE:ci.ascii:MW_const.en
.Add_replace_many (Byte_ascii.Apos_bry , "", "", ""); .Add_bry_byte(Dir_lat_bry , Dir_lat_id)
private static final Btrie_slim_mgr Trie__normalize__rest = Btrie_slim_mgr.cs() .Add_bry_byte(Dir_long_bry , Dir_long_id)
.Add_replace_many ("' " , "'") ;
.Add_replace_many ("\" " , "\"", "''", "“", "”", "″") private static final byte[]
.Add_replace_many (Byte_ascii.Dash_bry , "-", "") // NOTE: emdash and endash Compass_N = new byte[] {Byte_ascii.Ltr_N}
.Add_replace_many (Byte_ascii.Space_bry , " ", "_", "/", "\t", "\n", "\r") // NOTE: " " = &nbsp; , Compass_E = new byte[] {Byte_ascii.Ltr_E}
.Add_replace_many ("/ " , "°") , Compass_S = new byte[] {Byte_ascii.Ltr_S}
.Add_replace_many (" N" , "N", "n") , Compass_W = new byte[] {Byte_ascii.Ltr_W}
.Add_replace_many (" S" , "S", "s") ;
.Add_replace_many (" E" , "E", "e") private static final byte Input_byte_degree = Byte_ascii.Slash; // NOTE: ugly cheat to avoid using multi-byte char; note that all "/" are swapped out to " ", so any remaining "/" was added by the normalizer; EX: "123° 4/5" -> "123/ 4 5"
.Add_replace_many (" W" , "W", "w"); private static final byte[] Input_units = new byte[] {Input_byte_degree, Byte_ascii.Apos, Byte_ascii.Quote, Byte_ascii.Space};
public static final Map_math Instance = new Map_math(); private static final int Input_units_len = Input_units.length;
} private static final Btrie_slim_mgr Trie__normalize__apos = Btrie_slim_mgr.cs()
.Add_replace_many (Byte_ascii.Apos_bry , "", "", "");
private static final Btrie_slim_mgr Trie__normalize__rest = Btrie_slim_mgr.cs()
.Add_replace_many ("' " , "'")
.Add_replace_many ("\" " , "\"", "''", "“", "”", "″")
.Add_replace_many (Byte_ascii.Dash_bry , "-", "") // NOTE: emdash and endash
.Add_replace_many (Byte_ascii.Space_bry , " ", "_", "/", "\t", "\n", "\r") // NOTE: " " = &nbsp;
.Add_replace_many ("/ " , "°")
.Add_replace_many (" N" , "N", "n")
.Add_replace_many (" S" , "S", "s")
.Add_replace_many (" E" , "E", "e")
.Add_replace_many (" W" , "W", "w");
public static final Map_math Instance = new Map_math();
}

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, 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. or alternatively under the terms of the Apache License Version 2.0.
@ -13,202 +13,207 @@ 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 GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx.xowa.xtns.wbases.pfuncs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.wbases.*; package gplx.xowa.xtns.wbases.pfuncs;
import org.junit.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*;
public class Wdata_pf_property__basic__tst { import gplx.Bry_;
@Before public void init() {fxt.Init();} private final Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt(); import gplx.xowa.xtns.wbases.Wdata_wiki_mgr_fxt;
@Test public void String() { import org.junit.Before;
fxt.Init__docs__add(fxt.Wdoc("Q1") import org.junit.Test;
.Add_claims(fxt.Make_claim_string(1, "a"))
.Add_sitelink("enwiki", "Test_page") public class Wdata_pf_property__basic__tst {
); @Before public void init() {fxt.Init();} private final Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt();
fxt.Test_parse("{{#property:p1}}", "a"); @Test public void String() {
fxt.Test_parse("{{#property:p2}}", ""); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_string(1, "a"))
@Test public void Entity() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q2") );
.Add_label("en", "b") fxt.Test_parse("{{#property:p1}}", "a");
); fxt.Test_parse("{{#property:p2}}", "");
fxt.Init__docs__add(fxt.Wdoc("Q1") }
.Add_claims(fxt.Make_claim_entity_qid(1, 2)) @Test public void Entity() {
.Add_sitelink("enwiki", "Test_page") fxt.Init__docs__add(fxt.Wdoc("Q2")
); .Add_label("en", "b")
fxt.Test_parse("{{#property:p1}}", "b"); );
} fxt.Init__docs__add(fxt.Wdoc("Q1")
@Test public void Entity_fr() { // PURPOSE: non-English wiki should default to English label if non-English label not available; DATE:2013-12-19 .Add_claims(fxt.Make_claim_entity_qid(1, 2))
// set wiki to French .Add_sitelink("enwiki", "Test_page")
fxt.Wiki().Wdata_wiki_lang_(Bry_.new_a7("fr")); );
fxt.Test_parse("{{#property:p1}}", "b");
fxt.Init__docs__add(fxt.Wdoc("Q1") }
.Add_claims(fxt.Make_claim_entity_qid(1, 2)) @Test public void Entity_fr() { // PURPOSE: non-English wiki should default to English label if non-English label not available; DATE:2013-12-19
.Add_sitelink("frwiki", "Test_page") // set wiki to French
); fxt.Wiki().Wdata_wiki_lang_(Bry_.new_a7("fr"));
// create wdata page Q2 with label in en (not fr) fxt.Init__docs__add(fxt.Wdoc("Q1")
fxt.Init__docs__add(fxt.Wdoc("Q2") .Add_claims(fxt.Make_claim_entity_qid(1, 2))
.Add_label("en", "b") .Add_sitelink("frwiki", "Test_page")
); );
// parse; should get en label // create wdata page Q2 with label in en (not fr)
fxt.Test_parse("{{#property:p1}}", "b"); fxt.Init__docs__add(fxt.Wdoc("Q2")
} .Add_label("en", "b")
@Test public void Entity_missing() { // PURPOSE: wiki may refer to entity that no longer exists; EX: {{#property:p1}} which links to Q1, but p1 links to Q2 and Q2 was deleted; DATE:2014-02-01 );
fxt.Init__docs__add(fxt.Wdoc("Q1")
.Add_claims(fxt.Make_claim_entity_qid(1, 2)) // create wdata page Q1 with prop entity reference to Q2; note that Q2 is not created // parse; should get en label
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "b");
); }
@Test public void Entity_missing() { // PURPOSE: wiki may refer to entity that no longer exists; EX: {{#property:p1}} which links to Q1, but p1 links to Q2 and Q2 was deleted; DATE:2014-02-01
fxt.Test_parse("{{#property:p1}}", ""); // parse; get "" fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_entity_qid(1, 2)) // create wdata page Q1 with prop entity reference to Q2; note that Q2 is not created
@Test public void Time() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_time(1, "2012-01-02 03:04:05"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", ""); // parse; get ""
); }
@Test public void Time() {
fxt.Test_parse("{{#property:p1}}", "30405 2 Jan 2012"); // NOTE: format is missing ":" b/c test does not init messages for html_wtr; DATE:2015-08-03 fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_time(1, "2012-01-02 03:04:05"))
@Test public void Geodata() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_geo(1, "6.789", "1.2345"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "30405 2 Jan 2012"); // NOTE: format is missing ":" b/c test does not init messages for html_wtr; DATE:2015-08-03
); }
@Test public void Geodata() {
fxt.Test_parse("{{#property:p1}}", "1°14&#39;4.2&#34;N, 6°47&#39;20.4&#34;E"); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_geo(1, "6.789", "1.2345"))
@Test public void Quantity__plus_minus__y() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_quantity(1, "+1234", "1", "+1236", "+1232"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "1°14&#39;4.2&#34;N, 6°47&#39;20.4&#34;E");
); }
@Test public void Quantity__plus_minus__y() {
fxt.Test_parse("{{#property:p1}}", "1,234±2"); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_quantity(1, "+1234", "1", "+1236", "+1232"))
@Test public void Quantity__plus_minus__n() { // PURPOSE:do not output ± if lbound == val == ubound; PAGE:en.w:Tintinan DATE:2015-08-02 .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_quantity(1, "+1234", "1", "+1234", "+1234"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "1,234±2");
); }
@Test public void Quantity__plus_minus__n() { // PURPOSE:do not output ± if lbound == val == ubound; PAGE:en.w:Tintinan DATE:2015-08-02
fxt.Test_parse("{{#property:p1}}", "1,234"); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_quantity(1, "+1234", "1", "+1234", "+1234"))
@Test public void Quantity__range() { // PURPOSE:do not output ± if lbound == val == ubound; PAGE:en.w:Tintinan DATE:2015-08-02 .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_quantity(1, "+1234", "1", "+1236", "+1233"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "1,234");
); }
@Test public void Quantity__range() { // PURPOSE:do not output ± if lbound == val == ubound; PAGE:en.w:Tintinan DATE:2015-08-02
fxt.Test_parse("{{#property:p1}}", "1,233-1,236"); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_quantity(1, "+1234", "1", "+1236", "+1233"))
@Test public void Quantity__long() { // PURPOSE: must cast to long for large numbers; EX:{{#property:P1082}} PAGE:en.w:Earth; DATE:2015-08-02 .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_quantity(1, "+4321000000", "1", "4321000000", "4321000000"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "1,233-1,236");
); }
@Test public void Quantity__long() { // PURPOSE: must cast to long for large numbers; EX:{{#property:P1082}} PAGE:en.w:Earth; DATE:2015-08-02
fxt.Test_parse("{{#property:p1}}", "4,321,000,000"); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_quantity(1, "+4321000000", "1", "4321000000", "4321000000"))
@Test public void Quantity__unit__entity() {// PURPOSE: get entity name; EX:{{#invoke:Wikidata|getUnits|P2386|FETCH_WIKIDATA}} PAGE:en.w:Arecibo_Observatory; DATE:2016-10-11 .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_quantity(1, "+1234", "http://www.wikidata.org/entity/Q2", "+1236", "+1232"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "4,321,000,000");
); }
@Test public void Quantity__unit__entity() {// PURPOSE: get entity name; EX:{{#invoke:Wikidata|getUnits|P2386|FETCH_WIKIDATA}} PAGE:en.w:Arecibo_Observatory; DATE:2016-10-11
fxt.Init__docs__add(fxt.Wdoc("Q2") fxt.Init__docs__add(fxt.Wdoc("Q1")
.Add_claims(fxt.Make_claim_string(2, "a")) .Add_claims(fxt.Make_claim_quantity(1, "+1234", "http://www.wikidata.org/entity/Q2", "+1236", "+1232"))
.Add_label("en", "meter") .Add_sitelink("enwiki", "Test_page")
); );
fxt.Test_parse("{{#property:p1}}", "1,234±2 meter"); fxt.Init__docs__add(fxt.Wdoc("Q2")
} .Add_claims(fxt.Make_claim_string(2, "a"))
@Test public void Quantity__decimal() { .Add_label("en", "meter")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_quantity(1, "+1234.50", "1", "+1236.75", "+1232.25"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "1,234±2 meter");
); }
@Test public void Quantity__decimal() {
fxt.Test_parse("{{#property:p1}}", "1,234.5±2.25"); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_quantity(1, "+1234.50", "1", "+1236.75", "+1232.25"))
@Test public void Monolingualtext() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_monolingual(1, "la", "Lorem ipsum dolor sit amet"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "1,234.5±2.25");
); }
@Test public void Monolingualtext() {
fxt.Test_parse("{{#property:p1}}", "Lorem ipsum dolor sit amet"); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_monolingual(1, "la", "Lorem ipsum dolor sit amet"))
@Test public void Novalue() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_novalue(1))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "Lorem ipsum dolor sit amet");
); }
@Test public void Novalue() {
fxt.Test_parse("{{#property:p1}}", "no value"); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_novalue(1))
@Test public void Somevalue() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_somevalue(1))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "no value");
); }
@Test public void Somevalue() {
fxt.Test_parse("{{#property:p1}}", "unknown value"); fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_somevalue(1))
@Test public void Multiple() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q1") );
.Add_claims(fxt.Make_claim_string(1, "a"), fxt.Make_claim_string(1, "b"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "unknown value");
); }
@Test public void Multiple() {
fxt.Test_parse("{{#property:p1}}", "a"); // only take first; DATE:2015-08-02 fxt.Init__docs__add(fxt.Wdoc("Q1")
} .Add_claims(fxt.Make_claim_string(1, "a"), fxt.Make_claim_string(1, "b"))
@Test public void Q() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q2") );
.Add_claims(fxt.Make_claim_string(1, "a"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1}}", "a"); // only take first; DATE:2015-08-02
); }
@Test public void Q() {
fxt.Test_parse("{{#property:p1|q=Q2}}", "a"); fxt.Init__docs__add(fxt.Wdoc("Q2")
} .Add_claims(fxt.Make_claim_string(1, "a"))
@Test public void Of() { .Add_sitelink("enwiki", "Test_page")
fxt.Init__docs__add(fxt.Wdoc("Q2") );
.Add_claims(fxt.Make_claim_string(1, "a"))
.Add_sitelink("enwiki", "Of_page") fxt.Test_parse("{{#property:p1|q=Q2}}", "a");
); }
@Test public void Of() {
fxt.Test_parse("{{#property:p1|of=Of_page}}", "a"); fxt.Init__docs__add(fxt.Wdoc("Q2")
} .Add_claims(fxt.Make_claim_string(1, "a"))
@Test public void From() { .Add_sitelink("enwiki", "Of_page")
fxt.Init__docs__add(fxt.Wdoc("Property:P2") );
.Add_claims(fxt.Make_claim_string(1, "a"))
); fxt.Test_parse("{{#property:p1|of=Of_page}}", "a");
}
fxt.Test_parse("{{#property:p1|from=P2}}", "a"); @Test public void From() {
fxt.Test_parse("{{#property:p1|from=}}", ""); fxt.Init__docs__add(fxt.Wdoc("Property:P2")
fxt.Test_parse("{{#property:p1| from = P2 }}", "a"); // PURPOSE: trim ws; ISSUE#:361; DATE:2019-02-11 .Add_claims(fxt.Make_claim_string(1, "a"))
} );
@Test public void Pid_as_name() {
fxt.Init__docs__add(fxt.Wdoc("Q2") fxt.Test_parse("{{#property:p1|from=P2}}", "a");
.Add_claims(fxt.Make_claim_string(1, "a")) fxt.Test_parse("{{#property:p1|from=}}", "");
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:p1| from = P2 }}", "a"); // PURPOSE: trim ws; ISSUE#:361; DATE:2019-02-11
); }
fxt.Init_pids_add("en", "astronomic symbol", 1); @Test public void Pid_as_name() {
fxt.Init__docs__add(fxt.Wdoc("Q2")
fxt.Test_parse("{{#property:astronomic symbol}}", "a"); .Add_claims(fxt.Make_claim_string(1, "a"))
} .Add_sitelink("enwiki", "Test_page")
@Test public void Empty_arg() { // PURPOSE: {{#property:p1|}} should not fail / warn; DATE:2013-11-15 );
fxt.Init__docs__add(fxt.Wdoc("Q2") fxt.Init_pids_add("en", "astronomic symbol", 1);
.Add_claims(fxt.Make_claim_string(1, "a"))
.Add_sitelink("enwiki", "Test_page") fxt.Test_parse("{{#property:astronomic symbol}}", "a");
); }
fxt.Init_pids_add("en", "astronomic symbol", 1); @Test public void Empty_arg() { // PURPOSE: {{#property:p1|}} should not fail / warn; DATE:2013-11-15
fxt.Init__docs__add(fxt.Wdoc("Q2")
fxt.Test_parse("{{#property:p1|}}", "a"); .Add_claims(fxt.Make_claim_string(1, "a"))
} .Add_sitelink("enwiki", "Test_page")
@Test public void Parse_pid() { );
fxt.Test_parse_pid ("p123" , 123); // basic fxt.Init_pids_add("en", "astronomic symbol", 1);
fxt.Test_parse_pid ("P123" , 123); // uppercase
fxt.Test_parse_pid_null ("population"); // name test fxt.Test_parse("{{#property:p1|}}", "a");
fxt.Test_parse_pid_null ("123"); // missing p }
fxt.Test_parse_pid_null (""); // empty String test @Test public void Parse_pid() {
} fxt.Test_parse_pid ("p123" , 123); // basic
} fxt.Test_parse_pid ("P123" , 123); // uppercase
fxt.Test_parse_pid_null ("population"); // name test
fxt.Test_parse_pid_null ("123"); // missing p
fxt.Test_parse_pid_null (""); // empty String test
}
}

Loading…
Cancel
Save