Most JavaScript developers are familiar with the concepts of truthy and falsy.  As a quick refresher, the falsy values are:

false
null
undefined
0 (the number zero)
"" (an empty string)

Everything else is truthy.  This is one of those things you just have to memorize, but it's simpler if you think of the falsy stuff as things that are false or have no value.  Just watch out for zero and empty string.

I got burned by a bug today in a passing Jasmine test by not paying enough attention to the truthy values.  The code I was testing was a little function to make sure scaleMin was smaller than scaleMax, but if they were both set to 0, that was OK.  If scaleMin was greater than or equal to scaleMax, we'd return an error message.

Here are the function and tests I started with.  All the tests pass.  Done, right?!?!

// Code under test
var MyApp = function () {

    var isValid = function (scaleMin, scaleMax) {
        if (scaleMax <= scaleMin) {
            return "Scale max must be greater than Scale min.";
        }

        return true;
    };
    
    return {
        isValid: isValid
    };
};

// Specs
describe("isValid", function () {

    var myApp = new MyApp();
    
    it("Should be valid when scale min/max are both 0", function () {
        var scaleMin = 0,
            scaleMax = 0;

        expect(myApp.isValid(scaleMin, scaleMax)).toBeTruthy();
    });

    it("Should be valid when scale min is less than scaleMax", function () {
        var scaleMin = 0,
            scaleMax = 1;

        expect(myApp.isValid(scaleMin, scaleMax)).toBeTruthy();
    });

    it("Should be invalid when scale min is equal to scaleMax", function () {
        var scaleMin = 1,
            scaleMax = 1;

        expect(myApp.isValid(scaleMin, scaleMax)).toBe("Scale max must be greater than Scale min.");
    });

    it("Should be invalid when scale min is greater than scaleMax", function () {
        var scaleMin = 1,
            scaleMax = 0;

        expect(myApp.isValid(scaleMin, scaleMax)).toBe("Scale max must be greater than Scale min.");
    });

});

Not so much.

Jasmine's toBeTruthy() checks for any truthy value, and a string with something in it is truthy.  So in the test where I'm checking that it's OK if scaleMin and scaleMax are both 0, I'm getting the error string, which is truthy.  Since the error string and the value true are both truthy, my check for toBeTruthy() will always pass.  I'm getting false positives.

This is why you are supposed to write a failing test, then a passing test to prove your code was the thing that made the test pass.  I skipped that here because this code was so simple.  What could go wrong?  Oops!

Here's the fixed function and test code, which uses Jasmine's toBe(true) instead of toBeTruthy() to tease apart error strings and the value true:

// Code under test
var MyApp = function () {

    var isValid = function (scaleMin, scaleMax) {
        if (scaleMin === 0 && scaleMax === 0) {
            return true;
        }
        
        if (scaleMax <= scaleMin) {
            return "Scale max must be greater than Scale min.";
        }

        return true;
    };
    
    return {
        isValid: isValid
    };
};

// Specs
describe("isValid", function () {

    var myApp = new MyApp();
    
    it("Should be valid when scale min/max are both 0", function () {
        var scaleMin = 0,
            scaleMax = 0;

        expect(myApp.isValid(scaleMin, scaleMax)).toBe(true);
    });

    it("Should be valid when scale min is less than scaleMax", function () {
        var scaleMin = 0,
            scaleMax = 1;

        expect(myApp.isValid(scaleMin, scaleMax)).toBe(true);
    });

    it("Should be invalid when scale min is equal to scaleMax", function () {
        var scaleMin = 1,
            scaleMax = 1;

        expect(myApp.isValid(scaleMin, scaleMax)).toBe("Scale max must be greater than Scale min.");
    });

    it("Should be invalid when scale min is greater than scaleMax", function () {
        var scaleMin = 1,
            scaleMax = 0;

        expect(myApp.isValid(scaleMin, scaleMax)).toBe("Scale max must be greater than Scale min.");
    });

});