From daddd5e809f3621fb2aba583ec61a3de05623502 Mon Sep 17 00:00:00 2001 From: bartcharbon Date: Wed, 27 Jan 2021 11:16:23 +0100 Subject: [PATCH 1/2] Add <,>,<=,>= operators --- src/__tests__/index.test.ts | 97 +++++++++++++++++++++++++++++++++++++ src/index.ts | 70 +++++++++++++++++++++++++- 2 files changed, 166 insertions(+), 1 deletion(-) diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 0f97408..639866f 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -242,6 +242,103 @@ test('get - one record with invalid selector', async () => { await expect(api.getRecords(params)).rejects.toThrow("value '10042538' is of type 'number' instead of 'object'"); }); +test('get - records with greater than query', async () => { + const params: Params = { + query: { + selector: ['n', 'n_number2'], + operator: '>', + args: 0, + }, + }; + const records = await api.getRecords(params); + expect(records).toEqual({ + items: [record0], + page: { number: 0, size: 10, totalElements: 1 }, + total: 32, + }); +}); + +test('get - records with greater than or equal query', async () => { + const params: Params = { + query: { + selector: ['n', 'n_number2'], + operator: '>=', + args: 1, + }, + }; + const records = await api.getRecords(params); + expect(records).toEqual({ + items: [record0], + page: { number: 0, size: 10, totalElements: 1 }, + total: 32, + }); +}); + +test('get - records with less than query', async () => { + const params: Params = { + query: { + selector: ['n', 'n_number2'], + operator: '<', + args: 1, + }, + }; + const records = await api.getRecords(params); + expect(records).toEqual({ + items: [record1], + page: { number: 0, size: 10, totalElements: 1 }, + total: 32, + }); +}); + +test('get - records with less than or equal query', async () => { + const params: Params = { + query: { + selector: ['n', 'n_number2'], + operator: '<=', + args: 1, + }, + }; + const records = await api.getRecords(params); + expect(records).toEqual({ + items: [record0, record1], + page: { number: 0, size: 10, totalElements: 2 }, + total: 32, + }); +}); + +test('get - one record with invalid selector', async () => { + const params: Params = { + query: { + selector: ['p', 'x', 'y', 'z'], + operator: '==', + args: 10042538, + }, + }; + await expect(api.getRecords(params)).rejects.toThrow("value '10042538' is of type 'number' instead of 'object'"); +}); + +test('get - one record with invalid selector', async () => { + const params: Params = { + query: { + selector: ['p', 'x', 'y', 'z'], + operator: '==', + args: 10042538, + }, + }; + await expect(api.getRecords(params)).rejects.toThrow("value '10042538' is of type 'number' instead of 'object'"); +}); + +test('get - one record with invalid selector', async () => { + const params: Params = { + query: { + selector: ['p', 'x', 'y', 'z'], + operator: '==', + args: 10042538, + }, + }; + await expect(api.getRecords(params)).rejects.toThrow("value '10042538' is of type 'number' instead of 'object'"); +}); + test('get - one record using composed and query', async () => { const params: Params = { query: { diff --git a/src/index.ts b/src/index.ts index 0be0a87..86d8b2e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -116,7 +116,7 @@ export interface ComposedQuery { } export interface Query { - operator: '==' | '!=' | 'in' | '!in' | 'has_any' | '!has_any' | 'any_has_any' | '!any_has_any'; + operator: '==' | '!=' | 'in' | '!in' | 'has_any' | '!has_any' | 'any_has_any' | '!any_has_any' | '>' | '>=' | '<' | '<='; selector: Selector; args: string | number | boolean | string[] | number[]; } @@ -356,6 +356,18 @@ function matches(query: Query | ComposedQuery, resource: Resource): boolean { case '!in': match = !matchesIn(query, resource); break; + case '>': + match = matchesGreaterThan(query, resource); + break; + case '>=': + match = matchesGreaterThanOrEqual(query, resource); + break; + case '<': + match = matchesLesserThan(query, resource); + break; + case '<=': + match = matchesLesserThanOrEqual(query, resource); + break; default: throw new Error('unexpected query operator ' + query.operator); } @@ -427,6 +439,62 @@ function matchesHasAny(query: Query, resource: Resource): boolean { return match; } +function matchesGreaterThan(query: Query, resource: Resource): boolean { + const value: any = select(query.selector, resource); + + if (value === undefined) { + return false; + } + + if (!Number.isInteger(value)) { + throw new Error(`value '${value}' is of type '${typeof value}' instead of 'number'`); + } + + return value > query.args; +} + +function matchesGreaterThanOrEqual(query: Query, resource: Resource): boolean { + const value: any = select(query.selector, resource); + + if (value === undefined) { + return false; + } + + if (!Number.isInteger(value)) { + throw new Error(`value '${value}' is of type '${typeof value}' instead of 'number'`); + } + + return value >= query.args; +} + +function matchesLesserThan(query: Query, resource: Resource): boolean { + const value: any = select(query.selector, resource); + + if (value === undefined) { + return false; + } + + if (!Number.isInteger(value)) { + throw new Error(`value '${value}' is of type '${typeof value}' instead of 'number'`); + } + + return value < query.args; +} + +function matchesLesserThanOrEqual(query: Query, resource: Resource): boolean { + const value: any = select(query.selector, resource); + + if (value === undefined) { + return false; + } + + if (!Number.isInteger(value)) { + throw new Error(`value '${value}' is of type '${typeof value}' instead of 'number'`); + } + + return value <= query.args; +} + function select(selector: Selector, resource: Resource) { let parts: SelectorPart[]; if (Array.isArray(selector)) { From 107118fc23af79bdd21e1f884d5fc867e3c30f34 Mon Sep 17 00:00:00 2001 From: bartcharbon Date: Thu, 28 Jan 2021 07:54:06 +0100 Subject: [PATCH 2/2] change fieldtype check to support non int values --- src/__tests__/index.test.ts | 11 +++++++++++ src/index.ts | 16 ++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 639866f..fc97073 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -306,6 +306,17 @@ test('get - records with less than or equal query', async () => { }); }); +test('get - records with less than or equal query invalid field', async () => { + const params: Params = { + query: { + selector: ['n', 'n_string0'], + operator: '<=', + args: 1, + }, + }; + await expect(api.getRecords(params)).rejects.toThrow("value 'a' is of type 'string' instead of 'number'"); +}); + test('get - one record with invalid selector', async () => { const params: Params = { query: { diff --git a/src/index.ts b/src/index.ts index 86d8b2e..a22291e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -442,11 +442,11 @@ function matchesHasAny(query: Query, resource: Resource): boolean { function matchesGreaterThan(query: Query, resource: Resource): boolean { const value: any = select(query.selector, resource); - if (value === undefined) { + if (value === undefined || value === null) { return false; } - if (!Number.isInteger(value)) { + if (typeof value !== 'number') { throw new Error(`value '${value}' is of type '${typeof value}' instead of 'number'`); } @@ -456,11 +456,11 @@ function matchesGreaterThan(query: Query, resource: Resource): boolean { function matchesGreaterThanOrEqual(query: Query, resource: Resource): boolean { const value: any = select(query.selector, resource); - if (value === undefined) { + if (value === undefined || value === null) { return false; } - if (!Number.isInteger(value)) { + if (typeof value !== 'number') { throw new Error(`value '${value}' is of type '${typeof value}' instead of 'number'`); } @@ -470,11 +470,11 @@ function matchesGreaterThanOrEqual(query: Query, resource: Resource): boolean { function matchesLesserThan(query: Query, resource: Resource): boolean { const value: any = select(query.selector, resource); - if (value === undefined) { + if (value === undefined || value === null) { return false; } - if (!Number.isInteger(value)) { + if (typeof value !== 'number') { throw new Error(`value '${value}' is of type '${typeof value}' instead of 'number'`); } @@ -484,11 +484,11 @@ function matchesLesserThan(query: Query, resource: Resource): boolean { function matchesLesserThanOrEqual(query: Query, resource: Resource): boolean { const value: any = select(query.selector, resource); - if (value === undefined) { + if (value === undefined || value === null) { return false; } - if (!Number.isInteger(value)) { + if (typeof value !== 'number') { throw new Error(`value '${value}' is of type '${typeof value}' instead of 'number'`); }