mzgoddard / preact-render-spy

Render preact components with access to the produced virtual dom for testing.

Home Page:https://www.npmjs.com/package/preact-render-spy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

target.className is null

tomascasas opened this issue · comments

let attr = target.class || target.className;
if (typeof attr === 'object') {

Upon a couple of context.render(<Component />) calls, when calling context.find('.class') I get an exception thrown since target.className is null and typeof null === 'object'.
I am tempted to say that the flow is expected to return false in the next if and for that to happen, previous check needs to exclude null values before checking typeof.

else if (!target || target[key] !== value) {
return false;
}

But I have to say that I don't know why target.className is null in the first place.

@tomascasas I think my changes in #49 might also fix this problem... Could you try using npm install git://github.com/mzgoddard/preact-render-spy#nodes and/or could you possibly write a failing test in our shared-render test suite?

@gnarf The issue still persists. The error triggers on is-where.js#72 cause target.className is null, so Object.keys(null) throws an exception:

attr = Object.keys(attr).filter(key => attr[key]);

@gnarf I just found that I have className set in the component to undefined and as a result preact might be initializing target.className to null

Alright, let me get that other one landed first then I will get this working. Any chance you could write a minimal failing test scenario to make this easier on me?

I think that you test case could include rendering something like this:

<div className={undefined}>test</div>

This test passes:

  it(`${name}: find by class works with null and undefined class and className`, () => {
    const context = func(<div class={null}>test</div>);
    expect(() => context.find('.test')).not.toThrow();

    context.render(<div className={null}>test</div>);
    expect(() => context.find('.test')).not.toThrow();

    context.render(<div class={undefined}>test</div>);
    expect(() => context.find('.test')).not.toThrow();

    context.render(<div className={undefined}>test</div>);
    expect(() => context.find('.test')).not.toThrow();
  });

I pushed up this test to a branch class-undefined - could you help me figure out how to make this fail the same way yours does?

Also can confirm that it passed on node 6, 7, and 8 on travis: https://travis-ci.org/mzgoddard/preact-render-spy/builds/287678078

@gnarf I am committing a failing test, that shares the same structure as my actual test and that fails, perhaps you can help me figure out if the way I am using your module needs some tuning.
Thank you very for following up, and sorry for this delayed response. Invested a long time trying to reproduce the issue, and finally did so.

@gnarf could not commit, these are my lines at the end of src/shared-render.test.js:

class NullClassName extends Component {
  constructor(props) {
    super(props);
    this.state = {className: null};
  }

  render({other}, {className}) {
    return (
      <DivChildren other={other}>
        <Div className={className} />
        <DivChildren className={'children'}>
          <ClickCount className={'counter'} />
        </DivChildren>
      </DivChildren>
    );
  }
}

describe('test multiple component re-renders', () => {
  const context = deep(<NullClassName />);
  context.render(<NullClassName other="attempt1"/>);
  context.render(<NullClassName other="attempt2"/>);
  expect(() => context.find('.children').find('.counter').simulate('click')).not.toThrow();
  context.render(<NullClassName other="attempt3"/>);
  expect(() => context.find('.children').find('.counter').simulate('click')).not.toThrow();
});

The error is not actually due to any of the searched nodes, but to <Div className={null}/>

Alright - check out the class-undefined branch again, I think I have your test case passing.

Will send in a PR for it after we land #49

@gnarf Problem fixed. Thank you so much!
PS: Sorry for the late response, was out this weekend.