this repo has no description
at trunk 428 lines 13 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "Python.h" 3#include "gtest/gtest.h" 4 5#include "capi-fixture.h" 6#include "capi-testing.h" 7 8namespace py { 9namespace testing { 10 11using SetExtensionApiTest = ExtensionApi; 12 13TEST_F(SetExtensionApiTest, AddWithNonSetReturnsNegative) { 14 PyObjectPtr dict(PyDict_New()); 15 PyObjectPtr key(PyLong_FromLong(1)); 16 17 EXPECT_EQ(PySet_Add(dict, key), -1); 18 ASSERT_NE(PyErr_Occurred(), nullptr); 19 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 20} 21 22TEST_F(SetExtensionApiTest, AnySetCheckWithNonSetReturnsFalse) { 23 PyObjectPtr set(PyDict_New()); 24 EXPECT_FALSE(PyAnySet_Check(set)); 25} 26 27TEST_F(SetExtensionApiTest, AnySetCheckWithAnySetSubclassReturnsTrue) { 28 PyRun_SimpleString(R"( 29class FrozenSub(frozenset): 30 pass 31class SetSub(set): 32 pass 33frozen_instance = FrozenSub() 34set_instance = SetSub() 35)"); 36 PyObjectPtr frozen(mainModuleGet("frozen_instance")); 37 PyObjectPtr set(mainModuleGet("set_instance")); 38 EXPECT_TRUE(PyAnySet_Check(frozen)); 39 EXPECT_TRUE(PyAnySet_Check(set)); 40} 41 42TEST_F(SetExtensionApiTest, AnySetCheckWithAnySetReturnsTrue) { 43 PyObjectPtr frozenset(PyFrozenSet_New(nullptr)); 44 PyObjectPtr set(PySet_New(nullptr)); 45 EXPECT_TRUE(PyAnySet_Check(frozenset)); 46 EXPECT_TRUE(PyAnySet_Check(set)); 47} 48 49TEST_F(SetExtensionApiTest, AnySetCheckExactWithNonSetReturnsFalse) { 50 PyObjectPtr set(PyDict_New()); 51 EXPECT_FALSE(PyAnySet_CheckExact(set)); 52} 53 54TEST_F(SetExtensionApiTest, AnySetCheckExactWithAnySetSubclassReturnsFalse) { 55 PyRun_SimpleString(R"( 56class FrozenSub(frozenset): 57 pass 58class SetSub(set): 59 pass 60frozen_instance = FrozenSub() 61set_instance = SetSub() 62)"); 63 PyObjectPtr frozen(mainModuleGet("frozen_instance")); 64 PyObjectPtr set(mainModuleGet("set_instance")); 65 EXPECT_FALSE(PyAnySet_CheckExact(frozen)); 66 EXPECT_FALSE(PyAnySet_CheckExact(set)); 67} 68 69TEST_F(SetExtensionApiTest, AnySetCheckExactWithAnySetReturnsTrue) { 70 PyObjectPtr frozenset(PyFrozenSet_New(nullptr)); 71 PyObjectPtr set(PySet_New(nullptr)); 72 EXPECT_TRUE(PyAnySet_CheckExact(frozenset)); 73 EXPECT_TRUE(PyAnySet_CheckExact(set)); 74} 75 76TEST_F(SetExtensionApiTest, FrozenSetCheckWithSetReturnsFalse) { 77 PyObjectPtr set(PySet_New(nullptr)); 78 EXPECT_FALSE(PyFrozenSet_Check(set)); 79} 80 81TEST_F(SetExtensionApiTest, FrozenSetCheckWithFrozenSetSubclassReturnsTrue) { 82 PyRun_SimpleString(R"( 83class C(frozenset): 84 pass 85c = C() 86)"); 87 PyObjectPtr c(mainModuleGet("c")); 88 EXPECT_TRUE(PyFrozenSet_Check(c)); 89} 90 91TEST_F(SetExtensionApiTest, FrozenSetCheckWithFrozenSetReturnsTrue) { 92 PyObjectPtr set(PyFrozenSet_New(nullptr)); 93 EXPECT_TRUE(PyFrozenSet_Check(set)); 94} 95 96TEST_F(SetExtensionApiTest, FrozenSetCheckExactWithSetReturnsFalse) { 97 PyObjectPtr set(PySet_New(nullptr)); 98 EXPECT_FALSE(PyFrozenSet_CheckExact(set)); 99} 100 101TEST_F(SetExtensionApiTest, 102 FrozenSetCheckExactWithFrozenSetSubclassReturnsFalse) { 103 PyRun_SimpleString(R"( 104class C(frozenset): 105 pass 106c = C() 107)"); 108 PyObjectPtr c(mainModuleGet("c")); 109 EXPECT_FALSE(PyFrozenSet_CheckExact(c)); 110} 111 112TEST_F(SetExtensionApiTest, FrozenSetCheckExactWithFrozenSetReturnsTrue) { 113 PyObjectPtr set(PyFrozenSet_New(nullptr)); 114 EXPECT_TRUE(PyFrozenSet_CheckExact(set)); 115} 116 117TEST_F(SetExtensionApiTest, SetCheckWithFrozenSetReturnsFalse) { 118 PyObjectPtr set(PyFrozenSet_New(nullptr)); 119 EXPECT_FALSE(PySet_Check(set)); 120} 121 122TEST_F(SetExtensionApiTest, SetCheckWithSetSubclassReturnsTrue) { 123 PyRun_SimpleString(R"( 124class C(set): 125 pass 126c = C() 127)"); 128 PyObjectPtr c(mainModuleGet("c")); 129 EXPECT_TRUE(PySet_Check(c)); 130} 131 132TEST_F(SetExtensionApiTest, SetCheckWithSetReturnsTrue) { 133 PyObjectPtr set(PySet_New(nullptr)); 134 EXPECT_TRUE(PySet_Check(set)); 135} 136 137TEST_F(SetExtensionApiTest, ContainsReturnsPositiveAfterAdd) { 138 PyObjectPtr set(PySet_New(nullptr)); 139 PyObjectPtr key(PyLong_FromLong(1)); 140 141 ASSERT_EQ(PySet_Contains(set, key), 0); 142 ASSERT_EQ(PySet_Add(set, key), 0); 143 EXPECT_EQ(PySet_Contains(set, key), 1); 144} 145 146TEST_F(SetExtensionApiTest, ContainsWithEmptySetReturnsFalse) { 147 PyObjectPtr set(PySet_New(nullptr)); 148 PyObjectPtr key(PyLong_FromLong(1)); 149 150 EXPECT_EQ(PySet_Contains(set, key), 0); 151} 152 153TEST_F(SetExtensionApiTest, ContainsWithNonSetReturnsNegative) { 154 PyObjectPtr dict(PyDict_New()); 155 PyObjectPtr key(PyLong_FromLong(1)); 156 157 EXPECT_EQ(PySet_Contains(dict, key), -1); 158 ASSERT_NE(PyErr_Occurred(), nullptr); 159 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 160} 161 162TEST_F(SetExtensionApiTest, NewWithDictCopiesKeys) { 163 PyObjectPtr dict(PyDict_New()); 164 PyObjectPtr key1(PyLong_FromLong(1)); 165 PyObjectPtr key2(PyLong_FromLong(2)); 166 PyObjectPtr key3(PyLong_FromLong(3)); 167 PyObjectPtr value(PyLong_FromLong(4)); 168 169 PyDict_SetItem(dict, key1, value); 170 PyDict_SetItem(dict, key2, value); 171 PyDict_SetItem(dict, key3, value); 172 173 PyObjectPtr set(PySet_New(dict)); 174 175 EXPECT_EQ(PySet_Contains(set, key1), 1); 176 EXPECT_EQ(PySet_Contains(set, key2), 1); 177 EXPECT_EQ(PySet_Contains(set, key3), 1); 178} 179 180TEST_F(SetExtensionApiTest, NewFromSet) { 181 PyObjectPtr set(PySet_New(nullptr)); 182 PyObjectPtr one(PyLong_FromLong(1)); 183 PyObjectPtr two(PyLong_FromLong(2)); 184 185 ASSERT_EQ(PySet_Add(set, one), 0); 186 ASSERT_EQ(PySet_Add(set, two), 0); 187 188 PyObjectPtr set_copy(PySet_New(set)); 189 190 EXPECT_EQ(PySet_Contains(set_copy, one), 1); 191 EXPECT_EQ(PySet_Contains(set_copy, two), 1); 192 EXPECT_EQ(PySet_Size(set_copy), 2); 193} 194 195TEST_F(SetExtensionApiTest, NewWithList) { 196 PyObjectPtr one(PyLong_FromLong(1)); 197 PyObjectPtr two(PyLong_FromLong(2)); 198 PyObjectPtr list(PyList_New(0)); 199 200 PyList_Append(list, one); 201 PyList_Append(list, two); 202 PyList_Append(list, one); 203 204 PyObjectPtr set(PySet_New(list)); 205 EXPECT_EQ(PySet_Contains(set, one), 1); 206 EXPECT_EQ(PySet_Contains(set, two), 1); 207 EXPECT_EQ(PySet_Size(set), 2); 208} 209 210TEST_F(SetExtensionApiTest, NewWithNonIterableReturnsNull) { 211 PyObjectPtr num(PyLong_FromLong(1)); 212 213 EXPECT_EQ(PySet_New(num), nullptr); 214 ASSERT_NE(PyErr_Occurred(), nullptr); 215 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 216} 217 218TEST_F(SetExtensionApiTest, NewWithNullReturnsEmpty) { 219 PyObjectPtr set(PySet_New(nullptr)); 220 ASSERT_NE(set, nullptr); 221 EXPECT_EQ(PySet_Size(set), 0); 222} 223 224TEST_F(SetExtensionApiTest, NextEntryWithNonSetRaisesSystemError) { 225 PyObject* key = nullptr; 226 Py_hash_t hash = 0; 227 Py_ssize_t pos = 0; 228 PyObjectPtr nonset(PyDict_New()); 229 EXPECT_EQ(_PySet_NextEntry(nonset, &pos, &key, &hash), -1); 230 ASSERT_NE(PyErr_Occurred(), nullptr); 231 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 232} 233 234TEST_F(SetExtensionApiTest, NextEntryWithEmptySetReturnsFalse) { 235 PyObject* key = nullptr; 236 Py_hash_t hash = 0; 237 Py_ssize_t pos = 0; 238 PyObjectPtr set(PySet_New(nullptr)); 239 EXPECT_EQ(_PySet_NextEntry(set, &pos, &key, &hash), 0); 240 ASSERT_EQ(PyErr_Occurred(), nullptr); 241} 242 243TEST_F(SetExtensionApiTest, NextEntryWithNonEmptySetReturnsKeysAndHashes) { 244 PyObjectPtr set(PySet_New(nullptr)); 245 PyObjectPtr one(PyLong_FromLong(1)); 246 ASSERT_EQ(PySet_Add(set, one), 0); 247 PyObjectPtr two(PyLong_FromLong(2)); 248 ASSERT_EQ(PySet_Add(set, two), 0); 249 250 Py_ssize_t pos = 0; 251 PyObject* key = nullptr; 252 Py_hash_t hash = -1; 253 ASSERT_EQ(_PySet_NextEntry(set, &pos, &key, &hash), 1); 254 ASSERT_EQ(PyErr_Occurred(), nullptr); 255 EXPECT_EQ(key, one); 256 EXPECT_EQ(hash, PyObject_Hash(one)); 257 258 ASSERT_EQ(_PySet_NextEntry(set, &pos, &key, &hash), 1); 259 ASSERT_EQ(PyErr_Occurred(), nullptr); 260 EXPECT_EQ(key, two); 261 EXPECT_EQ(hash, PyObject_Hash(two)); 262 263 ASSERT_EQ(_PySet_NextEntry(set, &pos, &key, &hash), 0); 264 ASSERT_EQ(PyErr_Occurred(), nullptr); 265} 266 267TEST_F(SetExtensionApiTest, SizeIncreasesAfterAdd) { 268 PyObjectPtr set(PySet_New(nullptr)); 269 PyObjectPtr one(PyLong_FromLong(1)); 270 PyObjectPtr two(PyLong_FromLong(2)); 271 272 EXPECT_EQ(PySet_Size(set), 0); 273 ASSERT_EQ(PySet_Add(set, one), 0); 274 EXPECT_EQ(PySet_Size(set), 1); 275 ASSERT_EQ(PySet_Add(set, one), 0); 276 EXPECT_EQ(PySet_Size(set), 1); 277 ASSERT_EQ(PySet_Add(set, two), 0); 278 EXPECT_EQ(PySet_Size(set), 2); 279} 280 281TEST_F(SetExtensionApiTest, SizeOfNonSetReturnsNegative) { 282 PyObjectPtr list(PyList_New(2)); 283 284 EXPECT_EQ(PySet_Size(list), -1); 285 ASSERT_NE(PyErr_Occurred(), nullptr); 286 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 287} 288 289TEST_F(SetExtensionApiTest, FrozenSetNewWithDictCopiesKeys) { 290 PyObjectPtr dict(PyDict_New()); 291 PyObjectPtr value(PyLong_FromLong(4)); 292 PyObjectPtr key1(PyLong_FromLong(1)); 293 PyDict_SetItem(dict, key1, value); 294 PyObjectPtr key2(PyLong_FromLong(2)); 295 PyDict_SetItem(dict, key2, value); 296 PyObjectPtr key3(PyLong_FromLong(3)); 297 PyDict_SetItem(dict, key3, value); 298 299 PyObjectPtr set(PyFrozenSet_New(dict)); 300 ASSERT_EQ(PyErr_Occurred(), nullptr); 301 EXPECT_EQ(PySet_Contains(set, key1), 1); 302 EXPECT_EQ(PySet_Contains(set, key2), 1); 303 EXPECT_EQ(PySet_Contains(set, key3), 1); 304} 305 306TEST_F(SetExtensionApiTest, FrozenSetNewFromSetContainsElementsOfSet) { 307 PyObjectPtr set(PySet_New(nullptr)); 308 PyObjectPtr one(PyLong_FromLong(1)); 309 ASSERT_EQ(PySet_Add(set, one), 0); 310 PyObjectPtr two(PyLong_FromLong(2)); 311 ASSERT_EQ(PySet_Add(set, two), 0); 312 313 PyObjectPtr set_copy(PyFrozenSet_New(set)); 314 ASSERT_EQ(PyErr_Occurred(), nullptr); 315 EXPECT_EQ(PySet_Contains(set_copy, one), 1); 316 EXPECT_EQ(PySet_Contains(set_copy, two), 1); 317 EXPECT_EQ(PySet_Size(set_copy), 2); 318} 319 320TEST_F(SetExtensionApiTest, FrozenSetNewWithListContainsElementsOfList) { 321 PyObjectPtr list(PyList_New(0)); 322 PyObjectPtr one(PyLong_FromLong(1)); 323 PyList_Append(list, one); 324 PyObjectPtr two(PyLong_FromLong(2)); 325 PyList_Append(list, two); 326 327 PyObjectPtr set(PyFrozenSet_New(list)); 328 ASSERT_EQ(PyErr_Occurred(), nullptr); 329 EXPECT_EQ(PySet_Contains(set, one), 1); 330 EXPECT_EQ(PySet_Contains(set, two), 1); 331 EXPECT_EQ(PySet_Size(set), 2); 332} 333 334TEST_F(SetExtensionApiTest, FrozenSetNewWithNonIterableRaisesTypeError) { 335 PyObjectPtr num(PyLong_FromLong(1)); 336 EXPECT_EQ(PyFrozenSet_New(num), nullptr); 337 ASSERT_NE(PyErr_Occurred(), nullptr); 338 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 339} 340 341TEST_F(SetExtensionApiTest, FrozenSetNewWithNullReturnsEmpty) { 342 PyObjectPtr set(PyFrozenSet_New(nullptr)); 343 ASSERT_NE(set, nullptr); 344 EXPECT_EQ(PySet_Size(set), 0); 345} 346 347TEST_F(SetExtensionApiTest, ContainsWithFrozenSetDoesNotRaiseSystemError) { 348 PyObjectPtr set(PyFrozenSet_New(nullptr)); 349 EXPECT_EQ(PySet_Contains(set, Py_None), 0); 350 EXPECT_EQ(PyErr_Occurred(), nullptr); 351} 352 353TEST_F(SetExtensionApiTest, SizeWithFrozenSetDoesNotRaiseSystemError) { 354 PyObjectPtr set(PyFrozenSet_New(nullptr)); 355 EXPECT_EQ(PySet_Size(set), 0); 356 EXPECT_EQ(PyErr_Occurred(), nullptr); 357} 358 359TEST_F(SetExtensionApiTest, ClearWithNonSetRaisesSystemError) { 360 ASSERT_EQ(PySet_Clear(Py_None), -1); 361 ASSERT_NE(PyErr_Occurred(), nullptr); 362 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 363} 364 365TEST_F(SetExtensionApiTest, ClearRemovesAllItems) { 366 PyObjectPtr set(PySet_New(nullptr)); 367 PyObjectPtr one(PyLong_FromLong(1)); 368 PySet_Add(set, one); 369 PyObjectPtr two(PyLong_FromLong(2)); 370 PySet_Add(set, two); 371 PyObjectPtr three(PyLong_FromLong(3)); 372 PySet_Add(set, three); 373 374 ASSERT_EQ(PySet_Clear(set), 0); 375 ASSERT_EQ(PyErr_Occurred(), nullptr); 376 EXPECT_EQ(PySet_Size(set), 0); 377} 378 379TEST_F(SetExtensionApiTest, PopWithNonSetRaisesSystemError) { 380 ASSERT_EQ(PySet_Pop(Py_None), nullptr); 381 ASSERT_NE(PyErr_Occurred(), nullptr); 382 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 383} 384 385TEST_F(SetExtensionApiTest, PopWithEmptySetRaisesKeyError) { 386 PyObjectPtr set(PySet_New(nullptr)); 387 ASSERT_EQ(PySet_Pop(set), nullptr); 388 ASSERT_NE(PyErr_Occurred(), nullptr); 389 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_KeyError)); 390} 391 392TEST_F(SetExtensionApiTest, PopWithNonEmptySetRemovesItem) { 393 PyObjectPtr set(PySet_New(nullptr)); 394 PyObjectPtr elt(PyLong_FromLong(5)); 395 ASSERT_EQ(PySet_Add(set, elt), 0); 396 ASSERT_EQ(PySet_Size(set), 1); 397 PyObjectPtr result(PySet_Pop(set)); 398 ASSERT_EQ(result, elt); 399 EXPECT_EQ(PySet_Size(set), 0); 400} 401 402TEST_F(SetExtensionApiTest, PopWithSetContainingErrorsRemovesItem) { 403 PyObjectPtr set(PySet_New(nullptr)); 404 PyObjectPtr elt(PyExc_KeyError); 405 ASSERT_EQ(PySet_Add(set, elt), 0); 406 ASSERT_EQ(PySet_Size(set), 1); 407 ASSERT_EQ(PySet_Pop(set), elt); 408 EXPECT_EQ(PySet_Size(set), 0); 409} 410 411TEST_F(SetExtensionApiTest, DiscardWithNonSetRaisesSystemError) { 412 ASSERT_EQ(PySet_Discard(Py_None, Py_None), -1); 413 ASSERT_NE(PyErr_Occurred(), nullptr); 414 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 415} 416 417TEST_F(SetExtensionApiTest, DiscardWithSetRemovesItem) { 418 PyObjectPtr set(PySet_New(nullptr)); 419 PyObjectPtr elt(PyLong_FromLong(5)); 420 ASSERT_EQ(PySet_Add(set, elt), 0); 421 ASSERT_EQ(PySet_Size(set), 1); 422 ASSERT_EQ(PySet_Discard(set, elt), 1); 423 ASSERT_EQ(PyErr_Occurred(), nullptr); 424 EXPECT_EQ(PySet_Size(set), 0); 425} 426 427} // namespace testing 428} // namespace py