Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix #2, #4, use node.js for tests

  • Loading branch information...
commit d1e3320e6015fab1c76de06469d3373c55d5321e 1 parent b3f9fa6
@cho45 authored
View
4 Rakefile
@@ -39,7 +39,8 @@ task :create => RELEASES
desc "Test JSDeferred"
task :test => RELEASES do
- sh %{rhino -opt 0 -w -strict test-rhino.js jsdeferred.js}
+ # sh %{rhino -opt 0 -w -strict test-rhino.js jsdeferred.js}
+ sh %{node test-node.js}
end
desc "Make all release file and tagging #{Version}"
@@ -88,6 +89,7 @@ file "jsdeferred.jquery.js" => ["jsdeferred.js", "binding/jquery.js"] do |t|
}
end
+
file "jsdeferred.userscript.js" => ["jsdeferred.js", "binding/userscript.js"] do |t|
File.open(t.name, "w") {|f|
f.puts "// Usage:: with (D()) { your code }"
View
2  binding/jquery.js
@@ -1,7 +1,7 @@
(function ($) {
$.deferred = Deferred;
$.fn.extend({
- deferred: function(name) {
+ deferred: function (name) {
var args = Array.prototype.slice.call(arguments, 1);
return Deferred.connect(this[name], { target:this }).apply(null, args);
}
View
55 binding/userscript.js
@@ -1,32 +1,6 @@
function D () {
/*include JSDeferred*/
-/* function xhttp (opts) //=> Deferred
- * Cross site version of `http`.
- */
-/* function xhttp.get (url) //=> Deferred
- */
-/* function xhttp.post (url, data) //=> Deferred
- */
-function xhttp (opts) {
- var d = Deferred();
- if (opts.onload) d = d.next(opts.onload);
- if (opts.onerror) d = d.error(opts.onerror);
- opts.onload = function (res) {
- d.call(res);
- };
- opts.onerror = function (res) {
- d.fail(res);
- };
- setTimeout(function () {
- GM_xmlhttpRequest(opts);
- }, 0);
- return d;
-}
-xhttp.get = function (url) { return xhttp({method:"get", url:url}) };
-xhttp.post = function (url, data) { return xhttp({method:"post", url:url, data:data, headers:{"Content-Type":"application/x-www-form-urlencoded"}}) };
-
-
/* function http (opts) //=> Deferred
* Sample:
* http.get("http://example.com/hogehoge")
@@ -91,8 +65,35 @@ http.jsonp = function (url, params) {
return d;
};
+/* function xhttp (opts) //=> Deferred
+ * Cross site version of `http`.
+ */
+/* function xhttp.get (url) //=> Deferred
+ */
+/* function xhttp.post (url, data) //=> Deferred
+ */
+function xhttp (opts) {
+ var d = Deferred();
+ if (opts.onload) d = d.next(opts.onload);
+ if (opts.onerror) d = d.error(opts.onerror);
+ opts.onload = function (res) {
+ d.call(res);
+ };
+ opts.onerror = function (res) {
+ d.fail(res);
+ };
+ setTimeout(function () {
+ GM_xmlhttpRequest(opts);
+ }, 0);
+ return d;
+}
+xhttp.get = function (url) { return xhttp({method:"get", url:url}) };
+xhttp.post = function (url, data) { return xhttp({method:"post", url:url, data:data, headers:{"Content-Type":"application/x-www-form-urlencoded"}}) };
+
+
+
Deferred.Deferred = Deferred;
Deferred.http = http;
-Deferred.xhttp = xhttp;
+Deferred.xhttp = (typeof(GM_xmlhttpRequest) == 'undefined') ? http : xhttp;
return Deferred;
}
View
6 jsdeferred.jquery.js
@@ -284,7 +284,7 @@ Deferred.connect = function () {
var d = new Deferred();
d.next = function (fun) { return this._post("ok", function () {
- fun.apply(this, (arguments[0] instanceof Deferred.Arguments) ? arguments[0].args : arguments);
+ return fun.apply(this, (arguments[0] instanceof Deferred.Arguments) ? arguments[0].args : arguments);
}) };
var args = partialArgs.concat(Array.prototype.slice.call(arguments, 0));
@@ -336,10 +336,12 @@ Deferred.define = function (obj, list) {
return Deferred;
};
+this.Deferred = Deferred;
+
(function ($) {
$.deferred = Deferred;
$.fn.extend({
- deferred: function(name) {
+ deferred: function (name) {
var args = Array.prototype.slice.call(arguments, 1);
return Deferred.connect(this[name], { target:this }).apply(null, args);
}
View
4 jsdeferred.js
@@ -536,7 +536,7 @@ Deferred.connect = function () {
var d = new Deferred();
d.next = function (fun) { return this._post("ok", function () {
- fun.apply(this, (arguments[0] instanceof Deferred.Arguments) ? arguments[0].args : arguments);
+ return fun.apply(this, (arguments[0] instanceof Deferred.Arguments) ? arguments[0].args : arguments);
}) };
var args = partialArgs.concat(Array.prototype.slice.call(arguments, 0));
@@ -603,3 +603,5 @@ Deferred.define = function (obj, list) {
return Deferred;
};
+this.Deferred = Deferred;
+
View
345 jsdeferred.node.js
@@ -0,0 +1,345 @@
+// JSDeferred 0.3.1 Copyright (c) 2007 cho45 ( www.lowreal.net )
+// See http://coderepos.org/share/wiki/JSDeferred
+function Deferred () { return (this instanceof Deferred) ? this.init() : new Deferred() }
+Deferred.ok = function (x) { return x };
+Deferred.ng = function (x) { throw x };
+Deferred.prototype = {
+ init : function () {
+ this._next = null;
+ this.callback = {
+ ok: Deferred.ok,
+ ng: Deferred.ng
+ };
+ return this;
+ },
+
+ next : function (fun) { return this._post("ok", fun) },
+ error : function (fun) { return this._post("ng", fun) },
+ call : function (val) { return this._fire("ok", val) },
+ fail : function (err) { return this._fire("ng", err) },
+
+ cancel : function () {
+ (this.canceller || function () {})();
+ return this.init();
+ },
+
+ _post : function (okng, fun) {
+ this._next = new Deferred();
+ this._next.callback[okng] = fun;
+ return this._next;
+ },
+
+ _fire : function (okng, value) {
+ var next = "ok";
+ try {
+ value = this.callback[okng].call(this, value);
+ } catch (e) {
+ next = "ng";
+ value = e;
+ if (Deferred.onerror) Deferred.onerror(e);
+ }
+ if (value instanceof Deferred) {
+ value._next = this._next;
+ } else {
+ if (this._next) this._next._fire(next, value);
+ }
+ return this;
+ }
+};
+
+Deferred.next_default = function (fun) {
+ var d = new Deferred();
+ var id = setTimeout(function () { d.call() }, 0);
+ d.canceller = function () { clearTimeout(id) };
+ if (fun) d.callback.ok = fun;
+ return d;
+};
+Deferred.next_faster_way_readystatechange = ((typeof window === 'object') && (location.protocol == "http:") && !window.opera && /\bMSIE\b/.test(navigator.userAgent)) && function (fun) {
+ var d = new Deferred();
+ var t = new Date().getTime();
+ if (t - arguments.callee._prev_timeout_called < 150) {
+ var cancel = false;
+ var script = document.createElement("script");
+ script.type = "text/javascript";
+ script.src = "javascript:";
+ script.onreadystatechange = function () {
+ if (!cancel) {
+ d.canceller();
+ d.call();
+ }
+ };
+ d.canceller = function () {
+ if (!cancel) {
+ cancel = true;
+ script.onreadystatechange = null;
+ document.body.removeChild(script);
+ }
+ };
+ document.body.appendChild(script);
+ } else {
+ arguments.callee._prev_timeout_called = t;
+ var id = setTimeout(function () { d.call() }, 0);
+ d.canceller = function () { clearTimeout(id) };
+ }
+ if (fun) d.callback.ok = fun;
+ return d;
+};
+Deferred.next_faster_way_Image = ((typeof window === 'object') && (typeof(Image) != "undefined") && document.addEventListener) && function (fun) {
+ var d = new Deferred();
+ var img = new Image();
+ var handler = function () {
+ d.canceller();
+ d.call();
+ };
+ img.addEventListener("load", handler, false);
+ img.addEventListener("error", handler, false);
+ d.canceller = function () {
+ img.removeEventListener("load", handler, false);
+ img.removeEventListener("error", handler, false);
+ };
+ img.src = "data:,/ _ / X";
+ if (fun) d.callback.ok = fun;
+ return d;
+};
+Deferred.next = Deferred.next_faster_way_readystatechange ||
+ Deferred.next_faster_way_Image ||
+ Deferred.next_default;
+
+Deferred.chain = function () {
+ var chain = next();
+ for (var i = 0, len = arguments.length; i < len; i++) (function (obj) {
+ switch (typeof obj) {
+ case "function":
+ var name = null;
+ try {
+ name = obj.toString().match(/^\s*function\s+([^\s()]+)/)[1];
+ } catch (e) { }
+ if (name != "error") {
+ chain = chain.next(obj);
+ } else {
+ chain = chain.error(obj);
+ }
+ break;
+ case "object":
+ chain = chain.next(function() { return parallel(obj) });
+ break;
+ default:
+ throw "unknown type in process chains";
+ }
+ })(arguments[i]);
+ return chain;
+}
+
+Deferred.wait = function (n) {
+ var d = new Deferred(), t = new Date();
+ var id = setTimeout(function () {
+ d.call((new Date).getTime() - t.getTime());
+ }, n * 1000);
+ d.canceller = function () { clearTimeout(id) };
+ return d;
+};
+
+Deferred.call = function (f ) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return Deferred.next(function () {
+ return f.apply(this, args);
+ });
+};
+
+Deferred.parallel = function (dl) {
+ if (arguments.length > 1) dl = Array.prototype.slice.call(arguments);
+ var ret = new Deferred(), values = {}, num = 0;
+ for (var i in dl) if (dl.hasOwnProperty(i)) (function (d, i) {
+ if (typeof d == "function") d = next(d);
+ d.next(function (v) {
+ values[i] = v;
+ if (--num <= 0) {
+ if (dl instanceof Array) {
+ values.length = dl.length;
+ values = Array.prototype.slice.call(values, 0);
+ }
+ ret.call(values);
+ }
+ }).error(function (e) {
+ ret.fail(e);
+ });
+ num++;
+ })(dl[i], i);
+
+ if (!num) Deferred.next(function () { ret.call() });
+ ret.canceller = function () {
+ for (var i in dl) if (dl.hasOwnProperty(i)) {
+ dl[i].cancel();
+ }
+ };
+ return ret;
+};
+
+Deferred.earlier = function (dl) {
+ if (arguments.length > 1) dl = Array.prototype.slice.call(arguments);
+ var ret = new Deferred(), values = {}, num = 0;
+ for (var i in dl) if (dl.hasOwnProperty(i)) (function (d, i) {
+ d.next(function (v) {
+ values[i] = v;
+ if (dl instanceof Array) {
+ values.length = dl.length;
+ values = Array.prototype.slice.call(values, 0);
+ }
+ ret.canceller();
+ ret.call(values);
+ }).error(function (e) {
+ ret.fail(e);
+ });
+ num++;
+ })(dl[i], i);
+
+ if (!num) Deferred.next(function () { ret.call() });
+ ret.canceller = function () {
+ for (var i in dl) if (dl.hasOwnProperty(i)) {
+ dl[i].cancel();
+ }
+ };
+ return ret;
+};
+
+
+Deferred.loop = function (n, fun) {
+ var o = {
+ begin : n.begin || 0,
+ end : (typeof n.end == "number") ? n.end : n - 1,
+ step : n.step || 1,
+ last : false,
+ prev : null
+ };
+ var ret, step = o.step;
+ return Deferred.next(function () {
+ function _loop (i) {
+ if (i <= o.end) {
+ if ((i + step) > o.end) {
+ o.last = true;
+ o.step = o.end - i + 1;
+ }
+ o.prev = ret;
+ ret = fun.call(this, i, o);
+ if (ret instanceof Deferred) {
+ return ret.next(function (r) {
+ ret = r;
+ return Deferred.call(_loop, i + step);
+ });
+ } else {
+ return Deferred.call(_loop, i + step);
+ }
+ } else {
+ return ret;
+ }
+ }
+ return (o.begin <= o.end) ? Deferred.call(_loop, o.begin) : null;
+ });
+};
+
+
+Deferred.repeat = function (n, f) {
+ var i = 0, end = {}, ret = null;
+ return Deferred.next(function () {
+ var t = (new Date()).getTime();
+ divide: {
+ do {
+ if (i >= n) break divide;
+ ret = f(i++);
+ } while ((new Date()).getTime() - t < 20);
+ return Deferred.call(arguments.callee);
+ }
+ });
+};
+
+Deferred.register = function (name, fun) {
+ this.prototype[name] = function () {
+ var a = arguments;
+ return this.next(function () {
+ return fun.apply(this, a);
+ });
+ };
+};
+
+Deferred.register("loop", Deferred.loop);
+Deferred.register("wait", Deferred.wait);
+Deferred.Arguments = function (args) { this.args = Array.prototype.slice.call(args, 0) }
+Deferred.connect = function () {
+ var target, func, obj;
+ if (typeof arguments[1] == "string") {
+ target = arguments[0];
+ func = target[arguments[1]];
+ obj = arguments[2] || {};
+ } else {
+ func = arguments[0];
+ obj = arguments[1] || {};
+ target = obj.target;
+ }
+
+ var partialArgs = obj.args ? Array.prototype.slice.call(obj.args, 0) : [];
+ var callbackArgIndex = isFinite(obj.ok) ? obj.ok : obj.args ? obj.args.length : undefined;
+ var errorbackArgIndex = obj.ng;
+
+ return function () {
+ var d = new Deferred();
+
+ d.next = function (fun) { return this._post("ok", function () {
+ fun.apply(this, (arguments[0] instanceof Deferred.Arguments) ? arguments[0].args : arguments);
+ }) };
+
+ var args = partialArgs.concat(Array.prototype.slice.call(arguments, 0));
+ if (!(isFinite(callbackArgIndex) && callbackArgIndex !== null)) {
+ callbackArgIndex = args.length;
+ }
+ var callback = function () { d.call(new Deferred.Arguments(arguments)) };
+ args.splice(callbackArgIndex, 0, callback);
+ if (isFinite(errorbackArgIndex) && errorbackArgIndex !== null) {
+ var errorback = function () { d.fail(arguments) };
+ args.splice(errorbackArgIndex, 0, errorback);
+ }
+ Deferred.next(function () { func.apply(target, args) });
+ return d;
+ }
+}
+
+Deferred.retry = function (retryCount, funcDeferred, options) {
+ if (!options) options = {};
+
+ var wait = options.wait || 0;
+ var d = new Deferred();
+ var retry = function () {
+ var m = funcDeferred(retryCount);
+ m.
+ next(function (mes) {
+ d.call(mes);
+ }).
+ error(function (e) {
+ if (--retryCount <= 0) {
+ d.fail(['retry failed', e]);
+ } else {
+ setTimeout(retry, wait * 1000);
+ }
+ });
+ };
+ setTimeout(retry, 0);
+ return d;
+}
+
+Deferred.methods = ["parallel", "wait", "next", "call", "loop", "repeat", "chain"];
+Deferred.define = function (obj, list) {
+ if (!list) list = Deferred.methods;
+ if (!obj) obj = (function getGlobal () { return this })();
+ for (var i = 0; i < list.length; i++) {
+ var n = list[i];
+ obj[n] = Deferred[n];
+ }
+ return Deferred;
+};
+
+
+(function () {
+ for (var key in Deferred) if (Deferred.hasOwnProperty(key)) {
+ var val = Deferred[key];
+ exports[key] = val;
+ }
+})();
View
6 jsdeferred.nodoc.js
@@ -284,7 +284,7 @@ Deferred.connect = function () {
var d = new Deferred();
d.next = function (fun) { return this._post("ok", function () {
- fun.apply(this, (arguments[0] instanceof Deferred.Arguments) ? arguments[0].args : arguments);
+ return fun.apply(this, (arguments[0] instanceof Deferred.Arguments) ? arguments[0].args : arguments);
}) };
var args = partialArgs.concat(Array.prototype.slice.call(arguments, 0));
@@ -334,4 +334,6 @@ Deferred.define = function (obj, list) {
obj[n] = Deferred[n];
}
return Deferred;
-};
+};
+
+this.Deferred = Deferred;
View
43 jsdeferred.userscript.js
@@ -288,7 +288,7 @@ Deferred.connect = function () {
var d = new Deferred();
d.next = function (fun) { return this._post("ok", function () {
- fun.apply(this, (arguments[0] instanceof Deferred.Arguments) ? arguments[0].args : arguments);
+ return fun.apply(this, (arguments[0] instanceof Deferred.Arguments) ? arguments[0].args : arguments);
}) };
var args = partialArgs.concat(Array.prototype.slice.call(arguments, 0));
@@ -340,26 +340,9 @@ Deferred.define = function (obj, list) {
return Deferred;
};
+this.Deferred = Deferred;
-function xhttp (opts) {
- var d = Deferred();
- if (opts.onload) d = d.next(opts.onload);
- if (opts.onerror) d = d.error(opts.onerror);
- opts.onload = function (res) {
- d.call(res);
- };
- opts.onerror = function (res) {
- d.fail(res);
- };
- setTimeout(function () {
- GM_xmlhttpRequest(opts);
- }, 0);
- return d;
-}
-xhttp.get = function (url) { return xhttp({method:"get", url:url}) };
-xhttp.post = function (url, data) { return xhttp({method:"post", url:url, data:data, headers:{"Content-Type":"application/x-www-form-urlencoded"}}) };
-
function http (opts) {
var d = Deferred();
@@ -411,8 +394,28 @@ http.jsonp = function (url, params) {
return d;
};
+function xhttp (opts) {
+ var d = Deferred();
+ if (opts.onload) d = d.next(opts.onload);
+ if (opts.onerror) d = d.error(opts.onerror);
+ opts.onload = function (res) {
+ d.call(res);
+ };
+ opts.onerror = function (res) {
+ d.fail(res);
+ };
+ setTimeout(function () {
+ GM_xmlhttpRequest(opts);
+ }, 0);
+ return d;
+}
+xhttp.get = function (url) { return xhttp({method:"get", url:url}) };
+xhttp.post = function (url, data) { return xhttp({method:"post", url:url, data:data, headers:{"Content-Type":"application/x-www-form-urlencoded"}}) };
+
+
+
Deferred.Deferred = Deferred;
Deferred.http = http;
-Deferred.xhttp = xhttp;
+Deferred.xhttp = (typeof(GM_xmlhttpRequest) == 'undefined') ? http : xhttp;
return Deferred;
}// End of JSDeferred
View
52 test-jsdeferred.js
@@ -149,6 +149,22 @@ next(function () {
return d;
}).
next(function () {
+ msg("Process sequence (Complex)");
+
+ var vs = [];
+ return next(function () {
+ expect("Process sequence (Complex)", "", vs.join(","));
+ vs.push("1");
+ return next(function() {
+ expect("Process sequence (Complex)", "1", vs.join(","));
+ vs.push("2");
+ });
+ }).
+ next(function () {
+ expect("Process sequence (Complex)", "1,2", vs.join(","));
+ });
+}).
+next(function () {
msg("Test Callback, Errorback chain::");
return next(function () { throw "Error"; }).
error(function (e) {
@@ -635,13 +651,33 @@ next(function () {
return fd().next(function(r) {
expect('connect f bind args 2', 5, r);
});
- });
-}).
-next(function () {
- return skip('setTimeout.apply is unavailable in IE', 1);
- var timeout = Deferred.connect(setTimeout, { target: window, ok: 0 });
- return timeout(0.1).next(function () {
- ok('connect setTimeout');
+ }).
+ next(function () {
+ var timeout = Deferred.connect(function (n, cb) {
+ setTimeout(cb, n);
+ });
+
+ return timeout(1).next(function () {
+ ok('connect setTimeout');
+ });
+ }).
+ next(function () {
+ var timeout = Deferred.connect(function (n, cb) {
+ setTimeout(cb, n);
+ });
+
+ var seq = [0];
+ return timeout(1).next(function () {
+ expect('sequence of connect', '0', seq.join(','));
+ seq.push(1);
+ return next(function () {
+ expect('sequence of connect', '0,1', seq.join(','));
+ seq.push(2);
+ });
+ }).
+ next(function () {
+ expect('sequence of connect', '0,1,2', seq.join(','));
+ });
});
}).
next(function () {
@@ -761,7 +797,7 @@ next(function () {
}).
next(function () {
msg("jQuery binding test")
- if (!/Rhino/.test(Global.navigator.userAgent)) {
+ if (Global.navigator && !/Rhino/.test(Global.navigator.userAgent)) {
return next(function() {
expect("$.ajax should return deferred", true, $.ajax({ url: "." }) instanceof $.deferred);
expect("$.get should return deferred", true, $.get(".") instanceof $.deferred);
View
96 test-node.js
@@ -0,0 +1,96 @@
+#!node
+
+var sys = require('sys');
+var fs = require('fs');
+var Deferred = require('./jsdeferred.js').Deferred;
+var Global = global;
+Deferred.define();
+
+var data;
+data = fs.readFileSync('./test-jsdeferred.js', 'ascii');
+data = data.match(/\/\/ ::Test::Start::([\s\S]+)::Test::End::/)[1];
+var testfuns = []; data.replace(/(ok|expect)\(.+/g, function (m) {
+ testfuns.push(m);
+ return m;
+});
+
+var expects = testfuns.length;
+
+function uneval (obj) {
+ return sys.inspect(obj);
+}
+
+function show (msg, expect, result) {
+ var okng = this;
+
+ var out = [];
+ out.push(color(46, "[", [expects - testfuns.length, expects].join("/"), "]"));
+ if (okng == "skip") {
+ out.push(" ", color(33, "skipped " + expect + "tests: " + msg));
+ console.log(out.join(""));
+ while (expect--) testfuns.pop();
+ } else
+ if (okng == "ng") {
+ testfuns.pop();
+ expect = (typeof expect == "function") ? uneval(expect).match(/[^{]+/)+"..." : uneval(expect);
+ result = (typeof result == "function") ? uneval(result).match(/[^{]+/)+"..." : uneval(result);
+ out.push(["NG Test::", msg, expect, result].join("\n"));
+ console.log(out.join(""));
+ process.exit(1);
+ } else {
+ testfuns.pop();
+ out.push(" ", color(32, "ok"));
+ console.log(out.join(""));
+ }
+}
+
+function msg (m) {
+ console.log(m);
+}
+log = msg;
+print = msg;
+
+function ok () {
+ show.apply("ok", arguments);
+ return true;
+}
+
+function ng () {
+ show.apply("ng", arguments);
+ return true;
+}
+
+function skip () {
+ show.apply("skip", arguments);
+ return true;
+}
+
+function expect (msg, expect, result) {
+ if (expect == result) {
+ show.apply("ok", arguments);
+ } else {
+ show.apply("ng", arguments);
+ }
+ return true;
+}
+
+function color (code) {
+ var str = "";
+ for (var i = 1; i < arguments.length; i++) str += arguments[i];
+ return [
+ String.fromCharCode(27), "[", code, "m",
+ str,
+ String.fromCharCode(27), "[0m"
+ ].join("");
+}
+
+// run tests
+eval(data);
+
+process.on('exit', function () {
+ if (expects - testfuns.length == expects) {
+ print(color(32, "All tests passed"));
+ } else {
+ print(color(31, "Some tests failed..."));
+ }
+});
Please sign in to comment.
Something went wrong with that request. Please try again.