Python unit tests

master
Yevgen Muntyan 2011-01-01 18:53:27 -08:00
parent 30584189c2
commit 76c4c2b085
16 changed files with 240 additions and 106 deletions

View File

@ -1,13 +1,17 @@
local test_ret = {}
local function getline()
return debug.getinfo(4, "l").currentline
end
local medit = require("medit")
local function _tassert(cond, msg, ...)
table.insert(test_ret, string.format(msg or '', ...))
table.insert(test_ret, not not cond)
table.insert(test_ret, getline())
local info = debug.getinfo(3, "Slf")
if not cond then
local message = string.format(msg or '', ...)
local name = info.name
if name then
message = string.format('in function %s: %s', name, message)
end
medit.test_assert_impl(false, message, info.short_src, info.currentline)
else
medit.test_assert_impl(true, '', info.short_src, info.currentline)
end
end
function tassert(cond, msg, ...)
@ -57,7 +61,3 @@ function tassert_eq(actual, exp, msg)
_tassert(cmp(actual, exp), "%sexpected %s, got %s",
msg, pr(exp), pr(actual))
end
munit_report = function()
return unpack(test_ret)
end

View File

@ -0,0 +1,14 @@
import moo
import traceback
def _tassert(cond, msg):
st = traceback.extract_stack()
loc = st[len(st) - 3]
if not msg:
msg = "`%s'" % loc[3]
if loc[2] != '<module>':
msg = 'in function %s: %s' % (loc[2], msg)
moo.test_assert_impl(bool(cond), msg, loc[0], loc[1])
def tassert(cond, msg=None):
_tassert(cond, msg)

View File

@ -0,0 +1,20 @@
from munit import *
import moo
editor = moo.editor_instance()
tassert(editor is not None)
tassert(isinstance(editor, moo.Editor))
window = editor.get_active_window()
tassert(window is not None)
tassert(isinstance(window, moo.EditWindow))
doc = window.get_active_doc()
tassert(doc is not None)
tassert(isinstance(doc, moo.Edit))
tassert(doc == editor.get_active_doc())
tassert(doc.get_window() == window)
view = doc.get_view()
tassert(view is not None)
tassert(isinstance(view, moo.EditView))
tassert(isinstance(view, moo.TextView))
tassert(view is window.get_active_view())
tassert(view is editor.get_active_view())

View File

@ -1,5 +1,6 @@
#include <mooedit/mooeditor-tests.h>
#include <moolua/moolua-tests.h>
#include <moopython/moopython-tests.h>
#include <mooutils/mooutils-tests.h>
#include <gtk/gtk.h>
#include <stdio.h>
@ -21,6 +22,10 @@ add_tests (void)
moo_test_lua ();
#ifdef MOO_ENABLE_PYTHON
moo_test_python ();
#endif
// moo_test_key_file ();
moo_test_editor ();
}

View File

@ -21,6 +21,7 @@
#include "mooutils/moonotebook.h"
#include "mooutils/mooundo.h"
#include "mooutils/mooutils-script.h"
#include "mooutils/moo-test-utils.h"
#include "moofileview/moofileview.h"

View File

@ -30,7 +30,6 @@ moo_test_run_lua_script (lua_State *L,
const char *filename)
{
int ret;
int i;
if (lua_gettop (L) != 0)
{
@ -70,29 +69,6 @@ moo_test_run_lua_script (lua_State *L,
return;
}
luaL_loadstring (L, "return munit_report()");
if ((ret = lua_pcall (L, 0, LUA_MULTRET, 0)) != 0)
g_error ("%s: fix me!", G_STRFUNC);
for (i = 1; i+2 <= lua_gettop (L); i += 3)
{
if (!lua_isstring (L, i) || !lua_isboolean (L, i+1) || !lua_isnumber (L, i+2))
{
TEST_FAILED_MSG ("script `%s' returned wrong value!", filename);
}
else
{
const char *msg = lua_tostring (L, i);
gboolean success = lua_toboolean (L, i+1);
int line = lua_tointeger (L, i+2);
moo_test_assert_msg (success, filename, line, "%s", msg);
}
}
if (i != lua_gettop (L) + 1)
TEST_FAILED_MSG ("script `%s' returned wrong number of values (%d)",
filename, lua_gettop (L));
}
static void

View File

@ -12,7 +12,9 @@ moo_python_sources += \
moopython/moopython-loader.h \
moopython/moopython-loader.c \
moopython/moopython-utils.h \
moopython/moopython-utils.c
moopython/moopython-utils.c \
moopython/moopython-tests.h \
moopython/moopython-tests.c
moo_sources += \
moopython/medit-python.h \

View File

@ -37,10 +37,12 @@ create_script_dict (const char *name)
static PyObject *
run_string (const char *str,
const char *filename,
PyObject *globals,
PyObject *locals)
{
PyObject *ret;
PyObject *code;
g_return_val_if_fail (str != NULL, NULL);
@ -49,13 +51,18 @@ run_string (const char *str,
else
Py_INCREF ((PyObject*) locals);
g_return_val_if_fail (locals != NULL, NULL);
if (!globals)
globals = locals;
ret = PyRun_String (str, Py_file_input, globals, locals);
g_return_val_if_fail (locals != NULL, NULL);
g_return_val_if_fail (globals != NULL, NULL);
code = Py_CompileString (str, filename ? filename : "<script>", Py_file_input);
if (code)
ret = PyEval_EvalCode ((PyCodeObject*) code, globals, locals);
Py_XDECREF (code);
Py_DECREF (locals);
return ret;
}
@ -128,9 +135,10 @@ moo_python_state_free (MooPythonState *state)
}
}
gboolean
moo_python_run_string (MooPythonState *state,
const char *string)
static gboolean
moo_python_run_string_impl (MooPythonState *state,
const char *string,
const char *filename)
{
PyObject *pyret;
gboolean ret = TRUE;
@ -138,11 +146,14 @@ moo_python_run_string (MooPythonState *state,
moo_return_val_if_fail (state && state->locals, FALSE);
moo_return_val_if_fail (string != NULL, FALSE);
pyret = run_string (string, NULL, state->locals);
pyret = run_string (string, filename, NULL, state->locals);
if (!pyret)
{
moo_message ("error running python script '%s'", string);
if (filename)
g_warning ("error running python file '%s'", filename);
else
g_warning ("error running python script '%s'", string);
if (PyErr_Occurred ())
PyErr_Print ();
else
@ -154,6 +165,13 @@ moo_python_run_string (MooPythonState *state,
return ret;
}
gboolean
moo_python_run_string (MooPythonState *state,
const char *string)
{
return moo_python_run_string_impl (state, string, NULL);
}
gboolean
moo_python_run_file (MooPythonState *state,
const char *filename)
@ -172,15 +190,16 @@ moo_python_run_file (MooPythonState *state,
return FALSE;
}
ret = moo_python_run_string (state, contents);
ret = moo_python_run_string_impl (state, contents, filename);
g_free (contents);
return ret;
}
gboolean
medit_python_run_string (const char *string,
gboolean default_init)
static gboolean
medit_python_run_string_impl (const char *string,
const char *filename,
gboolean default_init)
{
MooPythonState *state;
gboolean ret;
@ -192,12 +211,19 @@ medit_python_run_string (const char *string,
if (!state)
return FALSE;
ret = moo_python_run_string (state, string);
ret = moo_python_run_string_impl (state, string, filename);
moo_python_state_free (state);
return ret;
}
gboolean
medit_python_run_string (const char *string,
gboolean default_init)
{
return medit_python_run_string_impl (string, NULL, default_init);
}
gboolean
medit_python_run_file (const char *filename,
gboolean default_init)
@ -215,7 +241,7 @@ medit_python_run_file (const char *filename,
return FALSE;
}
ret = medit_python_run_string (contents, default_init);
ret = medit_python_run_string_impl (contents, filename, default_init);
g_free (contents);
return ret;

View File

@ -22,60 +22,9 @@
#include <string.h>
#include "moopython/moopython-loader.h"
#include "moopython/moopython-utils.h"
#include "mooutils/mooutils-misc.h"
static gboolean
sys_path_add_dir (const char *dir)
{
PyObject *path;
PyObject *s;
path = PySys_GetObject ((char*) "path");
if (!path)
{
PyErr_Print ();
return FALSE;
}
if (!PyList_Check (path))
{
g_critical ("sys.path is not a list");
return FALSE;
}
s = PyString_FromString (dir);
PyList_Append (path, s);
Py_DECREF (s);
return TRUE;
}
static void
sys_path_remove_dir (const char *dir)
{
PyObject *path;
int i;
path = PySys_GetObject ((char*) "path");
if (!path || !PyList_Check (path))
return;
for (i = PyList_GET_SIZE (path) - 1; i >= 0; --i)
{
PyObject *item = PyList_GET_ITEM (path, i);
if (PyString_CheckExact (item) &&
!strcmp (PyString_AsString (item), dir))
{
if (PySequence_DelItem (path, i) != 0)
PyErr_Print ();
break;
}
}
}
static void
sys_path_add_plugin_dirs (void)
{
@ -90,7 +39,7 @@ sys_path_add_plugin_dirs (void)
dirs = moo_get_data_and_lib_subdirs ("python");
for (d = dirs; d && *d; ++d)
sys_path_add_dir (*d);
moo_python_add_path (*d);
g_strfreev (dirs);
}
@ -178,12 +127,12 @@ load_file (const char *path)
sys_path_add_plugin_dirs ();
dirname = g_path_get_dirname (path);
dir_added = sys_path_add_dir (dirname);
dir_added = moo_python_add_path (dirname);
retval = do_load_file (path);
if (dir_added)
sys_path_remove_dir (dirname);
moo_python_remove_path (dirname);
g_free (dirname);

View File

@ -0,0 +1,46 @@
#include "moopython-utils.h"
#include "moopython-tests.h"
#include "medit-python.h"
static void
moo_test_run_python_file (const char *basename)
{
char *filename = moo_test_find_data_file (basename);
if (!filename)
TEST_FAILED_MSG ("could not find file `%s'", basename);
else if (!medit_python_run_file (filename, TRUE))
TEST_FAILED_MSG ("error running file `%s'", basename);
g_free (filename);
}
static void
test_func (MooTestEnv *env)
{
static gboolean been_here = FALSE;
if (!been_here)
{
been_here = TRUE;
moo_python_add_path (moo_test_get_data_dir ());
}
moo_test_run_python_file ((const char *) env->test_data);
}
static void
add_test (MooTestSuite *suite, const char *name, const char *description, const char *python_file)
{
moo_test_suite_add_test (suite, name, description, test_func, (void*) python_file);
}
void
moo_test_python (void)
{
MooTestSuite *suite;
suite = moo_test_suite_new ("MooPython", "Python scripting tests", NULL, NULL, NULL);
add_test (suite, "moo", "test of moo module", "testmoo.py");
}

View File

@ -0,0 +1,12 @@
#ifndef MOO_PYTHON_TESTS_H
#define MOO_PYTHON_TESTS_H
#include "mooutils/moo-test-macros.h"
G_BEGIN_DECLS
void moo_test_python (void);
G_END_DECLS
#endif /* MOO_PYTHON_TESTS_H */

View File

@ -25,6 +25,62 @@
MOO_DEFINE_BOXED_TYPE_R (MooPyObject, _moo_py_object)
gboolean
moo_python_add_path (const char *dir)
{
PyObject *path;
PyObject *s;
g_return_val_if_fail (dir != NULL, FALSE);
path = PySys_GetObject ((char*) "path");
if (!path)
{
PyErr_Print ();
return FALSE;
}
if (!PyList_Check (path))
{
g_critical ("sys.path is not a list");
return FALSE;
}
s = PyString_FromString (dir);
PyList_Append (path, s);
Py_DECREF (s);
return TRUE;
}
void
moo_python_remove_path (const char *dir)
{
PyObject *path;
int i;
g_return_if_fail (dir != NULL);
path = PySys_GetObject ((char*) "path");
if (!path || !PyList_Check (path))
return;
for (i = PyList_GET_SIZE (path) - 1; i >= 0; --i)
{
PyObject *item = PyList_GET_ITEM (path, i);
if (PyString_CheckExact (item) &&
!strcmp (PyString_AsString (item), dir))
{
if (PySequence_DelItem (path, i) != 0)
PyErr_Print ();
break;
}
}
}
static PyTypeObject *
moo_get_pygobject_type (void)
{

View File

@ -54,6 +54,8 @@ void _moo_pyobject_to_gvalue (PyObject *object,
char *_moo_py_err_string (void);
void _moo_py_init_print_funcs (void);
gboolean moo_python_add_path (const char *dir);
void moo_python_remove_path (const char *dir);
#define return_Obj(obj) return Py_INCREF (obj), obj
#define return_Self return_Obj (self)

View File

@ -46,6 +46,7 @@ headers
#include "mooutils/moonotebook.h"
#include "mooutils/mooundo.h"
#include "mooutils/mooutils-script.h"
#include "mooutils/moo-test-utils.h"
#include "moofileview/moofileview.h"

View File

@ -378,6 +378,14 @@ moo_test_get_result (void)
}
/**
* moo_test_assert_impl: (moo.private 1)
*
* @passed:
* @text: (type const-utf8)
* @file: (type const-utf8) (allow-none) (default NULL)
* @line: (default -1)
**/
void
moo_test_assert_impl (gboolean passed,
const char *text,
@ -438,6 +446,21 @@ moo_test_get_working_dir (void)
return "test-working-dir";
}
char *
moo_test_find_data_file (const char *basename)
{
char *fullname;
g_return_val_if_fail (registry.data_dir != NULL, NULL);
if (!_moo_path_is_absolute (basename))
fullname = g_build_filename (registry.data_dir, basename, NULL);
else
fullname = g_strdup (basename);
return fullname;
}
char *
moo_test_load_data_file (const char *basename)
{

View File

@ -73,6 +73,7 @@ void moo_test_assert_msg (gboolean passed,
...) G_GNUC_PRINTF(4,5);
char *moo_test_load_data_file (const char *basename);
char *moo_test_find_data_file (const char *basename);
const char *moo_test_get_data_dir (void);
const char *moo_test_get_working_dir (void);