this repo has no description
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