this repo has no description
at trunk 215 lines 8.7 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "range-builtins.h" 3 4#include "gtest/gtest.h" 5 6#include "builtins.h" 7#include "frame.h" 8#include "objects.h" 9#include "runtime.h" 10#include "test-utils.h" 11 12namespace py { 13namespace testing { 14 15using LongRangeIteratorBuiltinsTest = RuntimeFixture; 16using RangeBuiltinsTest = RuntimeFixture; 17using RangeIteratorBuiltinsTest = RuntimeFixture; 18 19TEST_F(LongRangeIteratorBuiltinsTest, DunderIterReturnsSelf) { 20 HandleScope scope(thread_); 21 Int start(&scope, SmallInt::fromWord(0)); 22 Int stop(&scope, runtime_->newIntFromUnsigned(kMaxUword)); 23 Int step(&scope, SmallInt::fromWord(1)); 24 Object iter(&scope, runtime_->newLongRangeIterator(start, stop, step)); 25 Object result(&scope, runBuiltin(METH(longrange_iterator, __iter__), iter)); 26 EXPECT_EQ(result, iter); 27} 28 29TEST_F(LongRangeIteratorBuiltinsTest, DunderLengthHintReturnsPendingLength) { 30 HandleScope scope(thread_); 31 Int zero(&scope, SmallInt::fromWord(0)); 32 Int six(&scope, SmallInt::fromWord(6)); 33 Int neg(&scope, SmallInt::fromWord(-6)); 34 Int max(&scope, runtime_->newIntFromUnsigned(kMaxUword)); 35 Object empty(&scope, runtime_->newLongRangeIterator(max, zero, six)); 36 Object forwards(&scope, runtime_->newLongRangeIterator(zero, max, six)); 37 Object backwards(&scope, runtime_->newLongRangeIterator(max, zero, neg)); 38 word expected = static_cast<word>(kMaxUword / 6 + 1); 39 40 Object length_hint1( 41 &scope, runBuiltin(METH(longrange_iterator, __length_hint__), empty)); 42 EXPECT_TRUE(isIntEqualsWord(*length_hint1, 0)); 43 44 Object length_hint2( 45 &scope, runBuiltin(METH(longrange_iterator, __length_hint__), forwards)); 46 EXPECT_TRUE(isIntEqualsWord(*length_hint2, expected)); 47 48 Object length_hint3( 49 &scope, runBuiltin(METH(longrange_iterator, __length_hint__), backwards)); 50 EXPECT_TRUE(isIntEqualsWord(*length_hint3, expected)); 51} 52 53TEST_F(LongRangeIteratorBuiltinsTest, DunderNextWithEmptyRaisesStopIteration) { 54 HandleScope scope(thread_); 55 Int start(&scope, runtime_->newIntFromUnsigned(kMaxUword)); 56 Int stop(&scope, SmallInt::fromWord(0)); 57 Int step(&scope, SmallInt::fromWord(1)); 58 Object iter(&scope, runtime_->newLongRangeIterator(start, stop, step)); 59 EXPECT_TRUE(raised(runBuiltin(METH(longrange_iterator, __next__), iter), 60 LayoutId::kStopIteration)); 61} 62 63TEST_F(LongRangeIteratorBuiltinsTest, DunderNextWithNonEmptyReturnsInts) { 64 HandleScope scope(thread_); 65 Int start(&scope, runtime_->newIntFromUnsigned(kMaxUword - 15)); 66 Int stop(&scope, runtime_->newIntFromUnsigned(kMaxUword)); 67 Int step(&scope, SmallInt::fromWord(10)); 68 Object iter(&scope, runtime_->newLongRangeIterator(start, stop, step)); 69 70 Object item1(&scope, runBuiltin(METH(longrange_iterator, __next__), iter)); 71 const uword result1[] = {kMaxUword - 15, 0}; 72 EXPECT_TRUE(isIntEqualsDigits(*item1, result1)); 73 74 Object item2(&scope, runBuiltin(METH(longrange_iterator, __next__), iter)); 75 const uword result2[] = {kMaxUword - 5, 0}; 76 EXPECT_TRUE(isIntEqualsDigits(*item2, result2)); 77 78 EXPECT_TRUE(raised(runBuiltin(METH(longrange_iterator, __next__), iter), 79 LayoutId::kStopIteration)); 80} 81 82TEST_F(LongRangeIteratorBuiltinsTest, DunderNextModifiesPendingLength) { 83 HandleScope scope(thread_); 84 Int start(&scope, SmallInt::fromWord(0)); 85 Int stop(&scope, runtime_->newIntFromUnsigned(kMaxUword)); 86 Int step(&scope, SmallInt::fromWord(4)); 87 LongRangeIterator iter(&scope, 88 runtime_->newLongRangeIterator(start, stop, step)); 89 Object length_hint( 90 &scope, runBuiltin(METH(longrange_iterator, __length_hint__), iter)); 91 word result1 = static_cast<word>(kMaxUword / 4 + 1); 92 EXPECT_TRUE(isIntEqualsWord(*length_hint, result1)); 93 94 ASSERT_FALSE(runBuiltin(METH(longrange_iterator, __next__), iter).isError()); 95 length_hint = runBuiltin(METH(longrange_iterator, __length_hint__), iter); 96 word result2 = result1 - 1; 97 EXPECT_TRUE(isIntEqualsWord(*length_hint, result2)); 98} 99 100TEST_F(RangeBuiltinsTest, DunderIterReturnsRangeIter) { 101 HandleScope scope(thread_); 102 Int zero(&scope, SmallInt::fromWord(0)); 103 Int one(&scope, SmallInt::fromWord(1)); 104 Object range(&scope, runtime_->newRange(zero, one, one)); 105 Object iter(&scope, runBuiltin(METH(range, __iter__), range)); 106 EXPECT_TRUE(iter.isRangeIterator()); 107} 108 109TEST_F(RangeBuiltinsTest, DunderLenWithNonRangeRaisesTypeError) { 110 HandleScope scope(thread_); 111 Object not_range(&scope, runtime_->emptySlice()); 112 ASSERT_TRUE(raised(runBuiltin(METH(range, __len__), not_range), 113 LayoutId::kTypeError)); 114} 115 116TEST_F(RangeBuiltinsTest, DunderLenWithForwardRangeReturnsSliceLength) { 117 HandleScope scope(thread_); 118 Int start(&scope, SmallInt::fromWord(-4)); 119 Int stop(&scope, SmallInt::fromWord(13)); 120 Int step(&scope, SmallInt::fromWord(5)); 121 Object empty(&scope, runtime_->newRange(stop, start, step)); 122 Object range(&scope, runtime_->newRange(start, stop, step)); 123 Object len1(&scope, runBuiltin(METH(range, __len__), empty)); 124 Object len2(&scope, runBuiltin(METH(range, __len__), range)); 125 EXPECT_TRUE(isIntEqualsWord(*len1, 0)); 126 EXPECT_TRUE(isIntEqualsWord(*len2, 4)); 127} 128 129TEST_F(RangeBuiltinsTest, DunderLenWithBackwardRangeReturnsSliceLength) { 130 HandleScope scope(thread_); 131 Int start(&scope, SmallInt::fromWord(15)); 132 Int stop(&scope, SmallInt::fromWord(3)); 133 Int step(&scope, SmallInt::fromWord(-2)); 134 Object empty(&scope, runtime_->newRange(stop, start, step)); 135 Object range(&scope, runtime_->newRange(start, stop, step)); 136 Object len1(&scope, runBuiltin(METH(range, __len__), empty)); 137 Object len2(&scope, runBuiltin(METH(range, __len__), range)); 138 EXPECT_TRUE(isIntEqualsWord(*len1, 0)); 139 EXPECT_TRUE(isIntEqualsWord(*len2, 6)); 140} 141 142TEST_F(RangeBuiltinsTest, DunderLenWithLargeIntReturnsLength) { 143 HandleScope scope(thread_); 144 Int start(&scope, SmallInt::fromWord(0)); 145 Int stop(&scope, runtime_->newIntFromUnsigned(kMaxUword)); 146 Int step(&scope, SmallInt::fromWord(10)); 147 word expected = static_cast<word>(kMaxUword / 10 + 1); 148 Object range(&scope, runtime_->newRange(start, stop, step)); 149 Object len(&scope, runBuiltin(METH(range, __len__), range)); 150 EXPECT_TRUE(isIntEqualsWord(*len, expected)); 151} 152 153TEST_F(RangeIteratorBuiltinsTest, DunderIterReturnsSelf) { 154 HandleScope scope(thread_); 155 Object iter(&scope, runtime_->newRangeIterator(0, 2, 13)); 156 Object result(&scope, runBuiltin(METH(range_iterator, __iter__), iter)); 157 EXPECT_EQ(result, iter); 158} 159 160TEST_F(RangeIteratorBuiltinsTest, DunderLengthHintReturnsPendingLength) { 161 HandleScope scope(thread_); 162 Object empty(&scope, runtime_->newRangeIterator(-12, 10, 0)); 163 Object forwards(&scope, runtime_->newRangeIterator(3, 15, 4)); 164 Object backwards(&scope, runtime_->newRangeIterator(0, -3, 2)); 165 166 Object length_hint1(&scope, 167 runBuiltin(METH(range_iterator, __length_hint__), empty)); 168 EXPECT_TRUE(isIntEqualsWord(*length_hint1, 0)); 169 170 Object length_hint2( 171 &scope, runBuiltin(METH(range_iterator, __length_hint__), forwards)); 172 EXPECT_TRUE(isIntEqualsWord(*length_hint2, 4)); 173 174 Object length_hint3( 175 &scope, runBuiltin(METH(range_iterator, __length_hint__), backwards)); 176 EXPECT_TRUE(isIntEqualsWord(*length_hint3, 2)); 177} 178 179TEST_F(RangeIteratorBuiltinsTest, DunderNextWithEmptyRaisesStopIteration) { 180 HandleScope scope(thread_); 181 Object iter(&scope, runtime_->newRangeIterator(23, 5, 0)); 182 EXPECT_TRUE(raised(runBuiltin(METH(range_iterator, __next__), iter), 183 LayoutId::kStopIteration)); 184} 185 186TEST_F(RangeIteratorBuiltinsTest, DunderNextWithNonEmptyReturnsInts) { 187 HandleScope scope(thread_); 188 Object iter(&scope, runtime_->newRangeIterator(0, 1, 2)); 189 190 Object item1(&scope, runBuiltin(METH(range_iterator, __next__), iter)); 191 EXPECT_TRUE(isIntEqualsWord(*item1, 0)); 192 193 Object item2(&scope, runBuiltin(METH(range_iterator, __next__), iter)); 194 EXPECT_TRUE(isIntEqualsWord(*item2, 1)); 195 196 EXPECT_TRUE(raised(runBuiltin(METH(range_iterator, __next__), iter), 197 LayoutId::kStopIteration)); 198} 199 200TEST_F(RangeIteratorBuiltinsTest, DunderNextModifiesPendingLength) { 201 HandleScope scope(thread_); 202 RangeIterator iter(&scope, runtime_->newRangeIterator(0, 1, 2)); 203 204 ASSERT_FALSE(runBuiltin(METH(range_iterator, __next__), iter).isError()); 205 Object length_hint(&scope, 206 runBuiltin(METH(range_iterator, __length_hint__), iter)); 207 EXPECT_TRUE(isIntEqualsWord(*length_hint, 1)); 208 209 ASSERT_FALSE(runBuiltin(METH(range_iterator, __next__), iter).isError()); 210 length_hint = runBuiltin(METH(range_iterator, __length_hint__), iter); 211 EXPECT_TRUE(isIntEqualsWord(*length_hint, 0)); 212} 213 214} // namespace testing 215} // namespace py