Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: basic Redis grammar, parseRedisQueryWithoutCursor function, tests #207

Merged
merged 9 commits into from
Aug 7, 2024
19 changes: 19 additions & 0 deletions src/autocomplete/databases/redis/tests/decrement/decrement.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {parseRedisQueryWithoutCursor} from '../../index';

test('should not report errors on DECR command', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('DECR test');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on multiple DECR commands', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('DECR test\nDECR 123');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should report errors on DECR command without arguments', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('DECR');

expect(autocompleteResult.errors).toHaveLength(1);
});
19 changes: 19 additions & 0 deletions src/autocomplete/databases/redis/tests/get/get.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {parseRedisQueryWithoutCursor} from '../../index';

test('should not report errors on GET command', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('GET test');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on multiple GET commands', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('GET test\nGET 123');

expect(autocompleteResult.errors).toHaveLength(0);
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to have a separete multiple commands test. Because in the end we want to test commands rule 3fd0a09#diff-b96534631ee82ffc85910f193fcacb74b496e3324eef92e1d7121103f2321683R16


test('should report errors on GET command without arguments', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('GET');

expect(autocompleteResult.errors).toHaveLength(1);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {parseRedisQueryWithoutCursor} from '../../index';

test('should not report errors on string identifier', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('GET test');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on number identifier', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('GET 123');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on identifier with special symbols', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('GET test123;:,.$#!@%-=+-~()[]{}');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should report errors on identifier with double quote', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('GET test"');

expect(autocompleteResult.errors).toHaveLength(1);
});

test('should report errors on identifier with single quote', () => {
const autocompleteResult = parseRedisQueryWithoutCursor("GET test'");

expect(autocompleteResult.errors).toHaveLength(1);
});

test('should report errors on identifier with space', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('GET test test');

expect(autocompleteResult.errors).toHaveLength(1);
});

test('should not report errors on double quoted identifier', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('GET "test123;:,.$#!@%-=+-~()[]{}"');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on single quoted identifier', () => {
const autocompleteResult = parseRedisQueryWithoutCursor("GET 'test123;:,.$#!@%-=+-~()[]{}'");

expect(autocompleteResult.errors).toHaveLength(0);
});
19 changes: 19 additions & 0 deletions src/autocomplete/databases/redis/tests/increment/increment.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {parseRedisQueryWithoutCursor} from '../../index';

test('should not report errors on INCR command', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('INCR test');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on multiple INCR commands', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('INCR test\nINCR 123');
Copy link
Collaborator

@NikitaShkaruba NikitaShkaruba Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We split queries by newline? Maybe it's better to force ; in the end? This way it's gonna be easier for us to parse multiple commands too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can't use semicolon, because it is valid to use in key/value name, e.g. SET key value; will set value to value;
that's why Redis commands are separated by newline, that's also the way they do it in DataGrip


expect(autocompleteResult.errors).toHaveLength(0);
});

test('should report errors on INCR command without arguments', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('INCR');

expect(autocompleteResult.errors).toHaveLength(1);
});
73 changes: 73 additions & 0 deletions src/autocomplete/databases/redis/tests/set/set.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {parseRedisQueryWithoutCursor} from '../../index';

test('should not report errors on SET command', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on multiple SET commands', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test\nSET 123 123');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should report errors on SET command without arguments', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET');

expect(autocompleteResult.errors).toHaveLength(1);
});

test('should not report errors on SET command with NX argument', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test NX');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on SET command with XX argument', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test XX');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on SET command with GET argument', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test GET');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on SET command with EX argument', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test EX 123');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on SET command with PX argument', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test PX 123');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on SET command with EXAT argument', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test EXAT 123');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on SET command with PXAT argument', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test PXAT 123');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on SET command with KEEPTTL argument', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test KEEPTTL');

expect(autocompleteResult.errors).toHaveLength(0);
});

test('should not report errors on SET command with all argument', () => {
const autocompleteResult = parseRedisQueryWithoutCursor('SET test test XX GET PXAT 123');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These XX, EXAT are declared in the redis grammar? Or is it our doing? How will we document this syntax in our documentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's part of official syntax of course - https://redis.io/docs/latest/commands/set/
I don't see why we need to document Redis syntax in our own docs


expect(autocompleteResult.errors).toHaveLength(0);
});