diff --git a/docs/unittest/ajax-simple-sub.json b/docs/unittest/ajax-simple-sub.json new file mode 100644 index 0000000..1cef475 --- /dev/null +++ b/docs/unittest/ajax-simple-sub.json @@ -0,0 +1 @@ +[{ "title": "SubNode 1" }, { "title": "SubNode 2" }] diff --git a/docs/unittest/ajax-simple.json b/docs/unittest/ajax-simple.json new file mode 100644 index 0000000..76f8934 --- /dev/null +++ b/docs/unittest/ajax-simple.json @@ -0,0 +1,8 @@ +[ + { + "title": "Node 1", + "expanded": true, + "children": [{ "title": "Node 1.1" }, { "title": "Node 1.2" }] + }, + { "title": "Node 2", "lazy": true } +] diff --git a/docs/unittest/test-core-fixture1.js b/docs/unittest/test-core-fixture1.js new file mode 100644 index 0000000..1c14dba --- /dev/null +++ b/docs/unittest/test-core-fixture1.js @@ -0,0 +1,37 @@ +/*! + * Wunderbaum - Unit Test + * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license. + * @VERSION, @DATE (https://github.com/mar10/wunderbaum) + */ + +const { test } = QUnit; +const Wunderbaum = mar10.Wunderbaum; + +const FIXTURE_1 = [ + { + title: "Node 1", + expanded: true, + children: [{ title: "Node 1.1" }, { title: "Node 1.2" }], + }, + { title: "Node 2", lazy: true }, +]; + +QUnit.module("Fixture-1 tests", (hooks) => { + let tree; + + hooks.beforeEach(() => { + tree = new Wunderbaum({ + element: "#tree", + source: FIXTURE_1, + }); + }); + hooks.afterEach(() => { + tree.destroy(); + tree = null; + }); + + test("fixture ok", (assert) => { + assert.expect(1); + assert.equal(tree.count(), 4); + }); +}); diff --git a/docs/unittest/test-core.js b/docs/unittest/test-core.js new file mode 100644 index 0000000..cf8b6fe --- /dev/null +++ b/docs/unittest/test-core.js @@ -0,0 +1,225 @@ +/*! + * Wunderbaum - Unit Test + * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license. + * @VERSION, @DATE (https://github.com/mar10/wunderbaum) + */ +/* global mar10, QUnit */ +/* eslint-env browser */ +/* eslint-disable no-console */ + +const { test } = QUnit; +const Wunderbaum = mar10.Wunderbaum; +const util = Wunderbaum.util; +const FIXTURE_1 = [ + { + title: "Node 1", + expanded: true, + children: [{ title: "Node 1.1" }, { title: "Node 1.2" }], + }, + { title: "Node 2", lazy: true }, +]; + +/* Setup */ +QUnit.testStart(function () { + window.sessionStorage.clear(); + window.localStorage.clear(); +}); + +/* Tear Down */ +QUnit.testDone(function () {}); + +QUnit.module("Utility tests", (hooks) => { + test("Static utility functions", (assert) => { + assert.expect(2); + + assert.equal(util.type([]), "array", "type([])"); + assert.equal(util.type({}), "object", "type({})"); + }); +}); + +QUnit.module("Static tests", (hooks) => { + test("Access static properties", (assert) => { + assert.expect(4); + + assert.true(Wunderbaum.version != null, "Statics defined"); + + assert.throws( + function () { + const _dummy = Wunderbaum(); + }, + /TypeError/, + "Fail if 'new' keyword is missing" + ); + assert.throws( + function () { + const _dummy = new Wunderbaum(); + }, + /Error: Invalid 'element' option: null/, + "Fail if option is missing" + ); + assert.throws( + function () { + const _dummy = new Wunderbaum({}); + }, + /Error: Invalid 'element' option: null/, + "Fail if 'element' option is missing" + ); + }); +}); + +QUnit.module("Instance tests", (hooks) => { + let tree = null; + + hooks.beforeEach(() => {}); + hooks.afterEach(() => { + tree.destroy(); + tree = null; + }); + + test("Initial event sequence (fetch)", (assert) => { + assert.expect(5); + assert.timeout(1000); // Timeout after 1 second + const done = assert.async(); + + tree = new Wunderbaum({ + element: "#tree", + source: "ajax-simple.json", + // source: FIXTURE_1, + receive: (e) => { + assert.step("receive"); + assert.equal( + e.response[0].title, + "Node 1", + "receive(e) passes e.response" + ); + }, + load: (e) => { + assert.step("load"); + }, + // render: (e) => { + // assert.step("render"); + // }, + init: (e) => { + assert.step("init"); + assert.verifySteps(["receive", "load", "init"], "Event sequence"); + done(); + }, + }); + }); + + test("Lazy load (fetch)", (assert) => { + assert.expect(8); + assert.timeout(1000); // Timeout after 1 second + const done = assert.async(); + let initComplete = false; + + tree = new Wunderbaum({ + element: "#tree", + source: "ajax-simple.json", + lazyLoad: (e) => { + if (initComplete) { + assert.step("lazyLoad"); + assert.equal( + e.node.title, + "Node 2", + "lazyLoad(e) passes parent node" + ); + return { url: "ajax-simple-sub.json" }; + } + }, + receive: (e) => { + if (initComplete) { + assert.step("receive"); + assert.equal( + e.response[0].title, + "SubNode 1", + "receive(e) passes e.response" + ); + } + }, + load: (e) => { + if (initComplete) { + assert.step("load"); + assert.verifySteps( + ["init", "lazyLoad", "receive", "load"], + "Event sequence" + ); + done(); + } + }, + // render: (e) => { + // assert.step("render"); + // }, + init: (e) => { + initComplete = true; + assert.step("init"); + const lazyNode = tree.findFirst("Node 2"); + assert.equal(lazyNode.title, "Node 2", "Find node by name"); + + // We need the markup, to issue a click event + // tree.updateViewport(true); + // assert.true(lazyNode.isRendered(), "Node is rendered"); + // lazyNode.colspan.click(); + lazyNode.setExpanded(); + }, + }); + }); + + test("applyCommand", (assert) => { + assert.expect(2); + assert.timeout(1000); // Timeout after 1 second + const done = assert.async(); + + tree = new Wunderbaum({ + element: "#tree", + source: FIXTURE_1, + init: (e) => { + const node1 = tree.findFirst("Node 1"); + const node2 = tree.findFirst("Node 2"); + assert.equal(node1.getPrevSibling(), null); + + node1.applyCommand("moveDown"); + assert.equal(node1.getPrevSibling(), node2); + // Avoid errors reported by ResizeObserver + done(); + }, + }); + }); + test("clones", (assert) => { + assert.expect(11); + assert.timeout(1000); // Timeout after 1 second + const done = assert.async(); + + tree = new Wunderbaum({ + element: "#tree", + source: [ + { title: "Node 1", key: "1", refKey: "n1" }, + { title: "Node 2", key: "2", refKey: "nX" }, + { title: "Node 3", key: "3", refKey: "nX" }, + ], + init: (e) => { + const n1 = tree.findKey("1"); + const n2 = tree.findKey("2"); + const n3 = tree.findKey("3"); + + // console.warn(`tree.findByRefKey('nX'): >${tree.findByRefKey("nX")}<`); + + assert.deepEqual(tree.findByRefKey("x"), []); + assert.deepEqual(tree.findByRefKey("n1"), [n1]); + assert.equal(tree.findByRefKey("nX").length, 2); + + assert.false(n1.isClone()); + assert.true(n2.isClone()); + assert.true(n3.isClone()); + + assert.deepEqual(n1.getCloneList(), []); + assert.deepEqual(n1.getCloneList(true), [n1]); + assert.equal(n2.getCloneList().length, 1); + assert.equal(n2.getCloneList(false).length, 1); + assert.equal(n2.getCloneList(true).length, 2); + + done(); + }, + }); + }); +}); diff --git a/docs/unittest/test-dev.html b/docs/unittest/test-dev.html new file mode 100644 index 0000000..179f4ef --- /dev/null +++ b/docs/unittest/test-dev.html @@ -0,0 +1,28 @@ + + + + + Test Suite (DEV) | Wunderbaum + + + + + + + + + + + + + + + + +
+
+ +
+
+ + diff --git a/docs/unittest/test-dist.html b/docs/unittest/test-dist.html new file mode 100644 index 0000000..943173e --- /dev/null +++ b/docs/unittest/test-dist.html @@ -0,0 +1,23 @@ + + + + + Test Suite (DIST) | Wunderbaum + + + + + + + + + + + +
+
+ +
+
+ + diff --git a/unittest/ajax-simple-sub.json b/unittest/ajax-simple-sub.json new file mode 100644 index 0000000..1cef475 --- /dev/null +++ b/unittest/ajax-simple-sub.json @@ -0,0 +1 @@ +[{ "title": "SubNode 1" }, { "title": "SubNode 2" }] diff --git a/unittest/ajax-simple.json b/unittest/ajax-simple.json new file mode 100644 index 0000000..76f8934 --- /dev/null +++ b/unittest/ajax-simple.json @@ -0,0 +1,8 @@ +[ + { + "title": "Node 1", + "expanded": true, + "children": [{ "title": "Node 1.1" }, { "title": "Node 1.2" }] + }, + { "title": "Node 2", "lazy": true } +] diff --git a/unittest/test-core-fixture1.js b/unittest/test-core-fixture1.js new file mode 100644 index 0000000..1c14dba --- /dev/null +++ b/unittest/test-core-fixture1.js @@ -0,0 +1,37 @@ +/*! + * Wunderbaum - Unit Test + * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license. + * @VERSION, @DATE (https://github.com/mar10/wunderbaum) + */ + +const { test } = QUnit; +const Wunderbaum = mar10.Wunderbaum; + +const FIXTURE_1 = [ + { + title: "Node 1", + expanded: true, + children: [{ title: "Node 1.1" }, { title: "Node 1.2" }], + }, + { title: "Node 2", lazy: true }, +]; + +QUnit.module("Fixture-1 tests", (hooks) => { + let tree; + + hooks.beforeEach(() => { + tree = new Wunderbaum({ + element: "#tree", + source: FIXTURE_1, + }); + }); + hooks.afterEach(() => { + tree.destroy(); + tree = null; + }); + + test("fixture ok", (assert) => { + assert.expect(1); + assert.equal(tree.count(), 4); + }); +}); diff --git a/unittest/test-core.js b/unittest/test-core.js new file mode 100644 index 0000000..cf8b6fe --- /dev/null +++ b/unittest/test-core.js @@ -0,0 +1,225 @@ +/*! + * Wunderbaum - Unit Test + * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license. + * @VERSION, @DATE (https://github.com/mar10/wunderbaum) + */ +/* global mar10, QUnit */ +/* eslint-env browser */ +/* eslint-disable no-console */ + +const { test } = QUnit; +const Wunderbaum = mar10.Wunderbaum; +const util = Wunderbaum.util; +const FIXTURE_1 = [ + { + title: "Node 1", + expanded: true, + children: [{ title: "Node 1.1" }, { title: "Node 1.2" }], + }, + { title: "Node 2", lazy: true }, +]; + +/* Setup */ +QUnit.testStart(function () { + window.sessionStorage.clear(); + window.localStorage.clear(); +}); + +/* Tear Down */ +QUnit.testDone(function () {}); + +QUnit.module("Utility tests", (hooks) => { + test("Static utility functions", (assert) => { + assert.expect(2); + + assert.equal(util.type([]), "array", "type([])"); + assert.equal(util.type({}), "object", "type({})"); + }); +}); + +QUnit.module("Static tests", (hooks) => { + test("Access static properties", (assert) => { + assert.expect(4); + + assert.true(Wunderbaum.version != null, "Statics defined"); + + assert.throws( + function () { + const _dummy = Wunderbaum(); + }, + /TypeError/, + "Fail if 'new' keyword is missing" + ); + assert.throws( + function () { + const _dummy = new Wunderbaum(); + }, + /Error: Invalid 'element' option: null/, + "Fail if option is missing" + ); + assert.throws( + function () { + const _dummy = new Wunderbaum({}); + }, + /Error: Invalid 'element' option: null/, + "Fail if 'element' option is missing" + ); + }); +}); + +QUnit.module("Instance tests", (hooks) => { + let tree = null; + + hooks.beforeEach(() => {}); + hooks.afterEach(() => { + tree.destroy(); + tree = null; + }); + + test("Initial event sequence (fetch)", (assert) => { + assert.expect(5); + assert.timeout(1000); // Timeout after 1 second + const done = assert.async(); + + tree = new Wunderbaum({ + element: "#tree", + source: "ajax-simple.json", + // source: FIXTURE_1, + receive: (e) => { + assert.step("receive"); + assert.equal( + e.response[0].title, + "Node 1", + "receive(e) passes e.response" + ); + }, + load: (e) => { + assert.step("load"); + }, + // render: (e) => { + // assert.step("render"); + // }, + init: (e) => { + assert.step("init"); + assert.verifySteps(["receive", "load", "init"], "Event sequence"); + done(); + }, + }); + }); + + test("Lazy load (fetch)", (assert) => { + assert.expect(8); + assert.timeout(1000); // Timeout after 1 second + const done = assert.async(); + let initComplete = false; + + tree = new Wunderbaum({ + element: "#tree", + source: "ajax-simple.json", + lazyLoad: (e) => { + if (initComplete) { + assert.step("lazyLoad"); + assert.equal( + e.node.title, + "Node 2", + "lazyLoad(e) passes parent node" + ); + return { url: "ajax-simple-sub.json" }; + } + }, + receive: (e) => { + if (initComplete) { + assert.step("receive"); + assert.equal( + e.response[0].title, + "SubNode 1", + "receive(e) passes e.response" + ); + } + }, + load: (e) => { + if (initComplete) { + assert.step("load"); + assert.verifySteps( + ["init", "lazyLoad", "receive", "load"], + "Event sequence" + ); + done(); + } + }, + // render: (e) => { + // assert.step("render"); + // }, + init: (e) => { + initComplete = true; + assert.step("init"); + const lazyNode = tree.findFirst("Node 2"); + assert.equal(lazyNode.title, "Node 2", "Find node by name"); + + // We need the markup, to issue a click event + // tree.updateViewport(true); + // assert.true(lazyNode.isRendered(), "Node is rendered"); + // lazyNode.colspan.click(); + lazyNode.setExpanded(); + }, + }); + }); + + test("applyCommand", (assert) => { + assert.expect(2); + assert.timeout(1000); // Timeout after 1 second + const done = assert.async(); + + tree = new Wunderbaum({ + element: "#tree", + source: FIXTURE_1, + init: (e) => { + const node1 = tree.findFirst("Node 1"); + const node2 = tree.findFirst("Node 2"); + assert.equal(node1.getPrevSibling(), null); + + node1.applyCommand("moveDown"); + assert.equal(node1.getPrevSibling(), node2); + // Avoid errors reported by ResizeObserver + done(); + }, + }); + }); + test("clones", (assert) => { + assert.expect(11); + assert.timeout(1000); // Timeout after 1 second + const done = assert.async(); + + tree = new Wunderbaum({ + element: "#tree", + source: [ + { title: "Node 1", key: "1", refKey: "n1" }, + { title: "Node 2", key: "2", refKey: "nX" }, + { title: "Node 3", key: "3", refKey: "nX" }, + ], + init: (e) => { + const n1 = tree.findKey("1"); + const n2 = tree.findKey("2"); + const n3 = tree.findKey("3"); + + // console.warn(`tree.findByRefKey('nX'): >${tree.findByRefKey("nX")}<`); + + assert.deepEqual(tree.findByRefKey("x"), []); + assert.deepEqual(tree.findByRefKey("n1"), [n1]); + assert.equal(tree.findByRefKey("nX").length, 2); + + assert.false(n1.isClone()); + assert.true(n2.isClone()); + assert.true(n3.isClone()); + + assert.deepEqual(n1.getCloneList(), []); + assert.deepEqual(n1.getCloneList(true), [n1]); + assert.equal(n2.getCloneList().length, 1); + assert.equal(n2.getCloneList(false).length, 1); + assert.equal(n2.getCloneList(true).length, 2); + + done(); + }, + }); + }); +}); diff --git a/unittest/test-dev.html b/unittest/test-dev.html new file mode 100644 index 0000000..179f4ef --- /dev/null +++ b/unittest/test-dev.html @@ -0,0 +1,28 @@ + + + + + Test Suite (DEV) | Wunderbaum + + + + + + + + + + + + + + + + +
+
+ +
+
+ + diff --git a/unittest/test-dist.html b/unittest/test-dist.html new file mode 100644 index 0000000..943173e --- /dev/null +++ b/unittest/test-dist.html @@ -0,0 +1,23 @@ + + + + + Test Suite (DIST) | Wunderbaum + + + + + + + + + + + +
+
+ +
+
+ +