Repository: vazco/uniforms
Pull request #720 (2020-05-09 11:03:36)

Removed injectName helper
As said in #717, there are different types of fields. A long time ago, a new `injectName` helper got introduced as `NestField` couldn't use context for context propagation due to the problems with blocking updates (more about it is in #716). This change simplifies `NestField` and removes the `injectName` helper completely.

This is a first step of removing `includeInChain` option of `connectField`. The only field that still uses it is the `ListField`, but it'd require one more change (more about it soon).

codecov[bot]: # [Codecov](https://codecov.io/gh/vazco/uniforms/pull/720?src=pr&el=h1) Report
> Merging [#720](https://codecov.io/gh/vazco/uniforms/pull/720?src=pr&el=desc) into [v3](https://codecov.io/gh/vazco/uniforms/commit/ed1ad0ae84ad58c62eff21a2a9b2b3cf5e716117&el=desc) will **decrease** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/vazco/uniforms/pull/720/graphs/tree.svg?width=650&height=150&src=pr&token=PEY7QrNpKu)](https://codecov.io/gh/vazco/uniforms/pull/720?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##               v3     #720      +/-   ##
==========================================
- Coverage   97.99%   97.98%   -0.01%     
==========================================
  Files         159      158       -1     
  Lines        1645     1640       -5     
  Branches      598      597       -1     
==========================================
- Hits         1612     1607       -5     
  Misses          8        8              
  Partials       25       25              
```


| [Impacted Files](https://codecov.io/gh/vazco/uniforms/pull/720?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [packages/uniforms-antd/src/NestField.tsx](https://codecov.io/gh/vazco/uniforms/pull/720/diff?src=pr&el=tree#diff-cGFja2FnZXMvdW5pZm9ybXMtYW50ZC9zcmMvTmVzdEZpZWxkLnRzeA==) | `100.00% <100.00%> (ø)` | |
| [packages/uniforms-bootstrap3/src/NestField.tsx](https://codecov.io/gh/vazco/uniforms/pull/720/diff?src=pr&el=tree#diff-cGFja2FnZXMvdW5pZm9ybXMtYm9vdHN0cmFwMy9zcmMvTmVzdEZpZWxkLnRzeA==) | `100.00% <100.00%> (ø)` | |
| [packages/uniforms-bootstrap4/src/NestField.tsx](https://codecov.io/gh/vazco/uniforms/pull/720/diff?src=pr&el=tree#diff-cGFja2FnZXMvdW5pZm9ybXMtYm9vdHN0cmFwNC9zcmMvTmVzdEZpZWxkLnRzeA==) | `100.00% <100.00%> (ø)` | |
| [packages/uniforms-material/src/NestField.tsx](https://codecov.io/gh/vazco/uniforms/pull/720/diff?src=pr&el=tree#diff-cGFja2FnZXMvdW5pZm9ybXMtbWF0ZXJpYWwvc3JjL05lc3RGaWVsZC50c3g=) | `100.00% <100.00%> (ø)` | |
| [packages/uniforms-semantic/src/NestField.tsx](https://codecov.io/gh/vazco/uniforms/pull/720/diff?src=pr&el=tree#diff-cGFja2FnZXMvdW5pZm9ybXMtc2VtYW50aWMvc3JjL05lc3RGaWVsZC50c3g=) | `100.00% <100.00%> (ø)` | |
| [packages/uniforms-unstyled/src/NestField.tsx](https://codecov.io/gh/vazco/uniforms/pull/720/diff?src=pr&el=tree#diff-cGFja2FnZXMvdW5pZm9ybXMtdW5zdHlsZWQvc3JjL05lc3RGaWVsZC50c3g=) | `100.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/vazco/uniforms/pull/720?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/vazco/uniforms/pull/720?src=pr&el=footer). Last update [ed1ad0a...f69d9fc](https://codecov.io/gh/vazco/uniforms/pull/720?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7bf81920..e5cf5c06 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## Next
+
+- **Breaking:** Removed `injectName` helper. It was used to force context updates and got replaced by the new context directly. [\#720](https://github.com/vazco/uniforms/issues/720)
+
 ## [v3.0.0-alpha.3](https://github.com/vazco/uniforms/tree/v3.0.0-alpha.3) (2020-05-06)
 
 - **Breaking:** Removed `BaseForm.getChangedKeys`. Use `changedKeys` directly.
diff --git a/packages/uniforms-antd/src/NestField.tsx b/packages/uniforms-antd/src/NestField.tsx
index b3a0a081..dfa4e031 100644
--- a/packages/uniforms-antd/src/NestField.tsx
+++ b/packages/uniforms-antd/src/NestField.tsx
@@ -1,11 +1,5 @@
 import React, { HTMLProps } from 'react';
-import {
-  connectField,
-  filterDOMProps,
-  injectName,
-  joinName,
-  Override,
-} from 'uniforms';
+import { Override, connectField, filterDOMProps } from 'uniforms';
 
 import AutoField from './AutoField';
 
@@ -38,13 +32,12 @@ function Nest({
 
       {!!(error && showInlineError) && <div>{errorMessage}</div>}
 
-      {children
-        ? injectName(name, children)
-        : fields?.map(key => (
-            <AutoField key={key} name={joinName(name, key)} {...itemProps} />
-          ))}
+      {children ||
+        fields?.map(field => (
+          <AutoField key={field} name={field} {...itemProps} />
+        ))}
     </div>
   );
 }
 
-export default connectField(Nest, { includeInChain: false });
+export default connectField(Nest);
diff --git a/packages/uniforms-bootstrap3/src/NestField.tsx b/packages/uniforms-bootstrap3/src/NestField.tsx
index 244e6e77..f0307606 100644
--- a/packages/uniforms-bootstrap3/src/NestField.tsx
+++ b/packages/uniforms-bootstrap3/src/NestField.tsx
@@ -1,12 +1,6 @@
 import React, { HTMLProps } from 'react';
 import classnames from 'classnames';
-import {
-  connectField,
-  filterDOMProps,
-  injectName,
-  joinName,
-  Override,
-} from 'uniforms';
+import { Override, connectField, filterDOMProps } from 'uniforms';
 
 import AutoField from './AutoField';
 
@@ -45,12 +39,11 @@ const Nest = ({
       <span className="help-block">{errorMessage}</span>
     )}
 
-    {children
-      ? injectName(name, children)
-      : fields?.map((key: any) => (
-          <AutoField key={key} name={joinName(name, key)} {...itemProps} />
-        ))}
+    {children ||
+      fields?.map(field => (
+        <AutoField key={field} name={field} {...itemProps} />
+      ))}
   </div>
 );
 
-export default connectField(Nest, { includeInChain: false });
+export default connectField(Nest);
diff --git a/packages/uniforms-bootstrap4/src/NestField.tsx b/packages/uniforms-bootstrap4/src/NestField.tsx
index b56590c9..081b00e5 100644
--- a/packages/uniforms-bootstrap4/src/NestField.tsx
+++ b/packages/uniforms-bootstrap4/src/NestField.tsx
@@ -1,12 +1,6 @@
 import classnames from 'classnames';
 import React, { HTMLProps } from 'react';
-import {
-  connectField,
-  filterDOMProps,
-  injectName,
-  joinName,
-  Override,
-} from 'uniforms';
+import { Override, connectField, filterDOMProps } from 'uniforms';
 
 import AutoField from './AutoField';
 
@@ -45,13 +39,12 @@ function Nest({
         <span className="text-danger">{errorMessage}</span>
       )}
 
-      {children
-        ? injectName(name, children)
-        : fields?.map(key => (
-            <AutoField key={key} name={joinName(name, key)} {...itemProps} />
-          ))}
+      {children ||
+        fields?.map(field => (
+          <AutoField key={field} name={field} {...itemProps} />
+        ))}
     </div>
   );
 }
 
-export default connectField(Nest, { includeInChain: false });
+export default connectField(Nest);
diff --git a/packages/uniforms-material/src/NestField.tsx b/packages/uniforms-material/src/NestField.tsx
index 23e23c44..cb387636 100644
--- a/packages/uniforms-material/src/NestField.tsx
+++ b/packages/uniforms-material/src/NestField.tsx
@@ -1,6 +1,6 @@
 import FormLabel from '@material-ui/core/FormLabel';
 import React, { HTMLProps } from 'react';
-import { connectField, injectName, joinName, Override } from 'uniforms';
+import { Override, connectField } from 'uniforms';
 
 import AutoField from './AutoField';
 import wrapField from './wrapField';
@@ -25,12 +25,11 @@ function Nest({
   return wrapField(
     { ...props, component: undefined },
     label && <FormLabel component="legend">{label}</FormLabel>,
-    children
-      ? injectName(name, children)
-      : fields?.map(key => (
-          <AutoField key={key} name={joinName(name, key)} {...itemProps} />
-        )),
+    children ||
+      fields?.map(field => (
+        <AutoField key={field} name={field} {...itemProps} />
+      )),
   );
 }
 
-export default connectField(Nest, { includeInChain: false });
+export default connectField(Nest);
diff --git a/packages/uniforms-semantic/src/NestField.tsx b/packages/uniforms-semantic/src/NestField.tsx
index 3353d050..2adf7d73 100644
--- a/packages/uniforms-semantic/src/NestField.tsx
+++ b/packages/uniforms-semantic/src/NestField.tsx
@@ -1,12 +1,6 @@
-import classnames from 'classnames';
 import React, { HTMLProps } from 'react';
-import {
-  connectField,
-  filterDOMProps,
-  injectName,
-  joinName,
-  Override,
-} from 'uniforms';
+import classnames from 'classnames';
+import { Override, connectField, filterDOMProps } from 'uniforms';
 
 import AutoField from './AutoField';
 
@@ -52,15 +46,14 @@ function Nest({
         <div className="ui red basic label">{errorMessage}</div>
       )}
 
-      {children
-        ? injectName(name, children)
-        : fields?.map(key => (
-            <AutoField key={key} name={joinName(name, key)} {...itemProps} />
-          ))}
+      {children ||
+        fields?.map(field => (
+          <AutoField key={field} name={field} {...itemProps} />
+        ))}
     </div>
   );
 }
 
 Nest.defaultProps = { grouped: true };
 
-export default connectField(Nest, { includeInChain: false });
+export default connectField(Nest);
diff --git a/packages/uniforms-unstyled/src/NestField.tsx b/packages/uniforms-unstyled/src/NestField.tsx
index 2e29c210..c2abd9da 100644
--- a/packages/uniforms-unstyled/src/NestField.tsx
+++ b/packages/uniforms-unstyled/src/NestField.tsx
@@ -1,11 +1,5 @@
 import React, { HTMLProps } from 'react';
-import {
-  connectField,
-  filterDOMProps,
-  injectName,
-  joinName,
-  Override,
-} from 'uniforms';
+import { Override, connectField, filterDOMProps } from 'uniforms';
 
 import AutoField from './AutoField';
 
@@ -29,14 +23,12 @@ function Nest({
   return (
     <div {...filterDOMProps(props)}>
       {label && <label>{label}</label>}
-
-      {children
-        ? injectName(name, children)
-        : fields?.map(key => (
-            <AutoField key={key} name={joinName(name, key)} {...itemProps} />
-          ))}
+      {children ||
+        fields?.map(field => (
+          <AutoField key={field} name={field} {...itemProps} />
+        ))}
     </div>
   );
 }
 
-export default connectField(Nest, { includeInChain: false });
+export default connectField(Nest);
diff --git a/packages/uniforms/src/index.ts b/packages/uniforms/src/index.ts
index 4d433e53..b85330ec 100644
--- a/packages/uniforms/src/index.ts
+++ b/packages/uniforms/src/index.ts
@@ -8,7 +8,6 @@ export * from './changedKeys';
 export * from './connectField';
 export * from './context';
 export * from './filterDOMProps';
-export * from './injectName';
 export * from './joinName';
 export * from './randomIds';
 export * from './types';
diff --git a/packages/uniforms/src/injectName.ts b/packages/uniforms/src/injectName.ts
deleted file mode 100644
index 55c3f37e..00000000
--- a/packages/uniforms/src/injectName.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import get from 'lodash/get';
-import { Children, ReactElement, ReactNode, cloneElement } from 'react';
-
-import { joinName } from './joinName';
-
-export function injectName(
-  name: string,
-  children: ReactNode,
-  parent?: ReactNode,
-): ReactNode[] {
-  return Children.map(Children.toArray(children), child => {
-    if (!child || typeof child !== 'object' || get(parent, 'props.name'))
-      return child;
-
-    // TODO: It's probably the only case left.
-    const element = child as ReactElement;
-    return cloneElement(element, {
-      children: injectName(name, element.props.children, child),
-      name: joinName(name, element.props.name),
-    });
-  });
-}


Test patch:
diff --git a/packages/uniforms-antd/__tests__/NestField.tsx b/packages/uniforms-antd/__tests__/NestField.tsx
index f1ba97d6..f4ad8182 100644
--- a/packages/uniforms-antd/__tests__/NestField.tsx
+++ b/packages/uniforms-antd/__tests__/NestField.tsx
@@ -16,8 +16,8 @@ test('<NestField> - renders an <AutoField> for each field', () => {
   );
 
   expect(wrapper.find(AutoField)).toHaveLength(2);
-  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('x.a');
-  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('x.b');
+  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('a');
+  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('b');
 });
 
 test('<NestField> - renders custom content if given', () => {
diff --git a/packages/uniforms-bootstrap3/__tests__/NestField.tsx b/packages/uniforms-bootstrap3/__tests__/NestField.tsx
index d0b08cbd..793418a7 100644
--- a/packages/uniforms-bootstrap3/__tests__/NestField.tsx
+++ b/packages/uniforms-bootstrap3/__tests__/NestField.tsx
@@ -16,8 +16,8 @@ test('<NestField> - renders an <AutoField> for each field', () => {
   );
 
   expect(wrapper.find(AutoField)).toHaveLength(2);
-  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('x.a');
-  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('x.b');
+  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('a');
+  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('b');
 });
 
 test('<NestField> - renders custom content if given', () => {
diff --git a/packages/uniforms-bootstrap4/__tests__/NestField.tsx b/packages/uniforms-bootstrap4/__tests__/NestField.tsx
index 356ae5ea..c1606ba7 100644
--- a/packages/uniforms-bootstrap4/__tests__/NestField.tsx
+++ b/packages/uniforms-bootstrap4/__tests__/NestField.tsx
@@ -16,8 +16,8 @@ test('<NestField> - renders an <AutoField> for each field', () => {
   );
 
   expect(wrapper.find(AutoField)).toHaveLength(2);
-  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('x.a');
-  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('x.b');
+  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('a');
+  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('b');
 });
 
 test('<NestField> - renders custom content if given', () => {
diff --git a/packages/uniforms-material/__tests__/NestField.tsx b/packages/uniforms-material/__tests__/NestField.tsx
index 971125c1..dca28f44 100644
--- a/packages/uniforms-material/__tests__/NestField.tsx
+++ b/packages/uniforms-material/__tests__/NestField.tsx
@@ -18,8 +18,8 @@ test('<NestField> - renders an <AutoField> for each field', () => {
   );
 
   expect(wrapper.find(AutoField)).toHaveLength(2);
-  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('x.a');
-  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('x.b');
+  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('a');
+  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('b');
 });
 
 test('<NestField> - renders custom content if given', () => {
diff --git a/packages/uniforms-semantic/__tests__/NestField.tsx b/packages/uniforms-semantic/__tests__/NestField.tsx
index 70a8a165..e98a5302 100644
--- a/packages/uniforms-semantic/__tests__/NestField.tsx
+++ b/packages/uniforms-semantic/__tests__/NestField.tsx
@@ -16,8 +16,8 @@ test('<NestField> - renders an <AutoField> for each field', () => {
   );
 
   expect(wrapper.find(AutoField)).toHaveLength(2);
-  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('x.a');
-  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('x.b');
+  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('a');
+  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('b');
 });
 
 test('<NestField> - renders custom content if given', () => {
diff --git a/packages/uniforms-unstyled/__tests__/NestField.tsx b/packages/uniforms-unstyled/__tests__/NestField.tsx
index 61cb4055..38d6addc 100644
--- a/packages/uniforms-unstyled/__tests__/NestField.tsx
+++ b/packages/uniforms-unstyled/__tests__/NestField.tsx
@@ -16,8 +16,8 @@ test('<NestField> - renders an <AutoField> for each field', () => {
   );
 
   expect(wrapper.find(AutoField)).toHaveLength(2);
-  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('x.a');
-  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('x.b');
+  expect(wrapper.find(AutoField).at(0).prop('name')).toBe('a');
+  expect(wrapper.find(AutoField).at(1).prop('name')).toBe('b');
 });
 
 test('<NestField> - renders custom content if given', () => {
diff --git a/packages/uniforms/__tests__/index.ts b/packages/uniforms/__tests__/index.ts
index 9686e937..263a6547 100644
--- a/packages/uniforms/__tests__/index.ts
+++ b/packages/uniforms/__tests__/index.ts
@@ -12,7 +12,6 @@ it('exports everything', () => {
     connectField: expect.any(Function),
     context: expect.any(Object),
     filterDOMProps: expect.any(Function),
-    injectName: expect.any(Function),
     joinName: expect.any(Function),
     randomIds: expect.any(Function),
     useField: expect.any(Function),
diff --git a/packages/uniforms/__tests__/injectName.tsx b/packages/uniforms/__tests__/injectName.tsx
deleted file mode 100644
index daeed44a..00000000
--- a/packages/uniforms/__tests__/injectName.tsx
+++ /dev/null
@@ -1,278 +0,0 @@
-import React, { FC, ReactNode } from 'react';
-import { Context, connectField, injectName, randomIds } from 'uniforms';
-import { SimpleSchemaBridge } from 'uniforms-bridge-simple-schema';
-
-import mount from './_mount';
-
-jest.mock('meteor/aldeed:simple-schema');
-jest.mock('meteor/check');
-
-describe('injectName', () => {
-  const schema = new SimpleSchemaBridge({
-    getDefinition(name) {
-      return {
-        fieldA: { type: Object, label: 'FieldA' },
-        'fieldA.fieldB': { type: Object, label: 'FieldB' },
-        'fieldA.fieldB.fieldC': { type: String, label: 'FieldC' },
-      }[name];
-    },
-
-    messageForError() {},
-
-    objectKeys(name) {
-      return {
-        fieldA: ['FieldB'],
-        'fieldA.FieldB': ['FieldC'],
-        'fieldA.FieldB.FieldC': [],
-      }[name];
-    },
-
-    validator() {},
-  });
-
-  const reactContext = {
-    context: {
-      changed: false,
-      changedMap: {},
-      error: undefined,
-      model: {},
-      name: [],
-      onChange() {},
-      onSubmit() {},
-      randomId: randomIds(),
-      schema,
-      state: {
-        label: true,
-        disabled: false,
-        placeholder: false,
-        showInlineError: true,
-      },
-      submitting: false,
-      validating: false,
-    } as Context<any>,
-  };
-
-  type TestProps = { children?: ReactNode };
-  const Test: jest.Mock & FC<TestProps> = jest.fn((props: TestProps) => (
-    <span>{props.children}</span>
-  ));
-  const Field = connectField(Test);
-
-  beforeEach(() => {
-    Test.mockClear();
-  });
-
-  describe('when called', () => {
-    it('does nothing on normal elements', () => {
-      mount(
-        <Field name="fieldA">{injectName('fieldB', <Test />)}</Field>,
-        reactContext,
-      );
-
-      expect(Test.mock.calls[0]).toEqual(
-        expect.arrayContaining([expect.objectContaining({ name: 'fieldA' })]),
-      );
-      expect(Test.mock.calls[1]).not.toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB' }),
-        ]),
-      );
-    });
-
-    it('injects name into field', () => {
-      const spy = jest
-        .spyOn(global.console, 'error')
-        .mockImplementation(() => {});
-
-      mount(
-        <Field name="fieldA">{injectName('fieldB', <Field name="" />)}</Field>,
-        reactContext,
-      );
-
-      spy.mockRestore();
-
-      expect(Test.mock.calls[0]).toEqual(
-        expect.arrayContaining([expect.objectContaining({ name: 'fieldA' })]),
-      );
-      expect(Test.mock.calls[1]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB' }),
-        ]),
-      );
-    });
-
-    it('injects name into fields', () => {
-      const spy = jest
-        .spyOn(global.console, 'error')
-        .mockImplementation(() => {});
-
-      mount(
-        <Field name="fieldA">
-          {injectName('fieldB', [
-            <Field name="" key={1} />,
-            <Field name="" key={2} />,
-            <Field name="" key={3} />,
-          ])}
-        </Field>,
-        reactContext,
-      );
-
-      spy.mockRestore();
-
-      expect(Test.mock.calls[0]).toEqual(
-        expect.arrayContaining([expect.objectContaining({ name: 'fieldA' })]),
-      );
-      expect(Test.mock.calls[1]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB' }),
-        ]),
-      );
-      expect(Test.mock.calls[2]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB' }),
-        ]),
-      );
-      expect(Test.mock.calls[3]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB' }),
-        ]),
-      );
-    });
-
-    it('injects name into nested field', () => {
-      const spy = jest
-        .spyOn(global.console, 'error')
-        .mockImplementation(() => {});
-
-      mount(
-        <Field name="fieldA">
-          {injectName(
-            'fieldB',
-            <span>
-              <Field name="" />
-            </span>,
-          )}
-        </Field>,
-        reactContext,
-      );
-
-      spy.mockRestore();
-
-      expect(Test.mock.calls[0]).toEqual(
-        expect.arrayContaining([expect.objectContaining({ name: 'fieldA' })]),
-      );
-      expect(Test.mock.calls[1]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB' }),
-        ]),
-      );
-    });
-
-    it('injects name into nested fields', () => {
-      const spy = jest
-        .spyOn(global.console, 'error')
-        .mockImplementation(() => {});
-
-      mount(
-        <Field name="fieldA">
-          {injectName(
-            'fieldB',
-            <span>
-              <Field name="" />
-              <Field name="" />
-              <Field name="" />
-            </span>,
-          )}
-        </Field>,
-        reactContext,
-      );
-
-      spy.mockRestore();
-
-      expect(Test.mock.calls[0]).toEqual(
-        expect.arrayContaining([expect.objectContaining({ name: 'fieldA' })]),
-      );
-      expect(Test.mock.calls[1]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB' }),
-        ]),
-      );
-      expect(Test.mock.calls[2]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB' }),
-        ]),
-      );
-      expect(Test.mock.calls[3]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB' }),
-        ]),
-      );
-    });
-
-    it('injects joined name', () => {
-      const spy = jest
-        .spyOn(global.console, 'error')
-        .mockImplementation(() => {});
-
-      mount(
-        <Field name="fieldA">
-          {injectName('fieldB', <Field name="fieldC" />)}
-
-          {injectName(
-            'fieldB',
-            <span>
-              <Field name="fieldC" />
-            </span>,
-          )}
-        </Field>,
-        reactContext,
-      );
-
-      spy.mockRestore();
-
-      expect(Test.mock.calls[0]).toEqual(
-        expect.arrayContaining([expect.objectContaining({ name: 'fieldA' })]),
-      );
-      expect(Test.mock.calls[1]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB.fieldC' }),
-        ]),
-      );
-      expect(Test.mock.calls[2]).toEqual(
-        expect.arrayContaining([
-          expect.objectContaining({ name: 'fieldA.fieldB.fieldC' }),
-        ]),
-      );
-    });
-
-    it('injects only the first level', () => {
-      mount(
-        <Field name="fieldA">
-          {injectName(
-            'fieldB',
-            <Field name="fieldC">
-              <Test name="fieldD" />
-            </Field>,
-          )}
-
-          {injectName(
-            'fieldB',
-            <span>
-              <Field name="fieldC">
-                <Test name="fieldD" />
-              </Field>
-            </span>,
-          )}
-        </Field>,
-        reactContext,
-      );
-
-      expect(Test.mock.calls[2]).toEqual(
-        expect.arrayContaining([expect.objectContaining({ name: 'fieldD' })]),
-      );
-      expect(Test.mock.calls[4]).toEqual(
-        expect.arrayContaining([expect.objectContaining({ name: 'fieldD' })]),
-      );
-    });
-  });
-});