Skip to content

Commit b2357f0

Browse files
committed
Add unit tests
1 parent 47c5ce3 commit b2357f0

5 files changed

Lines changed: 163 additions & 2 deletions

File tree

‎.gitignore‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
Modules/python.exp
44
buildaix/
55
installp/
6-
.gitignore
76

87
# Two-trick pony for OSX and other case insensitive file systems:
98
# Ignore ./python binary on Unix but still look into ./Python/ directory.
@@ -33,7 +32,7 @@ Include/pydtrace_probes.h
3332
Lib/distutils/command/*.pdb
3433
Lib/lib2to3/*.pickle
3534
Lib/test/data/*
36-
Makefile
35+
#Makefile
3736
Makefile.pre
3837
Misc/python.pc
3938
Misc/python-config.sh

‎README.rst‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ The intent is to experiment to implement the new C API described at:
66

77
https://pythoncapi.readthedocs.io/
88

9+
Build and run unit tests::
10+
11+
./configure --with-shared --with-pydebug
12+
make
13+
cd capi/tests
14+
make
15+
916
The changes live in the **pythoncapi** branch. See also:
1017

1118
* `github.com/pythoncapi/cpython <https://github.com/pythoncapi/cpython>`_

‎capi/tests/.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test_tuple

‎capi/tests/Makefile‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CPYTHON_SRC=../..
2+
LIBPYTHON=python3.8dm
3+
4+
all: test_tuple
5+
LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./test_tuple
6+
7+
test_tuple: test_tuple.c
8+
$(CC) -o $@ $< -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include -l $(LIBPYTHON) -L $(CPYTHON_SRC)
9+

‎capi/tests/test_tuple.c‎

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#include <Python.h>
2+
3+
typedef enum {
4+
capitest_enum_SUCCESS,
5+
capitest_enum_FAIL,
6+
capitest_enum_SKIPPED
7+
} capitest_ResultEnum;
8+
9+
typedef struct {
10+
capitest_ResultEnum result;
11+
const char *msg;
12+
const char *filename;
13+
int lineno;
14+
} capitest_Result;
15+
16+
typedef capitest_Result (*capitest_TestFunc) ();
17+
18+
typedef struct {
19+
capitest_Result result;
20+
const char *name;
21+
capitest_TestFunc func;
22+
} capitest_Test;
23+
24+
typedef struct {
25+
size_t ntest;
26+
/* FIXME: don't use hardcoded array size */
27+
capitest_Test tests[10];
28+
} capitest_TestSuite;
29+
30+
#define capitest_TestSuite_INIT {.ntest = 0}
31+
32+
#define capitest_FAIL_MSG(message) \
33+
(capitest_Result){.result = capitest_enum_FAIL, .msg = (message), .filename = __FILE__, .lineno = __LINE__}
34+
#define capitest_FAIL(message) capitest_FAIL_MSG(NULL)
35+
#define capitest_SUCCESS() \
36+
(capitest_Result){.result = capitest_enum_SUCCESS, .filename = __FILE__, .lineno = __LINE__}
37+
38+
static capitest_Result
39+
check_PyTuple_New_Size(size_t size)
40+
{
41+
PyObject *tuple = PyTuple_New(size);
42+
if (tuple == NULL) {
43+
return capitest_FAIL();
44+
}
45+
if (Py_TYPE(tuple) != &PyTuple_Type) {
46+
return capitest_FAIL();
47+
}
48+
/* don't check Py_REFCNT() to PyTuple_New(0): CPython uses a singleton */
49+
if (size != 0) {
50+
if (Py_REFCNT(tuple) != 1) {
51+
return capitest_FAIL();
52+
}
53+
}
54+
if (PyTuple_Size(tuple) != size) {
55+
return capitest_FAIL();
56+
}
57+
Py_DECREF(tuple);
58+
return capitest_SUCCESS();
59+
}
60+
61+
62+
static capitest_Result
63+
test_PyTuple_New(void)
64+
{
65+
capitest_Result result;
66+
result = check_PyTuple_New_Size(0);
67+
if (result.result != capitest_enum_SUCCESS) {
68+
return result;
69+
}
70+
result = check_PyTuple_New_Size(1);
71+
if (result.result != capitest_enum_SUCCESS) {
72+
return result;
73+
}
74+
result = check_PyTuple_New_Size(5);
75+
return result;
76+
}
77+
78+
79+
static capitest_Result
80+
test_PyTuple_GET_ITEM(void)
81+
{
82+
PyObject *tuple = PyTuple_New(0);
83+
if (tuple == NULL) {
84+
return capitest_FAIL();
85+
}
86+
Py_DECREF(tuple);
87+
return capitest_SUCCESS();
88+
}
89+
90+
91+
static void
92+
capitest_run_test(capitest_Test *test)
93+
{
94+
printf("%s: ", test->name);
95+
fflush(stdout);
96+
97+
test->result = test->func();
98+
capitest_Result *result = &test->result;
99+
100+
if (result->result == capitest_enum_FAIL) {
101+
printf("FAIL at %s:%i", result->filename, result->lineno);
102+
if (result->msg) {
103+
printf("(%s)", result->msg);
104+
}
105+
printf("\n");
106+
}
107+
else {
108+
assert(result->result == capitest_enum_SUCCESS);
109+
printf("ok\n");
110+
}
111+
fflush(stdout);
112+
}
113+
114+
/* FIXME: handle error */
115+
static void
116+
capitest_register(capitest_TestSuite *suite, const char *name, capitest_TestFunc func)
117+
{
118+
capitest_Test test = {.name = name, .func = func};
119+
assert(suite->ntest < Py_ARRAY_LENGTH(suite->tests));
120+
size_t i = suite->ntest;
121+
suite->ntest++;
122+
suite->tests[i] = test;
123+
}
124+
125+
#define CAPITEST_REGISTER(suite, test_func) capitest_register(&suite, #test_func, test_func)
126+
127+
static void
128+
capitest_run_testsuite(capitest_TestSuite *suite)
129+
{
130+
Py_Initialize();
131+
for (size_t i=0; i < suite->ntest; i++) {
132+
capitest_Test *test = &suite->tests[i];
133+
capitest_run_test(test);
134+
/* FIXME: store result somewhere */
135+
}
136+
Py_Finalize();
137+
}
138+
139+
int main()
140+
{
141+
capitest_TestSuite suite = capitest_TestSuite_INIT ;
142+
CAPITEST_REGISTER(suite, test_PyTuple_New);
143+
CAPITEST_REGISTER(suite, test_PyTuple_GET_ITEM);
144+
capitest_run_testsuite(&suite);
145+
}

0 commit comments

Comments
 (0)