From 388a089035f31ba1170a874cfc414f6530516925 Mon Sep 17 00:00:00 2001 From: Flavio Corpa Date: Sun, 4 Oct 2020 22:41:35 +0200 Subject: [PATCH] fix(functions): add isNil and do not depend on nullish coallesce --- .babelrc | 1 - __tests__/functions.test.js | 12 +++++++++++- package.json | 1 - src/Lens.js | 4 ++-- src/Optional.js | 6 +++--- src/functions.js | 2 ++ 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/.babelrc b/.babelrc index 7b30f86..7521eb0 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,4 @@ { - "plugins": ["@babel/plugin-proposal-nullish-coalescing-operator"], "env": { "test": { "plugins": ["@babel/plugin-transform-modules-commonjs"] diff --git a/__tests__/functions.test.js b/__tests__/functions.test.js index 7c93d59..9dd2d04 100644 --- a/__tests__/functions.test.js +++ b/__tests__/functions.test.js @@ -1,4 +1,4 @@ -import { curry, get, set, setIndex, toUpper } from '../src/functions' +import { curry, get, isNil, set, setIndex, toUpper } from '../src/functions' const obj = { foo: 'bar' } const arr = [1, 2, 3] @@ -15,6 +15,16 @@ describe('Function Operators', () => { expect(toUpper('yeah!')).toBe('YEAH!') }) + test('isNil -> should work better than falsy values', () => { + expect(isNil(null)).toBe(true) + expect(isNil(undefined)).toBe(true) + expect(isNil(0)).toBe(false) + expect(isNil(-0)).toBe(false) + expect(isNil('')).toBe(false) + expect(isNil(NaN)).toBe(false) + expect(isNil(false)).toBe(false) + }) + test('get -> should retrieve the value of the property if it exists', () => { expect(get('foo')(obj)).toBe(obj.foo) }) diff --git a/package.json b/package.json index a5fbd59..9dd3ecf 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "@babel/core": "^7.11.6", "@babel/eslint-parser": "^7.11.5", "@babel/eslint-plugin": "^7.11.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", "@babel/plugin-transform-modules-commonjs": "^7.10.4", "@commitlint/cli": "latest", "@commitlint/config-conventional": "latest", diff --git a/src/Lens.js b/src/Lens.js index 5136ff7..695d907 100644 --- a/src/Lens.js +++ b/src/Lens.js @@ -1,5 +1,5 @@ import { fold } from './Fold' -import { curry, get, set, setIndex } from './functions' +import { curry, get, isNil, set, setIndex } from './functions' import { getter } from './Getter' import { isNotFound, notFound } from './notFound' import { optional } from './Optional' @@ -68,7 +68,7 @@ export const mustBePresent = key => lens(get(key), set(key)) // alter : String → Lens (Maybe s) (Maybe a) export const alter = key => lens( - obj => (isNotFound(obj) ? notFound : obj[key] ?? notFound), + obj => (isNotFound(obj) || isNil(obj[key]) ? notFound : obj[key]), (val, obj) => { if (isNotFound(val)) { if (typeof obj === 'object') { diff --git a/src/Optional.js b/src/Optional.js index 15a44dc..c36428e 100644 --- a/src/Optional.js +++ b/src/Optional.js @@ -1,6 +1,6 @@ import { OpticCreationError } from './errors' import { fold } from './Fold' -import { curry, setIndex } from './functions' +import { curry, isNil, setIndex } from './functions' import { isNotFound, notFound, notFoundToList } from './notFound' import { partialGetter } from './PartialGetter' import { setter } from './Setter' @@ -56,14 +56,14 @@ export const optional = curry((preview, set) => new Optional(preview, set)) // optionalProp : String → Optional s a export const optionalProp = key => optional( - obj => obj[key] ?? notFound, + obj => (isNil(obj[key]) ? notFound : obj[key]), (val, obj) => (obj[key] ? { ...obj, [key]: val } : obj), ) // optionalIx : Number → Optional s a export const optionalIx = index => optional( - obj => obj[index] ?? notFound, + obj => (isNil(obj[index]) ? notFound : obj[index]), (val, obj) => (obj[index] ? setIndex(index, val, obj) : obj), ) diff --git a/src/functions.js b/src/functions.js index 46158a3..f966f98 100644 --- a/src/functions.js +++ b/src/functions.js @@ -23,3 +23,5 @@ export const setIndex = curry((index, val, array) => array.map((v, i) => (i == i // toUpper : String -> String export const toUpper = str => str.toUpperCase() + +export const isNil = x => x === null || x === undefined