Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added .props() and .render() to trigger re-renders
- Loading branch information
1 parent
93b4669
commit 0d94f46
Showing
12 changed files
with
230 additions
and
9 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import $ from "../constructor"; | ||
import { act } from "react-dom/test-utils"; | ||
|
||
$.prototype.props = function (props) { | ||
const container = this.nodes[0].closest("#root"); | ||
const component = container.component; | ||
const root = container.root; | ||
if (typeof props === "function") { | ||
props = props(component.props); | ||
} | ||
act(() => root.render({ ...component, props })); | ||
this.nodes = [...container.childNodes]; | ||
return this; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
### .props() | ||
|
||
```js | ||
.props(newProps) -> $ | ||
``` | ||
|
||
Rerender the component with the new specified props. | ||
|
||
```js | ||
const Demo = (props) => <div {...props}>world</div>; | ||
|
||
it("can force-update the props on the root", () => { | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveHtml(`<div class="hello">world</div>`); | ||
// Rerender with a new className on the top component: | ||
demo.props({ className: "bye" }); | ||
expect(demo).toHaveHtml(`<div class="bye">world</div>`); | ||
}); | ||
``` | ||
|
||
#### Parameters | ||
|
||
`newProps`: the props to pass to the component in a new re-render. It can be either a plain object, or a function that will receive the old props and should return the new props. | ||
|
||
#### Return | ||
|
||
An instance of React Test that has re-rendered with the new props. | ||
|
||
#### Examples | ||
|
||
Update the prop className: | ||
|
||
```js | ||
const Demo = ({ className }) => <div className={className}>world</div>; | ||
|
||
it("can inject new props", async () => { | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveHtml(`<div class="hello">world</div>`); | ||
demo.props({ className: "bye" }); | ||
expect(demo).toHaveHtml(`<div class="bye">world</div>`); | ||
}); | ||
|
||
it("can accept the old props", async () => { | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveHtml(`<div class="hello">world</div>`); | ||
demo.props((p) => ({ className: p.className + "-bye" })); | ||
expect(demo).toHaveHtml(`<div class="hello-bye">world</div>`); | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import $ from "../../"; | ||
import "babel-polyfill"; | ||
|
||
const Demo = ({ className }) => <div className={className}>world</div>; | ||
|
||
describe(".props()", () => { | ||
it("can render a simple string", async () => { | ||
expect($(<Demo />)).toHaveHtml("<div>world</div>"); | ||
}); | ||
|
||
it("can inject new props", async () => { | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveHtml(`<div class="hello">world</div>`); | ||
demo.props({ className: "bye" }); | ||
expect(demo).toHaveHtml(`<div class="bye">world</div>`); | ||
}); | ||
|
||
it("can accept the old props", async () => { | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveHtml(`<div class="hello">world</div>`); | ||
demo.props((p) => ({ className: p.className + "-bye" })); | ||
expect(demo).toHaveHtml(`<div class="hello-bye">world</div>`); | ||
}); | ||
|
||
it("has continuity", () => { | ||
const Demo = ({ className }) => { | ||
const [state, setState] = useState(0); | ||
useEffect(() => { | ||
setState((s) => s + 1); | ||
}, [className]); | ||
return <div>{state}</div>; | ||
}; | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveText(`1`); | ||
demo.props({ className: "bye" }); | ||
expect(demo).toHaveText(`2`); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import $ from "../constructor"; | ||
import { act } from "react-dom/test-utils"; | ||
|
||
$.prototype.render = function (component) { | ||
const container = this.nodes[0].closest("#root"); | ||
const root = container.root; | ||
act(() => root.render(component)); | ||
this.nodes = [...container.childNodes]; | ||
return this; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
### .render() | ||
|
||
```js | ||
.render(newComponent) -> $ | ||
``` | ||
|
||
Rerender the component as specified with the new value, or unmount/mount the new component. | ||
|
||
```js | ||
const Demo = (props) => <div {...props}>world</div>; | ||
|
||
it("can force-update the props on the root", () => { | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveHtml(`<div class="hello">world</div>`); | ||
// Rerender with a new className on the top component: | ||
demo.props(<Demo className="bye" />); | ||
expect(demo).toHaveHtml(`<div class="bye">world</div>`); | ||
}); | ||
``` | ||
|
||
> Note: if you only want to re-render changing the props, you might prefer using [`.props()`](#props). | ||
#### Parameters | ||
|
||
`newComponent`: the new component to render in place of the old one. If it's the same component, it'll trigger a re-render, otherwise it'll unmount the old one and mount the new one. | ||
|
||
#### Return | ||
|
||
An instance of React Test that has re-rendered with the new component. | ||
|
||
#### Examples | ||
|
||
Rerender with a new prop: | ||
|
||
```js | ||
const Demo = ({ className }) => <div className={className}>world</div>; | ||
|
||
it("can inject new props", async () => { | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveHtml(`<div class="hello">world</div>`); | ||
demo.render(<Demo className="bye" />); | ||
expect(demo).toHaveHtml(`<div class="bye">world</div>`); | ||
}); | ||
|
||
it("can render a different component", () => { | ||
const demo = $(<div>Hello</div>); | ||
expect(demo).toHaveHtml(`<div>Hello</div>`); | ||
demo.render(<span>Bye</span>); | ||
expect(demo).toHaveHtml(`<span>Bye</span>`); | ||
}); | ||
``` | ||
|
||
#### Notes | ||
|
||
Do not reuse a root node (by using this `.render()`) more than necessary (e.g. testing rerenders); instead create a raw instance of a component with `$()` as usual for testing new components. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import $ from "../../"; | ||
import "babel-polyfill"; | ||
|
||
const Demo = ({ className }) => <div className={className}>world</div>; | ||
|
||
describe(".render()", () => { | ||
it("can render a simple string", async () => { | ||
expect($(<Demo />)).toHaveHtml("<div>world</div>"); | ||
}); | ||
|
||
it("can render with new data", async () => { | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveHtml(`<div class="hello">world</div>`); | ||
demo.render(<Demo className="bye" />); | ||
expect(demo).toHaveHtml(`<div class="bye">world</div>`); | ||
}); | ||
|
||
it("has continuity", () => { | ||
const Demo = ({ className }) => { | ||
const [state, setState] = useState(0); | ||
useEffect(() => { | ||
setState((s) => s + 1); | ||
}, [className]); | ||
return <div>{state}</div>; | ||
}; | ||
const demo = $(<Demo className="hello" />); | ||
expect(demo).toHaveText(`1`); | ||
demo.render(<Demo className="bye" />); | ||
expect(demo).toHaveText(`2`); | ||
}); | ||
|
||
it("can render a different component", () => { | ||
const demo = $(<div>Hello</div>); | ||
expect(demo).toHaveHtml(`<div>Hello</div>`); | ||
demo.render(<span>Bye</span>); | ||
expect(demo).toHaveHtml(`<span>Bye</span>`); | ||
}); | ||
}); |