# HG changeset patch # User Atul Varma # Date 1251579963 25200 # Node ID 657afb7307ebe6bbea071a5b1a63a9e3df7cb384 # Parent aea82140758c8baec3a615cf24078db022a0a288 Added a pymonkey.get_debug_info() function and used it on test teardown to ensure that unit tests don't leak. diff -r aea82140758c -r 657afb7307eb src/pymonkey.cpp --- a/src/pymonkey.cpp Sat Aug 29 13:33:41 2009 -0700 +++ b/src/pymonkey.cpp Sat Aug 29 14:06:03 2009 -0700 @@ -42,7 +42,17 @@ #include "script.h" #include "utils.h" +static PyObject * +PYM_getDebugInfo(PyObject *self, PyObject *args) +{ + PyObject *info = Py_BuildValue("{sI}", + "runtime_count", PYM_getJSRuntimeCount()); + return info; +} + static PyMethodDef PYM_methods[] = { + {"get_debug_info", PYM_getDebugInfo, METH_VARARGS, + "Get debugging information about the module."}, {NULL, NULL, 0, NULL} }; diff -r aea82140758c -r 657afb7307eb src/runtime.cpp --- a/src/runtime.cpp Sat Aug 29 13:33:41 2009 -0700 +++ b/src/runtime.cpp Sat Aug 29 14:06:03 2009 -0700 @@ -38,6 +38,13 @@ #include "context.h" #include "utils.h" +static unsigned int runtimeCount = 0; + +unsigned int PYM_getJSRuntimeCount() +{ + return runtimeCount; +} + static PyObject * PYM_JSRuntimeNew(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -79,6 +86,9 @@ } } + if (self) + runtimeCount++; + return (PyObject *) self; } @@ -106,6 +116,8 @@ } self->ob_type->tp_free((PyObject *) self); + + runtimeCount--; } static PyObject * diff -r aea82140758c -r 657afb7307eb src/runtime.h --- a/src/runtime.h Sat Aug 29 13:33:41 2009 -0700 +++ b/src/runtime.h Sat Aug 29 14:06:03 2009 -0700 @@ -65,4 +65,6 @@ extern PyTypeObject PYM_JSRuntimeType; +extern unsigned int PYM_getJSRuntimeCount(); + #endif diff -r aea82140758c -r 657afb7307eb tests/test_pymonkey.py --- a/tests/test_pymonkey.py Sat Aug 29 13:33:41 2009 -0700 +++ b/tests/test_pymonkey.py Sat Aug 29 14:06:03 2009 -0700 @@ -8,6 +8,22 @@ import pymonkey class PymonkeyTests(unittest.TestCase): + def setUp(self): + self._teardowns = [] + + def tearDown(self): + self.last_exception = None + while self._teardowns: + obj = self._teardowns.pop() + runtime = obj.get_runtime() + runtime.new_context().clear_object_private(obj) + del runtime + del obj + self.assertEqual(pymonkey.get_debug_info()['runtime_count'], 0) + + def _clearOnTeardown(self, obj): + self._teardowns.append(obj) + def _evaljs(self, code): rt = pymonkey.Runtime() cx = rt.new_context() @@ -28,6 +44,7 @@ obj = cx.new_object() cx.init_standard_classes(obj) jsfunc = cx.new_function(func, func.__name__) + self._clearOnTeardown(jsfunc) cx.define_property(obj, func.__name__, jsfunc) return cx.evaluate_script(obj, code, '', 1) @@ -62,6 +79,7 @@ obj = cx.new_object() cx.init_standard_classes(obj) jsfunc = cx.new_function(func, func.__name__) + self._clearOnTeardown(jsfunc) cx.define_property(obj, func.__name__, jsfunc) cx.evaluate_script(obj, 'func()', '', 1) script = stack_holder[0]['caller']['script'] @@ -281,6 +299,7 @@ obj = cx.new_object() cx.init_standard_classes(obj) jsfunc = cx.new_function(func, func.__name__) + self._clearOnTeardown(jsfunc) cx.define_property(obj, func.__name__, jsfunc) cx.evaluate_script(obj, code, '', 1) self.assertEqual(contexts[0], cx) @@ -297,6 +316,7 @@ obj = cx.new_object() cx.init_standard_classes(obj) jsfunc = cx.new_function(func, func.__name__) + self._clearOnTeardown(jsfunc) cx.define_property(obj, func.__name__, jsfunc) cx.evaluate_script(obj, code, '', 1) self.assertEqual(thisObjs[0], obj) @@ -312,6 +332,8 @@ obj = cx.new_object() cx.init_standard_classes(obj) jsfunc = cx.new_function(func, func.__name__) + self._clearOnTeardown(jsfunc) + cx.define_property(obj, func.__name__, jsfunc) cx.evaluate_script(obj, "func()", '', 1)