Skip to content

Commit

Permalink
fix: replaceDeepEqual special case for non-plain arrays (#3669)
Browse files Browse the repository at this point in the history
* Fix case where replaceDeepEqual was returning incorrect value for non-plain arrays

* fix pr comments
  • Loading branch information
jxom authored Jun 6, 2022
1 parent 97484dc commit a46ba65
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
18 changes: 18 additions & 0 deletions src/core/tests/utils.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
matchMutation,
scheduleMicrotask,
sleep,
isPlainArray,
} from '../utils'
import { Mutation } from '../mutation'
import { createQueryClient } from '../../tests/utils'
Expand Down Expand Up @@ -56,6 +57,16 @@ describe('core/utils', () => {
})
})

describe('isPlainArray', () => {
it('should return `true` for plain arrays', () => {
expect(isPlainArray([1, 2])).toEqual(true)
})

it('should return `false` for non plain arrays', () => {
expect(isPlainArray(Object.assign([1, 2], { a: 'b' }))).toEqual(false)
})
})

describe('partialDeepEqual', () => {
it('should return `true` if a includes b', () => {
const a = { a: { b: 'b' }, c: 'c', d: [{ d: 'd ' }] }
Expand Down Expand Up @@ -258,6 +269,13 @@ describe('core/utils', () => {
expect(result[1]).toBe(prev[1])
})

it('should support objects which are not plain arrays', () => {
const prev = Object.assign([1, 2], { a: { b: 'b' }, c: 'c' })
const next = Object.assign([1, 2], { a: { b: 'b' }, c: 'c' })
const result = replaceEqualDeep(prev, next)
expect(result).toBe(next)
})

it('should replace all parent objects if some nested value changes', () => {
const prev = {
todo: { id: '1', meta: { createdAt: 0 }, state: { done: false } },
Expand Down
6 changes: 5 additions & 1 deletion src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ export function replaceEqualDeep(a: any, b: any): any {
return a
}

const array = Array.isArray(a) && Array.isArray(b)
const array = isPlainArray(a) && isPlainArray(b)

if (array || (isPlainObject(a) && isPlainObject(b))) {
const aSize = array ? a.length : Object.keys(a).length
Expand Down Expand Up @@ -355,6 +355,10 @@ export function shallowEqualObjects<T>(a: T, b: T): boolean {
return true
}

export function isPlainArray(value: unknown) {
return Array.isArray(value) && value.length === Object.keys(value).length
}

// Copied from: https://github.com/jonschlinkert/is-plain-object
export function isPlainObject(o: any): o is Object {
if (!hasObjectPrototype(o)) {
Expand Down

0 comments on commit a46ba65

Please sign in to comment.