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