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_collator.h"
17 #include "ecmascript/global_env.h"
18 #include "ecmascript/tests/test_helper.h"
19
20 using namespace panda::ecmascript;
21
22 namespace panda::test {
23 class JSCollatorTest : public testing::Test {
24 public:
SetUpTestCase()25 static void SetUpTestCase()
26 {
27 GTEST_LOG_(INFO) << "SetUpTestCase";
28 }
29
TearDownTestCase()30 static void TearDownTestCase()
31 {
32 GTEST_LOG_(INFO) << "TearDownCase";
33 }
34
SetUp()35 void SetUp() override
36 {
37 JSRuntimeOptions options;
38 #if PANDA_TARGET_LINUX
39 // for consistency requirement, use ohos_icu4j/data as icu-data-path
40 options.SetIcuDataPath(ICU_PATH);
41 #endif
42 options.SetEnableForceGC(true);
43 instance = JSNApi::CreateEcmaVM(options);
44 instance->SetEnableForceGC(true);
45 ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
46 thread = instance->GetJSThread();
47 scope = new EcmaHandleScope(thread);
48 }
49
TearDown()50 void TearDown() override
51 {
52 TestHelper::DestroyEcmaVMWithScope(instance, scope);
53 }
54
55 EcmaVM *instance {nullptr};
56 ecmascript::EcmaHandleScope *scope {nullptr};
57 JSThread *thread {nullptr};
58 };
59
60 /**
61 * @tc.name: GetIcuCollatorAndCompare
62 * @tc.desc: Call "SetIcuCollator" function set IcuCollator arrributes, then check whether the return value is
63 * expected and Call "CompareStrings" function to compare the two strings to check whether the attribute
64 * setting of ICU Collator meets the requirements.
65 * @tc.type: FUNC
66 * @tc.require:
67 */
HWTEST_F_L0(JSCollatorTest,GetIcuCollatorAndCompare)68 HWTEST_F_L0(JSCollatorTest, GetIcuCollatorAndCompare)
69 {
70 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
71 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
72 // test string
73 JSHandle<EcmaString> string1 = factory->NewFromASCII("ABC");
74 JSHandle<EcmaString> string2 = factory->NewFromASCII("abc");
75 JSHandle<EcmaString> string3 = factory->NewFromASCII("cde");
76 UErrorCode status = U_ZERO_ERROR;
77 JSHandle<JSTaggedValue> ctor = env->GetCollatorFunction();
78 JSHandle<JSCollator> collator =
79 JSHandle<JSCollator>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
80 // test Collator for US and set its strength to PRIMARY
81 icu::Collator *icuCollator = icu::Collator::createInstance("US", status);
82 EXPECT_TRUE(icuCollator != nullptr);
83 icuCollator->setStrength(icu::Collator::PRIMARY);
84 // Call "SetIcuCollator" function set icu collator
85 JSCollator::SetIcuCollator(thread, collator, icuCollator, JSCollator::FreeIcuCollator);
86 icu::Collator *icuCollator1 = collator->GetIcuCollator();
87 EXPECT_TRUE(icuCollator1 == icuCollator);
88 JSTaggedValue result = JSCollator::CompareStrings(icuCollator1, string1, string2);
89 EXPECT_EQ(result.GetInt(), 0); // equivalent
90 result = JSCollator::CompareStrings(icuCollator1, string1, string3);
91 EXPECT_EQ(result.GetInt(), -1); // less than
92 // test Collator is zh-Hans-CN locale
93 icu::Locale zhLocale("zh", "Hans", "CN");
94 icuCollator = icu::Collator::createInstance(zhLocale, status);
95 icuCollator->setStrength(icu::Collator::PRIMARY);
96 JSCollator::SetIcuCollator(thread, collator, icuCollator, JSCollator::FreeIcuCollator);
97 icu::Collator *icuCollator2 = collator->GetIcuCollator();
98 EXPECT_TRUE(icuCollator2 == icuCollator);
99 result = JSCollator::CompareStrings(icuCollator2, string1, string2);
100 EXPECT_EQ(result.GetInt(), 0); // equivalent
101 }
102
103 /**
104 * @tc.name: InitializeCollatorAndGetIcuCollator
105 * @tc.desc: Call "InitializeCollator" function initialize the attributes of Collator,then check whether the
106 * attributes is expected.
107 * @tc.type: FUNC
108 * @tc.require:
109 */
HWTEST_F_L0(JSCollatorTest,InitializeCollatorAndGetIcuCollator)110 HWTEST_F_L0(JSCollatorTest, InitializeCollatorAndGetIcuCollator)
111 {
112 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
113 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
114 JSHandle<JSTaggedValue> ctor = env->GetCollatorFunction();
115 JSHandle<JSCollator> collator =
116 JSHandle<JSCollator>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
117 JSHandle<JSTaggedValue> localeStr = thread->GlobalConstants()->GetHandledEnUsString();
118 JSHandle<JSTaggedValue> undefinedHandle(thread, JSTaggedValue::Undefined());
119
120 JSHandle<JSCollator> initCollator = JSCollator::InitializeCollator(thread, collator, localeStr, undefinedHandle);
121 EXPECT_EQ(JSTaggedValue::SameValue(collator.GetTaggedValue(), initCollator.GetTaggedValue()), true);
122 // check attributes
123 EXPECT_TRUE(initCollator->GetBoundCompare().IsUndefined());
124 EXPECT_EQ(initCollator->GetIgnorePunctuation(), false);
125 EXPECT_EQ(initCollator->GetSensitivity(), SensitivityOption::VARIANT);
126 EXPECT_EQ(initCollator->GetCaseFirst(), CaseFirstOption::UNDEFINED);
127 EXPECT_TRUE(initCollator->GetCollation().IsUndefined());
128 EXPECT_EQ(initCollator->GetUsage(), UsageOption::SORT);
129 EXPECT_TRUE(JSTaggedValue::SameValue(JSHandle<JSTaggedValue>(thread, initCollator->GetLocale()), localeStr));
130 // check icucollator
131 icu::Collator *icuCollator = initCollator->GetIcuCollator();
132 EXPECT_EQ(icuCollator->getStrength(), icu::Collator::TERTIARY);
133 }
134 } // namespace panda::test