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 "builtin_test_util.h"
17 #include "ecmascript/builtins/builtins_list_format.h"
18
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_list_format.h"
21 #include "ecmascript/js_array.h"
22 #include "ecmascript/tests/test_helper.h"
23
24 using namespace panda::ecmascript;
25 using namespace panda::ecmascript::builtins;
26
27 namespace panda::test {
28 class BuiltinsListFormatTest : public BaseTestWithScope<true> {
29 };
30
CommonTest(JSThread * thread,JSHandle<JSTaggedValue> & locale,JSHandle<JSTaggedValue> & typeValue,std::vector<std::string> & strValues)31 JSTaggedValue CommonTest(JSThread* thread, JSHandle<JSTaggedValue>& locale, JSHandle<JSTaggedValue>& typeValue,
32 std::vector<std::string>& strValues)
33 {
34 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
35 JSHandle<JSListFormat> jsListFormat =
36 JSHandle<JSListFormat>(thread, BuiltTestUtil::JSListFormatCreateWithOptionTest(thread, locale, typeValue));
37 JSArray *arr = JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetObject<JSArray>();
38 EXPECT_TRUE(arr != nullptr);
39 JSHandle<JSObject> value(thread, arr);
40 std::vector<JSHandle<JSTaggedValue>> vals;
41 for (size_t i = 0; i < strValues.size(); i++) {
42 JSHandle<JSTaggedValue> listValue(factory->NewFromStdString(strValues[i]));
43 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(static_cast<int>(i)));
44 PropertyDescriptor desc(thread, listValue, true, true, true);
45 JSArray::DefineOwnProperty(thread, value, key, desc);
46 }
47
48 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
49 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
50 ecmaRuntimeCallInfo->SetThis(jsListFormat.GetTaggedValue());
51 ecmaRuntimeCallInfo->SetCallArg(0, value.GetTaggedValue());
52
53 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
54 JSTaggedValue result = BuiltinsListFormat::FormatToParts(ecmaRuntimeCallInfo);
55 TestHelper::TearDownFrame(thread, prev);
56 return result;
57 }
58
HWTEST_F_L0(BuiltinsListFormatTest,FormatToParts_001)59 HWTEST_F_L0(BuiltinsListFormatTest, FormatToParts_001)
60 {
61 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
62 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-DE"));
63 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("conjunction"));
64 JSHandle<JSListFormat> jSListFormat =
65 JSHandle<JSListFormat>(thread, BuiltTestUtil::JSListFormatCreateWithOptionTest(thread, locale, typeValue));
66 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
67 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
68 ecmaRuntimeCallInfo->SetThis(jSListFormat.GetTaggedValue());
69 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
70
71 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
72 JSTaggedValue result = BuiltinsListFormat::FormatToParts(ecmaRuntimeCallInfo);
73 TestHelper::TearDownFrame(thread, prev);
74
75 JSHandle<JSArray> resultHandle(thread, result);
76 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
77 EXPECT_EQ(elements->GetLength(), 0U); // zero formatters
78 }
79
80 // FormatToParts(["Apple", "Orange", "Pineapple" ], type(conjunction))
HWTEST_F_L0(BuiltinsListFormatTest,FormatToParts_002)81 HWTEST_F_L0(BuiltinsListFormatTest, FormatToParts_002)
82 {
83 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
84 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-GB"));
85 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("conjunction")); // the default value
86
87 std::vector<std::string> vals{"Apple", "Orange", "Pineapple"};
88 JSTaggedValue result = CommonTest(thread, locale, typeValue, vals);
89
90 JSHandle<JSArray> resultHandle(thread, result);
91 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
92 EXPECT_EQ(elements->GetLength(), 6U);
93 }
94
HWTEST_F_L0(BuiltinsListFormatTest,FormatToParts_003)95 HWTEST_F_L0(BuiltinsListFormatTest, FormatToParts_003)
96 {
97 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
98 JSHandle<JSTaggedValue> lengthKey = thread->GlobalConstants()->GetHandledLengthString();
99 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("en-GB"));
100 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("conjunction")); // the default value
101
102 std::vector<std::string> vals{"Apple", "Orange", "Pineapple"};
103 JSTaggedValue result = CommonTest(thread, locale, typeValue, vals);
104
105 JSTaggedValue valueList(static_cast<JSTaggedType>(result.GetRawData()));
106
107 ASSERT_TRUE(valueList.IsECMAObject());
108 JSHandle<JSObject> valueHandle(thread, valueList);
109 EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKey).GetValue()->GetInt(), 5);
110 }
111
112 // FormatToParts(["中文", "英文"], type(conjunction))
HWTEST_F_L0(BuiltinsListFormatTest,FormatToParts_004)113 HWTEST_F_L0(BuiltinsListFormatTest, FormatToParts_004)
114 {
115 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
116 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("zh-cn"));
117 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("conjunction"));
118
119 std::vector<std::string> vals{"中文", "英文"};
120 JSTaggedValue result = CommonTest(thread, locale, typeValue, vals);
121
122 JSHandle<JSArray> resultHandle(thread, result);
123 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
124 EXPECT_EQ(elements->GetLength(), 3U);
125 }
126
127 // FormatToParts(["中文", "英文","韩文","葡萄牙语"], type(disjunction))
HWTEST_F_L0(BuiltinsListFormatTest,FormatToParts_005)128 HWTEST_F_L0(BuiltinsListFormatTest, FormatToParts_005)
129 {
130 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
131 JSHandle<JSTaggedValue> lengthKey = thread->GlobalConstants()->GetHandledLengthString();
132 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("zh-cn"));
133 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("disjunction"));
134
135 std::vector<std::string> vals{"中文", "英文", "韩文", "葡萄牙语"};
136 JSTaggedValue result = CommonTest(thread, locale, typeValue, vals);
137 JSTaggedValue valueList(static_cast<JSTaggedType>(result.GetRawData()));
138
139 ASSERT_TRUE(valueList.IsECMAObject());
140 JSHandle<JSObject> valueHandle(thread, valueList);
141 EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(valueHandle), lengthKey).GetValue()->GetInt(), 7);
142 }
143
144 // SupportedLocalesOf("best fit")
HWTEST_F_L0(BuiltinsListFormatTest,SupportedLocalesOf_001)145 HWTEST_F_L0(BuiltinsListFormatTest, SupportedLocalesOf_001)
146 {
147 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
148 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-ID"));
149
150 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
151 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
152 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
153 ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
154 // set the tag is default value
155 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
156
157 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
158 JSTaggedValue resultArr = BuiltinsListFormat::SupportedLocalesOf(ecmaRuntimeCallInfo);
159 TestHelper::TearDownFrame(thread, prev);
160
161 JSHandle<JSArray> resultHandle(thread, resultArr);
162 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
163 EXPECT_EQ(elements->GetLength(), 1U);
164 JSHandle<EcmaString> handleEcmaStr(thread, elements->Get(0));
165 EXPECT_STREQ("id-u-co-pinyin-de-id", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
166 }
167
168 // SupportedLocalesOf("look up")
HWTEST_F_L0(BuiltinsListFormatTest,SupportedLocalesOf_002)169 HWTEST_F_L0(BuiltinsListFormatTest, SupportedLocalesOf_002)
170 {
171 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
172 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
173
174 JSHandle<JSTaggedValue> localeMatcherKey = thread->GlobalConstants()->GetHandledLocaleMatcherString();
175 JSHandle<JSTaggedValue> localeMatcherValue(factory->NewFromASCII("lookup"));
176 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-DE"));
177
178 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
179 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
180 JSObject::SetProperty(thread, optionsObj, localeMatcherKey, localeMatcherValue);
181
182 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
183 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
184 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
185 ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
186 ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
187
188 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
189 JSTaggedValue resultArr = BuiltinsListFormat::SupportedLocalesOf(ecmaRuntimeCallInfo);
190 TestHelper::TearDownFrame(thread, prev);
191
192 JSHandle<JSArray> resultHandle(thread, resultArr);
193 JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
194 EXPECT_EQ(elements->GetLength(), 1U);
195
196 JSHandle<EcmaString> resultStr(thread, elements->Get(0));
197 EXPECT_STREQ("id-u-co-pinyin-de", EcmaStringAccessor(resultStr).ToCString().c_str());
198 }
199
HWTEST_F_L0(BuiltinsListFormatTest,ResolvedOptions)200 HWTEST_F_L0(BuiltinsListFormatTest, ResolvedOptions)
201 {
202 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
203 auto globalConst = thread->GlobalConstants();
204 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-DE"));
205 JSHandle<JSTaggedValue> typeValue(factory->NewFromASCII("disjunction"));
206 JSHandle<JSListFormat> jSListFormat =
207 JSHandle<JSListFormat>(thread, BuiltTestUtil::JSListFormatCreateWithOptionTest(thread, locale, typeValue));
208
209 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
210 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
211 ecmaRuntimeCallInfo->SetThis(jSListFormat.GetTaggedValue());
212
213 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
214 JSTaggedValue result = BuiltinsListFormat::ResolvedOptions(ecmaRuntimeCallInfo);
215 TestHelper::TearDownFrame(thread, prev);
216
217 JSHandle<JSTaggedValue> resultObj =
218 JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result.GetRawData())));
219 // judge whether the properties of the object are the same as those of jslistformat tag
220 JSHandle<JSTaggedValue> localeKey = globalConst->GetHandledLocaleString();
221 JSHandle<JSTaggedValue> localeValue(factory->NewFromASCII("de-DE"));
222 EXPECT_EQ(JSTaggedValue::SameValue(
223 JSObject::GetProperty(thread, resultObj, localeKey).GetValue(), localeValue), true);
224 JSHandle<JSTaggedValue> typeKey = globalConst->GetHandledTypeString();
225 EXPECT_EQ(JSTaggedValue::SameValue(
226 JSObject::GetProperty(thread, resultObj, typeKey).GetValue(), typeValue), true);
227 }
228 } // namespace panda::test