import { Restate } from "./Restate"; import { Store } from "../data/Store"; import { createTestRenderer, act } from "../util/test/createTestRenderer"; import assert from "assert"; import { Controller } from "./Controller"; import { bind } from "./bind"; import { FirstVisibleChildLayout } from "./layout/FirstVisibleChildLayout"; describe("Restate", () => { it("provides a blank slate", async () => { let widget = (
); let store = new Store({ data: { value: "bad", value2: "also bad", }, }); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert.deepEqual(tree, { type: "div", props: {}, children: [ { type: "span", props: {}, children: ["good"], }, { type: "span", props: {}, children: null, }, ], }); }); it("wires declared data", async () => { let widget = (
); let changed = false; let store = new Store(); store.subscribe(() => { //console.log(store.getData()); changed = true; }); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert.equal(store.get("person.name"), "Sasa"); assert(store.get("person.nickname") === undefined); assert(changed); }); it("causes a global update if internal data changes", async () => { let controller: TestController | undefined; class TestController extends Controller { onInit() { controller = this; } setNickname(nname: string) { this.store.set("nickname", nname); } } let widget = (
); let changed = false; let store = new Store(); store.subscribe(() => { changed = true; }); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert.deepEqual(tree, { type: "div", props: {}, children: [ { type: "div", props: {}, children: null, }, ], }); await act(async () => { controller!.setNickname("Sale"); }); let tree2 = component.toJSON(); assert.deepEqual(tree2, { type: "div", props: {}, children: [ { type: "div", props: {}, children: ["Sale"], }, ], }); }); it("doesn't notify parent if not necessary in detached mode", async () => { class TestController extends Controller { onInit() { this.store.init("nickname", "Sale"); } } let widget = (
); let changed = false; let store = new Store(); store.subscribe(() => { changed = true; }); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert(!changed); }); it("shared state can be used across components inside and outside Restate", async () => { let widget = (
); let changed = false; let store = new Store(); store.subscribe(() => { changed = true; //console.log(store.getData()); }); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert.deepEqual(store.getData(), { person: { firstName: "John", lastName: "Doe", address: "Unknown", gender: "Male", }, }); }); it("updates if shared state is changed from outside", async () => { for (const detached of [true, false]) { let widget = (
); let store = new Store(); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert.deepEqual(tree, { type: "div", props: {}, children: [ { type: "div", props: {}, children: ["John"], }, { type: "div", props: {}, children: ["John"], }, ], }); await act(async () => { store.set("person.firstName", "Jack"); }); tree = component.toJSON(); assert.deepEqual(tree, { type: "div", props: {}, children: [ { type: "div", props: {}, children: ["Jack"], }, { type: "div", props: {}, children: ["Jack"], }, ], }); } }); it("allows field initialization in data declaration", async () => { for (const detached of [true, false]) { let widget = (
); let store = new Store(); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert.deepEqual(tree, { type: "div", props: {}, children: [ { type: "div", props: {}, children: ["Cx"], }, ], }); } }); it("updates if internal data changes", async () => { class TestController extends Controller { onInit() { this.store.init("nickname", "Sale"); } } let widget = (
); let changed = false; let store = new Store(); store.subscribe(() => { changed = true; }); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert.deepEqual(tree, { type: "div", props: {}, children: [ { type: "div", props: {}, children: ["Sale"], }, ], }); }); it("works with FirstVisibleChildLayout", async () => { let widget = (
First
Second
); let store = new Store(); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert.deepEqual(tree, { type: "div", props: {}, children: [{ type: "div", props: {}, children: ["First"] }], }); }); it("is transparent to FirstVisibleChildLayout", async () => { let widget = (
First
Second
); let store = new Store(); const component = await createTestRenderer(store, widget); let tree = component.toJSON(); assert.deepEqual(tree, { type: "div", props: {}, children: [{ type: "div", props: {}, children: ["Second"] }], }); }); });