• 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/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 testing::Test {
28 public:
SetUpTestCase()29     static void SetUpTestCase()
30     {
31         GTEST_LOG_(INFO) << "SetUpTestCase";
32     }
33 
TearDownTestCase()34     static void TearDownTestCase()
35     {
36         GTEST_LOG_(INFO) << "TearDownCase";
37     }
38 
SetUp()39     void SetUp() override
40     {
41         JSRuntimeOptions options;
42 #if PANDA_TARGET_LINUX
43         // for consistency requirement, use ohos_icu4j/data/icudt67l.dat as icu-data-path
44         options.SetIcuDataPath(ICU_PATH);
45 #endif
46         options.SetEnableForceGC(true);
47         instance = JSNApi::CreateEcmaVM(options);
48         instance->SetEnableForceGC(true);
49         ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
50         thread = instance->GetJSThread();
51         scope = new EcmaHandleScope(thread);
52     }
53 
TearDown()54     void TearDown() override
55     {
56         TestHelper::DestroyEcmaVMWithScope(instance, scope);
57     }
58 
59     EcmaVM *instance {nullptr};
60     ecmascript::EcmaHandleScope *scope {nullptr};
61     JSThread *thread {nullptr};
62 };
63 
HWTEST_F_L0(JSRelativeTimeFormatTest,InitializeRelativeTimeFormat)64 HWTEST_F_L0(JSRelativeTimeFormatTest, InitializeRelativeTimeFormat)
65 {
66     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
67     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
68 
69     JSHandle<JSTaggedValue> ctor = env->GetRelativeTimeFormatFunction();
70     JSHandle<JSRelativeTimeFormat> relativeTimeFormat =
71         JSHandle<JSRelativeTimeFormat>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
72     EXPECT_TRUE(*relativeTimeFormat != nullptr);
73 
74     JSHandle<JSTaggedValue> locales(factory->NewFromASCII("en"));
75     JSHandle<JSTaggedValue> undefinedOptions(thread, JSTaggedValue::Undefined());
76     JSRelativeTimeFormat::InitializeRelativeTimeFormat(thread, relativeTimeFormat, locales, undefinedOptions);
77     // Initialize attribute comparison
78     JSHandle<EcmaString> numberingSystemStr(thread, relativeTimeFormat->GetNumberingSystem().GetTaggedObject());
79     EXPECT_STREQ("latn", EcmaStringAccessor(numberingSystemStr).ToCString().c_str());
80     JSHandle<EcmaString> localeStr(thread, relativeTimeFormat->GetLocale().GetTaggedObject());
81     EXPECT_STREQ("en", EcmaStringAccessor(localeStr).ToCString().c_str());
82     EXPECT_EQ(NumericOption::ALWAYS, relativeTimeFormat->GetNumeric());
83     EXPECT_EQ(RelativeStyleOption::LONG, relativeTimeFormat->GetStyle());
84 }
85 
HWTEST_F_L0(JSRelativeTimeFormatTest,GetIcuRTFFormatter)86 HWTEST_F_L0(JSRelativeTimeFormatTest, GetIcuRTFFormatter)
87 {
88     double value = base::NAN_VALUE;
89     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
90     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
91 
92     JSHandle<JSTaggedValue> ctor = env->GetRelativeTimeFormatFunction();
93     JSHandle<JSRelativeTimeFormat> relativeTimeFormat =
94         JSHandle<JSRelativeTimeFormat>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
95     // Create Icu RelativeDateTimeFormatter
96     icu::Locale icuLocale("en", "US");
97     UErrorCode status = U_ZERO_ERROR;
98     icu::NumberFormat *icuNumberFormat = icu::NumberFormat::createInstance(icuLocale, UNUM_DECIMAL, status);
99     icu::RelativeDateTimeFormatter rtfFormatter(icuLocale, icuNumberFormat, UDAT_STYLE_LONG,
100                                                 UDISPCTX_CAPITALIZATION_NONE, status);
101     icu::UnicodeString result1 = rtfFormatter.formatNumericToValue(value, UDAT_REL_UNIT_YEAR, status).toString(status);
102     JSHandle<EcmaString> stringValue1 = intl::LocaleHelper::UStringToString(thread, result1);
103     // Set Icu RelativeDateTimeFormatter to Icu Field
104     factory->NewJSIntlIcuData(relativeTimeFormat, rtfFormatter, JSRelativeTimeFormat::FreeIcuRTFFormatter);
105     // Get Icu Field
106     icu::RelativeDateTimeFormatter *resultRelativeDateTimeFormatter = relativeTimeFormat->GetIcuRTFFormatter();
107     icu::UnicodeString result2 =
108         resultRelativeDateTimeFormatter->formatNumericToValue(value, UDAT_REL_UNIT_YEAR, status).toString(status);
109     JSHandle<EcmaString> stringValue2 = intl::LocaleHelper::UStringToString(thread, result2);
110     EXPECT_EQ(EcmaStringAccessor::StringsAreEqual(*stringValue1, *stringValue2), true);
111 }
112 
HWTEST_F_L0(JSRelativeTimeFormatTest,UnwrapRelativeTimeFormat)113 HWTEST_F_L0(JSRelativeTimeFormatTest, UnwrapRelativeTimeFormat)
114 {
115     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
116     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
117     EcmaVM *vm = thread->GetEcmaVM();
118 
119     JSHandle<JSTaggedValue> relativeTimeFormatFunc = env->GetRelativeTimeFormatFunction();
120     JSHandle<JSTaggedValue> relativeTimeFormat(
121         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(relativeTimeFormatFunc), relativeTimeFormatFunc));
122 
123     Local<FunctionRef> relativeTimeFormatLocal = JSNApiHelper::ToLocal<FunctionRef>(relativeTimeFormatFunc);
124     JSHandle<JSTaggedValue> disPlayNamesFunc = env->GetDisplayNamesFunction();
125     Local<FunctionRef> disPlayNamesLocal = JSNApiHelper::ToLocal<FunctionRef>(disPlayNamesFunc);
126     // displaynames Inherit relativeTimeFormat
127     disPlayNamesLocal->Inherit(vm, relativeTimeFormatLocal);
128     JSHandle<JSTaggedValue> disPlayNamesHandle = JSNApiHelper::ToJSHandle(disPlayNamesLocal);
129     JSHandle<JSTaggedValue> disPlayNamesObj(
130         factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(disPlayNamesHandle), disPlayNamesHandle));
131     // object has no Instance
132     JSHandle<JSTaggedValue> unwrapNumberFormat1 =
133         JSRelativeTimeFormat::UnwrapRelativeTimeFormat(thread, relativeTimeFormat);
134     EXPECT_TRUE(JSTaggedValue::SameValue(relativeTimeFormat, unwrapNumberFormat1));
135     // object has Instance
136     JSHandle<JSTaggedValue> unwrapNumberFormat2 =
137         JSRelativeTimeFormat::UnwrapRelativeTimeFormat(thread, disPlayNamesObj);
138     EXPECT_TRUE(unwrapNumberFormat2->IsUndefined());
139 }
140 } // namespace panda::test