├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.yml
├── .github
└── workflows
│ ├── ci-node-10.yml
│ ├── ci-node-12.yml
│ └── ci-node-8.yml
├── .gitignore
├── .npmignore
├── .prettierignore
├── .prettierrc.yml
├── History.md
├── LICENSE
├── README.md
├── package.json
├── specs
├── find-all-with-class.spec.js
├── find-all-with-type.spec.js
├── find-all.spec.js
├── find-with-class.spec.js
├── find-with-ref.spec.js
├── find-with-type.spec.js
├── is-component-of-type.spec.js
└── is-dom-component.spec.js
└── src
├── find-all-with-class.js
├── find-all-with-type.js
├── find-all.js
├── find-with-class.js
├── find-with-ref.js
├── find-with-type.js
├── index.js
├── is-component-of-type.js
└── is-dom-component.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["@babel/plugin-proposal-export-default-from"],
3 | "presets": [
4 | [
5 | "@babel/preset-env",
6 | {
7 | "targets": {
8 | "node": "8"
9 | }
10 | }
11 | ],
12 | "@babel/preset-react"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/**/*
2 | lib/**/*.*
3 |
--------------------------------------------------------------------------------
/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | parser: babel-eslint
2 |
3 | extends:
4 | - airbnb
5 | - prettier
6 | - prettier/react
7 |
8 | env:
9 | browser: true
10 | jest: true
11 | node: true
12 |
13 | rules:
14 | react/jsx-filename-extension:
15 | - 1
16 | - extensions:
17 | - ".js"
18 | - ".jsx"
19 |
--------------------------------------------------------------------------------
/.github/workflows/ci-node-10.yml:
--------------------------------------------------------------------------------
1 | name: CI on Node 10
2 |
3 | on: [push]
4 |
5 | jobs:
6 | test:
7 | name: Test on Node 10
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v1
11 | - uses: docker://node:10-alpine
12 | name: Install
13 | with:
14 | entrypoint: yarn
15 | args: install --pure-lockfile --audit
16 | - uses: docker://node:10-alpine
17 | name: Lint
18 | with:
19 | entrypoint: yarn
20 | args: lint
21 | - uses: docker://node:10-alpine
22 | name: Test
23 | with:
24 | entrypoint: yarn
25 | args: test
26 |
--------------------------------------------------------------------------------
/.github/workflows/ci-node-12.yml:
--------------------------------------------------------------------------------
1 | name: CI on Node 12
2 |
3 | on: [push]
4 |
5 | jobs:
6 | test:
7 | name: Test on Node 12
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v1
11 | - uses: docker://node:12-alpine
12 | name: Install
13 | with:
14 | entrypoint: yarn
15 | args: install --pure-lockfile --audit
16 | - uses: docker://node:12-alpine
17 | name: Lint
18 | with:
19 | entrypoint: yarn
20 | args: lint
21 | - uses: docker://node:12-alpine
22 | name: Test
23 | with:
24 | entrypoint: yarn
25 | args: test
26 |
--------------------------------------------------------------------------------
/.github/workflows/ci-node-8.yml:
--------------------------------------------------------------------------------
1 | name: CI on Node 8
2 |
3 | on: [push]
4 |
5 | jobs:
6 | test:
7 | name: Test on Node 8
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v1
11 | - uses: docker://node:8-alpine
12 | name: Install
13 | with:
14 | entrypoint: yarn
15 | args: install --pure-lockfile --audit
16 | - uses: docker://node:8-alpine
17 | name: Lint
18 | with:
19 | entrypoint: yarn
20 | args: lint
21 | - uses: docker://node:8-alpine
22 | name: Test
23 | with:
24 | entrypoint: yarn
25 | args: test
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # node-waf configuration
20 | .lock-wscript
21 |
22 | # Compiled binary addons (http://nodejs.org/api/addons.html)
23 | build/Release
24 |
25 | # Dependency directory
26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
27 | node_modules
28 |
29 | lib
30 |
31 | .eslintcache
32 |
33 | yarn.lock
34 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .babelrc
2 | .eslintrc
3 | .eslintcache
4 | .eslintignore
5 | .editorconfig
6 | specs/
7 | src/
8 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | package.json
2 |
--------------------------------------------------------------------------------
/.prettierrc.yml:
--------------------------------------------------------------------------------
1 | jsxBracketSameLine: true
2 | trailingComma: all
3 |
--------------------------------------------------------------------------------
/History.md:
--------------------------------------------------------------------------------
1 | # v3.0.1 / 2017-12-08
2 |
3 | Update peerDependencies to allow React 16
4 | Update dependencies
5 |
6 | # v3.0.0 / 2017-04-26
7 |
8 | Updated to `react@15.5.4`
9 |
10 | # v2.0.0 / 2016-04-21
11 |
12 | No changes from v2.0.0-beta1
13 |
14 | # v2.0.0-beta1 / 2016-04-09
15 |
16 | Updated to `react@15` [#30](https://github.com/sheepsteak/react-shallow-testutils/pull/30)
17 | Updated ESLint and Babel
18 | Added `npm run clean` command
19 |
20 | # v1.0.0 / 2016-01-22
21 |
22 | Updated to Babel 6 [#15](https://github.com/sheepsteak/react-shallow-testutils/pull/15)
23 |
24 | # v0.7.1 / 2015-12-07
25 |
26 | Fixed forgetting to add export for `findWithRef`
27 |
28 | # v0.7.0 / 2015-12-07
29 |
30 | Added `findWithRef` [#13](https://github.com/sheepsteak/react-shallow-testutils/pull/13) ([@rkovacevic](https://github.com/rkovacevic))
31 |
32 | # v0.6.1 / 2015-11-17
33 |
34 | Fixed `findAllWithClass` to not use `String.includes` #12
35 |
36 | # v0.6.0 / 2015-10-15
37 |
38 | _Contains a breaking change by removing `Renderer`_
39 |
40 | Removed `Renderer` as it's no longer needed with React 0.14 #10
41 | Added `getMountedInstance` function to retreive the root component from renderer #10
42 | Added `pre-commit` hook that checks linting and tests #9
43 |
44 | # v0.5.0 / 2015-10-08
45 |
46 | _Contains a breaking change by using React 0.14_
47 |
48 | Updated to React 0.14 #8 (plus help from @themouette #2)
49 |
50 | # 0.4.0 / 2015-10-08
51 |
52 | _Contains a breaking change to `Renderer`_
53 |
54 | Changed `render` of `Renderer` to now take a function #6
55 |
56 | # 0.3.0 / 2015-09-13
57 |
58 | Add support for multiple class names @stefanbuck #4
59 |
60 | # 0.2.1 / 2015-07-22
61 |
62 | Fixed space in package.json entry point
63 |
64 | # 0.2.0 / 2015-07-20
65 |
66 | Added more documentation
67 | Added `isComponentOfType`
68 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Chris Shepherd
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-shallow-testutils
2 |
3 | Replacement for TestUtils when using React's shallow rendering.
4 |
5 | [](https://www.npmjs.com/package/react-shallow-testutils)
6 |
7 | ```
8 | npm install react-shallow-testutils
9 | ```
10 |
11 | ## React Versions
12 |
13 | | Version | React version |
14 | | ------- | ------------- |
15 | | 0.4.0 | 0.13 |
16 | | 0.5.0 | 0.14 |
17 | | 2.0.0 | 15 |
18 | | 3.0.0 | 15.5.4 |
19 | | 3.0.1 | ^15.5.4 & ^16 |
20 |
21 | ## Usage
22 |
23 | All the functions are exported separately. This means you can pull in just the ones you want like this:
24 |
25 | ```javascript
26 | import {findWithType, findWithClass} from 'react-shallow-testutils';
27 |
28 | findWithType(tree, …);
29 | ```
30 |
31 | However, if you want everything then you can do this:
32 |
33 | ```javascript
34 | import * as ShallowTestUtils from 'react-shallow-testutils';
35 |
36 | ShallowTestUtils.findWithType(tree, …);
37 | ```
38 |
39 | ### isComponentOfType
40 |
41 | Returns whether a `ReactElement` is of a particular type.
42 |
43 | ```javascript
44 | boolean isComponentOfType(ReactElement element, function componentClass | string tagName)
45 | ```
46 |
47 | ```javascript
48 | import React from "react";
49 | import { createRenderer } from "react-test-renderer/shallow";
50 | import { isComponentOfType } from "react-shallow-testutils";
51 |
52 | function MyOtherComponent() {
53 | return
;
54 | }
55 |
56 | function MyComponent() {
57 | return ;
58 | }
59 |
60 | const renderer = createRenderer();
61 |
62 | const tree1 = renderer.render();
63 | expect(isComponentOfType(tree1, OtherComponent)).toBe(true);
64 |
65 | const tree2 = renderer.render();
66 | expect(isComponentOfType(tree2, "div")).toBe(true);
67 | ```
68 |
69 | ### isDOMComponent
70 |
71 | Returns whether the supplied `ReactElement` is a DOM component or not
72 |
73 | ```javascript
74 | boolean isDOMComponent(ReactElement element)
75 | ```
76 |
77 | ```javascript
78 | import React from "react";
79 | import { createRenderer } from "react-test-renderer/shallow";
80 | import { isDOMComponent } from "react-shallow-testutils";
81 |
82 | function MyComponent() {
83 | return ;
84 | }
85 |
86 | const renderer = createRenderer();
87 |
88 | const tree = renderer.render();
89 | expect(isDOMComponent(tree)).toBe(true);
90 | ```
91 |
92 | ### findAll
93 |
94 | Traverses the tree and returns all elements that satisfy the function `test`. A lot of the other functions are implemented in terms of this one.
95 |
96 | ```javascript
97 | array findAll(ReactElement tree, function test)
98 | ```
99 |
100 | ```javascript
101 | import React from "react";
102 | import { createRenderer } from "react-test-renderer/shallow";
103 | import { findAll } from "react-shallow-testutils";
104 |
105 | function MyComponent() {
106 | return (
107 |
108 |
109 |
110 |
111 |
112 | );
113 | }
114 |
115 | const renderer = createRenderer();
116 |
117 | const tree = renderer.render();
118 | const spans = findAll(tree, element => element.type === "span");
119 | expect(spans.length).toBe(3);
120 | ```
121 |
122 | ### findAllWithType
123 |
124 | Finds all instances of elements in the tree with a type that matches
125 | `type`. This is like both React's `scryRenderedDOMComponentsWithTag` and `scryRenderedComponentsWithType` as you can supply a component class or a DOM tag.
126 |
127 | ```javascript
128 | array findAllWithType(ReactElement tree, function componentClass | string tagName)
129 | ```
130 |
131 | ```javascript
132 | import React from "react";
133 | import { createRenderer } from "react-test-renderer/shallow";
134 | import { findAllWithType } from "react-shallow-testutils";
135 |
136 | function MyOtherComponent() {
137 | return ;
138 | }
139 |
140 | function MyComponent() {
141 | return (
142 |
143 |
144 |
145 |
146 |
147 | );
148 | }
149 |
150 | const renderer = createRenderer();
151 |
152 | const tree = renderer.render();
153 | expect(findAllWithType(tree, MyOtherComponent).length).toBe(1);
154 | expect(findAllWithType(tree, "span").length).toBe(2);
155 | ```
156 |
157 | ### findWithType
158 |
159 | Find only one instance of an element in the tree with a type that matches
160 | `type`. This is like both React's `findRenderedDOMComponentWithTag` and `findRenderedComponentWithType` as you can supply a component class or a DOM tag. It will throw an error if not exactly one instance is found.
161 |
162 | ```javascript
163 | ReactElement findWithType(ReactElement tree, function componentClass | string tagName)
164 | ```
165 |
166 | ```javascript
167 | import React from "react";
168 | import { createRenderer } from "react-test-renderer/shallow";
169 | import { findWithType } from "react-shallow-testutils";
170 |
171 | function MyOtherComponent() {
172 | return ;
173 | }
174 |
175 | function MyComponent() {
176 | return (
177 |
178 |
179 |
180 |
181 |
182 | );
183 | }
184 |
185 | const renderer = createRenderer();
186 |
187 | const tree = renderer.render();
188 | expect(findWithType(tree, MyOtherComponent)).not.toThrow();
189 | expect(findWithType(tree, "form")).toThrow();
190 | ```
191 |
192 | ### findAllWithClass
193 |
194 | Finds all elements in the tree with a `className` prop that matches `className`. This is different to React's `scryRenderedDOMComponentsWithClass` in that it will check **all** components and not just DOM components.
195 |
196 | You can pass a `className` like `test-class.test-class--modified` to find an element that has both classes.
197 |
198 | ```javascript
199 | array findAllWithClass(ReactElement tree, string className)
200 | ```
201 |
202 | ```javascript
203 | import React from "react";
204 | import { createRenderer } from "react-test-renderer/shallow";
205 | import { findAllWithClass } from "react-shallow-testutils";
206 |
207 | function MyOtherComponent() {
208 | return ;
209 | }
210 |
211 | function MyComponent() {
212 | return (
213 |
214 |
215 |
216 |
217 |
218 | );
219 | }
220 |
221 | const renderer = createRenderer();
222 |
223 | const tree = renderer.render();
224 | expect(findAllWithClass(tree, "my-div").length).toBe(0);
225 | expect(findAllWithClass(tree, "my-span").length).toBe(2);
226 | ```
227 |
228 | ### findWithClass
229 |
230 | Find only one element in the tree with a `className` prop that matches `className`. This is different to React's `findRenderedDOMComponentWithClass` in that it will check **all** components and not just DOM components. It will throw an error if not exactly one instance is found.
231 |
232 | You can pass a `className` like `test-class.test-class--modified` to find an element that has both classes.
233 |
234 | ```javascript
235 | ReactElement findWithClass(ReactElement tree, string className)
236 | ```
237 |
238 | ```javascript
239 | import React from "react";
240 | import { createRenderer } from "react-test-renderer/shallow";
241 | import { findWithClass } from "react-shallow-testutils";
242 |
243 | function MyOtherComponent() {
244 | return ;
245 | }
246 |
247 | function MyComponent() {
248 | return (
249 |
250 |
251 |
252 |
253 |
254 | );
255 | }
256 |
257 | const renderer = createRenderer();
258 |
259 | const tree = renderer.render();
260 | expect(findWithClass(tree, "my-div")).not.toThrow();
261 | expect(findWithClass(tree, "my-span")).toThrow(); // More than 1
262 | ```
263 |
264 | ### findWithRef
265 |
266 | Find only one element in the tree with a `ref` prop that matches `ref`. This is only useful for a `ref` that has been defined as a string and not as a function.
267 |
268 | ```javascript
269 | ReactElement findWithRef(ReactElement tree, string ref)
270 | ```
271 |
272 | ```javascript
273 | import React from "react";
274 | import { createRenderer } from "react-test-renderer/shallow";
275 | import { findWithRef } from "react-shallow-testutils";
276 |
277 | function MyComponent() {
278 | return (
279 |
284 | );
285 | }
286 |
287 | const renderer = createRenderer();
288 |
289 | const tree = renderer.render();
290 | expect(findWithRef(tree, "div-ref").props.className).toBe("div-ref-class");
291 | ```
292 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-shallow-testutils",
3 | "version": "3.0.1",
4 | "description": "Replacement for TestUtils when using React's shallow rendering",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "clean": "rimraf lib/",
8 | "compile": "babel -d lib/ src/",
9 | "lint": "eslint .",
10 | "lint-staged": "lint-staged",
11 | "prepublishOnly": "npm run clean && npm run compile",
12 | "test": "jest"
13 | },
14 | "pre-commit": [
15 | "lint-staged",
16 | "test"
17 | ],
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/sheepsteak/react-shallow-testutils.git"
21 | },
22 | "keywords": [
23 | "React",
24 | "testing",
25 | "components"
26 | ],
27 | "author": "Chris Shepherd ",
28 | "license": "MIT",
29 | "bugs": {
30 | "url": "https://github.com/sheepsteak/react-shallow-testutils/issues"
31 | },
32 | "homepage": "https://github.com/sheepsteak/react-shallow-testutils#readme",
33 | "lint-staged": {
34 | "*.js": [
35 | "eslint --fix",
36 | "prettier --write",
37 | "git add"
38 | ],
39 | "*.{json,md,yml}": [
40 | "prettier --write",
41 | "git add"
42 | ]
43 | },
44 | "dependencies": {},
45 | "devDependencies": {
46 | "@babel/cli": "^7.6.2",
47 | "@babel/core": "^7.6.2",
48 | "@babel/plugin-proposal-export-default-from": "^7.5.2",
49 | "@babel/preset-env": "^7.6.2",
50 | "@babel/preset-react": "^7.0.0",
51 | "@babel/register": "^7.6.2",
52 | "babel-eslint": "^10.0.3",
53 | "eslint": "6.1.0",
54 | "eslint-config-airbnb": "18.0.1",
55 | "eslint-config-prettier": "^6.3.0",
56 | "eslint-plugin-import": "^2.18.2",
57 | "eslint-plugin-jsx-a11y": "^6.2.3",
58 | "eslint-plugin-react": "^7.14.3",
59 | "eslint-plugin-react-hooks": "^1.7.0",
60 | "jest": "^24.9.0",
61 | "lint-staged": "^9.4.1",
62 | "pre-commit": "^1.1.1",
63 | "prettier": "^1.18.2",
64 | "react": "^16.10.1",
65 | "react-test-renderer": "^16.10.1",
66 | "rimraf": "3.0.0"
67 | },
68 | "peerDependencies": {
69 | "react": "^15.5.4 || ^16.0.0-0",
70 | "react-test-renderer": "^15.5.4 || ^16.0.0-0"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/specs/find-all-with-class.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { createRenderer } from "react-test-renderer/shallow";
3 | import { findAllWithClass } from "../src";
4 |
5 | describe("`findAllWithClass`", () => {
6 | let renderer;
7 | let tree;
8 |
9 | beforeEach(() => {
10 | const TestWithClasses = () => (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
Some content
18 |
19 | );
20 |
21 | renderer = createRenderer();
22 | tree = renderer.render();
23 | });
24 |
25 | it("should find two `test-class` components", () => {
26 | const found = findAllWithClass(tree, "test-class");
27 |
28 | expect(found.length).toBe(2);
29 | });
30 |
31 | it("should find two `test-class2--modified` component", () => {
32 | const found = findAllWithClass(tree, "test-class2--modified");
33 |
34 | expect(found.length).toBe(2);
35 | });
36 |
37 | it("should find two `test-class2.test-class2--modified` components", () => {
38 | const found = findAllWithClass(tree, "test-class2.test-class2--modified");
39 |
40 | expect(found.length).toBe(2);
41 | });
42 |
43 | it("should find no `test-class2.test-class10--modified` components", () => {
44 | const found = findAllWithClass(tree, "test-class2.test-class10");
45 |
46 | expect(found.length).toBe(0);
47 | });
48 |
49 | it("should find no `test-class10` components", () => {
50 | const found = findAllWithClass(tree, "test-class10");
51 |
52 | expect(found.length).toBe(0);
53 | });
54 | });
55 |
--------------------------------------------------------------------------------
/specs/find-all-with-type.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { createRenderer } from "react-test-renderer/shallow";
3 | import { findAllWithType } from "../src";
4 |
5 | const OtherComponent = () => ;
6 |
7 | const YetAnotherComponent = () => ;
8 |
9 | const TestWithTypes = () => (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 |
24 | describe("`findAllWithType`", () => {
25 | let renderer;
26 | let tree;
27 |
28 | beforeEach(() => {
29 | renderer = createRenderer();
30 | tree = renderer.render();
31 | });
32 |
33 | it("should find three `OtherComponent` components", () => {
34 | const found = findAllWithType(tree, OtherComponent);
35 |
36 | expect(found.length).toBe(3);
37 | });
38 |
39 | it("should find three `YetAnotherComponent` components", () => {
40 | const found = findAllWithType(tree, YetAnotherComponent);
41 |
42 | expect(found.length).toBe(3);
43 | });
44 |
45 | it("should find four `div` components", () => {
46 | const found = findAllWithType(tree, "div");
47 |
48 | expect(found.length).toBe(4);
49 | });
50 |
51 | it("should find no `button` components", () => {
52 | const found = findAllWithType(tree, "button");
53 |
54 | expect(found.length).toBe(0);
55 | });
56 | });
57 |
--------------------------------------------------------------------------------
/specs/find-all.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { createRenderer } from "react-test-renderer/shallow";
3 | import { findAll } from "../src";
4 |
5 | const OtherComponent = () => ;
6 |
7 | const TestWithForm = () => (
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
Some content
20 |
21 | );
22 |
23 | describe("`findAll`", () => {
24 | let renderer;
25 | let tree;
26 |
27 | beforeEach(() => {
28 | renderer = createRenderer();
29 | tree = renderer.render();
30 | });
31 |
32 | it("should traverse all thirteen items in tree", () => {
33 | let traversed = 0;
34 |
35 | findAll(tree, () => {
36 | traversed += 1;
37 | });
38 |
39 | expect(traversed).toBe(13);
40 | });
41 |
42 | it("should traverse child-first", () => {
43 | let traversed = 0;
44 |
45 | findAll(tree, component => {
46 | traversed += 1;
47 |
48 | switch (traversed) {
49 | case 1:
50 | expect(component.props.className).toBe("test-class");
51 | break;
52 | case 6:
53 | expect(component.type).toBe("form");
54 | break;
55 | case 11:
56 | expect(component.type).toBe(OtherComponent);
57 | break;
58 | default:
59 | break;
60 | }
61 | });
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/specs/find-with-class.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { createRenderer } from "react-test-renderer/shallow";
3 | import { findWithClass } from "../src";
4 |
5 | describe("`findWithClass`", () => {
6 | let renderer;
7 | let tree;
8 |
9 | beforeEach(() => {
10 | const TestWithClasses = () => (
11 |
12 |
13 |
14 |
15 |
16 |
Some content
17 |
18 | );
19 |
20 | renderer = createRenderer();
21 | tree = renderer.render();
22 | });
23 |
24 | it("should find `test-class2` component", () => {
25 | expect(() => findWithClass(tree, "test-class2")).not.toThrow();
26 | });
27 |
28 | it("should find one `test-class2--modified` component", () => {
29 | expect(() => findWithClass(tree, "test-class2--modified")).not.toThrow();
30 | });
31 |
32 | it("should find one `test-class2.test-class2--modified` component", () => {
33 | expect(() =>
34 | findWithClass(tree, "test-class2.test-class2--modified"),
35 | ).not.toThrow();
36 | });
37 |
38 | it("should not find exactly one `test-class` component", () => {
39 | expect(() => findWithClass(tree, "test-class")).toThrow();
40 | });
41 |
42 | it("should not find `test-class10` component", () => {
43 | expect(() => findWithClass(tree, "test-class10")).toThrow();
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/specs/find-with-ref.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { createRenderer } from "react-test-renderer/shallow";
3 | import { findWithRef } from "../src";
4 |
5 | const OtherComponent = () => ;
6 |
7 | /* eslint-disable react/no-string-refs */
8 | class TestWithRefs extends React.Component {
9 | render() {
10 | return (
11 |
17 | );
18 | }
19 | }
20 | /* eslint-enable react/no-string-refs */
21 |
22 | describe("`findWithRef`", () => {
23 | let renderer;
24 | let tree;
25 |
26 | beforeEach(() => {
27 | renderer = createRenderer();
28 | tree = renderer.render();
29 | });
30 |
31 | it("should find `OtherComponent` component", () => {
32 | expect(findWithRef(tree, "other-component-ref").props.test).toBe("test");
33 | });
34 |
35 | it("should find `div` component", () => {
36 | expect(findWithRef(tree, "div-ref").props.className).toBe("div-ref-class");
37 | });
38 |
39 | it("should find `input` component", () => {
40 | expect(findWithRef(tree, "input-ref").props.className).toBe(
41 | "input-ref-class",
42 | );
43 | });
44 |
45 | it("should not find non existing ref", () => {
46 | expect(() => findWithRef(tree, "non-existing")).toThrow();
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/specs/find-with-type.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { createRenderer } from "react-test-renderer/shallow";
3 | import { findWithType } from "../src";
4 |
5 | const OtherComponent = () => ;
6 |
7 | const TestWithTypes = () => (
8 |
9 |
10 |
11 |
12 |
13 |
Some content
14 |
15 |
16 | );
17 |
18 | describe("`findWithType`", () => {
19 | let renderer;
20 | let tree;
21 |
22 | beforeEach(() => {
23 | renderer = createRenderer();
24 | tree = renderer.render();
25 | });
26 |
27 | it("should find `OtherComponent` component", () => {
28 | expect(() => findWithType(tree, OtherComponent)).not.toThrow();
29 | });
30 |
31 | it("should not find exactly one `div` component", () => {
32 | expect(() => findWithType(tree, "div")).toThrow();
33 | });
34 |
35 | it("should not find `button` component", () => {
36 | expect(() => findWithType(tree, "button")).toThrow();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/specs/is-component-of-type.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { createRenderer } from "react-test-renderer/shallow";
3 | import { isComponentOfType } from "../src";
4 |
5 | const OtherComponent = () => ;
6 |
7 | const WrongComponent = () => ;
8 |
9 | const Test = () => (
10 |
11 |
12 |
13 | );
14 |
15 | describe("`isComponentOfType`", () => {
16 | let renderer;
17 | let tree;
18 |
19 | beforeEach(() => {
20 | renderer = createRenderer();
21 | tree = renderer.render();
22 | });
23 |
24 | it("should return `true` when a DOM component is the correct type", () => {
25 | expect(isComponentOfType(tree, "div")).toBe(true);
26 | });
27 |
28 | it("should return `false` when a DOM component is not the correct type", () => {
29 | expect(isComponentOfType(tree, "header")).toBe(false);
30 | });
31 |
32 | it("should return `true` when a composite component is the right type", () => {
33 | expect(isComponentOfType(tree.props.children, OtherComponent)).toBe(true);
34 | });
35 |
36 | it("should return `false` when a composite component is not the right type", () => {
37 | expect(isComponentOfType(tree.props.children, WrongComponent)).toBe(false);
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/specs/is-dom-component.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { createRenderer } from "react-test-renderer/shallow";
3 | import { isDOMComponent } from "../src";
4 |
5 | const OtherComponent = () => ;
6 |
7 | const Test = () => (
8 |
9 |
10 |
11 | );
12 |
13 | describe("`isDOMComponent`", () => {
14 | let renderer;
15 | let tree;
16 |
17 | beforeEach(() => {
18 | renderer = createRenderer();
19 | tree = renderer.render();
20 | });
21 |
22 | it("should return `true` for a DOM component", () => {
23 | expect(isDOMComponent(tree)).toBe(true);
24 | });
25 |
26 | it("should return `false` for a composite component", () => {
27 | expect(isDOMComponent(tree.props.children)).toBe(false);
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/src/find-all-with-class.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import findAll from "./find-all";
3 |
4 | /**
5 | * Returns true if the given parameter `classNameList` contains the
6 | * given parameter `className`.
7 | *
8 | * @param {String} classNameList String of all class names
9 | * @param {String} className The class name to search for
10 | * @return {Boolean}
11 | */
12 | function hasClassName(classNameList, className) {
13 | return ` ${classNameList} `.indexOf(` ${className} `) !== -1;
14 | }
15 |
16 | /**
17 | * Finds all elements in the tree with a class that matches `className`.
18 | *
19 | * This is different to React's `scryRenderedDOMComponentsWithClass` in that
20 | * it will check *all* components and not just DOM components.
21 | *
22 | * @param {ReactElement} tree the rendered tree to traverse
23 | * @param {String} className the class to find
24 | * @return {Array} all matching elements
25 | */
26 | export default function findAllWithClass(tree, className) {
27 | return findAll(tree, component => {
28 | if (React.isValidElement(component)) {
29 | if (component.props.className != null) {
30 | if (className.indexOf(".") !== -1) {
31 | const classNameList = className.split(".");
32 |
33 | return classNameList.every(val =>
34 | hasClassName(component.props.className, val),
35 | );
36 | }
37 |
38 | return hasClassName(component.props.className, className);
39 | }
40 |
41 | return false;
42 | }
43 |
44 | return false;
45 | });
46 | }
47 |
--------------------------------------------------------------------------------
/src/find-all-with-type.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import findAll from "./find-all";
3 |
4 | /**
5 | * Finds all elements in the tree with a `type` prop that matches `type`.
6 | *
7 | * This is like both React's `scryRenderedDOMComponentsWithTag` and
8 | * `scryRenderedComponentsWithType` as you can supply a component class or a
9 | * DOM tag.
10 | *
11 | * @param {ReactElement} tree the rendered tree to traverse
12 | * @param {Function|String} type the component type or tag to find
13 | * @return {Array} all matching elements
14 | */
15 | export default function findAllWithType(tree, type) {
16 | return findAll(tree, component => {
17 | if (React.isValidElement(component)) {
18 | return component.type != null && component.type === type;
19 | }
20 |
21 | return false;
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/src/find-all.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | /**
4 | * Traverses the tree and returns all elements that satisfy the function `test`.
5 | *
6 | * @param {ReactElement} tree the tree to traverse
7 | * @param {Function} test the test for each component
8 | * @return {Array} the elements that satisfied `test`
9 | */
10 | export default function findAll(tree, test) {
11 | let found = test(tree) ? [tree] : [];
12 |
13 | if (React.isValidElement(tree)) {
14 | if (React.Children.count(tree.props.children) > 0) {
15 | React.Children.forEach(tree.props.children, child => {
16 | found = found.concat(findAll(child, test));
17 | });
18 | }
19 | }
20 |
21 | return found;
22 | }
23 |
--------------------------------------------------------------------------------
/src/find-with-class.js:
--------------------------------------------------------------------------------
1 | import findAllWithClass from "./find-all-with-class";
2 |
3 | /**
4 | * Find only one element in the tree with a `className` prop that matches
5 | * `className`.
6 | *
7 | * This is different to React's `findRenderedDOMComponentWithClass` in that
8 | * it will check *all* components and not just DOM components.
9 | *
10 | * @param {ReactElement} tree the rendered tree to traverse
11 | * @param {String} className the class to find
12 | * @return {ReactElement} the matching element
13 | */
14 | export default function findWithClass(root, className) {
15 | const found = findAllWithClass(root, className);
16 |
17 | if (found.length !== 1) {
18 | throw new Error(`Did not find exactly one match for class: ${className}`);
19 | }
20 |
21 | return found[0];
22 | }
23 |
--------------------------------------------------------------------------------
/src/find-with-ref.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import findAll from "./find-all";
3 |
4 | /**
5 | * Finds an element in the tree with a ref that matches `ref`.
6 | *
7 | * @param {ReactElement} tree the rendered tree to traverse
8 | * @param {String} ref to find
9 | * @return {ReactElement} the found element
10 | */
11 | export default function findWithRef(tree, ref) {
12 | const found = findAll(tree, component => {
13 | if (React.isValidElement(component)) {
14 | return component.ref != null && component.ref === ref;
15 | }
16 |
17 | return false;
18 | });
19 |
20 | if (found.length !== 1) {
21 | throw new Error(`Did not find exactly one match for ref: ${ref}`);
22 | }
23 |
24 | return found[0];
25 | }
26 |
--------------------------------------------------------------------------------
/src/find-with-type.js:
--------------------------------------------------------------------------------
1 | import findAllWithType from "./find-all-with-type";
2 |
3 | /**
4 | * Find only one element in the tree with a `type` prop that matches `type`.
5 | *
6 | * This is like both React's `findRenderedDOMComponentWithTag` and
7 | * `findRenderedComponentWithType` as you can supply a component class or a
8 | * DOM tag.
9 | *
10 | * @param {ReactElement} tree the rendered tree to traverse
11 | * @param {Function|String} type the component type or tag to find
12 | * @return {ReactElement} the matching element
13 | */
14 | export default function findWithType(root, type) {
15 | const found = findAllWithType(root, type);
16 |
17 | if (found.length !== 1) {
18 | throw new Error(`Did not find exactly one match for type: ${type}`);
19 | }
20 |
21 | return found[0];
22 | }
23 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export findAll from "./find-all";
2 | export findAllWithClass from "./find-all-with-class";
3 | export findAllWithType from "./find-all-with-type";
4 | export findWithClass from "./find-with-class";
5 | export findWithRef from "./find-with-ref";
6 | export findWithType from "./find-with-type";
7 | export isComponentOfType from "./is-component-of-type";
8 | export isDOMComponent from "./is-dom-component";
9 |
--------------------------------------------------------------------------------
/src/is-component-of-type.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns whether an element instance is of a particular type.
3 | * @param {ReactElement} element the element to check
4 | * @param {Function|String} componentType the type of element to check against
5 | * @return {Boolean} whether the element is the supplied type
6 | */
7 | export default function isComponentOfType(element, componentType) {
8 | return element.type === componentType;
9 | }
10 |
--------------------------------------------------------------------------------
/src/is-dom-component.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns whether an element is a DOM element.
3 | *
4 | * @param {ReactElement} element
5 | * @return {Boolean} whether the element is a DOM element
6 | */
7 | export default function isDOMComponent(element) {
8 | return typeof element.type === "string";
9 | }
10 |
--------------------------------------------------------------------------------