@gtkx/testing 0.1.47 → 0.1.49

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/README.md CHANGED
@@ -186,6 +186,14 @@ A comprehensive showcase of GTK4 widgets and features:
186
186
  turbo start --filter=gtk4-demo
187
187
  ```
188
188
 
189
+ ### List Example
190
+
191
+ Comprehensive showcase of ListView, GridView, and ColumnView with sorting:
192
+
193
+ ```bash
194
+ turbo start --filter=list-example
195
+ ```
196
+
189
197
  ## Packages
190
198
 
191
199
  | Package | Description |
package/dist/queries.js CHANGED
@@ -18,20 +18,20 @@ const matchText = (actual, expected, options) => {
18
18
  }
19
19
  return expected.test(normalizedActual);
20
20
  };
21
+ const asAccessible = (widget) => widget;
21
22
  const asButton = (widget) => getObject(widget.ptr, Button);
22
23
  const asLabel = (widget) => getObject(widget.ptr, Label);
23
24
  const asCheckButton = (widget) => getObject(widget.ptr, CheckButton);
24
25
  const asToggleButton = (widget) => getObject(widget.ptr, ToggleButton);
25
26
  const asExpander = (widget) => getObject(widget.ptr, Expander);
26
27
  const isInternalLabel = (widget) => {
27
- const accessible = widget;
28
+ const accessible = asAccessible(widget);
28
29
  if (accessible.getAccessibleRole() !== AccessibleRole.LABEL)
29
30
  return false;
30
31
  const parent = widget.getParent();
31
32
  if (!parent)
32
33
  return false;
33
- const parentAccessible = parent;
34
- const parentRole = parentAccessible.getAccessibleRole();
34
+ const parentRole = asAccessible(parent).getAccessibleRole();
35
35
  return (parentRole === AccessibleRole.BUTTON ||
36
36
  parentRole === AccessibleRole.TOGGLE_BUTTON ||
37
37
  parentRole === AccessibleRole.CHECKBOX ||
@@ -43,8 +43,7 @@ const isInternalLabel = (widget) => {
43
43
  const getWidgetText = (widget) => {
44
44
  if (isInternalLabel(widget))
45
45
  return null;
46
- const accessible = widget;
47
- const role = accessible.getAccessibleRole();
46
+ const role = asAccessible(widget).getAccessibleRole();
48
47
  switch (role) {
49
48
  case AccessibleRole.BUTTON:
50
49
  case AccessibleRole.TOGGLE_BUTTON:
@@ -68,8 +67,7 @@ const getWidgetTestId = (widget) => {
68
67
  return widget.getName();
69
68
  };
70
69
  const getWidgetCheckedState = (widget) => {
71
- const accessible = widget;
72
- const role = accessible.getAccessibleRole();
70
+ const role = asAccessible(widget).getAccessibleRole();
73
71
  if (role === AccessibleRole.CHECKBOX || role === AccessibleRole.RADIO) {
74
72
  return asCheckButton(widget).getActive();
75
73
  }
@@ -79,8 +77,7 @@ const getWidgetCheckedState = (widget) => {
79
77
  return undefined;
80
78
  };
81
79
  const getWidgetExpandedState = (widget) => {
82
- const accessible = widget;
83
- const role = accessible.getAccessibleRole();
80
+ const role = asAccessible(widget).getAccessibleRole();
84
81
  if (role === AccessibleRole.BUTTON) {
85
82
  const parent = widget.getParent();
86
83
  if (!parent)
@@ -128,8 +125,7 @@ const formatByRoleError = (role, options) => {
128
125
  };
129
126
  const getAllByRole = (container, role, options) => {
130
127
  const matches = findAll(container, (node) => {
131
- const accessible = node;
132
- if (accessible.getAccessibleRole() !== role)
128
+ if (asAccessible(node).getAccessibleRole() !== role)
133
129
  return false;
134
130
  return matchByRoleOptions(node, options);
135
131
  });
@@ -143,7 +139,10 @@ const getByRole = (container, role, options) => {
143
139
  if (matches.length > 1) {
144
140
  throw new Error(`Found ${matches.length} elements with ${formatByRoleError(role, options)}`);
145
141
  }
146
- return matches[0];
142
+ const [first] = matches;
143
+ if (!first)
144
+ throw new Error(`Unable to find element with ${formatByRoleError(role, options)}`);
145
+ return first;
147
146
  };
148
147
  const getAllByLabelText = (container, text, options) => {
149
148
  const matches = findAll(container, (node) => {
@@ -160,7 +159,10 @@ const getByLabelText = (container, text, options) => {
160
159
  if (matches.length > 1) {
161
160
  throw new Error(`Found ${matches.length} elements with label text "${text}"`);
162
161
  }
163
- return matches[0];
162
+ const [first] = matches;
163
+ if (!first)
164
+ throw new Error(`Unable to find element with label text "${text}"`);
165
+ return first;
164
166
  };
165
167
  const getAllByText = (container, text, options) => {
166
168
  const matches = findAll(container, (node) => {
@@ -177,7 +179,10 @@ const getByText = (container, text, options) => {
177
179
  if (matches.length > 1) {
178
180
  throw new Error(`Found ${matches.length} elements with text "${text}"`);
179
181
  }
180
- return matches[0];
182
+ const [first] = matches;
183
+ if (!first)
184
+ throw new Error(`Unable to find element with text "${text}"`);
185
+ return first;
181
186
  };
182
187
  const getAllByTestId = (container, testId, options) => {
183
188
  const matches = findAll(container, (node) => {
@@ -194,7 +199,10 @@ const getByTestId = (container, testId, options) => {
194
199
  if (matches.length > 1) {
195
200
  throw new Error(`Found ${matches.length} elements with test id "${testId}"`);
196
201
  }
197
- return matches[0];
202
+ const [first] = matches;
203
+ if (!first)
204
+ throw new Error(`Unable to find element with test id "${testId}"`);
205
+ return first;
198
206
  };
199
207
  /**
200
208
  * Waits for and finds a single widget matching the specified accessible role.
package/dist/render.js CHANGED
@@ -4,14 +4,15 @@ import * as Gtk from "@gtkx/ffi/gtk";
4
4
  import { ApplicationWindow, reconciler } from "@gtkx/react";
5
5
  import * as queries from "./queries.js";
6
6
  import { setScreenRoot } from "./screen.js";
7
+ import { tick } from "./timing.js";
7
8
  const ROOT_NODE_CONTAINER = Symbol.for("ROOT_NODE_CONTAINER");
8
9
  const APP_ID = "com.gtkx.testing";
9
10
  let container = null;
10
11
  const hasGetLabel = (widget) => typeof widget.getLabel === "function";
12
+ const asAccessible = (widget) => widget;
11
13
  const printWidgetTree = (root, indent = 0) => {
12
- const accessible = root;
13
14
  const prefix = " ".repeat(indent);
14
- const role = Gtk.AccessibleRole[accessible.getAccessibleRole()] ?? "UNKNOWN";
15
+ const role = Gtk.AccessibleRole[asAccessible(root).getAccessibleRole()] ?? "UNKNOWN";
15
16
  const label = hasGetLabel(root) ? ` label="${root.getLabel()}"` : "";
16
17
  let result = `${prefix}<${root.constructor.name} role=${role}${label}>\n`;
17
18
  let child = root.getFirstChild();
@@ -21,7 +22,6 @@ const printWidgetTree = (root, indent = 0) => {
21
22
  }
22
23
  return result;
23
24
  };
24
- const tick = () => new Promise((resolve) => setTimeout(resolve, 0));
25
25
  const update = async (instance, element, fiberRoot) => {
26
26
  instance.updateContainer(element, fiberRoot, null, () => { });
27
27
  await tick();
@@ -30,9 +30,7 @@ const ensureInitialized = () => {
30
30
  const app = start(APP_ID);
31
31
  if (!container) {
32
32
  const instance = reconciler.getInstance();
33
- container = instance.createContainer(
34
- // biome-ignore lint/suspicious/noExplicitAny: testing only
35
- ROOT_NODE_CONTAINER, 0, null, false, null, "", (error) => console.error("Test reconciler error:", error), () => { }, () => { }, () => { }, null);
33
+ container = instance.createContainer(ROOT_NODE_CONTAINER, 0, null, false, null, "", (error) => console.error("Test reconciler error:", error), () => { }, () => { }, () => { }, null);
36
34
  }
37
35
  return { app, container };
38
36
  };
@@ -0,0 +1 @@
1
+ export declare const tick: () => Promise<void>;
package/dist/timing.js ADDED
@@ -0,0 +1 @@
1
+ export const tick = () => new Promise((resolve) => setTimeout(resolve, 0));
@@ -1,6 +1,6 @@
1
1
  import { fireEvent } from "./fire-event.js";
2
+ import { tick } from "./timing.js";
2
3
  import { hasGetText, hasSetText } from "./widget.js";
3
- const tick = () => new Promise((resolve) => setTimeout(resolve, 0));
4
4
  const createUserEventInstance = (_options) => {
5
5
  return {
6
6
  click: async (element) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/testing",
3
- "version": "0.1.47",
3
+ "version": "0.1.49",
4
4
  "description": "Testing utilities for GTKX applications",
5
5
  "keywords": [
6
6
  "gtk",
@@ -32,9 +32,9 @@
32
32
  "dist"
33
33
  ],
34
34
  "dependencies": {
35
- "@gtkx/ffi": "0.1.47",
36
- "@gtkx/react": "0.1.47",
37
- "@gtkx/native": "0.1.47"
35
+ "@gtkx/ffi": "0.1.49",
36
+ "@gtkx/native": "0.1.49",
37
+ "@gtkx/react": "0.1.49"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "tsc -b && cp ../../README.md .",