155 lines
7.1 KiB
JavaScript
155 lines
7.1 KiB
JavaScript
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
|
|
import { test, expect } from "@perspective-dev/test";
|
|
import perspective from "../perspective_client";
|
|
|
|
import * as common from "./common.js";
|
|
|
|
/**
|
|
* Tests the correctness of user-defined vectors inside expressions.
|
|
*
|
|
* @param {*} perspective
|
|
*/
|
|
((perspective) => {
|
|
test.describe("Vectors", () => {
|
|
test("Create vector and return value", async () => {
|
|
const table = await perspective.table(common.int_float_data);
|
|
const view = await table.view({
|
|
expressions: { a: `var vec[3] := {1, "w", 2}; vec[1]` },
|
|
});
|
|
expect(await view.expression_schema()).toEqual({
|
|
a: "float",
|
|
});
|
|
const result = await view.to_columns();
|
|
expect(result["a"]).toEqual(result["w"]);
|
|
await view.delete();
|
|
await table.delete();
|
|
});
|
|
|
|
test("Return from empty vector should be 0", async () => {
|
|
const table = await perspective.table(common.int_float_data);
|
|
const view = await table.view({
|
|
expressions: { a: `var vec[3]; vec[1]` },
|
|
});
|
|
expect(await view.expression_schema()).toEqual({
|
|
a: "float",
|
|
});
|
|
const result = await view.to_columns();
|
|
expect(result["a"]).toEqual(Array(4).fill(0));
|
|
await view.delete();
|
|
await table.delete();
|
|
});
|
|
|
|
test("Dynamic return types from vector", async () => {
|
|
const table = await perspective.table(common.int_float_data);
|
|
const view = await table.view({
|
|
expressions: {
|
|
[`a`]: `var vec[3] := {'abc', 123, today()}; vec[0]`,
|
|
[`b`]: `var vec[3] := {'abc', 123, today()}; vec[1]`,
|
|
[`c`]: `var vec[3] := {'abc', 123, date(2020, 5, 23)}; vec[2]`,
|
|
[`d`]: `var vec[3] := {'abc', 123, is_null(null)}; vec[2]`,
|
|
},
|
|
});
|
|
|
|
expect(await view.expression_schema()).toEqual({
|
|
a: "string",
|
|
b: "float",
|
|
c: "date",
|
|
d: "boolean",
|
|
});
|
|
|
|
const result = await view.to_columns();
|
|
|
|
expect(result["a"]).toEqual(Array(4).fill("abc"));
|
|
expect(result["b"]).toEqual(Array(4).fill(123));
|
|
expect(result["c"]).toEqual(
|
|
Array(4).fill(new Date(2020, 4, 23).getTime()),
|
|
);
|
|
expect(result["d"]).toEqual(Array(4).fill(true));
|
|
await view.delete();
|
|
await table.delete();
|
|
});
|
|
|
|
test("Use vector items as inputs", async () => {
|
|
const table = await perspective.table(common.int_float_data);
|
|
const view = await table.view({
|
|
expressions: {
|
|
[`a`]: `var vec[2] := {"w", "x"}; vec[0] * vec[1]`,
|
|
},
|
|
});
|
|
expect(await view.expression_schema()).toEqual({
|
|
a: "float",
|
|
});
|
|
const result = await view.to_columns();
|
|
expect(result["a"]).toEqual(
|
|
result["w"].map((item, idx) => item * result["x"][idx]),
|
|
);
|
|
await view.delete();
|
|
await table.delete();
|
|
});
|
|
|
|
test("Custom function takes vector item input", async () => {
|
|
const table = await perspective.table(common.int_float_data);
|
|
const view = await table.view({
|
|
expressions: {
|
|
[`a`]: `var vec[2] := {"w", "x"}; max(vec[0], vec[1])`,
|
|
},
|
|
});
|
|
expect(await view.expression_schema()).toEqual({
|
|
a: "float",
|
|
});
|
|
const result = await view.to_columns();
|
|
expect(result["a"]).toEqual(
|
|
result["w"].map((item, idx) =>
|
|
Math.max(item, result["x"][idx]),
|
|
),
|
|
);
|
|
await view.delete();
|
|
await table.delete();
|
|
});
|
|
|
|
test("`norm3` with a vector shorter than 3 is rejected", async () => {
|
|
const table = await perspective.table(common.int_float_data);
|
|
await expect(
|
|
table.view({
|
|
expressions: { a: `var v[2] := {1, 2}; norm3(v)` },
|
|
}),
|
|
).rejects.toThrow();
|
|
await table.delete();
|
|
});
|
|
|
|
test("`diff3` with vectors shorter than 3 is rejected", async () => {
|
|
const table = await perspective.table(common.int_float_data);
|
|
await expect(
|
|
table.view({
|
|
expressions: {
|
|
a: `var x[2] := {1, 2}; var y[2] := {3, 4}; var o[2]; diff3(x, y, o)`,
|
|
},
|
|
}),
|
|
).rejects.toThrow();
|
|
await table.delete();
|
|
});
|
|
|
|
test("`norm3` with a 3-element vector still computes", async () => {
|
|
const table = await perspective.table(common.int_float_data);
|
|
const view = await table.view({
|
|
expressions: { a: `var v[3] := {3, 4, 0}; norm3(v)` },
|
|
});
|
|
const result = await view.to_columns();
|
|
expect(result["a"]).toEqual(Array(4).fill(5)); // sqrt(9+16+0)
|
|
await view.delete();
|
|
await table.delete();
|
|
});
|
|
});
|
|
})(perspective);
|