this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include <cstring>
3
4#include "Python.h"
5#include "gtest/gtest.h"
6
7#include "capi-fixture.h"
8#include "capi-testing.h"
9
10namespace py {
11namespace testing {
12
13using ByteArrayExtensionApiTest = ExtensionApi;
14
15TEST_F(ByteArrayExtensionApiTest, AsStringWithByteArrayReturnsString) {
16 PyObjectPtr array(PyByteArray_FromStringAndSize("hello world", 7));
17 const char* result = PyByteArray_AsString(array);
18 ASSERT_EQ(PyErr_Occurred(), nullptr);
19 EXPECT_STREQ(result, "hello w");
20}
21
22TEST_F(ByteArrayExtensionApiTest,
23 AsStringWithModifiedByteArrayReturnsUpdatedString) {
24 PyObjectPtr array(PyByteArray_FromStringAndSize("hello world", 7));
25 const char* result = PyByteArray_AsString(array);
26 ASSERT_EQ(PyErr_Occurred(), nullptr);
27 EXPECT_STREQ(result, "hello w");
28
29 ASSERT_EQ(PyByteArray_Resize(array, 2), 0);
30 result = PyByteArray_AsString(array);
31 ASSERT_EQ(PyErr_Occurred(), nullptr);
32 EXPECT_STREQ(result, "he");
33}
34
35TEST_F(ByteArrayExtensionApiTest, CheckWithBytesReturnsFalse) {
36 PyObjectPtr bytes(PyBytes_FromString("hello"));
37 EXPECT_FALSE(PyByteArray_CheckExact(bytes));
38 EXPECT_FALSE(PyByteArray_Check(bytes));
39}
40
41TEST_F(ByteArrayExtensionApiTest, ConcatWithNonBytesLikeSelfRaisesTypeError) {
42 PyObjectPtr self(PyList_New(0));
43 PyObjectPtr other(PyByteArray_FromStringAndSize("world", 5));
44 ASSERT_EQ(PyByteArray_Concat(self, other), nullptr);
45 ASSERT_NE(PyErr_Occurred(), nullptr);
46 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError));
47}
48
49TEST_F(ByteArrayExtensionApiTest, ConcatWithNonBytesLikeOtherRaisesTypeError) {
50 PyObjectPtr self(PyByteArray_FromStringAndSize("hello", 5));
51 PyObjectPtr other(PyList_New(0));
52 ASSERT_EQ(PyByteArray_Concat(self, other), nullptr);
53 ASSERT_NE(PyErr_Occurred(), nullptr);
54 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError));
55}
56
57TEST_F(ByteArrayExtensionApiTest, ConcatWithEmptyByteArraysReturnsEmpty) {
58 PyObjectPtr self(PyByteArray_FromStringAndSize("", 0));
59 PyObjectPtr other(PyByteArray_FromStringAndSize("", 0));
60 PyObjectPtr result(PyByteArray_Concat(self, other));
61 ASSERT_EQ(PyErr_Occurred(), nullptr);
62 EXPECT_EQ(PyByteArray_Size(result), 0);
63}
64
65TEST_F(ByteArrayExtensionApiTest,
66 ConcatWithBytesSelfReturnsNewConcatenatedByteArray) {
67 const char* str1 = "hello";
68 const char* str2 = "world";
69 Py_ssize_t len1 = static_cast<Py_ssize_t>(std::strlen(str1));
70 Py_ssize_t len2 = static_cast<Py_ssize_t>(std::strlen(str2));
71 PyObjectPtr self(PyBytes_FromString(str1));
72 PyObjectPtr other(PyBytes_FromString(str2));
73 PyObjectPtr result(PyByteArray_Concat(self, other));
74 ASSERT_EQ(PyErr_Occurred(), nullptr);
75 ASSERT_EQ(PyBytes_Size(self), len1);
76 ASSERT_TRUE(PyByteArray_CheckExact(result));
77 EXPECT_EQ(PyByteArray_Size(result), len1 + len2);
78 EXPECT_STREQ(PyByteArray_AsString(result), "helloworld");
79}
80
81TEST_F(ByteArrayExtensionApiTest,
82 ConcatWithByteArraysReturnsNewConcatenatedByteArray) {
83 const char* str1 = "hello";
84 const char* str2 = "world";
85 Py_ssize_t len1 = static_cast<Py_ssize_t>(std::strlen(str1));
86 Py_ssize_t len2 = static_cast<Py_ssize_t>(std::strlen(str2));
87 PyObjectPtr self(PyByteArray_FromStringAndSize(str1, len1));
88 PyObjectPtr other(PyByteArray_FromStringAndSize(str2, len2));
89 PyObjectPtr result(PyByteArray_Concat(self, other));
90 ASSERT_EQ(PyErr_Occurred(), nullptr);
91 ASSERT_EQ(PyByteArray_Size(self), len1);
92 ASSERT_TRUE(PyByteArray_CheckExact(result));
93 EXPECT_EQ(PyByteArray_Size(result), len1 + len2);
94 EXPECT_STREQ(PyByteArray_AsString(result), "helloworld");
95}
96
97TEST_F(ByteArrayExtensionApiTest, FromObjectWithNullReturnsEmptyByteArray) {
98 PyObjectPtr array(PyByteArray_FromObject(nullptr));
99 EXPECT_TRUE(PyByteArray_CheckExact(array));
100 EXPECT_EQ(PyByteArray_Size(array), 0);
101}
102
103TEST_F(ByteArrayExtensionApiTest, FromObjectWithByteArrayReturnsByteArray) {
104 const char* hello = "hello";
105 Py_ssize_t size = static_cast<Py_ssize_t>(std::strlen(hello));
106 PyObjectPtr bytes(PyByteArray_FromStringAndSize(hello, size));
107 PyObjectPtr array(PyByteArray_FromObject(bytes));
108 EXPECT_TRUE(PyByteArray_CheckExact(array));
109 EXPECT_EQ(PyByteArray_Size(array), size);
110}
111
112TEST_F(ByteArrayExtensionApiTest, FromObjectWithBytesReturnsByteArray) {
113 PyObjectPtr bytes(PyBytes_FromString("hello"));
114 PyObjectPtr array(PyByteArray_FromObject(bytes));
115 EXPECT_TRUE(PyByteArray_CheckExact(array));
116 EXPECT_EQ(PyByteArray_Size(array), 5);
117}
118
119TEST_F(ByteArrayExtensionApiTest, FromObjectWithIntReturnsByteArray) {
120 Py_ssize_t size = 10;
121 PyObjectPtr value(PyLong_FromSsize_t(size));
122 PyObjectPtr array(PyByteArray_FromObject(value));
123 EXPECT_TRUE(PyByteArray_CheckExact(array));
124 EXPECT_EQ(PyByteArray_Size(array), size);
125}
126
127TEST_F(ByteArrayExtensionApiTest, FromObjectWithListReturnsByteArray) {
128 PyObjectPtr list(PyList_New(3));
129 PyList_SetItem(list, 0, PyLong_FromLong(0));
130 PyList_SetItem(list, 1, PyLong_FromLong(1));
131 PyList_SetItem(list, 2, PyLong_FromLong(2));
132 PyObjectPtr array(PyByteArray_FromObject(list));
133 EXPECT_TRUE(PyByteArray_CheckExact(array));
134 EXPECT_EQ(PyByteArray_Size(array), 3);
135}
136
137TEST_F(ByteArrayExtensionApiTest, FromObjectWithStringRaisesTypeError) {
138 PyObjectPtr str(PyUnicode_FromString("hello"));
139 EXPECT_EQ(PyByteArray_FromObject(str), nullptr);
140 EXPECT_NE(PyErr_Occurred(), nullptr);
141 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError));
142}
143
144TEST_F(ByteArrayExtensionApiTest, FromStringAndSizeReturnsByteArray) {
145 PyObjectPtr array(PyByteArray_FromStringAndSize("hello", 5));
146 EXPECT_TRUE(PyByteArray_Check(array));
147 EXPECT_TRUE(PyByteArray_CheckExact(array));
148}
149
150TEST_F(ByteArrayExtensionApiTest, FromStringAndSizeSetsSize) {
151 PyObjectPtr array(PyByteArray_FromStringAndSize("hello", 3));
152 ASSERT_TRUE(PyByteArray_CheckExact(array));
153 EXPECT_EQ(PyByteArray_Size(array), 3);
154}
155
156TEST_F(ByteArrayExtensionApiTest,
157 FromStringAndSizeWithNegativeSizeRaisesSystemError) {
158 ASSERT_EQ(PyByteArray_FromStringAndSize("hello", -1), nullptr);
159 ASSERT_NE(PyErr_Occurred(), nullptr);
160 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError));
161}
162
163TEST_F(ByteArrayExtensionApiTest, FromStringAndSizeWithNullReturnsNew) {
164 PyObjectPtr array(PyByteArray_FromStringAndSize(nullptr, 10));
165 ASSERT_TRUE(PyByteArray_CheckExact(array));
166 EXPECT_EQ(PyByteArray_Size(array), 10);
167}
168
169TEST_F(ByteArrayExtensionApiTest, ResizeWithSameSizeIsNoop) {
170 const char* hello = "hello";
171 Py_ssize_t len = static_cast<Py_ssize_t>(std::strlen(hello));
172 PyObjectPtr array(PyByteArray_FromStringAndSize(hello, len));
173 ASSERT_EQ(PyByteArray_Resize(array, len), 0);
174 ASSERT_EQ(PyErr_Occurred(), nullptr);
175 EXPECT_EQ(PyByteArray_Size(array), len);
176}
177
178TEST_F(ByteArrayExtensionApiTest, ResizeWithSmallerSizeShrinks) {
179 const char* hello = "hello";
180 Py_ssize_t len = static_cast<Py_ssize_t>(std::strlen(hello));
181 PyObjectPtr array(PyByteArray_FromStringAndSize(hello, len));
182 ASSERT_EQ(PyByteArray_Resize(array, len - 2), 0);
183 ASSERT_EQ(PyErr_Occurred(), nullptr);
184 EXPECT_EQ(PyByteArray_Size(array), len - 2);
185}
186
187TEST_F(ByteArrayExtensionApiTest, ResizeWithLargerSizeGrows) {
188 const char* hello = "hello";
189 Py_ssize_t len = static_cast<Py_ssize_t>(std::strlen(hello));
190 PyObjectPtr array(PyByteArray_FromStringAndSize(hello, len));
191 ASSERT_EQ(PyByteArray_Resize(array, len + 2), 0);
192 ASSERT_EQ(PyErr_Occurred(), nullptr);
193 EXPECT_EQ(PyByteArray_Size(array), len + 2);
194}
195
196TEST_F(ByteArrayExtensionApiTest, ResizeLargerThenSmaller) {
197 const char* hello = "hello";
198 Py_ssize_t len = static_cast<Py_ssize_t>(std::strlen(hello));
199 PyObjectPtr array(PyByteArray_FromStringAndSize(hello, len));
200 ASSERT_EQ(PyByteArray_Resize(array, len + 3), 0);
201 ASSERT_EQ(PyErr_Occurred(), nullptr);
202 EXPECT_EQ(PyByteArray_Size(array), len + 3);
203
204 ASSERT_EQ(PyByteArray_Resize(array, len - 1), 0);
205 ASSERT_EQ(PyErr_Occurred(), nullptr);
206 EXPECT_EQ(PyByteArray_Size(array), len - 1);
207}
208
209TEST_F(ByteArrayExtensionApiTest, ResizeSmallerThenLarger) {
210 const char* hello = "hello";
211 Py_ssize_t len = static_cast<Py_ssize_t>(std::strlen(hello));
212 PyObjectPtr array(PyByteArray_FromStringAndSize(hello, len));
213 ASSERT_EQ(PyByteArray_Resize(array, len - 3), 0);
214 ASSERT_EQ(PyErr_Occurred(), nullptr);
215 EXPECT_EQ(PyByteArray_Size(array), len - 3);
216
217 ASSERT_EQ(PyByteArray_Resize(array, len + 1), 0);
218 ASSERT_EQ(PyErr_Occurred(), nullptr);
219 EXPECT_EQ(PyByteArray_Size(array), len + 1);
220}
221
222} // namespace testing
223} // namespace py