From e4f45168158a1b2b3717ea1ba45713b27ad2b381 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Mon, 28 Jun 2021 15:37:25 +0300 Subject: [PATCH] arrayConnection: return all elements if cursors are on the outside Fixes #51 --- .../__tests__/arrayConnection-test.js | 32 +++++++++++-------- src/connection/arrayConnection.js | 20 +++++++++--- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/connection/__tests__/arrayConnection-test.js b/src/connection/__tests__/arrayConnection-test.js index 3cd867f..a20eaed 100644 --- a/src/connection/__tests__/arrayConnection-test.js +++ b/src/connection/__tests__/arrayConnection-test.js @@ -2,6 +2,7 @@ import { describe, it } from 'mocha'; import { expect } from 'chai'; import { + offsetToCursor, connectionFromArray, connectionFromArraySlice, connectionFromPromisedArray, @@ -289,19 +290,24 @@ describe('connectionFromArray()', () => { }); it('returns all elements if cursors are on the outside', () => { - const c = connectionFromArray(arrayABCDE, { - before: 'YXJyYXljb25uZWN0aW9uOjY=' /* offsetToCursor(6) */, - after: 'YXJyYXljb25uZWN0aW9uOi0x' /* offsetToCursor(-1) */, - }); - expect(c).to.deep.equal({ - edges: [edgeA, edgeB, edgeC, edgeD, edgeE], - pageInfo: { - startCursor: cursorA, - endCursor: cursorE, - hasPreviousPage: false, - hasNextPage: false, - }, - }); + function expectAllEdges(args: { before?: string, after?: string }) { + const c = connectionFromArray(arrayABCDE, args); + expect(c).to.deep.equal({ + edges: [edgeA, edgeB, edgeC, edgeD, edgeE], + pageInfo: { + startCursor: cursorA, + endCursor: cursorE, + hasPreviousPage: false, + hasNextPage: false, + }, + }); + } + + expectAllEdges({ before: offsetToCursor(6) }); + expectAllEdges({ before: offsetToCursor(-1) }); + + expectAllEdges({ after: offsetToCursor(-1) }); + expectAllEdges({ after: offsetToCursor(6) }); }); it('returns no elements if cursors cross', () => { diff --git a/src/connection/arrayConnection.js b/src/connection/arrayConnection.js index 1c8b15c..4f0681e 100644 --- a/src/connection/arrayConnection.js +++ b/src/connection/arrayConnection.js @@ -54,11 +54,21 @@ export function connectionFromArraySlice( const { after, before, first, last } = args; const { sliceStart, arrayLength } = meta; const sliceEnd = sliceStart + arraySlice.length; - const beforeOffset = getOffsetWithDefault(before, arrayLength); + + let startOffset = Math.max(sliceStart, 0); + let endOffset = Math.min(sliceEnd, arrayLength); + console.log(startOffset, endOffset); + const afterOffset = getOffsetWithDefault(after, -1); + if (0 <= afterOffset && afterOffset < arrayLength) { + startOffset = Math.max(startOffset, afterOffset + 1); + } + + const beforeOffset = getOffsetWithDefault(before, endOffset); + if (0 <= beforeOffset && beforeOffset < arrayLength) { + endOffset = Math.min(endOffset, beforeOffset); + } - let startOffset = Math.max(sliceStart - 1, afterOffset, -1) + 1; - let endOffset = Math.min(sliceEnd, beforeOffset, arrayLength); if (typeof first === 'number') { if (first < 0) { throw new Error('Argument "first" must be a non-negative integer'); @@ -76,8 +86,8 @@ export function connectionFromArraySlice( // If supplied slice is too large, trim it down before mapping over it. const slice = arraySlice.slice( - Math.max(startOffset - sliceStart, 0), - arraySlice.length - (sliceEnd - endOffset), + startOffset - sliceStart, + endOffset - sliceStart, ); const edges = slice.map((value, index) => ({