jqtree 1.7.5 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +13 -3
- package/.github/workflows/ci.yml +6 -6
- package/.github/workflows/codeql-analysis.yml +4 -4
- package/.github/workflows/size.yml +3 -3
- package/.github/workflows/static.yml +1 -1
- package/bower.json +1 -1
- package/config/babel.config.json +1 -1
- package/config/jest.config.js +4 -0
- package/config/jest.polyfills.js +14 -0
- package/config/production +2 -0
- package/devserver/devserver_scroll.js +8 -0
- package/devserver/test_index.html +9 -0
- package/devserver/test_scroll.html +28 -0
- package/devserver/test_scroll_container.html +39 -0
- package/docs/.ruby-version +1 -1
- package/docs/_config.yml +1 -1
- package/docs/_entries/general/changelog.md +11 -0
- package/docs/_entries/multiple_selection/get-selected-nodes.md +1 -1
- package/docs/_entries/node/getnextnode.md +3 -6
- package/docs/_entries/node/getnextsibling.md +1 -1
- package/docs/_entries/node/getnextvisiblenode.md +8 -5
- package/docs/_entries/node/getpreviousnode.md +12 -0
- package/docs/_entries/node/getprevioussibling.md +1 -1
- package/docs/_entries/node/getpreviousvisiblenode.md +6 -5
- package/package.json +35 -29
- package/src/dataLoader.ts +57 -34
- package/src/dragAndDropHandler/dragElement.ts +54 -0
- package/src/dragAndDropHandler/generateHitAreas.ts +176 -0
- package/src/dragAndDropHandler/index.ts +454 -0
- package/src/dragAndDropHandler/iterateVisibleNodes.ts +91 -0
- package/src/dragAndDropHandler/types.ts +13 -0
- package/src/elementsRenderer.ts +75 -40
- package/src/jqtreeMethodTypes.ts +40 -0
- package/src/jqtreeOptions.ts +43 -25
- package/src/keyHandler.ts +59 -30
- package/src/mouseHandler.ts +385 -0
- package/src/mouseUtils.ts +23 -0
- package/src/node.ts +1 -29
- package/src/nodeElement/borderDropHint.ts +32 -0
- package/src/nodeElement/folderElement.ts +133 -0
- package/src/nodeElement/ghostDropHint.ts +69 -0
- package/src/nodeElement/index.ts +102 -0
- package/src/playwright/coverage.ts +4 -7
- package/src/playwright/playwright.test.ts +150 -53
- package/src/playwright/testUtils.ts +28 -5
- package/src/position.ts +28 -0
- package/src/saveStateHandler.ts +75 -26
- package/src/scrollHandler/containerScrollParent.ts +13 -23
- package/src/scrollHandler/createScrollParent.ts +22 -22
- package/src/scrollHandler/documentScrollParent.ts +16 -13
- package/src/scrollHandler.ts +13 -15
- package/src/selectNodeHandler.ts +10 -16
- package/src/test/jqTree/events.test.ts +97 -30
- package/src/test/jqTree/keyboard.test.ts +18 -23
- package/src/test/jqTree/loadOnDemand.test.ts +22 -15
- package/src/test/jqTree/methods.test.ts +40 -14
- package/src/test/jqTree/mouse.test.ts +82 -0
- package/src/test/jqTree/options.test.ts +24 -12
- package/src/test/node.test.ts +3 -2
- package/src/test/{nodeUtil.test.ts → position.test.ts} +1 -1
- package/src/tree.jquery.ts +314 -208
- package/src/util.ts +12 -0
- package/src/version.ts +1 -1
- package/tree.jquery.debug.js +2594 -3419
- package/tree.jquery.debug.js.map +1 -1
- package/tree.jquery.js +3 -3
- package/tree.jquery.js.map +1 -1
- package/tsconfig.json +5 -3
- package/docs/_entries/functions/get-selected-nodes.md +0 -10
- package/lib/dataLoader.js +0 -123
- package/lib/dragAndDropHandler.js +0 -588
- package/lib/elementsRenderer.js +0 -267
- package/lib/jqtreeOptions.js +0 -1
- package/lib/keyHandler.js +0 -111
- package/lib/mouse.widget.js +0 -255
- package/lib/node.js +0 -708
- package/lib/nodeElement.js +0 -274
- package/lib/nodeUtils.js +0 -10
- package/lib/playwright/coverage.js +0 -99
- package/lib/playwright/playwright.test.js +0 -606
- package/lib/playwright/testUtils.js +0 -210
- package/lib/saveStateHandler.js +0 -277
- package/lib/scrollHandler/containerScrollParent.js +0 -160
- package/lib/scrollHandler/createScrollParent.js +0 -57
- package/lib/scrollHandler/documentScrollParent.js +0 -169
- package/lib/scrollHandler/scrollParent.js +0 -58
- package/lib/scrollHandler/types.js +0 -1
- package/lib/scrollHandler.js +0 -71
- package/lib/selectNodeHandler.js +0 -128
- package/lib/simple.widget.js +0 -158
- package/lib/test/global.d.js +0 -3
- package/lib/test/jqTree/accessibility.test.js +0 -37
- package/lib/test/jqTree/create.test.js +0 -48
- package/lib/test/jqTree/events.test.js +0 -210
- package/lib/test/jqTree/keyboard.test.js +0 -225
- package/lib/test/jqTree/loadOnDemand.test.js +0 -218
- package/lib/test/jqTree/methods.test.js +0 -1348
- package/lib/test/jqTree/options.test.js +0 -548
- package/lib/test/jqTree/scrollHandler/containerScrollParent.test.js +0 -94
- package/lib/test/node.test.js +0 -1202
- package/lib/test/nodeUtil.test.js +0 -27
- package/lib/test/nodeUtils.test.js +0 -20
- package/lib/test/support/exampleData.js +0 -35
- package/lib/test/support/jqTreeMatchers.js +0 -70
- package/lib/test/support/matchers.d.js +0 -1
- package/lib/test/support/setupTests.js +0 -7
- package/lib/test/support/testUtil.js +0 -29
- package/lib/test/support/treeStructure.js +0 -38
- package/lib/test/util.test.js +0 -26
- package/lib/tree.jquery.d.js +0 -1
- package/lib/tree.jquery.js +0 -1105
- package/lib/types.js +0 -1
- package/lib/typings.d.js +0 -2
- package/lib/util.js +0 -15
- package/lib/version.js +0 -8
- package/src/dragAndDropHandler.ts +0 -713
- package/src/mouse.widget.ts +0 -266
- package/src/nodeElement.ts +0 -272
- package/src/types.ts +0 -19
|
@@ -1,31 +1,24 @@
|
|
|
1
1
|
import getGiven from "givens";
|
|
2
|
-
import {
|
|
2
|
+
import { http, HttpResponse } from "msw";
|
|
3
3
|
import { setupServer } from "msw/node";
|
|
4
4
|
import { waitFor } from "@testing-library/dom";
|
|
5
|
+
import { userEvent } from "@testing-library/user-event";
|
|
5
6
|
import "../../tree.jquery";
|
|
6
7
|
import exampleData from "../support/exampleData";
|
|
7
8
|
import { titleSpan } from "../support/testUtil";
|
|
8
9
|
|
|
9
10
|
const context = describe;
|
|
10
11
|
|
|
11
|
-
const server = setupServer();
|
|
12
|
-
|
|
13
|
-
beforeAll(() => server.listen());
|
|
14
|
-
|
|
15
12
|
beforeEach(() => {
|
|
16
13
|
$("body").append('<div id="tree1"></div>');
|
|
17
14
|
});
|
|
18
15
|
|
|
19
16
|
afterEach(() => {
|
|
20
|
-
server.resetHandlers();
|
|
21
|
-
|
|
22
17
|
const $tree = $("#tree1");
|
|
23
18
|
$tree.tree("destroy");
|
|
24
19
|
$tree.remove();
|
|
25
20
|
});
|
|
26
21
|
|
|
27
|
-
afterAll(() => server.close());
|
|
28
|
-
|
|
29
22
|
describe("tree.click", () => {
|
|
30
23
|
interface Vars {
|
|
31
24
|
node1: INode;
|
|
@@ -42,13 +35,13 @@ describe("tree.click", () => {
|
|
|
42
35
|
given.$tree.tree({ data: exampleData });
|
|
43
36
|
});
|
|
44
37
|
|
|
45
|
-
it("fires tree.click", () => {
|
|
38
|
+
it("fires tree.click", async () => {
|
|
46
39
|
const onClick = jest.fn();
|
|
47
40
|
given.$tree.on("tree.click", onClick);
|
|
48
41
|
|
|
49
|
-
given.titleSpan.
|
|
42
|
+
await userEvent.click(given.titleSpan.get(0) as HTMLElement);
|
|
50
43
|
expect(onClick).toHaveBeenCalledWith(
|
|
51
|
-
expect.objectContaining({ node: given.node1 })
|
|
44
|
+
expect.objectContaining({ node: given.node1 }),
|
|
52
45
|
);
|
|
53
46
|
});
|
|
54
47
|
});
|
|
@@ -69,13 +62,16 @@ describe("tree.contextmenu", () => {
|
|
|
69
62
|
given.$tree.tree({ data: exampleData });
|
|
70
63
|
});
|
|
71
64
|
|
|
72
|
-
it("fires tree.contextmenu", () => {
|
|
65
|
+
it("fires tree.contextmenu", async () => {
|
|
73
66
|
const onContextMenu = jest.fn();
|
|
74
67
|
given.$tree.on("tree.contextmenu", onContextMenu);
|
|
75
68
|
|
|
76
|
-
|
|
69
|
+
await userEvent.pointer({
|
|
70
|
+
target: given.titleSpan.get(0) as HTMLElement,
|
|
71
|
+
keys: "[MouseRight]",
|
|
72
|
+
});
|
|
77
73
|
expect(onContextMenu).toHaveBeenCalledWith(
|
|
78
|
-
expect.objectContaining({ node: given.node1 })
|
|
74
|
+
expect.objectContaining({ node: given.node1 }),
|
|
79
75
|
);
|
|
80
76
|
});
|
|
81
77
|
});
|
|
@@ -96,13 +92,13 @@ describe("tree.dblclick", () => {
|
|
|
96
92
|
given.$tree.tree({ data: exampleData });
|
|
97
93
|
});
|
|
98
94
|
|
|
99
|
-
it("fires tree.dblclick", () => {
|
|
95
|
+
it("fires tree.dblclick", async () => {
|
|
100
96
|
const onDoubleClick = jest.fn();
|
|
101
97
|
given.$tree.on("tree.dblclick", onDoubleClick);
|
|
102
98
|
|
|
103
|
-
given.titleSpan.
|
|
99
|
+
await userEvent.dblClick(given.titleSpan.get(0) as HTMLElement);
|
|
104
100
|
expect(onDoubleClick).toHaveBeenCalledWith(
|
|
105
|
-
expect.objectContaining({ node: given.node1 })
|
|
101
|
+
expect.objectContaining({ node: given.node1 }),
|
|
106
102
|
);
|
|
107
103
|
});
|
|
108
104
|
});
|
|
@@ -129,12 +125,15 @@ describe("tree.init", () => {
|
|
|
129
125
|
});
|
|
130
126
|
|
|
131
127
|
context("with data loaded from an url", () => {
|
|
128
|
+
const server = setupServer(
|
|
129
|
+
http.get("/tree/", () => HttpResponse.json(exampleData)),
|
|
130
|
+
);
|
|
132
131
|
beforeEach(() => {
|
|
133
|
-
server.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
);
|
|
132
|
+
server.listen();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
afterAll(() => {
|
|
136
|
+
server.close();
|
|
138
137
|
});
|
|
139
138
|
|
|
140
139
|
it("is called", async () => {
|
|
@@ -165,7 +164,7 @@ describe("tree.load_data", () => {
|
|
|
165
164
|
|
|
166
165
|
given.$tree.tree({ data: exampleData });
|
|
167
166
|
expect(onLoadData).toHaveBeenCalledWith(
|
|
168
|
-
expect.objectContaining({ tree_data: exampleData })
|
|
167
|
+
expect.objectContaining({ tree_data: exampleData }),
|
|
169
168
|
);
|
|
170
169
|
});
|
|
171
170
|
});
|
|
@@ -189,16 +188,16 @@ describe("tree.select", () => {
|
|
|
189
188
|
});
|
|
190
189
|
});
|
|
191
190
|
|
|
192
|
-
it("fires tree.select", () => {
|
|
191
|
+
it("fires tree.select", async () => {
|
|
193
192
|
const onSelect = jest.fn();
|
|
194
193
|
given.$tree.on("tree.select", onSelect);
|
|
195
194
|
|
|
196
|
-
given.titleSpan.
|
|
195
|
+
await userEvent.click(given.titleSpan.get(0) as HTMLElement);
|
|
197
196
|
expect(onSelect).toHaveBeenCalledWith(
|
|
198
197
|
expect.objectContaining({
|
|
199
198
|
node: given.node1,
|
|
200
199
|
deselected_node: null,
|
|
201
|
-
})
|
|
200
|
+
}),
|
|
202
201
|
);
|
|
203
202
|
});
|
|
204
203
|
|
|
@@ -207,17 +206,85 @@ describe("tree.select", () => {
|
|
|
207
206
|
given.$tree.tree("selectNode", given.node1);
|
|
208
207
|
});
|
|
209
208
|
|
|
210
|
-
it("fires tree.select with node is null", () => {
|
|
209
|
+
it("fires tree.select with node is null", async () => {
|
|
211
210
|
const onSelect = jest.fn();
|
|
212
211
|
given.$tree.on("tree.select", onSelect);
|
|
213
212
|
|
|
214
|
-
given.titleSpan.
|
|
213
|
+
await userEvent.click(given.titleSpan.get(0) as HTMLElement);
|
|
215
214
|
expect(onSelect).toHaveBeenCalledWith(
|
|
216
215
|
expect.objectContaining({
|
|
217
216
|
node: null,
|
|
218
217
|
previous_node: given.node1,
|
|
219
|
-
})
|
|
218
|
+
}),
|
|
219
|
+
);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe("tree.loading_data", () => {
|
|
225
|
+
const server = setupServer(
|
|
226
|
+
http.get("/tree/", () => HttpResponse.json(exampleData)),
|
|
227
|
+
);
|
|
228
|
+
beforeEach(() => {
|
|
229
|
+
server.listen();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
afterAll(() => {
|
|
233
|
+
server.close();
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it("fires tree.loading_data when the data is loading from an url", async () => {
|
|
237
|
+
const $tree = $("#tree1");
|
|
238
|
+
|
|
239
|
+
const onLoading = jest.fn();
|
|
240
|
+
$tree.on("tree.loading_data", onLoading);
|
|
241
|
+
|
|
242
|
+
$tree.tree({ dataUrl: "/tree/" });
|
|
243
|
+
|
|
244
|
+
await waitFor(() => {
|
|
245
|
+
expect(onLoading).toHaveBeenCalledWith(
|
|
246
|
+
expect.objectContaining({
|
|
247
|
+
isLoading: true,
|
|
248
|
+
node: null,
|
|
249
|
+
}),
|
|
220
250
|
);
|
|
221
251
|
});
|
|
252
|
+
|
|
253
|
+
await waitFor(() => {
|
|
254
|
+
expect(onLoading).toHaveBeenCalledWith(
|
|
255
|
+
expect.objectContaining({
|
|
256
|
+
isLoading: false,
|
|
257
|
+
node: null,
|
|
258
|
+
}),
|
|
259
|
+
);
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
describe("onLoading", () => {
|
|
265
|
+
const server = setupServer(
|
|
266
|
+
http.get("/tree/", () => HttpResponse.json(exampleData)),
|
|
267
|
+
);
|
|
268
|
+
beforeEach(() => {
|
|
269
|
+
server.listen();
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
afterAll(() => {
|
|
273
|
+
server.close();
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it("calls onLoading", async () => {
|
|
277
|
+
const $tree = $("#tree1");
|
|
278
|
+
const onLoading = jest.fn();
|
|
279
|
+
|
|
280
|
+
$tree.tree({ dataUrl: "/tree/", onLoading });
|
|
281
|
+
|
|
282
|
+
await waitFor(() => {
|
|
283
|
+
expect(onLoading).toHaveBeenCalledWith(false, null, $tree);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
await waitFor(() => {
|
|
287
|
+
expect(onLoading).toHaveBeenCalledWith(false, null, $tree);
|
|
288
|
+
});
|
|
222
289
|
});
|
|
223
290
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import getGiven from "givens";
|
|
2
|
+
import { userEvent } from "@testing-library/user-event";
|
|
2
3
|
import "../../tree.jquery";
|
|
3
4
|
import exampleData from "../support/exampleData";
|
|
4
5
|
|
|
@@ -18,22 +19,16 @@ describe("keyboard support", () => {
|
|
|
18
19
|
interface Vars {
|
|
19
20
|
autoOpen: boolean;
|
|
20
21
|
initialSelectedNode: INode | null;
|
|
21
|
-
pressedKey:
|
|
22
|
+
pressedKey: string;
|
|
22
23
|
$tree: JQuery<HTMLElement>;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
const KEY_DOWN = 40;
|
|
26
|
-
const KEY_LEFT = 37;
|
|
27
|
-
const KEY_RIGHT = 39;
|
|
28
|
-
const KEY_UP = 38;
|
|
29
|
-
const KEY_PAGE_UP = 33;
|
|
30
|
-
|
|
31
26
|
const given = getGiven<Vars>();
|
|
32
27
|
given("autoOpen", () => false);
|
|
33
28
|
given("initialSelectedNode", () => null);
|
|
34
29
|
given("$tree", () => $("#tree1"));
|
|
35
30
|
|
|
36
|
-
beforeEach(() => {
|
|
31
|
+
beforeEach(async () => {
|
|
37
32
|
given.$tree.tree({
|
|
38
33
|
animationSpeed: 0,
|
|
39
34
|
autoOpen: given.autoOpen,
|
|
@@ -44,15 +39,15 @@ describe("keyboard support", () => {
|
|
|
44
39
|
given.$tree.tree("selectNode", given.initialSelectedNode);
|
|
45
40
|
}
|
|
46
41
|
|
|
47
|
-
|
|
42
|
+
await userEvent.keyboard(`{${given.pressedKey}}`);
|
|
48
43
|
});
|
|
49
44
|
|
|
50
45
|
context("with key down", () => {
|
|
51
|
-
given("pressedKey", () =>
|
|
46
|
+
given("pressedKey", () => "ArrowDown");
|
|
52
47
|
|
|
53
48
|
context("when a node is selected", () => {
|
|
54
49
|
given("initialSelectedNode", () =>
|
|
55
|
-
given.$tree.tree("getNodeByNameMustExist", "node1")
|
|
50
|
+
given.$tree.tree("getNodeByNameMustExist", "node1"),
|
|
56
51
|
);
|
|
57
52
|
|
|
58
53
|
it("selects the next node", () => {
|
|
@@ -71,7 +66,7 @@ describe("keyboard support", () => {
|
|
|
71
66
|
|
|
72
67
|
context("when the last node is selected", () => {
|
|
73
68
|
given("initialSelectedNode", () =>
|
|
74
|
-
given.$tree.tree("getNodeByNameMustExist", "node2")
|
|
69
|
+
given.$tree.tree("getNodeByNameMustExist", "node2"),
|
|
75
70
|
);
|
|
76
71
|
|
|
77
72
|
it("keeps the node selected", () => {
|
|
@@ -83,11 +78,11 @@ describe("keyboard support", () => {
|
|
|
83
78
|
});
|
|
84
79
|
|
|
85
80
|
context("with key up", () => {
|
|
86
|
-
given("pressedKey", () =>
|
|
81
|
+
given("pressedKey", () => "ArrowUp");
|
|
87
82
|
|
|
88
83
|
context("when a node is selected", () => {
|
|
89
84
|
given("initialSelectedNode", () =>
|
|
90
|
-
given.$tree.tree("getNodeByNameMustExist", "node2")
|
|
85
|
+
given.$tree.tree("getNodeByNameMustExist", "node2"),
|
|
91
86
|
);
|
|
92
87
|
|
|
93
88
|
it("selects the next node", () => {
|
|
@@ -106,11 +101,11 @@ describe("keyboard support", () => {
|
|
|
106
101
|
});
|
|
107
102
|
|
|
108
103
|
context("with key right", () => {
|
|
109
|
-
given("pressedKey", () =>
|
|
104
|
+
given("pressedKey", () => "ArrowRight");
|
|
110
105
|
|
|
111
106
|
context("when a closed folder is selected", () => {
|
|
112
107
|
given("initialSelectedNode", () =>
|
|
113
|
-
given.$tree.tree("getNodeByNameMustExist", "node1")
|
|
108
|
+
given.$tree.tree("getNodeByNameMustExist", "node1"),
|
|
114
109
|
);
|
|
115
110
|
|
|
116
111
|
it("opens the folder", () => {
|
|
@@ -132,7 +127,7 @@ describe("keyboard support", () => {
|
|
|
132
127
|
context("when an open folder is selected", () => {
|
|
133
128
|
given("autoOpen", () => true);
|
|
134
129
|
given("initialSelectedNode", () =>
|
|
135
|
-
given.$tree.tree("getNodeByNameMustExist", "node1")
|
|
130
|
+
given.$tree.tree("getNodeByNameMustExist", "node1"),
|
|
136
131
|
);
|
|
137
132
|
|
|
138
133
|
it("selects the first child", () => {
|
|
@@ -168,7 +163,7 @@ describe("keyboard support", () => {
|
|
|
168
163
|
|
|
169
164
|
context("when a child is selected", () => {
|
|
170
165
|
given("initialSelectedNode", () =>
|
|
171
|
-
given.$tree.tree("getNodeByNameMustExist", "child1")
|
|
166
|
+
given.$tree.tree("getNodeByNameMustExist", "child1"),
|
|
172
167
|
);
|
|
173
168
|
|
|
174
169
|
it("does nothing", () => {
|
|
@@ -179,11 +174,11 @@ describe("keyboard support", () => {
|
|
|
179
174
|
});
|
|
180
175
|
});
|
|
181
176
|
context("with key left", () => {
|
|
182
|
-
given("pressedKey", () =>
|
|
177
|
+
given("pressedKey", () => "ArrowLeft");
|
|
183
178
|
|
|
184
179
|
context("when a closed folder is selected", () => {
|
|
185
180
|
given("initialSelectedNode", () =>
|
|
186
|
-
given.$tree.tree("getNodeByNameMustExist", "node3")
|
|
181
|
+
given.$tree.tree("getNodeByNameMustExist", "node3"),
|
|
187
182
|
);
|
|
188
183
|
|
|
189
184
|
it("selects the previous node", () => {
|
|
@@ -210,7 +205,7 @@ describe("keyboard support", () => {
|
|
|
210
205
|
context("when an open folder is selected", () => {
|
|
211
206
|
given("autoOpen", () => true);
|
|
212
207
|
given("initialSelectedNode", () =>
|
|
213
|
-
given.$tree.tree("getNodeByNameMustExist", "node2")
|
|
208
|
+
given.$tree.tree("getNodeByNameMustExist", "node2"),
|
|
214
209
|
);
|
|
215
210
|
|
|
216
211
|
it("closes the folder", () => {
|
|
@@ -237,10 +232,10 @@ describe("keyboard support", () => {
|
|
|
237
232
|
});
|
|
238
233
|
|
|
239
234
|
context("with page up key", () => {
|
|
240
|
-
given("pressedKey", () =>
|
|
235
|
+
given("pressedKey", () => "PageUp");
|
|
241
236
|
|
|
242
237
|
given("initialSelectedNode", () =>
|
|
243
|
-
given.$tree.tree("getNodeByNameMustExist", "child1")
|
|
238
|
+
given.$tree.tree("getNodeByNameMustExist", "child1"),
|
|
244
239
|
);
|
|
245
240
|
|
|
246
241
|
it("does nothing", () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import getGiven from "givens";
|
|
2
2
|
import { screen } from "@testing-library/dom";
|
|
3
|
-
import {
|
|
3
|
+
import { userEvent } from "@testing-library/user-event";
|
|
4
|
+
import { http, HttpResponse } from "msw";
|
|
4
5
|
import { setupServer } from "msw/node";
|
|
5
6
|
import "../../tree.jquery";
|
|
6
7
|
import { togglerLink } from "../support/testUtil";
|
|
@@ -47,16 +48,16 @@ context("when a node has load_on_demand in the data", () => {
|
|
|
47
48
|
|
|
48
49
|
beforeEach(() => {
|
|
49
50
|
server.use(
|
|
50
|
-
|
|
51
|
-
const
|
|
51
|
+
http.get("/tree/", ({ request }) => {
|
|
52
|
+
const url = new URL(request.url);
|
|
53
|
+
const parentId = url.searchParams.get("node");
|
|
52
54
|
|
|
53
55
|
if (parentId === "1") {
|
|
54
|
-
return
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
);
|
|
56
|
+
return HttpResponse.json([
|
|
57
|
+
{ id: 2, name: "loaded-on-demand" },
|
|
58
|
+
]);
|
|
58
59
|
} else {
|
|
59
|
-
return
|
|
60
|
+
return new HttpResponse(null, { status: 400 });
|
|
60
61
|
}
|
|
61
62
|
}),
|
|
62
63
|
);
|
|
@@ -91,7 +92,8 @@ context("when a node has load_on_demand in the data", () => {
|
|
|
91
92
|
);
|
|
92
93
|
|
|
93
94
|
it("loads the subtree", async () => {
|
|
94
|
-
togglerLink(given.node.element)
|
|
95
|
+
const toggler = togglerLink(given.node.element);
|
|
96
|
+
await userEvent.click(toggler.get(0) as HTMLElement);
|
|
95
97
|
|
|
96
98
|
await screen.findByText("loaded-on-demand");
|
|
97
99
|
|
|
@@ -106,20 +108,21 @@ context("when a node has load_on_demand in the data", () => {
|
|
|
106
108
|
]);
|
|
107
109
|
});
|
|
108
110
|
|
|
109
|
-
context("when the node is selected
|
|
111
|
+
context("when the node is selected", () => {
|
|
110
112
|
beforeEach(() => {
|
|
111
113
|
given.$tree.tree("selectNode", given.node);
|
|
112
114
|
});
|
|
113
115
|
|
|
114
|
-
it("keeps the node selected
|
|
116
|
+
it("keeps the node selected", async () => {
|
|
115
117
|
expect(given.node.element).toBeSelected();
|
|
116
118
|
expect(given.node.element).toBeFocused();
|
|
117
119
|
|
|
118
|
-
togglerLink(given.node.element)
|
|
120
|
+
const toggler = togglerLink(given.node.element);
|
|
121
|
+
await userEvent.click(toggler.get(0) as HTMLElement);
|
|
122
|
+
|
|
119
123
|
await screen.findByText("loaded-on-demand");
|
|
120
124
|
|
|
121
125
|
expect(given.node.element).toBeSelected();
|
|
122
|
-
expect(given.node.element).toBeFocused();
|
|
123
126
|
});
|
|
124
127
|
});
|
|
125
128
|
|
|
@@ -127,7 +130,9 @@ context("when a node has load_on_demand in the data", () => {
|
|
|
127
130
|
it("doesn't select the node", async () => {
|
|
128
131
|
expect(given.node.element).not.toBeSelected();
|
|
129
132
|
|
|
130
|
-
togglerLink(given.node.element)
|
|
133
|
+
const toggler = togglerLink(given.node.element);
|
|
134
|
+
await userEvent.click(toggler.get(0) as HTMLElement);
|
|
135
|
+
|
|
131
136
|
await screen.findByText("loaded-on-demand");
|
|
132
137
|
|
|
133
138
|
expect(given.node.element).not.toBeSelected();
|
|
@@ -144,7 +149,9 @@ context("when a node has load_on_demand in the data", () => {
|
|
|
144
149
|
expect(given.node.element).toBeSelected();
|
|
145
150
|
expect(given.node.element).not.toBeFocused();
|
|
146
151
|
|
|
147
|
-
togglerLink(given.node.element)
|
|
152
|
+
const toggler = togglerLink(given.node.element);
|
|
153
|
+
await userEvent.click(toggler.get(0) as HTMLElement);
|
|
154
|
+
|
|
148
155
|
await screen.findByText("loaded-on-demand");
|
|
149
156
|
|
|
150
157
|
expect(given.node.element).toBeSelected();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import getGiven from "givens";
|
|
2
2
|
import { screen, waitFor } from "@testing-library/dom";
|
|
3
|
-
import {
|
|
3
|
+
import { http, HttpResponse } from "msw";
|
|
4
|
+
import { userEvent } from "@testing-library/user-event";
|
|
4
5
|
import { setupServer } from "msw/node";
|
|
5
6
|
import "../../tree.jquery";
|
|
6
7
|
import exampleData from "../support/exampleData";
|
|
@@ -134,7 +135,7 @@ describe("addToSelection", () => {
|
|
|
134
135
|
given("child1", () => given.$tree.tree("getNodeByNameMustExist", "child1"));
|
|
135
136
|
given("child2", () => given.$tree.tree("getNodeByNameMustExist", "child2"));
|
|
136
137
|
|
|
137
|
-
|
|
138
|
+
it("selects the nodes", () => {
|
|
138
139
|
given.$tree.tree({
|
|
139
140
|
autoOpen: true,
|
|
140
141
|
data: exampleData,
|
|
@@ -142,15 +143,21 @@ describe("addToSelection", () => {
|
|
|
142
143
|
|
|
143
144
|
given.$tree.tree("addToSelection", given.child1);
|
|
144
145
|
given.$tree.tree("addToSelection", given.child2);
|
|
145
|
-
});
|
|
146
146
|
|
|
147
|
-
it("selects the nodes", () => {
|
|
148
147
|
expect(given.$tree.tree("getSelectedNodes")).toEqual(
|
|
149
148
|
expect.arrayContaining([given.child1, given.child2]),
|
|
150
149
|
);
|
|
151
150
|
});
|
|
152
151
|
|
|
153
152
|
it("renders the nodes correctly", () => {
|
|
153
|
+
given.$tree.tree({
|
|
154
|
+
autoOpen: true,
|
|
155
|
+
data: exampleData,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
given.$tree.tree("addToSelection", given.child1);
|
|
159
|
+
given.$tree.tree("addToSelection", given.child2);
|
|
160
|
+
|
|
154
161
|
expect(given.$tree).toHaveTreeStructure([
|
|
155
162
|
expect.objectContaining({
|
|
156
163
|
name: "node1",
|
|
@@ -172,6 +179,20 @@ describe("addToSelection", () => {
|
|
|
172
179
|
}),
|
|
173
180
|
]);
|
|
174
181
|
});
|
|
182
|
+
|
|
183
|
+
it("opens the parent node when it's closed", () => {
|
|
184
|
+
given.$tree.tree({
|
|
185
|
+
autoOpen: false,
|
|
186
|
+
data: exampleData,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const node1 = given.$tree.tree("getNodeByNameMustExist", "node1");
|
|
190
|
+
expect(node1.is_open).toBeFalsy();
|
|
191
|
+
|
|
192
|
+
given.$tree.tree("addToSelection", given.child1);
|
|
193
|
+
|
|
194
|
+
expect(node1.is_open).toBe(true);
|
|
195
|
+
});
|
|
175
196
|
});
|
|
176
197
|
|
|
177
198
|
describe("appendNode", () => {
|
|
@@ -749,9 +770,7 @@ describe("loadDataFromUrl", () => {
|
|
|
749
770
|
|
|
750
771
|
beforeEach(() => {
|
|
751
772
|
server.use(
|
|
752
|
-
|
|
753
|
-
response(ctx.status(200), ctx.json(given.serverData)),
|
|
754
|
-
),
|
|
773
|
+
http.get("/tree/", () => HttpResponse.json(given.serverData)),
|
|
755
774
|
);
|
|
756
775
|
|
|
757
776
|
given.$tree.tree({ data: given.initialData });
|
|
@@ -1011,11 +1030,7 @@ describe("reload", () => {
|
|
|
1011
1030
|
given("$tree", () => $("#tree1"));
|
|
1012
1031
|
|
|
1013
1032
|
beforeEach(async () => {
|
|
1014
|
-
server.use(
|
|
1015
|
-
rest.get("/tree2/", (_request, response, ctx) =>
|
|
1016
|
-
response(ctx.status(200), ctx.json(exampleData)),
|
|
1017
|
-
),
|
|
1018
|
-
);
|
|
1033
|
+
server.use(http.get("/tree2/", () => HttpResponse.json(exampleData)));
|
|
1019
1034
|
|
|
1020
1035
|
given.$tree.tree({ dataUrl: "/tree2/" });
|
|
1021
1036
|
await screen.findByText("node1");
|
|
@@ -1207,6 +1222,15 @@ describe("selectNode", () => {
|
|
|
1207
1222
|
expect(given.$tree.tree("getSelectedNode")).toBeFalse();
|
|
1208
1223
|
});
|
|
1209
1224
|
});
|
|
1225
|
+
|
|
1226
|
+
it("opens the parent node when it's closed", () => {
|
|
1227
|
+
expect(given.node1.is_open).toBeFalsy();
|
|
1228
|
+
|
|
1229
|
+
const child1 = given.$tree.tree("getNodeByNameMustExist", "child1");
|
|
1230
|
+
given.$tree.tree("selectNode", child1);
|
|
1231
|
+
|
|
1232
|
+
expect(given.node1.is_open).toBe(true);
|
|
1233
|
+
});
|
|
1210
1234
|
});
|
|
1211
1235
|
|
|
1212
1236
|
describe("setOption", () => {
|
|
@@ -1226,9 +1250,11 @@ describe("setOption", () => {
|
|
|
1226
1250
|
given("node1", () => given.$tree.tree("getNodeByNameMustExist", "node1"));
|
|
1227
1251
|
given("$tree", () => $("#tree1"));
|
|
1228
1252
|
|
|
1229
|
-
it("sets an option", () => {
|
|
1253
|
+
it("sets an option", async () => {
|
|
1230
1254
|
given.$tree.tree("setOption", "selectable", true);
|
|
1231
|
-
|
|
1255
|
+
await userEvent.click(
|
|
1256
|
+
titleSpan(given.node1.element).get(0) as HTMLElement,
|
|
1257
|
+
);
|
|
1232
1258
|
expect(given.$tree.tree("getSelectedNode")).toMatchObject({
|
|
1233
1259
|
name: "node1",
|
|
1234
1260
|
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import "../../tree.jquery";
|
|
2
|
+
import { userEvent } from "@testing-library/user-event";
|
|
3
|
+
import exampleData from "../support/exampleData";
|
|
4
|
+
import { titleSpan, togglerLink } from "../support/testUtil";
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
$("body").append('<div id="tree1"></div>');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
const $tree = $("#tree1");
|
|
12
|
+
$tree.tree("destroy");
|
|
13
|
+
$tree.remove();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("selects a node and sets the focus when it is clicked", async () => {
|
|
17
|
+
const $tree = $("#tree1");
|
|
18
|
+
$tree.tree({ data: exampleData });
|
|
19
|
+
|
|
20
|
+
const node = $tree.tree("getNodeByNameMustExist", "node1");
|
|
21
|
+
expect(node.element).not.toBeSelected();
|
|
22
|
+
expect(node.element).not.toBeFocused();
|
|
23
|
+
|
|
24
|
+
await userEvent.click(titleSpan(node.element).get(0) as HTMLElement);
|
|
25
|
+
|
|
26
|
+
expect(node.element).toBeSelected();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("deselects when a selected node is clicked", async () => {
|
|
30
|
+
const $tree = $("#tree1");
|
|
31
|
+
$tree.tree({ data: exampleData });
|
|
32
|
+
|
|
33
|
+
const node = $tree.tree("getNodeByNameMustExist", "node1");
|
|
34
|
+
$tree.tree("selectNode", node);
|
|
35
|
+
|
|
36
|
+
expect(node.element).toBeSelected();
|
|
37
|
+
|
|
38
|
+
await userEvent.click(titleSpan(node.element).get(0) as HTMLElement);
|
|
39
|
+
|
|
40
|
+
expect(node.element).not.toBeSelected();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("opens a node when the toggle button is clicked", async () => {
|
|
44
|
+
const $tree = $("#tree1");
|
|
45
|
+
$tree.tree({ data: exampleData });
|
|
46
|
+
|
|
47
|
+
const node = $tree.tree("getNodeByNameMustExist", "node1");
|
|
48
|
+
expect(node.element).not.toBeOpen();
|
|
49
|
+
|
|
50
|
+
await userEvent.click(togglerLink(node.element).get(0) as HTMLElement);
|
|
51
|
+
|
|
52
|
+
expect(node.element).toBeOpen();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("doesn't select a node when it is opened", async () => {
|
|
56
|
+
const $tree = $("#tree1");
|
|
57
|
+
$tree.tree({ data: exampleData });
|
|
58
|
+
|
|
59
|
+
const node = $tree.tree("getNodeByNameMustExist", "node1");
|
|
60
|
+
expect(node.element).not.toBeSelected();
|
|
61
|
+
expect(node.element).not.toBeOpen();
|
|
62
|
+
|
|
63
|
+
await userEvent.click(togglerLink(node.element).get(0) as HTMLElement);
|
|
64
|
+
|
|
65
|
+
expect(node.element).not.toBeSelected();
|
|
66
|
+
expect(node.element).toBeOpen();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("keeps it selected when a selected node is opened", async () => {
|
|
70
|
+
const $tree = $("#tree1");
|
|
71
|
+
$tree.tree({ data: exampleData });
|
|
72
|
+
|
|
73
|
+
const node = $tree.tree("getNodeByNameMustExist", "node1");
|
|
74
|
+
$tree.tree("selectNode", node);
|
|
75
|
+
expect(node.element).toBeSelected();
|
|
76
|
+
expect(node.element).not.toBeOpen();
|
|
77
|
+
|
|
78
|
+
await userEvent.click(togglerLink(node.element).get(0) as HTMLElement);
|
|
79
|
+
|
|
80
|
+
expect(node.element).toBeSelected();
|
|
81
|
+
expect(node.element).toBeOpen();
|
|
82
|
+
});
|