@homebound/form-state 2.18.1 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/FormStateApp.d.ts +2 -3
  2. package/dist/FormStateApp.js +8 -47
  3. package/dist/FormStateApp.test.js +14 -14
  4. package/dist/config.d.ts +6 -6
  5. package/dist/fields/fragmentField.js +3 -3
  6. package/dist/fields/listField.js +12 -12
  7. package/dist/fields/objectField.d.ts +4 -4
  8. package/dist/fields/objectField.js +10 -10
  9. package/dist/fields/valueField.d.ts +13 -0
  10. package/dist/fields/valueField.js +49 -14
  11. package/dist/formState.stories.d.ts +2 -4
  12. package/dist/formState.stories.js +1 -1
  13. package/dist/formState.test.js +171 -77
  14. package/dist/formStateDomain.js +1 -1
  15. package/dist/index.d.ts +3 -4
  16. package/dist/index.js +0 -11
  17. package/dist/proxies.d.ts +5 -0
  18. package/dist/proxies.js +21 -0
  19. package/dist/rules.d.ts +1 -1
  20. package/dist/rules.js +1 -1
  21. package/dist/setupTests.js +2 -2
  22. package/dist/useFormState.d.ts +4 -4
  23. package/dist/useFormState.js +13 -17
  24. package/dist/useFormState.test.js +141 -198
  25. package/dist/useFormStates.d.ts +3 -3
  26. package/dist/useFormStates.js +7 -11
  27. package/dist/useFormStates.test.js +56 -89
  28. package/dist/utils.d.ts +3 -3
  29. package/dist/utils.js +8 -8
  30. package/dist/utils.test.js +49 -49
  31. package/package.json +44 -39
  32. package/dist/AutoSaveStatus/AutoSaveStatusProvider.d.ts +0 -24
  33. package/dist/AutoSaveStatus/AutoSaveStatusProvider.js +0 -91
  34. package/dist/AutoSaveStatus/index.d.ts +0 -2
  35. package/dist/AutoSaveStatus/index.js +0 -9
  36. package/dist/AutoSaveStatus/useAutoSaveStatus.d.ts +0 -1
  37. package/dist/AutoSaveStatus/useAutoSaveStatus.js +0 -9
  38. package/dist/AutoSaveStatus/useAutoSaveStatus.test.d.ts +0 -1
  39. package/dist/AutoSaveStatus/useAutoSaveStatus.test.js +0 -152
@@ -3,14 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const jsx_runtime_1 = require("react/jsx-runtime");
4
4
  const rtl_utils_1 = require("@homebound/rtl-utils");
5
5
  const react_1 = require("@testing-library/react");
6
- const react_hooks_1 = require("@testing-library/react-hooks");
7
6
  const mobx_1 = require("mobx");
8
7
  const mobx_react_1 = require("mobx-react");
9
8
  const react_2 = require("react");
10
9
  const FormStateApp_1 = require("./FormStateApp");
11
10
  const rules_1 = require("./rules");
12
- const AutoSaveStatus_1 = require("./AutoSaveStatus/index");
13
- const AutoSaveStatusProvider_1 = require("./AutoSaveStatus/AutoSaveStatusProvider");
14
11
  const useFormState_1 = require("./useFormState");
15
12
  describe("useFormState", () => {
16
13
  it("calls init.map if init.input is defined", async () => {
@@ -19,32 +16,31 @@ describe("useFormState", () => {
19
16
  const config = { firstName: { type: "value" } };
20
17
  // And we have query data that may or may not be defined
21
18
  const data = { firstName: "bob" };
22
- const form = useFormState_1.useFormState({
19
+ const form = (0, useFormState_1.useFormState)({
23
20
  config,
24
21
  // Then the lambda is passed the "de-undefined" data, i.e. `d.firstName` is not a compile error
25
22
  init: { input: data, map: (d) => ({ firstName: d.firstName }) },
26
23
  });
27
- return jsx_runtime_1.jsx("div", { children: form.firstName.value }, void 0);
24
+ return (0, jsx_runtime_1.jsx)("div", { children: form.firstName.value });
28
25
  }
29
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
26
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
30
27
  expect(r.baseElement).toHaveTextContent("bob");
31
28
  });
32
29
  it("memoizes on init.input being an array", async () => {
33
30
  const config = { firstName: { type: "value" } };
34
31
  function TestComponent() {
35
- const [, setTick] = react_2.useState(0);
36
- const form = useFormState_1.useFormState({
32
+ const [, setTick] = (0, react_2.useState)(0);
33
+ const form = (0, useFormState_1.useFormState)({
37
34
  config,
38
35
  init: { input: ["a", "b"], map: ([a, b]) => ({ firstName: a + b }) },
39
36
  });
40
37
  const onClick = () => [form.firstName.set("fred"), setTick(1)];
41
- return (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("button", { "data-testid": "change", onClick: onClick }, void 0),
42
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0)] }, void 0));
38
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("button", { "data-testid": "change", onClick: onClick }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value })] }));
43
39
  }
44
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
45
- expect(r.firstName()).toHaveTextContent("ab");
46
- rtl_utils_1.click(r.change);
47
- expect(r.firstName()).toHaveTextContent("fred");
40
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
41
+ expect(r.firstName).toHaveTextContent("ab");
42
+ (0, rtl_utils_1.click)(r.change);
43
+ expect(r.firstName).toHaveTextContent("fred");
48
44
  });
49
45
  it("uses default if init.input is undefined", async () => {
50
46
  // Given a component
@@ -52,13 +48,13 @@ describe("useFormState", () => {
52
48
  const config = { firstName: { type: "value" } };
53
49
  // And we have query data that may or may not be defined (but is actually undefined)
54
50
  const data = Math.random() >= 0 ? undefined : { firstName: "bob" };
55
- const form = useFormState_1.useFormState({
51
+ const form = (0, useFormState_1.useFormState)({
56
52
  config,
57
53
  init: { input: data, map: (d) => ({ firstName: d.firstName }) },
58
54
  });
59
- return jsx_runtime_1.jsx("div", { children: form.firstName.value }, void 0);
55
+ return (0, jsx_runtime_1.jsx)("div", { children: form.firstName.value });
60
56
  }
61
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
57
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
62
58
  // Then we init.map wasn't called, and we used {} instead
63
59
  expect(r.baseElement.textContent).toEqual("");
64
60
  });
@@ -71,7 +67,7 @@ describe("useFormState", () => {
71
67
  };
72
68
  // And we have query data that may or may not be defined (but is actually undefined)
73
69
  const data = Math.random() >= 0 ? undefined : { firstName: "bob" };
74
- const form = useFormState_1.useFormState({
70
+ const form = (0, useFormState_1.useFormState)({
75
71
  config,
76
72
  // And we pass `ifUndefined`
77
73
  init: {
@@ -80,10 +76,9 @@ describe("useFormState", () => {
80
76
  ifUndefined: { firstName: "default" },
81
77
  },
82
78
  });
83
- return (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0),
84
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "changedValue" }, { children: JSON.stringify(form.changedValue) }), void 0)] }, void 0));
79
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "changedValue", children: JSON.stringify(form.changedValue) })] }));
85
80
  }
86
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
81
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
87
82
  // Then we use the ifUndefined value
88
83
  expect(r.firstName.textContent).toEqual("default");
89
84
  expect(r.changedValue.textContent).toEqual(JSON.stringify({ firstName: "default" }));
@@ -91,33 +86,32 @@ describe("useFormState", () => {
91
86
  it("uses init if set as a value", async () => {
92
87
  const config = { firstName: { type: "value" } };
93
88
  function TestComponent() {
94
- const [, setTick] = react_2.useState(0);
95
- const form = useFormState_1.useFormState({
89
+ const [, setTick] = (0, react_2.useState)(0);
90
+ const form = (0, useFormState_1.useFormState)({
96
91
  config,
97
92
  // That's using a raw init value
98
93
  init: { firstName: "bob" },
99
94
  });
100
- return (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("button", { "data-testid": "change", onClick: () => {
95
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("button", { "data-testid": "change", onClick: () => {
101
96
  // When that value changes
102
97
  form.firstName.set("fred");
103
98
  // And also we re-render the component
104
99
  setTick(1);
105
- } }, void 0),
106
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0)] }, void 0));
100
+ } }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value })] }));
107
101
  }
108
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
109
- expect(r.firstName()).toHaveTextContent("bob");
110
- rtl_utils_1.click(r.change);
102
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
103
+ expect(r.firstName).toHaveTextContent("bob");
104
+ (0, rtl_utils_1.click)(r.change);
111
105
  // Then the change didn't get dropped due to init being unstable
112
- expect(r.firstName()).toHaveTextContent("fred");
106
+ expect(r.firstName).toHaveTextContent("fred");
113
107
  });
114
108
  it("doesn't required an init value", async () => {
115
109
  function TestComponent() {
116
110
  const config = { firstName: { type: "value" } };
117
- const form = useFormState_1.useFormState({ config });
118
- return jsx_runtime_1.jsx("div", { children: form.firstName.value }, void 0);
111
+ const form = (0, useFormState_1.useFormState)({ config });
112
+ return (0, jsx_runtime_1.jsx)("div", { children: form.firstName.value });
119
113
  }
120
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
114
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
121
115
  expect(r.baseElement.textContent).toEqual("");
122
116
  });
123
117
  it("keeps local changed values when a query refreshes", async () => {
@@ -159,63 +153,53 @@ describe("useFormState", () => {
159
153
  ],
160
154
  };
161
155
  // And we start out with data1
162
- const [data, setData] = react_2.useState(data1);
163
- const form = useFormState_1.useFormState({ config, init: { input: data, map: (d) => d } });
156
+ const [data, setData] = (0, react_2.useState)(data1);
157
+ const form = (0, useFormState_1.useFormState)({ config, init: { input: data, map: (d) => d } });
164
158
  function makeLocalChanges() {
165
159
  form.firstName.value = "local";
166
160
  form.address.street.value = "local";
167
161
  form.books.rows[0].title.value = "local";
168
162
  }
169
- return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0),
170
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "lastName" }, { children: form.lastName.value }), void 0),
171
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "street" }, { children: form.address.street.value }), void 0),
172
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "city" }, { children: form.address.city.value }), void 0),
173
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "title1" }, { children: form.books.rows[0].title.value }), void 0),
174
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "title2" }, { children: form.books.rows[1].title.value }), void 0),
175
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "booksLength" }, { children: form.books.rows.length }), void 0),
176
- jsx_runtime_1.jsx("button", { "data-testid": "makeLocalChanges", onClick: makeLocalChanges }, void 0),
177
- jsx_runtime_1.jsx("button", { "data-testid": "refreshData", onClick: () => setData(data2) }, void 0),
178
- jsx_runtime_1.jsx("button", { "data-testid": "saveData", onClick: () => setData(data3) }, void 0),
179
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "changedValue" }, { children: JSON.stringify(form.changedValue) }), void 0)] }, void 0)) }, void 0));
163
+ return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "lastName", children: form.lastName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "street", children: form.address.street.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "city", children: form.address.city.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "title1", children: form.books.rows[0].title.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "title2", children: form.books.rows[1].title.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "booksLength", children: form.books.rows.length }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "makeLocalChanges", onClick: makeLocalChanges }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "refreshData", onClick: () => setData(data2) }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "saveData", onClick: () => setData(data3) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "changedValue", children: JSON.stringify(form.changedValue) })] })) }));
180
164
  }
181
165
  // And we start out with the initial query data
182
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
183
- expect(r.firstName().textContent).toEqual("f1");
184
- expect(r.street().textContent).toEqual("s1");
185
- expect(r.title1().textContent).toEqual("a1");
166
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
167
+ expect(r.firstName.textContent).toEqual("f1");
168
+ expect(r.street.textContent).toEqual("s1");
169
+ expect(r.title1.textContent).toEqual("a1");
186
170
  // When we make some local changes
187
- rtl_utils_1.click(r.makeLocalChanges);
171
+ (0, rtl_utils_1.click)(r.makeLocalChanges);
188
172
  // Then we see them
189
- expect(r.firstName().textContent).toEqual("local");
190
- expect(r.street().textContent).toEqual("local");
191
- expect(r.title1().textContent).toEqual("local");
192
- expect(JSON.parse(r.changedValue().textContent)).toEqual({
173
+ expect(r.firstName.textContent).toEqual("local");
174
+ expect(r.street.textContent).toEqual("local");
175
+ expect(r.title1.textContent).toEqual("local");
176
+ expect(JSON.parse(r.changedValue.textContent)).toEqual({
193
177
  id: "a:1",
194
178
  address: { id: "address:1", street: "local" },
195
179
  books: [{ id: "b:1", title: "local" }, { id: "b:2" }],
196
180
  firstName: "local",
197
181
  });
198
182
  // And when the new query is ran i.e. due to a cache refresh
199
- rtl_utils_1.click(r.refreshData);
183
+ (0, rtl_utils_1.click)(r.refreshData);
200
184
  // Then we kept our local changes
201
- expect(r.firstName().textContent).toEqual("local");
202
- expect(r.street().textContent).toEqual("local");
203
- expect(r.title1().textContent).toEqual("local");
185
+ expect(r.firstName.textContent).toEqual("local");
186
+ expect(r.street.textContent).toEqual("local");
187
+ expect(r.title1.textContent).toEqual("local");
204
188
  // But we also see the new data for fields we have not changed
205
- expect(r.lastName().textContent).toEqual("l2");
206
- expect(r.city().textContent).toEqual("c2");
207
- expect(r.title2().textContent).toEqual("b2");
208
- expect(r.booksLength().textContent).toEqual("3");
209
- expect(JSON.parse(r.changedValue().textContent)).toEqual({
189
+ expect(r.lastName.textContent).toEqual("l2");
190
+ expect(r.city.textContent).toEqual("c2");
191
+ expect(r.title2.textContent).toEqual("b2");
192
+ expect(r.booksLength.textContent).toEqual("3");
193
+ expect(JSON.parse(r.changedValue.textContent)).toEqual({
210
194
  id: "a:1",
211
195
  address: { id: "address:1", street: "local" },
212
196
  books: [{ id: "b:1", title: "local" }, { id: "b:2" }, { id: "b:3" }],
213
197
  firstName: "local",
214
198
  });
215
199
  // And then when our mutation results come back
216
- rtl_utils_1.click(r.saveData);
200
+ (0, rtl_utils_1.click)(r.saveData);
217
201
  // Then changedValue doesn't show our local changes anymore
218
- expect(JSON.parse(r.changedValue().textContent)).toEqual({
202
+ expect(JSON.parse(r.changedValue.textContent)).toEqual({
219
203
  id: "a:1",
220
204
  });
221
205
  });
@@ -235,29 +219,26 @@ describe("useFormState", () => {
235
219
  books: [{ title: "a2" }],
236
220
  };
237
221
  // And we start out with data1
238
- const [data, setData] = react_2.useState(data1);
239
- const form = useFormState_1.useFormState({
222
+ const [data, setData] = (0, react_2.useState)(data1);
223
+ const form = (0, useFormState_1.useFormState)({
240
224
  config,
241
225
  init: { input: data, map: (d) => d },
242
226
  // And the form is read only
243
227
  readOnly: true,
244
228
  });
245
- return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0),
246
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "street" }, { children: form.address.street.value }), void 0),
247
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "title1" }, { children: form.books.rows[0].title.value }), void 0),
248
- jsx_runtime_1.jsx("button", { "data-testid": "refreshData", onClick: () => setData(data2) }, void 0)] }, void 0)) }, void 0));
229
+ return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "street", children: form.address.street.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "title1", children: form.books.rows[0].title.value }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "refreshData", onClick: () => setData(data2) })] })) }));
249
230
  }
250
231
  // And we start out with the initial query data
251
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
252
- expect(r.firstName().textContent).toEqual("f1");
253
- expect(r.street().textContent).toEqual("s1");
254
- expect(r.title1().textContent).toEqual("a1");
232
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
233
+ expect(r.firstName.textContent).toEqual("f1");
234
+ expect(r.street.textContent).toEqual("s1");
235
+ expect(r.title1.textContent).toEqual("a1");
255
236
  // When the new query is ran i.e. due to a cache refresh
256
- rtl_utils_1.click(r.refreshData);
237
+ (0, rtl_utils_1.click)(r.refreshData);
257
238
  // Then we see the latest data
258
- expect(r.firstName().textContent).toEqual("f2");
259
- expect(r.street().textContent).toEqual("s2");
260
- expect(r.title1().textContent).toEqual("a2");
239
+ expect(r.firstName.textContent).toEqual("f2");
240
+ expect(r.street.textContent).toEqual("s2");
241
+ expect(r.title1.textContent).toEqual("a2");
261
242
  });
262
243
  it("useFormState can accept new data with computed fields", async () => {
263
244
  // Given a component
@@ -276,59 +257,54 @@ describe("useFormState", () => {
276
257
  const data1 = { firstName: "f1", lastName: "l1" };
277
258
  const data2 = { firstName: "f2", lastName: "l2" };
278
259
  // And we start out with data1
279
- const [data, setData] = react_2.useState(data1);
280
- const author = react_2.useMemo(() => new AuthorRow(data.firstName, data.lastName), [data]);
281
- const config = react_2.useMemo(() => ({
260
+ const [data, setData] = (0, react_2.useState)(data1);
261
+ const author = (0, react_2.useMemo)(() => new AuthorRow(data.firstName, data.lastName), [data]);
262
+ const config = (0, react_2.useMemo)(() => ({
282
263
  firstName: { type: "value" },
283
264
  lastName: { type: "value" },
284
265
  fullName: { type: "value", computed: true },
285
266
  }), []);
286
- const form = useFormState_1.useFormState({ config, init: { input: author, map: (a) => a } });
287
- return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "firstName" }, { children: form.firstName.value }), void 0),
288
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "fullName" }, { children: form.fullName.value }), void 0),
289
- jsx_runtime_1.jsx("button", { "data-testid": "refreshData", onClick: () => setData(data2) }, void 0)] }, void 0)) }, void 0));
267
+ const form = (0, useFormState_1.useFormState)({ config, init: { input: author, map: (a) => a } });
268
+ return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "firstName", children: form.firstName.value }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "fullName", children: form.fullName.value }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "refreshData", onClick: () => setData(data2) })] })) }));
290
269
  }
291
270
  // And we start out with the initial query data
292
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
293
- expect(r.firstName().textContent).toEqual("f1");
294
- expect(r.fullName().textContent).toEqual("f1 l1");
271
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
272
+ expect(r.firstName.textContent).toEqual("f1");
273
+ expect(r.fullName.textContent).toEqual("f1 l1");
295
274
  // When the new query is ran i.e. due to a cache refresh
296
- rtl_utils_1.click(r.refreshData);
297
- expect(r.firstName().textContent).toEqual("f2");
298
- expect(r.fullName().textContent).toEqual("f2 l2");
275
+ (0, rtl_utils_1.click)(r.refreshData);
276
+ expect(r.firstName.textContent).toEqual("f2");
277
+ expect(r.fullName.textContent).toEqual("f2 l2");
299
278
  });
300
279
  it("can trigger auto save for fields in list that were initially undefined", async () => {
301
280
  const autoSave = jest.fn();
302
281
  // Given a component
303
282
  function TestComponent() {
304
283
  // When the data is initially undefined
305
- const [data, setData] = react_2.useState();
284
+ const [data, setData] = (0, react_2.useState)();
306
285
  const data2 = { books: [{ title: "Title 1" }] };
307
- const form = useFormState_1.useFormState({
286
+ const form = (0, useFormState_1.useFormState)({
308
287
  config: authorWithBooksConfig,
309
288
  init: { input: data, map: (d) => d, ifUndefined: { books: [] } },
310
289
  autoSave,
311
290
  });
312
- return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("button", { "data-testid": "refreshData", onClick: () => setData(data2) }, void 0),
313
- jsx_runtime_1.jsx("button", { "data-testid": "add", onClick: () => form.books.add({ title: "New Book" }) }, void 0),
314
- jsx_runtime_1.jsx("button", { "data-testid": "blurBookOne", onClick: () => focusAndBlur(form.books.rows[0].title) }, void 0),
315
- jsx_runtime_1.jsx("button", { "data-testid": "blurBookTwo", onClick: () => focusAndBlur(form.books.rows[1].title) }, void 0)] }, void 0)) }, void 0));
291
+ return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("button", { "data-testid": "refreshData", onClick: () => setData(data2) }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "add", onClick: () => form.books.add({ title: "New Book" }) }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "blurBookOne", onClick: () => focusAndBlur(form.books.rows[0].title) }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "blurBookTwo", onClick: () => focusAndBlur(form.books.rows[1].title) })] })) }));
316
292
  }
317
293
  // Given a formState with `onBlur` set
318
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
294
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
319
295
  // When the data/child is now available
320
- rtl_utils_1.click(r.refreshData);
296
+ (0, rtl_utils_1.click)(r.refreshData);
321
297
  // And the field is blurred
322
- await rtl_utils_1.clickAndWait(r.blurBookOne);
298
+ await (0, rtl_utils_1.clickAndWait)(r.blurBookOne);
323
299
  // Then we don't auto-save because nothing has changed
324
300
  expect(autoSave).toBeCalledTimes(0);
325
301
  // And when adding a new book
326
- await rtl_utils_1.clickAndWait(r.add);
302
+ await (0, rtl_utils_1.clickAndWait)(r.add);
327
303
  // We autoSave the new row right away (because we don't have any validation rules
328
304
  // that say the new row can't be empty)
329
305
  expect(autoSave).toBeCalledTimes(1);
330
306
  // And the new book is blurred
331
- await rtl_utils_1.clickAndWait(r.blurBookTwo);
307
+ await (0, rtl_utils_1.clickAndWait)(r.blurBookTwo);
332
308
  // Then we auto save again
333
309
  expect(autoSave).toBeCalledTimes(2);
334
310
  });
@@ -338,7 +314,7 @@ describe("useFormState", () => {
338
314
  function TestComponent() {
339
315
  const config = authorConfig;
340
316
  const data = { firstName: "f1", lastName: "f1" };
341
- const form = useFormState_1.useFormState({
317
+ const form = (0, useFormState_1.useFormState)({
342
318
  config,
343
319
  init: data,
344
320
  // And there is reactive business logic in the `autoSave` method
@@ -347,11 +323,11 @@ describe("useFormState", () => {
347
323
  autoSaves++;
348
324
  },
349
325
  });
350
- return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx("button", { "data-testid": "setFirst", onClick: () => form.firstName.set("f2") }, void 0) }, void 0));
326
+ return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("button", { "data-testid": "setFirst", onClick: () => form.firstName.set("f2") }) }));
351
327
  }
352
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
328
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
353
329
  // When we change firstName
354
- await rtl_utils_1.clickAndWait(r.setFirst);
330
+ await (0, rtl_utils_1.clickAndWait)(r.setFirst);
355
331
  // When autoSave didn't infinite loop
356
332
  expect(autoSaves).toEqual(1);
357
333
  });
@@ -361,20 +337,20 @@ describe("useFormState", () => {
361
337
  function TestComponent() {
362
338
  const config = authorConfig;
363
339
  const data = { firstName: "f1", lastName: "f1" };
364
- const form = useFormState_1.useFormState({
340
+ const form = (0, useFormState_1.useFormState)({
365
341
  config,
366
342
  init: data,
367
343
  autoSave: (form) => autoSave(form.changedValue),
368
344
  });
369
- return (jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx("button", { "data-testid": "set", onClick: () => {
345
+ return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("button", { "data-testid": "set", onClick: () => {
370
346
  // And it sets two fields in a single callback
371
347
  form.firstName.set("f2");
372
348
  form.lastName.set("l2");
373
- } }, void 0) }, void 0));
349
+ } }) }));
374
350
  }
375
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
351
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
376
352
  // When we change both
377
- await rtl_utils_1.clickAndWait(r.set);
353
+ await (0, rtl_utils_1.clickAndWait)(r.set);
378
354
  // Then we only call autoSave once
379
355
  expect(autoSave).toBeCalledTimes(1);
380
356
  expect(autoSave).toBeCalledWith({ firstName: "f2", lastName: "l2" });
@@ -388,8 +364,8 @@ describe("useFormState", () => {
388
364
  };
389
365
  // Given a component using `getObjectState` for lazily creating ObjectStates
390
366
  function TestComponent() {
391
- const [apiData, setApiData] = react_2.useState({ id: "a:1", firstName: "Brandon", lastName: "Dow" });
392
- const state = useFormState_1.useFormState({ config, autoSave, init: { input: apiData, map: (v) => v } });
367
+ const [apiData, setApiData] = (0, react_2.useState)({ id: "a:1", firstName: "Brandon", lastName: "Dow" });
368
+ const state = (0, useFormState_1.useFormState)({ config, autoSave, init: { input: apiData, map: (v) => v } });
393
369
  async function autoSave(form) {
394
370
  autoSaveStub(form.changedValue);
395
371
  const changed = form.changedValue;
@@ -397,34 +373,32 @@ describe("useFormState", () => {
397
373
  await Promise.resolve(1);
398
374
  setApiData((prevState) => ({ ...prevState, ...changed }));
399
375
  }
400
- return (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsxs("div", Object.assign({ "data-testid": "name" }, { children: [apiData.firstName, " ", apiData.lastName] }), void 0),
401
- jsx_runtime_1.jsx("button", { "data-testid": "focusSetAndSaveField", onClick: () => {
376
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { "data-testid": "name", children: [apiData.firstName, " ", apiData.lastName] }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "focusSetAndSaveField", onClick: () => {
402
377
  state.firstName.focus();
403
378
  state.firstName.set("Foo");
404
379
  state.firstName.maybeAutoSave();
405
380
  state.firstName.blur();
406
- } }, void 0),
407
- jsx_runtime_1.jsx("button", { "data-testid": "focusSetAndSaveFieldLastName", onClick: () => {
381
+ } }), (0, jsx_runtime_1.jsx)("button", { "data-testid": "focusSetAndSaveFieldLastName", onClick: () => {
408
382
  state.lastName.focus();
409
383
  state.lastName.set("Bar");
410
384
  state.lastName.maybeAutoSave();
411
- } }, void 0)] }, void 0));
385
+ } })] }));
412
386
  }
413
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
387
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
414
388
  // And triggering the auto save behavior before awaiting the initial promise to
415
389
  // resolve so we have pending changes.
416
- rtl_utils_1.click(r.focusSetAndSaveField(), { allowAsync: true });
390
+ (0, rtl_utils_1.click)(r.focusSetAndSaveField, { allowAsync: true });
417
391
  // Let the initial autoSave be called
418
- react_1.act(() => {
392
+ (0, react_1.act)(() => {
419
393
  jest.runOnlyPendingTimers();
420
394
  });
421
- expect(r.name()).toHaveTextContent("Brandon Dow");
395
+ expect(r.name).toHaveTextContent("Brandon Dow");
422
396
  expect(autoSaveStub).toBeCalledTimes(1);
423
397
  expect(autoSaveStub).toBeCalledWith({ id: "a:1", firstName: "Foo" });
424
398
  // And while that is in flight, trigger another user action
425
- rtl_utils_1.click(r.focusSetAndSaveFieldLastName(), { allowAsync: true });
399
+ (0, rtl_utils_1.click)(r.focusSetAndSaveFieldLastName, { allowAsync: true });
426
400
  // (Use `wait` so that our timer flushes before the Promise.resolve(1) is ran)
427
- await rtl_utils_1.wait();
401
+ await (0, rtl_utils_1.wait)();
428
402
  // Then expect the auto save to only have been called twice. Once with each changedValues.
429
403
  expect(autoSaveStub).toBeCalledTimes(2);
430
404
  expect(autoSaveStub).toBeCalledWith({ id: "a:1", firstName: "Foo" });
@@ -439,20 +413,20 @@ describe("useFormState", () => {
439
413
  };
440
414
  // Given a component that is using autoSave
441
415
  function TestComponent() {
442
- const fs = useFormState_1.useFormState({
416
+ const fs = (0, useFormState_1.useFormState)({
443
417
  config,
444
418
  addRules(fs) {
445
419
  // And also has calculated values
446
- mobx_1.reaction(() => fs.firstName.value, (curr) => (fs.lastName.value = curr));
420
+ (0, mobx_1.reaction)(() => fs.firstName.value, (curr) => (fs.lastName.value = curr));
447
421
  },
448
422
  autoSave: (fs) => autoSaveStub(fs.changedValue),
449
423
  init: { id: "a:1" },
450
424
  });
451
- return jsx_runtime_1.jsx(FormStateApp_1.TextField, { field: fs.firstName }, void 0);
425
+ return (0, jsx_runtime_1.jsx)(FormStateApp_1.TextField, { field: fs.firstName });
452
426
  }
453
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
427
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
454
428
  // When the user sets one field
455
- await rtl_utils_1.typeAndWait(r.firstName, "first");
429
+ await (0, rtl_utils_1.typeAndWait)(r.firstName, "first");
456
430
  // Then we only called autoSave once
457
431
  expect(autoSaveStub).toBeCalledTimes(1);
458
432
  expect(autoSaveStub).toBeCalledWith({ id: "a:1", firstName: "first", lastName: "first" });
@@ -460,108 +434,77 @@ describe("useFormState", () => {
460
434
  it("sets loading if opts.loading is true", async () => {
461
435
  const config = { firstName: { type: "value" } };
462
436
  function TestComponent({ loading }) {
463
- const form = useFormState_1.useFormState({ config, loading });
464
- return jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "loading" }, { children: String(form.loading) }), void 0) }, void 0);
437
+ const form = (0, useFormState_1.useFormState)({ config, loading });
438
+ return (0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => (0, jsx_runtime_1.jsx)("div", { "data-testid": "loading", children: String(form.loading) }) });
465
439
  }
466
440
  // And we initially pass in `init.query.loading: true`
467
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, { loading: true }, void 0));
441
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { loading: true }));
468
442
  // Then the form is marked as loading
469
- expect(r.loading()).toHaveTextContent("true");
443
+ expect(r.loading).toHaveTextContent("true");
470
444
  // And when the query is not loading
471
- await r.rerender(jsx_runtime_1.jsx(TestComponent, { loading: false }, void 0));
445
+ await r.rerender((0, jsx_runtime_1.jsx)(TestComponent, { loading: false }));
472
446
  // Then the form is marked as not loading
473
- expect(r.loading()).toHaveTextContent("false");
447
+ expect(r.loading).toHaveTextContent("false");
474
448
  });
475
449
  it("sets loading if input.data is undefined", async () => {
476
450
  const config = { firstName: { type: "value" } };
477
451
  function TestComponent({ data }) {
478
- const form = useFormState_1.useFormState({ config, init: { input: data, map: (d) => d } });
479
- return jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "loading" }, { children: String(form.loading) }), void 0) }, void 0);
452
+ const form = (0, useFormState_1.useFormState)({ config, init: { input: data, map: (d) => d } });
453
+ return (0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => (0, jsx_runtime_1.jsx)("div", { "data-testid": "loading", children: String(form.loading) }) });
480
454
  }
481
455
  // And we initially pass in `init.input: undefined`
482
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, { data: undefined }, void 0));
456
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { data: undefined }));
483
457
  // Then the form is marked as loading
484
- expect(r.loading()).toHaveTextContent("true");
458
+ expect(r.loading).toHaveTextContent("true");
485
459
  // And when the data is no longer undefined
486
- await r.rerender(jsx_runtime_1.jsx(TestComponent, { data: { firstName: "first" } }, void 0));
460
+ await r.rerender((0, jsx_runtime_1.jsx)(TestComponent, { data: { firstName: "first" } }));
487
461
  // Then the form is marked as not loading
488
- expect(r.loading()).toHaveTextContent("false");
462
+ expect(r.loading).toHaveTextContent("false");
489
463
  });
490
464
  it("sets loading if query.loading is true", async () => {
491
465
  const config = { firstName: { type: "value" } };
492
466
  function TestComponent({ loading, data }) {
493
- const form = useFormState_1.useFormState({ config, init: { query: { data, loading, error: null }, map: (d) => d } });
494
- return jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "loading" }, { children: String(form.loading) }), void 0) }, void 0);
467
+ const form = (0, useFormState_1.useFormState)({ config, init: { query: { data, loading, error: null }, map: (d) => d } });
468
+ return (0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => (0, jsx_runtime_1.jsx)("div", { "data-testid": "loading", children: String(form.loading) }) });
495
469
  }
496
470
  // And we initially pass in `init.query.loading: true`
497
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, { loading: true, data: undefined }, void 0));
471
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, { loading: true, data: undefined }));
498
472
  // Then the form is marked as loading
499
- expect(r.loading()).toHaveTextContent("true");
473
+ expect(r.loading).toHaveTextContent("true");
500
474
  // And when the query is not loading
501
- await r.rerender(jsx_runtime_1.jsx(TestComponent, { loading: false, data: { firstName: "first" } }, void 0));
475
+ await r.rerender((0, jsx_runtime_1.jsx)(TestComponent, { loading: false, data: { firstName: "first" } }));
502
476
  // Then the form is marked as not loading
503
- expect(r.loading()).toHaveTextContent("false");
504
- });
505
- it("updates AutoSaveStatusProvider when autoSaving", async () => {
506
- const config = { firstName: { type: "value" } };
507
- const { result } = react_hooks_1.renderHook(() => ({
508
- fs: useFormState_1.useFormState({ config, autoSave: async () => { } }),
509
- autoSave: AutoSaveStatus_1.useAutoSaveStatus(),
510
- }), {
511
- wrapper: ({ children }) => (jsx_runtime_1.jsx(AutoSaveStatus_1.AutoSaveStatusProvider, { children: jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: children }, void 0) }, void 0) }, void 0)),
512
- });
513
- expect(result.current.autoSave.status).toBe(AutoSaveStatusProvider_1.AutoSaveStatus.IDLE);
514
- // When we invoke a change and autoSave fires
515
- react_hooks_1.act(() => {
516
- result.current.fs.set({ firstName: "test" });
517
- });
518
- react_hooks_1.act(() => {
519
- // useFormState has a setTimeout(..., 0) that needs to run
520
- jest.advanceTimersToNextTimer();
521
- });
522
- expect(result.current.autoSave.status).toBe(AutoSaveStatusProvider_1.AutoSaveStatus.SAVING);
523
- // Idk why this needs to be async but it doesn't work otherwise
524
- await react_hooks_1.act(async () => {
525
- jest.runAllTimers();
526
- });
527
- // Then we expect AutoSaveStatus to be notiied of Doneness
528
- expect(result.current.autoSave.status).toBe(AutoSaveStatusProvider_1.AutoSaveStatus.DONE);
529
- jest.clearAllTimers();
477
+ expect(r.loading).toHaveTextContent("false");
530
478
  });
531
479
  it("treats the id changing as a whole new entity instead of a delete", async () => {
532
480
  const config = { firstName: { type: "value" } };
533
481
  function TestComponent() {
534
482
  // Given an initial author a1
535
- const [author, setAuthor] = react_2.useState({ id: "a:1", firstName: "a1" });
536
- const form = useFormState_1.useFormState({ config, init: { input: author, map: (a) => a } });
537
- return (jsx_runtime_1.jsx(mobx_react_1.Observer, { children: () => (jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "value" }, { children: String(form.firstName.value) }), void 0),
538
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "dirty" }, { children: String(form.firstName.dirty) }), void 0),
539
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "originalValue" }, { children: String(form.firstName.originalValue) }), void 0),
540
- jsx_runtime_1.jsx("div", Object.assign({ "data-testid": "objectValue" }, { children: String(form.value.firstName) }), void 0),
541
- jsx_runtime_1.jsx("div", { "data-testid": "a1", onClick: () => setAuthor({ id: "a:1", firstName: "a1" }) }, void 0),
542
- jsx_runtime_1.jsx("div", { "data-testid": "a2", onClick: () => setAuthor({ id: "a:2", firstName: undefined }) }, void 0)] }, void 0)) }, void 0));
483
+ const [author, setAuthor] = (0, react_2.useState)({ id: "a:1", firstName: "a1" });
484
+ const form = (0, useFormState_1.useFormState)({ config, init: { input: author, map: (a) => a } });
485
+ return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { "data-testid": "value", children: String(form.firstName.value) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "dirty", children: String(form.firstName.dirty) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "originalValue", children: String(form.firstName.originalValue) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "objectValue", children: String(form.value.firstName) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "a1", onClick: () => setAuthor({ id: "a:1", firstName: "a1" }) }), (0, jsx_runtime_1.jsx)("div", { "data-testid": "a2", onClick: () => setAuthor({ id: "a:2", firstName: undefined }) })] })) }));
543
486
  }
544
- const r = await rtl_utils_1.render(jsx_runtime_1.jsx(TestComponent, {}, void 0));
487
+ const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(TestComponent, {}));
545
488
  // And the value is initially a1/and not dirty
546
- expect(r.value()).toHaveTextContent("a1");
547
- expect(r.dirty()).toHaveTextContent("false");
548
- expect(r.originalValue()).toHaveTextContent("a1");
549
- expect(r.objectValue()).toHaveTextContent("a1");
489
+ expect(r.value).toHaveTextContent("a1");
490
+ expect(r.dirty).toHaveTextContent("false");
491
+ expect(r.originalValue).toHaveTextContent("a1");
492
+ expect(r.objectValue).toHaveTextContent("a1");
550
493
  // When we switch to a completely separate author
551
- rtl_utils_1.click(r.a2);
494
+ (0, rtl_utils_1.click)(r.a2);
552
495
  // Then it switches to the next author
553
- expect(r.value()).toHaveTextContent("undefined");
496
+ expect(r.value).toHaveTextContent("undefined");
554
497
  // And the field is not dirty (which had been the case before this bug fix)
555
- expect(r.dirty()).toHaveTextContent("false");
556
- expect(r.originalValue()).toHaveTextContent("undefined");
557
- expect(r.objectValue()).toHaveTextContent("undefined");
498
+ expect(r.dirty).toHaveTextContent("false");
499
+ expect(r.originalValue).toHaveTextContent("undefined");
500
+ expect(r.objectValue).toHaveTextContent("undefined");
558
501
  // And when we switch back to the original author
559
- rtl_utils_1.click(r.a1);
502
+ (0, rtl_utils_1.click)(r.a1);
560
503
  // It again restores the value and does not think an edit was WIP
561
- expect(r.value()).toHaveTextContent("a1");
562
- expect(r.dirty()).toHaveTextContent("false");
563
- expect(r.originalValue()).toHaveTextContent("a1");
564
- expect(r.objectValue()).toHaveTextContent("a1");
504
+ expect(r.value).toHaveTextContent("a1");
505
+ expect(r.dirty).toHaveTextContent("false");
506
+ expect(r.originalValue).toHaveTextContent("a1");
507
+ expect(r.objectValue).toHaveTextContent("a1");
565
508
  });
566
509
  });
567
510
  const authorConfig = {