@react-text-game/ui 0.1.0
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 +297 -0
- package/dist/components/DevModeDrawer/CopyButton.d.ts +4 -0
- package/dist/components/DevModeDrawer/CopyButton.d.ts.map +1 -0
- package/dist/components/DevModeDrawer/CopyButton.js +17 -0
- package/dist/components/DevModeDrawer/CopyButton.js.map +1 -0
- package/dist/components/DevModeDrawer/CurrentPassageData.d.ts +4 -0
- package/dist/components/DevModeDrawer/CurrentPassageData.d.ts.map +1 -0
- package/dist/components/DevModeDrawer/CurrentPassageData.js +23 -0
- package/dist/components/DevModeDrawer/CurrentPassageData.js.map +1 -0
- package/dist/components/DevModeDrawer/DevModeDrawer.d.ts +7 -0
- package/dist/components/DevModeDrawer/DevModeDrawer.d.ts.map +1 -0
- package/dist/components/DevModeDrawer/DevModeDrawer.js +29 -0
- package/dist/components/DevModeDrawer/DevModeDrawer.js.map +1 -0
- package/dist/components/DevModeDrawer/GameData.d.ts +4 -0
- package/dist/components/DevModeDrawer/GameData.d.ts.map +1 -0
- package/dist/components/DevModeDrawer/GameData.js +22 -0
- package/dist/components/DevModeDrawer/GameData.js.map +1 -0
- package/dist/components/DevModeDrawer/JumpToPassage.d.ts +2 -0
- package/dist/components/DevModeDrawer/JumpToPassage.d.ts.map +1 -0
- package/dist/components/DevModeDrawer/JumpToPassage.js +15 -0
- package/dist/components/DevModeDrawer/JumpToPassage.js.map +1 -0
- package/dist/components/DevModeDrawer/RefreshButton.d.ts +4 -0
- package/dist/components/DevModeDrawer/RefreshButton.d.ts.map +1 -0
- package/dist/components/DevModeDrawer/RefreshButton.js +5 -0
- package/dist/components/DevModeDrawer/RefreshButton.js.map +1 -0
- package/dist/components/DevModeDrawer/index.d.ts +2 -0
- package/dist/components/DevModeDrawer/index.d.ts.map +1 -0
- package/dist/components/DevModeDrawer/index.js +2 -0
- package/dist/components/DevModeDrawer/index.js.map +1 -0
- package/dist/components/ErrorBoundary/ErrorBoundary.d.ts +22 -0
- package/dist/components/ErrorBoundary/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/ErrorBoundary/ErrorBoundary.js +135 -0
- package/dist/components/ErrorBoundary/ErrorBoundary.js.map +1 -0
- package/dist/components/ErrorBoundary/index.d.ts +2 -0
- package/dist/components/ErrorBoundary/index.d.ts.map +1 -0
- package/dist/components/ErrorBoundary/index.js +2 -0
- package/dist/components/ErrorBoundary/index.js.map +1 -0
- package/dist/components/ErrorBoundary/types.d.ts +12 -0
- package/dist/components/ErrorBoundary/types.d.ts.map +1 -0
- package/dist/components/ErrorBoundary/types.js +2 -0
- package/dist/components/ErrorBoundary/types.js.map +1 -0
- package/dist/components/GameProvider/AppIconMenu.d.ts +8 -0
- package/dist/components/GameProvider/AppIconMenu.d.ts.map +1 -0
- package/dist/components/GameProvider/AppIconMenu.js +12 -0
- package/dist/components/GameProvider/AppIconMenu.js.map +1 -0
- package/dist/components/GameProvider/GameProvider.d.ts +12 -0
- package/dist/components/GameProvider/GameProvider.d.ts.map +1 -0
- package/dist/components/GameProvider/GameProvider.js +36 -0
- package/dist/components/GameProvider/GameProvider.js.map +1 -0
- package/dist/components/GameProvider/SaveLoadMenuContext.d.ts +11 -0
- package/dist/components/GameProvider/SaveLoadMenuContext.d.ts.map +1 -0
- package/dist/components/GameProvider/SaveLoadMenuContext.js +3 -0
- package/dist/components/GameProvider/SaveLoadMenuContext.js.map +1 -0
- package/dist/components/GameProvider/SaveLoadMenuProvider.d.ts +4 -0
- package/dist/components/GameProvider/SaveLoadMenuProvider.d.ts.map +1 -0
- package/dist/components/GameProvider/SaveLoadMenuProvider.js +32 -0
- package/dist/components/GameProvider/SaveLoadMenuProvider.js.map +1 -0
- package/dist/components/GameProvider/index.d.ts +2 -0
- package/dist/components/GameProvider/index.d.ts.map +1 -0
- package/dist/components/GameProvider/index.js +2 -0
- package/dist/components/GameProvider/index.js.map +1 -0
- package/dist/components/InteractiveMapComponent/Hotspot.d.ts +9 -0
- package/dist/components/InteractiveMapComponent/Hotspot.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/Hotspot.js +30 -0
- package/dist/components/InteractiveMapComponent/Hotspot.js.map +1 -0
- package/dist/components/InteractiveMapComponent/HotspotMap.d.ts +8 -0
- package/dist/components/InteractiveMapComponent/HotspotMap.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/HotspotMap.js +37 -0
- package/dist/components/InteractiveMapComponent/HotspotMap.js.map +1 -0
- package/dist/components/InteractiveMapComponent/HotspotMenu.d.ts +9 -0
- package/dist/components/InteractiveMapComponent/HotspotMenu.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/HotspotMenu.js +37 -0
- package/dist/components/InteractiveMapComponent/HotspotMenu.js.map +1 -0
- package/dist/components/InteractiveMapComponent/ImageHotspot.d.ts +7 -0
- package/dist/components/InteractiveMapComponent/ImageHotspot.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/ImageHotspot.js +23 -0
- package/dist/components/InteractiveMapComponent/ImageHotspot.js.map +1 -0
- package/dist/components/InteractiveMapComponent/InteractiveMapComponent.d.ts +7 -0
- package/dist/components/InteractiveMapComponent/InteractiveMapComponent.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/InteractiveMapComponent.js +23 -0
- package/dist/components/InteractiveMapComponent/InteractiveMapComponent.js.map +1 -0
- package/dist/components/InteractiveMapComponent/LabelHotspot.d.ts +7 -0
- package/dist/components/InteractiveMapComponent/LabelHotspot.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/LabelHotspot.js +10 -0
- package/dist/components/InteractiveMapComponent/LabelHotspot.js.map +1 -0
- package/dist/components/InteractiveMapComponent/SideHotspot.d.ts +7 -0
- package/dist/components/InteractiveMapComponent/SideHotspot.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/SideHotspot.js +11 -0
- package/dist/components/InteractiveMapComponent/SideHotspot.js.map +1 -0
- package/dist/components/InteractiveMapComponent/helpers.d.ts +11 -0
- package/dist/components/InteractiveMapComponent/helpers.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/helpers.js +34 -0
- package/dist/components/InteractiveMapComponent/helpers.js.map +1 -0
- package/dist/components/InteractiveMapComponent/index.d.ts +2 -0
- package/dist/components/InteractiveMapComponent/index.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/index.js +2 -0
- package/dist/components/InteractiveMapComponent/index.js.map +1 -0
- package/dist/components/InteractiveMapComponent/types.d.ts +19 -0
- package/dist/components/InteractiveMapComponent/types.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/types.js +2 -0
- package/dist/components/InteractiveMapComponent/types.js.map +1 -0
- package/dist/components/InteractiveMapComponent/useHotspotMapSize.d.ts +3 -0
- package/dist/components/InteractiveMapComponent/useHotspotMapSize.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/useHotspotMapSize.js +74 -0
- package/dist/components/InteractiveMapComponent/useHotspotMapSize.js.map +1 -0
- package/dist/components/InteractiveMapComponent/useSortHotspots.d.ts +16 -0
- package/dist/components/InteractiveMapComponent/useSortHotspots.d.ts.map +1 -0
- package/dist/components/InteractiveMapComponent/useSortHotspots.js +13 -0
- package/dist/components/InteractiveMapComponent/useSortHotspots.js.map +1 -0
- package/dist/components/MainMenu.d.ts +2 -0
- package/dist/components/MainMenu.d.ts.map +1 -0
- package/dist/components/MainMenu.js +15 -0
- package/dist/components/MainMenu.js.map +1 -0
- package/dist/components/PassageController/PassageController.d.ts +2 -0
- package/dist/components/PassageController/PassageController.d.ts.map +1 -0
- package/dist/components/PassageController/PassageController.js +25 -0
- package/dist/components/PassageController/PassageController.js.map +1 -0
- package/dist/components/PassageController/index.d.ts +2 -0
- package/dist/components/PassageController/index.d.ts.map +1 -0
- package/dist/components/PassageController/index.js +2 -0
- package/dist/components/PassageController/index.js.map +1 -0
- package/dist/components/ReloadButton.d.ts +15 -0
- package/dist/components/ReloadButton.d.ts.map +1 -0
- package/dist/components/ReloadButton.js +10 -0
- package/dist/components/ReloadButton.js.map +1 -0
- package/dist/components/SaveButton.d.ts +21 -0
- package/dist/components/SaveButton.d.ts.map +1 -0
- package/dist/components/SaveButton.js +10 -0
- package/dist/components/SaveButton.js.map +1 -0
- package/dist/components/SaveLoadModal/SaveLoadModal.d.ts +9 -0
- package/dist/components/SaveLoadModal/SaveLoadModal.d.ts.map +1 -0
- package/dist/components/SaveLoadModal/SaveLoadModal.js +52 -0
- package/dist/components/SaveLoadModal/SaveLoadModal.js.map +1 -0
- package/dist/components/SaveLoadModal/index.d.ts +2 -0
- package/dist/components/SaveLoadModal/index.d.ts.map +1 -0
- package/dist/components/SaveLoadModal/index.js +2 -0
- package/dist/components/SaveLoadModal/index.js.map +1 -0
- package/dist/components/StoryComponent/StoryComponent.d.ts +7 -0
- package/dist/components/StoryComponent/StoryComponent.d.ts.map +1 -0
- package/dist/components/StoryComponent/StoryComponent.js +30 -0
- package/dist/components/StoryComponent/StoryComponent.js.map +1 -0
- package/dist/components/StoryComponent/components/Actions.d.ts +7 -0
- package/dist/components/StoryComponent/components/Actions.d.ts.map +1 -0
- package/dist/components/StoryComponent/components/Actions.js +6 -0
- package/dist/components/StoryComponent/components/Actions.js.map +1 -0
- package/dist/components/StoryComponent/components/Conversation.d.ts +7 -0
- package/dist/components/StoryComponent/components/Conversation.d.ts.map +1 -0
- package/dist/components/StoryComponent/components/Conversation.js +53 -0
- package/dist/components/StoryComponent/components/Conversation.js.map +1 -0
- package/dist/components/StoryComponent/components/Header.d.ts +7 -0
- package/dist/components/StoryComponent/components/Header.d.ts.map +1 -0
- package/dist/components/StoryComponent/components/Header.js +12 -0
- package/dist/components/StoryComponent/components/Header.js.map +1 -0
- package/dist/components/StoryComponent/components/Image.d.ts +5 -0
- package/dist/components/StoryComponent/components/Image.d.ts.map +1 -0
- package/dist/components/StoryComponent/components/Image.js +31 -0
- package/dist/components/StoryComponent/components/Image.js.map +1 -0
- package/dist/components/StoryComponent/components/Text.d.ts +7 -0
- package/dist/components/StoryComponent/components/Text.d.ts.map +1 -0
- package/dist/components/StoryComponent/components/Text.js +4 -0
- package/dist/components/StoryComponent/components/Text.js.map +1 -0
- package/dist/components/StoryComponent/components/Video.d.ts +7 -0
- package/dist/components/StoryComponent/components/Video.d.ts.map +1 -0
- package/dist/components/StoryComponent/components/Video.js +4 -0
- package/dist/components/StoryComponent/components/Video.js.map +1 -0
- package/dist/components/StoryComponent/components/index.d.ts +7 -0
- package/dist/components/StoryComponent/components/index.d.ts.map +1 -0
- package/dist/components/StoryComponent/components/index.js +7 -0
- package/dist/components/StoryComponent/components/index.js.map +1 -0
- package/dist/components/StoryComponent/index.d.ts +2 -0
- package/dist/components/StoryComponent/index.d.ts.map +1 -0
- package/dist/components/StoryComponent/index.js +2 -0
- package/dist/components/StoryComponent/index.js.map +1 -0
- package/dist/components/common/Button.d.ts +8 -0
- package/dist/components/common/Button.d.ts.map +1 -0
- package/dist/components/common/Button.js +64 -0
- package/dist/components/common/Button.js.map +1 -0
- package/dist/components/common/Spinner.d.ts +2 -0
- package/dist/components/common/Spinner.d.ts.map +1 -0
- package/dist/components/common/Spinner.js +3 -0
- package/dist/components/common/Spinner.js.map +1 -0
- package/dist/components/common/Tooltip.d.ts +12 -0
- package/dist/components/common/Tooltip.d.ts.map +1 -0
- package/dist/components/common/Tooltip.js +28 -0
- package/dist/components/common/Tooltip.js.map +1 -0
- package/dist/components/common/index.d.ts +4 -0
- package/dist/components/common/index.d.ts.map +1 -0
- package/dist/components/common/index.js +4 -0
- package/dist/components/common/index.js.map +1 -0
- package/dist/components/index.d.ts +6 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +6 -0
- package/dist/components/index.js.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useLocalStorage.d.ts +2 -0
- package/dist/hooks/useLocalStorage.d.ts.map +1 -0
- package/dist/hooks/useLocalStorage.js +44 -0
- package/dist/hooks/useLocalStorage.js.map +1 -0
- package/dist/hooks/useSaveLoadMenu.d.ts +2 -0
- package/dist/hooks/useSaveLoadMenu.d.ts.map +1 -0
- package/dist/hooks/useSaveLoadMenu.js +11 -0
- package/dist/hooks/useSaveLoadMenu.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/index.css +1809 -0
- package/dist/tests/ErrorBoundary.test.d.ts +2 -0
- package/dist/tests/ErrorBoundary.test.d.ts.map +1 -0
- package/dist/tests/ErrorBoundary.test.js +317 -0
- package/dist/tests/ErrorBoundary.test.js.map +1 -0
- package/dist/tests/dexie.mock.d.ts +56 -0
- package/dist/tests/dexie.mock.d.ts.map +1 -0
- package/dist/tests/dexie.mock.js +113 -0
- package/dist/tests/dexie.mock.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.test.d.ts","sourceRoot":"","sources":["../../src/tests/ErrorBoundary.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { Game } from "@react-text-game/core";
|
|
2
|
+
import { cleanup, render, screen, waitFor } from "@testing-library/react";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
4
|
+
import { createElement } from "react";
|
|
5
|
+
import { ErrorBoundary } from "../components/ErrorBoundary";
|
|
6
|
+
// Component that doesn't throw
|
|
7
|
+
const SafeComponent = () => createElement("div", null, "Safe content");
|
|
8
|
+
// Polyfill PromiseRejectionEvent for happy-dom
|
|
9
|
+
class PromiseRejectionEvent extends Event {
|
|
10
|
+
reason;
|
|
11
|
+
promise;
|
|
12
|
+
constructor(type, init) {
|
|
13
|
+
super(type);
|
|
14
|
+
this.reason = init.reason;
|
|
15
|
+
this.promise = init.promise;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
describe("ErrorBoundary", () => {
|
|
19
|
+
let consoleErrorSpy;
|
|
20
|
+
const originalError = console.error;
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
// init game
|
|
23
|
+
Game.init({ gameName: "test" });
|
|
24
|
+
// Suppress console.error during tests
|
|
25
|
+
consoleErrorSpy = mock(() => { });
|
|
26
|
+
console.error = consoleErrorSpy;
|
|
27
|
+
});
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
console.error = originalError;
|
|
30
|
+
cleanup();
|
|
31
|
+
});
|
|
32
|
+
test("renders children when there is no error", () => {
|
|
33
|
+
render(createElement(ErrorBoundary, null, createElement("div", null, "Test content")));
|
|
34
|
+
expect(screen.getByText("Test content")).toBeTruthy();
|
|
35
|
+
});
|
|
36
|
+
test("catches global errors from window.addEventListener", async () => {
|
|
37
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
38
|
+
// Simulate a global error
|
|
39
|
+
const errorEvent = new ErrorEvent("error", {
|
|
40
|
+
error: new Error("Global error test"),
|
|
41
|
+
message: "Global error test",
|
|
42
|
+
filename: "test.js",
|
|
43
|
+
lineno: 42,
|
|
44
|
+
colno: 10,
|
|
45
|
+
});
|
|
46
|
+
window.dispatchEvent(errorEvent);
|
|
47
|
+
await waitFor(() => {
|
|
48
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
49
|
+
});
|
|
50
|
+
expect(screen.getByText("Global error test")).toBeTruthy();
|
|
51
|
+
});
|
|
52
|
+
test("catches unhandled promise rejections", async () => {
|
|
53
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
54
|
+
// Create a promise that we'll reject and handle
|
|
55
|
+
const errorReason = new Error("Promise rejection test");
|
|
56
|
+
const promise = new Promise((_, reject) => {
|
|
57
|
+
setTimeout(() => reject(errorReason), 0);
|
|
58
|
+
});
|
|
59
|
+
// Catch the rejection to prevent it from failing the test
|
|
60
|
+
promise.catch(() => { });
|
|
61
|
+
// Simulate an unhandled promise rejection event
|
|
62
|
+
const rejectionEvent = new PromiseRejectionEvent("unhandledrejection", {
|
|
63
|
+
promise,
|
|
64
|
+
reason: errorReason,
|
|
65
|
+
});
|
|
66
|
+
window.dispatchEvent(rejectionEvent);
|
|
67
|
+
await waitFor(() => {
|
|
68
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
69
|
+
});
|
|
70
|
+
expect(screen.getByText("Promise rejection test")).toBeTruthy();
|
|
71
|
+
});
|
|
72
|
+
test("handles non-Error promise rejections", async () => {
|
|
73
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
74
|
+
// Create a promise that we'll reject with a string
|
|
75
|
+
const promise = new Promise((_, reject) => {
|
|
76
|
+
setTimeout(() => reject("String rejection"), 0);
|
|
77
|
+
});
|
|
78
|
+
// Catch the rejection to prevent it from failing the test
|
|
79
|
+
promise.catch(() => { });
|
|
80
|
+
const rejectionEvent = new PromiseRejectionEvent("unhandledrejection", {
|
|
81
|
+
promise,
|
|
82
|
+
reason: "String rejection",
|
|
83
|
+
});
|
|
84
|
+
window.dispatchEvent(rejectionEvent);
|
|
85
|
+
await waitFor(() => {
|
|
86
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
87
|
+
});
|
|
88
|
+
expect(screen.getByText("String rejection")).toBeTruthy();
|
|
89
|
+
});
|
|
90
|
+
test("removes event listeners on unmount", () => {
|
|
91
|
+
const removeEventListenerSpy = mock(window.removeEventListener.bind(window));
|
|
92
|
+
window.removeEventListener = removeEventListenerSpy;
|
|
93
|
+
const { unmount } = render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
94
|
+
unmount();
|
|
95
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith("error", expect.any(Function));
|
|
96
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith("unhandledrejection", expect.any(Function));
|
|
97
|
+
});
|
|
98
|
+
test("handles error events without error object", async () => {
|
|
99
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
100
|
+
// Simulate error event with only message
|
|
101
|
+
const errorEvent = new ErrorEvent("error", {
|
|
102
|
+
message: "Message only error",
|
|
103
|
+
});
|
|
104
|
+
window.dispatchEvent(errorEvent);
|
|
105
|
+
await waitFor(() => {
|
|
106
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
107
|
+
});
|
|
108
|
+
expect(screen.getByText("Message only error")).toBeTruthy();
|
|
109
|
+
});
|
|
110
|
+
test("handles resource load errors", async () => {
|
|
111
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
112
|
+
// Create a mock image element
|
|
113
|
+
const img = document.createElement("img");
|
|
114
|
+
img.id = "test-image";
|
|
115
|
+
img.className = "test-class";
|
|
116
|
+
const errorEvent = new ErrorEvent("error", {
|
|
117
|
+
message: "",
|
|
118
|
+
});
|
|
119
|
+
// Set the target on the event
|
|
120
|
+
Object.defineProperty(errorEvent, "target", {
|
|
121
|
+
value: img,
|
|
122
|
+
writable: false,
|
|
123
|
+
});
|
|
124
|
+
window.dispatchEvent(errorEvent);
|
|
125
|
+
await waitFor(() => {
|
|
126
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
127
|
+
});
|
|
128
|
+
const errorText = screen.getAllByText(/Resource error or unhandled error/)[0]?.textContent;
|
|
129
|
+
expect(errorText?.includes("IMG")).toBe(true);
|
|
130
|
+
});
|
|
131
|
+
test("prevents default on global error events", async () => {
|
|
132
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
133
|
+
const preventDefaultMock = mock(() => { });
|
|
134
|
+
const errorEvent = new ErrorEvent("error", {
|
|
135
|
+
error: new Error("Test"),
|
|
136
|
+
message: "Test",
|
|
137
|
+
});
|
|
138
|
+
errorEvent.preventDefault = preventDefaultMock;
|
|
139
|
+
window.dispatchEvent(errorEvent);
|
|
140
|
+
expect(preventDefaultMock).toHaveBeenCalled();
|
|
141
|
+
});
|
|
142
|
+
test("prevents default on promise rejection events", async () => {
|
|
143
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
144
|
+
const preventDefaultMock = mock(() => { });
|
|
145
|
+
const rejectionEvent = new PromiseRejectionEvent("unhandledrejection", {
|
|
146
|
+
promise: Promise.resolve(),
|
|
147
|
+
reason: new Error("Test"),
|
|
148
|
+
});
|
|
149
|
+
rejectionEvent.preventDefault = preventDefaultMock;
|
|
150
|
+
window.dispatchEvent(rejectionEvent);
|
|
151
|
+
expect(preventDefaultMock).toHaveBeenCalled();
|
|
152
|
+
});
|
|
153
|
+
test("calls onError callback for global errors", async () => {
|
|
154
|
+
const onErrorCallback = mock(() => { });
|
|
155
|
+
render(createElement(ErrorBoundary, { onError: onErrorCallback }, createElement(SafeComponent)));
|
|
156
|
+
const errorEvent = new ErrorEvent("error", {
|
|
157
|
+
error: new Error("Callback test"),
|
|
158
|
+
message: "Callback test",
|
|
159
|
+
});
|
|
160
|
+
window.dispatchEvent(errorEvent);
|
|
161
|
+
await waitFor(() => {
|
|
162
|
+
expect(onErrorCallback).toHaveBeenCalled();
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
test("displays default fallback UI for global errors", async () => {
|
|
166
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
167
|
+
const errorEvent = new ErrorEvent("error", {
|
|
168
|
+
error: new Error("UI test error"),
|
|
169
|
+
message: "UI test error",
|
|
170
|
+
});
|
|
171
|
+
window.dispatchEvent(errorEvent);
|
|
172
|
+
await waitFor(() => {
|
|
173
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
174
|
+
expect(screen.getByText("Something went wrong while running the game. This error has been logged.")).toBeTruthy();
|
|
175
|
+
expect(screen.getByText("Try Again")).toBeTruthy();
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
test("uses custom fallback for global errors", async () => {
|
|
179
|
+
const customFallback = mock(() => createElement("div", null, "Custom error UI"));
|
|
180
|
+
render(createElement(ErrorBoundary, { fallback: customFallback }, createElement(SafeComponent)));
|
|
181
|
+
const errorEvent = new ErrorEvent("error", {
|
|
182
|
+
error: new Error("Custom fallback test"),
|
|
183
|
+
message: "Custom fallback test",
|
|
184
|
+
});
|
|
185
|
+
window.dispatchEvent(errorEvent);
|
|
186
|
+
await waitFor(() => {
|
|
187
|
+
expect(screen.getByText("Custom error UI")).toBeTruthy();
|
|
188
|
+
});
|
|
189
|
+
expect(customFallback).toHaveBeenCalled();
|
|
190
|
+
});
|
|
191
|
+
test("reset clears error state", async () => {
|
|
192
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
193
|
+
const errorEvent = new ErrorEvent("error", {
|
|
194
|
+
error: new Error("Reset test"),
|
|
195
|
+
message: "Reset test",
|
|
196
|
+
});
|
|
197
|
+
window.dispatchEvent(errorEvent);
|
|
198
|
+
await waitFor(() => {
|
|
199
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
200
|
+
});
|
|
201
|
+
const resetButton = screen.getByText("Try Again");
|
|
202
|
+
resetButton.click();
|
|
203
|
+
await waitFor(() => {
|
|
204
|
+
expect(screen.queryByText("Game Error")).toBeNull();
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
test("error details can be expanded", async () => {
|
|
208
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
209
|
+
const errorEvent = new ErrorEvent("error", {
|
|
210
|
+
error: new Error("Details test"),
|
|
211
|
+
message: "Details test",
|
|
212
|
+
});
|
|
213
|
+
window.dispatchEvent(errorEvent);
|
|
214
|
+
await waitFor(() => {
|
|
215
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
216
|
+
});
|
|
217
|
+
const summary = screen.getByText("Error Details");
|
|
218
|
+
expect(summary).toBeTruthy();
|
|
219
|
+
summary.click();
|
|
220
|
+
await waitFor(() => {
|
|
221
|
+
const copyButton = screen.getByTitle("Copy error to clipboard");
|
|
222
|
+
expect(copyButton).toBeTruthy();
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
test("displays error message and stack trace", async () => {
|
|
226
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
227
|
+
const error = new Error("Stack trace test");
|
|
228
|
+
const errorEvent = new ErrorEvent("error", {
|
|
229
|
+
error,
|
|
230
|
+
message: error.message,
|
|
231
|
+
});
|
|
232
|
+
window.dispatchEvent(errorEvent);
|
|
233
|
+
await waitFor(() => {
|
|
234
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
235
|
+
});
|
|
236
|
+
// Click to expand details
|
|
237
|
+
const summary = screen.getByText("Error Details");
|
|
238
|
+
summary.click();
|
|
239
|
+
await waitFor(() => {
|
|
240
|
+
expect(screen.getByText("Stack trace test")).toBeTruthy();
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
test("can copy error to clipboard", async () => {
|
|
244
|
+
const writeTextMock = mock(() => Promise.resolve());
|
|
245
|
+
Object.defineProperty(navigator, "clipboard", {
|
|
246
|
+
value: { writeText: writeTextMock },
|
|
247
|
+
writable: true,
|
|
248
|
+
configurable: true,
|
|
249
|
+
});
|
|
250
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
251
|
+
const error = new Error("Clipboard copy test");
|
|
252
|
+
error.stack = "Error: Clipboard copy test\n at test.ts:1:1";
|
|
253
|
+
const errorEvent = new ErrorEvent("error", {
|
|
254
|
+
error,
|
|
255
|
+
message: error.message,
|
|
256
|
+
});
|
|
257
|
+
window.dispatchEvent(errorEvent);
|
|
258
|
+
await waitFor(() => {
|
|
259
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
260
|
+
});
|
|
261
|
+
// Expand details
|
|
262
|
+
const summary = screen.getByText("Error Details");
|
|
263
|
+
summary.click();
|
|
264
|
+
await waitFor(() => {
|
|
265
|
+
const copyButton = screen.getByTitle("Copy error to clipboard");
|
|
266
|
+
expect(copyButton).toBeTruthy();
|
|
267
|
+
});
|
|
268
|
+
// Click copy button
|
|
269
|
+
const copyButton = screen.getByTitle("Copy error to clipboard");
|
|
270
|
+
copyButton.click();
|
|
271
|
+
await waitFor(() => {
|
|
272
|
+
expect(writeTextMock).toHaveBeenCalled();
|
|
273
|
+
});
|
|
274
|
+
const calls = writeTextMock.mock.calls;
|
|
275
|
+
const copiedText = calls[0]?.[0] || '';
|
|
276
|
+
expect(copiedText.includes("Error: Clipboard copy test")).toBe(true);
|
|
277
|
+
expect(copiedText.includes("Stack Trace:")).toBe(true);
|
|
278
|
+
expect(copiedText.includes("Component Stack:")).toBe(true);
|
|
279
|
+
});
|
|
280
|
+
test("can be closed with close button", async () => {
|
|
281
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
282
|
+
const errorEvent = new ErrorEvent("error", {
|
|
283
|
+
error: new Error("Close test"),
|
|
284
|
+
message: "Close test",
|
|
285
|
+
});
|
|
286
|
+
window.dispatchEvent(errorEvent);
|
|
287
|
+
await waitFor(() => {
|
|
288
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
289
|
+
});
|
|
290
|
+
// Find and click the close button (×)
|
|
291
|
+
const closeButton = screen.getByLabelText("Close error");
|
|
292
|
+
closeButton.click();
|
|
293
|
+
await waitFor(() => {
|
|
294
|
+
expect(screen.queryByText("Game Error")).toBeNull();
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
test("try again button can be clicked", async () => {
|
|
298
|
+
render(createElement(ErrorBoundary, null, createElement(SafeComponent)));
|
|
299
|
+
const errorEvent = new ErrorEvent("error", {
|
|
300
|
+
error: new Error("Try again test"),
|
|
301
|
+
message: "Try again test",
|
|
302
|
+
});
|
|
303
|
+
window.dispatchEvent(errorEvent);
|
|
304
|
+
await waitFor(() => {
|
|
305
|
+
expect(screen.getByText("Game Error")).toBeTruthy();
|
|
306
|
+
});
|
|
307
|
+
const tryAgainButton = screen.getByText("Try Again");
|
|
308
|
+
expect(tryAgainButton).toBeTruthy();
|
|
309
|
+
// Click the try again button
|
|
310
|
+
tryAgainButton.click();
|
|
311
|
+
await waitFor(() => {
|
|
312
|
+
expect(screen.queryByText("Game Error")).toBeNull();
|
|
313
|
+
expect(screen.getByText("Safe content")).toBeTruthy();
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
//# sourceMappingURL=ErrorBoundary.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.test.js","sourceRoot":"","sources":["../../src/tests/ErrorBoundary.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock implementation of Dexie for testing environments
|
|
3
|
+
* Provides an in-memory implementation of IndexedDB functionality
|
|
4
|
+
*/
|
|
5
|
+
interface DexieTable<T = Record<string, unknown>> {
|
|
6
|
+
add(item: T): Promise<number>;
|
|
7
|
+
where(query: Record<string, unknown> | string): DexieWhereClause<T>;
|
|
8
|
+
filter(callback: (item: T) => boolean): DexieCollection<T>;
|
|
9
|
+
toArray(): Promise<T[]>;
|
|
10
|
+
clear(): Promise<void>;
|
|
11
|
+
update(id: number, changes: Partial<T>): Promise<number>;
|
|
12
|
+
}
|
|
13
|
+
interface DexieWhereClause<T = Record<string, unknown>> {
|
|
14
|
+
equals(value: unknown): DexieCollection<T>;
|
|
15
|
+
first(): Promise<T | undefined>;
|
|
16
|
+
delete(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
interface DexieCollection<T = Record<string, unknown>> {
|
|
19
|
+
first(): Promise<T | undefined>;
|
|
20
|
+
toArray(): Promise<T[]>;
|
|
21
|
+
delete(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
declare class MockDexieTable<T extends {
|
|
24
|
+
id?: number;
|
|
25
|
+
} = Record<string, unknown> & {
|
|
26
|
+
id?: number;
|
|
27
|
+
}> implements DexieTable<T> {
|
|
28
|
+
private data;
|
|
29
|
+
private nextId;
|
|
30
|
+
private name;
|
|
31
|
+
constructor(name: string);
|
|
32
|
+
add(item: T): Promise<number>;
|
|
33
|
+
where(query: Record<string, unknown> | string): DexieWhereClause<T>;
|
|
34
|
+
filter(callback: (item: T) => boolean): DexieCollection<T>;
|
|
35
|
+
toArray(): Promise<T[]>;
|
|
36
|
+
clear(): Promise<void>;
|
|
37
|
+
update(id: number, changes: Partial<T>): Promise<number>;
|
|
38
|
+
private createCollection;
|
|
39
|
+
}
|
|
40
|
+
interface MockDexieVersion {
|
|
41
|
+
stores: (schema: Record<string, string>) => MockDexieVersion;
|
|
42
|
+
}
|
|
43
|
+
declare class MockDexie {
|
|
44
|
+
[key: string]: unknown;
|
|
45
|
+
private tables;
|
|
46
|
+
constructor(_databaseName: string);
|
|
47
|
+
version(_versionNumber: number): MockDexieVersion;
|
|
48
|
+
}
|
|
49
|
+
export declare function useLiveQuery<T>(querier: () => Promise<T> | T): T | undefined;
|
|
50
|
+
export default MockDexie;
|
|
51
|
+
export type EntityTable<T extends {
|
|
52
|
+
id?: number;
|
|
53
|
+
}, K extends keyof T> = MockDexieTable<T> & {
|
|
54
|
+
readonly __primaryKey?: K;
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=dexie.mock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dexie.mock.d.ts","sourceRoot":"","sources":["../../src/tests/dexie.mock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock implementation of Dexie for testing environments
|
|
3
|
+
* Provides an in-memory implementation of IndexedDB functionality
|
|
4
|
+
*/
|
|
5
|
+
class MockDexieTable {
|
|
6
|
+
data = new Map();
|
|
7
|
+
nextId = 1;
|
|
8
|
+
name;
|
|
9
|
+
constructor(name) {
|
|
10
|
+
this.name = name;
|
|
11
|
+
}
|
|
12
|
+
async add(item) {
|
|
13
|
+
const id = this.nextId++;
|
|
14
|
+
this.data.set(id, { ...item, id });
|
|
15
|
+
return id;
|
|
16
|
+
}
|
|
17
|
+
where(query) {
|
|
18
|
+
const data = this.data;
|
|
19
|
+
const queryKey = typeof query === "string" ? query : Object.keys(query)[0];
|
|
20
|
+
const queryValue = typeof query === "string" ? undefined : Object.values(query)[0];
|
|
21
|
+
const createCollection = this.createCollection.bind(this);
|
|
22
|
+
return {
|
|
23
|
+
equals(value) {
|
|
24
|
+
const val = queryValue ?? value;
|
|
25
|
+
return createCollection(Array.from(data.values()).filter((item) => item[queryKey] === val));
|
|
26
|
+
},
|
|
27
|
+
async first() {
|
|
28
|
+
const items = Array.from(data.values()).filter((item) => item[queryKey] === queryValue);
|
|
29
|
+
return items[0];
|
|
30
|
+
},
|
|
31
|
+
async delete() {
|
|
32
|
+
const itemsToDelete = Array.from(data.entries()).filter(([, item]) => item[queryKey] === queryValue);
|
|
33
|
+
for (const [id] of itemsToDelete) {
|
|
34
|
+
data.delete(id);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
filter(callback) {
|
|
40
|
+
return this.createCollection(Array.from(this.data.values()).filter(callback));
|
|
41
|
+
}
|
|
42
|
+
async toArray() {
|
|
43
|
+
return Array.from(this.data.values());
|
|
44
|
+
}
|
|
45
|
+
async clear() {
|
|
46
|
+
this.data.clear();
|
|
47
|
+
}
|
|
48
|
+
async update(id, changes) {
|
|
49
|
+
const existing = this.data.get(id);
|
|
50
|
+
if (existing) {
|
|
51
|
+
this.data.set(id, { ...existing, ...changes });
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
createCollection(items) {
|
|
57
|
+
return {
|
|
58
|
+
async first() {
|
|
59
|
+
return items[0];
|
|
60
|
+
},
|
|
61
|
+
async toArray() {
|
|
62
|
+
return items;
|
|
63
|
+
},
|
|
64
|
+
async delete() {
|
|
65
|
+
// In a real implementation, this would delete from the parent table
|
|
66
|
+
// For testing purposes, this is sufficient
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
class MockDexie {
|
|
72
|
+
tables = new Map();
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
74
|
+
constructor(_databaseName) {
|
|
75
|
+
// Store database name for potential debugging
|
|
76
|
+
}
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
78
|
+
version(_versionNumber) {
|
|
79
|
+
const versionObj = {
|
|
80
|
+
stores: (schema) => {
|
|
81
|
+
// Initialize tables based on schema
|
|
82
|
+
for (const tableName of Object.keys(schema)) {
|
|
83
|
+
if (!this.tables.has(tableName)) {
|
|
84
|
+
const table = new MockDexieTable(tableName);
|
|
85
|
+
this.tables.set(tableName, table);
|
|
86
|
+
// Make table accessible as property
|
|
87
|
+
this[tableName] = table;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return versionObj;
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
return versionObj;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Mock the useLiveQuery hook from dexie-react-hooks
|
|
97
|
+
export function useLiveQuery(querier) {
|
|
98
|
+
// In tests, we'll just return undefined or execute the querier synchronously
|
|
99
|
+
// This is a simplified version - adjust based on your testing needs
|
|
100
|
+
try {
|
|
101
|
+
const result = querier();
|
|
102
|
+
if (result instanceof Promise) {
|
|
103
|
+
return undefined; // Return undefined for async queries in tests
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Export default Dexie class
|
|
112
|
+
export default MockDexie;
|
|
113
|
+
//# sourceMappingURL=dexie.mock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dexie.mock.js","sourceRoot":"","sources":["../../src/tests/dexie.mock.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@react-text-game/ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "UI components library for react-text-game",
|
|
5
|
+
"private": false,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "tsc --watch & tsc-alias --watch & bun run build:css --watch",
|
|
12
|
+
"build": "tsc && tsc-alias && bun run build:css",
|
|
13
|
+
"build:css": "mkdir -p dist/styles && bunx @tailwindcss/cli@latest -i src/styles/index.css -o dist/styles/index.css",
|
|
14
|
+
"prepack": "rm -rf dist && bun run build",
|
|
15
|
+
"test-pack": "npm pack --dry-run && bunx publint"
|
|
16
|
+
},
|
|
17
|
+
"author": "laruss",
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public",
|
|
20
|
+
"registry": "https://registry.npmjs.org/"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"tailwind-merge": "^3.3.1"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
31
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
32
|
+
"tailwindcss": "^4.0.0",
|
|
33
|
+
"typescript": "^5",
|
|
34
|
+
"@react-text-game/core": "workspace:*"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^24.6.2",
|
|
38
|
+
"@types/bun": "^1.2.23",
|
|
39
|
+
"@types/react": "^19.0.10",
|
|
40
|
+
"@types/react-dom": "^19.0.5",
|
|
41
|
+
"tsc-alias": "^1.8.16",
|
|
42
|
+
"@tailwindcss/postcss": "^4.0.0",
|
|
43
|
+
"postcss": "^8.4.49"
|
|
44
|
+
},
|
|
45
|
+
"imports": {
|
|
46
|
+
"#*": "./dist/*"
|
|
47
|
+
},
|
|
48
|
+
"exports": {
|
|
49
|
+
".": {
|
|
50
|
+
"types": "./dist/index.d.ts",
|
|
51
|
+
"import": "./dist/index.js"
|
|
52
|
+
},
|
|
53
|
+
"./styles": "./dist/styles/index.css"
|
|
54
|
+
}
|
|
55
|
+
}
|