[pypy-svn] r19566 - in pypy/dist/pypy/translator/js: . test

ericvrp at codespeak.net ericvrp at codespeak.net
Sat Nov 5 23:41:24 CET 2005


Author: ericvrp
Date: Sat Nov  5 23:41:23 2005
New Revision: 19566

Added:
   pypy/dist/pypy/translator/js/test/browsertest.py
Modified:
   pypy/dist/pypy/translator/js/js.py
   pypy/dist/pypy/translator/js/test/runtest.py
Log:
* Added hacks to make testing the Javascript code against browsers work.

* Currently only tested with Firefox on OSX!
  Running the with the commandline executable (js) [Spidermonkey]
  is still supported by disabling use_browsertest in test/runtest.py

[for some reason firefox passes one more test than Spidermonkey]


Modified: pypy/dist/pypy/translator/js/js.py
==============================================================================
--- pypy/dist/pypy/translator/js/js.py	(original)
+++ pypy/dist/pypy/translator/js/js.py	Sat Nov  5 23:41:23 2005
@@ -131,10 +131,10 @@
         #    codewriter.append(llexterns_functions)
 
         entry_point= c.value._obj
-        graph      = self.db.obj2node[entry_point].graph
-        startblock = graph.startblock
+        self.graph = self.db.obj2node[entry_point].graph
+        startblock = self.graph.startblock
         args       = ','.join(['arguments[%d]' % i for i,v in enumerate(startblock.inputargs)])
-        self.wrappertemplate = "load('%s'); print(%s%s(%%s))" % (self.filename, pypy_prefix, graph.name)
+        self.wrappertemplate = "load('%s'); print(%s%s(%%s))" % (self.filename, pypy_prefix, self.graph.name)
 
         #codewriter.newline()
         #codewriter.comment("Wrapper code for the Javascript CLI", 0)

Added: pypy/dist/pypy/translator/js/test/browsertest.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/test/browsertest.py	Sat Nov  5 23:41:23 2005
@@ -0,0 +1,156 @@
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+import py
+from os   import system
+from cgi  import parse_qs
+from time import sleep
+from pypy.translator.js.log import log
+log = log.browsertest
+
+
+class config:
+
+    #XXX remove this hardcoding (currently OSX only)
+    browser = ('/Applications/Firefox.app/Contents/MacOS/', 'firefox-bin')
+
+    #XXX Safari does not accept a http://... format, it still thinks it's a file://...
+    #browser = ('/Applications/Safari.app/Contents/MacOS/', 'Safari')
+
+    http_port = 10001
+
+    html_page = """<html>
+<head>
+<title>%(jsfilename)s</title>
+<script type="text/javascript">
+%(jscode)s
+</script>
+<script type="text/javascript">
+    function runTest() {
+        var result = undefined;
+        try {
+            result = %(jstestcase)s;
+        } catch (e) {
+            //result = 'Exception("' + e.toString() + '")'
+            result = 'undefined'
+        }
+        var resultform = document.forms['resultform'];
+        resultform.result.value = result;
+        resultform.submit();
+    };
+</script>
+</head>
+<body onload="runTest()">
+    %(jsfilename)s
+    <form method="post" name="resultform" id="resultform">
+        <input name="result" type="hidden" value="UNKNOWN" />
+    </form>
+</body>
+</html>"""
+
+    #issue a GET after one second
+    #note: 0 second did not work probably because the GET would
+    #      be received before the refresh socket was closed (or so)
+    refresh_page = """<html>
+<head>
+<meta http-equiv="refresh" content="0">
+</head>
+<body>
+refresh after %(jsfilename)s
+</body>
+</html>"""
+
+
+class TestCase(object):
+    def __init__(self, jsfilename, jstestcase):
+        self.jsfilename = jsfilename
+        self.jstestcase = jstestcase
+        self.result     = None
+
+
+class TestHandler(BaseHTTPRequestHandler):
+    """The HTTP handler class that provides the tests and handles results"""
+
+    def do_GET(self):
+        global do_status
+        log('do_GET path', self.path)
+        if self.path != "/":
+            self.send_error(404, "File not found")
+            return
+        jstestcase = jstest.jstestcase
+        jsfilename = str(jstest.jsfilename)
+        jscode     = open(jsfilename).read()
+        html_page  = config.html_page % locals()
+        log('do_GET sends', jsfilename)
+        self.serve_data('text/html', html_page)
+        do_status = 'do_GET'
+
+    def do_POST(self):
+        global do_status
+        log('do_POST path', self.path)
+        if self.path != "/":
+            self.send_error(404, "File not found")
+            return
+        form = parse_qs(self.rfile.read(int(self.headers['content-length'])))
+        jstest.result = form['result'][0]
+        log('do_POST received result', jstest.result)
+
+        #we force a page refresh here because of two reason:
+        # 1. we don't have the next testcase ready yet
+        # 2. browser should ask again when we do have a test
+        jsfilename = jstest.jsfilename
+        refresh_page = config.refresh_page % locals()
+        self.serve_data('text/html', refresh_page)
+        log('do_POST sends refresh page')
+        do_status = 'do_POST'
+
+    def serve_data(self, content_type, data):
+        self.send_response(200)
+        self.send_header("Content-type", content_type)
+        self.send_header("Content-length", len(data))
+        self.end_headers()
+        self.wfile.write(data)
+
+
+class BrowserTest(object):
+    """The browser driver"""
+
+    def start_server(self, port):
+        log('BrowserTest.start_server')
+        server_address = ('', port)
+        self.httpd = HTTPServer(server_address, TestHandler)
+
+    def get_result(self):
+        global do_status
+        do_status = None
+        while do_status != 'do_GET':
+            log('waiting for do_GET')
+            self.httpd.handle_request()
+        while do_status != 'do_POST':
+            log('waiting for do_POST')
+            self.httpd.handle_request()
+        while not jstest.result:
+            log('waiting for result')
+            sleep(1.0)
+        return jstest.result
+
+
+def jstest(jsfilename, jstestcase):
+    global driver, jstest
+    jstest = TestCase(jsfilename, jstestcase)
+
+    try:
+        driver
+    except:
+        browser_path, browser_exe = config.browser
+        cmd = 'killall %(browser_exe)s 2>&1 2>/dev/null' % locals()
+        log(cmd)
+        system(cmd)
+
+        driver = BrowserTest()
+        driver.start_server(config.http_port)
+
+        cmd = '%s%s http://localhost:%d &' % (browser_path, browser_exe, config.http_port)
+        log(cmd)
+        system(cmd)
+
+    result = driver.get_result()
+    return result

Modified: pypy/dist/pypy/translator/js/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/js/test/runtest.py	Sat Nov  5 23:41:23 2005
@@ -1,8 +1,10 @@
 import py, os
 from pypy.translator.translator import Translator
 from pypy.translator.js.js import JS
+from pypy.translator.js.test.browsertest import jstest
 from pypy.translator.js.log import log
 log = log.runtest
+use_browsertest = True
 
 
 def _CLI_is_on_path():
@@ -12,9 +14,10 @@
         return False
     return True
 
+
 class compile_function(object):
     def __init__(self, function, annotation, view=False):
-        if not _CLI_is_on_path():
+        if not use_browsertest and not _CLI_is_on_path():
             py.test.skip('Javascript CLI (js) not found')
 
         t = Translator(function)
@@ -30,10 +33,15 @@
 
     def __call__(self, *kwds):
         args = ', '.join([str(kw).lower() for kw in kwds]) #lowerstr for (py)False->(js)false, etc.
-        wrappercode = self.js.wrappertemplate % args
-        cmd = 'echo "%s" | js 2>&1' % wrappercode
-        log(cmd)
-        s   = os.popen(cmd).read().strip()
+
+        if use_browsertest:
+            jstestcase = '%s(%s)' % (self.js.graph.name, args)
+            s = jstest(self.js.filename, jstestcase)
+        else:
+            wrappercode = self.js.wrappertemplate % args
+            cmd = 'echo "%s" | js 2>&1' % wrappercode
+            log(cmd)
+            s   = os.popen(cmd).read().strip()
         if s == 'false':
             res = False
         elif s == 'true':



More information about the Pypy-commit mailing list