this repo has no description
at trunk 192 lines 7.0 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "slice-builtins.h" 3 4#include "gtest/gtest.h" 5 6#include "builtins.h" 7#include "runtime.h" 8#include "test-utils.h" 9 10namespace py { 11namespace testing { 12 13using SliceBuiltinsTest = RuntimeFixture; 14 15TEST_F(SliceBuiltinsTest, SliceHasStartAttribute) { 16 HandleScope scope(thread_); 17 Layout layout(&scope, runtime_->layoutAt(LayoutId::kSlice)); 18 Str name(&scope, runtime_->newStrFromCStr("start")); 19 AttributeInfo info; 20 ASSERT_TRUE(Runtime::layoutFindAttribute(*layout, name, &info)); 21 EXPECT_TRUE(info.isInObject()); 22 EXPECT_TRUE(info.isFixedOffset()); 23} 24 25TEST_F(SliceBuiltinsTest, SliceHasStopAttribute) { 26 HandleScope scope(thread_); 27 Layout layout(&scope, runtime_->layoutAt(LayoutId::kSlice)); 28 Str name(&scope, runtime_->newStrFromCStr("stop")); 29 AttributeInfo info; 30 ASSERT_TRUE(Runtime::layoutFindAttribute(*layout, name, &info)); 31 EXPECT_TRUE(info.isInObject()); 32 EXPECT_TRUE(info.isFixedOffset()); 33} 34 35TEST_F(SliceBuiltinsTest, SliceHasStepAttribute) { 36 HandleScope scope(thread_); 37 Layout layout(&scope, runtime_->layoutAt(LayoutId::kSlice)); 38 Str name(&scope, runtime_->newStrFromCStr("step")); 39 AttributeInfo info; 40 ASSERT_TRUE(Runtime::layoutFindAttribute(*layout, name, &info)); 41 EXPECT_TRUE(info.isInObject()); 42 EXPECT_TRUE(info.isFixedOffset()); 43} 44 45TEST_F(SliceBuiltinsTest, DunderNewWithNonTypeRaisesTypeError) { 46 HandleScope scope(thread_); 47 Object num(&scope, SmallInt::fromWord(0)); 48 Object result(&scope, runBuiltin(METH(slice, __new__), num)); 49 EXPECT_TRUE(raised(*result, LayoutId::kTypeError)); 50} 51 52TEST_F(SliceBuiltinsTest, DunderNewWithNonSliceTypeRaisesTypeError) { 53 HandleScope scope(thread_); 54 Object type(&scope, runtime_->typeAt(LayoutId::kInt)); 55 Object result(&scope, runBuiltin(METH(slice, __new__), type)); 56 EXPECT_TRUE(raised(*result, LayoutId::kTypeError)); 57} 58 59TEST_F(SliceBuiltinsTest, DunderNewWithOneArgSetsStop) { 60 HandleScope scope(thread_); 61 ASSERT_FALSE(runFromCStr(runtime_, "result = slice(0)").isError()); 62 Object result(&scope, mainModuleAt(runtime_, "result")); 63 ASSERT_TRUE(result.isSlice()); 64 Slice slice(&scope, *result); 65 EXPECT_EQ(slice.start(), NoneType::object()); 66 EXPECT_EQ(slice.stop(), SmallInt::fromWord(0)); 67 EXPECT_EQ(slice.step(), NoneType::object()); 68} 69 70TEST_F(SliceBuiltinsTest, DunderNewWithTwoArgsSetsStartAndStop) { 71 HandleScope scope(thread_); 72 ASSERT_FALSE(runFromCStr(runtime_, "result = slice(0, 1)").isError()); 73 Object result(&scope, mainModuleAt(runtime_, "result")); 74 ASSERT_TRUE(result.isSlice()); 75 Slice slice(&scope, *result); 76 EXPECT_EQ(slice.start(), SmallInt::fromWord(0)); 77 EXPECT_EQ(slice.stop(), SmallInt::fromWord(1)); 78 EXPECT_EQ(slice.step(), NoneType::object()); 79} 80 81TEST_F(SliceBuiltinsTest, DunderNewWithThreeArgsSetsAllIndices) { 82 HandleScope scope(thread_); 83 ASSERT_FALSE(runFromCStr(runtime_, "result = slice(0, 1, 2)").isError()); 84 Object result(&scope, mainModuleAt(runtime_, "result")); 85 ASSERT_TRUE(result.isSlice()); 86 Slice slice(&scope, *result); 87 EXPECT_EQ(slice.start(), SmallInt::fromWord(0)); 88 EXPECT_EQ(slice.stop(), SmallInt::fromWord(1)); 89 EXPECT_EQ(slice.step(), SmallInt::fromWord(2)); 90} 91 92TEST_F(SliceBuiltinsTest, IndicesWithNonIntRaisesTypeError) { 93 EXPECT_TRUE(raisedWithStr( 94 runFromCStr(runtime_, "slice(1).indices([])"), LayoutId::kTypeError, 95 "'list' object cannot be interpreted as an integer")); 96} 97 98TEST_F(SliceBuiltinsTest, IndicesWithNegativeLengthRaisesValueError) { 99 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "slice(1).indices(-1)"), 100 LayoutId::kValueError, 101 "length should not be negative")); 102} 103 104TEST_F(SliceBuiltinsTest, IndicesWithZeroStepRaisesValueError) { 105 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "slice(1, 1, 0).indices(10)"), 106 LayoutId::kValueError, 107 "slice step cannot be zero")); 108} 109 110TEST_F(SliceBuiltinsTest, IndicesWithNonIntStartRaisesTypeError) { 111 EXPECT_TRUE(raisedWithStr( 112 runFromCStr(runtime_, "slice('').indices(10)"), LayoutId::kTypeError, 113 "slice indices must be integers or None or have an __index__ method")); 114} 115 116TEST_F(SliceBuiltinsTest, IndicesWithNonIntStopRaisesTypeError) { 117 EXPECT_TRUE(raisedWithStr( 118 runFromCStr(runtime_, "slice(1, '').indices(10)"), LayoutId::kTypeError, 119 "slice indices must be integers or None or have an __index__ method")); 120} 121 122TEST_F(SliceBuiltinsTest, IndicesWithNonIntStepRaisesTypeError) { 123 EXPECT_TRUE(raisedWithStr( 124 runFromCStr(runtime_, "slice(1, 6, '').indices(10)"), 125 LayoutId::kTypeError, 126 "slice indices must be integers or None or have an __index__ method")); 127} 128 129TEST_F(SliceBuiltinsTest, IndicesWithNoneReturnsDefaults) { 130 HandleScope scope(thread_); 131 ASSERT_FALSE( 132 runFromCStr(runtime_, "result = slice(None).indices(10)").isError()); 133 Object result(&scope, mainModuleAt(runtime_, "result")); 134 ASSERT_TRUE(result.isTuple()); 135 Tuple indices(&scope, *result); 136 ASSERT_EQ(indices.length(), 3); 137 EXPECT_EQ(indices.at(0), SmallInt::fromWord(0)); 138 EXPECT_EQ(indices.at(1), SmallInt::fromWord(10)); 139 EXPECT_EQ(indices.at(2), SmallInt::fromWord(1)); 140} 141 142TEST_F(SliceBuiltinsTest, IndicesWithNoneAndNegativeReturnsDefaults) { 143 HandleScope scope(thread_); 144 ASSERT_FALSE( 145 runFromCStr(runtime_, "result = slice(None, None, -1).indices(10)") 146 .isError()); 147 Object result(&scope, mainModuleAt(runtime_, "result")); 148 ASSERT_TRUE(result.isTuple()); 149 Tuple indices(&scope, *result); 150 ASSERT_EQ(indices.length(), 3); 151 EXPECT_EQ(indices.at(0), SmallInt::fromWord(9)); 152 EXPECT_EQ(indices.at(1), SmallInt::fromWord(-1)); 153 EXPECT_EQ(indices.at(2), SmallInt::fromWord(-1)); 154} 155 156TEST_F(SliceBuiltinsTest, IndicesCallsDunderIndex) { 157 HandleScope scope(thread_); 158 ASSERT_FALSE(runFromCStr(runtime_, R"( 159class Idx: 160 def __init__(self): 161 self.count = 0 162 def __index__(self): 163 self.count += 1 164 return self.count 165idx = Idx() 166result = slice(idx, idx, idx).indices(10) 167)") 168 .isError()); 169 Object result(&scope, mainModuleAt(runtime_, "result")); 170 ASSERT_TRUE(result.isTuple()); 171 Tuple indices(&scope, *result); 172 ASSERT_EQ(indices.length(), 3); 173 EXPECT_EQ(indices.at(0), SmallInt::fromWord(2)); 174 EXPECT_EQ(indices.at(1), SmallInt::fromWord(3)); 175 EXPECT_EQ(indices.at(2), SmallInt::fromWord(1)); 176} 177 178TEST_F(SliceBuiltinsTest, IndicesTruncatesToLength) { 179 HandleScope scope(thread_); 180 ASSERT_FALSE( 181 runFromCStr(runtime_, "result = slice(-4, 10, 2).indices(5)").isError()); 182 Object result(&scope, mainModuleAt(runtime_, "result")); 183 ASSERT_TRUE(result.isTuple()); 184 Tuple indices(&scope, *result); 185 ASSERT_EQ(indices.length(), 3); 186 EXPECT_EQ(indices.at(0), SmallInt::fromWord(1)); 187 EXPECT_EQ(indices.at(1), SmallInt::fromWord(5)); 188 EXPECT_EQ(indices.at(2), SmallInt::fromWord(2)); 189} 190 191} // namespace testing 192} // namespace py