this repo has no description
at trunk 1170 lines 46 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "bytearray-builtins.h" 3 4#include "gtest/gtest.h" 5 6#include "builtins.h" 7#include "test-utils.h" 8 9namespace py { 10namespace testing { 11 12using BytearrayBuiltinsTest = RuntimeFixture; 13 14TEST_F(BytearrayBuiltinsTest, Add) { 15 HandleScope scope(thread_); 16 17 Bytearray array(&scope, runtime_->newBytearray()); 18 bytearrayAdd(thread_, runtime_, array, 0); 19 bytearrayAdd(thread_, runtime_, array, 1); 20 bytearrayAdd(thread_, runtime_, array, 2); 21 EXPECT_GE(array.capacity(), 3); 22 EXPECT_EQ(array.numItems(), 3); 23 EXPECT_EQ(array.byteAt(0), 0); 24 EXPECT_EQ(array.byteAt(1), 1); 25 EXPECT_EQ(array.byteAt(2), 2); 26} 27 28TEST_F(BytearrayBuiltinsTest, AsBytes) { 29 HandleScope scope(thread_); 30 31 Bytearray array(&scope, runtime_->newBytearray()); 32 Bytes bytes(&scope, bytearrayAsBytes(thread_, array)); 33 EXPECT_TRUE(isBytesEqualsBytes(bytes, View<byte>(nullptr, 0))); 34 35 array.setItems(runtime_->mutableBytesWith(10, 0)); 36 array.setNumItems(3); 37 bytes = bytearrayAsBytes(thread_, array); 38 const byte expected_bytes[] = {0, 0, 0}; 39 EXPECT_TRUE(isBytesEqualsBytes(bytes, expected_bytes)); 40} 41 42TEST_F(BytearrayBuiltinsTest, ClearSetsLengthToZero) { 43 HandleScope scope(thread_); 44 ASSERT_FALSE(runFromCStr(runtime_, R"( 45array = bytearray(b'foo') 46array.clear() 47)") 48 .isError()); 49 Bytearray array(&scope, mainModuleAt(runtime_, "array")); 50 EXPECT_EQ(array.numItems(), 0); 51} 52 53TEST_F(BytearrayBuiltinsTest, DunderAddWithNonBytesLikeRaisesTypeError) { 54 EXPECT_TRUE(raisedWithStr( 55 runFromCStr(runtime_, "bytearray(b'') + None"), LayoutId::kTypeError, 56 "can only concatenate bytearray or bytes to bytearray")); 57} 58 59TEST_F(BytearrayBuiltinsTest, DunderAddWithBytearrayOtherReturnsNewBytearray) { 60 HandleScope scope(thread_); 61 Bytearray self(&scope, runtime_->newBytearray()); 62 Bytearray other(&scope, runtime_->newBytearray()); 63 const byte byte_array[] = {'1', '2', '3'}; 64 runtime_->bytearrayExtend(thread_, other, byte_array); 65 Object result(&scope, runBuiltin(METH(bytearray, __add__), self, other)); 66 EXPECT_TRUE(isBytearrayEqualsCStr(self, "")); 67 EXPECT_TRUE(isBytearrayEqualsCStr(result, "123")); 68} 69 70TEST_F(BytearrayBuiltinsTest, DunderAddWithBytesOtherReturnsNewBytearray) { 71 HandleScope scope(thread_); 72 Bytearray self(&scope, runtime_->newBytearray()); 73 Bytes other(&scope, runtime_->newBytes(4, '1')); 74 Object result(&scope, runBuiltin(METH(bytearray, __add__), self, other)); 75 EXPECT_TRUE(isBytearrayEqualsCStr(self, "")); 76 EXPECT_TRUE(isBytearrayEqualsCStr(result, "1111")); 77} 78 79TEST_F(BytearrayBuiltinsTest, 80 DunderAddWithBytesSubclassOtherReturnsNewBytearray) { 81 ASSERT_FALSE(runFromCStr(runtime_, R"( 82class Foo(bytes): pass 83other = Foo(b"1234") 84)") 85 .isError()); 86 HandleScope scope(thread_); 87 Object self(&scope, runtime_->newBytearray()); 88 Object other(&scope, mainModuleAt(runtime_, "other")); 89 Object result(&scope, runBuiltin(METH(bytearray, __add__), self, other)); 90 EXPECT_TRUE(isBytearrayEqualsCStr(self, "")); 91 EXPECT_TRUE(isBytearrayEqualsCStr(result, "1234")); 92} 93 94TEST_F(BytearrayBuiltinsTest, DunderAddReturnsConcatenatedBytearray) { 95 HandleScope scope(thread_); 96 Bytearray self(&scope, runtime_->newBytearray()); 97 const byte byte_array[] = {'f', 'o', 'o'}; 98 runtime_->bytearrayExtend(thread_, self, byte_array); 99 Bytes other(&scope, runtime_->newBytes(1, 'd')); 100 Object result(&scope, runBuiltin(METH(bytearray, __add__), self, other)); 101 EXPECT_TRUE(isBytearrayEqualsCStr(self, "foo")); 102 EXPECT_TRUE(isBytearrayEqualsCStr(result, "food")); 103} 104 105TEST_F(BytearrayBuiltinsTest, DunderEqWithNonBytesOtherReturnsNotImplemented) { 106 HandleScope scope(thread_); 107 Object self(&scope, runtime_->newBytearray()); 108 Object other(&scope, SmallInt::fromWord(0)); 109 Object result(&scope, runBuiltin(METH(bytearray, __eq__), self, other)); 110 EXPECT_TRUE(result.isNotImplementedType()); 111} 112 113TEST_F(BytearrayBuiltinsTest, DunderEqWithEmptyBytearraysReturnsTrue) { 114 HandleScope scope(thread_); 115 Object self(&scope, runtime_->newBytearray()); 116 Object other(&scope, runtime_->newBytearray()); 117 EXPECT_EQ(runBuiltin(METH(bytearray, __eq__), self, other), Bool::trueObj()); 118} 119 120TEST_F(BytearrayBuiltinsTest, DunderEqWithEqualBytesReturnsTrue) { 121 HandleScope scope(thread_); 122 const byte bytes[] = {'f', 'o', 'o'}; 123 Bytearray self(&scope, runtime_->newBytearray()); 124 runtime_->bytearrayExtend(thread_, self, bytes); 125 Object other(&scope, runtime_->newBytesWithAll(bytes)); 126 EXPECT_EQ(runBuiltin(METH(bytearray, __eq__), self, other), Bool::trueObj()); 127} 128 129TEST_F(BytearrayBuiltinsTest, DunderEqWithEqualBytearrayReturnsTrue) { 130 HandleScope scope(thread_); 131 const byte bytes[] = {'f', 'o', 'o'}; 132 Bytearray self(&scope, runtime_->newBytearray()); 133 Bytearray other(&scope, runtime_->newBytearray()); 134 runtime_->bytearrayExtend(thread_, self, bytes); 135 runtime_->bytearrayExtend(thread_, other, bytes); 136 EXPECT_EQ(runBuiltin(METH(bytearray, __eq__), self, other), Bool::trueObj()); 137} 138 139TEST_F(BytearrayBuiltinsTest, DunderEqWithDifferentLengthsReturnsFalse) { 140 HandleScope scope(thread_); 141 const byte bytes[] = {'f', 'o', 'o'}; 142 Bytearray self(&scope, runtime_->newBytearray()); 143 Bytearray other(&scope, runtime_->newBytearray()); 144 runtime_->bytearrayExtend(thread_, self, bytes); 145 runtime_->bytearrayExtend(thread_, other, {bytes, 2}); 146 EXPECT_EQ(runBuiltin(METH(bytearray, __eq__), self, other), Bool::falseObj()); 147} 148 149TEST_F(BytearrayBuiltinsTest, DunderEqWithDifferentContentsReturnsFalse) { 150 HandleScope scope(thread_); 151 const byte bytes[] = {'f', 'o', 'o'}; 152 Bytearray self(&scope, runtime_->newBytearray()); 153 runtime_->bytearrayExtend(thread_, self, bytes); 154 Object other(&scope, runtime_->newBytes(3, 'f')); 155 EXPECT_EQ(runBuiltin(METH(bytearray, __eq__), self, other), Bool::falseObj()); 156} 157 158TEST_F(BytearrayBuiltinsTest, DunderGeWithNonBytesOtherReturnsNotImplemented) { 159 HandleScope scope(thread_); 160 Object self(&scope, runtime_->newBytearray()); 161 Object other(&scope, SmallInt::fromWord(0)); 162 Object result(&scope, runBuiltin(METH(bytearray, __ge__), self, other)); 163 EXPECT_TRUE(result.isNotImplementedType()); 164} 165 166TEST_F(BytearrayBuiltinsTest, DunderGeWithEmptyBytearraysReturnsTrue) { 167 HandleScope scope(thread_); 168 Object self(&scope, runtime_->newBytearray()); 169 Object other(&scope, runtime_->newBytearray()); 170 EXPECT_EQ(runBuiltin(METH(bytearray, __ge__), self, other), Bool::trueObj()); 171} 172 173TEST_F(BytearrayBuiltinsTest, DunderGeithEqualBytesReturnsTrue) { 174 HandleScope scope(thread_); 175 const byte bytes[] = {'f', 'o', 'o'}; 176 Bytearray self(&scope, runtime_->newBytearray()); 177 runtime_->bytearrayExtend(thread_, self, bytes); 178 Object other(&scope, runtime_->newBytesWithAll(bytes)); 179 EXPECT_EQ(runBuiltin(METH(bytearray, __ge__), self, other), Bool::trueObj()); 180} 181 182TEST_F(BytearrayBuiltinsTest, DunderGeWithEqualBytearrayReturnsTrue) { 183 HandleScope scope(thread_); 184 const byte bytes[] = {'f', 'o', 'o'}; 185 Bytearray self(&scope, runtime_->newBytearray()); 186 Bytearray other(&scope, runtime_->newBytearray()); 187 runtime_->bytearrayExtend(thread_, self, bytes); 188 runtime_->bytearrayExtend(thread_, other, bytes); 189 EXPECT_EQ(runBuiltin(METH(bytearray, __ge__), self, other), Bool::trueObj()); 190} 191 192TEST_F(BytearrayBuiltinsTest, DunderGeWithLongerOtherReturnsFalse) { 193 HandleScope scope(thread_); 194 const byte bytes[] = {'f', 'o', 'o'}; 195 Bytearray self(&scope, runtime_->newBytearray()); 196 Bytearray other(&scope, runtime_->newBytearray()); 197 runtime_->bytearrayExtend(thread_, self, {bytes, 2}); 198 runtime_->bytearrayExtend(thread_, other, bytes); 199 EXPECT_EQ(runBuiltin(METH(bytearray, __ge__), self, other), Bool::falseObj()); 200} 201 202TEST_F(BytearrayBuiltinsTest, DunderGeWithShorterOtherReturnsTrue) { 203 HandleScope scope(thread_); 204 const byte bytes[] = {'f', 'o', 'o'}; 205 Bytearray self(&scope, runtime_->newBytearray()); 206 Bytearray other(&scope, runtime_->newBytearray()); 207 runtime_->bytearrayExtend(thread_, self, bytes); 208 runtime_->bytearrayExtend(thread_, other, {bytes, 2}); 209 EXPECT_EQ(runBuiltin(METH(bytearray, __ge__), self, other), Bool::trueObj()); 210} 211 212TEST_F(BytearrayBuiltinsTest, DunderGeWithEarlierOtherReturnsTrue) { 213 HandleScope scope(thread_); 214 const byte bytes[] = {'f', 'o', 'o'}; 215 Bytearray self(&scope, runtime_->newBytearray()); 216 runtime_->bytearrayExtend(thread_, self, bytes); 217 Object other(&scope, runtime_->newBytes(3, 'f')); 218 EXPECT_EQ(runBuiltin(METH(bytearray, __ge__), self, other), Bool::trueObj()); 219} 220 221TEST_F(BytearrayBuiltinsTest, DunderGeWithLaterOtherReturnsFalse) { 222 HandleScope scope(thread_); 223 const byte bytes[] = {'o', 'o', 'f'}; 224 Bytearray self(&scope, runtime_->newBytearray()); 225 runtime_->bytearrayExtend(thread_, self, bytes); 226 Object other(&scope, runtime_->newBytes(3, 'o')); 227 EXPECT_EQ(runBuiltin(METH(bytearray, __ge__), self, other), Bool::falseObj()); 228} 229 230TEST_F(BytearrayBuiltinsTest, DunderGtWithNonBytesOtherReturnsNotImplemented) { 231 HandleScope scope(thread_); 232 Object self(&scope, runtime_->newBytearray()); 233 Object other(&scope, SmallInt::fromWord(0)); 234 Object result(&scope, runBuiltin(METH(bytearray, __gt__), self, other)); 235 EXPECT_TRUE(result.isNotImplementedType()); 236} 237 238TEST_F(BytearrayBuiltinsTest, DunderGtWithEmptyBytearraysReturnsFalse) { 239 HandleScope scope(thread_); 240 Object self(&scope, runtime_->newBytearray()); 241 Object other(&scope, runtime_->newBytearray()); 242 EXPECT_EQ(runBuiltin(METH(bytearray, __gt__), self, other), Bool::falseObj()); 243} 244 245TEST_F(BytearrayBuiltinsTest, DunderGtithEqualBytesReturnsFalse) { 246 HandleScope scope(thread_); 247 const byte bytes[] = {'f', 'o', 'o'}; 248 Bytearray self(&scope, runtime_->newBytearray()); 249 runtime_->bytearrayExtend(thread_, self, bytes); 250 Object other(&scope, runtime_->newBytesWithAll(bytes)); 251 EXPECT_EQ(runBuiltin(METH(bytearray, __gt__), self, other), Bool::falseObj()); 252} 253 254TEST_F(BytearrayBuiltinsTest, DunderGtWithEqualBytearrayReturnsFalse) { 255 HandleScope scope(thread_); 256 const byte bytes[] = {'f', 'o', 'o'}; 257 Bytearray self(&scope, runtime_->newBytearray()); 258 Bytearray other(&scope, runtime_->newBytearray()); 259 runtime_->bytearrayExtend(thread_, self, bytes); 260 runtime_->bytearrayExtend(thread_, other, bytes); 261 EXPECT_EQ(runBuiltin(METH(bytearray, __gt__), self, other), Bool::falseObj()); 262} 263 264TEST_F(BytearrayBuiltinsTest, DunderGtWithLongerOtherReturnsFalse) { 265 HandleScope scope(thread_); 266 const byte bytes[] = {'f', 'o', 'o'}; 267 Bytearray self(&scope, runtime_->newBytearray()); 268 Bytearray other(&scope, runtime_->newBytearray()); 269 runtime_->bytearrayExtend(thread_, self, {bytes, 2}); 270 runtime_->bytearrayExtend(thread_, other, bytes); 271 EXPECT_EQ(runBuiltin(METH(bytearray, __gt__), self, other), Bool::falseObj()); 272} 273 274TEST_F(BytearrayBuiltinsTest, DunderGtWithShorterOtherReturnsTrue) { 275 HandleScope scope(thread_); 276 const byte bytes[] = {'f', 'o', 'o'}; 277 Bytearray self(&scope, runtime_->newBytearray()); 278 Bytearray other(&scope, runtime_->newBytearray()); 279 runtime_->bytearrayExtend(thread_, self, bytes); 280 runtime_->bytearrayExtend(thread_, other, {bytes, 2}); 281 EXPECT_EQ(runBuiltin(METH(bytearray, __gt__), self, other), Bool::trueObj()); 282} 283 284TEST_F(BytearrayBuiltinsTest, DunderGtWithEarlierOtherReturnsTrue) { 285 HandleScope scope(thread_); 286 const byte bytes[] = {'f', 'o', 'o'}; 287 Bytearray self(&scope, runtime_->newBytearray()); 288 runtime_->bytearrayExtend(thread_, self, bytes); 289 Object other(&scope, runtime_->newBytes(3, 'f')); 290 EXPECT_EQ(runBuiltin(METH(bytearray, __gt__), self, other), Bool::trueObj()); 291} 292 293TEST_F(BytearrayBuiltinsTest, DunderGtWithLaterOtherReturnsFalse) { 294 HandleScope scope(thread_); 295 const byte bytes[] = {'o', 'o', 'f'}; 296 Bytearray self(&scope, runtime_->newBytearray()); 297 runtime_->bytearrayExtend(thread_, self, bytes); 298 Object other(&scope, runtime_->newBytes(3, 'o')); 299 EXPECT_EQ(runBuiltin(METH(bytearray, __gt__), self, other), Bool::falseObj()); 300} 301 302TEST_F(BytearrayBuiltinsTest, DunderIaddWithNonBytesLikeRaisesTypeError) { 303 const char* test = R"( 304array = bytearray(b'') 305array += None 306)"; 307 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, test), LayoutId::kTypeError, 308 "can't concat NoneType to bytearray")); 309} 310 311TEST_F(BytearrayBuiltinsTest, DunderIaddWithBytearrayOtherConcatenatesToSelf) { 312 HandleScope scope(thread_); 313 Bytearray self(&scope, runtime_->newBytearray()); 314 Bytearray other(&scope, runtime_->newBytearray()); 315 const byte bytes[] = {'1', '2', '3'}; 316 runtime_->bytearrayExtend(thread_, other, bytes); 317 Object result(&scope, runBuiltin(METH(bytearray, __iadd__), self, other)); 318 EXPECT_TRUE(isBytearrayEqualsBytes(self, bytes)); 319 EXPECT_TRUE(isBytearrayEqualsBytes(result, bytes)); 320} 321 322TEST_F(BytearrayBuiltinsTest, DunderIaddWithBytesOtherConcatenatesToSelf) { 323 HandleScope scope(thread_); 324 Bytearray self(&scope, runtime_->newBytearray()); 325 const byte bytes[] = {'1', '2', '3'}; 326 Bytes other(&scope, runtime_->newBytesWithAll(bytes)); 327 Object result(&scope, runBuiltin(METH(bytearray, __iadd__), self, other)); 328 EXPECT_TRUE(isBytearrayEqualsBytes(self, bytes)); 329 EXPECT_TRUE(isBytearrayEqualsBytes(result, bytes)); 330} 331 332TEST_F(BytearrayBuiltinsTest, 333 DunderIaddWithBytesSubclassOtherConcatenatesToSelf) { 334 ASSERT_FALSE(runFromCStr(runtime_, R"( 335class Foo(bytes): pass 336other = Foo(b"1234") 337)") 338 .isError()); 339 HandleScope scope(thread_); 340 Object self(&scope, runtime_->newBytearray()); 341 Object other(&scope, mainModuleAt(runtime_, "other")); 342 Object result(&scope, runBuiltin(METH(bytearray, __iadd__), self, other)); 343 const char* expected = "1234"; 344 EXPECT_TRUE(isBytearrayEqualsCStr(self, expected)); 345 EXPECT_TRUE(isBytearrayEqualsCStr(result, expected)); 346} 347 348TEST_F(BytearrayBuiltinsTest, DunderImulWithNonIntRaisesTypeError) { 349 HandleScope scope(thread_); 350 Object self(&scope, runtime_->newBytearray()); 351 Object count(&scope, runtime_->newList()); 352 EXPECT_TRUE(raisedWithStr( 353 runBuiltin(METH(bytearray, __imul__), self, count), LayoutId::kTypeError, 354 "'list' object cannot be interpreted as an integer")); 355} 356 357TEST_F(BytearrayBuiltinsTest, DunderImulWithIntSubclassReturnsRepeatedBytes) { 358 HandleScope scope(thread_); 359 Bytearray self(&scope, runtime_->newBytearray()); 360 bytearrayAdd(thread_, runtime_, self, 'a'); 361 ASSERT_FALSE(runFromCStr(runtime_, R"( 362class C(int): pass 363count = C(5) 364)") 365 .isError()); 366 Object count(&scope, mainModuleAt(runtime_, "count")); 367 Object result(&scope, runBuiltin(METH(bytearray, __imul__), self, count)); 368 EXPECT_TRUE(isBytearrayEqualsCStr(result, "aaaaa")); 369} 370 371TEST_F(BytearrayBuiltinsTest, DunderImulWithDunderIndexReturnsRepeatedBytes) { 372 HandleScope scope(thread_); 373 Bytearray self(&scope, runtime_->newBytearray()); 374 bytearrayAdd(thread_, runtime_, self, 'a'); 375 ASSERT_FALSE(runFromCStr(runtime_, R"( 376class C: 377 def __index__(self): 378 return 2 379count = C() 380)") 381 .isError()); 382 Object count(&scope, mainModuleAt(runtime_, "count")); 383 Object result(&scope, runBuiltin(METH(bytearray, __imul__), self, count)); 384 EXPECT_TRUE(isBytearrayEqualsCStr(result, "aa")); 385} 386 387TEST_F(BytearrayBuiltinsTest, DunderImulWithBadDunderIndexRaisesTypeError) { 388 HandleScope scope(thread_); 389 Object self(&scope, runtime_->newBytearray()); 390 ASSERT_FALSE(runFromCStr(runtime_, R"( 391class C: 392 def __index__(self): 393 return "foo" 394count = C() 395)") 396 .isError()); 397 Object count(&scope, mainModuleAt(runtime_, "count")); 398 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytearray, __imul__), self, count), 399 LayoutId::kTypeError, 400 "__index__ returned non-int (type str)")); 401} 402 403TEST_F(BytearrayBuiltinsTest, DunderImulPropagatesDunderIndexError) { 404 HandleScope scope(thread_); 405 Object self(&scope, runtime_->newBytearray()); 406 ASSERT_FALSE(runFromCStr(runtime_, R"( 407class C: 408 def __index__(self): 409 raise ArithmeticError("called __index__") 410count = C() 411)") 412 .isError()); 413 Object count(&scope, mainModuleAt(runtime_, "count")); 414 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytearray, __imul__), self, count), 415 LayoutId::kArithmeticError, "called __index__")); 416} 417 418TEST_F(BytearrayBuiltinsTest, DunderImulWithLargeIntRaisesOverflowError) { 419 HandleScope scope(thread_); 420 Bytearray self(&scope, runtime_->newBytearray()); 421 const uword digits[] = {1, 1}; 422 Object count(&scope, runtime_->newLargeIntWithDigits(digits)); 423 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytearray, __imul__), self, count), 424 LayoutId::kOverflowError, 425 "cannot fit 'int' into an index-sized integer")); 426} 427 428TEST_F(BytearrayBuiltinsTest, DunderImulWithOverflowRaisesMemoryError) { 429 HandleScope scope(thread_); 430 Bytearray self(&scope, runtime_->newBytearray()); 431 const byte bytes[] = {'a', 'b', 'c'}; 432 runtime_->bytearrayExtend(thread_, self, bytes); 433 Object count(&scope, SmallInt::fromWord(SmallInt::kMaxValue / 2)); 434 EXPECT_TRUE(raised(runBuiltin(METH(bytearray, __imul__), self, count), 435 LayoutId::kMemoryError)); 436} 437 438TEST_F(BytearrayBuiltinsTest, 439 DunderImulWithEmptyBytearrayReturnsEmptyBytearray) { 440 HandleScope scope(thread_); 441 Object self(&scope, runtime_->newBytearray()); 442 Object count(&scope, SmallInt::fromWord(5)); 443 Object result(&scope, runBuiltin(METH(bytearray, __imul__), self, count)); 444 EXPECT_TRUE(isBytearrayEqualsCStr(result, "")); 445} 446 447TEST_F(BytearrayBuiltinsTest, DunderImulWithNegativeReturnsEmptyBytearray) { 448 HandleScope scope(thread_); 449 Bytearray self(&scope, runtime_->newBytearray()); 450 self.setItems(runtime_->mutableBytesWith(8, 'a')); 451 self.setNumItems(8); 452 Object count(&scope, SmallInt::fromWord(-5)); 453 Object result(&scope, runBuiltin(METH(bytearray, __imul__), self, count)); 454 EXPECT_TRUE(isBytearrayEqualsCStr(result, "")); 455} 456 457TEST_F(BytearrayBuiltinsTest, DunderImulWithZeroReturnsEmptyBytearray) { 458 HandleScope scope(thread_); 459 Bytearray self(&scope, runtime_->newBytearray()); 460 self.setItems(runtime_->mutableBytesWith(8, 'a')); 461 self.setNumItems(8); 462 Object count(&scope, SmallInt::fromWord(0)); 463 Object result(&scope, runBuiltin(METH(bytearray, __imul__), self, count)); 464 EXPECT_TRUE(isBytearrayEqualsCStr(result, "")); 465} 466 467TEST_F(BytearrayBuiltinsTest, DunderImulWithOneReturnsSameBytearray) { 468 HandleScope scope(thread_); 469 Bytearray self(&scope, runtime_->newBytearray()); 470 const byte bytes[] = {'a', 'b'}; 471 runtime_->bytearrayExtend(thread_, self, bytes); 472 Object count(&scope, SmallInt::fromWord(1)); 473 Object result(&scope, runBuiltin(METH(bytearray, __imul__), self, count)); 474 EXPECT_TRUE(isBytearrayEqualsBytes(result, bytes)); 475} 476 477TEST_F(BytearrayBuiltinsTest, DunderImulReturnsRepeatedBytearray) { 478 HandleScope scope(thread_); 479 Bytearray self(&scope, runtime_->newBytearray()); 480 const byte bytes[] = {'a', 'b'}; 481 runtime_->bytearrayExtend(thread_, self, bytes); 482 Object count(&scope, SmallInt::fromWord(3)); 483 Object result(&scope, runBuiltin(METH(bytearray, __imul__), self, count)); 484 EXPECT_TRUE(isBytearrayEqualsCStr(result, "ababab")); 485} 486 487TEST_F(BytearrayBuiltinsTest, DunderLeWithNonBytesOtherReturnsNotImplemented) { 488 HandleScope scope(thread_); 489 Object self(&scope, runtime_->newBytearray()); 490 Object other(&scope, SmallInt::fromWord(0)); 491 Object result(&scope, runBuiltin(METH(bytearray, __le__), self, other)); 492 EXPECT_TRUE(result.isNotImplementedType()); 493} 494 495TEST_F(BytearrayBuiltinsTest, DunderLeWithEmptyBytearraysReturnsTrue) { 496 HandleScope scope(thread_); 497 Object self(&scope, runtime_->newBytearray()); 498 Object other(&scope, runtime_->newBytearray()); 499 EXPECT_EQ(runBuiltin(METH(bytearray, __le__), self, other), Bool::trueObj()); 500} 501 502TEST_F(BytearrayBuiltinsTest, DunderLeithEqualBytesReturnsTrue) { 503 HandleScope scope(thread_); 504 const byte bytes[] = {'f', 'o', 'o'}; 505 Bytearray self(&scope, runtime_->newBytearray()); 506 runtime_->bytearrayExtend(thread_, self, bytes); 507 Object other(&scope, runtime_->newBytesWithAll(bytes)); 508 EXPECT_EQ(runBuiltin(METH(bytearray, __le__), self, other), Bool::trueObj()); 509} 510 511TEST_F(BytearrayBuiltinsTest, DunderLeWithEqualBytearrayReturnsTrue) { 512 HandleScope scope(thread_); 513 const byte bytes[] = {'f', 'o', 'o'}; 514 Bytearray self(&scope, runtime_->newBytearray()); 515 Bytearray other(&scope, runtime_->newBytearray()); 516 runtime_->bytearrayExtend(thread_, self, bytes); 517 runtime_->bytearrayExtend(thread_, other, bytes); 518 EXPECT_EQ(runBuiltin(METH(bytearray, __le__), self, other), Bool::trueObj()); 519} 520 521TEST_F(BytearrayBuiltinsTest, DunderLeWithLongerOtherReturnsTrue) { 522 HandleScope scope(thread_); 523 const byte bytes[] = {'f', 'o', 'o'}; 524 Bytearray self(&scope, runtime_->newBytearray()); 525 Bytearray other(&scope, runtime_->newBytearray()); 526 runtime_->bytearrayExtend(thread_, self, {bytes, 2}); 527 runtime_->bytearrayExtend(thread_, other, bytes); 528 EXPECT_EQ(runBuiltin(METH(bytearray, __le__), self, other), Bool::trueObj()); 529} 530 531TEST_F(BytearrayBuiltinsTest, DunderLeWithShorterOtherReturnsFalse) { 532 HandleScope scope(thread_); 533 const byte bytes[] = {'f', 'o', 'o'}; 534 Bytearray self(&scope, runtime_->newBytearray()); 535 Bytearray other(&scope, runtime_->newBytearray()); 536 runtime_->bytearrayExtend(thread_, self, bytes); 537 runtime_->bytearrayExtend(thread_, other, {bytes, 2}); 538 EXPECT_EQ(runBuiltin(METH(bytearray, __le__), self, other), Bool::falseObj()); 539} 540 541TEST_F(BytearrayBuiltinsTest, DunderLeWithEarlierOtherReturnsFalse) { 542 HandleScope scope(thread_); 543 const byte bytes[] = {'f', 'o', 'o'}; 544 Bytearray self(&scope, runtime_->newBytearray()); 545 runtime_->bytearrayExtend(thread_, self, bytes); 546 Object other(&scope, runtime_->newBytes(3, 'f')); 547 EXPECT_EQ(runBuiltin(METH(bytearray, __le__), self, other), Bool::falseObj()); 548} 549 550TEST_F(BytearrayBuiltinsTest, DunderLeWithLaterOtherReturnsTrue) { 551 HandleScope scope(thread_); 552 const byte bytes[] = {'o', 'o', 'f'}; 553 Bytearray self(&scope, runtime_->newBytearray()); 554 runtime_->bytearrayExtend(thread_, self, bytes); 555 Object other(&scope, runtime_->newBytes(3, 'o')); 556 EXPECT_EQ(runBuiltin(METH(bytearray, __le__), self, other), Bool::trueObj()); 557} 558 559TEST_F(BytearrayBuiltinsTest, DunderLenWithEmptyBytearrayReturnsZero) { 560 HandleScope scope(thread_); 561 Bytearray self(&scope, runtime_->newBytearray()); 562 Object result(&scope, runBuiltin(METH(bytearray, __len__), self)); 563 EXPECT_TRUE(isIntEqualsWord(*result, 0)); 564} 565 566TEST_F(BytearrayBuiltinsTest, DunderLenWithNonEmptyBytearrayReturnsPositive) { 567 HandleScope scope(thread_); 568 Bytearray self(&scope, runtime_->newBytearray()); 569 const byte bytes[] = {1, 2, 3, 4, 5}; 570 runtime_->bytearrayExtend(thread_, self, bytes); 571 Object result(&scope, runBuiltin(METH(bytearray, __len__), self)); 572 EXPECT_TRUE(isIntEqualsWord(*result, 5)); 573 574 const byte bytes2[] = {6, 7}; 575 runtime_->bytearrayExtend(thread_, self, bytes2); 576 result = runBuiltin(METH(bytearray, __len__), self); 577 EXPECT_TRUE(isIntEqualsWord(*result, 7)); 578} 579 580TEST_F(BytearrayBuiltinsTest, DunderLtWithNonBytesOtherReturnsNotImplemented) { 581 HandleScope scope(thread_); 582 Object self(&scope, runtime_->newBytearray()); 583 Object other(&scope, SmallInt::fromWord(0)); 584 Object result(&scope, runBuiltin(METH(bytearray, __lt__), self, other)); 585 EXPECT_TRUE(result.isNotImplementedType()); 586} 587 588TEST_F(BytearrayBuiltinsTest, DunderLtWithEmptyBytearraysReturnsFalse) { 589 HandleScope scope(thread_); 590 Object self(&scope, runtime_->newBytearray()); 591 Object other(&scope, runtime_->newBytearray()); 592 EXPECT_EQ(runBuiltin(METH(bytearray, __lt__), self, other), Bool::falseObj()); 593} 594 595TEST_F(BytearrayBuiltinsTest, DunderLtithEqualBytesReturnsFalse) { 596 HandleScope scope(thread_); 597 const byte bytes[] = {'f', 'o', 'o'}; 598 Bytearray self(&scope, runtime_->newBytearray()); 599 runtime_->bytearrayExtend(thread_, self, bytes); 600 Object other(&scope, runtime_->newBytesWithAll(bytes)); 601 EXPECT_EQ(runBuiltin(METH(bytearray, __lt__), self, other), Bool::falseObj()); 602} 603 604TEST_F(BytearrayBuiltinsTest, DunderLtWithEqualBytearrayReturnsFalse) { 605 HandleScope scope(thread_); 606 const byte bytes[] = {'f', 'o', 'o'}; 607 Bytearray self(&scope, runtime_->newBytearray()); 608 Bytearray other(&scope, runtime_->newBytearray()); 609 runtime_->bytearrayExtend(thread_, self, bytes); 610 runtime_->bytearrayExtend(thread_, other, bytes); 611 EXPECT_EQ(runBuiltin(METH(bytearray, __lt__), self, other), Bool::falseObj()); 612} 613 614TEST_F(BytearrayBuiltinsTest, DunderLtWithLongerOtherReturnsTrue) { 615 HandleScope scope(thread_); 616 const byte bytes[] = {'f', 'o', 'o'}; 617 Bytearray self(&scope, runtime_->newBytearray()); 618 Bytearray other(&scope, runtime_->newBytearray()); 619 runtime_->bytearrayExtend(thread_, self, {bytes, 2}); 620 runtime_->bytearrayExtend(thread_, other, bytes); 621 EXPECT_EQ(runBuiltin(METH(bytearray, __lt__), self, other), Bool::trueObj()); 622} 623 624TEST_F(BytearrayBuiltinsTest, DunderLtWithShorterOtherReturnsFalse) { 625 HandleScope scope(thread_); 626 const byte bytes[] = {'f', 'o', 'o'}; 627 Bytearray self(&scope, runtime_->newBytearray()); 628 Bytearray other(&scope, runtime_->newBytearray()); 629 runtime_->bytearrayExtend(thread_, self, bytes); 630 runtime_->bytearrayExtend(thread_, other, {bytes, 2}); 631 EXPECT_EQ(runBuiltin(METH(bytearray, __lt__), self, other), Bool::falseObj()); 632} 633 634TEST_F(BytearrayBuiltinsTest, DunderLtWithEarlierOtherReturnsFalse) { 635 HandleScope scope(thread_); 636 const byte bytes[] = {'f', 'o', 'o'}; 637 Bytearray self(&scope, runtime_->newBytearray()); 638 runtime_->bytearrayExtend(thread_, self, bytes); 639 Object other(&scope, runtime_->newBytes(3, 'f')); 640 EXPECT_EQ(runBuiltin(METH(bytearray, __lt__), self, other), Bool::falseObj()); 641} 642 643TEST_F(BytearrayBuiltinsTest, DunderLtWithLaterOtherReturnsTrue) { 644 HandleScope scope(thread_); 645 const byte bytes[] = {'o', 'o', 'f'}; 646 Bytearray self(&scope, runtime_->newBytearray()); 647 runtime_->bytearrayExtend(thread_, self, bytes); 648 Object other(&scope, runtime_->newBytes(3, 'o')); 649 EXPECT_EQ(runBuiltin(METH(bytearray, __lt__), self, other), Bool::trueObj()); 650} 651 652TEST_F(BytearrayBuiltinsTest, DunderMulWithNonIntRaisesTypeError) { 653 HandleScope scope(thread_); 654 Object self(&scope, runtime_->newBytearray()); 655 Object count(&scope, runtime_->newList()); 656 EXPECT_TRUE(raisedWithStr( 657 runBuiltin(METH(bytearray, __mul__), self, count), LayoutId::kTypeError, 658 "'list' object cannot be interpreted as an integer")); 659} 660 661TEST_F(BytearrayBuiltinsTest, DunderMulWithIntSubclassReturnsRepeatedBytes) { 662 HandleScope scope(thread_); 663 const byte view[] = {'f', 'o', 'o'}; 664 Bytearray self(&scope, runtime_->newBytearray()); 665 runtime_->bytearrayExtend(thread_, self, view); 666 ASSERT_FALSE(runFromCStr(runtime_, R"( 667class C(int): pass 668count = C(3) 669)") 670 .isError()); 671 Object count(&scope, mainModuleAt(runtime_, "count")); 672 Object result(&scope, runBuiltin(METH(bytearray, __mul__), self, count)); 673 EXPECT_TRUE(isBytearrayEqualsCStr(result, "foofoofoo")); 674} 675 676TEST_F(BytearrayBuiltinsTest, DunderMulWithDunderIndexReturnsRepeatedBytes) { 677 HandleScope scope(thread_); 678 Bytearray self(&scope, runtime_->newBytearray()); 679 bytearrayAdd(thread_, runtime_, self, 'a'); 680 ASSERT_FALSE(runFromCStr(runtime_, R"( 681class C: 682 def __index__(self): 683 return 2 684count = C() 685)") 686 .isError()); 687 Object count(&scope, mainModuleAt(runtime_, "count")); 688 Object result(&scope, runBuiltin(METH(bytearray, __mul__), self, count)); 689 EXPECT_TRUE(isBytearrayEqualsCStr(result, "aa")); 690} 691 692TEST_F(BytearrayBuiltinsTest, DunderMulWithBadDunderIndexRaisesTypeError) { 693 HandleScope scope(thread_); 694 Object self(&scope, runtime_->newBytearray()); 695 ASSERT_FALSE(runFromCStr(runtime_, R"( 696class C: 697 def __index__(self): 698 return "foo" 699count = C() 700)") 701 .isError()); 702 Object count(&scope, mainModuleAt(runtime_, "count")); 703 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytearray, __mul__), self, count), 704 LayoutId::kTypeError, 705 "__index__ returned non-int (type str)")); 706} 707 708TEST_F(BytearrayBuiltinsTest, DunderMulPropagatesDunderIndexError) { 709 HandleScope scope(thread_); 710 Object self(&scope, runtime_->newBytearray()); 711 ASSERT_FALSE(runFromCStr(runtime_, R"( 712class C: 713 def __index__(self): 714 raise ArithmeticError("called __index__") 715count = C() 716)") 717 .isError()); 718 Object count(&scope, mainModuleAt(runtime_, "count")); 719 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytearray, __mul__), self, count), 720 LayoutId::kArithmeticError, "called __index__")); 721} 722 723TEST_F(BytearrayBuiltinsTest, DunderMulWithLargeIntRaisesOverflowError) { 724 HandleScope scope(thread_); 725 Bytearray self(&scope, runtime_->newBytearray()); 726 const uword digits[] = {1, 1}; 727 Object count(&scope, runtime_->newLargeIntWithDigits(digits)); 728 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytearray, __mul__), self, count), 729 LayoutId::kOverflowError, 730 "cannot fit 'int' into an index-sized integer")); 731} 732 733TEST_F(BytearrayBuiltinsTest, DunderMulWithOverflowRaisesMemoryError) { 734 HandleScope scope(thread_); 735 Bytearray self(&scope, runtime_->newBytearray()); 736 const byte bytes[] = {'a', 'b', 'c'}; 737 runtime_->bytearrayExtend(thread_, self, bytes); 738 Object count(&scope, SmallInt::fromWord(SmallInt::kMaxValue / 2)); 739 EXPECT_TRUE(raised(runBuiltin(METH(bytearray, __mul__), self, count), 740 LayoutId::kMemoryError)); 741} 742 743TEST_F(BytearrayBuiltinsTest, 744 DunderMulWithEmptyBytearrayReturnsEmptyBytearray) { 745 HandleScope scope(thread_); 746 Object self(&scope, runtime_->newBytearray()); 747 Object count(&scope, SmallInt::fromWord(5)); 748 Object result(&scope, runBuiltin(METH(bytearray, __mul__), self, count)); 749 EXPECT_TRUE(isBytearrayEqualsCStr(result, "")); 750} 751 752TEST_F(BytearrayBuiltinsTest, DunderMulWithNegativeReturnsEmptyBytearray) { 753 HandleScope scope(thread_); 754 Bytearray self(&scope, runtime_->newBytearray()); 755 self.setItems(runtime_->mutableBytesWith(8, 'a')); 756 self.setNumItems(8); 757 Object count(&scope, SmallInt::fromWord(-5)); 758 Object result(&scope, runBuiltin(METH(bytearray, __mul__), self, count)); 759 EXPECT_TRUE(isBytearrayEqualsCStr(result, "")); 760} 761 762TEST_F(BytearrayBuiltinsTest, DunderMulWithZeroReturnsEmptyBytearray) { 763 HandleScope scope(thread_); 764 Bytearray self(&scope, runtime_->newBytearray()); 765 self.setItems(runtime_->mutableBytesWith(8, 'a')); 766 self.setNumItems(8); 767 Object count(&scope, SmallInt::fromWord(0)); 768 Object result(&scope, runBuiltin(METH(bytearray, __mul__), self, count)); 769 EXPECT_TRUE(isBytearrayEqualsCStr(result, "")); 770} 771 772TEST_F(BytearrayBuiltinsTest, DunderMulWithOneReturnsSameBytearray) { 773 HandleScope scope(thread_); 774 Bytearray self(&scope, runtime_->newBytearray()); 775 const byte bytes[] = {'a', 'b'}; 776 runtime_->bytearrayExtend(thread_, self, bytes); 777 Object count(&scope, SmallInt::fromWord(1)); 778 Object result(&scope, runBuiltin(METH(bytearray, __mul__), self, count)); 779 EXPECT_TRUE(isBytearrayEqualsBytes(result, bytes)); 780} 781 782TEST_F(BytearrayBuiltinsTest, DunderMulReturnsRepeatedBytearray) { 783 HandleScope scope(thread_); 784 Bytearray self(&scope, runtime_->newBytearray()); 785 const byte bytes[] = {'a', 'b'}; 786 runtime_->bytearrayExtend(thread_, self, bytes); 787 Object count(&scope, SmallInt::fromWord(3)); 788 Object result(&scope, runBuiltin(METH(bytearray, __mul__), self, count)); 789 EXPECT_TRUE(isBytearrayEqualsCStr(result, "ababab")); 790} 791 792TEST_F(BytearrayBuiltinsTest, DunderNeWithNonBytesOtherReturnsNotImplemented) { 793 HandleScope scope(thread_); 794 Object self(&scope, runtime_->newBytearray()); 795 Object other(&scope, SmallInt::fromWord(0)); 796 Object result(&scope, runBuiltin(METH(bytearray, __ne__), self, other)); 797 EXPECT_TRUE(result.isNotImplementedType()); 798} 799 800TEST_F(BytearrayBuiltinsTest, DunderNeWithEmptyBytearraysReturnsFalse) { 801 HandleScope scope(thread_); 802 Object self(&scope, runtime_->newBytearray()); 803 Object other(&scope, runtime_->newBytearray()); 804 EXPECT_EQ(runBuiltin(METH(bytearray, __ne__), self, other), Bool::falseObj()); 805} 806 807TEST_F(BytearrayBuiltinsTest, DunderNeWithEqualBytesReturnsFalse) { 808 HandleScope scope(thread_); 809 const byte bytes[] = {'f', 'o', 'o'}; 810 Bytearray self(&scope, runtime_->newBytearray()); 811 runtime_->bytearrayExtend(thread_, self, bytes); 812 Object other(&scope, runtime_->newBytesWithAll(bytes)); 813 EXPECT_EQ(runBuiltin(METH(bytearray, __ne__), self, other), Bool::falseObj()); 814} 815 816TEST_F(BytearrayBuiltinsTest, DunderNeWithEqualBytearrayReturnsFalse) { 817 HandleScope scope(thread_); 818 const byte bytes[] = {'f', 'o', 'o'}; 819 Bytearray self(&scope, runtime_->newBytearray()); 820 Bytearray other(&scope, runtime_->newBytearray()); 821 runtime_->bytearrayExtend(thread_, self, bytes); 822 runtime_->bytearrayExtend(thread_, other, bytes); 823 EXPECT_EQ(runBuiltin(METH(bytearray, __ne__), self, other), Bool::falseObj()); 824} 825 826TEST_F(BytearrayBuiltinsTest, DunderNeWithDifferentLengthsReturnsTrue) { 827 HandleScope scope(thread_); 828 const byte bytes[] = {'f', 'o', 'o'}; 829 Bytearray self(&scope, runtime_->newBytearray()); 830 Bytearray other(&scope, runtime_->newBytearray()); 831 runtime_->bytearrayExtend(thread_, self, bytes); 832 runtime_->bytearrayExtend(thread_, other, {bytes, 2}); 833 EXPECT_EQ(runBuiltin(METH(bytearray, __ne__), self, other), Bool::trueObj()); 834} 835 836TEST_F(BytearrayBuiltinsTest, DunderNeWithDifferentContentsReturnsTrue) { 837 HandleScope scope(thread_); 838 const byte bytes[] = {'f', 'o', 'o'}; 839 Bytearray self(&scope, runtime_->newBytearray()); 840 runtime_->bytearrayExtend(thread_, self, bytes); 841 Object other(&scope, runtime_->newBytes(3, 'f')); 842 EXPECT_EQ(runBuiltin(METH(bytearray, __ne__), self, other), Bool::trueObj()); 843} 844 845TEST_F(BytearrayBuiltinsTest, DunderNewWithNonTypeRaisesTypeError) { 846 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytearray.__new__(3)"), 847 LayoutId::kTypeError, "not a type object")); 848} 849 850TEST_F(BytearrayBuiltinsTest, DunderNewWithNonBytearrayRaisesTypeError) { 851 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytearray.__new__(int)"), 852 LayoutId::kTypeError, 853 "not a subtype of bytearray")); 854} 855 856TEST_F(BytearrayBuiltinsTest, DunderNewReturnsEmptyBytearray) { 857 HandleScope scope(thread_); 858 Type cls(&scope, runtime_->typeAt(LayoutId::kBytearray)); 859 Object self(&scope, runBuiltin(METH(bytearray, __new__), cls)); 860 EXPECT_TRUE(isBytearrayEqualsCStr(self, "")); 861} 862 863TEST_F(BytearrayBuiltinsTest, NewBytearray) { 864 HandleScope scope(thread_); 865 ASSERT_FALSE( 866 runFromCStr(runtime_, "obj = bytearray(b'Hello world!')").isError()); 867 Bytearray self(&scope, mainModuleAt(runtime_, "obj")); 868 EXPECT_TRUE(isBytearrayEqualsCStr(self, "Hello world!")); 869} 870 871TEST_F(BytearrayBuiltinsTest, DunderReprWithEmptyBytearrayReturnsEmptyRepr) { 872 HandleScope scope(thread_); 873 Bytearray self(&scope, runtime_->newBytearray()); 874 Object repr(&scope, runBuiltin(METH(bytearray, __repr__), self)); 875 EXPECT_TRUE(isStrEqualsCStr(*repr, "bytearray(b'')")); 876} 877 878TEST_F(BytearrayBuiltinsTest, DunderReprWithSimpleBytearrayReturnsRepr) { 879 HandleScope scope(thread_); 880 Bytearray self(&scope, runtime_->newBytearray()); 881 const byte bytes[] = {'f', 'o', 'o'}; 882 runtime_->bytearrayExtend(thread_, self, bytes); 883 Object repr(&scope, runBuiltin(METH(bytearray, __repr__), self)); 884 EXPECT_TRUE(isStrEqualsCStr(*repr, "bytearray(b'foo')")); 885} 886 887TEST_F(BytearrayBuiltinsTest, 888 DunderReprWithDoubleQuoteUsesSingleQuoteDelimiters) { 889 HandleScope scope(thread_); 890 Bytearray self(&scope, runtime_->newBytearray()); 891 const byte bytes[] = {'_', '"', '_'}; 892 runtime_->bytearrayExtend(thread_, self, bytes); 893 Object repr(&scope, runBuiltin(METH(bytearray, __repr__), self)); 894 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(bytearray(b'_"_'))")); 895} 896 897TEST_F(BytearrayBuiltinsTest, 898 DunderReprWithSingleQuoteUsesDoubleQuoteDelimiters) { 899 HandleScope scope(thread_); 900 Bytearray self(&scope, runtime_->newBytearray()); 901 const byte bytes[] = {'_', '\'', '_'}; 902 runtime_->bytearrayExtend(thread_, self, bytes); 903 Object repr(&scope, runBuiltin(METH(bytearray, __repr__), self)); 904 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(bytearray(b"_\'_"))")); 905} 906 907TEST_F(BytearrayBuiltinsTest, 908 DunderReprWithBothQuotesUsesSingleQuoteDelimiters) { 909 HandleScope scope(thread_); 910 Bytearray self(&scope, runtime_->newBytearray()); 911 const byte bytes[] = {'_', '"', '_', '\'', '_'}; 912 runtime_->bytearrayExtend(thread_, self, bytes); 913 Object repr(&scope, runBuiltin(METH(bytearray, __repr__), self)); 914 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(bytearray(b'_"_\'_'))")); 915} 916 917TEST_F(BytearrayBuiltinsTest, DunderReprWithSpecialBytesUsesEscapeSequences) { 918 HandleScope scope(thread_); 919 Bytearray self(&scope, runtime_->newBytearray()); 920 const byte bytes[] = {'\\', '\t', '\n', '\r'}; 921 runtime_->bytearrayExtend(thread_, self, bytes); 922 Object repr(&scope, runBuiltin(METH(bytearray, __repr__), self)); 923 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(bytearray(b'\\\t\n\r'))")); 924} 925 926TEST_F(BytearrayBuiltinsTest, DunderReprWithSmallAndLargeBytesUsesHex) { 927 HandleScope scope(thread_); 928 Bytearray self(&scope, runtime_->newBytearray()); 929 const byte bytes[] = {0, 0x1f, 0x80, 0xff}; 930 runtime_->bytearrayExtend(thread_, self, bytes); 931 Object repr(&scope, runBuiltin(METH(bytearray, __repr__), self)); 932 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(bytearray(b'\x00\x1f\x80\xff'))")); 933} 934 935TEST_F(BytearrayBuiltinsTest, DunderReprWithSubclassUsesClassName) { 936 ASSERT_FALSE(runFromCStr(runtime_, R"( 937class C(bytearray): pass 938obj = C(b'hello world') 939)") 940 .isError()); 941 HandleScope scope(thread_); 942 Object obj(&scope, mainModuleAt(runtime_, "obj")); 943 Object repr(&scope, runBuiltin(METH(bytearray, __repr__), obj)); 944 EXPECT_TRUE(isStrEqualsCStr(*repr, "C(b'hello world')")); 945} 946 947TEST_F(BytearrayBuiltinsTest, DunderRmulCallsDunderMul) { 948 HandleScope scope(thread_); 949 ASSERT_FALSE( 950 runFromCStr(runtime_, "result = 3 * bytearray(b'123')").isError()); 951 Object result(&scope, mainModuleAt(runtime_, "result")); 952 EXPECT_TRUE(isBytearrayEqualsCStr(result, "123123123")); 953} 954 955TEST_F(BytearrayBuiltinsTest, HexWithEmptyBytearrayReturnsEmptyString) { 956 HandleScope scope(thread_); 957 Object self(&scope, runtime_->newBytearray()); 958 Object result(&scope, runBuiltin(METH(bytearray, hex), self)); 959 EXPECT_TRUE(isStrEqualsCStr(*result, "")); 960} 961 962TEST_F(BytearrayBuiltinsTest, HexWithNonEmptyBytesReturnsString) { 963 HandleScope scope(thread_); 964 Bytearray self(&scope, runtime_->newBytearray()); 965 const byte bytes[] = {0x60, 0xe, 0x18, 0x21}; 966 runtime_->bytearrayExtend(thread_, self, bytes); 967 Object result(&scope, runBuiltin(METH(bytearray, hex), self)); 968 EXPECT_TRUE(isStrEqualsCStr(*result, "600e1821")); 969} 970 971TEST_F(BytearrayBuiltinsTest, JoinWithNonIterableRaisesTypeError) { 972 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytearray(b'').join(0)"), 973 LayoutId::kTypeError, 974 "'int' object is not iterable")); 975} 976 977TEST_F(BytearrayBuiltinsTest, JoinWithMistypedIterableRaisesTypeError) { 978 EXPECT_TRUE(raisedWithStr( 979 runFromCStr(runtime_, "bytearray(b' ').join([1])"), LayoutId::kTypeError, 980 "sequence item 0: expected a bytes-like object, 'int' found")); 981} 982 983TEST_F(BytearrayBuiltinsTest, JoinWithIterableReturnsBytearray) { 984 ASSERT_FALSE(runFromCStr(runtime_, R"( 985class Foo: 986 def __iter__(self): 987 return [b'ab', b'c', b'def'].__iter__() 988result = bytearray(b' ').join(Foo()) 989)") 990 .isError()); 991 HandleScope scope(thread_); 992 Object result(&scope, mainModuleAt(runtime_, "result")); 993 EXPECT_TRUE(isBytearrayEqualsCStr(result, "ab c def")); 994} 995 996TEST_F(BytearrayBuiltinsTest, MaketransWithNonBytesLikeFromRaisesTypeError) { 997 EXPECT_TRUE(raisedWithStr( 998 runFromCStr(runtime_, "bytearray.maketrans([1,2], b'ab')"), 999 LayoutId::kTypeError, "a bytes-like object is required, not 'list'")); 1000} 1001 1002TEST_F(BytearrayBuiltinsTest, MaketransWithNonBytesLikeToRaisesTypeError) { 1003 EXPECT_TRUE(raisedWithStr( 1004 runFromCStr(runtime_, "bytearray.maketrans(b'1', 2)"), 1005 LayoutId::kTypeError, "a bytes-like object is required, not 'int'")); 1006} 1007 1008TEST_F(BytearrayBuiltinsTest, MaketransWithDifferentLengthsRaisesValueError) { 1009 EXPECT_TRUE(raisedWithStr( 1010 runFromCStr(runtime_, "bytearray.maketrans(b'12', bytearray())"), 1011 LayoutId::kValueError, "maketrans arguments must have same length")); 1012} 1013 1014TEST_F(BytearrayBuiltinsTest, MaketransWithEmptyReturnsDefaultBytes) { 1015 HandleScope scope(thread_); 1016 ASSERT_FALSE( 1017 runFromCStr(runtime_, "result = bytearray.maketrans(bytearray(), b'')") 1018 .isError()); 1019 Object result(&scope, mainModuleAt(runtime_, "result")); 1020 byte expected[256]; 1021 for (word i = 0; i < 256; i++) { 1022 expected[i] = i; 1023 } 1024 EXPECT_TRUE(isBytesEqualsBytes(result, expected)); 1025} 1026 1027TEST_F(BytearrayBuiltinsTest, MaketransWithNonEmptyReturnsBytes) { 1028 HandleScope scope(thread_); 1029 ASSERT_FALSE( 1030 runFromCStr(runtime_, 1031 "result = bytearray.maketrans(bytearray(b'abc'), b'123')") 1032 .isError()); 1033 Object result(&scope, mainModuleAt(runtime_, "result")); 1034 ASSERT_TRUE(result.isBytes()); 1035 LargeBytes actual(&scope, *result); 1036 EXPECT_EQ(actual.byteAt('a'), '1'); 1037 EXPECT_EQ(actual.byteAt('b'), '2'); 1038 EXPECT_EQ(actual.byteAt('c'), '3'); 1039} 1040 1041TEST_F(BytearrayBuiltinsTest, TranslateWithNonBytesLikeTableRaisesTypeError) { 1042 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytearray().translate(42)"), 1043 LayoutId::kTypeError, 1044 "a bytes-like object is required, not 'int'")); 1045} 1046 1047TEST_F(BytearrayBuiltinsTest, TranslateWithNonBytesLikeDeleteRaisesTypeError) { 1048 EXPECT_TRUE(raisedWithStr( 1049 runFromCStr(runtime_, "bytearray().translate(None, 42)"), 1050 LayoutId::kTypeError, "a bytes-like object is required, not 'int'")); 1051} 1052 1053TEST_F(BytearrayBuiltinsTest, TranslateWithShortTableRaisesValueError) { 1054 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytearray().translate(b'')"), 1055 LayoutId::kValueError, 1056 "translation table must be 256 characters long")); 1057} 1058 1059TEST_F(BytearrayBuiltinsTest, TranslateWithEmptyBytearrayReturnsNewBytearray) { 1060 HandleScope scope(thread_); 1061 Object self(&scope, runtime_->newBytearray()); 1062 Object table(&scope, NoneType::object()); 1063 Object del(&scope, runtime_->newBytearray()); 1064 Object result(&scope, 1065 runBuiltin(METH(bytearray, translate), self, table, del)); 1066 EXPECT_TRUE(isBytearrayEqualsCStr(result, "")); 1067 EXPECT_NE(result, self); 1068} 1069 1070TEST_F(BytearrayBuiltinsTest, TranslateWithNonEmptySecondArgDeletesBytes) { 1071 HandleScope scope(thread_); 1072 const byte alabama[] = {'A', 'l', 'a', 'b', 'a', 'm', 'a'}; 1073 const byte abc[] = {'a', 'b', 'c'}; 1074 Bytearray self(&scope, runtime_->newBytearray()); 1075 runtime_->bytearrayExtend(thread_, self, alabama); 1076 Object table(&scope, NoneType::object()); 1077 Object del(&scope, runtime_->newBytesWithAll(abc)); 1078 Object result(&scope, 1079 runBuiltin(METH(bytearray, translate), self, table, del)); 1080 EXPECT_TRUE(isBytearrayEqualsCStr(result, "Alm")); 1081} 1082 1083TEST_F(BytearrayBuiltinsTest, TranslateWithTableTranslatesBytes) { 1084 HandleScope scope(thread_); 1085 ASSERT_FALSE( 1086 runFromCStr(runtime_, "table = bytes.maketrans(b'Aa', b'12')").isError()); 1087 const byte alabama[] = {'A', 'l', 'a', 'b', 'a', 'm', 'a'}; 1088 Bytearray self(&scope, runtime_->newBytearray()); 1089 runtime_->bytearrayExtend(thread_, self, alabama); 1090 Object table(&scope, mainModuleAt(runtime_, "table")); 1091 Object del(&scope, runtime_->newBytearray()); 1092 Object result(&scope, 1093 runBuiltin(METH(bytearray, translate), self, table, del)); 1094 EXPECT_TRUE(isBytearrayEqualsCStr(result, "1l2b2m2")); 1095} 1096 1097TEST_F(BytearrayBuiltinsTest, 1098 TranslateWithTableAndDeleteTranslatesAndDeletesBytes) { 1099 HandleScope scope(thread_); 1100 ASSERT_FALSE( 1101 runFromCStr(runtime_, "table = bytes.maketrans(b'Aa', b'12')").isError()); 1102 const byte alabama[] = {'A', 'l', 'a', 'b', 'a', 'm', 'a'}; 1103 const byte abc[] = {'a', 'b', 'c'}; 1104 Bytearray self(&scope, runtime_->newBytearray()); 1105 runtime_->bytearrayExtend(thread_, self, alabama); 1106 Object table(&scope, mainModuleAt(runtime_, "table")); 1107 Object del(&scope, runtime_->newBytesWithAll(abc)); 1108 Object result(&scope, 1109 runBuiltin(METH(bytearray, translate), self, table, del)); 1110 EXPECT_TRUE(isBytearrayEqualsCStr(result, "1lm")); 1111} 1112 1113TEST_F(BytearrayBuiltinsTest, TranslateDeletesAllBytes) { 1114 HandleScope scope(thread_); 1115 const byte alabama[] = {'b', 'a', 'c', 'a', 'a', 'c', 'a'}; 1116 const byte abc[] = {'a', 'b', 'c'}; 1117 Bytearray self(&scope, runtime_->newBytearray()); 1118 runtime_->bytearrayExtend(thread_, self, alabama); 1119 Object table(&scope, NoneType::object()); 1120 Object del(&scope, runtime_->newBytesWithAll(abc)); 1121 Object result(&scope, 1122 runBuiltin(METH(bytearray, translate), self, table, del)); 1123 EXPECT_TRUE(isBytearrayEqualsCStr(result, "")); 1124} 1125 1126TEST_F(BytearrayBuiltinsTest, DunderIterReturnsBytearrayIterator) { 1127 ASSERT_FALSE( 1128 runFromCStr(runtime_, "result = type(bytearray().__iter__())").isError()); 1129 HandleScope scope(thread_); 1130 Object result(&scope, mainModuleAt(runtime_, "result")); 1131 EXPECT_EQ(*result, runtime_->typeAt(LayoutId::kBytearrayIterator)); 1132} 1133 1134TEST_F(BytearrayBuiltinsTest, IteratorDunderNextReturnsNextElement) { 1135 ASSERT_FALSE(runFromCStr(runtime_, R"( 1136ba = bytearray(b'abc') 1137it = iter(ba) 1138r0 = it.__next__() 1139r1 = it.__next__() 1140r2 = it.__next__() 1141try: 1142 it.__next__() 1143 r3 = False 1144except StopIteration: 1145 r3 = True 1146)") 1147 .isError()); 1148 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "r0"), 'a')); 1149 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "r1"), 'b')); 1150 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "r2"), 'c')); 1151 EXPECT_EQ(mainModuleAt(runtime_, "r3"), Bool::trueObj()); 1152} 1153 1154TEST_F(BytearrayBuiltinsTest, 1155 IteratorDunderNextStopsIterationWhenBytearrayIsShrunk) { 1156 ASSERT_FALSE(runFromCStr(runtime_, R"( 1157ba = bytearray(b'abc') 1158it = iter(ba) 1159)") 1160 .isError()); 1161 HandleScope scope(thread_); 1162 Bytearray ba(&scope, mainModuleAt(runtime_, "ba")); 1163 BytearrayIterator it(&scope, mainModuleAt(runtime_, "it")); 1164 ba.setNumItems(0); 1165 EXPECT_TRUE(raised(thread_->invokeMethod1(it, ID(__next__)), 1166 LayoutId::kStopIteration)); 1167} 1168 1169} // namespace testing 1170} // namespace py