From 972422d386743e0ad3f435a1f43e7d2af55e78b8 Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Thu, 23 Apr 2020 21:21:10 +0200 Subject: [PATCH 1/6] popping debug nodes --- exchanges/graphcache/src/helpers/help.ts | 2 ++ exchanges/graphcache/src/operations/query.ts | 18 ++++++++++++++---- exchanges/graphcache/src/operations/shared.ts | 6 +++++- exchanges/graphcache/src/operations/write.ts | 17 ++++++++++++++++- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/exchanges/graphcache/src/helpers/help.ts b/exchanges/graphcache/src/helpers/help.ts index e6bb146e24..39a6004079 100644 --- a/exchanges/graphcache/src/helpers/help.ts +++ b/exchanges/graphcache/src/helpers/help.ts @@ -32,6 +32,8 @@ const cache = new Set(); export const currentDebugStack: string[] = []; +export const popDebugNode = () => currentDebugStack.pop(); + export const pushDebugNode = (typename: void | string, node: DebugNode) => { let identifier = ''; if (node.kind === Kind.INLINE_FRAGMENT) { diff --git a/exchanges/graphcache/src/operations/query.ts b/exchanges/graphcache/src/operations/query.ts index 7807b1a9c4..331fb66b89 100644 --- a/exchanges/graphcache/src/operations/query.ts +++ b/exchanges/graphcache/src/operations/query.ts @@ -34,7 +34,7 @@ import { } from '../store'; import * as InMemoryData from '../store/data'; -import { warn, pushDebugNode } from '../helpers/help'; +import { warn, pushDebugNode, popDebugNode } from '../helpers/help'; import { Context, @@ -94,6 +94,10 @@ export const read = ( ? readRoot(ctx, rootKey, rootSelect, data) : readSelection(ctx, rootKey, rootSelect, data); + if (process.env.NODE_ENV !== 'production') { + popDebugNode(); + } + return { dependencies: getCurrentDependencies(), partial: data === undefined ? false : ctx.partial, @@ -209,9 +213,15 @@ export const readFragment = ( entityKey ); - return ( - readSelection(ctx, entityKey, getSelectionSet(fragment), {} as Data) || null - ); + const result = + readSelection(ctx, entityKey, getSelectionSet(fragment), {} as Data) || + null; + + if (process.env.NODE_ENV !== 'production') { + popDebugNode(); + } + + return result; }; const readSelection = ( diff --git a/exchanges/graphcache/src/operations/shared.ts b/exchanges/graphcache/src/operations/shared.ts index da7c8f4771..30e5992c70 100644 --- a/exchanges/graphcache/src/operations/shared.ts +++ b/exchanges/graphcache/src/operations/shared.ts @@ -7,7 +7,7 @@ import { SelectionSet, isFieldNode, } from '../ast'; -import { warn, pushDebugNode } from '../helpers/help'; +import { warn, pushDebugNode, popDebugNode } from '../helpers/help'; import { hasField } from '../store/data'; import { Store, keyOfField } from '../store'; @@ -151,6 +151,10 @@ export class SelectionIterator { this.indexStack.push(0); this.selectionStack.push(getSelectionSet(fragmentNode)); } + + if (process.env.NODE_ENV !== 'production') { + popDebugNode(); + } } continue; diff --git a/exchanges/graphcache/src/operations/write.ts b/exchanges/graphcache/src/operations/write.ts index 912647fcf6..8296fab2bf 100644 --- a/exchanges/graphcache/src/operations/write.ts +++ b/exchanges/graphcache/src/operations/write.ts @@ -13,7 +13,7 @@ import { getFieldAlias, } from '../ast'; -import { invariant, warn, pushDebugNode } from '../helpers/help'; +import { invariant, warn, pushDebugNode, popDebugNode } from '../helpers/help'; import { NullArray, Variables, Data, Link, OperationRequest } from '../types'; @@ -75,6 +75,11 @@ export const startWrite = ( } writeSelection(ctx, operationName, getSelectionSet(operation), data); + + if (process.env.NODE_ENV !== 'production') { + popDebugNode(); + } + return result; }; @@ -113,6 +118,11 @@ export const writeOptimistic = ( ); writeSelection(ctx, operationName, getSelectionSet(operation), result.data!); + + if (process.env.NODE_ENV !== 'production') { + popDebugNode(); + } + clearDataState(); return result; }; @@ -160,6 +170,10 @@ export const writeFragment = ( ); writeSelection(ctx, entityKey, getSelectionSet(fragment), writeData); + + if (process.env.NODE_ENV !== 'production') { + popDebugNode(); + } }; const writeSelection = ( @@ -221,6 +235,7 @@ const writeSelection = ( if (ctx.optimistic && isRoot) { const resolver = ctx.store.optimisticMutations[fieldName]; + if (!resolver) continue; // We have to update the context to reflect up-to-date ResolveInfo updateContext(ctx, typename, typename, fieldKey, fieldName); From 2429bff0c84f76c19d5d340608f9c322957031ec Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Mon, 27 Apr 2020 16:25:10 +0200 Subject: [PATCH 2/6] move pop --- exchanges/graphcache/src/operations/shared.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/exchanges/graphcache/src/operations/shared.ts b/exchanges/graphcache/src/operations/shared.ts index 30e5992c70..54a4970793 100644 --- a/exchanges/graphcache/src/operations/shared.ts +++ b/exchanges/graphcache/src/operations/shared.ts @@ -118,6 +118,9 @@ export class SelectionIterator { if (index >= select.length) { this.indexStack.pop(); this.selectionStack.pop(); + if (process.env.NODE_ENV !== 'production') { + popDebugNode(); + } continue; } else { const node = select[index]; @@ -151,10 +154,6 @@ export class SelectionIterator { this.indexStack.push(0); this.selectionStack.push(getSelectionSet(fragmentNode)); } - - if (process.env.NODE_ENV !== 'production') { - popDebugNode(); - } } continue; From c0256f1a75949aaf1e45f50b1a4677c5f5eab7fd Mon Sep 17 00:00:00 2001 From: Phil Pluckthun Date: Mon, 27 Apr 2020 15:39:08 +0100 Subject: [PATCH 3/6] Add test case to query operation --- .../graphcache/src/operations/query.test.ts | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/exchanges/graphcache/src/operations/query.test.ts b/exchanges/graphcache/src/operations/query.test.ts index cc83f38a11..d49e892b43 100644 --- a/exchanges/graphcache/src/operations/query.test.ts +++ b/exchanges/graphcache/src/operations/query.test.ts @@ -4,7 +4,7 @@ import { write } from './write'; import { query } from './query'; const TODO_QUERY = gql` - query todos { + query Todos { todos { id text @@ -22,17 +22,12 @@ const TODO_QUERY = gql` describe('Query', () => { let schema, store, alteredRoot; - const spy: { console?: any } = {}; beforeAll(() => { schema = require('../test-utils/simple_schema.json'); alteredRoot = require('../test-utils/altered_root_schema.json'); }); - afterEach(() => { - spy.console.mockRestore(); - }); - beforeEach(() => { store = new Store({ schema }); write( @@ -46,7 +41,8 @@ describe('Query', () => { ], } ); - spy.console = jest.spyOn(console, 'warn'); + + jest.resetAllMocks(); }); it('test partial results', () => { @@ -75,7 +71,7 @@ describe('Query', () => { it('should warn once for invalid fields on an entity', () => { const INVALID_TODO_QUERY = gql` - query { + query InvalidTodo { todos { id text @@ -83,16 +79,22 @@ describe('Query', () => { } } `; + query(store, { query: INVALID_TODO_QUERY }); expect(console.warn).toHaveBeenCalledTimes(1); + expect((console.warn as any).mock.calls[0][0]).toMatch( + /Caused At: "InvalidTodo" query/ + ); + query(store, { query: INVALID_TODO_QUERY }); expect(console.warn).toHaveBeenCalledTimes(1); + expect((console.warn as any).mock.calls[0][0]).toMatch(/incomplete/); }); it('should warn once for invalid sub-entities on an entity', () => { const INVALID_TODO_QUERY = gql` - query { + query InvalidTodo { todos { id text @@ -102,8 +104,46 @@ describe('Query', () => { } } `; + query(store, { query: INVALID_TODO_QUERY }); expect(console.warn).toHaveBeenCalledTimes(1); + expect((console.warn as any).mock.calls[0][0]).toMatch( + /Caused At: "InvalidTodo" query/ + ); + + query(store, { query: INVALID_TODO_QUERY }); + expect(console.warn).toHaveBeenCalledTimes(1); + expect((console.warn as any).mock.calls[0][0]).toMatch(/writer/); + }); + + it.only('should warn once for invalid sub-entities on an entity at the right stack', () => { + const INVALID_TODO_QUERY = gql` + query InvalidTodo { + todos { + ...ValidTodo + ...InvalidFields + } + } + + fragment ValidTodo on Todo { + id + text + } + + fragment InvalidFields on Todo { + id + writer { + id + } + } + `; + + query(store, { query: INVALID_TODO_QUERY }); + expect(console.warn).toHaveBeenCalledTimes(1); + expect((console.warn as any).mock.calls[0][0]).toMatch( + /Caused At: "InvalidTodo" query, "InvalidFields" Fragment/ + ); + query(store, { query: INVALID_TODO_QUERY }); expect(console.warn).toHaveBeenCalledTimes(1); expect((console.warn as any).mock.calls[0][0]).toMatch(/writer/); From 8e49a2e402a6cc4fd253dd855ed27678dccf8b02 Mon Sep 17 00:00:00 2001 From: Phil Pluckthun Date: Mon, 27 Apr 2020 17:35:36 +0100 Subject: [PATCH 4/6] Add changeset --- .changeset/spotty-maps-kick.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/spotty-maps-kick.md diff --git a/.changeset/spotty-maps-kick.md b/.changeset/spotty-maps-kick.md new file mode 100644 index 0000000000..e6eb76dcaa --- /dev/null +++ b/.changeset/spotty-maps-kick.md @@ -0,0 +1,5 @@ +--- +'@urql/exchange-graphcache': patch +--- + +Improve warning and error console output in development by cleaning up the GraphQL trace stack. From 3a3afb7df2695fc672057e9311bc0bc58cd192eb Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Mon, 27 Apr 2020 18:40:29 +0200 Subject: [PATCH 5/6] remove .only --- exchanges/graphcache/src/operations/query.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchanges/graphcache/src/operations/query.test.ts b/exchanges/graphcache/src/operations/query.test.ts index d49e892b43..7a921c6db7 100644 --- a/exchanges/graphcache/src/operations/query.test.ts +++ b/exchanges/graphcache/src/operations/query.test.ts @@ -116,7 +116,7 @@ describe('Query', () => { expect((console.warn as any).mock.calls[0][0]).toMatch(/writer/); }); - it.only('should warn once for invalid sub-entities on an entity at the right stack', () => { + it('should warn once for invalid sub-entities on an entity at the right stack', () => { const INVALID_TODO_QUERY = gql` query InvalidTodo { todos { From aadfddfb2e55e62fdf1e207c2126837bcce68409 Mon Sep 17 00:00:00 2001 From: Phil Pluckthun Date: Mon, 27 Apr 2020 18:02:26 +0100 Subject: [PATCH 6/6] Remove duplicate test --- .../graphcache/src/operations/query.test.ts | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/exchanges/graphcache/src/operations/query.test.ts b/exchanges/graphcache/src/operations/query.test.ts index 7a921c6db7..a7adb78b20 100644 --- a/exchanges/graphcache/src/operations/query.test.ts +++ b/exchanges/graphcache/src/operations/query.test.ts @@ -92,30 +92,6 @@ describe('Query', () => { expect((console.warn as any).mock.calls[0][0]).toMatch(/incomplete/); }); - it('should warn once for invalid sub-entities on an entity', () => { - const INVALID_TODO_QUERY = gql` - query InvalidTodo { - todos { - id - text - writer { - id - } - } - } - `; - - query(store, { query: INVALID_TODO_QUERY }); - expect(console.warn).toHaveBeenCalledTimes(1); - expect((console.warn as any).mock.calls[0][0]).toMatch( - /Caused At: "InvalidTodo" query/ - ); - - query(store, { query: INVALID_TODO_QUERY }); - expect(console.warn).toHaveBeenCalledTimes(1); - expect((console.warn as any).mock.calls[0][0]).toMatch(/writer/); - }); - it('should warn once for invalid sub-entities on an entity at the right stack', () => { const INVALID_TODO_QUERY = gql` query InvalidTodo {