@schmock/core 2.2.3 → 2.3.1

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.
Files changed (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -0
  3. package/dist/abort.d.ts +3 -0
  4. package/dist/abort.d.ts.map +1 -0
  5. package/dist/abort.js +30 -0
  6. package/dist/binary.d.ts +8 -0
  7. package/dist/binary.d.ts.map +1 -0
  8. package/dist/binary.js +9 -0
  9. package/dist/builder.d.ts +31 -10
  10. package/dist/builder.d.ts.map +1 -1
  11. package/dist/builder.js +804 -203
  12. package/dist/constants.d.ts +38 -0
  13. package/dist/constants.d.ts.map +1 -1
  14. package/dist/constants.js +123 -2
  15. package/dist/errors.d.ts +14 -3
  16. package/dist/errors.d.ts.map +1 -1
  17. package/dist/errors.js +41 -6
  18. package/dist/helpers.d.ts +9 -0
  19. package/dist/helpers.d.ts.map +1 -1
  20. package/dist/helpers.js +18 -2
  21. package/dist/http-helpers.d.ts +52 -5
  22. package/dist/http-helpers.d.ts.map +1 -1
  23. package/dist/http-helpers.js +153 -37
  24. package/dist/index.d.ts +381 -60
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +9 -3
  27. package/dist/interceptor.d.ts +11 -1
  28. package/dist/interceptor.d.ts.map +1 -1
  29. package/dist/interceptor.js +354 -156
  30. package/dist/parser.d.ts.map +1 -1
  31. package/dist/parser.js +12 -3
  32. package/dist/plugin-pipeline.d.ts +11 -4
  33. package/dist/plugin-pipeline.d.ts.map +1 -1
  34. package/dist/plugin-pipeline.js +117 -39
  35. package/dist/response-normalizer.d.ts +16 -0
  36. package/dist/response-normalizer.d.ts.map +1 -0
  37. package/dist/response-normalizer.js +316 -0
  38. package/dist/response-parser.d.ts.map +1 -1
  39. package/dist/response-parser.js +85 -18
  40. package/dist/route-matcher.d.ts +3 -0
  41. package/dist/route-matcher.d.ts.map +1 -1
  42. package/dist/route-matcher.js +12 -6
  43. package/dist/types.d.ts +7 -2
  44. package/dist/types.d.ts.map +1 -1
  45. package/package.json +18 -8
  46. package/src/audit-core-builder.test.ts +0 -218
  47. package/src/audit-response-guard.test.ts +0 -38
  48. package/src/builder.test.ts +0 -289
  49. package/src/builder.ts +0 -701
  50. package/src/constants.test.ts +0 -99
  51. package/src/constants.ts +0 -73
  52. package/src/debug.test.ts +0 -241
  53. package/src/delay.test.ts +0 -319
  54. package/src/dist-shape.test.ts +0 -35
  55. package/src/errors.test.ts +0 -223
  56. package/src/errors.ts +0 -130
  57. package/src/factory.test.ts +0 -133
  58. package/src/helpers.test.ts +0 -147
  59. package/src/helpers.ts +0 -58
  60. package/src/http-helpers.ts +0 -113
  61. package/src/index.ts +0 -151
  62. package/src/interceptor.test.ts +0 -291
  63. package/src/interceptor.ts +0 -320
  64. package/src/namespace.test.ts +0 -274
  65. package/src/parser.property.test.ts +0 -594
  66. package/src/parser.test.ts +0 -148
  67. package/src/parser.ts +0 -64
  68. package/src/plugin-pipeline.ts +0 -103
  69. package/src/plugin-system.test.ts +0 -602
  70. package/src/response-parser.ts +0 -75
  71. package/src/response-parsing.test.ts +0 -333
  72. package/src/route-matcher.ts +0 -69
  73. package/src/route-matching.test.ts +0 -394
  74. package/src/server.test.ts +0 -165
  75. package/src/smart-defaults.test.ts +0 -361
  76. package/src/steps/async-support.steps.ts +0 -400
  77. package/src/steps/audit-core-builder.steps.ts +0 -188
  78. package/src/steps/audit-onerror-tuple.steps.ts +0 -99
  79. package/src/steps/basic-usage.steps.ts +0 -245
  80. package/src/steps/developer-experience.steps.ts +0 -204
  81. package/src/steps/error-handling.steps.ts +0 -345
  82. package/src/steps/fluent-api.steps.ts +0 -255
  83. package/src/steps/http-methods.steps.ts +0 -331
  84. package/src/steps/interceptor.steps.ts +0 -260
  85. package/src/steps/lifecycle-events.steps.ts +0 -142
  86. package/src/steps/performance-reliability.steps.ts +0 -423
  87. package/src/steps/plugin-integration.steps.ts +0 -280
  88. package/src/steps/request-history.steps.ts +0 -276
  89. package/src/steps/response-delay.steps.ts +0 -88
  90. package/src/steps/route-key-format.steps.ts +0 -99
  91. package/src/steps/standalone-server.steps.ts +0 -233
  92. package/src/steps/state-concurrency.steps.ts +0 -739
  93. package/src/steps/stateful-workflows.steps.ts +0 -353
  94. package/src/types.ts +0 -36
@@ -1,361 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { schmock } from "./index";
3
-
4
- describe("smart content-type defaults", () => {
5
- describe("primitive values", () => {
6
- it("converts numbers to strings with text/plain", async () => {
7
- const mock = schmock();
8
- mock("GET /number", 42);
9
-
10
- const response = await mock.handle("GET", "/number");
11
-
12
- expect(response.status).toBe(200);
13
- expect(response.body).toBe("42");
14
- expect(response.headers["content-type"]).toBe("text/plain");
15
- });
16
-
17
- it("converts booleans to strings with text/plain", async () => {
18
- const mock = schmock();
19
- mock("GET /bool", true);
20
-
21
- const response = await mock.handle("GET", "/bool");
22
-
23
- expect(response.status).toBe(200);
24
- expect(response.body).toBe("true");
25
- expect(response.headers["content-type"]).toBe("text/plain");
26
- });
27
-
28
- it("handles strings as text/plain", async () => {
29
- const mock = schmock();
30
- mock("GET /string", "Hello World");
31
-
32
- const response = await mock.handle("GET", "/string");
33
-
34
- expect(response.status).toBe(200);
35
- expect(response.body).toBe("Hello World");
36
- expect(response.headers["content-type"]).toBe("text/plain");
37
- });
38
-
39
- it("handles empty string as text/plain", async () => {
40
- const mock = schmock();
41
- mock("GET /empty", "");
42
-
43
- const response = await mock.handle("GET", "/empty");
44
-
45
- expect(response.status).toBe(200);
46
- expect(response.body).toBe("");
47
- expect(response.headers["content-type"]).toBe("text/plain");
48
- });
49
- });
50
-
51
- describe("objects and arrays", () => {
52
- it("handles objects as application/json", async () => {
53
- const mock = schmock();
54
- mock("GET /object", { id: 1, name: "John" });
55
-
56
- const response = await mock.handle("GET", "/object");
57
-
58
- expect(response.status).toBe(200);
59
- expect(response.body).toEqual({ id: 1, name: "John" });
60
- expect(response.headers["content-type"]).toBe("application/json");
61
- });
62
-
63
- it("handles arrays as application/json", async () => {
64
- const mock = schmock();
65
- mock("GET /array", ["one", "two", "three"]);
66
-
67
- const response = await mock.handle("GET", "/array");
68
-
69
- expect(response.status).toBe(200);
70
- expect(response.body).toEqual(["one", "two", "three"]);
71
- expect(response.headers["content-type"]).toBe("application/json");
72
- });
73
-
74
- it("handles empty arrays as application/json", async () => {
75
- const mock = schmock();
76
- mock("GET /empty-array", []);
77
-
78
- const response = await mock.handle("GET", "/empty-array");
79
-
80
- expect(response.status).toBe(200);
81
- expect(response.body).toEqual([]);
82
- expect(response.headers["content-type"]).toBe("application/json");
83
- });
84
-
85
- it("handles empty objects as application/json", async () => {
86
- const mock = schmock();
87
- mock("GET /empty-object", {});
88
-
89
- const response = await mock.handle("GET", "/empty-object");
90
-
91
- expect(response.status).toBe(200);
92
- expect(response.body).toEqual({});
93
- expect(response.headers["content-type"]).toBe("application/json");
94
- });
95
- });
96
-
97
- describe("null and undefined values", () => {
98
- it("handles null with 204 No Content", async () => {
99
- const mock = schmock();
100
- mock("GET /null", null);
101
-
102
- const response = await mock.handle("GET", "/null");
103
-
104
- expect(response.status).toBe(204);
105
- expect(response.body).toBeUndefined();
106
- expect(response.headers["content-type"]).toBe("application/json");
107
- });
108
-
109
- it("handles undefined with 204 No Content", async () => {
110
- const mock = schmock();
111
- mock("GET /undefined", undefined);
112
-
113
- const response = await mock.handle("GET", "/undefined");
114
-
115
- expect(response.status).toBe(204);
116
- expect(response.body).toBeUndefined();
117
- expect(response.headers["content-type"]).toBe("application/json");
118
- });
119
- });
120
-
121
- describe("Buffer responses", () => {
122
- it("handles Buffers as application/octet-stream", async () => {
123
- const mock = schmock();
124
- const buffer = Buffer.from("binary data");
125
- mock("GET /binary", buffer);
126
-
127
- const response = await mock.handle("GET", "/binary");
128
-
129
- expect(response.status).toBe(200);
130
- expect(response.body).toBe(buffer);
131
- expect(response.headers["content-type"]).toBe("application/octet-stream");
132
- });
133
- });
134
-
135
- describe("function generators", () => {
136
- it("function returning string gets application/json by default", async () => {
137
- const mock = schmock();
138
- mock("GET /func-string", () => "Hello");
139
-
140
- const response = await mock.handle("GET", "/func-string");
141
-
142
- expect(response.status).toBe(200);
143
- expect(response.body).toBe("Hello");
144
- expect(response.headers["content-type"]).toBe("application/json");
145
- });
146
-
147
- it("function returning number gets application/json by default", async () => {
148
- const mock = schmock();
149
- mock("GET /func-number", () => 42);
150
-
151
- const response = await mock.handle("GET", "/func-number");
152
-
153
- expect(response.status).toBe(200);
154
- expect(response.body).toBe(42);
155
- expect(response.headers["content-type"]).toBe("application/json");
156
- });
157
-
158
- it("function returning object gets application/json by default", async () => {
159
- const mock = schmock();
160
- mock("GET /func-object", () => ({ id: 1 }));
161
-
162
- const response = await mock.handle("GET", "/func-object");
163
-
164
- expect(response.status).toBe(200);
165
- expect(response.body).toEqual({ id: 1 });
166
- expect(response.headers["content-type"]).toBe("application/json");
167
- });
168
-
169
- it("function returning null gets 204 status", async () => {
170
- const mock = schmock();
171
- mock("GET /func-null", () => null);
172
-
173
- const response = await mock.handle("GET", "/func-null");
174
-
175
- expect(response.status).toBe(204);
176
- expect(response.body).toBeUndefined();
177
- expect(response.headers["content-type"]).toBe("application/json");
178
- });
179
- });
180
-
181
- describe("explicit contentType overrides", () => {
182
- it("overrides object to text/plain and stringifies", async () => {
183
- const mock = schmock();
184
- mock("GET /override", { foo: "bar" }, { contentType: "text/plain" });
185
-
186
- const response = await mock.handle("GET", "/override");
187
-
188
- expect(response.status).toBe(200);
189
- expect(response.body).toBe('{"foo":"bar"}');
190
- expect(response.headers["content-type"]).toBe("text/plain");
191
- });
192
-
193
- it("overrides number to text/plain and converts to string", async () => {
194
- const mock = schmock();
195
- mock("GET /override-number", 123, { contentType: "text/plain" });
196
-
197
- const response = await mock.handle("GET", "/override-number");
198
-
199
- expect(response.status).toBe(200);
200
- expect(response.body).toBe("123");
201
- expect(response.headers["content-type"]).toBe("text/plain");
202
- });
203
-
204
- it("overrides string to application/json", async () => {
205
- const mock = schmock();
206
- mock("GET /override-string", "hello", {
207
- contentType: "application/json",
208
- });
209
-
210
- const response = await mock.handle("GET", "/override-string");
211
-
212
- expect(response.status).toBe(200);
213
- expect(response.body).toBe("hello");
214
- expect(response.headers["content-type"]).toBe("application/json");
215
- });
216
-
217
- it("sets custom content-type", async () => {
218
- const mock = schmock();
219
- mock("GET /custom", "<h1>Hello</h1>", { contentType: "text/html" });
220
-
221
- const response = await mock.handle("GET", "/custom");
222
-
223
- expect(response.status).toBe(200);
224
- expect(response.body).toBe("<h1>Hello</h1>");
225
- expect(response.headers["content-type"]).toBe("text/html");
226
- });
227
- });
228
-
229
- describe("tuple responses preserve explicit control", () => {
230
- it("tuple responses don't get automatic content-type", async () => {
231
- const mock = schmock();
232
- mock("GET /tuple", () => [200, { id: 1 }]);
233
-
234
- const response = await mock.handle("GET", "/tuple");
235
-
236
- expect(response.status).toBe(200);
237
- expect(response.body).toEqual({ id: 1 });
238
- expect(response.headers).toEqual({});
239
- });
240
-
241
- it("tuple with explicit headers keeps them", async () => {
242
- const mock = schmock();
243
- mock("GET /tuple-headers", () => [
244
- 201,
245
- { created: true },
246
- { "X-Custom": "value" },
247
- ]);
248
-
249
- const response = await mock.handle("GET", "/tuple-headers");
250
-
251
- expect(response.status).toBe(201);
252
- expect(response.body).toEqual({ created: true });
253
- expect(response.headers).toEqual({ "X-Custom": "value" });
254
- });
255
-
256
- it("tuple with null body preserves explicit status", async () => {
257
- const mock = schmock();
258
- mock("GET /tuple-null", () => [200, null]);
259
-
260
- const response = await mock.handle("GET", "/tuple-null");
261
-
262
- expect(response.status).toBe(200); // Tuple format preserves explicit status
263
- expect(response.body).toBeUndefined();
264
- expect(response.headers).toEqual({});
265
- });
266
-
267
- it("tuple with 204 status and null body", async () => {
268
- const mock = schmock();
269
- mock("GET /tuple-204", () => [204, null]);
270
-
271
- const response = await mock.handle("GET", "/tuple-204");
272
-
273
- expect(response.status).toBe(204);
274
- expect(response.body).toBeUndefined();
275
- expect(response.headers).toEqual({});
276
- });
277
- });
278
-
279
- describe("edge cases", () => {
280
- it("handles zero as text/plain", async () => {
281
- const mock = schmock();
282
- mock("GET /zero", 0);
283
-
284
- const response = await mock.handle("GET", "/zero");
285
-
286
- expect(response.status).toBe(200);
287
- expect(response.body).toBe("0");
288
- expect(response.headers["content-type"]).toBe("text/plain");
289
- });
290
-
291
- it("handles false as text/plain", async () => {
292
- const mock = schmock();
293
- mock("GET /false", false);
294
-
295
- const response = await mock.handle("GET", "/false");
296
-
297
- expect(response.status).toBe(200);
298
- expect(response.body).toBe("false");
299
- expect(response.headers["content-type"]).toBe("text/plain");
300
- });
301
-
302
- it("handles nested objects as application/json", async () => {
303
- const mock = schmock();
304
- const nested = {
305
- user: { id: 1, profile: { name: "John", settings: { theme: "dark" } } },
306
- };
307
- mock("GET /nested", nested);
308
-
309
- const response = await mock.handle("GET", "/nested");
310
-
311
- expect(response.status).toBe(200);
312
- expect(response.body).toEqual(nested);
313
- expect(response.headers["content-type"]).toBe("application/json");
314
- });
315
-
316
- it("handles arrays with mixed types as application/json", async () => {
317
- const mock = schmock();
318
- mock("GET /mixed", ["first", 2, { id: 1 }, ["nested", "array"]]);
319
-
320
- const response = await mock.handle("GET", "/mixed");
321
-
322
- expect(response.status).toBe(200);
323
- expect(response.body).toEqual([
324
- "first",
325
- 2,
326
- { id: 1 },
327
- ["nested", "array"],
328
- ]);
329
- expect(response.headers["content-type"]).toBe("application/json");
330
- });
331
- });
332
-
333
- describe("consistency with existing auto-detection", () => {
334
- it("static string gets text/plain", async () => {
335
- const mock = schmock();
336
- mock("GET /static-string", "Hello World");
337
-
338
- const response = await mock.handle("GET", "/static-string");
339
-
340
- expect(response.headers["content-type"]).toBe("text/plain");
341
- });
342
-
343
- it("static object gets application/json", async () => {
344
- const mock = schmock();
345
- mock("GET /static-object", { id: 1 });
346
-
347
- const response = await mock.handle("GET", "/static-object");
348
-
349
- expect(response.headers["content-type"]).toBe("application/json");
350
- });
351
-
352
- it("function generator gets application/json by default", async () => {
353
- const mock = schmock();
354
- mock("GET /func", () => "anything");
355
-
356
- const response = await mock.handle("GET", "/func");
357
-
358
- expect(response.headers["content-type"]).toBe("application/json");
359
- });
360
- });
361
- });