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