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/js_relative_time_format.h"
17 #include "ecmascript/intl/locale_helper.h"
18 #include "ecmascript/base/number_helper.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/napi/jsnapi_helper.h"
21 #include "ecmascript/tests/test_helper.h"
22
23 using namespace panda::ecmascript;
24 using namespace panda::ecmascript::base;
25
26 namespace panda::test {
27 class JSRelativeTimeFormatTest : public BaseTestWithScope<true> {
28 };
29
HWTEST_F_L0(JSRelativeTimeFormatTest,InitializeRelativeTimeFormat)30 HWTEST_F_L0(JSRelativeTimeFormatTest, InitializeRelativeTimeFormat)
31 {
32 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
33 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
34
35 JSHandle<JSTaggedValue> ctor = env->GetRelativeTimeFormatFunction();
36 JSHandle<JSRelativeTimeFormat> relativeTimeFormat =
37 JSHandle<JSRelativeTimeFormat>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
38 EXPECT_TRUE(*relativeTimeFormat != nullptr);
39
40 JSHandle<JSTaggedValue> locales(factory->NewFromASCII("en"));
41 JSHandle<JSTaggedValue> undefinedOptions(thread, JSTaggedValue::Undefined());
42 JSRelativeTimeFormat::InitializeRelativeTimeFormat(thread, relativeTimeFormat, locales, undefinedOptions);
43 // Initialize attribute comparison
44 JSHandle<EcmaString> numberingSystemStr(thread, relativeTimeFormat->GetNumberingSystem().GetTaggedObject());
45 EXPECT_STREQ("latn", EcmaStringAccessor(numberingSystemStr).ToCString().c_str());
46 JSHandle<EcmaString> localeStr(thread, relativeTimeFormat->GetLocale().GetTaggedObject());
47 EXPECT_STREQ("en", EcmaStringAccessor(localeStr).ToCString().c_str());
48 EXPECT_EQ(NumericOption::ALWAYS, relativeTimeFormat->GetNumeric());
49 EXPECT_EQ(RelativeStyleOption::LONG, relativeTimeFormat->GetStyle());
50 }
51
HWTEST_F_L0(JSRelativeTimeFormatTest,GetIcuRTFFormatter)52 HWTEST_F_L0(JSRelativeTimeFormatTest, GetIcuRTFFormatter)
53 {
54 double value = base::NAN_VALUE;
55 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
56 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
57
58 JSHandle<JSTaggedValue> ctor = env->GetRelativeTimeFormatFunction();
59 JSHandle<JSRelativeTimeFormat> relativeTimeFormat =
60 JSHandle<JSRelativeTimeFormat>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
61 // Create Icu RelativeDateTimeFormatter
62 icu::Locale icuLocale("en", "US");
63 UErrorCode status = U_ZERO_ERROR;
64 icu::NumberFormat *icuNumberFormat = icu::NumberFormat::createInstance(icuLocale, UNUM_DECIMAL, status);
65 icu::RelativeDateTimeFormatter rtfFormatter(icuLocale, icuNumberFormat, UDAT_STYLE_LONG,
66 UDISPCTX_CAPITALIZATION_NONE, status);
67 icu::UnicodeString result1 = rtfFormatter.formatNumericToValue(value, UDAT_REL_UNIT_YEAR, status).toString(status);
68 JSHandle<EcmaString> stringValue1 = intl::LocaleHelper::UStringToString(thread, result1);
69 // Set Icu RelativeDateTimeFormatter to Icu Field
70 factory->NewJSIntlIcuData(relativeTimeFormat, rtfFormatter, JSRelativeTimeFormat::FreeIcuRTFFormatter);
71 // Get Icu Field
72 icu::RelativeDateTimeFormatter *resultRelativeDateTimeFormatter = relativeTimeFormat->GetIcuRTFFormatter();
73 icu::UnicodeString result2 =
74 resultRelativeDateTimeFormatter->formatNumericToValue(value, UDAT_REL_UNIT_YEAR, status).toString(status);
75 JSHandle<EcmaString> stringValue2 = intl::LocaleHelper::UStringToString(thread, result2);
76 EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*stringValue1, *stringValue2), true);
77 }
78
HWTEST_F_L0(JSRelativeTimeFormatTest,UnwrapRelativeTimeFormat)79 HWTEST_F_L0(JSRelativeTimeFormatTest, UnwrapRelativeTimeFormat)
80 {
81 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
82 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
83 EcmaVM *vm = thread->GetEcmaVM();
84
85 JSHandle<JSTaggedValue> relativeTimeFormatFunc = env->GetRelativeTimeFormatFunction();
86 JSHandle<JSTaggedValue> relativeTimeFormat(
87 factory->NewJSObjectByConstructor(JSHandle<JSFunction>(relativeTimeFormatFunc), relativeTimeFormatFunc));
88
89 Local<FunctionRef> relativeTimeFormatLocal = JSNApiHelper::ToLocal<FunctionRef>(relativeTimeFormatFunc);
90 JSHandle<JSTaggedValue> disPlayNamesFunc = env->GetDisplayNamesFunction();
91 Local<FunctionRef> disPlayNamesLocal = JSNApiHelper::ToLocal<FunctionRef>(disPlayNamesFunc);
92 // displaynames Inherit relativeTimeFormat
93 disPlayNamesLocal->Inherit(vm, relativeTimeFormatLocal);
94 JSHandle<JSTaggedValue> disPlayNamesHandle = JSNApiHelper::ToJSHandle(disPlayNamesLocal);
95 JSHandle<JSTaggedValue> disPlayNamesObj(
96 factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(disPlayNamesHandle), disPlayNamesHandle));
97 // object has no Instance
98 JSHandle<JSTaggedValue> unwrapNumberFormat1 =
99 JSRelativeTimeFormat::UnwrapRelativeTimeFormat(thread, relativeTimeFormat);
100 EXPECT_TRUE(JSTaggedValue::SameValue(relativeTimeFormat, unwrapNumberFormat1));
101 // object has Instance
102 JSHandle<JSTaggedValue> unwrapNumberFormat2 =
103 JSRelativeTimeFormat::UnwrapRelativeTimeFormat(thread, disPlayNamesObj);
104 EXPECT_TRUE(unwrapNumberFormat2->IsUndefined());
105 }
106 } // namespace panda::test