diff options
author | Kristian Lyngstol <kristian@bohemians.org> | 2015-04-02 19:24:45 +0200 |
---|---|---|
committer | Kristian Lyngstol <kristian@bohemians.org> | 2015-04-02 19:24:45 +0200 |
commit | 0d8bba263dc195147d6fdb09662e7926f0a58b3e (patch) | |
tree | 4c570b4376c323e585120e7695b8715be7aa8881 /web/nms.gathering.org/speedometer/d3-master/test/arrays | |
parent | e4354b47bd8891c5b1ee591fdf74b3ca67eee461 (diff) |
Bump lots of changes
Diffstat (limited to 'web/nms.gathering.org/speedometer/d3-master/test/arrays')
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); |