From 2e4b8920dc49804d83231950e253f98deb86a4e3 Mon Sep 17 00:00:00 2001 From: Achille Urbain <7644970+WaldoJeffers@users.noreply.github.com> Date: Sat, 20 Jul 2019 19:00:28 +0200 Subject: [PATCH] fix: Make slice compatible with all types of collections --- __tests__/slice.js | 106 +++++++++++++++++++++++++++++++++++++++++++-- src/slice.js | 6 ++- 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/__tests__/slice.js b/__tests__/slice.js index e43ccc7..f8cadf9 100644 --- a/__tests__/slice.js +++ b/__tests__/slice.js @@ -1,9 +1,109 @@ const slice = require('../src/slice') +const object = { + 'hello': 'Hello', + 'bonsoir': 'Bonsoir', + 'elliott': 'Elliot', + 'world': 'World', +} +const map = new Map(Object.entries(object)) +const array = Object.values(object) +const set = new Set(array) +const newObject = { bonsoir: 'Bonsoir', elliott: 'Elliot' } +const newMap = new Map(Object.entries(newObject)) +const newArray = Object.values(newObject) +const newSet = new Set(newArray) + + describe('slice', () => { - it('should retrieve a part of the input array', () => { - const words = ['Hello', 'Bonsoir', 'Elliot', 'World'] - expect(slice(1, 3, words)).toEqual(['Bonsoir', 'Elliot']) + describe('it should retrieve a slice of the input collection', () => { + it('should retrieve a slice of the input array', () => { + expect(slice(1, 3, array)).toEqual(newArray) + }) + + it('should retrieve a slice of the input set', () => { + expect(slice(1, 3, set)).toEqual(newSet) + }) + + it('should retrieve a slice of the input map', () => { + expect(slice(1, 3, map)).toEqual(newMap) + }) + + it('should retrieve a slice of the input object', () => { + expect(slice(1, 3, object)).toEqual(newObject) + }) + }) + + describe('it should start from the end if the first parameter is negative', () => { + it('should retrieve a slice of the input array', () => { + expect(slice(-3, 3, array)).toEqual(newArray) + }) + + it('should retrieve a slice of the input set', () => { + expect(slice(-3, 3, set)).toEqual(newSet) + }) + + it('should retrieve a slice of the input map', () => { + expect(slice(-3, 3, map)).toEqual(newMap) + }) + + it('should retrieve a slice of the input object', () => { + expect(slice(-3, 3, object)).toEqual(newObject) + }) + }) + + describe('it should start from the end if the second parameter is negative', () => { + it('should retrieve a slice of the input array', () => { + expect(slice(1, -1, array)).toEqual(newArray) + }) + + it('should retrieve a slice of the input set', () => { + expect(slice(1, -1, set)).toEqual(newSet) + }) + + it('should retrieve a slice of the input map', () => { + expect(slice(1, -1, map)).toEqual(newMap) + }) + + it('should retrieve a slice of the input object', () => { + expect(slice(1, -1, object)).toEqual(newObject) + }) + }) + + describe('it should work if both start and end are negative', () => { + it('should retrieve a slice of the input array', () => { + expect(slice(-3, -1, array)).toEqual(newArray) + }) + + it('should retrieve a slice of the input set', () => { + expect(slice(-3, -1, set)).toEqual(newSet) + }) + + it('should retrieve a slice of the input map', () => { + expect(slice(-3, -1, map)).toEqual(newMap) + }) + + it('should retrieve a slice of the input object', () => { + expect(slice(-3, -1, object)).toEqual(newObject) + }) + }) + + describe('it should return an empty collection if no results are found', () => { + it('should retrieve a slice of the input array', () => { + expect(slice(-3, 1, array)).toEqual([]) + }) + + it('should retrieve a slice of the input set', () => { + expect(slice(-3, 1, set)).toEqual(new Set()) + }) + + it('should retrieve a slice of the input map', () => { + expect(slice(-3, 1, map)).toEqual(new Map([])) + }) + + it('should retrieve a slice of the input object', () => { + expect(slice(-3, 1, object)).toEqual({}) + }) }) it('should be a pure function', () => { diff --git a/src/slice.js b/src/slice.js index e07cb00..0e6c682 100644 --- a/src/slice.js +++ b/src/slice.js @@ -1,5 +1,9 @@ const curry = require('./curry') +const dump = require('./dump') +const length = require('./length') -const slice = (start, end, array) => array.slice(start, end) +const sliceTransformer = (start, end) => reducer => (acc, item, key, collection, index) => index >= start && index < end ? reducer(acc, item, key, collection, index) : acc + +const slice = (start, end, collection) => typeof collection.__proto__.slice === 'function' ? collection.slice(start, end) : dump(sliceTransformer(start < 0 ? start + length(collection) : start, end < 0 ? end + length(collection) : end), collection) module.exports = curry(slice)