mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-10-27 20:34:16 +00:00
Scribunto: Trim zeroes when stringifying Doubles [#697]
This commit is contained in:
parent
f122a8d8a3
commit
bdae819908
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,40 +13,43 @@ 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;
|
||||
package gplx;
|
||||
|
||||
public class Double_ {
|
||||
public static final String Cls_val_name = "double";
|
||||
public static final Class<?> Cls_ref_type = Double.class;
|
||||
public static final double
|
||||
MinValue = Double.MIN_VALUE
|
||||
, NaN = Double.NaN
|
||||
, Inf_pos = Double.POSITIVE_INFINITY
|
||||
;
|
||||
public static final byte[]
|
||||
NaN_bry = Bry_.new_a7("NaN")
|
||||
, Inf_pos_bry = Bry_.new_a7("INF")
|
||||
;
|
||||
public static boolean IsNaN(double v) {return Double.isNaN(v);}
|
||||
public static double cast(Object o) {try {return (Double)o;} catch(Exception e) {throw Err_.new_type_mismatch_w_exc(e, double.class, o);}}
|
||||
public static double parse(String raw) {try {return Double.parseDouble(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, double.class, raw);}}
|
||||
public static double parse_or(String raw, double v) {try {return Double.parseDouble(raw);} catch(Exception e) {Err_.Noop(e); return v;}}
|
||||
public static double coerce_(Object v) {
|
||||
try {String s = String_.as_(v); return s == null ? Double_.cast(v) : Double_.parse(s);}
|
||||
catch (Exception e) {throw Err_.new_cast(e, double.class, v);}
|
||||
}
|
||||
public static String To_str(double v) {
|
||||
int v_int = (int)v;
|
||||
return v - v_int == 0 ? Int_.To_str(v_int) : Double.toString(v);
|
||||
}
|
||||
public static String To_str_loose(double v) {
|
||||
int v_as_int = (int)v;
|
||||
return v == v_as_int
|
||||
? Int_.To_str(v_as_int) // convert to int, and call print String to eliminate any trailing decimal places
|
||||
: Float_.To_str((float)v); // calling ((float)v).toString is better at removing trailing 0s than String.format("%g", v). note that .net .toString() handles it better; EX:2449.600000000000d; DATE:2014-07-29
|
||||
}
|
||||
public static int Compare(double lhs, double rhs) {
|
||||
if (lhs == rhs) return CompareAble_.Same;
|
||||
else if (lhs < rhs) return CompareAble_.Less;
|
||||
else return CompareAble_.More;
|
||||
}
|
||||
}
|
||||
public static final String Cls_val_name = "double";
|
||||
public static final Class<?> Cls_ref_type = Double.class;
|
||||
public static final double
|
||||
MinValue = Double.MIN_VALUE
|
||||
, NaN = Double.NaN
|
||||
, Inf_pos = Double.POSITIVE_INFINITY
|
||||
;
|
||||
public static final byte[]
|
||||
NaN_bry = Bry_.new_a7("NaN")
|
||||
, Inf_pos_bry = Bry_.new_a7("INF")
|
||||
;
|
||||
public static boolean IsNaN(double v) {return Double.isNaN(v);}
|
||||
public static double cast(Object o) {try {return (Double)o;} catch(Exception e) {throw Err_.new_type_mismatch_w_exc(e, double.class, o);}}
|
||||
public static double parse(String raw) {try {return Double.parseDouble(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, double.class, raw);}}
|
||||
public static double parse_or(String raw, double v) {try {return Double.parseDouble(raw);} catch(Exception e) {Err_.Noop(e); return v;}}
|
||||
public static double coerce_(Object v) {
|
||||
try {String s = String_.as_(v); return s == null ? Double_.cast(v) : Double_.parse(s);}
|
||||
catch (Exception e) {throw Err_.new_cast(e, double.class, v);}
|
||||
}
|
||||
public static String To_str(double v) {
|
||||
int v_int = (int)v;
|
||||
return v - v_int == 0 ? Int_.To_str(v_int) : Double.toString(v);
|
||||
}
|
||||
public static String To_str_loose(double v) {
|
||||
int v_as_int = (int)v;
|
||||
return v == v_as_int
|
||||
? Int_.To_str(v_as_int) // convert to int, and call print String to eliminate any trailing decimal places
|
||||
// DATE:2014-07-29; calling ((float)v).toString is better at removing trailing 0s than String.format("%g", v). note that .net .toString() handles it better; EX:2449.600000000000d
|
||||
// DATE:2020-08-12; calling ToStrByPrintF b/c better at removing trailing 0s; ISSUE#:697;
|
||||
: gplx.objects.primitives.Double_.ToStrByPrintF(v);
|
||||
}
|
||||
public static int Compare(double lhs, double rhs) {
|
||||
if (lhs == rhs) return CompareAble_.Same;
|
||||
else if (lhs < rhs) return CompareAble_.Less;
|
||||
else return CompareAble_.More;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,181 +13,198 @@ 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.xtns.scribunto.libs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
|
||||
import org.junit.*;
|
||||
import gplx.langs.jsons.*;
|
||||
import gplx.xowa.langs.*; import gplx.xowa.langs.msgs.*; import gplx.xowa.langs.numbers.*;
|
||||
import gplx.xowa.xtns.cldrs.*;
|
||||
public class Scrib_lib_language_tst {
|
||||
@Before public void init() {
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_language().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void GetContLangCode() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_getContLangCode, Object_.Ary_empty, "en");
|
||||
}
|
||||
@Test public void IsSupportedLanguage() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isSupportedLanguage, Object_.Ary("fr"), true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isSupportedLanguage, Object_.Ary("qq"), false);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isSupportedLanguage, Object_.Ary("EN"), false);
|
||||
}
|
||||
@Test public void IsKnownLanguageTag() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isKnownLanguageTag, Object_.Ary("fr"), true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isKnownLanguageTag, Object_.Ary("qq"), false);
|
||||
}
|
||||
@Test public void IsKnownLanguageTag_cldr() {
|
||||
Io_mgr.Instance.InitEngine_mem();
|
||||
Cldr_name_loader_fxt.Create_file_w_langs(fxt.Core().Lang().Key_str(), Keyval_.Ary(Keyval_.new_("goh", "goh_name")));
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isKnownLanguageTag, Object_.Ary("goh"), true);
|
||||
}
|
||||
@Test public void IsValidCode() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isValidCode, Object_.Ary("a,b"), true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isValidCode, Object_.Ary("a'b"), false);
|
||||
}
|
||||
@Test public void IsValidBuiltInCode() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isValidBuiltInCode, Object_.Ary("e-N"), true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isValidBuiltInCode, Object_.Ary("e n"), false);
|
||||
}
|
||||
@Test public void FetchLanguageName() {
|
||||
Io_mgr.Instance.SaveFilStr("mem/xowa/bin/any/xowa/cfg/lang/data/names.json", Json_doc.Make_str_by_apos
|
||||
( "["
|
||||
, " {"
|
||||
, " 'code':'en'"
|
||||
, " , 'name':'English'"
|
||||
, " , 'note':'en_note'"
|
||||
, " }"
|
||||
, ", {"
|
||||
, " 'code':'fr'"
|
||||
, " , 'name':'Français'"
|
||||
, " , 'note':'fr_note'"
|
||||
, " }"
|
||||
, "]"
|
||||
|
||||
));
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_fetchLanguageName, Object_.Ary("en"), "English");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_fetchLanguageName, Object_.Ary("fr"), "Français");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_fetchLanguageName, Object_.Ary("qz"), "");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_fetchLanguageName, Object_.Ary("459"), ""); // PAGE:en.w:United_States_Strategic_Bombing_Survey; DATE:2018-07-01
|
||||
}
|
||||
@Test public void GetFallbacksFor() {
|
||||
Xol_lang_itm other_lang = fxt.Core().App().Lang_mgr().Get_by_or_new(Bry_.new_a7("zh"));
|
||||
other_lang.Fallback_bry_(Bry_.new_a7("gan-hant, zh-hant, zh-hans"));
|
||||
fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_language.Invk_getFallbacksFor, Object_.Ary("zh"), String_.Concat_lines_nl
|
||||
( "1="
|
||||
, " 1=gan-hant"
|
||||
, " 2=zh-hant"
|
||||
, " 3=zh-hans"
|
||||
, " 4=en" // auto-add en
|
||||
));
|
||||
}
|
||||
@Test public void GetFallbacksFor_unknown() {
|
||||
fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_language.Invk_getFallbacksFor, Object_.Ary("unknown"), String_.Concat_lines_nl
|
||||
( "1="
|
||||
, " 1=en" // use "en" if unknown; REF:/languages/Language.php|getFallbacksFor; ISSUE#:340; DATE:2019-02-01
|
||||
));
|
||||
}
|
||||
@Test public void FormatNum() {
|
||||
// init
|
||||
Xol_lang_itm other_lang = fxt.Core().App().Lang_mgr().Get_by_or_load(Bry_.new_a7("de")); // NOTE: must call load now, else load will be called by scrib and sprs below will get overwritten during load;
|
||||
fxt.Parser_fxt().Init_lang_numbers_separators(other_lang, ".", ",");
|
||||
|
||||
// test
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("de", 1234), "1.234"); // german spr
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", 1234), "1,234"); // english spr
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", "1234"), "1,234"); // String passed (not int)
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", "1234", Keyval_.Ary(Keyval_.new_("noCommafy", true))) , "1234"); // noCommafy.y
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", "1234", Keyval_.Ary(Keyval_.new_("noCommafy", false))) , "1,234"); // noCommafy.n
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", "1234", Keyval_.Ary(Keyval_.new_("noCommafy", "y"))) , "1234"); // noCommafy."y"; ISSUE#:372 DATE:2019-03-02
|
||||
}
|
||||
@Test public void FormatDate() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", "2013-03-17", false), "2013-03-17");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d"), Datetime_now.Get().XtoStr_fmt_yyyy_MM_dd()); // empty date should default to today;
|
||||
}
|
||||
@Test public void FormatDate__ymd_12() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", "201603160102", false), "2016-03-16"); // handle long numeric date (12 digits); PAGE:en.w:Boron; DATE:2015-07-29
|
||||
}
|
||||
@Test public void FormatDate__utc() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", "+00000002010-05-01T00:00:00Z", false), "2010-05-01"); // handle Wikidata style dates; PAGE:en.w:Mountain_Province; DATE:2015-07-29
|
||||
}
|
||||
@Test public void FormatDate__bce() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", "+0065-12-08T00:00:00Z", false), "0065-12-08"); // ISSUE#:500
|
||||
}
|
||||
@Test public void FormatDate_date_omitted() { // PURPOSE: some calls skip the date; retrieve arg_4 by int; EX: pl.w:L._Frank_Baum
|
||||
Datetime_now.Manual_y_();
|
||||
Datetime_now.Manual_(DateAdp_.new_(2013, 12, 19, 1, 2, 3, 4));
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Keyval_.Ary(Keyval_.int_(1, "en"), Keyval_.int_(2, "Y-m-d"), Keyval_.int_(4, false)), "2013-12-19");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", ""), "2013-12-19");// PURPOSE: '' should return today, not fail; EX: th.w:สถานีรถไฟตรัง
|
||||
Datetime_now.Manual_n_();
|
||||
}
|
||||
@Test public void Lc() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_lc, Object_.Ary("en", "ABC"), "abc");
|
||||
}
|
||||
@Test public void Uc() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_uc, Object_.Ary("en", "abc"), "ABC");
|
||||
}
|
||||
@Test public void LcFirst() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_lcfirst, Object_.Ary("en", "ABC"), "aBC");
|
||||
}
|
||||
@Test public void UcFirst() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_uc, Object_.Ary("en", "abc"), "ABC");
|
||||
}
|
||||
@Test public void ParseFormattedNumber() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en", "1,234.56") , "1234.56"); // formatted String
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en", "1234") , "1234"); // String
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en", 1234) , "1234"); // int
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en", 1234.56) , "1234.56"); // double
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en"), Scrib_invoke_func_fxt.Null_rslt); // PURPOSE: missing arg should not fail; EX: ru.w:Туйон DATE:2014-01-06
|
||||
}
|
||||
@Test public void ConvertGrammar() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_convertGrammar, Object_.Ary("fi", "talo", "elative"), "talosta");
|
||||
}
|
||||
@Test public void ConvertPlural() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_convertPlural, Object_.Ary("ru", 5, Kv_ary_("a", "b", "c")), "c"); // forms in kv_ary
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_convertPlural, Object_.Ary("ru", 5, "a", "b", "c"), "c"); // forms as rest of ary; PAGE:ru.w:Ленин,_Владимир_Ильич DATE:2014-07-01
|
||||
}
|
||||
@Test public void IsRTL() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isRTL, Object_.Ary("en"), false);
|
||||
Xol_lang_itm other_lang = fxt.Core().App().Lang_mgr().Get_by_or_new(Bry_.new_a7("ar"));
|
||||
Gfo_invk_.Invk_by_val(other_lang, Xol_lang_itm.Invk_dir_rtl_, true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isRTL, Object_.Ary("ar"), true);
|
||||
}
|
||||
@Test public void Format_duration() {
|
||||
Init_lang_durations(fxt.Core().Wiki());
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDuration, Object_.Ary("en", 3723d, Kv_ary_("hours", "minutes", "seconds")), "1 hour, 2 minutes and 3 seconds"); // basic
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDuration, Object_.Ary("en", 123d, Kv_ary_("hours", "minutes", "seconds")), "2 minutes and 3 seconds"); // omit hour since < 1
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDuration, Object_.Ary("en", 123d, Kv_ary_("hours")) , "0 hours"); // handle fractional duration
|
||||
}
|
||||
@Test public void Get_duration_intervals() {
|
||||
Init_lang_durations(fxt.Core().Wiki());
|
||||
fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_language.Invk_getDurationIntervals, Object_.Ary("en", 3723d, Kv_ary_("hours", "minutes", "seconds")), String_.Concat_lines_nl_skip_last
|
||||
( "1="
|
||||
, " hours=1"
|
||||
, " minutes=2"
|
||||
, " seconds=3"
|
||||
));
|
||||
}
|
||||
public static Keyval[] Kv_ary_(String... ary) {
|
||||
int ary_len = ary.length;
|
||||
Keyval[] rv = new Keyval[ary_len];
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
rv[i] = Keyval_.int_(i, ary[i]);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static void Init_lang_durations(Xowe_wiki wiki) {
|
||||
Xol_msg_mgr msg_mgr = wiki.Lang().Msg_mgr();
|
||||
msg_mgr.Clear();
|
||||
msg_mgr.Itm_by_key_or_new("duration-millenia" , "~{0} {{PLURAL:~{0}\u007Cmillennium\u007Cmillennia}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-centuries" , "~{0} {{PLURAL:~{0}\u007Ccentury\u007Ccenturies}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-decades" , "~{0} {{PLURAL:~{0}\u007Cdecade\u007Cdecades}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-years" , "~{0} {{PLURAL:~{0}\u007Cyear\u007Cyears}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-weeks" , "~{0} {{PLURAL:~{0}\u007Cweek\u007Cweeks}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-days" , "~{0} {{PLURAL:~{0}\u007Cday\u007Cdays}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-hours" , "~{0} {{PLURAL:~{0}\u007Chour\u007Chours}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-minutes" , "~{0} {{PLURAL:~{0}\u007Cminute\u007Cminutes}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-seconds" , "~{0} {{PLURAL:~{0}\u007Csecond\u007Cseconds}}");
|
||||
msg_mgr.Itm_by_key_or_new("and" , " and");
|
||||
msg_mgr.Itm_by_key_or_new("word-separator" , " ");
|
||||
msg_mgr.Itm_by_key_or_new("comma-separator" , ", ");
|
||||
}
|
||||
}
|
||||
package gplx.xowa.xtns.scribunto.libs;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.DateAdp_;
|
||||
import gplx.Datetime_now;
|
||||
import gplx.Gfo_invk_;
|
||||
import gplx.Io_mgr;
|
||||
import gplx.Keyval;
|
||||
import gplx.Keyval_;
|
||||
import gplx.Object_;
|
||||
import gplx.String_;
|
||||
import gplx.langs.jsons.Json_doc;
|
||||
import gplx.xowa.Xowe_wiki;
|
||||
import gplx.xowa.langs.Xol_lang_itm;
|
||||
import gplx.xowa.langs.msgs.Xol_msg_mgr;
|
||||
import gplx.xowa.xtns.cldrs.Cldr_name_loader_fxt;
|
||||
import gplx.xowa.xtns.scribunto.Scrib_invoke_func_fxt;
|
||||
import gplx.xowa.xtns.scribunto.Scrib_lib;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class Scrib_lib_language_tst {
|
||||
@Before public void init() {
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_language().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void GetContLangCode() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_getContLangCode, Object_.Ary_empty, "en");
|
||||
}
|
||||
@Test public void IsSupportedLanguage() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isSupportedLanguage, Object_.Ary("fr"), true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isSupportedLanguage, Object_.Ary("qq"), false);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isSupportedLanguage, Object_.Ary("EN"), false);
|
||||
}
|
||||
@Test public void IsKnownLanguageTag() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isKnownLanguageTag, Object_.Ary("fr"), true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isKnownLanguageTag, Object_.Ary("qq"), false);
|
||||
}
|
||||
@Test public void IsKnownLanguageTag_cldr() {
|
||||
Io_mgr.Instance.InitEngine_mem();
|
||||
Cldr_name_loader_fxt.Create_file_w_langs(fxt.Core().Lang().Key_str(), Keyval_.Ary(Keyval_.new_("goh", "goh_name")));
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isKnownLanguageTag, Object_.Ary("goh"), true);
|
||||
}
|
||||
@Test public void IsValidCode() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isValidCode, Object_.Ary("a,b"), true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isValidCode, Object_.Ary("a'b"), false);
|
||||
}
|
||||
@Test public void IsValidBuiltInCode() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isValidBuiltInCode, Object_.Ary("e-N"), true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isValidBuiltInCode, Object_.Ary("e n"), false);
|
||||
}
|
||||
@Test public void FetchLanguageName() {
|
||||
Io_mgr.Instance.SaveFilStr("mem/xowa/bin/any/xowa/cfg/lang/data/names.json", Json_doc.Make_str_by_apos
|
||||
( "["
|
||||
, " {"
|
||||
, " 'code':'en'"
|
||||
, " , 'name':'English'"
|
||||
, " , 'note':'en_note'"
|
||||
, " }"
|
||||
, ", {"
|
||||
, " 'code':'fr'"
|
||||
, " , 'name':'Français'"
|
||||
, " , 'note':'fr_note'"
|
||||
, " }"
|
||||
, "]"
|
||||
|
||||
));
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_fetchLanguageName, Object_.Ary("en"), "English");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_fetchLanguageName, Object_.Ary("fr"), "Français");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_fetchLanguageName, Object_.Ary("qz"), "");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_fetchLanguageName, Object_.Ary("459"), ""); // PAGE:en.w:United_States_Strategic_Bombing_Survey; DATE:2018-07-01
|
||||
}
|
||||
@Test public void GetFallbacksFor() {
|
||||
Xol_lang_itm other_lang = fxt.Core().App().Lang_mgr().Get_by_or_new(Bry_.new_a7("zh"));
|
||||
other_lang.Fallback_bry_(Bry_.new_a7("gan-hant, zh-hant, zh-hans"));
|
||||
fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_language.Invk_getFallbacksFor, Object_.Ary("zh"), String_.Concat_lines_nl
|
||||
( "1="
|
||||
, " 1=gan-hant"
|
||||
, " 2=zh-hant"
|
||||
, " 3=zh-hans"
|
||||
, " 4=en" // auto-add en
|
||||
));
|
||||
}
|
||||
@Test public void GetFallbacksFor_unknown() {
|
||||
fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_language.Invk_getFallbacksFor, Object_.Ary("unknown"), String_.Concat_lines_nl
|
||||
( "1="
|
||||
, " 1=en" // use "en" if unknown; REF:/languages/Language.php|getFallbacksFor; ISSUE#:340; DATE:2019-02-01
|
||||
));
|
||||
}
|
||||
@Test public void FormatNum() {
|
||||
// init
|
||||
Xol_lang_itm other_lang = fxt.Core().App().Lang_mgr().Get_by_or_load(Bry_.new_a7("de")); // NOTE: must call load now, else load will be called by scrib and sprs below will get overwritten during load;
|
||||
fxt.Parser_fxt().Init_lang_numbers_separators(other_lang, ".", ",");
|
||||
|
||||
// test
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("de", 1234), "1.234"); // german spr
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", 1234), "1,234"); // english spr
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", "1234"), "1,234"); // String passed (not int)
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", "1234", Keyval_.Ary(Keyval_.new_("noCommafy", true))) , "1234"); // noCommafy.y
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", "1234", Keyval_.Ary(Keyval_.new_("noCommafy", false))) , "1,234"); // noCommafy.n
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", "1234", Keyval_.Ary(Keyval_.new_("noCommafy", "y"))) , "1234"); // noCommafy."y"; ISSUE#:372 DATE:2019-03-02
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatNum, Object_.Ary("en", 768d / 10000000d) , "7.68E-5"); // ensure "e-05" -> "E-5" ISSUE#:697; DATE:2020-08-12
|
||||
}
|
||||
@Test public void FormatDate() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", "2013-03-17", false), "2013-03-17");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d"), Datetime_now.Get().XtoStr_fmt_yyyy_MM_dd()); // empty date should default to today;
|
||||
}
|
||||
@Test public void FormatDate__ymd_12() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", "201603160102", false), "2016-03-16"); // handle long numeric date (12 digits); PAGE:en.w:Boron; DATE:2015-07-29
|
||||
}
|
||||
@Test public void FormatDate__utc() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", "+00000002010-05-01T00:00:00Z", false), "2010-05-01"); // handle Wikidata style dates; PAGE:en.w:Mountain_Province; DATE:2015-07-29
|
||||
}
|
||||
@Test public void FormatDate__bce() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", "+0065-12-08T00:00:00Z", false), "0065-12-08"); // ISSUE#:500
|
||||
}
|
||||
@Test public void FormatDate_date_omitted() { // PURPOSE: some calls skip the date; retrieve arg_4 by int; EX: pl.w:L._Frank_Baum
|
||||
Datetime_now.Manual_y_();
|
||||
Datetime_now.Manual_(DateAdp_.new_(2013, 12, 19, 1, 2, 3, 4));
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Keyval_.Ary(Keyval_.int_(1, "en"), Keyval_.int_(2, "Y-m-d"), Keyval_.int_(4, false)), "2013-12-19");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDate, Object_.Ary("en", "Y-m-d", ""), "2013-12-19");// PURPOSE: '' should return today, not fail; EX: th.w:สถานีรถไฟตรัง
|
||||
Datetime_now.Manual_n_();
|
||||
}
|
||||
@Test public void Lc() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_lc, Object_.Ary("en", "ABC"), "abc");
|
||||
}
|
||||
@Test public void Uc() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_uc, Object_.Ary("en", "abc"), "ABC");
|
||||
}
|
||||
@Test public void LcFirst() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_lcfirst, Object_.Ary("en", "ABC"), "aBC");
|
||||
}
|
||||
@Test public void UcFirst() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_uc, Object_.Ary("en", "abc"), "ABC");
|
||||
}
|
||||
@Test public void ParseFormattedNumber() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en", "1,234.56") , "1234.56"); // formatted String
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en", "1234") , "1234"); // String
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en", 1234) , "1234"); // int
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en", 1234.56) , "1234.56"); // double
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_parseFormattedNumber, Object_.Ary("en"), Scrib_invoke_func_fxt.Null_rslt); // PURPOSE: missing arg should not fail; EX: ru.w:Туйон DATE:2014-01-06
|
||||
}
|
||||
@Test public void ConvertGrammar() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_convertGrammar, Object_.Ary("fi", "talo", "elative"), "talosta");
|
||||
}
|
||||
@Test public void ConvertPlural() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_convertPlural, Object_.Ary("ru", 5, Kv_ary_("a", "b", "c")), "c"); // forms in kv_ary
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_convertPlural, Object_.Ary("ru", 5, "a", "b", "c"), "c"); // forms as rest of ary; PAGE:ru.w:Ленин,_Владимир_Ильич DATE:2014-07-01
|
||||
}
|
||||
@Test public void IsRTL() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isRTL, Object_.Ary("en"), false);
|
||||
Xol_lang_itm other_lang = fxt.Core().App().Lang_mgr().Get_by_or_new(Bry_.new_a7("ar"));
|
||||
Gfo_invk_.Invk_by_val(other_lang, Xol_lang_itm.Invk_dir_rtl_, true);
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_language.Invk_isRTL, Object_.Ary("ar"), true);
|
||||
}
|
||||
@Test public void Format_duration() {
|
||||
Init_lang_durations(fxt.Core().Wiki());
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDuration, Object_.Ary("en", 3723d, Kv_ary_("hours", "minutes", "seconds")), "1 hour, 2 minutes and 3 seconds"); // basic
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDuration, Object_.Ary("en", 123d, Kv_ary_("hours", "minutes", "seconds")), "2 minutes and 3 seconds"); // omit hour since < 1
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_language.Invk_formatDuration, Object_.Ary("en", 123d, Kv_ary_("hours")) , "0 hours"); // handle fractional duration
|
||||
}
|
||||
@Test public void Get_duration_intervals() {
|
||||
Init_lang_durations(fxt.Core().Wiki());
|
||||
fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_language.Invk_getDurationIntervals, Object_.Ary("en", 3723d, Kv_ary_("hours", "minutes", "seconds")), String_.Concat_lines_nl_skip_last
|
||||
( "1="
|
||||
, " hours=1"
|
||||
, " minutes=2"
|
||||
, " seconds=3"
|
||||
));
|
||||
}
|
||||
public static Keyval[] Kv_ary_(String... ary) {
|
||||
int ary_len = ary.length;
|
||||
Keyval[] rv = new Keyval[ary_len];
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
rv[i] = Keyval_.int_(i, ary[i]);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static void Init_lang_durations(Xowe_wiki wiki) {
|
||||
Xol_msg_mgr msg_mgr = wiki.Lang().Msg_mgr();
|
||||
msg_mgr.Clear();
|
||||
msg_mgr.Itm_by_key_or_new("duration-millenia" , "~{0} {{PLURAL:~{0}\u007Cmillennium\u007Cmillennia}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-centuries" , "~{0} {{PLURAL:~{0}\u007Ccentury\u007Ccenturies}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-decades" , "~{0} {{PLURAL:~{0}\u007Cdecade\u007Cdecades}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-years" , "~{0} {{PLURAL:~{0}\u007Cyear\u007Cyears}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-weeks" , "~{0} {{PLURAL:~{0}\u007Cweek\u007Cweeks}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-days" , "~{0} {{PLURAL:~{0}\u007Cday\u007Cdays}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-hours" , "~{0} {{PLURAL:~{0}\u007Chour\u007Chours}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-minutes" , "~{0} {{PLURAL:~{0}\u007Cminute\u007Cminutes}}");
|
||||
msg_mgr.Itm_by_key_or_new("duration-seconds" , "~{0} {{PLURAL:~{0}\u007Csecond\u007Cseconds}}");
|
||||
msg_mgr.Itm_by_key_or_new("and" , " and");
|
||||
msg_mgr.Itm_by_key_or_new("word-separator" , " ");
|
||||
msg_mgr.Itm_by_key_or_new("comma-separator" , ", ");
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,8 +13,100 @@ 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.objects.primitives; import gplx.*; import gplx.objects.*;
|
||||
public class Double_ {
|
||||
public static final String Cls_val_name = "double";
|
||||
public static final Class<?> Cls_ref_type = Double.class;
|
||||
}
|
||||
package gplx.objects.primitives;
|
||||
|
||||
public class Double_ {
|
||||
public static final String Cls_val_name = "double";
|
||||
public static final Class<?> Cls_ref_type = Double.class;
|
||||
|
||||
public static String ToStrByPrintF(double val) {
|
||||
// call sprintf-like format; EX:"sprintf((s), "%.14g", (n));"
|
||||
return TrimZeroes(String.format("%.14g", val));
|
||||
}
|
||||
public static String TrimZeroes(String valStr) { // TEST
|
||||
// NOTE:this function was originally in LuaDouble; it was refactored for clarity, and also to handle trimming zeroes from exponent; EX:"e-05" ISSUE#:697; DATE:2020-08-12
|
||||
int valStrLen = valStr.length();
|
||||
boolean startTrimming = true; // will be set to true at end of string (12.00), or before "e" (1.00e5)
|
||||
boolean trimmingZeroes = false;
|
||||
int trimIdx = -1;
|
||||
int expIdx = -1;
|
||||
|
||||
// read backwards from end of string
|
||||
for (int i = valStrLen - 1; i > -1; i--) {
|
||||
switch (valStr.charAt(i)) {
|
||||
case '0':
|
||||
// if startTrimming is true, then enable trimmingZeroes; should only occur twice; (1) end of string ("12.00"); (2) before "e" ("1.00e5")
|
||||
if (startTrimming) {
|
||||
startTrimming = false;
|
||||
trimmingZeroes = true;
|
||||
}
|
||||
|
||||
// if trimmingZeroes, set trimIdx just before this `0`
|
||||
if (trimmingZeroes)
|
||||
trimIdx = i;
|
||||
break;
|
||||
case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
// disable trimmingZeroes; EX: "12.30"
|
||||
trimmingZeroes = false;
|
||||
startTrimming = false; // mark startTrimming false else will gobble up zeroes before numbers; EX: "0.00001" x> "0.1"; ISSUE#:697; DATE:2020-08-11
|
||||
break;
|
||||
case '-': // ignore scientific notation or negative sign; EX: "5.0e-17", "-1"
|
||||
break;
|
||||
case 'e': // scientific notation; reset startTrimming; EX: 5.0000000000000e-17
|
||||
expIdx = i;
|
||||
startTrimming = true;
|
||||
break;
|
||||
case '.':
|
||||
// if still trimmingZeroes, and reached decimalPoint, then update trimIdx to truncate decimalPoint also; EX: "123.0000" -> "123" x> "123."
|
||||
if (trimmingZeroes)
|
||||
trimIdx = i;
|
||||
|
||||
// trimIdx has been set
|
||||
if (trimIdx != -1) {
|
||||
if (expIdx == -1) { // decimal; EX: "12.00"
|
||||
valStr = valStr.substring(0, trimIdx);
|
||||
}
|
||||
else { // exponent; "1.00e5"
|
||||
// get exponent portion; EX: "e-05"
|
||||
String expStr = valStr.substring(expIdx, valStrLen);
|
||||
int expStrLen = expStr.length();
|
||||
|
||||
// set expSymIdx to be after "e" or "e-"
|
||||
int expSymIdx = 1; // skip the "e"
|
||||
if (expSymIdx < expStrLen && !Character.isDigit(expStr.charAt(expSymIdx))) { // skip "-" if it's there
|
||||
expSymIdx++;
|
||||
}
|
||||
|
||||
// exponent can have 0s; skip them; EX: 1.1e-05
|
||||
int expNumIdx = expSymIdx;
|
||||
for (int j = expNumIdx; j < expStrLen; j++) {
|
||||
if (expStr.charAt(j) == '0') { // skip zeroes
|
||||
expNumIdx++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// now stitch it together
|
||||
valStr = valStr.substring(0, trimIdx)
|
||||
+ expStr.substring(0, expSymIdx) // add "e-"
|
||||
+ expStr.substring(expNumIdx); // add numbers with any leading zeroes trimmed
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: "e" needs to be uppercased to "E"; PAGE:en.w:List_of_countries_and_dependencies_by_population
|
||||
if (expIdx != -1) {
|
||||
valStr = valStr.toUpperCase();
|
||||
}
|
||||
i = -1; // no more trimming needed before decimalPoint; stop looping
|
||||
break;
|
||||
default: // anything else; stop looping
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return valStr;
|
||||
}
|
||||
}
|
||||
|
51
baselib/tst/gplx/objects/primitives/Double_Test.java
Normal file
51
baselib/tst/gplx/objects/primitives/Double_Test.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 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.objects.primitives;
|
||||
|
||||
import gplx.tests.Gftest_fxt;
|
||||
import org.junit.Test;
|
||||
|
||||
public class Double_Test {
|
||||
private final Double_Tstr tstr = new Double_Tstr();
|
||||
|
||||
@Test
|
||||
public void TrimZeroes() {
|
||||
tstr.Test_TrimZeroes("12.100" , "12.1");
|
||||
tstr.Test_TrimZeroes("12.000" , "12");
|
||||
tstr.Test_TrimZeroes("12.001" , "12.001");
|
||||
tstr.Test_TrimZeroes("1020.00" , "1020");
|
||||
tstr.Test_TrimZeroes("1020.00" , "1020");
|
||||
tstr.Test_TrimZeroes("1.200e5" , "1.2E5");
|
||||
tstr.Test_TrimZeroes("1.200e-05" , "1.2E-5");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ToStrByPrintF() {
|
||||
tstr.Test_ToStrByPrintF(1d / 2d , "0.5"); // fails with 0.50000000000000
|
||||
tstr.Test_ToStrByPrintF(5d / 100000000000000000d, "5E-17"); // fails with 5.0000000000000e-17
|
||||
tstr.Test_ToStrByPrintF(7538000d / 7773352000d , "0.00096972322879499"); // fails with 0; ISSUE#:697; DATE:2020-08-11
|
||||
tstr.Test_ToStrByPrintF(56225d / 7776747000d , "7.2298867379895E-06"); // fails with 0; ISSUE#:697; DATE:2020-08-11
|
||||
tstr.Test_ToStrByPrintF(35746d / 7805411000d , "4.5796435319037E-06"); // fails with 0; ISSUE#:697; DATE:2020-08-11
|
||||
}
|
||||
}
|
||||
class Double_Tstr {
|
||||
public void Test_ToStrByPrintF(double v, String expd) {
|
||||
Gftest_fxt.Eq__str(expd, Double_.ToStrByPrintF(v));
|
||||
}
|
||||
public void Test_TrimZeroes(String val, String expd) {
|
||||
Gftest_fxt.Eq__str(expd, Double_.TrimZeroes(val));
|
||||
}
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user