define([
    'lodash',
    'bitbucket/internal/util/math'
], function(
    _,
    math
) {

    'use strict';

    module('util-math');

    /**
     * Test a function that takes in two args exactly. Should return NaN on one arg, and ignore third arg.
     * @param {string} name - name of test
     * @param {Function} fn - function to test.
     * @param {number} a - first arg
     * @param {number} b - second arg
     * @param {number} c - third arg (should be ignored)
     * @param {number} expected - expected result of fn(a,b)
     */
    function testTwoArg(name, fn, a, b, c, expected) {
        test(name, function() {
            ok(isNaN(fn(a)), 'NaN on single arg');
            equal(fn(a, b), expected, 'works.');
            equal(fn(a, b, c), expected, 'ignores additional params. Important for use in .map, .filter and .reduce');
        });
    }

    // see above
    function testTwoArgCompare(name, fn, a, b, c, expected) {
        test(name, function() {
            equal(fn(a), false, 'false on single arg');
            equal(fn(a, b), expected, 'works.');
            equal(fn(a, b, c), expected, 'ignores additional params. Important for use in .map, .filter and .reduce');
        });
    }

    testTwoArg('add', math.add, 1, 2, 3, 3);
    testTwoArg('multiply', math.multiply, 1, 2, 3, 2);

    testTwoArgCompare('lessThan', math.lessThan, 1, 2, 1, true);
    testTwoArgCompare('greaterThan', math.greaterThan, 1, 2, 1, false);

    test("lowpass", function(){
        deepEqual(_.map([-2, -1, 0, 1, 2], math.lowPass(0)), [-2, -1, 0, 0, 0]);
    });

    test("highpass", function(){
        deepEqual(_.map([-2, -1, 0, 1, 2], math.highPass(0)), [0, 0, 0, 1, 2]);
    });

    test("clamp", function(){
       deepEqual(_.map([-2, -1, 0, 1, 2], math.clamp(-1, 1)), [-1, -1, 0, 1, 1]);
    });

    test("isPositive", function(){
       ok(math.isPositive(1), 'Positive number is positive');
       ok(!math.isPositive(-1), 'Negative number is not positive');
       ok(!math.isPositive(0), 'Zero is not positive');
       ok(!math.isPositive('positive'), 'String is not positive');
       ok(math.isPositive('1'), 'Positive numeric string is positive');
       ok(!math.isPositive('-1'), 'Negative numeric string is not positive');
       ok(!math.isPositive({}), 'Object is not positive');
       ok(!math.isPositive(), 'Undefined is not positive');
    });

    test("isNegative", function(){
        ok(math.isNegative(-1), 'Negative number is negative');
        ok(!math.isNegative(1), 'Positive number is not negative');
        ok(!math.isNegative(0), 'Zero is not negative');
        ok(!math.isNegative('negative'), 'String is not negative');
        ok(math.isNegative('-1'), 'Negative numeric string is negative');
        ok(!math.isNegative('1'), 'Positive numeric string is not negative');
        ok(!math.isNegative({}), 'Object is not negative');
        ok(!math.isNegative(), 'Undefined is not negative');
    });
});
