[Checkins] SVN: Sandbox/J1m/customdoctests/src/zc/customdoctests/js.py Lots of hacks:

Jim Fulton jim at zope.com
Wed Mar 2 16:50:51 EST 2011


Log message for revision 120705:
  Lots of hacks:
  
  - Provide a Python wrapper for the JS context manager that provides
    lots of conveniences.
  
  - Provide some better error handling to work around some
    python-spidermonkey error handling issues.
  

Changed:
  U   Sandbox/J1m/customdoctests/src/zc/customdoctests/js.py

-=-
Modified: Sandbox/J1m/customdoctests/src/zc/customdoctests/js.py
===================================================================
--- Sandbox/J1m/customdoctests/src/zc/customdoctests/js.py	2011-03-02 21:48:43 UTC (rev 120704)
+++ Sandbox/J1m/customdoctests/src/zc/customdoctests/js.py	2011-03-02 21:50:50 UTC (rev 120705)
@@ -13,6 +13,7 @@
 ##############################################################################
 
 import doctest
+import os
 import re
 import spidermonkey
 import sys
@@ -20,11 +21,11 @@
 
 run_time = None
 
-def transform(s):
+def transform(s, f='JS'):
     if s[-1] == '\n':
-        return (r'JS(r"""%s"""+"\n")' % s) + '\n'
+        return (r'%s(r"""%s"""+"\n")' % (f, s)) + '\n'
     else:
-        return r'JS(r"""%s""")' % s
+        return r'%s(r"""%s""")' % (f, s)
 
 parser = zc.customdoctests.DocTestParser(
     ps1='js>', comment_prefix='//', transform=transform)
@@ -33,36 +34,88 @@
 # the fron of the executed code.
 eq_parser = zc.customdoctests.DocTestParser(
     ps1='js!', comment_prefix='//',
-    transform=lambda s: transform('var _ = ' + s))
+    transform=lambda s: transform(s, 'JS_'))
 
-def setUp(test_or_self):
-    globs = getattr(test_or_self, 'globs', test_or_self.__dict__)
+class JavaScriptError(Exception):
 
+    def __str__(self):
+        try:
+            return "%s\nJS Traceback:%s" % (
+                self.args[0].message,
+                '\n'.join(reversed(self.args[0].stack.split('\n')))
+                )
+        except:
+            return str(self.args[0])
+
+
+class ContextConvenience(object):
+
+    def __init__(self, context):
+        object.__setattr__(self, '_context', context)
+
+    def __getattr__(self, name):
+        return self._context.execute(name)
+
+    def __setattr__(self, name, v):
+        self._context.add_global(name, v)
+
+    def __call__(self, src):
+        self._context.execute(load_template % src)
+        if self.spidermonkey_error is not None:
+            raise JavaScriptError(self.spidermonkey_error)
+
+def setUp(test_or_self=None):
     global run_time
     if run_time is None:
         run_time = spidermonkey.Runtime()
-
     cx = run_time.new_context()
-    globs['JS'] = JS = cx.execute
-    globs['add_js_global'] = cx.add_global
+    JS = cx.execute
 
+    js = ContextConvenience(cx)
+
+    if test_or_self is not None:
+        globs = getattr(test_or_self, 'globs', test_or_self.__dict__)
+        globs['JS'] = JS
+        globs['JS_'] = js
+        globs['add_js_global'] = cx.add_global
+
+    def load_(name):
+        if name.startswith('file://'):
+            name = name[7:]
+        return JS(load_template % open(name).read(), name)
+
     # Rhino & spidermonkey/js compatability functions
-    cx.add_global('load_',
-                  lambda name: JS(load_template % open(name).read(), name))
+    cx.add_global('python', dict(
+        os = os,
+        open = open,
+        ))
+    cx.add_global('load_', load_)
     JS(load_js)
     cx.add_global('print',
-                  lambda *s: sys.stdout.write('%s\n' % ' '.join(map(str, s)))
+                  lambda *s: sys.stdout.write(('%s\n' % ' '.join(map(unicode, s))).encode('utf-8'))
                   )
     cx.add_global('printe',
-                  lambda *s: sys.stderr.write('%s\n' % ' '.join(map(str, s)))
+                  lambda *s: sys.stderr.write('%s\n' % ' '.join(map(unicode, s)))
                   )
+    return js
 
-load_template = "try { %s } catch (e) {spidermonkey_error = e;}"
 
+load_template = ("spidermonkey_error = undefined; "
+                 "try { %s } catch (e) {spidermonkey_error = e;}")
+
 load_js = """
 function load(p) {
-    spidermonkey_error = undefined;
-    load_(p);
-    if (spidermonkey_error) throw spidermonkey_error;
+    if (p.slice(0, 7) == 'file://') {
+        p = p.slice(7);
+    }
+    try { console.debug('loading', p); } catch (e) {}
+    if (! python.os.path.exists(p)) {
+        throw "Doesn't exist: "+p;
+    }
+    var result = load_(p);
+    if (spidermonkey_error) {
+        throw spidermonkey_error;
+    }
+    return result;
 }
 """



More information about the checkins mailing list