budibase/packages/client/tests/stateBinding.spec.js

147 lines
4.0 KiB
JavaScript

import {
setupBinding,
BB_STATE_BINDINGPATH,
BB_STATE_FALLBACK
} from "../src/state/stateBinding";
import { EVENT_TYPE_MEMBER_NAME } from "../src/state/eventHandlers";
import {writable} from "svelte/store";
import { isFunction } from "lodash/fp";
describe("setupBinding", () => {
it("should correctly create initials props, including fallback values", () => {
const {store, props, component} = testSetup();
const {initialProps} = testSetupBinding(store, props, component);
expect(initialProps.boundWithFallback).toBe("Bob");
expect(initialProps.boundNoFallback).toBeUndefined();
expect(initialProps.unbound).toBe("hello");
expect(isFunction(initialProps.eventBound)).toBeTruthy();
initialProps.eventBound();
});
it("should update component bound props when store is updated", () => {
const {component, store, props} = testSetup();
const {bind} = testSetupBinding(store, props, component);
bind(component);
store.update(s => {
s.FirstName = "Bobby";
s.LastName = "Thedog";
s.Customer = {
Name: "ACME inc",
Address: ""
};
s.addressToSet = "123 Main Street"
return s;
});
expect(component.props.boundWithFallback).toBe("Bobby");
expect(component.props.boundNoFallback).toBe("Thedog");
expect(component.props.multiPartBound).toBe("ACME inc");
});
it("should not update unbound props when store is updated", () => {
const {component, store, props} = testSetup();
const {bind} = testSetupBinding(store, props, component);
bind(component);
store.update(s => {
s.FirstName = "Bobby";
s.LastName = "Thedog";
s.Customer = {
Name: "ACME inc",
Address: ""
};
s.addressToSet = "123 Main Street"
return s;
});
expect(component.props.unbound).toBe("hello");
});
it("should update event handlers on state change", () => {
const {component, store, props} = testSetup();
const {bind} = testSetupBinding(store, props, component);
bind(component);
expect(component.props.boundToEventOutput).toBe("initial address");
component.props.eventBound();
expect(component.props.boundToEventOutput).toBe("event fallback address");
store.update(s => {
s.addressToSet = "123 Main Street"
return s;
});
component.props.eventBound();
expect(component.props.boundToEventOutput).toBe("123 Main Street");
});
});
const testSetupBinding = (store, props, component) => {
const setup = setupBinding(store, props);
component.props = setup.initialProps; // svelte does this for us in real life
return setup;
}
const testSetup = () => {
const c = {};
c.props = {};
c.$set = propsToSet => {
for(let pname in propsToSet)
c.props[pname] = propsToSet[pname];
}
const binding = (path, fallback) => {
const b = {};
b[BB_STATE_BINDINGPATH] = path;
b[BB_STATE_FALLBACK] = fallback;
return b;
};
const event = (handlerType, parameters) => {
const e = {};
e[EVENT_TYPE_MEMBER_NAME] = handlerType;
e.parameters = parameters;
return e;
}
const props = {
boundWithFallback : binding("FirstName", "Bob"),
boundNoFallback : binding("LastName"),
unbound: "hello",
multiPartBound: binding("Customer.Name", "ACME"),
boundToEventOutput: binding("Customer.Address", "initial address"),
eventBound: [
event("Set State", {
path: "Customer.Address",
value: binding("addressToSet", "event fallback address")
})
]
}
return {
component:c,
store:writable({}),
props
};
}