-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResourceDemo.test.ts
More file actions
145 lines (130 loc) · 5.4 KB
/
Copy pathResourceDemo.test.ts
File metadata and controls
145 lines (130 loc) · 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import { describe, it, expect } from "vitest"
import { testScreen } from "@intent-framework/testing"
import { createScreenRuntime, inspectScreen } from "@intent-framework/core"
import { ResourceDemo, teamLoadCount, cachedTeamLoadCount, dedupeReportLoadCount } from "./ResourceDemo.js"
const testServices = {
route: { name: "demo", path: "/:id", params: { id: "team_1" } },
navigate: () => {},
} as const
describe("ResourceDemo", () => {
it("autoLoad resource reaches ready", async () => {
await testScreen(ResourceDemo, async app => {
expect(app.resource("team").status()).toBe("ready")
}, { services: testServices as any })
})
it("autoLoad: false resource starts idle", async () => {
await testScreen(ResourceDemo, async app => {
expect(app.resource("auditLog").status()).toBe("idle")
}, { services: testServices as any })
})
it("manual load transitions resource to ready", async () => {
await testScreen(ResourceDemo, async app => {
expect(app.resource("auditLog").status()).toBe("idle")
await app.resource("auditLog").load()
expect(app.resource("auditLog").status()).toBe("ready")
}, { services: testServices as any })
})
it("reload increments load count", async () => {
await testScreen(ResourceDemo, async app => {
const before = teamLoadCount
await app.resource("team").reload()
expect(teamLoadCount).toBe(before + 1)
}, { services: testServices as any })
})
it("invalidate marks resource stale without reloading", async () => {
await testScreen(ResourceDemo, async app => {
const team = app.resource("team")
expect(team.stale()).toBe(false)
const before = teamLoadCount
team.invalidate()
expect(team.stale()).toBe(true)
expect(teamLoadCount).toBe(before)
}, { services: testServices as any })
})
it("reload clears stale", async () => {
await testScreen(ResourceDemo, async app => {
const team = app.resource("team")
team.invalidate()
expect(team.stale()).toBe(true)
await team.reload()
expect(team.stale()).toBe(false)
}, { services: testServices as any })
})
it("action .invalidates() marks resource stale after success", async () => {
await testScreen(ResourceDemo, async app => {
const team = app.resource("team")
expect(team.stale()).toBe(false)
await app.act("Save team").run()
expect(team.stale()).toBe(true)
}, { services: testServices as any })
})
it("failed loader produces failed status and error", async () => {
await testScreen(ResourceDemo, async app => {
expect(app.resource("unstableReport").status()).toBe("failed")
}, { services: testServices as any })
})
it("failed action does not invalidate resources", async () => {
await testScreen(ResourceDemo, async app => {
const team = app.resource("team")
expect(team.stale()).toBe(false)
await app.act("Broken save").run()
expect(team.stale()).toBe(false)
}, { services: testServices as any })
})
it("cache.staleTime marks resource stale after timeout", async () => {
await testScreen(ResourceDemo, async app => {
const cached = app.resource("cachedTeam")
expect(cached.status()).toBe("ready")
expect(cached.stale()).toBe(false)
await new Promise(r => setTimeout(r, 100))
expect(cached.stale()).toBe(true)
expect(cached.status()).toBe("ready")
}, { services: testServices as any })
})
it("reload resets staleTime timer and clears stale", async () => {
await testScreen(ResourceDemo, async app => {
const cached = app.resource("cachedTeam")
await new Promise(r => setTimeout(r, 60))
expect(cached.stale()).toBe(true)
const before = cachedTeamLoadCount
await cached.reload()
expect(cachedTeamLoadCount).toBe(before + 1)
expect(cached.stale()).toBe(false)
}, { services: testServices as any })
})
it("cache.deduplicate shares in-flight promise", async () => {
await testScreen(ResourceDemo, async app => {
const report = app.resource("dedupeReport")
expect(report.status()).toBe("idle")
const before = dedupeReportLoadCount
await Promise.all([report.load(), report.load()])
expect(dedupeReportLoadCount).toBe(before + 1)
expect(report.status()).toBe("ready")
}, { services: testServices as any })
})
it("inspectScreen reports resources with status/stale/error", async () => {
const runtime = createScreenRuntime(ResourceDemo, { services: testServices as any })
await runtime.start()
const graph = runtime.graph
const resources = graph.resources
expect(resources).toHaveLength(5)
const teamRes = resources.find(r => r.name === "team")!
expect(teamRes.status).toBe("ready")
expect(teamRes.hasValue).toBe(true)
expect(teamRes.stale).toBe(false)
const auditRes = resources.find(r => r.name === "auditLog")!
expect(auditRes.status).toBe("idle")
expect(auditRes.hasValue).toBe(false)
expect(auditRes.stale).toBe(false)
const failedRes = resources.find(r => r.name === "unstableReport")!
expect(failedRes.status).toBe("failed")
expect(failedRes.hasValue).toBe(false)
expect(failedRes.stale).toBe(false)
expect(failedRes.error).toBe("Report generation failed")
runtime.dispose()
})
it("no unrelated graph diagnostics are introduced", () => {
const graph = inspectScreen(ResourceDemo)
expect(graph.diagnostics).toHaveLength(0)
})
})