@curl-runner/cli 1.16.0 → 1.16.2

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 (40) hide show
  1. package/package.json +2 -2
  2. package/src/ci-exit.test.ts +0 -216
  3. package/src/cli.ts +0 -1351
  4. package/src/commands/upgrade.ts +0 -262
  5. package/src/diff/baseline-manager.test.ts +0 -181
  6. package/src/diff/baseline-manager.ts +0 -266
  7. package/src/diff/diff-formatter.ts +0 -316
  8. package/src/diff/index.ts +0 -3
  9. package/src/diff/response-differ.test.ts +0 -330
  10. package/src/diff/response-differ.ts +0 -489
  11. package/src/executor/max-concurrency.test.ts +0 -139
  12. package/src/executor/profile-executor.test.ts +0 -132
  13. package/src/executor/profile-executor.ts +0 -167
  14. package/src/executor/request-executor.ts +0 -663
  15. package/src/parser/yaml.test.ts +0 -480
  16. package/src/parser/yaml.ts +0 -271
  17. package/src/snapshot/index.ts +0 -3
  18. package/src/snapshot/snapshot-differ.test.ts +0 -358
  19. package/src/snapshot/snapshot-differ.ts +0 -296
  20. package/src/snapshot/snapshot-formatter.ts +0 -170
  21. package/src/snapshot/snapshot-manager.test.ts +0 -204
  22. package/src/snapshot/snapshot-manager.ts +0 -342
  23. package/src/types/bun-yaml.d.ts +0 -11
  24. package/src/types/config.ts +0 -638
  25. package/src/utils/colors.ts +0 -30
  26. package/src/utils/condition-evaluator.test.ts +0 -415
  27. package/src/utils/condition-evaluator.ts +0 -327
  28. package/src/utils/curl-builder.test.ts +0 -165
  29. package/src/utils/curl-builder.ts +0 -209
  30. package/src/utils/installation-detector.test.ts +0 -52
  31. package/src/utils/installation-detector.ts +0 -123
  32. package/src/utils/logger.ts +0 -856
  33. package/src/utils/response-store.test.ts +0 -213
  34. package/src/utils/response-store.ts +0 -108
  35. package/src/utils/stats.test.ts +0 -161
  36. package/src/utils/stats.ts +0 -151
  37. package/src/utils/version-checker.ts +0 -158
  38. package/src/version.ts +0 -43
  39. package/src/watcher/file-watcher.test.ts +0 -186
  40. package/src/watcher/file-watcher.ts +0 -140
@@ -1,415 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import type { ConditionExpression, ResponseStoreContext, WhenCondition } from '../types/config';
3
- import { evaluateCondition, evaluateExpression, parseStringCondition } from './condition-evaluator';
4
-
5
- describe('parseStringCondition', () => {
6
- test('should parse equality condition', () => {
7
- const result = parseStringCondition('store.status == 200');
8
- expect(result).toEqual({
9
- left: 'store.status',
10
- operator: '==',
11
- right: 200,
12
- });
13
- });
14
-
15
- test('should parse inequality condition', () => {
16
- const result = parseStringCondition('store.type != admin');
17
- expect(result).toEqual({
18
- left: 'store.type',
19
- operator: '!=',
20
- right: 'admin',
21
- });
22
- });
23
-
24
- test('should parse greater than condition', () => {
25
- const result = parseStringCondition('store.count > 10');
26
- expect(result).toEqual({
27
- left: 'store.count',
28
- operator: '>',
29
- right: 10,
30
- });
31
- });
32
-
33
- test('should parse less than condition', () => {
34
- const result = parseStringCondition('store.price < 100.5');
35
- expect(result).toEqual({
36
- left: 'store.price',
37
- operator: '<',
38
- right: 100.5,
39
- });
40
- });
41
-
42
- test('should parse greater than or equal condition', () => {
43
- const result = parseStringCondition('store.version >= 2');
44
- expect(result).toEqual({
45
- left: 'store.version',
46
- operator: '>=',
47
- right: 2,
48
- });
49
- });
50
-
51
- test('should parse less than or equal condition', () => {
52
- const result = parseStringCondition('store.age <= 65');
53
- expect(result).toEqual({
54
- left: 'store.age',
55
- operator: '<=',
56
- right: 65,
57
- });
58
- });
59
-
60
- test('should parse contains condition', () => {
61
- const result = parseStringCondition('store.message contains error');
62
- expect(result).toEqual({
63
- left: 'store.message',
64
- operator: 'contains',
65
- right: 'error',
66
- });
67
- });
68
-
69
- test('should parse matches condition', () => {
70
- const result = parseStringCondition('store.email matches ^[a-z]+@');
71
- expect(result).toEqual({
72
- left: 'store.email',
73
- operator: 'matches',
74
- right: '^[a-z]+@',
75
- });
76
- });
77
-
78
- test('should parse exists condition', () => {
79
- const result = parseStringCondition('store.userId exists');
80
- expect(result).toEqual({
81
- left: 'store.userId',
82
- operator: 'exists',
83
- });
84
- });
85
-
86
- test('should parse not-exists condition', () => {
87
- const result = parseStringCondition('store.error not-exists');
88
- expect(result).toEqual({
89
- left: 'store.error',
90
- operator: 'not-exists',
91
- });
92
- });
93
-
94
- test('should parse boolean true', () => {
95
- const result = parseStringCondition('store.enabled == true');
96
- expect(result).toEqual({
97
- left: 'store.enabled',
98
- operator: '==',
99
- right: true,
100
- });
101
- });
102
-
103
- test('should parse boolean false', () => {
104
- const result = parseStringCondition('store.disabled == false');
105
- expect(result).toEqual({
106
- left: 'store.disabled',
107
- operator: '==',
108
- right: false,
109
- });
110
- });
111
-
112
- test('should parse quoted strings', () => {
113
- const result = parseStringCondition('store.name == "John Doe"');
114
- expect(result).toEqual({
115
- left: 'store.name',
116
- operator: '==',
117
- right: 'John Doe',
118
- });
119
- });
120
-
121
- test('should return null for invalid syntax', () => {
122
- expect(parseStringCondition('invalid')).toBeNull();
123
- expect(parseStringCondition('')).toBeNull();
124
- expect(parseStringCondition('store.x')).toBeNull();
125
- });
126
- });
127
-
128
- describe('evaluateExpression', () => {
129
- const context: ResponseStoreContext = {
130
- status: '200',
131
- userId: '123',
132
- name: 'John',
133
- empty: '',
134
- enabled: 'true',
135
- count: '42',
136
- body: '{"type":"user","nested":{"id":1}}',
137
- };
138
-
139
- describe('exists operator', () => {
140
- test('should return true for existing value', () => {
141
- const expr: ConditionExpression = { left: 'store.userId', operator: 'exists' };
142
- expect(evaluateExpression(expr, context).passed).toBe(true);
143
- });
144
-
145
- test('should return false for empty string', () => {
146
- const expr: ConditionExpression = { left: 'store.empty', operator: 'exists' };
147
- expect(evaluateExpression(expr, context).passed).toBe(false);
148
- });
149
-
150
- test('should return false for missing value', () => {
151
- const expr: ConditionExpression = { left: 'store.missing', operator: 'exists' };
152
- expect(evaluateExpression(expr, context).passed).toBe(false);
153
- });
154
- });
155
-
156
- describe('not-exists operator', () => {
157
- test('should return true for missing value', () => {
158
- const expr: ConditionExpression = { left: 'store.missing', operator: 'not-exists' };
159
- expect(evaluateExpression(expr, context).passed).toBe(true);
160
- });
161
-
162
- test('should return true for empty string', () => {
163
- const expr: ConditionExpression = { left: 'store.empty', operator: 'not-exists' };
164
- expect(evaluateExpression(expr, context).passed).toBe(true);
165
- });
166
-
167
- test('should return false for existing value', () => {
168
- const expr: ConditionExpression = { left: 'store.userId', operator: 'not-exists' };
169
- expect(evaluateExpression(expr, context).passed).toBe(false);
170
- });
171
- });
172
-
173
- describe('== operator', () => {
174
- test('should compare numbers', () => {
175
- const expr: ConditionExpression = { left: 'store.status', operator: '==', right: 200 };
176
- expect(evaluateExpression(expr, context).passed).toBe(true);
177
- });
178
-
179
- test('should compare strings case-insensitively by default', () => {
180
- const expr: ConditionExpression = { left: 'store.name', operator: '==', right: 'john' };
181
- expect(evaluateExpression(expr, context).passed).toBe(true);
182
- });
183
-
184
- test('should compare strings case-sensitively when specified', () => {
185
- const expr: ConditionExpression = {
186
- left: 'store.name',
187
- operator: '==',
188
- right: 'john',
189
- caseSensitive: true,
190
- };
191
- expect(evaluateExpression(expr, context).passed).toBe(false);
192
- });
193
-
194
- test('should compare booleans', () => {
195
- const expr: ConditionExpression = { left: 'store.enabled', operator: '==', right: true };
196
- expect(evaluateExpression(expr, context).passed).toBe(true);
197
- });
198
- });
199
-
200
- describe('!= operator', () => {
201
- test('should return true for different values', () => {
202
- const expr: ConditionExpression = { left: 'store.status', operator: '!=', right: 404 };
203
- expect(evaluateExpression(expr, context).passed).toBe(true);
204
- });
205
-
206
- test('should return false for equal values', () => {
207
- const expr: ConditionExpression = { left: 'store.status', operator: '!=', right: 200 };
208
- expect(evaluateExpression(expr, context).passed).toBe(false);
209
- });
210
- });
211
-
212
- describe('comparison operators', () => {
213
- test('should compare with >', () => {
214
- const expr: ConditionExpression = { left: 'store.count', operator: '>', right: 40 };
215
- expect(evaluateExpression(expr, context).passed).toBe(true);
216
- });
217
-
218
- test('should compare with <', () => {
219
- const expr: ConditionExpression = { left: 'store.count', operator: '<', right: 50 };
220
- expect(evaluateExpression(expr, context).passed).toBe(true);
221
- });
222
-
223
- test('should compare with >=', () => {
224
- const expr: ConditionExpression = { left: 'store.count', operator: '>=', right: 42 };
225
- expect(evaluateExpression(expr, context).passed).toBe(true);
226
- });
227
-
228
- test('should compare with <=', () => {
229
- const expr: ConditionExpression = { left: 'store.count', operator: '<=', right: 42 };
230
- expect(evaluateExpression(expr, context).passed).toBe(true);
231
- });
232
- });
233
-
234
- describe('contains operator', () => {
235
- test('should find substring case-insensitively', () => {
236
- const expr: ConditionExpression = { left: 'store.name', operator: 'contains', right: 'OH' };
237
- expect(evaluateExpression(expr, context).passed).toBe(true);
238
- });
239
-
240
- test('should find substring case-sensitively when specified', () => {
241
- const expr: ConditionExpression = {
242
- left: 'store.name',
243
- operator: 'contains',
244
- right: 'OH',
245
- caseSensitive: true,
246
- };
247
- expect(evaluateExpression(expr, context).passed).toBe(false);
248
- });
249
-
250
- test('should return false when substring not found', () => {
251
- const expr: ConditionExpression = { left: 'store.name', operator: 'contains', right: 'xyz' };
252
- expect(evaluateExpression(expr, context).passed).toBe(false);
253
- });
254
- });
255
-
256
- describe('matches operator', () => {
257
- test('should match regex pattern', () => {
258
- const expr: ConditionExpression = {
259
- left: 'store.name',
260
- operator: 'matches',
261
- right: '^[A-Z]',
262
- };
263
- expect(evaluateExpression(expr, context).passed).toBe(true);
264
- });
265
-
266
- test('should be case-insensitive by default', () => {
267
- const expr: ConditionExpression = {
268
- left: 'store.name',
269
- operator: 'matches',
270
- right: '^john$',
271
- };
272
- expect(evaluateExpression(expr, context).passed).toBe(true);
273
- });
274
-
275
- test('should respect caseSensitive flag', () => {
276
- const expr: ConditionExpression = {
277
- left: 'store.name',
278
- operator: 'matches',
279
- right: '^john$',
280
- caseSensitive: true,
281
- };
282
- expect(evaluateExpression(expr, context).passed).toBe(false);
283
- });
284
-
285
- test('should handle invalid regex', () => {
286
- const expr: ConditionExpression = { left: 'store.name', operator: 'matches', right: '[' };
287
- expect(evaluateExpression(expr, context).passed).toBe(false);
288
- });
289
- });
290
- });
291
-
292
- describe('evaluateCondition', () => {
293
- const context: ResponseStoreContext = {
294
- status: '200',
295
- userId: '123',
296
- type: 'admin',
297
- enabled: 'true',
298
- };
299
-
300
- describe('string shorthand', () => {
301
- test('should evaluate valid string condition', () => {
302
- const result = evaluateCondition('store.status == 200', context);
303
- expect(result.shouldRun).toBe(true);
304
- expect(result.reason).toBeUndefined();
305
- });
306
-
307
- test('should return false with reason for failing condition', () => {
308
- const result = evaluateCondition('store.status == 404', context);
309
- expect(result.shouldRun).toBe(false);
310
- expect(result.reason).toContain('condition not met');
311
- });
312
-
313
- test('should return false for invalid syntax', () => {
314
- const result = evaluateCondition('invalid syntax', context);
315
- expect(result.shouldRun).toBe(false);
316
- expect(result.reason).toContain('invalid condition syntax');
317
- });
318
- });
319
-
320
- describe('single condition object', () => {
321
- test('should evaluate single condition', () => {
322
- const condition: WhenCondition = {
323
- left: 'store.userId',
324
- operator: 'exists',
325
- };
326
- expect(evaluateCondition(condition, context).shouldRun).toBe(true);
327
- });
328
-
329
- test('should fail single condition', () => {
330
- const condition: WhenCondition = {
331
- left: 'store.missing',
332
- operator: 'exists',
333
- };
334
- const result = evaluateCondition(condition, context);
335
- expect(result.shouldRun).toBe(false);
336
- expect(result.reason).toContain('condition not met');
337
- });
338
- });
339
-
340
- describe('all (AND) conditions', () => {
341
- test('should pass when all conditions true', () => {
342
- const condition: WhenCondition = {
343
- all: [
344
- { left: 'store.status', operator: '==', right: 200 },
345
- { left: 'store.userId', operator: 'exists' },
346
- { left: 'store.type', operator: '==', right: 'admin' },
347
- ],
348
- };
349
- expect(evaluateCondition(condition, context).shouldRun).toBe(true);
350
- });
351
-
352
- test('should fail when any condition false (short-circuit)', () => {
353
- const condition: WhenCondition = {
354
- all: [
355
- { left: 'store.status', operator: '==', right: 200 },
356
- { left: 'store.status', operator: '==', right: 404 }, // fails
357
- { left: 'store.userId', operator: 'exists' },
358
- ],
359
- };
360
- const result = evaluateCondition(condition, context);
361
- expect(result.shouldRun).toBe(false);
362
- expect(result.reason).toContain('store.status == 404');
363
- });
364
- });
365
-
366
- describe('any (OR) conditions', () => {
367
- test('should pass when any condition true (short-circuit)', () => {
368
- const condition: WhenCondition = {
369
- any: [
370
- { left: 'store.status', operator: '==', right: 404 }, // fails
371
- { left: 'store.status', operator: '==', right: 200 }, // passes
372
- { left: 'store.status', operator: '==', right: 500 }, // skipped
373
- ],
374
- };
375
- expect(evaluateCondition(condition, context).shouldRun).toBe(true);
376
- });
377
-
378
- test('should fail when all conditions false', () => {
379
- const condition: WhenCondition = {
380
- any: [
381
- { left: 'store.status', operator: '==', right: 404 },
382
- { left: 'store.status', operator: '==', right: 500 },
383
- ],
384
- };
385
- const result = evaluateCondition(condition, context);
386
- expect(result.shouldRun).toBe(false);
387
- expect(result.reason).toContain('no conditions met');
388
- });
389
- });
390
-
391
- describe('edge cases', () => {
392
- test('should run when no valid condition specified', () => {
393
- const condition: WhenCondition = {};
394
- expect(evaluateCondition(condition, context).shouldRun).toBe(true);
395
- });
396
-
397
- test('should handle empty all array', () => {
398
- const condition: WhenCondition = { all: [] };
399
- expect(evaluateCondition(condition, context).shouldRun).toBe(true);
400
- });
401
-
402
- test('should handle empty any array', () => {
403
- const condition: WhenCondition = { any: [] };
404
- expect(evaluateCondition(condition, context).shouldRun).toBe(true);
405
- });
406
-
407
- test('should handle nested JSON in store', () => {
408
- const nestedContext: ResponseStoreContext = {
409
- body: '{"user":{"id":123,"role":"admin"}}',
410
- };
411
- const result = evaluateCondition('store.body.user.role == admin', nestedContext);
412
- expect(result.shouldRun).toBe(true);
413
- });
414
- });
415
- });