chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
||||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
||||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
||||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
||||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
||||
// ┃ 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-dev/client";
|
||||
|
||||
let server;
|
||||
let port;
|
||||
|
||||
test.describe("WebSocketManager", function () {
|
||||
test.beforeEach(() => {
|
||||
server = new perspective.WebSocketServer({ port: 0 });
|
||||
port = server._server.address().port;
|
||||
});
|
||||
|
||||
test.afterEach(() => {
|
||||
server.close();
|
||||
});
|
||||
|
||||
test("sends initial data client on subscribe", async () => {
|
||||
const data = [{ x: 1 }];
|
||||
const table = await perspective.table(data, { name: "test" });
|
||||
const client = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_table = await client.open_table("test");
|
||||
const client_view = await client_table.view();
|
||||
const client_data = await client_view.to_json();
|
||||
expect(client_data).toEqual(data);
|
||||
await client.terminate();
|
||||
|
||||
// // TODO Can't await delete here because `terminate()` doesn't
|
||||
// // guarantee server-side cleanup happens immediately. So this test
|
||||
// // leaks a small `Table` sometimes, as do several others in this
|
||||
// // suite.
|
||||
|
||||
await new Promise((x) => setTimeout(x, 10));
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("Throws an exception when the server is detached", async () => {
|
||||
const data = [{ x: 1 }];
|
||||
const _table = await perspective.table(data, { name: "test2" });
|
||||
const client = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_table = await client.open_table("test2");
|
||||
const client_view = await client_table.view();
|
||||
await server.close();
|
||||
const client_data = client_view.to_json();
|
||||
await expect(client_data).rejects.toThrow();
|
||||
});
|
||||
|
||||
test("passes back errors from server", async () => {
|
||||
expect.assertions(2);
|
||||
const data = [{ x: 1 }];
|
||||
const table = await perspective.table(data, { name: "test" });
|
||||
const client = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_table = await client.open_table("test");
|
||||
client_table.view({ columns: ["z"] }).catch((error) => {
|
||||
expect(error.message).toContain(
|
||||
"Abort(): Invalid column 'z' found in View columns.\n",
|
||||
);
|
||||
});
|
||||
|
||||
const client_view = await client_table.view();
|
||||
const client_data = await client_view.to_json();
|
||||
expect(client_data).toEqual(data);
|
||||
await client.terminate();
|
||||
|
||||
await new Promise((x) => setTimeout(x, 10));
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("sends initial data multiple client on subscribe", async () => {
|
||||
const data = [{ x: 1 }];
|
||||
const table = await perspective.table(data, { name: "test" });
|
||||
const client_1 = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_2 = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_1_table = await client_1.open_table("test");
|
||||
const client_2_table = await client_2.open_table("test");
|
||||
const client_1_view = await client_1_table.view();
|
||||
const client_2_view = await client_2_table.view();
|
||||
const client_1_data = await client_1_view.to_json();
|
||||
const client_2_data = await client_2_view.to_json();
|
||||
await client_1.terminate();
|
||||
await client_2.terminate();
|
||||
expect(client_1_data).toEqual(data);
|
||||
expect(client_2_data).toEqual(data);
|
||||
|
||||
await new Promise((x) => setTimeout(x, 10));
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("passes back errors with multiple client on subscribe", async () => {
|
||||
expect.assertions(3);
|
||||
const data = [{ x: 1 }];
|
||||
const table = await perspective.table(data, { name: "test" });
|
||||
const client_1 = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_2 = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_1_table = await client_1.open_table("test");
|
||||
const client_2_table = await client_2.open_table("test");
|
||||
client_1_table.view({ columns: ["z"] }).catch((error) => {
|
||||
expect(error.message).toContain(
|
||||
"Abort(): Invalid column 'z' found in View columns.\n",
|
||||
);
|
||||
});
|
||||
|
||||
const client_1_view = await client_1_table.view();
|
||||
const client_2_view = await client_2_table.view();
|
||||
const client_1_data = await client_1_view.to_json();
|
||||
const client_2_data = await client_2_view.to_json();
|
||||
await client_1.terminate();
|
||||
await client_2.terminate();
|
||||
expect(client_1_data).toEqual(data);
|
||||
expect(client_2_data).toEqual(data);
|
||||
|
||||
await new Promise((x) => setTimeout(x, 10));
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("sends updates to client on subscribe", async () => {
|
||||
const data = [{ x: 1 }];
|
||||
const table = await perspective.table(data, { name: "test" });
|
||||
const client = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_table = await client.open_table("test");
|
||||
const client_view = await client_table.view();
|
||||
let done;
|
||||
let result = new Promise((x) => {
|
||||
done = x;
|
||||
});
|
||||
|
||||
const on_update = () => {
|
||||
client_view.to_json().then(async (updated_data) => {
|
||||
await client_view.delete();
|
||||
await table.delete();
|
||||
expect(updated_data).toEqual([{ x: 1 }, { x: 2 }]);
|
||||
await client.terminate();
|
||||
setTimeout(done);
|
||||
});
|
||||
};
|
||||
|
||||
client_view.on_update(on_update);
|
||||
client_view.to_json().then((client_data) => {
|
||||
expect(client_data).toEqual(data);
|
||||
return table.update([{ x: 2 }]);
|
||||
});
|
||||
|
||||
await result;
|
||||
});
|
||||
|
||||
test("Calls `update` and sends arraybuffers using `binary_length`", async () => {
|
||||
const data = [{ x: 1 }];
|
||||
const table = await perspective.table(data, { name: "test" });
|
||||
const view = await table.view();
|
||||
const arrow = await view.to_arrow();
|
||||
const client = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_table = await client.open_table("test");
|
||||
await client_table.update(arrow);
|
||||
const client_view = await client_table.view();
|
||||
const client_data = await client_view.to_json();
|
||||
expect(client_data).toEqual([{ x: 1 }, { x: 1 }]);
|
||||
await client_view.delete();
|
||||
await client.terminate();
|
||||
await view.delete();
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("Calls `update` and sends `Uint8Array` using `binary_length` multiple times", async () => {
|
||||
const data = [{ x: 1 }];
|
||||
const table = await perspective.table(data, { name: "test" });
|
||||
const view = await table.view();
|
||||
const arrow = await view.to_arrow();
|
||||
const client = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_table = await client.open_table("test");
|
||||
await client_table.update(arrow);
|
||||
await client_table.update(arrow);
|
||||
await client_table.update(arrow);
|
||||
const client_view = await client_table.view();
|
||||
const client_data = await client_view.to_json();
|
||||
expect(client_data).toEqual([{ x: 1 }, { x: 1 }, { x: 1 }, { x: 1 }]);
|
||||
await client_view.delete();
|
||||
await view.delete();
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("Calls `update` and sends `Uint8Array` using `on_update`", async () => {
|
||||
const data = [{ x: 1 }];
|
||||
const table = await perspective.table(data, { name: "test" });
|
||||
const view = await table.view();
|
||||
const arrow = await view.to_arrow();
|
||||
let update_port;
|
||||
let done;
|
||||
let result = new Promise((x) => {
|
||||
done = x;
|
||||
});
|
||||
|
||||
const updater = async (updated) => {
|
||||
expect(updated.port_id).toEqual(update_port);
|
||||
expect(updated.delta instanceof Uint8Array).toEqual(true);
|
||||
expect(updated.delta.byteLength).toBeGreaterThan(0);
|
||||
await view.delete();
|
||||
await table.delete();
|
||||
await client.terminate();
|
||||
|
||||
done();
|
||||
};
|
||||
|
||||
view.on_update(updater, { mode: "row" });
|
||||
const client = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const client_table = await client.open_table("test");
|
||||
for (let i = 0; i < 5; i++) {
|
||||
// take up some ports on the remote table
|
||||
await client_table.make_port();
|
||||
}
|
||||
|
||||
update_port = await client_table.make_port();
|
||||
await client_table.update(arrow, { port_id: update_port });
|
||||
await result;
|
||||
});
|
||||
|
||||
// TODO ping loop is not yet implemented
|
||||
test.skip("disables ping loop on disconnect", async () => {
|
||||
const data = [{ x: 1 }];
|
||||
const table = await perspective.table(data, { name: "test" });
|
||||
const client = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const _client_table = await client.open_table("test");
|
||||
expect(await _client_table.size()).toEqual(1);
|
||||
expect(client._ping_loop).toBeDefined();
|
||||
await server.close();
|
||||
expect(client._ping_loop).toBeUndefined();
|
||||
await table.delete();
|
||||
});
|
||||
|
||||
test("Can get hosted table names", async () => {
|
||||
const data = [{ x: 1 }];
|
||||
const host_table_name = "test";
|
||||
const table = await perspective.table(data, { name: host_table_name });
|
||||
const client = await perspective.websocket(`ws://localhost:${port}`);
|
||||
const table_names = await client.get_hosted_table_names();
|
||||
expect(table_names).toContain(host_table_name);
|
||||
await client.terminate();
|
||||
await table.delete();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user