@mastra/libsql 0.13.8-alpha.0 → 0.13.8-alpha.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.
@@ -1,906 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import type { LibSQLVectorFilter } from './filter';
4
- import { LibSQLFilterTranslator } from './filter';
5
-
6
- describe('LibSQLFilterTranslator', () => {
7
- const translator = new LibSQLFilterTranslator();
8
-
9
- // Basic Filter Translation
10
- describe('Basic Filter Translation', () => {
11
- it('handles empty filter', () => {
12
- expect(translator.translate({})).toEqual({});
13
- });
14
-
15
- it('translates primitive to $eq', () => {
16
- expect(translator.translate({ field: 'value' })).toEqual({
17
- field: { $eq: 'value' },
18
- });
19
- });
20
-
21
- it('preserves comparison operators', () => {
22
- const filter: LibSQLVectorFilter = {
23
- field1: { $eq: 'value' },
24
- field2: { $ne: 'value' },
25
- field3: { $gt: 5 },
26
- field4: { $gte: 5 },
27
- field5: { $lt: 5 },
28
- field6: { $lte: 5 },
29
- };
30
- expect(translator.translate(filter)).toEqual(filter);
31
- });
32
-
33
- it('preserves multiple comparison operators', () => {
34
- expect(translator.translate({ field: { $gt: 5, $lt: 10 } })).toEqual({ field: { $gt: 5, $lt: 10 } });
35
- });
36
-
37
- it('handles nested paths', () => {
38
- expect(
39
- translator.translate({
40
- 'nested.field': { $eq: 'value' },
41
- }),
42
- ).toEqual({
43
- 'nested.field': { $eq: 'value' },
44
- });
45
- });
46
-
47
- it('handles nested objects', () => {
48
- expect(
49
- translator.translate({
50
- nested: {
51
- field: 'value',
52
- },
53
- } as any),
54
- ).toEqual({
55
- 'nested.field': { $eq: 'value' },
56
- });
57
- });
58
- });
59
-
60
- // Array Operations
61
- describe('array operations', () => {
62
- it('translates array to $in', () => {
63
- const filter: LibSQLVectorFilter = { field: ['a', 'b'] };
64
- expect(translator.translate(filter)).toEqual({
65
- field: { $in: ['a', 'b'] },
66
- });
67
- });
68
-
69
- it('translates arrays to JSON for basic operators', () => {
70
- expect(translator.translate({ field: { $eq: ['a', 'b'] } })).toEqual({
71
- field: { $eq: JSON.stringify(['a', 'b']) },
72
- });
73
- expect(translator.translate({ field: { $ne: ['a', 'b'] } })).toEqual({
74
- field: { $ne: JSON.stringify(['a', 'b']) },
75
- });
76
- });
77
-
78
- it('handles empty arrays', () => {
79
- expect(
80
- translator.translate({
81
- field: [] as any,
82
- }),
83
- ).toEqual({
84
- field: { $in: [] },
85
- });
86
- });
87
-
88
- it('validates $elemMatch translation', () => {
89
- expect(
90
- translator.translate({
91
- field: {
92
- $elemMatch: {
93
- $eq: 'value',
94
- },
95
- },
96
- }),
97
- ).toEqual({
98
- field: {
99
- $elemMatch: {
100
- $eq: 'value',
101
- },
102
- },
103
- });
104
-
105
- // Test multiple conditions
106
- expect(
107
- translator.translate({
108
- field: {
109
- $elemMatch: {
110
- $gt: 5,
111
- $lt: 10,
112
- },
113
- },
114
- }),
115
- ).toEqual({
116
- field: {
117
- $elemMatch: {
118
- $gt: 5,
119
- $lt: 10,
120
- },
121
- },
122
- });
123
- });
124
- });
125
-
126
- // Array Operator Normalization
127
- describe('Array operator normalization', () => {
128
- it('normalizes single values for $all', () => {
129
- expect(
130
- translator.translate({
131
- field: { $all: 'value' },
132
- }),
133
- ).toEqual({
134
- field: { $all: ['value'] },
135
- });
136
- });
137
-
138
- it('normalizes single values for $in', () => {
139
- expect(
140
- translator.translate({
141
- field: { $in: 'value' },
142
- }),
143
- ).toEqual({
144
- field: { $in: ['value'] },
145
- });
146
- });
147
-
148
- it('normalizes single values for $nin', () => {
149
- expect(
150
- translator.translate({
151
- field: { $nin: 'value' },
152
- }),
153
- ).toEqual({
154
- field: { $nin: ['value'] },
155
- });
156
- });
157
-
158
- it('preserves arrays for array operators', () => {
159
- expect(
160
- translator.translate({
161
- field: { $all: ['value1', 'value2'] },
162
- }),
163
- ).toEqual({
164
- field: { $all: ['value1', 'value2'] },
165
- });
166
- });
167
- });
168
-
169
- // Logical Operators
170
- describe('Logical Operators', () => {
171
- it('handles logical operators', () => {
172
- const filter: LibSQLVectorFilter = {
173
- $and: [{ field1: { $eq: 'value1' } }, { field2: { $eq: 'value2' } }],
174
- $or: [{ field3: { $eq: 'value3' } }, { field4: { $eq: 'value4' } }],
175
- };
176
- expect(translator.translate(filter)).toEqual(filter);
177
- });
178
-
179
- it('handles empty logical operators', () => {
180
- expect(
181
- translator.translate({
182
- $and: [],
183
- $or: [],
184
- }),
185
- ).toEqual({
186
- $and: [],
187
- $or: [],
188
- });
189
- });
190
-
191
- it('handles multiple logical operators at root level', () => {
192
- expect(
193
- translator.translate({
194
- $and: [{ category: 'electronics' }],
195
- $or: [{ price: { $lt: 100 } }, { price: { $gt: 20 } }],
196
- }),
197
- ).toEqual({
198
- $and: [{ category: { $eq: 'electronics' } }],
199
- $or: [{ price: { $lt: 100 } }, { price: { $gt: 20 } }],
200
- });
201
- });
202
-
203
- it('handles empty conditions in logical operators', () => {
204
- expect(
205
- translator.translate({
206
- $and: [],
207
- category: 'electronics',
208
- }),
209
- ).toEqual({
210
- $and: [],
211
- category: { $eq: 'electronics' },
212
- });
213
- });
214
-
215
- it('handles $nor operator', () => {
216
- expect(
217
- translator.translate({
218
- $nor: [{ field1: 'value1' }, { field2: { $gt: 100 } }],
219
- }),
220
- ).toEqual({
221
- $nor: [{ field1: { $eq: 'value1' } }, { field2: { $gt: 100 } }],
222
- });
223
- });
224
-
225
- it('handles $not operator with comparison', () => {
226
- expect(
227
- translator.translate({
228
- field: { $not: { $eq: 'value' } },
229
- }),
230
- ).toEqual({
231
- field: { $not: { $eq: 'value' } },
232
- });
233
- });
234
-
235
- it('handles $not operator with regex', () => {
236
- expect(
237
- translator.translate({
238
- field: { $not: { $regex: 'pattern' } },
239
- }),
240
- ).toEqual({
241
- field: { $not: { $regex: 'pattern' } },
242
- });
243
- });
244
-
245
- it('handles nested logical operators', () => {
246
- expect(
247
- translator.translate({
248
- $and: [
249
- {
250
- $or: [{ field1: 'value1' }, { field2: 'value2' }],
251
- },
252
- {
253
- $nor: [{ field3: 'value3' }, { field4: 'value4' }],
254
- },
255
- ],
256
- }),
257
- ).toEqual({
258
- $and: [
259
- {
260
- $or: [{ field1: { $eq: 'value1' } }, { field2: { $eq: 'value2' } }],
261
- },
262
- {
263
- $nor: [{ field3: { $eq: 'value3' } }, { field4: { $eq: 'value4' } }],
264
- },
265
- ],
266
- });
267
- });
268
-
269
- it('handles logical operators with empty arrays and primitives', () => {
270
- expect(
271
- translator.translate({
272
- $and: [],
273
- $or: [{ field1: 'value1' }],
274
- field2: true,
275
- $nor: [],
276
- }),
277
- ).toEqual({
278
- $and: [],
279
- $or: [{ field1: { $eq: 'value1' } }],
280
- field2: { $eq: true },
281
- $nor: [],
282
- });
283
- });
284
-
285
- it('handles $not operator with comparison', () => {
286
- expect(
287
- translator.translate({
288
- field: { $not: { $eq: 'value' } },
289
- }),
290
- ).toEqual({
291
- field: { $not: { $eq: 'value' } },
292
- });
293
- });
294
-
295
- it('handles $not operator with array operators', () => {
296
- expect(
297
- translator.translate({
298
- field: { $not: { $in: ['value1', 'value2'] } },
299
- }),
300
- ).toEqual({
301
- field: { $not: { $in: ['value1', 'value2'] } },
302
- });
303
- });
304
-
305
- it('handles multiple $not conditions', () => {
306
- expect(
307
- translator.translate({
308
- $and: [{ field1: { $not: { $eq: 'value1' } } }, { field2: { $not: { $in: ['value2', 'value3'] } } }],
309
- }),
310
- ).toEqual({
311
- $and: [{ field1: { $not: { $eq: 'value1' } } }, { field2: { $not: { $in: ['value2', 'value3'] } } }],
312
- });
313
- });
314
-
315
- it('handles combination of all logical operators', () => {
316
- expect(
317
- translator.translate({
318
- $and: [
319
- {
320
- $or: [{ field1: 'value1' }, { field2: { $gt: 100 } }],
321
- },
322
- {
323
- $nor: [{ field3: { $lt: 50 } }, { field4: { $eq: 'value4' } }],
324
- },
325
- {
326
- field5: { $not: { $in: ['value5', 'value6'] } },
327
- },
328
- ],
329
- }),
330
- ).toEqual({
331
- $and: [
332
- {
333
- $or: [{ field1: { $eq: 'value1' } }, { field2: { $gt: 100 } }],
334
- },
335
- {
336
- $nor: [{ field3: { $lt: 50 } }, { field4: { $eq: 'value4' } }],
337
- },
338
- {
339
- field5: { $not: { $in: ['value5', 'value6'] } },
340
- },
341
- ],
342
- });
343
- });
344
- });
345
-
346
- // Complex Filter Structures
347
- describe('complex filter structures', () => {
348
- it('handles nested logical operators with mixed conditions', () => {
349
- expect(
350
- translator.translate({
351
- $or: [
352
- {
353
- $and: [{ category: 'value1' }, { price: { $gt: 90 } }, { active: true }],
354
- },
355
- {
356
- $and: [{ category: 'value2' }, { tags: { $exists: true } }, { price: { $lt: 30 } }],
357
- },
358
- ],
359
- }),
360
- ).toEqual({
361
- $or: [
362
- {
363
- $and: [{ category: { $eq: 'value1' } }, { price: { $gt: 90 } }, { active: { $eq: true } }],
364
- },
365
- {
366
- $and: [{ category: { $eq: 'value2' } }, { tags: { $exists: true } }, { price: { $lt: 30 } }],
367
- },
368
- ],
369
- });
370
- });
371
-
372
- it('handles deeply nested metadata paths', () => {
373
- expect(
374
- translator.translate({
375
- 'level1.level2.level3': 'deep value',
376
- }),
377
- ).toEqual({
378
- 'level1.level2.level3': { $eq: 'deep value' },
379
- });
380
- });
381
-
382
- it('handles non-existent nested paths', () => {
383
- expect(
384
- translator.translate({
385
- 'nonexistent.path': 'value',
386
- }),
387
- ).toEqual({
388
- 'nonexistent.path': { $eq: 'value' },
389
- });
390
- });
391
-
392
- it('handles logical operators with empty arrays and primitives', () => {
393
- expect(
394
- translator.translate({
395
- $and: [],
396
- $or: [{ field1: 'value1' }],
397
- field2: true,
398
- $nor: [],
399
- }),
400
- ).toEqual({
401
- $and: [],
402
- $or: [{ field1: { $eq: 'value1' } }],
403
- field2: { $eq: true },
404
- $nor: [],
405
- });
406
- });
407
- });
408
-
409
- // Edge Cases and Special Values
410
- describe('Edge Cases and Special Values', () => {
411
- it('handles null values', () => {
412
- expect(
413
- translator.translate({
414
- field: null,
415
- }),
416
- ).toEqual({
417
- field: { $eq: null },
418
- });
419
- });
420
-
421
- it('handles boolean values', () => {
422
- expect(
423
- translator.translate({
424
- field1: true,
425
- field2: false,
426
- }),
427
- ).toEqual({
428
- field1: { $eq: true },
429
- field2: { $eq: false },
430
- });
431
- });
432
-
433
- it('handles numeric values', () => {
434
- expect(
435
- translator.translate({
436
- int: 42,
437
- float: 42.42,
438
- negative: -42,
439
- }),
440
- ).toEqual({
441
- int: { $eq: 42 },
442
- float: { $eq: 42.42 },
443
- negative: { $eq: -42 },
444
- });
445
- });
446
-
447
- it('handles empty strings', () => {
448
- expect(
449
- translator.translate({
450
- field: '',
451
- }),
452
- ).toEqual({
453
- field: { $eq: '' },
454
- });
455
- });
456
- });
457
-
458
- // Complex Filter Structures
459
- describe('Complex Filter Structures', () => {
460
- it('handles nested logical operators with mixed conditions', () => {
461
- expect(
462
- translator.translate({
463
- $or: [
464
- {
465
- $and: [{ category: 'value1' }, { price: { $gt: 90 } }, { active: true }],
466
- },
467
- {
468
- $and: [{ category: 'value2' }, { tags: { $exists: true } }, { price: { $lt: 30 } }],
469
- },
470
- ],
471
- }),
472
- ).toEqual({
473
- $or: [
474
- {
475
- $and: [{ category: { $eq: 'value1' } }, { price: { $gt: 90 } }, { active: { $eq: true } }],
476
- },
477
- {
478
- $and: [{ category: { $eq: 'value2' } }, { tags: { $exists: true } }, { price: { $lt: 30 } }],
479
- },
480
- ],
481
- });
482
- });
483
-
484
- it('handles multiple logical operators at root level', () => {
485
- expect(
486
- translator.translate({
487
- $and: [{ category: 'electronics' }],
488
- $or: [{ price: { $lt: 100 } }, { price: { $gt: 20 } }],
489
- }),
490
- ).toEqual({
491
- $and: [{ category: { $eq: 'electronics' } }],
492
- $or: [{ price: { $lt: 100 } }, { price: { $gt: 20 } }],
493
- });
494
- });
495
-
496
- it('handles empty conditions in logical operators', () => {
497
- expect(
498
- translator.translate({
499
- $and: [],
500
- category: 'electronics',
501
- }),
502
- ).toEqual({
503
- $and: [],
504
- category: { $eq: 'electronics' },
505
- });
506
- });
507
-
508
- it('handles deeply nested metadata paths', () => {
509
- expect(
510
- translator.translate({
511
- 'level1.level2.level3': 'deep value',
512
- }),
513
- ).toEqual({
514
- 'level1.level2.level3': { $eq: 'deep value' },
515
- });
516
- });
517
-
518
- it('handles non-existent nested paths', () => {
519
- expect(
520
- translator.translate({
521
- 'nonexistent.path': 'value',
522
- }),
523
- ).toEqual({
524
- 'nonexistent.path': { $eq: 'value' },
525
- });
526
- });
527
- });
528
-
529
- // Operator Support Validation
530
- describe('Operator Support Validation', () => {
531
- it('ensure all operator filters are supported', () => {
532
- const supportedFilters: LibSQLVectorFilter[] = [
533
- // Basic comparison operators
534
- { field: { $eq: 'value' } },
535
- { field: { $ne: 'value' } },
536
- { field: { $gt: 'value' } },
537
- { field: { $gte: 'value' } },
538
- { field: { $lt: 'value' } },
539
- { field: { $lte: 'value' } },
540
-
541
- // Array operators
542
- { field: { $in: ['value'] } },
543
- { field: { $nin: ['value'] } },
544
- { field: { $all: ['value'] } },
545
- { field: { $elemMatch: { $gt: 5 } } },
546
-
547
- // Pattern matching
548
- // { field: { $regex: 'value' } },
549
- { field: { $contains: 'value' } },
550
-
551
- // Existence
552
- { field: { $exists: true } },
553
-
554
- { $and: [{ field1: 'value1' }, { field2: 'value2' }] },
555
- { $or: [{ field1: 'value1' }, { field2: 'value2' }] },
556
- { $nor: [{ field1: 'value1' }, { field2: 'value2' }] },
557
-
558
- { $or: [{ $and: [{ field1: 'value1' }] }, { $not: { field2: 'value2' } }] },
559
-
560
- { field: { $not: { $eq: 'value' } } },
561
- { field: { $not: { $in: ['value1', 'value2'] } } },
562
- { field: { $not: { $gt: 100 } } },
563
- { field: { $not: { $lt: 50 } } },
564
-
565
- { field: { $size: 1 } },
566
- ];
567
-
568
- supportedFilters.forEach(filter => {
569
- expect(() => translator.translate(filter)).not.toThrow();
570
- });
571
- });
572
-
573
- it('throws error for $not if not an object', () => {
574
- expect(() => translator.translate({ $not: 'value' })).toThrow();
575
- expect(() => translator.translate({ $not: [{ field: 'value' }] } as any)).toThrow();
576
- });
577
- it('throws error for $not if empty', () => {
578
- expect(() => translator.translate({ $not: {} })).toThrow();
579
- });
580
-
581
- // Add tests for logical operator placement restrictions
582
- it('throws error when logical operators are used in field-level conditions', () => {
583
- // $and cannot be used in field conditions
584
- expect(() =>
585
- translator.translate({
586
- field: { $and: [{ $eq: 'value1' }, { $eq: 'value2' }] },
587
- } as any),
588
- ).toThrow();
589
-
590
- // $or cannot be used in field conditions
591
- expect(() =>
592
- translator.translate({
593
- field: { $or: [{ $eq: 'value1' }, { $eq: 'value2' }] },
594
- } as any),
595
- ).toThrow();
596
-
597
- // $nor cannot be used in field conditions
598
- expect(() =>
599
- translator.translate({
600
- field: { $nor: [{ $eq: 'value1' }, { $eq: 'value2' }] },
601
- } as any),
602
- ).toThrow();
603
- });
604
-
605
- it('allows logical operators at root level', () => {
606
- // Valid root level usage
607
- expect(() =>
608
- translator.translate({
609
- $and: [{ field1: 'value1' }, { field2: 'value2' }],
610
- $or: [{ field3: 'value3' }, { field4: 'value4' }],
611
- $nor: [{ field5: 'value5' }, { field6: 'value6' }],
612
- }),
613
- ).not.toThrow();
614
- });
615
-
616
- it('allows logical operators nested within other logical operators', () => {
617
- // Valid nested usage
618
- expect(() =>
619
- translator.translate({
620
- $and: [
621
- {
622
- $or: [{ field1: 'value1' }, { field2: 'value2' }],
623
- },
624
- {
625
- $nor: [{ field3: 'value3' }, { field4: 'value4' }],
626
- },
627
- ],
628
- }),
629
- ).not.toThrow();
630
- });
631
-
632
- it('allows $not in field-level conditions', () => {
633
- // $not is allowed in field conditions
634
- expect(() =>
635
- translator.translate({
636
- field1: { $not: { $eq: 'value1' } },
637
- field2: { $not: { $in: ['value2', 'value3'] } },
638
- field3: { $not: { $regex: 'pattern' } },
639
- }),
640
- ).not.toThrow();
641
- });
642
-
643
- it('throws error for deeply nested logical operators in non-logical contexts', () => {
644
- // Invalid deep nesting in comparison operators
645
- expect(() =>
646
- translator.translate({
647
- field: {
648
- $gt: {
649
- $or: [{ subfield: 'value1' }, { subfield: 'value2' }],
650
- } as any,
651
- },
652
- }),
653
- ).toThrow();
654
-
655
- // Invalid deep nesting in array operators
656
- expect(() =>
657
- translator.translate({
658
- field: {
659
- $in: [
660
- {
661
- $and: [{ subfield: 'value1' }, { subfield: 'value2' }],
662
- },
663
- ],
664
- } as any,
665
- }),
666
- ).toThrow();
667
- });
668
-
669
- it('validates $not operator structure', () => {
670
- // $not must be an object
671
- expect(() => translator.translate({ field: { $not: 'value' } } as any)).toThrow();
672
- expect(() => translator.translate({ field: { $not: ['value'] } })).toThrow();
673
- expect(() => translator.translate({ $not: 'value' })).toThrow();
674
- expect(() => translator.translate({ $not: ['value'] } as any)).toThrow();
675
- });
676
-
677
- it('validates $not operator nesting', () => {
678
- // $not can be nested
679
- expect(() =>
680
- translator.translate({
681
- field: { $not: { $not: { $eq: 'value' } } },
682
- }),
683
- ).not.toThrow();
684
-
685
- // $not can be deeply nested
686
- expect(() =>
687
- translator.translate({
688
- field: { $not: { $not: { $not: { $eq: 'value' } } } },
689
- }),
690
- ).not.toThrow();
691
-
692
- // Cannot use $not with logical operators
693
- expect(() =>
694
- translator.translate({
695
- field: { $not: { $and: [{ $eq: 'value1' }, { $eq: 'value2' }] } },
696
- }),
697
- ).not.toThrow();
698
-
699
- expect(() =>
700
- translator.translate({
701
- field: { $not: { $or: [{ $eq: 'value1' }, { $eq: 'value2' }] } },
702
- }),
703
- ).not.toThrow();
704
-
705
- // $not can be used with comparison operators at any nesting level
706
- expect(() =>
707
- translator.translate({
708
- field: { $not: { $not: { $gt: 100 } } },
709
- field2: { $not: { $not: { $lt: 50 } } },
710
- }),
711
- ).not.toThrow();
712
- });
713
-
714
- it('allows $not with comparison operators', () => {
715
- expect(() =>
716
- translator.translate({
717
- field: { $not: { $eq: 'value' } },
718
- field2: { $not: { $gt: 100 } },
719
- field3: { $not: { $lt: 50 } },
720
- field4: { $not: { $in: ['value1', 'value2'] } },
721
- }),
722
- ).not.toThrow();
723
- });
724
-
725
- it('validates empty $not conditions', () => {
726
- expect(() => translator.translate({ field: { $not: {} } })).toThrow();
727
- expect(() => translator.translate({ $not: {} })).toThrow();
728
- });
729
-
730
- it('throws error for non-logical operators at top level', () => {
731
- const invalidFilters = [{ $gt: 100 }, { $in: ['value1', 'value2'] }, { $eq: true }];
732
-
733
- invalidFilters.forEach(filter => {
734
- expect(() => translator.translate(filter as any)).toThrow(/Invalid top-level operator/);
735
- });
736
- });
737
- it('allows logical operators at top level', () => {
738
- const validFilters = [{ $and: [{ field: 'value' }] }, { $or: [{ field: 'value' }] }];
739
-
740
- validFilters.forEach(filter => {
741
- expect(() => translator.translate(filter)).not.toThrow();
742
- });
743
- });
744
-
745
- it('should throw error for direct regex patterns', () => {
746
- const filter = {
747
- field: /pattern/,
748
- };
749
- expect(() => translator.translate(filter)).toThrow();
750
- });
751
-
752
- it('validates $elemMatch requires an object with conditions', () => {
753
- // Should throw for non-object values
754
- expect(() =>
755
- translator.translate({
756
- field: { $elemMatch: 'value' } as any,
757
- }),
758
- ).toThrow('$elemMatch requires an object with conditions');
759
-
760
- expect(() =>
761
- translator.translate({
762
- field: { $elemMatch: ['value'] } as any,
763
- }),
764
- ).toThrow('$elemMatch requires an object with conditions');
765
- });
766
- });
767
-
768
- // Regex Support (Currently Commented)
769
- // describe('regex translation', () => {
770
- // it('translates string pattern', () => {
771
- // expect(
772
- // translator.translate({
773
- // field: { $regex: 'pattern' },
774
- // }),
775
- // ).toEqual({
776
- // field: { $regex: 'pattern' },
777
- // });
778
- // });
779
- // it('translates regex with options', () => {
780
- // expect(
781
- // translator.translate({
782
- // field: { $regex: 'pattern', $options: 'i' },
783
- // }),
784
- // ).toEqual({
785
- // field: { $regex: 'pattern', $options: 'i' },
786
- // });
787
- // });
788
- // it('translates regex literal', () => {
789
- // expect(
790
- // translator.translate({
791
- // field: /pattern/i,
792
- // }),
793
- // ).toEqual({
794
- // field: { $regex: 'pattern', $options: 'i' },
795
- // });
796
- // });
797
- // it('translates starts with pattern', () => {
798
- // expect(
799
- // translator.translate({
800
- // field: { $regex: '^start' },
801
- // }),
802
- // ).toEqual({
803
- // field: { $regex: '^start' },
804
- // });
805
- // });
806
- // it('translates ends with pattern', () => {
807
- // expect(
808
- // translator.translate({
809
- // field: { $regex: 'end$' },
810
- // }),
811
- // ).toEqual({
812
- // field: { $regex: 'end$' },
813
- // });
814
- // });
815
- // it('translates exact match pattern', () => {
816
- // expect(
817
- // translator.translate({
818
- // field: { $regex: '^exact$' },
819
- // }),
820
- // ).toEqual({
821
- // field: { $regex: '^exact$' },
822
- // });
823
- // });
824
- // it('translates contains pattern', () => {
825
- // expect(
826
- // translator.translate({
827
- // field: { $regex: 'contains' },
828
- // }),
829
- // ).toEqual({
830
- // field: { $regex: 'contains' },
831
- // });
832
- // });
833
- // it('supports complex patterns', () => {
834
- // expect(
835
- // translator.translate({
836
- // field: { $regex: 'pat.*ern' },
837
- // }),
838
- // ).toEqual({
839
- // field: { $regex: 'pat.*ern' },
840
- // });
841
- // });
842
- // it('combines multiple regex flags', () => {
843
- // expect(
844
- // translator.translate({
845
- // field: { $regex: 'pattern', $options: 'imsx' },
846
- // }),
847
- // ).toEqual({
848
- // field: { $regex: 'pattern', $options: 'imsx' },
849
- // });
850
- // });
851
- // it('throws on $options without $regex', () => {
852
- // expect(() =>
853
- // translator.translate({
854
- // field: { $options: 'i' },
855
- // }),
856
- // ).toThrow();
857
- // });
858
- // it('handles nested regex patterns', () => {
859
- // expect(
860
- // translator.translate({
861
- // nested: {
862
- // field: { $regex: 'pattern', $options: 'i' },
863
- // },
864
- // }),
865
- // ).toEqual({
866
- // 'nested.field': { $regex: 'pattern', $options: 'i' },
867
- // });
868
- // });
869
- // it('handles multiple regex patterns', () => {
870
- // expect(
871
- // translator.translate({
872
- // field1: { $regex: 'pattern1' },
873
- // field2: { $regex: 'pattern2', $options: 'i' },
874
- // }),
875
- // ).toEqual({
876
- // field1: { $regex: 'pattern1' },
877
- // field2: { $regex: 'pattern2', $options: 'i' },
878
- // });
879
- // });
880
- // it('handles regex in logical operators', () => {
881
- // expect(
882
- // translator.translate({
883
- // $or: [{ field: { $regex: 'pattern1' } }, { field: { $regex: 'pattern2', $options: 'i' } }],
884
- // }),
885
- // ).toEqual({
886
- // $or: [{ field: { $regex: 'pattern1' } }, { field: { $regex: 'pattern2', $options: 'i' } }],
887
- // });
888
- // });
889
- // it('handles deeply nested paths with regex', () => {
890
- // expect(
891
- // translator.translate({
892
- // 'level1.level2.level3': { $regex: 'pattern', $options: 'i' },
893
- // }),
894
- // ).toEqual({
895
- // 'level1.level2.level3': { $regex: 'pattern', $options: 'i' },
896
- // });
897
- // });
898
- // });
899
-
900
- // Unsupported Operations
901
- describe('unsupported operators', () => {
902
- it('throws on unsupported operators', () => {
903
- expect(() => translator.translate({ field: { $regex: 'value' } } as any)).toThrow();
904
- });
905
- });
906
- });