Skip to content

Commit

Permalink
Merge branch 'test'
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Aug 16, 2011
2 parents 41f769e + e388606 commit ae4306e
Show file tree
Hide file tree
Showing 11 changed files with 462 additions and 11 deletions.
15 changes: 10 additions & 5 deletions d3.js
@@ -1,4 +1,4 @@
(function(){d3 = {version: "1.29.3"}; // semver
(function(){d3 = {version: "1.29.4"}; // semver
if (!Date.now) Date.now = function() {
return +new Date;
};
Expand Down Expand Up @@ -322,8 +322,13 @@ function d3_call(callback) {
* @param {number=} step
*/
d3.range = function(start, stop, step) {
if (arguments.length === 1) { stop = start; start = 0; }
if (step == null) step = 1;
if (arguments.length < 3) {
step = 1;
if (arguments.length < 2) {
stop = start;
start = 0;
}
}
if ((stop - start) / step == Infinity) throw new Error("infinite range");
var range = [],
i = -1,
Expand All @@ -336,7 +341,7 @@ d3.requote = function(s) {
return s.replace(d3_requote_re, "\\$&");
};

var d3_requote_re = /[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;
var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
d3.round = function(x, n) {
return n
? Math.round(x * Math.pow(10, n)) * Math.pow(10, -n)
Expand Down Expand Up @@ -628,7 +633,7 @@ function d3_ease_sin(t) {
}

function d3_ease_exp(t) {
return t ? Math.pow(2, 10 * (t - 1)) - 1e-3 : 0;
return Math.pow(2, 10 * (t - 1));
}

function d3_ease_circle(t) {
Expand Down
2 changes: 1 addition & 1 deletion d3.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/core/core.js
@@ -1 +1 @@
d3 = {version: "1.29.3"}; // semver
d3 = {version: "1.29.4"}; // semver
2 changes: 1 addition & 1 deletion src/core/ease.js
Expand Up @@ -90,7 +90,7 @@ function d3_ease_sin(t) {
}

function d3_ease_exp(t) {
return t ? Math.pow(2, 10 * (t - 1)) - 1e-3 : 0;
return Math.pow(2, 10 * (t - 1));
}

function d3_ease_circle(t) {
Expand Down
9 changes: 7 additions & 2 deletions src/core/range.js
Expand Up @@ -4,8 +4,13 @@
* @param {number=} step
*/
d3.range = function(start, stop, step) {
if (arguments.length === 1) { stop = start; start = 0; }
if (step == null) step = 1;
if (arguments.length < 3) {
step = 1;
if (arguments.length < 2) {
stop = start;
start = 0;
}
}
if ((stop - start) / step == Infinity) throw new Error("infinite range");
var range = [],
i = -1,
Expand Down
2 changes: 1 addition & 1 deletion src/core/requote.js
Expand Up @@ -2,4 +2,4 @@ d3.requote = function(s) {
return s.replace(d3_requote_re, "\\$&");
};

var d3_requote_re = /[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;
var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
116 changes: 116 additions & 0 deletions test/core/dispatch-test.js
@@ -0,0 +1,116 @@
require("../env");
require("../../d3");

var vows = require("vows"),
assert = require("assert");

var suite = vows.describe("d3.dispatch");

suite.addBatch({
"dispatch": {
topic: function() {
return d3.dispatch;
},
"returns a map of dispatchers for each event type": function(dispatch) {
assert.deepEqual(dispatch(), {});
var d = dispatch("foo");
assert.isTrue("foo" in d);
assert.isFalse("bar" in d);
var d = dispatch("foo", "bar");
assert.isTrue("foo" in d);
assert.isTrue("bar" in d);
},
"added listeners receive subsequent events": function(dispatch) {
var d = dispatch("foo"), events = 0;
d.foo.add(function() { ++events; });
d.foo.dispatch();
assert.equal(events, 1);
d.foo.dispatch();
d.foo.dispatch();
assert.equal(events, 3);
},
"the listener is passed any arguments to dispatch": function(dispatch) {
var d = dispatch("foo"), a = {}, b = {}, aa, bb;
d.foo.add(function(a, b) { aa = a; bb = b; });
d.foo.dispatch(a, b);
assert.equal(aa, a);
assert.equal(bb, b);
d.foo.dispatch(1, "foo");
assert.equal(aa, 1);
assert.equal(bb, "foo");
},
"the listener's context is the same as dispatch's": function(dispatch) {
var d = dispatch("foo"), a = {}, b = {}, that;
d.foo.add(function() { that = this; });
d.foo.dispatch.call(a);
assert.equal(that, a);
d.foo.dispatch.call(b);
assert.equal(that, b);
},
"listeners are notified in the order they are first added": function(dispatch) {
var d = dispatch("foo"), a = {}, b = {}, those = [];
function A() { those.push(a); }
function B() { those.push(b); }
d.foo.add(A);
d.foo.add(B);
d.foo.dispatch();
assert.deepEqual(those, [a, b]);
those = [];
d.foo.remove(A);
d.foo.add(A);
d.foo.dispatch();
assert.deepEqual(those, [a, b]);
},
"removed listeners do not receive subsequent events": function(dispatch) {
var d = dispatch("foo"), a = {}, b = {}, those = [];
function A() { those.push(a); }
function B() { those.push(b); }
d.foo.add(A);
d.foo.add(B);
d.foo.dispatch();
those = [];
d.foo.remove(A);
d.foo.dispatch();
assert.deepEqual(those, [b]);
},
"adding an existing listener has no effect": function(dispatch) {
var d = dispatch("foo"), events = 0;
function A() { ++events; }
d.foo.add(A);
d.foo.dispatch();
d.foo.add(A);
d.foo.add(A);
d.foo.dispatch();
assert.equal(events, 2);
},
"removing a missing listener has no effect": function(dispatch) {
var d = dispatch("foo"), events = 0;
function A() { ++events; }
d.foo.remove(A);
d.foo.add(A);
d.foo.remove(A);
d.foo.remove(A);
d.foo.dispatch();
assert.equal(events, 0);
},
"adding a listener does not affect the current event": function(dispatch) {
var d = dispatch("foo"), a = {}, b = {}, those = [];
function A() { d.foo.add(B); those.push(a); }
function B() { those.push(b); }
d.foo.add(A);
d.foo.dispatch();
assert.deepEqual(those, [a]);
},
"removing a listener does affect the current event": function(dispatch) {
var d = dispatch("foo"), a = {}, b = {}, those = [];
function A() { d.foo.remove(B); those.push(a); }
function B() { those.push(b); }
d.foo.add(A);
d.foo.add(B);
d.foo.dispatch();
assert.deepEqual(those, [a]);
}
}
});

suite.export(module);
129 changes: 129 additions & 0 deletions test/core/ease-test.js
@@ -0,0 +1,129 @@
require("../env");
require("../../d3");

var vows = require("vows"),
assert = require("assert");

var suite = vows.describe("d3.ease");

suite.addBatch({
"ease": {
topic: function() {
return d3.ease;
},
"supports linear easing": function(ease) {
var e = ease("linear");
assert.inDelta(e(.5), .5, 1e-6);
},
"supports polynomial easing": function(ease) {
var e = ease("poly", 2);
assert.inDelta(e(.5), .25, 1e-6);
},
"supports quadratic easing": function(ease) {
var e = ease("quad");
assert.inDelta(e(.5), .25, 1e-6);
},
"supports cubic easing": function(ease) {
var e = ease("cubic");
assert.inDelta(e(.5), .125, 1e-6);
},
"supports sinusoidal easing": function(ease) {
var e = ease("sin");
assert.inDelta(e(.5), 1 - Math.cos(Math.PI / 4), 1e-6);
},
"supports exponential easing": function(ease) {
var e = ease("exp");
assert.inDelta(e(.5), 0.03125, 1e-6);
},
"supports circular easing": function(ease) {
var e = ease("circle");
assert.inDelta(e(.5), 0.133975, 1e-6);
},
"supports elastic easing": function(ease) {
var e = ease("elastic");
assert.inDelta(e(.5), 0.976061, 1e-6);
},
"supports back easing": function(ease) {
var e = ease("back");
assert.inDelta(e(.5), -0.0876975, 1e-6);
},
"supports bounce easing": function(ease) {
var e = ease("bounce");
assert.inDelta(e(.5), 0.765625, 1e-6);
},
"all easing functions return approximately 0 for t = 0": function(ease) {
assert.inDelta(ease("linear")(0), 0, 1e-9);
assert.inDelta(ease("poly", 2)(0), 0, 1e-9);
assert.inDelta(ease("quad")(0), 0, 1e-9);
assert.inDelta(ease("cubic")(0), 0, 1e-9);
assert.inDelta(ease("sin")(0), 0, 1e-9);
assert.inDelta(ease("exp")(0), 0, 1e-3); // XXX
assert.inDelta(ease("circle")(0), 0, 1e-9);
assert.inDelta(ease("elastic")(0), 0, 1e-9);
assert.inDelta(ease("back")(0), 0, 1e-9);
assert.inDelta(ease("bounce")(0), 0, 1e-9);
},
"all easing functions return approximately 1 for t = 1": function(ease) {
assert.inDelta(ease("linear")(1), 1, 1e-9);
assert.inDelta(ease("poly", 2)(1), 1, 1e-9);
assert.inDelta(ease("quad")(1), 1, 1e-9);
assert.inDelta(ease("cubic")(1), 1, 1e-9);
assert.inDelta(ease("sin")(1), 1, 1e-9);
assert.inDelta(ease("exp")(1), 1, 1e-9);
assert.inDelta(ease("circle")(1), 1, 1e-9);
assert.inDelta(ease("elastic")(1), 1, 1e-3); // XXX
assert.inDelta(ease("back")(1), 1, 1e-9);
assert.inDelta(ease("bounce")(1), 1, 1e-9);
},
"the -in suffix returns the identity": function(ease) {
assert.equal(ease("linear-in"), ease("linear"));
assert.equal(ease("quad-in"), ease("quad"));
},
"the -out suffix returns the reverse": function(ease) {
assert.inDelta(ease("sin-out")(.25), 1 - ease("sin-in")(.75), 1e-6);
assert.inDelta(ease("bounce-out")(.25), 1 - ease("bounce-in")(.75), 1e-6);
assert.inDelta(ease("elastic-out")(.25), 1 - ease("elastic-in")(.75), 1e-6);
},
"the -in-out suffix returns the reflection": function(ease) {
assert.inDelta(ease("sin-in-out")(.25), .5 * ease("sin-in")(.5), 1e-6);
assert.inDelta(ease("bounce-in-out")(.25), .5 * ease("bounce-in")(.5), 1e-6);
assert.inDelta(ease("elastic-in-out")(.25), .5 * ease("elastic-in")(.5), 1e-6);
},
"the -out-in suffix returns the reverse reflection": function(ease) {
assert.inDelta(ease("sin-out-in")(.25), .5 * ease("sin-out")(.5), 1e-6);
assert.inDelta(ease("bounce-out-in")(.25), .5 * ease("bounce-out")(.5), 1e-6);
assert.inDelta(ease("elastic-out-in")(.25), .5 * ease("elastic-out")(.5), 1e-6);
},
"does not clamp input time": function(ease) {
var e = ease("linear");
assert.inDelta(e(-1), -1, 1e-6);
assert.inDelta(e(2), 2, 1e-6);
},
"poly": {
"supports an optional polynomial": function(ease) {
var e = ease("poly", 1);
assert.inDelta(e(.5), .5, 1e-6);
var e = ease("poly", .5);
assert.inDelta(e(.5), Math.SQRT1_2, 1e-6);
}
},
"elastic": {
"supports an optional amplifier (>1)": function(ease) {
var e = ease("elastic", 1.5);
assert.inDelta(e(.5), 0.998519, 1e-6);
},
"supports an optional amplifier (>1) and period (>0)": function(ease) {
var e = ease("elastic", 1.5, .5);
assert.inDelta(e(.5), 0.96875, 1e-6);
}
},
"back": {
"supports an optional speed": function(ease) {
var e = ease("back", 2);
assert.inDelta(e(.5), -0.125, 1e-6);
}
}
}
});

suite.export(module);
50 changes: 50 additions & 0 deletions test/core/quantile-test.js
@@ -0,0 +1,50 @@
require("../env");
require("../../d3");

var vows = require("vows"),
assert = require("assert");

var suite = vows.describe("d3.quantile");

suite.addBatch({
"quantile": {
topic: function() {
return d3.quantile;
},
"requires sorted numeric input": function(quantile) {
assert.equal(quantile([1, 2, 3, 4], 0), 1);
assert.equal(quantile([1, 2, 3, 4], 1), 4);
assert.equal(quantile([4, 3, 2, 1], 0), 4);
assert.equal(quantile([4, 3, 2, 1], 1), 1);
},
"uses the R-7 algorithm": function(quantile) {
var data = [3, 6, 7, 8, 8, 10, 13, 15, 16, 20];
assert.equal(quantile(data, 0), 3);
assert.equal(quantile(data, .25), 7.25);
assert.equal(quantile(data, .5), 9);
assert.equal(quantile(data, .75), 14.5);
assert.equal(quantile(data, 1), 20);
var data = [3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20];
assert.equal(quantile(data, 0), 3);
assert.equal(quantile(data, .25), 7.5);
assert.equal(quantile(data, .5), 9);
assert.equal(quantile(data, .75), 14);
assert.equal(quantile(data, 1), 20);
},
"returns an exact value for integer p-values": function(quantile) {
var a = {}, b = {}, c = {}, d = {}, data = [a, b, c, d];
assert.equal(quantile(data, 1/3), b);
assert.equal(quantile(data, 2/3), c);
},
"returns the first value for p = 0": function(quantile) {
var a = {}, b = {}, c = {}, d = {}, data = [a, b, c, d];
assert.equal(quantile(data, 0), a);
},
"returns the last value for p = 1": function(quantile) {
var a = {}, b = {}, c = {}, d = {}, data = [a, b, c, d];
assert.equal(quantile(data, 1), d);
}
}
});

suite.export(module);

0 comments on commit ae4306e

Please sign in to comment.