From 6a80a0f1a74c81018284466a095f6bc73f9e228f Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Tue, 9 May 2023 10:11:18 -0700 Subject: [PATCH] Add runtime test validating plural @live field Reviewed By: voideanvalue Differential Revision: D45677696 fbshipit-source-id: 12b16097e1be9fb62dd1167dd4ef8aae0cdbfd8c --- .../RelayResolvers-withOutputType-test.js | 60 +++++ ...utputTypeTestManyLiveTodosQuery.graphql.js | 251 ++++++++++++++++++ .../__tests__/resolvers/ExampleTodoStore.js | 2 +- .../__tests__/resolvers/QueryManyLiveTodos.js | 40 +++ ...__many_live_todos$normalization.graphql.js | 48 ++++ 5 files changed, 400 insertions(+), 1 deletion(-) create mode 100644 packages/react-relay/__tests__/__generated__/RelayResolversWithOutputTypeTestManyLiveTodosQuery.graphql.js create mode 100644 packages/relay-runtime/store/__tests__/resolvers/QueryManyLiveTodos.js create mode 100644 packages/relay-runtime/store/__tests__/resolvers/__generated__/Query__many_live_todos$normalization.graphql.js diff --git a/packages/react-relay/__tests__/RelayResolvers-withOutputType-test.js b/packages/react-relay/__tests__/RelayResolvers-withOutputType-test.js index 6230ad2ae370b..59726d13be65d 100644 --- a/packages/react-relay/__tests__/RelayResolvers-withOutputType-test.js +++ b/packages/react-relay/__tests__/RelayResolvers-withOutputType-test.js @@ -279,6 +279,26 @@ describe.each([ }); } + function ManyLiveTodosComponent() { + const data = useClientQuery( + graphql` + query RelayResolversWithOutputTypeTestManyLiveTodosQuery { + many_live_todos { + ...RelayResolversWithOutputTypeTestFragment + } + } + `, + {}, + ); + if (data.many_live_todos?.length === 0) { + return 'No Items'; + } + + return data.many_live_todos?.map((todo, index) => { + return ; + }); + } + test('should render empty state', () => { const renderer = TestRenderer.create( @@ -718,4 +738,44 @@ describe.each([ 'color: color is red', ]); }); + + test('rendering live list', () => { + addTodo('Todo 1'); + addTodo('Todo 2'); + addTodo('Todo 3'); + + const renderer = TestRenderer.create( + + + , + ); + + expect(renderer.toJSON()).toEqual([ + 'Todo 1', + 'is not completed', + 'style: bold', + 'color: color is red', + 'Todo 2', + 'is not completed', + 'style: bold', + 'color: color is red', + 'Todo 3', + 'is not completed', + 'style: bold', + 'color: color is red', + ]); + + TestRenderer.act(() => { + removeTodo('todo-1'); + removeTodo('todo-2'); + jest.runAllImmediates(); + }); + + expect(renderer.toJSON()).toEqual([ + 'Todo 3', + 'is not completed', + 'style: bold', + 'color: color is red', + ]); + }); }); diff --git a/packages/react-relay/__tests__/__generated__/RelayResolversWithOutputTypeTestManyLiveTodosQuery.graphql.js b/packages/react-relay/__tests__/__generated__/RelayResolversWithOutputTypeTestManyLiveTodosQuery.graphql.js new file mode 100644 index 0000000000000..b66de38224b06 --- /dev/null +++ b/packages/react-relay/__tests__/__generated__/RelayResolversWithOutputTypeTestManyLiveTodosQuery.graphql.js @@ -0,0 +1,251 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @oncall relay + * + * @generated SignedSource<<451e85f22d8b3a215a63a985c1fd88e7>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { ClientRequest, ClientQuery } from 'relay-runtime'; +import type { LiveState } from "relay-runtime/store/experimental-live-resolvers/LiveResolverStore"; +import type { RelayResolversWithOutputTypeTestFragment$fragmentType } from "./RelayResolversWithOutputTypeTestFragment.graphql"; +import {many_live_todos as queryManyLiveTodosResolverType} from "../../../relay-runtime/store/__tests__/resolvers/QueryManyLiveTodos.js"; +// Type assertion validating that `queryManyLiveTodosResolverType` resolver is correctly implemented. +// A type error here indicates that the type signature of the resolver module is incorrect. +(queryManyLiveTodosResolverType: () => LiveState<$ReadOnlyArray>); +import type { Query__many_live_todos$normalization } from "./../../../relay-runtime/store/__tests__/resolvers/__generated__/Query__many_live_todos$normalization.graphql"; +export type RelayResolversWithOutputTypeTestManyLiveTodosQuery$variables = {||}; +export type RelayResolversWithOutputTypeTestManyLiveTodosQuery$data = {| + +many_live_todos: ?$ReadOnlyArray, +|}; +export type RelayResolversWithOutputTypeTestManyLiveTodosQuery = {| + response: RelayResolversWithOutputTypeTestManyLiveTodosQuery$data, + variables: RelayResolversWithOutputTypeTestManyLiveTodosQuery$variables, +|}; +*/ + +var node/*: ClientRequest*/ = (function(){ +var v0 = { + "kind": "InlineFragment", + "selections": [ + { + "name": "self", + "args": null, + "fragment": { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "todo_id", + "storageKey": null + } + ], + "type": "Todo", + "abstractKey": null + }, + "kind": "RelayResolver", + "storageKey": null, + "isOutputType": false + } + ], + "type": "Todo", + "abstractKey": null +}; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": { + "hasClientEdges": true + }, + "name": "RelayResolversWithOutputTypeTestManyLiveTodosQuery", + "selections": [ + { + "kind": "ClientEdgeToClientObject", + "concreteType": "Todo", + "backingField": { + "alias": null, + "args": null, + "fragment": null, + "kind": "RelayLiveResolver", + "name": "many_live_todos", + "resolverModule": require('./../../../relay-runtime/store/__tests__/resolvers/QueryManyLiveTodos').many_live_todos, + "path": "many_live_todos", + "normalizationInfo": { + "concreteType": "Todo", + "plural": true, + "normalizationNode": require('./../../../relay-runtime/store/__tests__/resolvers/__generated__/Query__many_live_todos$normalization.graphql') + } + }, + "linkedField": { + "alias": null, + "args": null, + "concreteType": "Todo", + "kind": "LinkedField", + "name": "many_live_todos", + "plural": true, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "RelayResolversWithOutputTypeTestFragment" + } + ], + "storageKey": null + } + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "RelayResolversWithOutputTypeTestManyLiveTodosQuery", + "selections": [ + { + "kind": "ClientEdgeToClientObject", + "backingField": { + "name": "many_live_todos", + "args": null, + "fragment": null, + "kind": "RelayResolver", + "storageKey": null, + "isOutputType": true + }, + "linkedField": { + "alias": null, + "args": null, + "concreteType": "Todo", + "kind": "LinkedField", + "name": "many_live_todos", + "plural": true, + "selections": [ + { + "kind": "ClientEdgeToClientObject", + "backingField": { + "name": "text", + "args": null, + "fragment": (v0/*: any*/), + "kind": "RelayResolver", + "storageKey": null, + "isOutputType": true + }, + "linkedField": { + "alias": null, + "args": null, + "concreteType": "TodoText", + "kind": "LinkedField", + "name": "text", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "content", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "TodoTextStyle", + "kind": "LinkedField", + "name": "style", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "font_style", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "TodoTextColor", + "kind": "LinkedField", + "name": "color", + "plural": false, + "selections": [ + { + "name": "human_readable_color", + "args": null, + "fragment": { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hex", + "storageKey": null + } + ], + "type": "TodoTextColor", + "abstractKey": null + }, + "kind": "RelayResolver", + "storageKey": null, + "isOutputType": false + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + }, + { + "name": "complete", + "args": null, + "fragment": (v0/*: any*/), + "kind": "RelayResolver", + "storageKey": null, + "isOutputType": false + } + ], + "storageKey": null + } + } + ] + }, + "params": { + "cacheID": "b9aabe2c5911f0a5daf91a73d666b31c", + "id": null, + "metadata": {}, + "name": "RelayResolversWithOutputTypeTestManyLiveTodosQuery", + "operationKind": "query", + "text": null + } +}; +})(); + +if (__DEV__) { + (node/*: any*/).hash = "f42ffca5f81738e839984490939acc31"; +} + +module.exports = ((node/*: any*/)/*: ClientQuery< + RelayResolversWithOutputTypeTestManyLiveTodosQuery$variables, + RelayResolversWithOutputTypeTestManyLiveTodosQuery$data, +>*/); diff --git a/packages/relay-runtime/store/__tests__/resolvers/ExampleTodoStore.js b/packages/relay-runtime/store/__tests__/resolvers/ExampleTodoStore.js index 691dd61b1cfb7..3893687cacfea 100644 --- a/packages/relay-runtime/store/__tests__/resolvers/ExampleTodoStore.js +++ b/packages/relay-runtime/store/__tests__/resolvers/ExampleTodoStore.js @@ -13,7 +13,7 @@ import type {LogEvent} from '../../RelayStoreTypes'; -export opaque type TodoID = string; +export opaque type TodoID: string = string; export type TodoItem = { todoID: TodoID, diff --git a/packages/relay-runtime/store/__tests__/resolvers/QueryManyLiveTodos.js b/packages/relay-runtime/store/__tests__/resolvers/QueryManyLiveTodos.js new file mode 100644 index 0000000000000..4c4f1c4bfd037 --- /dev/null +++ b/packages/relay-runtime/store/__tests__/resolvers/QueryManyLiveTodos.js @@ -0,0 +1,40 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall relay + */ + +'use strict'; + +import type {LiveState} from '../../experimental-live-resolvers/LiveResolverStore'; + +const { + Selectors, + TODO_STORE, +} = require('relay-runtime/store/__tests__/resolvers/ExampleTodoStore'); + +/** + * @RelayResolver Query.many_live_todos: [Todo] + * @live + */ +function many_live_todos(): LiveState<$ReadOnlyArray<{todo_id: string}>> { + return { + read() { + return Selectors.getTodoIDs(TODO_STORE.getState()).map(id => ({ + todo_id: id, + })); + }, + subscribe(cb) { + return TODO_STORE.subscribe(null, cb); + }, + }; +} + +module.exports = { + many_live_todos, +}; diff --git a/packages/relay-runtime/store/__tests__/resolvers/__generated__/Query__many_live_todos$normalization.graphql.js b/packages/relay-runtime/store/__tests__/resolvers/__generated__/Query__many_live_todos$normalization.graphql.js new file mode 100644 index 0000000000000..42b692cb0eec8 --- /dev/null +++ b/packages/relay-runtime/store/__tests__/resolvers/__generated__/Query__many_live_todos$normalization.graphql.js @@ -0,0 +1,48 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @oncall relay + * + * @generated SignedSource<<74fd0ae7e5c35857bcd216ec356d5ceb>> + * @flow + * @lightSyntaxTransform + * @nogrep + */ + +/* eslint-disable */ + +'use strict'; + +/*:: +import type { NormalizationSplitOperation } from 'relay-runtime'; + +export type Query__many_live_todos$normalization = {| + +todo_id: string, +|}; + +*/ + +var node/*: NormalizationSplitOperation*/ = { + "kind": "SplitOperation", + "metadata": {}, + "name": "Query__many_live_todos$normalization", + "selections": [ + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "todo_id", + "storageKey": null + } + ] + } + ] +}; + +module.exports = node;