/* 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.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" , ", "); } }