| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- import { assert } from "chai";
- import { init, h, thunk, VNode } from "../../src/index";
- const patch = init([]);
- describe("thunk", function () {
- let elm: any, vnode0: any;
- beforeEach(function () {
- elm = vnode0 = document.createElement("div");
- });
- it("returns vnode with data and render function", function () {
- function numberInSpan(n: number) {
- return h("span", `Number is ${n}`);
- }
- const vnode = thunk("span", "num", numberInSpan, [22]);
- assert.deepEqual(vnode.sel, "span");
- assert.deepEqual(vnode.data.key, "num");
- assert.deepEqual(vnode.data.args, [22]);
- });
- it("calls render function once on data change", function () {
- let called = 0;
- function numberInSpan(n: number) {
- called++;
- return h("span", { key: "num" }, `Number is ${n}`);
- }
- const vnode1 = h("div", [thunk("span", "num", numberInSpan, [1])]);
- const vnode2 = h("div", [thunk("span", "num", numberInSpan, [2])]);
- patch(vnode0, vnode1);
- assert.strictEqual(called, 1);
- patch(vnode1, vnode2);
- assert.strictEqual(called, 2);
- });
- it("does not call render function on data unchanged", function () {
- let called = 0;
- function numberInSpan(n: number) {
- called++;
- return h("span", { key: "num" }, `Number is ${n}`);
- }
- const vnode1 = h("div", [thunk("span", "num", numberInSpan, [1])]);
- const vnode2 = h("div", [thunk("span", "num", numberInSpan, [1])]);
- patch(vnode0, vnode1);
- assert.strictEqual(called, 1);
- patch(vnode1, vnode2);
- assert.strictEqual(called, 1);
- });
- it("calls render function once on data-length change", function () {
- let called = 0;
- function numberInSpan(n: number) {
- called++;
- return h("span", { key: "num" }, `Number is ${n}`);
- }
- const vnode1 = h("div", [thunk("span", "num", numberInSpan, [1])]);
- const vnode2 = h("div", [thunk("span", "num", numberInSpan, [1, 2])]);
- patch(vnode0, vnode1);
- assert.strictEqual(called, 1);
- patch(vnode1, vnode2);
- assert.strictEqual(called, 2);
- });
- it("calls render function once on function change", function () {
- let called = 0;
- function numberInSpan(n: number) {
- called++;
- return h("span", { key: "num" }, `Number is ${n}`);
- }
- function numberInSpan2(n: number) {
- called++;
- return h("span", { key: "num" }, `Number really is ${n}`);
- }
- const vnode1 = h("div", [thunk("span", "num", numberInSpan, [1])]);
- const vnode2 = h("div", [thunk("span", "num", numberInSpan2, [1])]);
- patch(vnode0, vnode1);
- assert.strictEqual(called, 1);
- patch(vnode1, vnode2);
- assert.strictEqual(called, 2);
- });
- it("renders correctly", function () {
- let called = 0;
- function numberInSpan(n: number) {
- called++;
- return h("span", { key: "num" }, `Number is ${n}`);
- }
- const vnode1 = h("div", [thunk("span", "num", numberInSpan, [1])]);
- const vnode2 = h("div", [thunk("span", "num", numberInSpan, [1])]);
- const vnode3 = h("div", [thunk("span", "num", numberInSpan, [2])]);
- elm = patch(vnode0, vnode1).elm;
- assert.strictEqual(elm.firstChild.tagName.toLowerCase(), "span");
- assert.strictEqual(elm.firstChild.innerHTML, "Number is 1");
- elm = patch(vnode1, vnode2).elm;
- assert.strictEqual(elm.firstChild.tagName.toLowerCase(), "span");
- assert.strictEqual(elm.firstChild.innerHTML, "Number is 1");
- elm = patch(vnode2, vnode3).elm;
- assert.strictEqual(elm.firstChild.tagName.toLowerCase(), "span");
- assert.strictEqual(elm.firstChild.innerHTML, "Number is 2");
- assert.strictEqual(called, 2);
- });
- it("supports leaving out the `key` argument", function () {
- function vnodeFn(s: string) {
- return h("span.number", "Hello " + s);
- }
- const vnode1 = thunk("span.number", vnodeFn, ["World!"]);
- elm = patch(vnode0, vnode1).elm;
- assert.strictEqual(elm.innerText, "Hello World!");
- });
- it("renders correctly when root", function () {
- let called = 0;
- function numberInSpan(n: number) {
- called++;
- return h("span", { key: "num" }, `Number is ${n}`);
- }
- const vnode1 = thunk("span", "num", numberInSpan, [1]);
- const vnode2 = thunk("span", "num", numberInSpan, [1]);
- const vnode3 = thunk("span", "num", numberInSpan, [2]);
- elm = patch(vnode0, vnode1).elm;
- assert.strictEqual(elm.tagName.toLowerCase(), "span");
- assert.strictEqual(elm.innerHTML, "Number is 1");
- elm = patch(vnode1, vnode2).elm;
- assert.strictEqual(elm.tagName.toLowerCase(), "span");
- assert.strictEqual(elm.innerHTML, "Number is 1");
- elm = patch(vnode2, vnode3).elm;
- assert.strictEqual(elm.tagName.toLowerCase(), "span");
- assert.strictEqual(elm.innerHTML, "Number is 2");
- assert.strictEqual(called, 2);
- });
- it("can be replaced and removed", function () {
- function numberInSpan(n: number) {
- return h("span", { key: "num" }, `Number is ${n}`);
- }
- function oddEven(n: number): VNode {
- const prefix = n % 2 === 0 ? "Even" : "Odd";
- return h("div", { key: oddEven as any }, `${prefix}: ${n}`);
- }
- const vnode1 = h("div", [thunk("span", "num", numberInSpan, [1])]);
- const vnode2 = h("div", [thunk("div", "oddEven", oddEven, [4])]);
- elm = patch(vnode0, vnode1).elm;
- assert.strictEqual(elm.firstChild.tagName.toLowerCase(), "span");
- assert.strictEqual(elm.firstChild.innerHTML, "Number is 1");
- elm = patch(vnode1, vnode2).elm;
- assert.strictEqual(elm.firstChild.tagName.toLowerCase(), "div");
- assert.strictEqual(elm.firstChild.innerHTML, "Even: 4");
- });
- it("can be replaced and removed when root", function () {
- function numberInSpan(n: number) {
- return h("span", { key: "num" }, `Number is ${n}`);
- }
- function oddEven(n: number): VNode {
- const prefix = n % 2 === 0 ? "Even" : "Odd";
- return h("div", { key: oddEven as any }, `${prefix}: ${n}`);
- }
- const vnode1 = thunk("span", "num", numberInSpan, [1]);
- const vnode2 = thunk("div", "oddEven", oddEven, [4]);
- elm = patch(vnode0, vnode1).elm;
- assert.strictEqual(elm.tagName.toLowerCase(), "span");
- assert.strictEqual(elm.innerHTML, "Number is 1");
- elm = patch(vnode1, vnode2).elm;
- assert.strictEqual(elm.tagName.toLowerCase(), "div");
- assert.strictEqual(elm.innerHTML, "Even: 4");
- });
- it("invokes destroy hook on thunks", function () {
- let called = 0;
- function destroyHook() {
- called++;
- }
- function numberInSpan(n: number) {
- return h(
- "span",
- { key: "num", hook: { destroy: destroyHook } },
- `Number is ${n}`
- );
- }
- const vnode1 = h("div", [
- h("div", "Foo"),
- thunk("span", "num", numberInSpan, [1]),
- h("div", "Foo"),
- ]);
- const vnode2 = h("div", [h("div", "Foo"), h("div", "Foo")]);
- patch(vnode0, vnode1);
- patch(vnode1, vnode2);
- assert.strictEqual(called, 1);
- });
- it("invokes remove hook on thunks", function () {
- let called = 0;
- function hook() {
- called++;
- }
- function numberInSpan(n: number) {
- return h(
- "span",
- { key: "num", hook: { remove: hook } },
- `Number is ${n}`
- );
- }
- const vnode1 = h("div", [
- h("div", "Foo"),
- thunk("span", "num", numberInSpan, [1]),
- h("div", "Foo"),
- ]);
- const vnode2 = h("div", [h("div", "Foo"), h("div", "Foo")]);
- patch(vnode0, vnode1);
- patch(vnode1, vnode2);
- assert.strictEqual(called, 1);
- });
- });
|