Standardize on Enzyme shallow rendering (#104)

Summary:
This commit moves our existing frontend tests to use Enzyme’s shallow
rendering API <http://airbnb.io/enzyme/docs/api/shallow.html>. The
benefit over also using `react-test-renderer` is simply consistency (the
two are functionally equivalent); the benefits over `mount` are that
subcomponents cannot contaminate the test state (i.e., you’re only
testing one component at a time), that the resulting snapshots are more
readable because the root props are not shown, and that the
implementation is more efficient. This is a follow-up to #102.

In a case where we actually need a full DOM tree, we should still feel
free to use `mount`, but we haven’t needed that yet.

Test Plan:
Verify that the new `ContributionList.test.js.snap` represents the same
data as the old one.

wchargin-branch: standardize-enzyme-shallow
This commit is contained in:
William Chargin 2018-03-21 18:28:06 -07:00 committed by GitHub
parent feac85ad2c
commit 8fdf758cb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 245 additions and 383 deletions

View File

@ -43,7 +43,6 @@
"react": "^16.2.0",
"react-dev-utils": "^5.0.0",
"react-dom": "^16.2.0",
"react-test-renderer": "^16.2.0",
"style-loader": "0.19.0",
"sw-precache-webpack-plugin": "0.11.4",
"url-loader": "0.6.2",

View File

@ -2,7 +2,7 @@
import type {ReactWrapper} from "enzyme";
import React from "react";
import {mount} from "enzyme";
import {shallow} from "enzyme";
import enzymeToJSON from "enzyme-to-json";
import type {Address} from "../../../core/address";
@ -157,7 +157,7 @@ describe("ContributionList", () => {
// Render a contribution list with the above test data.
function render() {
const data = createTestData();
const result = mount(
const result = shallow(
<ContributionList graph={data.graph()} adapters={data.adapters()} />
);
return result;

View File

@ -1,391 +1,251 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ContributionList renders some test data in the default state 1`] = `
<ContributionList
adapters={
AdapterSet {
"adapters": Object {
"sourcecred/example-plugin-a": Object {
"extractTitle": [Function],
"extractType": [Function],
"pluginName": "sourcecred/example-plugin-a",
"renderer": [Function],
},
"sourcecred/example-plugin-b": Object {
"extractTitle": [Function],
"extractType": [Function],
"pluginName": "sourcecred/example-plugin-b",
"renderer": [Function],
},
},
}
}
graph={
Object {
"edges": Object {
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"one-to-two\\"}": Object {
"dst": Object {
"id": "two",
"pluginName": "sourcecred/example-plugin-a",
"repositoryName": "sourcecred/tests",
},
"payload": null,
"src": Object {
"id": "one",
"pluginName": "sourcecred/example-plugin-a",
"repositoryName": "sourcecred/tests",
},
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-c\\",\\"id\\":\\"four-to-three\\"}": Object {
"dst": Object {
"id": "three",
"pluginName": "sourcecred/example-plugin-a",
"repositoryName": "sourcecred/tests",
},
"payload": null,
"src": Object {
"id": "four",
"pluginName": "sourcecred/example-plugin-b",
"repositoryName": "sourcecred/tests",
},
},
},
"nodes": Object {
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"one\\"}": Object {
"payload": 111,
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"three\\"}": Object {
"payload": 616,
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"two\\"}": Object {
"payload": 234,
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-b\\",\\"id\\":\\"four\\"}": Object {
"payload": true,
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-c\\",\\"id\\":\\"five\\"}": Object {
"payload": "I have no adapter :-(",
},
},
}
}
>
<div>
<h2>
Contributions
</h2>
<label>
Filter by contribution type:
<select
onChange={[Function]}
<div>
<h2>
Contributions
</h2>
<label>
Filter by contribution type:
<select
onChange={[Function]}
value="null"
>
<option
value="null"
>
<option
value="null"
>
Show all
</option>
<option
disabled={true}
key="sourcecred/example-plugin-a"
style={
Object {
"fontWeight": "bold",
}
Show all
</option>
<option
disabled={true}
key="sourcecred/example-plugin-a"
style={
Object {
"fontWeight": "bold",
}
>
sourcecred/example-plugin-a
</option>
<option
key="big"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"type\\":\\"big\\"}"
>
big
</option>
<option
key="small"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"type\\":\\"small\\"}"
>
small
</option>
<option
disabled={true}
key="sourcecred/example-plugin-b"
style={
Object {
"fontWeight": "bold",
}
}
>
sourcecred/example-plugin-a
</option>
<option
key="big"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"type\\":\\"big\\"}"
>
big
</option>
<option
key="small"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"type\\":\\"small\\"}"
>
small
</option>
<option
disabled={true}
key="sourcecred/example-plugin-b"
style={
Object {
"fontWeight": "bold",
}
}
>
sourcecred/example-plugin-b
</option>
<option
key="very true"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-b\\",\\"type\\":\\"very true\\"}"
>
very true
</option>
</select>
</label>
<table>
<thead>
<tr>
<th>
Title
</th>
<th>
Artifact
</th>
<th>
Weight
</th>
</tr>
</thead>
<tbody>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"one\\"}"
>
<td>
the number 111
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"two\\"}"
>
<td>
the number 234
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"three\\"}"
>
<td>
the number 616
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-b\\",\\"id\\":\\"four\\"}"
>
<td>
TRUE!
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-c\\",\\"id\\":\\"five\\"}"
>
<td
colSpan={3}
>
sourcecred/example-plugin-b
</option>
<option
key="very true"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-b\\",\\"type\\":\\"very true\\"}"
>
very true
</option>
</select>
</label>
<table>
<thead>
<tr>
<th>
Title
</th>
<th>
Artifact
</th>
<th>
Weight
</th>
</tr>
</thead>
<tbody>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"one\\"}"
>
<td>
the number 111
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"two\\"}"
>
<td>
the number 234
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"three\\"}"
>
<td>
the number 616
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-b\\",\\"id\\":\\"four\\"}"
>
<td>
TRUE!
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-c\\",\\"id\\":\\"five\\"}"
>
<td
colSpan={3}
>
<i>
unknown
</i>
(plugin:
sourcecred/example-plugin-c
)
</td>
</tr>
</tbody>
</table>
</div>
</ContributionList>
<i>
unknown
</i>
(plugin:
sourcecred/example-plugin-c
)
</td>
</tr>
</tbody>
</table>
</div>
`;
exports[`ContributionList updates the node table when a filter is selected 1`] = `
<ContributionList
adapters={
AdapterSet {
"adapters": Object {
"sourcecred/example-plugin-a": Object {
"extractTitle": [Function],
"extractType": [Function],
"pluginName": "sourcecred/example-plugin-a",
"renderer": [Function],
},
"sourcecred/example-plugin-b": Object {
"extractTitle": [Function],
"extractType": [Function],
"pluginName": "sourcecred/example-plugin-b",
"renderer": [Function],
},
},
}
}
graph={
Object {
"edges": Object {
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"one-to-two\\"}": Object {
"dst": Object {
"id": "two",
"pluginName": "sourcecred/example-plugin-a",
"repositoryName": "sourcecred/tests",
},
"payload": null,
"src": Object {
"id": "one",
"pluginName": "sourcecred/example-plugin-a",
"repositoryName": "sourcecred/tests",
},
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-c\\",\\"id\\":\\"four-to-three\\"}": Object {
"dst": Object {
"id": "three",
"pluginName": "sourcecred/example-plugin-a",
"repositoryName": "sourcecred/tests",
},
"payload": null,
"src": Object {
"id": "four",
"pluginName": "sourcecred/example-plugin-b",
"repositoryName": "sourcecred/tests",
},
},
},
"nodes": Object {
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"one\\"}": Object {
"payload": 111,
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"three\\"}": Object {
"payload": 616,
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"two\\"}": Object {
"payload": 234,
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-b\\",\\"id\\":\\"four\\"}": Object {
"payload": true,
},
"{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-c\\",\\"id\\":\\"five\\"}": Object {
"payload": "I have no adapter :-(",
},
},
}
}
>
<div>
<h2>
Contributions
</h2>
<label>
Filter by contribution type:
<select
onChange={[Function]}
<div>
<h2>
Contributions
</h2>
<label>
Filter by contribution type:
<select
onChange={[Function]}
value="{\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"type\\":\\"small\\"}"
>
<option
value="null"
>
Show all
</option>
<option
disabled={true}
key="sourcecred/example-plugin-a"
style={
Object {
"fontWeight": "bold",
}
}
>
sourcecred/example-plugin-a
</option>
<option
key="big"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"type\\":\\"big\\"}"
>
big
</option>
<option
key="small"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"type\\":\\"small\\"}"
>
<option
value="null"
>
Show all
</option>
<option
disabled={true}
key="sourcecred/example-plugin-a"
style={
Object {
"fontWeight": "bold",
}
small
</option>
<option
disabled={true}
key="sourcecred/example-plugin-b"
style={
Object {
"fontWeight": "bold",
}
>
sourcecred/example-plugin-a
</option>
<option
key="big"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"type\\":\\"big\\"}"
>
big
</option>
<option
key="small"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"type\\":\\"small\\"}"
>
small
</option>
<option
disabled={true}
key="sourcecred/example-plugin-b"
style={
Object {
"fontWeight": "bold",
}
}
>
sourcecred/example-plugin-b
</option>
<option
key="very true"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-b\\",\\"type\\":\\"very true\\"}"
>
very true
</option>
</select>
</label>
<table>
<thead>
<tr>
<th>
Title
</th>
<th>
Artifact
</th>
<th>
Weight
</th>
</tr>
</thead>
<tbody>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"one\\"}"
>
<td>
the number 111
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"two\\"}"
>
<td>
the number 234
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
</tbody>
</table>
</div>
</ContributionList>
}
>
sourcecred/example-plugin-b
</option>
<option
key="very true"
value="{\\"pluginName\\":\\"sourcecred/example-plugin-b\\",\\"type\\":\\"very true\\"}"
>
very true
</option>
</select>
</label>
<table>
<thead>
<tr>
<th>
Title
</th>
<th>
Artifact
</th>
<th>
Weight
</th>
</tr>
</thead>
<tbody>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"one\\"}"
>
<td>
the number 111
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
<tr
key="{\\"repositoryName\\":\\"sourcecred/tests\\",\\"pluginName\\":\\"sourcecred/example-plugin-a\\",\\"id\\":\\"two\\"}"
>
<td>
the number 234
</td>
<td>
[TODO]
</td>
<td>
[TODO]
</td>
</tr>
</tbody>
</table>
</div>
`;

View File

@ -1,7 +1,8 @@
// @flow
import React from "react";
import reactTestRenderer from "react-test-renderer";
import {shallow} from "enzyme";
import enzymeToJSON from "enzyme-to-json";
import stringify from "json-stable-stringify";
import type {NodeID} from "../../../github/githubPlugin";
@ -9,6 +10,8 @@ import {GithubParser} from "../../../github/githubPlugin";
import exampleRepoData from "../../../github/demoData/example-repo.json";
import adapter from "./githubPluginAdapter";
require("../testUtil").configureEnzyme();
describe("githubPluginAdapter", () => {
it("operates on the example repo", () => {
const parser = new GithubParser("sourcecred/example-repo");
@ -22,8 +25,8 @@ describe("githubPluginAdapter", () => {
payload: node.payload,
type: adapter.extractType(graph, node),
title: adapter.extractTitle(graph, node),
rendered: reactTestRenderer.create(
<adapter.renderer graph={graph} node={node} />
rendered: enzymeToJSON(
shallow(<adapter.renderer graph={graph} node={node} />)
),
}))
.sort((a, b) => {

View File

@ -5655,7 +5655,7 @@ react-reconciler@^0.7.0:
object-assign "^4.1.1"
prop-types "^15.6.0"
react-test-renderer@^16.0.0-0, react-test-renderer@^16.2.0:
react-test-renderer@^16.0.0-0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.2.0.tgz#bddf259a6b8fcd8555f012afc8eacc238872a211"
dependencies: