1/*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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/builtins/builtins_segmenter.h"
17#include "ecmascript/builtins/builtins_segments.h"
18#include "ecmascript/builtins/builtins_segment_iterator.h"
19
20#include "ecmascript/global_env.h"
21#include "ecmascript/js_segmenter.h"
22#include "ecmascript/tests/test_helper.h"
23
24using namespace panda::ecmascript;
25using namespace panda::ecmascript::builtins;
26namespace panda::test {
27class BuiltinsSegmenterTest : public BaseTestWithScope<true> {
28};
29
30static JSTaggedValue JSSegmenterCreateWithLocaleTest(JSThread *thread, JSHandle<JSTaggedValue> &locale)
31{
32    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
33    JSHandle<JSFunction> newTarget(env->GetSegmenterFunction());
34
35    auto ecmaRuntimeCallInfo =
36        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 6); // 6 means 1 call args
37    ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
38    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
39    ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
40
41    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
42    JSTaggedValue result = BuiltinsSegmenter::SegmenterConstructor(ecmaRuntimeCallInfo);
43    EXPECT_TRUE(result.IsJSSegmenter());
44    TestHelper::TearDownFrame(thread, prev);
45    return result;
46}
47
48static JSTaggedValue JSSegmenterCreateWithLocaleAndOptionsTest(JSThread *thread, JSHandle<JSTaggedValue> &locale,
49                                                               JSHandle<JSTaggedValue> &granularity)
50{
51    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
52    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
53    JSHandle<JSFunction> newTarget(env->GetSegmenterFunction());
54    JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
55
56    JSHandle<JSTaggedValue> granularityKey = thread->GlobalConstants()->GetHandledGranularityString();
57    JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
58    JSObject::SetProperty(thread, optionsObj, granularityKey, granularity);
59
60    auto ecmaRuntimeCallInfo =
61        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8); // 8 means 2 call args
62    ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
63    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
64    ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
65    ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
66
67    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
68    JSTaggedValue result = BuiltinsSegmenter::SegmenterConstructor(ecmaRuntimeCallInfo);
69    EXPECT_TRUE(result.IsJSSegmenter());
70    TestHelper::TearDownFrame(thread, prev);
71    return result;
72}
73
74static JSTaggedValue JSSegmentsCreateTest(JSThread *thread, JSHandle<JSTaggedValue> &locale,
75                                          JSHandle<JSTaggedValue> &granularity, JSHandle<JSTaggedValue> &stringValue)
76{
77    JSHandle<JSSegmenter> jsSegmenter =
78        JSHandle<JSSegmenter>(thread, JSSegmenterCreateWithLocaleAndOptionsTest(thread, locale, granularity));
79    auto ecmaRuntimeCallInfo =
80        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);  // 6 means 1 call args
81    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
82    ecmaRuntimeCallInfo->SetThis(jsSegmenter.GetTaggedValue());
83    ecmaRuntimeCallInfo->SetCallArg(0, stringValue.GetTaggedValue());
84
85    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
86    JSTaggedValue segments = BuiltinsSegmenter::Segment(ecmaRuntimeCallInfo);
87    EXPECT_TRUE(segments.IsJSSegments());
88    TestHelper::TearDownFrame(thread, prev);
89    return segments;
90}
91
92// new  Intl.Segmenter ( [ locales [ , options ] ] )
93HWTEST_F_L0(BuiltinsSegmenterTest, SegmenterConstructor)
94{
95    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
96    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
97    JSHandle<JSFunction> newTarget(env->GetSegmenterFunction());
98
99    JSHandle<JSTaggedValue> localesString(factory->NewFromASCII("en-US"));
100    auto ecmaRuntimeCallInfo =
101        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 6); // 6 means 1 call args
102    ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
103    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
104    ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
105
106    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
107    JSTaggedValue result = BuiltinsSegmenter::SegmenterConstructor(ecmaRuntimeCallInfo);
108    TestHelper::TearDownFrame(thread, prev);
109
110    EXPECT_TRUE(result.IsJSSegmenter());
111}
112
113// Intl.Segmenter.prototype.segment ( string )
114HWTEST_F_L0(BuiltinsSegmenterTest, segment)
115{
116    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
117    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("zh-cn"));
118    JSHandle<JSTaggedValue> granularity(factory->NewFromASCII("word"));
119    JSHandle<JSTaggedValue> stringValue(factory->NewFromUtf8("这句话是中文"));
120    JSHandle<JSSegmenter> jsSegmenter =
121        JSHandle<JSSegmenter>(thread, JSSegmenterCreateWithLocaleAndOptionsTest(thread, locale, granularity));
122    auto ecmaRuntimeCallInfo =
123        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);  // 6 means 1 call args
124    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
125    ecmaRuntimeCallInfo->SetThis(jsSegmenter.GetTaggedValue());
126    ecmaRuntimeCallInfo->SetCallArg(0, stringValue.GetTaggedValue());
127
128    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
129    JSTaggedValue result = BuiltinsSegmenter::Segment(ecmaRuntimeCallInfo);
130    TestHelper::TearDownFrame(thread, prev);
131    EXPECT_TRUE(result.IsJSSegments());
132}
133
134// SupportedLocalesOf("lookup")
135HWTEST_F_L0(BuiltinsSegmenterTest, SupportedLocalesOf)
136{
137    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
138    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
139    JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
140
141    JSHandle<JSTaggedValue> localeMatcherKey = thread->GlobalConstants()->GetHandledLocaleMatcherString();
142    JSHandle<JSTaggedValue> localeMatcherValue(factory->NewFromASCII("lookup"));
143    JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
144    JSObject::SetProperty(thread, optionsObj, localeMatcherKey, localeMatcherValue);
145    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("id-u-co-pinyin-de-ID"));
146
147    auto ecmaRuntimeCallInfo =
148        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means 2 call args
149    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
150    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
151    ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
152    ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
153
154    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
155    JSTaggedValue resultArr = BuiltinsSegmenter::SupportedLocalesOf(ecmaRuntimeCallInfo);
156    TestHelper::TearDownFrame(thread, prev);
157
158    JSHandle<JSArray> resultHandle(thread, resultArr);
159    JSHandle<TaggedArray> elements(thread, resultHandle->GetElements());
160    EXPECT_EQ(elements->GetLength(), 1U);
161    JSHandle<EcmaString> handleEcmaStr(thread, elements->Get(0));
162    EXPECT_STREQ("id-u-co-pinyin-de-id", EcmaStringAccessor(handleEcmaStr).ToCString().c_str());
163}
164
165// Intl.Segmenter.prototype.resolvedOptions
166HWTEST_F_L0(BuiltinsSegmenterTest, ResolvedOptions)
167{
168    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
169    auto globalConst = thread->GlobalConstants();
170    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-DE"));
171    JSHandle<JSSegmenter> jsSegmenter =
172        JSHandle<JSSegmenter>(thread, JSSegmenterCreateWithLocaleTest(thread, locale));
173    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
174    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
175    ecmaRuntimeCallInfo->SetThis(jsSegmenter.GetTaggedValue());
176
177    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
178    JSTaggedValue result = BuiltinsSegmenter::ResolvedOptions(ecmaRuntimeCallInfo);
179    TestHelper::TearDownFrame(thread, prev);
180
181    JSHandle<JSTaggedValue> resultObj =
182        JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<JSTaggedType>(result.GetRawData())));
183    // judge whether the properties of the object are the same as those of jsdatetimeformat tag
184    JSHandle<JSTaggedValue> localeKey = globalConst->GetHandledLocaleString();
185    EXPECT_EQ(JSTaggedValue::SameValue(
186        JSObject::GetProperty(thread, resultObj, localeKey).GetValue(), locale), true);
187    JSHandle<JSTaggedValue> granularityKey = globalConst->GetHandledGranularityString();
188    JSHandle<JSTaggedValue> defaultGranularityValue(factory->NewFromASCII("grapheme"));
189    EXPECT_EQ(JSTaggedValue::SameValue(
190        JSObject::GetProperty(thread, resultObj, granularityKey).GetValue(), defaultGranularityValue), true);
191}
192
193void SegmentsPrototypeCommon(JSThread *thread, JSHandle<JSTaggedValue> &result,
194                             std::vector<JSHandle<JSTaggedValue>> &values)
195{
196    auto globalConst = thread->GlobalConstants();
197    JSHandle<JSTaggedValue> segmentKey = globalConst->GetHandledSegmentString();
198    JSHandle<JSTaggedValue> indexKey = globalConst->GetHandledIndexString();
199    JSHandle<JSTaggedValue> inputKey = globalConst->GetHandledInputString();
200    JSHandle<JSTaggedValue> isWordLikeKey = globalConst->GetHandledIsWordLikeString();
201    JSHandle<JSTaggedValue> segmentValue(JSObject::GetProperty(thread, result, segmentKey).GetValue());
202    JSHandle<JSTaggedValue> indexValue(JSObject::GetProperty(thread, result, indexKey).GetValue());
203    JSHandle<JSTaggedValue> inputValue(JSObject::GetProperty(thread, result, inputKey).GetValue());
204    JSHandle<JSTaggedValue> isWordLikeValue(JSObject::GetProperty(thread, result, isWordLikeKey).GetValue());
205    values.push_back(segmentValue);
206    values.push_back(indexValue);
207    values.push_back(inputValue);
208    values.push_back(isWordLikeValue);
209}
210
211// %SegmentsPrototype%.containing ( index )
212HWTEST_F_L0(BuiltinsSegmenterTest, SegmentsPrototypeContaining_001)
213{
214    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
215    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("zh-cn"));
216    JSHandle<JSTaggedValue> granularity(factory->NewFromASCII("sentence"));
217    JSHandle<JSTaggedValue> stringValue(factory->NewFromUtf8("这句话是中文。这句还是中文!"));
218    JSHandle<JSTaggedValue> segments(thread, JSSegmentsCreateTest(thread, locale, granularity, stringValue));
219
220    std::vector<JSTaggedValue> args{ JSTaggedValue(static_cast<double>(3))};
221    auto ecmaRuntimeCallInfo =
222        TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6, segments.GetTaggedValue());  // 6 means 1 call args
223
224    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
225    JSHandle<JSTaggedValue> result(thread, BuiltinsSegments::Containing(ecmaRuntimeCallInfo));
226    TestHelper::TearDownFrame(thread, prev);
227    EXPECT_TRUE(result->IsJSObject());
228    std::vector<JSHandle<JSTaggedValue>> outValues;
229    SegmentsPrototypeCommon(thread, result, outValues);
230
231    EXPECT_STREQ(EcmaStringAccessor(JSHandle<EcmaString>::Cast(outValues[0])).ToCString().c_str(),
232                 "这句话是中文。");
233    EXPECT_EQ(outValues[1]->GetRawData(), JSTaggedValue(0).GetRawData());   // 1:index value
234    EXPECT_STREQ(EcmaStringAccessor(JSHandle<EcmaString>::Cast(outValues[2])).ToCString().c_str(), // 2: input value
235                 "这句话是中文。这句还是中文!");
236    EXPECT_TRUE(outValues[3]->IsUndefined()); // 2: word link value
237}
238
239HWTEST_F_L0(BuiltinsSegmenterTest, SegmentsPrototypeContaining_002)
240{
241    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
242    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("fr"));
243    JSHandle<JSTaggedValue> granularity(factory->NewFromASCII("word"));
244    JSHandle<JSTaggedValue> stringValue(factory->NewFromUtf8("Que ma joie demeure"));
245    JSHandle<JSTaggedValue> segments(thread, JSSegmentsCreateTest(thread, locale, granularity, stringValue));
246
247    std::vector<JSTaggedValue> args{ JSTaggedValue(static_cast<double>(10))};
248    auto ecmaRuntimeCallInfo =
249        TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6, segments.GetTaggedValue());  // 6 means 1 call args
250
251    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
252    JSHandle<JSTaggedValue> result(thread, BuiltinsSegments::Containing(ecmaRuntimeCallInfo));
253    TestHelper::TearDownFrame(thread, prev);
254    EXPECT_TRUE(result->IsJSObject());
255
256    std::vector<JSHandle<JSTaggedValue>> outValues;
257    SegmentsPrototypeCommon(thread, result, outValues);
258    EXPECT_STREQ(EcmaStringAccessor(JSHandle<EcmaString>::Cast(outValues[0])).ToCString().c_str(),
259                 "joie");
260    EXPECT_EQ(outValues[1]->GetRawData(), JSTaggedValue(7).GetRawData());
261    EXPECT_STREQ(EcmaStringAccessor(JSHandle<EcmaString>::Cast(outValues[2])).ToCString().c_str(),
262                 "Que ma joie demeure");
263    EXPECT_EQ(outValues[3]->GetRawData(), JSTaggedValue::True().GetRawData());
264}
265
266HWTEST_F_L0(BuiltinsSegmenterTest, SegmentsPrototypeContaining_003)
267{
268    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
269    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("fr"));
270    JSHandle<JSTaggedValue> granularity(factory->NewFromASCII("word"));
271    JSHandle<JSTaggedValue> stringValue(factory->NewFromUtf8("Que ma joie demeure"));
272    JSHandle<JSTaggedValue> segments(thread, JSSegmentsCreateTest(thread, locale, granularity, stringValue));
273
274    std::vector<JSTaggedValue> args{ JSTaggedValue(static_cast<double>(-10))};
275    auto ecmaRuntimeCallInfo =
276        TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6, segments.GetTaggedValue());  // 6 means 1 call args
277
278    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
279    JSHandle<JSTaggedValue> result(thread, BuiltinsSegments::Containing(ecmaRuntimeCallInfo));
280    TestHelper::TearDownFrame(thread, prev);
281    EXPECT_TRUE(result->IsUndefined());
282}
283
284// %SegmentsPrototype% [ @@iterator ] ( )
285HWTEST_F_L0(BuiltinsSegmenterTest, GetSegmentIterator)
286{
287    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
288    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("fr"));
289    JSHandle<JSTaggedValue> granularity(factory->NewFromASCII("word"));
290    JSHandle<JSTaggedValue> stringValue(factory->NewFromUtf8("Que ma joie demeure"));
291    JSHandle<JSTaggedValue> segments(thread, JSSegmentsCreateTest(thread, locale, granularity, stringValue));
292
293    auto ecmaRuntimeCallInfo =
294        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);  // 4 means 0 call args
295    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
296    ecmaRuntimeCallInfo->SetThis(segments.GetTaggedValue());
297
298    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
299    JSTaggedValue result = BuiltinsSegments::GetSegmentIterator(ecmaRuntimeCallInfo);
300    TestHelper::TearDownFrame(thread, prev);
301    EXPECT_TRUE(result.IsJSSegmentIterator());
302}
303
304// %SegmentIteratorPrototype%.next ( )
305HWTEST_F_L0(BuiltinsSegmenterTest, SegmentIteratorNext)
306{
307    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
308    JSHandle<JSTaggedValue> locale(factory->NewFromASCII("fr"));
309    JSHandle<JSTaggedValue> granularity(factory->NewFromASCII("sentence"));
310    JSHandle<JSTaggedValue> stringValue(factory->NewFromUtf8("Que ma joie demeure."));
311    JSHandle<JSTaggedValue> segments(thread, JSSegmentsCreateTest(thread, locale, granularity, stringValue));
312
313    auto ecmaRuntimeCallInfo =
314        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);  // 4 means 0 call args
315    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
316    ecmaRuntimeCallInfo->SetThis(segments.GetTaggedValue());
317
318    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
319    JSHandle<JSTaggedValue> iterator(thread, BuiltinsSegments::GetSegmentIterator(ecmaRuntimeCallInfo));
320    TestHelper::TearDownFrame(thread, prev);
321    EXPECT_TRUE(iterator->IsJSSegmentIterator());
322
323    auto ecmaRuntimeCallInfo1 =
324        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);  // 4 means 0 call args
325    ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
326    ecmaRuntimeCallInfo1->SetThis(iterator.GetTaggedValue());
327
328    [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
329    JSHandle<JSTaggedValue> result1(thread, BuiltinsSegmentIterator::Next(ecmaRuntimeCallInfo1));
330    TestHelper::TearDownFrame(thread, prev1);
331    EXPECT_TRUE(result1->IsJSObject());
332    auto globalConst = thread->GlobalConstants();
333    JSHandle<JSTaggedValue> valueKey = globalConst->GetHandledValueString();
334    JSHandle<JSTaggedValue> doneKey = globalConst->GetHandledDoneString();
335    JSHandle<JSTaggedValue> value1(JSObject::GetProperty(thread, result1, valueKey).GetValue());
336    JSHandle<JSTaggedValue> done1(JSObject::GetProperty(thread, result1, doneKey).GetValue());
337    EXPECT_TRUE(value1->IsJSObject());
338    JSHandle<JSTaggedValue> segmentKey = globalConst->GetHandledSegmentString();
339    JSHandle<JSTaggedValue> segmentValue(JSObject::GetProperty(thread, value1, segmentKey).GetValue());
340    EXPECT_STREQ(EcmaStringAccessor(JSHandle<EcmaString>::Cast(segmentValue)).ToCString().c_str(),
341                 "Que ma joie demeure.");
342    EXPECT_FALSE(done1->ToBoolean());
343
344    auto ecmaRuntimeCallInfo2 =
345        TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);  // 4 means 0 call args
346    ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
347    ecmaRuntimeCallInfo2->SetThis(iterator.GetTaggedValue());
348
349    [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
350    JSHandle<JSTaggedValue> result2(thread, BuiltinsSegmentIterator::Next(ecmaRuntimeCallInfo2));
351    TestHelper::TearDownFrame(thread, prev2);
352    EXPECT_TRUE(result2->IsJSObject());
353    JSHandle<JSTaggedValue> value2(JSObject::GetProperty(thread, result2, valueKey).GetValue());
354    JSHandle<JSTaggedValue> done2(JSObject::GetProperty(thread, result2, doneKey).GetValue());
355    EXPECT_TRUE(value2->IsUndefined());
356    EXPECT_TRUE(done2->ToBoolean());
357}
358}
359