rescript-vitest-extras 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/.yarnrc.yml ADDED
@@ -0,0 +1 @@
1
+ nodeLinker: node-modules
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # rescript-vitest-extras
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a50a78c: Add ReScript bindings extending rescript-vitest with:
8
+
9
+ - `VitestExtras.Assert`: Chai-style assert API with ReScript-specific assertions for `option`, `result`, `Null.t`, `Nullable.t`, and `undefined`
10
+ - `VitestExtras.Mock`: Arity-specific mock function types (`mockFn0`–`mockFn5`) with mock context, implementation control, and return value stubbing
11
+ - `VitestExtras.MockExpect`: Expect matchers for mock assertions (`toHaveBeenCalled`, `toHaveBeenCalledWith`, `toHaveReturned`, etc.)
12
+ - `VitestExtras.BrowserLocator`: Locator API for browser-mode element queries, filtering, interaction, and element access
13
+ - `VitestExtras.BrowserPage`: `page` singleton with query methods, viewport control, and screenshot support
14
+ - `VitestExtras.BrowserUserEvent`: `userEvent` singleton for click, fill, type, hover, keyboard, drag-and-drop, and clipboard operations
15
+ - `VitestExtras.BrowserExpect`: `expect.element()` with 25 DOM assertion matchers (visibility, state, content, attributes, form values)
16
+ - `VitestExtras.BrowserReact`: `render` and `renderHook` bindings for `vitest-browser-react` with auto-cleanup and a `Pure` submodule
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # rescript-vitest-extras
2
+
3
+ Additional ReScript bindings for [Vitest](https://vitest.dev/), extending [rescript-vitest](https://github.com/cometkim/rescript-vitest).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install rescript-vitest-extras rescript-vitest vitest
9
+ # or
10
+ yarn add rescript-vitest-extras rescript-vitest vitest
11
+ ```
12
+
13
+ Add to your `rescript.json`:
14
+
15
+ ```json
16
+ {
17
+ "dependencies": ["rescript-vitest", "rescript-vitest-extras"]
18
+ }
19
+ ```
20
+
21
+ ## Modules
22
+
23
+ ### VitestExtras.Assert
24
+
25
+ Chai-style assert API bindings with ReScript-specific assertions for `option`, `result`, `Null.t`, `Nullable.t`, and `undefined`.
26
+
27
+ ```rescript
28
+ open Vitest
29
+ module A = VitestExtras.Assert
30
+
31
+ test("equality", _ => {
32
+ A.equal(1, 1)
33
+ A.deepEqual([1, 2, 3], [1, 2, 3])
34
+ })
35
+
36
+ test("option assertions", _ => {
37
+ A.Option.isSome(Some(42))
38
+ A.Option.isNone(None)
39
+ })
40
+
41
+ test("result assertions", _ => {
42
+ A.Result.isOk(Ok(42))
43
+ A.Result.isError(Error("fail"))
44
+ })
45
+
46
+ test("nullable assertions", _ => {
47
+ let value: Nullable.t<int> = Nullable.make(42)
48
+ A.Nullable.exists(value)
49
+ A.Nullable.isNotNull(value)
50
+ })
51
+
52
+ test("array assertions", _ => {
53
+ A.Array.includes([1, 2, 3], 2)
54
+ A.Array.sameMembers([1, 2, 3], [3, 1, 2])
55
+ A.Array.lengthOf([1, 2], 2)
56
+ })
57
+
58
+ test("string assertions", _ => {
59
+ A.String.includes("hello world", "world")
60
+ A.String.isEmpty("")
61
+ })
62
+
63
+ test("numeric comparisons", _ => {
64
+ A.isAbove(10.0, 5.0)
65
+ A.closeTo(1.5, 1.0, ~delta=1.0)
66
+ })
67
+
68
+ test("exceptions", _ => {
69
+ A.throws(() => JsError.throwWithMessage("error"))
70
+ A.doesNotThrow(() => ())
71
+ })
72
+ ```
73
+
74
+ All assertions accept an optional `~message` parameter for custom failure messages.
75
+
76
+ ### VitestExtras.Mock
77
+
78
+ Arity-specific mock function types with full access to mock context, implementation control, and return value stubbing.
79
+
80
+ ```rescript
81
+ open Vitest
82
+ open VitestExtras
83
+
84
+ module M = Mock
85
+
86
+ describe("mock functions", () => {
87
+ test("create and call mocks", _ => {
88
+ // Create with implementation
89
+ let add = M.fnWithImpl2((a, b) => a + b)
90
+ let fn = add->M.MockFn2.toFunction
91
+
92
+ A.equal(fn(2, 3), 5)
93
+ })
94
+
95
+ test("stub return values", _ => {
96
+ let mock = M.fn0()->M.MockFn0.mockReturnValue(42)
97
+ let fn = mock->M.MockFn0.toFunction
98
+
99
+ A.equal(fn(), 42)
100
+ })
101
+
102
+ test("access call history", _ => {
103
+ let mock = M.fnWithImpl1(x => x * 2)
104
+ let fn = mock->M.MockFn1.toFunction
105
+
106
+ let _ = fn(5)
107
+ let _ = fn(10)
108
+
109
+ let ctx = mock->M.MockFn1.mock
110
+ A.Array.lengthOf(ctx.calls, 2)
111
+ })
112
+
113
+ test("mock implementation once", _ => {
114
+ let mock = M.fn0()
115
+ ->M.MockFn0.mockReturnValueOnce(1)
116
+ ->M.MockFn0.mockReturnValueOnce(2)
117
+ ->M.MockFn0.mockReturnValue(999)
118
+ let fn = mock->M.MockFn0.toFunction
119
+
120
+ A.equal(fn(), 1)
121
+ A.equal(fn(), 2)
122
+ A.equal(fn(), 999)
123
+ })
124
+
125
+ test("async mocks", async () => {
126
+ let mock = M.fn0()->M.MockFn0.mockResolvedValue(42)
127
+ let fn = mock->M.MockFn0.toFunction
128
+
129
+ let result = await fn()
130
+ A.equal(result, 42)
131
+ })
132
+ })
133
+ ```
134
+
135
+ Available arities: `mockFn0` through `mockFn5`, each with corresponding `MockFn0` through `MockFn5` modules.
136
+
137
+ ### VitestExtras.MockExpect
138
+
139
+ Expect matchers for mock function assertions.
140
+
141
+ ```rescript
142
+ open Vitest
143
+ open VitestExtras
144
+
145
+ module M = Mock
146
+ module ME = MockExpect
147
+
148
+ test("mock matchers", _ => {
149
+ let mock = M.fnWithImpl1(x => x + 1)
150
+ let fn = mock->M.MockFn1.toFunction
151
+
152
+ let _ = fn(5)
153
+
154
+ expect(mock)->ME.toHaveBeenCalled
155
+ expect(mock)->ME.toHaveBeenCalledTimes(1)
156
+ expect(mock)->ME.toHaveBeenCalledWith1(5)
157
+ expect(mock)->ME.toHaveReturnedWith(6)
158
+ })
159
+ ```
160
+
161
+ ## Module Organization
162
+
163
+ This library uses the `VitestExtras__` namespace for internal modules with a public `VitestExtras` entry point that exports all public APIs. You can access modules in two ways:
164
+
165
+ **Recommended** — via the public `VitestExtras` entry point:
166
+ ```rescript
167
+ open VitestExtras
168
+ module A = Assert
169
+ module M = Mock
170
+ ```
171
+
172
+ **Alternatively** — use fully qualified internal names:
173
+ ```rescript
174
+ module A = VitestExtras__Assert
175
+ module M = VitestExtras__Mock
176
+ ```
177
+
178
+ ## Mock Function Types
179
+
180
+ | Type | Signature |
181
+ | ----------------------------------- | ------------------------------ |
182
+ | `mockFn0<'ret>` | `() => 'ret` |
183
+ | `mockFn1<'a, 'ret>` | `'a => 'ret` |
184
+ | `mockFn2<'a, 'b, 'ret>` | `('a, 'b) => 'ret` |
185
+ | `mockFn3<'a, 'b, 'c, 'ret>` | `('a, 'b, 'c) => 'ret` |
186
+ | `mockFn4<'a, 'b, 'c, 'd, 'ret>` | `('a, 'b, 'c, 'd) => 'ret` |
187
+ | `mockFn5<'a, 'b, 'c, 'd, 'e, 'ret>` | `('a, 'b, 'c, 'd, 'e) => 'ret` |
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "rescript-vitest-extras",
3
+ "version": "0.1.0",
4
+ "packageManager": "yarn@4.12.0",
5
+ "scripts": {
6
+ "res:build": "rescript build",
7
+ "res:clean": "rescript clean",
8
+ "res:watch": "rescript watch",
9
+ "test": "vitest",
10
+ "test:browser": "vitest --config vitest.browser.config.mjs"
11
+ },
12
+ "devDependencies": {
13
+ "@changesets/cli": "^2.29.8",
14
+ "@playwright/test": "^1.48.0",
15
+ "@rescript/react": "^0.14.1",
16
+ "@vitejs/plugin-react": "^5.1.4",
17
+ "@vitest/browser": "^3.2.4",
18
+ "@vitest/browser-playwright": "^4.0.18",
19
+ "@vitest/browser-preview": "^4.0.18",
20
+ "@vitest/coverage-v8": "^3.2.4",
21
+ "@vitest/ui": "^4.0.18",
22
+ "react": "^19.1.0",
23
+ "react-dom": "^19.1.0",
24
+ "rescript": "^12.1.0",
25
+ "rescript-vitest": "^2.1.1",
26
+ "vite": "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0",
27
+ "vitest": "^4.0.18",
28
+ "vitest-browser-react": "^2.0.5"
29
+ },
30
+ "peerDependencies": {
31
+ "@rescript/react": "^0.14.0",
32
+ "rescript-vitest": "^2.1.1",
33
+ "vitest": "^3.0.0"
34
+ },
35
+ "peerDependenciesMeta": {
36
+ "@rescript/react": {
37
+ "optional": true
38
+ },
39
+ "@vitest/browser": {
40
+ "optional": true
41
+ },
42
+ "resolutions": {},
43
+ "vitest-browser-react": {
44
+ "optional": true
45
+ }
46
+ }
47
+ }
package/rescript.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "rescript-vitest-extras",
3
+ "dependencies": ["rescript-vitest", "@rescript/react"],
4
+ "sources": [
5
+ {
6
+ "dir": "src",
7
+ "subdirs": true
8
+ },
9
+ {
10
+ "dir": "__tests__",
11
+ "type": "dev",
12
+ "subdirs": true
13
+ },
14
+ {
15
+ "dir": "examples",
16
+ "type": "dev",
17
+ "subdirs": true
18
+ },
19
+ {
20
+ "dir": "__browser_tests__",
21
+ "type": "dev",
22
+ "subdirs": true
23
+ }
24
+ ],
25
+ "package-specs": {
26
+ "module": "esmodule",
27
+ "suffix": ".res.mjs",
28
+ "in-source": true
29
+ },
30
+ "jsx": {
31
+ "version": 4,
32
+ "mode": "automatic"
33
+ }
34
+ }
@@ -0,0 +1,8 @@
1
+ module Assert = VitestExtras__Assert
2
+ module Mock = VitestExtras__Mock
3
+ module MockExpect = VitestExtras__MockExpect
4
+ module BrowserLocator = VitestExtras__BrowserLocator
5
+ module BrowserPage = VitestExtras__BrowserPage
6
+ module BrowserUserEvent = VitestExtras__BrowserUserEvent
7
+ module BrowserExpect = VitestExtras__BrowserExpect
8
+ module BrowserReact = VitestExtras__BrowserReact