Comparing version 0.4.1 to 0.6.0
{ | ||
"name": "espower", | ||
"version": "0.4.1", | ||
"version": "0.6.0", | ||
"main": "lib/espower.js", | ||
@@ -16,6 +16,6 @@ "ignore": [ | ||
"dependencies": { | ||
"esprima": "~1.0.4", | ||
"estraverse": "~1.5.0" | ||
}, | ||
"devDependencies": { | ||
"esprima": "~1.0.4", | ||
"escodegen": "1.3.0", | ||
@@ -22,0 +22,0 @@ "mocha": "~1.18.2", |
module.exports = function(grunt) { | ||
var pkg = grunt.file.readJSON('package.json'); | ||
require('load-grunt-tasks')(grunt); | ||
require('jit-grunt')(grunt); | ||
@@ -6,0 +6,0 @@ grunt.initConfig({ |
@@ -25,9 +25,9 @@ /** | ||
if (typeof define === 'function' && define.amd) { | ||
define(['estraverse'], factory); | ||
define(['estraverse', 'esprima'], factory); | ||
} else if (typeof exports === 'object') { | ||
module.exports = factory(require('estraverse')); | ||
module.exports = factory(require('estraverse'), require('esprima')); | ||
} else { | ||
root.espower = factory(root.estraverse); | ||
root.espower = factory(root.estraverse, root.esprima); | ||
} | ||
}(this, function (estraverse) { | ||
}(this, function (estraverse, esprima) { | ||
'use strict'; | ||
@@ -38,94 +38,19 @@ | ||
deepCopy, | ||
handlers = { | ||
Identifier: function (instrumentor, node) { | ||
return instrumentor.captureNode('ident', node, instrumentor.locationOf(node)); | ||
}, | ||
supportedNodeTypes = [ | ||
syntax.Identifier, | ||
syntax.MemberExpression, | ||
syntax.CallExpression, | ||
syntax.UnaryExpression, | ||
syntax.BinaryExpression, | ||
syntax.LogicalExpression, | ||
syntax.AssignmentExpression, | ||
syntax.ObjectExpression, | ||
syntax.NewExpression, | ||
syntax.ArrayExpression, | ||
syntax.ConditionalExpression, | ||
syntax.UpdateExpression, | ||
syntax.Property | ||
]; | ||
MemberExpression: function (instrumentor, node) { | ||
var propLocation = instrumentor.propertyLocationOf(node); | ||
node.object = instrumentor.captureRecursively(node.object); | ||
if (node.computed) { | ||
node.property = instrumentor.captureRecursively(node.property); | ||
} | ||
return instrumentor.captureNode('ident', node, propLocation); | ||
}, | ||
CallExpression: function (instrumentor, node) { | ||
node.arguments = node.arguments.map(function (arg) { | ||
return instrumentor.captureRecursively(arg); | ||
}); | ||
if (node.callee.type === syntax.MemberExpression) { | ||
node.callee.object = instrumentor.captureRecursively(node.callee.object); | ||
if (node.callee.computed) { | ||
node.callee.property = instrumentor.captureRecursively(node.callee.property); | ||
} | ||
return instrumentor.captureNode('funcall', node, instrumentor.propertyLocationOf(node.callee)); | ||
} else { | ||
return instrumentor.captureNode('funcall', node, instrumentor.locationOf(node)); | ||
} | ||
}, | ||
UnaryExpression: function (instrumentor, node) { | ||
if ((node.operator === 'typeof' || node.operator === 'delete') && node.argument.type === syntax.Identifier) { | ||
// 'typeof Identifier' or 'delete Identifier' is not instrumented | ||
} else { | ||
node.argument = instrumentor.captureRecursively(node.argument); | ||
} | ||
return instrumentor.captureNode('unary', node, instrumentor.locationOf(node)); | ||
}, | ||
BinaryExpression: function (instrumentor, node) { | ||
return instrumentor.captureExpressionWithInfixOperator('binary', node); | ||
}, | ||
LogicalExpression: function (instrumentor, node) { | ||
return instrumentor.captureExpressionWithInfixOperator('logical', node); | ||
}, | ||
AssignmentExpression: function (instrumentor, node) { | ||
return instrumentor.captureExpressionWithInfixOperator('assignment', node); | ||
}, | ||
ObjectExpression: function (instrumentor, node) { | ||
node.properties.forEach(function (prop) { | ||
if (prop.type === syntax.Property && prop.kind === 'init') { | ||
prop.value = instrumentor.captureRecursively(prop.value); | ||
} | ||
}); | ||
return node; | ||
}, | ||
NewExpression: function (instrumentor, node) { | ||
node.arguments = node.arguments.map(function (arg) { | ||
return instrumentor.captureRecursively(arg); | ||
}); | ||
return instrumentor.captureNode('new', node, instrumentor.locationOf(node)); | ||
}, | ||
ArrayExpression: function (instrumentor, node) { | ||
node.elements = node.elements.map(function (elem) { | ||
return instrumentor.captureRecursively(elem); | ||
}); | ||
return node; | ||
}, | ||
ConditionalExpression: function (instrumentor, node) { | ||
node.test = instrumentor.captureRecursively(node.test); | ||
node.consequent = instrumentor.captureRecursively(node.consequent); | ||
node.alternate = instrumentor.captureRecursively(node.alternate); | ||
return node; | ||
}, | ||
UpdateExpression: function (instrumentor, node) { | ||
return instrumentor.captureNode('update', node, instrumentor.locationOf(node)); | ||
} | ||
//// unsupported expressions | ||
// FunctionExpression | ||
// RegularExpression | ||
// SequenceExpression | ||
// ThisExpression | ||
}; | ||
function defaultOptions () { | ||
@@ -174,25 +99,106 @@ return { | ||
var that = this, | ||
capturingStartPath, | ||
capturedMetaTree, | ||
capturedTokens, | ||
skipping = false, | ||
instrumentor, | ||
result = (this.options.destructive) ? ast : deepCopy(ast); | ||
this.tokens = result.tokens; | ||
estraverse.replace(result, { | ||
enter: function (currentNode, parentNode) { | ||
var numTargetArgs, indexOfCurrentArg; | ||
if (!parentNode || parentNode.type !== syntax.CallExpression) { | ||
return undefined; | ||
var controller = this, | ||
path = controller.path(), | ||
currentPath = path ? path[path.length - 1] : null, | ||
numTargetArgs, indexOfCurrentArg; | ||
//console.log('enter currentNode:' + currentNode.type + ' parentNode: ' + parentNode.type + ' path: ' + path); | ||
if (capturingStartPath) { | ||
if ((!isSupportedNodeType(currentNode)) || | ||
(isLeftHandSideOfAssignment(parentNode, currentPath)) || | ||
(isObjectLiteralKey(parentNode, currentPath)) || | ||
(isUpdateExpression(parentNode)) || | ||
(isCallExpressionWithNonComputedMemberExpression(currentNode, parentNode, currentPath)) || | ||
(isTypeOfOrDeleteUnaryExpression(currentNode, parentNode, currentPath))) { | ||
skipping = true; | ||
return estraverse.VisitorOption.Skip; | ||
} | ||
} else { | ||
if (!parentNode || parentNode.type !== syntax.CallExpression) { | ||
return undefined; | ||
} | ||
if (parentNode.callee === currentNode) { | ||
return undefined; | ||
} | ||
if (!isSupportedNodeType(currentNode)) { | ||
return undefined; | ||
} | ||
numTargetArgs = numberOfTargetArguments(parentNode.callee, that.options); | ||
if (numTargetArgs === 0) { | ||
return undefined; | ||
} | ||
indexOfCurrentArg = parentNode.arguments.indexOf(currentNode); | ||
if (indexOfCurrentArg < numTargetArgs) { | ||
capturingStartPath = path; | ||
capturedMetaTree = metaAst(currentNode); | ||
capturedTokens = metaAst(subTokens(result.tokens, currentNode.loc.start, currentNode.loc.end)); | ||
instrumentor = that.instrumentArgument(parentNode, currentNode); | ||
return undefined; | ||
} | ||
} | ||
if (parentNode.callee === currentNode) { | ||
return undefined; | ||
}, | ||
leave: function (currentNode, parentNode) { | ||
var controller = this, | ||
path = controller.path(), | ||
modifiedTree, | ||
subpath, | ||
instrumentedTree; | ||
//console.log('leave ' + currentNode.type + ' path: ' + path); | ||
if (!capturingStartPath) { | ||
return undefined; | ||
} | ||
if (!isSupportedNodeType(currentNode)) { | ||
if (skipping) { | ||
skipping = false; | ||
return undefined; | ||
} | ||
numTargetArgs = numberOfTargetArguments(parentNode.callee, that.options); | ||
if (numTargetArgs === 0) { | ||
if (parentNode.callee === currentNode) { | ||
return undefined; | ||
} | ||
indexOfCurrentArg = parentNode.arguments.indexOf(currentNode); | ||
if (indexOfCurrentArg < numTargetArgs) { | ||
return that.instrumentArgument(parentNode, currentNode); | ||
subpath = path.slice(capturingStartPath.length); | ||
//console.log('leave ' + currentNode.type + ' path: ' + path + ' ' + currentNode.name); | ||
switch(currentNode.type) { | ||
case syntax.Identifier: | ||
case syntax.MemberExpression: | ||
case syntax.CallExpression: | ||
case syntax.UnaryExpression: | ||
case syntax.BinaryExpression: | ||
case syntax.LogicalExpression: | ||
case syntax.AssignmentExpression: | ||
case syntax.UpdateExpression: | ||
case syntax.NewExpression: | ||
modifiedTree = instrumentor.captureNode(currentNode, subpath); | ||
break; | ||
case syntax.ObjectExpression: | ||
case syntax.ArrayExpression: | ||
case syntax.ConditionalExpression: | ||
modifiedTree = currentNode; | ||
break; | ||
default: | ||
break; | ||
} | ||
return undefined; | ||
if (modifiedTree && path && isLeavingAssertion(capturingStartPath, path)) { | ||
instrumentedTree = instrumentor.captureAssertion(modifiedTree, capturedMetaTree, capturedTokens); | ||
capturingStartPath = null; | ||
capturedMetaTree = null; | ||
capturedTokens = null; | ||
return instrumentedTree; | ||
} | ||
return modifiedTree; | ||
} | ||
@@ -204,4 +210,3 @@ }); | ||
SourceInstrumentor.prototype.instrumentArgument = function (callExpression, argumentNode) { | ||
var instrumentor = new LineInstrumentor(this.retrieveLineFor(callExpression), this.options, this.tokens); | ||
return instrumentor.instrument(argumentNode); | ||
return new LineInstrumentor(this.retrieveLineFor(callExpression), this.options, this.tokens); | ||
}; | ||
@@ -224,166 +229,50 @@ | ||
LineInstrumentor.prototype.instrument = function (node) { | ||
ensureAstPrerequisites(node, this.options); | ||
var loc = this.locationOf(node), | ||
modifiedTree = this.captureRecursively(node); | ||
return this.captureAssertion(modifiedTree, loc); | ||
}; | ||
LineInstrumentor.prototype.captureRecursively = function (node) { | ||
if (isSupportedNodeType (node)) { | ||
return nodeHandlerFor(node.type).call(null, this, node); | ||
} else { | ||
return node; | ||
LineInstrumentor.prototype.captureAssertion = function (node, metaAstTree, metaAstTokens) { | ||
var n = newNodeWithLocationCopyOf(node), | ||
namedArgs = n({ | ||
type: syntax.ObjectExpression, | ||
properties: [] | ||
}); | ||
if (metaAstTree) { | ||
namedArgs.properties.push(n({ | ||
type: syntax.Property, | ||
key: n({ | ||
type: syntax.Identifier, | ||
name: 'tree' | ||
}), | ||
value: metaAstTree, | ||
kind: 'init' | ||
})); | ||
} | ||
}; | ||
LineInstrumentor.prototype.captureExpressionWithInfixOperator = function (kind, expression) { | ||
// BK: need to detect operator location before left/right instrumentation | ||
var infixOperatorLocation = this.infixOperatorLocationOf(expression); | ||
if (kind !== 'assignment') { | ||
// Do not instrument left due to 'Invalid left-hand side in assignment' | ||
expression.left = this.captureRecursively(expression.left); | ||
if (metaAstTokens) { | ||
namedArgs.properties.push(n({ | ||
type: syntax.Property, | ||
key: n({ | ||
type: syntax.Identifier, | ||
name: 'tokens' | ||
}), | ||
value: metaAstTokens, | ||
kind: 'init' | ||
})); | ||
} | ||
expression.right = this.captureRecursively(expression.right); | ||
return this.captureNode(kind, expression, infixOperatorLocation); | ||
}; | ||
// calculate property location of MemberExpression. | ||
LineInstrumentor.prototype.propertyLocationOf = function (memberExpression) { | ||
var n = newNodeWithLocationCopyOf(memberExpression), | ||
newLocation, | ||
prop = memberExpression.property, | ||
foundIndex, | ||
propLocation; | ||
if (typeof prop.loc !== 'undefined') { | ||
propLocation = this.locationOf(prop); | ||
if (memberExpression.computed) { | ||
this.adjustPropertyLocationOfComputedMemberExpression(memberExpression, propLocation); | ||
} | ||
return propLocation; | ||
} else if (typeof memberExpression.loc !== 'undefined') { // non-computed MemberExpression under CoffeeScriptRedux | ||
foundIndex = this.line.indexOf(prop.name, memberExpression.loc.start.column); | ||
if (foundIndex === -1) { | ||
throw new Error('Cannot detect property location: ' + prop.name + ' line: ' + this.line + ' col: ' + memberExpression.loc.start.column); | ||
} | ||
newLocation = n({}); | ||
newLocation.loc.start = { | ||
line: memberExpression.loc.start.line, | ||
column: foundIndex | ||
}; | ||
return this.locationOf(newLocation); | ||
} else { | ||
throw new Error('Cannot detect property location: ' + prop.name + ' line: ' + this.line); | ||
} | ||
}; | ||
LineInstrumentor.prototype.adjustPropertyLocationOfComputedMemberExpression = function (memberExpression, propLocation) { | ||
var startObjectLiteralNode = propLocation.properties[0].value, | ||
columnObjectLiteralNode = startObjectLiteralNode.properties[1].value, | ||
token, | ||
substr, | ||
foundIndex; | ||
if (this.tokens) { | ||
token = this.findLeftBracketTokenOf(memberExpression); | ||
} | ||
if (token) { | ||
// console.log('left bracket: ' + token.loc.start.column); | ||
columnObjectLiteralNode.value = token.loc.start.column; | ||
} else { | ||
substr = this.line.substring(memberExpression.loc.start.column, memberExpression.property.loc.start.column); | ||
foundIndex = substr.lastIndexOf('['); | ||
if (foundIndex !== -1) { | ||
columnObjectLiteralNode.value = memberExpression.loc.start.column + foundIndex; | ||
} else { | ||
columnObjectLiteralNode.value -= 1; | ||
} | ||
} | ||
}; | ||
// calculate location of infix operator for BinaryExpression, AssignmentExpression and LogicalExpression. | ||
LineInstrumentor.prototype.infixOperatorLocationOf = function (expression) { | ||
var n = newNodeWithLocationCopyOf(expression), | ||
newLocation, | ||
endOfLeftColumn, | ||
operatorStartColumn, | ||
operatorIndex, | ||
token; | ||
if (expression.left.loc.end && expression.left.loc.end.column) { // esprima | ||
endOfLeftColumn = expression.left.loc.end.column; | ||
} else if (expression.left.range) { // CoffeeScriptRedux | ||
endOfLeftColumn = expression.left.loc.start.column + (expression.left.range[1] - expression.left.range[0]); | ||
} else { | ||
throw new Error('Cannot detect operator location: ' + expression.operator + ' line: ' + this.line); | ||
} | ||
operatorStartColumn = endOfLeftColumn + 1; | ||
if (this.tokens) { // esprima | ||
token = this.findOperatorTokenOf(expression); | ||
if (token) { | ||
// console.log('TOKEN INDEX: ' + token.loc.start.column); | ||
operatorStartColumn = token.loc.start.column; | ||
} | ||
} else if (this.line) { | ||
operatorIndex = this.line.indexOf(expression.operator, endOfLeftColumn); | ||
if (operatorIndex !== -1) { | ||
operatorStartColumn = operatorIndex; | ||
} | ||
} | ||
newLocation = n({}); | ||
newLocation.loc.start = { | ||
line: expression.left.loc.start.line, | ||
column: operatorStartColumn | ||
}; | ||
return this.locationOf(newLocation); | ||
}; | ||
LineInstrumentor.prototype.findLeftBracketTokenOf = function (expression) { | ||
var tokens = this.tokens, | ||
fromColumn = expression.property.loc.start.column, | ||
fromLine = expression.loc.start.line, | ||
toLine = expression.property.loc.start.line; | ||
return searchToken(tokens, fromLine, toLine, function (token, index) { | ||
var prevToken; | ||
if (token.loc.start.column === fromColumn) { | ||
prevToken = tokens[index - 1]; | ||
if (prevToken.type === 'Punctuator' && prevToken.value === '[') { | ||
return prevToken; | ||
} | ||
} | ||
return undefined; | ||
}); | ||
}; | ||
LineInstrumentor.prototype.findOperatorTokenOf = function (expression) { | ||
var tokens = this.tokens, | ||
fromColumn = expression.left.loc.end.column, | ||
toColumn = expression.right.loc.start.column, | ||
fromLine = expression.left.loc.end.line, | ||
toLine = expression.right.loc.start.line; | ||
return searchToken(tokens, fromLine, toLine, function (token, index) { | ||
if (fromColumn < token.loc.start.column && | ||
token.loc.end.column < toColumn && | ||
token.type === 'Punctuator' && | ||
token.value === expression.operator) { | ||
return token; | ||
} | ||
return undefined; | ||
}); | ||
}; | ||
LineInstrumentor.prototype.captureAssertion = function (node, location) { | ||
var n = newNodeWithLocationCopyOf(node), | ||
exprArgs = [node, location]; | ||
if (this.line) { | ||
exprArgs.push(n({ | ||
type: syntax.Literal, | ||
value: this.line | ||
namedArgs.properties.push(n({ | ||
type: syntax.Property, | ||
key: n({ | ||
type: syntax.Identifier, | ||
name: 'content' | ||
}), | ||
value: n({ | ||
type: syntax.Literal, | ||
value: this.line | ||
}), | ||
kind: 'init' | ||
})); | ||
} | ||
if (this.options.path) { | ||
location.properties.push(n({ | ||
namedArgs.properties.push(n({ | ||
type: syntax.Property, | ||
key: n({ | ||
type: syntax.Identifier, | ||
name: 'path' | ||
name: 'filepath' | ||
}), | ||
@@ -411,7 +300,7 @@ value: n({ | ||
}), | ||
arguments: exprArgs | ||
arguments: [node].concat(namedArgs) | ||
}); | ||
}; | ||
LineInstrumentor.prototype.captureNode = function (kind, target, location) { | ||
LineInstrumentor.prototype.captureNode = function (target, subpath) { | ||
var n = newNodeWithLocationCopyOf(target); | ||
@@ -436,50 +325,3 @@ return n({ | ||
type: syntax.Literal, | ||
value: kind | ||
}), | ||
location | ||
] | ||
}); | ||
}; | ||
LineInstrumentor.prototype.locationOf = function (node) { | ||
var n = newNodeWithLocationCopyOf(node); | ||
return n({ | ||
type: syntax.ObjectExpression, | ||
properties: [ | ||
n({ | ||
type: syntax.Property, | ||
key: n({ | ||
type: syntax.Identifier, | ||
name: 'start' | ||
}), | ||
value: n({ | ||
type: syntax.ObjectExpression, | ||
properties: [ | ||
n({ | ||
type: syntax.Property, | ||
key: n({ | ||
type: syntax.Identifier, | ||
name: 'line' | ||
}), | ||
value: n({ | ||
type: syntax.Literal, | ||
value: node.loc.start.line | ||
}), | ||
kind: 'init' | ||
}), | ||
n({ | ||
type: syntax.Property, | ||
key: n({ | ||
type: syntax.Identifier, | ||
name: 'column' | ||
}), | ||
value: n({ | ||
type: syntax.Literal, | ||
value: node.loc.start.column | ||
}), | ||
kind: 'init' | ||
}) | ||
] | ||
}), | ||
kind: 'init' | ||
value: subpath.join('/') | ||
}) | ||
@@ -491,2 +333,57 @@ ] | ||
function metaAst (tree) { | ||
var tempAst = esprima.parse('!' + JSON.stringify(tree)); | ||
return tempAst.body[0].expression.argument; | ||
} | ||
function subTokens (tokens, from, to) { | ||
var i, token, result = []; | ||
for(i = 0; i < tokens.length; i += 1) { | ||
token = tokens[i]; | ||
if (token.loc.start.line < from.line) { | ||
continue; | ||
} | ||
if (to.line < token.loc.end.line) { | ||
break; | ||
} | ||
if (token.loc.start.column < from.column) { | ||
continue; | ||
} | ||
if (to.column < token.loc.end.column) { | ||
break; | ||
} | ||
result.push(token); | ||
} | ||
return result; | ||
} | ||
function isLeftHandSideOfAssignment(parentNode, currentPath) { | ||
// Do not instrument left due to 'Invalid left-hand side in assignment' | ||
return parentNode.type === syntax.AssignmentExpression && currentPath === 'left'; | ||
} | ||
function isObjectLiteralKey(parentNode, currentPath) { | ||
// Do not instrument Object literal key | ||
return parentNode.type === syntax.Property && parentNode.kind === 'init' && currentPath === 'key'; | ||
} | ||
function isUpdateExpression(parentNode) { | ||
// Just wrap UpdateExpression, not digging in. | ||
return parentNode.type === syntax.UpdateExpression; | ||
} | ||
function isCallExpressionWithNonComputedMemberExpression(currentNode, parentNode, currentPath) { | ||
// Do not instrument non-computed property of MemberExpression within CallExpression. | ||
return currentNode.type === syntax.Identifier && parentNode.type === syntax.MemberExpression && !parentNode.computed && currentPath === 'property'; | ||
} | ||
function isTypeOfOrDeleteUnaryExpression(currentNode, parentNode, currentPath) { | ||
// 'typeof Identifier' or 'delete Identifier' is not instrumented | ||
return currentNode.type === syntax.Identifier && parentNode.type === syntax.UnaryExpression && (parentNode.operator === 'typeof' || parentNode.operator === 'delete') && currentPath === 'argument'; | ||
} | ||
function isLeavingAssertion(capturingStartPath, path) { | ||
return capturingStartPath.join('/') === path.join('/'); | ||
} | ||
function newNodeWithLocationCopyOf (original) { | ||
@@ -544,9 +441,5 @@ return function (newNode) { | ||
function isSupportedNodeType (node) { | ||
return typeof nodeHandlerFor(node.type) === 'function'; | ||
return supportedNodeTypes.indexOf(node.type) !== -1; | ||
} | ||
function nodeHandlerFor (nodeType) { | ||
return handlers[nodeType]; | ||
} | ||
function ensureAstPrerequisites (ast, options) { | ||
@@ -590,21 +483,3 @@ var errorMessage; | ||
function searchToken (tokens, fromLine, toLine, predicate) { | ||
var i, token, found; | ||
for(i = 0; i < tokens.length; i += 1) { | ||
token = tokens[i]; | ||
if (token.loc.start.line < fromLine) { | ||
continue; | ||
} | ||
if (toLine < token.loc.end.line) { | ||
break; | ||
} | ||
found = predicate(token, i); | ||
if (found) { | ||
return found; | ||
} | ||
} | ||
return undefined; | ||
} | ||
// borrowed from esmangle | ||
@@ -662,3 +537,2 @@ deepCopy = (function () { | ||
// using returnExports UMD pattern with substack pattern | ||
espower.handlers = handlers; | ||
espower.deepCopy = deepCopy; | ||
@@ -665,0 +539,0 @@ espower.defaultOptions = defaultOptions; |
{ | ||
"name": "espower", | ||
"description": "Power Assert feature instrumentor based on the Mozilla JavaScript AST", | ||
"version": "0.4.1", | ||
"version": "0.6.0", | ||
"keywords": [ | ||
"power-assert", | ||
"test", | ||
@@ -32,21 +33,20 @@ "assert", | ||
"dependencies": { | ||
"esprima": "~1.1.1", | ||
"estraverse": "~1.5.0" | ||
}, | ||
"devDependencies": { | ||
"esprima": "~1.1.1", | ||
"blanket": "~1.1.6", | ||
"bower": "~1.3.1", | ||
"coveralls": "~2.10.0", | ||
"escodegen": "~1.3.1", | ||
"coffee-script-redux": "2.0.0-beta8", | ||
"grunt": "~0.4.2", | ||
"grunt-mocha-test": "~0.10.0", | ||
"grunt-contrib-jshint": "~0.9.2", | ||
"grunt-bower-requirejs": "~0.9.2", | ||
"grunt-bump": "~0.0.13", | ||
"grunt-contrib-connect": "~0.7.1", | ||
"grunt-contrib-jshint": "~0.10.0", | ||
"grunt-contrib-watch": "~0.6.1", | ||
"grunt-bump": "~0.0.13", | ||
"mocha-lcov-reporter": "0.0.1", | ||
"blanket": "~1.1.6", | ||
"coveralls": "~2.10.0", | ||
"load-grunt-tasks": "~0.3.0", | ||
"bower": "~1.3.1", | ||
"grunt-bower-requirejs": "~0.9.2", | ||
"grunt-mocha": "~0.4.10", | ||
"grunt-contrib-connect": "~0.7.1" | ||
"grunt-mocha-test": "~0.10.0", | ||
"jit-grunt": "~0.4.1", | ||
"mocha-lcov-reporter": "0.0.1" | ||
}, | ||
@@ -53,0 +53,0 @@ "licenses": [ |
@@ -51,3 +51,3 @@ (function (root, factory) { | ||
function instrument (jsCode, options) { | ||
var jsAST = esprima.parse(jsCode, {tolerant: true, loc: true, range: true, tokens: true});; | ||
var jsAST = esprima.parse(jsCode, {tolerant: true, loc: true, tokens: true});; | ||
var espoweredAST = espower(jsAST, options); | ||
@@ -89,7 +89,7 @@ var instrumentedCode = escodegen.generate(espoweredAST, {format: {compact: true}}); | ||
var instrumentedCode = instrument('assert(falsyStr);', {source: 'assert(falsyStr);'}); | ||
assert.equal(instrumentedCode, "assert(assert._expr(assert._capt(falsyStr,'ident',{start:{line:1,column:7}}),{start:{line:1,column:7}},'assert(falsyStr);'));"); | ||
assert.equal(instrumentedCode, "assert(assert._expr(assert._capt(falsyStr,''),{tree:{'type':'Identifier','name':'falsyStr','loc':{'start':{'line':1,'column':7},'end':{'line':1,'column':15}}},tokens:[{'type':'Identifier','value':'falsyStr','loc':{'start':{'line':1,'column':7},'end':{'line':1,'column':15}}}],content:'assert(falsyStr);'}));"); | ||
}); | ||
it('with source and path', function () { | ||
var instrumentedCode = instrument('assert(falsyStr);', {source: 'assert(falsyStr);', path: '/path/to/baz_test.js'}); | ||
assert.equal(instrumentedCode, "assert(assert._expr(assert._capt(falsyStr,'ident',{start:{line:1,column:7}}),{start:{line:1,column:7},path:'/path/to/baz_test.js'},'assert(falsyStr);'));"); | ||
assert.equal(instrumentedCode, "assert(assert._expr(assert._capt(falsyStr,''),{tree:{'type':'Identifier','name':'falsyStr','loc':{'start':{'line':1,'column':7},'end':{'line':1,'column':15}}},tokens:[{'type':'Identifier','value':'falsyStr','loc':{'start':{'line':1,'column':7},'end':{'line':1,'column':15}}}],content:'assert(falsyStr);',filepath:'/path/to/baz_test.js'}));"); | ||
}); | ||
@@ -102,7 +102,7 @@ }); | ||
var instrumentedCode = instrument('assert(falsyStr);', {source: 'assert(falsyStr);'}); | ||
assert.equal(instrumentedCode, "assert(assert._expr(assert._capt(falsyStr,'ident',{start:{line:1,column:7}}),{start:{line:1,column:7}},'assert(falsyStr);'));"); | ||
assert.equal(instrumentedCode, "assert(assert._expr(assert._capt(falsyStr,''),{tree:{'type':'Identifier','name':'falsyStr','loc':{'start':{'line':1,'column':7},'end':{'line':1,'column':15}}},tokens:[{'type':'Identifier','value':'falsyStr','loc':{'start':{'line':1,'column':7},'end':{'line':1,'column':15}}}],content:'assert(falsyStr);'}));"); | ||
}); | ||
it('powerAssertVariableName: "test"', function () { | ||
var instrumentedCode = instrument('test.ok(falsyStr);', {source: 'test.ok(falsyStr);', powerAssertVariableName: 'test'}); | ||
assert.equal(instrumentedCode, "test.ok(test._expr(test._capt(falsyStr,'ident',{start:{line:1,column:8}}),{start:{line:1,column:8}},'test.ok(falsyStr);'));"); | ||
assert.equal(instrumentedCode, "test.ok(test._expr(test._capt(falsyStr,''),{tree:{'type':'Identifier','name':'falsyStr','loc':{'start':{'line':1,'column':8},'end':{'line':1,'column':16}}},tokens:[{'type':'Identifier','value':'falsyStr','loc':{'start':{'line':1,'column':8},'end':{'line':1,'column':16}}}],content:'test.ok(falsyStr);'}));"); | ||
}); | ||
@@ -117,4 +117,6 @@ it('not instrumented if powerAssertVariableName and actual variable name is different.', function () { | ||
describe('lineSeparator option', function () { | ||
var lineDetected = "var falsyStr='';assert.ok(assert._expr(assert._capt(falsyStr,'ident',{start:{line:3,column:10}}),{start:{line:3,column:10}},'assert.ok(falsyStr);'));", | ||
lineNotDetected = "var falsyStr='';assert.ok(assert._expr(assert._capt(falsyStr,'ident',{start:{line:3,column:10}}),{start:{line:3,column:10}}));"; | ||
var lineDetected = "var falsyStr='';assert.ok(assert._expr(assert._capt(falsyStr,''),{tree:{'type':'Identifier','name':'falsyStr','loc':{'start':{'line':3,'column':10},'end':{'line':3,'column':18}}},tokens:[{'type':'Identifier','value':'falsyStr','loc':{'start':{'line':3,'column':10},'end':{'line':3,'column':18}}}],content:'assert.ok(falsyStr);'}));", | ||
lineNotDetected = "var falsyStr='';assert.ok(assert._expr(assert._capt(falsyStr,''),{tree:{'type':'Identifier','name':'falsyStr','loc':{'start':{'line':3,'column':10},'end':{'line':3,'column':18}}},tokens:[{'type':'Identifier','value':'falsyStr','loc':{'start':{'line':3,'column':10},'end':{'line':3,'column':18}}}]}));"; | ||
function lineSeparatorTest (name, lineSeparatorInCode, options, expected) { | ||
@@ -155,3 +157,3 @@ it(name, function () { | ||
when('option: LF', {lineSeparator: '\n'}, lineDetected); | ||
when('option: CR', {lineSeparator: '\r'}, "var falsyStr='';assert.ok(assert._expr(assert._capt(falsyStr,'ident',{start:{line:3,column:10}}),{start:{line:3,column:10}},'\\nassert.ok(falsyStr);'));"); | ||
when('option: CR', {lineSeparator: '\r'}, "var falsyStr='';assert.ok(assert._expr(assert._capt(falsyStr,''),{tree:{'type':'Identifier','name':'falsyStr','loc':{'start':{'line':3,'column':10},'end':{'line':3,'column':18}}},tokens:[{'type':'Identifier','value':'falsyStr','loc':{'start':{'line':3,'column':10},'end':{'line':3,'column':18}}}],content:'\\nassert.ok(falsyStr);'}));"); | ||
when('option: CRLF', {lineSeparator: '\r\n'}, lineDetected); | ||
@@ -158,0 +160,0 @@ }); |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
161968
14
1468
2
13
45
+ Addedesprima@~1.1.1
+ Addedesprima@1.1.1(transitive)