Is there any reason why user has to manually import react-test-renderer and render their React tree "by hand"?
import test from 'ava';
import React from 'react';
import renderer from 'react-test-renderer';
test('snapshots', t => {
const tree = renderer.create(<h1>Test</h1>).toJSON();
t.snapshot(tree);
});
We could bundle react-test-renderer and that test would become:
import test from 'ava';
import React from 'react';
test('snapshots', t => {
const tree = <h1>Test</h1>;
t.snapshot(tree);
});
...which is cleaner and nicer, imo.
Main reason for it is to also allow magic assert to do diffing on snapshots. Because trees in snapshots are not shallowly rendered (full trees are saved instead), we can't use react-element-to-jsx-string module, so we need react-test-renderer inside AVA either way.
What do you think?
Sounds like an easy win. I don't like how big its dependency tree is though. It brings with it 2.5MB of mostly unused dependencies...
What about projects that use JSX with another tool than React (Inferno, Preact, Snabbdom, ...)?
Hmm, good point. Would be great if we had a universal render-to-string package, that would detect React/Preact/Inferno/etc vnodes and render them to string.
Then t.jsxEqual() would be universal as well.
On the other hand though, t.jsxEqual(), diffs and syntax highlighting in magic assert are tied to React. Unfortunately we can't be "easily" universal at the moment.
Here are the possible routes we can go:
This way would be the most comfortable from the user's perspective, but the most time consuming and expensive in terms of maintenance for us.
Least preferable way for both users and AVA, despite being the easiest solution. For diffs users would use libraries like chai-jsx.
t.jsxEquals() and make it accept JSON tree, like in t.snapshot()This would make t.jsxEquals() compatible with every possible JSX-based library. I think this is best way to go. Developers can create similar libraries to react-test-renderer (converts JSX to JSON), which would allow AVA users to write tests with these libraries.
A shortcut could make it simpler to transform JSX for assertions:
import renderer from 'react-test-renderer';
const render = tree => renderer.create(tree).toJSON();
test('jsx', t => {
t.jsxEqual(render(<HelloNewYork/>), render(<HelloSanFrancisco/>));
});
Can we use a Babel plugin to solve this?
I don't think it can be reliably implemented, because we'd have to detect which library is imported (react/preact/inferno/etc) and import according react-test-renderer alternative (and I don't think there are any right now).
In my opinion, we could do just fine with the third option for a while. Minimal maintenance, universal compatibility.
Rephrasing yesterday's comment, now that I actually know what I meant to say…:
Could we support Babel plugins that rewrite t.jsxEqual() to automatically apply the JSON conversion? That way (assuming you don't mix JSX dialects within the same project) you don't need to do it manually. So option three, on steroids.
So steroids (babel plugins to transform JSX into JSON) are basically left for community to implement? Sure, why not? They can freely use any babel plugins in configuration.
Closing this, since the issue is now resolved.
Most helpful comment
What about projects that use JSX with another tool than React (Inferno, Preact, Snabbdom, ...)?