this repo has no description
at trunk 1845 lines 72 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "bytes-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 BytesBuiltinsTest = RuntimeFixture; 13using BytesIteratorBuiltinsTest = RuntimeFixture; 14 15TEST_F(BytesBuiltinsTest, BuiltinBaseIsBytes) { 16 HandleScope scope(thread_); 17 Type bytes_type(&scope, runtime_->typeAt(LayoutId::kBytes)); 18 EXPECT_EQ(bytes_type.builtinBase(), LayoutId::kBytes); 19} 20 21TEST_F(BytesBuiltinsTest, BytesIsValidUTF8ReturnsTrue) { 22 EXPECT_TRUE(bytesIsValidUTF8(Bytes::empty())); 23 24 HandleScope scope(thread_); 25 const byte zeros_bytes[] = {0, 0, 0}; 26 Bytes zeros(&scope, runtime_->newBytesWithAll(zeros_bytes)); 27 EXPECT_TRUE(bytesIsValidUTF8(*zeros)); 28 29 const byte test0[] = {'S', ':', 'a'}; 30 EXPECT_TRUE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test0)))); 31 const byte test1[] = {'S', ':', 0xC3, 0xA4}; 32 EXPECT_TRUE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test1)))); 33 const byte test2[] = {'S', ':', 0xE2, 0x88, 0x91}; 34 EXPECT_TRUE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test2)))); 35 const byte test3[] = {'S', ':', 0xF0, 0x9F, 0x90, 0x8D}; 36 EXPECT_TRUE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test3)))); 37 38 const byte test_misc[] = {0xEC, 0x95, 0x88, 0xEB, 0x85, 0x95, ' ', 39 0xEC, 0x84, 0xB8, 0xEC, 0x83, 0x81, 0}; 40 EXPECT_TRUE( 41 bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test_misc)))); 42 43 const byte max_unicode[] = {0xF4, 0x8F, 0xBF, 0xBF}; 44 EXPECT_TRUE( 45 bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(max_unicode)))); 46 47 const byte min_surrogate_minus_one[] = {0xED, 0x9F, 0xBF}; 48 EXPECT_TRUE(bytesIsValidUTF8( 49 Bytes::cast(runtime_->newBytesWithAll(min_surrogate_minus_one)))); 50 const byte max_surrogate_plus_one[] = {0xEE, 0x80, 0x80}; 51 EXPECT_TRUE(bytesIsValidUTF8( 52 Bytes::cast(runtime_->newBytesWithAll(max_surrogate_plus_one)))); 53} 54 55TEST_F(BytesBuiltinsTest, 56 BytesIsValidUTF8WithContinuationAfterValidCharReturnsFalse) { 57 const byte test0[] = {0x80}; 58 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test0)))); 59 const byte test1[] = {'a', 0xB3}; 60 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test1)))); 61 const byte test2[] = {0xC3, 0xA4, 0xB3}; 62 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test2)))); 63 const byte test3[] = {0xE2, 0x88, 0x91, 0xB3}; 64 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test3)))); 65 const byte test4[] = {0xF0, 0x9F, 0x90, 0x8D, 0xB3}; 66 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test4)))); 67} 68 69TEST_F(BytesBuiltinsTest, BytesIsValidUTF8WithMissingContinuationReturnsFalse) { 70 const byte test0[] = {0xC3}; 71 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test0)))); 72 const byte test1[] = {0xC3, 0}; 73 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test1)))); 74 75 const byte test2[] = {0xE2}; 76 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test2)))); 77 const byte test3[] = {0xE2, 0}; 78 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test3)))); 79 const byte test5[] = {0xE2, 0x88}; 80 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test5)))); 81 const byte test4[] = {0xE2, 0, 0}; 82 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test4)))); 83 const byte test6[] = {0xE2, 0x88, 0}; 84 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test6)))); 85 86 const byte test7[] = {0xF0}; 87 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test7)))); 88 const byte test8[] = {0xF0, 0}; 89 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test8)))); 90 const byte test9[] = {0xF0, 0x9F}; 91 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test9)))); 92 const byte test10[] = {0xF0, 0, 0}; 93 EXPECT_FALSE( 94 bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test10)))); 95 const byte test11[] = {0xF0, 0x9F, 0}; 96 EXPECT_FALSE( 97 bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test11)))); 98 const byte test12[] = {0xF0, 0x9F, 0x90}; 99 EXPECT_FALSE( 100 bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test12)))); 101 const byte test13[] = {0xF0, 0, 0, 0}; 102 EXPECT_FALSE( 103 bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test13)))); 104 const byte test14[] = {0xF0, 0x9F, 0x90, 0}; 105 EXPECT_FALSE( 106 bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test14)))); 107} 108 109TEST_F(BytesBuiltinsTest, 110 BytesIsValidUTF8WithValueTooSmallForEncodingReturnsFalse) { 111 const byte test0[] = {0xC0, 0x84}; 112 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test0)))); 113 const byte test1[] = {0xE0, 0x80, 0x80}; 114 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test1)))); 115 const byte test2[] = {0xE0, 0x9F, 0xBF}; 116 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test2)))); 117 const byte test3[] = {0xF0, 0x80, 0x80, 0x80}; 118 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test3)))); 119 const byte test4[] = {0xF0, 0x80, 0x9F, 0xBF}; 120 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test4)))); 121 const byte test5[] = {0xF4, 0x90, 0x80, 0x80}; 122 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test5)))); 123 const byte test6[] = {0xF7, 0xBF, 0xBF, 0xBF}; 124 EXPECT_FALSE(bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(test6)))); 125} 126 127TEST_F(BytesBuiltinsTest, BytesIsValidUTF8WithSurrogateReturnsFalse) { 128 const byte min_surrogate[] = {0xED, 0xA0, 0x80}; 129 EXPECT_FALSE( 130 bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(min_surrogate)))); 131 const byte max_surrogate[] = {0xED, 0xBF, 0xBF}; 132 EXPECT_FALSE( 133 bytesIsValidUTF8(Bytes::cast(runtime_->newBytesWithAll(max_surrogate)))); 134} 135 136TEST_F(BytesBuiltinsTest, BytesIsValidStrWithSurrogateReturnsTrue) { 137 const byte min_surrogate[] = {0xED, 0xA0, 0x80}; 138 EXPECT_TRUE( 139 bytesIsValidStr(Bytes::cast(runtime_->newBytesWithAll(min_surrogate)))); 140 const byte max_surrogate[] = {0xED, 0xBF, 0xBF}; 141 EXPECT_TRUE( 142 bytesIsValidStr(Bytes::cast(runtime_->newBytesWithAll(max_surrogate)))); 143} 144 145TEST_F(BytesBuiltinsTest, BytesSubseqReturnsBytes) { 146 HandleScope scope(thread_); 147 148 View<byte> hello(reinterpret_cast<const byte*>("Hello world!"), 12); 149 Bytes bytes(&scope, runtime_->newBytesWithAll(hello)); 150 ASSERT_EQ(bytes.length(), 12); 151 152 Bytes copy(&scope, bytesSubseq(thread_, bytes, 6, 5)); 153 EXPECT_TRUE(isBytesEqualsCStr(copy, "world")); 154} 155 156TEST_F(BytesBuiltinsTest, FindWithSameBytesReturnsZero) { 157 HandleScope scope(thread_); 158 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 159 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 160 word start = 0; 161 word end = haystack.length(); 162 word result = bytesFind(haystack, haystack.length(), haystack, 163 haystack.length(), start, end); 164 EXPECT_EQ(result, 0); 165} 166 167TEST_F(BytesBuiltinsTest, FindWithWideBoundsReturnsIndex) { 168 HandleScope scope(thread_); 169 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 170 const byte needle_bytes[] = {100, 74}; 171 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 172 Bytes needle(&scope, runtime_->newBytesWithAll(needle_bytes)); 173 word start = -1000; 174 word end = 123; 175 word result = bytesFind(haystack, haystack.length(), needle, needle.length(), 176 start, end); 177 EXPECT_EQ(result, 2); 178} 179 180TEST_F(BytesBuiltinsTest, FindWithNegativeBoundsReturnsIndex) { 181 HandleScope scope(thread_); 182 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 183 const byte needle_bytes[] = {100, 74}; 184 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 185 Bytes needle(&scope, runtime_->newBytesWithAll(needle_bytes)); 186 word start = -5; 187 word end = -2; 188 word result = bytesFind(haystack, haystack.length(), needle, needle.length(), 189 start, end); 190 EXPECT_EQ(result, 2); 191} 192 193TEST_F(BytesBuiltinsTest, FindWithEmptyReturnsAdjustedStart) { 194 HandleScope scope(thread_); 195 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 196 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 197 Bytes needle(&scope, Bytes::empty()); 198 word start = -3; 199 word end = -1; 200 word result = bytesFind(haystack, haystack.length(), needle, needle.length(), 201 start, end); 202 EXPECT_EQ(result, 3); 203} 204 205TEST_F(BytesBuiltinsTest, FindWithEndLessThanStartReturnsNegativeOne) { 206 HandleScope scope(thread_); 207 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 208 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 209 Bytes needle(&scope, Bytes::empty()); 210 word start = 3; 211 word end = 2; 212 word result = bytesFind(haystack, haystack.length(), needle, needle.length(), 213 start, end); 214 EXPECT_EQ(result, -1); 215} 216 217TEST_F(BytesBuiltinsTest, FindWithSingleCharReturnsFirstIndexInRange) { 218 HandleScope scope(thread_); 219 const byte haystack_bytes[] = {100, 55, 100, 74, 100, 118}; 220 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 221 Bytes needle(&scope, runtime_->newBytes(1, 100)); 222 word start = 1; 223 word end = haystack.length(); 224 word result = bytesFind(haystack, haystack.length(), needle, needle.length(), 225 start, end); 226 EXPECT_EQ(result, 2); 227} 228 229TEST_F(BytesBuiltinsTest, RFindWithSameBytesReturnsZero) { 230 HandleScope scope(thread_); 231 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 232 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 233 word start = 0; 234 word end = haystack.length(); 235 word result = bytesRFind(haystack, haystack.length(), haystack, 236 haystack.length(), start, end); 237 EXPECT_EQ(result, 0); 238} 239 240TEST_F(BytesBuiltinsTest, RFindWithWideBoundsReturnsIndex) { 241 HandleScope scope(thread_); 242 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 243 const byte needle_bytes[] = {100, 74}; 244 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 245 Bytes needle(&scope, runtime_->newBytesWithAll(needle_bytes)); 246 word start = -1000; 247 word end = 123; 248 word result = bytesRFind(haystack, haystack.length(), needle, needle.length(), 249 start, end); 250 EXPECT_EQ(result, 2); 251} 252 253TEST_F(BytesBuiltinsTest, RFindWithNegativeBoundsReturnsIndex) { 254 HandleScope scope(thread_); 255 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 256 const byte needle_bytes[] = {100, 74}; 257 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 258 Bytes needle(&scope, runtime_->newBytesWithAll(needle_bytes)); 259 word start = -5; 260 word end = -2; 261 word result = bytesRFind(haystack, haystack.length(), needle, needle.length(), 262 start, end); 263 EXPECT_EQ(result, 2); 264} 265 266TEST_F(BytesBuiltinsTest, RFindWithEmptyReturnsAdjustedEnd) { 267 HandleScope scope(thread_); 268 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 269 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 270 Bytes needle(&scope, Bytes::empty()); 271 word start = -3; 272 word end = -1; 273 word result = bytesRFind(haystack, haystack.length(), needle, needle.length(), 274 start, end); 275 EXPECT_EQ(result, 5); 276} 277 278TEST_F(BytesBuiltinsTest, RFindWithEndLessThanStartReturnsNegativeOne) { 279 HandleScope scope(thread_); 280 const byte haystack_bytes[] = {102, 55, 100, 74, 91, 118}; 281 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 282 Bytes needle(&scope, Bytes::empty()); 283 word start = 3; 284 word end = 2; 285 word result = bytesRFind(haystack, haystack.length(), needle, needle.length(), 286 start, end); 287 EXPECT_EQ(result, -1); 288} 289 290TEST_F(BytesBuiltinsTest, RFindWithSingleCharReturnsLastIndexInRange) { 291 HandleScope scope(thread_); 292 const byte haystack_bytes[] = {100, 55, 100, 74, 100, 118}; 293 Bytes haystack(&scope, runtime_->newBytesWithAll(haystack_bytes)); 294 Bytes needle(&scope, runtime_->newBytes(1, 100)); 295 word start = 0; 296 word end = 4; 297 word result = bytesRFind(haystack, haystack.length(), needle, needle.length(), 298 start, end); 299 EXPECT_EQ(result, 2); 300} 301 302TEST_F(BytesBuiltinsTest, DunderAddWithTooFewArgsRaisesTypeError) { 303 EXPECT_TRUE(raisedWithStr( 304 runFromCStr(runtime_, "bytes.__add__(b'')"), LayoutId::kTypeError, 305 "'bytes.__add__' takes min 2 positional arguments but 1 given")); 306} 307 308TEST_F(BytesBuiltinsTest, DunderAddWithTooManyArgsRaisesTypeError) { 309 EXPECT_TRUE(raisedWithStr( 310 runFromCStr(runtime_, "bytes.__add__(b'', b'', b'')"), 311 LayoutId::kTypeError, 312 "'bytes.__add__' takes max 2 positional arguments but 3 given")); 313} 314 315TEST_F(BytesBuiltinsTest, DunderAddWithNonBytesSelfRaisesTypeError) { 316 HandleScope scope(thread_); 317 Object self(&scope, SmallInt::fromWord(0)); 318 Object other(&scope, runtime_->newBytes(1, '1')); 319 Object sum(&scope, runBuiltin(METH(bytes, __add__), self, other)); 320 EXPECT_TRUE(raised(*sum, LayoutId::kTypeError)); 321} 322 323TEST_F(BytesBuiltinsTest, DunderAddWithNonBytesOtherRaisesTypeError) { 324 HandleScope scope(thread_); 325 Object self(&scope, runtime_->newBytes(1, '1')); 326 Object other(&scope, SmallInt::fromWord(2)); 327 Object sum(&scope, runBuiltin(METH(bytes, __add__), self, other)); 328 EXPECT_TRUE(raised(*sum, LayoutId::kTypeError)); 329} 330 331TEST_F(BytesBuiltinsTest, DunderAddWithBytesLikeOtherReturnsBytes) { 332 Thread* thread = Thread::current(); 333 HandleScope scope(thread); 334 Object self(&scope, runtime_->newBytes(1, '1')); 335 Bytearray other(&scope, runtime_->newBytearray()); 336 const byte buf[] = {'2', '3'}; 337 runtime_->bytearrayExtend(thread, other, buf); 338 Object sum(&scope, runBuiltin(METH(bytes, __add__), self, other)); 339 EXPECT_TRUE(isBytesEqualsCStr(sum, "123")); 340} 341 342TEST_F(BytesBuiltinsTest, DunderAddWithBytesSubclassReturnsBytes) { 343 ASSERT_FALSE(runFromCStr(runtime_, R"( 344class Foo(bytes): pass 345self = Foo(b'abc') 346other = Foo(b'123') 347)") 348 .isError()); 349 HandleScope scope(thread_); 350 Object self(&scope, mainModuleAt(runtime_, "self")); 351 Object other(&scope, mainModuleAt(runtime_, "other")); 352 Object sum(&scope, runBuiltin(METH(bytes, __add__), self, other)); 353 EXPECT_TRUE(isBytesEqualsCStr(sum, "abc123")); 354} 355 356TEST_F(BytesBuiltinsTest, DunderAddWithTwoBytesReturnsConcatenatedBytes) { 357 HandleScope scope(thread_); 358 Object self(&scope, runtime_->newBytes(1, '1')); 359 Object other(&scope, runtime_->newBytes(2, '2')); 360 Object sum(&scope, runBuiltin(METH(bytes, __add__), self, other)); 361 EXPECT_TRUE(isBytesEqualsCStr(sum, "122")); 362} 363 364TEST_F(BytesBuiltinsTest, DunderEqWithTooFewArgsRaisesTypeError) { 365 EXPECT_TRUE(raisedWithStr( 366 runFromCStr(runtime_, "bytes.__eq__(b'')"), LayoutId::kTypeError, 367 "'bytes.__eq__' takes min 2 positional arguments but 1 given")); 368} 369 370TEST_F(BytesBuiltinsTest, DunderEqWithTooManyArgsRaisesTypeError) { 371 EXPECT_TRUE(raisedWithStr( 372 runFromCStr(runtime_, "bytes.__eq__(b'', b'', b'')"), 373 LayoutId::kTypeError, 374 "'bytes.__eq__' takes max 2 positional arguments but 3 given")); 375} 376 377TEST_F(BytesBuiltinsTest, DunderEqWithNonBytesSelfRaisesTypeError) { 378 HandleScope scope(thread_); 379 Object self(&scope, SmallInt::fromWord(0)); 380 Object other(&scope, runtime_->newBytes(1, 'a')); 381 Object eq(&scope, runBuiltin(METH(bytes, __eq__), self, other)); 382 EXPECT_TRUE(raised(*eq, LayoutId::kTypeError)); 383} 384 385TEST_F(BytesBuiltinsTest, DunderEqWithNonBytesOtherReturnsNotImplemented) { 386 HandleScope scope(thread_); 387 Object self(&scope, runtime_->newBytes(1, 'a')); 388 Object other(&scope, SmallInt::fromWord(0)); 389 Object eq(&scope, runBuiltin(METH(bytes, __eq__), self, other)); 390 EXPECT_TRUE(eq.isNotImplementedType()); 391} 392 393TEST_F(BytesBuiltinsTest, DunderEqWithBytesSubclassComparesBytes) { 394 ASSERT_FALSE(runFromCStr(runtime_, R"( 395class Foo(bytes): pass 396self = Foo(b'123') 397other = Foo(b'123') 398)") 399 .isError()); 400 HandleScope scope(thread_); 401 Object self(&scope, mainModuleAt(runtime_, "self")); 402 Object other(&scope, mainModuleAt(runtime_, "other")); 403 Object eq(&scope, runBuiltin(METH(bytes, __eq__), self, other)); 404 EXPECT_EQ(eq, Bool::trueObj()); 405} 406 407TEST_F(BytesBuiltinsTest, DunderEqWithEqualBytesReturnsTrue) { 408 HandleScope scope(thread_); 409 Object self(&scope, runtime_->newBytes(5, 'a')); 410 Object other(&scope, runtime_->newBytes(5, 'a')); 411 Object eq(&scope, runBuiltin(METH(bytes, __eq__), self, other)); 412 ASSERT_TRUE(eq.isBool()); 413 EXPECT_TRUE(Bool::cast(*eq).value()); 414} 415 416TEST_F(BytesBuiltinsTest, DunderEqWithDifferentLengthsReturnsFalse) { 417 HandleScope scope(thread_); 418 Object self(&scope, runtime_->newBytes(1, 'a')); 419 Object other(&scope, runtime_->newBytes(4, 'a')); 420 Object eq(&scope, runBuiltin(METH(bytes, __eq__), self, other)); 421 ASSERT_TRUE(eq.isBool()); 422 EXPECT_FALSE(Bool::cast(*eq).value()); 423} 424 425TEST_F(BytesBuiltinsTest, DunderEqWithDifferentContentsReturnsFalse) { 426 HandleScope scope(thread_); 427 Object self(&scope, runtime_->newBytes(3, 'a')); 428 Object other(&scope, runtime_->newBytes(3, 'b')); 429 Object eq(&scope, runBuiltin(METH(bytes, __eq__), self, other)); 430 ASSERT_TRUE(eq.isBool()); 431 EXPECT_FALSE(Bool::cast(*eq).value()); 432} 433 434TEST_F(BytesBuiltinsTest, DunderGeWithTooFewArgsRaisesTypeError) { 435 EXPECT_TRUE(raisedWithStr( 436 runFromCStr(runtime_, "bytes.__ge__(b'')"), LayoutId::kTypeError, 437 "'bytes.__ge__' takes min 2 positional arguments but 1 given")); 438} 439 440TEST_F(BytesBuiltinsTest, DunderGeWithTooManyArgsRaisesTypeError) { 441 EXPECT_TRUE(raisedWithStr( 442 runFromCStr(runtime_, "bytes.__ge__(b'', b'', b'')"), 443 LayoutId::kTypeError, 444 "'bytes.__ge__' takes max 2 positional arguments but 3 given")); 445} 446 447TEST_F(BytesBuiltinsTest, DunderGeWithNonBytesSelfRaisesTypeError) { 448 HandleScope scope(thread_); 449 Object self(&scope, SmallInt::fromWord(0)); 450 Object other(&scope, runtime_->newBytes(1, 'a')); 451 Object ge(&scope, runBuiltin(METH(bytes, __ge__), self, other)); 452 EXPECT_TRUE(raised(*ge, LayoutId::kTypeError)); 453} 454 455TEST_F(BytesBuiltinsTest, DunderGeWithNonBytesOtherReturnsNotImplemented) { 456 HandleScope scope(thread_); 457 Object self(&scope, runtime_->newBytes(1, 'a')); 458 Object other(&scope, SmallInt::fromWord(0)); 459 Object ge(&scope, runBuiltin(METH(bytes, __ge__), self, other)); 460 ASSERT_TRUE(ge.isNotImplementedType()); 461} 462 463TEST_F(BytesBuiltinsTest, DunderGeWithBytesSubclassComparesBytes) { 464 ASSERT_FALSE(runFromCStr(runtime_, R"( 465class Foo(bytes): pass 466self = Foo(b'123') 467other = Foo(b'123') 468)") 469 .isError()); 470 HandleScope scope(thread_); 471 Object self(&scope, mainModuleAt(runtime_, "self")); 472 Object other(&scope, mainModuleAt(runtime_, "other")); 473 Object ge(&scope, runBuiltin(METH(bytes, __ge__), self, other)); 474 EXPECT_EQ(ge, Bool::trueObj()); 475} 476 477TEST_F(BytesBuiltinsTest, DunderGeWithEqualBytesReturnsTrue) { 478 HandleScope scope(thread_); 479 Object self(&scope, runtime_->newBytes(5, 'a')); 480 Object other(&scope, runtime_->newBytes(5, 'a')); 481 Object ge(&scope, runBuiltin(METH(bytes, __ge__), self, other)); 482 ASSERT_TRUE(ge.isBool()); 483 EXPECT_TRUE(Bool::cast(*ge).value()); 484} 485 486TEST_F(BytesBuiltinsTest, DunderGeWithShorterOtherReturnsTrue) { 487 HandleScope scope(thread_); 488 Object self(&scope, runtime_->newBytes(3, 'a')); 489 Object other(&scope, runtime_->newBytes(2, 'a')); 490 Object ge(&scope, runBuiltin(METH(bytes, __ge__), self, other)); 491 ASSERT_TRUE(ge.isBool()); 492 EXPECT_TRUE(Bool::cast(*ge).value()); 493} 494 495TEST_F(BytesBuiltinsTest, DunderGeWithLongerOtherReturnsFalse) { 496 HandleScope scope(thread_); 497 Object self(&scope, runtime_->newBytes(3, 'a')); 498 Object other(&scope, runtime_->newBytes(4, 'a')); 499 Object ge(&scope, runBuiltin(METH(bytes, __ge__), self, other)); 500 ASSERT_TRUE(ge.isBool()); 501 EXPECT_FALSE(Bool::cast(*ge).value()); 502} 503 504TEST_F(BytesBuiltinsTest, 505 DunderGeWithLexicographicallyEarlierOtherReturnsTrue) { 506 HandleScope scope(thread_); 507 Object self(&scope, runtime_->newBytes(3, 'b')); 508 Object other(&scope, runtime_->newBytes(3, 'a')); 509 Object ge(&scope, runBuiltin(METH(bytes, __ge__), self, other)); 510 ASSERT_TRUE(ge.isBool()); 511 EXPECT_TRUE(Bool::cast(*ge).value()); 512} 513 514TEST_F(BytesBuiltinsTest, DunderGeWithLexicographicallyLaterOtherReturnsFalse) { 515 HandleScope scope(thread_); 516 Object self(&scope, runtime_->newBytes(3, 'a')); 517 Object other(&scope, runtime_->newBytes(3, 'b')); 518 Object ge(&scope, runBuiltin(METH(bytes, __ge__), self, other)); 519 ASSERT_TRUE(ge.isBool()); 520 EXPECT_FALSE(Bool::cast(*ge).value()); 521} 522 523TEST_F(BytesBuiltinsTest, DunderGetitemWithTooFewArgsRaisesTypeError) { 524 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytes.__getitem__(b'')"), 525 LayoutId::kTypeError, 526 "'bytes.__getitem__' takes min 2 positional " 527 "arguments but 1 given")); 528} 529 530TEST_F(BytesBuiltinsTest, DunderGetitemWithTooManyArgsRaisesTypeError) { 531 EXPECT_TRUE( 532 raisedWithStr(runFromCStr(runtime_, "bytes.__getitem__(b'', b'', b'')"), 533 LayoutId::kTypeError, 534 "'bytes.__getitem__' takes max 2 positional " 535 "arguments but 3 given")); 536} 537 538TEST_F(BytesBuiltinsTest, DunderGetitemWithLargeIntRaisesIndexError) { 539 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "b''[2**64]"), 540 LayoutId::kIndexError, 541 "cannot fit 'int' into an index-sized integer")); 542} 543 544TEST_F(BytesBuiltinsTest, 545 DunderGetitemWithIntGreaterOrEqualLenRaisesIndexError) { 546 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "b'abc'[3]"), 547 LayoutId::kIndexError, "index out of range")); 548} 549 550TEST_F(BytesBuiltinsTest, 551 DunderGetitemWithNegativeIntGreaterThanLenRaisesIndexError) { 552 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "b'abc'[-4]"), 553 LayoutId::kIndexError, "index out of range")); 554} 555 556TEST_F(BytesBuiltinsTest, DunderGetitemWithNegativeIntIndexesFromEnd) { 557 HandleScope scope(thread_); 558 ASSERT_FALSE(runFromCStr(runtime_, "result = b'hello'[-5]").isError()); 559 Object result(&scope, mainModuleAt(runtime_, "result")); 560 EXPECT_TRUE(isIntEqualsWord(*result, 'h')); 561} 562 563TEST_F(BytesBuiltinsTest, DunderGetitemIndexesFromBeginning) { 564 HandleScope scope(thread_); 565 ASSERT_FALSE(runFromCStr(runtime_, "result = b'hello'[0]").isError()); 566 Object result(&scope, mainModuleAt(runtime_, "result")); 567 EXPECT_TRUE(isIntEqualsWord(*result, 'h')); 568} 569 570TEST_F(BytesBuiltinsTest, DunderGetitemWithSliceReturnsBytes) { 571 HandleScope scope(thread_); 572 ASSERT_FALSE(runFromCStr(runtime_, "result = b'hello world'[:3]").isError()); 573 Object result(&scope, mainModuleAt(runtime_, "result")); 574 EXPECT_TRUE(isBytesEqualsCStr(result, "hel")); 575} 576 577TEST_F(BytesBuiltinsTest, DunderGetitemWithSliceStepReturnsBytes) { 578 HandleScope scope(thread_); 579 ASSERT_FALSE( 580 runFromCStr(runtime_, "result = b'hello world'[1:6:2]").isError()); 581 Object result(&scope, mainModuleAt(runtime_, "result")); 582 EXPECT_TRUE(isBytesEqualsCStr(result, "el ")); 583} 584 585TEST_F(BytesBuiltinsTest, DunderGetitemWithNonIndexOtherRaisesTypeError) { 586 EXPECT_TRUE( 587 raisedWithStr(runFromCStr(runtime_, "b''[1.5]"), LayoutId::kTypeError, 588 "byte indices must be integers or slice, not float")); 589} 590 591TEST_F(BytesBuiltinsTest, DunderGtWithTooFewArgsRaisesTypeError) { 592 EXPECT_TRUE(raisedWithStr( 593 runFromCStr(runtime_, "bytes.__gt__(b'')"), LayoutId::kTypeError, 594 "'bytes.__gt__' takes min 2 positional arguments but 1 given")); 595} 596 597TEST_F(BytesBuiltinsTest, DunderGtWithTooManyArgsRaisesTypeError) { 598 EXPECT_TRUE(raisedWithStr( 599 runFromCStr(runtime_, "bytes.__gt__(b'', b'', b'')"), 600 LayoutId::kTypeError, 601 "'bytes.__gt__' takes max 2 positional arguments but 3 given")); 602} 603 604TEST_F(BytesBuiltinsTest, DunderGtWithNonBytesSelfRaisesTypeError) { 605 HandleScope scope(thread_); 606 Object self(&scope, SmallInt::fromWord(0)); 607 Object other(&scope, runtime_->newBytes(1, 'a')); 608 Object gt(&scope, runBuiltin(METH(bytes, __gt__), self, other)); 609 EXPECT_TRUE(raised(*gt, LayoutId::kTypeError)); 610} 611 612TEST_F(BytesBuiltinsTest, DunderGtWithNonBytesOtherReturnsNotImplemented) { 613 HandleScope scope(thread_); 614 Object self(&scope, runtime_->newBytes(1, 'a')); 615 Object other(&scope, SmallInt::fromWord(0)); 616 Object gt(&scope, runBuiltin(METH(bytes, __gt__), self, other)); 617 ASSERT_TRUE(gt.isNotImplementedType()); 618} 619 620TEST_F(BytesBuiltinsTest, DunderGtWithBytesSubclassComparesBytes) { 621 ASSERT_FALSE(runFromCStr(runtime_, R"( 622class Foo(bytes): pass 623self = Foo(b'123') 624other = Foo(b'123') 625)") 626 .isError()); 627 HandleScope scope(thread_); 628 Object self(&scope, mainModuleAt(runtime_, "self")); 629 Object other(&scope, mainModuleAt(runtime_, "other")); 630 Object gt(&scope, runBuiltin(METH(bytes, __gt__), self, other)); 631 EXPECT_EQ(gt, Bool::falseObj()); 632} 633 634TEST_F(BytesBuiltinsTest, DunderGtWithEqualBytesReturnsFalse) { 635 HandleScope scope(thread_); 636 Object self(&scope, runtime_->newBytes(5, 'a')); 637 Object other(&scope, runtime_->newBytes(5, 'a')); 638 Object gt(&scope, runBuiltin(METH(bytes, __gt__), self, other)); 639 ASSERT_TRUE(gt.isBool()); 640 EXPECT_FALSE(Bool::cast(*gt).value()); 641} 642 643TEST_F(BytesBuiltinsTest, DunderGtWithShorterOtherReturnsTrue) { 644 HandleScope scope(thread_); 645 Object self(&scope, runtime_->newBytes(3, 'a')); 646 Object other(&scope, runtime_->newBytes(2, 'a')); 647 Object gt(&scope, runBuiltin(METH(bytes, __gt__), self, other)); 648 ASSERT_TRUE(gt.isBool()); 649 EXPECT_TRUE(Bool::cast(*gt).value()); 650} 651 652TEST_F(BytesBuiltinsTest, DunderGtWithLongerOtherReturnsFalse) { 653 HandleScope scope(thread_); 654 Object self(&scope, runtime_->newBytes(3, 'a')); 655 Object other(&scope, runtime_->newBytes(4, 'a')); 656 Object gt(&scope, runBuiltin(METH(bytes, __gt__), self, other)); 657 ASSERT_TRUE(gt.isBool()); 658 EXPECT_FALSE(Bool::cast(*gt).value()); 659} 660 661TEST_F(BytesBuiltinsTest, 662 DunderGtWithLexicographicallyEarlierOtherReturnsTrue) { 663 HandleScope scope(thread_); 664 Object self(&scope, runtime_->newBytes(3, 'b')); 665 Object other(&scope, runtime_->newBytes(3, 'a')); 666 Object gt(&scope, runBuiltin(METH(bytes, __gt__), self, other)); 667 ASSERT_TRUE(gt.isBool()); 668 EXPECT_TRUE(Bool::cast(*gt).value()); 669} 670 671TEST_F(BytesBuiltinsTest, DunderGtWithLexicographicallyLaterOtherReturnsFalse) { 672 HandleScope scope(thread_); 673 Object self(&scope, runtime_->newBytes(3, 'a')); 674 Object other(&scope, runtime_->newBytes(3, 'b')); 675 Object gt(&scope, runBuiltin(METH(bytes, __gt__), self, other)); 676 ASSERT_TRUE(gt.isBool()); 677 EXPECT_FALSE(Bool::cast(*gt).value()); 678} 679 680TEST_F(BytesBuiltinsTest, DunderHashReturnsSmallInt) { 681 Thread* thread = Thread::current(); 682 HandleScope scope(thread); 683 const byte bytes[] = {'h', 'e', 'l', 'l', 'o', '\0'}; 684 Bytes bytes_obj(&scope, runtime_->newBytesWithAll(bytes)); 685 EXPECT_TRUE(runBuiltin(METH(bytes, __hash__), bytes_obj).isSmallInt()); 686} 687 688TEST_F(BytesBuiltinsTest, DunderHashSmallBytesReturnsSmallInt) { 689 Thread* thread = Thread::current(); 690 HandleScope scope(thread); 691 const byte bytes[] = {'h'}; 692 Bytes bytes_obj(&scope, runtime_->newBytesWithAll(bytes)); 693 EXPECT_TRUE(runBuiltin(METH(bytes, __hash__), bytes_obj).isSmallInt()); 694} 695 696TEST_F(BytesBuiltinsTest, DunderHashWithEquivalentBytesReturnsSameHash) { 697 Thread* thread = Thread::current(); 698 HandleScope scope(thread); 699 const byte bytes[] = {'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd', '\0'}; 700 Bytes bytes_obj1(&scope, runtime_->newBytesWithAll(bytes)); 701 Bytes bytes_obj2(&scope, runtime_->newBytesWithAll(bytes)); 702 EXPECT_NE(*bytes_obj1, *bytes_obj2); 703 Object result1(&scope, runBuiltin(METH(bytes, __hash__), bytes_obj1)); 704 Object result2(&scope, runBuiltin(METH(bytes, __hash__), bytes_obj2)); 705 EXPECT_TRUE(result1.isSmallInt()); 706 EXPECT_TRUE(result2.isSmallInt()); 707 EXPECT_EQ(*result1, *result2); 708} 709 710TEST_F(BytesBuiltinsTest, DunderHashWithBytesSubclassReturnsSameHash) { 711 HandleScope scope(thread_); 712 ASSERT_FALSE(runFromCStr(runtime_, R"( 713class C(bytes): pass 714i0 = C(b"abc") 715i1 = b"abc" 716)") 717 .isError()); 718 Object i0(&scope, mainModuleAt(runtime_, "i0")); 719 Object i1(&scope, mainModuleAt(runtime_, "i1")); 720 721 Object result0(&scope, runBuiltin(METH(bytes, __hash__), i0)); 722 Object result1(&scope, runBuiltin(METH(bytes, __hash__), i1)); 723 EXPECT_TRUE(result0.isSmallInt()); 724 EXPECT_TRUE(result1.isSmallInt()); 725 EXPECT_EQ(result0, result1); 726} 727 728TEST_F(BytesBuiltinsTest, DunderIterReturnsBytesIterator) { 729 HandleScope scope(thread_); 730 Object self(&scope, Bytes::empty()); 731 Object result(&scope, runBuiltin(METH(bytes, __iter__), self)); 732 EXPECT_TRUE(result.isBytesIterator()); 733} 734 735TEST_F(BytesBuiltinsTest, DunderLeWithTooFewArgsRaisesTypeError) { 736 EXPECT_TRUE(raisedWithStr( 737 runFromCStr(runtime_, "bytes.__le__(b'')"), LayoutId::kTypeError, 738 "'bytes.__le__' takes min 2 positional arguments but 1 given")); 739} 740 741TEST_F(BytesBuiltinsTest, DunderLeWithTooManyArgsRaisesTypeError) { 742 EXPECT_TRUE(raisedWithStr( 743 runFromCStr(runtime_, "bytes.__le__(b'', b'', b'')"), 744 LayoutId::kTypeError, 745 "'bytes.__le__' takes max 2 positional arguments but 3 given")); 746} 747 748TEST_F(BytesBuiltinsTest, DunderLeWithNonBytesSelfRaisesTypeError) { 749 HandleScope scope(thread_); 750 Object self(&scope, SmallInt::fromWord(0)); 751 Object other(&scope, runtime_->newBytes(1, 'a')); 752 Object le(&scope, runBuiltin(METH(bytes, __le__), self, other)); 753 EXPECT_TRUE(raised(*le, LayoutId::kTypeError)); 754} 755 756TEST_F(BytesBuiltinsTest, DunderLeWithNonBytesOtherReturnsNotImplemented) { 757 HandleScope scope(thread_); 758 Object self(&scope, runtime_->newBytes(1, 'a')); 759 Object other(&scope, SmallInt::fromWord(0)); 760 Object le(&scope, runBuiltin(METH(bytes, __le__), self, other)); 761 ASSERT_TRUE(le.isNotImplementedType()); 762} 763 764TEST_F(BytesBuiltinsTest, DunderLeWithBytesSubclassComparesBytes) { 765 ASSERT_FALSE(runFromCStr(runtime_, R"( 766class Foo(bytes): pass 767self = Foo(b'123') 768other = Foo(b'123') 769)") 770 .isError()); 771 HandleScope scope(thread_); 772 Object self(&scope, mainModuleAt(runtime_, "self")); 773 Object other(&scope, mainModuleAt(runtime_, "other")); 774 Object le(&scope, runBuiltin(METH(bytes, __le__), self, other)); 775 EXPECT_EQ(le, Bool::trueObj()); 776} 777 778TEST_F(BytesBuiltinsTest, DunderLeWithEqualBytesReturnsTrue) { 779 HandleScope scope(thread_); 780 Object self(&scope, runtime_->newBytes(5, 'a')); 781 Object other(&scope, runtime_->newBytes(5, 'a')); 782 Object le(&scope, runBuiltin(METH(bytes, __le__), self, other)); 783 ASSERT_TRUE(le.isBool()); 784 EXPECT_TRUE(Bool::cast(*le).value()); 785} 786 787TEST_F(BytesBuiltinsTest, DunderLeWithShorterOtherReturnsFalse) { 788 HandleScope scope(thread_); 789 Object self(&scope, runtime_->newBytes(3, 'a')); 790 Object other(&scope, runtime_->newBytes(2, 'a')); 791 Object le(&scope, runBuiltin(METH(bytes, __le__), self, other)); 792 ASSERT_TRUE(le.isBool()); 793 EXPECT_FALSE(Bool::cast(*le).value()); 794} 795 796TEST_F(BytesBuiltinsTest, DunderLeWithLongerOtherReturnsTrue) { 797 HandleScope scope(thread_); 798 Object self(&scope, runtime_->newBytes(3, 'a')); 799 Object other(&scope, runtime_->newBytes(4, 'a')); 800 Object le(&scope, runBuiltin(METH(bytes, __le__), self, other)); 801 ASSERT_TRUE(le.isBool()); 802 EXPECT_TRUE(Bool::cast(*le).value()); 803} 804 805TEST_F(BytesBuiltinsTest, 806 DunderLeWithLexicographicallyEarlierOtherReturnsFalse) { 807 HandleScope scope(thread_); 808 Object self(&scope, runtime_->newBytes(3, 'b')); 809 Object other(&scope, runtime_->newBytes(3, 'a')); 810 Object le(&scope, runBuiltin(METH(bytes, __le__), self, other)); 811 ASSERT_TRUE(le.isBool()); 812 EXPECT_FALSE(Bool::cast(*le).value()); 813} 814 815TEST_F(BytesBuiltinsTest, DunderLeWithLexicographicallyLaterOtherReturnsTrue) { 816 HandleScope scope(thread_); 817 Object self(&scope, runtime_->newBytes(3, 'a')); 818 Object other(&scope, runtime_->newBytes(3, 'b')); 819 Object le(&scope, runBuiltin(METH(bytes, __le__), self, other)); 820 ASSERT_TRUE(le.isBool()); 821 EXPECT_TRUE(Bool::cast(*le).value()); 822} 823 824TEST_F(BytesBuiltinsTest, DunderLenWithTooFewArgsRaisesTypeError) { 825 EXPECT_TRUE(raisedWithStr( 826 runFromCStr(runtime_, "bytes.__len__()"), LayoutId::kTypeError, 827 "'bytes.__len__' takes min 1 positional arguments but 0 given")); 828} 829 830TEST_F(BytesBuiltinsTest, DunderLenWithTooManyArgsRaisesTypeError) { 831 EXPECT_TRUE(raisedWithStr( 832 runFromCStr(runtime_, "bytes.__len__(b'', b'')"), LayoutId::kTypeError, 833 "'bytes.__len__' takes max 1 positional arguments but 2 given")); 834} 835 836TEST_F(BytesBuiltinsTest, DunderLenWithNonBytesSelfRaisesTypeError) { 837 HandleScope scope(thread_); 838 Object self(&scope, SmallInt::fromWord(0)); 839 Object len(&scope, runBuiltin(METH(bytes, __len__), self)); 840 EXPECT_TRUE(raised(*len, LayoutId::kTypeError)); 841} 842 843TEST_F(BytesBuiltinsTest, DunderLenWithEmptyBytesReturnsZero) { 844 HandleScope scope(thread_); 845 Object self(&scope, runtime_->newBytesWithAll(View<byte>(nullptr, 0))); 846 Object len(&scope, runBuiltin(METH(bytes, __len__), self)); 847 EXPECT_EQ(len, SmallInt::fromWord(0)); 848} 849 850TEST_F(BytesBuiltinsTest, DunderLenWithNonEmptyBytesReturnsLength) { 851 HandleScope scope(thread_); 852 Object self(&scope, runtime_->newBytes(4, 'a')); 853 Object len(&scope, runBuiltin(METH(bytes, __len__), self)); 854 EXPECT_EQ(len, SmallInt::fromWord(4)); 855} 856 857TEST_F(BytesBuiltinsTest, DunderLenWithBytesSubclassReturnsLength) { 858 ASSERT_FALSE(runFromCStr(runtime_, R"( 859class Foo(bytes): pass 860self = Foo(b"1234567890") 861 )") 862 .isError()); 863 HandleScope scope(thread_); 864 Object self(&scope, mainModuleAt(runtime_, "self")); 865 Object len(&scope, runBuiltin(METH(bytes, __len__), self)); 866 EXPECT_EQ(len, SmallInt::fromWord(10)); 867} 868 869TEST_F(BytesBuiltinsTest, DunderLtWithTooFewArgsRaisesTypeError) { 870 EXPECT_TRUE(raisedWithStr( 871 runFromCStr(runtime_, "bytes.__lt__(b'')"), LayoutId::kTypeError, 872 "'bytes.__lt__' takes min 2 positional arguments but 1 given")); 873} 874 875TEST_F(BytesBuiltinsTest, DunderLtWithTooManyArgsRaisesTypeError) { 876 EXPECT_TRUE(raisedWithStr( 877 runFromCStr(runtime_, "bytes.__lt__(b'', b'', b'')"), 878 LayoutId::kTypeError, 879 "'bytes.__lt__' takes max 2 positional arguments but 3 given")); 880} 881 882TEST_F(BytesBuiltinsTest, DunderLtWithNonBytesSelfRaisesTypeError) { 883 HandleScope scope(thread_); 884 Object self(&scope, SmallInt::fromWord(0)); 885 Object other(&scope, runtime_->newBytes(1, 'a')); 886 Object lt(&scope, runBuiltin(METH(bytes, __lt__), self, other)); 887 EXPECT_TRUE(raised(*lt, LayoutId::kTypeError)); 888} 889 890TEST_F(BytesBuiltinsTest, DunderLtWithNonBytesOtherReturnsNotImplemented) { 891 HandleScope scope(thread_); 892 Object self(&scope, runtime_->newBytes(1, 'a')); 893 Object other(&scope, SmallInt::fromWord(0)); 894 Object lt(&scope, runBuiltin(METH(bytes, __lt__), self, other)); 895 ASSERT_TRUE(lt.isNotImplementedType()); 896} 897 898TEST_F(BytesBuiltinsTest, DunderLtWithBytesSubclassComparesBytes) { 899 ASSERT_FALSE(runFromCStr(runtime_, R"( 900class Foo(bytes): pass 901self = Foo(b'123') 902other = Foo(b'123') 903)") 904 .isError()); 905 HandleScope scope(thread_); 906 Object self(&scope, mainModuleAt(runtime_, "self")); 907 Object other(&scope, mainModuleAt(runtime_, "other")); 908 Object lt(&scope, runBuiltin(METH(bytes, __lt__), self, other)); 909 EXPECT_EQ(lt, Bool::falseObj()); 910} 911 912TEST_F(BytesBuiltinsTest, DunderLtWithEqualBytesReturnsFalse) { 913 HandleScope scope(thread_); 914 Object self(&scope, runtime_->newBytes(5, 'a')); 915 Object other(&scope, runtime_->newBytes(5, 'a')); 916 Object lt(&scope, runBuiltin(METH(bytes, __lt__), self, other)); 917 ASSERT_TRUE(lt.isBool()); 918 EXPECT_FALSE(Bool::cast(*lt).value()); 919} 920 921TEST_F(BytesBuiltinsTest, DunderLtWithShorterOtherReturnsFalse) { 922 HandleScope scope(thread_); 923 Object self(&scope, runtime_->newBytes(3, 'a')); 924 Object other(&scope, runtime_->newBytes(2, 'a')); 925 Object lt(&scope, runBuiltin(METH(bytes, __lt__), self, other)); 926 ASSERT_TRUE(lt.isBool()); 927 EXPECT_FALSE(Bool::cast(*lt).value()); 928} 929 930TEST_F(BytesBuiltinsTest, DunderLtWithLongerOtherReturnsTrue) { 931 HandleScope scope(thread_); 932 Object self(&scope, runtime_->newBytes(3, 'a')); 933 Object other(&scope, runtime_->newBytes(4, 'a')); 934 Object lt(&scope, runBuiltin(METH(bytes, __lt__), self, other)); 935 ASSERT_TRUE(lt.isBool()); 936 EXPECT_TRUE(Bool::cast(*lt).value()); 937} 938 939TEST_F(BytesBuiltinsTest, 940 DunderLtWithLexicographicallyEarlierOtherReturnsFalse) { 941 HandleScope scope(thread_); 942 Object self(&scope, runtime_->newBytes(3, 'b')); 943 Object other(&scope, runtime_->newBytes(3, 'a')); 944 Object lt(&scope, runBuiltin(METH(bytes, __lt__), self, other)); 945 ASSERT_TRUE(lt.isBool()); 946 EXPECT_FALSE(Bool::cast(*lt).value()); 947} 948 949TEST_F(BytesBuiltinsTest, DunderLtWithLexicographicallyLaterOtherReturnsTrue) { 950 HandleScope scope(thread_); 951 Object self(&scope, runtime_->newBytes(3, 'a')); 952 Object other(&scope, runtime_->newBytes(3, 'b')); 953 Object lt(&scope, runBuiltin(METH(bytes, __lt__), self, other)); 954 ASSERT_TRUE(lt.isBool()); 955 EXPECT_TRUE(Bool::cast(*lt).value()); 956} 957 958TEST_F(BytesBuiltinsTest, DunderMulWithNonIntRaisesTypeError) { 959 HandleScope scope(thread_); 960 Object self(&scope, Bytes::empty()); 961 Object count(&scope, runtime_->newList()); 962 EXPECT_TRUE(raisedWithStr( 963 runBuiltin(METH(bytes, __mul__), self, count), LayoutId::kTypeError, 964 "'list' object cannot be interpreted as an integer")); 965} 966 967TEST_F(BytesBuiltinsTest, DunderMulWithIntSubclassReturnsRepeatedBytes) { 968 HandleScope scope(thread_); 969 const byte view[] = {'a', 'b', 'c'}; 970 Object self(&scope, runtime_->newBytesWithAll(view)); 971 ASSERT_FALSE(runFromCStr(runtime_, R"( 972class C(int): pass 973count = C(4) 974)") 975 .isError()); 976 Object count(&scope, mainModuleAt(runtime_, "count")); 977 Object result(&scope, runBuiltin(METH(bytes, __mul__), self, count)); 978 EXPECT_TRUE(isBytesEqualsCStr(result, "abcabcabcabc")); 979} 980 981TEST_F(BytesBuiltinsTest, DunderMulWithDunderIndexReturnsRepeatedBytes) { 982 HandleScope scope(thread_); 983 Object self(&scope, runtime_->newBytes(1, 'a')); 984 ASSERT_FALSE(runFromCStr(runtime_, R"( 985class C: 986 def __index__(self): 987 return 2 988count = C() 989)") 990 .isError()); 991 Object count(&scope, mainModuleAt(runtime_, "count")); 992 Object result(&scope, runBuiltin(METH(bytes, __mul__), self, count)); 993 EXPECT_TRUE(isBytesEqualsCStr(result, "aa")); 994} 995 996TEST_F(BytesBuiltinsTest, DunderMulWithBadDunderIndexRaisesTypeError) { 997 HandleScope scope(thread_); 998 Object self(&scope, runtime_->newBytes(1, 'a')); 999 ASSERT_FALSE(runFromCStr(runtime_, R"( 1000class C: 1001 def __index__(self): 1002 return "foo" 1003count = C() 1004)") 1005 .isError()); 1006 Object count(&scope, mainModuleAt(runtime_, "count")); 1007 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytes, __mul__), self, count), 1008 LayoutId::kTypeError, 1009 "__index__ returned non-int (type str)")); 1010} 1011 1012TEST_F(BytesBuiltinsTest, DunderMulPropagatesDunderIndexError) { 1013 HandleScope scope(thread_); 1014 Object self(&scope, runtime_->newBytes(1, 'a')); 1015 ASSERT_FALSE(runFromCStr(runtime_, R"( 1016class C: 1017 def __index__(self): 1018 raise ArithmeticError("called __index__") 1019count = C() 1020)") 1021 .isError()); 1022 Object count(&scope, mainModuleAt(runtime_, "count")); 1023 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytes, __mul__), self, count), 1024 LayoutId::kArithmeticError, "called __index__")); 1025} 1026 1027TEST_F(BytesBuiltinsTest, DunderMulWithLargeIntRaisesOverflowError) { 1028 HandleScope scope(thread_); 1029 Object self(&scope, Bytes::empty()); 1030 const uword digits[] = {1, 1}; 1031 Object count(&scope, runtime_->newLargeIntWithDigits(digits)); 1032 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytes, __mul__), self, count), 1033 LayoutId::kOverflowError, 1034 "cannot fit 'int' into an index-sized integer")); 1035} 1036 1037TEST_F(BytesBuiltinsTest, DunderMulWithOverflowRaisesOverflowError) { 1038 HandleScope scope(thread_); 1039 Object self(&scope, runtime_->newBytes(3, 'a')); 1040 Object count(&scope, SmallInt::fromWord(SmallInt::kMaxValue / 2)); 1041 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(bytes, __mul__), self, count), 1042 LayoutId::kOverflowError, 1043 "repeated bytes are too long")); 1044} 1045 1046TEST_F(BytesBuiltinsTest, DunderMulWithEmptyBytesReturnsEmptyBytes) { 1047 HandleScope scope(thread_); 1048 Object self(&scope, Bytes::empty()); 1049 Object count(&scope, runtime_->newInt(10)); 1050 Object result(&scope, runBuiltin(METH(bytes, __mul__), self, count)); 1051 EXPECT_TRUE(isBytesEqualsCStr(result, "")); 1052} 1053 1054TEST_F(BytesBuiltinsTest, DunderMulWithNegativeReturnsEmptyBytes) { 1055 HandleScope scope(thread_); 1056 Object self(&scope, runtime_->newBytes(4, 'a')); 1057 Object count(&scope, SmallInt::fromWord(-5)); 1058 Object result(&scope, runBuiltin(METH(bytes, __mul__), self, count)); 1059 EXPECT_TRUE(isBytesEqualsCStr(result, "")); 1060} 1061 1062TEST_F(BytesBuiltinsTest, DunderMulWithZeroReturnsEmptyBytes) { 1063 HandleScope scope(thread_); 1064 Object self(&scope, runtime_->newBytes(4, 'a')); 1065 Object count(&scope, SmallInt::fromWord(0)); 1066 Object result(&scope, runBuiltin(METH(bytes, __mul__), self, count)); 1067 EXPECT_TRUE(isBytesEqualsCStr(result, "")); 1068} 1069 1070TEST_F(BytesBuiltinsTest, DunderMulWithOneReturnsSameBytes) { 1071 HandleScope scope(thread_); 1072 const byte bytes_array[] = {'a', 'b'}; 1073 Object self(&scope, runtime_->newBytesWithAll(bytes_array)); 1074 Object count(&scope, SmallInt::fromWord(1)); 1075 Object result(&scope, runBuiltin(METH(bytes, __mul__), self, count)); 1076 EXPECT_TRUE(isBytesEqualsCStr(result, "ab")); 1077} 1078 1079TEST_F(BytesBuiltinsTest, DunderMulReturnsRepeatedBytes) { 1080 HandleScope scope(thread_); 1081 const byte bytes_array[] = {'a', 'b'}; 1082 Object self(&scope, runtime_->newBytesWithAll(bytes_array)); 1083 Object count(&scope, SmallInt::fromWord(3)); 1084 Object result(&scope, runBuiltin(METH(bytes, __mul__), self, count)); 1085 EXPECT_TRUE(isBytesEqualsCStr(result, "ababab")); 1086} 1087 1088TEST_F(BytesBuiltinsTest, DunderMulWithBytesSubclassReturnsRepeatedBytes) { 1089 ASSERT_FALSE(runFromCStr(runtime_, R"( 1090class Foo(bytes): pass 1091self = Foo(b"ab") 1092)") 1093 .isError()); 1094 HandleScope scope(thread_); 1095 Object self(&scope, mainModuleAt(runtime_, "self")); 1096 Object count(&scope, SmallInt::fromWord(3)); 1097 Object result(&scope, runBuiltin(METH(bytes, __mul__), self, count)); 1098 EXPECT_TRUE(isBytesEqualsCStr(result, "ababab")); 1099} 1100 1101TEST_F(BytesBuiltinsTest, DunderNeWithTooFewArgsRaisesTypeError) { 1102 EXPECT_TRUE(raisedWithStr( 1103 runFromCStr(runtime_, "bytes.__ne__(b'')"), LayoutId::kTypeError, 1104 "'bytes.__ne__' takes min 2 positional arguments but 1 given")); 1105} 1106 1107TEST_F(BytesBuiltinsTest, DunderNeWithTooManyArgsRaisesTypeError) { 1108 EXPECT_TRUE(raisedWithStr( 1109 runFromCStr(runtime_, "bytes.__ne__(b'', b'', b'')"), 1110 LayoutId::kTypeError, 1111 "'bytes.__ne__' takes max 2 positional arguments but 3 given")); 1112} 1113 1114TEST_F(BytesBuiltinsTest, DunderNeWithNonBytesSelfRaisesTypeError) { 1115 HandleScope scope(thread_); 1116 Object self(&scope, SmallInt::fromWord(0)); 1117 Object other(&scope, runtime_->newBytes(1, 'a')); 1118 Object ne(&scope, runBuiltin(METH(bytes, __ne__), self, other)); 1119 EXPECT_TRUE(raised(*ne, LayoutId::kTypeError)); 1120} 1121 1122TEST_F(BytesBuiltinsTest, DunderNeWithNonBytesOtherReturnsNotImplemented) { 1123 HandleScope scope(thread_); 1124 Object self(&scope, runtime_->newBytes(1, 'a')); 1125 Object other(&scope, SmallInt::fromWord(0)); 1126 Object ne(&scope, runBuiltin(METH(bytes, __ne__), self, other)); 1127 EXPECT_TRUE(ne.isNotImplementedType()); 1128} 1129 1130TEST_F(BytesBuiltinsTest, DunderNeWithBytesSubclassComparesBytes) { 1131 ASSERT_FALSE(runFromCStr(runtime_, R"( 1132class Foo(bytes): pass 1133self = Foo(b'123') 1134other = Foo(b'123') 1135)") 1136 .isError()); 1137 HandleScope scope(thread_); 1138 Object self(&scope, mainModuleAt(runtime_, "self")); 1139 Object other(&scope, mainModuleAt(runtime_, "other")); 1140 Object ne(&scope, runBuiltin(METH(bytes, __ne__), self, other)); 1141 EXPECT_EQ(ne, Bool::falseObj()); 1142} 1143 1144TEST_F(BytesBuiltinsTest, DunderNeWithEqualBytesReturnsFalse) { 1145 HandleScope scope(thread_); 1146 Object self(&scope, runtime_->newBytes(5, 'a')); 1147 Object other(&scope, runtime_->newBytes(5, 'a')); 1148 Object ne(&scope, runBuiltin(METH(bytes, __ne__), self, other)); 1149 ASSERT_TRUE(ne.isBool()); 1150 EXPECT_FALSE(Bool::cast(*ne).value()); 1151} 1152 1153TEST_F(BytesBuiltinsTest, DunderNeWithDifferentLengthsReturnsTrue) { 1154 HandleScope scope(thread_); 1155 Object self(&scope, runtime_->newBytes(1, 'a')); 1156 Object other(&scope, runtime_->newBytes(4, 'a')); 1157 Object ne(&scope, runBuiltin(METH(bytes, __ne__), self, other)); 1158 ASSERT_TRUE(ne.isBool()); 1159 EXPECT_TRUE(Bool::cast(*ne).value()); 1160} 1161 1162TEST_F(BytesBuiltinsTest, DunderNeWithDifferentContentsReturnsTrue) { 1163 HandleScope scope(thread_); 1164 Object self(&scope, runtime_->newBytes(3, 'a')); 1165 Object other(&scope, runtime_->newBytes(3, 'b')); 1166 Object ne(&scope, runBuiltin(METH(bytes, __ne__), self, other)); 1167 ASSERT_TRUE(ne.isBool()); 1168 EXPECT_TRUE(Bool::cast(*ne).value()); 1169} 1170 1171TEST_F(BytesBuiltinsTest, DunderNewWithoutSourceWithEncodingRaisesTypeError) { 1172 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytes(encoding='ascii')"), 1173 LayoutId::kTypeError, 1174 "encoding or errors without sequence argument")); 1175} 1176 1177TEST_F(BytesBuiltinsTest, DunderNewWithoutSourceWithErrorsRaisesTypeError) { 1178 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytes(errors='strict')"), 1179 LayoutId::kTypeError, 1180 "encoding or errors without sequence argument")); 1181} 1182 1183TEST_F(BytesBuiltinsTest, DunderNewWithoutArgsReturnsEmptyBytes) { 1184 HandleScope scope(thread_); 1185 ASSERT_FALSE(runFromCStr(runtime_, "obj = bytes()").isError()); 1186 Object obj(&scope, mainModuleAt(runtime_, "obj")); 1187 EXPECT_TRUE(isBytesEqualsCStr(obj, "")); 1188} 1189 1190TEST_F(BytesBuiltinsTest, 1191 DunderNewWithNonStringSourceWithEncodingRaisesTypeError) { 1192 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytes(1, 'ascii')"), 1193 LayoutId::kTypeError, 1194 "encoding without a string argument")); 1195} 1196 1197TEST_F(BytesBuiltinsTest, 1198 DunderNewWithoutEncodingWithErrorsAndStringSourceRaisesTypeError) { 1199 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytes('', errors='strict')"), 1200 LayoutId::kTypeError, 1201 "string argument without an encoding")); 1202} 1203 1204TEST_F(BytesBuiltinsTest, 1205 DunderNewWithoutEncodingWithErrorsAndNonStringSourceRaisesTypeError) { 1206 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytes(1, errors='strict')"), 1207 LayoutId::kTypeError, 1208 "errors without a string argument")); 1209} 1210 1211TEST_F(BytesBuiltinsTest, DunderNewWithMistypedDunderBytesRaisesTypeError) { 1212 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1213class Foo: 1214 def __bytes__(self): return 1 1215bytes(Foo()) 1216)"), 1217 LayoutId::kTypeError, 1218 "__bytes__ returned non-bytes (type int)")); 1219} 1220 1221TEST_F(BytesBuiltinsTest, DunderNewPropagatesDunderBytesError) { 1222 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1223class Foo: 1224 def __bytes__(self): raise SystemError("foo") 1225bytes(Foo()) 1226)"), 1227 LayoutId::kSystemError, "foo")); 1228} 1229 1230TEST_F(BytesBuiltinsTest, DunderNewWithDunderBytesReturnsBytes) { 1231 HandleScope scope(thread_); 1232 ASSERT_FALSE(runFromCStr(runtime_, R"( 1233class Foo: 1234 def __bytes__(self): return b'foo' 1235result = bytes(Foo()) 1236)") 1237 .isError()); 1238 Object result(&scope, mainModuleAt(runtime_, "result")); 1239 EXPECT_TRUE(isBytesEqualsCStr(result, "foo")); 1240} 1241 1242TEST_F(BytesBuiltinsTest, DunderNewWithNegativeIntegerSourceRaisesValueError) { 1243 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "result = bytes(-1)"), 1244 LayoutId::kValueError, "negative count")); 1245} 1246 1247TEST_F(BytesBuiltinsTest, DunderNewWithLargeIntegerSourceRaisesOverflowError) { 1248 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "result = bytes(2**63)"), 1249 LayoutId::kOverflowError, 1250 "cannot fit 'int' into an index-sized integer")); 1251} 1252 1253TEST_F(BytesBuiltinsTest, DunderNewWithIntegerSourceReturnsZeroFilledBytes) { 1254 HandleScope scope(thread_); 1255 ASSERT_FALSE(runFromCStr(runtime_, "result = bytes(10)").isError()); 1256 Object result(&scope, mainModuleAt(runtime_, "result")); 1257 const byte bytes[10] = {}; 1258 EXPECT_TRUE(isBytesEqualsBytes(result, bytes)); 1259} 1260 1261TEST_F(BytesBuiltinsTest, DunderNewWithBytesReturnsSameBytes) { 1262 HandleScope scope(thread_); 1263 ASSERT_FALSE(runFromCStr(runtime_, "result = bytes(b'123')").isError()); 1264 Object result(&scope, mainModuleAt(runtime_, "result")); 1265 const byte bytes[] = {'1', '2', '3'}; 1266 EXPECT_TRUE(isBytesEqualsBytes(result, bytes)); 1267} 1268 1269TEST_F(BytesBuiltinsTest, DunderNewWithBytearrayReturnsBytesCopy) { 1270 HandleScope scope(thread_); 1271 ASSERT_FALSE( 1272 runFromCStr(runtime_, "result = bytes(bytearray(b'123'))").isError()); 1273 Object result(&scope, mainModuleAt(runtime_, "result")); 1274 const byte bytes[] = {'1', '2', '3'}; 1275 EXPECT_TRUE(isBytesEqualsBytes(result, bytes)); 1276} 1277 1278TEST_F(BytesBuiltinsTest, DunderNewWithListReturnsNewBytes) { 1279 HandleScope scope(thread_); 1280 ASSERT_FALSE(runFromCStr(runtime_, "result = bytes([6, 28])").isError()); 1281 Object result(&scope, mainModuleAt(runtime_, "result")); 1282 const byte bytes[] = {6, 28}; 1283 EXPECT_TRUE(isBytesEqualsBytes(result, bytes)); 1284} 1285 1286TEST_F(BytesBuiltinsTest, DunderNewWithTupleReturnsNewBytes) { 1287 HandleScope scope(thread_); 1288 ASSERT_FALSE(runFromCStr(runtime_, "result = bytes((6, 28))").isError()); 1289 Object result(&scope, mainModuleAt(runtime_, "result")); 1290 const byte bytes[] = {6, 28}; 1291 EXPECT_TRUE(isBytesEqualsBytes(result, bytes)); 1292} 1293 1294TEST_F(BytesBuiltinsTest, DunderNewWithNegativeRaisesValueError) { 1295 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "result = bytes([-1])"), 1296 LayoutId::kValueError, 1297 "bytes must be in range(0, 256)")); 1298} 1299 1300TEST_F(BytesBuiltinsTest, DunderNewWithGreaterThanByteRaisesValueError) { 1301 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "result = bytes([256])"), 1302 LayoutId::kValueError, 1303 "bytes must be in range(0, 256)")); 1304} 1305 1306TEST_F(BytesBuiltinsTest, DunderNewWithIterableReturnsNewBytes) { 1307 HandleScope scope(thread_); 1308 ASSERT_FALSE(runFromCStr(runtime_, R"( 1309class Foo: 1310 def __iter__(self): 1311 return [1, 2, 3].__iter__() 1312result = bytes(Foo()) 1313)") 1314 .isError()); 1315 Object result(&scope, mainModuleAt(runtime_, "result")); 1316 const byte expected[] = {1, 2, 3}; 1317 EXPECT_TRUE(isBytesEqualsBytes(result, expected)); 1318} 1319 1320TEST_F(BytesBuiltinsTest, DunderReprWithEmptyBytesReturnsEmptyRepr) { 1321 HandleScope scope(thread_); 1322 Object self(&scope, Bytes::empty()); 1323 Object repr(&scope, runBuiltin(METH(bytes, __repr__), self)); 1324 EXPECT_TRUE(isStrEqualsCStr(*repr, "b''")); 1325} 1326 1327TEST_F(BytesBuiltinsTest, DunderReprWithSimpleBytesReturnsRepr) { 1328 HandleScope scope(thread_); 1329 Object self(&scope, runtime_->newBytes(10, '*')); 1330 Object repr(&scope, runBuiltin(METH(bytes, __repr__), self)); 1331 EXPECT_TRUE(isStrEqualsCStr(*repr, "b'**********'")); 1332} 1333 1334TEST_F(BytesBuiltinsTest, DunderReprWithBytesSubclassReturnsStr) { 1335 ASSERT_FALSE(runFromCStr(runtime_, R"( 1336class Foo(bytes): pass 1337self = Foo(b"*****") 1338)") 1339 .isError()); 1340 HandleScope scope(thread_); 1341 Object self(&scope, mainModuleAt(runtime_, "self")); 1342 Object repr(&scope, runBuiltin(METH(bytes, __repr__), self)); 1343 EXPECT_TRUE(isStrEqualsCStr(*repr, "b'*****'")); 1344} 1345 1346TEST_F(BytesBuiltinsTest, DunderReprWithDoubleQuoteUsesSingleQuoteDelimiters) { 1347 HandleScope scope(thread_); 1348 const byte view[] = {'_', '"', '_'}; 1349 Object self(&scope, runtime_->newBytesWithAll(view)); 1350 Object repr(&scope, runBuiltin(METH(bytes, __repr__), self)); 1351 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(b'_"_')")); 1352} 1353 1354TEST_F(BytesBuiltinsTest, DunderReprWithSingleQuoteUsesDoubleQuoteDelimiters) { 1355 HandleScope scope(thread_); 1356 const byte view[] = {'_', '\'', '_'}; 1357 Object self(&scope, runtime_->newBytesWithAll(view)); 1358 Object repr(&scope, runBuiltin(METH(bytes, __repr__), self)); 1359 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(b"_'_")")); 1360} 1361 1362TEST_F(BytesBuiltinsTest, DunderReprWithBothQuotesUsesSingleQuoteDelimiters) { 1363 HandleScope scope(thread_); 1364 const byte view[] = {'_', '"', '_', '\'', '_'}; 1365 Object self(&scope, runtime_->newBytesWithAll(view)); 1366 Object repr(&scope, runBuiltin(METH(bytes, __repr__), self)); 1367 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(b'_"_\'_')")); 1368} 1369 1370TEST_F(BytesBuiltinsTest, DunderReprWithSpeciaBytesUsesEscapeSequences) { 1371 HandleScope scope(thread_); 1372 const byte view[] = {'\\', '\t', '\n', '\r'}; 1373 Object self(&scope, runtime_->newBytesWithAll(view)); 1374 Object repr(&scope, runBuiltin(METH(bytes, __repr__), self)); 1375 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(b'\\\t\n\r')")); 1376} 1377 1378TEST_F(BytesBuiltinsTest, DunderReprWithSmallAndLargeBytesUsesHex) { 1379 HandleScope scope(thread_); 1380 const byte view[] = {0, 0x1f, 0x80, 0xff}; 1381 Object self(&scope, runtime_->newBytesWithAll(view)); 1382 Object repr(&scope, runBuiltin(METH(bytes, __repr__), self)); 1383 EXPECT_TRUE(isStrEqualsCStr(*repr, R"(b'\x00\x1f\x80\xff')")); 1384} 1385 1386TEST_F(BytesBuiltinsTest, DunderRmulCallsDunderMul) { 1387 HandleScope scope(thread_); 1388 ASSERT_FALSE(runFromCStr(runtime_, "result = 3 * b'1'").isError()); 1389 Object result(&scope, mainModuleAt(runtime_, "result")); 1390 EXPECT_TRUE(isBytesEqualsCStr(result, "111")); 1391} 1392 1393TEST_F(BytesBuiltinsTest, DecodeWithASCIIReturnsString) { 1394 HandleScope scope(thread_); 1395 ASSERT_FALSE( 1396 runFromCStr(runtime_, "result = b'hello'.decode('ascii')").isError()); 1397 Object result(&scope, mainModuleAt(runtime_, "result")); 1398 EXPECT_TRUE(isStrEqualsCStr(*result, "hello")); 1399} 1400 1401TEST_F(BytesBuiltinsTest, JoinWithBytesReturnsBytes) { 1402 HandleScope scope(thread_); 1403 Bytes sep(&scope, newBytesFromCStr(thread_, ",")); 1404 Bytes obj1(&scope, newBytesFromCStr(thread_, "hello")); 1405 Bytes obj2(&scope, newBytesFromCStr(thread_, "world")); 1406 Tuple src(&scope, runtime_->newTupleWith2(obj1, obj2)); 1407 Bytes result(&scope, 1408 bytesJoin(thread_, sep, sep.length(), src, src.length())); 1409 EXPECT_TRUE(isBytesEqualsCStr(result, "hello,world")); 1410} 1411 1412TEST_F(BytesBuiltinsTest, JoinWithBytearrayReturnsBytes) { 1413 HandleScope scope(thread_); 1414 Bytes sep(&scope, newBytesFromCStr(thread_, ",")); 1415 Bytearray obj1(&scope, newBytearrayFromCStr(thread_, "hello")); 1416 Bytearray obj2(&scope, newBytearrayFromCStr(thread_, "world")); 1417 Tuple src(&scope, runtime_->newTupleWith2(obj1, obj2)); 1418 Bytes result(&scope, 1419 bytesJoin(thread_, sep, sep.length(), src, src.length())); 1420 EXPECT_TRUE(isBytesEqualsCStr(result, "hello,world")); 1421} 1422 1423TEST_F(BytesBuiltinsTest, JoinWithMemoryviewReturnsBytes) { 1424 HandleScope scope(thread_); 1425 Bytes sep(&scope, newBytesFromCStr(thread_, ",")); 1426 Bytes src1(&scope, newBytesFromCStr(thread_, "hello")); 1427 MemoryView obj1(&scope, 1428 runtime_->newMemoryView(thread_, src1, src1, src1.length(), 1429 ReadOnly::ReadOnly)); 1430 Bytes src2(&scope, newBytesFromCStr(thread_, "world")); 1431 MemoryView obj2(&scope, 1432 runtime_->newMemoryView(thread_, src2, src2, src2.length(), 1433 ReadOnly::ReadOnly)); 1434 Tuple src(&scope, runtime_->newTupleWith2(obj1, obj2)); 1435 Bytes result(&scope, 1436 bytesJoin(thread_, sep, sep.length(), src, src.length())); 1437 EXPECT_TRUE(isBytesEqualsCStr(result, "hello,world")); 1438} 1439 1440TEST_F(BytesBuiltinsTest, HexWithEmptyBytesReturnsEmptyString) { 1441 HandleScope scope(thread_); 1442 Bytes self(&scope, Bytes::empty()); 1443 Object result(&scope, runBuiltin(METH(bytes, hex), self)); 1444 EXPECT_TRUE(isStrEqualsCStr(*result, "")); 1445} 1446 1447TEST_F(BytesBuiltinsTest, HexWithNonEmptyBytesReturnsString) { 1448 HandleScope scope(thread_); 1449 const byte bytes_array[] = {0x12, 0x34, 0xfe, 0x5b}; 1450 Bytes self(&scope, runtime_->newBytesWithAll(bytes_array)); 1451 Object result(&scope, runBuiltin(METH(bytes, hex), self)); 1452 EXPECT_TRUE(isStrEqualsCStr(*result, "1234fe5b")); 1453} 1454 1455TEST_F(BytesBuiltinsTest, HexWithBytesSubclassReturnsStr) { 1456 ASSERT_FALSE(runFromCStr(runtime_, R"( 1457class Foo(bytes): pass 1458self = Foo(b"*\x01a\x92") 1459)") 1460 .isError()); 1461 HandleScope scope(thread_); 1462 Object self(&scope, mainModuleAt(runtime_, "self")); 1463 Object repr(&scope, runBuiltin(METH(bytes, hex), self)); 1464 EXPECT_TRUE(isStrEqualsCStr(*repr, "2a016192")); 1465} 1466 1467TEST_F(BytesBuiltinsTest, IsalnumWithEmptyBytesReturnsFalse) { 1468 HandleScope scope(thread_); 1469 Bytes self(&scope, Bytes::empty()); 1470 Object result(&scope, runBuiltin(METH(bytes, isalnum), self)); 1471 EXPECT_EQ(result, Bool::falseObj()); 1472} 1473 1474TEST_F(BytesBuiltinsTest, IsalnumWithAllAlnumReturnsTrue) { 1475 HandleScope scope(thread_); 1476 const byte view[] = {'A', '1', 'a', '2', 'B'}; 1477 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1478 Object result(&scope, runBuiltin(METH(bytes, isalnum), self)); 1479 EXPECT_EQ(result, Bool::trueObj()); 1480} 1481 1482TEST_F(BytesBuiltinsTest, IsalnumWithOneNonAlnumReturnsFalse) { 1483 HandleScope scope(thread_); 1484 const byte view[] = {'A', '1', ' ', '2', 'b'}; 1485 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1486 Object result(&scope, runBuiltin(METH(bytes, isalnum), self)); 1487 EXPECT_EQ(result, Bool::falseObj()); 1488} 1489 1490TEST_F(BytesBuiltinsTest, IsalphaWithEmptyBytesReturnsFalse) { 1491 HandleScope scope(thread_); 1492 Bytes self(&scope, Bytes::empty()); 1493 Object result(&scope, runBuiltin(METH(bytes, isalpha), self)); 1494 EXPECT_EQ(result, Bool::falseObj()); 1495} 1496 1497TEST_F(BytesBuiltinsTest, IsalphaWithAllAlphaReturnsTrue) { 1498 HandleScope scope(thread_); 1499 const byte view[] = {'A', 'a', 'Z', 'z'}; 1500 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1501 Object result(&scope, runBuiltin(METH(bytes, isalpha), self)); 1502 EXPECT_EQ(result, Bool::trueObj()); 1503} 1504 1505TEST_F(BytesBuiltinsTest, IsAlphaWithOneDigitReturnsFalse) { 1506 HandleScope scope(thread_); 1507 const byte view[] = {'A', 'a', '1'}; 1508 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1509 Object result(&scope, runBuiltin(METH(bytes, isalpha), self)); 1510 EXPECT_EQ(result, Bool::falseObj()); 1511} 1512 1513TEST_F(BytesBuiltinsTest, IsdigitWithEmptyBytesReturnsFalse) { 1514 HandleScope scope(thread_); 1515 Bytes self(&scope, Bytes::empty()); 1516 Object result(&scope, runBuiltin(METH(bytes, isdigit), self)); 1517 EXPECT_EQ(result, Bool::falseObj()); 1518} 1519 1520TEST_F(BytesBuiltinsTest, IsdigitAllDigitsReturnsTrue) { 1521 HandleScope scope(thread_); 1522 const byte view[] = {'2', '0', '2', '0'}; 1523 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1524 Object result(&scope, runBuiltin(METH(bytes, isdigit), self)); 1525 EXPECT_EQ(result, Bool::trueObj()); 1526} 1527 1528TEST_F(BytesBuiltinsTest, IsdigitOneAlphaReturnsFalse) { 1529 HandleScope scope(thread_); 1530 const byte view[] = {'4', '0', '1', 'k'}; 1531 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1532 Object result(&scope, runBuiltin(METH(bytes, isdigit), self)); 1533 EXPECT_EQ(result, Bool::falseObj()); 1534} 1535 1536TEST_F(BytesBuiltinsTest, IsLowerWithEmptyBytesReturnsFalse) { 1537 HandleScope scope(thread_); 1538 Bytes self(&scope, Bytes::empty()); 1539 Object result(&scope, runBuiltin(METH(bytes, islower), self)); 1540 EXPECT_EQ(result, Bool::falseObj()); 1541} 1542 1543TEST_F(BytesBuiltinsTest, IslowerWithAllLowercaseReturnsTrue) { 1544 HandleScope scope(thread_); 1545 const byte view[] = {'a', 'b', 'c'}; 1546 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1547 Object result(&scope, runBuiltin(METH(bytes, islower), self)); 1548 EXPECT_EQ(result, Bool::trueObj()); 1549} 1550 1551TEST_F(BytesBuiltinsTest, IslowerWithOneUppercaseReturnsFalse) { 1552 HandleScope scope(thread_); 1553 const byte view[] = {'F', 'o', 'o'}; 1554 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1555 Object result(&scope, runBuiltin(METH(bytes, islower), self)); 1556 EXPECT_EQ(result, Bool::falseObj()); 1557} 1558 1559TEST_F(BytesBuiltinsTest, IslowerWithOneDigitReturnsFalse) { 1560 HandleScope scope(thread_); 1561 const byte view[] = {'f', '8'}; 1562 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1563 Object result(&scope, runBuiltin(METH(bytes, islower), self)); 1564 EXPECT_EQ(result, Bool::falseObj()); 1565} 1566 1567TEST_F(BytesBuiltinsTest, IsspaceWithEmptyBytesReturnsFalse) { 1568 HandleScope scope(thread_); 1569 Bytes self(&scope, Bytes::empty()); 1570 Object result(&scope, runBuiltin(METH(bytes, isspace), self)); 1571 EXPECT_EQ(result, Bool::falseObj()); 1572} 1573 1574TEST_F(BytesBuiltinsTest, IsspaceWithAllWhitespaceReturnsTrue) { 1575 HandleScope scope(thread_); 1576 const byte view[] = {' ', '\n', '\t', '\r'}; 1577 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1578 Object result(&scope, runBuiltin(METH(bytes, isspace), self)); 1579 EXPECT_EQ(result, Bool::trueObj()); 1580} 1581 1582TEST_F(BytesBuiltinsTest, IsspaceWithNonSpaceReturnsFalse) { 1583 HandleScope scope(thread_); 1584 const byte view[] = {'\t', '.', ' ', '\n'}; 1585 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1586 Object result(&scope, runBuiltin(METH(bytes, isspace), self)); 1587 EXPECT_EQ(result, Bool::falseObj()); 1588} 1589 1590TEST_F(BytesBuiltinsTest, IstitleWithEmptyBytesReturnsFalse) { 1591 HandleScope scope(thread_); 1592 Bytes self(&scope, Bytes::empty()); 1593 Object result(&scope, runBuiltin(METH(bytes, istitle), self)); 1594 EXPECT_EQ(result, Bool::falseObj()); 1595} 1596 1597TEST_F(BytesBuiltinsTest, IstitleWithTitlecaseWordsReturnsTrue) { 1598 HandleScope scope(thread_); 1599 const byte view[] = {'H', 'e', 'l', 'l', 'o', ' ', 1600 'W', 'o', 'r', 'l', 'd', '!'}; 1601 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1602 Object result(&scope, runBuiltin(METH(bytes, istitle), self)); 1603 EXPECT_EQ(result, Bool::trueObj()); 1604} 1605 1606TEST_F(BytesBuiltinsTest, IstitleWithLowercaseWordStartReturnsFalse) { 1607 HandleScope scope(thread_); 1608 const byte view[] = {'F', 'o', 'o', '1', 'b', 'a', 'r'}; 1609 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1610 Object result(&scope, runBuiltin(METH(bytes, istitle), self)); 1611 EXPECT_EQ(result, Bool::falseObj()); 1612} 1613 1614TEST_F(BytesBuiltinsTest, IstitleWithUppercaseMiddleReturnsFalse) { 1615 HandleScope scope(thread_); 1616 const byte view[] = {'F', 'o', 'O'}; 1617 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1618 Object result(&scope, runBuiltin(METH(bytes, istitle), self)); 1619 EXPECT_EQ(result, Bool::falseObj()); 1620} 1621 1622TEST_F(BytesBuiltinsTest, IsupperWithEmptyBytesReturnsFalse) { 1623 HandleScope scope(thread_); 1624 Bytes self(&scope, Bytes::empty()); 1625 Object result(&scope, runBuiltin(METH(bytes, isupper), self)); 1626 EXPECT_EQ(result, Bool::falseObj()); 1627} 1628 1629TEST_F(BytesBuiltinsTest, IsupperWithAllUppercaseReturnsTrue) { 1630 HandleScope scope(thread_); 1631 const byte view[] = {'F', 'O', 'O', 'B', 'A', 'R'}; 1632 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1633 Object result(&scope, runBuiltin(METH(bytes, isupper), self)); 1634 EXPECT_EQ(result, Bool::trueObj()); 1635} 1636 1637TEST_F(BytesBuiltinsTest, IsupperWithOneLowercaseReturnsFalse) { 1638 HandleScope scope(thread_); 1639 const byte view[] = {'F', 'O', 'O', 'B', 'a', 'R'}; 1640 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1641 Object result(&scope, runBuiltin(METH(bytes, isupper), self)); 1642 EXPECT_EQ(result, Bool::falseObj()); 1643} 1644 1645TEST_F(BytesBuiltinsTest, IsupperWithOneDigitReturnsFalse) { 1646 HandleScope scope(thread_); 1647 const byte view[] = {'F', '8'}; 1648 Bytes self(&scope, runtime_->newBytesWithAll(view)); 1649 Object result(&scope, runBuiltin(METH(bytes, isupper), self)); 1650 EXPECT_EQ(result, Bool::falseObj()); 1651} 1652 1653TEST_F(BytesBuiltinsTest, JoinWithNonIterableRaisesTypeError) { 1654 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "b''.join(0)"), 1655 LayoutId::kTypeError, 1656 "'int' object is not iterable")); 1657} 1658 1659TEST_F(BytesBuiltinsTest, JoinWithMistypedIterableRaisesTypeError) { 1660 EXPECT_TRUE(raisedWithStr( 1661 runFromCStr(runtime_, "b' '.join([1])"), LayoutId::kTypeError, 1662 "sequence item 0: expected a bytes-like object, 'int' found")); 1663} 1664 1665TEST_F(BytesBuiltinsTest, JoinWithIterableReturnsBytes) { 1666 ASSERT_FALSE(runFromCStr(runtime_, R"( 1667class Foo: 1668 def __iter__(self): 1669 return [b'ab', b'c', b'def'].__iter__() 1670result = b' '.join(Foo()) 1671)") 1672 .isError()); 1673 Thread* thread = Thread::current(); 1674 HandleScope scope(thread); 1675 Object result(&scope, mainModuleAt(runtime_, "result")); 1676 EXPECT_TRUE(isBytesEqualsCStr(result, "ab c def")); 1677} 1678 1679TEST_F(BytesBuiltinsTest, MaketransWithNonBytesLikeFromRaisesTypeError) { 1680 EXPECT_TRUE(raisedWithStr( 1681 runFromCStr(runtime_, "bytes.maketrans([1,2], b'ab')"), 1682 LayoutId::kTypeError, "a bytes-like object is required, not 'list'")); 1683} 1684 1685TEST_F(BytesBuiltinsTest, MaketransWithNonBytesLikeToRaisesTypeError) { 1686 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "bytes.maketrans(b'1', 2)"), 1687 LayoutId::kTypeError, 1688 "a bytes-like object is required, not 'int'")); 1689} 1690 1691TEST_F(BytesBuiltinsTest, MaketransWithDifferentLengthsRaisesValueError) { 1692 EXPECT_TRUE(raisedWithStr( 1693 runFromCStr(runtime_, "bytes.maketrans(b'12', bytearray())"), 1694 LayoutId::kValueError, "maketrans arguments must have same length")); 1695} 1696 1697TEST_F(BytesBuiltinsTest, MaketransWithEmptyReturnsDefaultBytes) { 1698 HandleScope scope(thread_); 1699 ASSERT_FALSE( 1700 runFromCStr(runtime_, "result = bytes.maketrans(bytearray(), b'')") 1701 .isError()); 1702 Object result(&scope, mainModuleAt(runtime_, "result")); 1703 byte expected[256]; 1704 for (word i = 0; i < 256; i++) { 1705 expected[i] = i; 1706 } 1707 EXPECT_TRUE(isBytesEqualsBytes(result, expected)); 1708} 1709 1710TEST_F(BytesBuiltinsTest, MaketransWithNonEmptyReturnsBytes) { 1711 HandleScope scope(thread_); 1712 ASSERT_FALSE( 1713 runFromCStr(runtime_, 1714 "result = bytes.maketrans(bytearray(b'abc'), b'123')") 1715 .isError()); 1716 Object result(&scope, mainModuleAt(runtime_, "result")); 1717 ASSERT_TRUE(result.isBytes()); 1718 LargeBytes actual(&scope, *result); 1719 EXPECT_EQ(actual.byteAt('a'), '1'); 1720 EXPECT_EQ(actual.byteAt('b'), '2'); 1721 EXPECT_EQ(actual.byteAt('c'), '3'); 1722} 1723 1724TEST_F(BytesBuiltinsTest, TranslateWithNonBytesLikeTableRaisesTypeError) { 1725 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "b''.translate(42)"), 1726 LayoutId::kTypeError, 1727 "a bytes-like object is required, not 'int'")); 1728} 1729 1730TEST_F(BytesBuiltinsTest, TranslateWithNonBytesLikeDeleteRaisesTypeError) { 1731 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "b''.translate(None, 42)"), 1732 LayoutId::kTypeError, 1733 "a bytes-like object is required, not 'int'")); 1734} 1735 1736TEST_F(BytesBuiltinsTest, TranslateWithShortTableRaisesValueError) { 1737 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "b''.translate(b'')"), 1738 LayoutId::kValueError, 1739 "translation table must be 256 characters long")); 1740} 1741 1742TEST_F(BytesBuiltinsTest, TranslateWithEmptyBytesReturnsEmptyBytes) { 1743 HandleScope scope(thread_); 1744 Object self(&scope, Bytes::empty()); 1745 Object table(&scope, NoneType::object()); 1746 Object del(&scope, runtime_->newBytearray()); 1747 Object result(&scope, runBuiltin(METH(bytes, translate), self, table, del)); 1748 EXPECT_EQ(result, Bytes::empty()); 1749} 1750 1751TEST_F(BytesBuiltinsTest, TranslateWithNonEmptySecondArgDeletesBytes) { 1752 HandleScope scope(thread_); 1753 const byte alabama[] = {'A', 'l', 'a', 'b', 'a', 'm', 'a'}; 1754 const byte abc[] = {'a', 'b', 'c'}; 1755 Object self(&scope, runtime_->newBytesWithAll(alabama)); 1756 Object table(&scope, NoneType::object()); 1757 Object del(&scope, runtime_->newBytesWithAll(abc)); 1758 Object result(&scope, runBuiltin(METH(bytes, translate), self, table, del)); 1759 EXPECT_TRUE(isBytesEqualsCStr(result, "Alm")); 1760} 1761 1762TEST_F(BytesBuiltinsTest, TranslateWithTableTranslatesBytes) { 1763 HandleScope scope(thread_); 1764 ASSERT_FALSE( 1765 runFromCStr(runtime_, "table = bytes.maketrans(b'Aa', b'12')").isError()); 1766 const byte alabama[] = {'A', 'l', 'a', 'b', 'a', 'm', 'a'}; 1767 Object self(&scope, runtime_->newBytesWithAll(alabama)); 1768 Object table(&scope, mainModuleAt(runtime_, "table")); 1769 Object del(&scope, Bytes::empty()); 1770 Object result(&scope, runBuiltin(METH(bytes, translate), self, table, del)); 1771 EXPECT_TRUE(isBytesEqualsCStr(result, "1l2b2m2")); 1772} 1773 1774TEST_F(BytesBuiltinsTest, 1775 TranslateWithTableAndDeleteTranslatesAndDeletesBytes) { 1776 HandleScope scope(thread_); 1777 ASSERT_FALSE( 1778 runFromCStr(runtime_, "table = bytes.maketrans(b'Aa', b'12')").isError()); 1779 const byte alabama[] = {'A', 'l', 'a', 'b', 'a', 'm', 'a'}; 1780 const byte abc[] = {'a', 'b', 'c'}; 1781 Object self(&scope, runtime_->newBytesWithAll(alabama)); 1782 Object table(&scope, mainModuleAt(runtime_, "table")); 1783 Object del(&scope, runtime_->newBytesWithAll(abc)); 1784 Object result(&scope, runBuiltin(METH(bytes, translate), self, table, del)); 1785 EXPECT_TRUE(isBytesEqualsCStr(result, "1lm")); 1786} 1787 1788TEST_F(BytesBuiltinsTest, TranslateDeletesAllBytes) { 1789 HandleScope scope(thread_); 1790 const byte alabama[] = {'b', 'a', 'c', 'a', 'a', 'c', 'a'}; 1791 const byte abc[] = {'a', 'b', 'c'}; 1792 Object self(&scope, runtime_->newBytesWithAll(alabama)); 1793 Object table(&scope, NoneType::object()); 1794 Object del(&scope, runtime_->newBytesWithAll(abc)); 1795 Object result(&scope, runBuiltin(METH(bytes, translate), self, table, del)); 1796 EXPECT_EQ(result, Bytes::empty()); 1797} 1798 1799TEST_F(BytesIteratorBuiltinsTest, DunderLengthHintReturnsRemainingCount) { 1800 HandleScope scope(thread_); 1801 const byte data[] = {100, 0, 37}; 1802 Bytes bytes(&scope, SmallBytes::fromBytes(data)); 1803 Object iter(&scope, runtime_->newBytesIterator(thread_, bytes)); 1804 Object result(&scope, 1805 runBuiltin(METH(bytes_iterator, __length_hint__), iter)); 1806 EXPECT_TRUE(isIntEqualsWord(*result, 3)); 1807 ASSERT_TRUE(!runBuiltin(METH(bytes_iterator, __next__), iter).isError()); 1808 result = runBuiltin(METH(bytes_iterator, __length_hint__), iter); 1809 EXPECT_TRUE(isIntEqualsWord(*result, 2)); 1810 ASSERT_TRUE(!runBuiltin(METH(bytes_iterator, __next__), iter).isError()); 1811 result = runBuiltin(METH(bytes_iterator, __length_hint__), iter); 1812 EXPECT_TRUE(isIntEqualsWord(*result, 1)); 1813 ASSERT_TRUE(!runBuiltin(METH(bytes_iterator, __next__), iter).isError()); 1814 result = runBuiltin(METH(bytes_iterator, __length_hint__), iter); 1815 EXPECT_TRUE(isIntEqualsWord(*result, 0)); 1816 EXPECT_TRUE(raised(runBuiltin(METH(bytes_iterator, __next__), iter), 1817 LayoutId::kStopIteration)); 1818} 1819 1820TEST_F(BytesIteratorBuiltinsTest, DunderIterReturnsSelf) { 1821 HandleScope scope(thread_); 1822 const byte data[] = {100, 0, 37}; 1823 Bytes bytes(&scope, SmallBytes::fromBytes(data)); 1824 Object iter(&scope, runtime_->newBytesIterator(thread_, bytes)); 1825 Object result(&scope, runBuiltin(METH(bytes_iterator, __iter__), iter)); 1826 EXPECT_EQ(result, iter); 1827} 1828 1829TEST_F(BytesIteratorBuiltinsTest, DunderNextReturnsNextElement) { 1830 HandleScope scope(thread_); 1831 const byte data[] = {100, 0, 37}; 1832 Bytes bytes(&scope, SmallBytes::fromBytes(data)); 1833 Object iter(&scope, runtime_->newBytesIterator(thread_, bytes)); 1834 Object result(&scope, runBuiltin(METH(bytes_iterator, __next__), iter)); 1835 EXPECT_TRUE(isIntEqualsWord(*result, 100)); 1836 result = runBuiltin(METH(bytes_iterator, __next__), iter); 1837 EXPECT_TRUE(isIntEqualsWord(*result, 0)); 1838 result = runBuiltin(METH(bytes_iterator, __next__), iter); 1839 EXPECT_TRUE(isIntEqualsWord(*result, 37)); 1840 EXPECT_TRUE(raised(runBuiltin(METH(bytes_iterator, __next__), iter), 1841 LayoutId::kStopIteration)); 1842} 1843 1844} // namespace testing 1845} // namespace py