491 lines
20 KiB
JavaScript
491 lines
20 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";
|
|
|
|
const _query = async (should_cache, table, config = {}, callback) => {
|
|
let cached_view;
|
|
if (should_cache) {
|
|
cached_view = await table.view(config);
|
|
}
|
|
|
|
const data_getter = async () => {
|
|
if (should_cache) {
|
|
return await cached_view.to_columns();
|
|
} else {
|
|
const view = await table.view(config);
|
|
const data = await view.to_columns();
|
|
await view.delete();
|
|
return data;
|
|
}
|
|
};
|
|
|
|
const v = await callback(data_getter);
|
|
if (cached_view) {
|
|
cached_view.delete();
|
|
}
|
|
|
|
return v;
|
|
};
|
|
|
|
const SCHEMA = {
|
|
str: "string",
|
|
int: "integer",
|
|
float: "float",
|
|
};
|
|
|
|
test.describe("Removes", () => {
|
|
for (const cond of [true, false]) {
|
|
const query = _query.bind(undefined, cond);
|
|
|
|
for (const idx of ["str", "int"]) {
|
|
const string_pkey = idx === "str";
|
|
|
|
test.describe(`View cached? ${cond}, index: ${idx}`, () => {
|
|
test("Output consistent with filter", async () => {
|
|
const table = await perspective.table(SCHEMA, {
|
|
index: idx,
|
|
});
|
|
const data = {
|
|
str: [1, 2, 3, 4, 5, 6].map((x) => x.toString()),
|
|
int: [1, 2, 3, 4, 5, 6],
|
|
float: [1, 2, 3, 4, 5, 6].map((x) => x * 0.5),
|
|
};
|
|
|
|
await table.update(data);
|
|
|
|
await query(
|
|
table,
|
|
{
|
|
filter: [["str", "!=", "2"]],
|
|
},
|
|
async (getter) => {
|
|
const pkey = 3;
|
|
await table.remove([
|
|
string_pkey ? pkey.toString() : pkey,
|
|
]);
|
|
|
|
expect(await getter()).toEqual({
|
|
str: ["1", "4", "5", "6"],
|
|
int: [1, 4, 5, 6],
|
|
float: [0.5, 2, 2.5, 3],
|
|
});
|
|
},
|
|
);
|
|
|
|
await table.delete();
|
|
});
|
|
|
|
test("Output consistent with filter, empty string", async () => {
|
|
const table = await perspective.table(SCHEMA, {
|
|
index: idx,
|
|
});
|
|
const data = {
|
|
str: [1, 2, 3, 4, 5, 6].map((x) => x.toString()),
|
|
int: [1, 2, 3, 4, 5, 6],
|
|
float: [1, 2, 3, 4, 5, 6].map((x) => x * 0.5),
|
|
};
|
|
|
|
data.str.push("");
|
|
data.int.push(7);
|
|
data.float.push(3.5);
|
|
|
|
await table.update(data);
|
|
|
|
await query(
|
|
table,
|
|
{
|
|
filter: [["str", "!=", "2"]],
|
|
},
|
|
async (getter) => {
|
|
const pkey = 3;
|
|
await table.remove([
|
|
string_pkey ? pkey.toString() : pkey,
|
|
]);
|
|
|
|
if (string_pkey) {
|
|
expect(await getter()).toEqual({
|
|
str: ["", "1", "4", "5", "6"],
|
|
int: [7, 1, 4, 5, 6],
|
|
float: [3.5, 0.5, 2, 2.5, 3],
|
|
});
|
|
} else {
|
|
expect(await getter()).toEqual({
|
|
str: ["1", "4", "5", "6", ""],
|
|
int: [1, 4, 5, 6, 7],
|
|
float: [0.5, 2, 2.5, 3, 3.5],
|
|
});
|
|
}
|
|
},
|
|
);
|
|
|
|
await table.delete();
|
|
});
|
|
|
|
test("Output consistent with filter, null", async () => {
|
|
const table = await perspective.table(SCHEMA, {
|
|
index: idx,
|
|
});
|
|
const data = {
|
|
str: [1, 2, 3, 4, 5, 6].map((x) => x.toString()),
|
|
int: [1, 2, 3, 4, 5, 6],
|
|
float: [1, 2, 3, 4, 5, 6].map((x) => x * 0.5),
|
|
};
|
|
|
|
data.str.push(null);
|
|
data.int.push(7);
|
|
data.float.push(3.5);
|
|
|
|
await table.update(data);
|
|
|
|
await query(
|
|
table,
|
|
{
|
|
filter: [["str", "!=", "2"]],
|
|
},
|
|
async (getter) => {
|
|
const pkey = 3;
|
|
await table.remove([
|
|
string_pkey ? pkey.toString() : pkey,
|
|
]);
|
|
|
|
if (string_pkey) {
|
|
expect(await getter()).toEqual({
|
|
str: [null, "1", "4", "5", "6"],
|
|
int: [7, 1, 4, 5, 6],
|
|
float: [3.5, 0.5, 2, 2.5, 3],
|
|
});
|
|
} else {
|
|
expect(await getter()).toEqual({
|
|
str: ["1", "4", "5", "6", null],
|
|
int: [1, 4, 5, 6, 7],
|
|
float: [0.5, 2, 2.5, 3, 3.5],
|
|
});
|
|
}
|
|
},
|
|
);
|
|
|
|
await table.delete();
|
|
});
|
|
|
|
test("Output consistent with filter, remove before view construction, sorted", async () => {
|
|
const table = await perspective.table(SCHEMA, {
|
|
index: idx,
|
|
});
|
|
const data = {
|
|
str: [1, 2, 3, 4, 5, 6].map((x) => x.toString()),
|
|
int: [1, 2, 3, 4, 5, 6],
|
|
float: [1, 2, 3, 4, 5, 6].map((x) => x * 0.5),
|
|
};
|
|
|
|
await table.update(data);
|
|
await table.remove(
|
|
[1, 3, 5].map((x) => (string_pkey ? x.toString() : x)),
|
|
);
|
|
|
|
await query(
|
|
table,
|
|
{
|
|
sort: [["str", "desc"]],
|
|
},
|
|
async (getter) => {
|
|
expect(await getter()).toEqual({
|
|
str: ["6", "4", "2"],
|
|
int: [6, 4, 2],
|
|
float: [3, 2, 1],
|
|
});
|
|
|
|
await table.update({
|
|
str: ["7", "9", "8"],
|
|
int: [7, 9, 8],
|
|
float: [3.5, 4.5, 4],
|
|
});
|
|
|
|
expect(await getter()).toEqual({
|
|
str: ["9", "8", "7", "6", "4", "2"],
|
|
int: [9, 8, 7, 6, 4, 2],
|
|
float: [4.5, 4, 3.5, 3, 2, 1],
|
|
});
|
|
},
|
|
);
|
|
|
|
await table.delete();
|
|
});
|
|
|
|
test("Output consistent with filter, remove and add identical", async () => {
|
|
const table = await perspective.table(SCHEMA, {
|
|
index: idx,
|
|
});
|
|
const data = {
|
|
str: [1, 2, 3, 4, 5, 6].map((x) => x.toString()),
|
|
int: [1, 2, 3, 4, 5, 6],
|
|
float: [1, 2, 3, 4, 5, 6].map((x) => x * 0.5),
|
|
};
|
|
|
|
await table.update(data);
|
|
|
|
await query(
|
|
table,
|
|
{
|
|
filter: [["str", "!=", "2"]],
|
|
},
|
|
async (getter) => {
|
|
const pkey = 3;
|
|
await table.remove([
|
|
string_pkey ? pkey.toString() : pkey,
|
|
]);
|
|
|
|
expect(await getter()).toEqual({
|
|
str: ["1", "4", "5", "6"],
|
|
int: [1, 4, 5, 6],
|
|
float: [0.5, 2, 2.5, 3],
|
|
});
|
|
|
|
await table.update({
|
|
str: ["7", "9", "8"],
|
|
int: [7, 9, 8],
|
|
float: [3.5, 4.5, 4],
|
|
});
|
|
|
|
expect(await getter()).toEqual({
|
|
str: ["1", "4", "5", "6", "7", "8", "9"],
|
|
int: [1, 4, 5, 6, 7, 8, 9],
|
|
float: [0.5, 2, 2.5, 3, 3.5, 4, 4.5],
|
|
});
|
|
},
|
|
);
|
|
|
|
await table.delete();
|
|
});
|
|
|
|
test("Output consistent with filter, add null and remove other", async () => {
|
|
const table = await perspective.table(SCHEMA, {
|
|
index: idx,
|
|
});
|
|
const data = {
|
|
str: [1, 2, 3, 4, 5, 6].map((x) => x.toString()),
|
|
int: [1, 2, 3, 4, 5, 6],
|
|
float: [1, 2, 3, 4, 5, 6].map((x) => x * 0.5),
|
|
};
|
|
|
|
await table.update(data);
|
|
|
|
await query(table, {}, async (getter) => {
|
|
expect(await getter()).toEqual(data);
|
|
|
|
await table.update({
|
|
str: [string_pkey ? null : "7"],
|
|
int: [string_pkey ? 7 : null],
|
|
float: [3.5],
|
|
});
|
|
|
|
if (string_pkey) {
|
|
expect(await getter()).toEqual({
|
|
str: [null, 1, 2, 3, 4, 5, 6].map((x) =>
|
|
x ? x.toString() : x,
|
|
),
|
|
int: [7, 1, 2, 3, 4, 5, 6],
|
|
float: [7, 1, 2, 3, 4, 5, 6].map(
|
|
(x) => x * 0.5,
|
|
),
|
|
});
|
|
} else {
|
|
expect(await getter()).toEqual({
|
|
str: [7, 1, 2, 3, 4, 5, 6].map((x) =>
|
|
x.toString(),
|
|
),
|
|
int: [null, 1, 2, 3, 4, 5, 6],
|
|
float: [7, 1, 2, 3, 4, 5, 6].map(
|
|
(x) => x * 0.5,
|
|
),
|
|
});
|
|
}
|
|
|
|
await table.remove([string_pkey ? "3" : 3]);
|
|
|
|
if (string_pkey) {
|
|
expect(await getter()).toEqual({
|
|
str: [null, 1, 2, 4, 5, 6].map((x) =>
|
|
x ? x.toString() : x,
|
|
),
|
|
int: [7, 1, 2, 4, 5, 6],
|
|
float: [7, 1, 2, 4, 5, 6].map((x) => x * 0.5),
|
|
});
|
|
} else {
|
|
expect(await getter()).toEqual({
|
|
str: [7, 1, 2, 4, 5, 6].map((x) =>
|
|
x.toString(),
|
|
),
|
|
int: [null, 1, 2, 4, 5, 6],
|
|
float: [7, 1, 2, 4, 5, 6].map((x) => x * 0.5),
|
|
});
|
|
}
|
|
});
|
|
|
|
await table.delete();
|
|
});
|
|
|
|
test("Output consistent with filter, remove and add new dataset", async () => {
|
|
const table = await perspective.table(SCHEMA, {
|
|
index: idx,
|
|
});
|
|
|
|
const data = {
|
|
str: [1, 2, 3, 4, 5, 6].map((x) => x.toString()),
|
|
int: [1, 2, 3, 4, 5, 6],
|
|
float: [1, 2, 3, 4, 5, 6].map((x) => x * 0.5),
|
|
};
|
|
|
|
await table.update(data);
|
|
|
|
await query(
|
|
table,
|
|
{
|
|
filter: [["int", "!=", 3]],
|
|
},
|
|
async (getter) => {
|
|
await table.remove(
|
|
[1, 2, 3, 4, 5, 6].map((x) =>
|
|
string_pkey ? x.toString() : x,
|
|
),
|
|
);
|
|
|
|
expect(await getter()).toEqual({
|
|
float: [],
|
|
int: [],
|
|
str: [],
|
|
});
|
|
|
|
await table.update({
|
|
str: ["def", "abc", "deff"],
|
|
int: [1, 2, 4],
|
|
float: [100.5, 200.5, 300.5],
|
|
});
|
|
|
|
if (string_pkey) {
|
|
expect(await getter()).toEqual({
|
|
str: ["abc", "def", "deff"],
|
|
int: [2, 1, 4],
|
|
float: [200.5, 100.5, 300.5],
|
|
});
|
|
} else {
|
|
expect(await getter()).toEqual({
|
|
str: ["def", "abc", "deff"],
|
|
int: [1, 2, 4],
|
|
float: [100.5, 200.5, 300.5],
|
|
});
|
|
}
|
|
},
|
|
);
|
|
|
|
await table.delete();
|
|
});
|
|
|
|
test.skip("Output consistent with filter, remove and add null", async () => {
|
|
// FIXME
|
|
const table = await perspective.table(SCHEMA, {
|
|
index: idx,
|
|
});
|
|
const data = {
|
|
str: [1, 2, 3, 4, 5, 6].map((x) => x.toString()),
|
|
int: [1, 2, 3, 4, 5, 6],
|
|
float: [1, 2, 3, 4, 5, 6].map((x) => x * 0.5),
|
|
};
|
|
|
|
const splice_idx = Math.floor(Math.random() * 6);
|
|
data.str.splice(splice_idx, 0, string_pkey ? null : "7");
|
|
data.int.splice(splice_idx, 0, string_pkey ? 7 : null);
|
|
data.float.splice(splice_idx, 0, 3.5);
|
|
|
|
await table.update(data);
|
|
|
|
await query(
|
|
table,
|
|
{
|
|
filter: [["float", "==", 3.5]],
|
|
},
|
|
async (getter) => {
|
|
await table.remove([null]);
|
|
const v = await table.view();
|
|
console.log(
|
|
"str?",
|
|
string_pkey,
|
|
await v.to_columns(),
|
|
);
|
|
await v.delete();
|
|
|
|
expect(await getter()).toEqual({});
|
|
|
|
await table.update({
|
|
str: [string_pkey ? null : "7"],
|
|
int: [string_pkey ? 7 : null],
|
|
float: [3.5],
|
|
});
|
|
|
|
expect(await getter()).toEqual({
|
|
str: [string_pkey ? null : "7"],
|
|
int: [string_pkey ? 7 : null],
|
|
float: [3.5],
|
|
});
|
|
},
|
|
);
|
|
|
|
await table.delete();
|
|
});
|
|
|
|
test.skip("Output consistent with filter, update null", async () => {
|
|
const table = await perspective.table(SCHEMA, {
|
|
index: idx,
|
|
});
|
|
const data = {
|
|
str: [1, 2, 3, 4, 5, 6].map((x) => x.toString()),
|
|
int: [1, 2, 3, 4, 5, 6],
|
|
float: [1, 2, 3, 4, 5, 6].map((x) => x * 0.5),
|
|
};
|
|
|
|
const splice_idx = Math.floor(Math.random() * 6);
|
|
data.str.splice(splice_idx, 0, string_pkey ? null : "7");
|
|
data.int.splice(splice_idx, 0, string_pkey ? 7 : null);
|
|
data.float.splice(splice_idx, 0, 3.5);
|
|
|
|
await table.update(data);
|
|
|
|
await query(table, {}, async (getter) => {
|
|
const expected = {
|
|
str: data.str.slice(),
|
|
int: data.int.slice(),
|
|
float: data.float.slice(),
|
|
};
|
|
|
|
expect(await getter()).toEqual(expected);
|
|
|
|
await table.update([
|
|
{
|
|
str: string_pkey ? null : "7",
|
|
int: string_pkey ? 7 : null,
|
|
float: 4.5,
|
|
},
|
|
]);
|
|
|
|
expected.float[splice_idx] = 4.5;
|
|
|
|
expect(await getter()).toEqual(expected);
|
|
});
|
|
|
|
await table.delete();
|
|
});
|
|
});
|
|
}
|
|
}
|
|
});
|