Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getPublicInstance is not a function #4

Closed
bsr203 opened this issue Sep 22, 2016 · 12 comments
Closed

getPublicInstance is not a function #4

bsr203 opened this issue Sep 22, 2016 · 12 comments
Labels

Comments

@bsr203
Copy link

bsr203 commented Sep 22, 2016

Hi,

I have a bit of a complex component, which renders pretty printed message with enzyme w.debug(). But, getting following stack when use with mountToJson

  const w = mount(<MyComponent ... />);
  // console.log(w.debug());
  expect(mountToJson(w)).toMatchSnapshot();

can you give some pointers to identify the issue without a test repo :-)

thanks.
bsr.

TypeError: renderedChildren[key].getPublicInstance is not a function

      at node_modules/enzyme/build/MountedTraversal.js:153:40
      at Array.map (native)
      at node_modules/enzyme/build/MountedTraversal.js:149:12
      at childrenOfInstInternal (node_modules/enzyme/build/MountedTraversal.js:156:6)
      at childrenOfInstInternal (node_modules/enzyme/build/MountedTraversal.js:160:12)
      at childrenOfInst (node_modules/enzyme/build/MountedTraversal.js:179:10)
      at ReactWrapper.<anonymous> (node_modules/enzyme/build/ReactWrapper.js:818:55)
      at node_modules/enzyme/build/ReactWrapper.js:1190:21
      at Array.map (native)
      at ReactWrapper.flatMap (node_modules/enzyme/build/ReactWrapper.js:1189:32)
      at ReactWrapper.children (node_modules/enzyme/build/ReactWrapper.js:817:32)
      at shallowToJson (node_modules/enzyme-to-json/build/index.js:33:52)
      at ReactWrapper.<anonymous> (node_modules/enzyme-to-json/build/index.js:34:16)
      at node_modules/enzyme/build/ReactWrapper.js:1043:21
      at Array.map (native)
      at ReactWrapper.map (node_modules/enzyme/build/ReactWrapper.js:1042:27)
      at shallowToJson (node_modules/enzyme-to-json/build/index.js:33:63)
      at ReactWrapper.<anonymous> (node_modules/enzyme-to-json/build/index.js:34:16)
      at node_modules/enzyme/build/ReactWrapper.js:1043:21
      at Array.map (native)
      at ReactWrapper.map (node_modules/enzyme/build/ReactWrapper.js:1042:27)
      at shallowToJson (node_modules/enzyme-to-json/build/index.js:33:63)
      at ReactWrapper.<anonymous> (node_modules/enzyme-to-json/build/index.js:34:16)
      at node_modules/enzyme/build/ReactWrapper.js:1043:21
      at Array.map (native)
      at ReactWrapper.map (node_modules/enzyme/build/ReactWrapper.js:1042:27)
      at shallowToJson (node_modules/enzyme-to-json/build/index.js:33:63)
      at ReactWrapper.<anonymous> (node_modules/enzyme-to-json/build/index.js:34:16)
      at node_modules/enzyme/build/ReactWrapper.js:1043:21
      at Array.map (native)
      at ReactWrapper.map (node_modules/enzyme/build/ReactWrapper.js:1042:27)
      at shallowToJson (node_modules/enzyme-to-json/build/index.js:33:63)
      at ReactWrapper.<anonymous> (node_modules/enzyme-to-json/build/index.js:34:16)
      at node_modules/enzyme/build/ReactWrapper.js:1043:21
      at Array.map (native)
      at ReactWrapper.map (node_modules/enzyme/build/ReactWrapper.js:1042:27)
      at shallowToJson (node_modules/enzyme-to-json/build/index.js:33:63)
      at ReactWrapper.<anonymous> (node_modules/enzyme-to-json/build/index.js:34:16)
      at node_modules/enzyme/build/ReactWrapper.js:1043:21
      at Array.map (native)
      at ReactWrapper.map (node_modules/enzyme/build/ReactWrapper.js:1042:27)
      at shallowToJson (node_modules/enzyme-to-json/build/index.js:33:63)

@mark0978
Copy link

mark0978 commented Sep 22, 2016

This is actually a problem in enzyme, however I've been unable to fix it. I do I have a test that provokes the problem. I'll have a PR up shortly. The problem is in knowing what MountedTraversal:childrenOfInstInternal should return at certain points.

// called with a private instance
export function childrenOfInstInternal(inst) {
  if (!inst) {
    return [];
  }
  if (!inst.getPublicInstance) {
    const internal = internalInstance(inst);
    return childrenOfInstInternal(internal);
  }

  const publicInst = inst.getPublicInstance();
  const currentElement = inst._currentElement;
  if (isDOMComponent(publicInst)) {
    const renderedChildren = renderedChildrenOfInst(inst);
    return Object.keys(renderedChildren || {}).filter((key) => {
      if (REACT013 && !renderedChildren[key].getPublicInstance) {
        return false;
      }
      return true;
    }).map(key => {
      if (!REACT013 && typeof renderedChildren[key]._currentElement.type === 'function') {
        return renderedChildren[key]._instance;
      }
    if(renderedChildren[key].getPublicInstance) {
        return renderedChildren[key].getPublicInstance();
    }
        // Here's the problem:
        //  Neither of these really work
    return null; //childrenOfInstInternal(internalInstance(renderedChildren[key]));
    });
  } else if (
    !REACT013 &&
    isElement(currentElement) &&
    typeof currentElement.type === 'function'
  ) {
    return childrenOfInstInternal(inst._renderedComponent);
  } else if (
    REACT013 &&
    isCompositeComponent(publicInst)
  ) {
    return childrenOfInstInternal(inst._renderedComponent);
  }
  return [];
}

One of the choices truncates the tree, another causes a different fatal error.

@adriantoine
Copy link
Owner

Hi!
Thanks for raising the issue, I'll have a look as soon as I can!

@adriantoine
Copy link
Owner

adriantoine commented Sep 22, 2016

From @mark0978's provided example, this fails:

<div>
  <div></div>
  <div>B<span></span></div>
</div>

but this works:

<div>
  <div></div>
  <div>B</div>
</div>

It seems like wrapper.children() from Enzyme fails for one of the children nodes in this particular case.

EDIT: Narrowing down the issue, this is enough to reproduce the issue:

const mounted = mount(<div>B<span></span></div>);
expect(mountToJson(mounted)).toMatchSnapshot();

Probably because of the text node being next to the span.

@adriantoine
Copy link
Owner

Actually just running this:

mount(<div>B<span></span></div>).children();

provokes the error, and it doesn't involve our library, so that looks like an Enzyme issue. 🤔

@bsr203
Copy link
Author

bsr203 commented Sep 22, 2016

thanks. do you mind raising an issue there. Hopefully you can explain better on what the desired output, ... thanks again for your quick response.

@adriantoine
Copy link
Owner

Yeah I will raise an issue in Enzyme and look at making this plugin work as closely as possible to wrapper.debug(), because mount(<div>B<span></span></div>).debug() works and shows the correct output.

@adriantoine
Copy link
Owner

The issue is being solved on Enzyme side see: enzymejs/enzyme#603 and enzymejs/enzyme#604

@bsr203
Copy link
Author

bsr203 commented Sep 22, 2016

thanks. I been watching that issue. you guys are awesome :-)
can't wait to get it all working.

@bsr203
Copy link
Author

bsr203 commented Sep 23, 2016

@adriantoine I patched my enzyme with the changes enzymejs/enzyme#604 and it worked well.
But, when I compares with react-test-renderer output, I see the snapshot though enzyme-to-json contains all the HOC and other react components. This causes two issues

  1. huge snapshot file and it is hard to see the changes in the diff.
  2. change in source code which doesn't affect the dom (extra props, refactor to multiple component, ..) cause cause the test to fail.

Is there a way to consider only the real dom nodes?

thanks.

@adriantoine
Copy link
Owner

adriantoine commented Sep 23, 2016

Hi @bsr203,

Thanks for the suggestions, can you open that in another github issue? I'll close this one when the issue is fixed in Enzyme 😊

@adriantoine
Copy link
Owner

FYI the exception won't be there in v1.1.3 but the Snapshot output is still wrong in this particular case.

This test:

const mounted = mount(<div>B<span></span></div>);
expect(mountToJson(mounted)).toMatchSnapshot();

Gives this snapshot:

<div>
  <span />
</div>

So the B text element is somehow lost 🤔

@adriantoine
Copy link
Owner

I don't think this bug occurs anymore, if it does, feel free to leave a comment here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants