From 596da096b4aa65d3ff09f7686c1c863b2267ed2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 22 Aug 2023 18:24:43 +0200 Subject: [PATCH 01/11] stack rejects an invalid order --- test/transforms/stack-test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/transforms/stack-test.js b/test/transforms/stack-test.js index c64f57face..1eab7feea7 100644 --- a/test/transforms/stack-test.js +++ b/test/transforms/stack-test.js @@ -13,3 +13,7 @@ it("Plot.stack returns the expected values", () => { assert.deepStrictEqual(Y1, Float64Array.of(0, 1, 0, -2)); assert.deepStrictEqual(Y2, Float64Array.of(1, 3, -2, -3)); }); + +it("Plot.stack rejects an invalid order", () => { + assert.throws(() => Plot.barY([], {y: 1, order: 42}), /^Error: invalid order: 42$/); +}); From f15991e1b15ab9510bba802a29e4412df579e6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 23 Aug 2023 10:26:53 +0200 Subject: [PATCH 02/11] these tests used the default labelAnchor --- test/plots/us-congress-age-color-explicit.ts | 11 ++--------- test/plots/us-congress-age-gender.ts | 6 +----- test/plots/us-congress-age-symbol-explicit.ts | 11 ++--------- test/plots/us-congress-age.ts | 11 ++--------- 4 files changed, 7 insertions(+), 32 deletions(-) diff --git a/test/plots/us-congress-age-color-explicit.ts b/test/plots/us-congress-age-color-explicit.ts index a359e90825..4eff8cd376 100644 --- a/test/plots/us-congress-age-color-explicit.ts +++ b/test/plots/us-congress-age-color-explicit.ts @@ -5,15 +5,8 @@ export async function usCongressAgeColorExplicit() { const data = await d3.csv("data/us-congress-members.csv", d3.autoType); return Plot.plot({ height: 300, - x: { - nice: true, - label: "Age", - labelAnchor: "right" - }, - y: { - grid: true, - label: "Frequency" - }, + x: {nice: true, label: "Age"}, + y: {grid: true, label: "Frequency"}, marks: [ Plot.dot( data, diff --git a/test/plots/us-congress-age-gender.ts b/test/plots/us-congress-age-gender.ts index cc8f6331dd..c3f1962a39 100644 --- a/test/plots/us-congress-age-gender.ts +++ b/test/plots/us-congress-age-gender.ts @@ -5,11 +5,7 @@ export async function usCongressAgeGender() { const data = await d3.csv("data/us-congress-members.csv", d3.autoType); return Plot.plot({ height: 300, - x: { - nice: true, - label: "Age", - labelAnchor: "right" - }, + x: {nice: true, label: "Age"}, y: { grid: true, label: "← Women · Men →", diff --git a/test/plots/us-congress-age-symbol-explicit.ts b/test/plots/us-congress-age-symbol-explicit.ts index 9d9b9d6fe0..9802ebe826 100644 --- a/test/plots/us-congress-age-symbol-explicit.ts +++ b/test/plots/us-congress-age-symbol-explicit.ts @@ -5,15 +5,8 @@ export async function usCongressAgeSymbolExplicit() { const data = await d3.csv("data/us-congress-members.csv", d3.autoType); return Plot.plot({ height: 300, - x: { - nice: true, - label: "Age", - labelAnchor: "right" - }, - y: { - grid: true, - label: "Frequency" - }, + x: {nice: true, label: "Age"}, + y: {grid: true, label: "Frequency"}, marks: [ Plot.dot( data, diff --git a/test/plots/us-congress-age.ts b/test/plots/us-congress-age.ts index a6e45f695e..8697c79f89 100644 --- a/test/plots/us-congress-age.ts +++ b/test/plots/us-congress-age.ts @@ -5,15 +5,8 @@ export async function usCongressAge() { const data = await d3.csv("data/us-congress-members.csv", d3.autoType); return Plot.plot({ height: 300, - x: { - nice: true, - label: "Age", - labelAnchor: "right" - }, - y: { - grid: true, - label: "Frequency" - }, + x: {nice: true, label: "Age"}, + y: {grid: true, label: "Frequency"}, marks: [ Plot.dot(data, Plot.stackY2({x: (d) => 2021 - d.birth, fill: "currentColor", title: "full_name"})), Plot.ruleY([0]) From 90014a9e6989bb4795a5a3c3b335bf1ae591024c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 23 Aug 2023 10:43:28 +0200 Subject: [PATCH 03/11] test curve tension --- test/output/curves.svg | 83 ++++++++++++++++++++++++++++++++++++++++++ test/plots/curves.ts | 26 +++++++++++++ test/plots/index.ts | 1 + 3 files changed, 110 insertions(+) create mode 100644 test/output/curves.svg create mode 100644 test/plots/curves.ts diff --git a/test/output/curves.svg b/test/output/curves.svg new file mode 100644 index 0000000000..30f5f54719 --- /dev/null +++ b/test/output/curves.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/curves.ts b/test/plots/curves.ts new file mode 100644 index 0000000000..eb7381c1d3 --- /dev/null +++ b/test/plots/curves.ts @@ -0,0 +1,26 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; + +export async function curves() { + const random = d3.randomLcg(42); + const values = d3.ticks(0, 1, 11).map((t) => { + const r = 1 + 2 * random(); + return [r * Math.cos(t * 2 * Math.PI), r * Math.sin(t * 2 * Math.PI)]; + }); + return Plot.plot({ + width: 500, + axis: null, + aspectRatio: true, + inset: 10, + marks: [ + d3 + .ticks(0, 1, 4) + .map((tension) => [ + Plot.line(values, {curve: "bundle", tension, stroke: "red", mixBlendMode: "multiply"}), + Plot.line(values, {curve: "cardinal-closed", tension, stroke: "green", mixBlendMode: "multiply"}), + Plot.line(values, {curve: "catmull-rom-closed", tension, stroke: "blue", mixBlendMode: "multiply"}) + ]), + Plot.dot(values, {stroke: "white", fill: "black"}) + ] + }); +} diff --git a/test/plots/index.ts b/test/plots/index.ts index 82b3c2e88a..f54ad0948a 100644 --- a/test/plots/index.ts +++ b/test/plots/index.ts @@ -58,6 +58,7 @@ export * from "./crimean-war-line.js"; export * from "./crimean-war-overlapped.js"; export * from "./crimean-war-stacked.js"; export * from "./crosshair.js"; +export * from "./curves.js"; export * from "./d3-survey-2015-comfort.js"; export * from "./d3-survey-2015-why.js"; export * from "./darker-dodge.js"; From 67e32d7d8eef0508536fb106e507aa9ee9241c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 23 Aug 2023 11:16:42 +0200 Subject: [PATCH 04/11] coverage: valid and invalid curves --- test/transforms/curve-test.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 test/transforms/curve-test.js diff --git a/test/transforms/curve-test.js b/test/transforms/curve-test.js new file mode 100644 index 0000000000..b23c929f0a --- /dev/null +++ b/test/transforms/curve-test.js @@ -0,0 +1,11 @@ +import * as Plot from "@observablehq/plot"; +import assert from "assert"; + +it("Plot.line rejects an invalid curve", () => { + assert.throws(() => Plot.lineY([], {y: 1, curve: "neo"}), /^Error: unknown curve: neo$/); + assert.throws(() => Plot.lineY([], {y: 1, curve: 42}), /^Error: unknown curve: 42$/); +}); + +it("Plot.line accepts the explicit auto curve", () => { + assert.strictEqual(Plot.lineY([], {y: 1, curve: "auto"}).curve?.name, "curveAuto"); +}); From ada6969ee44ab7ddc682f4ffe8827085c48627e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 23 Aug 2023 11:26:25 +0200 Subject: [PATCH 05/11] move curve tests to a features directory --- test/{transforms => features}/curve-test.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{transforms => features}/curve-test.js (100%) diff --git a/test/transforms/curve-test.js b/test/features/curve-test.js similarity index 100% rename from test/transforms/curve-test.js rename to test/features/curve-test.js From 8f079052fa618f3245c7876bbc17406f64eb340f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 23 Aug 2023 11:26:40 +0200 Subject: [PATCH 06/11] test channel scales: false, invalid --- test/scales/scales-test.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/scales/scales-test.js b/test/scales/scales-test.js index 5135cec632..2480e03f03 100644 --- a/test/scales/scales-test.js +++ b/test/scales/scales-test.js @@ -2192,6 +2192,20 @@ it("plot(…).scale(name) returns a deduplicated ordinal/temporal domain", () => }); }); +it("Plot channels respect a scale set to false", () => { + assert.strictEqual( + Plot.dot([], {channels: {fill: {value: (d) => d, scale: false}}}).initialize().channels.fill.scale, + null + ); +}); + +it("Plot channels reject unknown scales", () => { + assert.throws( + () => Plot.dot([], {channels: {fill: {value: (d) => d, scale: "neo"}}}).initialize().channels.fill.scale, + /^Error: unknown scale: neo$/ + ); +}); + // Given a plot specification (or, as shorthand, an array of marks or a single // mark), asserts that the given named scales, when materialized from the first // plot and used to produce a second plot, produce the same output and the same From 395bc882e5d8b48feae2f02fb4dfd68a2c4d828e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 23 Aug 2023 11:51:02 +0200 Subject: [PATCH 07/11] invalid domain sort options --- test/features/channel-test.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/features/channel-test.js diff --git a/test/features/channel-test.js b/test/features/channel-test.js new file mode 100644 index 0000000000..395707061f --- /dev/null +++ b/test/features/channel-test.js @@ -0,0 +1,23 @@ +import * as Plot from "@observablehq/plot"; +import assert from "assert"; +import {JSDOM} from "jsdom"; +const { + window: {document} +} = new JSDOM(""); + +it("The difference channel domain sort option needs two channels", () => { + assert.throws(() => Plot.dot([], {sort: {x: "height"}}).plot({document}), /^Error: missing channel: y1$/); + assert.throws( + () => Plot.dot([], {channels: {y1: "1"}, sort: {x: "height"}}).plot({document}), + /^Error: missing channel: y2$/ + ); + assert.throws(() => Plot.dot([], {sort: {y: "width"}}).plot({document}), /^Error: missing channel: x1$/); + assert.throws( + () => Plot.dot([], {channels: {x1: "1"}, sort: {y: "width"}}).plot({document}), + /^Error: missing channel: x2$/ + ); +}); + +it("A invalid domain order is rejected", () => { + assert.throws(() => Plot.dotY([0, 1], {sort: {y: {order: "neo"}}}).plot({document}), /^Error: invalid order: neo$/); +}); From 876589c93b1a210667d8203872a3b8bd19a42a93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 23 Aug 2023 11:51:06 +0200 Subject: [PATCH 08/11] The aspectRatio option rejects unsupported scale type --- test/features/aspectratio-test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/features/aspectratio-test.ts diff --git a/test/features/aspectratio-test.ts b/test/features/aspectratio-test.ts new file mode 100644 index 0000000000..b3e904ddd6 --- /dev/null +++ b/test/features/aspectratio-test.ts @@ -0,0 +1,17 @@ +import * as Plot from "@observablehq/plot"; +import assert from "assert"; +import {JSDOM} from "jsdom"; +const { + window: {document} +} = new JSDOM(""); + +it("The aspectRatio option rejects unsupported scale types", () => { + assert.throws( + () => Plot.dot([]).plot({document, aspectRatio: true, x: {type: "symlog"}}), + /^Error: unsupported x scale for aspectRatio: symlog$/ + ); + assert.throws( + () => Plot.dot([]).plot({document, aspectRatio: true, y: {type: "symlog"}}), + /^Error: unsupported y scale for aspectRatio: symlog$/ + ); +}); From 2163db286bf1001eeee1aaced482099679786934 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 23 Aug 2023 15:38:29 -0700 Subject: [PATCH 09/11] test style --- package.json | 10 ++++++++-- test/features/aspectratio-test.ts | 17 ----------------- test/features/channel-test.js | 23 ----------------------- test/features/curve-test.js | 11 ----------- test/mark-test.ts | 17 +++++++++++++++++ test/marks/line-test.js | 10 ++++++++++ test/plot-test.ts | 8 ++++++++ yarn.lock | 5 +++++ 8 files changed, 48 insertions(+), 53 deletions(-) delete mode 100644 test/features/aspectratio-test.ts delete mode 100644 test/features/channel-test.js delete mode 100644 test/features/curve-test.js create mode 100644 test/mark-test.ts create mode 100644 test/plot-test.ts diff --git a/package.json b/package.json index f176ce9a96..a344b65f1f 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-terser": "^0.4.0", "@types/d3": "^7.4.0", + "@types/mocha": "^10.0.1", "@types/node": "^20.5.0", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", @@ -77,8 +78,13 @@ }, "c8": { "all": true, - "include": ["src/**/*.js"], - "reporter": ["text", "lcov"] + "include": [ + "src/**/*.js" + ], + "reporter": [ + "text", + "lcov" + ] }, "dependencies": { "d3": "^7.8.0", diff --git a/test/features/aspectratio-test.ts b/test/features/aspectratio-test.ts deleted file mode 100644 index b3e904ddd6..0000000000 --- a/test/features/aspectratio-test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as Plot from "@observablehq/plot"; -import assert from "assert"; -import {JSDOM} from "jsdom"; -const { - window: {document} -} = new JSDOM(""); - -it("The aspectRatio option rejects unsupported scale types", () => { - assert.throws( - () => Plot.dot([]).plot({document, aspectRatio: true, x: {type: "symlog"}}), - /^Error: unsupported x scale for aspectRatio: symlog$/ - ); - assert.throws( - () => Plot.dot([]).plot({document, aspectRatio: true, y: {type: "symlog"}}), - /^Error: unsupported y scale for aspectRatio: symlog$/ - ); -}); diff --git a/test/features/channel-test.js b/test/features/channel-test.js deleted file mode 100644 index 395707061f..0000000000 --- a/test/features/channel-test.js +++ /dev/null @@ -1,23 +0,0 @@ -import * as Plot from "@observablehq/plot"; -import assert from "assert"; -import {JSDOM} from "jsdom"; -const { - window: {document} -} = new JSDOM(""); - -it("The difference channel domain sort option needs two channels", () => { - assert.throws(() => Plot.dot([], {sort: {x: "height"}}).plot({document}), /^Error: missing channel: y1$/); - assert.throws( - () => Plot.dot([], {channels: {y1: "1"}, sort: {x: "height"}}).plot({document}), - /^Error: missing channel: y2$/ - ); - assert.throws(() => Plot.dot([], {sort: {y: "width"}}).plot({document}), /^Error: missing channel: x1$/); - assert.throws( - () => Plot.dot([], {channels: {x1: "1"}, sort: {y: "width"}}).plot({document}), - /^Error: missing channel: x2$/ - ); -}); - -it("A invalid domain order is rejected", () => { - assert.throws(() => Plot.dotY([0, 1], {sort: {y: {order: "neo"}}}).plot({document}), /^Error: invalid order: neo$/); -}); diff --git a/test/features/curve-test.js b/test/features/curve-test.js deleted file mode 100644 index b23c929f0a..0000000000 --- a/test/features/curve-test.js +++ /dev/null @@ -1,11 +0,0 @@ -import * as Plot from "@observablehq/plot"; -import assert from "assert"; - -it("Plot.line rejects an invalid curve", () => { - assert.throws(() => Plot.lineY([], {y: 1, curve: "neo"}), /^Error: unknown curve: neo$/); - assert.throws(() => Plot.lineY([], {y: 1, curve: 42}), /^Error: unknown curve: 42$/); -}); - -it("Plot.line accepts the explicit auto curve", () => { - assert.strictEqual(Plot.lineY([], {y: 1, curve: "auto"}).curve?.name, "curveAuto"); -}); diff --git a/test/mark-test.ts b/test/mark-test.ts new file mode 100644 index 0000000000..8624a8b1d5 --- /dev/null +++ b/test/mark-test.ts @@ -0,0 +1,17 @@ +import * as Plot from "@observablehq/plot"; +import assert from "assert"; +import it from "./jsdom.js"; + +it("mark(data, {sort}) needs y1 and y2 when sorting by height", () => { + assert.throws(() => Plot.dot([], {sort: {x: "height"}}).plot(), /^Error: missing channel: y1$/); + assert.throws(() => Plot.dot([], {channels: {y1: "1"}, sort: {x: "height"}}).plot(), /^Error: missing channel: y2$/); +}); + +it("mark(data, {sort}) needs x1 and x2 when sorting by width", () => { + assert.throws(() => Plot.dot([], {sort: {y: "width"}}).plot(), /^Error: missing channel: x1$/); + assert.throws(() => Plot.dot([], {channels: {x1: "1"}, sort: {y: "width"}}).plot(), /^Error: missing channel: x2$/); +}); + +it("mark(data, {sort}) rejects an invalid order", () => { + assert.throws(() => Plot.dotY([0, 1], {sort: {y: {value: "x", order: "neo" as any}}}).plot(), /^Error: invalid order: neo$/); // prettier-ignore +}); diff --git a/test/marks/line-test.js b/test/marks/line-test.js index d60c58fc20..a66fdec79e 100644 --- a/test/marks/line-test.js +++ b/test/marks/line-test.js @@ -1,5 +1,6 @@ import * as Plot from "@observablehq/plot"; import {curveStep} from "d3"; +import {curveAuto} from "../../src/curve.js"; import assert from "assert"; it("line() has the expected defaults", () => { @@ -114,3 +115,12 @@ it("line(data, {curve}) specifies a named curve or function", () => { assert.strictEqual(Plot.line(undefined, {curve: "step"}).curve, curveStep); assert.strictEqual(Plot.line(undefined, {curve: curveStep}).curve, curveStep); }); + +it("line(data, {curve}) rejects an invalid curve", () => { + assert.throws(() => Plot.lineY([], {y: 1, curve: "neo"}), /^Error: unknown curve: neo$/); + assert.throws(() => Plot.lineY([], {y: 1, curve: 42}), /^Error: unknown curve: 42$/); +}); + +it("line(data, {curve}) accepts the explicit auto curve", () => { + assert.strictEqual(Plot.lineY([], {y: 1, curve: "auto"}).curve, curveAuto); +}); diff --git a/test/plot-test.ts b/test/plot-test.ts new file mode 100644 index 0000000000..baedd583ae --- /dev/null +++ b/test/plot-test.ts @@ -0,0 +1,8 @@ +import * as Plot from "@observablehq/plot"; +import assert from "assert"; +import it from "./jsdom.js"; + +it("plot({aspectRatio}) rejects unsupported scale types", () => { + assert.throws(() => Plot.dot([]).plot({aspectRatio: true, x: {type: "symlog"}}), /^Error: unsupported x scale for aspectRatio: symlog$/); // prettier-ignore + assert.throws(() => Plot.dot([]).plot({aspectRatio: true, y: {type: "symlog"}}), /^Error: unsupported y scale for aspectRatio: symlog$/); // prettier-ignore +}); diff --git a/yarn.lock b/yarn.lock index c45db2c2b9..62e89e1b36 100644 --- a/yarn.lock +++ b/yarn.lock @@ -815,6 +815,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== +"@types/mocha@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" + integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== + "@types/node@^20.5.0": version "20.5.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.0.tgz#7fc8636d5f1aaa3b21e6245e97d56b7f56702313" From 49cedcfed50531b3827586a7b777785b51755287 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 23 Aug 2023 15:54:24 -0700 Subject: [PATCH 10/11] test polish --- test/scales/scales-test.js | 40 ++++++++++++++++++++++++++++++++--- test/transforms/stack-test.js | 19 ----------------- 2 files changed, 37 insertions(+), 22 deletions(-) delete mode 100644 test/transforms/stack-test.js diff --git a/test/scales/scales-test.js b/test/scales/scales-test.js index 2480e03f03..faa4ab6d1b 100644 --- a/test/scales/scales-test.js +++ b/test/scales/scales-test.js @@ -2192,14 +2192,48 @@ it("plot(…).scale(name) returns a deduplicated ordinal/temporal domain", () => }); }); -it("Plot channels respect a scale set to false", () => { +it("mark(data, {channels}) respects a scale set to undefined", () => { assert.strictEqual( - Plot.dot([], {channels: {fill: {value: (d) => d, scale: false}}}).initialize().channels.fill.scale, + Plot.dot({length: 1}, {channels: {fill: {value: ["red"]}}}).initialize().channels.fill.scale, + undefined + ); + assert.strictEqual( + Plot.dot({length: 1}, {channels: {fill: {value: ["foo"]}}}).initialize().channels.fill.scale, + undefined + ); +}); + +it("mark(data, {channels}) respects a scale set to auto", () => { + assert.strictEqual( + Plot.dot({length: 1}, {channels: {fill: {value: ["red"], scale: "auto"}}}).initialize().channels.fill.scale, + null + ); + assert.strictEqual( + Plot.dot({length: 1}, {channels: {fill: {value: ["foo"], scale: "auto"}}}).initialize().channels.fill.scale, + "color" + ); +}); + +it("mark(data, {channels}) respects a scale set to true or false", () => { + assert.strictEqual( + Plot.dot({length: 1}, {channels: {fill: {value: ["red"], scale: true}}}).initialize().channels.fill.scale, + "color" + ); + assert.strictEqual( + Plot.dot({length: 1}, {channels: {fill: {value: ["red"], scale: false}}}).initialize().channels.fill.scale, + null + ); + assert.strictEqual( + Plot.dot({length: 1}, {channels: {fill: {value: ["foo"], scale: true}}}).initialize().channels.fill.scale, + "color" + ); + assert.strictEqual( + Plot.dot({length: 1}, {channels: {fill: {value: ["foo"], scale: false}}}).initialize().channels.fill.scale, null ); }); -it("Plot channels reject unknown scales", () => { +it("mark(data, {channels}) rejects unknown scales", () => { assert.throws( () => Plot.dot([], {channels: {fill: {value: (d) => d, scale: "neo"}}}).initialize().channels.fill.scale, /^Error: unknown scale: neo$/ diff --git a/test/transforms/stack-test.js b/test/transforms/stack-test.js deleted file mode 100644 index 1eab7feea7..0000000000 --- a/test/transforms/stack-test.js +++ /dev/null @@ -1,19 +0,0 @@ -import * as Plot from "@observablehq/plot"; -import assert from "assert"; - -it("Plot.stack returns the expected values", () => { - const y = [1, 2, -2, -1]; - const { - channels: { - y1: {value: Y1}, - y2: {value: Y2} - } - } = Plot.barY(y, Plot.stackY({y})).initialize(); - assert.deepStrictEqual(y, [1, 2, -2, -1]); - assert.deepStrictEqual(Y1, Float64Array.of(0, 1, 0, -2)); - assert.deepStrictEqual(Y2, Float64Array.of(1, 3, -2, -3)); -}); - -it("Plot.stack rejects an invalid order", () => { - assert.throws(() => Plot.barY([], {y: 1, order: 42}), /^Error: invalid order: 42$/); -}); From fe0de75ba3f7f5d901cd386fa5c1e9d3ba534b21 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 23 Aug 2023 15:54:34 -0700 Subject: [PATCH 11/11] add missing test --- test/transforms/stack-test.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 test/transforms/stack-test.ts diff --git a/test/transforms/stack-test.ts b/test/transforms/stack-test.ts new file mode 100644 index 0000000000..df23b4f6da --- /dev/null +++ b/test/transforms/stack-test.ts @@ -0,0 +1,19 @@ +import * as Plot from "@observablehq/plot"; +import assert from "assert"; + +it("stackY(options) returns the expected values", () => { + const y = [1, 2, -2, -1]; + const { + channels: { + y1: {value: Y1}, + y2: {value: Y2} + } + } = (Plot.barY(y, Plot.stackY({y})) as any).initialize(); + assert.deepStrictEqual(y, [1, 2, -2, -1]); + assert.deepStrictEqual(Y1, Float64Array.of(0, 1, 0, -2)); + assert.deepStrictEqual(Y2, Float64Array.of(1, 3, -2, -3)); +}); + +it("stackY({order}) rejects an invalid order", () => { + assert.throws(() => Plot.barY([], {y: 1, order: 42 as any}), /^Error: invalid order: 42$/); +});