'use strict';

var slice = Array.prototype.slice,
    map = require('array-map'),
    some = require('array-some');

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

    return function decoratedAssert () {
        var context, message, args = slice.apply(arguments);

        if (!some(args, isCaptured)) {
            return func.apply(thisObj, args);
        }

        var 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;
        });

        if (numArgsToCapture === (args.length - 1)) {
            message = args[args.length - 1];
        }

        var invocation = {
            thisObj: thisObj,
            func: func,
            values: values,
            message: message
        };
        return decorator.concreteAssert(invocation, context);
    };
}

function isNotCaptured (value) {
    return !isCaptured(value);
}

function isCaptured (value) {
    return (typeof value === 'object') &&
        (value !== null) &&
        (typeof value.powerAssertContext !== 'undefined');
}

module.exports = decorate;

'use strict';

var slice = Array.prototype.slice,
    map = require('array-map'),
    some = require('array-some');

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

    return function decoratedAssert () {
        var context, message, args = slice.apply(arguments);
        if (some(args, isCaptured)) {
            var 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;
            });

            if (numArgsToCapture === (args.length - 1)) {
                message = args[args.length - 1];
            }

            var invocation = {
                thisObj: thisObj,
                func: func,
                values: values,
                message: message
            };
            return decorator.concreteAssert(invocation, context);
        } else {
            return func.apply(thisObj, args);
        }
    };
}

function isNotCaptured (value) {
    return !isCaptured(value);
}

function isCaptured (value) {
    return (typeof value === 'object') &&
        (value !== null) &&
        (typeof value.powerAssertContext !== 'undefined');
}

module.exports = decorate;

refactor double-negative conditional