"use strict";
/*global setImmediate: false, clearImmediate: false, specify: false, window: false */

var assert = require("assert");
require("../setImmediate");

// The Node version of setImmediate does not support string handlers.
var global = Function("return this")();
var originalGlobalSetImmediate = global.setImmediate;
if (originalGlobalSetImmediate) {
    global.setImmediate = function(handler) {
        var args = arguments;
        if (typeof handler !== "function") {
            handler = args[0] = eval.bind(null, "" + handler);
        }
        return originalGlobalSetImmediate.apply(this, args);
    };
}

specify("Handlers do execute", function (done) {
    setImmediate(function () {
        done();
    });
});

specify("Handlers do not execute in the same event loop turn as the call to `setImmediate`", function (done) {
    var handlerCalled = false;
    function handler() {
        handlerCalled = true;
        done();
    }

    setImmediate(handler);
    assert(!handlerCalled);
});

specify("Handlers can be strings", function(done) {
    var property = "handler$" + Math.random().toString(36).slice(2);
    done.called = false;
    global[property] = function () {
        delete global[property];
        done();
    };

    setImmediate(property + ".called = true; " + property + "()");
    assert.strictEqual(done.called, false);
});

specify("`setImmediate` passes through an argument to the handler", function (done) {
    var expectedArg = { expected: true };

    function handler(actualArg) {
        assert.strictEqual(actualArg, expectedArg);
        done();
    }

    setImmediate(handler, expectedArg);
});

specify("`setImmediate` passes through two arguments to the handler", function (done) {
    var expectedArg1 = { arg1: true };
    var expectedArg2 = { arg2: true };

    function handler(actualArg1, actualArg2) {
        assert.strictEqual(actualArg1, expectedArg1);
        assert.strictEqual(actualArg2, expectedArg2);
        done();
    }

    setImmediate(handler, expectedArg1, expectedArg2);
});

specify("`clearImmediate` within the same event loop turn prevents the handler from executing", function (done) {
    var handlerCalled = false;
    function handler() {
        handlerCalled = true;
    }

    var handle = setImmediate(handler);
    clearImmediate(handle);

    setTimeout(function () {
        assert(!handlerCalled);
        done();
    }, 100);
});

specify("`clearImmediate` does not interfere with handlers other than the one with ID passed to it", function (done) {
    var expectedArgs = ["A", "D"];
    var recordedArgs = [];
    function handler(arg) {
        recordedArgs.push(arg);
    }

    setImmediate(handler, "A");
    clearImmediate(setImmediate(handler, "B"));
    var handle = setImmediate(handler, "C");
    setImmediate(handler, "D");
    clearImmediate(handle);

    setTimeout(function () {
        assert.deepEqual(recordedArgs, expectedArgs);
        done();
    }, 100);
});

@@ -98,69 +98,8 @@
 */%0A%0A
-var assert = require(%22assert%22);%0Arequire(%22../setImmediate%22);%0A%0A
 // T
@@ -557,16 +557,77 @@
   %7D;%0A%7D%0A%0A
+var assert = require(%22assert%22);%0Arequire(%22../setImmediate%22);%0A%0A
 specify(
@@ -1157,22 +1157,28 @@
 se;%0A    
-global
+setImmediate
 %5Bpropert
@@ -1211,22 +1211,28 @@
  delete 
-global
+setImmediate
 %5Bpropert
@@ -1235,16 +1235,17 @@
 perty%5D;%0A
+%0A
         
@@ -1277,16 +1277,34 @@
 mediate(
+%22setImmediate.%22 + 
 property
@@ -1323,16 +1323,29 @@
 = true; 
+setImmediate.
 %22 + prop

Fix tests in oldIE.