effect-start 0.9.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/LICENSE +21 -0
- package/README.md +109 -0
- package/package.json +57 -0
- package/src/Bundle.ts +167 -0
- package/src/BundleFiles.ts +174 -0
- package/src/BundleHttp.test.ts +160 -0
- package/src/BundleHttp.ts +259 -0
- package/src/Commander.test.ts +1378 -0
- package/src/Commander.ts +672 -0
- package/src/Datastar.test.ts +267 -0
- package/src/Datastar.ts +68 -0
- package/src/Effect_HttpRouter.test.ts +570 -0
- package/src/EncryptedCookies.test.ts +427 -0
- package/src/EncryptedCookies.ts +451 -0
- package/src/FileHttpRouter.test.ts +207 -0
- package/src/FileHttpRouter.ts +122 -0
- package/src/FileRouter.ts +405 -0
- package/src/FileRouterCodegen.test.ts +598 -0
- package/src/FileRouterCodegen.ts +251 -0
- package/src/FileRouter_files.test.ts +64 -0
- package/src/FileRouter_path.test.ts +132 -0
- package/src/FileRouter_tree.test.ts +126 -0
- package/src/FileSystemExtra.ts +102 -0
- package/src/HttpAppExtra.ts +127 -0
- package/src/Hyper.ts +194 -0
- package/src/HyperHtml.test.ts +90 -0
- package/src/HyperHtml.ts +139 -0
- package/src/HyperNode.ts +37 -0
- package/src/JsModule.test.ts +14 -0
- package/src/JsModule.ts +116 -0
- package/src/PublicDirectory.test.ts +280 -0
- package/src/PublicDirectory.ts +108 -0
- package/src/Route.test.ts +873 -0
- package/src/Route.ts +992 -0
- package/src/Router.ts +80 -0
- package/src/SseHttpResponse.ts +55 -0
- package/src/Start.ts +133 -0
- package/src/StartApp.ts +43 -0
- package/src/StartHttp.ts +42 -0
- package/src/StreamExtra.ts +146 -0
- package/src/TestHttpClient.test.ts +54 -0
- package/src/TestHttpClient.ts +100 -0
- package/src/bun/BunBundle.test.ts +277 -0
- package/src/bun/BunBundle.ts +309 -0
- package/src/bun/BunBundle_imports.test.ts +50 -0
- package/src/bun/BunFullstackServer.ts +45 -0
- package/src/bun/BunFullstackServer_httpServer.ts +541 -0
- package/src/bun/BunImportTrackerPlugin.test.ts +77 -0
- package/src/bun/BunImportTrackerPlugin.ts +97 -0
- package/src/bun/BunTailwindPlugin.test.ts +335 -0
- package/src/bun/BunTailwindPlugin.ts +322 -0
- package/src/bun/BunVirtualFilesPlugin.ts +59 -0
- package/src/bun/index.ts +4 -0
- package/src/client/Overlay.ts +34 -0
- package/src/client/ScrollState.ts +120 -0
- package/src/client/index.ts +101 -0
- package/src/index.ts +24 -0
- package/src/jsx-datastar.d.ts +63 -0
- package/src/jsx-runtime.ts +23 -0
- package/src/jsx.d.ts +4402 -0
- package/src/testing.ts +55 -0
- package/src/x/cloudflare/CloudflareTunnel.ts +110 -0
- package/src/x/cloudflare/index.ts +1 -0
- package/src/x/datastar/Datastar.test.ts +267 -0
- package/src/x/datastar/Datastar.ts +68 -0
- package/src/x/datastar/index.ts +4 -0
- package/src/x/datastar/jsx-datastar.d.ts +63 -0
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file tests `@effect/platform/HttpRouter`, not our code.
|
|
3
|
+
* Since Platform code is still unstable and we relay heavily on its
|
|
4
|
+
* chaining/fallback behavior in `BundleHttp` & `FileHttpRouter`.
|
|
5
|
+
* We want to ensure the behavior doesn't change across versions.
|
|
6
|
+
*/
|
|
7
|
+
import * as HttpRouter from "@effect/platform/HttpRouter"
|
|
8
|
+
import * as HttpServerResponse from "@effect/platform/HttpServerResponse"
|
|
9
|
+
import * as t from "bun:test"
|
|
10
|
+
import * as Effect from "effect/Effect"
|
|
11
|
+
import * as TestHttpClient from "../src/TestHttpClient.ts"
|
|
12
|
+
import { effectFn } from "../src/testing.ts"
|
|
13
|
+
|
|
14
|
+
const effect = effectFn()
|
|
15
|
+
|
|
16
|
+
t.it("Single app mounted on path", () =>
|
|
17
|
+
effect(function*() {
|
|
18
|
+
const app1 = HttpRouter.empty.pipe(
|
|
19
|
+
HttpRouter.get("/hello", HttpServerResponse.text("Hello from app1")),
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
const router = HttpRouter.empty.pipe(
|
|
23
|
+
HttpRouter.mount("/api", app1),
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
const client = TestHttpClient.make(router)
|
|
27
|
+
const response = yield* client.get("/api/hello")
|
|
28
|
+
|
|
29
|
+
t
|
|
30
|
+
.expect(response.status)
|
|
31
|
+
.toBe(200)
|
|
32
|
+
|
|
33
|
+
t
|
|
34
|
+
.expect(yield* response.text)
|
|
35
|
+
.toBe("Hello from app1")
|
|
36
|
+
}))
|
|
37
|
+
|
|
38
|
+
t.it(
|
|
39
|
+
"Multiple apps mounted on same path chain together",
|
|
40
|
+
() =>
|
|
41
|
+
effect(function*() {
|
|
42
|
+
const app1 = HttpRouter.empty.pipe(
|
|
43
|
+
HttpRouter.get("/hello", HttpServerResponse.text("Hello from app1")),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
const app2 = HttpRouter.empty.pipe(
|
|
47
|
+
HttpRouter.get("/world", HttpServerResponse.text("World from app2")),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
const router = HttpRouter.empty.pipe(
|
|
51
|
+
HttpRouter.mount("/api", app1),
|
|
52
|
+
HttpRouter.mount("/api", app2),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
const client = TestHttpClient.make(router)
|
|
56
|
+
|
|
57
|
+
const response1 = yield* client.get("/api/hello")
|
|
58
|
+
|
|
59
|
+
t
|
|
60
|
+
.expect(response1.status)
|
|
61
|
+
.toBe(200)
|
|
62
|
+
|
|
63
|
+
t
|
|
64
|
+
.expect(yield* response1.text)
|
|
65
|
+
.toBe("Hello from app1")
|
|
66
|
+
|
|
67
|
+
const response2 = yield* client.get("/api/world")
|
|
68
|
+
|
|
69
|
+
t
|
|
70
|
+
.expect(response2.status)
|
|
71
|
+
.toBe(200)
|
|
72
|
+
|
|
73
|
+
t
|
|
74
|
+
.expect(yield* response2.text)
|
|
75
|
+
.toBe("World from app2")
|
|
76
|
+
}),
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
t.it(
|
|
80
|
+
"First app has no matching route - second app should be called",
|
|
81
|
+
() =>
|
|
82
|
+
effect(function*() {
|
|
83
|
+
const app1 = HttpRouter.empty.pipe(
|
|
84
|
+
HttpRouter.get("/hello", HttpServerResponse.text("Hello from app1")),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
const app2 = HttpRouter.empty.pipe(
|
|
88
|
+
HttpRouter.get("/missing", HttpServerResponse.text("Found in app2")),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
const router = HttpRouter.empty.pipe(
|
|
92
|
+
HttpRouter.mount("/api", app1),
|
|
93
|
+
HttpRouter.mount("/api", app2),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
const client = TestHttpClient.make(router)
|
|
97
|
+
const response = yield* client.get("/api/missing")
|
|
98
|
+
|
|
99
|
+
t
|
|
100
|
+
.expect(response.status)
|
|
101
|
+
.toBe(200)
|
|
102
|
+
|
|
103
|
+
t
|
|
104
|
+
.expect(yield* response.text)
|
|
105
|
+
.toBe("Found in app2")
|
|
106
|
+
}),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
t.it(
|
|
110
|
+
"First app has no matching route - second app should be called",
|
|
111
|
+
() =>
|
|
112
|
+
effect(function*() {
|
|
113
|
+
const app1 = HttpRouter.empty.pipe(
|
|
114
|
+
HttpRouter.get("/specific", HttpServerResponse.text("Specific route")),
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
const app2 = HttpRouter.empty.pipe(
|
|
118
|
+
HttpRouter.get(
|
|
119
|
+
"/different",
|
|
120
|
+
HttpServerResponse.text("Different route"),
|
|
121
|
+
),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
const router = HttpRouter.empty.pipe(
|
|
125
|
+
HttpRouter.mount("/api", app1),
|
|
126
|
+
HttpRouter.mount("/api", app2),
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
const client = TestHttpClient.make(router)
|
|
130
|
+
const response = yield* client.get("/api/different")
|
|
131
|
+
|
|
132
|
+
t
|
|
133
|
+
.expect(response.status)
|
|
134
|
+
.toBe(200)
|
|
135
|
+
|
|
136
|
+
t
|
|
137
|
+
.expect(yield* response.text)
|
|
138
|
+
.toBe("Different route")
|
|
139
|
+
}),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
t.it("Multiple mounts with different methods", () =>
|
|
143
|
+
effect(function*() {
|
|
144
|
+
const app1 = HttpRouter.empty.pipe(
|
|
145
|
+
HttpRouter.get("/data", HttpServerResponse.text("GET data")),
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
const app2 = HttpRouter.empty.pipe(
|
|
149
|
+
HttpRouter.post("/data", HttpServerResponse.text("POST data")),
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
const router = HttpRouter.empty.pipe(
|
|
153
|
+
HttpRouter.mount("/api", app1),
|
|
154
|
+
HttpRouter.mount("/api", app2),
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
const client = TestHttpClient.make(router)
|
|
158
|
+
|
|
159
|
+
const getResponse = yield* client.get("/api/data")
|
|
160
|
+
|
|
161
|
+
t
|
|
162
|
+
.expect(getResponse.status)
|
|
163
|
+
.toBe(200)
|
|
164
|
+
|
|
165
|
+
t
|
|
166
|
+
.expect(yield* getResponse.text)
|
|
167
|
+
.toBe("GET data")
|
|
168
|
+
|
|
169
|
+
const postResponse = yield* client.post("/api/data")
|
|
170
|
+
|
|
171
|
+
t
|
|
172
|
+
.expect(postResponse.status)
|
|
173
|
+
.toBe(200)
|
|
174
|
+
|
|
175
|
+
t
|
|
176
|
+
.expect(yield* postResponse.text)
|
|
177
|
+
.toBe("POST data")
|
|
178
|
+
}))
|
|
179
|
+
|
|
180
|
+
t.it(
|
|
181
|
+
"Route chaining: RouteNotFound error chains to next router (root mount)",
|
|
182
|
+
() =>
|
|
183
|
+
effect(function*() {
|
|
184
|
+
const subApp1 = HttpRouter.empty.pipe(
|
|
185
|
+
HttpRouter.get(
|
|
186
|
+
"/admin/dashboard",
|
|
187
|
+
HttpServerResponse.text("Dashboard from subApp1"),
|
|
188
|
+
),
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
const subApp2 = HttpRouter.empty.pipe(
|
|
192
|
+
HttpRouter.get(
|
|
193
|
+
"/admin/page",
|
|
194
|
+
HttpServerResponse.text("Page from subApp2"),
|
|
195
|
+
),
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
const router = HttpRouter.empty.pipe(
|
|
199
|
+
HttpRouter.mount("/", subApp1),
|
|
200
|
+
HttpRouter.mount("/", subApp2),
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
const client = TestHttpClient.make(router)
|
|
204
|
+
const response = yield* client.get("/admin/page")
|
|
205
|
+
|
|
206
|
+
t
|
|
207
|
+
.expect(response.status)
|
|
208
|
+
.toBe(200)
|
|
209
|
+
|
|
210
|
+
t
|
|
211
|
+
.expect(yield* response.text)
|
|
212
|
+
.toBe("Page from subApp2")
|
|
213
|
+
}),
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
t.it(
|
|
217
|
+
"Route chaining: explicit 404 response does not chain to next router (root mount)",
|
|
218
|
+
() =>
|
|
219
|
+
effect(function*() {
|
|
220
|
+
const subApp1 = HttpRouter.empty.pipe(
|
|
221
|
+
HttpRouter.get(
|
|
222
|
+
"/admin/page",
|
|
223
|
+
HttpServerResponse.empty({ status: 404 }),
|
|
224
|
+
),
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
const subApp2 = HttpRouter.empty.pipe(
|
|
228
|
+
HttpRouter.get(
|
|
229
|
+
"/admin/fallback",
|
|
230
|
+
HttpServerResponse.text("Fallback from subApp2"),
|
|
231
|
+
),
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
const router = HttpRouter.empty.pipe(
|
|
235
|
+
HttpRouter.mount("/", subApp1),
|
|
236
|
+
HttpRouter.mount("/", subApp2),
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
const client = TestHttpClient.make(router)
|
|
240
|
+
const response = yield* client.get("/admin/page")
|
|
241
|
+
|
|
242
|
+
t
|
|
243
|
+
.expect(response.status)
|
|
244
|
+
.toBe(404)
|
|
245
|
+
|
|
246
|
+
t
|
|
247
|
+
.expect(yield* response.text)
|
|
248
|
+
.toBe("")
|
|
249
|
+
}),
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
t.it(
|
|
253
|
+
"Route conflicts: direct handlers win when defined before root mount",
|
|
254
|
+
() =>
|
|
255
|
+
effect(function*() {
|
|
256
|
+
const subApp = HttpRouter.empty.pipe(
|
|
257
|
+
HttpRouter.get(
|
|
258
|
+
"/admin/dashboard",
|
|
259
|
+
HttpServerResponse.text("Dashboard from subApp"),
|
|
260
|
+
),
|
|
261
|
+
HttpRouter.get(
|
|
262
|
+
"/admin/profile",
|
|
263
|
+
HttpServerResponse.text("Profile from subApp"),
|
|
264
|
+
),
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
const router = HttpRouter.empty.pipe(
|
|
268
|
+
HttpRouter.get(
|
|
269
|
+
"/admin/settings",
|
|
270
|
+
HttpServerResponse.text("Settings from direct handler"),
|
|
271
|
+
),
|
|
272
|
+
HttpRouter.get(
|
|
273
|
+
"/admin/users",
|
|
274
|
+
HttpServerResponse.text("Users from direct handler"),
|
|
275
|
+
),
|
|
276
|
+
HttpRouter.mount("/", subApp),
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
const client = TestHttpClient.make(router)
|
|
280
|
+
|
|
281
|
+
const settingsResponse = yield* client.get("/admin/settings")
|
|
282
|
+
|
|
283
|
+
t
|
|
284
|
+
.expect(settingsResponse.status)
|
|
285
|
+
.toBe(200)
|
|
286
|
+
|
|
287
|
+
t
|
|
288
|
+
.expect(yield* settingsResponse.text)
|
|
289
|
+
.toBe("Settings from direct handler")
|
|
290
|
+
|
|
291
|
+
const usersResponse = yield* client.get("/admin/users")
|
|
292
|
+
|
|
293
|
+
t
|
|
294
|
+
.expect(usersResponse.status)
|
|
295
|
+
.toBe(200)
|
|
296
|
+
|
|
297
|
+
t
|
|
298
|
+
.expect(yield* usersResponse.text)
|
|
299
|
+
.toBe("Users from direct handler")
|
|
300
|
+
|
|
301
|
+
const dashboardResponse = yield* client.get("/admin/dashboard")
|
|
302
|
+
|
|
303
|
+
t
|
|
304
|
+
.expect(dashboardResponse.status)
|
|
305
|
+
.toBe(200)
|
|
306
|
+
|
|
307
|
+
t
|
|
308
|
+
.expect(yield* dashboardResponse.text)
|
|
309
|
+
.toBe("Dashboard from subApp")
|
|
310
|
+
}),
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
t.it(
|
|
314
|
+
"Route conflicts: root mount wins when defined before direct handlers",
|
|
315
|
+
() =>
|
|
316
|
+
effect(function*() {
|
|
317
|
+
const subApp = HttpRouter.empty.pipe(
|
|
318
|
+
HttpRouter.get(
|
|
319
|
+
"/admin/dashboard",
|
|
320
|
+
HttpServerResponse.text("Dashboard from subApp"),
|
|
321
|
+
),
|
|
322
|
+
HttpRouter.get(
|
|
323
|
+
"/admin/profile",
|
|
324
|
+
HttpServerResponse.text("Profile from subApp"),
|
|
325
|
+
),
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
const router = HttpRouter.empty.pipe(
|
|
329
|
+
HttpRouter.mount("/", subApp),
|
|
330
|
+
HttpRouter.get(
|
|
331
|
+
"/admin/settings",
|
|
332
|
+
HttpServerResponse.text("Settings from direct handler"),
|
|
333
|
+
),
|
|
334
|
+
HttpRouter.get(
|
|
335
|
+
"/admin/users",
|
|
336
|
+
HttpServerResponse.text("Users from direct handler"),
|
|
337
|
+
),
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
const client = TestHttpClient.make(router)
|
|
341
|
+
|
|
342
|
+
const profileResponse = yield* client.get("/admin/profile")
|
|
343
|
+
|
|
344
|
+
t
|
|
345
|
+
.expect(profileResponse.status)
|
|
346
|
+
.toBe(200)
|
|
347
|
+
|
|
348
|
+
t
|
|
349
|
+
.expect(yield* profileResponse.text)
|
|
350
|
+
.toBe("Profile from subApp")
|
|
351
|
+
|
|
352
|
+
const usersResponse = yield* client.get("/admin/users")
|
|
353
|
+
|
|
354
|
+
t
|
|
355
|
+
.expect(usersResponse.status)
|
|
356
|
+
.toBe(200)
|
|
357
|
+
|
|
358
|
+
t
|
|
359
|
+
.expect(yield* usersResponse.text)
|
|
360
|
+
.toBe("Users from direct handler")
|
|
361
|
+
|
|
362
|
+
const dashboardResponse = yield* client.get("/admin/dashboard")
|
|
363
|
+
|
|
364
|
+
t
|
|
365
|
+
.expect(dashboardResponse.status)
|
|
366
|
+
.toBe(200)
|
|
367
|
+
|
|
368
|
+
t
|
|
369
|
+
.expect(yield* dashboardResponse.text)
|
|
370
|
+
.toBe("Dashboard from subApp")
|
|
371
|
+
}),
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
t.it(
|
|
375
|
+
"Route conflicts: mountApp does not chain with direct handlers defined before",
|
|
376
|
+
() =>
|
|
377
|
+
effect(function*() {
|
|
378
|
+
const subApp = HttpRouter.empty.pipe(
|
|
379
|
+
HttpRouter.get(
|
|
380
|
+
"/admin/dashboard",
|
|
381
|
+
HttpServerResponse.text("Dashboard from subApp"),
|
|
382
|
+
),
|
|
383
|
+
HttpRouter.get(
|
|
384
|
+
"/admin/profile",
|
|
385
|
+
HttpServerResponse.text("Profile from subApp"),
|
|
386
|
+
),
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
const router = HttpRouter.empty.pipe(
|
|
390
|
+
HttpRouter.get(
|
|
391
|
+
"/admin/settings",
|
|
392
|
+
HttpServerResponse.text("Settings from direct handler"),
|
|
393
|
+
),
|
|
394
|
+
HttpRouter.get(
|
|
395
|
+
"/admin/users",
|
|
396
|
+
HttpServerResponse.text("Users from direct handler"),
|
|
397
|
+
),
|
|
398
|
+
HttpRouter.mountApp("/", subApp),
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
const client = TestHttpClient.make(router)
|
|
402
|
+
|
|
403
|
+
const settingsResponse = yield* client.get("/admin/settings")
|
|
404
|
+
|
|
405
|
+
t
|
|
406
|
+
.expect(settingsResponse.status)
|
|
407
|
+
.toBe(404)
|
|
408
|
+
|
|
409
|
+
const usersResponse = yield* client.get("/admin/users")
|
|
410
|
+
|
|
411
|
+
t
|
|
412
|
+
.expect(usersResponse.status)
|
|
413
|
+
.toBe(404)
|
|
414
|
+
|
|
415
|
+
const dashboardResponse = yield* client.get("/admin/dashboard")
|
|
416
|
+
|
|
417
|
+
t
|
|
418
|
+
.expect(dashboardResponse.status)
|
|
419
|
+
.toBe(200)
|
|
420
|
+
|
|
421
|
+
t
|
|
422
|
+
.expect(yield* dashboardResponse.text)
|
|
423
|
+
.toBe("Dashboard from subApp")
|
|
424
|
+
}),
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
t.it(
|
|
428
|
+
"Route conflicts: mountApp does not chain with direct handlers defined after",
|
|
429
|
+
() =>
|
|
430
|
+
effect(function*() {
|
|
431
|
+
const subApp = HttpRouter.empty.pipe(
|
|
432
|
+
HttpRouter.get(
|
|
433
|
+
"/admin/dashboard",
|
|
434
|
+
HttpServerResponse.text("Dashboard from subApp"),
|
|
435
|
+
),
|
|
436
|
+
HttpRouter.get(
|
|
437
|
+
"/admin/profile",
|
|
438
|
+
HttpServerResponse.text("Profile from subApp"),
|
|
439
|
+
),
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
const router = HttpRouter.empty.pipe(
|
|
443
|
+
HttpRouter.mountApp("/", subApp),
|
|
444
|
+
HttpRouter.get(
|
|
445
|
+
"/admin/settings",
|
|
446
|
+
HttpServerResponse.text("Settings from direct handler"),
|
|
447
|
+
),
|
|
448
|
+
HttpRouter.get(
|
|
449
|
+
"/admin/users",
|
|
450
|
+
HttpServerResponse.text("Users from direct handler"),
|
|
451
|
+
),
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
const client = TestHttpClient.make(router)
|
|
455
|
+
|
|
456
|
+
const profileResponse = yield* client.get("/admin/profile")
|
|
457
|
+
|
|
458
|
+
t
|
|
459
|
+
.expect(profileResponse.status)
|
|
460
|
+
.toBe(200)
|
|
461
|
+
|
|
462
|
+
t
|
|
463
|
+
.expect(yield* profileResponse.text)
|
|
464
|
+
.toBe("Profile from subApp")
|
|
465
|
+
|
|
466
|
+
const settingsResponse = yield* client.get("/admin/settings")
|
|
467
|
+
|
|
468
|
+
t
|
|
469
|
+
.expect(settingsResponse.status)
|
|
470
|
+
.toBe(404)
|
|
471
|
+
|
|
472
|
+
const dashboardResponse = yield* client.get("/admin/dashboard")
|
|
473
|
+
|
|
474
|
+
t
|
|
475
|
+
.expect(dashboardResponse.status)
|
|
476
|
+
.toBe(200)
|
|
477
|
+
|
|
478
|
+
t
|
|
479
|
+
.expect(yield* dashboardResponse.text)
|
|
480
|
+
.toBe("Dashboard from subApp")
|
|
481
|
+
}),
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
t.it(
|
|
485
|
+
"Wildcard routes: single asterisk wildcard handler",
|
|
486
|
+
() =>
|
|
487
|
+
effect(function*() {
|
|
488
|
+
const router = HttpRouter.empty.pipe(
|
|
489
|
+
HttpRouter.get("*", HttpServerResponse.text("Wildcard handler")),
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
const client = TestHttpClient.make(router)
|
|
493
|
+
|
|
494
|
+
const response = yield* client.get("/anything")
|
|
495
|
+
|
|
496
|
+
t
|
|
497
|
+
.expect(response.status)
|
|
498
|
+
.toBe(200)
|
|
499
|
+
|
|
500
|
+
t
|
|
501
|
+
.expect(yield* response.text)
|
|
502
|
+
.toBe("Wildcard handler")
|
|
503
|
+
}),
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
t.it(
|
|
507
|
+
"Wildcard routes: wildcard defined before literal route",
|
|
508
|
+
() =>
|
|
509
|
+
effect(function*() {
|
|
510
|
+
const router = HttpRouter.empty.pipe(
|
|
511
|
+
HttpRouter.get("*", HttpServerResponse.text("Wildcard handler")),
|
|
512
|
+
HttpRouter.get("/specific", HttpServerResponse.text("Literal handler")),
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
const client = TestHttpClient.make(router)
|
|
516
|
+
|
|
517
|
+
const wildcardResponse = yield* client.get("/anything")
|
|
518
|
+
|
|
519
|
+
t
|
|
520
|
+
.expect(wildcardResponse.status)
|
|
521
|
+
.toBe(200)
|
|
522
|
+
|
|
523
|
+
t
|
|
524
|
+
.expect(yield* wildcardResponse.text)
|
|
525
|
+
.toBe("Wildcard handler")
|
|
526
|
+
|
|
527
|
+
const literalResponse = yield* client.get("/specific")
|
|
528
|
+
|
|
529
|
+
t
|
|
530
|
+
.expect(literalResponse.status)
|
|
531
|
+
.toBe(200)
|
|
532
|
+
|
|
533
|
+
t
|
|
534
|
+
.expect(yield* literalResponse.text)
|
|
535
|
+
.toBe("Literal handler")
|
|
536
|
+
}),
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
t.it(
|
|
540
|
+
"Wildcard routes: literal route defined before wildcard",
|
|
541
|
+
() =>
|
|
542
|
+
effect(function*() {
|
|
543
|
+
const router = HttpRouter.empty.pipe(
|
|
544
|
+
HttpRouter.get("/specific", HttpServerResponse.text("Literal handler")),
|
|
545
|
+
HttpRouter.get("*", HttpServerResponse.text("Wildcard handler")),
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
const client = TestHttpClient.make(router)
|
|
549
|
+
|
|
550
|
+
const literalResponse = yield* client.get("/specific")
|
|
551
|
+
|
|
552
|
+
t
|
|
553
|
+
.expect(literalResponse.status)
|
|
554
|
+
.toBe(200)
|
|
555
|
+
|
|
556
|
+
t
|
|
557
|
+
.expect(yield* literalResponse.text)
|
|
558
|
+
.toBe("Literal handler")
|
|
559
|
+
|
|
560
|
+
const wildcardResponse = yield* client.get("/anything")
|
|
561
|
+
|
|
562
|
+
t
|
|
563
|
+
.expect(wildcardResponse.status)
|
|
564
|
+
.toBe(200)
|
|
565
|
+
|
|
566
|
+
t
|
|
567
|
+
.expect(yield* wildcardResponse.text)
|
|
568
|
+
.toBe("Wildcard handler")
|
|
569
|
+
}),
|
|
570
|
+
)
|