tutuca 0.9.71 → 0.9.72
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/chai.js +3389 -0
- package/dist/immutable.js +4333 -0
- package/dist/tutuca-cli.js +111 -1
- package/dist/tutuca-dev.ext.js +86 -3392
- package/package.json +9 -1
- package/skill/tutuca/cli.md +5 -5
- package/skill/tutuca/core.md +11 -0
- package/skill/tutuca/testing.md +16 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tutuca",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.72",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Zero-dependency SPA framework with immutable state and virtual DOM",
|
|
6
6
|
"main": "./dist/tutuca.js",
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
"./ext": "./dist/tutuca.ext.js",
|
|
14
14
|
"./extra-ext": "./dist/tutuca-extra.ext.js",
|
|
15
15
|
"./dev-ext": "./dist/tutuca-dev.ext.js",
|
|
16
|
+
"./immutable": "./dist/immutable.js",
|
|
17
|
+
"./chai": "./dist/chai.js",
|
|
16
18
|
"./package.json": "./package.json"
|
|
17
19
|
},
|
|
18
20
|
"bin": {
|
|
@@ -49,6 +51,8 @@
|
|
|
49
51
|
"dist/tutuca.ext.js",
|
|
50
52
|
"dist/tutuca-extra.ext.js",
|
|
51
53
|
"dist/tutuca-dev.ext.js",
|
|
54
|
+
"dist/immutable.js",
|
|
55
|
+
"dist/chai.js",
|
|
52
56
|
"skill"
|
|
53
57
|
],
|
|
54
58
|
"dependencies": {
|
|
@@ -56,9 +60,13 @@
|
|
|
56
60
|
"prettier": "^3.0.0"
|
|
57
61
|
},
|
|
58
62
|
"peerDependencies": {
|
|
63
|
+
"chai": "^6.2.2",
|
|
59
64
|
"immutable": "*"
|
|
60
65
|
},
|
|
61
66
|
"peerDependenciesMeta": {
|
|
67
|
+
"chai": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
62
70
|
"immutable": {
|
|
63
71
|
"optional": true
|
|
64
72
|
}
|
package/skill/tutuca/cli.md
CHANGED
|
@@ -158,25 +158,25 @@ export function getTests({ describe, test, expect }) {
|
|
|
158
158
|
describe("inc()", () => { // method
|
|
159
159
|
test("returns a Counter with count + 1", () => {
|
|
160
160
|
const next = Counter.make().inc();
|
|
161
|
-
expect(next).
|
|
162
|
-
expect(next.count).
|
|
161
|
+
expect(next).toBeInstanceOf(Counter.Class);
|
|
162
|
+
expect(next.count).toBe(1);
|
|
163
163
|
});
|
|
164
164
|
test("does not mutate the original instance", () => {
|
|
165
165
|
const c = Counter.make({ count: 7 });
|
|
166
166
|
c.inc();
|
|
167
|
-
expect(c.count).
|
|
167
|
+
expect(c.count).toBe(7); // immutability
|
|
168
168
|
});
|
|
169
169
|
});
|
|
170
170
|
|
|
171
171
|
describe("dec()", () => { // input handler
|
|
172
172
|
test("returns a Counter with count - 1", () => {
|
|
173
173
|
const next = Counter.input.dec.call(Counter.make());
|
|
174
|
-
expect(next.count).
|
|
174
|
+
expect(next.count).toBe(-1);
|
|
175
175
|
});
|
|
176
176
|
});
|
|
177
177
|
|
|
178
178
|
test("inc and dec round-trip", () => { // untagged path
|
|
179
|
-
expect(Counter.input.dec.call(Counter.make().inc()).count).
|
|
179
|
+
expect(Counter.input.dec.call(Counter.make().inc()).count).toBe(0);
|
|
180
180
|
});
|
|
181
181
|
});
|
|
182
182
|
}
|
package/skill/tutuca/core.md
CHANGED
|
@@ -514,6 +514,17 @@ input: { onPick(detail) { return this.setCurrent(detail.unicode); } }
|
|
|
514
514
|
view: html`<emoji-picker @on.emoji-click="onPick value"></emoji-picker>`,
|
|
515
515
|
```
|
|
516
516
|
|
|
517
|
+
Handle these events declaratively with `@on.<event-name>` in the view —
|
|
518
|
+
don't grab the node from host/glue code and `addEventListener` on it. A
|
|
519
|
+
listener attached from outside the component runs outside the handler
|
|
520
|
+
model: no `return this.set…()`, no transactor batching, and the mutation
|
|
521
|
+
is invisible to the component that owns the state (the same hazard as
|
|
522
|
+
reaching into `app.state` directly). For any event with a real element in
|
|
523
|
+
the tree, `@on.` is the only entry point you need. Genuinely external
|
|
524
|
+
inbound sources (WebSocket, `postMessage`, timers) have no element to bind
|
|
525
|
+
— route those through `app.sendAtRoot` instead (see
|
|
526
|
+
[request-response.md](./request-response.md)).
|
|
527
|
+
|
|
517
528
|
Pitfall: binding camelCase JS properties on a custom element silently
|
|
518
529
|
fails. `:mapId=".id"` does *not* invoke a `set mapId` setter
|
|
519
530
|
— the HTML parser lowercased the attribute name, so the framework assigns
|
package/skill/tutuca/testing.md
CHANGED
|
@@ -16,13 +16,19 @@ A module opts into `tutuca test` by exporting `getTests`:
|
|
|
16
16
|
export function getTests({ describe, test, expect }) {
|
|
17
17
|
describe(MyComp, () => {
|
|
18
18
|
test("does the thing", () => {
|
|
19
|
-
expect(MyComp.make().doTheThing().count).
|
|
19
|
+
expect(MyComp.make().doTheThing().count).toBe(1);
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
- `expect` is chai
|
|
25
|
+
- `expect` is chai, extended with **jest-style matchers** (`toBe`,
|
|
26
|
+
`toEqual`, `toContain`, `toThrow`, `.not.toBe`, …) — the recommended
|
|
27
|
+
style. Chai's BDD chain (`expect(x).to.equal(1)`) still works for those
|
|
28
|
+
who prefer it. Run `tutuca help` for the full matcher list (it's
|
|
29
|
+
surfaced from code). Asymmetric/mock matchers
|
|
30
|
+
(`expect.objectContaining`, `toHaveBeenCalled…`, `toMatchSnapshot`) are
|
|
31
|
+
**not** available — tutuca has no mocking layer.
|
|
26
32
|
- `test` and `describe` are **Tutuca's own** subset of the common
|
|
27
33
|
Mocha/Bun-style API, injected by `tutuca test` — not Bun's built-ins.
|
|
28
34
|
Available calls: `describe(title, fn)`, `describe(Component, fn)`,
|
|
@@ -147,7 +153,7 @@ test("filters and enriches", () => {
|
|
|
147
153
|
when: "keepEven",
|
|
148
154
|
enrichWith: "addLabel",
|
|
149
155
|
});
|
|
150
|
-
expect(r).
|
|
156
|
+
expect(r).toEqual([
|
|
151
157
|
{ key: 0, value: 10, label: "0/4: 10" },
|
|
152
158
|
{ key: 2, value: 30, label: "2/4: 30" },
|
|
153
159
|
]);
|
|
@@ -211,8 +217,8 @@ input: { setCount(n) { return this.setCount(n); } }
|
|
|
211
217
|
At test time, the "good" forms become trivial:
|
|
212
218
|
|
|
213
219
|
```js
|
|
214
|
-
expect(MyComp.make().setName("Ada").name).
|
|
215
|
-
expect(MyComp.input.setCount.call(MyComp.make(), 42).count).
|
|
220
|
+
expect(MyComp.make().setName("Ada").name).toBe("Ada");
|
|
221
|
+
expect(MyComp.input.setCount.call(MyComp.make(), 42).count).toBe(42);
|
|
216
222
|
```
|
|
217
223
|
|
|
218
224
|
The "bad" forms force every test to construct
|
|
@@ -237,31 +243,31 @@ export function getTests({ describe, test, expect }) {
|
|
|
237
243
|
describe(Counter, () => {
|
|
238
244
|
describe("inc()", () => { // method
|
|
239
245
|
test("returns a Counter with count + 1", () => {
|
|
240
|
-
expect(Counter.make().inc().count).
|
|
246
|
+
expect(Counter.make().inc().count).toBe(1);
|
|
241
247
|
});
|
|
242
248
|
test("does not mutate the original instance", () => {
|
|
243
249
|
const c = Counter.make({ count: 7 });
|
|
244
250
|
c.inc();
|
|
245
|
-
expect(c.count).
|
|
251
|
+
expect(c.count).toBe(7);
|
|
246
252
|
});
|
|
247
253
|
});
|
|
248
254
|
|
|
249
255
|
describe("dec()", () => { // input handler, no args
|
|
250
256
|
test("returns a Counter with count - 1", () => {
|
|
251
257
|
const next = Counter.input.dec.call(Counter.make());
|
|
252
|
-
expect(next.count).
|
|
258
|
+
expect(next.count).toBe(-1);
|
|
253
259
|
});
|
|
254
260
|
});
|
|
255
261
|
|
|
256
262
|
describe("setCount()", () => { // input handler, valueAsInt
|
|
257
263
|
test("sets the count from a parsed int", () => {
|
|
258
264
|
const next = Counter.input.setCount.call(Counter.make(), 42);
|
|
259
|
-
expect(next.count).
|
|
265
|
+
expect(next.count).toBe(42);
|
|
260
266
|
});
|
|
261
267
|
});
|
|
262
268
|
|
|
263
269
|
test("inc and dec round-trip", () => { // untagged, inherits Counter
|
|
264
|
-
expect(Counter.input.dec.call(Counter.make().inc()).count).
|
|
270
|
+
expect(Counter.input.dec.call(Counter.make().inc()).count).toBe(0);
|
|
265
271
|
});
|
|
266
272
|
});
|
|
267
273
|
}
|