From 324b87e77bc654f071696a181de2df98da1cf3e8 Mon Sep 17 00:00:00 2001 From: azu Date: Sat, 22 Mar 2014 20:16:21 +0900 Subject: [PATCH] fix(error): add domain error handling --- example/async-code.js | 5 +++ example/example.js | 5 --- example/string.js | 2 + lib/ast-generator/mixin-assert.js | 24 +++++++++-- lib/cli/exec.js | 15 +++---- lib/count-method.js | 8 +++- lib/power-doctest.js | 67 ++++++++++--------------------- 7 files changed, 63 insertions(+), 63 deletions(-) create mode 100644 example/async-code.js delete mode 100644 example/example.js create mode 100644 example/string.js diff --git a/example/async-code.js b/example/async-code.js new file mode 100644 index 0000000..0e71232 --- /dev/null +++ b/example/async-code.js @@ -0,0 +1,5 @@ +"use strict"; +var a = "string"; +setTimeout(function () { + a;// => "ss"; +}, 1); diff --git a/example/example.js b/example/example.js deleted file mode 100644 index 4b040e5..0000000 --- a/example/example.js +++ /dev/null @@ -1,5 +0,0 @@ -function isNotUndefined(node) { - return typeof node === "undefined"; -} -var result = [1, 2]; -result.toString(); // > "1,2" diff --git a/example/string.js b/example/string.js new file mode 100644 index 0000000..72d4185 --- /dev/null +++ b/example/string.js @@ -0,0 +1,2 @@ +var result = [1, 2]; +result.toString(); // > "1,2" diff --git a/lib/ast-generator/mixin-assert.js b/lib/ast-generator/mixin-assert.js index 6d9fa38..c403a16 100644 --- a/lib/ast-generator/mixin-assert.js +++ b/lib/ast-generator/mixin-assert.js @@ -89,8 +89,16 @@ function mixinGenerator(node, commentExpression) { "expression": { "type": "CallExpression", "callee": { - "type": "Identifier", - "name": "_docDeepEqual" + "type": "MemberExpression", + "computed": false, + "object": { + "type": "Identifier", + "name": "assert" + }, + "property": { + "type": "Identifier", + "name": "deepEqual" + } }, "arguments": [ { // actual @@ -114,8 +122,16 @@ function mixinGenerator(node, commentExpression) { "expression": { "type": "CallExpression", "callee": { - "type": "Identifier", - "name": "_docAssert" + "type": "MemberExpression", + "computed": false, + "object": { + "type": "Identifier", + "name": "assert" + }, + "property": { + "type": "Identifier", + "name": "ok" + } }, "arguments": [ { diff --git a/lib/cli/exec.js b/lib/cli/exec.js index 4de6e96..18f446c 100644 --- a/lib/cli/exec.js +++ b/lib/cli/exec.js @@ -3,13 +3,14 @@ var path = require("path"); var docPower = require("../power-doctest"); module.exports = function (argv, filePath) { var fileData = fs.readFileSync(filePath, "utf-8"); - var results = docPower.runDocTest({ - fileData: fileData, - filePath: filePath - }, {isDebug: argv.debug}); - docPower.printTestResult(results); - if (results.length > 0) { + docPower.runDocTestAsPromise(fileData, { + filePath: filePath, + isDebug: argv.debug + }).then(function (results) { + docPower.printTestResult(results); + }).catch(function (error) { + docPower.printTestResult([error]); process.exit(1); - } + }); }; diff --git a/lib/count-method.js b/lib/count-method.js index 696f3ed..38807b4 100644 --- a/lib/count-method.js +++ b/lib/count-method.js @@ -11,7 +11,13 @@ function isFunctionCall(node,functionName) { if(node.expression.type !== estraverse.Syntax.CallExpression) { return false } - return node.expression.callee.name === functionName; + var callee = node.expression.callee; + if(callee.type === estraverse.Syntax.MemberExpression) { + if(callee.object.name === functionName) { + return true; + } + } + return callee.name === functionName; } function countMethodCall(ast, functionName) { var count = 0; diff --git a/lib/power-doctest.js b/lib/power-doctest.js index 9752fd8..9f67915 100644 --- a/lib/power-doctest.js +++ b/lib/power-doctest.js @@ -15,9 +15,6 @@ var astUtil = { token.type === 'LineBreak' || token.type === 'Indent'); }, - isWhiteSpace: function isWhiteSpace(node) { - return node.type === "WhiteSpace"; - }, isSemicolon: function isSemicolon(node) { return node.type === "Punctuator" && node.value === ";"; }, @@ -296,49 +293,15 @@ function powerizeCode(source, options) { var espower = require('espower'); var reCode = convertCode(source, options); var jsAst = esprima.parse(reCode, {loc: true, range: true}); - var assertCount = require("./count-method").countMethodCall(jsAst, "_docAssert"); + var assertCount = require("./count-method").countMethodCall(jsAst, "assert"); var espowerOptions = { source: reCode }; var modifiedAst = espower(jsAst, espowerOptions); var generated = escodegen.generate(modifiedAst); - return {context: context, generated: generated, assertCount: assertCount}; + return {context: context, generated: generated, assertCount: assertCount / 2}; } -function runDocTest(source, options) { - eventEmitter.on("parse-error", function (node, message) { - if (node instanceof Error) { - console.error(node.message); - } else if (typeof node === "object") { - var logPath = [source.filePath, node.loc.start.line, node.loc.start.column].join(":"); - console.error(logPath + "\n" + message); - } else { - console.error(node); - } - }); - options = getOptions(options); - var __ret = powerizeCode(source, options); - var context = __ret.context; - var generated = __ret.generated; - var resultError = []; - - if (options.isDebug) { - console.info("====== Generated Code ==========\n", generated, "\n====== /Generated Code =========="); - } - try { - require("vm").runInNewContext(generated, context); - } catch (error) { - // When unexpected error - if (error.name !== "AssertionError") { - throw error; - } - var filteredError = filterPowerAssertMessage(error); - filteredError.filePath = source.filePath; - resultError.push(filteredError); - } - eventEmitter.removeAllListeners("parse-error"); - return resultError; -} function runDocTestAsPromise(source, options) { eventEmitter.on("parse-error", function (node, message) { if (node instanceof Error) { @@ -358,6 +321,8 @@ function runDocTestAsPromise(source, options) { if (options.isDebug) { console.info("====== Generated Code ==========\n", generated, "\n====== /Generated Code =========="); } + var domain = require('domain'); + var vmDoamin = domain.create(); var promise = new Promise(function (resolve, reject) { var calledCount = 0; @@ -368,16 +333,27 @@ function runDocTestAsPromise(source, options) { } } - var assert = require("assert"); - context._docAssert = function () { - assert.apply(null, arguments); + var assertOK = context.assert.ok; + var deepEqual = context.assert.deepEqual; + context.assert.ok = function () { + assertOK.apply(context.assert, arguments); assertCallback(); }; - context._docDeepEqual = function () { - assert.deepEqual.apply(null, arguments); + context.assert.deepEqual = function () { + deepEqual.apply(context.assert, arguments); assertCallback(); }; - require("vm").runInNewContext(generated, context); + vmDoamin.on('error', function (error) { + if (error.name !== "AssertionError") { + return reject(error); + } + var filteredError = filterPowerAssertMessage(error); + filteredError.filePath = options.filePath; + reject(filteredError); + }); + vmDoamin.run(function () { + require("vm").runInNewContext(generated, context); + }); if (assertCount === 0) { return resolve(0); } @@ -436,7 +412,6 @@ function insertAssertModule(ast) { // options exports.convertCode = convertCode; exports.convertFromCodeToTree = convertFromCodeToTree; -exports.runDocTest = runDocTest; exports.runDocTestAsPromise = runDocTestAsPromise; exports.printTestResult = printTestResult; exports.insertAssertModule = insertAssertModule; \ No newline at end of file