From a709b04e4ada050ba23080424a4e48cf7bce101e Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sat, 9 May 2026 14:26:11 +0900 Subject: [PATCH 1/3] test(query-devtools/utils): add tests for 'array nested path' and 'primitive' cases of 'deleteNestedDataByPath' (#10673) --- .../src/__tests__/utils.test.ts | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/query-devtools/src/__tests__/utils.test.ts b/packages/query-devtools/src/__tests__/utils.test.ts index 0c1fb6ec50..26ae5a93b6 100644 --- a/packages/query-devtools/src/__tests__/utils.test.ts +++ b/packages/query-devtools/src/__tests__/utils.test.ts @@ -539,6 +539,38 @@ describe('Utils tests', () => { `) }) + describe('array nested path', () => { + it('should delete nested data inside an array correctly', () => { + const oldData = [ + { id: 1, title: 'first' }, + { id: 2, title: 'second' }, + ] + + const newData = deleteNestedDataByPath(oldData, ['1', 'title']) + + expect(newData).not.toBe(oldData) + expect(newData).toMatchInlineSnapshot(` + [ + { + "id": 1, + "title": "first", + }, + { + "id": 2, + }, + ] + `) + }) + }) + + describe('primitive', () => { + it('should return primitive data as-is when it is not an Object/Array/Map/Set', () => { + expect(deleteNestedDataByPath(42, ['x'])).toBe(42) + expect(deleteNestedDataByPath('hello', ['x'])).toBe('hello') + expect(deleteNestedDataByPath(null, ['x'])).toBe(null) + }) + }) + describe('nested data', () => { it('should delete nested items correctly', () => { /* eslint-disable cspell/spellchecker */ From a37c003ca1ecd889e23d534dc120a4eee5db690d Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sat, 9 May 2026 16:38:20 +0900 Subject: [PATCH 2/3] test(query-devtools/utils): add test for stale vs fresh rank in 'status' sort of 'sortFns' (#10674) * test(query-devtools/utils): add test for stale vs fresh rank in 'status' sort of 'sortFns' * ci: apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .../src/__tests__/utils.test.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/packages/query-devtools/src/__tests__/utils.test.ts b/packages/query-devtools/src/__tests__/utils.test.ts index 26ae5a93b6..07dff9ece4 100644 --- a/packages/query-devtools/src/__tests__/utils.test.ts +++ b/packages/query-devtools/src/__tests__/utils.test.ts @@ -1146,6 +1146,37 @@ describe('Utils tests', () => { } }) + it('should place a stale query after a fresh one when both are idle and have observers', () => { + const staleObserver = new QueryObserver(queryClient, { + queryKey: ['stale'], + staleTime: 0, + }) + const staleUnsubscribe = staleObserver.subscribe(() => {}) + const stale = queryClient.getQueryCache().find({ queryKey: ['stale'] })! + stale.setState({ + ...stale.state, + fetchStatus: 'idle', + data: 'data', + dataUpdatedAt: 200, + }) + + const fresh = buildQuery(['fresh'], { + fetchStatus: 'idle', + data: 'fresh-data', + dataUpdatedAt: 100, + }) + const freshUnsubscribe = addObserver(fresh) + + try { + expect(stale.isStale()).toBe(true) + expect(statusSort(fresh, stale)).toBe(-1) + expect(statusSort(stale, fresh)).toBe(1) + } finally { + staleUnsubscribe() + freshUnsubscribe() + } + }) + it('should fall back to "last updated" sort within the same status rank', () => { const older = buildQuery(['older'], { dataUpdatedAt: 100 }) const newer = buildQuery(['newer'], { dataUpdatedAt: 200 }) From 9963b2fc97dc5133a973db10e8eb741741adf76e Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Sat, 9 May 2026 17:59:10 +0900 Subject: [PATCH 3/3] test(query-devtools/TanstackQueryDevtools{,Panel}): add tests for setters (#10676) --- .../__tests__/TanstackQueryDevtools.test.tsx | 57 +++++++++++++++++ .../TanstackQueryDevtoolsPanel.test.tsx | 62 +++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/packages/query-devtools/src/__tests__/TanstackQueryDevtools.test.tsx b/packages/query-devtools/src/__tests__/TanstackQueryDevtools.test.tsx index 01c8969f3a..cef4475d83 100644 --- a/packages/query-devtools/src/__tests__/TanstackQueryDevtools.test.tsx +++ b/packages/query-devtools/src/__tests__/TanstackQueryDevtools.test.tsx @@ -56,4 +56,61 @@ describe('TanstackQueryDevtools', () => { expect(() => devtools.unmount()).toThrow('Devtools is not mounted') }) }) + + describe('setters', () => { + describe('before mount', () => { + it('should not throw when "setButtonPosition" is called', () => { + expect(() => devtools.setButtonPosition('top-left')).not.toThrow() + }) + + it('should not throw when "setPosition" is called', () => { + expect(() => devtools.setPosition('left')).not.toThrow() + }) + + it('should not throw when "setInitialIsOpen" is called', () => { + expect(() => devtools.setInitialIsOpen(true)).not.toThrow() + }) + + it('should not throw when "setErrorTypes" is called', () => { + expect(() => + devtools.setErrorTypes([ + { name: 'NetworkError', initializer: () => new Error('Network') }, + ]), + ).not.toThrow() + }) + + it('should not throw when "setClient" is called', () => { + expect(() => devtools.setClient(new QueryClient())).not.toThrow() + }) + + it('should not throw when "setTheme" is called', () => { + expect(() => devtools.setTheme('dark')).not.toThrow() + expect(() => devtools.setTheme('light')).not.toThrow() + expect(() => devtools.setTheme('system')).not.toThrow() + expect(() => devtools.setTheme(undefined)).not.toThrow() + }) + }) + + describe('after mount', () => { + it('should not throw when setters are called on a mounted instance', () => { + const el = document.createElement('div') + devtools.mount(el) + + try { + expect(() => devtools.setButtonPosition('top-left')).not.toThrow() + expect(() => devtools.setPosition('left')).not.toThrow() + expect(() => devtools.setInitialIsOpen(true)).not.toThrow() + expect(() => + devtools.setErrorTypes([ + { name: 'NetworkError', initializer: () => new Error('Network') }, + ]), + ).not.toThrow() + expect(() => devtools.setClient(new QueryClient())).not.toThrow() + expect(() => devtools.setTheme('dark')).not.toThrow() + } finally { + devtools.unmount() + } + }) + }) + }) }) diff --git a/packages/query-devtools/src/__tests__/TanstackQueryDevtoolsPanel.test.tsx b/packages/query-devtools/src/__tests__/TanstackQueryDevtoolsPanel.test.tsx index 1993ef6779..f7407ad5ff 100644 --- a/packages/query-devtools/src/__tests__/TanstackQueryDevtoolsPanel.test.tsx +++ b/packages/query-devtools/src/__tests__/TanstackQueryDevtoolsPanel.test.tsx @@ -56,4 +56,66 @@ describe('TanstackQueryDevtoolsPanel', () => { expect(() => devtools.unmount()).toThrow('Devtools is not mounted') }) }) + + describe('setters', () => { + describe('before mount', () => { + it('should not throw when "setButtonPosition" is called', () => { + expect(() => devtools.setButtonPosition('top-left')).not.toThrow() + }) + + it('should not throw when "setPosition" is called', () => { + expect(() => devtools.setPosition('left')).not.toThrow() + }) + + it('should not throw when "setInitialIsOpen" is called', () => { + expect(() => devtools.setInitialIsOpen(true)).not.toThrow() + }) + + it('should not throw when "setErrorTypes" is called', () => { + expect(() => + devtools.setErrorTypes([ + { name: 'NetworkError', initializer: () => new Error('Network') }, + ]), + ).not.toThrow() + }) + + it('should not throw when "setClient" is called', () => { + expect(() => devtools.setClient(new QueryClient())).not.toThrow() + }) + + it('should not throw when "setOnClose" is called', () => { + expect(() => devtools.setOnClose(() => {})).not.toThrow() + }) + + it('should not throw when "setTheme" is called', () => { + expect(() => devtools.setTheme('dark')).not.toThrow() + expect(() => devtools.setTheme('light')).not.toThrow() + expect(() => devtools.setTheme('system')).not.toThrow() + expect(() => devtools.setTheme(undefined)).not.toThrow() + }) + }) + + describe('after mount', () => { + it('should not throw when setters are called on a mounted instance', () => { + const el = document.createElement('div') + devtools.mount(el) + + try { + expect(() => devtools.setButtonPosition('top-left')).not.toThrow() + expect(() => devtools.setPosition('left')).not.toThrow() + expect(() => devtools.setInitialIsOpen(true)).not.toThrow() + expect(() => + devtools.setErrorTypes([ + { name: 'NetworkError', initializer: () => new Error('Network') }, + ]), + ).not.toThrow() + expect(() => devtools.setClient(new QueryClient())).not.toThrow() + expect(() => devtools.setOnClose(() => {})).not.toThrow() + expect(() => devtools.setTheme('dark')).not.toThrow() + } finally { + devtools.unmount() + } + }) + }) + }) })