this repo has no description
at trunk 1948 lines 66 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include <cstdint> 3 4#include "gtest/gtest.h" 5 6#include "byteslike.h" 7#include "runtime.h" 8#include "str-builtins.h" 9#include "test-utils.h" 10 11namespace py { 12namespace testing { 13 14using BytearrayTest = RuntimeFixture; 15using LargeBytesTest = RuntimeFixture; 16using SmallBytesTest = RuntimeFixture; 17using CodeTest = RuntimeFixture; 18using ComplexTest = RuntimeFixture; 19using DequeTest = RuntimeFixture; 20using DoubleTest = RuntimeFixture; 21using IntTest = RuntimeFixture; 22using LargeStrTest = RuntimeFixture; 23using ListTest = RuntimeFixture; 24using MmapTest = RuntimeFixture; 25using ModulesTest = RuntimeFixture; 26using MutableBytesTest = RuntimeFixture; 27using MutableTupleTest = RuntimeFixture; 28using SliceTest = RuntimeFixture; 29using SmallStrTest = RuntimeFixture; 30using StrArrayTest = RuntimeFixture; 31using StrTest = RuntimeFixture; 32using StringTest = RuntimeFixture; 33using ValueCellTest = RuntimeFixture; 34using WeakRefTest = RuntimeFixture; 35 36TEST_F(BytearrayTest, DownsizeMaintainsCapacity) { 37 HandleScope scope(thread_); 38 Bytearray array(&scope, runtime_->newBytearray()); 39 const byte byte_array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; 40 runtime_->bytearrayExtend(thread_, array, byte_array); 41 ASSERT_EQ(array.numItems(), 9); 42 word capacity = array.capacity(); 43 array.downsize(5); 44 EXPECT_EQ(array.numItems(), 5); 45 EXPECT_EQ(array.capacity(), capacity); 46} 47 48TEST_F(DequeTest, DequeClearRemovesElements) { 49 HandleScope scope(thread_); 50 Deque self(&scope, runtime_->newDeque()); 51 MutableTuple underlying_tuple(&scope, runtime_->newMutableTuple(5)); 52 underlying_tuple.atPut(0, SmallInt::fromWord(0)); 53 underlying_tuple.atPut(1, SmallInt::fromWord(1)); 54 underlying_tuple.atPut(2, SmallInt::fromWord(2)); 55 56 self.setItems(*underlying_tuple); 57 self.setNumItems(3); 58 self.clear(); 59 ASSERT_EQ(self.numItems(), 0); 60 ASSERT_EQ(self.left(), 0); 61 EXPECT_EQ(self.at(0), NoneType::object()); 62 EXPECT_EQ(self.at(1), NoneType::object()); 63 EXPECT_EQ(self.at(2), NoneType::object()); 64} 65 66TEST_F(SmallBytesTest, CopyToStartAtCopiesToDestinationStartingAtIndex) { 67 byte src_bytes[] = "hello"; 68 HandleScope scope(thread_); 69 Bytes src(&scope, runtime_->newBytesWithAll(src_bytes)); 70 byte result[5] = {0}; 71 src.copyToStartAt(result, 4, 1); 72 EXPECT_STREQ(reinterpret_cast<char*>(result), "ello"); 73} 74 75TEST_F(SmallBytesTest, FindByteWithZeroLengthReturnsNegativeOne) { 76 byte src_bytes[] = "hello"; 77 HandleScope scope(thread_); 78 SmallBytes bytes(&scope, runtime_->newBytesWithAll(src_bytes)); 79 EXPECT_EQ(bytes.findByte('h', 0, 0), -1); 80} 81 82TEST_F(SmallBytesTest, FindByteWithEndBeforeByteReturnsNegativeOne) { 83 byte src_bytes[] = "hello"; 84 HandleScope scope(thread_); 85 SmallBytes bytes(&scope, runtime_->newBytesWithAll(src_bytes)); 86 EXPECT_EQ(bytes.findByte('o', 1, 2), -1); 87} 88 89TEST_F(SmallBytesTest, FindByteWithByteNotInBytesReturnsNegativeOne) { 90 byte src_bytes[] = "hello"; 91 HandleScope scope(thread_); 92 SmallBytes bytes(&scope, runtime_->newBytesWithAll(src_bytes)); 93 EXPECT_EQ(bytes.findByte('x', 0, bytes.length()), -1); 94} 95 96TEST_F(SmallBytesTest, FindByteWithByteInBytesReturnsIndex) { 97 byte src_bytes[] = "hello"; 98 HandleScope scope(thread_); 99 SmallBytes bytes(&scope, runtime_->newBytesWithAll(src_bytes)); 100 EXPECT_EQ(bytes.findByte('o', 0, bytes.length()), 4); 101} 102 103TEST_F(LargeBytesTest, FindByteWithZerolengthReturnsNegativeOne) { 104 byte src_bytes[] = "hello world this is patrick"; 105 HandleScope scope(thread_); 106 LargeBytes bytes(&scope, runtime_->newBytesWithAll(src_bytes)); 107 EXPECT_EQ(bytes.findByte('h', 0, 0), -1); 108} 109 110TEST_F(LargeBytesTest, FindByteWithEndBeforeByteReturnsNegativeOne) { 111 byte src_bytes[] = "hello world"; 112 HandleScope scope(thread_); 113 LargeBytes bytes(&scope, runtime_->newBytesWithAll(src_bytes)); 114 EXPECT_EQ(bytes.findByte('d', 3, 5), -1); 115} 116 117TEST_F(LargeBytesTest, FindByteWithByteNotInBytesReturnsNegativeOne) { 118 byte src_bytes[] = "hello world"; 119 HandleScope scope(thread_); 120 LargeBytes bytes(&scope, runtime_->newBytesWithAll(src_bytes)); 121 EXPECT_EQ(bytes.findByte('x', 0, bytes.length()), -1); 122} 123 124TEST_F(LargeBytesTest, FindByteWithByteInBytesReturnsIndex) { 125 byte src_bytes[] = "hello world"; 126 HandleScope scope(thread_); 127 LargeBytes bytes(&scope, runtime_->newBytesWithAll(src_bytes)); 128 EXPECT_EQ(bytes.findByte('o', 0, bytes.length()), 4); 129} 130 131TEST_F(LargeBytesTest, FindByteNonZeroStartReturnsIndex) { 132 byte src_bytes[] = "hello world"; 133 HandleScope scope(thread_); 134 LargeBytes bytes(&scope, runtime_->newBytesWithAll(src_bytes)); 135 EXPECT_EQ(bytes.findByte('o', 5, bytes.length() - 5), 7); 136} 137 138TEST_F(LargeBytesTest, CopyToStartAtCopiesToDestinationStartingAtIndex) { 139 byte src_bytes[] = "hello world this is patrick"; 140 HandleScope scope(thread_); 141 LargeBytes src(&scope, runtime_->newBytesWithAll(src_bytes)); 142 byte result[8] = {0}; 143 src.copyToStartAt(result, 7, 20); 144 EXPECT_STREQ(reinterpret_cast<char*>(result), "patrick"); 145} 146 147TEST_F(MutableBytesTest, 148 IndexOfAnyWithDifferentStartReturnsFirstMatchIndexAfterStart) { 149 HandleScope scope(thread_); 150 151 const byte src_bytes[] = {'h', 'e', 'l', 'l', 'o', ' ', 152 'w', 'o', 'r', 'l', 'd'}; 153 word src_length = ARRAYSIZE(src_bytes); 154 MutableBytes src(&scope, runtime_->newMutableBytesUninitialized(src_length)); 155 for (word i = 0; i < src_length; i++) { 156 src.byteAtPut(i, src_bytes[i]); 157 } 158 const byte needle[] = "eor"; 159 EXPECT_EQ(src.indexOfAny(needle, 0), 1); 160 EXPECT_EQ(src.indexOfAny(needle, 2), 4); 161 EXPECT_EQ(src.indexOfAny(needle, 5), 7); 162} 163 164TEST_F(MutableBytesTest, IndexOfAnyWithNeedleNoMatchReturnsHaystackLength) { 165 HandleScope scope(thread_); 166 167 const byte src_bytes[] = {'h', 'e', 'l', 'l', 'o', ' ', 168 'w', 'o', 'r', 'l', 'd'}; 169 word src_length = ARRAYSIZE(src_bytes); 170 MutableBytes src(&scope, runtime_->newMutableBytesUninitialized(src_length)); 171 for (word i = 0; i < src_length; i++) { 172 src.byteAtPut(i, src_bytes[i]); 173 } 174 const byte needle[] = "abc"; 175 EXPECT_EQ(src.indexOfAny(needle, 0), src_length); 176 EXPECT_EQ(src.indexOfAny(needle, 5), src_length); 177 EXPECT_EQ(src.indexOfAny(needle, 9), src_length); 178} 179 180TEST_F(MutableBytesTest, ReplaceFromWithByteslikeReplacesBytes) { 181 HandleScope scope(thread_); 182 const byte bytes[] = "hello world"; 183 Object value(&scope, runtime_->newBytesWithAll(bytes)); 184 Byteslike byteslike(&scope, thread_, *value); 185 ASSERT_TRUE(byteslike.isValid()); 186 MutableBytes mutable_bytes(&scope, 187 runtime_->newMutableBytesUninitialized(11)); 188 mutable_bytes.replaceFromWithByteslike(0, byteslike, 5); 189 mutable_bytes.replaceFromWithByteslike(5, byteslike, 2); 190 mutable_bytes.replaceFromWithByteslike(11, byteslike, 0); 191 mutable_bytes.replaceFromWithByteslike(7, byteslike, 3); 192 mutable_bytes.byteAtPut(10, '\0'); 193 const byte expected[] = "hellohehel"; 194 EXPECT_TRUE(isMutableBytesEqualsBytes(mutable_bytes, expected)); 195} 196 197TEST_F(MutableBytesTest, ReplaceFromWithByteslikeStartAtReplacesBytes) { 198 HandleScope scope(thread_); 199 const byte bytes[] = "hello world"; 200 Object value(&scope, runtime_->newBytesWithAll(bytes)); 201 Byteslike byteslike(&scope, thread_, *value); 202 ASSERT_TRUE(byteslike.isValid()); 203 MutableBytes mutable_bytes(&scope, 204 runtime_->newMutableBytesUninitialized(10)); 205 mutable_bytes.replaceFromWithByteslikeStartAt(0, byteslike, 5, 0); 206 mutable_bytes.replaceFromWithByteslikeStartAt(2, byteslike, 4, 1); 207 mutable_bytes.replaceFromWithByteslikeStartAt(6, byteslike, 4, 8); 208 mutable_bytes.replaceFromWithByteslikeStartAt(7, byteslike, 0, 11); 209 mutable_bytes.replaceFromWithByteslikeStartAt(10, byteslike, 0, 0); 210 const byte expected[] = "heellorld"; 211 EXPECT_TRUE(isMutableBytesEqualsBytes(mutable_bytes, expected)); 212} 213 214TEST_F(MutableBytesTest, ReplaceFromWithStartAtSelfNoop) { 215 HandleScope scope(thread_); 216 const byte src_bytes[] = "patrick"; 217 word src_length = ARRAYSIZE(src_bytes); 218 MutableBytes src(&scope, runtime_->newMutableBytesUninitialized(src_length)); 219 for (word i = 0; i < src_length; i++) { 220 src.byteAtPut(i, src_bytes[i]); 221 } 222 ASSERT_TRUE(isMutableBytesEqualsBytes(src, src_bytes)); 223 src.replaceFromWithStartAt(0, *src, 3, 0); 224 EXPECT_TRUE(isMutableBytesEqualsBytes(src, src_bytes)); 225} 226 227TEST_F(MutableBytesTest, ReplaceFromWithStartAtSelfBackward) { 228 HandleScope scope(thread_); 229 const byte src_bytes[] = "patrick"; 230 word src_length = ARRAYSIZE(src_bytes); 231 MutableBytes src(&scope, runtime_->newMutableBytesUninitialized(src_length)); 232 for (word i = 0; i < src_length; i++) { 233 src.byteAtPut(i, src_bytes[i]); 234 } 235 ASSERT_TRUE(isMutableBytesEqualsBytes(src, src_bytes)); 236 src.replaceFromWithStartAt(0, *src, 3, 4); 237 const byte expected[] = "ickrick"; 238 EXPECT_TRUE(isMutableBytesEqualsBytes(src, expected)); 239} 240 241TEST_F(MutableBytesTest, ReplaceFromWithStartAtSelfForward) { 242 HandleScope scope(thread_); 243 const byte src_bytes[] = "patrick"; 244 word src_length = ARRAYSIZE(src_bytes); 245 MutableBytes src(&scope, runtime_->newMutableBytesUninitialized(src_length)); 246 for (word i = 0; i < src_length; i++) { 247 src.byteAtPut(i, src_bytes[i]); 248 } 249 ASSERT_TRUE(isMutableBytesEqualsBytes(src, src_bytes)); 250 src.replaceFromWithStartAt(4, *src, 3, 0); 251 const byte expected[] = "patrpat"; 252 EXPECT_TRUE(isMutableBytesEqualsBytes(src, expected)); 253} 254 255TEST_F(MutableBytesTest, ReplaceFromWithStartAtReplacesStartingAtSrcIndex) { 256 byte src_bytes[] = "hello world this is patrick"; 257 HandleScope scope(thread_); 258 LargeBytes src(&scope, runtime_->newBytesWithAll(src_bytes)); 259 MutableBytes dst(&scope, runtime_->newMutableBytesUninitialized(8)); 260 dst.replaceFromWithStartAt(0, *src, 7, 20); 261 const byte expected[] = "patrick"; 262 EXPECT_TRUE(isMutableBytesEqualsBytes(dst, expected)); 263} 264 265TEST_F(CodeTest, OffsetToLineNumReturnsLineNumber) { 266 const char* src = R"( 267def func(): 268 a = 1 269 b = 2 270 print(a, b) 271)"; 272 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 273 HandleScope scope(thread_); 274 275 // The bytecode for func is roughly: 276 // LOAD_CONST # a = 1 277 // STORE_FAST 278 // 279 // LOAD_CONST # b = 2 280 // STORE_FAST 281 // 282 // LOAD_GLOBAL # print(a, b) 283 // LOAD_FAST 284 // LOAD_FAST 285 // CALL_FUNCTION 286 287 Function func(&scope, mainModuleAt(runtime_, "func")); 288 Code code(&scope, func.code()); 289 ASSERT_EQ(code.firstlineno(), 2); 290 291 // a = 1 292 EXPECT_EQ(code.offsetToLineNum(0), 3); 293 EXPECT_EQ(code.offsetToLineNum(2 * kCodeUnitScale), 3); 294 295 // b = 2 296 EXPECT_EQ(code.offsetToLineNum(4 * kCodeUnitScale), 4); 297 EXPECT_EQ(code.offsetToLineNum(6 * kCodeUnitScale), 4); 298 299 // print(a, b) 300 for (word i = 8; i < Bytes::cast(code.code()).length(); i++) { 301 EXPECT_EQ(code.offsetToLineNum(i * kCodeUnitScale), 5); 302 } 303} 304 305TEST_F(DoubleTest, DoubleTest) { 306 RawObject o = runtime_->newFloat(3.14); 307 ASSERT_TRUE(o.isFloat()); 308 RawFloat d = Float::cast(o); 309 EXPECT_EQ(d.value(), 3.14); 310} 311 312TEST_F(ComplexTest, ComplexTest) { 313 RawObject o = runtime_->newComplex(1.0, 2.0); 314 ASSERT_TRUE(o.isComplex()); 315 RawComplex c = Complex::cast(o); 316 EXPECT_EQ(c.real(), 1.0); 317 EXPECT_EQ(c.imag(), 2.0); 318} 319 320TEST_F(IntTest, IntTest) { 321 HandleScope scope(thread_); 322 323 Object o1(&scope, runtime_->newInt(42)); 324 EXPECT_TRUE(isIntEqualsWord(*o1, 42)); 325 326 Object o2(&scope, runtime_->newInt(9223372036854775807L)); 327 EXPECT_TRUE(isIntEqualsWord(*o2, 9223372036854775807L)); 328 329 int stack_val = 123; 330 Int o3(&scope, runtime_->newIntFromCPtr(&stack_val)); 331 EXPECT_EQ(*static_cast<int*>(o3.asCPtr()), 123); 332 333 Object o4(&scope, runtime_->newInt(kMinWord)); 334 EXPECT_TRUE(isIntEqualsWord(*o4, kMinWord)); 335 336 uword digits[] = {kMaxUword, 0}; 337 Int o5(&scope, runtime_->newLargeIntWithDigits(digits)); 338 EXPECT_TRUE(o5.isLargeInt()); 339 EXPECT_EQ(o5.bitLength(), kBitsPerWord); 340 341 uword digits2[] = {kMaxUword, 1}; 342 Int o6(&scope, runtime_->newLargeIntWithDigits(digits2)); 343 EXPECT_TRUE(o6.isLargeInt()); 344 EXPECT_EQ(o6.bitLength(), kBitsPerWord + 1); 345} 346 347TEST_F(IntTest, LargeIntValid) { 348 HandleScope scope(thread_); 349 350 uword digits[] = {static_cast<uword>(-1234), static_cast<uword>(-1)}; 351 LargeInt i(&scope, newLargeIntWithDigits(digits)); 352 // Redundant sign-extension 353 EXPECT_FALSE(i.isValid()); 354 355 i.digitAtPut(1, -2); 356 EXPECT_TRUE(i.isValid()); 357 358 i.digitAtPut(0, 1234); 359 i.digitAtPut(1, 0); 360 // Redundant zero-extension 361 EXPECT_FALSE(i.isValid()); 362 363 i.digitAtPut(1, 1); 364 EXPECT_TRUE(i.isValid()); 365} 366 367TEST_F(IntTest, IsPositive) { 368 HandleScope scope(thread_); 369 370 Int zero(&scope, runtime_->newInt(0)); 371 EXPECT_FALSE(zero.isPositive()); 372 373 Int one(&scope, runtime_->newInt(1)); 374 EXPECT_TRUE(one.isPositive()); 375 376 Int neg_one(&scope, runtime_->newInt(-1)); 377 EXPECT_FALSE(neg_one.isPositive()); 378 379 Int max_small_int(&scope, runtime_->newInt(RawSmallInt::kMaxValue)); 380 EXPECT_TRUE(max_small_int.isPositive()); 381 382 Int min_small_int(&scope, runtime_->newInt(RawSmallInt::kMinValue)); 383 EXPECT_FALSE(min_small_int.isPositive()); 384 385 Int max_word(&scope, runtime_->newInt(kMaxWord)); 386 EXPECT_TRUE(max_word.isPositive()); 387 388 Int min_word(&scope, runtime_->newInt(kMinWord)); 389 EXPECT_FALSE(min_word.isPositive()); 390} 391 392TEST_F(IntTest, IsNegative) { 393 HandleScope scope(thread_); 394 395 Int zero(&scope, runtime_->newInt(0)); 396 EXPECT_FALSE(zero.isNegative()); 397 398 Int one(&scope, runtime_->newInt(1)); 399 EXPECT_FALSE(one.isNegative()); 400 401 Int neg_one(&scope, runtime_->newInt(-1)); 402 EXPECT_TRUE(neg_one.isNegative()); 403 404 Int max_small_int(&scope, runtime_->newInt(RawSmallInt::kMaxValue)); 405 EXPECT_FALSE(max_small_int.isNegative()); 406 407 Int min_small_int(&scope, runtime_->newInt(RawSmallInt::kMinValue)); 408 EXPECT_TRUE(min_small_int.isNegative()); 409 410 Int max_word(&scope, runtime_->newInt(kMaxWord)); 411 EXPECT_FALSE(max_word.isNegative()); 412 413 Int min_word(&scope, runtime_->newInt(kMinWord)); 414 EXPECT_TRUE(min_word.isNegative()); 415} 416 417TEST_F(IntTest, IsZero) { 418 HandleScope scope(thread_); 419 420 Int zero(&scope, runtime_->newInt(0)); 421 EXPECT_TRUE(zero.isZero()); 422 423 Int one(&scope, runtime_->newInt(1)); 424 EXPECT_FALSE(one.isZero()); 425 426 Int neg_one(&scope, runtime_->newInt(-1)); 427 EXPECT_FALSE(neg_one.isZero()); 428 429 Int max_small_int(&scope, runtime_->newInt(RawSmallInt::kMaxValue)); 430 EXPECT_FALSE(max_small_int.isZero()); 431 432 Int min_small_int(&scope, runtime_->newInt(RawSmallInt::kMinValue)); 433 EXPECT_FALSE(min_small_int.isZero()); 434 435 Int max_word(&scope, runtime_->newInt(kMaxWord)); 436 EXPECT_FALSE(max_word.isZero()); 437 438 Int min_word(&scope, runtime_->newInt(kMinWord)); 439 EXPECT_FALSE(min_word.isZero()); 440} 441 442TEST_F(IntTest, Compare) { 443 HandleScope scope(thread_); 444 445 Int zero(&scope, runtime_->newInt(0)); 446 Int one(&scope, runtime_->newInt(1)); 447 Int neg_one(&scope, runtime_->newInt(-1)); 448 449 EXPECT_EQ(zero.compare(*zero), 0); 450 EXPECT_GE(one.compare(*neg_one), 1); 451 EXPECT_LE(neg_one.compare(*one), -1); 452 453 Int min_small_int(&scope, runtime_->newInt(RawSmallInt::kMinValue)); 454 Int max_small_int(&scope, runtime_->newInt(RawSmallInt::kMaxValue)); 455 456 EXPECT_GE(max_small_int.compare(*min_small_int), 1); 457 EXPECT_LE(min_small_int.compare(*max_small_int), -1); 458 EXPECT_EQ(min_small_int.compare(*min_small_int), 0); 459 EXPECT_EQ(max_small_int.compare(*max_small_int), 0); 460 461 Int min_word(&scope, runtime_->newInt(kMinWord)); 462 Int max_word(&scope, runtime_->newInt(kMaxWord)); 463 464 EXPECT_GE(max_word.compare(*min_word), 1); 465 EXPECT_LE(min_word.compare(*max_word), -1); 466 EXPECT_EQ(min_word.compare(*min_word), 0); 467 EXPECT_EQ(max_word.compare(*max_word), 0); 468 469 EXPECT_GE(max_word.compare(*max_small_int), 1); 470 EXPECT_LE(min_word.compare(*min_small_int), -1); 471} 472 473TEST_F(IntTest, LargeIntCompare) { 474 HandleScope scope(thread_); 475 const uword digits_great[] = {1, 1}; 476 Int great(&scope, runtime_->newLargeIntWithDigits(digits_great)); 477 const uword digits_small[] = {0, 0, kMaxUword}; 478 Int small(&scope, runtime_->newLargeIntWithDigits(digits_small)); 479 EXPECT_EQ(great.compare(*small), 1); 480 EXPECT_EQ(small.compare(*great), -1); 481 482 const uword digits_great2[] = {1, 1, 1}; 483 const uword digits_small2[] = {1, 1}; 484 great = runtime_->newLargeIntWithDigits(digits_great2); 485 small = runtime_->newLargeIntWithDigits(digits_small2); 486 EXPECT_EQ(great.compare(*small), 1); 487 EXPECT_EQ(small.compare(*great), -1); 488 489 const uword digits_great3[] = {kMaxUword - 1, 1}; 490 const uword digits_small3[] = {2, 1}; 491 great = runtime_->newLargeIntWithDigits(digits_great3); 492 small = runtime_->newLargeIntWithDigits(digits_small3); 493 EXPECT_EQ(great.compare(*small), 1); 494 EXPECT_EQ(small.compare(*great), -1); 495 496 const uword digits_great4[] = {kMaxUword - 1, kMaxUword - 1}; 497 const uword digits_small4[] = {2, kMaxUword - 1}; 498 great = runtime_->newLargeIntWithDigits(digits_great4); 499 small = runtime_->newLargeIntWithDigits(digits_small4); 500 EXPECT_EQ(great.compare(*small), 1); 501 EXPECT_EQ(small.compare(*great), -1); 502} 503 504#define EXPECT_VALID(expr, expected_value) \ 505 { \ 506 auto const result = (expr); \ 507 EXPECT_EQ(result.error, CastError::None); \ 508 EXPECT_EQ(result.value, expected_value); \ 509 } 510 511TEST_F(IntTest, AsIntWithZeroReturnsZero) { 512 HandleScope scope(thread_); 513 Int zero(&scope, runtime_->newInt(0)); 514 EXPECT_VALID(zero.asInt<int>(), 0); 515 EXPECT_VALID(zero.asInt<unsigned>(), 0U); 516 EXPECT_VALID(zero.asInt<unsigned long>(), 0UL); 517 EXPECT_VALID(zero.asInt<unsigned long long>(), 0ULL); 518} 519 520TEST_F(IntTest, AsIntReturnsInt) { 521 HandleScope scope(thread_); 522 Int num(&scope, runtime_->newInt(1234)); 523 EXPECT_VALID(num.asInt<int>(), 1234); 524 EXPECT_VALID(num.asInt<long>(), 1234); 525 EXPECT_VALID(num.asInt<unsigned>(), 1234U); 526 EXPECT_VALID(num.asInt<unsigned long>(), 1234UL); 527} 528 529TEST_F(IntTest, AsIntReturnsOverflow) { 530 HandleScope scope(thread_); 531 Int num(&scope, runtime_->newInt(1234)); 532 EXPECT_EQ(num.asInt<byte>().error, CastError::Overflow); 533 EXPECT_EQ(num.asInt<int8_t>().error, CastError::Overflow); 534 Int word_max(&scope, runtime_->newInt(kMaxWord)); 535 EXPECT_EQ(word_max.asInt<int32_t>().error, CastError::Overflow); 536 Int word_min(&scope, runtime_->newInt(kMinWord)); 537 EXPECT_EQ(word_min.asInt<int32_t>().error, CastError::Overflow); 538} 539 540TEST_F(IntTest, AsIntWithNegativeIntReturnsInt) { 541 HandleScope scope(thread_); 542 Int neg_num(&scope, runtime_->newInt(-4567)); 543 EXPECT_VALID(neg_num.asInt<int16_t>(), -4567); 544 Int neg_one(&scope, runtime_->newInt(-1)); 545 EXPECT_VALID(neg_one.asInt<int>(), -1); 546} 547 548TEST_F(IntTest, AsIntReturnsUnderflow) { 549 HandleScope scope(thread_); 550 Int neg_num(&scope, runtime_->newInt(-4567)); 551 EXPECT_EQ(neg_num.asInt<unsigned>().error, CastError::Underflow); 552 EXPECT_EQ(neg_num.asInt<int8_t>().error, CastError::Underflow); 553 Int neg_one(&scope, runtime_->newInt(-1)); 554 EXPECT_EQ(neg_one.asInt<unsigned>().error, CastError::Underflow); 555 Int word_min(&scope, runtime_->newInt(kMinWord)); 556 EXPECT_EQ(word_min.asInt<uword>().error, CastError::Underflow); 557} 558 559TEST_F(IntTest, AsIntWithMaxInt32ReturnsInt) { 560 HandleScope scope(thread_); 561 Int int32_max(&scope, runtime_->newInt(kMaxInt32)); 562 EXPECT_VALID(int32_max.asInt<int32_t>(), kMaxInt32); 563 EXPECT_EQ(int32_max.asInt<int16_t>().error, CastError::Overflow); 564} 565 566TEST_F(IntTest, AsIntWithMaxUwordReturnsInt) { 567 HandleScope scope(thread_); 568 Int uword_max(&scope, runtime_->newIntFromUnsigned(kMaxUword)); 569 EXPECT_VALID(uword_max.asInt<uword>(), kMaxUword); 570 EXPECT_EQ(uword_max.asInt<word>().error, CastError::Overflow); 571} 572 573TEST_F(IntTest, AsIntWithMaxWordReturnsInt) { 574 HandleScope scope(thread_); 575 Int word_max(&scope, runtime_->newInt(kMaxWord)); 576 EXPECT_VALID(word_max.asInt<word>(), kMaxWord); 577 EXPECT_VALID(word_max.asInt<uword>(), uword{kMaxWord}); 578} 579 580TEST_F(IntTest, AsIntWithMinWordReturnsInt) { 581 HandleScope scope(thread_); 582 Int word_min(&scope, runtime_->newInt(kMinWord)); 583 EXPECT_VALID(word_min.asInt<word>(), kMinWord); 584} 585 586TEST_F(IntTest, AsIntWithNegativeLargeIntReturnsUnderflow) { 587 HandleScope scope(thread_); 588 uword digits[] = {0, kMaxUword}; 589 Int negative(&scope, runtime_->newLargeIntWithDigits(digits)); 590 EXPECT_EQ(negative.asInt<word>().error, CastError::Underflow); 591 EXPECT_EQ(negative.asInt<uword>().error, CastError::Underflow); 592} 593 594TEST_F(IntTest, AsIntWithTrueReturnsOne) { 595 HandleScope scope(thread_); 596 Int value(&scope, Bool::trueObj()); 597 EXPECT_VALID(value.asInt<word>(), 1); 598 EXPECT_VALID(value.asInt<uint8_t>(), 1); 599} 600 601TEST_F(IntTest, AsIntWithFalseReturnsZero) { 602 HandleScope scope(thread_); 603 Int value(&scope, Bool::falseObj()); 604 EXPECT_VALID(value.asInt<uword>(), uword{0}); 605 EXPECT_VALID(value.asInt<int32_t>(), 0); 606} 607 608#undef EXPECT_VALID 609 610TEST_F(IntTest, SmallIntFromWordTruncatedWithSmallNegativeNumberReturnsSelf) { 611 EXPECT_EQ(SmallInt::fromWord(-1), SmallInt::fromWordTruncated(-1)); 612} 613 614TEST_F(MmapTest, AccessSettersSetValues) { 615 HandleScope scope(thread_); 616 Object obj(&scope, runtime_->newMmap()); 617 ASSERT_TRUE(obj.isMmap()); 618 Mmap mmap_obj(&scope, *obj); 619 mmap_obj.setReadable(); 620 mmap_obj.setWritable(); 621 mmap_obj.setCopyOnWrite(); 622 EXPECT_EQ(mmap_obj.isReadable(), true); 623 EXPECT_EQ(mmap_obj.isWritable(), true); 624 EXPECT_EQ(mmap_obj.isCopyOnWrite(), true); 625} 626 627TEST_F(ModulesTest, TestCreate) { 628 HandleScope scope(thread_); 629 Object name(&scope, runtime_->newStrFromCStr("mymodule")); 630 Module module(&scope, runtime_->newModule(name)); 631 EXPECT_EQ(module.name(), *name); 632} 633 634TEST_F(MutableBytesTest, BecomeStrTurnsObjectIntoSmallStr) { 635 HandleScope scope(thread_); 636 Object test_0(&scope, runtime_->emptyMutableBytes()); 637 ASSERT_TRUE(test_0.isMutableBytes()); 638 Object as_str_0(&scope, MutableBytes::cast(*test_0).becomeStr()); 639 EXPECT_TRUE(test_0.isMutableBytes()); 640 EXPECT_TRUE(as_str_0.isSmallStr()); 641 EXPECT_TRUE(isStrEqualsCStr(*as_str_0, "")); 642 643 Str str(&scope, runtime_->newStrFromCStr("abcdefghi")); 644 645 Object test_1(&scope, runtime_->newMutableBytesUninitialized(1)); 646 ASSERT_TRUE(test_1.isMutableBytes()); 647 MutableBytes::cast(*test_1).replaceFromWithStr(0, *str, 1); 648 Object as_str_1(&scope, MutableBytes::cast(*test_1).becomeStr()); 649 EXPECT_TRUE(test_1.isMutableBytes()); 650 EXPECT_TRUE(as_str_1.isSmallStr()); 651 EXPECT_TRUE(isStrEqualsCStr(*as_str_1, "a")); 652 653 Object test_m(&scope, 654 runtime_->newMutableBytesUninitialized(SmallStr::kMaxLength)); 655 ASSERT_TRUE(test_m.isMutableBytes()); 656 MutableBytes::cast(*test_m).replaceFromWithStr(0, *str, SmallStr::kMaxLength); 657 Object as_str_m(&scope, MutableBytes::cast(*test_m).becomeStr()); 658 EXPECT_TRUE(test_m.isMutableBytes()); 659 EXPECT_TRUE(as_str_m.isSmallStr()); 660 EXPECT_TRUE(isStrEqualsCStr(*as_str_m, "abcdefg")); 661} 662 663TEST_F(MutableBytesTest, BecomeStrTurnsObjectIntoLargeStr) { 664 HandleScope scope(thread_); 665 Str str(&scope, runtime_->newStrFromCStr("hello world!")); 666 667 Object test(&scope, runtime_->newMutableBytesUninitialized(str.length())); 668 ASSERT_TRUE(test.isMutableBytes()); 669 MutableBytes::cast(*test).replaceFromWithStr(0, *str, str.length()); 670 MutableBytes::cast(*test).becomeStr(); 671 EXPECT_TRUE(test.isLargeStr()); 672 EXPECT_TRUE(isStrEqualsCStr(*test, "hello world!")); 673} 674 675TEST_F(SliceTest, AdjustIndices) { 676 // Test: 0:10:1 on len: 10 677 word length = 10; 678 word start = 0; 679 word stop = 10; 680 word step = 1; 681 word new_length = Slice::adjustIndices(length, &start, &stop, step); 682 ASSERT_EQ(new_length, 10); 683 ASSERT_EQ(start, 0); 684 ASSERT_EQ(stop, 10); 685 686 // Test: 2:10:1 on len: 10 687 start = 2; 688 new_length = Slice::adjustIndices(length, &start, &stop, step); 689 ASSERT_EQ(new_length, 8); 690 ASSERT_EQ(start, 2); 691 ASSERT_EQ(stop, 10); 692 693 // Test: -4:10:1 on len: 10 694 start = -4; 695 new_length = Slice::adjustIndices(length, &start, &stop, step); 696 ASSERT_EQ(new_length, 4); 697 ASSERT_EQ(start, 6); 698 ASSERT_EQ(stop, 10); 699 700 // Test: 0:2:1 on len: 10 701 start = 0; 702 stop = 2; 703 new_length = Slice::adjustIndices(length, &start, &stop, step); 704 ASSERT_EQ(new_length, 2); 705 ASSERT_EQ(start, 0); 706 ASSERT_EQ(stop, 2); 707 708 // Test: 0:-2:1 on len: 10 709 start = 0; 710 stop = -2; 711 new_length = Slice::adjustIndices(length, &start, &stop, step); 712 ASSERT_EQ(new_length, 8); 713 ASSERT_EQ(start, 0); 714 ASSERT_EQ(stop, 8); 715 716 // Test: 0:10:2 on len: 10 717 start = 0; 718 stop = 10; 719 step = 2; 720 new_length = Slice::adjustIndices(length, &start, &stop, step); 721 ASSERT_EQ(new_length, 5); 722 ASSERT_EQ(start, 0); 723 ASSERT_EQ(stop, 10); 724 725 // Test: 0:10:-2 on len: 10 726 start = 0; 727 stop = 10; 728 step = -2; 729 new_length = Slice::adjustIndices(length, &start, &stop, step); 730 ASSERT_EQ(new_length, 0); 731 ASSERT_EQ(start, 0); 732 ASSERT_EQ(stop, 9); 733} 734 735TEST_F(SliceTest, AdjustIndicesOutOfBounds) { 736 // Test: 10:5:1 on len: 5 737 word length = 5; 738 word start = 10; 739 word stop = 5; 740 word step = 1; 741 word new_length = Slice::adjustIndices(length, &start, &stop, step); 742 ASSERT_EQ(new_length, 0); 743 ASSERT_EQ(start, 5); 744 ASSERT_EQ(stop, 5); 745 746 // Test: -10:5:1 on len: 5 747 start = -10; 748 new_length = Slice::adjustIndices(length, &start, &stop, step); 749 ASSERT_EQ(new_length, 5); 750 ASSERT_EQ(start, 0); 751 ASSERT_EQ(stop, 5); 752 753 // Test: 0:10:1 on len: 5 754 start = 0; 755 stop = 10; 756 new_length = Slice::adjustIndices(length, &start, &stop, step); 757 ASSERT_EQ(new_length, 5); 758 ASSERT_EQ(start, 0); 759 ASSERT_EQ(stop, 5); 760 761 // Test: 0:-10:1 on len: 5 762 stop = -10; 763 new_length = Slice::adjustIndices(length, &start, &stop, step); 764 ASSERT_EQ(new_length, 0); 765 ASSERT_EQ(start, 0); 766 ASSERT_EQ(stop, 0); 767 768 // Test: 0:5:10 on len: 5 769 stop = 5; 770 step = 10; 771 new_length = Slice::adjustIndices(length, &start, &stop, step); 772 ASSERT_EQ(new_length, 1); 773 ASSERT_EQ(start, 0); 774 ASSERT_EQ(stop, 5); 775 776 // Test: 0:5:-10 on len: 5 777 step = -10; 778 new_length = Slice::adjustIndices(length, &start, &stop, step); 779 ASSERT_EQ(new_length, 0); 780 ASSERT_EQ(start, 0); 781 ASSERT_EQ(stop, 4); 782} 783 784TEST_F(SliceTest, LengthWithNegativeStepAndStopLessThanStartReturnsLength) { 785 EXPECT_EQ(Slice::length(5, 2, -1), 3); 786} 787 788TEST_F(SliceTest, LengthWithNegativeStepAndStartLessThanStopReturnsZero) { 789 EXPECT_EQ(Slice::length(2, 5, -1), 0); 790} 791 792TEST_F(SliceTest, LengthWithNegativeStepAndStartEqualsStopReturnsZero) { 793 EXPECT_EQ(Slice::length(2, 2, -1), 0); 794} 795 796TEST_F(SliceTest, LengthWithPositiveStepAndStartLessThanStopReturnsLength) { 797 EXPECT_EQ(Slice::length(2, 5, 1), 3); 798} 799 800TEST_F(SliceTest, LengthWithPositiveStepAndStopLessThanStartReturnsZero) { 801 EXPECT_EQ(Slice::length(5, 2, 1), 0); 802} 803 804TEST_F(SliceTest, LengthWithPositiveStepAndStartEqualsStopReturnsZero) { 805 EXPECT_EQ(Slice::length(2, 2, 1), 0); 806} 807 808TEST_F(StrArrayTest, OffsetByCodePoints) { 809 HandleScope scope(thread_); 810 811 StrArray empty(&scope, runtime_->newStrArray()); 812 EXPECT_EQ(empty.numItems(), 0); 813 EXPECT_EQ(empty.offsetByCodePoints(0, 1), 0); 814 EXPECT_EQ(empty.offsetByCodePoints(2, 0), 0); 815 EXPECT_EQ(empty.offsetByCodePoints(2, 1), 0); 816 817 StrArray ascii(&scope, runtime_->newStrArray()); 818 Str ascii_str(&scope, runtime_->newStrFromCStr("abcd")); 819 runtime_->strArrayAddStr(thread_, ascii, ascii_str); 820 EXPECT_EQ(ascii.numItems(), 4); 821 822 // for ASCII, each code point is one byte wide 823 EXPECT_EQ(ascii.offsetByCodePoints(0, 0), 0); 824 EXPECT_EQ(ascii.offsetByCodePoints(0, 3), 3); 825 EXPECT_EQ(ascii.offsetByCodePoints(1, 0), 1); 826 EXPECT_EQ(ascii.offsetByCodePoints(2, 0), 2); 827 EXPECT_EQ(ascii.offsetByCodePoints(2, 1), 3); 828 EXPECT_EQ(ascii.offsetByCodePoints(3, 0), 3); 829 830 // return the length once we reach the end of the string 831 EXPECT_EQ(ascii.offsetByCodePoints(0, 4), 4); 832 EXPECT_EQ(ascii.offsetByCodePoints(0, 5), 4); 833 EXPECT_EQ(ascii.offsetByCodePoints(1, 3), 4); 834 EXPECT_EQ(ascii.offsetByCodePoints(1, 4), 4); 835 EXPECT_EQ(ascii.offsetByCodePoints(2, 2), 4); 836 EXPECT_EQ(ascii.offsetByCodePoints(2, 3), 4); 837 EXPECT_EQ(ascii.offsetByCodePoints(3, 1), 4); 838 EXPECT_EQ(ascii.offsetByCodePoints(3, 2), 4); 839 EXPECT_EQ(ascii.offsetByCodePoints(4, 0), 4); 840 EXPECT_EQ(ascii.offsetByCodePoints(6, 0), 4); 841 842 StrArray unicode(&scope, runtime_->newStrArray()); 843 Str unicode_str( 844 &scope, runtime_->newStrFromCStr("\xd7\x90pq\xd7\x91\xd7\x92-\xd7\x93")); 845 runtime_->strArrayAddStr(thread_, unicode, unicode_str); 846 EXPECT_EQ(unicode.numItems(), 11); 847 848 // for Unicode, code points may be more than one byte wide 849 EXPECT_EQ(unicode.offsetByCodePoints(0, 0), 0); 850 EXPECT_EQ(unicode.offsetByCodePoints(0, 1), 2); 851 EXPECT_EQ(unicode.offsetByCodePoints(0, 2), 3); 852 EXPECT_EQ(unicode.offsetByCodePoints(0, 3), 4); 853 EXPECT_EQ(unicode.offsetByCodePoints(0, 4), 6); 854 EXPECT_EQ(unicode.offsetByCodePoints(0, 5), 8); 855 EXPECT_EQ(unicode.offsetByCodePoints(0, 6), 9); 856 EXPECT_EQ(unicode.offsetByCodePoints(2, 0), 2); 857 EXPECT_EQ(unicode.offsetByCodePoints(2, 1), 3); 858 EXPECT_EQ(unicode.offsetByCodePoints(2, 2), 4); 859 EXPECT_EQ(unicode.offsetByCodePoints(2, 3), 6); 860 EXPECT_EQ(unicode.offsetByCodePoints(2, 4), 8); 861 EXPECT_EQ(unicode.offsetByCodePoints(2, 5), 9); 862 EXPECT_EQ(unicode.offsetByCodePoints(2, 6), 11); 863 EXPECT_EQ(unicode.offsetByCodePoints(4, 0), 4); 864 EXPECT_EQ(unicode.offsetByCodePoints(4, 1), 6); 865 EXPECT_EQ(unicode.offsetByCodePoints(6, 0), 6); 866 867 // return the length once we reach the end of the string 868 EXPECT_EQ(unicode.offsetByCodePoints(0, 7), 11); 869 EXPECT_EQ(unicode.offsetByCodePoints(0, 9), 11); 870 EXPECT_EQ(unicode.offsetByCodePoints(2, 7), 11); 871 EXPECT_EQ(unicode.offsetByCodePoints(3, 6), 11); 872 EXPECT_EQ(unicode.offsetByCodePoints(4, 5), 11); 873 EXPECT_EQ(unicode.offsetByCodePoints(8, 3), 11); 874 EXPECT_EQ(unicode.offsetByCodePoints(12, 0), 11); 875} 876 877TEST_F(StrArrayTest, RotateCodePointWithSameFirstAndLastIsNoop) { 878 HandleScope scope(thread_); 879 StrArray array(&scope, runtime_->newStrArray()); 880 runtime_->strArrayAddASCII(thread_, array, 'H'); 881 runtime_->strArrayAddASCII(thread_, array, 'i'); 882 runtime_->strArrayAddASCII(thread_, array, '!'); 883 EXPECT_TRUE(isStrEqualsCStr(runtime_->strFromStrArray(array), "Hi!")); 884 885 array.rotateCodePoint(1, 1); 886 EXPECT_TRUE(isStrEqualsCStr(runtime_->strFromStrArray(array), "Hi!")); 887} 888 889TEST_F(StrArrayTest, RotateCodePointWithFirstBeforeLastRotatesCodePoint) { 890 HandleScope scope(thread_); 891 StrArray array(&scope, runtime_->newStrArray()); 892 runtime_->strArrayAddASCII(thread_, array, 'a'); 893 runtime_->strArrayAddASCII(thread_, array, 'b'); 894 runtime_->strArrayAddASCII(thread_, array, 'c'); 895 EXPECT_TRUE(isStrEqualsCStr(runtime_->strFromStrArray(array), "abc")); 896 897 array.rotateCodePoint(0, 2); 898 EXPECT_TRUE(isStrEqualsCStr(runtime_->strFromStrArray(array), "cab")); 899} 900 901TEST_F(StrArrayTest, RotateCodePointWithNonASCIIRotatesEntireCodePoint) { 902 HandleScope scope(thread_); 903 StrArray array(&scope, runtime_->newStrArray()); 904 Str str(&scope, runtime_->newStrFromCStr("Chopin \u00e9tude")); 905 runtime_->strArrayAddStr(thread_, array, str); 906 907 array.rotateCodePoint(1, 7); 908 EXPECT_TRUE( 909 isStrEqualsCStr(runtime_->strFromStrArray(array), "C\u00e9hopin tude")); 910} 911 912TEST_F(StrArrayTest, RotateCodePointWithNonASCIIUsesCharIndex) { 913 HandleScope scope(thread_); 914 StrArray array(&scope, runtime_->newStrArray()); 915 Str str(&scope, runtime_->newStrFromCStr("Chopin \u00e9tude")); 916 runtime_->strArrayAddStr(thread_, array, str); 917 918 array.rotateCodePoint(1, 10); 919 EXPECT_TRUE( 920 isStrEqualsCStr(runtime_->strFromStrArray(array), "Cuhopin \u00e9tde")); 921} 922 923TEST_F(LargeStrTest, CopyTo) { 924 RawObject obj = runtime_->newStrFromCStr("hello world!"); 925 ASSERT_TRUE(obj.isLargeStr()); 926 RawStr str = Str::cast(obj); 927 928 byte array[5]; 929 memset(array, 'a', ARRAYSIZE(array)); 930 str.copyTo(array, 0); 931 EXPECT_EQ(array[0], 'a'); 932 EXPECT_EQ(array[1], 'a'); 933 EXPECT_EQ(array[2], 'a'); 934 EXPECT_EQ(array[3], 'a'); 935 EXPECT_EQ(array[4], 'a'); 936 937 memset(array, 'b', ARRAYSIZE(array)); 938 str.copyTo(array, 1); 939 EXPECT_EQ(array[0], 'h'); 940 EXPECT_EQ(array[1], 'b'); 941 EXPECT_EQ(array[2], 'b'); 942 EXPECT_EQ(array[3], 'b'); 943 EXPECT_EQ(array[4], 'b'); 944 945 memset(array, 'c', ARRAYSIZE(array)); 946 str.copyTo(array, 5); 947 EXPECT_EQ(array[0], 'h'); 948 EXPECT_EQ(array[1], 'e'); 949 EXPECT_EQ(array[2], 'l'); 950 EXPECT_EQ(array[3], 'l'); 951 EXPECT_EQ(array[4], 'o'); 952} 953 954TEST_F(StringTest, CompareSmallStrCStrASCII) { 955 HandleScope scope(thread_); 956 957 Str small_ascii(&scope, runtime_->newStrFromCStr("sm")); 958 ASSERT_TRUE(small_ascii.isSmallStr()); 959 960 // Equal 961 EXPECT_EQ(small_ascii.compareCStr("sm"), 0); 962 963 // Less 964 EXPECT_EQ(small_ascii.compareCStr("sma"), -1); 965 EXPECT_EQ(small_ascii.compareCStr("sn"), -1); 966 967 // Greater 968 EXPECT_EQ(small_ascii.compareCStr("s"), 1); 969 EXPECT_EQ(small_ascii.compareCStr("sl"), 1); 970} 971 972TEST_F(StringTest, CompareSmallStrWithNulCStrASCII) { 973 HandleScope scope(thread_); 974 975 const byte data[] = {'s', '\0', 'm'}; 976 Str small_ascii(&scope, runtime_->newStrWithAll(data)); 977 ASSERT_TRUE(small_ascii.isSmallStr()); 978 979 // Less 980 EXPECT_EQ(small_ascii.compareCStr("t"), -1); 981 982 // Greater 983 EXPECT_EQ(small_ascii.compareCStr("s"), 1); 984 EXPECT_EQ(small_ascii.compareCStr("a\0m"), 1); 985} 986 987TEST_F(StringTest, CompareLargeStrWithNulCStrASCII) { 988 HandleScope scope(thread_); 989 990 const byte data[] = {'l', 'a', 'r', 'g', 'e', '\0', 's', 't'}; 991 Str large_ascii(&scope, runtime_->newStrWithAll(data)); 992 ASSERT_TRUE(large_ascii.isLargeStr()); 993 994 // Less 995 EXPECT_EQ(large_ascii.compareCStr("largz"), -1); 996 997 // Greater 998 EXPECT_EQ(large_ascii.compareCStr("large"), 1); 999 EXPECT_EQ(large_ascii.compareCStr("larga\0st"), 1); 1000} 1001 1002TEST_F(StringTest, CompareLargeStrCStrASCII) { 1003 HandleScope scope(thread_); 1004 1005 Str large_ascii(&scope, runtime_->newStrFromCStr("large string")); 1006 ASSERT_TRUE(large_ascii.isLargeStr()); 1007 1008 // Equal 1009 EXPECT_EQ(large_ascii.compareCStr("large string"), 0); 1010 1011 // Less 1012 EXPECT_EQ(large_ascii.compareCStr("large strings"), -1); 1013 EXPECT_EQ(large_ascii.compareCStr("large tbigger"), -1); 1014 1015 // Greater 1016 EXPECT_EQ(large_ascii.compareCStr("large strin"), 1); 1017 EXPECT_EQ(large_ascii.compareCStr("large smaller"), 1); 1018} 1019 1020TEST_F(StringTest, CompareSmallStrCStrUTF8) { 1021 HandleScope scope(thread_); 1022 1023 Str small_utf8(&scope, runtime_->newStrFromCStr("\xC3\x87")); 1024 ASSERT_TRUE(small_utf8.isSmallStr()); 1025 1026 // Equal 1027 EXPECT_EQ(small_utf8.compareCStr("\xC3\x87"), 0); 1028 1029 // Less 1030 EXPECT_EQ(small_utf8.compareCStr("\xC3\x87s"), -1); 1031 EXPECT_EQ(small_utf8.compareCStr("\xC3\x88"), -1); 1032 EXPECT_EQ(small_utf8.compareCStr("\xC3\xA7"), -1); 1033 1034 // Greater 1035 EXPECT_EQ(small_utf8.compareCStr(""), 1); 1036 EXPECT_EQ(small_utf8.compareCStr("\xC3\x86"), 1); 1037 EXPECT_EQ(small_utf8.compareCStr("\xC3\x67"), 1); 1038} 1039 1040TEST_F(StringTest, CompareLargeStrCStrUTF8) { 1041 HandleScope scope(thread_); 1042 1043 Str large_utf8(&scope, runtime_->newStrFromCStr("\xC3\x87 large")); 1044 ASSERT_TRUE(large_utf8.isLargeStr()); 1045 1046 // Equal 1047 EXPECT_EQ(large_utf8.compareCStr("\xC3\x87 large"), 0); 1048 1049 // Less 1050 EXPECT_EQ(large_utf8.compareCStr("\xC3\x87 larges"), -1); 1051 EXPECT_EQ(large_utf8.compareCStr("\xC3\x88 large"), -1); 1052 EXPECT_EQ(large_utf8.compareCStr("\xC3\xA7 large"), -1); 1053 1054 // Greater 1055 EXPECT_EQ(large_utf8.compareCStr("\xC3\x87"), 1); 1056 EXPECT_EQ(large_utf8.compareCStr("\xC3\x86 large"), 1); 1057 EXPECT_EQ(large_utf8.compareCStr("g large"), 1); 1058} 1059 1060TEST_F(StringTest, CompareSmallStrCStrLatin1) { 1061 HandleScope scope(thread_); 1062 1063 Str small_latin1(&scope, runtime_->newStrFromCStr("\xDC")); 1064 ASSERT_TRUE(small_latin1.isSmallStr()); 1065 1066 // Equal 1067 EXPECT_EQ(small_latin1.compareCStr("\xDC"), 0); 1068 1069 // Less 1070 EXPECT_EQ(small_latin1.compareCStr("\xDCs"), -1); 1071 EXPECT_EQ(small_latin1.compareCStr("\xDD"), -1); 1072 EXPECT_EQ(small_latin1.compareCStr("\xEC"), -1); 1073 1074 // Greater 1075 EXPECT_EQ(small_latin1.compareCStr(""), 1); 1076 EXPECT_EQ(small_latin1.compareCStr("\xDB"), 1); 1077 EXPECT_EQ(small_latin1.compareCStr("\xAC"), 1); 1078} 1079 1080TEST_F(StringTest, CompareLargeStrCStrLatin1) { 1081 HandleScope scope(thread_); 1082 1083 Str large_latin1(&scope, runtime_->newStrFromCStr("\xDClarge str")); 1084 ASSERT_TRUE(large_latin1.isLargeStr()); 1085 1086 // Equal 1087 EXPECT_EQ(large_latin1.compareCStr("\xDClarge str"), 0); 1088 1089 // Less 1090 EXPECT_EQ(large_latin1.compareCStr("\xDClarge strs"), -1); 1091 EXPECT_EQ(large_latin1.compareCStr("\xDDlarge str"), -1); 1092 EXPECT_EQ(large_latin1.compareCStr("\xEClarge str"), -1); 1093 1094 // Greater 1095 EXPECT_EQ(large_latin1.compareCStr("\xDC"), 1); 1096 EXPECT_EQ(large_latin1.compareCStr("\xDBlarge str"), 1); 1097 EXPECT_EQ(large_latin1.compareCStr("\xBClarge str"), 1); 1098} 1099 1100TEST_F(StringTest, CopyToStartAtWithLargeStrCopiesBytes) { 1101 HandleScope scope(thread_); 1102 Str str(&scope, runtime_->newStrFromCStr("Hello world!")); 1103 1104 byte actual0[5]; 1105 LargeStr::cast(*str).copyToStartAt(actual0, 5, 3); 1106 EXPECT_EQ(std::memcmp(actual0, "lo", 2), 0); 1107 1108 byte actual1[3]; 1109 LargeStr::cast(*str).copyToStartAt(actual1, 3, 4); 1110 EXPECT_EQ(std::memcmp(actual1, "o w", 3), 0); 1111 1112 // zero-sized copies should do nothing. 1113 str.copyToStartAt(nullptr, 0, 0); 1114 LargeStr::cast(*str).copyToStartAt(nullptr, 0, 12); 1115} 1116 1117TEST_F(StringTest, CopyToStartAtWithSmallStrCopiesBytes) { 1118 HandleScope scope(thread_); 1119 Str str(&scope, SmallStr::fromCStr("bar")); 1120 1121 byte actual0[3]; 1122 str.copyToStartAt(actual0, 3, 0); 1123 EXPECT_EQ(std::memcmp(actual0, "bar", 3), 0); 1124 1125 byte actual1[2]; 1126 str.copyToStartAt(actual1, 2, 1); 1127 EXPECT_EQ(std::memcmp(actual1, "ar", 2), 0); 1128 1129 // zero-sized copies should do nothing. 1130 str.copyToStartAt(nullptr, 0, 0); 1131 str.copyToStartAt(nullptr, 0, 3); 1132} 1133 1134TEST_F(SmallStrTest, CodePointLengthWithAsciiReturnsLength) { 1135 HandleScope scope(thread_); 1136 SmallStr len0(&scope, SmallStr::fromCStr("")); 1137 EXPECT_EQ(len0.length(), 0); 1138 EXPECT_EQ(len0.codePointLength(), 0); 1139 1140 SmallStr len1(&scope, SmallStr::fromCStr("1")); 1141 EXPECT_EQ(len1.length(), 1); 1142 EXPECT_EQ(len1.codePointLength(), 1); 1143 1144 SmallStr len2(&scope, SmallStr::fromCStr("12")); 1145 EXPECT_EQ(len2.length(), 2); 1146 EXPECT_EQ(len2.codePointLength(), 2); 1147 1148 SmallStr len3(&scope, SmallStr::fromCStr("123")); 1149 EXPECT_EQ(len3.length(), 3); 1150 EXPECT_EQ(len3.codePointLength(), 3); 1151} 1152 1153TEST_F(SmallStrTest, CodePointLengthWithOneCodePoint) { 1154 HandleScope scope(thread_); 1155 SmallStr len1(&scope, SmallStr::fromCStr("\x24")); 1156 EXPECT_EQ(len1.length(), 1); 1157 EXPECT_EQ(len1.codePointLength(), 1); 1158 1159 SmallStr len2(&scope, SmallStr::fromCStr("\xC2\xA2")); 1160 EXPECT_EQ(len2.length(), 2); 1161 EXPECT_EQ(len2.codePointLength(), 1); 1162 1163 SmallStr len3(&scope, SmallStr::fromCStr("\xE0\xA4\xB9")); 1164 EXPECT_EQ(len3.length(), 3); 1165 EXPECT_EQ(len3.codePointLength(), 1); 1166 1167 SmallStr len4(&scope, SmallStr::fromCStr("\xF0\x90\x8D\x88")); 1168 EXPECT_EQ(len4.length(), 4); 1169 EXPECT_EQ(len4.codePointLength(), 1); 1170} 1171 1172TEST_F(SmallStrTest, CodePointLengthWithTwoCodePoints) { 1173 HandleScope scope(thread_); 1174 SmallStr len1(&scope, SmallStr::fromCStr("\x24\x65")); 1175 EXPECT_EQ(len1.length(), 2); 1176 EXPECT_EQ(len1.codePointLength(), 2); 1177 1178 SmallStr len2(&scope, SmallStr::fromCStr("\xC2\xA2\xC2\xA3")); 1179 EXPECT_EQ(len2.length(), 4); 1180 EXPECT_EQ(len2.codePointLength(), 2); 1181 1182 SmallStr len3(&scope, SmallStr::fromCStr("\xE0\xA4\xB9\xC2\xA3")); 1183 EXPECT_EQ(len3.length(), 5); 1184 EXPECT_EQ(len3.codePointLength(), 2); 1185 1186 SmallStr len4(&scope, SmallStr::fromCStr("\xF0\x90\x8D\x88\xC2\xA3")); 1187 EXPECT_EQ(len4.length(), 6); 1188 EXPECT_EQ(len4.codePointLength(), 2); 1189} 1190 1191TEST_F(SmallStrTest, CodePointLengthWithThreeCodePoints) { 1192 HandleScope scope(thread_); 1193 SmallStr len1(&scope, SmallStr::fromCStr("\x24\x65\x66")); 1194 EXPECT_EQ(len1.length(), 3); 1195 EXPECT_EQ(len1.codePointLength(), 3); 1196 1197 SmallStr len2(&scope, SmallStr::fromCStr("\xC2\xA2\xC2\xA3\xC2\xA4")); 1198 EXPECT_EQ(len2.length(), 6); 1199 EXPECT_EQ(len2.codePointLength(), 3); 1200 1201 SmallStr len3(&scope, SmallStr::fromCStr("\xE0\xA4\xB9\xC2\xA3\xC2\xA4")); 1202 EXPECT_EQ(len3.length(), 7); 1203 EXPECT_EQ(len3.codePointLength(), 3); 1204 1205 SmallStr len4(&scope, SmallStr::fromCStr("\xF0\x90\x8D\x88\x65\xC2\xA3")); 1206 EXPECT_EQ(len4.length(), 7); 1207 EXPECT_EQ(len4.codePointLength(), 3); 1208} 1209 1210TEST_F(SmallStrTest, CopyToCopiesBytes) { 1211 HandleScope scope(thread_); 1212 SmallStr str(&scope, SmallStr::fromCStr("AB")); 1213 EXPECT_EQ(str.length(), 2); 1214 EXPECT_EQ(str.byteAt(0), 'A'); 1215 EXPECT_EQ(str.byteAt(1), 'B'); 1216 1217 byte array[3]{0, 0, 0}; 1218 str.copyTo(array, 2); 1219 EXPECT_EQ(array[0], 'A'); 1220 EXPECT_EQ(array[1], 'B'); 1221 EXPECT_EQ(array[2], 0); 1222} 1223 1224TEST_F(SmallStrTest, FromCodePointOneByte) { 1225 HandleScope scope(thread_); 1226 SmallStr str(&scope, SmallStr::fromCodePoint(0x24)); 1227 ASSERT_EQ(str.length(), 1); 1228 EXPECT_EQ(str.byteAt(0), 0x24); 1229} 1230 1231TEST_F(SmallStrTest, FromCodePointTwoByte) { 1232 HandleScope scope(thread_); 1233 SmallStr str(&scope, SmallStr::fromCodePoint(0xA2)); 1234 ASSERT_EQ(str.length(), 2); 1235 EXPECT_EQ(str.byteAt(0), 0xC2); 1236 EXPECT_EQ(str.byteAt(1), 0xA2); 1237} 1238 1239TEST_F(SmallStrTest, FromCodePointThreeByte) { 1240 HandleScope scope(thread_); 1241 SmallStr str1(&scope, SmallStr::fromCodePoint(0x0939)); 1242 ASSERT_EQ(str1.length(), 3); 1243 EXPECT_EQ(str1.byteAt(0), 0xE0); 1244 EXPECT_EQ(str1.byteAt(1), 0xA4); 1245 EXPECT_EQ(str1.byteAt(2), 0xB9); 1246 1247 SmallStr str2(&scope, SmallStr::fromCodePoint(0x20AC)); 1248 ASSERT_EQ(str2.length(), 3); 1249 EXPECT_EQ(str2.byteAt(0), 0xE2); 1250 EXPECT_EQ(str2.byteAt(1), 0x82); 1251 EXPECT_EQ(str2.byteAt(2), 0xAC); 1252} 1253 1254TEST_F(SmallStrTest, FromCodePointFourByte) { 1255 HandleScope scope(thread_); 1256 SmallStr str(&scope, SmallStr::fromCodePoint(0x10348)); 1257 ASSERT_EQ(str.length(), 4); 1258 EXPECT_EQ(str.byteAt(0), 0xF0); 1259 EXPECT_EQ(str.byteAt(1), 0x90); 1260 EXPECT_EQ(str.byteAt(2), 0x8D); 1261 EXPECT_EQ(str.byteAt(3), 0x88); 1262} 1263 1264TEST_F(SmallStrTest, IncludesLargeStrReturnsFalse) { 1265 HandleScope scope(thread_); 1266 SmallStr haystack(&scope, SmallStr::fromCStr("abcd")); 1267 LargeStr needle(&scope, runtime_->newStrFromCStr("abcdefgh")); 1268 EXPECT_FALSE(haystack.includes(*needle)); 1269} 1270 1271TEST_F(SmallStrTest, IncludesSmallStrChecksSubstr) { 1272 HandleScope scope(thread_); 1273 SmallStr haystack(&scope, SmallStr::fromCStr("abcd")); 1274 SmallStr empty(&scope, Str::empty()); 1275 SmallStr needle(&scope, SmallStr::fromCStr("bc")); 1276 SmallStr not_needle(&scope, SmallStr::fromCStr("abcde")); 1277 1278 EXPECT_TRUE(haystack.includes(*empty)); 1279 EXPECT_TRUE(haystack.includes(*needle)); 1280 EXPECT_TRUE(haystack.includes(*haystack)); 1281 EXPECT_FALSE(haystack.includes(*not_needle)); 1282} 1283 1284TEST_F(SmallStrTest, IsASCIIReturnsTrueIfAndOnlyIfAllASCII) { 1285 HandleScope scope(thread_); 1286 SmallStr all_ascii(&scope, SmallStr::fromCStr("abc")); 1287 EXPECT_TRUE(all_ascii.isASCII()); 1288 1289 SmallStr some_non_ascii(&scope, SmallStr::fromCStr("a\xC2\xA3g")); 1290 EXPECT_FALSE(some_non_ascii.isASCII()); 1291} 1292 1293TEST_F(SmallStrTest, OccurrencesOfWithEmptyStringReturnsZero) { 1294 HandleScope scope(thread_); 1295 Str haystack(&scope, SmallStr::fromCStr("hello")); 1296 Str needle(&scope, runtime_->newStrFromCStr("")); 1297 EXPECT_EQ(haystack.occurrencesOf(*needle), 0); 1298} 1299 1300TEST_F(SmallStrTest, OccurrencesOfWithLargeStrReturnsZero) { 1301 HandleScope scope(thread_); 1302 Str haystack(&scope, SmallStr::fromCStr("abab")); 1303 Str needle(&scope, runtime_->newStrFromCStr("ababababab")); 1304 EXPECT_EQ(haystack.occurrencesOf(*needle), 0); 1305} 1306 1307TEST_F(SmallStrTest, OccurrencesOfWithNoOccurenceReturnsZero) { 1308 HandleScope scope(thread_); 1309 Str haystack(&scope, SmallStr::fromCStr("abab")); 1310 Str needle(&scope, SmallStr::fromCStr("cd")); 1311 EXPECT_EQ(haystack.occurrencesOf(*needle), 0); 1312} 1313 1314TEST_F(SmallStrTest, OccurrencesOfWithSmallStrFindsOccurrenceAtSecondChar) { 1315 HandleScope scope(thread_); 1316 Str haystack(&scope, SmallStr::fromCStr("abab")); 1317 Str needle(&scope, SmallStr::fromCStr("ba")); 1318 EXPECT_EQ(haystack.occurrencesOf(*needle), 1); 1319} 1320 1321TEST_F(SmallStrTest, OccurrencesOfWithSmallStrMultipleOccurrencesFindsAll) { 1322 HandleScope scope(thread_); 1323 Str haystack(&scope, SmallStr::fromCStr("hello")); 1324 Str needle(&scope, SmallStr::fromCStr("l")); 1325 EXPECT_EQ(haystack.occurrencesOf(*needle), 2); 1326} 1327 1328TEST_F(StrTest, OffsetByCodePoints) { 1329 HandleScope scope(thread_); 1330 1331 Str empty(&scope, Str::empty()); 1332 EXPECT_EQ(empty.length(), 0); 1333 EXPECT_EQ(empty.codePointLength(), 0); 1334 EXPECT_EQ(empty.offsetByCodePoints(0, 1), 0); 1335 EXPECT_EQ(empty.offsetByCodePoints(2, 0), 0); 1336 EXPECT_EQ(empty.offsetByCodePoints(2, 1), 0); 1337 1338 Str ascii(&scope, runtime_->newStrFromCStr("abcd")); 1339 EXPECT_EQ(ascii.length(), 4); 1340 EXPECT_EQ(ascii.codePointLength(), 4); 1341 1342 // for ASCII, each code point is one byte wide 1343 EXPECT_EQ(ascii.offsetByCodePoints(0, 0), 0); 1344 EXPECT_EQ(ascii.offsetByCodePoints(0, 3), 3); 1345 EXPECT_EQ(ascii.offsetByCodePoints(1, 0), 1); 1346 EXPECT_EQ(ascii.offsetByCodePoints(2, 0), 2); 1347 EXPECT_EQ(ascii.offsetByCodePoints(2, 1), 3); 1348 EXPECT_EQ(ascii.offsetByCodePoints(3, 0), 3); 1349 1350 // return the length once we reach the end of the string 1351 EXPECT_EQ(ascii.offsetByCodePoints(0, 4), 4); 1352 EXPECT_EQ(ascii.offsetByCodePoints(0, 5), 4); 1353 EXPECT_EQ(ascii.offsetByCodePoints(1, 3), 4); 1354 EXPECT_EQ(ascii.offsetByCodePoints(1, 4), 4); 1355 EXPECT_EQ(ascii.offsetByCodePoints(2, 2), 4); 1356 EXPECT_EQ(ascii.offsetByCodePoints(2, 3), 4); 1357 EXPECT_EQ(ascii.offsetByCodePoints(3, 1), 4); 1358 EXPECT_EQ(ascii.offsetByCodePoints(3, 2), 4); 1359 EXPECT_EQ(ascii.offsetByCodePoints(4, 0), 4); 1360 EXPECT_EQ(ascii.offsetByCodePoints(6, 0), 4); 1361 1362 Str unicode(&scope, 1363 runtime_->newStrFromCStr("\xd7\x90pq\xd7\x91\xd7\x92-\xd7\x93")); 1364 EXPECT_EQ(unicode.length(), 11); 1365 EXPECT_EQ(unicode.codePointLength(), 7); 1366 1367 // for Unicode, code points may be more than one byte wide 1368 EXPECT_EQ(unicode.offsetByCodePoints(0, 0), 0); 1369 EXPECT_EQ(unicode.offsetByCodePoints(0, 1), 2); 1370 EXPECT_EQ(unicode.offsetByCodePoints(0, 2), 3); 1371 EXPECT_EQ(unicode.offsetByCodePoints(0, 3), 4); 1372 EXPECT_EQ(unicode.offsetByCodePoints(0, 4), 6); 1373 EXPECT_EQ(unicode.offsetByCodePoints(0, 5), 8); 1374 EXPECT_EQ(unicode.offsetByCodePoints(0, 6), 9); 1375 EXPECT_EQ(unicode.offsetByCodePoints(2, 0), 2); 1376 EXPECT_EQ(unicode.offsetByCodePoints(2, 1), 3); 1377 EXPECT_EQ(unicode.offsetByCodePoints(2, 2), 4); 1378 EXPECT_EQ(unicode.offsetByCodePoints(2, 3), 6); 1379 EXPECT_EQ(unicode.offsetByCodePoints(2, 4), 8); 1380 EXPECT_EQ(unicode.offsetByCodePoints(2, 5), 9); 1381 EXPECT_EQ(unicode.offsetByCodePoints(2, 6), 11); 1382 EXPECT_EQ(unicode.offsetByCodePoints(4, 0), 4); 1383 EXPECT_EQ(unicode.offsetByCodePoints(4, 1), 6); 1384 EXPECT_EQ(unicode.offsetByCodePoints(6, 0), 6); 1385 1386 // return the length once we reach the end of the string 1387 EXPECT_EQ(unicode.offsetByCodePoints(0, 7), 11); 1388 EXPECT_EQ(unicode.offsetByCodePoints(0, 9), 11); 1389 EXPECT_EQ(unicode.offsetByCodePoints(2, 7), 11); 1390 EXPECT_EQ(unicode.offsetByCodePoints(3, 6), 11); 1391 EXPECT_EQ(unicode.offsetByCodePoints(4, 5), 11); 1392 EXPECT_EQ(unicode.offsetByCodePoints(8, 3), 11); 1393 EXPECT_EQ(unicode.offsetByCodePoints(12, 0), 11); 1394} 1395 1396TEST_F(LargeStrTest, CodePointLengthAscii) { 1397 HandleScope scope(thread_); 1398 1399 const char* code_units = "01234567012345670"; 1400 1401 Str str(&scope, runtime_->newStrFromCStr(code_units)); 1402 EXPECT_TRUE(str.isLargeStr()); 1403 EXPECT_EQ(str.length(), static_cast<word>(std::strlen(code_units))); 1404 EXPECT_EQ(str.codePointLength(), 17); 1405} 1406 1407TEST_F(LargeStrTest, CodePointLength) { 1408 HandleScope scope(thread_); 1409 1410 const char* code_units = 1411 "\xd7\x99\xd7\xa9 \xd7\x9c\xd7\x99 \xd7\x94\xd7\xa8\xd7\x91\xd7\x94 " 1412 "\xd7\x90\xd7\x95\xd7\xaa\xd7\x99\xd7\x95\xd7\xaa " 1413 "\xd7\xa2\xd7\x9b\xd7\xa9\xd7\x99\xd7\x95"; 1414 1415 Str str(&scope, runtime_->newStrFromCStr(code_units)); 1416 EXPECT_TRUE(str.isLargeStr()); 1417 EXPECT_EQ(str.length(), static_cast<word>(std::strlen(code_units))); 1418 EXPECT_EQ(str.codePointLength(), 23); 1419} 1420 1421TEST_F(LargeStrTest, IncludesLargeStrChecksSubstr) { 1422 HandleScope scope(thread_); 1423 LargeStr haystack(&scope, runtime_->newStrFromCStr("abcdefghijk")); 1424 LargeStr needle(&scope, runtime_->newStrFromCStr("bcdefghi")); 1425 LargeStr not_needle(&scope, runtime_->newStrFromCStr("aaaaaaaa")); 1426 1427 EXPECT_TRUE(haystack.includes(*haystack)); 1428 EXPECT_TRUE(haystack.includes(*needle)); 1429 EXPECT_FALSE(haystack.includes(*not_needle)); 1430} 1431 1432TEST_F(LargeStrTest, IncludesSmallStrChecksSubstr) { 1433 HandleScope scope(thread_); 1434 LargeStr haystack(&scope, runtime_->newStrFromCStr("abcdefghijkl")); 1435 SmallStr empty(&scope, Str::empty()); 1436 SmallStr needle(&scope, SmallStr::fromCStr("fgh")); 1437 SmallStr not_needle(&scope, SmallStr::fromCStr("bb")); 1438 1439 EXPECT_TRUE(haystack.includes(*empty)); 1440 EXPECT_TRUE(haystack.includes(*needle)); 1441 EXPECT_FALSE(haystack.includes(*not_needle)); 1442 1443 Str chars(&scope, runtime_->newStrFromCStr(".\\[{()*+?^$|")); 1444 Str hash(&scope, SmallStr::fromCStr("#")); 1445 EXPECT_FALSE(chars.includes(*hash)); 1446} 1447 1448TEST_F(LargeStrTest, IsASCIIReturnsTrueIfAndOnlyIfAllASCII) { 1449 HandleScope scope(thread_); 1450 1451 Str ascii(&scope, runtime_->newStrFromCStr("01234567012345670")); 1452 EXPECT_TRUE(ascii.isLargeStr()); 1453 EXPECT_TRUE(ascii.isASCII()); 1454 1455 Str unicode(&scope, runtime_->newStrFromCStr("ascii \xd7\x99\xd7\xa9 pad")); 1456 EXPECT_TRUE(unicode.isLargeStr()); 1457 EXPECT_FALSE(unicode.isASCII()); 1458} 1459 1460TEST_F(LargeStrTest, OccurrencesOfWithEmptyStringReturnsZero) { 1461 HandleScope scope(thread_); 1462 Str haystack(&scope, runtime_->newStrFromCStr("hello world")); 1463 Str needle(&scope, runtime_->newStrFromCStr("")); 1464 EXPECT_EQ(haystack.occurrencesOf(*needle), 0); 1465} 1466 1467TEST_F(LargeStrTest, OccurrencesOfWithLargeStrFindsOccurrenceAtFirstChar) { 1468 HandleScope scope(thread_); 1469 Str haystack(&scope, runtime_->newStrFromCStr("hello world")); 1470 Str needle(&scope, runtime_->newStrFromCStr("hello wor")); 1471 EXPECT_EQ(haystack.occurrencesOf(*needle), 1); 1472} 1473 1474TEST_F(LargeStrTest, OccurrencesOfWithLargeStrMultipleOccurrencesFindsAll) { 1475 HandleScope scope(thread_); 1476 Str haystack(&scope, runtime_->newStrFromCStr("hello world hello world")); 1477 Str needle(&scope, runtime_->newStrFromCStr("hello world")); 1478 EXPECT_EQ(haystack.occurrencesOf(*needle), 2); 1479} 1480 1481TEST_F(LargeStrTest, OccurrencesOfWithNoOccurenceReturnsZero) { 1482 HandleScope scope(thread_); 1483 Str haystack(&scope, runtime_->newStrFromCStr("hello world")); 1484 Str needle(&scope, runtime_->newStrFromCStr("is not here")); 1485 EXPECT_EQ(haystack.occurrencesOf(*needle), 0); 1486} 1487 1488TEST_F(LargeStrTest, OccurrencesOfWithSmallStrFindsOccurrenceAtThirdChar) { 1489 HandleScope scope(thread_); 1490 Str haystack(&scope, runtime_->newStrFromCStr("hello world")); 1491 Str needle(&scope, SmallStr::fromCStr("llo")); 1492 EXPECT_EQ(haystack.occurrencesOf(*needle), 1); 1493} 1494 1495TEST_F(LargeStrTest, OccurrencesOfWithSmallStrMultipleOccurrencesFindsAll) { 1496 HandleScope scope(thread_); 1497 Str haystack(&scope, runtime_->newStrFromCStr("hello hello")); 1498 Str needle(&scope, SmallStr::fromCStr("llo")); 1499 EXPECT_EQ(haystack.occurrencesOf(*needle), 2); 1500} 1501 1502TEST_F(LargeStrTest, OccurrencesOfWithSmallStrUsesCorrectEndian) { 1503 HandleScope scope(thread_); 1504 Str haystack(&scope, runtime_->newStrFromCStr("ababababab")); 1505 Str needle(&scope, SmallStr::fromCStr("ab")); 1506 EXPECT_EQ(haystack.occurrencesOf(*needle), 5); 1507} 1508 1509TEST_F(StringTest, ReverseOffsetByCodePointsEmptyString) { 1510 HandleScope scope(thread_); 1511 Str empty(&scope, Str::empty()); 1512 1513 word i = empty.length(); 1514 ASSERT_EQ(0, i); 1515 1516 EXPECT_EQ(-1, empty.offsetByCodePoints(i, -1)); 1517} 1518 1519TEST_F(StringTest, ReverseOffsetByCodePointsStringLength1) { 1520 HandleScope scope(thread_); 1521 1522 Str str1(&scope, runtime_->newStrFromCStr("1")); 1523 word len = str1.length(); 1524 ASSERT_EQ(1, len); 1525 1526 EXPECT_EQ(1, str1.offsetByCodePoints(len, 0)); 1527 EXPECT_EQ(0, str1.offsetByCodePoints(len, -1)); 1528 EXPECT_EQ(-1, str1.offsetByCodePoints(len, -2)); 1529} 1530 1531TEST_F(StringTest, ReverseOffsetByCodePointsStringLength3) { 1532 HandleScope scope(thread_); 1533 1534 Str str3(&scope, runtime_->newStrFromCStr("123")); 1535 word len = str3.length(); 1536 ASSERT_EQ(3, len); 1537 1538 EXPECT_EQ(2, str3.offsetByCodePoints(len, -1)); 1539 EXPECT_EQ(1, str3.offsetByCodePoints(len, -2)); 1540 EXPECT_EQ(0, str3.offsetByCodePoints(len, -3)); 1541 EXPECT_EQ(-1, str3.offsetByCodePoints(len, -4)); 1542 1543 EXPECT_EQ(1, str3.offsetByCodePoints(len - 1, -1)); 1544 EXPECT_EQ(0, str3.offsetByCodePoints(len - 1, -2)); 1545 EXPECT_EQ(-1, str3.offsetByCodePoints(len - 1, -3)); 1546 EXPECT_EQ(-1, str3.offsetByCodePoints(len - 1, -4)); 1547 1548 EXPECT_EQ(0, str3.offsetByCodePoints(len - 2, -1)); 1549 EXPECT_EQ(-1, str3.offsetByCodePoints(len - 2, -2)); 1550 EXPECT_EQ(-1, str3.offsetByCodePoints(len - 2, -3)); 1551 EXPECT_EQ(-1, str3.offsetByCodePoints(len - 2, -4)); 1552} 1553 1554TEST_F(StringTest, ReverseOffsetByCodePointsUnicodeStringLength5) { 1555 HandleScope scope(thread_); 1556 1557 Str str5(&scope, runtime_->newStrFromCStr("\x41\xD7\x91\xD7\x92")); 1558 word len = str5.length(); 1559 ASSERT_EQ(5, len); 1560 1561 EXPECT_EQ(3, str5.offsetByCodePoints(len, -1)); 1562 EXPECT_EQ(1, str5.offsetByCodePoints(len, -2)); 1563 EXPECT_EQ(0, str5.offsetByCodePoints(len, -3)); 1564 EXPECT_EQ(-1, str5.offsetByCodePoints(len, -4)); 1565 1566 EXPECT_EQ(1, str5.offsetByCodePoints(len - 2, -1)); 1567 EXPECT_EQ(0, str5.offsetByCodePoints(len - 2, -2)); 1568 EXPECT_EQ(-1, str5.offsetByCodePoints(len - 2, -3)); 1569 EXPECT_EQ(-1, str5.offsetByCodePoints(len - 2, -4)); 1570 1571 EXPECT_EQ(0, str5.offsetByCodePoints(len - 4, -1)); 1572 EXPECT_EQ(-1, str5.offsetByCodePoints(len - 4, -2)); 1573 EXPECT_EQ(-1, str5.offsetByCodePoints(len - 4, -3)); 1574 EXPECT_EQ(-1, str5.offsetByCodePoints(len - 4, -4)); 1575} 1576 1577TEST_F(StringTest, ToCString) { 1578 HandleScope scope(thread_); 1579 1580 Str empty(&scope, Str::empty()); 1581 char* c_empty = empty.toCStr(); 1582 ASSERT_NE(c_empty, nullptr); 1583 EXPECT_STREQ(c_empty, ""); 1584 std::free(c_empty); 1585 1586 Str length1(&scope, runtime_->newStrFromCStr("a")); 1587 char* c_length1 = length1.toCStr(); 1588 ASSERT_NE(c_length1, nullptr); 1589 EXPECT_STREQ(c_length1, "a"); 1590 std::free(c_length1); 1591 1592 Str length2(&scope, runtime_->newStrFromCStr("ab")); 1593 char* c_length2 = length2.toCStr(); 1594 ASSERT_NE(c_length2, nullptr); 1595 EXPECT_STREQ(c_length2, "ab"); 1596 std::free(c_length2); 1597 1598 Str length10(&scope, runtime_->newStrFromCStr("1234567890")); 1599 char* c_length10 = length10.toCStr(); 1600 ASSERT_NE(c_length10, nullptr); 1601 EXPECT_STREQ(c_length10, "1234567890"); 1602 std::free(c_length10); 1603 1604 Str nulchar(&scope, runtime_->newStrFromCStr("wx\0yz")); 1605 char* c_nulchar = nulchar.toCStr(); 1606 ASSERT_NE(c_nulchar, nullptr); 1607 EXPECT_STREQ(c_nulchar, "wx"); 1608 std::free(c_nulchar); 1609} 1610 1611TEST_F(StringTest, CompareSmallStr) { 1612 HandleScope scope(thread_); 1613 1614 Str small(&scope, runtime_->newStrFromCStr("foo")); 1615 EXPECT_TRUE(small.isSmallStr()); 1616 1617 EXPECT_TRUE(small.equalsCStr("foo")); 1618 // This apparently stupid test is in response to a bug where we assumed 1619 // that the c-string passed to SmallStr::equalsCStr would always 1620 // be small itself. 1621 EXPECT_FALSE(small.equalsCStr("123456789")); 1622} 1623 1624TEST_F(StringTest, CompareWithUnicode) { 1625 HandleScope scope(thread_); 1626 Str small(&scope, runtime_->newStrFromCStr(u8"hello\u2028")); 1627 EXPECT_TRUE(small.equalsCStr("hello\u2028")); 1628} 1629 1630TEST_F(ValueCellTest, SetPlaceholderRendersIsPlaceholderToReturnTrue) { 1631 HandleScope scope(thread_); 1632 ValueCell value_cell(&scope, runtime_->newValueCell()); 1633 ASSERT_FALSE(value_cell.isPlaceholder()); 1634 value_cell.makePlaceholder(); 1635 EXPECT_TRUE(value_cell.isPlaceholder()); 1636} 1637 1638TEST_F(WeakRefTest, EnqueueAndDequeue) { 1639 HandleScope scope(thread_); 1640 RawObject list = NoneType::object(); 1641 Object o0(&scope, runtime_->newList()); 1642 Object o1(&scope, runtime_->newList()); 1643 Object o2(&scope, runtime_->newList()); 1644 1645 WeakRef::enqueue(runtime_->newWeakRef(thread_, o0), &list); 1646 WeakRef::enqueue(runtime_->newWeakRef(thread_, o1), &list); 1647 WeakRef::enqueue(runtime_->newWeakRef(thread_, o2), &list); 1648 1649 WeakRef weak(&scope, WeakRef::dequeue(&list)); 1650 EXPECT_EQ(weak.referent(), o0); 1651 1652 weak = WeakRef::dequeue(&list); 1653 EXPECT_EQ(weak.referent(), o1); 1654 1655 weak = WeakRef::dequeue(&list); 1656 EXPECT_EQ(weak.referent(), o2); 1657 1658 EXPECT_EQ(list, NoneType::object()); 1659} 1660 1661TEST_F(WeakRefTest, SpliceQueue) { 1662 HandleScope scope(thread_); 1663 RawObject list1 = NoneType::object(); 1664 RawObject list2 = NoneType::object(); 1665 EXPECT_EQ(WeakRef::spliceQueue(list1, list2), NoneType::object()); 1666 1667 Object none(&scope, NoneType::object()); 1668 RawObject list3 = runtime_->newWeakRef(thread_, none); 1669 WeakRef::cast(list3).setLink(list3); 1670 EXPECT_EQ(WeakRef::spliceQueue(list1, list3), list3); 1671 EXPECT_EQ(WeakRef::spliceQueue(list3, list2), list3); 1672 1673 Object o0(&scope, runtime_->newDict()); 1674 Object o1(&scope, runtime_->newDict()); 1675 Object o2(&scope, runtime_->newDict()); 1676 Object o3(&scope, runtime_->newDict()); 1677 1678 WeakRef::enqueue(runtime_->newWeakRef(thread_, o0), &list1); 1679 WeakRef::enqueue(runtime_->newWeakRef(thread_, o2), &list2); 1680 WeakRef::enqueue(runtime_->newWeakRef(thread_, o1), &list1); 1681 WeakRef::enqueue(runtime_->newWeakRef(thread_, o3), &list2); 1682 1683 RawObject list = WeakRef::spliceQueue(list1, list2); 1684 WeakRef weak(&scope, WeakRef::dequeue(&list)); 1685 EXPECT_EQ(weak.referent(), o0); 1686 1687 weak = WeakRef::dequeue(&list); 1688 EXPECT_EQ(weak.referent(), o1); 1689 1690 weak = WeakRef::dequeue(&list); 1691 EXPECT_EQ(weak.referent(), o2); 1692 1693 weak = WeakRef::dequeue(&list); 1694 EXPECT_EQ(weak.referent(), o3); 1695 1696 EXPECT_EQ(list, NoneType::object()); 1697} 1698 1699TEST_F(ListTest, ReplaceFromWithReplacesElementsStartingAtZero) { 1700 HandleScope scope(thread_); 1701 List dst(&scope, runtime_->newList()); 1702 Tuple dst_tuple(&scope, runtime_->newMutableTuple(5)); 1703 dst.setItems(*dst_tuple); 1704 dst.setNumItems(5); 1705 List src(&scope, listFromRange(0, 5)); 1706 dst.replaceFromWith(0, *src, 2); 1707 ASSERT_EQ(dst.numItems(), 5); 1708 EXPECT_TRUE(isIntEqualsWord(dst.at(0), 0)); 1709 EXPECT_TRUE(isIntEqualsWord(dst.at(1), 1)); 1710 EXPECT_EQ(dst.at(2), SmallInt::fromWord(0)); 1711 EXPECT_EQ(dst.at(3), SmallInt::fromWord(0)); 1712 EXPECT_EQ(dst.at(4), SmallInt::fromWord(0)); 1713} 1714 1715TEST_F(ListTest, ReplaceFromWithReplacesElementsStartingInMiddle) { 1716 HandleScope scope(thread_); 1717 List dst(&scope, runtime_->newList()); 1718 Tuple dst_tuple(&scope, runtime_->newMutableTuple(5)); 1719 dst.setItems(*dst_tuple); 1720 dst.setNumItems(5); 1721 List src(&scope, listFromRange(0, 5)); 1722 dst.replaceFromWith(1, *src, 2); 1723 ASSERT_EQ(dst.numItems(), 5); 1724 EXPECT_EQ(dst.at(0), SmallInt::fromWord(0)); 1725 EXPECT_TRUE(isIntEqualsWord(dst.at(1), 0)); 1726 EXPECT_TRUE(isIntEqualsWord(dst.at(2), 1)); 1727 EXPECT_EQ(dst.at(3), SmallInt::fromWord(0)); 1728 EXPECT_EQ(dst.at(4), SmallInt::fromWord(0)); 1729} 1730 1731TEST_F(ListTest, ReplaceFromWithCopiesZeroElements) { 1732 HandleScope scope(thread_); 1733 List dst(&scope, runtime_->newList()); 1734 Tuple dst_tuple(&scope, runtime_->newMutableTuple(5)); 1735 dst.setItems(*dst_tuple); 1736 dst.setNumItems(5); 1737 List src(&scope, listFromRange(0, 5)); 1738 dst.replaceFromWith(0, *src, 0); 1739 ASSERT_EQ(dst.numItems(), 5); 1740 EXPECT_EQ(dst.at(0), SmallInt::fromWord(0)); 1741 EXPECT_EQ(dst.at(1), SmallInt::fromWord(0)); 1742 EXPECT_EQ(dst.at(2), SmallInt::fromWord(0)); 1743 EXPECT_EQ(dst.at(3), SmallInt::fromWord(0)); 1744 EXPECT_EQ(dst.at(4), SmallInt::fromWord(0)); 1745} 1746 1747TEST_F(ListTest, ReplaceFromWithCopiesEveryElementFromSrc) { 1748 HandleScope scope(thread_); 1749 List dst(&scope, runtime_->newList()); 1750 Tuple dst_tuple(&scope, runtime_->newMutableTuple(5)); 1751 dst.setItems(*dst_tuple); 1752 dst.setNumItems(5); 1753 List src(&scope, listFromRange(0, 5)); 1754 dst.replaceFromWith(0, *src, 5); 1755 ASSERT_EQ(dst.numItems(), 5); 1756 EXPECT_TRUE(isIntEqualsWord(dst.at(0), 0)); 1757 EXPECT_TRUE(isIntEqualsWord(dst.at(1), 1)); 1758 EXPECT_TRUE(isIntEqualsWord(dst.at(2), 2)); 1759 EXPECT_TRUE(isIntEqualsWord(dst.at(3), 3)); 1760 EXPECT_TRUE(isIntEqualsWord(dst.at(4), 4)); 1761} 1762 1763TEST_F(ListTest, ReplaceFromWithStartAtReplacesElementsStartingAtSrcStart) { 1764 HandleScope scope(thread_); 1765 List dst(&scope, runtime_->newList()); 1766 Tuple dst_tuple(&scope, runtime_->newMutableTuple(5)); 1767 dst.setItems(*dst_tuple); 1768 dst.setNumItems(5); 1769 List src(&scope, listFromRange(0, 5)); 1770 dst.replaceFromWithStartAt(0, *src, 2, 2); 1771 ASSERT_EQ(dst.numItems(), 5); 1772 EXPECT_TRUE(isIntEqualsWord(dst.at(0), 2)); 1773 EXPECT_TRUE(isIntEqualsWord(dst.at(1), 3)); 1774 EXPECT_EQ(dst.at(2), SmallInt::fromWord(0)); 1775 EXPECT_EQ(dst.at(3), SmallInt::fromWord(0)); 1776 EXPECT_EQ(dst.at(4), SmallInt::fromWord(0)); 1777} 1778 1779TEST_F(ListTest, ReplaceFromWithStartAtWithSelfNoop) { 1780 HandleScope scope(thread_); 1781 List dst(&scope, listFromRange(0, 5)); 1782 dst.replaceFromWithStartAt(0, *dst, 2, 0); 1783 EXPECT_PYLIST_EQ(dst, {0, 1, 2, 3, 4}); 1784} 1785 1786TEST_F(ListTest, ReplaceFromWithStartAtWithSelfBackward) { 1787 HandleScope scope(thread_); 1788 List dst(&scope, listFromRange(0, 5)); 1789 dst.replaceFromWithStartAt(0, *dst, 2, 2); 1790 EXPECT_PYLIST_EQ(dst, {2, 3, 2, 3, 4}); 1791} 1792 1793TEST_F(ListTest, ReplaceFromWithStartAtWithSelfForward) { 1794 HandleScope scope(thread_); 1795 List dst(&scope, listFromRange(0, 5)); 1796 dst.replaceFromWithStartAt(2, *dst, 2, 0); 1797 EXPECT_PYLIST_EQ(dst, {0, 1, 0, 1, 4}); 1798} 1799 1800TEST_F(ListTest, SwapSwapsElementsAtIndices) { 1801 HandleScope scope(thread_); 1802 List src(&scope, listFromRange(0, 5)); 1803 EXPECT_PYLIST_EQ(src, {0, 1, 2, 3, 4}); 1804 src.swap(1, 3); 1805 EXPECT_PYLIST_EQ(src, {0, 3, 2, 1, 4}); 1806} 1807 1808TEST_F(MutableTupleTest, NoneFillTupleFillsTupleWithNone) { 1809 HandleScope scope(thread_); 1810 MutableTuple tuple(&scope, runtime_->newMutableTuple(3)); 1811 tuple.atPut(0, SmallInt::fromWord(0)); 1812 tuple.atPut(1, SmallInt::fromWord(1)); 1813 tuple.atPut(2, SmallInt::fromWord(2)); 1814 tuple.fill(NoneType::object()); 1815 EXPECT_EQ(tuple.at(0), NoneType::object()); 1816 EXPECT_EQ(tuple.at(1), NoneType::object()); 1817 EXPECT_EQ(tuple.at(2), NoneType::object()); 1818} 1819 1820TEST_F(MutableTupleTest, ReplaceFromWithReplacesElementsStartingAtZero) { 1821 HandleScope scope(thread_); 1822 MutableTuple dst(&scope, runtime_->newMutableTuple(5)); 1823 List src(&scope, listFromRange(0, 5)); 1824 Tuple src_items(&scope, src.items()); 1825 dst.replaceFromWith(0, *src_items, 2); 1826 EXPECT_TRUE(isIntEqualsWord(dst.at(0), 0)); 1827 EXPECT_TRUE(isIntEqualsWord(dst.at(1), 1)); 1828 EXPECT_EQ(dst.at(2), SmallInt::fromWord(0)); 1829 EXPECT_EQ(dst.at(3), SmallInt::fromWord(0)); 1830 EXPECT_EQ(dst.at(4), SmallInt::fromWord(0)); 1831} 1832 1833TEST_F(MutableTupleTest, ReplaceFromWithReplacesElementsStartingInMiddle) { 1834 HandleScope scope(thread_); 1835 MutableTuple dst(&scope, runtime_->newMutableTuple(5)); 1836 List src(&scope, listFromRange(0, 5)); 1837 Tuple src_items(&scope, src.items()); 1838 dst.replaceFromWith(1, *src_items, 2); 1839 EXPECT_EQ(dst.at(0), SmallInt::fromWord(0)); 1840 EXPECT_TRUE(isIntEqualsWord(dst.at(1), 0)); 1841 EXPECT_TRUE(isIntEqualsWord(dst.at(2), 1)); 1842 EXPECT_EQ(dst.at(3), SmallInt::fromWord(0)); 1843 EXPECT_EQ(dst.at(4), SmallInt::fromWord(0)); 1844} 1845 1846TEST_F(MutableTupleTest, ReplaceFromWithCopiesZeroElements) { 1847 HandleScope scope(thread_); 1848 MutableTuple dst(&scope, runtime_->newMutableTuple(5)); 1849 List src(&scope, listFromRange(0, 5)); 1850 Tuple src_items(&scope, src.items()); 1851 dst.replaceFromWith(0, *src_items, 0); 1852 EXPECT_EQ(dst.at(0), SmallInt::fromWord(0)); 1853 EXPECT_EQ(dst.at(1), SmallInt::fromWord(0)); 1854 EXPECT_EQ(dst.at(2), SmallInt::fromWord(0)); 1855 EXPECT_EQ(dst.at(3), SmallInt::fromWord(0)); 1856 EXPECT_EQ(dst.at(4), SmallInt::fromWord(0)); 1857} 1858 1859TEST_F(MutableTupleTest, ReplaceFromWithCopiesEveryElementFromSrc) { 1860 HandleScope scope(thread_); 1861 MutableTuple dst(&scope, runtime_->newMutableTuple(5)); 1862 List src(&scope, listFromRange(0, 5)); 1863 Tuple src_items(&scope, src.items()); 1864 dst.replaceFromWith(0, *src_items, 5); 1865 EXPECT_TRUE(isIntEqualsWord(dst.at(0), 0)); 1866 EXPECT_TRUE(isIntEqualsWord(dst.at(1), 1)); 1867 EXPECT_TRUE(isIntEqualsWord(dst.at(2), 2)); 1868 EXPECT_TRUE(isIntEqualsWord(dst.at(3), 3)); 1869 EXPECT_TRUE(isIntEqualsWord(dst.at(4), 4)); 1870} 1871 1872TEST_F(MutableTupleTest, ReplaceFromWithStartAtWithSelfNoop) { 1873 HandleScope scope(thread_); 1874 List dst_list(&scope, listFromRange(0, 5)); 1875 MutableTuple dst(&scope, dst_list.items()); 1876 dst.replaceFromWithStartAt(0, *dst, 2, 0); 1877 EXPECT_PYLIST_EQ(dst_list, {0, 1, 2, 3, 4}); 1878} 1879 1880TEST_F(MutableTupleTest, ReplaceFromWithStartAtWithSelfBackward) { 1881 HandleScope scope(thread_); 1882 List dst_list(&scope, listFromRange(0, 5)); 1883 MutableTuple dst(&scope, dst_list.items()); 1884 dst.replaceFromWithStartAt(0, *dst, 2, 2); 1885 EXPECT_PYLIST_EQ(dst_list, {2, 3, 2, 3, 4}); 1886} 1887 1888TEST_F(MutableTupleTest, ReplaceFromWithStartAtWithSelfForward) { 1889 HandleScope scope(thread_); 1890 List dst_list(&scope, listFromRange(0, 5)); 1891 MutableTuple dst(&scope, dst_list.items()); 1892 dst.replaceFromWithStartAt(2, *dst, 2, 0); 1893 EXPECT_PYLIST_EQ(dst_list, {0, 1, 0, 1, 4}); 1894} 1895 1896TEST_F(MutableTupleTest, 1897 ReplaceFromWithStartAtReplacesElementsStartingAtSrcStart) { 1898 HandleScope scope(thread_); 1899 MutableTuple dst(&scope, runtime_->newMutableTuple(5)); 1900 List src_list(&scope, listFromRange(0, 5)); 1901 Tuple src(&scope, src_list.items()); 1902 dst.replaceFromWithStartAt(0, *src, 2, 2); 1903 EXPECT_TRUE(isIntEqualsWord(dst.at(0), 2)); 1904 EXPECT_TRUE(isIntEqualsWord(dst.at(1), 3)); 1905 EXPECT_EQ(dst.at(2), SmallInt::fromWord(0)); 1906 EXPECT_EQ(dst.at(3), SmallInt::fromWord(0)); 1907 EXPECT_EQ(dst.at(4), SmallInt::fromWord(0)); 1908} 1909 1910TEST_F(MutableTupleTest, SwapSwapsElementsAtIndices) { 1911 HandleScope scope(thread_); 1912 List src_list(&scope, listFromRange(0, 5)); 1913 MutableTuple src(&scope, src_list.items()); 1914 EXPECT_PYLIST_EQ(src_list, {0, 1, 2, 3, 4}); 1915 src.swap(1, 3); 1916 EXPECT_PYLIST_EQ(src_list, {0, 3, 2, 1, 4}); 1917} 1918 1919TEST(ErrorTest, ErrorIsError) { 1920 EXPECT_TRUE(Error::error().isError()); 1921 1922 EXPECT_TRUE(Error::exception().isError()); 1923 EXPECT_TRUE(Error::exception().isErrorException()); 1924 1925 EXPECT_TRUE(Error::notFound().isError()); 1926 EXPECT_TRUE(Error::notFound().isErrorNotFound()); 1927 1928 EXPECT_TRUE(Error::noMoreItems().isError()); 1929 EXPECT_TRUE(Error::noMoreItems().isErrorNoMoreItems()); 1930 1931 EXPECT_TRUE(Error::outOfMemory().isError()); 1932 EXPECT_TRUE(Error::outOfMemory().isErrorOutOfMemory()); 1933 1934 EXPECT_TRUE(Error::outOfBounds().isError()); 1935 EXPECT_TRUE(Error::outOfBounds().isErrorOutOfBounds()); 1936} 1937 1938TEST(ErrorTest, ErrorHasCorrectKind) { 1939 EXPECT_EQ(Error::error().kind(), ErrorKind::kNone); 1940 EXPECT_EQ(Error::exception().kind(), ErrorKind::kException); 1941 EXPECT_EQ(Error::notFound().kind(), ErrorKind::kNotFound); 1942 EXPECT_EQ(Error::noMoreItems().kind(), ErrorKind::kNoMoreItems); 1943 EXPECT_EQ(Error::outOfMemory().kind(), ErrorKind::kOutOfMemory); 1944 EXPECT_EQ(Error::outOfBounds().kind(), ErrorKind::kOutOfBounds); 1945} 1946 1947} // namespace testing 1948} // namespace py