commit 915936f7cc7ad3eb0213efbb2439414ac5b13f02 Author: sharpshark28 Date: Fri May 26 06:10:36 2017 -0500 v1.0.0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..0fe294a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "7" diff --git a/index.js b/index.js new file mode 100644 index 0000000..d879c2f --- /dev/null +++ b/index.js @@ -0,0 +1,47 @@ +module.exports = class Query { + constructor (data) { + this.data = data.map(item => { + item.sortScore = 0; + return item; + }); + }; + + get results () { + return this.data; + }; + + search (key, term, score = 0) { + switch (typeof term) { + case 'boolean': + this.data = this.data.filter(item => item[key] === term); + break; + case 'string': + if (term.length >= 3) { + this.data = this.data.filter(item => { + let regFind = new RegExp(term, 'gi'); + let termMatches = (item[key].match(regFind) || []).length; + item.sortScore += termMatches; + return termMatches; + }); + } + break; + } + return this; + }; + + sort (key = 'sortScore') { + this.data = this.data.sort((a, b) => { + if (a[key] < b[key]) return -1; + if (a[key] > b[key]) return 1; + return 0; + }); + return this; + }; + + paginate (page = 1, perPage = 10) { + let min = page * perPage - perPage; + let max = min + perPage; + this.data = this.data.slice(min, max); + return this; + }; +}; diff --git a/index.test.js b/index.test.js new file mode 100644 index 0000000..3cc570c --- /dev/null +++ b/index.test.js @@ -0,0 +1,79 @@ +const Query = require('./index'); +const TestData = require('./testdata.json'); + +test('should not modify passed data without chain alterations', () => { + let query = new Query(TestData) + .results; + + expect(query).toMatchObject(TestData); +}); + +test('should paginate with default params', () => { + let query = new Query(TestData) + .paginate() + .results; + + expect(query.length).toBe(9); +}); + +test('should paginate with custom page length', () => { + let query = new Query(TestData) + .paginate(1, 3) + .results; + + expect(query.length).toBe(3); + expect(query[0].name).toBe('Haynes Meadows') +}); + +test('should paginate to second page with custom page length', () => { + let query = new Query(TestData) + .paginate(2, 3) + .results; + + expect(query.length).toBe(3); + expect(query[0].name).toBe('Howard Buckley') +}); + +test('should search by boolean isActive', () => { + let query = new Query(TestData) + .search('isActive', true) + .results; + + expect(query.length).toBe(4); +}); + +test('should search by age', () => { + let query = new Query(TestData) + .search('name', 'steele') + .results; + + expect(query.length).toBe(2); +}); + +test('should sort by boolean isActive', () => { + let query = new Query(TestData) + .sort('isActive') + .results; + + expect(query[0].name).toBe('Katelyn Steele'); +}); + +test('should sort by string name', () => { + let query = new Query(TestData) + .sort('name') + .results; + + expect(query[0].name).toBe('Dudley Conner'); +}); + +test('should chain everything together', () => { + let query = new Query(TestData) + .search('isActive', true) + .sort('name') + .paginate(1, 2) + .results; + + expect(query.length).toBe(2); + expect(query[0].name).toBe('Dudley Conner'); + expect(query[query.length - 1].name).toBe('Haynes Meadows'); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..14bb756 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "json-query-chain", + "version": "1.0.0", + "description": "Chain queries onto POJOs to return precise results.", + "main": "index.js", + "scripts": { + "test": "jest" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/sharpshark28/json-query-chain.git" + }, + "author": "Joe Wroten ", + "license": "ISC", + "bugs": { + "url": "https://github.com/sharpshark28/json-query-chain/issues" + }, + "homepage": "https://github.com/sharpshark28/json-query-chain#readme", + "devDependencies": { + "jest": "^20.0.4" + } +} diff --git a/testdata.json b/testdata.json new file mode 100644 index 0000000..584c507 --- /dev/null +++ b/testdata.json @@ -0,0 +1,137 @@ +[ + { + "_id": "5928038b69b33613f3577487", + "isActive": true, + "age": 20, + "name": "Haynes Meadows", + "tags": [ + "et", + "enim", + "cillum", + "minim", + "consequat", + "aliquip", + "voluptate" + ] + }, + { + "_id": "5928038ba2400e7e09550991", + "isActive": false, + "age": 22, + "name": "Katelyn Steele", + "tags": [ + "cupidatat", + "mollit", + "eiusmod", + "ex", + "officia", + "aliquip", + "ea" + ] + }, + { + "_id": "5928038bff4df5c29016be22", + "isActive": false, + "age": 29, + "name": "Natalia Petty", + "tags": [ + "nulla", + "dolor", + "anim", + "cupidatat", + "quis", + "magna", + "ea" + ] + }, + { + "_id": "5928038b496f64e646cb8d69", + "isActive": false, + "age": 34, + "name": "Howard Buckley", + "tags": [ + "qui", + "ullamco", + "occaecat", + "et", + "voluptate", + "tempor", + "culpa" + ] + }, + { + "_id": "5928038b4d214186ba1e7fa2", + "isActive": false, + "age": 22, + "name": "Jenkins Mosley", + "tags": [ + "adipisicing", + "sunt", + "officia", + "deserunt", + "quis", + "nulla", + "est" + ] + }, + { + "_id": "5928038b67ae9fd2f9ba536b", + "isActive": true, + "age": 33, + "name": "Keith Short", + "tags": [ + "deserunt", + "cupidatat", + "nostrud", + "nostrud", + "magna", + "ex", + "deserunt" + ] + }, + { + "_id": "5928038b6b878f937b544826", + "isActive": false, + "age": 33, + "name": "Wade Steele", + "tags": [ + "mollit", + "dolore", + "fugiat", + "magna", + "fugiat", + "officia", + "aute" + ] + }, + { + "_id": "5928038b605e95ea58efa47a", + "isActive": true, + "age": 33, + "name": "Dudley Conner", + "tags": [ + "aliquip", + "aliquip", + "reprehenderit", + "nostrud", + "irure", + "sint", + "laborum" + ] + }, + { + "_id": "5928038bfece811301f276c7", + "isActive": true, + "age": 33, + "name": "Newman Mays", + "tags": [ + "et", + "amet", + "dolore", + "ipsum", + "ea", + "ea", + "enim" + ] + } +]