@vickbk/tests 0.1.0 → 0.2.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/dist/vitest.mjs CHANGED
@@ -1,460 +1,6 @@
1
- import { fireEvent as fireEvent$1, screen, within } from "@testing-library/react";
2
- import userEvent from "@testing-library/user-event";
3
- import { expect, vi } from "vitest";
4
- //#region src/features/vitest/modules/dom/modules/toggle-event/utils/togglePolyfill.ts
5
- /**
6
- * Creates the browser ToggleEvent instance used by the fireEvent.toggle polyfill.
7
- *
8
- * @param type - Event type to dispatch.
9
- * @param initDict - Optional toggle event initialization state.
10
- * @returns A ToggleEvent matching the requested state.
11
- * @example
12
- * ```ts
13
- * const event = createToggleEvent("toggle", {
14
- * oldState: "closed",
15
- * newState: "open",
16
- * });
17
- * ```
18
- */
19
- function createToggleEvent(type, initDict = {
20
- oldState: "closed",
21
- newState: "open"
22
- }) {
23
- if (typeof globalThis.ToggleEvent === "undefined") {
24
- class ToggleEventPolyfill extends Event {
25
- oldState;
26
- newState;
27
- source = null;
28
- constructor(eventType, eventInitDict = {}) {
29
- super(eventType, eventInitDict);
30
- this.oldState = eventInitDict.oldState ?? "closed";
31
- this.newState = eventInitDict.newState ?? "open";
32
- }
33
- }
34
- globalThis.ToggleEvent = ToggleEventPolyfill;
35
- }
36
- return new globalThis.ToggleEvent(type, {
37
- bubbles: false,
38
- cancelable: false,
39
- ...initDict
40
- });
41
- }
42
- /**
43
- * Polyfills `fireEvent.toggle` for tests by dispatching a native ToggleEvent.
44
- *
45
- * @param element - Element or window to dispatch the toggle event on.
46
- * @param initDict - Optional state values for the toggle transition.
47
- * @returns Whether the event dispatch completed successfully.
48
- * @example
49
- * ```ts
50
- * fireEvent.toggle(document.body, { newState: "open" });
51
- * ```
52
- */
53
- function togglePolyfill(element, initDict = {
54
- oldState: "closed",
55
- newState: "open"
56
- }) {
57
- const event = createToggleEvent("toggle", initDict);
58
- return fireEvent$1(element, event);
59
- }
60
- //#endregion
61
- //#region src/features/vitest/modules/dom/modules/toggle-event/utils/fireEvent.ts
62
- const callableFireEvent = (...args) => fireEvent$1(...args);
63
- /**
64
- * Testing Library's fireEvent API with an additional `toggle` event helper.
65
- *
66
- * The exported object copies the standard `fireEvent` properties and adds
67
- * `toggle`, which dispatches the toggle event through `togglePolyfill`.
68
- * It does not install the extension onto Testing Library's original export.
69
- *
70
- * Standard Testing Library event helpers remain available, including
71
- * `click`, `change`, `input`, `submit`, `focus`, and keyboard/mouse events.
72
- *
73
- * @remarks
74
- * The `toggle` helper defaults to a transition from `closed` to `open`.
75
- * Call-specific configuration overrides those defaults. This helper does
76
- * not maintain state between calls.
77
- *
78
- * @example
79
- * ```ts
80
- * import { fireEvent } from "@vickbk/tests/vitest";
81
- *
82
- * const disclosure = document.querySelector("details")!;
83
- *
84
- * fireEvent.toggle(disclosure);
85
- * fireEvent.toggle(disclosure, { newState: "closed" });
86
- * ```
87
- *
88
- * @example
89
- * ```ts
90
- * import { fireEvent } from "@vickbk/tests/vitest";
91
- *
92
- * const button = document.querySelector("button")!;
93
- *
94
- * fireEvent.click(button);
95
- * ```
96
- */
97
- const fireEvent = Object.assign(callableFireEvent, fireEvent$1, {
98
- /**
99
- * Dispatches a toggle event using the toggle polyfill.
100
- *
101
- * @param element - The document, element, node, or window receiving the event.
102
- * @param initDict - Optional old/new state overrides for this dispatch.
103
- * @returns The result returned by `togglePolyfill`.
104
- *
105
- * @example
106
- * ```ts
107
- * fireEvent.toggle(document.body, {
108
- * oldState: "closed",
109
- * newState: "open",
110
- * });
111
- * ```
112
- */
113
- toggle: (element, initDict) => togglePolyfill(element, {
114
- oldState: "closed",
115
- newState: "open",
116
- ...initDict
117
- }) });
118
- //#endregion
119
- //#region src/shared/regex/utils/escape-regex.ts
120
- function escapeRegExp(str) {
121
- if (typeof RegExp.escape === "function") return RegExp.escape(str);
122
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
123
- }
124
- //#endregion
125
- //#region src/shared/regex/utils/pattern-to-regex.ts
126
- function patternToRegex(target, flags = "i") {
127
- return typeof target === "string" ? new RegExp(escapeRegExp(target), flags) : target;
128
- }
129
- //#endregion
130
- //#region src/features/vitest/modules/dom/utils/getSearchArea.ts
131
- /**
132
- * Returns the Testing Library query API for a container or the whole document.
133
- *
134
- * @param container Optional element to scope queries to.
135
- * @returns The scoped query API, or the global `screen` query API.
136
- * @example
137
- * ```ts
138
- * const queries = getSearchArea(formElement);
139
- * queries.getByRole("button", { name: "Submit" });
140
- * ```
141
- */
142
- function getSearchArea(container) {
143
- return container ? within(container) : screen;
144
- }
145
- //#endregion
146
- //#region src/features/vitest/modules/dom/utils/clickLabelInput.ts
147
- /**
148
- * Simulates clicking an input found by its label or placeholder.
149
- *
150
- * @param label Label or placeholder text/regular expression identifying the input.
151
- * @param container Optional element that limits the input search.
152
- * @returns A promise that resolves after the click interaction completes.
153
- * @example
154
- * ```ts
155
- * await clickLabelInput("Email address");
156
- * ```
157
- */
158
- async function clickLabelInput(label, container) {
159
- const user = userEvent.setup();
160
- const regex = patternToRegex(label);
161
- const searchArea = getSearchArea(container);
162
- const element = typeof label === "string" && label.length === 0 ? searchArea.queryByPlaceholderText(regex) || searchArea.getByLabelText(regex) : searchArea.queryByLabelText(regex) || searchArea.getByPlaceholderText(regex);
163
- await user.click(element);
164
- }
165
- //#endregion
166
- //#region src/features/vitest/modules/dom/utils/getCheckboxRadio.ts
167
- /**
168
- * Finds a checkbox or radio control by its accessible name.
169
- *
170
- * @param target Accessible name to match, as text or a regular expression.
171
- * @param container Optional element that limits the search.
172
- * @returns The matching checkbox or radio input.
173
- * @throws If neither a checkbox nor a radio control matches the target.
174
- * @example
175
- * ```ts
176
- * const consent = getCheckboxRadio("Accept terms");
177
- * expect(consent).toBeChecked();
178
- * ```
179
- */
180
- function getCheckboxRadio(target, container) {
181
- const regex = patternToRegex(target);
182
- const searchArea = getSearchArea(container);
183
- const element = searchArea.queryByRole("checkbox", { name: regex }) || searchArea.queryByRole("radio", { name: regex });
184
- if (element) return element;
185
- throw new Error(`Unable to find a checkbox or radio control named "${String(target)}".`);
186
- }
187
- //#endregion
188
- //#region src/features/vitest/modules/dom/utils/isChecked.ts
189
- /**
190
- * Asserts that the radio button or checkbox matching the accessible name is checked.
191
- *
192
- * @param selector Accessible label text or regular expression for the control.
193
- * @param container Optional element that limits the control search.
194
- * @returns Nothing; throws an assertion error if the control is absent or unchecked.
195
- * @example
196
- * ```ts
197
- * isChecked("Accept terms");
198
- * ```
199
- */
200
- function isChecked(selector, container) {
201
- expect(getCheckboxRadio(selector, container)).toBeChecked();
202
- }
203
- //#endregion
204
- //#region src/features/vitest/modules/dom/utils/isNotChecked.ts
205
- /**
206
- * Asserts that the radio button or checkbox matching the accessible name is unchecked.
207
- *
208
- * @param selector Accessible label text or regular expression for the control.
209
- * @param container Optional element that limits the control search.
210
- * @returns Nothing; throws an assertion error if the control is absent or checked.
211
- * @example
212
- * ```ts
213
- * isNotChecked("Subscribe to updates");
214
- * ```
215
- */
216
- function isNotChecked(selector, container) {
217
- expect(getCheckboxRadio(selector, container)).not.toBeChecked();
218
- }
219
- //#endregion
220
- //#region src/features/vitest/modules/dom/utils/shouldHaveAttributes.ts
221
- /**
222
- * Asserts that an HTMLElement possesses the expected set of DOM attributes and values.
223
- *
224
- * Handles string/numeric values, boolean attributes (true = present, false = absent),
225
- * and null/undefined values (absent).
226
- *
227
- * @param element The DOM element whose attributes will be checked.
228
- * @param attributes Attribute names mapped to their expected values.
229
- * @returns Nothing; throws an assertion error when any attribute does not match.
230
- * @example
231
- * ```ts
232
- * shouldHaveAttributes(input, { required: true, "aria-label": "Email" });
233
- * ```
234
- */
235
- function shouldHaveAttributes(element, attributes) {
236
- Object.entries(attributes).forEach(([key, value]) => {
237
- if (value === null || value === void 0 || value === false) expect(element).not.toHaveAttribute(key);
238
- else if (value === true) expect(element).toHaveAttribute(key);
239
- else expect(element).toHaveAttribute(key, String(value));
240
- });
241
- }
242
- //#endregion
243
- //#region src/features/vitest/modules/dom/utils/shouldHaveTestId.ts
244
- /**
245
- * Asserts that elements with all supplied test IDs are present in the document.
246
- *
247
- * @param ids One or more `data-testid` values to locate.
248
- * @returns The elements found, in the same order as the supplied IDs.
249
- * @example
250
- * ```ts
251
- * const [submitButton] = shouldHaveTestId("submit-button");
252
- * ```
253
- */
254
- function shouldHaveTestId(...ids) {
255
- const testElements = ids.map((id) => screen.getByTestId(id));
256
- testElements.forEach((element) => expect(element).toBeInTheDocument());
257
- return testElements;
258
- }
259
- //#endregion
260
- //#region src/features/vitest/modules/dom/utils/shouldNotHaveTestId.ts
261
- /**
262
- * Asserts that elements with all supplied test IDs are absent from the document.
263
- *
264
- * @param ids One or more `data-testid` values to verify are absent.
265
- * @returns The query results (`null` for each absent element), in ID order.
266
- * @example
267
- * ```ts
268
- * shouldNotHaveTestId("loading-spinner");
269
- * ```
270
- */
271
- function shouldNotHaveTestId(...ids) {
272
- const testElements = ids.map((id) => screen.queryByTestId(id));
273
- testElements.forEach((element) => expect(element).not.toBeInTheDocument());
274
- return testElements;
275
- }
276
- //#endregion
277
- //#region src/features/vitest/modules/dom/utils/shouldGetByText.ts
278
- /**
279
- * Creates assertion/element pairs for text matchers, supporting a zero-based occurrence index.
280
- *
281
- * @param texts Text strings, regular expressions, or `[matcher, occurrenceIndex]` pairs.
282
- * @returns Assertion and matching-element pairs, with `null` for missing text.
283
- * @example
284
- * ```ts
285
- * const [{ expected, element }] = shouldGetByText(["Item", 1]);
286
- * ```
287
- */
288
- function shouldGetByText(...texts) {
289
- return texts.map((text) => {
290
- if (Array.isArray(text)) {
291
- const [matcher, nth] = text;
292
- const element = screen.queryAllByText(patternToRegex(matcher))[nth] ?? null;
293
- return {
294
- expected: expect(element),
295
- element
296
- };
297
- }
298
- const element = screen.queryByText(patternToRegex(text));
299
- return {
300
- expected: expect(element),
301
- element
302
- };
303
- });
304
- }
305
- //#endregion
306
- //#region src/features/vitest/modules/dom/utils/shouldNotSee.ts
307
- /**
308
- * Asserts that none of the supplied text matchers appear in the document.
309
- *
310
- * @param texts Text strings or regular expressions that must be absent.
311
- * @returns Nothing; throws an assertion error if any text is found.
312
- * @example
313
- * ```ts
314
- * shouldNotSee("Error", /failed/i);
315
- * ```
316
- */
317
- const shouldNotSee = (...texts) => {
318
- shouldGetByText(...texts).forEach(({ expected }) => expected.not.toBeInTheDocument());
319
- };
320
- //#endregion
321
- //#region src/features/vitest/modules/dom/utils/shouldSee.ts
322
- /**
323
- * Asserts that each requested text matcher is present in the document.
324
- *
325
- * @param texts Text strings, regular expressions, or `[matcher, occurrenceIndex]` pairs.
326
- * @returns The matching elements in the same order as the supplied matchers.
327
- * @example
328
- * ```ts
329
- * const [heading] = shouldSee("Welcome");
330
- * ```
331
- */
332
- const shouldSee = (...texts) => {
333
- return shouldGetByText(...texts).map(({ expected, element }) => {
334
- expected.toBeInTheDocument();
335
- return element;
336
- });
337
- };
338
- //#endregion
339
- //#region src/features/vitest/modules/dom/utils/togglePopover.ts
340
- /**
341
- * Dispatches a toggle event on the first element matching a selector.
342
- *
343
- * @param options Selector, optional search container, and target open/closed state.
344
- * @returns The matched element, or `undefined` when no matching element exists.
345
- * @example
346
- * ```ts
347
- * const popover = togglePopover({ selector: "#help", newState: "open" });
348
- * ```
349
- */
350
- function togglePopover({ container, selector, newState = "open" }) {
351
- const element = (container ?? document).querySelector(selector);
352
- if (!element) return;
353
- fireEvent.toggle(element, { newState });
354
- return element;
355
- }
356
- //#endregion
357
- //#region src/features/vitest/modules/dom/utils/userClicks.ts
358
- /**
359
- * Simulates a user click on a button with the requested name, or matching text.
360
- *
361
- * @param target Button accessible name or text string/regular expression.
362
- * @param container Optional element that limits the target search.
363
- * @returns A promise that resolves after the click interaction completes.
364
- * @example
365
- * ```ts
366
- * await userClicks("Save");
367
- * ```
368
- */
369
- const userClicks = async (target, container) => {
370
- const user = userEvent.setup();
371
- const regex = patternToRegex(target);
372
- const searchArea = container ? within(container) : screen;
373
- const element = searchArea.queryByRole("button", { name: regex }) || searchArea.getByText(regex);
374
- await user.click(element);
375
- };
376
- //#endregion
377
- //#region src/features/vitest/modules/dom/utils/getTextBox.ts
378
- /**
379
- * Finds a text-entry control by its accessible name or placeholder.
380
- *
381
- * Supported controls are text-like inputs, textareas, and elements exposed
382
- * with the textbox role. A matching non-text element is rejected.
383
- *
384
- * @param target Accessible name or placeholder to match, as text or a regular expression.
385
- * @param container Optional element that limits the search.
386
- * @returns The matching textbox element.
387
- * @throws If no textbox matches, or a placeholder match is not a text-entry control.
388
- * @example
389
- * ```ts
390
- * const email = getTextBox("Email address");
391
- * const notes = getTextBox("Notes", dialog);
392
- * ```
393
- */
394
- function getTextBox(target, container) {
395
- const regex = patternToRegex(target);
396
- const searchArea = getSearchArea(container);
397
- const textBox = searchArea.queryByRole("textbox", { name: regex });
398
- if (textBox) return textBox;
399
- const placeholderMatch = searchArea.queryByPlaceholderText(regex);
400
- if (placeholderMatch) {
401
- const isTextInput = placeholderMatch instanceof HTMLInputElement && [
402
- "text",
403
- "search",
404
- "email",
405
- "url",
406
- "tel",
407
- "password"
408
- ].includes(placeholderMatch.type);
409
- const isTextArea = placeholderMatch instanceof HTMLTextAreaElement;
410
- const isContentEditable = placeholderMatch.getAttribute("contenteditable") === "true" && placeholderMatch.getAttribute("role") === "textbox";
411
- if (isTextInput || isTextArea || isContentEditable) return placeholderMatch;
412
- throw new Error(`Element matching placeholder "${String(target)}" is not a text-entry control.`);
413
- }
414
- return searchArea.getByRole("textbox", { name: regex });
415
- }
416
- //#endregion
417
- //#region src/features/vitest/modules/dom/utils/userTypes.ts
418
- /**
419
- * Replaces the value of a textbox found by its label, placeholder, or textbox name.
420
- *
421
- * @param target Accessible label, placeholder, or textbox name as text or a regex.
422
- * @param text Text to type after clearing the existing value.
423
- * @param container Optional element that limits the textbox search.
424
- * @param user User-event instance used for the interaction; defaults to a new instance.
425
- * @returns A promise resolving to the textbox that was updated.
426
- * @example
427
- * ```ts
428
- * const emailInput = await userTypes("Email", "person@example.com");
429
- * ```
430
- */
431
- const userTypes = async (target, text, container, user = userEvent.setup()) => {
432
- const element = getTextBox(target, container);
433
- await user.clear(element);
434
- if (text) await user.type(element, text);
435
- return element;
436
- };
437
- //#endregion
438
- //#region src/features/vitest/modules/dom/utils/userTypesMultiple.ts
439
- /**
440
- * Replaces the values of multiple textboxes, located by their respective selectors.
441
- *
442
- * @param inputs Object mapping each textbox label/placeholder to the text to enter.
443
- * @param container Optional element that limits all textbox searches.
444
- * @returns A promise resolving to an object mapping each selector to its updated textbox.
445
- * @example
446
- * ```ts
447
- * const fields = await userTypesMultiple({ Email: "person@example.com", Name: "Pat" });
448
- * ```
449
- */
450
- async function userTypesMultiple(inputs, container) {
451
- const entries = Object.entries(inputs);
452
- const outputs = {};
453
- for (const [selector, value] of entries) outputs[selector] = await userTypes(selector, value, container);
454
- return outputs;
455
- }
456
- //#endregion
457
- //#region src/features/vitest/modules/promises/utils/resolvedPromise.ts
1
+ import { n as shutConsole, t as resetConsole } from "./console-Cf1taTRK.mjs";
2
+ import { a as shouldSee, c as shouldHaveTestId, d as isChecked, f as clickLabelInput, i as togglePopover, l as shouldHaveAttributes, n as userTypes, o as shouldNotSee, p as fireEvent, r as userClicks, s as shouldNotHaveTestId, t as userTypesMultiple, u as isNotChecked } from "./dom-DeHbD1ni.mjs";
3
+ //#region src/features/promises/utils/resolvedPromise.ts
458
4
  /**
459
5
  * Creates a fulfilled promise augmented with Vitest's fulfilled-promise metadata.
460
6
  *
@@ -466,7 +12,7 @@ async function userTypesMultiple(inputs, container) {
466
12
  * expect(payload).toEqual({ id: 1 });
467
13
  * ```
468
14
  */
469
- function resolvedPromise(value) {
15
+ function resolvedPromise$1(value) {
470
16
  const promise = Promise.resolve(value);
471
17
  return Object.assign(promise, {
472
18
  status: "fulfilled",
@@ -474,7 +20,7 @@ function resolvedPromise(value) {
474
20
  });
475
21
  }
476
22
  //#endregion
477
- //#region src/features/vitest/modules/promises/utils/rejectedPromise.ts
23
+ //#region src/features/promises/utils/rejectedPromise.ts
478
24
  /**
479
25
  * Creates a rejected promise augmented with Vitest's rejected-promise metadata.
480
26
  *
@@ -485,7 +31,7 @@ function resolvedPromise(value) {
485
31
  * await expect(rejectedPromise(new Error("Request failed"))).rejects.toThrow("Request failed");
486
32
  * ```
487
33
  */
488
- function rejectedPromise(reason = void 0) {
34
+ function rejectedPromise$1(reason = void 0) {
489
35
  const promise = Promise.reject(reason);
490
36
  promise.catch((error) => error);
491
37
  return Object.assign(promise, {
@@ -494,40 +40,17 @@ function rejectedPromise(reason = void 0) {
494
40
  });
495
41
  }
496
42
  //#endregion
497
- //#region src/features/vitest/utils/console.ts
498
- const CONSOLES = [
499
- "log",
500
- "warn",
501
- "error"
502
- ];
503
- let activeSpies = [];
43
+ //#region src/features/vitest/index.ts
504
44
  /**
505
- * Suppresses console.log, console.warn, and console.error until resetConsole runs.
506
- *
507
- * @example
508
- * ```ts
509
- * beforeEach(shutConsole);
510
- * afterEach(resetConsole);
511
- * ```
45
+ * @deprecated Import `rejectedPromise` from `@vickbk/tests/promises` instead.
46
+ * This re-export is retained for backward compatibility.
512
47
  */
513
- function shutConsole() {
514
- resetConsole();
515
- activeSpies = CONSOLES.map((cons) => vi.spyOn(console, cons).mockImplementation(() => {}));
516
- }
48
+ const rejectedPromise = rejectedPromise$1;
517
49
  /**
518
- * Restores the console methods most recently suppressed by shutConsole.
519
- *
520
- * @example
521
- * ```ts
522
- * shutConsole();
523
- * // Run code whose console output should be ignored.
524
- * resetConsole();
525
- * ```
50
+ * @deprecated Import `resolvedPromise` from `@vickbk/tests/promises` instead.
51
+ * This re-export is retained for backward compatibility.
526
52
  */
527
- function resetConsole() {
528
- for (const spy of activeSpies) spy.mockRestore();
529
- activeSpies = [];
530
- }
53
+ const resolvedPromise = resolvedPromise$1;
531
54
  //#endregion
532
55
  export { clickLabelInput, fireEvent, isChecked, isNotChecked, rejectedPromise, resetConsole, resolvedPromise, shouldHaveAttributes, shouldHaveTestId, shouldNotHaveTestId, shouldNotSee, shouldSee, shutConsole, togglePopover, userClicks, userTypes, userTypesMultiple };
533
56
 
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.mjs","names":["fireEvent","rtlFireEvent"],"sources":["../src/features/vitest/modules/dom/modules/toggle-event/utils/togglePolyfill.ts","../src/features/vitest/modules/dom/modules/toggle-event/utils/fireEvent.ts","../src/shared/regex/utils/escape-regex.ts","../src/shared/regex/utils/pattern-to-regex.ts","../src/features/vitest/modules/dom/utils/getSearchArea.ts","../src/features/vitest/modules/dom/utils/clickLabelInput.ts","../src/features/vitest/modules/dom/utils/getCheckboxRadio.ts","../src/features/vitest/modules/dom/utils/isChecked.ts","../src/features/vitest/modules/dom/utils/isNotChecked.ts","../src/features/vitest/modules/dom/utils/shouldHaveAttributes.ts","../src/features/vitest/modules/dom/utils/shouldHaveTestId.ts","../src/features/vitest/modules/dom/utils/shouldNotHaveTestId.ts","../src/features/vitest/modules/dom/utils/shouldGetByText.ts","../src/features/vitest/modules/dom/utils/shouldNotSee.ts","../src/features/vitest/modules/dom/utils/shouldSee.ts","../src/features/vitest/modules/dom/utils/togglePopover.ts","../src/features/vitest/modules/dom/utils/userClicks.ts","../src/features/vitest/modules/dom/utils/getTextBox.ts","../src/features/vitest/modules/dom/utils/userTypes.ts","../src/features/vitest/modules/dom/utils/userTypesMultiple.ts","../src/features/vitest/modules/promises/utils/resolvedPromise.ts","../src/features/vitest/modules/promises/utils/rejectedPromise.ts","../src/features/vitest/utils/console.ts"],"sourcesContent":["import { fireEvent } from \"@testing-library/react\";\r\nimport type { ToggleConfig } from \"./types\";\r\n\r\n/**\r\n * Creates the browser ToggleEvent instance used by the fireEvent.toggle polyfill.\r\n *\r\n * @param type - Event type to dispatch.\r\n * @param initDict - Optional toggle event initialization state.\r\n * @returns A ToggleEvent matching the requested state.\r\n * @example\r\n * ```ts\r\n * const event = createToggleEvent(\"toggle\", {\r\n * oldState: \"closed\",\r\n * newState: \"open\",\r\n * });\r\n * ```\r\n */\r\nexport function createToggleEvent(\r\n type: string,\r\n initDict: Partial<ToggleConfig> = {\r\n oldState: \"closed\",\r\n newState: \"open\",\r\n },\r\n): ToggleEvent {\r\n if (typeof globalThis.ToggleEvent === \"undefined\") {\r\n class ToggleEventPolyfill extends Event {\r\n oldState: string;\r\n newState: string;\r\n source: Element | null = null;\r\n\r\n constructor(eventType: string, eventInitDict: ToggleEventInit = {}) {\r\n super(eventType, eventInitDict);\r\n this.oldState = (eventInitDict as Partial<ToggleConfig>).oldState ?? \"closed\";\r\n this.newState = (eventInitDict as Partial<ToggleConfig>).newState ?? \"open\";\r\n }\r\n }\r\n\r\n globalThis.ToggleEvent = ToggleEventPolyfill as typeof ToggleEvent;\r\n }\r\n\r\n return new globalThis.ToggleEvent(type, {\r\n bubbles: false,\r\n cancelable: false,\r\n ...initDict,\r\n });\r\n}\r\n\r\n/**\r\n * Polyfills `fireEvent.toggle` for tests by dispatching a native ToggleEvent.\r\n *\r\n * @param element - Element or window to dispatch the toggle event on.\r\n * @param initDict - Optional state values for the toggle transition.\r\n * @returns Whether the event dispatch completed successfully.\r\n * @example\r\n * ```ts\r\n * fireEvent.toggle(document.body, { newState: \"open\" });\r\n * ```\r\n */\r\nexport function togglePolyfill(\r\n element: Document | Element | Node | Window,\r\n initDict: Partial<ToggleConfig> = {\r\n oldState: \"closed\",\r\n newState: \"open\",\r\n },\r\n): boolean {\r\n const event = createToggleEvent(\"toggle\", initDict);\r\n return fireEvent(element, event);\r\n}\r\n","import { fireEvent as rtlFireEvent } from \"@testing-library/react\";\r\nimport { togglePolyfill } from \"./togglePolyfill\";\r\nimport type { ToggleConfig, ToggleFireEventExtensions } from \"./types\";\r\n\r\nconst callableFireEvent = (...args: Parameters<typeof rtlFireEvent>) =>\r\n rtlFireEvent(...args);\r\n/**\r\n * Testing Library's fireEvent API with an additional `toggle` event helper.\r\n *\r\n * The exported object copies the standard `fireEvent` properties and adds\r\n * `toggle`, which dispatches the toggle event through `togglePolyfill`.\r\n * It does not install the extension onto Testing Library's original export.\r\n *\r\n * Standard Testing Library event helpers remain available, including\r\n * `click`, `change`, `input`, `submit`, `focus`, and keyboard/mouse events.\r\n *\r\n * @remarks\r\n * The `toggle` helper defaults to a transition from `closed` to `open`.\r\n * Call-specific configuration overrides those defaults. This helper does\r\n * not maintain state between calls.\r\n *\r\n * @example\r\n * ```ts\r\n * import { fireEvent } from \"@vickbk/tests/vitest\";\r\n *\r\n * const disclosure = document.querySelector(\"details\")!;\r\n *\r\n * fireEvent.toggle(disclosure);\r\n * fireEvent.toggle(disclosure, { newState: \"closed\" });\r\n * ```\r\n *\r\n * @example\r\n * ```ts\r\n * import { fireEvent } from \"@vickbk/tests/vitest\";\r\n *\r\n * const button = document.querySelector(\"button\")!;\r\n *\r\n * fireEvent.click(button);\r\n * ```\r\n */\r\nexport const fireEvent = Object.assign(callableFireEvent, rtlFireEvent, {\r\n /**\r\n * Dispatches a toggle event using the toggle polyfill.\r\n *\r\n * @param element - The document, element, node, or window receiving the event.\r\n * @param initDict - Optional old/new state overrides for this dispatch.\r\n * @returns The result returned by `togglePolyfill`.\r\n *\r\n * @example\r\n * ```ts\r\n * fireEvent.toggle(document.body, {\r\n * oldState: \"closed\",\r\n * newState: \"open\",\r\n * });\r\n * ```\r\n */\r\n toggle: (\r\n element: Document | Element | Node | Window,\r\n initDict?: Partial<ToggleConfig>,\r\n ) =>\r\n togglePolyfill(element, {\r\n oldState: \"closed\",\r\n newState: \"open\",\r\n ...initDict,\r\n }),\r\n}) as typeof rtlFireEvent & ToggleFireEventExtensions;\r\n","export function escapeRegExp(str: string): string {\r\n if (typeof RegExp.escape === \"function\") {\r\n return RegExp.escape(str);\r\n }\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n","import { TEXT_PATTERN } from \"../types\";\r\nimport { escapeRegExp } from \"./escape-regex\";\r\n\r\nexport function patternToRegex(\r\n target: TEXT_PATTERN,\r\n flags: string = \"i\",\r\n): RegExp {\r\n return typeof target === \"string\"\r\n ? new RegExp(escapeRegExp(target), flags)\r\n : target;\r\n}\r\n","import { screen, within } from \"@testing-library/react\";\r\n\r\n/**\r\n * Returns the Testing Library query API for a container or the whole document.\r\n *\r\n * @param container Optional element to scope queries to.\r\n * @returns The scoped query API, or the global `screen` query API.\r\n * @example\r\n * ```ts\r\n * const queries = getSearchArea(formElement);\r\n * queries.getByRole(\"button\", { name: \"Submit\" });\r\n * ```\r\n */\r\nexport function getSearchArea(container?: HTMLElement) {\r\n return container ? within(container) : screen;\r\n}\r\n","import type { TEXT_PATTERN } from \"@/shared/regex\";\r\nimport { patternToRegex } from \"@/shared/regex\";\r\nimport userEvent from \"@testing-library/user-event\";\r\nimport { getSearchArea } from \"./getSearchArea\";\r\n\r\n/**\r\n * Simulates clicking an input found by its label or placeholder.\r\n *\r\n * @param label Label or placeholder text/regular expression identifying the input.\r\n * @param container Optional element that limits the input search.\r\n * @returns A promise that resolves after the click interaction completes.\r\n * @example\r\n * ```ts\r\n * await clickLabelInput(\"Email address\");\r\n * ```\r\n */\r\nexport async function clickLabelInput(\r\n label: TEXT_PATTERN,\r\n container?: HTMLElement,\r\n) {\r\n const user = userEvent.setup();\r\n const regex = patternToRegex(label);\r\n const searchArea = getSearchArea(container);\r\n const element =\r\n typeof label === \"string\" && label.length === 0\r\n ? searchArea.queryByPlaceholderText(regex) ||\r\n searchArea.getByLabelText(regex)\r\n : searchArea.queryByLabelText(regex) ||\r\n searchArea.getByPlaceholderText(regex);\r\n await user.click(element);\r\n}\r\n","import type { TEXT_PATTERN } from \"@/shared/regex\";\r\nimport { patternToRegex } from \"@/shared/regex\";\r\nimport { getSearchArea } from \"./getSearchArea\";\r\n\r\n/**\r\n * Finds a checkbox or radio control by its accessible name.\r\n *\r\n * @param target Accessible name to match, as text or a regular expression.\r\n * @param container Optional element that limits the search.\r\n * @returns The matching checkbox or radio input.\r\n * @throws If neither a checkbox nor a radio control matches the target.\r\n * @example\r\n * ```ts\r\n * const consent = getCheckboxRadio(\"Accept terms\");\r\n * expect(consent).toBeChecked();\r\n * ```\r\n */\r\nexport function getCheckboxRadio(\r\n target: TEXT_PATTERN,\r\n container?: HTMLElement,\r\n) {\r\n const regex = patternToRegex(target);\r\n const searchArea = getSearchArea(container);\r\n const element =\r\n searchArea.queryByRole(\"checkbox\", { name: regex }) ||\r\n searchArea.queryByRole(\"radio\", { name: regex });\r\n\r\n if (element) return element;\r\n\r\n throw new Error(\r\n `Unable to find a checkbox or radio control named \"${String(target)}\".`,\r\n );\r\n}\r\n","import type { TEXT_PATTERN } from \"@/shared/regex\";\r\nimport { expect } from \"vitest\";\r\nimport { getCheckboxRadio } from \"./getCheckboxRadio\";\r\n\r\n/**\r\n * Asserts that the radio button or checkbox matching the accessible name is checked.\r\n *\r\n * @param selector Accessible label text or regular expression for the control.\r\n * @param container Optional element that limits the control search.\r\n * @returns Nothing; throws an assertion error if the control is absent or unchecked.\r\n * @example\r\n * ```ts\r\n * isChecked(\"Accept terms\");\r\n * ```\r\n */\r\nexport function isChecked(selector: TEXT_PATTERN, container?: HTMLElement) {\r\n expect(getCheckboxRadio(selector, container)).toBeChecked();\r\n}\r\n","import type { TEXT_PATTERN } from \"@/shared/regex\";\r\nimport { expect } from \"vitest\";\r\nimport { getCheckboxRadio } from \"./getCheckboxRadio\";\r\n\r\n/**\r\n * Asserts that the radio button or checkbox matching the accessible name is unchecked.\r\n *\r\n * @param selector Accessible label text or regular expression for the control.\r\n * @param container Optional element that limits the control search.\r\n * @returns Nothing; throws an assertion error if the control is absent or checked.\r\n * @example\r\n * ```ts\r\n * isNotChecked(\"Subscribe to updates\");\r\n * ```\r\n */\r\nexport function isNotChecked(selector: TEXT_PATTERN, container?: HTMLElement) {\r\n expect(getCheckboxRadio(selector, container)).not.toBeChecked();\r\n}\r\n","import { expect } from \"vitest\";\r\n\r\n/**\r\n * Asserts that an HTMLElement possesses the expected set of DOM attributes and values.\r\n *\r\n * Handles string/numeric values, boolean attributes (true = present, false = absent),\r\n * and null/undefined values (absent).\r\n *\r\n * @param element The DOM element whose attributes will be checked.\r\n * @param attributes Attribute names mapped to their expected values.\r\n * @returns Nothing; throws an assertion error when any attribute does not match.\r\n * @example\r\n * ```ts\r\n * shouldHaveAttributes(input, { required: true, \"aria-label\": \"Email\" });\r\n * ```\r\n */\r\nexport function shouldHaveAttributes(\r\n element: HTMLElement,\r\n attributes: Record<string, unknown>,\r\n): void {\r\n Object.entries(attributes).forEach(([key, value]) => {\r\n if (value === null || value === undefined || value === false) {\r\n expect(element).not.toHaveAttribute(key);\r\n } else if (value === true) {\r\n expect(element).toHaveAttribute(key);\r\n } else {\r\n expect(element).toHaveAttribute(key, String(value));\r\n }\r\n });\r\n}\r\n","import { screen } from \"@testing-library/react\";\r\nimport { expect } from \"vitest\";\r\n\r\n/**\r\n * Asserts that elements with all supplied test IDs are present in the document.\r\n *\r\n * @param ids One or more `data-testid` values to locate.\r\n * @returns The elements found, in the same order as the supplied IDs.\r\n * @example\r\n * ```ts\r\n * const [submitButton] = shouldHaveTestId(\"submit-button\");\r\n * ```\r\n */\r\nexport function shouldHaveTestId(...ids: string[]) {\r\n const testElements = ids.map((id) => screen.getByTestId(id));\r\n\r\n testElements.forEach((element) => expect(element).toBeInTheDocument());\r\n return testElements;\r\n}\r\n","import { screen } from \"@testing-library/react\";\r\nimport { expect } from \"vitest\";\r\n\r\n/**\r\n * Asserts that elements with all supplied test IDs are absent from the document.\r\n *\r\n * @param ids One or more `data-testid` values to verify are absent.\r\n * @returns The query results (`null` for each absent element), in ID order.\r\n * @example\r\n * ```ts\r\n * shouldNotHaveTestId(\"loading-spinner\");\r\n * ```\r\n */\r\nexport function shouldNotHaveTestId(...ids: string[]) {\r\n const testElements = ids.map((id) => screen.queryByTestId(id));\r\n\r\n testElements.forEach((element) => expect(element).not.toBeInTheDocument());\r\n return testElements;\r\n}\r\n","import type { TEXT_MATCHER } from \"@/shared/regex\";\r\nimport { patternToRegex } from \"@/shared/regex\";\r\nimport { screen } from \"@testing-library/react\";\r\nimport { expect } from \"vitest\";\r\n\r\n/**\r\n * Creates assertion/element pairs for text matchers, supporting a zero-based occurrence index.\r\n *\r\n * @param texts Text strings, regular expressions, or `[matcher, occurrenceIndex]` pairs.\r\n * @returns Assertion and matching-element pairs, with `null` for missing text.\r\n * @example\r\n * ```ts\r\n * const [{ expected, element }] = shouldGetByText([\"Item\", 1]);\r\n * ```\r\n */\r\nexport function shouldGetByText(...texts: TEXT_MATCHER[]) {\r\n return texts.map((text) => {\r\n if (Array.isArray(text)) {\r\n const [matcher, nth] = text;\r\n const element =\r\n screen.queryAllByText(patternToRegex(matcher))[nth] ?? null;\r\n return { expected: expect(element), element };\r\n }\r\n const element = screen.queryByText(patternToRegex(text));\r\n return { expected: expect(element), element };\r\n });\r\n}\r\n","import { shouldGetByText } from \"./shouldGetByText\";\r\n\r\n/**\r\n * Asserts that none of the supplied text matchers appear in the document.\r\n *\r\n * @param texts Text strings or regular expressions that must be absent.\r\n * @returns Nothing; throws an assertion error if any text is found.\r\n * @example\r\n * ```ts\r\n * shouldNotSee(\"Error\", /failed/i);\r\n * ```\r\n */\r\nexport const shouldNotSee = (...texts: (string | RegExp)[]) => {\r\n shouldGetByText(...texts).forEach(({ expected }) =>\r\n expected.not.toBeInTheDocument(),\r\n );\r\n};\r\n","import type { TEXT_MATCHER } from \"@/shared/regex\";\r\nimport { shouldGetByText } from \"./shouldGetByText\";\r\n\r\n/**\r\n * Asserts that each requested text matcher is present in the document.\r\n *\r\n * @param texts Text strings, regular expressions, or `[matcher, occurrenceIndex]` pairs.\r\n * @returns The matching elements in the same order as the supplied matchers.\r\n * @example\r\n * ```ts\r\n * const [heading] = shouldSee(\"Welcome\");\r\n * ```\r\n */\r\nexport const shouldSee = (...texts: TEXT_MATCHER[]) => {\r\n return shouldGetByText(...texts).map(({ expected, element }) => {\r\n expected.toBeInTheDocument();\r\n return element!;\r\n });\r\n};\r\n","import { fireEvent, type ToggleState } from \"../modules/toggle-event\";\r\n\r\n/**\r\n * Dispatches a toggle event on the first element matching a selector.\r\n *\r\n * @param options Selector, optional search container, and target open/closed state.\r\n * @returns The matched element, or `undefined` when no matching element exists.\r\n * @example\r\n * ```ts\r\n * const popover = togglePopover({ selector: \"#help\", newState: \"open\" });\r\n * ```\r\n */\r\nexport function togglePopover({\r\n container,\r\n selector,\r\n newState = \"open\",\r\n}: {\r\n container?: HTMLElement;\r\n selector: string;\r\n newState?: ToggleState;\r\n}) {\r\n const element = (container ?? document).querySelector(selector);\r\n if (!element) return;\r\n fireEvent.toggle(element, { newState });\r\n return element;\r\n}\r\n","import { patternToRegex } from \"@/shared/regex\";\r\nimport { screen, within } from \"@testing-library/react\";\r\nimport userEvent from \"@testing-library/user-event\";\r\n\r\n/**\r\n * Simulates a user click on a button with the requested name, or matching text.\r\n *\r\n * @param target Button accessible name or text string/regular expression.\r\n * @param container Optional element that limits the target search.\r\n * @returns A promise that resolves after the click interaction completes.\r\n * @example\r\n * ```ts\r\n * await userClicks(\"Save\");\r\n * ```\r\n */\r\nexport const userClicks = async (\r\n target: string | RegExp,\r\n container?: HTMLElement,\r\n) => {\r\n const user = userEvent.setup();\r\n const regex = patternToRegex(target);\r\n const searchArea = container ? within(container) : screen;\r\n const element =\r\n searchArea.queryByRole(\"button\", { name: regex }) ||\r\n searchArea.getByText(regex);\r\n\r\n await user.click(element);\r\n};\r\n","import { patternToRegex, TEXT_PATTERN } from \"@/shared/regex\";\r\nimport { getSearchArea } from \"./getSearchArea\";\r\n\r\n/**\r\n * Finds a text-entry control by its accessible name or placeholder.\r\n *\r\n * Supported controls are text-like inputs, textareas, and elements exposed\r\n * with the textbox role. A matching non-text element is rejected.\r\n *\r\n * @param target Accessible name or placeholder to match, as text or a regular expression.\r\n * @param container Optional element that limits the search.\r\n * @returns The matching textbox element.\r\n * @throws If no textbox matches, or a placeholder match is not a text-entry control.\r\n * @example\r\n * ```ts\r\n * const email = getTextBox(\"Email address\");\r\n * const notes = getTextBox(\"Notes\", dialog);\r\n * ```\r\n */\r\nexport function getTextBox(target: TEXT_PATTERN, container?: HTMLElement) {\r\n const regex = patternToRegex(target);\r\n const searchArea = getSearchArea(container);\r\n const textBox = searchArea.queryByRole(\"textbox\", { name: regex });\r\n\r\n if (textBox) return textBox;\r\n\r\n const placeholderMatch = searchArea.queryByPlaceholderText(regex);\r\n if (placeholderMatch) {\r\n const isTextInput =\r\n placeholderMatch instanceof HTMLInputElement &&\r\n [\"text\", \"search\", \"email\", \"url\", \"tel\", \"password\"].includes(\r\n placeholderMatch.type,\r\n );\r\n const isTextArea = placeholderMatch instanceof HTMLTextAreaElement;\r\n const isContentEditable =\r\n placeholderMatch.getAttribute(\"contenteditable\") === \"true\" &&\r\n placeholderMatch.getAttribute(\"role\") === \"textbox\";\r\n\r\n if (isTextInput || isTextArea || isContentEditable) return placeholderMatch;\r\n\r\n throw new Error(\r\n `Element matching placeholder \"${String(target)}\" is not a text-entry control.`,\r\n );\r\n }\r\n\r\n return searchArea.getByRole(\"textbox\", { name: regex });\r\n}\r\n","import { TEXT_PATTERN } from \"@/shared/regex\";\r\nimport userEvent from \"@testing-library/user-event\";\r\nimport { getTextBox } from \"./getTextBox\";\r\n\r\n/**\r\n * Replaces the value of a textbox found by its label, placeholder, or textbox name.\r\n *\r\n * @param target Accessible label, placeholder, or textbox name as text or a regex.\r\n * @param text Text to type after clearing the existing value.\r\n * @param container Optional element that limits the textbox search.\r\n * @param user User-event instance used for the interaction; defaults to a new instance.\r\n * @returns A promise resolving to the textbox that was updated.\r\n * @example\r\n * ```ts\r\n * const emailInput = await userTypes(\"Email\", \"person@example.com\");\r\n * ```\r\n */\r\nexport const userTypes = async (\r\n target: TEXT_PATTERN,\r\n text: string,\r\n container?: HTMLElement,\r\n user = userEvent.setup(),\r\n) => {\r\n const element = getTextBox(target, container);\r\n\r\n await user.clear(element);\r\n if (text) await user.type(element, text);\r\n return element;\r\n};\r\n","import { userTypes } from \"./userTypes\";\r\n\r\n/**\r\n * Replaces the values of multiple textboxes, located by their respective selectors.\r\n *\r\n * @param inputs Object mapping each textbox label/placeholder to the text to enter.\r\n * @param container Optional element that limits all textbox searches.\r\n * @returns A promise resolving to an object mapping each selector to its updated textbox.\r\n * @example\r\n * ```ts\r\n * const fields = await userTypesMultiple({ Email: \"person@example.com\", Name: \"Pat\" });\r\n * ```\r\n */\r\nexport async function userTypesMultiple(\r\n inputs: Record<string, string>,\r\n container?: HTMLElement,\r\n) {\r\n const entries = Object.entries(inputs);\r\n const outputs: Record<keyof typeof inputs, HTMLElement> = {};\r\n\r\n for (const [selector, value] of entries) {\r\n outputs[selector] = await userTypes(selector, value, container);\r\n }\r\n\r\n return outputs;\r\n}\r\n","/**\r\n * Creates a fulfilled promise augmented with Vitest's fulfilled-promise metadata.\r\n *\r\n * @param value The value with which the promise is fulfilled.\r\n * @returns A fulfilled Promise<T> with `status: \"fulfilled\"` and its `value`.\r\n * @example\r\n * ```ts\r\n * const payload = await resolvedPromise({ id: 1 });\r\n * expect(payload).toEqual({ id: 1 });\r\n * ```\r\n */\r\nexport function resolvedPromise<T>(\r\n value: T,\r\n): Promise<T> & { status: \"fulfilled\"; value: T } {\r\n const promise = Promise.resolve(value);\r\n return Object.assign(promise, { status: \"fulfilled\" as const, value });\r\n}\r\n","/**\r\n * Creates a rejected promise augmented with Vitest's rejected-promise metadata.\r\n *\r\n * @param reason The rejection reason, preserved as an unknown value; defaults to `undefined`.\r\n * @returns A rejected Promise<never> with `status: \"rejected\"` and its `reason`.\r\n * @example\r\n * ```ts\r\n * await expect(rejectedPromise(new Error(\"Request failed\"))).rejects.toThrow(\"Request failed\");\r\n * ```\r\n */\r\nexport function rejectedPromise(\r\n reason: unknown = undefined,\r\n): Promise<never> & { status: \"rejected\"; reason: unknown } {\r\n const promise = Promise.reject<never>(reason);\r\n\r\n promise.catch((error) => error);\r\n\r\n return Object.assign(promise, { status: \"rejected\" as const, reason });\r\n}\r\n","import { MockInstance, vi } from \"vitest\";\r\n\r\nconst CONSOLES = [\"log\", \"warn\", \"error\"] as const;\r\n\r\nlet activeSpies: MockInstance[] = [];\r\n\r\n/**\r\n * Suppresses console.log, console.warn, and console.error until resetConsole runs.\r\n *\r\n * @example\r\n * ```ts\r\n * beforeEach(shutConsole);\r\n * afterEach(resetConsole);\r\n * ```\r\n */\r\nexport function shutConsole() {\r\n resetConsole();\r\n\r\n activeSpies = CONSOLES.map((cons) =>\r\n vi.spyOn(console, cons).mockImplementation(() => {}),\r\n );\r\n}\r\n\r\n/**\r\n * Restores the console methods most recently suppressed by shutConsole.\r\n *\r\n * @example\r\n * ```ts\r\n * shutConsole();\r\n * // Run code whose console output should be ignored.\r\n * resetConsole();\r\n * ```\r\n */\r\nexport function resetConsole() {\r\n for (const spy of activeSpies) {\r\n spy.mockRestore(); // Restores native console behavior\r\n }\r\n activeSpies = [];\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"vitest.mjs","names":["resolvedPromise","rejectedPromise","_rejectedPromise","_resolvedPromise"],"sources":["../src/features/promises/utils/resolvedPromise.ts","../src/features/promises/utils/rejectedPromise.ts","../src/features/vitest/index.ts"],"sourcesContent":["/**\n * Creates a fulfilled promise augmented with Vitest's fulfilled-promise metadata.\n *\n * @param value The value with which the promise is fulfilled.\n * @returns A fulfilled Promise<T> with `status: \"fulfilled\"` and its `value`.\n * @example\n * ```ts\n * const payload = await resolvedPromise({ id: 1 });\n * expect(payload).toEqual({ id: 1 });\n * ```\n */\nexport function resolvedPromise<T>(\n value: T,\n): Promise<T> & { status: \"fulfilled\"; value: T } {\n const promise = Promise.resolve(value);\n return Object.assign(promise, { status: \"fulfilled\" as const, value });\n}\n","/**\n * Creates a rejected promise augmented with Vitest's rejected-promise metadata.\n *\n * @param reason The rejection reason, preserved as an unknown value; defaults to `undefined`.\n * @returns A rejected Promise<never> with `status: \"rejected\"` and its `reason`.\n * @example\n * ```ts\n * await expect(rejectedPromise(new Error(\"Request failed\"))).rejects.toThrow(\"Request failed\");\n * ```\n */\nexport function rejectedPromise(\n reason: unknown = undefined,\n): Promise<never> & { status: \"rejected\"; reason: unknown } {\n const promise = Promise.reject<never>(reason);\n\n promise.catch((error) => error);\n\n return Object.assign(promise, { status: \"rejected\" as const, reason });\n}\n","/* eslint-disable boundaries/dependencies */\nexport * from \"./modules/console\";\nexport * from \"./modules/dom\";\n\nimport {\n rejectedPromise as _rejectedPromise,\n resolvedPromise as _resolvedPromise,\n} from \"@/features/promises\";\n\n/**\n * @deprecated Import `rejectedPromise` from `@vickbk/tests/promises` instead.\n * This re-export is retained for backward compatibility.\n */\nexport const rejectedPromise = _rejectedPromise;\n\n/**\n * @deprecated Import `resolvedPromise` from `@vickbk/tests/promises` instead.\n * This re-export is retained for backward compatibility.\n */\nexport const resolvedPromise = _resolvedPromise;\n"],"mappings":";;;;;;;;;;;;;;AAWA,SAAgBA,kBACd,OACgD;CAChD,MAAM,UAAU,QAAQ,QAAQ,KAAK;CACrC,OAAO,OAAO,OAAO,SAAS;EAAE,QAAQ;EAAsB;CAAM,CAAC;AACvE;;;;;;;;;;;;;ACNA,SAAgBC,kBACd,SAAkB,KAAA,GACwC;CAC1D,MAAM,UAAU,QAAQ,OAAc,MAAM;CAE5C,QAAQ,OAAO,UAAU,KAAK;CAE9B,OAAO,OAAO,OAAO,SAAS;EAAE,QAAQ;EAAqB;CAAO,CAAC;AACvE;;;;;;;ACLA,MAAa,kBAAkBC;;;;;AAM/B,MAAa,kBAAkBC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vickbk/tests",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Testing helpers for Vitest and Playwright.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -49,6 +49,28 @@
49
49
  "default": "./dist/vitest.mjs"
50
50
  }
51
51
  },
52
+ "./vitest/console": {
53
+ "import": {
54
+ "types": "./dist/vitest/console.d.mts",
55
+ "default": "./dist/vitest/console.mjs"
56
+ }
57
+ },
58
+ "./vitest/dom": {
59
+ "import": {
60
+ "types": "./dist/vitest/dom.d.mts",
61
+ "default": "./dist/vitest/dom.mjs"
62
+ }
63
+ },
64
+ "./promises": {
65
+ "import": {
66
+ "types": "./dist/promises.d.mts",
67
+ "default": "./dist/promises.mjs"
68
+ },
69
+ "require": {
70
+ "types": "./dist/promises.d.cts",
71
+ "default": "./dist/promises.cjs"
72
+ }
73
+ },
52
74
  "./react": {
53
75
  "import": {
54
76
  "types": "./dist/react.d.mts",