From 1e2f3e9b3f07c3db33314eb0d2c8ff978bb06b59 Mon Sep 17 00:00:00 2001 From: Yuri Komlev Date: Thu, 18 Jul 2019 04:09:49 +0300 Subject: [PATCH 1/9] adds withCount query constrain --- src/ParseQuery.js | 48 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/ParseQuery.js b/src/ParseQuery.js index 0f6cff424..0969cf431 100644 --- a/src/ParseQuery.js +++ b/src/ParseQuery.js @@ -224,6 +224,7 @@ class ParseQuery { _select: Array; _limit: number; _skip: number; + _count: boolean; _order: Array; _readPreference: string; _includeReadPreference: string; @@ -260,6 +261,7 @@ class ParseQuery { this._where = {}; this._include = []; this._exclude = []; + this._count = false; this._limit = -1; // negative limit is not sent in the server request this._skip = 0; this._readPreference = null; @@ -364,6 +366,12 @@ class ParseQuery { return handleOfflineSort(a, b, sorts); }); } + + let count // count total before applying limita/skip + if(params.count){ + count = results.length // total count from response + } + if (params.skip) { if (params.skip >= results.length) { results = []; @@ -375,7 +383,13 @@ class ParseQuery { if (params.limit !== 0 && params.limit < results.length) { limit = params.limit; } + results = results.splice(0, limit); + + if(typeof count === 'number'){ + return {results, count} + } + return results; } @@ -397,6 +411,9 @@ class ParseQuery { if (this._select) { params.keys = this._select.join(','); } + if (this._count) { + params.count = 1; + } if (this._limit >= 0) { params.limit = this._limit; } @@ -460,6 +477,10 @@ class ParseQuery { this._exclude = json.excludeKeys.split(","); } + if (json.count) { + this._count = json.count !== 0; + } + if (json.limit) { this._limit = json.limit; } @@ -486,7 +507,7 @@ class ParseQuery { for (const key in json) { if (json.hasOwnProperty(key)) { - if (["where", "include", "keys", "limit", "skip", "order", "readPreference", "includeReadPreference", "subqueryReadPreference"].indexOf(key) === -1) { + if (["where", "include", "keys", "count", "limit", "skip", "order", "readPreference", "includeReadPreference", "subqueryReadPreference"].indexOf(key) === -1) { this._extraOptions[key] = json[key]; } } @@ -588,7 +609,8 @@ class ParseQuery { this.toJSON(), findOptions ).then((response) => { - return response.results.map((data) => { + + const results = response.results.map((data) => { // In cases of relations, the server may send back a className // on the top level of the payload const override = response.className || this.className; @@ -605,6 +627,14 @@ class ParseQuery { return ParseObject.fromJSON(data, !select); }); + + const count = response.count; + + if(typeof count === "number"){ + return {results, count}; + } else { + return results; + } }); } @@ -1468,6 +1498,20 @@ class ParseQuery { return this; } + /** + * Sets the flag for api to count the total number of objects satisfying this query, despite limits/skip. + * Might be useful for pagination. Note that result of this query will be wrapped as an object + * with results holding {ParseObject} array, and integer count. + * @param {boolean} b false - disable, true - enable. + * @return {Parse.Query} Returns the query, so you can chain this call. + */ + withCount(b: boolean): ParseQuery { + if (typeof b !== 'boolean') { + throw new Error('You can only set withCount to a boolean value'); + } + this._count = b; + return this; + } /** * Includes nested Parse.Objects for the provided key. You can use dot * notation to specify which fields in the included object are also fetched. From 72bcedc2db788179a34ccdc6d2fd0287596a6751 Mon Sep 17 00:00:00 2001 From: Yuri Komlev Date: Thu, 18 Jul 2019 04:11:06 +0300 Subject: [PATCH 2/9] tests withCount --- src/__tests__/ParseQuery-test.js | 152 +++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/src/__tests__/ParseQuery-test.js b/src/__tests__/ParseQuery-test.js index 20edcb5fb..3e841f991 100644 --- a/src/__tests__/ParseQuery-test.js +++ b/src/__tests__/ParseQuery-test.js @@ -898,6 +898,24 @@ describe('ParseQuery', () => { }); }); + it('can set withCount flag in find query', () => { + const q = new ParseQuery('Item'); + expect(q.withCount.bind(q, 'string')).toThrow( + 'You can only set withCount to a boolean value' + ); + + q.withCount(true); + expect(q.toJSON()).toEqual({ + where: {}, + count: 1 + }); + q.withCount(false); + expect(q.toJSON()).toEqual({ + where: {} + }); + }); + + it('can generate queries that include full data for pointers', () => { const q = new ParseQuery('Item'); q.greaterThan('inStock', 0); @@ -1414,6 +1432,46 @@ describe('ParseQuery', () => { }); }); + it('can receive both count and objects from find() using withCount constraint', (done) => { + CoreManager.setQueryController({ + + aggregate() {}, + find(className, params, options) { + expect(className).toBe('Item'); + expect(params).toEqual({ + where: {}, + count: 1 + }); + expect(options).toEqual({ + useMasterKey: true, + sessionToken: '1234' + }); + return Promise.resolve({ + results:[ + { objectId: '1', name: 'Product 55' }, + { objectId: '2', name: 'Product 89' } ], + count: 2 + }); + }, + + }); + + const q = new ParseQuery('Item'); + q.withCount(true) + .find({ + useMasterKey: true, + sessionToken: '1234' + }) + .then((obj) => { + expect(obj.results).toBeDefined() + expect(obj.results.length).toBe(2) + expect(obj.count).toBeDefined() + expect(typeof obj.count).toBe('number') + done(); + }); + }); + + it('can iterate over results with each()', (done) => { CoreManager.setQueryController({ aggregate() {}, @@ -1809,6 +1867,7 @@ describe('ParseQuery', () => { q.include('manufacturer'); q.select('inStock', 'lastPurchase'); q.limit(10); + q.withCount(true) q.ascending(['a', 'b', 'c']); q.skip(4); q.equalTo('size', 'medium'); @@ -1823,6 +1882,7 @@ describe('ParseQuery', () => { include: 'manufacturer', keys: 'inStock,lastPurchase', limit: 10, + count: 1, order: 'a,b,c', skip: 4, where: { @@ -2670,6 +2730,98 @@ describe('ParseQuery LocalDatastore', () => { expect(results.length).toEqual(2); }); + it('can query offline withCount, skip and limit', async () => { + const obj1 = { + className: 'Item', + objectId: 'objectId1', + password: 123, + number: 3, + string: 'a', + }; + + const obj2 = { + className: 'Item', + objectId: 'objectId2', + number: 1, + string: 'b', + }; + + const obj3 = { + className: 'Item', + objectId: 'objectId3', + number: 2, + string: 'c', + }; + + const objects = [obj1, obj2, obj3]; + mockLocalDatastore + ._serializeObjectsFromPinName + .mockImplementation(() => objects); + + mockLocalDatastore + .checkIfEnabled + .mockImplementation(() => true); + + let q = new ParseQuery('Item'); + q.skip(0); + q.withCount(true) + q.fromLocalDatastore(); + let result = await q.find(); + expect(result.results.length).toEqual(3); + expect(result.count).toEqual(3); + + q = new ParseQuery('Item'); + q.skip(1); + q.withCount(true) + q.fromLocalDatastore(); + result = await q.find(); + expect(result.results.length).toEqual(2); + expect(result.count).toEqual(3); + + q = new ParseQuery('Item'); + q.skip(3); + q.withCount(true) + q.fromLocalDatastore(); + result = await q.find(); + expect(result.results.length).toEqual(0); + expect(result.count).toEqual(3); + + q = new ParseQuery('Item'); + q.withCount(true) + q.skip(4); + q.fromLocalDatastore(); + result = await q.find(); + expect(result.results.length).toEqual(0); + expect(result.count).toEqual(3); + + q = new ParseQuery('Item'); + q.limit(1); + q.skip(2); + q.withCount(true) + q.fromLocalDatastore(); + result = await q.find(); + expect(result.results.length).toEqual(1); + expect(result.count).toEqual(3); + + q = new ParseQuery('Item'); + q.limit(1); + q.skip(1); + q.withCount(true) + q.fromLocalDatastore(); + result = await q.find(); + expect(result.results.length).toEqual(1); + expect(result.count).toEqual(3); + + q = new ParseQuery('Item'); + q.limit(2); + q.skip(1); + q.withCount(true) + q.fromLocalDatastore(); + result = await q.find(); + expect(result.results.length).toEqual(2); + expect(result.count).toEqual(3); + }); + it('can query offline select keys', async () => { const obj1 = { className: 'Item', From 076595b2f8365b881078710b0ee898827d620e13 Mon Sep 17 00:00:00 2001 From: Yuri Komlev Date: Thu, 18 Jul 2019 04:54:07 +0300 Subject: [PATCH 3/9] doc --- src/ParseQuery.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ParseQuery.js b/src/ParseQuery.js index 0969cf431..456b533f5 100644 --- a/src/ParseQuery.js +++ b/src/ParseQuery.js @@ -367,7 +367,7 @@ class ParseQuery { }); } - let count // count total before applying limita/skip + let count // count total before applying limit/skip if(params.count){ count = results.length // total count from response } @@ -1499,17 +1499,18 @@ class ParseQuery { } /** - * Sets the flag for api to count the total number of objects satisfying this query, despite limits/skip. - * Might be useful for pagination. Note that result of this query will be wrapped as an object - * with results holding {ParseObject} array, and integer count. + * Sets the flag to include with response the total number of objects satisfying this query, + * despite limits/skip. Might be useful for pagination. + * Note that result of this query will be wrapped as an object with + *`results`: holding {ParseObject} array and `count`: integer holding total number * @param {boolean} b false - disable, true - enable. * @return {Parse.Query} Returns the query, so you can chain this call. */ - withCount(b: boolean): ParseQuery { - if (typeof b !== 'boolean') { + withCount(includeCount: boolean): ParseQuery { + if (typeof includeCount !== 'boolean') { throw new Error('You can only set withCount to a boolean value'); } - this._count = b; + this._count = includeCount; return this; } /** From c0c0a04e5adf0d1bc70ab82d6a2d6a23efe9990e Mon Sep 17 00:00:00 2001 From: Yuri Komlev Date: Thu, 18 Jul 2019 04:57:28 +0300 Subject: [PATCH 4/9] formatted --- src/__tests__/ParseQuery-test.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/__tests__/ParseQuery-test.js b/src/__tests__/ParseQuery-test.js index 3e841f991..9434ebc74 100644 --- a/src/__tests__/ParseQuery-test.js +++ b/src/__tests__/ParseQuery-test.js @@ -1432,9 +1432,8 @@ describe('ParseQuery', () => { }); }); - it('can receive both count and objects from find() using withCount constraint', (done) => { + it('can receive both count and objects from find() using withCount flag', (done) => { CoreManager.setQueryController({ - aggregate() {}, find(className, params, options) { expect(className).toBe('Item'); @@ -1452,8 +1451,7 @@ describe('ParseQuery', () => { { objectId: '2', name: 'Product 89' } ], count: 2 }); - }, - + }; }); const q = new ParseQuery('Item'); @@ -1461,12 +1459,12 @@ describe('ParseQuery', () => { .find({ useMasterKey: true, sessionToken: '1234' - }) + }); .then((obj) => { - expect(obj.results).toBeDefined() - expect(obj.results.length).toBe(2) - expect(obj.count).toBeDefined() - expect(typeof obj.count).toBe('number') + expect(obj.results).toBeDefined(); + expect(obj.results.length).toBe(2); + expect(obj.count).toBeDefined(); + expect(typeof obj.count).toBe('number'); done(); }); }); From 100793af411e6fe9420fa74288d29a6b99e12d95 Mon Sep 17 00:00:00 2001 From: Yuri Komlev Date: Thu, 18 Jul 2019 05:12:05 +0300 Subject: [PATCH 5/9] fix semicolons --- src/__tests__/ParseQuery-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/__tests__/ParseQuery-test.js b/src/__tests__/ParseQuery-test.js index 9434ebc74..07f635b54 100644 --- a/src/__tests__/ParseQuery-test.js +++ b/src/__tests__/ParseQuery-test.js @@ -1451,7 +1451,7 @@ describe('ParseQuery', () => { { objectId: '2', name: 'Product 89' } ], count: 2 }); - }; + } }); const q = new ParseQuery('Item'); @@ -1459,7 +1459,7 @@ describe('ParseQuery', () => { .find({ useMasterKey: true, sessionToken: '1234' - }); + }) .then((obj) => { expect(obj.results).toBeDefined(); expect(obj.results.length).toBe(2); From 2e323474cbc77fd44da11ba5900c71af061e5847 Mon Sep 17 00:00:00 2001 From: Yuri Komlev Date: Fri, 19 Jul 2019 04:43:50 +0300 Subject: [PATCH 6/9] integration --- integration/test/ParseQueryTest.js | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/integration/test/ParseQueryTest.js b/integration/test/ParseQueryTest.js index 3760ca3fc..87728de56 100644 --- a/integration/test/ParseQueryTest.js +++ b/integration/test/ParseQueryTest.js @@ -23,6 +23,7 @@ describe('Parse Query', () => { .then(() => { done() }, () => { done() }); }); + it('can do basic queries', (done) => { const baz = new TestObject({ foo: 'baz' }); const qux = new TestObject({ foo: 'qux' }); @@ -51,6 +52,86 @@ describe('Parse Query', () => { }).catch(done.fail); }); + it('can do query with count', async () => { + const items = []; + for (let i = 0; i < 4; i++) { + items.push(new TestObject({ countMe: true })); + } + await Parse.Object.saveAll(items); + + const query = new Parse.Query(TestObject); + query.withCount(true); + const {results,count} = await query.find(); + + assert(typeof count === 'number'); + assert.equal(results.length, 4); + assert.equal(count, 4); + for (let i = 0; i < 4; i++) { + assert.equal(results[i].className,'TestObject'); + } + }); + + it('can do query withCount set to false', async () => { + const items = []; + for (let i = 0; i < 4; i++) { + items.push(new TestObject({ countMe: true })); + } + await Parse.Object.saveAll(items); + + const query = new Parse.Query(TestObject); + query.withCount(false); + const results = await query.find(); + + assert.equal(results.length, 4); + for (let i = 0; i < 4; i++) { + assert.equal(results[i].className,'TestObject'); + } + }); + + it('can do query with count on empty collection', async () => { + const query = new Parse.Query(TestObject); + query.withCount(true); + const {results,count} = await query.find(); + + assert(typeof count == 'number'); + assert.equal(results.length, 0); + assert.equal(count, 0); + }); + + it('can do query with count and limit', async () => { + const items = []; + for (let i = 0; i < 4; i++) { + items.push(new TestObject({ countMe: 2})); + } + await Parse.Object.saveAll(items) + const query = new Parse.Query(TestObject); + query.withCount(true); + query.limit(2); + + const {results,count} = await query.find(); + + assert(typeof count == 'number'); + assert.equal(results.length, 2); + assert.equal(count, 4); + }); + + it('can do query withCount and skip', async () => { + const items = []; + for (let i = 0; i < 4; i++) { + items.push(new TestObject({ countMe: 2})); + } + await Parse.Object.saveAll(items); + const query = new Parse.Query(TestObject); + query.withCount(true); + query.skip(3); + + const {results,count} = await query.find(); + + assert(typeof count == 'number'); + assert.equal(results.length, 1); + assert.equal(count, 4); + }); + it('can do containedIn queries with arrays', (done) => { const messageList = []; for (let i = 0; i < 4; i++) { From 666d936229cbbffcb91d67ab60a87ae28f5168b7 Mon Sep 17 00:00:00 2001 From: Yuri Komlev Date: Fri, 19 Jul 2019 04:45:09 +0300 Subject: [PATCH 7/9] style --- package-lock.json | 45 +++++++++----------------------- src/ParseQuery.js | 4 +-- src/__tests__/ParseQuery-test.js | 16 ++++++------ 3 files changed, 22 insertions(+), 43 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7f5f93b02..c6c14ea14 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5592,8 +5592,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -5616,15 +5615,13 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5640,20 +5637,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -5783,8 +5777,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -5798,7 +5791,6 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5815,7 +5807,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5823,15 +5814,13 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5852,7 +5841,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5940,8 +5928,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -5955,7 +5942,6 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -6050,8 +6036,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -6093,7 +6078,6 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6115,7 +6099,6 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6163,14 +6146,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -9483,7 +9464,6 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -9493,8 +9473,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true, - "optional": true + "dev": true } } }, diff --git a/src/ParseQuery.js b/src/ParseQuery.js index 456b533f5..685a3fd75 100644 --- a/src/ParseQuery.js +++ b/src/ParseQuery.js @@ -369,7 +369,7 @@ class ParseQuery { let count // count total before applying limit/skip if(params.count){ - count = results.length // total count from response + count = results.length; // total count from response } if (params.skip) { @@ -387,7 +387,7 @@ class ParseQuery { results = results.splice(0, limit); if(typeof count === 'number'){ - return {results, count} + return {results, count}; } return results; diff --git a/src/__tests__/ParseQuery-test.js b/src/__tests__/ParseQuery-test.js index 07f635b54..0eed5193d 100644 --- a/src/__tests__/ParseQuery-test.js +++ b/src/__tests__/ParseQuery-test.js @@ -1865,7 +1865,7 @@ describe('ParseQuery', () => { q.include('manufacturer'); q.select('inStock', 'lastPurchase'); q.limit(10); - q.withCount(true) + q.withCount(true); q.ascending(['a', 'b', 'c']); q.skip(4); q.equalTo('size', 'medium'); @@ -2762,7 +2762,7 @@ describe('ParseQuery LocalDatastore', () => { let q = new ParseQuery('Item'); q.skip(0); - q.withCount(true) + q.withCount(true); q.fromLocalDatastore(); let result = await q.find(); expect(result.results.length).toEqual(3); @@ -2770,7 +2770,7 @@ describe('ParseQuery LocalDatastore', () => { q = new ParseQuery('Item'); q.skip(1); - q.withCount(true) + q.withCount(true); q.fromLocalDatastore(); result = await q.find(); expect(result.results.length).toEqual(2); @@ -2778,14 +2778,14 @@ describe('ParseQuery LocalDatastore', () => { q = new ParseQuery('Item'); q.skip(3); - q.withCount(true) + q.withCount(true); q.fromLocalDatastore(); result = await q.find(); expect(result.results.length).toEqual(0); expect(result.count).toEqual(3); q = new ParseQuery('Item'); - q.withCount(true) + q.withCount(true); q.skip(4); q.fromLocalDatastore(); result = await q.find(); @@ -2795,7 +2795,7 @@ describe('ParseQuery LocalDatastore', () => { q = new ParseQuery('Item'); q.limit(1); q.skip(2); - q.withCount(true) + q.withCount(true); q.fromLocalDatastore(); result = await q.find(); expect(result.results.length).toEqual(1); @@ -2804,7 +2804,7 @@ describe('ParseQuery LocalDatastore', () => { q = new ParseQuery('Item'); q.limit(1); q.skip(1); - q.withCount(true) + q.withCount(true); q.fromLocalDatastore(); result = await q.find(); expect(result.results.length).toEqual(1); @@ -2813,7 +2813,7 @@ describe('ParseQuery LocalDatastore', () => { q = new ParseQuery('Item'); q.limit(2); q.skip(1); - q.withCount(true) + q.withCount(true); q.fromLocalDatastore(); result = await q.find(); expect(result.results.length).toEqual(2); From 1b536501633a0f49e4983955d2d0c9cac79c6f00 Mon Sep 17 00:00:00 2001 From: Yuri Komlev Date: Fri, 19 Jul 2019 05:36:55 +0300 Subject: [PATCH 8/9] integration tests for default --- integration/test/ParseQueryTest.js | 35 +++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/integration/test/ParseQueryTest.js b/integration/test/ParseQueryTest.js index 87728de56..70916d0dd 100644 --- a/integration/test/ParseQueryTest.js +++ b/integration/test/ParseQueryTest.js @@ -103,7 +103,7 @@ describe('Parse Query', () => { for (let i = 0; i < 4; i++) { items.push(new TestObject({ countMe: 2})); } - await Parse.Object.saveAll(items) + await Parse.Object.saveAll(items); const query = new Parse.Query(TestObject); query.withCount(true); query.limit(2); @@ -132,6 +132,39 @@ describe('Parse Query', () => { assert.equal(count, 4); }); + it('can do query when withCount set without arguments', async () => { + const items = []; + for (let i = 0; i < 4; i++) { + items.push(new TestObject({ countMe: 2})); + } + await Parse.Object.saveAll(items); + const query = new Parse.Query(TestObject); + query.withCount(); + + const {results,count} = await query.find(); + + assert(typeof count == 'number'); + assert.equal(results.length, 4); + assert.equal(count, 4); + }); + + it('can do query when withCount undefined', async () => { + const items = []; + for (let i = 0; i < 4; i++) { + items.push(new TestObject({ countMe: 2})); + } + await Parse.Object.saveAll(items); + const query = new Parse.Query(TestObject); + let foo; + query.withCount(foo); + + const {results,count} = await query.find(); + + assert(typeof count == 'number'); + assert.equal(results.length, 4); + assert.equal(count, 4); + }); + it('can do containedIn queries with arrays', (done) => { const messageList = []; for (let i = 0; i < 4; i++) { From 789bab025e88765e635774da40ac123c2e038a69 Mon Sep 17 00:00:00 2001 From: Yuri Komlev Date: Fri, 19 Jul 2019 05:40:00 +0300 Subject: [PATCH 9/9] default to true; withJson - why not --- src/ParseQuery.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ParseQuery.js b/src/ParseQuery.js index 685a3fd75..93eceefd0 100644 --- a/src/ParseQuery.js +++ b/src/ParseQuery.js @@ -478,7 +478,7 @@ class ParseQuery { } if (json.count) { - this._count = json.count !== 0; + this._count = json.count === 1; } if (json.limit) { @@ -1506,7 +1506,7 @@ class ParseQuery { * @param {boolean} b false - disable, true - enable. * @return {Parse.Query} Returns the query, so you can chain this call. */ - withCount(includeCount: boolean): ParseQuery { + withCount(includeCount: boolean = true): ParseQuery { if (typeof includeCount !== 'boolean') { throw new Error('You can only set withCount to a boolean value'); }