summaryrefslogtreecommitdiffstats
path: root/dom/tests/mochitest/ajax/mochikit/tests
diff options
context:
space:
mode:
Diffstat (limited to 'dom/tests/mochitest/ajax/mochikit/tests')
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/FakeJSAN.js40
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Async.html408
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Base.html34
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Color.html84
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DOM.html316
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DateTime.html39
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DragAndDrop.html54
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Format.html39
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Iter.html38
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-JSAN.html32
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Logging.html40
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-MochiKit.html18
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Selector.html274
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Signal.html43
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Style.html141
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Visual.html190
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/SimpleTest.js473
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/TestRunner.js177
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/test.css28
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/cli.js6
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/index.html25
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/standalone.js16
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/test_Base.js509
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/test_Color.js137
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/test_DateTime.js45
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/test_DragAndDrop.js30
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/test_Format.js80
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/test_Iter.js176
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/test_Logging.js75
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/test_MochiKit-Async.json1
-rw-r--r--dom/tests/mochitest/ajax/mochikit/tests/test_Signal.js441
31 files changed, 4009 insertions, 0 deletions
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/FakeJSAN.js b/dom/tests/mochitest/ajax/mochikit/tests/FakeJSAN.js
new file mode 100644
index 0000000000..639519ecf0
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/FakeJSAN.js
@@ -0,0 +1,40 @@
+var JSAN = {
+ global: this,
+ use: function (module, symbols) {
+ var components = module.split(/\./);
+ var fn = components.join('/') + '.js';
+ var o = JSAN.global;
+ var i, c;
+ for (i = 0; i < components.length; i++) {
+ o = o[components[i]];
+ if (typeof(o) == 'undefined') {
+ break;
+ }
+ }
+ if (typeof(o) != 'undefined') {
+ return o;
+ }
+
+ load(fn);
+ o = JSAN.global;
+ for (i = 0; i < components.length; i++) {
+ o = o[components[i]];
+ if (typeof(o) == 'undefined') {
+ return undefined;
+ }
+ }
+ if (!symbols) {
+ var tags = o.EXPORT_TAGS;
+ if (tags) {
+ symbols = tags[':common'] || tags[':all'];
+ }
+ }
+ if (symbols) {
+ for (i = 0; i < symbols.length; i++) {
+ c = symbols[i];
+ JSAN.global[c] = o[c];
+ }
+ }
+ return o;
+ }
+};
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Async.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Async.html
new file mode 100644
index 0000000000..32889ea821
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Async.html
@@ -0,0 +1,408 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Async.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript">
+try {
+
+ var increment = function (res) {
+ return res + 1;
+ }
+
+ var throwStuff = function (res) {
+ throw new GenericError(res);
+ }
+
+ var catchStuff = function (res) {
+ return res.message;
+ }
+
+ var returnError = function (res) {
+ return new GenericError(res);
+ }
+
+ var anythingOkCallback = function (msg) {
+ return function (res) {
+ ok(true, msg);
+ return res;
+ }
+ }
+
+ var testEqCallback = function () {
+ /*
+ sort of emulate how deferreds work in Twisted
+ for "convenient" testing
+ */
+ var args = [];
+ for (var i = 0; i < arguments.length; i++) {
+ args.push(arguments[i]);
+ }
+ return function (res) {
+ var nargs = args.slice();
+ nargs.unshift(res);
+ is.apply(this, nargs);
+ return res;
+ }
+ }
+
+ var neverHappen = function (d) {
+ ok(false, "this should never happen");
+ }
+
+ /*
+ Test normal Deferred operation
+ */
+ var d = new Deferred();
+ d.addCallback(testEqCallback(1, "pre-deferred callback"));
+ d.callback(1);
+ d.addCallback(increment);
+ d.addCallback(testEqCallback(2, "post-deferred callback"));
+ d.addCallback(throwStuff);
+ d.addCallback(neverHappen);
+ d.addErrback(catchStuff);
+ d.addCallback(testEqCallback(2, "throw -> err, catch -> success"));
+ d.addCallback(returnError);
+ d.addCallback(neverHappen);
+ d.addErrback(catchStuff);
+ d.addCallback(testEqCallback(2, "return -> err, catch -> succcess"));
+
+ /*
+ Test Deferred cancellation
+ */
+ var cancelled = function (d) {
+ ok(true, "canceller called!");
+ }
+
+ var cancelledError = function (res) {
+ ok(res instanceof CancelledError, "CancelledError here");
+ }
+
+ d = new Deferred(cancelled);
+ d.addCallback(neverHappen);
+ d.addErrback(cancelledError);
+ d.cancel();
+
+ /*
+ Test succeed / fail
+ */
+
+ d = succeed(1).addCallback(testEqCallback(1, "succeed"));
+
+ // default error
+ d = fail().addCallback(neverHappen);
+ d = d.addErrback(anythingOkCallback("default fail"));
+
+ // default wrapped error
+ d = fail("web taco").addCallback(neverHappen).addErrback(catchStuff);
+ d = d.addCallback(testEqCallback("web taco", "wrapped fail"));
+
+ // default unwrapped error
+ d = fail(new GenericError("ugh")).addCallback(neverHappen).addErrback(catchStuff);
+ d = d.addCallback(testEqCallback("ugh", "unwrapped fail"));
+
+ /*
+ Test deferred dependencies
+ */
+
+ var deferredIncrement = function (res) {
+ var rval = succeed(res);
+ rval.addCallback(increment);
+ return rval;
+ }
+
+ d = succeed(1).addCallback(deferredIncrement);
+ d = d.addCallback(testEqCallback(2, "dependent deferred succeed"));
+
+ var deferredFailure = function (res) {
+ return fail(res);
+ }
+
+ d = succeed("ugh").addCallback(deferredFailure).addErrback(catchStuff);
+ d = d.addCallback(testEqCallback("ugh", "dependent deferred fail"));
+
+ /*
+ Test double-calling, double-failing, etc.
+ */
+ try {
+ succeed(1).callback(2);
+ neverHappen();
+ } catch (e) {
+ ok(e instanceof AlreadyCalledError, "double-call");
+ }
+ try {
+ fail(1).errback(2);
+ neverHappen();
+ } catch (e) {
+ ok(e instanceof AlreadyCalledError, "double-fail");
+ }
+ try {
+ d = succeed(1);
+ d.cancel();
+ d = d.callback(2);
+ ok(true, "swallowed one callback, no canceller");
+ d.callback(3);
+ neverHappen();
+ } catch (e) {
+ ok(e instanceof AlreadyCalledError, "swallow cancel");
+ }
+ try {
+ d = new Deferred(cancelled);
+ d.cancel();
+ d = d.callback(1);
+ neverHappen();
+ } catch (e) {
+ ok(e instanceof AlreadyCalledError, "non-swallowed cancel");
+ }
+
+ /* Test incorrect Deferred usage */
+
+ d = new Deferred();
+ try {
+ d.callback(new Deferred());
+ neverHappen();
+ } catch (e) {
+ ok (e instanceof Error, "deferred not allowed for callback");
+ }
+ d = new Deferred();
+ try {
+ d.errback(new Deferred());
+ neverHappen();
+ } catch (e) {
+ ok (e instanceof Error, "deferred not allowed for errback");
+ }
+
+ d = new Deferred();
+ (new Deferred()).addCallback(function () { return d; }).callback(1);
+ try {
+ d.addCallback(function () {});
+ neverHappen();
+ } catch (e) {
+ ok (e instanceof Error, "chained deferred not allowed to be re-used");
+ }
+
+ /*
+ evalJSONRequest test
+ */
+ var fakeReq = {"responseText":'[1,2,3,4,"asdf",{"a":["b", "c"]}]'};
+ var obj = [1,2,3,4,"asdf",{"a":["b", "c"]}];
+ isDeeply(obj, evalJSONRequest(fakeReq), "evalJSONRequest");
+
+ try {
+ MochiKit.Async.getXMLHttpRequest();
+ ok(true, "getXMLHttpRequest");
+ } catch (e) {
+ ok(false, "no love from getXMLHttpRequest");
+ }
+
+ var lock = new DeferredLock();
+ var lst = [];
+ var pushNumber = function (x) {
+ return function (res) { lst.push(x); }
+ };
+ lock.acquire().addCallback(pushNumber(1));
+ is( compare(lst, [1]), 0, "lock acquired" );
+ lock.acquire().addCallback(pushNumber(2));
+ is( compare(lst, [1]), 0, "lock waiting for release" );
+ lock.acquire().addCallback(pushNumber(3));
+ is( compare(lst, [1]), 0, "lock waiting for release" );
+ lock.release();
+ is( compare(lst, [1, 2]), 0, "lock passed on" );
+ lock.release();
+ is( compare(lst, [1, 2, 3]), 0, "lock passed on" );
+ lock.release();
+ try {
+ lock.release();
+ ok( false, "over-release didn't raise" );
+ } catch (e) {
+ ok( true, "over-release raised" );
+ }
+ lock.acquire().addCallback(pushNumber(1));
+ is( compare(lst, [1, 2, 3, 1]), 0, "lock acquired" );
+ lock.release();
+ is( compare(lst, [1, 2, 3, 1]), 0, "lock released" );
+
+ var d = new Deferred();
+ lst = [];
+ d.addCallback(operator.add, 2);
+ d.addBoth(operator.add, 4);
+ d.addCallback(bind(lst.push, lst));
+ d.callback(1);
+ is( lst[0], 7, "auto-partial addCallback addBoth" );
+ d.addCallback(function () { throw new Error(); });
+ ebTest = function(a, b) {
+ map(bind(lst.push, lst), arguments);
+ };
+ d.addErrback(ebTest, "foo");
+ is( lst[1], "foo", "auto-partial errback" );
+ is( lst.length, 3, "auto-partial errback" );
+
+ /*
+ Test DeferredList
+ */
+
+ var callList = [new Deferred(), new Deferred(), new Deferred()];
+ callList[0].addCallback(increment);
+ callList[1].addCallback(increment);
+ callList[2].addCallback(increment);
+ var defList = new DeferredList(callList);
+ ok(defList instanceof Deferred, "DeferredList looks like a Deferred");
+
+ callList[0].callback(3);
+ callList[1].callback(5);
+ callList[2].callback(4);
+
+ defList.addCallback(function (lst) {
+ is( arrayEqual(lst, [[true, 4], [true, 6], [true, 5]]), 1,
+ "deferredlist result ok" );
+ });
+
+ /*
+ Test fireOnOneCallback
+ */
+
+ var callList2 = [new Deferred(), new Deferred(), new Deferred()];
+ callList2[0].addCallback(increment);
+ callList2[1].addCallback(increment);
+ callList2[2].addCallback(increment);
+ var defList2 = new DeferredList(callList2, true);
+ callList2[1].callback(5);
+ callList2[0].callback(3);
+ callList2[2].callback(4);
+
+ defList2.addCallback(function (lst) {
+ is( arrayEqual(lst, [1, 6]), 1, "deferredlist fireOnOneCallback ok" );
+ });
+
+ /*
+ Test fireOnOneErrback
+ */
+
+ var callList3 = [new Deferred(), new Deferred(), new Deferred()];
+ callList3[0].addCallback(increment);
+ callList3[1].addCallback(throwStuff);
+ callList3[2].addCallback(increment);
+ var defList3 = new DeferredList(callList3, false, true);
+ defList3.callback = neverHappen;
+ callList3[0].callback(3);
+ callList3[1].callback("foo");
+ callList3[2].callback(4);
+
+ defList3.addErrback(function (err) {
+ is( err.message, "foo", "deferredlist fireOnOneErrback ok" );
+ });
+
+ /*
+ Test consumeErrors
+ */
+
+ var callList4 = [new Deferred(), new Deferred(), new Deferred()];
+ callList4[0].addCallback(increment);
+ callList4[1].addCallback(throwStuff);
+ callList4[2].addCallback(increment);
+ var defList4 = new DeferredList(callList4, false, false, true);
+ defList4.addErrback(neverHappen);
+ callList4[1].addCallback(function (arg) {
+ is(arg, null, "deferredlist consumeErrors ok" );
+ });
+ callList4[0].callback(3);
+ callList4[1].callback("foo");
+ callList4[2].callback(4);
+
+ /*
+ Test gatherResults
+ */
+
+ var callList5 = [new Deferred(), new Deferred(), new Deferred()];
+ callList5[0].addCallback(increment);
+ callList5[1].addCallback(increment);
+ callList5[2].addCallback(increment);
+ var gatherRet = gatherResults(callList5);
+ callList5[0].callback(3);
+ callList5[1].callback(5);
+ callList5[2].callback(4);
+
+ gatherRet.addCallback(function (lst) {
+ is( arrayEqual(lst, [4, 6, 5]), 1,
+ "gatherResults result ok" );
+ });
+
+ /*
+ Test maybeDeferred
+ */
+
+ var maybeDef = maybeDeferred(increment, 4);
+ maybeDef.addCallback(testEqCallback(5, "maybeDeferred sync ok"));
+
+ var maybeDef2 = deferredIncrement(8);
+ maybeDef2.addCallback(testEqCallback(9, "maybeDeferred async ok"));
+
+ ok( true, "synchronous test suite finished!");
+
+ var t = (new Date().getTime());
+ SimpleTest.waitForExplicitFinish();
+ checkCallLater = function (originalTime) {
+ is(originalTime, t, "argument passed in OK");
+ is(arguments.length, 1, "argument count right");
+ };
+ var lock = new DeferredLock();
+ withLock = function (msg) {
+ var cb = partial.apply(null, extend(null, arguments, 1));
+ var d = lock.acquire().addCallback(cb);
+ d.addErrback(ok, false, msg);
+ d.addCallback(function () {
+ ok(true, msg);
+ lock.release();
+ });
+ return d;
+ }
+ withLock("callLater", function () {
+ return callLater(0.05, checkCallLater, t);
+ });
+ withLock("wait", function () {
+ return wait(0.05, t).addCallback(checkCallLater);
+ });
+ withLock("loadJSONDoc", function () {
+ var d = loadJSONDoc("test_MochiKit-Async.json");
+ d.addCallback(function (doc) {
+ is(doc.passed, true, "loadJSONDoc passed");
+ });
+ d.addErrback(function (doc) {
+ ok(false, "loadJSONDoc failed");
+ });
+ return d;
+ });
+ lock.acquire().addCallback(function () {
+ ok(true, "async suite finished");
+ SimpleTest.finish();
+ });
+
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+ SimpleTest.finish();
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Base.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Base.html
new file mode 100644
index 0000000000..3db71e1e75
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Base.html
@@ -0,0 +1,34 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="test_Base.js"></script>
+<script type="text/javascript">
+try {
+ tests.test_Base({ok:ok,is:is});
+ ok( true, "test suite finished!");
+} catch (err) {
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Color.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Color.html
new file mode 100644
index 0000000000..bad32dfb18
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Color.html
@@ -0,0 +1,84 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="../MochiKit/Logging.js"></script>
+ <script type="text/javascript" src="../MochiKit/Color.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+ <style type="text/css">.redtext {color: red}</style>
+</head>
+<body>
+<div style="position:absolute; top: 0px; left:0px; width:0px; height:0px">
+ <span style="color: red" id="c_direct"></span>
+ <span class="redtext" id="c_indirect"></span>
+</div>
+<pre id="test">
+<script type="text/javascript" src="test_Color.js"></script>
+<script type="text/javascript">
+try {
+
+ var t = {ok:ok, is:is};
+ tests.test_Color({ok:ok, is:is});
+ is(
+ Color.fromText(SPAN()).toHexString(),
+ "#000000",
+ "fromText no style"
+ );
+
+ is(
+ Color.fromText("c_direct").toHexString(),
+ Color.fromName("red").toHexString(),
+ "fromText direct style"
+ );
+
+ is(
+ Color.fromText("c_indirect").toHexString(),
+ Color.fromName("red").toHexString(),
+ "fromText indirect style"
+ );
+
+ is(
+ Color.fromComputedStyle("c_direct", "color").toHexString(),
+ Color.fromName("red").toHexString(),
+ "fromComputedStyle direct style"
+ );
+
+ is(
+ Color.fromComputedStyle("c_indirect", "color").toHexString(),
+ Color.fromName("red").toHexString(),
+ "fromComputedStyle indirect style"
+ );
+
+ is(
+ Color.fromBackground((SPAN(null, 'test'))).toHexString(),
+ Color.fromName("white").toHexString(),
+ "fromBackground with DOM"
+ );
+
+
+ // Done!
+
+ ok( true, "test suite finished!");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DOM.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DOM.html
new file mode 100644
index 0000000000..45036d9c74
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DOM.html
@@ -0,0 +1,316 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/MockDOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+</head>
+<body>
+
+<div style="display: none;">
+ <form id="form_test">
+ <select name="select">
+ <option value="foo" selected="selected">foo</option>
+ <option value="bar">bar</option>
+ <option value="baz">baz</option>
+ </select>
+ <select name="selmultiple" multiple="multiple">
+ <option value="bar" selected="selected">bar</option>
+ <option value="baz" selected="selected">baz</option>
+ <option value="foo">foo</option>
+ </select>
+ <input type="hidden" name="hidden" value="test" />
+ <input type="radio" name="radio_off" value="1" />
+ <input type="radio" name="radio_off" value="2" />
+ <input type="radio" name="radio_off" value="3" />
+ <input type="radio" name="radio_on" value="1" />
+ <input type="radio" name="radio_on" value="2" checked="checked" />
+ <input type="radio" name="radio_on" value="3" />
+ </form>
+ <form id="form_test2">
+ <select name="selempty">
+ <option value="" selected="selected">foo</option>
+ </select>
+ <select name="selempty2">
+ <option selected="selected">foo</option>
+ </select>
+ </form>
+ <div id="parentTwo" class="two">
+ <div id="parentOne" class="one">
+ <div id="parentZero" class="zero">
+ <span id="child">child</span>
+ </div>
+ </div>
+ </div>
+</div>
+
+<pre id="test">
+<script type="text/javascript">
+try {
+
+ lst = [];
+ o = {"blah": function () { lst.push("original"); }};
+ addToCallStack(o, "blah", function () { lst.push("new"); }, true);
+ addToCallStack(o, "blah", function () { lst.push("stuff"); }, true);
+ is( typeof(o.blah), 'function', 'addToCallStack has a function' );
+ is( o.blah.callStack.length, 3, 'callStack length 3' );
+ o.blah();
+ is( lst.join(" "), "original new stuff", "callStack in correct order" );
+ is( o.blah, null, "set to null" );
+ lst = [];
+ o = {"blah": function () { lst.push("original"); }};
+ addToCallStack(o, "blah",
+ function () { lst.push("new"); return false;}, false);
+ addToCallStack(o, "blah", function () { lst.push("stuff"); }, false);
+ o.blah();
+ is( lst.join(" "), "original new", "callStack in correct order (abort)" );
+ o.blah();
+ is( lst.join(" "), "original new original new", "callStack in correct order (again)" );
+
+
+ is( escapeHTML("<>\"&bar"), "&lt;&gt;&quot;&amp;bar", "escapeHTML" ); // for emacs highlighting: "
+
+ var isDOM = function (value, expected, message) {
+ is( escapeHTML(toHTML(value)), escapeHTML(expected), message );
+ };
+
+ var d = document.createElement('span');
+ updateNodeAttributes(d, {"foo": "bar", "baz": "wibble"});
+ isDOM( d, '<span baz="wibble" foo="bar"/>', "updateNodeAttributes" );
+
+ var d = document.createElement('span');
+ appendChildNodes(d, 'word up', [document.createElement('span')]);
+ isDOM( d, '<span>word up<span/></span>', 'appendChildNodes' );
+
+ replaceChildNodes(d, 'Think Different');
+ isDOM( d, '<span>Think Different</span>', 'replaceChildNodes' );
+
+
+ insertSiblingNodesBefore(d.childNodes[0], 'word up', document.createElement('span'));
+ isDOM( d, '<span>word up<span/>Think Different</span>', 'insertSiblingNodesBefore' );
+
+ insertSiblingNodesAfter(d.childNodes[0], 'purple monkey', document.createElement('span'));
+ isDOM( d, '<span>word uppurple monkey<span/><span/>Think Different</span>', 'insertSiblingNodesAfter' );
+
+ d = createDOM("span");
+ isDOM( d, "<span/>", "createDOM empty" );
+
+
+ d = createDOM("span", {"foo": "bar", "baz": "wibble"});
+ isDOM( d, '<span baz="wibble" foo="bar"/>', "createDOM attributes" );
+
+ d = createDOM("span", {"foo": "bar", "baz": "wibble", "spam": "egg"}, "one", "two", "three");
+ is( getNodeAttribute(d, 'foo'), "bar", "createDOM attribute" );
+ is( getNodeAttribute(d, 'baz'), "wibble", "createDOM attribute" );
+ removeNodeAttribute(d, "spam");
+ is( scrapeText(d), "onetwothree", "createDOM contents" );
+
+ isDOM( d, '<span baz="wibble" foo="bar">onetwothree</span>', "createDOM contents" );
+
+ d = createDOM("span", null, function (f) {
+ return this.nodeName.toLowerCase() + "hi" + f.nodeName.toLowerCase();});
+ isDOM( d, '<span>spanhispan</span>', 'createDOM function call' );
+
+ d = createDOM("span", null, {msg: "hi", dom: function (f) {
+ return f.nodeName.toLowerCase() + this.msg; }});
+ isDOM( d, '<span>spanhi</span>', 'createDOM this.dom() call' );
+
+ d = createDOM("span", null, {msg: "hi", __dom__: function (f) {
+ return f.nodeName.toLowerCase() + this.msg; }});
+ isDOM( d, '<span>spanhi</span>', 'createDOM this.__dom__() call' );
+
+ d = createDOM("span", null, range(4));
+ isDOM( d, '<span>0123</span>', 'createDOM iterable' );
+
+
+ var d = {"taco": "pork"};
+ registerDOMConverter("taco",
+ function (o) { return !isUndefinedOrNull(o.taco); },
+ function (o) { return "Goddamn, I like " + o.taco + " tacos"; }
+ );
+ d = createDOM("span", null, d);
+ // not yet public API
+ domConverters.unregister("taco");
+
+ isDOM( d, "<span>Goddamn, I like pork tacos</span>", "createDOM with custom converter" );
+
+ is(
+ escapeHTML(toHTML(SPAN(null))),
+ escapeHTML(toHTML(createDOM("span", null))),
+ "createDOMFunc vs createDOM"
+ );
+
+ is( scrapeText(d), "Goddamn, I like pork tacos", "scrape OK" );
+ is( scrapeText(d, true).join(""), "Goddamn, I like pork tacos", "scrape Array OK" );
+
+ var st = DIV(null, STRONG(null, "d"), "oor ", STRONG(null, "f", SPAN(null, "r"), "a"), "me");
+ is( scrapeText(st), "door frame", "scrape in-order" );
+
+
+ ok( !isUndefinedOrNull(getElement("test")), "getElement might work" );
+ ok( !isUndefinedOrNull($("test")), "$alias$$ CASH MONEY alias might work" );
+
+ d = createDOM("span", null, "one", "two");
+ swapDOM(d.childNodes[0], document.createTextNode("uno"));
+ isDOM( d, "<span>unotwo</span>", "swapDOM" );
+
+ is( scrapeText(d, true).join(" "), "uno two", "multi-node scrapeText" );
+ /*
+
+ TODO:
+ addLoadEvent (async test?)
+
+ */
+
+ d = createDOM("span", {"class": "foo"});
+ setElementClass(d, "bar baz");
+ ok( d.className == "bar baz", "setElementClass");
+ toggleElementClass("bar", d);
+ ok( d.className == "baz", "toggleElementClass: " + d.className);
+ toggleElementClass("bar", d);
+ ok( hasElementClass(d, "baz", "bar"),
+ "toggleElementClass 2: " + d.className);
+ addElementClass(d, "bar");
+ ok( hasElementClass(d, "baz", "bar"),
+ "toggleElementClass 3: " + d.className);
+ ok( addElementClass(d, "blah"), "addElementClass return");
+ ok( hasElementClass(d, "baz", "bar", "blah"), "addElementClass action");
+ ok( !hasElementClass(d, "not"), "hasElementClass single");
+ ok( !hasElementClass(d, "baz", "not"), "hasElementClass multiple");
+ ok( removeElementClass(d, "blah"), "removeElementClass" );
+ ok( !removeElementClass(d, "blah"), "removeElementClass again" );
+ ok( !hasElementClass(d, "blah"), "removeElementClass again (hasElement)" );
+ removeElementClass(d, "baz");
+ ok( !swapElementClass(d, "blah", "baz"), "false swapElementClass" );
+ ok( !hasElementClass(d, "baz"), "false swapElementClass from" );
+ ok( !hasElementClass(d, "blah"), "false swapElementClass to" );
+ addElementClass(d, "blah");
+ ok( swapElementClass(d, "blah", "baz"), "swapElementClass" );
+ ok( hasElementClass(d, "baz"), "swapElementClass has toClass" );
+ ok( !hasElementClass(d, "blah"), "swapElementClass !has fromClass" );
+ ok( !swapElementClass(d, "blah", "baz"), "swapElementClass twice" );
+ ok( hasElementClass(d, "baz"), "swapElementClass has toClass" );
+ ok( !hasElementClass(d, "blah"), "swapElementClass !has fromClass" );
+
+ TABLE;
+ TBODY;
+ TR;
+ var t = TABLE(null,
+ TBODY({"class": "foo bar", "id":"tbody0"},
+ TR({"class": "foo", "id":"tr0"}),
+ TR({"class": "bar", "id":"tr1"})
+ )
+ );
+
+ var matchElements = getElementsByTagAndClassName;
+ is(
+ map(itemgetter("id"), matchElements(null, "foo", t)).join(" "),
+ "tbody0 tr0",
+ "getElementsByTagAndClassName found all tags with foo class"
+ );
+ is(
+ map(itemgetter("id"), matchElements("tr", "foo", t)).join(" "),
+ "tr0",
+ "getElementsByTagAndClassName found all tr tags with foo class"
+ );
+ is(
+ map(itemgetter("id"), matchElements("tr", null, t)).join(" "),
+ "tr0 tr1",
+ "getElementsByTagAndClassName found all tr tags"
+ );
+
+ var oldDoc = document;
+ var doc = MochiKit.MockDOM.createDocument();
+ is( currentDocument(), document, "currentDocument() correct" );
+ withDocument(doc, function () {
+ ok( document != doc, "global doc unchanged" );
+ is( currentDocument(), doc, "currentDocument() correct" );
+ var h1 = H1();
+ var span = SPAN(null, "foo", h1);
+ appendChildNodes(currentDocument().body, span);
+ });
+ is( document, oldDoc, "doc restored" );
+ is( doc.childNodes.length, 1, "doc has one child" );
+ is( doc.body.childNodes.length, 1, "body has one child" );
+ var sp = doc.body.childNodes[0];
+ is( sp.nodeName, "SPAN", "only child is SPAN" );
+ is( sp.childNodes.length, 2, "SPAN has two childNodes" );
+ is( sp.childNodes[0].nodeValue, "foo", "first node is text" );
+ is( sp.childNodes[1].nodeName, "H1", "second child is H1" );
+
+ is( currentDocument(), document, "currentDocument() correct" );
+ try {
+ withDocument(doc, function () {
+ ok( document != doc, "global doc unchanged" );
+ is( currentDocument(), doc, "currentDocument() correct" );
+ throw new Error("foo");
+ });
+ ok( false, "didn't throw" );
+ } catch (e) {
+ ok( true, "threw" );
+ }
+
+ var mockWindow = {"foo": "bar"};
+ is (currentWindow(), window, "currentWindow ok");
+ withWindow(mockWindow, function () {
+ is(currentWindow(), mockWindow, "withWindow ok");
+ });
+ is (currentWindow(), window, "currentWindow ok");
+
+ doc = MochiKit.MockDOM.createDocument();
+ var frm;
+ withDocument(doc, function () {
+ frm = FORM({name: "ignore"},
+ INPUT({name:"foo", value:"bar"}),
+ INPUT({name:"foo", value:"bar"}),
+ INPUT({name:"baz", value:"bar"})
+ );
+ });
+ var kv = formContents(frm);
+ is( kv[0].join(","), "foo,foo,baz", "mock formContents names" );
+ is( kv[1].join(","), "bar,bar,bar", "mock formContents values" );
+ is( queryString(frm), "foo=bar&foo=bar&baz=bar", "mock queryString hook" );
+
+ var kv = formContents("form_test");
+ is( kv[0].join(","), "select,selmultiple,selmultiple,hidden,radio_on", "formContents names" );
+ is( kv[1].join(","), "foo,bar,baz,test,2", "formContents values" );
+ is( queryString("form_test"), "select=foo&selmultiple=bar&selmultiple=baz&hidden=test&radio_on=2", "queryString hook" );
+ kv = formContents("form_test2");
+ is( kv[0].join(","), "selempty,selempty2", "formContents names empty option values" );
+ is( kv[1].join(","), ",foo", "formContents empty option values" );
+ is( queryString("form_test2"), "selempty=&selempty2=foo", "queryString empty option values" );
+
+ var d = DIV(null, SPAN(), " \n\t", SPAN(), "foo", SPAN(), " ");
+ is( d.childNodes.length, 6, "removeEmptyNodes test conditions correct" );
+ removeEmptyTextNodes(d);
+ is( d.childNodes.length, 4, "removeEmptyNodes" );
+
+ is( getFirstParentByTagAndClassName('child', 'div', 'two'), getElement("parentTwo"), "getFirstParentByTagAndClassName found parent" );
+ is( getFirstParentByTagAndClassName('child', 'div'), getElement("parentZero"), "getFirstParentByTagAndClassName found parent (any class)" );
+ is( getFirstParentByTagAndClassName('child', '*', 'two'), getElement("parentTwo"), "getFirstParentByTagAndClassName found parent (any tag)" );
+
+ ok( true, "test suite finished!");
+
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DateTime.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DateTime.html
new file mode 100644
index 0000000000..43ad9d4abd
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DateTime.html
@@ -0,0 +1,39 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/DateTime.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="test_DateTime.js"></script>
+<script type="text/javascript">
+try {
+
+ tests.test_DateTime({ok:ok, is:is});
+ ok( true, "test suite finished!");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DragAndDrop.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DragAndDrop.html
new file mode 100644
index 0000000000..a191a53bee
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-DragAndDrop.html
@@ -0,0 +1,54 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="../MochiKit/Color.js"></script>
+ <script type="text/javascript" src="../MochiKit/Signal.js"></script>
+ <script type="text/javascript" src="../MochiKit/Visual.js"></script>
+ <script type="text/javascript" src="../MochiKit/DragAndDrop.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+ <style type="text/css">
+ .drop-hover {
+ }
+ #drag1 {
+ visibility: hidden;
+ }
+ #drop1 {
+ visibility: hidden;
+ }
+ </style>
+</head>
+<body>
+<div id='drag1'>drag1</div>
+<div id='drop1'>drop1</div>
+<pre id="test">
+<script type="text/javascript" src="test_DragAndDrop.js"></script>
+<script type="text/javascript">
+try {
+
+ // Counting the number of tests is really lame
+ tests.test_DragAndDrop({ok:ok, is:is});
+ ok( true, "test suite finished!");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Format.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Format.html
new file mode 100644
index 0000000000..58bffa6bf8
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Format.html
@@ -0,0 +1,39 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Format.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="test_Format.js"></script>
+<script type="text/javascript">
+try {
+
+ tests.test_Format({ok:ok, is:is});
+ ok( true, "test suite finished!");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Iter.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Iter.html
new file mode 100644
index 0000000000..8086acc2db
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Iter.html
@@ -0,0 +1,38 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="test_Iter.js"></script>
+<script type="text/javascript">
+try {
+
+ tests.test_Iter({ok:ok, is:is});
+ ok( true, "test suite finished!");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-JSAN.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-JSAN.html
new file mode 100644
index 0000000000..53a0e0ed04
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-JSAN.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+ <script type="text/javascript" src="JSAN.js"></script>
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript">
+ // TODO: Make this a harness for the other tests
+ JSAN.use('Test.More');
+ JSAN.addRepository('..');
+ var lst = [];
+ plan({"tests": 1});
+ var wc = {};
+ wc['MochiKit'] = true;
+ for (var k in window) { wc[k] = true; }
+ for (var k in window) { wc[k] = true; }
+ JSAN.use('MochiKit.MochiKit', []);
+ for (var k in window) {
+ if (!(k in wc) && !(k.charAt(0) == '[')) {
+ lst.push(k);
+ }
+ }
+ lst.sort();
+ pollution = lst.join(" ");
+ is(pollution, "compare reduce", "namespace pollution?");
+ JSAN.use('MochiKit.MochiKit');
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Logging.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Logging.html
new file mode 100644
index 0000000000..d92229a6e0
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Logging.html
@@ -0,0 +1,40 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Logging.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="test_Logging.js"></script>
+<script type="text/javascript">
+try {
+
+ tests.test_Logging({ok:ok, is:is});
+ ok( true, "test suite finished!");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-MochiKit.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-MochiKit.html
new file mode 100644
index 0000000000..d1a8b60d89
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-MochiKit.html
@@ -0,0 +1,18 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript">
+ is( isUndefined(null), false, "null is not undefined" );
+ is( isUndefined(""), false, "empty string is not undefined" );
+ is( isUndefined(undefined), true, "undefined is undefined" );
+ is( isUndefined({}.foo), true, "missing property is undefined" );
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Selector.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Selector.html
new file mode 100644
index 0000000000..503acef071
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Selector.html
@@ -0,0 +1,274 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/MockDOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="../MochiKit/Selector.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+ <style type="text/css">
+ p, #sequence {
+ display: none;
+ }
+ </style>
+</head>
+<body>
+ <p>Test originally from <a href="http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector" rel="bookmark">this blog entry</a>.</p>
+
+ <p>Here are some links in a normal paragraph: <a href="http://www.google.com/" title="Google!">Google</a>, <a href="http://groups.google.com/">Google Groups</a>. This link has <code>class="blog"</code>: <a href="http://diveintomark.org/" class="blog" fakeattribute="bla">diveintomark</a></p>
+ <div id="foo">
+ <p>Everything inside the red border is inside a div with <code>id="foo"</code>.</p>
+ <p>This is a normal link: <a href="http://www.yahoo.com/">Yahoo</a></p>
+
+ <a style="display: none" href="http://www.example.com/outsidep">This a is not inside a p</a>
+
+ <p>This link has <code>class="blog"</code>: <a href="http://simon.incutio.com/" class="blog">Simon Willison's Weblog</a></p>
+ <p>This <span><a href="http://www.example.com/insidespan">link</a></span> is inside a span, not directly child of p</p>
+ <p lang="en-us">Nonninn</p>
+ <p lang="is-IS">Sniðugt</p>
+ <p>
+ <input type="button" name="enabled" value="enabled" id="enabled">
+ <input type="button" name="disabled" value="disabled" id="disabled" disabled="1" />
+ <input type="checkbox" name="checked" value="checked" id="checked" checked="1" />
+ </p>
+ </div>
+
+ <div id="sequence">
+ <a href="http://www.example.com/link1">Link 1</a>
+ <a href="http://www.example.com/link2">Link 2</a>
+ <a href="http://www.example.com/link3">Link 3</a>
+ <a href="http://www.example.com/link4">Link 4</a>
+ <p>Something else</p>
+ <a href="http://www.example.com/link5">Link 5</a>
+ <a href="http://www.example.com/link6">Link 6</a>
+ <a href="http://www.example.com/link7">Link 7</a>
+ <a href="http://www.example.com/link8">Link 8</a>
+ </div>
+
+ <div id="multiclass" class="multiple classnames here"></div>
+<pre id="test">
+<script type="text/javascript">
+try {
+
+ var testExpected = function (res, exp, lbl) {
+ for (var i=0; i < res.length; i ++) {
+ is( res[i].href, exp[i], lbl + ' (' + i + ')');
+ }
+ };
+
+ var expected = ['http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector',
+ 'http://www.google.com/',
+ 'http://groups.google.com/',
+ 'http://diveintomark.org/',
+ 'http://www.yahoo.com/',
+ 'http://www.example.com/outsidep',
+ 'http://simon.incutio.com/',
+ 'http://www.example.com/insidespan',
+ 'http://www.example.com/link1',
+ 'http://www.example.com/link2',
+ 'http://www.example.com/link3',
+ 'http://www.example.com/link4',
+ 'http://www.example.com/link5',
+ 'http://www.example.com/link6',
+ 'http://www.example.com/link7',
+ 'http://www.example.com/link8'];
+ var results = $$('a');
+ testExpected(results, expected, "'a' selector");
+
+ expected = ['http://diveintomark.org/', 'http://simon.incutio.com/'];
+ results = $$('p a.blog');
+ testExpected(results, expected, "'p a.blog' selector");
+
+ expected = ['http://www.yahoo.com/',
+ 'http://www.example.com/outsidep',
+ 'http://simon.incutio.com/',
+ 'http://www.example.com/insidespan',
+ 'http://www.example.com/link1',
+ 'http://www.example.com/link2',
+ 'http://www.example.com/link3',
+ 'http://www.example.com/link4',
+ 'http://www.example.com/link5',
+ 'http://www.example.com/link6',
+ 'http://www.example.com/link7',
+ 'http://www.example.com/link8'];
+ results = $$('div a');
+ testExpected(results, expected, "'div a' selector");
+
+ expected = ['http://www.yahoo.com/',
+ 'http://www.example.com/outsidep',
+ 'http://simon.incutio.com/',
+ 'http://www.example.com/insidespan'];
+ results = $$('div#foo a');
+ testExpected(results, expected, "'div#foo a' selector");
+
+ expected = ['http://simon.incutio.com/',
+ 'http://www.example.com/insidespan'];
+ results = $$('#foo a.blog');
+ testExpected(results, expected, "'#foo a.blog' selector");
+
+ expected = ['http://diveintomark.org/',
+ 'http://simon.incutio.com/',
+ 'http://www.example.com/insidespan'];
+ results = $$('.blog');
+ testExpected(results, expected, "'.blog' selector");
+
+ expected = ['http://www.google.com/',
+ 'http://www.yahoo.com/',
+ 'http://www.example.com/outsidep',
+ 'http://www.example.com/insidespan',
+ 'http://www.example.com/link1',
+ 'http://www.example.com/link2',
+ 'http://www.example.com/link3',
+ 'http://www.example.com/link4',
+ 'http://www.example.com/link5',
+ 'http://www.example.com/link6',
+ 'http://www.example.com/link7',
+ 'http://www.example.com/link8'];
+ results = $$('a[href^="http://www"]');
+ testExpected(results, expected, "'a[href^=http://www]' selector");
+
+ expected = ['http://diveintomark.org/'];
+ results = $$('a[href$="org/"]');
+ testExpected(results, expected, "'a[href$=org/]' selector");
+
+ expected = ['http://www.google.com/',
+ 'http://groups.google.com/'];
+ results = $$('a[href*="google"]');
+ testExpected(results, expected, "'a[href*=google]' selector");
+
+ expected = ['http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector'];
+ results = $$('a[rel="bookmark"]');
+ testExpected(results, expected, "'a[rel=bookmark]' selector");
+
+ expected = ['http://diveintomark.org/'];
+ results = $$('a[fakeattribute]');
+ testExpected(results, expected, "'a[fakeattribute]' selector");
+
+ /* This doesn't work in IE due to silly DOM implementation
+ expected = ['http://www.google.com/'];
+ results = $$('a[title]');
+ testExpected(results, expected, "'a[title]' selector");
+ */
+
+ results = $$('p[lang|="en"]');
+ is( results[0].firstChild.nodeValue, 'Nonninn', "'p[lang|=en]' selector");
+
+ expected = ['http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector',
+ 'http://www.google.com/',
+ 'http://groups.google.com/',
+ 'http://diveintomark.org/',
+ 'http://www.yahoo.com/',
+ 'http://simon.incutio.com/',
+ 'http://www.example.com/insidespan'];
+ results = $$('p > a');
+ testExpected(results, expected, "'p > a' selector");
+
+ expected = ['http://www.example.com/insidespan'];
+ results = $$('span > a');
+ testExpected(results, expected, "'span > a' selector");
+
+ expected = ['http://groups.google.com/',
+ 'http://www.example.com/link2',
+ 'http://www.example.com/link3',
+ 'http://www.example.com/link4',
+ 'http://www.example.com/link6',
+ 'http://www.example.com/link7',
+ 'http://www.example.com/link8'];
+ results = $$('a + a');
+ testExpected(results, expected, "'a + a' selector");
+
+ expected = ['http://www.example.com/link1',
+ 'http://www.example.com/link3',
+ 'http://www.example.com/link6',
+ 'http://www.example.com/link8'];
+ results = $$('#sequence a:nth-child(odd)');
+ testExpected(results, expected, "'#sequence a:nth-child(odd)' selector");
+
+ expected = ['http://www.example.com/link1',
+ 'http://www.example.com/link3',
+ 'http://www.example.com/link5',
+ 'http://www.example.com/link7'];
+ results = $$('#sequence a:nth-of-type(odd)');
+ testExpected(results, expected, "'#sequence a:nth-of-type(odd)' selector");
+
+ expected = ['http://www.example.com/link1',
+ 'http://www.example.com/link4',
+ 'http://www.example.com/link7'];
+ results = $$('#sequence a:nth-of-type(3n+1)');
+ testExpected(results, expected, "'#sequence a:nth-of-type(3n+1)' selector");
+
+ expected = ['http://www.example.com/link5'];
+ results = $$('#sequence a:nth-child(6)');
+ testExpected(results, expected, "'#sequence a:nth-child(6)' selector");
+
+ expected = ['http://www.example.com/link5'];
+ results = $$('#sequence a:nth-of-type(5)');
+ testExpected(results, expected, "'#sequence a:nth-of-type(5)' selector");
+
+ expected = [$('enabled'), $('checked')];
+ results = $$('body :enabled');
+ for (var i=0; i < results.length; i ++) {
+ is( results[i], expected[i], "'body :enabled" + ' (' + i + ')');
+ }
+
+ expected = [$('disabled')];
+ results = $$('body :disabled');
+ for (var i=0; i < results.length; i ++) {
+ is( results[i], expected[i], "'body :disabled" + ' (' + i + ')');
+ }
+
+ expected = [$('checked')];
+ results = $$('body :checked');
+ for (var i=0; i < results.length; i ++) {
+ is( results[i], expected[i], "'body :checked" + ' (' + i + ')');
+ }
+
+ expected = document.getElementsByTagName('p');
+ results = $$('a[href$=outsidep] ~ *');
+ for (var i=0; i < results.length; i ++) {
+ is( results[i], expected[i+4], "'a[href$=outsidep] ~ *' selector" + ' (' + i + ')');
+ }
+
+ expected = [document.documentElement];
+ results = $$(':root');
+ for (var i=0; i < results.length; i ++) {
+ is( results[i], expected[i], "':root' selector" + ' (' + i + ')');
+ }
+
+ expected = [$('multiclass')];
+ results = $$('[class~=classnames]');
+ for (var i=0; i < results.length; i ++) {
+ is( results[i], expected[i], "'~=' attribute test" + ' (' + i + ')');
+ }
+
+ var doc = MochiKit.MockDOM.createDocument();
+ appendChildNodes(doc.body, A({"href": "http://www.example.com/insideAnotherDocument"}, "Inside a document"));
+ withDocument(doc, function(){
+ is( $$(":root")[0], doc, ":root on a different document" );
+ is( $$("a")[0], doc.body.firstChild, "a inside a different document" );
+ });
+
+ ok( true, "test suite finished!");
+
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Signal.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Signal.html
new file mode 100644
index 0000000000..9c37416d68
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Signal.html
@@ -0,0 +1,43 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="../MochiKit/Signal.js"></script>
+ <script type="text/javascript" src="../MochiKit/Logging.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+
+</head>
+<body>
+
+Please ignore this button: <input type="submit" id="submit" /><br />
+
+<pre id="test">
+<script type="text/javascript" src="test_Signal.js"></script>
+<script type="text/javascript">
+try {
+
+ tests.test_Signal({ok:ok, is:is});
+ ok(true, "test suite finished!");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok(false, s);
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Style.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Style.html
new file mode 100644
index 0000000000..b01adc6e7e
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Style.html
@@ -0,0 +1,141 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/MockDOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="../MochiKit/Color.js"></script>
+ <script type="text/javascript" src="../MochiKit/Logging.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+</head>
+<body style="border: 0; margin: 0; padding: 0;">
+
+<div id="styleTest" style="position: absolute; left: 400px; top: 100px; width: 100px; height: 100px; background: rgb(255, 0, 0); opacity: 0.5; filter: alpha(opacity=50); font-size: 10px">TEST<span id="styleSubTest">SUB</span></div>
+
+<pre id="test">
+<script type="text/javascript">
+
+try {
+
+ // initial
+ var pos = getElementPosition('styleTest');
+ is(pos.x, 400, 'initial x position');
+ is(pos.y, 100, 'initial y position');
+
+ // moved
+ var newPos = new MochiKit.Style.Coordinates(500, 200);
+ setElementPosition('styleTest', newPos);
+ pos = getElementPosition('styleTest');
+ is(pos.x, 500, 'updated x position');
+ is(pos.y, 200, 'updated y position');
+
+ // moved with relativeTo
+ anotherPos = new MochiKit.Style.Coordinates(100, 100);
+ pos = getElementPosition('styleTest', anotherPos);
+ is(pos.x, 400, 'updated x position (using relativeTo parameter)');
+ is(pos.y, 100, 'updated y position (using relativeTo parameter)');
+
+ // Coordinates object
+ pos = getElementPosition({x: 123, y: 321});
+ is(pos.x, 123, 'passthrough x position');
+ is(pos.y, 321, 'passthrough y position');
+
+ // Coordinates object with relativeTo
+ pos = getElementPosition({x: 123, y: 321}, {x: 100, y: 50});
+ is(pos.x, 23, 'passthrough x position (using relativeTo parameter)');
+ is(pos.y, 271, 'passthrough y position (using relativeTo parameter)');
+
+ pos = getElementPosition('garbage');
+ is(typeof(pos), 'undefined',
+ 'invalid element should return an undefined position');
+
+ // Only set one coordinate
+ setElementPosition('styleTest', {'x': 300});
+ pos = getElementPosition('styleTest');
+ is(pos.x, 300, 'updated only x position');
+ is(pos.y, 200, 'not updated y position');
+
+ var mc = MochiKit.Color.Color;
+ var red = mc.fromString('rgb(255,0,0)');
+ var color = null;
+
+ color = mc.fromString(getStyle('styleTest', 'background-color'));
+ is(color.toHexString(), red.toHexString(),
+ 'test getStyle selector case');
+
+ color = mc.fromString(getStyle('styleTest', 'backgroundColor'));
+ is(color.toHexString(), red.toHexString(),
+ 'test getStyle camel case');
+
+ is(getStyle('styleSubTest', 'font-size'), '10px',
+ 'test computed getStyle selector case');
+
+ is(getStyle('styleSubTest', 'fontSize'), '10px',
+ 'test computed getStyle camel case');
+
+ is(eval(getStyle('styleTest', 'opacity')), 0.5,
+ 'test getStyle opacity');
+
+ is(getStyle('styleTest', 'opacity'), 0.5, 'test getOpacity');
+
+ setStyle('styleTest', {'opacity': 0.2});
+ is(getStyle('styleTest', 'opacity'), 0.2, 'test setOpacity');
+
+ setStyle('styleTest', {'opacity': 0});
+ is(getStyle('styleTest', 'opacity'), 0, 'test setOpacity');
+
+ setStyle('styleTest', {'opacity': 1});
+ var t = getStyle('styleTest', 'opacity');
+ ok(t > 0.999 && t <= 1, 'test setOpacity');
+
+ var dims = getElementDimensions('styleTest');
+ is(dims.w, 100, 'getElementDimensions w ok');
+ is(dims.h, 100, 'getElementDimensions h ok');
+
+ setElementDimensions('styleTest', {'w': 200, 'h': 150});
+ dims = getElementDimensions('styleTest');
+ is(dims.w, 200, 'setElementDimensions w ok');
+ is(dims.h, 150, 'setElementDimensions h ok');
+
+ setElementDimensions('styleTest', {'w': 150});
+ dims = getElementDimensions('styleTest');
+ is(dims.w, 150, 'setElementDimensions only w ok');
+ is(dims.h, 150, 'setElementDimensions h not updated ok');
+
+ hideElement('styleTest');
+ dims = getElementDimensions('styleTest');
+ is(dims.w, 150, 'getElementDimensions w ok when display none');
+ is(dims.h, 150, 'getElementDimensions h ok when display none');
+
+ dims = getViewportDimensions();
+ is(dims.w > 0, true, 'test getViewportDimensions w');
+ is(dims.h > 0, true, 'test getViewportDimensions h');
+
+ pos = getViewportPosition();
+ is(pos.x, 0, 'test getViewportPosition x');
+ is(pos.y, 0, 'test getViewportPosition y');
+
+ ok( true, "test suite finished!");
+
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Visual.html b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Visual.html
new file mode 100644
index 0000000000..e4a40c7e48
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/MochiKit-Visual.html
@@ -0,0 +1,190 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../MochiKit/Iter.js"></script>
+ <script type="text/javascript" src="../MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../MochiKit/Async.js"></script>
+ <script type="text/javascript" src="../MochiKit/Style.js"></script>
+ <script type="text/javascript" src="../MochiKit/Color.js"></script>
+ <script type="text/javascript" src="../MochiKit/Signal.js"></script>
+ <script type="text/javascript" src="../MochiKit/Position.js"></script>
+ <script type="text/javascript" src="../MochiKit/Visual.js"></script>
+ <script type="text/javascript" src="SimpleTest/SimpleTest.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="SimpleTest/test.css">
+ <style type="text/css">
+ #elt1, #elt2, #ctn1 {
+ visibility: hidden;
+ font-size: 1em;
+ margin: 2px;
+ }
+ #elt3 {
+ display: none;
+ }
+ #ctn1 {
+ height: 2px;
+ }
+ </style>
+</head>
+<body>
+
+<div id='elt1'>elt1</div>
+<div id='ctn1'><div id='elt2'></div></div>
+<div id='elt3'>elt3</div>
+<pre id="test">
+<script type="text/javascript">
+try {
+ var TestQueue = function () {
+ };
+
+ TestQueue.prototype = new MochiKit.Visual.ScopedQueue();
+
+ MochiKit.Base.update(TestQueue.prototype, {
+ startLoop: function (func, interval) {
+ this.started = true;
+ var timePos = new Date().getTime();
+ while (this.started) {
+ timePos += interval;
+ MochiKit.Base.map(function (effect) {
+ effect.loop(timePos);
+ }, this.effects);
+ }
+ },
+ stopLoop: function () {
+ this.started = false;
+ }
+ });
+
+ var gl = new TestQueue();
+ MochiKit.Visual.Queues.instances['global'] = gl;
+ MochiKit.Visual.Queues.instances['elt1'] = gl;
+ MochiKit.Visual.Queues.instances['elt2'] = gl;
+ MochiKit.Visual.Queues.instances['elt3'] = gl;
+ MochiKit.Visual.Queues.instances['ctn1'] = gl;
+ MochiKit.Visual.Queue = gl;
+
+ pulsate("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display != 'none', true, "pulsate ok");
+ }});
+
+ pulsate("elt1", {pulses: 2, afterFinish: function () {
+ is(getElement('elt1').style.display != 'none', true, "pulsate with numbered pulses ok");
+ }});
+
+ shake("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display != 'none', true, "shake ok");
+ }});
+
+ fade("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display, 'none', "fade ok");
+ }});
+
+ appear("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display != 'none', true, "appear ok");
+ }});
+
+ toggle("elt1", "size", {afterFinish: function () {
+ is(getElement('elt1').style.display, 'none', "toggle size ok");
+ }});
+
+ toggle("elt1", "size", {afterFinish: function () {
+ is(getElement('elt1').style.display != 'none', true, "toggle size reverse ok");
+ }});
+
+ Morph("elt1", {"style": {"font-size": "2em"}, afterFinish: function () {
+ is(getStyle("elt1", "font-size"), "2em", "Morph OK");
+ }});
+
+ Morph("elt1", {"style": {"font-size": "1em", "margin-left": "4px"}, afterFinish: function () {
+ is(getStyle("elt1", "font-size"), "1em", "Morph multiple (font) OK");
+ is(getStyle("elt1", "margin-left"), "4px", "Morph multiple (margin) OK");
+ }});
+
+ switchOff("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display, 'none', "switchOff ok");
+ }});
+
+ grow("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display != 'none', true, "grow ok");
+ }});
+
+ shrink("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display, 'none', "shrink ok");
+ }});
+
+ showElement('elt1');
+ dropOut("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display, 'none', "dropOut ok");
+ }});
+
+ showElement('elt1');
+ puff("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display, 'none', "puff ok");
+ }});
+
+ showElement('elt1');
+ fold("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display, 'none', "fold ok");
+ }});
+
+ showElement('elt1');
+ squish("elt1", {afterFinish: function () {
+ is(getElement('elt1').style.display, 'none', "squish ok");
+ }});
+
+ slideUp("ctn1", {afterFinish: function () {
+ is(getElement('ctn1').style.display, 'none', "slideUp ok");
+ }});
+
+ slideDown("ctn1", {afterFinish: function () {
+ is(getElement('ctn1').style.display != 'none', true, "slideDown ok");
+ }});
+
+ blindDown("ctn1", {afterFinish: function () {
+ is(getElement('ctn1').style.display != 'none', true, "blindDown ok");
+ }});
+
+ blindUp("ctn1", {afterFinish: function () {
+ is(getElement('ctn1').style.display, 'none', "blindUp ok");
+ }});
+
+ multiple(["elt1", "ctn1"], appear, {afterFinish: function (effect) {
+ is(effect.element.style.display != 'none', true, "multiple ok");
+ }});
+
+ toggle("elt3", "size", {afterFinish: function () {
+ is(getElement('elt3').style.display != 'none', true, "toggle with css ok");
+ }});
+
+ toggle("elt3", "size", {afterFinish: function () {
+ is(getElement('elt3').style.display, 'none', "toggle with css ok");
+ }});
+
+ var toTests = [roundElement, roundClass, tagifyText, Opacity, Move, Scale, Highlight, ScrollTo, Morph];
+ for (var m in toTests) {
+ toTests[m]("elt1");
+ ok(true, toTests[m].NAME + " doesn't need 'new' keyword");
+ }
+ ok(true, "visual suite finished");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+ SimpleTest.finish();
+
+}
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/SimpleTest.js b/dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/SimpleTest.js
new file mode 100644
index 0000000000..53c2a87939
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/SimpleTest.js
@@ -0,0 +1,473 @@
+/**
+ * SimpleTest, a partial Test.Simple/Test.More API compatible test library.
+ *
+ * Why?
+ *
+ * Test.Simple doesn't work on IE < 6.
+ * TODO:
+ * * Support the Test.Simple API used by MochiKit, to be able to test MochiKit
+ * itself against IE 5.5
+ *
+**/
+
+if (typeof(SimpleTest) == "undefined") {
+ var SimpleTest = {};
+}
+
+var parentRunner = null;
+if (typeof(parent) != "undefined" && parent.TestRunner) {
+ parentRunner = parent.TestRunner;
+} else if (parent && parent.wrappedJSObject &&
+ parent.wrappedJSObject.TestRunner) {
+ parentRunner = parent.wrappedJSObject.TestRunner;
+}
+
+// Check to see if the TestRunner is present and has logging
+if (parentRunner) {
+ SimpleTest._logEnabled = parentRunner.logEnabled;
+}
+
+SimpleTest._tests = [];
+SimpleTest._stopOnLoad = true;
+
+/**
+ * Something like assert.
+**/
+SimpleTest.ok = function (condition, name) {
+ if (arguments.length > 2) {
+ const diag = "Too many arguments passed to `ok(condition, name)`";
+ SimpleTest.record(false, name, diag);
+ } else {
+ SimpleTest.record(condition, name);
+ }
+}
+
+SimpleTest.record = function (condition, name, diag) {
+ var test = {'result': !!condition, 'name': name, 'diag': diag || ""};
+ if (SimpleTest._logEnabled)
+ SimpleTest._logResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL");
+ SimpleTest._tests.push(test);
+};
+
+/**
+ * Roughly equivalent to ok(a==b, name)
+**/
+SimpleTest.is = function (a, b, name) {
+ var repr = MochiKit.Base.repr;
+ SimpleTest.record(a == b, name, "got " + repr(a) + ", expected " + repr(b));
+};
+
+SimpleTest.isnot = function (a, b, name) {
+ var repr = MochiKit.Base.repr;
+ SimpleTest.record(a != b, name, "Didn't expect " + repr(a) + ", but got it.");
+};
+
+// --------------- Test.Builder/Test.More todo() -----------------
+
+SimpleTest.todo = function(condition, name, diag) {
+ var test = {'result': !!condition, 'name': name, 'diag': diag || "", todo: true};
+ if (SimpleTest._logEnabled)
+ SimpleTest._logResult(test, "TEST-UNEXPECTED-PASS", "TEST-KNOWN-FAIL");
+ SimpleTest._tests.push(test);
+};
+
+SimpleTest._logResult = function(test, passString, failString) {
+ var msg = test.result ? passString : failString;
+ msg += " | ";
+ if (parentRunner.currentTestURL)
+ msg += parentRunner.currentTestURL;
+ msg += " | " + test.name;
+ var diag = "";
+ if (test.diag)
+ diag = " - " + test.diag;
+ if (test.result) {
+ if (test.todo)
+ parentRunner.logger.error(msg + diag);
+ else
+ parentRunner.logger.log(msg);
+ } else {
+ if (test.todo)
+ parentRunner.logger.log(msg);
+ else
+ parentRunner.logger.error(msg + diag);
+ }
+};
+
+/**
+ * Copies of is and isnot with the call to ok replaced by a call to todo.
+**/
+
+SimpleTest.todo_is = function (a, b, name) {
+ var repr = MochiKit.Base.repr;
+ SimpleTest.todo(a == b, name, "got " + repr(a) + ", expected " + repr(b));
+};
+
+SimpleTest.todo_isnot = function (a, b, name) {
+ var repr = MochiKit.Base.repr;
+ SimpleTest.todo(a != b, name, "Didn't expect " + repr(a) + ", but got it.");
+};
+
+
+/**
+ * Makes a test report, returns it as a DIV element.
+**/
+SimpleTest.report = function () {
+ var DIV = MochiKit.DOM.DIV;
+ var passed = 0;
+ var failed = 0;
+ var todo = 0;
+ var results = MochiKit.Base.map(
+ function (test) {
+ var cls, msg;
+ if (test.todo && !test.result) {
+ todo++;
+ cls = "test_todo";
+ msg = "todo - " + test.name + " " + test.diag;
+ } else if (test.result &&!test.todo) {
+ passed++;
+ cls = "test_ok";
+ msg = "ok - " + test.name;
+ } else {
+ failed++;
+ cls = "test_not_ok";
+ msg = "not ok - " + test.name + " " + test.diag;
+ }
+ return DIV({"class": cls}, msg);
+ },
+ SimpleTest._tests
+ );
+ var summary_class = ((failed == 0) ? 'all_pass' : 'some_fail');
+ return DIV({'class': 'tests_report'},
+ DIV({'class': 'tests_summary ' + summary_class},
+ DIV({'class': 'tests_passed'}, "Passed: " + passed),
+ DIV({'class': 'tests_failed'}, "Failed: " + failed),
+ DIV({'class': 'tests_todo'}, "Todo: " + todo)),
+ results
+ );
+};
+
+/**
+ * Toggle element visibility
+**/
+SimpleTest.toggle = function(el) {
+ if (MochiKit.Style.computedStyle(el, 'display') == 'block') {
+ el.style.display = 'none';
+ } else {
+ el.style.display = 'block';
+ }
+};
+
+/**
+ * Toggle visibility for divs with a specific class.
+**/
+SimpleTest.toggleByClass = function (cls, evt) {
+ var elems = getElementsByTagAndClassName('div', cls);
+ MochiKit.Base.map(SimpleTest.toggle, elems);
+ if (evt)
+ evt.preventDefault();
+};
+
+/**
+ * Shows the report in the browser
+**/
+
+SimpleTest.showReport = function() {
+ var togglePassed = A({'href': '#'}, "Toggle passed tests");
+ var toggleFailed = A({'href': '#'}, "Toggle failed tests");
+ togglePassed.onclick = partial(SimpleTest.toggleByClass, 'test_ok');
+ toggleFailed.onclick = partial(SimpleTest.toggleByClass, 'test_not_ok');
+ var body = document.body; // Handles HTML documents
+ if (!body) {
+ // Do the XML thing
+ body = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml",
+ "body")[0]
+ }
+ var firstChild = body.childNodes[0];
+ var addNode;
+ if (firstChild) {
+ addNode = function (el) {
+ body.insertBefore(el, firstChild);
+ };
+ } else {
+ addNode = function (el) {
+ body.appendChild(el)
+ };
+ }
+ addNode(togglePassed);
+ addNode(SPAN(null, " "));
+ addNode(toggleFailed);
+ addNode(SimpleTest.report());
+};
+
+/**
+ * Tells SimpleTest to don't finish the test when the document is loaded,
+ * useful for asynchronous tests.
+ *
+ * When SimpleTest.waitForExplicitFinish is called,
+ * explicit SimpleTest.finish() is required.
+**/
+SimpleTest.waitForExplicitFinish = function () {
+ SimpleTest._stopOnLoad = false;
+};
+
+/**
+ * Talks to the TestRunner if being ran on a iframe and the parent has a
+ * TestRunner object.
+**/
+SimpleTest.talkToRunner = function () {
+ if (parentRunner) {
+ parentRunner.testFinished(document);
+ }
+};
+
+/**
+ * Finishes the tests. This is automatically called, except when
+ * SimpleTest.waitForExplicitFinish() has been invoked.
+**/
+SimpleTest.finish = function () {
+ SimpleTest.showReport();
+ SimpleTest.talkToRunner();
+};
+
+
+addLoadEvent(function() {
+ if (SimpleTest._stopOnLoad) {
+ SimpleTest.finish();
+ }
+});
+
+// --------------- Test.Builder/Test.More isDeeply() -----------------
+
+
+SimpleTest.DNE = {dne: 'Does not exist'};
+SimpleTest.LF = "\r\n";
+SimpleTest._isRef = function (object) {
+ var type = typeof(object);
+ return type == 'object' || type == 'function';
+};
+
+
+SimpleTest._deepCheck = function (e1, e2, stack, seen) {
+ var ok = false;
+ // Either they're both references or both not.
+ var sameRef = !(!SimpleTest._isRef(e1) ^ !SimpleTest._isRef(e2));
+ if (e1 == null && e2 == null) {
+ ok = true;
+ } else if (e1 != null ^ e2 != null) {
+ ok = false;
+ } else if (e1 == SimpleTest.DNE ^ e2 == SimpleTest.DNE) {
+ ok = false;
+ } else if (sameRef && e1 == e2) {
+ // Handles primitives and any variables that reference the same
+ // object, including functions.
+ ok = true;
+ } else if (SimpleTest.isa(e1, 'Array') && SimpleTest.isa(e2, 'Array')) {
+ ok = SimpleTest._eqArray(e1, e2, stack, seen);
+ } else if (typeof e1 == "object" && typeof e2 == "object") {
+ ok = SimpleTest._eqAssoc(e1, e2, stack, seen);
+ } else {
+ // If we get here, they're not the same (function references must
+ // always simply rererence the same function).
+ stack.push({ vals: [e1, e2] });
+ ok = false;
+ }
+ return ok;
+};
+
+SimpleTest._eqArray = function (a1, a2, stack, seen) {
+ // Return if they're the same object.
+ if (a1 == a2) return true;
+
+ // JavaScript objects have no unique identifiers, so we have to store
+ // references to them all in an array, and then compare the references
+ // directly. It's slow, but probably won't be much of an issue in
+ // practice. Start by making a local copy of the array to as to avoid
+ // confusing a reference seen more than once (such as [a, a]) for a
+ // circular reference.
+ for (var j = 0; j < seen.length; j++) {
+ if (seen[j][0] == a1) {
+ return seen[j][1] == a2;
+ }
+ }
+
+ // If we get here, we haven't seen a1 before, so store it with reference
+ // to a2.
+ seen.push([ a1, a2 ]);
+
+ var ok = true;
+ // Only examines enumerable attributes. Only works for numeric arrays!
+ // Associative arrays return 0. So call _eqAssoc() for them, instead.
+ var max = a1.length > a2.length ? a1.length : a2.length;
+ if (max == 0) return SimpleTest._eqAssoc(a1, a2, stack, seen);
+ for (var i = 0; i < max; i++) {
+ var e1 = i > a1.length - 1 ? SimpleTest.DNE : a1[i];
+ var e2 = i > a2.length - 1 ? SimpleTest.DNE : a2[i];
+ stack.push({ type: 'Array', idx: i, vals: [e1, e2] });
+ if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
+ stack.pop();
+ } else {
+ break;
+ }
+ }
+ return ok;
+};
+
+SimpleTest._eqAssoc = function (o1, o2, stack, seen) {
+ // Return if they're the same object.
+ if (o1 == o2) return true;
+
+ // JavaScript objects have no unique identifiers, so we have to store
+ // references to them all in an array, and then compare the references
+ // directly. It's slow, but probably won't be much of an issue in
+ // practice. Start by making a local copy of the array to as to avoid
+ // confusing a reference seen more than once (such as [a, a]) for a
+ // circular reference.
+ seen = seen.slice(0);
+ for (var j = 0; j < seen.length; j++) {
+ if (seen[j][0] == o1) {
+ return seen[j][1] == o2;
+ }
+ }
+
+ // If we get here, we haven't seen o1 before, so store it with reference
+ // to o2.
+ seen.push([ o1, o2 ]);
+
+ // They should be of the same class.
+
+ var ok = true;
+ // Only examines enumerable attributes.
+ var o1Size = 0; for (var i in o1) o1Size++;
+ var o2Size = 0; for (var i in o2) o2Size++;
+ var bigger = o1Size > o2Size ? o1 : o2;
+ for (var i in bigger) {
+ var e1 = o1[i] == undefined ? SimpleTest.DNE : o1[i];
+ var e2 = o2[i] == undefined ? SimpleTest.DNE : o2[i];
+ stack.push({ type: 'Object', idx: i, vals: [e1, e2] });
+ if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
+ stack.pop();
+ } else {
+ break;
+ }
+ }
+ return ok;
+};
+
+SimpleTest._formatStack = function (stack) {
+ var variable = '$Foo';
+ for (var i = 0; i < stack.length; i++) {
+ var entry = stack[i];
+ var type = entry['type'];
+ var idx = entry['idx'];
+ if (idx != null) {
+ if (/^\d+$/.test(idx)) {
+ // Numeric array index.
+ variable += '[' + idx + ']';
+ } else {
+ // Associative array index.
+ idx = idx.replace("'", "\\'");
+ variable += "['" + idx + "']";
+ }
+ }
+ }
+
+ var vals = stack[stack.length-1]['vals'].slice(0, 2);
+ var vars = [
+ variable.replace('$Foo', 'got'),
+ variable.replace('$Foo', 'expected')
+ ];
+
+ var out = "Structures begin differing at:" + SimpleTest.LF;
+ for (var i = 0; i < vals.length; i++) {
+ var val = vals[i];
+ if (val == null) {
+ val = 'undefined';
+ } else {
+ val == SimpleTest.DNE ? "Does not exist" : "'" + val + "'";
+ }
+ }
+
+ out += vars[0] + ' = ' + vals[0] + SimpleTest.LF;
+ out += vars[1] + ' = ' + vals[1] + SimpleTest.LF;
+
+ return ' ' + out;
+};
+
+
+SimpleTest.isDeeply = function (it, as, name) {
+ var ok;
+ // ^ is the XOR operator.
+ if (SimpleTest._isRef(it) ^ SimpleTest._isRef(as)) {
+ // One's a reference, one isn't.
+ ok = false;
+ } else if (!SimpleTest._isRef(it) && !SimpleTest._isRef(as)) {
+ // Neither is an object.
+ ok = SimpleTest.is(it, as, name);
+ } else {
+ // We have two objects. Do a deep comparison.
+ var stack = [], seen = [];
+ if ( SimpleTest._deepCheck(it, as, stack, seen)) {
+ ok = SimpleTest.ok(true, name);
+ } else {
+ ok = SimpleTest.ok(false, name, SimpleTest._formatStack(stack));
+ }
+ }
+ return ok;
+};
+
+SimpleTest.typeOf = function (object) {
+ var c = Object.prototype.toString.apply(object);
+ var name = c.substring(8, c.length - 1);
+ if (name != 'Object') return name;
+ // It may be a non-core class. Try to extract the class name from
+ // the constructor function. This may not work in all implementations.
+ if (/function ([^(\s]+)/.test(Function.toString.call(object.constructor))) {
+ return RegExp.$1;
+ }
+ // No idea. :-(
+ return name;
+};
+
+SimpleTest.isa = function (object, clas) {
+ return SimpleTest.typeOf(object) == clas;
+};
+
+if ( parent.SimpleTest && parent.runAJAXTest ) (function(){
+ var oldRecord = SimpleTest.record;
+
+ SimpleTest.record = function(condition, name, diag, stack) {
+ parent.SimpleTest.record( condition, name, diag, stack );
+ return oldRecord( condition, name, diag, stack );
+ };
+
+ var oldFinish = SimpleTest.finish;
+
+ SimpleTest.finish = function() {
+ oldFinish();
+ parent.runAJAXTest();
+ };
+})();
+
+// Global symbols:
+var ok = SimpleTest.ok;
+var record = SimpleTest.record;
+var is = SimpleTest.is;
+var isnot = SimpleTest.isnot;
+var todo = SimpleTest.todo;
+var todo_is = SimpleTest.todo_is;
+var todo_isnot = SimpleTest.todo_isnot;
+var isDeeply = SimpleTest.isDeeply;
+var oldOnError = window.onerror;
+window.onerror = function (ev) {
+ is(0, 1, "Error thrown during test: " + ev);
+ if (oldOnError) {
+ try {
+ oldOnError(ev);
+ } catch (e) {
+ }
+ }
+ if (SimpleTest._stopOnLoad == false) {
+ // Need to finish() manually here
+ SimpleTest.finish();
+ }
+}
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/TestRunner.js b/dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/TestRunner.js
new file mode 100644
index 0000000000..a4e3130759
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/TestRunner.js
@@ -0,0 +1,177 @@
+/**
+ * TestRunner: A test runner for SimpleTest
+ * TODO:
+ *
+ * * Avoid moving iframes: That causes reloads on mozilla and opera.
+ *
+ *
+**/
+var TestRunner = {};
+TestRunner.logEnabled = false;
+TestRunner._iframes = {};
+TestRunner._iframeDocuments = {};
+TestRunner._iframeRows = {};
+TestRunner._currentTest = 0;
+TestRunner._urls = [];
+TestRunner._testsDiv = DIV();
+TestRunner._progressDiv = DIV();
+TestRunner._summaryDiv = DIV(null,
+ H1(null, "Tests Summary"),
+ TABLE(null,
+ THEAD(null,
+ TR(null,
+ TH(null, "Test"),
+ TH(null, "Passed"),
+ TH(null, "Failed")
+ )
+ ),
+ TBODY()
+ )
+);
+
+/**
+ * This function is called after generating the summary.
+**/
+TestRunner.onComplete = null;
+
+/**
+ * If logEnabled is true, this is the logger that will be used.
+**/
+TestRunner.logger = MochiKit.Logging.logger;
+
+/**
+ * Toggle element visibility
+**/
+TestRunner._toggle = function(el) {
+ if (el.className == "noshow") {
+ el.className = "";
+ el.style.cssText = "";
+ } else {
+ el.className = "noshow";
+ el.style.cssText = "width:0px; height:0px; border:0px;";
+ }
+};
+
+
+/**
+ * Creates the iframe that contains a test
+**/
+TestRunner._makeIframe = function (url) {
+ var iframe = document.createElement('iframe');
+ iframe.src = url;
+ iframe.name = url;
+ iframe.width = "500";
+ var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
+ var tr = TR(null, TD({'colspan': '3'}, iframe));
+ iframe._row = tr;
+ tbody.appendChild(tr);
+ return iframe;
+};
+
+/**
+ * TestRunner entry point.
+ *
+ * The arguments are the URLs of the test to be ran.
+ *
+**/
+TestRunner.runTests = function (/*url...*/) {
+ if (TestRunner.logEnabled)
+ TestRunner.logger.log("SimpleTest START");
+
+ var body = document.getElementsByTagName("body")[0];
+ appendChildNodes(body,
+ TestRunner._testsDiv,
+ TestRunner._progressDiv,
+ TestRunner._summaryDiv
+ );
+ for (var i = 0; i < arguments.length; i++) {
+ TestRunner._urls.push(arguments[i]);
+ }
+ TestRunner.runNextTest();
+};
+
+/**
+ * Run the next test. If no test remains, calls makeSummary
+**/
+TestRunner.runNextTest = function() {
+ if (TestRunner._currentTest < TestRunner._urls.length) {
+ var url = TestRunner._urls[TestRunner._currentTest];
+ var progress = SPAN(null,
+ "Running ", A({href:url}, url), "..."
+ );
+
+ if (TestRunner.logEnabled)
+ TestRunner.logger.log(scrapeText(progress));
+
+ TestRunner._progressDiv.appendChild(progress);
+ TestRunner._iframes[url] = TestRunner._makeIframe(url);
+ } else {
+ TestRunner.makeSummary();
+ if (TestRunner.onComplete)
+ TestRunner.onComplete();
+ }
+};
+
+/**
+ * This stub is called by SimpleTest when a test is finished.
+**/
+TestRunner.testFinished = function (doc) {
+ appendChildNodes(TestRunner._progressDiv, SPAN(null, "Done"), BR());
+ var finishedURL = TestRunner._urls[TestRunner._currentTest];
+
+ if (TestRunner.logEnabled)
+ TestRunner.logger.debug("SimpleTest finished " + finishedURL);
+
+ TestRunner._iframeDocuments[finishedURL] = doc;
+ // TestRunner._iframes[finishedURL].style.display = "none";
+ TestRunner._toggle(TestRunner._iframes[finishedURL]);
+ TestRunner._currentTest++;
+ TestRunner.runNextTest();
+};
+
+/**
+ * Display the summary in the browser
+**/
+TestRunner.makeSummary = function() {
+ if (TestRunner.logEnabled)
+ TestRunner.logger.log("SimpleTest FINISHED");
+ var rows = [];
+ for (var url in TestRunner._iframeDocuments) {
+ var doc = TestRunner._iframeDocuments[url];
+ var nOK = withDocument(doc,
+ partial(getElementsByTagAndClassName, 'div', 'test_ok')
+ ).length;
+ var nNotOK = withDocument(doc,
+ partial(getElementsByTagAndClassName, 'div', 'test_not_ok')
+ ).length;
+ var toggle = partial(TestRunner._toggle, TestRunner._iframes[url]);
+ var jsurl = "TestRunner._toggle(TestRunner._iframes['" + url + "'])";
+ var row = TR(
+ {'style': {'backgroundColor': nNotOK > 0 ? "#f00":"#0f0"}},
+ TD(null, url),
+ TD(null, nOK),
+ TD(null, nNotOK)
+ );
+ row.onclick = toggle;
+ var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
+ tbody.insertBefore(row, TestRunner._iframes[url]._row)
+ }
+};
+
+if ( parent.SimpleTest && parent.runAJAXTest ) {
+ TestRunner.makeSummary = function() {
+ for (var url in TestRunner._iframeDocuments) {
+ var doc = TestRunner._iframeDocuments[url];
+
+ var OK = withDocument(doc, partial(getElementsByTagAndClassName, 'div', 'test_ok'));
+ for ( var i = 0; i < OK.length; i++ )
+ parent.SimpleTest.ok( true, OK[i].innerHTML );
+
+ var NotOK = withDocument(doc, partial(getElementsByTagAndClassName, 'div', 'test_not_ok'));
+ for ( var i = 0; i < NotOK.length; i++ )
+ parent.SimpleTest.ok( false, NotOK[i].innerHTML );
+ }
+
+ parent.runAJAXTest();
+ };
+}
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/test.css b/dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/test.css
new file mode 100644
index 0000000000..38a401402f
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/SimpleTest/test.css
@@ -0,0 +1,28 @@
+.test_ok {
+ color: green;
+ display: none;
+}
+.test_not_ok {
+ color: red;
+ display: block;
+}
+
+.test_ok, .test_not_ok {
+ border-bottom-width: 2px;
+ border-bottom-style: solid;
+ border-bottom-color: black;
+}
+
+.all_pass {
+ background-color: lime;
+}
+
+.some_fail {
+ background-color: red;
+}
+
+.tests_report {
+ border-width: 2px;
+ border-style: solid;
+ width: 20em;
+}
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/cli.js b/dom/tests/mochitest/ajax/mochikit/tests/cli.js
new file mode 100644
index 0000000000..18434604c8
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/cli.js
@@ -0,0 +1,6 @@
+MochiKit = {__export__: true};
+load('tests/FakeJSAN.js')
+JSAN.use('MochiKit.MockDOM');
+var window = this;
+var document = MochiKit.MockDOM.document;
+JSAN.use('MochiKit.MochiKit');
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/index.html b/dom/tests/mochitest/ajax/mochikit/tests/index.html
new file mode 100644
index 0000000000..da46bd32ce
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/index.html
@@ -0,0 +1,25 @@
+<html>
+<head>
+ <script type="text/javascript" src="../MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script type="text/javascript">
+TestRunner.runTests(
+ 'MochiKit-Async.html',
+ 'MochiKit-Base.html',
+ 'MochiKit-DateTime.html',
+ 'MochiKit-DOM.html',
+ 'MochiKit-Style.html',
+ 'MochiKit-Format.html',
+ 'MochiKit-Iter.html',
+ 'MochiKit-Logging.html',
+ 'MochiKit-MochiKit.html',
+ 'MochiKit-Color.html',
+ 'MochiKit-Selector.html',
+ 'MochiKit-Signal.html',
+ 'MochiKit-Visual.html'
+);
+</script>
+</body>
+</html>
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/standalone.js b/dom/tests/mochitest/ajax/mochikit/tests/standalone.js
new file mode 100644
index 0000000000..d48571238f
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/standalone.js
@@ -0,0 +1,16 @@
+load('tests/cli.js');
+
+JSAN.use('MochiKit.Test');
+
+print("[[ MochiKit.Base ]]");
+runTests('tests.test_Base');
+print("[[ MochiKit.Color ]]");
+runTests('tests.test_Color');
+print("[[ MochiKit.DateTime ]]");
+runTests('tests.test_DateTime');
+print("[[ MochiKit.Format ]]");
+runTests('tests.test_Format');
+print("[[ MochiKit.Iter ]]");
+runTests('tests.test_Iter');
+print("[[ MochiKit.Logging ]]");
+runTests('tests.test_Logging');
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/test_Base.js b/dom/tests/mochitest/ajax/mochikit/tests/test_Base.js
new file mode 100644
index 0000000000..2cbf2848d1
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/test_Base.js
@@ -0,0 +1,509 @@
+if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Base'); }
+if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Base'); }
+if (typeof(tests) == 'undefined') { tests = {}; }
+
+tests.test_Base = function (t) {
+ // test bind
+ var not_self = {"toString": function () { return "not self"; } };
+ var self = {"toString": function () { return "self"; } };
+ var func = function (arg) { return this.toString() + " " + arg; };
+ var boundFunc = bind(func, self);
+ not_self.boundFunc = boundFunc;
+
+ t.is( isEmpty([], [], ""), true, "isEmpty true" )
+ t.is( isEmpty([], [1], ""), true, "isEmpty true" )
+ t.is( isNotEmpty([], [], ""), false, "isNotEmpty false" )
+ t.is( isNotEmpty([], [1], ""), false, "isNotEmpty false" )
+
+ t.is( isEmpty([1], [1], "1"), false, "isEmpty false" )
+ t.is( isEmpty([1], [1], "1"), false, "isEmpty false" )
+ t.is( isNotEmpty([1], [1], "1"), true, "isNotEmpty true" )
+ t.is( isNotEmpty([1], [1], "1"), true, "isNotEmpty true" )
+
+ t.is( boundFunc("foo"), "self foo", "boundFunc bound to self properly" );
+ t.is( not_self.boundFunc("foo"), "self foo", "boundFunc bound to self on another obj" );
+ t.is( bind(boundFunc, not_self)("foo"), "not self foo", "boundFunc successfully rebound!" );
+ t.is( bind(boundFunc, undefined, "foo")(), "self foo", "boundFunc partial no self change" );
+ t.is( bind(boundFunc, not_self, "foo")(), "not self foo", "boundFunc partial self change" );
+
+ // test method
+ not_self = {"toString": function () { return "not self"; } };
+ self = {"toString": function () { return "self"; } };
+ func = function (arg) { return this.toString() + " " + arg; };
+ var boundMethod = method(self, func);
+ not_self.boundMethod = boundMethod;
+
+ t.is( boundMethod("foo"), "self foo", "boundMethod bound to self properly" );
+ t.is( not_self.boundMethod("foo"), "self foo", "boundMethod bound to self on another obj" );
+ t.is( method(not_self, boundMethod)("foo"), "not self foo", "boundMethod successfully rebound!" );
+ t.is( method(undefined, boundMethod, "foo")(), "self foo", "boundMethod partial no self change" );
+ t.is( method(not_self, boundMethod, "foo")(), "not self foo", "boundMethod partial self change" );
+
+
+
+
+ // test bindMethods
+
+ var O = function (value) {
+ bindMethods(this);
+ this.value = value;
+ };
+ O.prototype.func = function () {
+ return this.value;
+ };
+
+ var o = new O("boring");
+ var p = {};
+ p.func = o.func;
+ var func = o.func;
+ t.is( o.func(), "boring", "bindMethods doesn't break shit" );
+ t.is( p.func(), "boring", "bindMethods works on other objects" );
+ t.is( func(), "boring", "bindMethods works on functions" );
+
+ var p = clone(o);
+ t.ok( p instanceof O, "cloned correct inheritance" );
+ var q = clone(p);
+ t.ok( q instanceof O, "clone-cloned correct inheritance" );
+ q.foo = "bar";
+ t.is( p.foo, undefined, "clone-clone is copy-on-write" );
+ p.bar = "foo";
+ t.is( o.bar, undefined, "clone is copy-on-write" );
+ t.is( q.bar, "foo", "clone-clone has proper delegation" );
+ // unbind
+ p.func = bind(p.func, null);
+ t.is( p.func(), "boring", "clone function calls correct" );
+ q.value = "awesome";
+ t.is( q.func(), "awesome", "clone really does work" );
+
+ // test boring boolean funcs
+
+ t.is( isCallable(isCallable), true, "isCallable returns true on itself" );
+ t.is( isCallable(1), false, "isCallable returns false on numbers" );
+
+ t.is( isUndefined(null), false, "null is not undefined" );
+ t.is( isUndefined(""), false, "empty string is not undefined" );
+ t.is( isUndefined(undefined), true, "undefined is undefined" );
+ t.is( isUndefined({}.foo), true, "missing property is undefined" );
+
+ t.is( isUndefinedOrNull(null), true, "null is undefined or null" );
+ t.is( isUndefinedOrNull(""), false, "empty string is not undefined or null" );
+ t.is( isUndefinedOrNull(undefined), true, "undefined is undefined or null" );
+ t.is( isUndefinedOrNull({}.foo), true, "missing property is undefined or null" );
+
+ // test extension of arrays
+ var a = [];
+ var b = [];
+ var three = [1, 2, 3];
+
+ extend(a, three, 1);
+ t.ok( objEqual(a, [2, 3]), "extend to an empty array" );
+ extend(a, three, 1)
+ t.ok( objEqual(a, [2, 3, 2, 3]), "extend to a non-empty array" );
+
+ extend(b, three);
+ t.ok( objEqual(b, three), "extend of an empty array" );
+
+ t.is( compare(1, 2), -1, "numbers compare lt" );
+ t.is( compare(2, 1), 1, "numbers compare gt" );
+ t.is( compare(1, 1), 0, "numbers compare eq" );
+ t.is( compare([1], [1]), 0, "arrays compare eq" );
+ t.is( compare([1], [1, 2]), -1, "arrays compare lt (length)" );
+ t.is( compare([1, 2], [2, 1]), -1, "arrays compare lt (contents)" );
+ t.is( compare([1, 2], [1]), 1, "arrays compare gt (length)" );
+ t.is( compare([2, 1], [1, 1]), 1, "arrays compare gt (contents)" );
+
+ // test partial application
+ var a = [];
+ var func = function (a, b) {
+ if (arguments.length != 2) {
+ return "bad args";
+ } else {
+ return this.value + a + b;
+ }
+ };
+ var self = {"value": 1, "func": func};
+ var self2 = {"value": 2};
+ t.is( self.func(2, 3), 6, "setup for test is correct" );
+ self.funcTwo = partial(self.func, 2);
+ t.is( self.funcTwo(3), 6, "partial application works" );
+ t.is( self.funcTwo(3), 6, "partial application works still" );
+ t.is( bind(self.funcTwo, self2)(3), 7, "rebinding partial works" );
+ self.funcTwo = bind(bind(self.funcTwo, self2), null);
+ t.is( self.funcTwo(3), 6, "re-unbinding partial application works" );
+
+
+ // nodeWalk test
+ // ... looks a lot like a DOM tree on purpose
+ var tree = {
+ "id": "nodeWalkTestTree",
+ "test:int": "1",
+ "childNodes": [
+ {
+ "test:int": "2",
+ "childNodes": [
+ {"test:int": "5"},
+ "ignored string",
+ {"ignored": "object"},
+ ["ignored", "list"],
+ {
+ "test:skipchildren": "1",
+ "childNodes": [{"test:int": 6}]
+ }
+ ]
+ },
+ {"test:int": "3"},
+ {"test:int": "4"}
+ ]
+ }
+
+ var visitedNodes = [];
+ nodeWalk(tree, function (node) {
+ var attr = node["test:int"];
+ if (attr) {
+ visitedNodes.push(attr);
+ }
+ if (node["test:skipchildren"]) {
+ return;
+ }
+ return node.childNodes;
+ });
+
+ t.ok( objEqual(visitedNodes, ["1", "2", "3", "4", "5"]), "nodeWalk looks like it works");
+
+ // test map
+ var minusOne = function (x) { return x - 1; };
+ var res = map(minusOne, [1, 2, 3]);
+ t.ok( objEqual(res, [0, 1, 2]), "map works" );
+
+ var res2 = xmap(minusOne, 1, 2, 3);
+ t.ok( objEqual(res2, res), "xmap works" );
+
+ res = map(operator.add, [1, 2, 3], [2, 4, 6]);
+ t.ok( objEqual(res, [3, 6, 9]), "map(fn, p, q) works" );
+
+ res = map(operator.add, [1, 2, 3], [2, 4, 6, 8]);
+ t.ok( objEqual(res, [3, 6, 9]), "map(fn, p, q) works (q long)" );
+
+ res = map(operator.add, [1, 2, 3, 4], [2, 4, 6]);
+ t.ok( objEqual(res, [3, 6, 9]), "map(fn, p, q) works (p long)" );
+
+ res = map(null, [1, 2, 3], [2, 4, 6]);
+ t.ok( objEqual(res, [[1, 2], [2, 4], [3, 6]]), "map(null, p, q) works" );
+
+ res = zip([1, 2, 3], [2, 4, 6]);
+ t.ok( objEqual(res, [[1, 2], [2, 4], [3, 6]]), "zip(p, q) works" );
+
+ res = map(null, [1, 2, 3]);
+ t.ok( objEqual(res, [1, 2, 3]), "map(null, lst) works" );
+
+
+
+
+ t.is( isNotEmpty("foo"), true, "3 char string is not empty" );
+ t.is( isNotEmpty(""), false, "0 char string is empty" );
+ t.is( isNotEmpty([1, 2, 3]), true, "3 element list is not empty" );
+ t.is( isNotEmpty([]), false, "0 element list is empty" );
+
+ // test filter
+ var greaterThanThis = function (x) { return x > this; };
+ var greaterThanOne = function (x) { return x > 1; };
+ var res = filter(greaterThanOne, [-1, 0, 1, 2, 3]);
+ t.ok( objEqual(res, [2, 3]), "filter works" );
+ var res = filter(greaterThanThis, [-1, 0, 1, 2, 3], 1);
+ t.ok( objEqual(res, [2, 3]), "filter self works" );
+ var res2 = xfilter(greaterThanOne, -1, 0, 1, 2, 3);
+ t.ok( objEqual(res2, res), "xfilter works" );
+
+ t.is(objMax(1, 2, 9, 12, 42, -16, 16), 42, "objMax works (with numbers)");
+ t.is(objMin(1, 2, 9, 12, 42, -16, 16), -16, "objMin works (with numbers)");
+
+ // test adapter registry
+
+ var R = new AdapterRegistry();
+ R.register("callable", isCallable, function () { return "callable"; });
+ R.register("arrayLike", isArrayLike, function () { return "arrayLike"; });
+ t.is( R.match(function () {}), "callable", "registry found callable" );
+ t.is( R.match([]), "arrayLike", "registry found ArrayLike" );
+ try {
+ R.match(null);
+ t.ok( false, "non-matching didn't raise!" );
+ } catch (e) {
+ t.is( e, NotFound, "non-matching raised correctly" );
+ }
+ R.register("undefinedOrNull", isUndefinedOrNull, function () { return "undefinedOrNull" });
+ R.register("undefined", isUndefined, function () { return "undefined" });
+ t.is( R.match(undefined), "undefinedOrNull", "priorities are as documented" );
+ t.ok( R.unregister("undefinedOrNull"), "removed adapter" );
+ t.is( R.match(undefined), "undefined", "adapter was removed" );
+ R.register("undefinedOrNull", isUndefinedOrNull, function () { return "undefinedOrNull" }, true);
+ t.is( R.match(undefined), "undefinedOrNull", "override works" );
+
+ var a1 = {"a": 1, "b": 2, "c": 2};
+ var a2 = {"a": 2, "b": 1, "c": 2};
+ t.is( keyComparator("a")(a1, a2), -1, "keyComparator 1 lt" );
+ t.is( keyComparator("c")(a1, a2), 0, "keyComparator 1 eq" );
+ t.is( keyComparator("c", "b")(a1, a2), 1, "keyComparator 2 eq gt" );
+ t.is( keyComparator("c", "a")(a1, a2), -1, "keyComparator 2 eq lt" );
+ t.is( reverseKeyComparator("a")(a1, a2), 1, "reverseKeyComparator" );
+ t.is( compare(concat([1], [2], [3]), [1, 2, 3]), 0, "concat" );
+ t.is( repr("foo"), '"foo"', "string repr" );
+ t.is( repr(1), '1', "number repr" );
+ t.is( listMin([1, 3, 5, 3, -1]), -1, "listMin" );
+ t.is( objMin(1, 3, 5, 3, -1), -1, "objMin" );
+ t.is( listMax([1, 3, 5, 3, -1]), 5, "listMax" );
+ t.is( objMax(1, 3, 5, 3, -1), 5, "objMax" );
+
+ var v = keys(a1);
+ v.sort();
+ t.is( compare(v, ["a", "b", "c"]), 0, "keys" );
+ v = items(a1);
+ v.sort();
+ t.is( compare(v, [["a", 1], ["b", 2], ["c", 2]]), 0, "items" );
+
+ var StringMap = function() {};
+ a = new StringMap();
+ a.foo = "bar";
+ b = new StringMap();
+ b.foo = "bar";
+ try {
+ compare(a, b);
+ t.ok( false, "bad comparison registered!?" );
+ } catch (e) {
+ t.ok( e instanceof TypeError, "bad comparison raised TypeError" );
+ }
+
+ t.is( repr(a), "[object Object]", "default repr for StringMap" );
+ var isStringMap = function () {
+ for (var i = 0; i < arguments.length; i++) {
+ if (!(arguments[i] instanceof StringMap)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ registerRepr("stringMap",
+ isStringMap,
+ function (obj) {
+ return "StringMap(" + repr(items(obj)) + ")";
+ }
+ );
+
+ t.is( repr(a), 'StringMap([["foo", "bar"]])', "repr worked" );
+
+ // not public API
+ MochiKit.Base.reprRegistry.unregister("stringMap");
+
+ t.is( repr(a), "[object Object]", "default repr for StringMap" );
+
+ registerComparator("stringMap",
+ isStringMap,
+ function (a, b) {
+ // no sorted(...) in base
+ a = items(a);
+ b = items(b);
+ a.sort(compare);
+ b.sort(compare);
+ return compare(a, b);
+ }
+ );
+
+ t.is( compare(a, b), 0, "registerComparator" );
+
+ update(a, {"foo": "bar"}, {"wibble": "baz"}, undefined, null, {"grr": 1});
+ t.is( a.foo, "bar", "update worked (first obj)" );
+ t.is( a.wibble, "baz", "update worked (second obj)" );
+ t.is( a.grr, 1, "update worked (skipped undefined and null)" );
+ t.is( compare(a, b), 1, "update worked (comparison)" );
+
+
+ setdefault(a, {"foo": "unf"}, {"bar": "web taco"} );
+ t.is( a.foo, "bar", "setdefault worked (skipped existing)" );
+ t.is( a.bar, "web taco", "setdefault worked (set non-existing)" );
+
+ var c = items(merge({"foo": "bar"}, {"wibble": "baz"}));
+ c.sort(compare);
+ t.is( compare(c, [["foo", "bar"], ["wibble", "baz"]]), 0, "merge worked" );
+
+ // not public API
+ MochiKit.Base.comparatorRegistry.unregister("stringMap");
+
+ try {
+ compare(a, b);
+ t.ok( false, "bad comparison registered!?" );
+ } catch (e) {
+ t.ok( e instanceof TypeError, "bad comparison raised TypeError" );
+ }
+
+ var o = {"__repr__": function () { return "__repr__"; }};
+ t.is( repr(o), "__repr__", "__repr__ protocol" );
+ t.is( repr(MochiKit.Base), MochiKit.Base.__repr__(), "__repr__ protocol when repr is defined" );
+ var o = {"NAME": "NAME"};
+ t.is( repr(o), "NAME", "NAME protocol (obj)" );
+ o = function () { return "TACO" };
+ o.NAME = "NAME";
+ t.is( repr(o), "NAME", "NAME protocol (func)" );
+
+ t.is( repr(MochiKit.Base.nameFunctions), "MochiKit.Base.nameFunctions", "test nameFunctions" );
+ // Done!
+
+ t.is( urlEncode("1+2=2").toUpperCase(), "1%2B2%3D2", "urlEncode" );
+ t.is( queryString(["a", "b"], [1, "two"]), "a=1&b=two", "queryString");
+ t.is( queryString({"a": 1}), "a=1", "one item alternate form queryString" );
+ var o = {"a": 1, "b": 2, "c": function() {}};
+ var res = queryString(o).split("&");
+ res.sort();
+ t.is( res.join("&"), "a=1&b=2", "two item alternate form queryString, function skip" );
+ var res = parseQueryString("1+1=2&b=3%3D2");
+ t.is( res["1 1"], "2", "parseQueryString pathological name" );
+ t.is( res.b, "3=2", "parseQueryString second name:value pair" );
+ var res = parseQueryString("foo=one&foo=two", true);
+ t.is( res["foo"].join(" "), "one two", "parseQueryString useArrays" );
+ var res = parseQueryString("?foo=2&bar=1");
+ t.is( res["foo"], "2", "parseQueryString strip leading question mark");
+
+ t.is( serializeJSON("foo\n\r\b\f\t"), "\"foo\\n\\r\\b\\f\\t\"", "string JSON" );
+ t.is( serializeJSON(null), "null", "null JSON");
+ try {
+ serializeJSON(undefined);
+ t.ok(false, "undefined should not be serializable");
+ } catch (e) {
+ t.ok(e instanceof TypeError, "undefined not serializable");
+ }
+ t.is( serializeJSON(1), "1", "1 JSON");
+ t.is( serializeJSON(1.23), "1.23", "1.23 JSON");
+ t.is( serializeJSON(serializeJSON), null, "function JSON (null, not string)" );
+ t.is( serializeJSON([1, "2", 3.3]), "[1, \"2\", 3.3]", "array JSON" );
+ var res = evalJSON(serializeJSON({"a":1, "b":2}));
+ t.is( res.a, 1, "evalJSON on an object (1)" );
+ t.is( res.b, 2, "evalJSON on an object (2)" );
+ var res = {"a": 1, "b": 2, "json": function () { return this; }};
+ var res = evalJSON(serializeJSON(res));
+ t.is( res.a, 1, "evalJSON on an object that jsons self (1)" );
+ t.is( res.b, 2, "evalJSON on an object that jsons self (2)" );
+ var strJSON = {"a": 1, "b": 2, "json": function () { return "json"; }};
+ t.is( serializeJSON(strJSON), "\"json\"", "json serialization calling" );
+ t.is( serializeJSON([strJSON]), "[\"json\"]", "json serialization calling in a structure" );
+ t.is( evalJSON('/* {"result": 1} */').result, 1, "json comment stripping" );
+ t.is( evalJSON('/* {"*/ /*": 1} */')['*/ /*'], 1, "json comment stripping" );
+ registerJSON("isDateLike",
+ isDateLike,
+ function (d) {
+ return "this was a date";
+ }
+ );
+ t.is( serializeJSON(new Date()), "\"this was a date\"", "json registry" );
+ MochiKit.Base.jsonRegistry.unregister("isDateLike");
+
+ var a = {"foo": {"bar": 12, "wibble": 13}};
+ var b = {"foo": {"baz": 4, "bar": 16}, "bar": 4};
+ updatetree(a, b);
+ var expect = [["bar", 16], ["baz", 4], ["wibble", 13]];
+ var got = items(a.foo);
+ got.sort(compare);
+ t.is( repr(got), repr(expect), "updatetree merge" );
+ t.is( a.bar, 4, "updatetree insert" );
+
+ var c = counter();
+ t.is( c(), 1, "counter starts at 1" );
+ t.is( c(), 2, "counter increases" );
+ c = counter(2);
+ t.is( c(), 2, "counter starts at 2" );
+ t.is( c(), 3, "counter increases" );
+
+ t.is( findValue([1, 2, 3], 4), -1, "findValue returns -1 on not found");
+ t.is( findValue([1, 2, 3], 1), 0, "findValue returns correct index");
+ t.is( findValue([1, 2, 3], 1, 1), -1, "findValue honors start");
+ t.is( findValue([1, 2, 3], 2, 0, 1), -1, "findValue honors end");
+ t.is( findIdentical([1, 2, 3], 4), -1, "findIdentical returns -1");
+ t.is( findIdentical([1, 2, 3], 1), 0, "findIdentical returns correct index");
+ t.is( findIdentical([1, 2, 3], 1, 1), -1, "findIdentical honors start");
+ t.is( findIdentical([1, 2, 3], 2, 0, 1), -1, "findIdentical honors end");
+ t.is( isNull(undefined), false, "isNull doesn't match undefined" );
+
+ var flat = flattenArguments(1, "2", 3, [4, [5, [6, 7], 8, [], 9]]);
+ var expect = [1, "2", 3, 4, 5, 6, 7, 8, 9];
+ t.is( repr(flat), repr(expect), "flattenArguments" );
+
+ var fn = function () {
+ return [this, concat(arguments)];
+ }
+ t.is( methodcaller("toLowerCase")("FOO"), "foo", "methodcaller with a method name" );
+ t.is( repr(methodcaller(fn, 2, 3)(1)), "[1, [2, 3]]", "methodcaller with a function" );
+
+ var f1 = function (x) { return [1, x]; };
+ var f2 = function (x) { return [2, x]; };
+ var f3 = function (x) { return [3, x]; };
+ t.is( repr(f1(f2(f3(4)))), "[1, [2, [3, 4]]]", "test the compose test" );
+ t.is( repr(compose(f1,f2,f3)(4)), "[1, [2, [3, 4]]]", "three fn composition works" );
+ t.is( repr(compose(compose(f1,f2),f3)(4)), "[1, [2, [3, 4]]]", "associative left" );
+ t.is( repr(compose(f1,compose(f2,f3))(4)), "[1, [2, [3, 4]]]", "associative right" );
+
+ try {
+ compose(f1, "foo");
+ t.ok( false, "wrong compose argument not raised!" );
+ } catch (e) {
+ t.is( e.name, 'TypeError', "wrong compose argument raised correctly" );
+ }
+
+ t.is(camelize('one'), 'one', 'one word');
+ t.is(camelize('one-two'), 'oneTwo', 'two words');
+ t.is(camelize('one-two-three'), 'oneTwoThree', 'three words');
+ t.is(camelize('1-one'), '1One', 'letter and word');
+ t.is(camelize('one-'), 'one', 'trailing hyphen');
+ t.is(camelize('-one'), 'One', 'starting hyphen');
+ t.is(camelize('o-two'), 'oTwo', 'one character and word');
+
+ var flat = flattenArray([1, "2", 3, [4, [5, [6, 7], 8, [], 9]]]);
+ var expect = [1, "2", 3, 4, 5, 6, 7, 8, 9];
+ t.is( repr(flat), repr(expect), "flattenArray" );
+
+ /* mean */
+ try {
+ mean();
+ t.ok( false, "no arguments didn't raise!" );
+ } catch (e) {
+ t.is( e.name, 'TypeError', "no arguments raised correctly" );
+ }
+ t.is( mean(1), 1, 'single argument (arg list)');
+ t.is( mean([1]), 1, 'single argument (array)');
+ t.is( mean(1,2,3), 2, 'three arguments (arg list)');
+ t.is( mean([1,2,3]), 2, 'three arguments (array)');
+ t.is( average(1), 1, 'test the average alias');
+
+ /* median */
+ try {
+ median();
+ t.ok( false, "no arguments didn't raise!" );
+ } catch (e) {
+ t.is( e.name, 'TypeError', "no arguments raised correctly" );
+ }
+ t.is( median(1), 1, 'single argument (arg list)');
+ t.is( median([1]), 1, 'single argument (array)');
+ t.is( median(3,1,2), 2, 'three arguments (arg list)');
+ t.is( median([3,1,2]), 2, 'three arguments (array)');
+ t.is( median(3,1,2,4), 2.5, 'four arguments (arg list)');
+ t.is( median([3,1,2,4]), 2.5, 'four arguments (array)');
+
+ /* #185 */
+ t.is( serializeJSON(parseQueryString("")), "{}", "parseQueryString('')" );
+ t.is( serializeJSON(parseQueryString("", true)), "{}", "parseQueryString('', true)" );
+
+ /* #109 */
+ t.is( queryString({ids: [1,2,3]}), "ids=1&ids=2&ids=3", "queryString array value" );
+ t.is( queryString({ids: "123"}), "ids=123", "queryString string value" );
+
+ /* test values */
+ var o = {a: 1, b: 2, c: 4, d: -1};
+ var got = values(o);
+ got.sort();
+ t.is( repr(got), repr([-1, 1, 2, 4]), "values()" );
+
+ t.is( queryString([["foo", "bar"], ["baz", "wibble"]]), "foo=baz&bar=wibble" );
+ o = parseQueryString("foo=1=1=1&bar=2&baz&wibble=");
+ t.is( o.foo, "1=1=1", "parseQueryString multiple = first" );
+ t.is( o.bar, "2", "parseQueryString multiple = second" );
+ t.is( o.baz, "", "parseQueryString multiple = third" );
+ t.is( o.wibble, "", "parseQueryString multiple = fourth" );
+
+};
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/test_Color.js b/dom/tests/mochitest/ajax/mochikit/tests/test_Color.js
new file mode 100644
index 0000000000..c736c8db34
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/test_Color.js
@@ -0,0 +1,137 @@
+if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Color'); }
+if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Color'); }
+if (typeof(tests) == 'undefined') { tests = {}; }
+
+tests.test_Color = function (t) {
+ var approx = function (a, b, msg) {
+ return t.is(a.toPrecision(4), b.toPrecision(4), msg);
+ };
+
+ t.is( Color.whiteColor().toHexString(), "#ffffff", "whiteColor has right hex" );
+ t.is( Color.blackColor().toHexString(), "#000000", "blackColor has right hex" );
+ t.is( Color.blueColor().toHexString(), "#0000ff", "blueColor has right hex" );
+ t.is( Color.redColor().toHexString(), "#ff0000", "redColor has right hex" );
+ t.is( Color.greenColor().toHexString(), "#00ff00", "greenColor has right hex" );
+ t.is( compare(Color.whiteColor(), Color.whiteColor()), 0, "default colors compare right" );
+ t.ok( Color.whiteColor() == Color.whiteColor(), "default colors are interned" );
+ t.is( Color.whiteColor().toRGBString(), "rgb(255,255,255)", "toRGBString white" );
+ t.is( Color.blueColor().toRGBString(), "rgb(0,0,255)", "toRGBString blue" );
+ t.is( Color.fromRGB(190/255, 222/255, 173/255).toHexString(), "#bedead", "fromRGB works" );
+ t.is( Color.fromRGB(226/255, 15.9/255, 182/255).toHexString(), "#e210b6", "fromRGB < 16 works" );
+ t.is( Color.fromRGB({r:190/255,g:222/255,b:173/255}).toHexString(), "#bedead", "alt fromRGB works" );
+ t.is( Color.fromHexString("#bedead").toHexString(), "#bedead", "round-trip hex" );
+ t.is( Color.fromString("#bedead").toHexString(), "#bedead", "round-trip string(hex)" );
+ t.is( Color.fromRGBString("rgb(190,222,173)").toHexString(), "#bedead", "round-trip rgb" );
+ t.is( Color.fromString("rgb(190,222,173)").toHexString(), "#bedead", "round-trip rgb" );
+
+ var hsl = Color.redColor().asHSL();
+ approx( hsl.h, 0.0, "red hsl.h" );
+ approx( hsl.s, 1.0, "red hsl.s" );
+ approx( hsl.l, 0.5, "red hsl.l" );
+ hsl = Color.fromRGB(0, 0, 0.5).asHSL();
+ approx( hsl.h, 2/3, "darkblue hsl.h" );
+ approx( hsl.s, 1.0, "darkblue hsl.s" );
+ approx( hsl.l, 0.25, "darkblue hsl.l" );
+ hsl = Color.fromString("#4169E1").asHSL();
+ approx( hsl.h, (5/8), "4169e1 h");
+ approx( hsl.s, (8/11), "4169e1 s");
+ approx( hsl.l, (29/51), "4169e1 l");
+ hsl = Color.fromString("#555544").asHSL();
+ approx( hsl.h, (1/6), "555544 h" );
+ approx( hsl.s, (1/9), "555544 s" );
+ approx( hsl.l, (3/10), "555544 l" );
+ hsl = Color.fromRGB(0.5, 1, 0.5).asHSL();
+ approx( hsl.h, 1/3, "aqua hsl.h" );
+ approx( hsl.s, 1.0, "aqua hsl.s" );
+ approx( hsl.l, 0.75, "aqua hsl.l" );
+ t.is(
+ Color.fromHSL(hsl.h, hsl.s, hsl.l).toHexString(),
+ Color.fromRGB(0.5, 1, 0.5).toHexString(),
+ "fromHSL works with components"
+ );
+ t.is(
+ Color.fromHSL(hsl).toHexString(),
+ Color.fromRGB(0.5, 1, 0.5).toHexString(),
+ "fromHSL alt form"
+ );
+ t.is(
+ Color.fromString("hsl(120,100%,75%)").toHexString(),
+ "#80ff80",
+ "fromHSLString"
+ );
+ t.is(
+ Color.fromRGB(0.5, 1, 0.5).toHSLString(),
+ "hsl(120,100.0%,75.00%)",
+ "toHSLString"
+ );
+ t.is( Color.fromHSL(0, 0, 0).toHexString(), "#000000", "fromHSL to black" );
+ hsl = Color.blackColor().asHSL();
+ approx( hsl.h, 0.0, "black hsl.h" );
+ approx( hsl.s, 0.0, "black hsl.s" );
+ approx( hsl.l, 0.0, "black hsl.l" );
+ hsl.h = 1.0;
+ hsl = Color.blackColor().asHSL();
+ approx( hsl.h, 0.0, "asHSL returns copy" );
+ var rgb = Color.brownColor().asRGB();
+ approx( rgb.r, 153/255, "brown rgb.r" );
+ approx( rgb.g, 102/255, "brown rgb.g" );
+ approx( rgb.b, 51/255, "brown rgb.b" );
+ rgb.r = 0;
+ rgb = Color.brownColor().asRGB();
+ approx( rgb.r, 153/255, "asRGB returns copy" );
+
+ t.is( Color.fromName("aqua").toHexString(), "#00ffff", "aqua fromName" );
+ t.is( Color.fromString("aqua").toHexString(), "#00ffff", "aqua fromString" );
+ t.is( Color.fromName("transparent"), Color.transparentColor(), "transparent fromName" );
+ t.is( Color.fromString("transparent"), Color.transparentColor(), "transparent fromString" );
+ t.is( Color.transparentColor().toRGBString(), "rgba(0,0,0,0)", "transparent toRGBString" );
+ t.is( Color.fromRGBString("rgba( 0, 255, 255, 50%)").asRGB().a, 0.5, "rgba parsing alpha correctly" );
+ t.is( Color.fromRGBString("rgba( 0, 255, 255, 50%)").toRGBString(), "rgba(0,255,255,0.5)", "rgba output correctly" );
+ t.is( Color.fromRGBString("rgba( 0, 255, 255, 1)").toHexString(), "#00ffff", "fromRGBString with spaces and alpha" );
+ t.is( Color.fromRGBString("rgb( 0, 255, 255)").toHexString(), "#00ffff", "fromRGBString with spaces" );
+ t.is( Color.fromRGBString("rgb( 0, 100%, 255)").toHexString(), "#00ffff", "fromRGBString with percents" );
+
+ var hsv = Color.redColor().asHSV();
+ approx( hsv.h, 0.0, "red hsv.h" );
+ approx( hsv.s, 1.0, "red hsv.s" );
+ approx( hsv.v, 1.0, "red hsv.v" );
+ t.is( Color.fromHSV(hsv).toHexString(), Color.redColor().toHexString(), "red hexstring" );
+ hsv = Color.fromRGB(0, 0, 0.5).asHSV();
+ approx( hsv.h, 2/3, "darkblue hsv.h" );
+ approx( hsv.s, 1.0, "darkblue hsv.s" );
+ approx( hsv.v, 0.5, "darkblue hsv.v" );
+ t.is( Color.fromHSV(hsv).toHexString(), Color.fromRGB(0, 0, 0.5).toHexString(), "darkblue hexstring" );
+ hsv = Color.fromString("#4169E1").asHSV();
+ approx( hsv.h, 5/8, "4169e1 h");
+ approx( hsv.s, 32/45, "4169e1 s");
+ approx( hsv.v, 15/17, "4169e1 l");
+ t.is( Color.fromHSV(hsv).toHexString(), "#4169e1", "4169e1 hexstring" );
+ hsv = Color.fromString("#555544").asHSV();
+ approx( hsv.h, 1/6, "555544 h" );
+ approx( hsv.s, 1/5, "555544 s" );
+ approx( hsv.v, 1/3, "555544 l" );
+ t.is( Color.fromHSV(hsv).toHexString(), "#555544", "555544 hexstring" );
+ hsv = Color.fromRGB(0.5, 1, 0.5).asHSV();
+ approx( hsv.h, 1/3, "aqua hsv.h" );
+ approx( hsv.s, 0.5, "aqua hsv.s" );
+ approx( hsv.v, 1, "aqua hsv.v" );
+ t.is(
+ Color.fromHSV(hsv.h, hsv.s, hsv.v).toHexString(),
+ Color.fromRGB(0.5, 1, 0.5).toHexString(),
+ "fromHSV works with components"
+ );
+ t.is(
+ Color.fromHSV(hsv).toHexString(),
+ Color.fromRGB(0.5, 1, 0.5).toHexString(),
+ "fromHSV alt form"
+ );
+ hsv = Color.fromRGB(1, 1, 1).asHSV()
+ approx( hsv.h, 0, 'white hsv.h' );
+ approx( hsv.s, 0, 'white hsv.s' );
+ approx( hsv.v, 1, 'white hsv.v' );
+ t.is(
+ Color.fromHSV(0, 0, 1).toHexString(),
+ '#ffffff',
+ 'HSV saturation'
+ );
+};
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/test_DateTime.js b/dom/tests/mochitest/ajax/mochikit/tests/test_DateTime.js
new file mode 100644
index 0000000000..cc2d958e3c
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/test_DateTime.js
@@ -0,0 +1,45 @@
+if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.DateTime'); }
+if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.DateTime'); }
+if (typeof(tests) == 'undefined') { tests = {}; }
+
+tests.test_DateTime = function (t) {
+ var testDate = isoDate('2005-2-3');
+ t.is(testDate.getFullYear(), 2005, "isoDate year ok");
+ t.is(testDate.getDate(), 3, "isoDate day ok");
+ t.is(testDate.getMonth(), 1, "isoDate month ok");
+ t.ok(objEqual(testDate, new Date("February 3, 2005")), "matches string date");
+ t.is(toISODate(testDate), '2005-02-03', 'toISODate ok');
+
+ var testDate = isoDate('2005-06-08');
+ t.is(testDate.getFullYear(), 2005, "isoDate year ok");
+ t.is(testDate.getDate(), 8, "isoDate day ok");
+ t.is(testDate.getMonth(), 5, "isoDate month ok");
+ t.ok(objEqual(testDate, new Date("June 8, 2005")), "matches string date");
+ t.is(toISODate(testDate), '2005-06-08', 'toISODate ok');
+
+ t.is(compare(new Date("February 3, 2005"), new Date(2005, 1, 3)), 0, "dates compare eq");
+ t.is(compare(new Date("February 3, 2005"), new Date(2005, 2, 3)), -1, "dates compare lt");
+ t.is(compare(new Date("February 3, 2005"), new Date(2005, 0, 3)), 1, "dates compare gt");
+
+ var testDate = isoDate('2005-2-3');
+ t.is(compare(americanDate('2/3/2005'), testDate), 0, "americanDate eq");
+ t.is(compare('2/3/2005', toAmericanDate(testDate)), 0, "toAmericanDate eq");
+
+ var testTimestamp = isoTimestamp('2005-2-3 22:01:03');
+ t.is(compare(testTimestamp, new Date(2005,1,3,22,1,3)), 0, "isoTimestamp eq");
+ t.is(compare(testTimestamp, isoTimestamp('2005-2-3T22:01:03')), 0, "isoTimestamp (real ISO) eq");
+ t.is(compare(toISOTimestamp(testTimestamp), '2005-02-03 22:01:03'), 0, "toISOTimestamp eq");
+ testTimestamp = isoTimestamp('2005-2-3T22:01:03Z');
+ t.is(toISOTimestamp(testTimestamp, true), '2005-02-03T22:01:03Z', "toISOTimestamp (real ISO) eq");
+
+ var localTZ = Math.round((new Date(2005,1,3,22,1,3)).getTimezoneOffset()/60)
+ var direction = (localTZ < 0) ? "+" : "-";
+ localTZ = Math.abs(localTZ);
+ localTZ = direction + ((localTZ < 10) ? "0" : "") + localTZ;
+ testTimestamp = isoTimestamp("2005-2-3T22:01:03" + localTZ);
+ var testDateTimestamp = new Date(2005,1,3,22,1,3);
+ t.is(compare(testTimestamp, testDateTimestamp), 0, "equal with local tz");
+ testTimestamp = isoTimestamp("2005-2-3T17:01:03-05");
+ var testDateTimestamp = new Date(Date.UTC(2005,1,3,22,1,3));
+ t.is(compare(testTimestamp, testDateTimestamp), 0, "equal with specific tz");
+};
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/test_DragAndDrop.js b/dom/tests/mochitest/ajax/mochikit/tests/test_DragAndDrop.js
new file mode 100644
index 0000000000..d3a3c58379
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/test_DragAndDrop.js
@@ -0,0 +1,30 @@
+if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Signal'); }
+if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Signal'); }
+if (typeof(tests) == 'undefined') { tests = {}; }
+
+tests.test_DragAndDrop = function (t) {
+
+ var drag1 = new MochiKit.DragAndDrop.Draggable('drag1', {'revert': true, 'ghosting': true});
+
+ var drop1 = new MochiKit.DragAndDrop.Droppable('drop1', {'hoverclass': 'drop-hover'});
+ drop1.activate();
+ t.is(hasElementClass('drop1', 'drop-hover'), true, "hoverclass ok");
+ drop1.deactivate();
+ t.is(hasElementClass('drop1', 'drop-hover'), false, "remove hoverclass ok");
+ drop1.destroy();
+
+ t.is( isEmpty(MochiKit.DragAndDrop.Droppables.drops), true, "Unregister droppable ok");
+
+ var onhover = function (element) {
+ t.is(element, getElement('drag1'), 'onhover ok');
+ };
+ var drop2 = new MochiKit.DragAndDrop.Droppable('drop1', {'onhover': onhover});
+ var pos = getElementPosition('drop1');
+ pos = {"x": pos.x + 5, "y": pos.y + 5};
+ MochiKit.DragAndDrop.Droppables.show({"page": pos}, getElement('drag1'));
+
+ drag1.destroy();
+ t.is( isEmpty(MochiKit.DragAndDrop.Draggables.drops), true, "Unregister draggable ok");
+
+};
+
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/test_Format.js b/dom/tests/mochitest/ajax/mochikit/tests/test_Format.js
new file mode 100644
index 0000000000..785cebf823
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/test_Format.js
@@ -0,0 +1,80 @@
+if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Format'); }
+if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Format'); }
+if (typeof(tests) == 'undefined') { tests = {}; }
+
+tests.test_Format = function (t) {
+ t.is( truncToFixed(0.1234, 3), "0.123", "truncToFixed truncate" );
+ t.is( truncToFixed(0.12, 3), "0.120", "truncToFixed trailing zeros" );
+ t.is( truncToFixed(0.15, 1), "0.1", "truncToFixed no round" );
+ t.is( truncToFixed(0.15, 0), "0", "truncToFixed zero (edge case)" );
+
+ t.is( roundToFixed(0.1234, 3), "0.123", "roundToFixed truncate" );
+ t.is( roundToFixed(0.12, 3), "0.120", "roundToFixed trailing zeros" );
+ t.is( roundToFixed(0.15, 1), "0.2", "roundToFixed round" );
+ t.is( roundToFixed(0.15, 0), "0", "roundToFixed zero (edge case)" );
+
+ t.is( twoDigitFloat(-0.1234), "-0.12", "twoDigitFloat -0.1234 correct");
+ t.is( twoDigitFloat(-0.1), "-0.1", "twoDigitFloat -0.1 correct");
+ t.is( twoDigitFloat(-0), "0", "twoDigitFloat -0 correct");
+ t.is( twoDigitFloat(0), "0", "twoDigitFloat 0 correct");
+ t.is( twoDigitFloat(1), "1", "twoDigitFloat 1 correct");
+ t.is( twoDigitFloat(1.0), "1", "twoDigitFloat 1.0 correct");
+ t.is( twoDigitFloat(1.2), "1.2", "twoDigitFloat 1.2 correct");
+ t.is( twoDigitFloat(1.234), "1.23", "twoDigitFloat 1.234 correct");
+ t.is( percentFormat(123), "12300%", "percentFormat 123 correct");
+ t.is( percentFormat(1.23), "123%", "percentFormat 123 correct");
+ t.is( twoDigitAverage(1, 0), "0", "twoDigitAverage dbz correct");
+ t.is( twoDigitAverage(1, 1), "1", "twoDigitAverage 1 correct");
+ t.is( twoDigitAverage(1, 10), "0.1", "twoDigitAverage .1 correct");
+ function reprIs(a, b) {
+ arguments[0] = repr(a);
+ arguments[1] = repr(b);
+ t.is.apply(this, arguments);
+ }
+ reprIs( lstrip("\r\t\n foo \n\t\r"), "foo \n\t\r", "lstrip whitespace chars" );
+ reprIs( rstrip("\r\t\n foo \n\t\r"), "\r\t\n foo", "rstrip whitespace chars" );
+ reprIs( strip("\r\t\n foo \n\t\r"), "foo", "strip whitespace chars" );
+ reprIs( lstrip("\r\n\t \r", "\r"), "\n\t \r", "lstrip custom chars" );
+ reprIs( rstrip("\r\n\t \r", "\r"), "\r\n\t ", "rstrip custom chars" );
+ reprIs( strip("\r\n\t \r", "\r"), "\n\t ", "strip custom chars" );
+
+ var nf = numberFormatter("$###,###.00 footer");
+ t.is( nf(1000.1), "$1,000.10 footer", "trailing zeros" );
+ t.is( nf(1000000.1), "$1,000,000.10 footer", "two seps" );
+ t.is( nf(100), "$100.00 footer", "shorter than sep" );
+ t.is( nf(100.555), "$100.56 footer", "rounding" );
+ t.is( nf(-100.555), "$-100.56 footer", "default neg" );
+ nf = numberFormatter("-$###,###.00");
+ t.is( nf(-100.555), "-$100.56", "custom neg" );
+ nf = numberFormatter("0000.0000");
+ t.is( nf(0), "0000.0000", "leading and trailing" );
+ t.is( nf(1.1), "0001.1000", "leading and trailing" );
+ t.is( nf(12345.12345), "12345.1235", "no need for leading/trailing" );
+ nf = numberFormatter("0000.0000");
+ t.is( nf("taco"), "", "default placeholder" );
+ nf = numberFormatter("###,###.00", "foo", "de_DE");
+ t.is( nf("taco"), "foo", "custom placeholder" );
+ t.is( nf(12345.12345), "12.345,12", "de_DE locale" );
+ nf = numberFormatter("#%");
+ t.is( nf(1), "100%", "trivial percent" );
+ t.is( nf(0.55), "55%", "percent" );
+
+ var customLocale = {
+ separator: " apples and ",
+ decimal: " bagels at ",
+ percent: "am for breakfast"};
+ var customFormatter = numberFormatter("###,###.0%", "No breakfast", customLocale);
+ t.is( customFormatter(23.458), "2 apples and 345 bagels at 8am for breakfast", "custom locale" );
+
+ nf = numberFormatter("###,###");
+ t.is( nf(123), "123", "large number format" );
+ t.is( nf(1234), "1,234", "large number format" );
+ t.is( nf(12345), "12,345", "large number format" );
+ t.is( nf(123456), "123,456", "large number format" );
+ t.is( nf(1234567), "1,234,567", "large number format" );
+ t.is( nf(12345678), "12,345,678", "large number format" );
+ t.is( nf(123456789), "123,456,789", "large number format" );
+ t.is( nf(1234567890), "1,234,567,890", "large number format" );
+ t.is( nf(12345678901), "12,345,678,901", "large number format" );
+ t.is( nf(123456789012), "123,456,789,012", "large number format" );
+};
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/test_Iter.js b/dom/tests/mochitest/ajax/mochikit/tests/test_Iter.js
new file mode 100644
index 0000000000..d0ff146ad1
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/test_Iter.js
@@ -0,0 +1,176 @@
+if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Iter'); }
+if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Iter'); }
+if (typeof(tests) == 'undefined') { tests = {}; }
+
+tests.test_Iter = function (t) {
+ t.is( sum([1, 2, 3, 4, 5]), 15, "sum works on Arrays" );
+ t.is( compare(list([1, 2, 3]), [1, 2, 3]), 0, "list([x]) == [x]" );
+ t.is( compare(list(range(6, 0, -1)), [6, 5, 4, 3, 2, 1]), 0, "list(range(6, 0, -1)");
+ t.is( compare(list(range(6)), [0, 1, 2, 3, 4, 5]), 0, "list(range(6))" );
+ var moreThanTwo = partial(operator.lt, 2);
+ t.is( sum(ifilter(moreThanTwo, range(6))), 12, "sum(ifilter(, range()))" );
+ t.is( sum(ifilterfalse(moreThanTwo, range(6))), 3, "sum(ifilterfalse(, range()))" );
+
+ var c = count(10);
+ t.is( compare([c.next(), c.next(), c.next()], [10, 11, 12]), 0, "count()" );
+ c = cycle([1, 2]);
+ t.is( compare([c.next(), c.next(), c.next()], [1, 2, 1]), 0, "cycle()" );
+ c = repeat("foo", 3);
+ t.is( compare(list(c), ["foo", "foo", "foo"]), 0, "repeat()" );
+ c = izip([1, 2], [3, 4, 5], repeat("foo"));
+ t.is( compare(list(c), [[1, 3, "foo"], [2, 4, "foo"]]), 0, "izip()" );
+
+ t.is( compare(list(range(5)), [0, 1, 2, 3, 4]), 0, "range(x)" );
+ c = islice(range(10), 0, 10, 2);
+ t.is( compare(list(c), [0, 2, 4, 6, 8]), 0, "islice(x, y, z)" );
+
+ c = imap(operator.add, [1, 2, 3], [2, 4, 6]);
+ t.is( compare(list(c), [3, 6, 9]), 0, "imap(fn, p, q)" );
+
+ c = filter(partial(operator.lt, 1), iter([1, 2, 3]));
+ t.is( compare(c, [2, 3]), 0, "filter(fn, iterable)" );
+
+ c = map(partial(operator.add, -1), iter([1, 2, 3]));
+ t.is( compare(c, [0, 1, 2]), 0, "map(fn, iterable)" );
+
+ c = map(operator.add, iter([1, 2, 3]), [2, 4, 6]);
+ t.is( compare(c, [3, 6, 9]), 0, "map(fn, iterable, q)" );
+
+ c = map(operator.add, iter([1, 2, 3]), iter([2, 4, 6]));
+ t.is( compare(c, [3, 6, 9]), 0, "map(fn, iterable, iterable)" );
+
+ c = applymap(operator.add, [[1, 2], [2, 4], [3, 6]]);
+ t.is( compare(list(c), [3, 6, 9]), 0, "applymap()" );
+
+ c = applymap(function (a) { return [this, a]; }, [[1], [2]], 1);
+ t.is( compare(list(c), [[1, 1], [1, 2]]), 0, "applymap(self)" );
+
+ c = chain(range(2), range(3));
+ t.is( compare(list(c), [0, 1, 0, 1, 2]), 0, "chain(p, q)" );
+
+ var lessThanFive = partial(operator.gt, 5);
+ c = takewhile(lessThanFive, count());
+ t.is( compare(list(c), [0, 1, 2, 3, 4]), 0, "takewhile()" );
+
+ c = dropwhile(lessThanFive, range(10));
+ t.is( compare(list(c), [5, 6, 7, 8, 9]), 0, "dropwhile()" );
+
+ c = tee(range(5), 3);
+ t.is( compare(list(c[0]), list(c[1])), 0, "tee(..., 3) p0 == p1" );
+ t.is( compare(list(c[2]), [0, 1, 2, 3, 4]), 0, "tee(..., 3) p2 == fixed" );
+
+ t.is( compare(reduce(operator.add, range(10)), 45), 0, "reduce(op.add)" );
+
+ try {
+ reduce(operator.add, []);
+ t.ok( false, "reduce didn't raise anything with empty list and no start?!" );
+ } catch (e) {
+ if (e instanceof TypeError) {
+ t.ok( true, "reduce raised TypeError correctly" );
+ } else {
+ t.ok( false, "reduce raised the wrong exception?" );
+ }
+ }
+
+ t.is( reduce(operator.add, [], 10), 10, "range initial value OK empty" );
+ t.is( reduce(operator.add, [1], 10), 11, "range initial value OK populated" );
+
+ t.is( compare(iextend([1], range(2)), [1, 0, 1]), 0, "iextend(...)" );
+
+ var x = [];
+ exhaust(imap(bind(x.push, x), range(5)));
+ t.is( compare(x, [0, 1, 2, 3, 4]), 0, "exhaust(...)" );
+
+ t.is( every([1, 2, 3, 4, 5, 4], lessThanFive), false, "every false" );
+ t.is( every([1, 2, 3, 4, 4], lessThanFive), true, "every true" );
+ t.is( some([1, 2, 3, 4, 4], lessThanFive), true, "some true" );
+ t.is( some([5, 6, 7, 8, 9], lessThanFive), false, "some false" );
+ t.is( some([5, 6, 7, 8, 4], lessThanFive), true, "some true" );
+
+ var rval = [];
+ forEach(range(2), rval.push, rval);
+ t.is( compare(rval, [0, 1]), 0, "forEach works bound" );
+
+ function foo(o) {
+ rval.push(o);
+ }
+ forEach(range(2), foo);
+ t.is( compare(rval, [0, 1, 0, 1]), 0, "forEach works unbound" );
+
+ t.is( compare(sorted([3, 2, 1]), [1, 2, 3]), 0, "sorted default" );
+ rval = sorted(["aaa", "bb", "c"], keyComparator("length"));
+ t.is(compare(rval, ["c", "bb", "aaa"]), 0, "sorted custom");
+
+ t.is( compare(reversed(range(4)), [3, 2, 1, 0]), 0, "reversed iterator" );
+ t.is( compare(reversed([5, 6, 7]), [7, 6, 5]), 0, "reversed list" );
+
+ var o = {lst: [1, 2, 3], iterateNext: function () { return this.lst.shift(); }};
+ t.is( compare(list(o), [1, 2, 3]), 0, "iterateNext" );
+
+
+ function except(exc, func) {
+ try {
+ func();
+ t.ok(false, exc.name + " was not raised.");
+ } catch (e) {
+ if (e == exc) {
+ t.ok( true, "raised " + exc.name + " correctly" );
+ } else {
+ t.ok( false, "raised the wrong exception?" );
+ }
+ }
+ }
+
+ odd = partial(operator.and, 1)
+
+ // empty
+ grouped = groupby([]);
+ except(StopIteration, grouped.next);
+
+ // exhaust sub-iterator
+ grouped = groupby([2,4,6,7], odd);
+ kv = grouped.next(); k = kv[0], subiter = kv[1];
+ t.is(k, 0, "odd(2) = odd(4) = odd(6) == 0");
+ t.is(subiter.next(), 2, "sub-iterator.next() == 2");
+ t.is(subiter.next(), 4, "sub-iterator.next() == 4");
+ t.is(subiter.next(), 6, "sub-iterator.next() == 6");
+ except(StopIteration, subiter.next);
+ kv = grouped.next(); key = kv[0], subiter = kv[1];
+ t.is(key, 1, "odd(7) == 1");
+ t.is(subiter.next(), 7, "sub-iterator.next() == 7");
+ except(StopIteration, subiter.next);
+
+ // not consume sub-iterator
+ grouped = groupby([2,4,6,7], odd);
+ kv = grouped.next(); key = kv[0], subiter = kv[1];
+ t.is(key, 0, "0 = odd(2) = odd(4) = odd(6)");
+ kv = grouped.next(); key = kv[0], subiter = kv[1];
+ t.is(key, 1, "1 = odd(7)");
+ except(StopIteration, grouped.next);
+
+ // consume sub-iterator partially
+ grouped = groupby([3,1,1,2], odd);
+ kv = grouped.next(); key = kv[0], subiter = kv[1];
+ t.is(key, 1, "odd(1) == 1");
+ t.is(subiter.next(), 3, "sub-iterator.next() == 3");
+ kv = grouped.next(); key = kv[0], v = kv[1];
+ t.is(key, 0, "skip (1,1), odd(2) == 0");
+ except(StopIteration, grouped.next);
+
+ // null
+ grouped = groupby([null,null]);
+ kv = grouped.next(); k = kv[0], v = kv[1];
+ t.is(k, null, "null ok");
+
+ // groupby - array version
+ isEqual = (t.isDeeply || function (a, b, msg) {
+ return t.ok(compare(a, b) == 0, msg);
+ });
+ isEqual(groupby_as_array([ ] ), [ ], "empty");
+ isEqual(groupby_as_array([1,1,1]), [ [1,[1,1,1]] ], "[1,1,1]: [1,1,1]");
+ isEqual(groupby_as_array([1,2,2]), [ [1,[1] ], [2,[2,2]] ], "[1,2,2]: [1], [2,2]");
+ isEqual(groupby_as_array([1,1,2]), [ [1,[1,1] ], [2,[2 ]] ], "[1,1,2]: [1,1], [2]");
+ isEqual(groupby_as_array([null,null] ), [ [null,[null,null]] ], "[null,null]: [null,null]");
+ grouped = groupby_as_array([1,1,3,2,4,6,8], odd);
+ isEqual(grouped, [[1, [1,1,3]], [0,[2,4,6,8]]], "[1,1,3,2,4,6,7] odd: [1,1,3], [2,4,6,8]");
+};
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/test_Logging.js b/dom/tests/mochitest/ajax/mochikit/tests/test_Logging.js
new file mode 100644
index 0000000000..66f4989b02
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/test_Logging.js
@@ -0,0 +1,75 @@
+if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Logging'); }
+if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Logging'); }
+if (typeof(tests) == 'undefined') { tests = {}; }
+
+tests.test_Logging = function (t) {
+
+ // just in case
+ logger.clear();
+
+ t.is( logLevelAtLeast('DEBUG')('INFO'), false, 'logLevelAtLeast false' );
+ t.is( logLevelAtLeast('WARNING')('INFO'), false, 'logLevelAtLeast true' );
+ t.ok( logger instanceof Logger, "global logger installed" );
+
+ var allMessages = [];
+ logger.addListener("allMessages", null,
+ bind(allMessages.push, allMessages));
+
+ var fatalMessages = [];
+ logger.addListener("fatalMessages", "FATAL",
+ bind(fatalMessages.push, fatalMessages));
+
+ var firstTwo = [];
+ logger.addListener("firstTwo", null,
+ bind(firstTwo.push, firstTwo));
+
+
+ log("foo");
+ var msgs = logger.getMessages();
+ t.is( msgs.length, 1, 'global log() put one message in queue' );
+ t.is( compare(allMessages, msgs), 0, "allMessages listener" );
+ var msg = msgs.pop();
+ t.is( compare(msg.info, ["foo"]), 0, "info matches" );
+ t.is( msg.level, "INFO", "level matches" );
+
+ logDebug("debugFoo");
+ t.is( msgs.length, 0, 'getMessages() returns copy' );
+ msgs = logger.getMessages();
+ t.is( compare(allMessages, msgs), 0, "allMessages listener" );
+ t.is( msgs.length, 2, 'logDebug()' );
+ msg = msgs.pop();
+ t.is( compare(msg.info, ["debugFoo"]), 0, "info matches" );
+ t.is( msg.level, "DEBUG", "level matches" );
+
+ logger.removeListener("firstTwo");
+
+ logError("errorFoo");
+ msgs = logger.getMessages();
+ t.is( compare(allMessages, msgs), 0, "allMessages listener" );
+ t.is( msgs.length, 3, 'logError()' );
+ msg = msgs.pop();
+ t.is( compare(msg.info, ["errorFoo"]), 0, "info matches" );
+ t.is( msg.level, "ERROR", "level matches" );
+
+ logWarning("warningFoo");
+ msgs = logger.getMessages();
+ t.is( compare(allMessages, msgs), 0, "allMessages listener" );
+ t.is( msgs.length, 4, 'logWarning()' );
+ msg = msgs.pop();
+ t.is( compare(msg.info, ["warningFoo"]), 0, "info matches" );
+ t.is( msg.level, "WARNING", "level matches" );
+
+ logFatal("fatalFoo");
+ msgs = logger.getMessages();
+ t.is( compare(allMessages, msgs), 0, "allMessages listener" );
+ t.is( msgs.length, 5, 'logFatal()' );
+ msg = msgs.pop();
+ t.is( compare(fatalMessages, [msg]), 0, "fatalMessages listener" );
+ t.is( compare(msg.info, ["fatalFoo"]), 0, "info matches" );
+ t.is( msg.level, "FATAL", "level matches" );
+
+ logger.removeListener("allMessages");
+ logger.removeListener("fatalMessages");
+
+ t.is( compare(firstTwo, logger.getMessages().slice(0, 2)), 0, "firstTwo" );
+};
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/test_MochiKit-Async.json b/dom/tests/mochitest/ajax/mochikit/tests/test_MochiKit-Async.json
new file mode 100644
index 0000000000..037e18c818
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/test_MochiKit-Async.json
@@ -0,0 +1 @@
+{"passed": true}
diff --git a/dom/tests/mochitest/ajax/mochikit/tests/test_Signal.js b/dom/tests/mochitest/ajax/mochikit/tests/test_Signal.js
new file mode 100644
index 0000000000..6a905952f7
--- /dev/null
+++ b/dom/tests/mochitest/ajax/mochikit/tests/test_Signal.js
@@ -0,0 +1,441 @@
+if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Signal'); }
+if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Signal'); }
+if (typeof(tests) == 'undefined') { tests = {}; }
+
+tests.test_Signal = function (t) {
+
+ var submit = MochiKit.DOM.getElement('submit');
+ var ident = null;
+ var i = 0;
+ var aFunction = function() {
+ t.ok(this === submit, "aFunction should have 'this' as submit");
+ i++;
+ if (typeof(this.someVar) != 'undefined') {
+ i += this.someVar;
+ }
+ };
+
+ var aObject = {};
+ aObject.aMethod = function() {
+ t.ok(this === aObject, "aMethod should have 'this' as aObject");
+ i++;
+ };
+
+ ident = connect('submit', 'onclick', aFunction);
+ MochiKit.DOM.getElement('submit').click();
+ t.is(i, 1, 'HTML onclick event can be connected to a function');
+
+ disconnect(ident);
+ MochiKit.DOM.getElement('submit').click();
+ t.is(i, 1, 'HTML onclick can be disconnected from a function');
+
+ var submit = MochiKit.DOM.getElement('submit');
+
+ ident = connect(submit, 'onclick', aFunction);
+ submit.click();
+ t.is(i, 2, 'Checking that a DOM element can be connected to a function');
+
+ disconnect(ident);
+ submit.click();
+ t.is(i, 2, '...and then disconnected');
+
+ if (MochiKit.DOM.getElement('submit').fireEvent ||
+ (document.createEvent &&
+ typeof(document.createEvent('MouseEvents').initMouseEvent) == 'function')) {
+
+ /*
+
+ Adapted from:
+ http://www.devdaily.com/java/jwarehouse/jforum/tests/selenium/javascript/htmlutils.js.shtml
+ License: Apache
+ Copyright: Copyright 2004 ThoughtWorks, Inc
+
+ */
+ var triggerMouseEvent = function(element, eventType, canBubble) {
+ element = MochiKit.DOM.getElement(element);
+ canBubble = (typeof(canBubble) == 'undefined') ? true : canBubble;
+ if (element.fireEvent) {
+ var newEvt = document.createEventObject();
+ newEvt.clientX = 1;
+ newEvt.clientY = 1;
+ newEvt.button = 1;
+ element.fireEvent('on' + eventType, newEvt);
+ } else if (document.createEvent && (typeof(document.createEvent('MouseEvents').initMouseEvent) == 'function')) {
+ var evt = document.createEvent('MouseEvents');
+ evt.initMouseEvent(eventType, canBubble, true, // event, bubbles, cancelable
+ document.defaultView, 1, // view, # of clicks
+ 1, 0, 0, 0, // screenX, screenY, clientX, clientY
+ false, false, false, false, // ctrlKey, altKey, shiftKey, metaKey
+ 0, null); // buttonCode, relatedTarget
+ element.dispatchEvent(evt);
+ }
+ };
+
+ var eventTest = function(e) {
+ i++;
+ t.ok((typeof(e.event()) === 'object'), 'checking that event() is an object');
+ t.ok((typeof(e.type()) === 'string'), 'checking that type() is a string');
+ t.ok((e.target() === MochiKit.DOM.getElement('submit')), 'checking that target is "submit"');
+ t.ok((typeof(e.modifier()) === 'object'), 'checking that modifier() is an object');
+ t.ok(e.modifier().alt === false, 'checking that modifier().alt is defined, but false');
+ t.ok(e.modifier().ctrl === false, 'checking that modifier().ctrl is defined, but false');
+ t.ok(e.modifier().meta === false, 'checking that modifier().meta is defined, but false');
+ t.ok(e.modifier().shift === false, 'checking that modifier().shift is defined, but false');
+ t.ok((typeof(e.mouse()) === 'object'), 'checking that mouse() is an object');
+ t.ok((typeof(e.mouse().button) === 'object'), 'checking that mouse().button is an object');
+ t.ok(e.mouse().button.left === true, 'checking that mouse().button.left is true');
+ t.ok(e.mouse().button.middle === false, 'checking that mouse().button.middle is false');
+ t.ok(e.mouse().button.right === false, 'checking that mouse().button.right is false');
+ t.ok((typeof(e.mouse().page) === 'object'), 'checking that mouse().page is an object');
+ t.ok((typeof(e.mouse().page.x) === 'number'), 'checking that mouse().page.x is a number');
+ t.ok((typeof(e.mouse().page.y) === 'number'), 'checking that mouse().page.y is a number');
+ t.ok((typeof(e.mouse().client) === 'object'), 'checking that mouse().client is an object');
+ t.ok((typeof(e.mouse().client.x) === 'number'), 'checking that mouse().client.x is a number');
+ t.ok((typeof(e.mouse().client.y) === 'number'), 'checking that mouse().client.y is a number');
+
+ /* these should not be defined */
+ t.ok((typeof(e.relatedTarget()) === 'undefined'), 'checking that relatedTarget() is undefined');
+ t.ok((typeof(e.key()) === 'undefined'), 'checking that key() is undefined');
+ };
+
+
+ ident = connect('submit', 'onmousedown', eventTest);
+ triggerMouseEvent('submit', 'mousedown', false);
+ t.is(i, 3, 'Connecting an event to an HTML object and firing a synthetic event');
+
+ disconnect(ident);
+ triggerMouseEvent('submit', 'mousedown', false);
+ t.is(i, 3, 'Disconnecting an event to an HTML object and firing a synthetic event');
+
+
+
+ }
+
+ // non-DOM tests
+
+ var hasNoSignals = {};
+
+ var hasSignals = {someVar: 1};
+
+ var i = 0;
+
+ var aFunction = function() {
+ i++;
+ if (typeof(this.someVar) != 'undefined') {
+ i += this.someVar;
+ }
+ };
+
+ var bFunction = function(someArg, someOtherArg) {
+ i += someArg + someOtherArg;
+ };
+
+
+ var aObject = {};
+ aObject.aMethod = function() {
+ i++;
+ };
+
+ aObject.bMethod = function() {
+ i++;
+ };
+
+ var bObject = {};
+ bObject.bMethod = function() {
+ i++;
+ };
+
+
+ ident = connect(hasSignals, 'signalOne', aFunction);
+ signal(hasSignals, 'signalOne');
+ t.is(i, 2, 'Connecting function');
+ i = 0;
+
+ disconnect(ident);
+ signal(hasSignals, 'signalOne');
+ t.is(i, 0, 'New style disconnecting function');
+ i = 0;
+
+
+ ident = connect(hasSignals, 'signalOne', bFunction);
+ signal(hasSignals, 'signalOne', 1, 2);
+ t.is(i, 3, 'Connecting function');
+ i = 0;
+
+ disconnect(ident);
+ signal(hasSignals, 'signalOne', 1, 2);
+ t.is(i, 0, 'New style disconnecting function');
+ i = 0;
+
+
+ connect(hasSignals, 'signalOne', aFunction);
+ signal(hasSignals, 'signalOne');
+ t.is(i, 2, 'Connecting function');
+ i = 0;
+
+ disconnect(hasSignals, 'signalOne', aFunction);
+ signal(hasSignals, 'signalOne');
+ t.is(i, 0, 'Old style disconnecting function');
+ i = 0;
+
+
+ ident = connect(hasSignals, 'signalOne', aObject, aObject.aMethod);
+ signal(hasSignals, 'signalOne');
+ t.is(i, 1, 'Connecting obj-function');
+ i = 0;
+
+ disconnect(ident);
+ signal(hasSignals, 'signalOne');
+ t.is(i, 0, 'New style disconnecting obj-function');
+ i = 0;
+
+ connect(hasSignals, 'signalOne', aObject, aObject.aMethod);
+ signal(hasSignals, 'signalOne');
+ t.is(i, 1, 'Connecting obj-function');
+ i = 0;
+
+ disconnect(hasSignals, 'signalOne', aObject, aObject.aMethod);
+ signal(hasSignals, 'signalOne');
+ t.is(i, 0, 'Disconnecting obj-function');
+ i = 0;
+
+
+ ident = connect(hasSignals, 'signalTwo', aObject, 'aMethod');
+ signal(hasSignals, 'signalTwo');
+ t.is(i, 1, 'Connecting obj-string');
+ i = 0;
+
+ disconnect(ident);
+ signal(hasSignals, 'signalTwo');
+ t.is(i, 0, 'New style disconnecting obj-string');
+ i = 0;
+
+
+ connect(hasSignals, 'signalTwo', aObject, 'aMethod');
+ signal(hasSignals, 'signalTwo');
+ t.is(i, 1, 'Connecting obj-string');
+ i = 0;
+
+ disconnect(hasSignals, 'signalTwo', aObject, 'aMethod');
+ signal(hasSignals, 'signalTwo');
+ t.is(i, 0, 'Old style disconnecting obj-string');
+ i = 0;
+
+
+ var shouldRaise = function() { return undefined.attr; };
+
+ try {
+ connect(hasSignals, 'signalOne', shouldRaise);
+ signal(hasSignals, 'signalOne');
+ t.ok(false, 'An exception was not raised');
+ } catch (e) {
+ t.ok(true, 'An exception was raised');
+ }
+ disconnect(hasSignals, 'signalOne', shouldRaise);
+ t.is(i, 0, 'Exception raised, signal should not have fired');
+ i = 0;
+
+
+ connect(hasSignals, 'signalOne', aObject, 'aMethod');
+ connect(hasSignals, 'signalOne', aObject, 'bMethod');
+ signal(hasSignals, 'signalOne');
+ t.is(i, 2, 'Connecting one signal to two slots in one object');
+ i = 0;
+
+ disconnect(hasSignals, 'signalOne', aObject, 'aMethod');
+ disconnect(hasSignals, 'signalOne', aObject, 'bMethod');
+ signal(hasSignals, 'signalOne');
+ t.is(i, 0, 'Disconnecting one signal from two slots in one object');
+ i = 0;
+
+
+ connect(hasSignals, 'signalOne', aObject, 'aMethod');
+ connect(hasSignals, 'signalOne', bObject, 'bMethod');
+ signal(hasSignals, 'signalOne');
+ t.is(i, 2, 'Connecting one signal to two slots in two objects');
+ i = 0;
+
+ disconnect(hasSignals, 'signalOne', aObject, 'aMethod');
+ disconnect(hasSignals, 'signalOne', bObject, 'bMethod');
+ signal(hasSignals, 'signalOne');
+ t.is(i, 0, 'Disconnecting one signal from two slots in two objects');
+ i = 0;
+
+
+ try {
+ connect(nothing, 'signalOne', aObject, 'aMethod');
+ signal(nothing, 'signalOne');
+ t.ok(false, 'An exception was not raised when connecting undefined');
+ } catch (e) {
+ t.ok(true, 'An exception was raised when connecting undefined');
+ }
+
+ try {
+ disconnect(nothing, 'signalOne', aObject, 'aMethod');
+ t.ok(false, 'An exception was not raised when disconnecting undefined');
+ } catch (e) {
+ t.ok(true, 'An exception was raised when disconnecting undefined');
+ }
+
+
+ try {
+ connect(hasSignals, 'signalOne', nothing);
+ signal(hasSignals, 'signalOne');
+ t.ok(false, 'An exception was not raised when connecting an undefined function');
+ } catch (e) {
+ t.ok(true, 'An exception was raised when connecting an undefined function');
+ }
+
+ try {
+ disconnect(hasSignals, 'signalOne', nothing);
+ t.ok(false, 'An exception was not raised when disconnecting an undefined function');
+ } catch (e) {
+ t.ok(true, 'An exception was raised when disconnecting an undefined function');
+ }
+
+
+ try {
+ connect(hasSignals, 'signalOne', aObject, aObject.nothing);
+ signal(hasSignals, 'signalOne');
+ t.ok(false, 'An exception was not raised when connecting an undefined method');
+ } catch (e) {
+ t.ok(true, 'An exception was raised when connecting an undefined method');
+ }
+
+ try {
+ connect(hasSignals, 'signalOne', aObject, 'nothing');
+ signal(hasSignals, 'signalOne');
+ t.ok(false, 'An exception was not raised when connecting an undefined method (as string)');
+ } catch (e) {
+ t.ok(true, 'An exception was raised when connecting an undefined method (as string)');
+ }
+
+ t.is(i, 0, 'Signals should not have fired');
+
+ connect(hasSignals, 'signalOne', aFunction);
+ connect(hasSignals, 'signalOne', aObject, 'aMethod');
+ disconnectAll(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalOne');
+ t.is(i, 0, 'disconnectAll works with single explicit signal');
+ i = 0;
+
+ connect(hasSignals, 'signalOne', aFunction);
+ connect(hasSignals, 'signalOne', aObject, 'aMethod');
+ connect(hasSignals, 'signalTwo', aFunction);
+ connect(hasSignals, 'signalTwo', aObject, 'aMethod');
+ disconnectAll(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalOne');
+ t.is(i, 0, 'disconnectAll works with single explicit signal');
+ signal(hasSignals, 'signalTwo');
+ t.is(i, 3, 'disconnectAll does not disconnect unrelated signals');
+ i = 0;
+
+ connect(hasSignals, 'signalOne', aFunction);
+ connect(hasSignals, 'signalOne', aObject, 'aMethod');
+ connect(hasSignals, 'signalTwo', aFunction);
+ connect(hasSignals, 'signalTwo', aObject, 'aMethod');
+ disconnectAll(hasSignals, 'signalOne', 'signalTwo');
+ signal(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalTwo');
+ t.is(i, 0, 'disconnectAll works with two explicit signals');
+ i = 0;
+
+ connect(hasSignals, 'signalOne', aFunction);
+ connect(hasSignals, 'signalOne', aObject, 'aMethod');
+ connect(hasSignals, 'signalTwo', aFunction);
+ connect(hasSignals, 'signalTwo', aObject, 'aMethod');
+ disconnectAll(hasSignals, ['signalOne', 'signalTwo']);
+ signal(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalTwo');
+ t.is(i, 0, 'disconnectAll works with two explicit signals as a list');
+ i = 0;
+
+ connect(hasSignals, 'signalOne', aFunction);
+ connect(hasSignals, 'signalOne', aObject, 'aMethod');
+ connect(hasSignals, 'signalTwo', aFunction);
+ connect(hasSignals, 'signalTwo', aObject, 'aMethod');
+ disconnectAll(hasSignals);
+ signal(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalTwo');
+ t.is(i, 0, 'disconnectAll works with implicit signals');
+ i = 0;
+
+ var toggle = function() {
+ disconnectAll(hasSignals, 'signalOne');
+ connect(hasSignals, 'signalOne', aFunction);
+ i++;
+ };
+
+ connect(hasSignals, 'signalOne', aFunction);
+ connect(hasSignals, 'signalTwo', function() { i++; });
+ connect(hasSignals, 'signalTwo', toggle);
+ connect(hasSignals, 'signalTwo', function() { i++; }); // #147
+ connect(hasSignals, 'signalTwo', function() { i++; });
+ signal(hasSignals, 'signalTwo');
+ t.is(i, 4, 'disconnectAll fired in a signal loop works');
+ i = 0;
+ disconnectAll('signalOne');
+ disconnectAll('signalTwo');
+
+ var testfunc = function () { arguments.callee.count++; };
+ testfunc.count = 0;
+ var testObj = {
+ methOne: function () { this.countOne++; }, countOne: 0,
+ methTwo: function () { this.countTwo++; }, countTwo: 0
+ };
+ connect(hasSignals, 'signalOne', testfunc);
+ connect(hasSignals, 'signalTwo', testfunc);
+ signal(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalTwo');
+ t.is(testfunc.count, 2, 'disconnectAllTo func precondition');
+ disconnectAllTo(testfunc);
+ signal(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalTwo');
+ t.is(testfunc.count, 2, 'disconnectAllTo func');
+
+ connect(hasSignals, 'signalOne', testObj, 'methOne');
+ connect(hasSignals, 'signalTwo', testObj, 'methTwo');
+ signal(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalTwo');
+ t.is(testObj.countOne, 1, 'disconnectAllTo obj precondition');
+ t.is(testObj.countTwo, 1, 'disconnectAllTo obj precondition');
+ disconnectAllTo(testObj);
+ signal(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalTwo');
+ t.is(testObj.countOne, 1, 'disconnectAllTo obj');
+ t.is(testObj.countTwo, 1, 'disconnectAllTo obj');
+
+ testObj.countOne = testObj.countTwo = 0;
+ connect(hasSignals, 'signalOne', testObj, 'methOne');
+ connect(hasSignals, 'signalTwo', testObj, 'methTwo');
+ disconnectAllTo(testObj, 'methOne');
+ signal(hasSignals, 'signalOne');
+ signal(hasSignals, 'signalTwo');
+ t.is(testObj.countOne, 0, 'disconnectAllTo obj+str');
+ t.is(testObj.countTwo, 1, 'disconnectAllTo obj+str');
+
+ has__Connect = {
+ count: 0,
+ __connect__: function (ident) {
+ this.count += arguments.length;
+ disconnect(ident);
+ }
+ };
+
+ connect(has__Connect, 'signalOne', aFunction);
+ t.is(has__Connect.count, 3, '__connect__ is called when it exists');
+ signal(has__Connect, 'signalOne');
+ t.is(has__Connect.count, 3, '__connect__ can disconnect the signal');
+
+ var events = {};
+ var test_ident = connect(events, "test", function() {
+ var fail_ident = connect(events, "fail", function () {
+ events.failed = true;
+ });
+ disconnect(fail_ident);
+ signal(events, "fail");
+ });
+ signal(events, "test");
+ t.is(events.failed, undefined, 'disconnected slots do not fire');
+
+};