From 081de923bbb852d37ed85b585ddcabbbe6dbe620 Mon Sep 17 00:00:00 2001
From: Thomas Wood <thomas.wood09@imperial.ac.uk>
Date: Fri, 20 May 2016 21:27:16 +0100
Subject: [PATCH] Begin testing of jsjsref interpreter code.

---
 Makefile               |  13 +++++-
 test/helper-test262.js |  74 +++++++++++++++++++++++++++++
 test/interpreter.js    |  26 ++++++++++-
 test/mocha.opts        |   2 -
 test/parser.js         | 103 +++++++++++++----------------------------
 5 files changed, 141 insertions(+), 77 deletions(-)
 create mode 100644 test/helper-test262.js
 delete mode 100644 test/mocha.opts

diff --git a/Makefile b/Makefile
index 542f745..af11313 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,16 @@ PUB_FILES=driver.html libraries jquery-ui-1.11.4.custom jquery_scroll \
 	esprima-to-ast.js generator/tests/jsref/lineof.js navig-driver.js \
 	generator/tests/jsref/assembly.js
 
-publish: $(PUB_FILES)
+publish: generator $(PUB_FILES)
 	rsync -azR --no-p --rsh=ssh -O $^ gf:/home/groups/ajacs/htdocs/jsexplain/
 
-.PHONY: publish
+generator:
+	$(MAKE) -C generator
+
+test_init:
+	npm install
+
+test: generator
+	node_modules/.bin/mocha
+
+.PHONY: publish generator test_init test
diff --git a/test/helper-test262.js b/test/helper-test262.js
new file mode 100644
index 0000000..3fc23a1
--- /dev/null
+++ b/test/helper-test262.js
@@ -0,0 +1,74 @@
+"use strict";
+
+// Registers test cases to be run against Test262
+// To add a testcase to be tested against test262:
+//   var test262tests = require('./helper-test262.js')'
+//   test262tests.push(function testConstructorFunction(source, negativity) {});
+//
+// Tests are run in the order added to the array. If inter-module test ordering is required,
+// ensure the later test module depends on the earlier one.
+//
+// Arguments to testConstructorFunction:
+// - source: The raw test source code
+// - negativity: The @negative test header content
+// -
+
+var fs = require('mz/fs');
+var walk = require('klaw');
+var filter = require('through2-filter');
+fs.readlinkSync = require('readlink').sync; // a non-broken readlink...
+
+var testConstructors = [];
+
+function testNegativity(str) {
+  var result = /@negative[ \t]*(\S*)?[ \t]*$/m.exec(str);
+  if(result) {
+    result = result[1] || true;
+  } else {
+    result = false;
+  }
+  return result;
+}
+
+before(function(done) {
+  var test262path = fs.readlinkSync(__dirname + '/test262');
+  var tests = [];
+
+  walk(test262path)
+  .pipe(filter.obj(file => file.stats.isFile() && file.path.endsWith(".js")))
+  .on('readable', function() {
+    var item;
+    while((item = this.read())) { tests.push(item.path); }
+  })
+  .on('end', function() {
+    describe("test262", function() {
+      tests.forEach(item => {
+        describe(item, function() {
+          // Preseed test arguments with safe defaults
+          var args = {
+            source: "if // invalid syntax",
+            negative: false
+          };
+
+          var source;
+          var negative = '';
+
+          before(function(doneFile) {
+            fs.readFile(item).then(
+              data => {
+                args.source = data.toString();
+                args.negative = testNegativity(args.source);
+              }
+            ).then(doneFile);
+          });
+
+          testConstructors.forEach(constructor => constructor(args));
+        });
+      });
+    });
+
+    done();
+  });
+});
+
+module.exports = testConstructors;
diff --git a/test/interpreter.js b/test/interpreter.js
index e0b4c2c..7ff1dcc 100644
--- a/test/interpreter.js
+++ b/test/interpreter.js
@@ -4,6 +4,9 @@ var esprima = require('esprima');
 var esprimaToAST = require('../esprima-to-ast.js').esprimaToAST;
 var JsInterpreter = require('../generator/tests/jsref/assembly.js');
 
+require('./parser.js');
+var test262tests = require('./helper-test262.js');
+
 // Stub logging functions
 ['ctx_empty', 'ctx_push', 'log_event'].forEach(f => global[f] = function(){})
 
@@ -28,5 +31,24 @@ var parse_and_run_multiple = function(sources) {
   return run_multiple(programs);
 }
 
-console.dir(parse_and_run_multiple(["var x = 10", "x+1"]), {depth: 6, colors: true});
-console.dir(parse_and_run_multiple(["throw 10", "x+1"]), {depth: 6, colors: true});
+Error.stackTraceLimit = 30;
+
+test262tests.push(args => {
+  it("interprets", function() {
+    try {
+      var ast = parse(args.source);
+    } catch(e) { return; }
+
+    var result = JsInterpreter.run_javascript(ast);
+  });
+});
+
+test262tests.push(args => {
+  it.skip("executes correctly");
+  // TODO
+  // This test should be combined with the interprets test
+  // It also needs to:
+  // * Load the test262 prelude functions
+  // * Execute the test in this heap
+  // * Check the result of the testcase
+});
diff --git a/test/mocha.opts b/test/mocha.opts
deleted file mode 100644
index 2fd4eb7..0000000
--- a/test/mocha.opts
+++ /dev/null
@@ -1,2 +0,0 @@
---delay
---reporter dot
diff --git a/test/parser.js b/test/parser.js
index 1d84542..fd46fc8 100644
--- a/test/parser.js
+++ b/test/parser.js
@@ -1,29 +1,17 @@
 "use strict";
 
-var fs = require('mz/fs');
-var walk = require('klaw');
-var filter = require('through2-filter');
-fs.readlinkSync = require('readlink').sync; // a non-broken readlink...
 var assert = require('chai').assert;
 
 var esprima = require('esprima');
 var esprimaToAST = require('../esprima-to-ast.js');
 
+var test262tests = require('./helper-test262.js');
+
 /* Tests whether a given test is negative.
+ * Param: negative (boolean or string): Return value of helper-test262.testNegativity
  * Returns: a string if type of failure specified, true, or false
  */
-function testNegativity(str) {
-  var result = /@negative[ \t]*(\S*)?[ \t]*$/m.exec(str);
-  if(result) {
-    result = result[1] || true;
-  } else {
-    result = false;
-  }
-  return result;
-}
-
-function isParserNegativeTest(str) {
-  var negative = testNegativity(str);
+function isParserNegativeTest(negative) {
   if (typeof negative === 'boolean') {
     return negative;
   }
@@ -200,7 +188,7 @@ function typecheckAST(ast) {
   return typecheck("prog", ast);
 }
 
-describe("Custom testcases", function() {
+describe("EsprimaToAST", function() {
   it("Extracts function body strings", function() {
     var source =
 `function f() {
@@ -269,60 +257,33 @@ a()};`;
   });
 });
 
-var test262path = fs.readlinkSync(__dirname + '/test262');
-var tests = [];
-
-walk(test262path)
-.pipe(filter.obj(file => file.stats.isFile() && file.path.endsWith(".js")))
-.on('readable', function() {
-  var item;
-  while((item = this.read())) { tests.push(item.path); }
-})
-.on('end', function() {
-  describe("test262", function() {
-    tests.forEach(item => {
-      describe(item, function() {
-
-        var source;
-        var negative = '';
-
-        before(function(done) {
-          fs.readFile(item).then(
-            data => {
-              source = data.toString();
-              negative = isParserNegativeTest(source);
-            }
-          ).then(done);
-        });
-
-        it('parses', function() {
-          try {
-            esprima.parse(source, {loc: true, range: true});
-          } catch(e) {
-            if (!negative) {
-              throw e;
-            }
-          }
-        });
-
-        it('converts', function() {
-          try {
-            var prog = esprima.parse(source, {loc: true, range: true});
-          } catch(e) { return; }
-
-          try {
-            var ast = esprimaToAST.esprimaToAST(prog, source);
-            typecheckAST(ast);
-          } catch (e) {
-            if (e instanceof esprimaToAST.UnsupportedSyntaxError) {
-            } else {
-              throw e;
-            }
-          }
-        });
-      })
-    });
+test262tests.push(args => {
+  it('parse', function() {
+    var negative = isParserNegativeTest(args.negative);
+    try {
+      esprima.parse(args.source, {loc: true, range: true});
+    } catch(e) {
+      if (!negative) {
+        throw e;
+      }
+    }
   });
+});
 
-  run();
+test262tests.push(args => {
+  it('convert ast', function() {
+    try {
+      var prog = esprima.parse(args.source, {loc: true, range: true});
+    } catch(e) { return; }
+
+    try {
+      var ast = esprimaToAST.esprimaToAST(prog, args.source);
+      typecheckAST(ast);
+    } catch (e) {
+      if (e instanceof esprimaToAST.UnsupportedSyntaxError) {
+      } else {
+        throw e;
+      }
+    }
+  });
 });
-- 
GitLab