this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "memoryview-builtins.h"
3
4#include "gtest/gtest.h"
5
6#include "builtins.h"
7#include "handles.h"
8#include "test-utils.h"
9
10namespace py {
11namespace testing {
12
13using MemoryViewBuiltinsTest = RuntimeFixture;
14
15TEST_F(MemoryViewBuiltinsTest, CastReturnsMemoryView) {
16 HandleScope scope(thread_);
17 const byte bytes[] = {0, 1, 2, 3};
18 MemoryView view(&scope, newMemoryView(bytes, "f", ReadOnly::ReadWrite));
19 Str new_format(&scope, runtime_->newStrFromCStr("h"));
20 Object result_obj(&scope,
21 runBuiltin(METH(memoryview, cast), view, new_format));
22 ASSERT_TRUE(result_obj.isMemoryView());
23 MemoryView result(&scope, *result_obj);
24 EXPECT_NE(result, view);
25 EXPECT_EQ(result.buffer(), view.buffer());
26 EXPECT_TRUE(isStrEqualsCStr(view.format(), "f"));
27 EXPECT_TRUE(isStrEqualsCStr(result.format(), "h"));
28 EXPECT_EQ(view.readOnly(), result.readOnly());
29}
30
31TEST_F(MemoryViewBuiltinsTest, CastWithAtFormatReturnsMemoryView) {
32 HandleScope scope(thread_);
33 const byte bytes[] = {0, 1, 2, 3};
34 MemoryView view(&scope, newMemoryView(bytes, "h", ReadOnly::ReadWrite));
35 Str new_format(&scope, runtime_->newStrFromCStr("@H"));
36 Object result_obj(&scope,
37 runBuiltin(METH(memoryview, cast), view, new_format));
38 ASSERT_TRUE(result_obj.isMemoryView());
39 MemoryView result(&scope, *result_obj);
40 EXPECT_NE(result, view);
41 EXPECT_EQ(result.buffer(), view.buffer());
42 EXPECT_TRUE(isStrEqualsCStr(view.format(), "h"));
43 EXPECT_TRUE(isStrEqualsCStr(result.format(), "@H"));
44 EXPECT_EQ(view.readOnly(), result.readOnly());
45}
46
47TEST_F(MemoryViewBuiltinsTest, CastWithBadLengthForFormatRaisesValueError) {
48 HandleScope scope(thread_);
49 const byte bytes[] = {0, 1, 2, 3, 4, 5};
50 MemoryView view(&scope, newMemoryView(bytes, "B"));
51 Str new_format(&scope, runtime_->newStrFromCStr("f"));
52 Object result(&scope, runBuiltin(METH(memoryview, cast), view, new_format));
53 EXPECT_TRUE(
54 raisedWithStr(*result, LayoutId::kValueError,
55 "memoryview: length is not a multiple of itemsize"));
56}
57
58TEST_F(MemoryViewBuiltinsTest, CastWithInvalidFormatRaisesValueError) {
59 HandleScope scope(thread_);
60 const byte bytes[] = {0, 1, 2, 3, 4, 5, 6, 7};
61 MemoryView view(&scope, newMemoryView(bytes, "B"));
62 Str new_format(&scope, runtime_->newStrFromCStr(" "));
63 Object result(&scope, runBuiltin(METH(memoryview, cast), view, new_format));
64 EXPECT_TRUE(raisedWithStr(*result, LayoutId::kValueError,
65 "memoryview: destination must be a native single "
66 "character format prefixed with an optional '@'"));
67}
68
69TEST_F(MemoryViewBuiltinsTest, CastWithNonStrFormatRaisesTypeError) {
70 HandleScope scope(thread_);
71 const byte bytes[] = {0, 1, 2, 3, 4, 5, 6, 7};
72 MemoryView view(&scope, newMemoryView(bytes, "B"));
73 Object not_str(&scope, NoneType::object());
74 Object result(&scope, runBuiltin(METH(memoryview, cast), view, not_str));
75 EXPECT_TRUE(raisedWithStr(*result, LayoutId::kTypeError,
76 "format argument must be a string"));
77}
78
79TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatbSetsInt) {
80 HandleScope scope(thread_);
81 const byte bytes[] = {0xab};
82 MemoryView view(&scope, newMemoryView(bytes, "b", ReadOnly::ReadWrite));
83 word index = 0;
84 Object value(&scope, runtime_->newInt(-59));
85 EXPECT_EQ(memoryviewSetitem(thread_, view, index, value), NoneType::object());
86 Object index_obj(&scope, runtime_->newInt(index));
87 Object result(&scope, runBuiltin(FUNC(_builtins, _memoryview_getitem), view,
88 index_obj));
89 EXPECT_TRUE(isIntEqualsWord(*result, -59));
90}
91
92TEST_F(MemoryViewBuiltinsTest,
93 SetitemWithFormatbAndOversizedValueRaisesValueError) {
94 HandleScope scope(thread_);
95 const byte bytes[] = {0xab};
96 MemoryView view(&scope, newMemoryView(bytes, "b", ReadOnly::ReadWrite));
97 Object value(&scope, runtime_->newInt(0x101));
98 Object result(&scope, memoryviewSetitem(thread_, view, 0, value));
99 EXPECT_TRUE(raisedWithStr(*result, LayoutId::kValueError,
100 "memoryview: invalid value for format 'b'"));
101}
102
103TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatBSetsInt) {
104 HandleScope scope(thread_);
105 const byte bytes[] = {0xee};
106 MemoryView view(&scope, newMemoryView(bytes, "B", ReadOnly::ReadWrite));
107 word index = 0;
108 Object value(&scope, runtime_->newInt(0xd8));
109 EXPECT_EQ(memoryviewSetitem(thread_, view, index, value), NoneType::object());
110 Object index_obj(&scope, runtime_->newInt(index));
111 Object result(&scope, runBuiltin(FUNC(_builtins, _memoryview_getitem), view,
112 index_obj));
113 EXPECT_TRUE(isIntEqualsWord(*result, 216));
114}
115
116TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatcSetsBytes) {
117 HandleScope scope(thread_);
118 const byte bytes[] = {97, 98};
119 MemoryView view(&scope, newMemoryView(bytes, "c", ReadOnly::ReadWrite));
120 word index = 0;
121 Bytes value(&scope, runtime_->newBytes(1, 100));
122 EXPECT_EQ(memoryviewSetitem(thread_, view, index, value), NoneType::object());
123 Object index_obj(&scope, runtime_->newInt(index));
124 Object result(&scope, runBuiltin(FUNC(_builtins, _memoryview_getitem), view,
125 index_obj));
126 const byte expected_bytes[] = {100};
127 EXPECT_TRUE(isBytesEqualsBytes(result, expected_bytes));
128}
129
130TEST_F(MemoryViewBuiltinsTest, SetitemWithFormathSetsInt) {
131 HandleScope scope(thread_);
132 const byte bytes[] = {0xcd, 0x2c, 0xBE, 0xEF};
133 MemoryView view(&scope, newMemoryView(bytes, "h", ReadOnly::ReadWrite));
134 Object value(&scope, runtime_->newInt(-932));
135 EXPECT_EQ(memoryviewSetitem(thread_, view, 2, value), NoneType::object());
136 Object key(&scope, runtime_->newInt(1));
137 Object result(&scope,
138 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
139 EXPECT_TRUE(isIntEqualsWord(*result, -932));
140}
141
142TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatHSetsInt) {
143 HandleScope scope(thread_);
144 const byte bytes[] = {0xb2, 0x11, 0xBE, 0xEF};
145 MemoryView view(&scope, newMemoryView(bytes, "H", ReadOnly::ReadWrite));
146 Object value(&scope, runtime_->newInt(49300));
147 EXPECT_EQ(memoryviewSetitem(thread_, view, 2, value), NoneType::object());
148 Object key(&scope, runtime_->newInt(1));
149 Object result(&scope,
150 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
151 EXPECT_TRUE(isIntEqualsWord(*result, 49300));
152}
153
154TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatiSetsInt) {
155 HandleScope scope(thread_);
156 const byte bytes[] = {0x30, 0x8A, 0x43, 0xF2, 0xDE, 0xAD, 0xBE, 0xEF};
157 MemoryView view(&scope, newMemoryView(bytes, "i", ReadOnly::ReadWrite));
158 word index = 0;
159 Object value(&scope, runtime_->newInt(-464070943));
160 EXPECT_EQ(memoryviewSetitem(thread_, view, index, value), NoneType::object());
161 Object index_obj(&scope, runtime_->newInt(index));
162 Object result(&scope, runBuiltin(FUNC(_builtins, _memoryview_getitem), view,
163 index_obj));
164 EXPECT_TRUE(isIntEqualsWord(*result, -464070943));
165}
166
167TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatISetsInt) {
168 HandleScope scope(thread_);
169 const byte bytes[] = {0x30, 0x8A, 0x43, 0xF2, 0xDE, 0xAD, 0xBE, 0xEF};
170 MemoryView view(&scope, newMemoryView(bytes, "I", ReadOnly::ReadWrite));
171 Object value(&scope, runtime_->newInt(149624948));
172 EXPECT_EQ(memoryviewSetitem(thread_, view, 4, value), NoneType::object());
173 Object key(&scope, runtime_->newInt(1));
174 Object result(&scope,
175 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
176 EXPECT_TRUE(isIntEqualsWord(*result, 149624948));
177}
178
179TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatlSetsInt) {
180 HandleScope scope(thread_);
181 const byte bytes[] = {0xD8, 0x76, 0x97, 0xD1, 0x8B, 0xA1, 0xD2, 0x62,
182 0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D};
183 MemoryView view(&scope, newMemoryView(bytes, "l", ReadOnly::ReadWrite));
184 word index = 0;
185 Object value(&scope, runtime_->newInt(-9099618978295131431));
186 EXPECT_EQ(memoryviewSetitem(thread_, view, index, value), NoneType::object());
187 Object index_obj(&scope, runtime_->newInt(index));
188 Object result(&scope, runBuiltin(FUNC(_builtins, _memoryview_getitem), view,
189 index_obj));
190 EXPECT_TRUE(isIntEqualsWord(*result, -9099618978295131431));
191}
192
193TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatLSetsInt) {
194 HandleScope scope(thread_);
195 const byte bytes[] = {0xD8, 0x76, 0x97, 0xD1, 0x8B, 0xA1, 0xD2, 0x62,
196 0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D};
197 MemoryView view(&scope, newMemoryView(bytes, "L", ReadOnly::ReadWrite));
198 Object value(&scope, runtime_->newIntFromUnsigned(7082027347532687782));
199 EXPECT_EQ(memoryviewSetitem(thread_, view, 8, value), NoneType::object());
200 Object key(&scope, runtime_->newInt(1));
201 Object result(&scope,
202 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
203 EXPECT_TRUE(isIntEqualsWord(*result, 7082027347532687782));
204}
205
206TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatqSetsInt) {
207 HandleScope scope(thread_);
208 const byte bytes[] = {0x7, 0xE2, 0x42, 0x9E, 0x8F, 0xBF, 0xDB, 0x1B,
209 0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D};
210 MemoryView view(&scope, newMemoryView(bytes, "q", ReadOnly::ReadWrite));
211 Object value(&scope, runtime_->newInt(2534191260184616076));
212 EXPECT_EQ(memoryviewSetitem(thread_, view, 8, value), NoneType::object());
213 Object key(&scope, runtime_->newInt(1));
214 Object result(&scope,
215 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
216 EXPECT_TRUE(isIntEqualsWord(*result, 2534191260184616076));
217}
218
219TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatQSetsInt) {
220 HandleScope scope(thread_);
221 const byte bytes[] = {0xD9, 0xC6, 0xD2, 0x40, 0xBD, 0x19, 0xA9, 0xC8,
222 0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D};
223 MemoryView view(&scope, newMemoryView(bytes, "Q", ReadOnly::ReadWrite));
224 Object value(&scope, runtime_->newIntFromUnsigned(0xbdc73615af8b018aul));
225 EXPECT_EQ(memoryviewSetitem(thread_, view, 8, value), NoneType::object());
226 Object key(&scope, runtime_->newInt(1));
227 Object result(&scope,
228 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
229 const uword expected_digits[] = {0xbdc73615af8b018aul, 0};
230 EXPECT_TRUE(isIntEqualsDigits(*result, expected_digits));
231}
232
233TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatnSetsInt) {
234 HandleScope scope(thread_);
235 const byte bytes[] = {0xF2, 0x6F, 0xFA, 0x8B, 0x93, 0xC0, 0xED, 0x9D,
236 0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D};
237 MemoryView view(&scope, newMemoryView(bytes, "n", ReadOnly::ReadWrite));
238 Object value(&scope, runtime_->newInt(-1461155128888034195l));
239 EXPECT_EQ(memoryviewSetitem(thread_, view, 8, value), NoneType::object());
240 Object key(&scope, runtime_->newInt(1));
241 Object result(&scope,
242 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
243 EXPECT_TRUE(isIntEqualsWord(*result, -1461155128888034195l));
244}
245
246TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatNSetsInt) {
247 HandleScope scope(thread_);
248 const byte bytes[] = {0x6B, 0x8F, 0x6, 0xA2, 0xE0, 0x13, 0x88, 0x47,
249 0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D};
250 MemoryView view(&scope, newMemoryView(bytes, "N", ReadOnly::ReadWrite));
251 Object value(&scope, runtime_->newIntFromUnsigned(0xc009026b7e40b67eul));
252 EXPECT_EQ(memoryviewSetitem(thread_, view, 8, value), NoneType::object());
253 Object key(&scope, runtime_->newInt(1));
254 Object result(&scope,
255 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
256 const uword expected_digits[] = {0xc009026b7e40b67eul, 0};
257 EXPECT_TRUE(isIntEqualsDigits(*result, expected_digits));
258}
259
260TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatfSetsFloat) {
261 HandleScope scope(thread_);
262 const byte bytes[] = {0x67, 0x32, 0x23, 0x31, 0xDE, 0xAD, 0xBE, 0xEF};
263 MemoryView view(&scope, newMemoryView(bytes, "f", ReadOnly::ReadWrite));
264 Float value(&scope, runtime_->newFloat(
265 std::strtof("-0x1.78e1720000000p-120", nullptr)));
266 EXPECT_EQ(memoryviewSetitem(thread_, view, 4, value), NoneType::object());
267 Object key(&scope, runtime_->newInt(1));
268 Object result(&scope,
269 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
270 EXPECT_TRUE(isFloatEqualsDouble(
271 *result, std::strtof("-0x1.78e1720000000p-120", nullptr)));
272}
273
274TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatdSetsFloat) {
275 HandleScope scope(thread_);
276 const byte bytes[] = {0xEA, 0x43, 0xAD, 0x6F, 0x9D, 0x31, 0xE, 0x96,
277 0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D};
278 MemoryView view(&scope, newMemoryView(bytes, "d", ReadOnly::ReadWrite));
279 Float value(&scope, runtime_->newFloat(
280 std::strtod("0x1.c0c870d1a8028p+187", nullptr)));
281 EXPECT_EQ(memoryviewSetitem(thread_, view, 8, value), NoneType::object());
282 Object key(&scope, runtime_->newInt(1));
283 Object result(&scope,
284 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, key));
285 EXPECT_TRUE(isFloatEqualsDouble(
286 *result, std::strtod("0x1.c0c870d1a8028p+187", nullptr)));
287}
288
289TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatQuestionmarkSetsTrue) {
290 HandleScope scope(thread_);
291 const byte bytes[] = {0x92, 0xE1, 0x57, 0, 0x81, 0xA8};
292 MemoryView view(&scope, newMemoryView(bytes, "?", ReadOnly::ReadWrite));
293 word byte_index = 3;
294 Bool value(&scope, Bool::trueObj());
295 EXPECT_EQ(memoryviewSetitem(thread_, view, byte_index, value),
296 NoneType::object());
297 Object byte_index_obj(&scope, runtime_->newInt(byte_index));
298 Object result(&scope, runBuiltin(FUNC(_builtins, _memoryview_getitem), view,
299 byte_index_obj));
300 EXPECT_EQ(result, Bool::trueObj());
301}
302
303TEST_F(MemoryViewBuiltinsTest, SetitemWithFormatQuestionmarkSetsFalse) {
304 HandleScope scope(thread_);
305 const byte bytes[] = {0x92, 0xE1, 0xAB, 0xEA, 0x81, 0xA8};
306 MemoryView view(&scope, newMemoryView(bytes, "?", ReadOnly::ReadWrite));
307 word byte_index = 2;
308 Bool value(&scope, Bool::falseObj());
309 EXPECT_EQ(memoryviewSetitem(thread_, view, byte_index, value),
310 NoneType::object());
311 Object byte_index_obj(&scope, runtime_->newInt(byte_index));
312 Object result(&scope, runBuiltin(FUNC(_builtins, _memoryview_getitem), view,
313 byte_index_obj));
314 EXPECT_EQ(result, Bool::falseObj());
315}
316
317TEST_F(MemoryViewBuiltinsTest, SetitemWithMemoryBufferWritesMemory) {
318 HandleScope scope(thread_);
319 const word length = 5;
320 byte memory[length];
321 Object none(&scope, NoneType::object());
322 MemoryView view(&scope,
323 runtime_->newMemoryViewFromCPtr(thread_, none, memory, length,
324 ReadOnly::ReadWrite));
325 Object value(&scope, SmallInt::fromWord(0));
326 EXPECT_EQ(memoryviewSetitem(thread_, view, 0, value), NoneType::object());
327 value = SmallInt::fromWord(1);
328 EXPECT_EQ(memoryviewSetitem(thread_, view, 1, value), NoneType::object());
329 value = SmallInt::fromWord(2);
330 EXPECT_EQ(memoryviewSetitem(thread_, view, 2, value), NoneType::object());
331 value = SmallInt::fromWord(3);
332 EXPECT_EQ(memoryviewSetitem(thread_, view, 3, value), NoneType::object());
333 value = SmallInt::fromWord(4);
334 EXPECT_EQ(memoryviewSetitem(thread_, view, 4, value), NoneType::object());
335
336 Object idx_obj(&scope, runtime_->newInt(0));
337 EXPECT_TRUE(isIntEqualsWord(
338 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx_obj), 0));
339 idx_obj = runtime_->newInt(1);
340 EXPECT_TRUE(isIntEqualsWord(
341 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx_obj), 1));
342 idx_obj = runtime_->newInt(2);
343 EXPECT_TRUE(isIntEqualsWord(
344 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx_obj), 2));
345 idx_obj = runtime_->newInt(3);
346 EXPECT_TRUE(isIntEqualsWord(
347 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx_obj), 3));
348 idx_obj = runtime_->newInt(4);
349 EXPECT_TRUE(isIntEqualsWord(
350 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx_obj), 4));
351 EXPECT_EQ(memory[0], 0);
352 EXPECT_EQ(memory[1], 1);
353 EXPECT_EQ(memory[2], 2);
354 EXPECT_EQ(memory[3], 3);
355 EXPECT_EQ(memory[4], 4);
356}
357
358TEST_F(MemoryViewBuiltinsTest, SetitemWithBytearraySetsMutableBytes) {
359 Thread* thread = Thread::current();
360 HandleScope scope(thread);
361 Type type(&scope, runtime_->typeAt(LayoutId::kMemoryView));
362 Bytearray bytearray(&scope, runtime_->newBytearray());
363 const byte byte_array[] = {0xCE};
364 runtime_->bytearrayExtend(thread, bytearray, byte_array);
365 EXPECT_EQ(bytearray.byteAt(0), 0xCE);
366
367 Object result_obj(&scope,
368 runBuiltin(METH(memoryview, __new__), type, bytearray));
369 ASSERT_TRUE(result_obj.isMemoryView());
370 MemoryView view(&scope, *result_obj);
371 word index = 0;
372 Object value(&scope, runtime_->newInt(0xA5));
373 EXPECT_EQ(memoryviewSetitem(thread_, view, index, value), NoneType::object());
374 Object index_object(&scope, runtime_->newInt(index));
375 Object result(&scope, runBuiltin(FUNC(_builtins, _memoryview_getitem), view,
376 index_object));
377 EXPECT_TRUE(isIntEqualsWord(*result, 0xA5));
378 EXPECT_EQ(bytearray.byteAt(0), 0xA5);
379}
380
381TEST_F(MemoryViewBuiltinsTest, DunderLenWithMemoryViewFormatBReturnsInt) {
382 HandleScope scope(thread_);
383 const byte bytes[] = {0, 1, 2};
384 MemoryView view(&scope, newMemoryView(bytes, "B"));
385 Object result(&scope, runBuiltin(METH(memoryview, __len__), view));
386 EXPECT_TRUE(isIntEqualsWord(*result, 3));
387}
388
389TEST_F(MemoryViewBuiltinsTest, DunderLenWithMemoryViewFormatfReturnsInt) {
390 HandleScope scope(thread_);
391 const byte bytes[] = {0, 1, 2, 3, 4, 5, 6, 7};
392 MemoryView view(&scope, newMemoryView(bytes, "f"));
393 Object result(&scope, runBuiltin(METH(memoryview, __len__), view));
394 EXPECT_TRUE(isIntEqualsWord(*result, 2));
395}
396
397TEST_F(MemoryViewBuiltinsTest, DunderLenWithNonMemoryViewRaisesTypeError) {
398 HandleScope scope(thread_);
399 Object none(&scope, NoneType::object());
400 EXPECT_TRUE(raised(runBuiltin(METH(memoryview, __len__), none),
401 LayoutId::kTypeError));
402}
403
404TEST_F(MemoryViewBuiltinsTest, DunderNewWithBytesReturnsMemoryView) {
405 HandleScope scope(thread_);
406 const byte bytes_array[] = {0xa9};
407 Bytes bytes(&scope, runtime_->newBytesWithAll(bytes_array));
408 Type type(&scope, runtime_->typeAt(LayoutId::kMemoryView));
409 Object result_obj(&scope, runBuiltin(METH(memoryview, __new__), type, bytes));
410 ASSERT_TRUE(result_obj.isMemoryView());
411 MemoryView view(&scope, *result_obj);
412 EXPECT_EQ(view.buffer(), bytes);
413 EXPECT_TRUE(isStrEqualsCStr(view.format(), "B"));
414 EXPECT_TRUE(view.readOnly());
415 EXPECT_EQ(view.start(), 0);
416 Tuple shape(&scope, view.shape());
417 ASSERT_EQ(shape.length(), 1);
418 EXPECT_TRUE(isIntEqualsWord(shape.at(0), view.length()));
419 Tuple strides(&scope, view.strides());
420 ASSERT_EQ(strides.length(), 1);
421 EXPECT_TRUE(isIntEqualsWord(strides.at(0), 1));
422}
423
424TEST_F(MemoryViewBuiltinsTest, DunderNewWithBytearrayReturnsMemoryView) {
425 Thread* thread = Thread::current();
426 HandleScope scope(thread);
427 Type type(&scope, runtime_->typeAt(LayoutId::kMemoryView));
428 Bytearray bytearray(&scope, runtime_->newBytearray());
429 const byte byte_array[] = {0xce};
430 runtime_->bytearrayExtend(thread, bytearray, byte_array);
431 Object result_obj(&scope,
432 runBuiltin(METH(memoryview, __new__), type, bytearray));
433 ASSERT_TRUE(result_obj.isMemoryView());
434 MemoryView view(&scope, *result_obj);
435 EXPECT_EQ(view.buffer(), bytearray.items());
436 EXPECT_EQ(view.length(), bytearray.numItems());
437 EXPECT_TRUE(isStrEqualsCStr(view.format(), "B"));
438 EXPECT_FALSE(view.readOnly());
439 EXPECT_EQ(view.start(), 0);
440 Tuple shape(&scope, view.shape());
441 ASSERT_EQ(shape.length(), 1);
442 EXPECT_TRUE(isIntEqualsWord(shape.at(0), view.length()));
443 Tuple strides(&scope, view.strides());
444 ASSERT_EQ(strides.length(), 1);
445 EXPECT_TRUE(isIntEqualsWord(strides.at(0), 1));
446}
447
448TEST_F(MemoryViewBuiltinsTest, DunderNewWithMemoryViewReturnsMemoryView) {
449 HandleScope scope(thread_);
450 Type type(&scope, runtime_->typeAt(LayoutId::kMemoryView));
451 const byte bytes[] = {0x96, 0xfc};
452 MemoryView view(&scope, newMemoryView(bytes, "H", ReadOnly::ReadWrite));
453 Object result_obj(&scope, runBuiltin(METH(memoryview, __new__), type, view));
454 ASSERT_TRUE(result_obj.isMemoryView());
455 MemoryView result(&scope, *result_obj);
456 EXPECT_NE(result, view);
457 EXPECT_EQ(view.buffer(), result.buffer());
458 EXPECT_TRUE(Str::cast(view.format()).equals(Str::cast(result.format())));
459 EXPECT_EQ(view.readOnly(), result.readOnly());
460 EXPECT_EQ(result.start(), 0);
461 Tuple shape(&scope, result.shape());
462 ASSERT_EQ(shape.length(), 1);
463 EXPECT_TRUE(isIntEqualsWord(shape.at(0), view.length()));
464 Tuple strides(&scope, result.strides());
465 ASSERT_EQ(strides.length(), 1);
466 EXPECT_TRUE(isIntEqualsWord(strides.at(0), 1));
467 EXPECT_EQ(strides.length(), 1);
468}
469
470TEST_F(MemoryViewBuiltinsTest, DunderNewWithUnsupportedObjectRaisesTypeError) {
471 HandleScope scope(thread_);
472 Type type(&scope, runtime_->typeAt(LayoutId::kMemoryView));
473 Object none(&scope, NoneType::object());
474 Object result(&scope, runBuiltin(METH(memoryview, __new__), type, none));
475 EXPECT_TRUE(raisedWithStr(*result, LayoutId::kTypeError,
476 "a bytes-like object is required, not 'NoneType'"));
477}
478
479TEST_F(MemoryViewBuiltinsTest, DunderNewWithInvalidTypeRaisesTypeError) {
480 HandleScope scope(thread_);
481 Object not_a_type(&scope, NoneType::object());
482 Bytes bytes(&scope, runtime_->newBytesWithAll(View<byte>(nullptr, 0)));
483 Object result(&scope,
484 runBuiltin(METH(memoryview, __new__), not_a_type, bytes));
485 EXPECT_TRUE(raisedWithStr(*result, LayoutId::kTypeError,
486 "memoryview.__new__(X): X is not 'memoryview'"));
487}
488
489} // namespace testing
490} // namespace py