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 = (
);
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 = (
);
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"] }],
});
});
});