Skip to content

Commit

Permalink
✨ Add unset on navigators (#318)
Browse files Browse the repository at this point in the history
  • Loading branch information
nlepage committed Jan 22, 2019
1 parent efb8c76 commit 1dd4a21
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 22 deletions.
8 changes: 4 additions & 4 deletions packages/immutadot/src/core/unset.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { apply } from 'path/apply'

const unsetOperation = (obj, prop) => { delete obj[prop] }
import { curry } from './curry'
import { nav } from 'nav/nav'
import { toPath } from '@immutadot/parser'

/**
* Removes the property at <code>path</code> of <code>object</code>.
Expand All @@ -12,6 +12,6 @@ const unsetOperation = (obj, prop) => { delete obj[prop] }
* @example unset({ nested: { prop: 'value' } }, 'nested.prop') // => { nested: {} }
* @since 1.0.0
*/
const unset = apply(unsetOperation)
const unset = curry((obj, path) => nav(toPath(path))(obj).unset(), { fixedArity: true })

export { unset }
47 changes: 47 additions & 0 deletions packages/immutadot/src/core/unset.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/* eslint-env jest */
import { immutaTest } from 'test.utils'
import { unset } from 'core'

describe('core.unset', () => {

it('should unset a prop', () => {
immutaTest({
nested: { prop: 'initial' },
Expand All @@ -15,4 +17,49 @@ describe('core.unset', () => {
return output
})
})

it('should unset an index', () => {
immutaTest({
nested: { arr: [1, 2, 3] },
other: {},
}, ['nested.arr.1'], input => {
const output = unset(input, 'nested.arr[1]')
expect(output).toEqual({
nested: { arr: [1, , 3] }, // eslint-disable-line no-sparse-arrays
other: {},
})
return output
})
})

it('should unset several props', () => {
immutaTest({
nested: {
prop1: 'initial1',
prop2: 'initial2',
},
other: {},
}, ['nested.prop1', 'nested.prop2'], input => {
const output = unset(input, 'nested.{prop1,prop2}')
expect(output).toEqual({
nested: {},
other: {},
})
return output
})
})

it('should unset a slice', () => {
immutaTest({
nested: { arr: [1, 2, 3, 4] },
other: {},
}, ['nested.arr.1', 'nested.arr.2'], input => {
const output = unset(input, 'nested.arr[1:3]')
expect(output).toEqual({
nested: { arr: [1, , , 4] }, // eslint-disable-line no-sparse-arrays
other: {},
})
return output
})
})
})
4 changes: 4 additions & 0 deletions packages/immutadot/src/nav/baseNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@ export class BaseNav {
this.value = value
this._next = next
}

get final() {
return false
}
}
21 changes: 21 additions & 0 deletions packages/immutadot/src/nav/finalNav.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class FinalNav {
constructor(value) {
this.value = value
}

get() {
return this.value
}

update(updater) {
return updater(this.value)
}

get final() {
return true
}
}

export function finalNav(value) {
return new FinalNav(value)
}
9 changes: 9 additions & 0 deletions packages/immutadot/src/nav/indexNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ class IndexNav extends ArrayNav {
copy[this.index] = this.next.update(updater)
return copy
}

unset() {
const copy = this.copy()
if (this.next.final)
delete copy[this.index]
else
copy[this.index] = this.next.unset()
return copy
}
}

export function indexNav(index, next) {
Expand Down
19 changes: 1 addition & 18 deletions packages/immutadot/src/nav/nav.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { allProps, index, list, prop, slice } from '@immutadot/parser/consts'
import { finalNav } from './finalNav'
import { indexNav } from './indexNav'
import { propNav } from './propNav'
import { propsNav } from './propsNav'
Expand All @@ -21,21 +22,3 @@ function toNav(type) {
default: throw TypeError(type)
}
}

class FinalNav {
constructor(value) {
this.value = value
}

get() {
return this.value
}

update(updater) {
return updater(this.value)
}
}

function finalNav(value) {
return new FinalNav(value)
}
9 changes: 9 additions & 0 deletions packages/immutadot/src/nav/propNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ class PropNav extends ObjectNav {
copy[this.key] = this.next.update(updater)
return copy
}

unset() {
const copy = this.copy()
if (this.next.final)
delete copy[this.key]
else
copy[this.key] = this.next.unset()
return copy
}
}

export function propNav(key, next) {
Expand Down
14 changes: 14 additions & 0 deletions packages/immutadot/src/nav/propsNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ class PropsNav extends ObjectNav {
for (const key of keys) copy[key] = _next(value[key]).update(updater)
return copy
}

unset() {
const { _next, keys, value } = this

const copy = this.copy()
for (const key of keys) {
const next = _next(value[key])
if (next.final)
delete copy[key]
else
copy[key] = next.unset()
}
return copy
}
}

export function propsNav(keys, next) {
Expand Down
14 changes: 14 additions & 0 deletions packages/immutadot/src/nav/sliceNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ class SliceNav extends ArrayNav {
for (const index of range) copy[index] = _next(value[index]).update(updater)
return copy
}

unset() {
const { _next, value, range } = this

const copy = this.copy()
for (const index of range) {
const next = _next(value[index])
if (next.final)
delete copy[index]
else
copy[index] = next.unset()
}
return copy
}
}

export function sliceNav(bounds, next) {
Expand Down

0 comments on commit 1dd4a21

Please sign in to comment.