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

How to simulate changing props on the container?

gnarf opened this issue · comments

Some components need to react on componentWillReceiveProps how would we test that with this interface?

The returned wrapper has a render method that takes a new top level dom. preact should retain the top level component instance and call componentWIllReceiveProps.

const spy = renderSpy(<Node count="1" />);
spy.render(<Node count="2" />);

componentWillReceiveProps can then set the state and its new render can include some value of that state to test against.

It may be useful for us to clarify this functionality by changing the interface to

const spy = renderSpy().render(<Node count="1" />);

Making the render method more obvious?

I think documentation can cover that case, renderSpy(jsx) is too convenient, even if it is just a fancy alias for renderSpy().render(jsx)

Did you already have a test case covering this re-render / will receive props?

re-render, not receive props. but the render returns the props. can totes add a test for this lifecycle bit.

it('renders changes', async () => {
class Node extends Component {
render({className}) {
return <div class={className} />;
}
}
const context = renderSpy(<Node className="node" />);
context.render(<Node className="node2" />);
expect(context.find('.node2').length).toBe(1);
expect(context.find('div')[0]).toEqual(<div class="node2" />);
});

Yeah, lets assert that preact did the right thing re-rendering using the same component instance by testing that the component received the props

Ah there is an issue with how it currently tracks generated vdom to its node in the parent vdom. Every thing gets a unique Spy class/function. Which will mean a new render will destroy and recreate the whole dom because every nodeName is different than the last ones.

The trickiest thing to this is knowing what generated vdom connects to what parent. We could add a private key to the attributes in the vdom that'll end up in the props of the component. That could well be fine since that would be in the spied dom that we are already modifying. And that the vdom returned to the user is the unmodified one they passed.

Err no didn't think that far enough. The Spy will received the polluted props. Meaning the Component will receive the polluted props. Hmm.

Ah. We could replace the polluted props in constructor and componentWillReceiveProps with the original? Hmm. Tricky. Since the props is created from vdom by putting childing in an object with the attributes of the vdom node. Maybe its enough to create a new object with all keys but the private identifier.

Would it serve well enough to just memoize the resulting class from spy wrapping?

I should improve on that answer. Memoify is part of the solution. We do need to do that. But then to support normal use, we need to support multiple instances of the same type which we can do by adding a hidden key.