Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compat/array/invokeMap.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

const actual = invokeMap(
array,
function (this: any, left: string, right: string) {

Check warning on line 31 in src/compat/array/invokeMap.spec.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
return left + this.toUpperCase() + right;
},
'(',
Expand Down Expand Up @@ -162,7 +162,7 @@
};

const aEmptyDotC = invokeMap([objectWithEmptyPart], 'a..c');
expect(aEmptyDotC[0]).toBeUndefined();
expect(aEmptyDotC[0]).toBe(objectWithEmptyPart.a['']);
});

it('should match the type of lodash', () => {
Expand Down
4 changes: 4 additions & 0 deletions src/compat/object/get.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

it(`should get symbol keyed property values`, () => {
const symbol = Symbol('a');
const object: any = {};

Check warning on line 52 in src/compat/object/get.spec.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
object[symbol] = 1;

expect(get(object, symbol)).toBe(1);
Expand Down Expand Up @@ -157,11 +157,15 @@
it('should prevent prototype pollution by returning defaultValue for __proto__ access', () => {
expect(get({ ['__proto__']: {} }, '__proto__', 'defaultValue')).toBe('defaultValue');
expect(get({ ['__proto__']: {} }, ['__proto__'], 'defaultValue')).toBe('defaultValue');
expect(get({ ['__proto__']: {} }, { toString: () => '__proto__' } as any, 'defaultValue')).toBe('defaultValue');

Check warning on line 160 in src/compat/object/get.spec.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
});

it('should return defaultValue when property value is undefined', () => {
const object = { '-0': undefined };
expect(get(object, Object(-0), 'defaultValue')).toBe('defaultValue');
});

it('should read empty-string keys produced by consecutive dots', () => {
expect(get({ a: { '': { b: 1 } } }, 'a..b')).toBe(1);
});
});
12 changes: 12 additions & 0 deletions src/compat/util/toPath.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ describe('toPath function', () => {
expect(result).toEqual(['a', '', 'b']);
});

it('keeps empty segments for consecutive dots', () => {
expect(toPath('a..b')).toEqual(['a', '', 'b']);
expect(toPath('a...b')).toEqual(['a', '', '', 'b']);
expect(toPath('..a')).toEqual(['', '', 'a']);
expect(toPath('a.b..c.d')).toEqual(['a', 'b', '', 'c', 'd']);
});

it('keeps a trailing empty segment for a trailing dot', () => {
expect(toPath('a.')).toEqual(['a', '']);
expect(toPath('a.b.')).toEqual(['a', 'b', '']);
});

it('should match the type of lodash', () => {
expectTypeOf(toPath).toEqualTypeOf<typeof toPathLodash>();
});
Expand Down
11 changes: 9 additions & 2 deletions src/compat/util/toPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* toPath('') // Returns []
* toPath('.a[b].c.d[e]["f.g"].h') // Returns ['', 'a', 'b', 'c', 'd', 'e', 'f.g', 'h']
*/
export function toPath(deepKey: any): string[] {

Check warning on line 21 in src/compat/util/toPath.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (Array.isArray(deepKey)) {
// @types/lodash defines this as string[], but lodash itself returns (string | symbol)[]
return deepKey.map(toKey) as string[];
Expand All @@ -40,10 +40,10 @@
let quoteChar = '';
let bracket = false;

// Leading dot
// Leading dot. Record the empty segment that precedes it, but leave the dot for the
// main loop so it is still treated as a separator (e.g. '..a' -> ['', '', 'a']).
if (deepKey.charCodeAt(0) === 46) {
result.push('');
index++;
}

while (index < length) {
Expand Down Expand Up @@ -85,6 +85,13 @@
result.push(key);
key = '';
}
// A dot that is directly followed by another dot or the end of the string
// separates an empty segment, matching lodash (e.g. 'a..b' -> ['a', '', 'b'],
// 'a.' -> ['a', '']).
const next = deepKey[index + 1];
if (next === undefined || next === '.') {
result.push('');
}
} else {
key += char;
}
Expand Down