• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/intl/locale_helper.h"
17 #include "ecmascript/js_number_format.h"
18 #include "ecmascript/napi/jsnapi_helper.h"
19 #include "ecmascript/tests/test_helper.h"
20 
21 using namespace panda::ecmascript;
22 
23 namespace panda::test {
24 class JSNumberFormatTest : public BaseTestWithScope<true> {
25 };
26 
27 /**
28  * @tc.name: GetIcuCallTarget
29  * @tc.desc: Call "NewJSIntlIcuData" function Set IcuCallTarget,check whether the IcuCallTarget through
30  *           "GetIcuCallTarget" function is within expectations then call "formatInt" function format
31  *           Int type data and check the returned value is within expectations.
32  * @tc.type: FUNC
33  * @tc.require:
34  */
HWTEST_F_L0(JSNumberFormatTest,GetIcuCallTarget)35 HWTEST_F_L0(JSNumberFormatTest, GetIcuCallTarget)
36 {
37     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
38     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
39 
40     JSHandle<JSTaggedValue> ctor = env->GetNumberFormatFunction();
41     JSHandle<JSNumberFormat> numberFormat =
42         JSHandle<JSNumberFormat>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
43 
44     icu::Locale icuLocale("en", "US");
45     icu::number::LocalizedNumberFormatter icuNumberFormatter =
46         icu::number::NumberFormatter::withLocale(icuLocale).roundingMode(UNUM_ROUND_HALFUP);
47     // Set IcuCallTarget
48     factory->NewJSIntlIcuData(numberFormat, icuNumberFormatter, JSNumberFormat::FreeIcuNumberformat);
49     icu::number::LocalizedNumberFormatter *resultIcuNumberFormatter = numberFormat->GetIcuCallTarget();
50     EXPECT_TRUE(resultIcuNumberFormatter != nullptr);
51     // Use IcuCallTarget format Int
52     int64_t value = -123456;
53     UErrorCode status = U_ZERO_ERROR;
54     icu::number::FormattedNumber formattedNumber = resultIcuNumberFormatter->formatInt(value, status);
55     icu::UnicodeString result = formattedNumber.toString(status);
56     JSHandle<EcmaString> stringValue = intl::LocaleHelper::UStringToString(thread, result);
57     EXPECT_STREQ("-123,456", EcmaStringAccessor(stringValue).ToCString().c_str());
58 }
59 
60 /**
61  * @tc.name: InitializeNumberFormat
62  * @tc.desc: Call "InitializeNumberFormat" function Initialize NumberFormat,and check whether the properties of
63  *           the object is within expectations.
64  * @tc.type: FUNC
65  * @tc.require:
66  */
HWTEST_F_L0(JSNumberFormatTest,InitializeNumberFormat)67 HWTEST_F_L0(JSNumberFormatTest, InitializeNumberFormat)
68 {
69     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
70     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
71 
72     JSHandle<JSTaggedValue> ctor = env->GetNumberFormatFunction();
73     JSHandle<JSNumberFormat> numberFormat =
74         JSHandle<JSNumberFormat>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
75     EXPECT_TRUE(*numberFormat != nullptr);
76 
77     JSHandle<JSTaggedValue> locales(factory->NewFromASCII("zh-Hans-CN"));
78     JSHandle<JSTaggedValue> undefinedOptions(thread, JSTaggedValue::Undefined());
79     JSNumberFormat::InitializeNumberFormat(thread, numberFormat, locales, undefinedOptions);
80     // Initialize attribute comparison
81     EXPECT_TRUE(numberFormat->GetNumberingSystem().IsUndefined());
82     JSHandle<EcmaString> localeStr(thread, numberFormat->GetLocale().GetTaggedObject());
83     EXPECT_STREQ("zh-Hans-CN", EcmaStringAccessor(localeStr).ToCString().c_str());
84     EXPECT_EQ(NotationOption::STANDARD, numberFormat->GetNotation());
85     EXPECT_EQ(CompactDisplayOption::SHORT, numberFormat->GetCompactDisplay());
86     EXPECT_EQ(SignDisplayOption::AUTO, numberFormat->GetSignDisplay());
87     EXPECT_EQ(CurrencyDisplayOption::SYMBOL, numberFormat->GetCurrencyDisplay());
88     EXPECT_EQ(CurrencySignOption::STANDARD, numberFormat->GetCurrencySign());
89     EXPECT_EQ(UnitDisplayOption::SHORT, numberFormat->GetUnitDisplay());
90     EXPECT_EQ(numberFormat->GetMinimumIntegerDigits().GetInt(), 1); // 1 : 1 default minimum integer
91     EXPECT_EQ(numberFormat->GetMinimumFractionDigits().GetInt(), 0); // 0 : 0 default minimum fraction
92     EXPECT_EQ(numberFormat->GetMaximumFractionDigits().GetInt(), 3); // 1 : 1 default maximum fraction
93     EXPECT_EQ(numberFormat->GetMinimumSignificantDigits().GetInt(), 0); // 0 : 0 default minimum sigfraction
94     EXPECT_EQ(numberFormat->GetMaximumSignificantDigits().GetInt(), 0); // 0 : 0 default maximum sigfraction
95     EXPECT_TRUE(numberFormat->GetUseGrouping().IsTrue());
96     EXPECT_TRUE(numberFormat->GetBoundFormat().IsUndefined());
97     EXPECT_TRUE(numberFormat->GetUnit().IsUndefined());
98     EXPECT_TRUE(numberFormat->GetCurrency().IsUndefined());
99 }
100 
101 /**
102  * @tc.name: CurrencyDigits
103  * @tc.desc: If the ISO 4217 currency contains currency as an alphabetic code, return the minor unit value
104  *           corresponding to the currency from the list
105  * @tc.type: FUNC
106  * @tc.require:
107  */
HWTEST_F_L0(JSNumberFormatTest,CurrencyDigits)108 HWTEST_F_L0(JSNumberFormatTest, CurrencyDigits)
109 {
110     // Alphabetic code:USD
111     icu::UnicodeString usdCurrency("USD");
112     // 2 : 2 fraction digits
113     EXPECT_EQ(JSNumberFormat::CurrencyDigits(usdCurrency), 2);
114     // Alphabetic code:EUR
115     icu::UnicodeString eurCurrency("EUR");
116     // 2 : 2 fraction digits
117     EXPECT_EQ(JSNumberFormat::CurrencyDigits(eurCurrency), 2);
118     // Alphabetic code:CHF
119     icu::UnicodeString numberCurrency("CHF");
120     // 2 : 2 fraction digits
121     EXPECT_EQ(JSNumberFormat::CurrencyDigits(numberCurrency), 2);
122 }
123 
124 /**
125  * @tc.name: FormatNumeric
126  * @tc.desc: Call "InitializeNumberFormat" function Initialize NumberFormat,Set the sytle attribute of the object to
127  *           decimal,construct a bigint type data,and the object calls the FormatNumeric method to interpret the bigint
128  *           type data into the corresponding decimal, and check whether the decimal meets the expectation.
129  * @tc.type: FUNC
130  * @tc.require:
131  */
HWTEST_F_L0(JSNumberFormatTest,FormatNumeric)132 HWTEST_F_L0(JSNumberFormatTest, FormatNumeric)
133 {
134     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
135     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
136     auto globalConst = thread->GlobalConstants();
137 
138     JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
139     JSHandle<JSTaggedValue> ctor = env->GetNumberFormatFunction();
140     JSHandle<JSNumberFormat> numberFormat =
141         JSHandle<JSNumberFormat>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
142 
143     JSHandle<JSTaggedValue> styleKey = globalConst->GetHandledStyleString();
144     JSHandle<JSTaggedValue> styleValue(factory->NewFromASCII("decimal"));
145     JSHandle<JSTaggedValue> localeString(factory->NewFromASCII("en-US"));
146     JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
147     JSObject::SetProperty(thread, optionsObj, styleKey, styleValue);
148     JSNumberFormat::InitializeNumberFormat(thread, numberFormat, localeString, JSHandle<JSTaggedValue>(optionsObj));
149     // format BigInt
150     JSHandle<JSTaggedValue> number(thread, JSTaggedValue(123456789));
151     JSHandle<BigInt> jsBigInt(thread, BigInt::NumberToBigInt(thread, number));
152     JSHandle<JSTaggedValue> formatResult =
153         JSNumberFormat::FormatNumeric(thread, numberFormat, jsBigInt.GetTaggedValue());
154 
155     JSHandle<EcmaString> resultEcmaStr(thread, formatResult.GetTaggedValue());
156     EXPECT_STREQ("123,456,789", EcmaStringAccessor(resultEcmaStr).ToCString().c_str());
157 }
158 
159 /**
160  * @tc.name: UnwrapNumberFormat
161  * @tc.desc: Construct an object,If it is a numberformat object,it will be returned.If it is an object of other types
162  *           and inherits the numberformat object, it will get value from the fallbacksymbol key and return.
163  * @tc.type: FUNC
164  * @tc.require:
165  */
HWTEST_F_L0(JSNumberFormatTest,UnwrapNumberFormat)166 HWTEST_F_L0(JSNumberFormatTest, UnwrapNumberFormat)
167 {
168     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
169     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
170     EcmaVM *vm = thread->GetEcmaVM();
171 
172     JSHandle<JSTaggedValue> numberFormatFunc = env->GetNumberFormatFunction();
173     JSHandle<JSTaggedValue> numberFormat(
174         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(numberFormatFunc), numberFormatFunc));
175 
176     Local<FunctionRef> numberFormatLocal = JSNApiHelper::ToLocal<FunctionRef>(numberFormatFunc);
177     JSHandle<JSTaggedValue> disPlayNamesFunc = env->GetDisplayNamesFunction();
178     Local<FunctionRef> disPlayNamesLocal = JSNApiHelper::ToLocal<FunctionRef>(disPlayNamesFunc);
179     // displaynames Inherit numberformat
180     disPlayNamesLocal->Inherit(vm, numberFormatLocal);
181     JSHandle<JSTaggedValue> disPlayNamesHandle = JSNApiHelper::ToJSHandle(disPlayNamesLocal);
182     JSHandle<JSTaggedValue> disPlayNamesObj(
183         factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(disPlayNamesHandle), disPlayNamesHandle));
184     // object has no Instance
185     JSHandle<JSTaggedValue> unwrapNumberFormat1 = JSNumberFormat::UnwrapNumberFormat(thread, numberFormat);
186     EXPECT_TRUE(JSTaggedValue::SameValue(numberFormat, unwrapNumberFormat1));
187     // object has Instance
188     JSHandle<JSTaggedValue> unwrapNumberFormat2 = JSNumberFormat::UnwrapNumberFormat(thread, disPlayNamesObj);
189     EXPECT_TRUE(unwrapNumberFormat2->IsUndefined());
190 }
191 }  // namespace panda::test