Skip to content

Commit

Permalink
Validate the input object
Browse files Browse the repository at this point in the history
Closes #15
  • Loading branch information
sindresorhus committed Jun 15, 2019
1 parent d35fa2d commit 5c6203e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 15 deletions.
25 changes: 16 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
'use strict';

const isObject = value => typeof value === 'object' && value !== null;

// Customized for this use-case
const isObject = value =>
typeof value === 'object' &&
value !== null &&
const isObjectCustom = value =>
isObject(value) &&
!(value instanceof RegExp) &&
!(value instanceof Error) &&
!(value instanceof Date);

const mapObject = (object, fn, options, isSeen = new WeakMap()) => {
const mapObject = (object, mapper, options, isSeen = new WeakMap()) => {
options = {
deep: false,
target: {},
Expand All @@ -24,18 +25,18 @@ const mapObject = (object, fn, options, isSeen = new WeakMap()) => {
const {target} = options;
delete options.target;

const mapArray = array => array.map(element => isObject(element) ? mapObject(element, fn, options, isSeen) : element);
const mapArray = array => array.map(element => isObjectCustom(element) ? mapObject(element, mapper, options, isSeen) : element);
if (Array.isArray(object)) {
return mapArray(object);
}

for (const [key, value] of Object.entries(object)) {
let [newKey, newValue] = fn(key, value, object);
let [newKey, newValue] = mapper(key, value, object);

if (options.deep && isObject(newValue)) {
if (options.deep && isObjectCustom(newValue)) {
newValue = Array.isArray(newValue) ?
mapArray(newValue) :
mapObject(newValue, fn, options, isSeen);
mapObject(newValue, mapper, options, isSeen);
}

target[newKey] = newValue;
Expand All @@ -44,4 +45,10 @@ const mapObject = (object, fn, options, isSeen = new WeakMap()) => {
return target;
};

module.exports = mapObject;
module.exports = (object, mapper, options) => {
if (!isObject(object)) {
throw new TypeError(`Expected an object, got \`${object}\` (${typeof object})`);
}

return mapObject(object, mapper, options);
};
18 changes: 12 additions & 6 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ test('deep option', t => {
]
};

const fn = (key, value) => [key, typeof value === 'number' ? value * 2 : value];
const actual = mapObject(object, fn, {deep: true});
const mapper = (key, value) => [key, typeof value === 'number' ? value * 2 : value];
const actual = mapObject(object, mapper, {deep: true});
t.deepEqual(actual, expected);
});

Expand Down Expand Up @@ -74,8 +74,8 @@ test('nested arrays', t => {
]
};

const fn = (key, value) => [key, typeof value === 'number' ? value * 2 : value];
const actual = mapObject(object, fn, {deep: true});
const mapper = (key, value) => [key, typeof value === 'number' ? value * 2 : value];
const actual = mapObject(object, mapper, {deep: true});
t.deepEqual(actual, expected);
});

Expand All @@ -90,8 +90,8 @@ test('handles circular references', t => {
object.array2 = object.array;
object.array.push(object);

const fn = (key, value) => [key.toUpperCase(), value];
const actual = mapObject(object, fn, {deep: true});
const mapper = (key, value) => [key.toUpperCase(), value];
const actual = mapObject(object, mapper, {deep: true});

const expected = {
ONE: 1,
Expand All @@ -105,3 +105,9 @@ test('handles circular references', t => {

t.deepEqual(actual, expected);
});

test('validates input', t => {
t.throws(() => {
mapObject(1, () => {});
}, TypeError);
});

0 comments on commit 5c6203e

Please sign in to comment.