changeset 151:657afb7307eb

Added a pymonkey.get_debug_info() function and used it on test teardown to ensure that unit tests don't leak.
author Atul Varma <varmaa@toolness.com>
date Sat, 29 Aug 2009 14:06:03 -0700
parents aea82140758c
children 80463c8c7930
files src/pymonkey.cpp src/runtime.cpp src/runtime.h tests/test_pymonkey.py
diffstat 4 files changed, 46 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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}
 };
 
--- 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 *
--- 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
--- 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, '<string>', 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()', '<string>', 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, '<string>', 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, '<string>', 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()", '<string>', 1)