aboutsummaryrefslogtreecommitdiff
path: root/node_modules/empower-core/lib
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/empower-core/lib')
-rw-r--r--node_modules/empower-core/lib/decorate.js66
-rw-r--r--node_modules/empower-core/lib/decorator.js165
-rw-r--r--node_modules/empower-core/lib/default-options.js35
-rw-r--r--node_modules/empower-core/lib/define-properties.js16
4 files changed, 282 insertions, 0 deletions
diff --git a/node_modules/empower-core/lib/decorate.js b/node_modules/empower-core/lib/decorate.js
new file mode 100644
index 000000000..2eb6f5f20
--- /dev/null
+++ b/node_modules/empower-core/lib/decorate.js
@@ -0,0 +1,66 @@
+'use strict';
+
+var some = require('core-js/library/fn/array/some');
+var map = require('core-js/library/fn/array/map');
+
+function decorate (callSpec, decorator) {
+ var numArgsToCapture = callSpec.numArgsToCapture;
+
+ return function decoratedAssert () {
+ var context, message, hasMessage = false;
+
+ // see: https://github.com/twada/empower-core/pull/8#issue-127859465
+ // see: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
+ var args = new Array(arguments.length);
+ for(var i = 0; i < args.length; ++i) {
+ args[i] = arguments[i];
+ }
+
+ if (numArgsToCapture === (args.length - 1)) {
+ message = args.pop();
+ hasMessage = true;
+ }
+
+ var invocation = {
+ thisObj: this,
+ values: args,
+ message: message,
+ hasMessage: hasMessage
+ };
+
+ if (some(args, isCaptured)) {
+ invocation.values = map(args.slice(0, numArgsToCapture), function (arg) {
+ if (isNotCaptured(arg)) {
+ return arg;
+ }
+ if (!context) {
+ context = {
+ source: arg.source,
+ args: []
+ };
+ }
+ context.args.push({
+ value: arg.powerAssertContext.value,
+ events: arg.powerAssertContext.events
+ });
+ return arg.powerAssertContext.value;
+ });
+
+ return decorator.concreteAssert(callSpec, invocation, context);
+ } else {
+ return decorator.concreteAssert(callSpec, invocation);
+ }
+ };
+}
+
+function isNotCaptured (value) {
+ return !isCaptured(value);
+}
+
+function isCaptured (value) {
+ return (typeof value === 'object') &&
+ (value !== null) &&
+ (typeof value.powerAssertContext !== 'undefined');
+}
+
+module.exports = decorate;
diff --git a/node_modules/empower-core/lib/decorator.js b/node_modules/empower-core/lib/decorator.js
new file mode 100644
index 000000000..678f47283
--- /dev/null
+++ b/node_modules/empower-core/lib/decorator.js
@@ -0,0 +1,165 @@
+'use strict';
+
+var forEach = require('core-js/library/fn/array/for-each');
+var filter = require('core-js/library/fn/array/filter');
+var map = require('core-js/library/fn/array/map');
+var signature = require('call-signature');
+var decorate = require('./decorate');
+var keys = require('core-js/library/fn/object/keys');
+
+
+function Decorator (receiver, config) {
+ this.receiver = receiver;
+ this.config = config;
+ this.onError = config.onError;
+ this.onSuccess = config.onSuccess;
+ 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(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(matcherSpec),
+ matcherSpec: matcherSpec,
+ enhanced: enhanced
+ };
+ container[methodName] = callSpec.enhancedFunc = decorate(callSpec, that);
+ wrappedMethods.push(methodName);
+ }
+
+ forEach(filter(this.signatures, methodCall), function (matcher) {
+ attach(matcher, true);
+ });
+
+ forEach(filter(this.wrapOnlySignatures, methodCall), function (matcher) {
+ attach(matcher, false);
+ });
+
+ return container;
+};
+
+Decorator.prototype.container = function () {
+ var basement = {};
+ if (typeof this.receiver === 'function') {
+ var candidates = filter(this.signatures, functionCall);
+ var enhanced = true;
+ if (candidates.length === 0) {
+ enhanced = false;
+ candidates = filter(this.wrapOnlySignatures, functionCall);
+ }
+ if (candidates.length === 1) {
+ var callSpec = {
+ thisObj: null,
+ func: this.receiver,
+ numArgsToCapture: numberOfArgumentsToCapture(candidates[0]),
+ matcherSpec: candidates[0],
+ enhanced: enhanced
+ };
+ basement = callSpec.enhancedFunc = decorate(callSpec, this);
+ }
+ }
+ return basement;
+};
+
+Decorator.prototype.concreteAssert = function (callSpec, invocation, context) {
+ var func = callSpec.func;
+ var thisObj = this.config.bindReceiver ? callSpec.thisObj : invocation.thisObj;
+ var enhanced = callSpec.enhanced;
+ var args = invocation.values;
+ var message = invocation.message;
+ var matcherSpec = callSpec.matcherSpec;
+
+ if (context && typeof this.config.modifyMessageBeforeAssert === 'function') {
+ message = this.config.modifyMessageBeforeAssert({originalMessage: message, powerAssertContext: context});
+ }
+ args = args.concat(message);
+
+ var data = {
+ thisObj: invocation.thisObj,
+ assertionFunction: callSpec.enhancedFunc,
+ originalMessage: message,
+ defaultMessage: matcherSpec.defaultMessage,
+ matcherSpec: matcherSpec,
+ enhanced: enhanced,
+ args: args
+ };
+
+ if (context) {
+ data.powerAssertContext = context;
+ }
+
+ return this._callFunc(func, thisObj, args, data);
+};
+
+// see: https://github.com/twada/empower-core/pull/8#issuecomment-173480982
+Decorator.prototype._callFunc = function (func, thisObj, args, data) {
+ var ret;
+ try {
+ ret = func.apply(thisObj, args);
+ } catch (e) {
+ data.assertionThrew = true;
+ data.error = e;
+ return this.onError.call(thisObj, data);
+ }
+ data.assertionThrew = false;
+ data.returnValue = ret;
+ return this.onSuccess.call(thisObj, data);
+};
+
+function numberOfArgumentsToCapture (matcherSpec) {
+ var matcher = matcherSpec.parsed;
+ var len = matcher.args.length;
+ var lastArg;
+ if (0 < len) {
+ lastArg = matcher.args[len - 1];
+ if (lastArg.name === 'message' && lastArg.optional) {
+ len -= 1;
+ }
+ }
+ return len;
+}
+
+
+function detectMethodName (callee) {
+ if (callee.type === 'MemberExpression') {
+ return callee.member;
+ }
+ return null;
+}
+
+
+function functionCall (matcherSpec) {
+ return matcherSpec.parsed.callee.type === 'Identifier';
+}
+
+
+function methodCall (matcherSpec) {
+ return matcherSpec.parsed.callee.type === 'MemberExpression';
+}
+
+function parse(matcherSpec) {
+ if (typeof matcherSpec === 'string') {
+ matcherSpec = {pattern: matcherSpec};
+ }
+ var ret = {};
+ forEach(keys(matcherSpec), function (key) {
+ ret[key] = matcherSpec[key];
+ });
+ ret.parsed = signature.parse(matcherSpec.pattern);
+ return ret;
+}
+
+
+module.exports = Decorator;
diff --git a/node_modules/empower-core/lib/default-options.js b/node_modules/empower-core/lib/default-options.js
new file mode 100644
index 000000000..77b0f5c05
--- /dev/null
+++ b/node_modules/empower-core/lib/default-options.js
@@ -0,0 +1,35 @@
+'use strict';
+
+module.exports = function defaultOptions () {
+ return {
+ destructive: false,
+ bindReceiver: true,
+ onError: onError,
+ onSuccess: onSuccess,
+ patterns: [
+ 'assert(value, [message])',
+ 'assert.ok(value, [message])',
+ 'assert.equal(actual, expected, [message])',
+ 'assert.notEqual(actual, expected, [message])',
+ 'assert.strictEqual(actual, expected, [message])',
+ 'assert.notStrictEqual(actual, expected, [message])',
+ 'assert.deepEqual(actual, expected, [message])',
+ 'assert.notDeepEqual(actual, expected, [message])',
+ 'assert.deepStrictEqual(actual, expected, [message])',
+ 'assert.notDeepStrictEqual(actual, expected, [message])'
+ ],
+ wrapOnlyPatterns: []
+ };
+};
+
+function onError (errorEvent) {
+ var e = errorEvent.error;
+ if (errorEvent.powerAssertContext && e.name === 'AssertionError') {
+ e.powerAssertContext = errorEvent.powerAssertContext;
+ }
+ throw e;
+}
+
+function onSuccess(successEvent) {
+ return successEvent.returnValue;
+}
diff --git a/node_modules/empower-core/lib/define-properties.js b/node_modules/empower-core/lib/define-properties.js
new file mode 100644
index 000000000..340c7f065
--- /dev/null
+++ b/node_modules/empower-core/lib/define-properties.js
@@ -0,0 +1,16 @@
+'use strict';
+
+var defineProperty = require('core-js/library/fn/object/define-property');
+var forEach = require('core-js/library/fn/array/for-each');
+var keys = require('core-js/library/fn/object/keys');
+
+module.exports = function defineProperties (obj, map) {
+ forEach(keys(map), function (name) {
+ defineProperty(obj, name, {
+ configurable: true,
+ enumerable: false,
+ value: map[name],
+ writable: true
+ });
+ });
+};