Skip to content

Commit

Permalink
fixup! feat(internal): deepMapObject
Browse files Browse the repository at this point in the history
  • Loading branch information
mhofman committed Sep 5, 2024
1 parent acb2755 commit 70db003
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 52 deletions.
7 changes: 7 additions & 0 deletions packages/internal/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ const deepMapObjectInternal = (value, name, container, mapper) => {
};

/**
* Traverses a record object structure deeply, calling a replacer for each
* enumerable string property values of an object. If none of the values are
* changed, the original object is used as-is, maintaining its identity.
*
* When an object is found as a property value, the replacer is first called on
* it. If not replaced, the object is then traversed.
*
* @param {object} obj
* @param {(value: any, name: string, record: object) => any} mapper
* @returns {object}
Expand Down
103 changes: 51 additions & 52 deletions packages/internal/test/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,20 @@ test('deeplyFulfilledObject', async t => {
});
});

/**
* @typedef {object} DeepMapObjectTestParams
* @property {any} input
* @property {[any, any][]} replacements
* @property {string[][]} unchangedPaths
* @property {any} [expectedOutput]
*/

/** @type {import('ava').Macro<[DeepMapObjectTestParams]>} */
const deepMapObjectTest = test.macro({
/**
* @param {import('ava').ExecutionContext} t
* @param {any} input
* @param {[any, any][]} replacements
* @param {string[][]} unchangedPaths
* @param {any} [expectedOutput]
*/
exec(t, input, replacements, unchangedPaths, expectedOutput) {
title(providedTitle, { input }) {
return `deepMapObject - ${providedTitle || JSON.stringify(input)}`;
},
exec(t, { input, replacements, unchangedPaths, expectedOutput }) {
const replacementMap = new Map(replacements);
const output = deepMapObject(input, val =>
replacementMap.has(val) ? replacementMap.get(val) : val,
Expand All @@ -65,64 +70,58 @@ const deepMapObjectTest = test.macro({
t.deepEqual(output, expectedOutput);
}
},
title(providedTitle, input) {
return `deepMapObject - ${providedTitle || JSON.stringify(input)}`;
},
});

test('identity', deepMapObjectTest, { foo: 42 }, [], [[]]);
test(
'non object',
deepMapObjectTest,
'not an object',
[['not an object', 'not replaced']],
[[]],
'not an object',
);
test(
'one level deep',
deepMapObjectTest,
{ replace: 'replace me', notChanged: {} },
[['replace me', 'replaced']],
[['notChanged']],
{ replace: 'replaced', notChanged: {} },
);
test('identity', deepMapObjectTest, {
input: { foo: 42 },
replacements: [],
unchangedPaths: [[]],
});
test('non object', deepMapObjectTest, {
input: 'not an object',
replacements: [['not an object', 'not replaced']],
unchangedPaths: [[]],
expectedOutput: 'not an object',
});
test('one level deep', deepMapObjectTest, {
input: { replace: 'replace me', notChanged: {} },
replacements: [['replace me', 'replaced']],
unchangedPaths: [['notChanged']],
expectedOutput: { replace: 'replaced', notChanged: {} },
});

const testRecord = { maybeReplace: 'replace me' };
test(
'replace first before deep map',
deepMapObjectTest,
{ replace: testRecord, notChanged: {} },
[
test('replace first before deep map', deepMapObjectTest, {
input: { replace: testRecord, notChanged: {} },
replacements: [
[testRecord, { different: 'something new' }],
['replace me', 'should not be replaced'],
],
[['notChanged']],
{ replace: { different: 'something new' }, notChanged: {} },
);
unchangedPaths: [['notChanged']],
expectedOutput: { replace: { different: 'something new' }, notChanged: {} },
});

test(
'not mapping container',
deepMapObjectTest,
testRecord,
[
test('not mapping top level container', deepMapObjectTest, {
input: testRecord,
replacements: [
[testRecord, { different: 'should not be different' }],
['replace me', 'replaced'],
],
[],
{ maybeReplace: 'replaced' },
);
test(
'deep mapping',
deepMapObjectTest,
{
unchangedPaths: [],
expectedOutput: { maybeReplace: 'replaced' },
});
test('deep mapping', deepMapObjectTest, {
input: {
one: { two: { three: 'replace me' }, notChanged: {} },
another: 'replace me',
},
[['replace me', 'replaced']],
[['one', 'notChanged']],
{ one: { two: { three: 'replaced' }, notChanged: {} }, another: 'replaced' },
);
replacements: [['replace me', 'replaced']],
unchangedPaths: [['one', 'notChanged']],
expectedOutput: {
one: { two: { three: 'replaced' }, notChanged: {} },
another: 'replaced',
},
});

test('makeMeasureSeconds', async t => {
const times = [1000.25, 2000.75, NaN];
Expand Down

0 comments on commit 70db003

Please sign in to comment.