Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions lib/decorate.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ var map = require('core-js/library/fn/array/map');
var slice = Array.prototype.slice;

function decorate (callSpec, decorator) {
var func = callSpec.func;
var thisObj = callSpec.thisObj;
var numArgsToCapture = callSpec.numArgsToCapture;
var enhanced = callSpec.enhanced;

return function decoratedAssert () {
var context, message, hasMessage = false, args = slice.apply(arguments);
Expand All @@ -19,12 +16,9 @@ function decorate (callSpec, decorator) {
}

var invocation = {
thisObj: thisObj,
func: func,
values: args,
message: message,
hasMessage: hasMessage,
enhanced: enhanced
hasMessage: hasMessage
};

if (some(args, isCaptured)) {
Expand All @@ -45,9 +39,9 @@ function decorate (callSpec, decorator) {
return arg.powerAssertContext.value;
});

return decorator.concreteAssert(invocation, context);
return decorator.concreteAssert(callSpec, invocation, context);
} else {
return decorator.concreteAssert(invocation);
return decorator.concreteAssert(callSpec, invocation);
}
};
}
Expand Down
50 changes: 35 additions & 15 deletions lib/decorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,29 @@ function Decorator (receiver, config) {
this.config = config;
this.onError = config.onError;
this.onSuccess = config.onSuccess;
this.signatures = map(config.patterns, signature.parse);
this.wrapOnlySignatures = map(config.wrapOnlyPatterns, signature.parse);
this.signatures = map(config.patterns, parse);
this.wrapOnlySignatures = map(config.wrapOnlyPatterns, parse);
}

Decorator.prototype.enhancement = function () {
var that = this;
var container = this.container();
var wrappedMethods = [];

function attach(matcher, enhanced) {
function attach(matcherSpec, enhanced) {
var matcher = matcherSpec.parsed;
var methodName = detectMethodName(matcher.callee);
if (typeof that.receiver[methodName] !== 'function' || wrappedMethods.indexOf(methodName) !== -1) {
return;
}
var callSpec = {
thisObj: that.receiver,
func: that.receiver[methodName],
numArgsToCapture: numberOfArgumentsToCapture(matcher),
numArgsToCapture: numberOfArgumentsToCapture(matcherSpec),
matcherSpec: matcherSpec,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've attached it here.

enhanced: enhanced
};
container[methodName] = decorate(callSpec, that);
container[methodName] = callSpec.enhancedFunc = decorate(callSpec, that);
wrappedMethods.push(methodName);
}

Expand Down Expand Up @@ -61,27 +63,30 @@ Decorator.prototype.container = function () {
thisObj: null,
func: this.receiver,
numArgsToCapture: numberOfArgumentsToCapture(candidates[0]),
matcherSpec: candidates[0],
enhanced: enhanced
};
basement = decorate(callSpec, this);
basement = callSpec.enhancedFunc = decorate(callSpec, this);
}
}
return basement;
};

Decorator.prototype.concreteAssert = function (invocation, context) {
var func = invocation.func;
var thisObj = invocation.thisObj;
Decorator.prototype.concreteAssert = function (callSpec, invocation, context) {
var func = callSpec.func;
var thisObj = callSpec.thisObj;
var enhanced = callSpec.enhanced;
var args = invocation.values;
var message = invocation.message;
var enhanced = invocation.enhanced;
if (context && typeof this.config.modifyMessageBeforeAssert === 'function') {
message = this.config.modifyMessageBeforeAssert({originalMessage: message, powerAssertContext: context});
}
args = args.concat(message);

var data = {
assertionFunction: callSpec.enhancedFunc,
originalMessage: message,
defaultMessage: callSpec.matcherSpec.defaultMessage,
enhanced: enhanced,
args: args
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but this is the event object, and it doesn't have it.

};
Expand All @@ -103,7 +108,8 @@ Decorator.prototype.concreteAssert = function (invocation, context) {
return this.onSuccess(data);
};

function numberOfArgumentsToCapture (matcher) {
function numberOfArgumentsToCapture (matcherSpec) {
var matcher = matcherSpec.parsed;
var len = matcher.args.length;
var lastArg;
if (0 < len) {
Expand All @@ -124,13 +130,27 @@ function detectMethodName (callee) {
}


function functionCall (matcher) {
return matcher.callee.type === 'Identifier';
function functionCall (matcherSpec) {
return matcherSpec.parsed.callee.type === 'Identifier';
}


function methodCall (matcher) {
return matcher.callee.type === 'MemberExpression';
function methodCall (matcherSpec) {
return matcherSpec.parsed.callee.type === 'MemberExpression';
}

function parse(matcherSpec) {
if (typeof matcherSpec === 'string') {
return {
pattern: matcherSpec,
parsed: signature.parse(matcherSpec)
};
}
return {
pattern: matcherSpec.pattern,
parsed: signature.parse(matcherSpec.pattern),
defaultMessage: matcherSpec.defaultMessage
}
}


Expand Down
55 changes: 54 additions & 1 deletion test/empower_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,50 @@ suite('onSuccess can throw', function () {
});
});

suite('metadata for enhanced methods', function () {
var assert = empower(
{
fail: function (message) {
baseAssert.ok(false, message);
},
pass: function (message) {
// noop
}
},
{
patterns: [
{
pattern: 'assert.fail([message])',
defaultMessage: 'User! You have failed this assertion!'
},
'assert.pass([message])'
],
onError: function (event) {
baseAssert.equal(event.assertionThrew, true);
return event;
},
onSuccess: function (event) {
baseAssert.equal(event.assertionThrew, false);
return event;
}
}
);

test('instrumented', function () {
var event = eval(weave("assert.fail('doh!');"));
baseAssert.equal(event.defaultMessage, 'User! You have failed this assertion!');
baseAssert.strictEqual(event.enhanced, true);
baseAssert.strictEqual(event.assertionFunction, assert.fail);
});

test('non-instrumented', function () {
var event = assert.fail('doh!');
baseAssert.equal(event.defaultMessage, 'User! You have failed this assertion!');
baseAssert.strictEqual(event.enhanced, true);
baseAssert.strictEqual(event.assertionFunction, assert.fail);
});
});

suite('wrapOnlyPatterns', function () {
var assert = empower(
{
Expand All @@ -529,7 +573,10 @@ suite('wrapOnlyPatterns', function () {
},
{
wrapOnlyPatterns: [
'assert.fail([message])',
{
pattern: 'assert.fail([message])',
defaultMessage: 'User! You have failed this assertion!'
},
'assert.pass([message])'
],
onError: function (event) {
Expand All @@ -549,14 +596,17 @@ suite('wrapOnlyPatterns', function () {
baseAssert.strictEqual(event.enhanced, false);
baseAssert.equal(event.originalMessage, 'woot!');
baseAssert.deepEqual(event.args, ['woot!']);
baseAssert.strictEqual(event.assertionFunction, assert.pass);
});

test('instrumented code: error', function () {
var event = eval(weave('assert.fail("Oh no!")'));
baseAssert.equal(event.assertionThrew, true);
baseAssert.strictEqual(event.enhanced, false);
baseAssert.equal(event.originalMessage, 'Oh no!');
baseAssert.equal(event.defaultMessage, 'User! You have failed this assertion!');
baseAssert.deepEqual(event.args, ['Oh no!']);
baseAssert.strictEqual(event.assertionFunction, assert.fail);
});

test('non-instrumented code: success', function () {
Expand All @@ -565,14 +615,17 @@ suite('wrapOnlyPatterns', function () {
baseAssert.strictEqual(event.enhanced, false);
baseAssert.equal(event.originalMessage, 'woot!');
baseAssert.deepEqual(event.args, ['woot!']);
baseAssert.strictEqual(event.assertionFunction, assert.pass);
});

test('non-instrumented code: error', function () {
var event = assert.fail('Oh no!');
baseAssert.equal(event.assertionThrew, true);
baseAssert.strictEqual(event.enhanced, false);
baseAssert.equal(event.originalMessage, 'Oh no!');
baseAssert.equal(event.defaultMessage, 'User! You have failed this assertion!');
baseAssert.deepEqual(event.args, ['Oh no!']);
baseAssert.strictEqual(event.assertionFunction, assert.fail);
});
});

Expand Down