@xano/developer-mcp 1.0.26 → 1.0.27
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/xanoscript_docs/README.md +78 -64
- package/dist/xanoscript_docs/apis.md +81 -27
- package/dist/xanoscript_docs/branch.md +13 -13
- package/dist/xanoscript_docs/database.md +57 -17
- package/dist/xanoscript_docs/functions.md +43 -71
- package/dist/xanoscript_docs/performance.md +14 -23
- package/dist/xanoscript_docs/tables.md +47 -1
- package/dist/xanoscript_docs/tools.md +9 -7
- package/dist/xanoscript_docs/types.md +12 -10
- package/package.json +1 -1
- package/dist/api_docs/format.d.ts +0 -5
- package/dist/api_docs/format.js +0 -171
- package/dist/api_docs/index.d.ts +0 -52
- package/dist/api_docs/index.js +0 -111
- package/dist/api_docs/topics/agent.d.ts +0 -2
- package/dist/api_docs/topics/agent.js +0 -142
- package/dist/api_docs/topics/api.d.ts +0 -2
- package/dist/api_docs/topics/api.js +0 -176
- package/dist/api_docs/topics/apigroup.d.ts +0 -2
- package/dist/api_docs/topics/apigroup.js +0 -124
- package/dist/api_docs/topics/authentication.d.ts +0 -2
- package/dist/api_docs/topics/authentication.js +0 -61
- package/dist/api_docs/topics/branch.d.ts +0 -2
- package/dist/api_docs/topics/branch.js +0 -73
- package/dist/api_docs/topics/file.d.ts +0 -2
- package/dist/api_docs/topics/file.js +0 -70
- package/dist/api_docs/topics/function.d.ts +0 -2
- package/dist/api_docs/topics/function.js +0 -164
- package/dist/api_docs/topics/history.d.ts +0 -2
- package/dist/api_docs/topics/history.js +0 -149
- package/dist/api_docs/topics/mcp_server.d.ts +0 -2
- package/dist/api_docs/topics/mcp_server.js +0 -139
- package/dist/api_docs/topics/middleware.d.ts +0 -2
- package/dist/api_docs/topics/middleware.js +0 -156
- package/dist/api_docs/topics/realtime.d.ts +0 -2
- package/dist/api_docs/topics/realtime.js +0 -112
- package/dist/api_docs/topics/start.d.ts +0 -2
- package/dist/api_docs/topics/start.js +0 -107
- package/dist/api_docs/topics/table.d.ts +0 -2
- package/dist/api_docs/topics/table.js +0 -195
- package/dist/api_docs/topics/task.d.ts +0 -2
- package/dist/api_docs/topics/task.js +0 -165
- package/dist/api_docs/topics/tool.d.ts +0 -2
- package/dist/api_docs/topics/tool.js +0 -150
- package/dist/api_docs/topics/workflows.d.ts +0 -2
- package/dist/api_docs/topics/workflows.js +0 -131
- package/dist/api_docs/topics/workspace.d.ts +0 -2
- package/dist/api_docs/topics/workspace.js +0 -153
- package/dist/api_docs/types.d.ts +0 -79
- package/dist/api_docs/types.js +0 -4
- package/dist/templates/init-workspace.d.ts +0 -10
- package/dist/templates/init-workspace.js +0 -278
- package/dist/templates/xanoscript-index.d.ts +0 -11
- package/dist/templates/xanoscript-index.js +0 -72
- package/dist/xanoscript_docs/ephemeral.md +0 -330
- package/dist/xanoscript_docs_auto/README.md +0 -119
- package/dist/xanoscript_docs_auto/agents.md +0 -446
- package/dist/xanoscript_docs_auto/apis.md +0 -517
- package/dist/xanoscript_docs_auto/control-flow.md +0 -543
- package/dist/xanoscript_docs_auto/database.md +0 -551
- package/dist/xanoscript_docs_auto/debugging.md +0 -527
- package/dist/xanoscript_docs_auto/filters.md +0 -464
- package/dist/xanoscript_docs_auto/functions.md +0 -431
- package/dist/xanoscript_docs_auto/integrations.md +0 -657
- package/dist/xanoscript_docs_auto/mcp-servers.md +0 -408
- package/dist/xanoscript_docs_auto/operators.md +0 -368
- package/dist/xanoscript_docs_auto/syntax.md +0 -287
- package/dist/xanoscript_docs_auto/tables.md +0 -447
- package/dist/xanoscript_docs_auto/tasks.md +0 -479
- package/dist/xanoscript_docs_auto/testing.md +0 -574
- package/dist/xanoscript_docs_auto/tools.md +0 -485
- package/dist/xanoscript_docs_auto/triggers.md +0 -595
- package/dist/xanoscript_docs_auto/types.md +0 -323
- package/dist/xanoscript_docs_auto/variables.md +0 -462
- package/dist/xanoscript_docs_auto/version.json +0 -5
|
@@ -1,574 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
applyTo: "functions/**/*.xs,apis/**/*.xs"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Testing
|
|
6
|
-
|
|
7
|
-
Unit tests, mocks, and assertions in XanoScript.
|
|
8
|
-
|
|
9
|
-
## Quick Reference
|
|
10
|
-
|
|
11
|
-
```xs
|
|
12
|
-
function "my_function" {
|
|
13
|
-
// ... implementation ...
|
|
14
|
-
|
|
15
|
-
test "test name" {
|
|
16
|
-
function.call {
|
|
17
|
-
input = {param: "value"}
|
|
18
|
-
} as $result
|
|
19
|
-
|
|
20
|
-
expect.to_equal {
|
|
21
|
-
input = $result
|
|
22
|
-
value = "expected"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## Test Block
|
|
31
|
-
|
|
32
|
-
Add tests directly within functions:
|
|
33
|
-
|
|
34
|
-
```xs
|
|
35
|
-
function "add_numbers" {
|
|
36
|
-
input {
|
|
37
|
-
int a
|
|
38
|
-
int b
|
|
39
|
-
}
|
|
40
|
-
stack {
|
|
41
|
-
var $sum { value = $input.a + $input.b }
|
|
42
|
-
}
|
|
43
|
-
response = $sum
|
|
44
|
-
|
|
45
|
-
test "adds positive numbers" {
|
|
46
|
-
function.call {
|
|
47
|
-
input = {a: 2, b: 3}
|
|
48
|
-
} as $result
|
|
49
|
-
|
|
50
|
-
expect.to_equal {
|
|
51
|
-
input = $result
|
|
52
|
-
value = 5
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
test "adds negative numbers" {
|
|
57
|
-
function.call {
|
|
58
|
-
input = {a: -2, b: -3}
|
|
59
|
-
} as $result
|
|
60
|
-
|
|
61
|
-
expect.to_equal {
|
|
62
|
-
input = $result
|
|
63
|
-
value = -5
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
test "handles zero" {
|
|
68
|
-
function.call {
|
|
69
|
-
input = {a: 5, b: 0}
|
|
70
|
-
} as $result
|
|
71
|
-
|
|
72
|
-
expect.to_equal {
|
|
73
|
-
input = $result
|
|
74
|
-
value = 5
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## Calling Functions in Tests
|
|
83
|
-
|
|
84
|
-
### function.call
|
|
85
|
-
|
|
86
|
-
Call the current function:
|
|
87
|
-
|
|
88
|
-
```xs
|
|
89
|
-
function.call {
|
|
90
|
-
input = {
|
|
91
|
-
name: "test",
|
|
92
|
-
value: 123
|
|
93
|
-
}
|
|
94
|
-
} as $result
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### With Mocks
|
|
98
|
-
|
|
99
|
-
Override external calls:
|
|
100
|
-
|
|
101
|
-
```xs
|
|
102
|
-
test "handles database error" {
|
|
103
|
-
function.call {
|
|
104
|
-
input = {user_id: 1}
|
|
105
|
-
mock = {
|
|
106
|
-
"db.get user": null
|
|
107
|
-
}
|
|
108
|
-
} as $result
|
|
109
|
-
|
|
110
|
-
expect.to_be_null { input = $result }
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
## Assertions
|
|
117
|
-
|
|
118
|
-
### Equality
|
|
119
|
-
|
|
120
|
-
```xs
|
|
121
|
-
expect.to_equal {
|
|
122
|
-
input = $result
|
|
123
|
-
value = "expected value"
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
expect.to_not_equal {
|
|
127
|
-
input = $result
|
|
128
|
-
value = "unexpected value"
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### Boolean
|
|
133
|
-
|
|
134
|
-
```xs
|
|
135
|
-
expect.to_be_true { input = $condition }
|
|
136
|
-
|
|
137
|
-
expect.to_be_false { input = $condition }
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Null/Defined
|
|
141
|
-
|
|
142
|
-
```xs
|
|
143
|
-
expect.to_be_null { input = $value }
|
|
144
|
-
|
|
145
|
-
expect.to_not_be_null { input = $value }
|
|
146
|
-
|
|
147
|
-
expect.to_be_defined { input = $value }
|
|
148
|
-
|
|
149
|
-
expect.to_not_be_defined { input = $value }
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Empty
|
|
153
|
-
|
|
154
|
-
```xs
|
|
155
|
-
expect.to_be_empty { input = $array }
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### Contains
|
|
159
|
-
|
|
160
|
-
```xs
|
|
161
|
-
expect.to_contain {
|
|
162
|
-
input = $array
|
|
163
|
-
value = $item
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### String Assertions
|
|
168
|
-
|
|
169
|
-
```xs
|
|
170
|
-
expect.to_start_with {
|
|
171
|
-
input = $string
|
|
172
|
-
value = "prefix"
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
expect.to_end_with {
|
|
176
|
-
input = $string
|
|
177
|
-
value = "suffix"
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
expect.to_match {
|
|
181
|
-
input = $string
|
|
182
|
-
value = "^[A-Z]+$" // Regex pattern
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Numeric Comparisons
|
|
187
|
-
|
|
188
|
-
```xs
|
|
189
|
-
expect.to_be_greater_than {
|
|
190
|
-
input = $value
|
|
191
|
-
value = 10
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
expect.to_be_less_than {
|
|
195
|
-
input = $value
|
|
196
|
-
value = 100
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
expect.to_be_within {
|
|
200
|
-
input = $value
|
|
201
|
-
min = 0
|
|
202
|
-
max = 100
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### Date Assertions
|
|
207
|
-
|
|
208
|
-
```xs
|
|
209
|
-
expect.to_be_in_the_past { input = $timestamp }
|
|
210
|
-
|
|
211
|
-
expect.to_be_in_the_future { input = $timestamp }
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
### Error Assertions
|
|
215
|
-
|
|
216
|
-
```xs
|
|
217
|
-
expect.to_throw {
|
|
218
|
-
run {
|
|
219
|
-
function.call {
|
|
220
|
-
input = {invalid: true}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
---
|
|
227
|
-
|
|
228
|
-
## Mocking
|
|
229
|
-
|
|
230
|
-
### Mock Database Calls
|
|
231
|
-
|
|
232
|
-
```xs
|
|
233
|
-
test "returns user profile" {
|
|
234
|
-
function.call {
|
|
235
|
-
input = {user_id: 1}
|
|
236
|
-
mock = {
|
|
237
|
-
"db.get user": {
|
|
238
|
-
id: 1,
|
|
239
|
-
name: "Test User",
|
|
240
|
-
email: "test@example.com"
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
} as $result
|
|
244
|
-
|
|
245
|
-
expect.to_equal {
|
|
246
|
-
input = $result.name
|
|
247
|
-
value = "Test User"
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
### Mock Database Queries
|
|
253
|
-
|
|
254
|
-
```xs
|
|
255
|
-
test "returns filtered products" {
|
|
256
|
-
function.call {
|
|
257
|
-
input = {category: "electronics"}
|
|
258
|
-
mock = {
|
|
259
|
-
"db.query product": [
|
|
260
|
-
{id: 1, name: "Phone", price: 599},
|
|
261
|
-
{id: 2, name: "Laptop", price: 999}
|
|
262
|
-
]
|
|
263
|
-
}
|
|
264
|
-
} as $result
|
|
265
|
-
|
|
266
|
-
expect.to_equal {
|
|
267
|
-
input = $result|count
|
|
268
|
-
value = 2
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
### Mock API Calls
|
|
274
|
-
|
|
275
|
-
```xs
|
|
276
|
-
test "fetches external data" {
|
|
277
|
-
function.call {
|
|
278
|
-
input = {}
|
|
279
|
-
mock = {
|
|
280
|
-
"api.request": {
|
|
281
|
-
status: 200,
|
|
282
|
-
data: {items: [1, 2, 3]}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
} as $result
|
|
286
|
-
|
|
287
|
-
expect.to_equal {
|
|
288
|
-
input = $result.items|count
|
|
289
|
-
value = 3
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### Mock Function Calls
|
|
295
|
-
|
|
296
|
-
```xs
|
|
297
|
-
test "uses helper function" {
|
|
298
|
-
function.call {
|
|
299
|
-
input = {value: 100}
|
|
300
|
-
mock = {
|
|
301
|
-
"function.run calculate_tax": 10
|
|
302
|
-
}
|
|
303
|
-
} as $result
|
|
304
|
-
|
|
305
|
-
expect.to_equal {
|
|
306
|
-
input = $result.total
|
|
307
|
-
value = 110
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
---
|
|
313
|
-
|
|
314
|
-
## Testing Patterns
|
|
315
|
-
|
|
316
|
-
### Test Edge Cases
|
|
317
|
-
|
|
318
|
-
```xs
|
|
319
|
-
function "divide" {
|
|
320
|
-
input {
|
|
321
|
-
decimal a
|
|
322
|
-
decimal b
|
|
323
|
-
}
|
|
324
|
-
stack {
|
|
325
|
-
precondition ($input.b != 0) {
|
|
326
|
-
error_type = "inputerror"
|
|
327
|
-
error = "Cannot divide by zero"
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
var $result { value = $input.a / $input.b }
|
|
331
|
-
}
|
|
332
|
-
response = $result
|
|
333
|
-
|
|
334
|
-
test "divides numbers" {
|
|
335
|
-
function.call {
|
|
336
|
-
input = {a: 10, b: 2}
|
|
337
|
-
} as $result
|
|
338
|
-
|
|
339
|
-
expect.to_equal { input = $result, value = 5 }
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
test "handles decimals" {
|
|
343
|
-
function.call {
|
|
344
|
-
input = {a: 7, b: 2}
|
|
345
|
-
} as $result
|
|
346
|
-
|
|
347
|
-
expect.to_equal { input = $result, value = 3.5 }
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
test "throws on divide by zero" {
|
|
351
|
-
expect.to_throw {
|
|
352
|
-
run {
|
|
353
|
-
function.call {
|
|
354
|
-
input = {a: 10, b: 0}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
### Test Database Operations
|
|
363
|
-
|
|
364
|
-
```xs
|
|
365
|
-
function "get_user_orders" {
|
|
366
|
-
input {
|
|
367
|
-
int user_id
|
|
368
|
-
}
|
|
369
|
-
stack {
|
|
370
|
-
db.query order {
|
|
371
|
-
where = $db.order.user_id == $input.user_id
|
|
372
|
-
order_by = {field: "created_at", direction: "desc"}
|
|
373
|
-
} as $orders
|
|
374
|
-
}
|
|
375
|
-
response = $orders
|
|
376
|
-
|
|
377
|
-
test "returns orders for user" {
|
|
378
|
-
function.call {
|
|
379
|
-
input = {user_id: 1}
|
|
380
|
-
mock = {
|
|
381
|
-
"db.query order": [
|
|
382
|
-
{id: 1, user_id: 1, total: 100},
|
|
383
|
-
{id: 2, user_id: 1, total: 200}
|
|
384
|
-
]
|
|
385
|
-
}
|
|
386
|
-
} as $result
|
|
387
|
-
|
|
388
|
-
expect.to_equal { input = $result|count, value = 2 }
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
test "returns empty for user with no orders" {
|
|
392
|
-
function.call {
|
|
393
|
-
input = {user_id: 999}
|
|
394
|
-
mock = {
|
|
395
|
-
"db.query order": []
|
|
396
|
-
}
|
|
397
|
-
} as $result
|
|
398
|
-
|
|
399
|
-
expect.to_be_empty { input = $result }
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
### Test Conditional Logic
|
|
405
|
-
|
|
406
|
-
```xs
|
|
407
|
-
function "get_discount" {
|
|
408
|
-
input {
|
|
409
|
-
decimal total
|
|
410
|
-
text? coupon
|
|
411
|
-
}
|
|
412
|
-
stack {
|
|
413
|
-
var $discount { value = 0 }
|
|
414
|
-
|
|
415
|
-
// Volume discount
|
|
416
|
-
conditional {
|
|
417
|
-
if ($input.total >= 100) {
|
|
418
|
-
var.update $discount { value = 0.1 }
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// Coupon discount
|
|
423
|
-
conditional {
|
|
424
|
-
if ($input.coupon == "SAVE20") {
|
|
425
|
-
var.update $discount { value = 0.2 }
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
response = $discount
|
|
430
|
-
|
|
431
|
-
test "no discount for small orders" {
|
|
432
|
-
function.call {
|
|
433
|
-
input = {total: 50}
|
|
434
|
-
} as $result
|
|
435
|
-
|
|
436
|
-
expect.to_equal { input = $result, value = 0 }
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
test "volume discount for large orders" {
|
|
440
|
-
function.call {
|
|
441
|
-
input = {total: 150}
|
|
442
|
-
} as $result
|
|
443
|
-
|
|
444
|
-
expect.to_equal { input = $result, value = 0.1 }
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
test "coupon discount overrides volume" {
|
|
448
|
-
function.call {
|
|
449
|
-
input = {total: 150, coupon: "SAVE20"}
|
|
450
|
-
} as $result
|
|
451
|
-
|
|
452
|
-
expect.to_equal { input = $result, value = 0.2 }
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
---
|
|
458
|
-
|
|
459
|
-
## Testing APIs
|
|
460
|
-
|
|
461
|
-
```xs
|
|
462
|
-
query "create_user" verb=POST {
|
|
463
|
-
input {
|
|
464
|
-
text name
|
|
465
|
-
email user_email
|
|
466
|
-
}
|
|
467
|
-
stack {
|
|
468
|
-
db.add user {
|
|
469
|
-
data = {
|
|
470
|
-
name: $input.name,
|
|
471
|
-
email: $input.user_email
|
|
472
|
-
}
|
|
473
|
-
} as $user
|
|
474
|
-
}
|
|
475
|
-
response = $user
|
|
476
|
-
|
|
477
|
-
test "creates user" {
|
|
478
|
-
function.call {
|
|
479
|
-
input = {name: "Test", user_email: "test@example.com"}
|
|
480
|
-
mock = {
|
|
481
|
-
"db.add user": {
|
|
482
|
-
id: 1,
|
|
483
|
-
name: "Test",
|
|
484
|
-
email: "test@example.com"
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
} as $result
|
|
488
|
-
|
|
489
|
-
expect.to_equal { input = $result.name, value = "Test" }
|
|
490
|
-
expect.to_equal { input = $result.email, value = "test@example.com" }
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
---
|
|
496
|
-
|
|
497
|
-
## Testing Tasks
|
|
498
|
-
|
|
499
|
-
```xs
|
|
500
|
-
task "daily_cleanup" {
|
|
501
|
-
stack {
|
|
502
|
-
db.bulk.delete session {
|
|
503
|
-
where = $db.session.expires_at < now
|
|
504
|
-
} as $deleted
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
test "deletes expired sessions" {
|
|
508
|
-
task.call {
|
|
509
|
-
mock = {
|
|
510
|
-
"db.bulk.delete session": {count: 5}
|
|
511
|
-
}
|
|
512
|
-
} as $result
|
|
513
|
-
|
|
514
|
-
expect.to_be_true { input = true }
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
schedule { ... }
|
|
518
|
-
}
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
---
|
|
522
|
-
|
|
523
|
-
## Best Practices
|
|
524
|
-
|
|
525
|
-
### Name Tests Clearly
|
|
526
|
-
|
|
527
|
-
```xs
|
|
528
|
-
// Good: Describes behavior
|
|
529
|
-
test "returns null for non-existent user" { ... }
|
|
530
|
-
|
|
531
|
-
// Bad: Vague
|
|
532
|
-
test "test 1" { ... }
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
### Test One Thing Per Test
|
|
536
|
-
|
|
537
|
-
```xs
|
|
538
|
-
// Good: Focused tests
|
|
539
|
-
test "calculates subtotal" { ... }
|
|
540
|
-
test "applies discount" { ... }
|
|
541
|
-
test "adds tax" { ... }
|
|
542
|
-
|
|
543
|
-
// Bad: Multiple assertions
|
|
544
|
-
test "calculates order total" {
|
|
545
|
-
// Tests subtotal, discount, tax, and total
|
|
546
|
-
}
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
### Use Meaningful Mock Data
|
|
550
|
-
|
|
551
|
-
```xs
|
|
552
|
-
// Good: Realistic data
|
|
553
|
-
mock = {
|
|
554
|
-
"db.get user": {
|
|
555
|
-
id: 1,
|
|
556
|
-
name: "Jane Smith",
|
|
557
|
-
email: "jane@example.com",
|
|
558
|
-
created_at: "2024-01-15 10:30:00+0000"
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// Bad: Minimal data
|
|
563
|
-
mock = {
|
|
564
|
-
"db.get user": {id: 1}
|
|
565
|
-
}
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
### Test Error Cases
|
|
569
|
-
|
|
570
|
-
```xs
|
|
571
|
-
test "handles missing user" { ... }
|
|
572
|
-
test "rejects invalid input" { ... }
|
|
573
|
-
test "handles API timeout" { ... }
|
|
574
|
-
```
|