aboutsummaryrefslogtreecommitdiffstats
path: root/web/nms.gathering.org/speedometer/d3-master/test/arrays
diff options
context:
space:
mode:
authorKristian Lyngstol <kristian@bohemians.org>2015-04-02 19:24:45 +0200
committerKristian Lyngstol <kristian@bohemians.org>2015-04-02 19:24:45 +0200
commit0d8bba263dc195147d6fdb09662e7926f0a58b3e (patch)
tree4c570b4376c323e585120e7695b8715be7aa8881 /web/nms.gathering.org/speedometer/d3-master/test/arrays
parente4354b47bd8891c5b1ee591fdf74b3ca67eee461 (diff)
Bump lots of changes
Diffstat (limited to 'web/nms.gathering.org/speedometer/d3-master/test/arrays')
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/ascending-test.js45
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/bisect-test.js384
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/descending-test.js45
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/deviation-test.js43
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/entries-test.js39
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/extent-test.js50
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/keys-test.js27
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/map-test.js306
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/max-test.js51
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/mean-test.js47
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/median-test.js53
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/merge-test.js50
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/min-test.js51
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/nest-test.js256
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/one-time-number.js11
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/pairs-test.js27
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/permute-test.js49
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/quantile-test.js56
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/range-test.js99
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/set-test.js209
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/shuffle-test.js43
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/sum-test.js43
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/transpose-test.js28
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/values-test.js31
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/variance-test.js43
-rw-r--r--web/nms.gathering.org/speedometer/d3-master/test/arrays/zip-test.js28
26 files changed, 2114 insertions, 0 deletions
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/ascending-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/ascending-test.js
new file mode 100644
index 0000000..b7d9a7c
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/ascending-test.js
@@ -0,0 +1,45 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.ascending");
+
+suite.addBatch({
+ "d3.ascending": {
+ topic: load("arrays/ascending").expression("d3.ascending"),
+ "numbers": {
+ "returns a negative number if a < b": function(ascending) {
+ assert.isTrue(ascending(0, 1) < 0);
+ },
+ "returns a positive number if a > b": function(ascending) {
+ assert.isTrue(ascending(1, 0) > 0);
+ },
+ "returns zero if a == b": function(ascending) {
+ assert.equal(ascending(0, 0), 0);
+ },
+ "returns NaN if a or b is undefined": function(ascending) {
+ assert.isNaN(ascending(0, undefined));
+ assert.isNaN(ascending(undefined, 0));
+ assert.isNaN(ascending(undefined, undefined));
+ },
+ "returns NaN if a or b is NaN": function(ascending) {
+ assert.isNaN(ascending(0, NaN));
+ assert.isNaN(ascending(NaN, 0));
+ assert.isNaN(ascending(NaN, NaN));
+ }
+ },
+ "strings": {
+ "returns a negative number if a < b": function(ascending) {
+ assert.isTrue(ascending("a", "b") < 0);
+ },
+ "returns a positive number if a > b": function(ascending) {
+ assert.isTrue(ascending("b", "a") > 0);
+ },
+ "returns zero if a == b": function(ascending) {
+ assert.equal(ascending("a", "a"), 0);
+ }
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/bisect-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/bisect-test.js
new file mode 100644
index 0000000..b3c5f61
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/bisect-test.js
@@ -0,0 +1,384 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert"),
+ _ = require("../../");
+
+var suite = vows.describe("d3.bisect");
+
+var i30 = 1 << 30;
+
+suite.addBatch({
+ "bisectLeft": {
+ topic: load("arrays/bisect").expression("d3.bisectLeft"),
+ "finds the index of an exact match": function(bisect) {
+ var array = [1, 2, 3];
+ assert.equal(bisect(array, 1), 0);
+ assert.equal(bisect(array, 2), 1);
+ assert.equal(bisect(array, 3), 2);
+ },
+ "finds the index of the first match": function(bisect) {
+ var array = [1, 2, 2, 3];
+ assert.equal(bisect(array, 1), 0);
+ assert.equal(bisect(array, 2), 1);
+ assert.equal(bisect(array, 3), 3);
+ },
+ "finds the insertion point of a non-exact match": function(bisect) {
+ var array = [1, 2, 3];
+ assert.equal(bisect(array, 0.5), 0);
+ assert.equal(bisect(array, 1.5), 1);
+ assert.equal(bisect(array, 2.5), 2);
+ assert.equal(bisect(array, 3.5), 3);
+ },
+ "has undefined behavior if the search value is unorderable": function(bisect) {
+ var array = [1, 2, 3];
+ bisect(array, new Date(NaN)); // who knows what this will return!
+ bisect(array, undefined);
+ bisect(array, NaN);
+ },
+ "observes the optional lower bound": function(bisect) {
+ var array = [1, 2, 3, 4, 5];
+ assert.equal(bisect(array, 0, 2), 2);
+ assert.equal(bisect(array, 1, 2), 2);
+ assert.equal(bisect(array, 2, 2), 2);
+ assert.equal(bisect(array, 3, 2), 2);
+ assert.equal(bisect(array, 4, 2), 3);
+ assert.equal(bisect(array, 5, 2), 4);
+ assert.equal(bisect(array, 6, 2), 5);
+ },
+ "observes the optional bounds": function(bisect) {
+ var array = [1, 2, 3, 4, 5];
+ assert.equal(bisect(array, 0, 2, 3), 2);
+ assert.equal(bisect(array, 1, 2, 3), 2);
+ assert.equal(bisect(array, 2, 2, 3), 2);
+ assert.equal(bisect(array, 3, 2, 3), 2);
+ assert.equal(bisect(array, 4, 2, 3), 3);
+ assert.equal(bisect(array, 5, 2, 3), 3);
+ assert.equal(bisect(array, 6, 2, 3), 3);
+ },
+ "large arrays": function(bisect) {
+ var array = [],
+ i = i30;
+ array[i++] = 1;
+ array[i++] = 2;
+ array[i++] = 3;
+ array[i++] = 4;
+ array[i++] = 5;
+ assert.equal(bisect(array, 0, i - 5, i), i - 5);
+ assert.equal(bisect(array, 1, i - 5, i), i - 5);
+ assert.equal(bisect(array, 2, i - 5, i), i - 4);
+ assert.equal(bisect(array, 3, i - 5, i), i - 3);
+ assert.equal(bisect(array, 4, i - 5, i), i - 2);
+ assert.equal(bisect(array, 5, i - 5, i), i - 1);
+ assert.equal(bisect(array, 6, i - 5, i), i - 0);
+ }
+ },
+
+ "bisectRight": {
+ topic: load("arrays/bisect").expression("d3.bisectRight"),
+ "finds the index after an exact match": function(bisect) {
+ var array = [1, 2, 3];
+ assert.equal(bisect(array, 1), 1);
+ assert.equal(bisect(array, 2), 2);
+ assert.equal(bisect(array, 3), 3);
+ },
+ "finds the index after the last match": function(bisect) {
+ var array = [1, 2, 2, 3];
+ assert.equal(bisect(array, 1), 1);
+ assert.equal(bisect(array, 2), 3);
+ assert.equal(bisect(array, 3), 4);
+ },
+ "finds the insertion point of a non-exact match": function(bisect) {
+ var array = [1, 2, 3];
+ assert.equal(bisect(array, 0.5), 0);
+ assert.equal(bisect(array, 1.5), 1);
+ assert.equal(bisect(array, 2.5), 2);
+ assert.equal(bisect(array, 3.5), 3);
+ },
+ "observes the optional lower bound": function(bisect) {
+ var array = [1, 2, 3, 4, 5];
+ assert.equal(bisect(array, 0, 2), 2);
+ assert.equal(bisect(array, 1, 2), 2);
+ assert.equal(bisect(array, 2, 2), 2);
+ assert.equal(bisect(array, 3, 2), 3);
+ assert.equal(bisect(array, 4, 2), 4);
+ assert.equal(bisect(array, 5, 2), 5);
+ assert.equal(bisect(array, 6, 2), 5);
+ },
+ "observes the optional bounds": function(bisect) {
+ var array = [1, 2, 3, 4, 5];
+ assert.equal(bisect(array, 0, 2, 3), 2);
+ assert.equal(bisect(array, 1, 2, 3), 2);
+ assert.equal(bisect(array, 2, 2, 3), 2);
+ assert.equal(bisect(array, 3, 2, 3), 3);
+ assert.equal(bisect(array, 4, 2, 3), 3);
+ assert.equal(bisect(array, 5, 2, 3), 3);
+ assert.equal(bisect(array, 6, 2, 3), 3);
+ },
+ "large arrays": function(bisect) {
+ var array = [],
+ i = i30;
+ array[i++] = 1;
+ array[i++] = 2;
+ array[i++] = 3;
+ array[i++] = 4;
+ array[i++] = 5;
+ assert.equal(bisect(array, 0, i - 5, i), i - 5);
+ assert.equal(bisect(array, 1, i - 5, i), i - 4);
+ assert.equal(bisect(array, 2, i - 5, i), i - 3);
+ assert.equal(bisect(array, 3, i - 5, i), i - 2);
+ assert.equal(bisect(array, 4, i - 5, i), i - 1);
+ assert.equal(bisect(array, 5, i - 5, i), i - 0);
+ assert.equal(bisect(array, 6, i - 5, i), i - 0);
+ }
+ },
+
+ "bisector(comparator)": {
+ topic: load("arrays/bisect").expression("d3.bisector"),
+ "left": {
+ topic: function(bisector) {
+ return bisector(function(d, x) { return _.descending(d.key, x); }).left;
+ },
+ "finds the index of an exact match": function(bisect) {
+ var array = [{key: 3}, {key: 2}, {key: 1}];
+ assert.equal(bisect(array, 3), 0);
+ assert.equal(bisect(array, 2), 1);
+ assert.equal(bisect(array, 1), 2);
+ },
+ "finds the index of the first match": function(bisect) {
+ var array = [{key: 3}, {key: 2}, {key: 2}, {key: 1}];
+ assert.equal(bisect(array, 3), 0);
+ assert.equal(bisect(array, 2), 1);
+ assert.equal(bisect(array, 1), 3);
+ },
+ "finds the insertion point of a non-exact match": function(bisect) {
+ var array = [{key: 3}, {key: 2}, {key: 1}];
+ assert.equal(bisect(array, 3.5), 0);
+ assert.equal(bisect(array, 2.5), 1);
+ assert.equal(bisect(array, 1.5), 2);
+ assert.equal(bisect(array, 0.5), 3);
+ },
+ "observes the optional lower bound": function(bisect) {
+ var array = [{key: 5}, {key: 4}, {key: 3}, {key: 2}, {key: 1}];
+ assert.equal(bisect(array, 6, 2), 2);
+ assert.equal(bisect(array, 5, 2), 2);
+ assert.equal(bisect(array, 4, 2), 2);
+ assert.equal(bisect(array, 3, 2), 2);
+ assert.equal(bisect(array, 2, 2), 3);
+ assert.equal(bisect(array, 1, 2), 4);
+ assert.equal(bisect(array, 0, 2), 5);
+ },
+ "observes the optional bounds": function(bisect) {
+ var array = [{key: 5}, {key: 4}, {key: 3}, {key: 2}, {key: 1}];
+ assert.equal(bisect(array, 6, 2, 3), 2);
+ assert.equal(bisect(array, 5, 2, 3), 2);
+ assert.equal(bisect(array, 4, 2, 3), 2);
+ assert.equal(bisect(array, 3, 2, 3), 2);
+ assert.equal(bisect(array, 2, 2, 3), 3);
+ assert.equal(bisect(array, 1, 2, 3), 3);
+ assert.equal(bisect(array, 0, 2, 3), 3);
+ },
+ "large arrays": function(bisect) {
+ var array = [],
+ i = i30;
+ array[i++] = {key: 5};
+ array[i++] = {key: 4};
+ array[i++] = {key: 3};
+ array[i++] = {key: 2};
+ array[i++] = {key: 1};
+ assert.equal(bisect(array, 6, i - 5, i), i - 5);
+ assert.equal(bisect(array, 5, i - 5, i), i - 5);
+ assert.equal(bisect(array, 4, i - 5, i), i - 4);
+ assert.equal(bisect(array, 3, i - 5, i), i - 3);
+ assert.equal(bisect(array, 2, i - 5, i), i - 2);
+ assert.equal(bisect(array, 1, i - 5, i), i - 1);
+ assert.equal(bisect(array, 0, i - 5, i), i - 0);
+ }
+ },
+ "right": {
+ topic: function(bisector) {
+ return bisector(function(d, x) { return _.ascending(d.key, x); }).right;
+ },
+ "finds the index after an exact match": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}];
+ assert.equal(bisect(array, 1), 1);
+ assert.equal(bisect(array, 2), 2);
+ assert.equal(bisect(array, 3), 3);
+ },
+ "finds the index after the last match": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 2}, {key: 3}];
+ assert.equal(bisect(array, 1), 1);
+ assert.equal(bisect(array, 2), 3);
+ assert.equal(bisect(array, 3), 4);
+ },
+ "finds the insertion point of a non-exact match": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}];
+ assert.equal(bisect(array, 0.5), 0);
+ assert.equal(bisect(array, 1.5), 1);
+ assert.equal(bisect(array, 2.5), 2);
+ assert.equal(bisect(array, 3.5), 3);
+ },
+ "observes the optional lower bound": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}];
+ assert.equal(bisect(array, 0, 2), 2);
+ assert.equal(bisect(array, 1, 2), 2);
+ assert.equal(bisect(array, 2, 2), 2);
+ assert.equal(bisect(array, 3, 2), 3);
+ assert.equal(bisect(array, 4, 2), 4);
+ assert.equal(bisect(array, 5, 2), 5);
+ assert.equal(bisect(array, 6, 2), 5);
+ },
+ "observes the optional bounds": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}];
+ assert.equal(bisect(array, 0, 2, 3), 2);
+ assert.equal(bisect(array, 1, 2, 3), 2);
+ assert.equal(bisect(array, 2, 2, 3), 2);
+ assert.equal(bisect(array, 3, 2, 3), 3);
+ assert.equal(bisect(array, 4, 2, 3), 3);
+ assert.equal(bisect(array, 5, 2, 3), 3);
+ assert.equal(bisect(array, 6, 2, 3), 3);
+ },
+ "large arrays": function(bisect) {
+ var array = [],
+ i = i30;
+ array[i++] = {key: 1};
+ array[i++] = {key: 2};
+ array[i++] = {key: 3};
+ array[i++] = {key: 4};
+ array[i++] = {key: 5};
+ assert.equal(bisect(array, 0, i - 5, i), i - 5);
+ assert.equal(bisect(array, 1, i - 5, i), i - 4);
+ assert.equal(bisect(array, 2, i - 5, i), i - 3);
+ assert.equal(bisect(array, 3, i - 5, i), i - 2);
+ assert.equal(bisect(array, 4, i - 5, i), i - 1);
+ assert.equal(bisect(array, 5, i - 5, i), i - 0);
+ assert.equal(bisect(array, 6, i - 5, i), i - 0);
+ }
+ }
+ },
+
+ "bisector(accessor)": {
+ topic: load("arrays/bisect").expression("d3.bisector"),
+ "left": {
+ topic: function(bisector) {
+ return bisector(function(d) { return d.key; }).left;
+ },
+ "finds the index of an exact match": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}];
+ assert.equal(bisect(array, 1), 0);
+ assert.equal(bisect(array, 2), 1);
+ assert.equal(bisect(array, 3), 2);
+ },
+ "finds the index of the first match": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 2}, {key: 3}];
+ assert.equal(bisect(array, 1), 0);
+ assert.equal(bisect(array, 2), 1);
+ assert.equal(bisect(array, 3), 3);
+ },
+ "finds the insertion point of a non-exact match": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}];
+ assert.equal(bisect(array, 0.5), 0);
+ assert.equal(bisect(array, 1.5), 1);
+ assert.equal(bisect(array, 2.5), 2);
+ assert.equal(bisect(array, 3.5), 3);
+ },
+ "observes the optional lower bound": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}];
+ assert.equal(bisect(array, 0, 2), 2);
+ assert.equal(bisect(array, 1, 2), 2);
+ assert.equal(bisect(array, 2, 2), 2);
+ assert.equal(bisect(array, 3, 2), 2);
+ assert.equal(bisect(array, 4, 2), 3);
+ assert.equal(bisect(array, 5, 2), 4);
+ assert.equal(bisect(array, 6, 2), 5);
+ },
+ "observes the optional bounds": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}];
+ assert.equal(bisect(array, 0, 2, 3), 2);
+ assert.equal(bisect(array, 1, 2, 3), 2);
+ assert.equal(bisect(array, 2, 2, 3), 2);
+ assert.equal(bisect(array, 3, 2, 3), 2);
+ assert.equal(bisect(array, 4, 2, 3), 3);
+ assert.equal(bisect(array, 5, 2, 3), 3);
+ assert.equal(bisect(array, 6, 2, 3), 3);
+ },
+ "large arrays": function(bisect) {
+ var array = [],
+ i = i30;
+ array[i++] = {key: 1};
+ array[i++] = {key: 2};
+ array[i++] = {key: 3};
+ array[i++] = {key: 4};
+ array[i++] = {key: 5};
+ assert.equal(bisect(array, 0, i - 5, i), i - 5);
+ assert.equal(bisect(array, 1, i - 5, i), i - 5);
+ assert.equal(bisect(array, 2, i - 5, i), i - 4);
+ assert.equal(bisect(array, 3, i - 5, i), i - 3);
+ assert.equal(bisect(array, 4, i - 5, i), i - 2);
+ assert.equal(bisect(array, 5, i - 5, i), i - 1);
+ assert.equal(bisect(array, 6, i - 5, i), i - 0);
+ }
+ },
+ "right": {
+ topic: function(bisector) {
+ return bisector(function(d) { return d.key; }).right;
+ },
+ "finds the index after an exact match": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}];
+ assert.equal(bisect(array, 1), 1);
+ assert.equal(bisect(array, 2), 2);
+ assert.equal(bisect(array, 3), 3);
+ },
+ "finds the index after the last match": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 2}, {key: 3}];
+ assert.equal(bisect(array, 1), 1);
+ assert.equal(bisect(array, 2), 3);
+ assert.equal(bisect(array, 3), 4);
+ },
+ "finds the insertion point of a non-exact match": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}];
+ assert.equal(bisect(array, 0.5), 0);
+ assert.equal(bisect(array, 1.5), 1);
+ assert.equal(bisect(array, 2.5), 2);
+ assert.equal(bisect(array, 3.5), 3);
+ },
+ "observes the optional lower bound": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}];
+ assert.equal(bisect(array, 0, 2), 2);
+ assert.equal(bisect(array, 1, 2), 2);
+ assert.equal(bisect(array, 2, 2), 2);
+ assert.equal(bisect(array, 3, 2), 3);
+ assert.equal(bisect(array, 4, 2), 4);
+ assert.equal(bisect(array, 5, 2), 5);
+ assert.equal(bisect(array, 6, 2), 5);
+ },
+ "observes the optional bounds": function(bisect) {
+ var array = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}];
+ assert.equal(bisect(array, 0, 2, 3), 2);
+ assert.equal(bisect(array, 1, 2, 3), 2);
+ assert.equal(bisect(array, 2, 2, 3), 2);
+ assert.equal(bisect(array, 3, 2, 3), 3);
+ assert.equal(bisect(array, 4, 2, 3), 3);
+ assert.equal(bisect(array, 5, 2, 3), 3);
+ assert.equal(bisect(array, 6, 2, 3), 3);
+ },
+ "large arrays": function(bisect) {
+ var array = [],
+ i = i30;
+ array[i++] = {key: 1};
+ array[i++] = {key: 2};
+ array[i++] = {key: 3};
+ array[i++] = {key: 4};
+ array[i++] = {key: 5};
+ assert.equal(bisect(array, 0, i - 5, i), i - 5);
+ assert.equal(bisect(array, 1, i - 5, i), i - 4);
+ assert.equal(bisect(array, 2, i - 5, i), i - 3);
+ assert.equal(bisect(array, 3, i - 5, i), i - 2);
+ assert.equal(bisect(array, 4, i - 5, i), i - 1);
+ assert.equal(bisect(array, 5, i - 5, i), i - 0);
+ assert.equal(bisect(array, 6, i - 5, i), i - 0);
+ }
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/descending-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/descending-test.js
new file mode 100644
index 0000000..2c28c75
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/descending-test.js
@@ -0,0 +1,45 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.descending");
+
+suite.addBatch({
+ "descending": {
+ topic: load("arrays/descending").expression("d3.descending"),
+ "numbers": {
+ "returns a negative number if a > b": function(descending) {
+ assert.isTrue(descending(1, 0) < 0);
+ },
+ "returns a positive number if a < b": function(descending) {
+ assert.isTrue(descending(0, 1) > 0);
+ },
+ "returns zero if a == b": function(descending) {
+ assert.equal(descending(0, 0), 0);
+ },
+ "returns NaN if a or b is undefined": function(descending) {
+ assert.isNaN(descending(0, undefined));
+ assert.isNaN(descending(undefined, 0));
+ assert.isNaN(descending(undefined, undefined));
+ },
+ "returns NaN if a or b is NaN": function(descending) {
+ assert.isNaN(descending(0, NaN));
+ assert.isNaN(descending(NaN, 0));
+ assert.isNaN(descending(NaN, NaN));
+ }
+ },
+ "strings": {
+ "returns a negative number if a > b": function(descending) {
+ assert.isTrue(descending("b", "a") < 0);
+ },
+ "returns a positive number if a < b": function(descending) {
+ assert.isTrue(descending("a", "b") > 0);
+ },
+ "returns zero if a == b": function(descending) {
+ assert.equal(descending("a", "a"), 0);
+ }
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/deviation-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/deviation-test.js
new file mode 100644
index 0000000..6566362
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/deviation-test.js
@@ -0,0 +1,43 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.deviation");
+
+suite.addBatch({
+ "deviation": {
+ topic: load("arrays/deviation").expression("d3.deviation"),
+ "returns the sd value for numbers": function(deviation) {
+ assert.isUndefined(deviation([1]));
+ assert.equal(deviation([5, 1, 2, 3, 4]), 1.5811388300841898);
+ assert.equal(deviation([20, 3]), 12.020815280171307);
+ assert.equal(deviation([3, 20]), 12.020815280171307);
+ },
+ "ignores null, undefined and NaN": function(deviation) {
+ assert.equal(deviation([NaN, 1, 2, 3, 4, 5]), 1.5811388300841898);
+ assert.equal(deviation([1, 2, 3, 4, 5, NaN]), 1.5811388300841898);
+ assert.equal(deviation([10, null, 3, undefined, 5, NaN]), 3.605551275463989);
+ },
+ "can handle large numbers without overflowing": function(deviation) {
+ assert.equal(deviation([Number.MAX_VALUE, Number.MAX_VALUE]), 0);
+ assert.equal(deviation([-Number.MAX_VALUE, -Number.MAX_VALUE]), 0);
+ },
+ "returns undefined for empty array": function(deviation) {
+ assert.isUndefined(deviation([]));
+ assert.isUndefined(deviation([null]));
+ assert.isUndefined(deviation([undefined]));
+ assert.isUndefined(deviation([NaN]));
+ assert.isUndefined(deviation([NaN, NaN]));
+ },
+ "applies the optional accessor function": function(deviation) {
+ assert.equal(deviation([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], mean), 2.1213203435596424);
+ assert.equal(deviation([1, 2, 3, 4, 5], function(d, i) { return i; }), 1.5811388300841898);
+ }
+ }
+});
+
+function mean(array) {
+ return array.reduce(function(p, v) { return p + v; }) / array.length;
+}
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/entries-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/entries-test.js
new file mode 100644
index 0000000..32f53f9
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/entries-test.js
@@ -0,0 +1,39 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.entries");
+
+suite.addBatch({
+ "entries": {
+ topic: load("arrays/entries").expression("d3.entries"),
+ "enumerates every entry": function(entries) {
+ assert.deepEqual(entries({a: 1, b: 2}), [
+ {key: "a", value: 1},
+ {key: "b", value: 2}
+ ]);
+ },
+ "includes entries defined on prototypes": function(entries) {
+ function abc() {
+ this.a = 1;
+ this.b = 2;
+ }
+ abc.prototype.c = 3;
+ assert.deepEqual(entries(new abc()), [
+ {key: "a", value: 1},
+ {key: "b", value: 2},
+ {key: "c", value: 3}
+ ]);
+ },
+ "includes null or undefined values": function(entries) {
+ var v = entries({a: undefined, b: null, c: NaN});
+ assert.equal(v.length, 3);
+ assert.deepEqual(v[0], {key: "a", value: undefined});
+ assert.deepEqual(v[1], {key: "b", value: null});
+ assert.equal(v[2].key, "c");
+ assert.isNaN(v[2].value);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/extent-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/extent-test.js
new file mode 100644
index 0000000..bfdfa5f
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/extent-test.js
@@ -0,0 +1,50 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.extent");
+
+suite.addBatch({
+ "extent": {
+ topic: load("arrays/extent").expression("d3.extent"),
+ "returns the numeric extent for numbers": function(extent) {
+ assert.deepEqual(extent([1]), [1, 1]);
+ assert.deepEqual(extent([5, 1, 2, 3, 4]), [1, 5]);
+ assert.deepEqual(extent([20, 3]), [3, 20]);
+ assert.deepEqual(extent([3, 20]), [3, 20]);
+ },
+ "returns the lexicographic extent for strings": function(extent) {
+ assert.deepEqual(extent(["c", "a", "b"]), ["a", "c"]);
+ assert.deepEqual(extent(["20", "3"]), ["20", "3"]);
+ assert.deepEqual(extent(["3", "20"]), ["20", "3"]);
+ },
+ "ignores null, undefined and NaN": function(extent) {
+ var o = {valueOf: function() { return NaN; }};
+ assert.deepEqual(extent([NaN, 1, 2, 3, 4, 5]), [1, 5]);
+ assert.deepEqual(extent([o, 1, 2, 3, 4, 5]), [1, 5]);
+ assert.deepEqual(extent([1, 2, 3, 4, 5, NaN]), [1, 5]);
+ assert.deepEqual(extent([1, 2, 3, 4, 5, o]), [1, 5]);
+ assert.deepEqual(extent([10, null, 3, undefined, 5, NaN]), [3, 10]);
+ assert.deepEqual(extent([-1, null, -3, undefined, -5, NaN]), [-5, -1]);
+ },
+ "compares heterogenous types as numbers": function(extent) {
+ assert.deepEqual(extent([20, "3"]), ["3", 20]);
+ assert.deepEqual(extent(["20", 3]), [3, "20"]);
+ assert.deepEqual(extent([3, "20"]), [3, "20"]);
+ assert.deepEqual(extent(["3", 20]), ["3", 20]);
+ },
+ "returns undefined for empty array": function(extent) {
+ assert.deepEqual(extent([]), [undefined, undefined]);
+ assert.deepEqual(extent([null]), [undefined, undefined]);
+ assert.deepEqual(extent([undefined]), [undefined, undefined]);
+ assert.deepEqual(extent([NaN]), [undefined, undefined]);
+ assert.deepEqual(extent([NaN, NaN]), [undefined, undefined]);
+ },
+ "applies the optional accessor function exactly once": function(extent) {
+ var i = 10;
+ assert.deepEqual(extent([0,1,2,3], function() { return ++i; }), [11, 14]);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/keys-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/keys-test.js
new file mode 100644
index 0000000..c11bda6
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/keys-test.js
@@ -0,0 +1,27 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.keys");
+
+suite.addBatch({
+ "keys": {
+ topic: load("arrays/keys").expression("d3.keys"),
+ "enumerates every defined key": function(keys) {
+ assert.deepEqual(keys({a: 1, b: 1}), ["a", "b"]);
+ },
+ "includes keys defined on prototypes": function(keys) {
+ function abc() {
+ this.a = 1;
+ this.b = 2;
+ }
+ abc.prototype.c = 3;
+ assert.deepEqual(keys(new abc()), ["a", "b", "c"]);
+ },
+ "includes keys with null or undefined values": function(keys) {
+ assert.deepEqual(keys({a: undefined, b: null, c: NaN}), ["a", "b", "c"]);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/map-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/map-test.js
new file mode 100644
index 0000000..89290f1
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/map-test.js
@@ -0,0 +1,306 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.map");
+
+suite.addBatch({
+ "map": {
+ topic: load("arrays/map").expression("d3.map"),
+ "constructor": {
+ "map() returns an empty map": function(map) {
+ var m = map();
+ assert.deepEqual(m.keys(), []);
+ },
+ "map(null) returns an empty map": function(map) {
+ var m = map(null);
+ assert.deepEqual(m.keys(), []);
+ },
+ "map(object) copies enumerable keys": function(map) {
+ var m = map({foo: 42});
+ assert.isTrue(m.has("foo"));
+ assert.equal(m.get("foo"), 42);
+ var m = map(Object.create(null, {foo: {value: 42, enumerable: true}}));
+ assert.isTrue(m.has("foo"));
+ assert.equal(m.get("foo"), 42);
+ },
+ "map(object) copies inherited keys": function(map) {
+ function Foo() {}
+ Foo.prototype.foo = 42;
+ var m = map(Object.create({foo: 42}));
+ assert.isTrue(m.has("foo"));
+ assert.equal(m.get("foo"), 42);
+ var m = map(new Foo());
+ assert.isTrue(m.has("foo"));
+ assert.equal(m.get("foo"), 42);
+ },
+ "map(object) does not copy non-enumerable keys": function(map) {
+ var m = map({__proto__: 42}); // because __proto__ isn't enumerable
+ assert.isFalse(m.has("__proto__"));
+ assert.isUndefined(m.get("__proto__"));
+ var m = map(Object.create(null, {foo: {value: 42, enumerable: false}}));
+ assert.isFalse(m.has("foo"));
+ assert.isUndefined(m.get("foo"));
+ },
+ "map(map) copies the given map": function(map) {
+ var a = map({foo: 42}),
+ b = map(a);
+ assert.isTrue(b.has("foo"));
+ assert.equal(b.get("foo"), 42);
+ a.set("bar", true);
+ assert.isFalse(b.has("bar"));
+ },
+ "map(array) creates a map by index": function(map) {
+ assert.deepEqual(map(["foo", "bar"]).entries(), [{key: "0", value: "foo"}, {key: "1", value: "bar"}]);
+ },
+ "map(array) indexes missing elements in sparse arrays": function(map) {
+ assert.deepEqual(map(["foo", , "bar"]).entries(), [{key: "0", value: "foo"}, {key: "1", value: undefined}, {key: "2", value: "bar"}]);
+ },
+ "map(array, f) creates a map by accessor": function(map) {
+ assert.deepEqual(map([{field: "foo"}, {field: "bar"}], function(d) { return d.field; }).entries(), [{key: "foo", value: {field: "foo"}}, {key: "bar", value: {field: "bar"}}]);
+ assert.deepEqual(map([{field: "foo"}, {field: "bar"}], function(d, i) { return i; }).entries(), [{key: "0", value: {field: "foo"}}, {key: "1", value: {field: "bar"}}]);
+ assert.deepEqual(map([{field: "foo"}, {field: "bar"}], function(d, i) { return this[i].field; }).entries(), [{key: "foo", value: {field: "foo"}}, {key: "bar", value: {field: "bar"}}]);
+ }
+ },
+ "size": {
+ "returns the number of distinct keys": function(map) {
+ var m = map();
+ assert.deepEqual(m.size(), 0);
+ m.set("foo", 1);
+ assert.deepEqual(m.size(), 1);
+ m.set("foo", 2);
+ assert.deepEqual(m.size(), 1);
+ m.set("bar", 2);
+ assert.deepEqual(m.size(), 2);
+ m.remove("foo");
+ assert.deepEqual(m.size(), 1);
+ m.remove("foo");
+ assert.deepEqual(m.size(), 1);
+ m.remove("bar");
+ assert.deepEqual(m.size(), 0);
+ }
+ },
+ "empty": {
+ "returns true only if the map is empty": function(map) {
+ var m = map();
+ assert.isTrue(m.empty());
+ m.set("foo", 1);
+ assert.isFalse(m.empty());
+ m.set("foo", 2);
+ assert.isFalse(m.empty());
+ m.set("bar", 2);
+ assert.isFalse(m.empty());
+ m.remove("foo");
+ assert.isFalse(m.empty());
+ m.remove("foo");
+ assert.isFalse(m.empty());
+ m.remove("bar");
+ assert.isTrue(m.empty());
+ }
+ },
+ "forEach": {
+ "passes key and value": function(map) {
+ var m = map({foo: 1, bar: "42"}),
+ c = [];
+ m.forEach(function(k, v) { c.push([k, v]); });
+ c.sort(function(a, b) { return a[0].localeCompare(b[0]); });
+ assert.deepEqual(c, [["bar", "42"], ["foo", 1]]);
+ },
+ "uses the map as the context": function(map) {
+ var m = map({foo: 1, bar: "42"}),
+ c = [];
+ m.forEach(function() { c.push(this); });
+ assert.strictEqual(c[0], m);
+ assert.strictEqual(c[1], m);
+ assert.equal(c.length, 2);
+ },
+ "iterates in arbitrary order": function(map) {
+ var m1 = map({foo: 1, bar: "42"}),
+ m2 = map({bar: "42", foo: 1}),
+ c1 = [],
+ c2 = [];
+ m1.forEach(function(k, v) { c1.push([k, v]); });
+ m2.forEach(function(k, v) { c2.push([k, v]); });
+ c1.sort(function(a, b) { return a[0].localeCompare(b[0]); });
+ c2.sort(function(a, b) { return a[0].localeCompare(b[0]); });
+ assert.deepEqual(c1, c2);
+ }
+ },
+ "keys": {
+ "returns an array of string keys": function(map) {
+ var m = map({foo: 1, bar: "42"});
+ assert.deepEqual(m.keys().sort(), ["bar", "foo"]);
+ },
+ "properly unescapes zero-prefixed keys": function(map) {
+ var m = map();
+ m.set("__proto__", 42);
+ m.set("\0weird", 42);
+ assert.deepEqual(m.keys().sort(), ["\0weird", "__proto__"]);
+ }
+ },
+ "values": {
+ "returns an array of arbitrary values": function(map) {
+ var m = map({foo: 1, bar: "42"});
+ assert.deepEqual(m.values().sort(), [1, "42"]);
+ }
+ },
+ "entries": {
+ "returns an array of key-value objects": function(map) {
+ var m = map({foo: 1, bar: "42"});
+ assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "42"}, {key: "foo", value: 1}]);
+ },
+ "empty maps have an empty entries array": function(map) {
+ var m = map();
+ assert.deepEqual(m.entries(), []);
+ m.set("foo", "bar");
+ assert.deepEqual(m.entries(), [{key: "foo", value: "bar"}]);
+ m.remove("foo");
+ assert.deepEqual(m.entries(), []);
+ },
+ "entries are returned in arbitrary order": function(map) {
+ var m = map({foo: 1, bar: "42"});
+ assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "42"}, {key: "foo", value: 1}]);
+ var m = map({bar: "42", foo: 1});
+ assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "42"}, {key: "foo", value: 1}]);
+ },
+ "observes changes via set and remove": function(map) {
+ var m = map({foo: 1, bar: "42"});
+ assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "42"}, {key: "foo", value: 1}]);
+ m.remove("foo");
+ assert.deepEqual(m.entries(), [{key: "bar", value: "42"}]);
+ m.set("bar", "bar");
+ assert.deepEqual(m.entries(), [{key: "bar", value: "bar"}]);
+ m.set("foo", "foo");
+ assert.deepEqual(m.entries().sort(ascendingByKey), [{key: "bar", value: "bar"}, {key: "foo", value: "foo"}]);
+ m.remove("bar");
+ assert.deepEqual(m.entries(), [{key: "foo", value: "foo"}]);
+ m.remove("foo");
+ assert.deepEqual(m.entries(), []);
+ m.remove("foo");
+ assert.deepEqual(m.entries(), []);
+ }
+ },
+ "has": {
+ "empty maps do not have object built-ins": function(map) {
+ var m = map();
+ assert.isFalse(m.has("__proto__"));
+ assert.isFalse(m.has("hasOwnProperty"));
+ },
+ "can has keys using built-in names": function(map) {
+ var m = map();
+ m.set("__proto__", 42);
+ assert.isTrue(m.has("__proto__"));
+ },
+ "can has keys with null or undefined properties": function(map) {
+ var m = map();
+ m.set("", "");
+ m.set("null", null);
+ m.set("undefined", undefined);
+ assert.isTrue(m.has(""));
+ assert.isTrue(m.has("null"));
+ assert.isTrue(m.has("undefined"));
+ },
+ "coerces keys to strings": function(map) {
+ var m = map({"42": "foo", "null": 1, "undefined": 2});
+ assert.isTrue(m.has(42));
+ assert.isTrue(m.has(null));
+ assert.isTrue(m.has(undefined));
+ },
+ "returns the latest value": function(map) {
+ var m = map({foo: 42});
+ assert.isTrue(m.has("foo"));
+ m.set("foo", 43);
+ assert.isTrue(m.has("foo"));
+ m.remove("foo");
+ assert.isFalse(m.has("foo"));
+ m.set("foo", "bar");
+ assert.isTrue(m.has("foo"));
+ },
+ "returns undefined for missing keys": function(map) {
+ var m = map({foo: 42});
+ assert.isFalse(m.has("bar"));
+ }
+ },
+ "get": {
+ "empty maps do not have object built-ins": function(map) {
+ var m = map();
+ assert.isUndefined(m.get("__proto__"));
+ assert.isUndefined(m.get("hasOwnProperty"));
+ },
+ "can get keys using built-in names": function(map) {
+ var m = map();
+ m.set("__proto__", 42);
+ assert.equal(m.get("__proto__"), 42);
+ },
+ "coerces keys to strings": function(map) {
+ var m = map({"42": 1, "null": 2, "undefined": 3});
+ assert.equal(m.get(42), 1);
+ assert.equal(m.get(null), 2);
+ assert.equal(m.get(undefined), 3);
+ },
+ "returns the latest value": function(map) {
+ var m = map({foo: 42});
+ assert.equal(m.get("foo"), 42);
+ m.set("foo", 43);
+ assert.equal(m.get("foo"), 43);
+ m.remove("foo");
+ assert.isUndefined(m.get("foo"));
+ m.set("foo", "bar");
+ assert.equal(m.get("foo"), "bar");
+ },
+ "returns undefined for missing keys": function(map) {
+ var m = map({foo: 42});
+ assert.isUndefined(m.get("bar"));
+ }
+ },
+ "set": {
+ "returns the set value": function(map) {
+ var m = map();
+ assert.equal(m.set("foo", 42), 42);
+ },
+ "can set keys using built-in names": function(map) {
+ var m = map();
+ m.set("__proto__", 42);
+ assert.equal(m.get("__proto__"), 42);
+ },
+ "can set keys using zero-prefixed names": function(map) {
+ var m = map();
+ m.set("\0weird", 42);
+ assert.equal(m.get("\0weird"), 42);
+ },
+ "coerces keys to strings": function(map) {
+ var m = map();
+ m.set(42, 1);
+ assert.equal(m.get(42), 1);
+ m.set(null, 2);
+ assert.equal(m.get(null), 2);
+ m.set(undefined, 3);
+ assert.equal(m.get(undefined), 3);
+ assert.deepEqual(m.keys().sort(), ["42", "null", "undefined"]);
+ },
+ "can replace values": function(map) {
+ var m = map({foo: 42});
+ assert.equal(m.get("foo"), 42);
+ m.set("foo", 43);
+ assert.equal(m.get("foo"), 43);
+ m.set("foo", "bar");
+ assert.equal(m.get("foo"), "bar");
+ },
+ "can set null, undefined or empty string values": function(map) {
+ var m = map();
+ m.set("", "");
+ m.set("null", null);
+ m.set("undefined", undefined);
+ assert.equal(m.get(""), "");
+ assert.isNull(m.get("null"));
+ assert.isUndefined(m.get("undefined"));
+ }
+ }
+ }
+});
+
+function ascendingByKey(a, b) {
+ return a.key.localeCompare(b.key);
+}
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/max-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/max-test.js
new file mode 100644
index 0000000..2403ac2
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/max-test.js
@@ -0,0 +1,51 @@
+var vows = require("vows"),
+ _ = require("../../"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.max");
+
+suite.addBatch({
+ "max": {
+ topic: load("arrays/max").expression("d3.max"),
+ "returns the greatest numeric value for numbers": function(max) {
+ assert.equal(max([1]), 1);
+ assert.equal(max([5, 1, 2, 3, 4]), 5);
+ assert.equal(max([20, 3]), 20);
+ assert.equal(max([3, 20]), 20);
+ },
+ "returns the greatest lexicographic value for strings": function(max) {
+ assert.equal(max(["c", "a", "b"]), "c");
+ assert.equal(max(["20", "3"]), "3");
+ assert.equal(max(["3", "20"]), "3");
+ },
+ "ignores null, undefined and NaN": function(max) {
+ var o = {valueOf: function() { return NaN; }};
+ assert.equal(max([NaN, 1, 2, 3, 4, 5]), 5);
+ assert.equal(max([o, 1, 2, 3, 4, 5]), 5);
+ assert.equal(max([1, 2, 3, 4, 5, NaN]), 5);
+ assert.equal(max([1, 2, 3, 4, 5, o]), 5);
+ assert.equal(max([10, null, 3, undefined, 5, NaN]), 10);
+ assert.equal(max([-1, null, -3, undefined, -5, NaN]), -1);
+ },
+ "compares heterogenous types as numbers": function(max) {
+ assert.strictEqual(max([20, "3"]), 20);
+ assert.strictEqual(max(["20", 3]), "20");
+ assert.strictEqual(max([3, "20"]), "20");
+ assert.strictEqual(max(["3", 20]), 20);
+ },
+ "returns undefined for empty array": function(max) {
+ assert.isUndefined(max([]));
+ assert.isUndefined(max([null]));
+ assert.isUndefined(max([undefined]));
+ assert.isUndefined(max([NaN]));
+ assert.isUndefined(max([NaN, NaN]));
+ },
+ "applies the optional accessor function": function(max) {
+ assert.equal(max([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return _.min(d); }), 2);
+ assert.equal(max([1, 2, 3, 4, 5], function(d, i) { return i; }), 4);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/mean-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/mean-test.js
new file mode 100644
index 0000000..9c9421b
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/mean-test.js
@@ -0,0 +1,47 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert"),
+ OneTimeNumber = require("./one-time-number");
+
+var suite = vows.describe("d3.mean");
+
+suite.addBatch({
+ "mean": {
+ topic: load("arrays/mean").expression("d3.mean"),
+ "returns the mean value for numbers": function(mean) {
+ assert.equal(mean([1]), 1);
+ assert.equal(mean([5, 1, 2, 3, 4]), 3);
+ assert.equal(mean([20, 3]), 11.5);
+ assert.equal(mean([3, 20]), 11.5);
+ },
+ "ignores null, undefined and NaN": function(mean) {
+ assert.equal(mean([NaN, 1, 2, 3, 4, 5]), 3);
+ assert.equal(mean([1, 2, 3, 4, 5, NaN]), 3);
+ assert.equal(mean([10, null, 3, undefined, 5, NaN]), 6);
+ },
+ "returns undefined for empty array": function(mean) {
+ assert.isUndefined(mean([]));
+ assert.isUndefined(mean([null]));
+ assert.isUndefined(mean([undefined]));
+ assert.isUndefined(mean([NaN]));
+ assert.isUndefined(mean([NaN, NaN]));
+ },
+ "applies the optional accessor function": function(mean) {
+ assert.equal(mean([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return mean(d); }), 4.5);
+ assert.equal(mean([1, 2, 3, 4, 5], function(d, i) { return i; }), 2);
+ },
+ "coerces values to numbers": function(mean) {
+ assert.equal(mean(["1"]), 1);
+ assert.equal(mean(["5", "1", "2", "3", "4"]), 3);
+ assert.equal(mean(["20", "3"]), 11.5);
+ assert.equal(mean(["3", "20"]), 11.5);
+ },
+ "coerces values exactly once": function(mean) {
+ var array = [1, new OneTimeNumber(3)];
+ assert.equal(mean(array), 2);
+ assert.equal(mean(array), 1);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/median-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/median-test.js
new file mode 100644
index 0000000..4ab4a52
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/median-test.js
@@ -0,0 +1,53 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert"),
+ OneTimeNumber = require("./one-time-number");
+
+var suite = vows.describe("d3.median");
+
+suite.addBatch({
+ "median": {
+ topic: load("arrays/median").expression("d3.median"),
+ "returns the median value for numbers": function(median) {
+ assert.equal(median([1]), 1);
+ assert.equal(median([5, 1, 2, 3, 4]), 3);
+ assert.equal(median([20, 3]), 11.5);
+ assert.equal(median([3, 20]), 11.5);
+ },
+ "ignores null, undefined and NaN": function(median) {
+ assert.equal(median([NaN, 1, 2, 3, 4, 5]), 3);
+ assert.equal(median([1, 2, 3, 4, 5, NaN]), 3);
+ assert.equal(median([10, null, 3, undefined, 5, NaN]), 5);
+ },
+ "can handle large numbers without overflowing": function(median) {
+ assert.equal(median([Number.MAX_VALUE, Number.MAX_VALUE]), Number.MAX_VALUE);
+ assert.equal(median([-Number.MAX_VALUE, -Number.MAX_VALUE]), -Number.MAX_VALUE);
+ },
+ "returns undefined for empty array": function(median) {
+ assert.isUndefined(median([]));
+ assert.isUndefined(median([null]));
+ assert.isUndefined(median([undefined]));
+ assert.isUndefined(median([NaN]));
+ assert.isUndefined(median([NaN, NaN]));
+ },
+ "applies the optional accessor function": function(median) {
+ assert.equal(median([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return median(d); }), 4.5);
+ assert.equal(median([1, 2, 3, 4, 5], function(d, i) { return i; }), 2);
+ },
+ "coerces strings to numbers": function(median) {
+ assert.equal(median(["1"]), 1);
+ assert.equal(median(["5", "1", "2", "3", "4"]), 3);
+ assert.equal(median(["20", "3"]), 11.5);
+ assert.equal(median(["3", "20"]), 11.5);
+ assert.equal(median(["2", "3", "20"]), 3);
+ assert.equal(median(["20", "3", "2"]), 3);
+ },
+ "coerces values exactly once": function(median) {
+ var array = [1, new OneTimeNumber(3)];
+ assert.equal(median(array), 2);
+ assert.equal(median(array), 1);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/merge-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/merge-test.js
new file mode 100644
index 0000000..9d25080
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/merge-test.js
@@ -0,0 +1,50 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.merge");
+
+suite.addBatch({
+ "merge": {
+ topic: load("arrays/merge").expression("d3.merge"),
+ "merges an array of arrays": function(merge) {
+ var a = {}, b = {}, c = {}, d = {}, e = {}, f = {};
+ assert.deepEqual(merge([[a], [b, c], [d, e, f]]), [a, b, c, d, e, f]);
+ },
+ "returns a new array when zero arrays are passed": function(merge) {
+ var input = [],
+ output = merge(input);
+ assert.deepEqual(output, []);
+ input.push([0.1]);
+ assert.deepEqual(input, [[0.1]]);
+ assert.deepEqual(output, []);
+ },
+ "returns a new array when one array is passed": function(merge) {
+ var input = [[1, 2, 3]],
+ output = merge(input);
+ assert.deepEqual(output, [1, 2, 3]);
+ input.push([4.1]);
+ input[0].push(3.1);
+ assert.deepEqual(input, [[1, 2, 3, 3.1], [4.1]]);
+ assert.deepEqual(output, [1, 2, 3]);
+ },
+ "returns a new array when two or more arrays are passed": function(merge) {
+ var input = [[1, 2, 3], [4, 5], [6]],
+ output = merge(input);
+ assert.deepEqual(output, [1, 2, 3, 4, 5, 6]);
+ input.push([7.1]);
+ input[0].push(3.1);
+ input[1].push(5.1);
+ input[2].push(6.1);
+ assert.deepEqual(input, [[1, 2, 3, 3.1], [4, 5, 5.1], [6, 6.1], [7.1]]);
+ assert.deepEqual(output, [1, 2, 3, 4, 5, 6]);
+ },
+ "does not modify the input arrays": function(merge) {
+ var input = [[1, 2, 3], [4, 5], [6]];
+ merge(input);
+ assert.deepEqual(input, [[1, 2, 3], [4, 5], [6]]);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/min-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/min-test.js
new file mode 100644
index 0000000..5fe331b
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/min-test.js
@@ -0,0 +1,51 @@
+var vows = require("vows"),
+ _ = require("../../"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.min");
+
+suite.addBatch({
+ "min": {
+ topic: load("arrays/min").expression("d3.min"),
+ "returns the least numeric value for numbers": function(min) {
+ assert.equal(min([1]), 1);
+ assert.equal(min([5, 1, 2, 3, 4]), 1);
+ assert.equal(min([20, 3]), 3);
+ assert.equal(min([3, 20]), 3);
+ },
+ "returns the least lexicographic value for strings": function(min) {
+ assert.equal(min(["c", "a", "b"]), "a");
+ assert.equal(min(["20", "3"]), "20");
+ assert.equal(min(["3", "20"]), "20");
+ },
+ "ignores null, undefined and NaN": function(min) {
+ var o = {valueOf: function() { return NaN; }};
+ assert.equal(min([NaN, 1, 2, 3, 4, 5]), 1);
+ assert.equal(min([o, 1, 2, 3, 4, 5]), 1);
+ assert.equal(min([1, 2, 3, 4, 5, NaN]), 1);
+ assert.equal(min([1, 2, 3, 4, 5, o]), 1);
+ assert.equal(min([10, null, 3, undefined, 5, NaN]), 3);
+ assert.equal(min([-1, null, -3, undefined, -5, NaN]), -5);
+ },
+ "compares heterogenous types as numbers": function(min) {
+ assert.strictEqual(min([20, "3"]), "3");
+ assert.strictEqual(min(["20", 3]), 3);
+ assert.strictEqual(min([3, "20"]), 3);
+ assert.strictEqual(min(["3", 20]), "3");
+ },
+ "returns undefined for empty array": function(min) {
+ assert.isUndefined(min([]));
+ assert.isUndefined(min([null]));
+ assert.isUndefined(min([undefined]));
+ assert.isUndefined(min([NaN]));
+ assert.isUndefined(min([NaN, NaN]));
+ },
+ "applies the optional accessor function": function(min) {
+ assert.equal(min([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return _.max(d); }), 5);
+ assert.equal(min([1, 2, 3, 4, 5], function(d, i) { return i; }), 0);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/nest-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/nest-test.js
new file mode 100644
index 0000000..13d9001
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/nest-test.js
@@ -0,0 +1,256 @@
+var vows = require("vows"),
+ _ = require("../../"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.nest");
+
+suite.addBatch({
+ "entries": {
+ topic: load("arrays/nest").expression("d3.nest"),
+ "returns an array of each distinct key in arbitrary order": function(nest) {
+ var keys = nest()
+ .key(function(d) { return d.foo; })
+ .entries([{foo: 1}, {foo: 1}, {foo: 2}])
+ .map(function(d) { return d.key; })
+ .sort(_.ascending);
+ assert.deepEqual(keys, ["1", "2"]);
+ },
+ "each entry is a key-values object, with values in input order": function(nest) {
+ var entries = nest()
+ .key(function(d) { return d.foo; })
+ .entries([{foo: 1, bar: 0}, {foo: 2}, {foo: 1, bar: 1}]);
+ assert.deepEqual(entries, [
+ {key: "1", values: [{foo: 1, bar: 0}, {foo: 1, bar: 1}]},
+ {key: "2", values: [{foo: 2}]}
+ ]);
+ },
+ "keys can be sorted using an optional comparator": function(nest) {
+ var keys = nest()
+ .key(function(d) { return d.foo; }).sortKeys(_.descending)
+ .entries([{foo: 1}, {foo: 1}, {foo: 2}])
+ .map(function(d) { return d.key; });
+ assert.deepEqual(keys, ["2", "1"]);
+ },
+ "values can be sorted using an optional comparator": function(nest) {
+ var entries = nest()
+ .key(function(d) { return d.foo; })
+ .sortValues(function(a, b) { return a.bar - b.bar; })
+ .entries([{foo: 1, bar: 2}, {foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 2}]);
+ assert.deepEqual(entries, [
+ {key: "1", values: [{foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 1, bar: 2}]},
+ {key: "2", values: [{foo: 2}]}
+ ]);
+ },
+ "values can be aggregated using an optional rollup": function(nest) {
+ var entries = nest()
+ .key(function(d) { return d.foo; })
+ .rollup(function(values) { return _.sum(values, function(d) { return d.bar; }); })
+ .entries([{foo: 1, bar: 2}, {foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 2}]);
+ assert.deepEqual(entries, [
+ {key: "1", values: 3},
+ {key: "2", values: 0}
+ ]);
+ },
+ "multiple key functions can be specified": function(nest) {
+ var entries = nest()
+ .key(function(d) { return d[0]; }).sortKeys(_.ascending)
+ .key(function(d) { return d[1]; }).sortKeys(_.ascending)
+ .entries([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]);
+ assert.deepEqual(entries, [
+ {key: "0", values: [
+ {key: "1", values: [[0, 1]]},
+ {key: "2", values: [[0, 2], [0, 2]]}
+ ]},
+ {key: "1", values: [
+ {key: "1", values: [[1, 1]]},
+ {key: "2", values: [[1, 2]]}
+ ]}
+ ]);
+ },
+ "the rollup function only applies to leaf values": function(nest) {
+ var entries = nest()
+ .key(function(d) { return d[0]; }).sortKeys(_.ascending)
+ .key(function(d) { return d[1]; }).sortKeys(_.ascending)
+ .rollup(function(values) { return values.length; })
+ .entries([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]);
+ assert.deepEqual(entries, [
+ {key: "0", values: [
+ {key: "1", values: 1},
+ {key: "2", values: 2}
+ ]},
+ {key: "1", values: [
+ {key: "1", values: 1},
+ {key: "2", values: 1}
+ ]}
+ ]);
+ },
+ "the value comparator only applies to leaf values": function(nest) {
+ var entries = nest()
+ .key(function(d) { return d[0]; }).sortKeys(_.ascending)
+ .key(function(d) { return d[1]; }).sortKeys(_.ascending)
+ .sortValues(function(a, b) { return a[2] - b[2]; })
+ .entries([[0, 1], [0, 2, 1], [1, 1], [1, 2], [0, 2, 0]]);
+ assert.deepEqual(entries, [
+ {key: "0", values: [
+ {key: "1", values: [[0, 1]]},
+ {key: "2", values: [[0, 2, 0], [0, 2, 1]]}
+ ]},
+ {key: "1", values: [
+ {key: "1", values: [[1, 1]]},
+ {key: "2", values: [[1, 2]]}
+ ]}
+ ]);
+ },
+ "the key comparator only applies to the last-specified key": function(nest) {
+ var entries = nest()
+ .key(function(d) { return d[0]; }).sortKeys(_.ascending)
+ .key(function(d) { return d[1]; }).sortKeys(_.descending)
+ .entries([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]);
+ assert.deepEqual(entries, [
+ {key: "0", values: [
+ {key: "2", values: [[0, 2], [0, 2]]},
+ {key: "1", values: [[0, 1]]}
+ ]},
+ {key: "1", values: [
+ {key: "2", values: [[1, 2]]},
+ {key: "1", values: [[1, 1]]}
+ ]}
+ ]);
+ var entries = nest()
+ .key(function(d) { return d[0]; }).sortKeys(_.descending)
+ .key(function(d) { return d[1]; }).sortKeys(_.ascending)
+ .entries([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]);
+ assert.deepEqual(entries, [
+ {key: "1", values: [
+ {key: "1", values: [[1, 1]]},
+ {key: "2", values: [[1, 2]]}
+ ]},
+ {key: "0", values: [
+ {key: "1", values: [[0, 1]]},
+ {key: "2", values: [[0, 2], [0, 2]]}
+ ]}
+ ]);
+ },
+ "if no keys are specified, the input array is returned": function(nest) {
+ var array = [new Object()];
+ assert.strictEqual(nest().entries(array), array);
+ }
+ }
+});
+
+suite.addBatch({
+ "map": {
+ topic: load("arrays/nest").expression("d3.nest"),
+ "returns a map of each distinct key": function(nest) {
+ var map = nest()
+ .key(function(d) { return d.foo; })
+ .map([{foo: 1, bar: 0}, {foo: 2}, {foo: 1, bar: 1}]);
+ assert.deepEqual(map, {
+ "1": [{foo: 1, bar: 0}, {foo: 1, bar: 1}],
+ "2": [{foo: 2}]
+ });
+ },
+ "values can be sorted using an optional comparator": function(nest) {
+ var map = nest()
+ .key(function(d) { return d.foo; })
+ .sortValues(function(a, b) { return a.bar - b.bar; })
+ .map([{foo: 1, bar: 2}, {foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 2}]);
+ assert.deepEqual(map, {
+ "1": [{foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 1, bar: 2}],
+ "2": [{foo: 2}]
+ });
+ },
+ "values can be aggregated using an optional rollup": function(nest) {
+ var map = nest()
+ .key(function(d) { return d.foo; })
+ .rollup(function(values) { return _.sum(values, function(d) { return d.bar; }); })
+ .map([{foo: 1, bar: 2}, {foo: 1, bar: 0}, {foo: 1, bar: 1}, {foo: 2}]);
+ assert.deepEqual(map, {
+ "1": 3,
+ "2": 0
+ });
+ },
+ "multiple key functions can be specified": function(nest) {
+ var map = nest()
+ .key(function(d) { return d[0]; }).sortKeys(_.ascending)
+ .key(function(d) { return d[1]; }).sortKeys(_.ascending)
+ .map([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]);
+ assert.deepEqual(map, {
+ "0": {
+ "1": [[0, 1]],
+ "2": [[0, 2], [0, 2]]
+ },
+ "1": {
+ "1": [[1, 1]],
+ "2": [[1, 2]]
+ }
+ });
+ },
+ "the rollup function only applies to leaf values": function(nest) {
+ var map = nest()
+ .key(function(d) { return d[0]; }).sortKeys(_.ascending)
+ .key(function(d) { return d[1]; }).sortKeys(_.ascending)
+ .rollup(function(values) { return values.length; })
+ .map([[0, 1], [0, 2], [1, 1], [1, 2], [0, 2]]);
+ assert.deepEqual(map, {
+ "0": {
+ "1": 1,
+ "2": 2
+ },
+ "1": {
+ "1": 1,
+ "2": 1
+ }
+ });
+ },
+ "the value comparator only applies to leaf values": function(nest) {
+ var map = nest()
+ .key(function(d) { return d[0]; }).sortKeys(_.ascending)
+ .key(function(d) { return d[1]; }).sortKeys(_.ascending)
+ .sortValues(function(a, b) { return a[2] - b[2]; })
+ .map([[0, 1], [0, 2, 1], [1, 1], [1, 2], [0, 2, 0]]);
+ assert.deepEqual(map, {
+ "0": {
+ "1": [[0, 1]],
+ "2": [[0, 2, 0], [0, 2, 1]]
+ },
+ "1": {
+ "1": [[1, 1]],
+ "2": [[1, 2]]
+ }
+ });
+ },
+ "if no keys are specified, the input array is returned": function(nest) {
+ var array = [new Object()];
+ assert.strictEqual(nest().map(array), array);
+ },
+ "handles keys that are built-in prototype properties": function(nest) {
+ var map = nest()
+ .key(String)
+ .map(["hasOwnProperty"]); // but note __proto__ wouldn’t work!
+ assert.deepEqual(map, {hasOwnProperty: ["hasOwnProperty"]});
+ },
+ "a custom map implementation can be specified": function(nest) {
+ var map = nest()
+ .key(String)
+ .map(["hasOwnProperty", "__proto__"], _.map);
+ assert.deepEqual(map.entries(), [
+ {key: "hasOwnProperty", value: ["hasOwnProperty"]},
+ {key: "__proto__", value: ["__proto__"]}
+ ]);
+ },
+ "the custom map implementation works on multiple levels of nesting": function(nest) {
+ var map = nest()
+ .key(function(d) { return d.foo; })
+ .key(function(d) { return d.bar; })
+ .map([{foo: 42, bar: "red"}], _.map);
+ assert.deepEqual(map.keys(), ["42"]);
+ assert.deepEqual(map.get("42").keys(), ["red"]);
+ assert.deepEqual(map.get("42").values(), [[{foo: 42, bar: "red"}]]);
+ assert.deepEqual(map.get("42").entries(), [{key: "red", value: [{foo: 42, bar: "red"}]}]);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/one-time-number.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/one-time-number.js
new file mode 100644
index 0000000..2653283
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/one-time-number.js
@@ -0,0 +1,11 @@
+module.exports = OneTimeNumber;
+
+function OneTimeNumber(value) {
+ this.value = value;
+}
+
+OneTimeNumber.prototype.valueOf = function() {
+ var v = this.value;
+ this.value = NaN;
+ return v;
+};
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/pairs-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/pairs-test.js
new file mode 100644
index 0000000..23b07fa
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/pairs-test.js
@@ -0,0 +1,27 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.pairs");
+
+suite.addBatch({
+ "pairs": {
+ topic: load("arrays/pairs").expression("d3.pairs"),
+ "returns the empty array if input array has length less than two": function(pairs) {
+ assert.deepEqual(pairs([]), []);
+ assert.deepEqual(pairs([1]), []);
+ },
+ "returns pairs of adjacent elements in the given array": function(pairs) {
+ assert.deepEqual(pairs([1, 2]), [[1, 2]]);
+ assert.deepEqual(pairs([1, 2, 3]), [[1, 2], [2, 3]]);
+ var a = {}, b = {}, c = {}, d = {};
+ assert.deepEqual(pairs([a, b, c, d]), [[a, b], [b, c], [c, d]]);
+ },
+ "includes null or undefined elements in pairs": function(pairs) {
+ assert.deepEqual(pairs([1, null, 2]), [[1, null], [null, 2]]);
+ assert.deepEqual(pairs([1, 2, undefined]), [[1, 2], [2, undefined]]);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/permute-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/permute-test.js
new file mode 100644
index 0000000..4f3d01e
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/permute-test.js
@@ -0,0 +1,49 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.permute");
+
+suite.addBatch({
+ "permute": {
+ topic: load("arrays/permute").expression("d3.permute"),
+ "permutes according to the specified index": function(permute) {
+ assert.deepEqual(permute([3, 4, 5], [2, 1, 0]), [5, 4, 3]);
+ assert.deepEqual(permute([3, 4, 5], [2, 0, 1]), [5, 3, 4]);
+ assert.deepEqual(permute([3, 4, 5], [0, 1, 2]), [3, 4, 5]);
+ },
+ "does not modify the input array": function(permute) {
+ var input = [3, 4, 5];
+ permute(input, [2, 1, 0]);
+ assert.deepEqual(input, [3, 4, 5]);
+ },
+ "can duplicate input values": function(permute) {
+ assert.deepEqual(permute([3, 4, 5], [0, 1, 0]), [3, 4, 3]);
+ assert.deepEqual(permute([3, 4, 5], [2, 2, 2]), [5, 5, 5]);
+ assert.deepEqual(permute([3, 4, 5], [0, 1, 1]), [3, 4, 4]);
+ },
+ "can return more elements": function(permute) {
+ assert.deepEqual(permute([3, 4, 5], [0, 0, 1, 2]), [3, 3, 4, 5]);
+ assert.deepEqual(permute([3, 4, 5], [0, 1, 1, 1]), [3, 4, 4, 4]);
+ },
+ "can return fewer elements": function(permute) {
+ assert.deepEqual(permute([3, 4, 5], [0]), [3]);
+ assert.deepEqual(permute([3, 4, 5], [1, 2]), [4, 5]);
+ assert.deepEqual(permute([3, 4, 5], []), []);
+ },
+ "can return undefined elements": function(permute) {
+ var v1 = permute([3, 4, 5], [10]);
+ assert.equal(v1.length, 1);
+ assert.isUndefined(v1[0]);
+ var v2 = permute([3, 4, 5], [-1]);
+ assert.equal(v2.length, 1);
+ assert.isUndefined(v2[0]);
+ var v3 = permute([3, 4, 5], [0, -1]);
+ assert.equal(v3.length, 2);
+ assert.equal(v3[0], 3);
+ assert.isUndefined(v3[1]);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/quantile-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/quantile-test.js
new file mode 100644
index 0000000..2cbade9
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/quantile-test.js
@@ -0,0 +1,56 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.quantile");
+
+suite.addBatch({
+ "quantile": {
+ topic: load("arrays/quantile").expression("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);
+ },
+ "coerces values to numbers": function(quantile) {
+ var strings = ["1", "2", "3", "4"];
+ assert.strictEqual(quantile(strings, 1/3), 2);
+ assert.strictEqual(quantile(strings, 1/2), 2.5);
+ assert.strictEqual(quantile(strings, 2/3), 3);
+ var dates = [new Date(2011, 0, 1), new Date(2012, 0, 1)];
+ assert.strictEqual(quantile(dates, 0), +new Date(2011, 0, 1));
+ assert.strictEqual(quantile(dates, 1/2), +new Date(2011, 6, 2, 13));
+ assert.strictEqual(quantile(dates, 1), +new Date(2012, 0, 1));
+ },
+ "returns an exact value for integer p-values": function(quantile) {
+ var data = [1, 2, 3, 4];
+ assert.equal(quantile(data, 1/3), 2);
+ assert.equal(quantile(data, 2/3), 3);
+ },
+ "returns the first value for p = 0": function(quantile) {
+ var data = [1, 2, 3, 4];
+ assert.equal(quantile(data, 0), 1);
+ },
+ "returns the last value for p = 1": function(quantile) {
+ var data = [1, 2, 3, 4];
+ assert.equal(quantile(data, 1), 4);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/range-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/range-test.js
new file mode 100644
index 0000000..3561954
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/range-test.js
@@ -0,0 +1,99 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.range");
+
+suite.addBatch({
+ "range": {
+ topic: load("arrays/range").expression("d3.range"),
+ "start is an inclusive lower bound": function(range) {
+ assert.equal(range(5)[0], 0);
+ assert.equal(range(1, 5)[0], 1);
+ assert.equal(range(5, 1, -1)[0], 5);
+ },
+ "stop is an exclusive upper bound": function(range) {
+ assert.equal(range(5)[4], 4);
+ assert.equal(range(1, 5)[3], 4);
+ assert.equal(range(5, 1, -1)[3], 2);
+ },
+ "with one argument, returns integers [0 … stop)": function(range) {
+ assert.deepEqual(range(0), []);
+ assert.deepEqual(range(1), [0]);
+ assert.deepEqual(range(5), [0, 1, 2, 3, 4]);
+ },
+ "with two arguments, returns integers [start … stop)": function(range) {
+ assert.deepEqual(range(0, 5), [0, 1, 2, 3, 4]);
+ assert.deepEqual(range(5, 9), [5, 6, 7, 8]);
+ },
+ "with three arguments, returns start + k * step": function(range) {
+ assert.deepEqual(range(0, 5, 1), [0, 1, 2, 3, 4]);
+ assert.deepEqual(range(5, 9, .5), [5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5]);
+ assert.deepEqual(range(5, 8.5, .5), [5, 5.5, 6, 6.5, 7, 7.5, 8]);
+ assert.deepEqual(range(2, 0, -.5), [2, 1.5, 1, .5]);
+ },
+ "handles fractional steps without rounding errors": function(range) {
+ assert.deepEqual(range(0, 0.5, 0.1), [0, 0.1, 0.2, 0.3, 0.4]);
+ assert.deepEqual(range(-2, -1.2, 0.1), [-2, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3]);
+ },
+ "handles extremely small steps without rounding errors": function(range) {
+ assert.deepEqual(range(2.1e-31, 5e-31, 1.1e-31), [2.1e-31, 3.2e-31, 4.3e-31]);
+ },
+ "handles extremely large steps without rounding errors": function(range) {
+ assert.deepEqual(range(1e300, 2e300, 0.3e300), [1e300, 1.3e300, 1.6e300, 1.9e300]);
+ },
+ "returns an ascending range if step is positive": function(range) {
+ assert.deepEqual(range(0, 5, 1), [0, 1, 2, 3, 4]);
+ },
+ "returns a descending range if step is negative": function(range) {
+ assert.deepEqual(range(5, 0, -1), [5, 4, 3, 2, 1]);
+ },
+ "returns an empty range if start, stop or step are NaN": function(range) {
+ assert.isEmpty(range(0, NaN));
+ assert.isEmpty(range(1, NaN));
+ assert.isEmpty(range(-1, NaN));
+ assert.isEmpty(range(0, undefined));
+ assert.isEmpty(range(1, undefined));
+ assert.isEmpty(range(-1, undefined));
+ assert.isEmpty(range(NaN, 0));
+ assert.isEmpty(range(NaN, 1));
+ assert.isEmpty(range(NaN, -1));
+ assert.isEmpty(range(undefined, 0));
+ assert.isEmpty(range(undefined, 1));
+ assert.isEmpty(range(undefined, -1));
+ assert.isEmpty(range(NaN, NaN));
+ assert.isEmpty(range(undefined, undefined));
+ assert.isEmpty(range(NaN, NaN, NaN));
+ assert.isEmpty(range(undefined, undefined, undefined));
+ assert.isEmpty(range(0, 10, NaN));
+ assert.isEmpty(range(10, 0, NaN));
+ assert.isEmpty(range(0, 10, undefined));
+ assert.isEmpty(range(10, 0, undefined));
+ },
+ "returns an empty range if start equals stop": function(range) {
+ assert.isEmpty(range(10, 10));
+ assert.isEmpty(range(10, 10, 1));
+ assert.isEmpty(range(10, 10, -1));
+ assert.isEmpty(range(10, 10, -.5));
+ assert.isEmpty(range(10, 10, .5));
+ assert.isEmpty(range(0, 0));
+ assert.isEmpty(range(0, 0, 1));
+ assert.isEmpty(range(0, 0, -1));
+ assert.isEmpty(range(0, 0, -.5));
+ assert.isEmpty(range(0, 0, .5));
+ },
+ "returns an empty range if stop is less than start and step is positive": function(range) {
+ assert.isEmpty(range(20, 10));
+ assert.isEmpty(range(20, 10, 2));
+ assert.isEmpty(range(20, 10, 1));
+ assert.isEmpty(range(20, 10, .5));
+ },
+ "returns an empty range if stop is greater than start and step is negative": function(range) {
+ assert.isEmpty(range(10, 20, -2));
+ assert.isEmpty(range(10, 20, -1));
+ assert.isEmpty(range(10, 20, -.5));
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/set-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/set-test.js
new file mode 100644
index 0000000..ec24685
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/set-test.js
@@ -0,0 +1,209 @@
+var vows = require("vows"),
+ _ = require("../../"),
+ load = require("../load"),
+ assert = require("assert");
+
+var suite = vows.describe("d3.set");
+
+suite.addBatch({
+ "set": {
+ topic: load("arrays/set").expression("d3.set"),
+ "constructor": {
+ "set() returns an empty set": function(set) {
+ var s = set();
+ assert.deepEqual(s.values(), []);
+ },
+ "set(null) returns an empty set": function(set) {
+ var s = set(null);
+ assert.deepEqual(s.values(), []);
+ },
+ "set(array) adds array entries": function(set) {
+ var s = set(["foo"]);
+ assert.isTrue(s.has("foo"));
+ var s = set(["foo", "bar"]);
+ assert.isTrue(s.has("foo"));
+ assert.isTrue(s.has("bar"));
+ }
+ },
+ "size": {
+ "returns the number of distinct values": function(set) {
+ var s = set();
+ assert.deepEqual(s.size(), 0);
+ s.add("foo");
+ assert.deepEqual(s.size(), 1);
+ s.add("foo");
+ assert.deepEqual(s.size(), 1);
+ s.add("bar");
+ assert.deepEqual(s.size(), 2);
+ s.remove("foo");
+ assert.deepEqual(s.size(), 1);
+ s.remove("foo");
+ assert.deepEqual(s.size(), 1);
+ s.remove("bar");
+ assert.deepEqual(s.size(), 0);
+ }
+ },
+ "empty": {
+ "returns true only if the set is empty": function(set) {
+ var s = set();
+ assert.isTrue(s.empty());
+ s.add("foo");
+ assert.isFalse(s.empty());
+ s.add("foo");
+ assert.isFalse(s.empty());
+ s.add("bar");
+ assert.isFalse(s.empty());
+ s.remove("foo");
+ assert.isFalse(s.empty());
+ s.remove("foo");
+ assert.isFalse(s.empty());
+ s.remove("bar");
+ assert.isTrue(s.empty());
+ }
+ },
+ "forEach": {
+ "passes value": function(set) {
+ var s = set(["foo", "bar"]),
+ c = [];
+ s.forEach(function(v) { c.push(v); });
+ c.sort();
+ assert.deepEqual(c, ["bar", "foo"]);
+ },
+ "uses the set as the context": function(set) {
+ var s = set(["foo", "bar"]),
+ c = [];
+ s.forEach(function() { c.push(this); });
+ assert.strictEqual(c[0], s);
+ assert.strictEqual(c[1], s);
+ assert.equal(c.length, 2);
+ },
+ "iterates in arbitrary order": function(set) {
+ var s1 = set(["foo", "bar"]),
+ s2 = set(["bar", "foo"]),
+ c1 = [],
+ c2 = [];
+ s1.forEach(function(v) { c1.push(v); });
+ s2.forEach(function(v) { c2.push(v); });
+ c1.sort();
+ c2.sort();
+ assert.deepEqual(c1, c2);
+ }
+ },
+ "values": {
+ "returns an array of string values": function(set) {
+ var s = set(["foo", "bar"]);
+ assert.deepEqual(s.values().sort(), ["bar", "foo"]);
+ },
+ "empty sets have an empty values array": function(set) {
+ var s = set();
+ assert.deepEqual(s.values(), []);
+ s.add("foo");
+ assert.deepEqual(s.values(), ["foo"]);
+ s.remove("foo");
+ assert.deepEqual(s.values(), []);
+ },
+ "values are returned in arbitrary order": function(set) {
+ var s = set(["foo", "bar"]);
+ assert.deepEqual(s.values().sort(_.ascending), ["bar", "foo"]);
+ var s = set(["bar", "foo"]);
+ assert.deepEqual(s.values().sort(_.ascending), ["bar", "foo"]);
+ },
+ "properly unescapes zero-prefixed keys": function(set) {
+ var s = set(["__proto__", "\0weird"]);
+ assert.deepEqual(s.values().sort(_.ascending), ["\0weird", "__proto__"]);
+ },
+ "observes changes via add and remove": function(set) {
+ var s = set(["foo", "bar"]);
+ assert.deepEqual(s.values().sort(_.ascending), ["bar", "foo"]);
+ s.remove("foo");
+ assert.deepEqual(s.values(), ["bar"]);
+ s.add("bar");
+ assert.deepEqual(s.values(), ["bar"]);
+ s.add("foo");
+ assert.deepEqual(s.values().sort(_.ascending), ["bar", "foo"]);
+ s.remove("bar");
+ assert.deepEqual(s.values(), ["foo"]);
+ s.remove("foo");
+ assert.deepEqual(s.values(), []);
+ s.remove("foo");
+ assert.deepEqual(s.values(), []);
+ }
+ },
+ "has": {
+ "empty sets do not have object built-ins": function(set) {
+ var s = set();
+ assert.isFalse(s.has("__proto__"));
+ assert.isFalse(s.has("hasOwnProperty"));
+ },
+ "coerces values to strings": function(set) {
+ var s = set(["42", "null", "undefined"]);
+ assert.isTrue(s.has(42));
+ assert.isTrue(s.has(null));
+ assert.isTrue(s.has(undefined));
+ },
+ "observes changes via add and remove": function(set) {
+ var s = set(["foo"]);
+ assert.isTrue(s.has("foo"));
+ s.add("foo");
+ assert.isTrue(s.has("foo"));
+ s.remove("foo");
+ assert.isFalse(s.has("foo"));
+ s.add("foo");
+ assert.isTrue(s.has("foo"));
+ },
+ "returns undefined for missing values": function(set) {
+ var s = set(["foo"]);
+ assert.isFalse(s.has("bar"));
+ }
+ },
+ "add": {
+ "returns the set value, coerced to a string": function(set) {
+ var s = set();
+ assert.equal(s.add("foo"), "foo");
+ assert.strictEqual(s.add(2), "2");
+ assert.deepEqual(s.values().sort(), ["2", "foo"]);
+ },
+ "can add values using built-in names": function(set) {
+ var s = set();
+ s.add("__proto__");
+ assert.isTrue(s.has("__proto__"));
+ },
+ "can add values using zero-prefixed names": function(set) {
+ var s = set();
+ s.add("\0weird");
+ assert.isTrue(s.has("\0weird"));
+ },
+ "coerces values to strings": function(set) {
+ var s = set();
+ s.add(42);
+ assert.isTrue(s.has(42));
+ s.add(null);
+ assert.isTrue(s.has(null));
+ s.add(undefined);
+ assert.isTrue(s.has(undefined));
+ assert.deepEqual(s.values().sort(), ["42", "null", "undefined"]);
+ },
+ "can add null, undefined or empty string values": function(set) {
+ var s = set();
+ s.add("");
+ s.add("null");
+ s.add("undefined");
+ assert.isTrue(s.has(""));
+ assert.isTrue(s.has("null"));
+ assert.isTrue(s.has("undefined"));
+ }
+ },
+ "remove": {
+ "returns true if the value was removed": function(set) {
+ var s = set(["foo"]);
+ assert.isTrue(s.remove("foo"));
+ },
+ "returns false if the value is not an element": function(set) {
+ var s = set();
+ assert.isFalse(s.remove("foo"));
+ }
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/shuffle-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/shuffle-test.js
new file mode 100644
index 0000000..2f28457
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/shuffle-test.js
@@ -0,0 +1,43 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert"),
+ seedrandom = require("seedrandom");
+
+var suite = vows.describe("d3.shuffle");
+
+var _random;
+
+suite.addBatch({
+ "shuffle": {
+ topic: load("arrays/shuffle").sandbox({Math: Math}).expression("d3.shuffle"),
+ "(using seedrandom)": {
+ topic: function(random) {
+ _random = Math.random;
+ return random;
+ },
+ "shuffles an array in-place": function(shuffle) {
+ Math.seedrandom("a random seed.");
+ var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ assert.strictEqual(shuffle(array), array);
+ assert.deepEqual(array, [6, 4, 7, 9, 3, 1, 5, 8, 0, 2]);
+ },
+ "shuffles a subset of an array from the specified start": function(shuffle) {
+ Math.seedrandom("a random seed.");
+ var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ assert.strictEqual(shuffle(array, 4), array);
+ assert.deepEqual(array, [0, 1, 2, 3, 9, 7, 6, 8, 4, 5]);
+ },
+ "shuffles a subset of an array between the specified start and end": function(shuffle) {
+ Math.seedrandom("a random seed.");
+ var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ assert.strictEqual(shuffle(array, 3, 8), array);
+ assert.deepEqual(array, [0, 1, 2, 5, 7, 6, 3, 4, 8, 9]);
+ },
+ teardown: function() {
+ Math.random = _random;
+ }
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/sum-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/sum-test.js
new file mode 100644
index 0000000..81a3a9c
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/sum-test.js
@@ -0,0 +1,43 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.sum");
+
+suite.addBatch({
+ "sum": {
+ topic: load("arrays/sum").expression("d3.sum"),
+ "sums numbers": function(sum) {
+ assert.equal(sum([1]), 1);
+ assert.equal(sum([5, 1, 2, 3, 4]), 15);
+ assert.equal(sum([20, 3]), 23);
+ assert.equal(sum([3, 20]), 23);
+ },
+ "sums types that can be coerced to numbers": function(sum) {
+ assert.equal(sum(["20", "3"]), 23);
+ assert.equal(sum(["3", "20"]), 23);
+ assert.equal(sum(["3", 20]), 23);
+ assert.equal(sum([20, "3"]), 23);
+ assert.equal(sum([3, "20"]), 23);
+ assert.equal(sum(["20", 3]), 23);
+ },
+ "ignores non-numeric types": function(sum) {
+ assert.equal(sum(["a", "b", "c"]), 0);
+ assert.equal(sum(["a", 1, "2"]), 3);
+ },
+ "ignores null, undefined and NaN": function(sum) {
+ assert.equal(sum([NaN, 1, 2, 3, 4, 5]), 15);
+ assert.equal(sum([1, 2, 3, 4, 5, NaN]), 15);
+ assert.equal(sum([10, null, 3, undefined, 5, NaN]), 18);
+ },
+ "applies the optional acccessor function": function(sum) {
+ assert.equal(sum([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return sum(d); }), 45);
+ assert.equal(sum([1, 2, 3, 4, 5], function(d, i) { return i; }), 10);
+ },
+ "returns zero for the empty array": function(sum) {
+ assert.equal(sum([]), 0);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/transpose-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/transpose-test.js
new file mode 100644
index 0000000..84b6b55
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/transpose-test.js
@@ -0,0 +1,28 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.transpose");
+
+suite.addBatch({
+ "transpose": {
+ topic: load("arrays/transpose").expression("d3.transpose"),
+ "transposes a square matrix": function(transpose) {
+ assert.deepEqual(transpose([[1, 2], [3, 4]]), [[1, 3], [2, 4]]);
+ },
+ "transposes a non-square matrix": function(transpose) {
+ assert.deepEqual(transpose([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]]), [[1, 2], [2, 4], [3, 6], [4, 8], [5, 10]]);
+ },
+ "transposes a single-row matrix": function(transpose) {
+ assert.deepEqual(transpose([[1, 2, 3, 4, 5]]), [[1], [2], [3], [4], [5]]);
+ },
+ "transposes an empty matrix": function(transpose) {
+ assert.deepEqual(transpose([]), []);
+ },
+ "ignores extra elements given an irregular matrix": function(transpose) {
+ assert.deepEqual(transpose([[1, 2], [3, 4], [5, 6, 7]]), [[1, 3, 5], [2, 4, 6]]);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/values-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/values-test.js
new file mode 100644
index 0000000..f244dee
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/values-test.js
@@ -0,0 +1,31 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.values");
+
+suite.addBatch({
+ "values": {
+ topic: load("arrays/values").expression("d3.values"),
+ "enumerates every value": function(values) {
+ assert.deepEqual(values({a: 1, b: 2}), [1, 2]);
+ },
+ "includes values defined on prototypes": function(values) {
+ function abc() {
+ this.a = 1;
+ this.b = 2;
+ }
+ abc.prototype.c = 3;
+ assert.deepEqual(values(new abc()), [1, 2, 3]);
+ },
+ "includes null or undefined values": function(values) {
+ var v = values({a: undefined, b: null, c: NaN});
+ assert.isUndefined(v[0]);
+ assert.isNull(v[1]);
+ assert.isNaN(v[2]);
+ assert.equal(v.length, 3);
+ }
+ }
+});
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/variance-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/variance-test.js
new file mode 100644
index 0000000..99af932
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/variance-test.js
@@ -0,0 +1,43 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.variance");
+
+suite.addBatch({
+ "variance": {
+ topic: load("arrays/variance").expression("d3.variance"),
+ "returns the variance value for numbers": function(variance) {
+ assert.isUndefined(variance([1]));
+ assert.equal(variance([5, 1, 2, 3, 4]), 2.5);
+ assert.equal(variance([20, 3]), 144.5);
+ assert.equal(variance([3, 20]), 144.5);
+ },
+ "ignores null, undefined and NaN": function(variance) {
+ assert.equal(variance([NaN, 1, 2, 3, 4, 5]), 2.5);
+ assert.equal(variance([1, 2, 3, 4, 5, NaN]), 2.5);
+ assert.equal(variance([10, null, 3, undefined, 5, NaN]), 13);
+ },
+ "can handle large numbers without overflowing": function(variance) {
+ assert.equal(variance([Number.MAX_VALUE, Number.MAX_VALUE]), 0);
+ assert.equal(variance([-Number.MAX_VALUE, -Number.MAX_VALUE]), 0);
+ },
+ "returns undefined for empty array": function(variance) {
+ assert.isUndefined(variance([]));
+ assert.isUndefined(variance([null]));
+ assert.isUndefined(variance([undefined]));
+ assert.isUndefined(variance([NaN]));
+ assert.isUndefined(variance([NaN, NaN]));
+ },
+ "applies the optional accessor function": function(variance) {
+ assert.equal(variance([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], mean), 4.5);
+ assert.equal(variance([1, 2, 3, 4, 5], function(d, i) { return i; }), 2.5);
+ }
+ }
+});
+
+function mean(array) {
+ return array.reduce(function(p, v) { return p + v; }) / array.length;
+}
+
+suite.export(module);
diff --git a/web/nms.gathering.org/speedometer/d3-master/test/arrays/zip-test.js b/web/nms.gathering.org/speedometer/d3-master/test/arrays/zip-test.js
new file mode 100644
index 0000000..56b4076
--- /dev/null
+++ b/web/nms.gathering.org/speedometer/d3-master/test/arrays/zip-test.js
@@ -0,0 +1,28 @@
+var vows = require("vows"),
+ load = require("../load"),
+ assert = require("../assert");
+
+var suite = vows.describe("d3.zip");
+
+suite.addBatch({
+ "zip": {
+ topic: load("arrays/zip").expression("d3.zip"),
+ "transposes a square matrix": function(zip) {
+ assert.deepEqual(zip([1, 2], [3, 4]), [[1, 3], [2, 4]]);
+ },
+ "transposes a non-square matrix": function(zip) {
+ assert.deepEqual(zip([1, 2, 3, 4, 5], [2, 4, 6, 8, 10]), [[1, 2], [2, 4], [3, 6], [4, 8], [5, 10]]);
+ },
+ "transposes a single-row matrix": function(zip) {
+ assert.deepEqual(zip([1, 2, 3, 4, 5]), [[1], [2], [3], [4], [5]]);
+ },
+ "transposes an empty matrix": function(zip) {
+ assert.deepEqual(zip(), []);
+ },
+ "ignores extra elements given an irregular matrix": function(zip) {
+ assert.deepEqual(zip([1, 2], [3, 4], [5, 6, 7]), [[1, 3, 5], [2, 4, 6]]);
+ }
+ }
+});
+
+suite.export(module);