Skip to content

Commit 89988c9

Browse files
committed
ctest is now python package
1 parent fae7203 commit 89988c9

File tree

5 files changed

+175
-143
lines changed

5 files changed

+175
-143
lines changed

ctest/base_ctest.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#include <Python.h>
2+
3+
#include "base.h"
4+
#include "test_common.h"
5+
6+
static PyObject *base_module;
7+
8+
/* setUp and tearDown must be nonstatic void(void) */
9+
void setUp(void) {}
10+
11+
void tearDown(void) {}
12+
13+
/**
14+
* @brief Tests _pg_is_int_tuple when passed a tuple of ints
15+
*/
16+
static PyObject*
17+
test__pg_is_int_tuple_nominal(PyObject *self, PyObject *_null)
18+
{
19+
PyObject *arg1 = Py_BuildValue("(iii)", 1, 2, 3);
20+
PyObject *arg2 = Py_BuildValue("(iii)", -1, -2, -3);
21+
PyObject *arg3 = Py_BuildValue("(iii)", 1, -2, -3);
22+
23+
TEST_ASSERT_EQUAL(1, _pg_is_int_tuple(arg1));
24+
TEST_ASSERT_EQUAL(1, _pg_is_int_tuple(arg2));
25+
TEST_ASSERT_EQUAL(1, _pg_is_int_tuple(arg3));
26+
27+
Py_RETURN_NONE;
28+
}
29+
30+
/**
31+
* @brief Tests _pg_is_int_tuple when passed a tuple of non-numeric values
32+
*/
33+
static PyObject*
34+
test__pg_is_int_tuple_failureModes(PyObject *self, PyObject *_null)
35+
{
36+
PyObject *arg1 =
37+
Py_BuildValue("(sss)", (char *)"Larry", (char *)"Moe", (char *)"Curly");
38+
PyObject *arg2 = Py_BuildValue("(sss)", (char *)NULL, (char *)NULL,
39+
(char *)NULL); // tuple of None's
40+
PyObject *arg3 = Py_BuildValue("(OOO)", arg1, arg2, arg1);
41+
42+
TEST_ASSERT_EQUAL(0, _pg_is_int_tuple(arg1));
43+
TEST_ASSERT_EQUAL(0, _pg_is_int_tuple(arg2));
44+
TEST_ASSERT_EQUAL(0, _pg_is_int_tuple(arg3));
45+
46+
Py_RETURN_NONE;
47+
}
48+
49+
/**
50+
* @brief Tests _pg_is_int_tuple when passed a tuple of floats
51+
*/
52+
static PyObject*
53+
test__pg_is_int_tuple_floats(PyObject *self, PyObject *_null)
54+
{
55+
PyObject *arg1 = Py_BuildValue("(ddd)", 1.0, 2.0, 3.0);
56+
PyObject *arg2 = Py_BuildValue("(ddd)", -1.1, -2.2, -3.3);
57+
PyObject *arg3 = Py_BuildValue("(ddd)", 1.0, -2.0, -3.1);
58+
59+
TEST_ASSERT_EQUAL(1, _pg_is_int_tuple(arg1));
60+
TEST_ASSERT_EQUAL(0, _pg_is_int_tuple(arg2));
61+
TEST_ASSERT_EQUAL(0, _pg_is_int_tuple(arg3));
62+
63+
Py_RETURN_NONE;
64+
}
65+
66+
/*=======Test Reset Option=====*/
67+
/* This must be void(void) */
68+
void resetTest(void)
69+
{
70+
tearDown();
71+
setUp();
72+
}
73+
74+
/*=======Exposed Test Reset Option=====*/
75+
static PyObject*
76+
reset_test(PyObject *self, PyObject *_null)
77+
{
78+
resetTest();
79+
80+
Py_RETURN_NONE;
81+
}
82+
83+
/*=======Run The Tests=======*/
84+
static PyObject*
85+
run_tests(PyObject *self, PyObject *_null)
86+
{
87+
UnityBegin("base_ctest.c");
88+
RUN_TEST_PG_INTERNAL(test__pg_is_int_tuple_nominal, 15, self, _null);
89+
RUN_TEST_PG_INTERNAL(test__pg_is_int_tuple_failureModes, 29, self, _null);
90+
RUN_TEST_PG_INTERNAL(test__pg_is_int_tuple_floats, 46, self, _null);
91+
92+
return PyLong_FromLong(UnityEnd());
93+
}
94+
95+
static PyMethodDef base_test_methods[] = {
96+
{"test__pg_is_int_tuple_nominal", (PyCFunction)test__pg_is_int_tuple_nominal, METH_NOARGS, "Tests _pg_is_int_tuple when passed a tuple of ints"},
97+
{"test__pg_is_int_tuple_failureModes", (PyCFunction)test__pg_is_int_tuple_failureModes, METH_NOARGS, "Tests _pg_is_int_tuple when passed a tuple of non-numeric values"},
98+
{"test__pg_is_int_tuple_floats", (PyCFunction)test__pg_is_int_tuple_floats, METH_NOARGS, "Tests _pg_is_int_tuple when passed a tuple of floats"},
99+
{"reset_test", (PyCFunction)reset_test, METH_NOARGS, "Resets the test suite between tests, run_tests automatically calls this after each test case it calls"},
100+
{"run_tests", (PyCFunction)run_tests, METH_NOARGS, "Runs all the tests in this test wuite"},
101+
{NULL, NULL, 0, NULL}};
102+
103+
MODINIT_DEFINE(base_ctest)
104+
{
105+
PyObject* module;
106+
107+
static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT,
108+
"base_ctest",
109+
"C unit tests for the pygame.base internal implementation",
110+
-1,
111+
base_test_methods,
112+
NULL,
113+
NULL,
114+
NULL,
115+
NULL};
116+
117+
/* create the module */
118+
module = PyModule_Create(&_module);
119+
if (!module) {
120+
return NULL;
121+
}
122+
123+
return module;
124+
}
125+
126+
// #undef main
127+
// /*=======MAIN=====*/
128+
// int main(void) {
129+
// Py_Initialize();
130+
// UnityBegin("test_base.c");
131+
// RUN_TEST(test__pg_is_int_tuple_nominal, 17);
132+
// RUN_TEST(test__pg_is_int_tuple_failureModes, 31);
133+
// RUN_TEST(test__pg_is_int_tuple_floats, 45);
134+
135+
// return (UnityEnd());
136+
// }

ctest/meson.build

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,13 @@
11
unity_subproject = subproject('unity')
22
unity_dependency = unity_subproject.get_variable('unity_dep')
33

4-
test_sources = files(
5-
'../src_c/base.c',
6-
'test_base.c'
7-
)
8-
9-
inc = include_directories('../src_c')
10-
11-
py_version = py.language_version().split('.')
12-
py_major = py_version[0]
13-
py_minor = py_version[1]
14-
libpython_name = 'python' + py_major + '.' + py_minor
15-
16-
libpython = cc.find_library(libpython_name, required: false)
17-
18-
python_dep = dependency(libpython_name, required: false)
19-
if not python_dep.found()
20-
python_dep = declare_dependency(
21-
dependencies: libpython
22-
)
23-
endif
24-
25-
executable('run_ctests',
26-
sources: [
27-
test_sources,
28-
],
29-
include_directories: [inc],
30-
dependencies: [unity_dependency, sdl_dep, python_dep, py_dep],
4+
base_ctest = py.extension_module(
5+
'base_ctest',
6+
'base_ctest.c',
7+
c_args: warnings_error,
8+
dependencies: [pg_base_deps, unity_dependency],
9+
sources: ['../src_c/base.c'],
3110
install: true,
32-
install_dir: pg_dir
11+
subdir: pg,
12+
include_directories: ['../src_c']
3313
)

ctest/test_base.c

Lines changed: 0 additions & 82 deletions
This file was deleted.

ctest/test_common.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "unity.h"
2+
3+
#ifndef TEST_COMMON_H
4+
#define TEST_COMMON_H
5+
6+
#define RUN_TEST_PG_INTERNAL(TestFunc, TestLineNum, self_arg, null_arg) \
7+
{ \
8+
Unity.CurrentTestName = #TestFunc; \
9+
Unity.CurrentTestLineNumber = TestLineNum; \
10+
Unity.NumberOfTests++; \
11+
if (TEST_PROTECT()) \
12+
{ \
13+
setUp(); \
14+
TestFunc(self_arg, null_arg); \
15+
} \
16+
if (TEST_PROTECT()) \
17+
{ \
18+
tearDown(); \
19+
} \
20+
UnityConcludeTest(); \
21+
}
22+
23+
#endif // #ifndef TEST_COMMON_H

test/ctest_test.py

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,15 @@
1-
import io
2-
import os
3-
import re
4-
import subprocess
51
import unittest
62

3+
base_ctest = None
4+
try:
5+
import pygame.base_ctest as base_ctest
6+
except ModuleNotFoundError:
7+
pass
78

89
class Ctest(unittest.TestCase):
9-
def test_run_ctests(self):
10-
filename_regex = re.compile(".*run_ctests.*")
11-
12-
test_dir = os.path.dirname(os.path.abspath(__file__))
13-
pg_dir = os.path.join(test_dir, "..")
14-
15-
test_executable_exists = False
16-
test_filename = ""
17-
for filename in os.listdir(pg_dir):
18-
if re.match(filename_regex, filename):
19-
test_filename = filename
20-
test_executable_exists = True
21-
break
22-
23-
if test_executable_exists:
24-
cwd = os.getcwd()
25-
os.chdir(pg_dir)
26-
27-
with open(f"{cwd}/ctest.log", 'w') as ctest_log:
28-
test_result = subprocess.run(
29-
[test_filename], stdout=ctest_log, stderr=subprocess.STDOUT
30-
)
31-
32-
os.chdir(cwd)
33-
34-
self.assertEqual(test_result.returncode, 0)
35-
36-
else:
37-
unittest.skip("Test Executable Not Available")
10+
@unittest.skipIf(base_ctest is None, "base_ctest not built")
11+
def test_run_base_ctests(self):
12+
self.assertEqual(base_ctest.run_tests(), 0)
3813

3914

4015
if __name__ == "__main__":

0 commit comments

Comments
 (0)