type-of-functions-and-objects.js   [plain text]


function foo(v) {
    return typeof v;
}

function bar(v) {
    switch (typeof v) {
    case "object":
        return 1;
    case "function":
        return 2;
    default:
        return 3;
    }
}

function baz(v) {
    return typeof v == "function";
}

function fuzz(v) {
    return typeof v == "object";
}

noInline(foo);
noInline(bar);
noInline(baz);
noInline(fuzz);

function test() {
    var errors = [];

    function testValue(v, expected) {
        function expect(f, expected) {
            var result = f(v);
            if (result != expected)
                errors.push(f.name + "(" + v + ") returned " + result + " instead of " + expected);
        }

        switch (expected) {
        case "function":
            expect(foo, "function");
            expect(bar, 2);
            expect(baz, true);
            expect(fuzz, false);
            break;
        case "object":
            expect(foo, "object");
            expect(bar, 1);
            expect(baz, false);
            expect(fuzz, true);
            break;
        case "other":
            var result = foo(v);
            if (result == "object" || result == "function")
                errors.push("foo(" + v + ") returned " + result + " but expected something other than object or function");
            expect(bar, 3);
            expect(baz, false);
            expect(fuzz, false);
            break;
        default:
            throw "Bad expected case";
        }
    }
    
    testValue({}, "object");
    testValue(function() { }, "function");
    testValue("hello", "other");
    testValue(42, "other");
    testValue(null, "object");
    testValue(void 0, "other");
    testValue(42.5, "other");
    testValue(Map, "function");
    testValue(Date, "function");
    testValue(Map.prototype, "object");
    
    if (!errors.length)
        return;
    
    for (var i = 0; i < errors.length; ++i)
        print("Error: " + errors[i]);
    throw "Encountered errors during test run.";
}

for (var i = 0; i < 10000; ++i)
    test();