| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911 | /*global _document:true, _Error:true, _args, _extend, _deepCopy, _pick, _omit, _deleteOwnProperties, _containedBy, _getDirPathOfUrl, _getCurrentScriptUrlFromErrorStack, _getCurrentScriptUrlFromError:true, _getCurrentScriptUrl, _getUnanimousScriptParentDir, _getDefaultSwfPath */(function(module, test) {  "use strict";  var doc, errorDef, getUrlFromError;  module("shared/private.js unit tests", {    setup: function() {      doc = _document;      errorDef = _Error;      getUrlFromError = _getCurrentScriptUrlFromError;    },    teardown: function() {      _document = doc;      _Error = errorDef;      _getCurrentScriptUrlFromError = getUrlFromError;    }  });  test("`_args` works", function(assert) {    assert.expect(4);    // Arrange    var _arguments = function() {      return arguments;    };    var fn = function() {};    var expectedOutput1 = [1, 2, 3];    var expectedOutput2 = [fn];    var expectedOutput3 = [{ foo: "bar" }];    var expectedOutput4 = [[1, 2, 3]];    var inputArgs1 = _arguments(1, 2, 3);    var inputArgs2 = _arguments(fn);    var inputArgs3 = _arguments({ foo: "bar" });    var inputArgs4 = _arguments([1, 2, 3]);    // Act    var actualOutput1 = _args(inputArgs1);    var actualOutput2 = _args(inputArgs2);    var actualOutput3 = _args(inputArgs3);    var actualOutput4 = _args(inputArgs4);    // Arrange    assert.deepEqual(actualOutput1, expectedOutput1);    assert.deepEqual(actualOutput2, expectedOutput2);    assert.deepEqual(actualOutput3, expectedOutput3);    assert.deepEqual(actualOutput4, expectedOutput4);  });  test("`_extend` works on plain objects", function(assert) {    assert.expect(5);    // Plain objects    var a = {      "a": "apple",      "c": "cantalope"    },    b = {      "b": "banana",      "c": "cherry"  // cuz cantalope sucks  ;)    },    c = {      "a": "apple",      "b": "banana",      "c": "cherry"    };    assert.deepEqual(_extend({}, a), a, "actual equals expected, `target` is updated, `source` is unaffected");    assert.deepEqual(_extend({}, b), b, "actual equals expected, `target` is updated, `source` is unaffected");    assert.deepEqual(_extend({}, c), c, "actual equals expected, `target` is updated, `source` is unaffected");    assert.deepEqual(_extend(a, b), c, "actual equals expected");    assert.deepEqual(a, c, "`a` equals `c` because `_extend` updates the `target` argument");  });  test("`_extend` only copies owned properties", function(assert) {    assert.expect(1);    // Now prototypes...    var SomeClass = function() {      this.b = "banana";    };    SomeClass.prototype.c = "cantalope";  // cuz cantalope sucks  ;)    var a = {      "a": "apple",      "c": "cherry"    },    b = new SomeClass(),    c = {      "a": "apple",      "b": "banana",      "c": "cherry"    };    assert.deepEqual(_extend(a, b), c, "actual equals expected because `_extend` does not copy over prototype properties");  });  test("`_extend` only copies owned properties from Array source", function(assert) {    assert.expect(3);    var a = {      "a": "apple",      "b": "banana"    },    b = ["zero", "one", "two"],    c = {      "a": "apple",      "b": "banana",      "0": "zero",      "1": "one",      "2": "two"    };    assert.deepEqual(_extend(a, b), c, "actual equals expected because `_extend` does not copy over prototype properties");    assert.strictEqual("length" in a, false, "`a` should not have gained a `length` property");    assert.strictEqual("length" in b, true, "`b` should still have a `length` property");  });  test("`_extend` will merge multiple objects", function(assert) {    assert.expect(2);    var a = {      "a": "apple",      "c": "cantalope",      "d": "dragon fruit"    },    b = {      "b": "banana",      "c": "cherry"  // cuz cantalope sucks  ;)    },    c = {      "a": "apricot",      "b": "blueberry"    },    d = {      "a": "apricot",      "b": "blueberry",      "c": "cherry",      "d": "dragon fruit"    };    assert.deepEqual(_extend({}, a, b, c), d, "actual equals expected, `target` is updated, `source` is unaffected");    assert.deepEqual(_extend(a, b, c), d, "actual equals expected");  });  test("`_deepCopy` works", function(assert) {    assert.expect(13);    // Arrange    var input1 = {      "a": "b",      "b": {        "c": "d"      }    };    var input2 = [[1, 2], 2];    var expected1 = {      "a": "b",      "b": {        "c": "d"      }    };    var expected2 = [[1, 2], 2];    // Act    var actual1 = _deepCopy(input1);    var actual2 = _deepCopy(input2);    // Assert    assert.deepEqual(actual1, expected1, "Objects are deeply equal");    assert.notStrictEqual(actual1, expected1, "Objects are not strictly equal");    assert.strictEqual(actual1.a, expected1.a, "Objects' non-object properties are strictly equal");    assert.deepEqual(actual1.b, expected1.b, "Objects' object properties are deeply equal");    assert.notStrictEqual(actual1.b, expected1.b, "Objects' object properties are not strictly equal");    assert.strictEqual(actual1.b.c, expected1.b.c, "Objects' object properties' non-object properties are strictly equal");    assert.deepEqual(actual2, expected2, "Arrays are deeply equal");    assert.notStrictEqual(actual2, expected2, "Arrays are not strictly equal");    assert.deepEqual(actual2[0], expected2[0], "Sub-arrays are deeply equal");    assert.notStrictEqual(actual2[0], expected2[0], "Sub-arrays are not strictly equal");    assert.strictEqual(actual2[0][0], expected2[0][0], "Sub-arrays' first items are strictly equal");    assert.strictEqual(actual2[0][1], expected2[0][1], "Sub-arrays' second items are strictly equal");    assert.strictEqual(actual2[1], expected2[1], "Sub-items are strictly equal");  });  test("`_pick` works", function(assert) {    assert.expect(6);    // Arrange    var obj1 = {};    var obj2 = {      "name": "Zero",      "version": "v2.x",      "other": "test"    };    var filter1 = [];    var filter2 = ["name", "version"];    var filter3 = ["name", "version", "other"];    var expected1x = {};    var expected21 = {};    var expected22 = {      "name": "Zero",      "version": "v2.x"    };    var expected23 = {      "name": "Zero",      "version": "v2.x",      "other": "test"    };    // Act    var result11 = _pick(obj1, filter1);    var result12 = _pick(obj1, filter2);    var result13 = _pick(obj1, filter3);    var result21 = _pick(obj2, filter1);    var result22 = _pick(obj2, filter2);    var result23 = _pick(obj2, filter3);    // Assert    assert.deepEqual(result11, expected1x, "An empty object cannot have any properties picked");    assert.deepEqual(result12, expected1x, "An empty object cannot have any properties picked");    assert.deepEqual(result13, expected1x, "An empty object cannot have any properties picked");    assert.deepEqual(result21, expected21, "An object with an empty pick list will have nothing picked");    assert.deepEqual(result22, expected22, "An object with a subset pick list will have only those properties picked");    assert.deepEqual(result23, expected23, "An object with a complete pick list will have all of its properties picked");  });  test("`_omit` works", function(assert) {    assert.expect(6);    // Arrange    var obj1 = {};    var obj2 = {      "name": "Zero",      "version": "v2.x",      "other": "test"    };    var filter1 = [];    var filter2 = ["name", "version"];    var filter3 = ["name", "version", "other"];    var expected1x = {};    var expected21 = {      "name": "Zero",      "version": "v2.x",      "other": "test"    };    var expected22 = {      "other": "test"    };    var expected23 = {};    // Act    var result11 = _omit(obj1, filter1);    var result12 = _omit(obj1, filter2);    var result13 = _omit(obj1, filter3);    var result21 = _omit(obj2, filter1);    var result22 = _omit(obj2, filter2);    var result23 = _omit(obj2, filter3);    // Assert    assert.deepEqual(result11, expected1x, "An empty object cannot have any properties picked");    assert.deepEqual(result12, expected1x, "An empty object cannot have any properties picked");    assert.deepEqual(result13, expected1x, "An empty object cannot have any properties picked");    assert.deepEqual(result21, expected21, "An object with an empty omit list will have everything picked");    assert.deepEqual(result22, expected22, "An object with a subset omit list will have everything but those properties picked");    assert.deepEqual(result23, expected23, "An object with a complete omit list will have nothing picked");  });  test("`_deleteOwnProperties` will delete all owned enumerable properties", function(assert) {    assert.expect(24);    var getNonObjectKeys = function(obj) {      var prop,          keys = [];      if (obj) {        for (prop in obj) {          if (obj.hasOwnProperty(prop)) {            keys.push(prop);          }        }      }      return keys;    };    var getProtoKeys = function(obj) {      var prop,          keys = [];      if (obj) {        for (prop in obj) {          if (!obj.hasOwnProperty(prop)) {            keys.push(prop);          }        }      }      return keys;    };    var a = {      "a": "apple",      "c": "cantalope",      "d": "dragon fruit"    },    b = {},    c = ["banana", "cherry"],    d = (function() {      function SomePrototype() {        this.protoProp = "foo";      }      function SomeClass() {        this.ownedProp = "bar";      }      SomeClass.prototype = new SomePrototype();      SomeClass.prototype.constructor = SomeClass;      return new SomeClass();    })(),    e = null,    f; // = undefined;    assert.deepEqual(Object.keys(a), ["a", "c", "d"]);    assert.deepEqual(getProtoKeys(a), []);    _deleteOwnProperties(a);    assert.deepEqual(Object.keys(a), []);    assert.deepEqual(getProtoKeys(a), []);    assert.deepEqual(Object.keys(b), []);    assert.deepEqual(getProtoKeys(b), []);    _deleteOwnProperties(b);    assert.deepEqual(Object.keys(b), []);    assert.deepEqual(getProtoKeys(b), []);    assert.deepEqual(getNonObjectKeys(c), ["0", "1"]);    assert.deepEqual(getProtoKeys(c), []);    _deleteOwnProperties(c);    assert.deepEqual(getNonObjectKeys(c), []);    assert.deepEqual(getProtoKeys(c), []);    assert.deepEqual(Object.keys(d), ["ownedProp"]);    assert.deepEqual(getProtoKeys(d), ["protoProp", "constructor"]);    _deleteOwnProperties(d);    assert.deepEqual(Object.keys(d), []);    assert.deepEqual(getProtoKeys(d), ["protoProp", "constructor"]);    assert.deepEqual(getNonObjectKeys(e), []);    assert.deepEqual(getProtoKeys(e), []);    _deleteOwnProperties(e);    assert.deepEqual(getNonObjectKeys(e), []);    assert.deepEqual(getProtoKeys(e), []);    assert.deepEqual(getNonObjectKeys(f), []);    assert.deepEqual(getProtoKeys(f), []);    _deleteOwnProperties(f);    assert.deepEqual(getNonObjectKeys(f), []);    assert.deepEqual(getProtoKeys(f), []);  });  test("`_containedBy` works", function(assert) {    /*jshint camelcase:false */    assert.expect(29);    // Arrange    var fixture = document.getElementById("qunit-fixture");    fixture.innerHTML =      "<div id='container'>" +        "<div id='contained1'>" +          "<div id='contained1_1'></div>" +          "<div id='contained1_2'>" +            "<div id='contained1_2_1'></div>" +          "</div>" +        "</div>" +        "<div id='contained2'></div>" +      "</div>" +      "<div id='not_container'>" +        "<div id='not_contained'></div>" +      "</div>";    var container = document.getElementById("container");    var contained1 = document.getElementById("contained1");    var contained1_1 = document.getElementById("contained1_1");    var contained1_2 = document.getElementById("contained1_2");    var contained1_2_1 = document.getElementById("contained1_2_1");    var contained2 = document.getElementById("contained2");    var not_container = document.getElementById("not_container");    var not_contained = document.getElementById("not_contained");    // Act & Assert    assert.strictEqual(_containedBy(contained1_2_1, contained1_2_1), true);    assert.strictEqual(_containedBy(contained1_2_1, contained1_2), true);    assert.strictEqual(_containedBy(contained1_2_1, contained1), true);    assert.strictEqual(_containedBy(contained1_2_1, container), true);    assert.strictEqual(_containedBy(contained1_2_1, fixture), true);    assert.strictEqual(_containedBy(contained1_2_1, not_container), false);    assert.strictEqual(_containedBy(contained1_1, contained1_1), true);    assert.strictEqual(_containedBy(contained1_1, contained1), true);    assert.strictEqual(_containedBy(contained1_1, container), true);    assert.strictEqual(_containedBy(contained1_1, fixture), true);    assert.strictEqual(_containedBy(contained1_1, not_container), false);    assert.strictEqual(_containedBy(contained1, contained1), true);    assert.strictEqual(_containedBy(contained1, container), true);    assert.strictEqual(_containedBy(contained1, fixture), true);    assert.strictEqual(_containedBy(contained1, not_container), false);    assert.strictEqual(_containedBy(contained2, contained2), true);    assert.strictEqual(_containedBy(contained2, container), true);    assert.strictEqual(_containedBy(contained2, fixture), true);    assert.strictEqual(_containedBy(contained2, not_container), false);    assert.strictEqual(_containedBy(container, container), true);    assert.strictEqual(_containedBy(container, fixture), true);    assert.strictEqual(_containedBy(container, not_container), false);    assert.strictEqual(_containedBy(not_contained, not_contained), true);    assert.strictEqual(_containedBy(not_contained, not_container), true);    assert.strictEqual(_containedBy(not_contained, fixture), true);    assert.strictEqual(_containedBy(not_contained, container), false);    assert.strictEqual(_containedBy(not_container, not_container), true);    assert.strictEqual(_containedBy(not_container, fixture), true);    assert.strictEqual(_containedBy(not_container, container), false);  });  test("`_getDirPathOfUrl` works", function(assert) {    assert.expect(8);    // Arrange    var input1 = "http://example.com/blah/foo/index.html";    var input2 = "http://example.com/blah/foo/index.html?q=p";    var input3 = "http://example.com/blah/foo/index.html?q=p&x=z";    var input4 = "http://example.com/blah/foo/index.html?#xyz";    var input5 = "http://example.com/blah/foo/index.html?q=p#xyz";    var input6 = "http://example.com/blah/foo/index.html?q=p&x=z#xyz";    var input7 = "http://example.com/blah/foo/";    var input8 = "";    var expected1 = "http://example.com/blah/foo/";    var expected2 = "http://example.com/blah/foo/";    var expected3 = "http://example.com/blah/foo/";    var expected4 = "http://example.com/blah/foo/";    var expected5 = "http://example.com/blah/foo/";    var expected6 = "http://example.com/blah/foo/";    var expected7 = "http://example.com/blah/foo/";    var expected8;    // Act    var actual1 = _getDirPathOfUrl(input1);    var actual2 = _getDirPathOfUrl(input2);    var actual3 = _getDirPathOfUrl(input3);    var actual4 = _getDirPathOfUrl(input4);    var actual5 = _getDirPathOfUrl(input5);    var actual6 = _getDirPathOfUrl(input6);    var actual7 = _getDirPathOfUrl(input7);    var actual8 = _getDirPathOfUrl(input8);    // Assert    assert.strictEqual(actual1, expected1);    assert.strictEqual(actual2, expected2);    assert.strictEqual(actual3, expected3);    assert.strictEqual(actual4, expected4);    assert.strictEqual(actual5, expected5);    assert.strictEqual(actual6, expected6);    assert.strictEqual(actual7, expected7);    assert.strictEqual(actual8, expected8);  });  test("`_getCurrentScriptUrlFromErrorStack` works", function(assert) {    assert.expect(25);    // Arrange    var localStacks = [      "Error: my uncaught error\n    at http://example.com/index.html:123:4\n    at jQuery.event.dispatch (http://code.jquery.com/blah.js:567:8)\n    at foo",      "http://example.com/index.html:123:4\ndispatch@http://code.jquery.com/blah.js:567:8\nfoo",      "@http://example.com/index.html:123\ndispatch@http://code.jquery.com/blah.js:567\nfoo",      "<anonymous function>([arguments not available])@http://example.com/index.html:123\n<anonymous function: dispatch>([arguments not available])@http://code.jquery.com/blah.js:567\nfoo",      "Error: my error\n    at http://example.com/index.html:123\n    at http://code.jquery.com/blah.js:567\nfoo",      "Error(\"my error\")@:0\u000a([object Object])@http://example.com/index.html:123\u000a([object Object])@http://code.jquery.com/blah.js:567\u000afoo",      "Error: my error\n    at Anonymous function (http://example.com/index.html:123:4)\n    at dispatch (http://code.jquery.com/blah.js:567:8)\n    at foo",      "Error: my sneaky error message has a URL in it at http://google.com/mean.js:987\n    at Anonymous function (http://example.com/index.html:123:4)\n    at dispatch (http://code.jquery.com/blah.js:567:8)\n    at foo"    ];    var remoteStacks = [      "Error: my error\n    at window.onload (http://example.com/blah/foo.js:95:11)\n    at jQuery.event.dispatch (http://code.jquery.com/blah.js:567:8)\n    at foo",      "onload@http://example.com/blah/foo.js:95:11\ndispatch@http://code.jquery.com/blah.js:567:8\nfoo",      "onload@http://example.com/blah/foo.js:95\ndispatch@http://code.jquery.com/blah.js:567\nfoo",      "<anonymous function: window.onload>([arguments not available])@http://example.com/blah/foo.js:95\n<anonymous function: dispatch>([arguments not available])@http://code.jquery.com/blah.js:567\nfoo",      "Error: my error\n    at http://example.com/blah/foo.js:95\n    at http://code.jquery.com/blah.js:567\nfoo",      "Error(\"my error\")@:0\u000a@http://example.com/blah/foo.js:95\u000a([object Object])@http://code.jquery.com/blah.js:567\u000afoo",      "Error: my error\n    at onload (http://example.com/blah/foo.js:95:11)\n    at dispatch (http://code.jquery.com/blah.js:567:8)\n    at foo",      "Error: my sneaky error message has a URL in it at http://google.com/mean.js:987\n    at onload (http://example.com/blah/foo.js:95:11)\n    at dispatch (http://code.jquery.com/blah.js:567:8)\n    at foo"    ];    var badStacks = [      "blah",      "",      [],      {},      null,      undefined    ];    var localExpected = "http://example.com/index.html",        remoteExpected = "http://example.com/blah/foo.js",        badExpected;    // Act & Assert    assert.strictEqual(localStacks.length, 8, "Local stacks x 8");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(localStacks[0]), localExpected, "Inline script: Chrome");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(localStacks[1]), localExpected, "Inline script: Safari 6.1+");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(localStacks[2]), localExpected, "Inline script: Safari 6.0");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(localStacks[3]), localExpected, "Inline script: Opera");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(localStacks[4]), localExpected, "Inline script: PhantomJS");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(localStacks[5]), localExpected, "Inline script: Firefox 3.6");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(localStacks[6]), localExpected, "Inline script: IE 10.0");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(localStacks[7]), localExpected, "Inline script: SneakyError");    assert.strictEqual(remoteStacks.length, 8, "Remote stacks x 8");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(remoteStacks[0]), remoteExpected, "External script: Chrome");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(remoteStacks[1]), remoteExpected, "External script: Safari 6.1+");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(remoteStacks[2]), remoteExpected, "External script: Safari 6.0");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(remoteStacks[3]), remoteExpected, "External script: Opera");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(remoteStacks[4]), remoteExpected, "External script: PhantomJS");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(remoteStacks[5]), remoteExpected, "External script: Firefox 3.6");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(remoteStacks[6]), remoteExpected, "External script: IE 10.0");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(remoteStacks[7]), remoteExpected, "External script: SneakyError");    assert.strictEqual(badStacks.length, 6, "Bad stacks x 6");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(badStacks[0]), badExpected, "Useless stack");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(badStacks[1]), badExpected, "Empty string");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(badStacks[2]), badExpected, "Array");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(badStacks[3]), badExpected, "Object");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(badStacks[4]), badExpected, "`null`");    assert.strictEqual(_getCurrentScriptUrlFromErrorStack(badStacks[5]), badExpected, "`undefined`");  });  test("`_getCurrentScriptUrlFromError` works", function(assert) {    assert.expect(4);    // Arrange    var actual1, actual2, actual3, actual4;    var expected = "http://example.com/blah/foo.js";    var _sourceUrl, _fileName, _stack;    // Do NOT inherit from the real `Error` definition    _Error = function() {      this.sourceURL = _sourceUrl;      this.fileName = _fileName;      this.stack = _stack;    };    // Act    _sourceUrl = expected;    _fileName = undefined;    _stack = undefined;    actual1 = _getCurrentScriptUrlFromError();    _sourceUrl = undefined;    _fileName = expected;    _stack = undefined;    actual2 = _getCurrentScriptUrlFromError();    _sourceUrl = undefined;    _fileName = undefined;    _stack = "Error: my uncaught error\n    at " + expected + ":123:4\n    at jQuery.event.dispatch (http://code.jquery.com/blah.js:123:0)\n    at foo";    actual3 = _getCurrentScriptUrlFromError();    _sourceUrl = undefined;    _fileName = undefined;    _stack = undefined;    actual4 = _getCurrentScriptUrlFromError();    // Assert    assert.strictEqual(actual1, expected, "Current script derived from `err.sourceURL`");    assert.strictEqual(actual2, expected, "Current script derived from `err.fileName`");    assert.strictEqual(actual3, expected, "Current script derived from `err.stack`");    assert.strictEqual(actual4, undefined, "Current script cannot be derived from the Error");  });  test("`_getCurrentScriptUrl` works", function(assert) {    assert.expect(9);    // Arrange    var actual1, actual2, actual3, actual4, actual5, actual6, actual7, actual8, actual9;    var expected1, expected2, expected3, expected4, expected5, expected6, expected7, expected8, expected9;    expected1 = expected2 = expected3 = expected4 = expected5 = "http://example.com/blah/foo/bar.js";    // Arrange & Act    _document = {      currentScript: {        src: "http://example.com/blah/foo/bar.js"      }    };    _getCurrentScriptUrlFromError = function() {};    actual1 = _getCurrentScriptUrl();    _document = {      getElementsByTagName: function(/* tagName */)  {        return [          { src: "http://example.com/blah/foo/bar.js" }        ];      }    };    actual2 = _getCurrentScriptUrl();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js", readyState: "complete" },          { src: "http://example.com/blah/foo/bar.js", readyState: "interactive" }        ];      }    };    actual3 = _getCurrentScriptUrl();    _document = {      readyState: "loading",      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { src: "http://example.com/blah/wat.js" },          { src: "http://example.com/blah/foo/bar.js" }        ];      }    };    actual4 = _getCurrentScriptUrl();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { src: "http://example.com/blah/wat.js" },          { src: "http://example.com/blah/foo/bar.js" }        ];      }    };    _getCurrentScriptUrlFromError = function() {      return "http://example.com/blah/foo/bar.js";    };    actual5 = _getCurrentScriptUrl();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { src: "http://example.com/blah/wat.js" }        ];      }    };    _getCurrentScriptUrlFromError = function() {};    actual6 = _getCurrentScriptUrl();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { /* inline script */ },          { src: "http://example.com/blah/wat.js" }        ];      }    };    actual7 = _getCurrentScriptUrl();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { src: "http://example.com/blah/wat.js" },          { /* inline script */ }        ];      }    };    actual8 = _getCurrentScriptUrl();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { /* inline script */ }        ];      }    };    actual9 = _getCurrentScriptUrl();    assert.strictEqual(actual1, expected1, "Value from `document.currentScript`");    assert.strictEqual(actual2, expected2, "Value from the only script");    assert.strictEqual(actual3, expected3, "Value from `scripts[i].readyState === \"interactive\"`");    assert.strictEqual(actual4, expected4, "Value from last script while `document.readyState === \"loading\"");    assert.strictEqual(actual5, expected5, "Value from `_getCurrentScriptUrlFromError`");    assert.strictEqual(actual6, expected6, "No value can be confirmed");    assert.strictEqual(actual7, expected7, "No value can be confirmed as there is at least one inline script (middle)");    assert.strictEqual(actual8, expected8, "No value can be confirmed as there is at least one inline script (last)");    assert.strictEqual(actual9, expected9, "No value can be confirmed as the only script tag is an inline script");  });  test("`_getUnanimousScriptParentDir` works", function(assert) {    assert.expect(5);    // Arrange    var actual1, actual2, actual3, actual4, actual5;    var expected1, expected2, expected3, expected4, expected5;    var _scripts = [];    _document = {      getElementsByTagName: function(/* tagName */) {        return _scripts;      }    };    expected1 = "http://example.com/blah/";    // Arrange & Act    _scripts.length = 0;    _scripts.push.apply(_scripts, [      { src: "http://example.com/blah/foo.js" },      { src: "http://example.com/blah/wat.js" },      { src: "http://example.com/blah/bar.js" }    ]);    actual1 = _getUnanimousScriptParentDir();    _scripts.length = 0;    _scripts.push.apply(_scripts, [      { src: "http://example.org/blah/foo.js" },      { src: "http://example.net/blah/wat.js" },      { src: "http://example.com/blah/bar.js" }    ]);    actual2 = _getUnanimousScriptParentDir();    _scripts.length = 0;    _scripts.push.apply(_scripts, [      { src: "http://example.com/blah/foo.js" },      { src: "http://example.com/blah/wat.js" },      { src: "http://example.com/blah/foo/bar.js" }    ]);    actual3 = _getUnanimousScriptParentDir();    _scripts.length = 0;    _scripts.push.apply(_scripts, [      { src: "http://example.com/blah/foo.js" },      { /* inline script */ },      { src: "http://example.com/blah/foo/bar.js" }    ]);    actual4 = _getUnanimousScriptParentDir();    _scripts.length = 0;    _scripts.push.apply(_scripts, [      { src: "http://example.com/blah/foo.js" },      { src: "http://example.com/blah/wat.js" },      { /* inline script */ }    ]);    actual5 = _getUnanimousScriptParentDir();    // Assert    assert.strictEqual(actual1, expected1, "All script tags have the same parent directory");    assert.strictEqual(actual2, expected2, "Not all script tags have the same domains");    assert.strictEqual(actual3, expected3, "Not all script tags have the same parent directory");    assert.strictEqual(actual4, expected4, "Not all script tags have `src` URLs (middle)");    assert.strictEqual(actual5, expected5, "Not all script tags have `src` URLs (last)");  });  test("`_getDefaultSwfPath` works", function(assert) {    assert.expect(11);    // Arrange    var actual1, actual2, actual3, actual4, actual5, actual6, actual7, actual8, actual9, actual10, actual11;    var expected1, expected2, expected3, expected4, expected5, expected6, expected7, expected8, expected9, expected10, expected11;    expected1 = expected2 = expected3 = expected4 = expected5 = "http://example.com/blah/foo/ZeroClipboard.swf";    expected6 = "http://example.com/blah/ZeroClipboard.swf";    expected7 = expected8 = expected9 = expected10 = expected11 = "ZeroClipboard.swf";    // Arrange & Act    _document = {      currentScript: {        src: "http://example.com/blah/foo/bar.js"      }    };    actual1 = _getDefaultSwfPath();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo/bar.js" }        ];      }    };    actual2 = _getDefaultSwfPath();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js", readyState: "complete" },          { src: "http://example.com/blah/foo/bar.js", readyState: "interactive" }        ];      }    };    actual3 = _getDefaultSwfPath();    _document = {      readyState: "loading",      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { src: "http://example.com/blah/wat.js" },          { src: "http://example.com/blah/foo/bar.js" }        ];      }    };    actual4 = _getDefaultSwfPath();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { src: "http://example.com/blah/wat.js" },          { src: "http://example.com/blah/foo/bar.js" }        ];      }    };    _getCurrentScriptUrlFromError = function() {      return "http://example.com/blah/foo/bar.js";    };    actual5 = _getDefaultSwfPath();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { src: "http://example.com/blah/wat.js" },          { src: "http://example.com/blah/bar.js" }        ];      }    };    _getCurrentScriptUrlFromError = function() {};    actual6 = _getDefaultSwfPath();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.org/blah/foo.js" },          { src: "http://example.net/blah/wat.js" },          { src: "http://example.com/blah/bar.js" }        ];      }    };    actual7 = _getDefaultSwfPath();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { src: "http://example.com/blah/wat.js" },          { src: "http://example.com/blah/foo/bar.js" }        ];      }    };    actual8 = _getDefaultSwfPath();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { /* inline script */ },          { src: "http://example.com/blah/foo/bar.js" }        ];      }    };    actual9 = _getDefaultSwfPath();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { src: "http://example.com/blah/foo.js" },          { src: "http://example.com/blah/wat.js" },          { /* inline script */ }        ];      }    };    actual10 = _getDefaultSwfPath();    _document = {      getElementsByTagName: function(/* tagName */) {        return [          { /* inline script */ }        ];      }    };    actual11 = _getDefaultSwfPath();    assert.strictEqual(actual1, expected1, "Value derived from `document.currentScript`");    assert.strictEqual(actual2, expected2, "Value derived from the only script");    assert.strictEqual(actual3, expected3, "Value derived from `scripts[i].readyState === \"interactive\"`");    assert.strictEqual(actual4, expected4, "Value derived from last script while `document.readyState === \"loading\"");    assert.strictEqual(actual5, expected5, "Value derived from Error stack");    assert.strictEqual(actual6, expected6, "Value derived from confirming all scripts have the same parent directory");    assert.strictEqual(actual7, expected7, "No value can be confirmed due to differing script domains");    assert.strictEqual(actual8, expected8, "No value can be confirmed due to differing script parent directories");    assert.strictEqual(actual9, expected9, "No value can be confirmed due to the existence of inline scripts");    assert.strictEqual(actual10, expected10, "No value can be confirmed as the last script is an inline script");    assert.strictEqual(actual11, expected11, "No value can be confirmed as the only script is an inline script");  });})(QUnit.module, QUnit.test);
 |