test_capi.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. // Test cases
  2. #include <gtest/gtest.h>
  3. #include <Python.h>
  4. #include "CPy.h"
  5. static PyObject *moduleDict;
  6. static PyObject *int_from_str(const char *str) {
  7. return PyLong_FromString(str, 0, 10);
  8. }
  9. static std::string str_from_object(PyObject *x) {
  10. PyObject *str = PyObject_Str(x);
  11. const char *utf8 = PyUnicode_AsUTF8(str);
  12. return std::string(utf8);
  13. }
  14. static std::string str_from_int(CPyTagged x) {
  15. return str_from_object(CPyTagged_AsObject(x));
  16. }
  17. static bool is_py_equal(PyObject *x, PyObject *y) {
  18. int result = PyObject_RichCompareBool(x, y, Py_EQ);
  19. if (result < 0) {
  20. std::cout << "ERROR: Rich compare failed";
  21. }
  22. return result == 1;
  23. }
  24. static bool is_int_equal(CPyTagged x, CPyTagged y) {
  25. if (CPyTagged_CheckShort(x)) {
  26. return x == y;
  27. } else if (CPyTagged_CheckShort(y)) {
  28. return false;
  29. } else {
  30. return is_py_equal(CPyTagged_LongAsObject(x), CPyTagged_LongAsObject(y));
  31. }
  32. }
  33. static void fail(std::string message) {
  34. std::cerr << message << "\n";
  35. exit(1);
  36. }
  37. static PyObject *eval(std::string expr) {
  38. PyObject *dict = PyDict_New();
  39. auto result = PyRun_String(expr.c_str(), Py_eval_input, moduleDict, dict);
  40. Py_DECREF(dict);
  41. if (result == 0) {
  42. fail("Python exception");
  43. }
  44. return result;
  45. }
  46. static CPyTagged eval_int(std::string expr) {
  47. auto o = eval(expr);
  48. EXPECT_TRUE(PyLong_Check(o));
  49. return CPyTagged_FromObject(o);
  50. }
  51. static PyObject *empty_list() {
  52. PyObject *list = PyList_New(0);
  53. EXPECT_TRUE(list);
  54. return list;
  55. }
  56. static void list_append(PyObject *list, std::string expr) {
  57. PyObject *obj = eval(expr);
  58. int result = PyList_Append(list, obj);
  59. EXPECT_TRUE(result == 0);
  60. }
  61. class CAPITest : public ::testing::Test {
  62. protected:
  63. PyObject *max_short;
  64. PyObject *min_short;
  65. PyObject *min_pos_long;
  66. PyObject *max_neg_long;
  67. Py_ssize_t c_max_short;
  68. Py_ssize_t c_min_short;
  69. Py_ssize_t c_min_pos_long;
  70. Py_ssize_t c_max_neg_long;
  71. virtual void SetUp() {
  72. if (!moduleDict) {
  73. fail("Could not find module dictionary");
  74. }
  75. c_max_short = CPY_TAGGED_MAX; // 2**62-1
  76. c_min_pos_long = c_max_short + 1; // 2**62
  77. c_min_short = CPY_TAGGED_MIN; // -2**62
  78. c_max_neg_long = c_min_short - 1; // -(2**62+1)
  79. max_short = PyLong_FromSsize_t(c_max_short);
  80. min_pos_long = PyLong_FromSsize_t(c_min_pos_long);
  81. min_short = PyLong_FromSsize_t(c_min_short);
  82. max_neg_long = PyLong_FromSsize_t(c_max_neg_long);
  83. }
  84. virtual void TearDown() {
  85. Py_DECREF(max_short);
  86. Py_DECREF(min_pos_long);
  87. Py_DECREF(min_short);
  88. Py_DECREF(max_neg_long);
  89. }
  90. };
  91. TEST_F(CAPITest, test_cint_conversions) {
  92. EXPECT_EQ(CPyTagged_ShortFromInt(0), 0);
  93. EXPECT_EQ(CPyTagged_ShortFromInt(3), 6);
  94. EXPECT_EQ(CPyTagged_ShortFromInt(-5), -10);
  95. EXPECT_EQ(CPyTagged_ShortAsSsize_t(0), 0);
  96. EXPECT_EQ(CPyTagged_ShortAsSsize_t(6), 3);
  97. EXPECT_EQ(CPyTagged_ShortAsSsize_t(-10), -5);
  98. }
  99. TEST_F(CAPITest, test_is_long_int) {
  100. EXPECT_TRUE(CPyTagged_CheckLong(1));
  101. EXPECT_TRUE(CPyTagged_CheckLong(15));
  102. EXPECT_FALSE(CPyTagged_CheckLong(0));
  103. EXPECT_FALSE(CPyTagged_CheckLong(6));
  104. EXPECT_FALSE(CPyTagged_CheckLong(-4));
  105. }
  106. TEST_F(CAPITest, test_is_short_int) {
  107. EXPECT_FALSE(CPyTagged_CheckShort(1));
  108. EXPECT_FALSE(CPyTagged_CheckShort(15));
  109. EXPECT_TRUE(CPyTagged_CheckShort(0));
  110. EXPECT_TRUE(CPyTagged_CheckShort(6));
  111. EXPECT_TRUE(CPyTagged_CheckShort(-4));
  112. }
  113. TEST_F(CAPITest, test_obj_to_short_int) {
  114. EXPECT_EQ(CPyTagged_FromObject(int_from_str("0")), CPyTagged_ShortFromInt(0));
  115. EXPECT_EQ(CPyTagged_FromObject(int_from_str("1234")), CPyTagged_ShortFromInt(1234));
  116. EXPECT_EQ(CPyTagged_FromObject(int_from_str("-1234")), CPyTagged_ShortFromInt(-1234));
  117. EXPECT_EQ(CPyTagged_FromObject(max_short), CPyTagged_ShortFromSsize_t(c_max_short));
  118. EXPECT_EQ(CPyTagged_FromObject(min_short), CPyTagged_ShortFromSsize_t(c_min_short));
  119. }
  120. TEST_F(CAPITest, test_obj_to_long_int) {
  121. // A value larger than 2**64
  122. PyObject *large = int_from_str("18464758493694263305");
  123. PyObject *small = int_from_str("-18464758493694263305");
  124. CPyTagged x;
  125. x = CPyTagged_FromObject(large);
  126. ASSERT_TRUE(CPyTagged_CheckLong(x));
  127. EXPECT_TRUE(is_py_equal(large, CPyTagged_LongAsObject(x)));
  128. x = CPyTagged_FromObject(small);
  129. ASSERT_TRUE(CPyTagged_CheckLong(x));
  130. EXPECT_TRUE(is_py_equal(small, CPyTagged_LongAsObject(x)));
  131. x = CPyTagged_FromObject(min_pos_long);
  132. ASSERT_TRUE(CPyTagged_CheckLong(x));
  133. EXPECT_TRUE(is_py_equal(min_pos_long, CPyTagged_LongAsObject(x)));
  134. x = CPyTagged_FromObject(max_neg_long);
  135. ASSERT_TRUE(CPyTagged_CheckLong(x));
  136. EXPECT_TRUE(is_py_equal(max_neg_long, CPyTagged_LongAsObject(x)));
  137. }
  138. TEST_F(CAPITest, test_short_int_to_obj) {
  139. EXPECT_TRUE(is_py_equal(CPyTagged_AsObject(CPyTagged_ShortFromInt(0)), int_from_str("0")));
  140. EXPECT_TRUE(is_py_equal(CPyTagged_AsObject(CPyTagged_ShortFromInt(1234)),
  141. int_from_str("1234")));
  142. EXPECT_TRUE(is_py_equal(CPyTagged_AsObject(CPyTagged_ShortFromInt(-1234)),
  143. int_from_str("-1234")));
  144. EXPECT_TRUE(is_py_equal(CPyTagged_AsObject(CPyTagged_ShortFromSsize_t(c_max_short)),
  145. max_short));
  146. EXPECT_TRUE(is_py_equal(CPyTagged_AsObject(CPyTagged_ShortFromSsize_t(c_min_short)),
  147. min_short));
  148. }
  149. TEST_F(CAPITest, test_long_int_to_obj) {
  150. // A value larger than 2**64
  151. PyObject *large = int_from_str("18464758493694263305");
  152. PyObject *small = int_from_str("-18464758493694263305");
  153. PyObject *x;
  154. x = CPyTagged_AsObject(CPyTagged_FromObject(large));
  155. EXPECT_TRUE(is_py_equal(large, x));
  156. x = CPyTagged_AsObject(CPyTagged_FromObject(small));
  157. EXPECT_TRUE(is_py_equal(small, x));
  158. x = CPyTagged_AsObject(CPyTagged_FromObject(min_pos_long));
  159. EXPECT_TRUE(is_py_equal(min_pos_long, x));
  160. x = CPyTagged_AsObject(CPyTagged_FromObject(max_neg_long));
  161. EXPECT_TRUE(is_py_equal(max_neg_long, x));
  162. }
  163. #define EXPECT_INT_EQUAL(x, y) \
  164. do { \
  165. if (!is_int_equal(x, y)) \
  166. std::cout << "Failure: " << str_from_int(x) << " != " << str_from_int(y) << \
  167. "\n"; \
  168. EXPECT_TRUE(is_int_equal(x, y)); \
  169. } while (false)
  170. #define ASSERT_ADD(x, y, result) \
  171. EXPECT_TRUE(is_int_equal(CPyTagged_Add(eval_int(x), eval_int(y)), eval_int(result)))
  172. TEST_F(CAPITest, test_add_short_int) {
  173. ASSERT_ADD("13", "8", "21");
  174. ASSERT_ADD("-13", "8", "-5");
  175. ASSERT_ADD("13", "-7", "6");
  176. ASSERT_ADD("13", "-14", "-1");
  177. ASSERT_ADD("-3", "-5", "-8");
  178. }
  179. TEST_F(CAPITest, test_add_long_ints) {
  180. ASSERT_ADD("2**64", "2**65", "2**64 + 2**65");
  181. ASSERT_ADD("2**64", "-2**65", "2**64 - 2**65");
  182. }
  183. TEST_F(CAPITest, test_add_long_and_short) {
  184. ASSERT_ADD("1", "2**65", "1 + 2**65");
  185. ASSERT_ADD("2**65", "1", "1 + 2**65");
  186. }
  187. TEST_F(CAPITest, test_add_short_overflow) {
  188. // Overfloat
  189. ASSERT_ADD("2**62 - 1", "1", "2**62");
  190. ASSERT_ADD("-2**62", "-1", "-2**62 - 1");
  191. }
  192. TEST_F(CAPITest, test_add_short_edge_cases) {
  193. // Close but not quite overflow
  194. ASSERT_ADD("2**62 - 2", "1", "2**62 - 1");
  195. ASSERT_ADD("-2**62 + 1", "-1", "-2**62");
  196. // Max magnitudes
  197. ASSERT_ADD("2**62 - 1", "2**62 - 1", "2**63 - 2");
  198. ASSERT_ADD("2**62 - 1", "-2**62", "-1");
  199. }
  200. #define ASSERT_SUBTRACT(x, y, result) \
  201. EXPECT_TRUE(is_int_equal(CPyTagged_Subtract(eval_int(x), eval_int(y)), eval_int(result)))
  202. TEST_F(CAPITest, test_subtract_short_int) {
  203. ASSERT_SUBTRACT("13", "8", "5");
  204. ASSERT_SUBTRACT("8", "13", "-5");
  205. ASSERT_SUBTRACT("-13", "8", "-21");
  206. ASSERT_SUBTRACT("13", "-7", "20");
  207. ASSERT_SUBTRACT("-3", "-5", "2");
  208. }
  209. TEST_F(CAPITest, test_subtract_long_int) {
  210. ASSERT_SUBTRACT("2**65", "2**64", "2**65 - 2**64");
  211. ASSERT_SUBTRACT("2**65", "-2**64", "2**65 + 2**64");
  212. }
  213. TEST_F(CAPITest, test_subtract_long_and_short) {
  214. ASSERT_SUBTRACT("1", "2**65", "1 - 2**65");
  215. ASSERT_SUBTRACT("2**65", "1", "2**65 - 1");
  216. }
  217. TEST_F(CAPITest, test_subtract_short_overflow) {
  218. ASSERT_SUBTRACT("2**62-1", "-1", "2**62");
  219. ASSERT_SUBTRACT("-2**62", "1", "-2**62 - 1");
  220. ASSERT_SUBTRACT("0", "-2**62", "2**62");
  221. ASSERT_SUBTRACT("1", "-2**62 + 1", "2**62");
  222. ASSERT_SUBTRACT("-2", "2**62 - 1", "-2**62 - 1");
  223. }
  224. TEST_F(CAPITest, test_subtract_short_edge_cases) {
  225. // Close but not quite overflow
  226. ASSERT_SUBTRACT("2**62 - 2", "-1", "2**62 - 1");
  227. ASSERT_SUBTRACT("-2**62 + 1", "1", "-2**62");
  228. // Max magnitudes
  229. ASSERT_SUBTRACT("2**62 - 1", "-2**62", "2**63 - 1");
  230. ASSERT_SUBTRACT("-2**62", "2**62 - 1", "-2**63 + 1");
  231. }
  232. #define ASSERT_MULTIPLY(x, y, result) \
  233. EXPECT_TRUE(is_int_equal(CPyTagged_Multiply(eval_int(x), eval_int(y)), eval_int(result)))
  234. TEST_F(CAPITest, test_multiply_int) {
  235. ASSERT_MULTIPLY("0", "0", "0");
  236. ASSERT_MULTIPLY("3", "5", "15");
  237. ASSERT_MULTIPLY("2**40", "2**40", "2**80");
  238. ASSERT_MULTIPLY("2**30-1", "2**30-1", "(2**30-1)**2");
  239. ASSERT_MULTIPLY("2**30", "2**30-1", "2**30 * (2**30-1)");
  240. ASSERT_MULTIPLY("2**30-1", "2**30", "2**30 * (2**30-1)");
  241. ASSERT_MULTIPLY("2**15", "2**15-1", "2**15 * (2**15-1)");
  242. ASSERT_MULTIPLY("2**15-1", "2**15", "2**15 * (2**15-1)");
  243. ASSERT_MULTIPLY("3", "-5", "-15");
  244. ASSERT_MULTIPLY("-3", "5", "-15");
  245. ASSERT_MULTIPLY("-3", "-5", "15");
  246. }
  247. #define ASSERT_FLOOR_DIV(x, y, result) \
  248. EXPECT_INT_EQUAL(CPyTagged_FloorDivide(eval_int(x), eval_int(y)), eval_int(result))
  249. TEST_F(CAPITest, test_floor_divide_short_int) {
  250. ASSERT_FLOOR_DIV("18", "6", "3");
  251. ASSERT_FLOOR_DIV("17", "6", "2");
  252. ASSERT_FLOOR_DIV("12", "6", "2");
  253. ASSERT_FLOOR_DIV("15", "5", "3");
  254. ASSERT_FLOOR_DIV("14", "5", "2");
  255. ASSERT_FLOOR_DIV("11", "5", "2");
  256. ASSERT_FLOOR_DIV("-18", "6", "-3");
  257. ASSERT_FLOOR_DIV("-13", "6", "-3");
  258. ASSERT_FLOOR_DIV("-12", "6", "-2");
  259. ASSERT_FLOOR_DIV("18", "-6", "-3");
  260. ASSERT_FLOOR_DIV("13", "-6", "-3");
  261. ASSERT_FLOOR_DIV("12", "-6", "-2");
  262. ASSERT_FLOOR_DIV("-3", "-3", "1");
  263. ASSERT_FLOOR_DIV("-5", "-3", "1");
  264. ASSERT_FLOOR_DIV("-6", "-3", "2");
  265. ASSERT_FLOOR_DIV("2**60", "3", "2**60 // 3");
  266. ASSERT_FLOOR_DIV("-2**62", "-1", "2**62");
  267. ASSERT_FLOOR_DIV("-2**62", "1", "-2**62");
  268. ASSERT_FLOOR_DIV("2**62 - 1", "1", "2**62 - 1");
  269. ASSERT_FLOOR_DIV("2**62 - 1", "-1", "-2**62 + 1");
  270. ASSERT_FLOOR_DIV("2**60", "3", "2**60 // 3");
  271. ASSERT_FLOOR_DIV("-2**30", "-1", "2**30");
  272. ASSERT_FLOOR_DIV("-2**30", "1", "-2**30");
  273. ASSERT_FLOOR_DIV("2**30 - 1", "1", "2**30 - 1");
  274. ASSERT_FLOOR_DIV("2**30 - 1", "-1", "-2**30 + 1");
  275. }
  276. TEST_F(CAPITest, test_floor_divide_long_int) {
  277. ASSERT_FLOOR_DIV("2**100", "3", "2**100 // 3");
  278. ASSERT_FLOOR_DIV("3", "2**100", "0");
  279. ASSERT_FLOOR_DIV("2**100", "2**70 // 3", "2**100 // (2**70 // 3)");
  280. }
  281. #define ASSERT_REMAINDER(x, y, result) \
  282. EXPECT_INT_EQUAL(CPyTagged_Remainder(eval_int(x), eval_int(y)), eval_int(result))
  283. TEST_F(CAPITest, test_remainder_short_int) {
  284. ASSERT_REMAINDER("18", "6", "0");
  285. ASSERT_REMAINDER("17", "6", "5");
  286. ASSERT_REMAINDER("13", "6", "1");
  287. ASSERT_REMAINDER("12", "6", "0");
  288. ASSERT_REMAINDER("15", "5", "0");
  289. ASSERT_REMAINDER("14", "5", "4");
  290. ASSERT_REMAINDER("11", "5", "1");
  291. ASSERT_REMAINDER("-18", "6", "0");
  292. ASSERT_REMAINDER("-13", "6", "5");
  293. ASSERT_REMAINDER("-12", "6", "0");
  294. ASSERT_REMAINDER("18", "-6", "0");
  295. ASSERT_REMAINDER("13", "-6", "-5");
  296. ASSERT_REMAINDER("12", "-6", "0");
  297. ASSERT_REMAINDER("-3", "-3", "0");
  298. ASSERT_REMAINDER("-5", "-3", "-2");
  299. ASSERT_REMAINDER("-6", "-3", "0");
  300. ASSERT_REMAINDER("-1", "2**62 - 1", "2**62 - 2");
  301. ASSERT_REMAINDER("1", "-2**62", "-2**62 + 1");
  302. }
  303. TEST_F(CAPITest, test_remainder_long_int) {
  304. ASSERT_REMAINDER("2**100", "3", "2**100 % 3");
  305. ASSERT_REMAINDER("3", "2**100", "3");
  306. ASSERT_REMAINDER("2**100", "2**70 // 3", "2**100 % (2**70 // 3)");
  307. }
  308. #define INT_EQ(x, y) \
  309. CPyTagged_IsEq(eval_int(x), eval_int(y))
  310. TEST_F(CAPITest, test_int_equality) {
  311. EXPECT_TRUE(INT_EQ("0", "0"));
  312. EXPECT_TRUE(INT_EQ("5", "5"));
  313. EXPECT_TRUE(INT_EQ("-7", "-7"));
  314. EXPECT_TRUE(INT_EQ("2**65 + 0x1234", "2**65 + 0x1234"));
  315. EXPECT_TRUE(INT_EQ("-2**65 + 0x1234", "-2**65 + 0x1234"));
  316. EXPECT_FALSE(INT_EQ("0", "1"));
  317. EXPECT_FALSE(INT_EQ("5", "4"));
  318. EXPECT_FALSE(INT_EQ("-7", "7"));
  319. EXPECT_FALSE(INT_EQ("-7", "-6"));
  320. EXPECT_FALSE(INT_EQ("-7", "-5"));
  321. EXPECT_FALSE(INT_EQ("2**65 + 0x1234", "2**65 + 0x1233"));
  322. EXPECT_FALSE(INT_EQ("2**65 + 0x1234", "2**66 + 0x1234"));
  323. EXPECT_FALSE(INT_EQ("2**65 + 0x1234", "-2**65 - 0x1234"));
  324. EXPECT_FALSE(INT_EQ("-2**65 + 0x1234", "-2**65 + 0x1233"));
  325. }
  326. #define INT_NE(x, y) \
  327. CPyTagged_IsNe(eval_int(x), eval_int(y))
  328. TEST_F(CAPITest, test_int_non_equality) {
  329. EXPECT_FALSE(INT_NE("0", "0"));
  330. EXPECT_FALSE(INT_NE("5", "5"));
  331. EXPECT_FALSE(INT_NE("-7", "-7"));
  332. EXPECT_FALSE(INT_NE("2**65 + 0x1234", "2**65 + 0x1234"));
  333. EXPECT_FALSE(INT_NE("-2**65 + 0x1234", "-2**65 + 0x1234"));
  334. EXPECT_TRUE(INT_NE("0", "1"));
  335. EXPECT_TRUE(INT_NE("5", "4"));
  336. EXPECT_TRUE(INT_NE("-7", "7"));
  337. EXPECT_TRUE(INT_NE("-7", "-6"));
  338. EXPECT_TRUE(INT_NE("-7", "-5"));
  339. EXPECT_TRUE(INT_NE("2**65 + 0x1234", "2**65 + 0x1233"));
  340. EXPECT_TRUE(INT_NE("2**65 + 0x1234", "2**66 + 0x1234"));
  341. EXPECT_TRUE(INT_NE("2**65 + 0x1234", "-2**65 - 0x1234"));
  342. EXPECT_TRUE(INT_NE("-2**65 + 0x1234", "-2**65 + 0x1233"));
  343. }
  344. #define INT_LT(x, y) \
  345. CPyTagged_IsLt(eval_int(x), eval_int(y))
  346. TEST_F(CAPITest, test_int_less_than) {
  347. EXPECT_TRUE(INT_LT("0", "5"));
  348. EXPECT_TRUE(INT_LT("4", "5"));
  349. EXPECT_TRUE(INT_LT("-3", "1"));
  350. EXPECT_TRUE(INT_LT("-3", "0"));
  351. EXPECT_TRUE(INT_LT("-3", "-2"));
  352. EXPECT_FALSE(INT_LT("5", "0"));
  353. EXPECT_FALSE(INT_LT("5", "4"));
  354. EXPECT_FALSE(INT_LT("1", "-3"));
  355. EXPECT_FALSE(INT_LT("0", "-3"));
  356. EXPECT_FALSE(INT_LT("-2", "-3"));
  357. EXPECT_FALSE(INT_LT("-3", "-3"));
  358. EXPECT_FALSE(INT_LT("3", "3"));
  359. EXPECT_TRUE(INT_LT("5", "2**65"));
  360. EXPECT_TRUE(INT_LT("-2**65", "-5"));
  361. EXPECT_TRUE(INT_LT("-2**66", "2**65"));
  362. EXPECT_TRUE(INT_LT("2**65", "2**66"));
  363. EXPECT_TRUE(INT_LT("-2**66", "-2**65"));
  364. EXPECT_FALSE(INT_LT("2**65", "5"));
  365. EXPECT_FALSE(INT_LT("-5", "-2**65"));
  366. EXPECT_FALSE(INT_LT("2**65", "-2**66"));
  367. EXPECT_FALSE(INT_LT("2**66", "2**65"));
  368. EXPECT_FALSE(INT_LT("-2**65", "-2**66"));
  369. EXPECT_FALSE(INT_LT("-2**65", "-2**65"));
  370. EXPECT_FALSE(INT_LT("2**65", "2**65"));
  371. }
  372. #define INT_GE(x, y) \
  373. CPyTagged_IsGe(eval_int(x), eval_int(y))
  374. TEST_F(CAPITest, test_int_greater_than_or_equal) {
  375. EXPECT_TRUE(INT_GE("3", "2"));
  376. EXPECT_TRUE(INT_GE("3", "3"));
  377. EXPECT_FALSE(INT_GE("3", "4"));
  378. EXPECT_TRUE(INT_GE("3", "-4"));
  379. EXPECT_TRUE(INT_GE("-3", "-4"));
  380. EXPECT_TRUE(INT_GE("-3", "-3"));
  381. EXPECT_FALSE(INT_GE("-3", "-2"));
  382. EXPECT_FALSE(INT_GE("-3", "2"));
  383. EXPECT_TRUE(INT_GE("2**65", "2**65"));
  384. EXPECT_TRUE(INT_GE("2**65", "2**65 - 1"));
  385. EXPECT_FALSE(INT_GE("2**65", "2**65 + 1"));
  386. EXPECT_TRUE(INT_GE("2**65", "2**60"));
  387. }
  388. #define INT_GT(x, y) \
  389. CPyTagged_IsGt(eval_int(x), eval_int(y))
  390. TEST_F(CAPITest, test_int_greater_than) {
  391. EXPECT_TRUE(INT_GT("5", "0"));
  392. EXPECT_TRUE(INT_GT("5", "4"));
  393. EXPECT_FALSE(INT_GT("5", "5"));
  394. EXPECT_FALSE(INT_GT("5", "6"));
  395. EXPECT_TRUE(INT_GT("1", "-3"));
  396. EXPECT_FALSE(INT_GT("-3", "1"));
  397. EXPECT_TRUE(INT_GT("0", "-3"));
  398. EXPECT_TRUE(INT_GT("-2", "-3"));
  399. EXPECT_FALSE(INT_GT("-2", "-2"));
  400. EXPECT_FALSE(INT_GT("-2", "-1"));
  401. EXPECT_TRUE(INT_GT("2**65", "5"));
  402. EXPECT_TRUE(INT_GT("2**65", "2**65 - 1"));
  403. EXPECT_FALSE(INT_GT("2**65", "2**65"));
  404. EXPECT_FALSE(INT_GT("2**65", "2**65 + 1"));
  405. EXPECT_FALSE(INT_GT("-2**65", "1"));
  406. EXPECT_TRUE(INT_GT("-2**65", "-2**65 - 1"));
  407. EXPECT_FALSE(INT_GT("-2**65", "-2**65"));
  408. EXPECT_FALSE(INT_GT("-2**65", "-2**65 + 1"));
  409. }
  410. #define INT_LE(x, y) \
  411. CPyTagged_IsLe(eval_int(x), eval_int(y))
  412. TEST_F(CAPITest, test_int_less_than_or_equal) {
  413. EXPECT_TRUE(INT_LE("0", "5"));
  414. EXPECT_TRUE(INT_LE("5", "6"));
  415. EXPECT_TRUE(INT_LE("5", "5"));
  416. EXPECT_FALSE(INT_LE("5", "4"));
  417. EXPECT_FALSE(INT_LE("1", "-3"));
  418. EXPECT_TRUE(INT_LE("-3", "1"));
  419. EXPECT_TRUE(INT_LT("-3", "0"));
  420. EXPECT_TRUE(INT_LE("-2", "-1"));
  421. EXPECT_TRUE(INT_LE("-2", "-2"));
  422. EXPECT_FALSE(INT_LT("-2", "-3"));
  423. EXPECT_TRUE(INT_LE("5", "2**65"));
  424. EXPECT_FALSE(INT_LE("2**65", "5"));
  425. EXPECT_TRUE(INT_LE("2**65", "2**65 + 1"));
  426. EXPECT_TRUE(INT_LE("2**65", "2**65"));
  427. EXPECT_FALSE(INT_LE("2**65", "2**65 - 1"));
  428. EXPECT_TRUE(INT_LE("-2**65", "1"));
  429. EXPECT_FALSE(INT_LE("1", "-2**65"));
  430. EXPECT_TRUE(INT_LE("-2**65", "-2**65 + 1"));
  431. EXPECT_TRUE(INT_LE("-2**65", "-2**65"));
  432. EXPECT_FALSE(INT_LE("-2**65", "-2**65 - 1"));
  433. }
  434. #define list_get_eq(list, index, value) \
  435. is_py_equal(CPyList_GetItem(list, eval_int(index)), eval(value))
  436. TEST_F(CAPITest, test_list_get) {
  437. auto l = empty_list();
  438. list_append(l, "3");
  439. list_append(l, "5");
  440. list_append(l, "7");
  441. EXPECT_TRUE(list_get_eq(l, "0", "3"));
  442. EXPECT_TRUE(list_get_eq(l, "1", "5"));
  443. EXPECT_TRUE(list_get_eq(l, "2", "7"));
  444. EXPECT_TRUE(list_get_eq(l, "-1", "7"));
  445. EXPECT_TRUE(list_get_eq(l, "-2", "5"));
  446. EXPECT_TRUE(list_get_eq(l, "-3", "3"));
  447. }
  448. TEST_F(CAPITest, test_tagged_as_long_long) {
  449. auto s = eval_int("3");
  450. auto neg = eval_int("-1");
  451. auto l = eval_int("2**128");
  452. EXPECT_TRUE(CPyTagged_AsSsize_t(s) == 3);
  453. EXPECT_FALSE(PyErr_Occurred());
  454. EXPECT_TRUE(CPyTagged_AsSsize_t(neg) == -1);
  455. EXPECT_FALSE(PyErr_Occurred());
  456. EXPECT_TRUE(CPyTagged_AsSsize_t(l) == -1);
  457. EXPECT_TRUE(PyErr_Occurred());
  458. PyErr_Clear();
  459. }
  460. ////
  461. // Python module glue to drive the C-API tests.
  462. //
  463. // The reason we have this as an extension module instead of a
  464. // standalone binary is because building an extension module is pretty
  465. // well behaved (just specify it with distutils/setuptools and it will
  466. // get compiled and linked against the running python) while linking a
  467. // library against libpython is a huge non-standard
  468. // PITA: python-config locations are janky and it behaves in weird
  469. // ways that I don't understand, while this works very cleanly.
  470. static PyObject *run_tests(PyObject *dummy, PyObject *should_be_null) {
  471. // Fake command line arguments. We could arrange to actually pass
  472. // in command line arguments (either real ones or ones given as
  473. // arguments) but have not bothered.
  474. int argc = 1;
  475. char asdf[] = "test_capi"; // InitGoogleTest wants char** which means it can't be const...
  476. char *argv[] = {asdf, NULL};
  477. ::testing::InitGoogleTest(&argc, argv);
  478. return PyLong_FromLong(RUN_ALL_TESTS());
  479. }
  480. static PyMethodDef test_methods[] = {
  481. {"run_tests", run_tests, METH_NOARGS, "Run the C API tests"},
  482. {NULL, NULL, 0, NULL}
  483. };
  484. static struct PyModuleDef test_module = {
  485. PyModuleDef_HEAD_INIT,
  486. "test_capi",
  487. NULL,
  488. -1,
  489. test_methods
  490. };
  491. PyMODINIT_FUNC
  492. PyInit_test_capi(void)
  493. {
  494. PyObject *module = PyModule_Create(&test_module);
  495. if (module) {
  496. moduleDict = PyModule_GetDict(module);
  497. }
  498. return module;
  499. }