Skip to content

Commit 8faaedf

Browse files
committed
test: add tests
1 parent 4a3ec74 commit 8faaedf

File tree

2 files changed

+358
-140
lines changed

2 files changed

+358
-140
lines changed

typescript/src/__tests__/pict.test.ts

Lines changed: 141 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe('PictConstraintsLexer with single constraints', () => {
2828

2929
it('should handle NOT conditions correctly', () => {
3030
const lexer = new PictConstraintsLexer(`
31-
IF NOT [PRODUCT] = "Book" THEN [AVAILABLE] = "Yes" ELSE [AVAILABLE] = "No";
31+
IF NOT [PRODUCT] = "Book" THEN [AVAILABLE] <> "No" ELSE [AVAILABLE] = "No";
3232
`, false);
3333
const row1 = { PRODUCT: 'Pen', AVAILABLE: 'Yes' };
3434
expect(lexer.filter(row1)).toBe(true);
@@ -47,7 +47,7 @@ describe('PictConstraintsLexer with single constraints', () => {
4747
const row1 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Included' };
4848
expect(lexer.filter(row1)).toBe(true);
4949

50-
const row2 = { CATEGORY: 'Electronics', BRAND: 'Samsung', WARRANTY: 'Not Included' };
50+
const row2 = { CATEGORY: 'Electronics', BRAND: 'General Electric Company', WARRANTY: 'Not Included' };
5151
expect(lexer.filter(row2)).toBe(true);
5252

5353
const row3 = { CATEGORY: 'Electronics', BRAND: 'Sony', WARRANTY: 'Not Included' };
@@ -71,17 +71,17 @@ describe('PictConstraintsLexer with single constraints', () => {
7171
expect(lexer.filter(row4)).toBe(false);
7272
});
7373

74-
it('should handle string equality conditions', () => {
74+
it('should handle fields containing spaces', () => {
7575
const lexer = new PictConstraintsLexer(`
76-
IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE [STATUS] = "Active";
76+
IF [PRODUCT NAME] = "Laptop" THEN [PRICE] > 500 ELSE [PRICE] <= 500;
7777
`, false);
78-
const row1 = { NAME: 'Bob', STATUS: 'Inactive' };
78+
const row1 = { 'PRODUCT NAME': 'Laptop', PRICE: 600 };
7979
expect(lexer.filter(row1)).toBe(true);
8080

81-
const row2 = { NAME: 'Alice', STATUS: 'Active' };
82-
expect(lexer.filter(row2)).toBe(true);
81+
const row2 = { 'PRODUCT NAME': 'Laptop', PRICE: 400 };
82+
expect(lexer.filter(row2)).toBe(false);
8383

84-
const row3 = { NAME: 'Bob', STATUS: 'Active' };
84+
const row3 = { 'PRODUCT NAME': 'Desktop', PRICE: 600 };
8585
expect(lexer.filter(row3)).toBe(false);
8686
});
8787

@@ -118,6 +118,40 @@ describe('PictConstraintsLexer with single constraints', () => {
118118
const row5 = { AGE: 25, COUNTRY: 'Canada', STATUS: 'Denied' };
119119
expect(lexer.filter(row5)).toBe(false);
120120
});
121+
it('should handle false in ELSE condition', () => {
122+
const lexer = new PictConstraintsLexer(`
123+
IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE FALSE;
124+
`, false);
125+
const row1 = { NAME: 'Bob', STATUS: 'Inactive' };
126+
expect(lexer.filter(row1)).toBe(true);
127+
128+
const row2 = { NAME: 'Alice', STATUS: 'Active' };
129+
expect(lexer.filter(row2)).toBe(false);
130+
});
131+
132+
it('should handle true in ELSE condition', () => {
133+
const lexer = new PictConstraintsLexer(`
134+
IF [NAME] = "Bob" THEN [STATUS] = "Inactive" ELSE true;
135+
`, false);
136+
const row1 = { NAME: 'Bob', STATUS: 'Inactive' };
137+
expect(lexer.filter(row1)).toBe(true);
138+
139+
const row2 = { NAME: 'Alice', STATUS: 'Active' };
140+
expect(lexer.filter(row2)).toBe(true);
141+
});
142+
it('Compare with other fields', () => {
143+
const lexer = new PictConstraintsLexer(`
144+
IF [NAME] = [ALIAS] THEN [AGE] <= 26;
145+
`, false);
146+
const row1 = { NAME: 'Bob', ALIAS: 'Bob', AGE: 18 };
147+
expect(lexer.filter(row1)).toBe(true);
148+
149+
const row2 = { NAME: 'Alice', ALIAS: 'Lissie', AGE: 25 };
150+
expect(lexer.filter(row2)).toBe(true);
151+
152+
const row3 = { NAME: 'Shohei', ALIAS: 'Shohei', AGE: 30 };
153+
expect(lexer.filter(row3)).toBe(false);
154+
});
121155
});
122156

123157
describe('PictConstraintsLexer with multiple constraints', () => {
@@ -248,3 +282,102 @@ describe('PictConstraintsLexer with multiple constraints', () => {
248282
expect(lexer.filter(row3)).toBe(true);
249283
});
250284
});
285+
286+
describe('PictConstraintsLexer with invalid constraints', () => {
287+
it('Unknown comparer', () => {
288+
const lexer = new PictConstraintsLexer(`
289+
IF [NAME] @ "Alice" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive";
290+
`, false);
291+
expect(lexer.errors.length).toBe(1);
292+
expect(lexer.errors[0]).toBe('Unknown comparison operator: @');
293+
});
294+
295+
it('Comparison operator missing, got a value', () => {
296+
const lexer = new PictConstraintsLexer(`
297+
IF [NAME] "Alice" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive";
298+
`, false);
299+
expect(lexer.errors.length).toBe(1);
300+
expect(lexer.errors[0]).toBe('Expected comparison operator but found value: "Alice"');
301+
});
302+
303+
it('Comparison operator missing, got an operator', () => {
304+
const lexer = new PictConstraintsLexer(`
305+
IF [NAME] AND TRUE THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive";
306+
`, false);
307+
expect(lexer.errors.length).toBe(1);
308+
expect(lexer.errors[0]).toBe('Expected comparison operator but found operator: AND');
309+
});
310+
311+
it('Comparison operator and value missing, got then', () => {
312+
const lexer = new PictConstraintsLexer(`
313+
IF [NAME] THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"
314+
`, false);
315+
expect(lexer.errors.length).toBe(1);
316+
expect(lexer.errors[0]).toBe('A comparison operator and value are required after the field.');
317+
});
318+
it('Nothing after IF', () => {
319+
const lexer = new PictConstraintsLexer(`
320+
IF THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive"
321+
`, false);
322+
expect(lexer.errors.length).toBe(1);
323+
expect(lexer.errors[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"');
324+
});
325+
326+
it('Nothing after THEN', () => {
327+
const lexer = new PictConstraintsLexer(`
328+
IF [NAME] = "Summer" THEN ELSE [STATUS] = "Active"
329+
`, false);
330+
expect(lexer.errors.length).toBe(1);
331+
expect(lexer.errors[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"');
332+
});
333+
334+
it('Nothing after ELSE', () => {
335+
const lexer = new PictConstraintsLexer(`
336+
IF [NAME] = "Summer" THEN [STATUS] = "Active" ELSE
337+
`, false);
338+
expect(lexer.errors.length).toBe(1);
339+
expect(lexer.errors[0]).toBe('Expected field or value after "IF", "THEN", "ELSE"');
340+
});
341+
342+
343+
it('IF is missing, typo', () => {
344+
const lexer = new PictConstraintsLexer(`
345+
F [NAME] = "Summer" THEN [STATUS] = "Active"
346+
`, false);
347+
expect(lexer.errors.length).toBe(1);
348+
expect(lexer.errors[0]).toBe('Unknown token: F');
349+
});
350+
351+
it('IF is nothing', () => {
352+
const lexer = new PictConstraintsLexer(`
353+
[NAME] = "Summer" THEN [STATUS] = "Active"
354+
`, false);
355+
expect(lexer.errors.length).toBe(1);
356+
expect(lexer.errors[0]).toBe('The leading "IF" is missing, found [NAME]');
357+
});
358+
359+
360+
it('Multiple invalid expressions', () => {
361+
const lexer = new PictConstraintsLexer(`
362+
IF [NAME] THEN [STATUS] = "Active";
363+
IF [NAME] = "Summer" THEN [STATUS] = "Active";
364+
IF [NAME] = "Summer" THEN [STATUS] = "Active" ELSE;
365+
IF [NAME] = "Summer" THEN [STATUS] = "Active";
366+
IF [NAME] @ "Summer" THEN [STATUS] = "Active" ELSE [STATUS] = "Inactive";
367+
`, false);
368+
369+
expect(lexer.errors.length).toBe(5);
370+
371+
expect(lexer.errors[0]).toBe('A comparison operator and value are required after the field.' );
372+
expect(lexer.errors[1]).toBe(null);
373+
expect(lexer.errors[2]).toBe('Expected field or value after "IF", "THEN", "ELSE"' );
374+
expect(lexer.errors[3]).toBe(null);
375+
expect(lexer.errors[4]).toBe('Unknown comparison operator: @');
376+
377+
expect(lexer.filters[0]).toBeNull();
378+
expect(lexer.filters[1]).not.toBeNull();
379+
expect(lexer.filters[2]).toBeNull();
380+
expect(lexer.filters[3]).not.toBeNull();
381+
expect(lexer.filters[4]).toBeNull();
382+
});
383+
});

0 commit comments

Comments
 (0)