Repository: enzymejs/enzyme
Branch: master
Commit: 61e1b47c4bdc
Files: 403
Total size: 1.3 MB
Directory structure:
gitextract_ky2tl6yi/
├── .babelrc
├── .eslintrc
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── Bug_report.md
│ │ └── Feature_request.md
│ └── workflows/
│ ├── node-pretest.yml
│ ├── node.yml
│ ├── rebase.yml
│ └── require-allow-edits.yml
├── .gitignore
├── .lgtm
├── .npmrc
├── .nycrc
├── CHANGELOG.md
├── CONTRIBUTING.md
├── INTHEWILD.md
├── LICENSE.md
├── MAINTAINERS
├── README.md
├── SUMMARY.md
├── book.json
├── docs/
│ ├── GLOSSARY.md
│ ├── api/
│ │ ├── README.md
│ │ ├── ReactWrapper/
│ │ │ ├── at.md
│ │ │ ├── childAt.md
│ │ │ ├── children.md
│ │ │ ├── closest.md
│ │ │ ├── contains.md
│ │ │ ├── containsAllMatchingElements.md
│ │ │ ├── containsAnyMatchingElements.md
│ │ │ ├── containsMatchingElement.md
│ │ │ ├── context.md
│ │ │ ├── debug.md
│ │ │ ├── detach.md
│ │ │ ├── equals.md
│ │ │ ├── every.md
│ │ │ ├── everyWhere.md
│ │ │ ├── exists.md
│ │ │ ├── filter.md
│ │ │ ├── filterWhere.md
│ │ │ ├── find.md
│ │ │ ├── findWhere.md
│ │ │ ├── first.md
│ │ │ ├── forEach.md
│ │ │ ├── get.md
│ │ │ ├── getDOMNode.md
│ │ │ ├── getElement.md
│ │ │ ├── getElements.md
│ │ │ ├── getWrappingComponent.md
│ │ │ ├── hasClass.md
│ │ │ ├── hostNodes.md
│ │ │ ├── html.md
│ │ │ ├── instance.md
│ │ │ ├── invoke.md
│ │ │ ├── is.md
│ │ │ ├── isEmpty.md
│ │ │ ├── isEmptyRender.md
│ │ │ ├── key.md
│ │ │ ├── last.md
│ │ │ ├── length.md
│ │ │ ├── map.md
│ │ │ ├── matchesElement.md
│ │ │ ├── mount.md
│ │ │ ├── name.md
│ │ │ ├── not.md
│ │ │ ├── parent.md
│ │ │ ├── parents.md
│ │ │ ├── prop.md
│ │ │ ├── props.md
│ │ │ ├── reduce.md
│ │ │ ├── reduceRight.md
│ │ │ ├── ref.md
│ │ │ ├── render.md
│ │ │ ├── renderProp.md
│ │ │ ├── setContext.md
│ │ │ ├── setProps.md
│ │ │ ├── setState.md
│ │ │ ├── simulate.md
│ │ │ ├── simulateError.md
│ │ │ ├── slice.md
│ │ │ ├── some.md
│ │ │ ├── someWhere.md
│ │ │ ├── state.md
│ │ │ ├── tap.md
│ │ │ ├── text.md
│ │ │ ├── type.md
│ │ │ ├── unmount.md
│ │ │ └── update.md
│ │ ├── ShallowWrapper/
│ │ │ ├── at.md
│ │ │ ├── childAt.md
│ │ │ ├── children.md
│ │ │ ├── closest.md
│ │ │ ├── contains.md
│ │ │ ├── containsAllMatchingElements.md
│ │ │ ├── containsAnyMatchingElements.md
│ │ │ ├── containsMatchingElement.md
│ │ │ ├── context.md
│ │ │ ├── debug.md
│ │ │ ├── dive.md
│ │ │ ├── equals.md
│ │ │ ├── every.md
│ │ │ ├── everyWhere.md
│ │ │ ├── exists.md
│ │ │ ├── filter.md
│ │ │ ├── filterWhere.md
│ │ │ ├── find.md
│ │ │ ├── findWhere.md
│ │ │ ├── first.md
│ │ │ ├── forEach.md
│ │ │ ├── get.md
│ │ │ ├── getElement.md
│ │ │ ├── getElements.md
│ │ │ ├── getWrappingComponent.md
│ │ │ ├── hasClass.md
│ │ │ ├── hostNodes.md
│ │ │ ├── html.md
│ │ │ ├── instance.md
│ │ │ ├── invoke.md
│ │ │ ├── is.md
│ │ │ ├── isEmpty.md
│ │ │ ├── isEmptyRender.md
│ │ │ ├── key.md
│ │ │ ├── last.md
│ │ │ ├── length.md
│ │ │ ├── map.md
│ │ │ ├── matchesElement.md
│ │ │ ├── name.md
│ │ │ ├── not.md
│ │ │ ├── parent.md
│ │ │ ├── parents.md
│ │ │ ├── prop.md
│ │ │ ├── props.md
│ │ │ ├── reduce.md
│ │ │ ├── reduceRight.md
│ │ │ ├── render.md
│ │ │ ├── renderProp.md
│ │ │ ├── setContext.md
│ │ │ ├── setProps.md
│ │ │ ├── setState.md
│ │ │ ├── shallow.md
│ │ │ ├── simulate.md
│ │ │ ├── simulateError.md
│ │ │ ├── slice.md
│ │ │ ├── some.md
│ │ │ ├── someWhere.md
│ │ │ ├── state.md
│ │ │ ├── tap.md
│ │ │ ├── text.md
│ │ │ ├── type.md
│ │ │ ├── unmount.md
│ │ │ └── update.md
│ │ ├── mount.md
│ │ ├── render.md
│ │ ├── selector.md
│ │ └── shallow.md
│ ├── common-issues.md
│ ├── future.md
│ ├── guides/
│ │ ├── browserify.md
│ │ ├── jest.md
│ │ ├── jsdom.md
│ │ ├── karma.md
│ │ ├── lab.md
│ │ ├── migration-from-2-to-3.md
│ │ ├── mocha.md
│ │ ├── react-native.md
│ │ ├── systemjs.md
│ │ ├── tape-ava.md
│ │ └── webpack.md
│ ├── guides.md
│ └── installation/
│ ├── README.md
│ ├── react-013.md
│ ├── react-014.md
│ ├── react-15.md
│ └── react-16.md
├── env.js
├── install-relevant-react.sh
├── karma.conf.js
├── lerna.json
├── package.json
├── packages/
│ ├── enzyme/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── ReactWrapper.js
│ │ ├── ShallowWrapper.js
│ │ ├── mount.js
│ │ ├── package.json
│ │ ├── render.js
│ │ ├── shallow.js
│ │ ├── src/
│ │ │ ├── Debug.js
│ │ │ ├── EnzymeAdapter.js
│ │ │ ├── RSTTraversal.js
│ │ │ ├── ReactWrapper.js
│ │ │ ├── ShallowWrapper.js
│ │ │ ├── Utils.js
│ │ │ ├── configuration.js
│ │ │ ├── getAdapter.js
│ │ │ ├── index.js
│ │ │ ├── mount.js
│ │ │ ├── render.js
│ │ │ ├── selectors.js
│ │ │ ├── shallow.js
│ │ │ └── validateAdapter.js
│ │ └── withDom.js
│ ├── enzyme-adapter-react-13/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── ReactThirteenAdapter.js
│ │ ├── ReactThirteenElementToTree.js
│ │ ├── ReactThirteenMapNativeEventNames.js
│ │ └── index.js
│ ├── enzyme-adapter-react-14/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── ReactFourteenAdapter.js
│ │ └── index.js
│ ├── enzyme-adapter-react-15/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── ReactFifteenAdapter.js
│ │ └── index.js
│ ├── enzyme-adapter-react-15.4/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── ReactFifteenFourAdapter.js
│ │ └── index.js
│ ├── enzyme-adapter-react-16/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── ReactSixteenAdapter.js
│ │ ├── detectFiberTags.js
│ │ ├── findCurrentFiberUsingSlowPath.js
│ │ └── index.js
│ ├── enzyme-adapter-react-16.1/
│ │ ├── .babelrc
│ │ ├── .eslintignore
│ │ ├── .eslintrc
│ │ ├── .npmrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── ReactSixteenOneAdapter.js
│ │ └── index.js
│ ├── enzyme-adapter-react-16.2/
│ │ ├── .babelrc
│ │ ├── .eslintignore
│ │ ├── .eslintrc
│ │ ├── .npmrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── ReactSixteenTwoAdapter.js
│ │ └── index.js
│ ├── enzyme-adapter-react-16.3/
│ │ ├── .babelrc
│ │ ├── .eslintignore
│ │ ├── .eslintrc
│ │ ├── .npmrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── ReactSixteenThreeAdapter.js
│ │ └── index.js
│ ├── enzyme-adapter-react-helper/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── enzyme-adapter-react-install.js
│ │ ├── getAdapterForReactVersion.js
│ │ ├── ifReact.js
│ │ ├── index.js
│ │ └── safeSFC.jsx
│ ├── enzyme-adapter-utils/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── package.json
│ │ └── src/
│ │ ├── RootFinder.jsx
│ │ ├── Utils.js
│ │ ├── createMountWrapper.jsx
│ │ ├── createRenderWrapper.jsx
│ │ ├── index.js
│ │ └── wrapWithSimpleWrapper.jsx
│ ├── enzyme-example-mocha/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── .gitignore
│ │ ├── .nycrc
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── Foo.jsx
│ │ │ └── Foo.spec.jsx
│ │ └── test/
│ │ ├── .setup.js
│ │ └── mocha.opts
│ ├── enzyme-shallow-equal/
│ │ ├── .babelrc
│ │ ├── .eslintrc
│ │ ├── README.md
│ │ ├── package.json
│ │ └── src/
│ │ └── index.js
│ └── enzyme-test-suite/
│ ├── .babelrc
│ ├── .eslintrc
│ ├── package.json
│ └── test/
│ ├── Adapter-spec.jsx
│ ├── Debug-spec.jsx
│ ├── RSTTraversal-spec.jsx
│ ├── ReactWrapper-spec.jsx
│ ├── ShallowWrapper-spec.jsx
│ ├── Utils-spec.jsx
│ ├── _helpers/
│ │ ├── adapter.js
│ │ ├── beforeEach.js
│ │ ├── describeHooks.js
│ │ ├── describeLifecycles.js
│ │ ├── describeMethods.js
│ │ ├── getLoadedLazyComponent.js
│ │ ├── index.jsx
│ │ ├── react-compat.js
│ │ ├── realArrowFunction.js
│ │ ├── selectors.js
│ │ ├── setupAdapters.js
│ │ ├── untranspiledArrowFunction.js
│ │ ├── untranspiledSloppyReturnThis.js
│ │ └── version.js
│ ├── adapter-utils-spec.jsx
│ ├── enzyme-adapter-react-install-spec.js
│ ├── enzyme-shallow-equal-spec.js
│ ├── selector-spec.jsx
│ ├── shared/
│ │ ├── hooks/
│ │ │ ├── _hook.template
│ │ │ ├── custom.jsx
│ │ │ ├── useCallback.jsx
│ │ │ ├── useContext.jsx
│ │ │ ├── useDebugValue.jsx
│ │ │ ├── useEffect.jsx
│ │ │ ├── useImperativeHandle.jsx
│ │ │ ├── useLayoutEffect.jsx
│ │ │ ├── useMemo.jsx
│ │ │ ├── useReducer.jsx
│ │ │ ├── useRef.jsx
│ │ │ └── useState.jsx
│ │ ├── lifecycles/
│ │ │ ├── componentDidCatch.jsx
│ │ │ ├── componentDidMount.jsx
│ │ │ ├── componentDidUpdate.jsx
│ │ │ ├── componentWillUnmount.jsx
│ │ │ ├── getDerivedStateFromError.jsx
│ │ │ ├── getDerivedStateFromProps.jsx
│ │ │ ├── getSnapshotBeforeUpdate.jsx
│ │ │ └── misc.jsx
│ │ └── methods/
│ │ ├── @@iterator.jsx
│ │ ├── _method.template
│ │ ├── at.jsx
│ │ ├── childAt.jsx
│ │ ├── children.jsx
│ │ ├── closest.jsx
│ │ ├── contains.jsx
│ │ ├── containsAllMatchingElements.jsx
│ │ ├── containsAnyMatchingElements.jsx
│ │ ├── containsMatchingElement.jsx
│ │ ├── context.jsx
│ │ ├── debug.jsx
│ │ ├── deprecatedInstanceProperties.jsx
│ │ ├── equals.jsx
│ │ ├── every.jsx
│ │ ├── everyWhere.jsx
│ │ ├── exists.jsx
│ │ ├── filter.jsx
│ │ ├── filterWhere.jsx
│ │ ├── find.jsx
│ │ ├── findWhere.jsx
│ │ ├── first.jsx
│ │ ├── flatMap.jsx
│ │ ├── forEach.jsx
│ │ ├── get.jsx
│ │ ├── getElement.jsx
│ │ ├── getElements.jsx
│ │ ├── getNode.jsx
│ │ ├── getNodes.jsx
│ │ ├── getWrappingComponent.jsx
│ │ ├── hasClass.jsx
│ │ ├── hostNodes.jsx
│ │ ├── html.jsx
│ │ ├── instance.jsx
│ │ ├── invoke.jsx
│ │ ├── is.jsx
│ │ ├── isEmpty.jsx
│ │ ├── isEmptyRender.jsx
│ │ ├── key.jsx
│ │ ├── last.jsx
│ │ ├── map.jsx
│ │ ├── matchesElement.jsx
│ │ ├── name.jsx
│ │ ├── not.jsx
│ │ ├── parent.jsx
│ │ ├── parents.jsx
│ │ ├── prop.jsx
│ │ ├── props.jsx
│ │ ├── reduce.jsx
│ │ ├── reduceRight.jsx
│ │ ├── render.jsx
│ │ ├── renderProp.jsx
│ │ ├── root.jsx
│ │ ├── setContext.jsx
│ │ ├── setProps.jsx
│ │ ├── setState.jsx
│ │ ├── simulate.jsx
│ │ ├── simulateError.jsx
│ │ ├── single.jsx
│ │ ├── slice.jsx
│ │ ├── some.jsx
│ │ ├── someWhere.jsx
│ │ ├── state.jsx
│ │ ├── tap.jsx
│ │ ├── text.jsx
│ │ ├── unmount.jsx
│ │ └── wrap.jsx
│ └── staticRender-spec.jsx
├── since.js
├── tea.yaml
└── test/
└── mocha.opts
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"presets": ["airbnb"],
"plugins": [
["transform-replace-object-assign", { "moduleSpecifier": "object.assign" }],
["add-module-exports"],
],
"ignore": [
"packages/enzyme-test-suite/test/_helpers/untranspiled*",
],
"sourceMaps": "both",
}
================================================
FILE: .eslintrc
================================================
{
"extends": "airbnb",
"root": true,
"env": {
"node": true,
},
"parser": "@babel/eslint-parser",
"ignorePatterns": [
"/build",
"_book",
"packages/*/build/",
// Temporarily copied
"packages/*/LICENSE.md",
"packages/enzyme/README.md",
"packages/enzyme-adapter-react-*/README.md",
"packages/enzyme-adapter-utils*/README.md",
],
"rules": {
"id-length": 0,
"react/no-find-dom-node": 1,
"import/first": 0,
"max-len": 0,
},
"overrides": [
{ // things that run in older envs, without babel
"files": [
"env.js",
"karma.conf.js",
"since.js",
],
"rules": {
"import/no-extraneous-dependencies": [2, {
"devDependencies": true,
}],
"comma-dangle": [2, {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "ignore",
}],
"strict": [2, "safe"],
"prefer-destructuring": 0,
"prefer-template": 0,
},
"parserOptions": {
"sourceType": "script",
},
},
{
"files": [
"**/*.md",
"**/*.md/**"
],
"extends": ["plugin:markdown/recommended"],
"rules": {
"class-methods-use-this": 0,
"import/extensions": 0,
"import/no-extraneous-dependencies": 0,
"import/no-unresolved": 0,
"import/prefer-default-export": 0,
"max-len": 0,
"no-console": 0,
"no-undef": 0,
"no-unused-vars": 0,
"react/jsx-filename-extension": 0,
"react/jsx-fragments": 0,
"react/jsx-no-undef": 0,
"react/jsx-no-useless-fragment": 0,
"react/jsx-one-expression-per-line": 0,
"react/no-multi-comp": 0,
"react/no-unknown-property": 0,
"react/no-unused-class-component-methods": 0,
"react/react-in-jsx-scope": 0,
},
},
],
}
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/enzyme
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE/Bug_report.md
================================================
---
name: 🐛 Bug report
about: Create a report to help us improve
---
Thanks for reporting an issue to us! We're glad you are using and invested in Enzyme.
Before submitting, please read over our commonly reported issues to prevent duplicates!
### All common issues
* [common issues](../blob/master/docs/common-issues.md)
### Notoriously common issues
* [Webpack build issues](../blob/master/docs/common-issues.md#webpack-build-issues)
* [Cannot find module 'react-dom/lib/ReactTestUtils'](../blob/master/docs/common-issues.md#error-cannot-find-module-react-domlibreacttestutils)
* [Query Selector fails](../blob/master/docs/common-issues.md#query-selector-fails)
* [Testing third party libraries](../blob/master/docs/common-issues.md#testing-third-party-libraries)
If you haven't found any duplicated issues, please report it with your environment!
### Current behavior
### Expected behavior
### Your environment
#### API
- [ ] shallow
- [ ] mount
- [ ] render
#### Version
| library | version
| ------------------- | -------
| enzyme |
| react |
| react-dom |
| react-test-renderer |
| adapter (below) |
#### Adapter
- [ ] enzyme-adapter-react-16
- [ ] enzyme-adapter-react-16.3
- [ ] enzyme-adapter-react-16.2
- [ ] enzyme-adapter-react-16.1
- [ ] enzyme-adapter-react-15
- [ ] enzyme-adapter-react-15.4
- [ ] enzyme-adapter-react-14
- [ ] enzyme-adapter-react-13
- [ ] enzyme-adapter-react-helper
- [ ] others ( )
================================================
FILE: .github/ISSUE_TEMPLATE/Feature_request.md
================================================
---
name: 🙏 Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. e.g. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/workflows/node-pretest.yml
================================================
name: 'Tests: pretest/posttest'
on: [pull_request, push]
jobs:
pretest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ljharb/actions/node/install@main
with:
skip-ls-check: true
- run: sh install-relevant-react.sh
- run: npx lerna bootstrap
- run: npm run build
- run: npm run pretest
# posttest:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
# - uses: ljharb/actions/node/install@main
# - run: npm run build
# - run: npm run posttest
================================================
FILE: .github/workflows/node.yml
================================================
name: 'Tests: node.js'
on: [pull_request, push]
jobs:
build:
name: 'install deps and build'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ljharb/actions/node/install@main
with:
skip-ls-check: true
- run: npx lerna bootstrap
- run: npm run build
- uses: actions/cache@v3
with:
path: |
packages/*/build
node_modules
packages/*/node_modules
key: enzyme-${{ github.workflow }}-${{ github.action }}-${{ github.run_id }}
karma-matrix:
needs: [build]
name: 'karma tests'
runs-on: ubuntu-latest
continue-on-error: true
strategy:
fail-fast: false
matrix:
react:
- '16'
- '16.3'
- '16.2'
- '16.1'
- '15'
- '15.4'
- '0.14'
- '0.13'
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: |
packages/*/build
node_modules
packages/*/node_modules
key: enzyme-${{ github.workflow }}-${{ github.action }}-${{ github.run_id }}
- run: sudo chmod -R a+w .
- uses: ljharb/actions/node/install@main
with:
node-version: 'lts/*'
skip-install: true
after_install: '(nvm install node && REACT=${{ matrix.react }} TRAVIS=1 sh install-relevant-react.sh)'
skip-ls-check: true
- run: npm run test:karma -- --single-run
continue-on-error: true
env:
CHROME_BIN: chromium-browser
DISPLAY: 99.0
- run: echo 'karma tests expected to fail'
tests:
needs: [build]
name: 'tests'
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.continue-on-error == 'true' }}
strategy:
fail-fast: false
matrix:
node-version:
- '18'
- '4'
react:
- '16.14'
- '16.13'
- '16.12'
- '16.11'
- '16.10'
- '16.9'
- '16.8'
- '16.7'
- '16.6'
- '16.5'
- '16.4'
- '16.3'
- '16.2'
- '16.1'
- '16.0'
- '15.5'
- '15.4'
- '15.3'
- '15.2'
- '15.1'
- '15.0'
- '0.14'
- '0.13'
include:
- node-version: '16'
react: '16'
- node-version: '14'
react: '16'
- node-version: '12'
react: '16'
- node-version: '10'
react: '16'
- node-version: '8'
react: '16'
- node-version: '6'
react: '16'
- node-version: 'lts/*'
react: '16.8.3'
- node-version: 'lts/*'
react: '16.8.5'
env:
RENDERER: '16.8.5'
- node-version: 'lts/*'
react: '16.8.5'
env:
RENDERER: '16.8.3'
- node-version: 'lts/*'
react: '16.3'
env:
ADAPTER: '16'
- node-version: 'lts/*'
react: '16.8'
env:
RENDERER: '16.7'
- node-version: 'lts/*'
react: '16.7'
env:
RENDERER: '16.8'
- node-version: 'lts/*'
react: '16.7'
env:
RENDERER: '16.7'
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: |
packages/*/build
node_modules
packages/*/node_modules
key: enzyme-${{ github.workflow }}-${{ github.action }}-${{ github.run_id }}
- run: sudo chmod -R a+w .
- uses: ljharb/actions/node/install@main
with:
node-version: ${{ matrix.node-version || 'lts/* '}}
skip-install: true
after_install: '(nvm install node && sh install-relevant-react.sh)'
skip-ls-check: true
env:
REACT: ${{ matrix.react }}
- run: npm run travis
- uses: codecov/codecov-action@v3
node:
name: 'node + react'
needs: [tests]
runs-on: ubuntu-latest
steps:
- run: 'echo tests completed'
karma:
name: 'node + react + karma'
needs: [karma-matrix]
runs-on: ubuntu-latest
steps:
- run: 'echo tests completed'
================================================
FILE: .github/workflows/rebase.yml
================================================
name: Automatic Rebase
on: [pull_request_target]
jobs:
_:
name: "Automatic Rebase"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ljharb/rebase@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/require-allow-edits.yml
================================================
name: Require “Allow Edits”
on: [pull_request_target]
jobs:
_:
name: "Require “Allow Edits”"
runs-on: ubuntu-latest
steps:
- uses: ljharb/require-allow-edits@main
================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
# Jetbrains IDEs
.idea
/build
_book
# Only apps should have lockfiles
npm-shrinkwrap.json
package-lock.json
yarn.lock
.DS_Store
._.DS_Store
packages/*/build/
# Temporarily copied
packages/*/LICENSE.md
packages/enzyme/README.md
packages/enzyme-adapter-react-*/README.md
packages/enzyme-adapter-utils*/README.md
.npmignore
================================================
FILE: .lgtm
================================================
approvals = 1
pattern = "(?i):shipit:|:\\+1:|LGTM"
================================================
FILE: .npmrc
================================================
package-lock=false
update-notifier=false
legacy-peer-deps=true
================================================
FILE: .nycrc
================================================
{
"extension": [
".js",
".jsx"
],
"include": [
"*",
"packages/*/*",
"packages/*/src"
],
"exclude": [
"packages/enzyme-test-suite",
"_book",
"coverage",
"packages/*/node_modules"
],
"require": [
],
"reporter": [
"text",
"html",
"json",
"lcov"
],
"all": false,
"check-coverage": false,
"statements": 100,
"branches": 100,
"lines": 100,
"functions": 100,
"sourceMap": true,
"instrument": true
}
================================================
FILE: CHANGELOG.md
================================================
# Change Log
## 3.11.0
### New Stuff
- `render`: handle Fiber strings and numbers (#2221)
### Fixes
- `shallow`: Share child context logic between `shallow` and `dive` (#2296)
- `mount`: `children`: include text nodes ($2269)
- `mount`: `invoke`: use adapter’s `wrapInvoke` if present (#2158)
### Docs
- `mount`/`shallow`: `closest`/`parent`: Add missing arguments description (#2264)
- `mount`/`shallow`: fix pluralization of “exist” (#2262)
- `shallow`/`mount`: `simulate`: added functional component example to simulate doc (#2248)
- `mount`: `debug`: add missing verbose option flag (#2184)
- `mount`/`shallow`: `update`: fix semantics description (#2194)
- add missing backticks to linked method names (#2170)
- `invoke`: Add missing backticks to end of codeblock (#2160)
- `invoke`: Fix typo (#2167)
- Explicit React CSS selector syntax description (#2178)
### Meta Stuff
- [meta] add `funding` field
- [meta] Update airbnb.io URLs to use https (#2222)
- [deps] update `is-boolean-object`, `is-callable`, `is-number-object`, `is-string`, `enzyme-shallow-equal`, `array.prototype.flat`, `function.prototype.name`, `html-element-map`, `is-regex`, `object-inspect`, `object-is`, `object.entries`, `object.vales`, `raf`, `string.prototype.trim`
- [dev deps] update `eslint`, `eslint-plugin-import`, `eslint-plugin-markdown`, `eslint-plugin-react`, `safe-publish-latest`, `eslint-config-airbnb`, `rimraf`, `safe-publish-latest`, `karma-firefox-launcher`, `babel-preset-airbnb`, `glob-gitignore`, `semver`, `eslint-plugin-jsx-a11y`
## 3.10.0
### New Stuff
- `shallow` add `suspenseFallback` option; support `Suspense`/`Lazy` (#1975)
- `shallow`/`mount`: add `invoke(propName)(...args)` (#1856, #945)
- `shallow`: Support rendering and `dive()`ing `createContext()` providers and consumers (#1966)
- `mount`/`shallow`: add `getWrappingComponent` (#1960)
- `Utils`: add `isCustomComponent` (#1960)
- `Utils`: add `stub` argument to `spyMethod`
- `EnzymeAdapter`: add `matchesElementType` (#2146)
- `RSTTraversal`: add `getHTMLFromHostNodes`
### Fixes
- `selectors`: unwrap `memo` elements - in both directions (#2146)
- `shallow`: properly determine "should render" for `PureComponent`s (#2096)
- `mount`/`shallow`: `renderProp`: improve error messages (#2070)
- `mount`: `setContext`: use proper wrapper name in error message
- `shallow`: `.contains()`: clean up error message
- `shallow`/`mount`: `hasClass`: avoid a crash with a non-string argument (#2057)
- `mount`: properly handle HTML of multiple nodes (#2052)
- `shallow`: ensure that if gDSFP exists, cDU is called. (#2027)
- `shallow`: Mock sCU if gDSFP defined in shallow renderer rerender (#1981)
- `mount`: `.state()`: allow getting state from stateful children of a stateless root (#2043)
- `mount`: `.text()`: properly recurse through fragments and arrays (#2028)
### Refactors
- `ReactWrapper`/`ShallowWrapper`: ensure calling an adapter‘s nodeToElement preserves the receiver
- `mount`: use `getHTMLFromHostNodes`
### Docs
- explain why need to re-call .find() after update (#2140)
- `shallow`: fix childAt (#2134)
- Update v2 -> v3 migration guide re props after a stage change (#1300)
- `debug`: Added documentation for `verbose` flag (#2104)
- Add on the fly JSDOM include example (#2072)
- `reduce`/`reduceRight`: fix example code (#2066, #2065, #2064)
- update `simulateError` with `getDerivedStateFromError` (#2036)
- `shallow`: `.hasClass`: fix use of `mount`
- add link to Cheerio API and another example (#756)
- `jest`: Update deprecated jest config key (#2024)
## 3.9.0
### New Stuff
- `shallow`: `isEmptyRender`: allow on multiple elements (#1924)
- `mount`: support `:focus` selector (#1965)
- `shallow`: Support `getChildContext()` (#1971)
- `shallow`/`mount`: `.find`: find HTML elements by their constructor (#1933)
- `shallow`/`mount`: `selectors`: support universal selector (#1945)
- `mount`/`shallow`: add regex support to `.hasClass` (#1987)
### Fixes
- `mount`/`shallow`: `.text`/`.html`: handle an array of nodes properly (#2001)
- `shallow`: `.setProps()`: only call cDU once (#2007)
- `mount`: ensure `findWhere` doesn‘t abort early on an empty string (#1995)
- `mount`: `findWhere`: avoid passing empty wrappers to predicate
- `mount`: `text()` via `findWhere`: return the string for a wrapper around a string
- `mount`/`shallow`: Fix .exists not accepting any EnzymeSelector (#1934)
- `mount`: Recursive `isEmptyRender` (#1924)
- `mount`: `setState`: allow setting state on a class child of an SFC root
### Documentation
- [jest] update Jest to setupFilesAfterEnv (#2015)
- [jest] Change deprecated `setupTestFrameworkScriptFile` to `setupFilesAfterEnv` (#2013)
- `mount`: `setState`: note that you can now call it on "not the root" (#2010)
- general improvements (#1947)
- Fix typos (#1992)
- Added missing pages: `isEmptyRender`, `renderProp`, `equals`, SystemJS guide (#1984, #1985)
- Fix link to .shallow() (#1951)
- update jsdoc to use "EnzymeSelector" where applicable
### Meta Stuff
- add "directory" field to package.json
## 3.8.0
### New Stuff
- `shallow`/`mount`: add `renderProp` (#1863, #1891)
### Fixes
- `shallow`/`mount`: improve error message for "single node" assertion (#1904)
- `shallow`: shallow compare, not deep compare, state and props to determine rerendering (#1915)
### Documentation
- `shallow`: `dive`: add a note about throwing an error (#1905)
- `selectors: update re `displayName` (#1932)
- `shallow`: `get`: fixed wrong `props()` usage (#1921)
- `shallow`: `html`: shallow renders full tree (#1912)
- Updated broken link for “.hostNodes()” in migration guide from enzyme 2 to 3 (#1909)
- Add tape example project link (#1898)
- `prop`: fix typo (#1883)
- Document full support for attribute selectors (#1881)
- Documentation update for testing React Native with jsdom (#1873)
- Update JSDOM docs to include {request|cancel}AnimationFrame polyfills (#1867)
- `mount`: `ref`: use correct type (#1865)
## 3.7.0
### New Stuff
- `mount`: `.state()`/`.setState()`: allow calling on children ([#1802](https://github.com/enzymejs/enzyme/pull/1802), @ljharb)
- `configuration`: add `reset` ([commit](https://github.com/enzymejs/enzyme/commit/d91d95b8da8900c8f4b7090d2256422a82398ca9))
### Fixes
- `makeOptions`: ensure that config-level `attachTo`/`hydrateIn` are inherited into wrapper options ([#1836](https://github.com/enzymejs/enzyme/issues/1836), @ljharb)
- `shallow`/`Utils`: call into adapter’s `isCustomComponentElement` if present ([#1832](https://github.com/enzymejs/enzyme/pull/1832), @SinHouse)
- `shallow`/`mount`: throw an explicit error when state is null/undefined ([commit](https://github.com/enzymejs/enzyme/commit/9ea33d7667a93885d6f1d6e12b0c2661d6d47cd1))
- freeze `ROOT_NODES` for child wrappers ([#1811](https://github.com/enzymejs/enzyme/pull/1811), @jgzuke)
- `shallow`: `.parents`: ensure that one `.find` call does not affect another ([#1781](https://github.com/enzymejs/enzyme/pull/1781), @ljharb)
- `mount`: update after `simulateError` ([#1812](https://github.com/enzymejs/enzyme/pull/1812), @jgzuke)
### Refactors
- `mount`/`shallow`: `getElement`: use `this.single` ([commit](https://github.com/enzymejs/enzyme/commit/6b63db3b002a419076c82d34554916400ef392fa))
## 3.6.0
### New Stuff
- `shallow`/`mount`: add `simulateError` ([#1797](https://github.com/enzymejs/enzyme/pull/1797), @ljharb)
## 3.5.1
### Fixes
- `shallow`/`mount`: `containsMatchingElement`: trim whitespace ([commit](https://github.com/enzymejs/enzyme/commit/171e952), [#636](https://github.com/enzymejs/enzyme/issues/636))
- `debug`: inspect objects instead of showing them as `` ([commit](https://github.com/enzymejs/enzyme/commit/a7b6e78))
### Documentation
- `mount`: `ref`: Update docs to be consistent with v3 ([#1242](https://github.com/enzymejs/enzyme/pull/1242), @adam-golab)
### Refactors
- `shallow`/`mount`: make tests and method ordering more consistent ([commit](https://github.com/enzymejs/enzyme/commit/d0fccaf))
- RSTTraversal: remove unnecessary `adapter` truthiness check ([commit](https://github.com/enzymejs/enzyme/commit/394a327))
## 3.5.0
### New Stuff
- Add forwardRef support ([#1592](https://github.com/enzymejs/enzyme/pull/1592), @jquense)
- Add Portal support ([#1760](https://github.com/enzymejs/enzyme/pull/1760), [#1761](https://github.com/enzymejs/enzyme/pull/1760), [#1772](https://github.com/enzymejs/enzyme/pull/1772), [#1774](https://github.com/enzymejs/enzyme/pull/1774), @jgzuke)
- Add pointer events support ([#1753](https://github.com/enzymejs/enzyme/pull/1753), @ljharb)
### Fixes
- preemptively fix compat with React v16.4.3 ([#1790](https://github.com/enzymejs/enzyme/pull/1790), [#1778](https://github.com/enzymejs/enzyme/pull/1778), @gaearon, @aweary)
- `shallow`: prevent rerenders with PureComponents ([#1786](https://github.com/enzymejs/enzyme/pull/1786), @koba04)
- `shallow`: skip updates when nextState is `null` or `undefined` ([#1785](https://github.com/enzymejs/enzyme/pull/1785), @koba04)
- `shallow`: `setState` after `setProps` calls `componentWillReceiveProps` ([#1779](https://github.com/enzymejs/enzyme/pull/1779), @peanutenthusiast)
- `mount`/`shallow`: be stricter on the wrapper’s setState/setProps callback ([commit](https://github.com/enzymejs/enzyme/commit/ff11d2219da575d09ca8edfa19df42b8f78b506f))
- `shallow`/`mount`: improve error message when wrapping invalid elements ([#1759](https://github.com/enzymejs/enzyme/pull/1759), @jgzuke)
### Refactors
- remove most uses of lodash ([commit](https://github.com/enzymejs/enzyme/commit/89b39b6f1c59aa771f4452a27b159f7aa2616e84))
### Meta Stuff
- ensure a license and readme is present in all packages when published
## 3.4.4
### Fixes
- @koba04: `shallow`: fix unexpected call to componentDidMount ([#1768](https://github.com/enzymejs/enzyme/pull/1768))
## 3.4.3
### Fixes
- @ljharb/@koba04: `shallow`: `.setState()`: stub out `setState` on non-root code paths as well ([#1763](https://github.com/enzymejs/enzyme/pull/1763))
- @ljharb: `shallow`/`mount`: restore fallback when adapter lacks `invokeSetStateCallback` ([commit](https://github.com/enzymejs/enzyme/commit/093b2edb98d3abfe6b61d800503e04aac08e7496))
- @ljharb: `mount`: `setState`: invoke callback with the proper receiver ([commit](https://github.com/enzymejs/enzyme/commit/ec3beef3ba86c4352fe6e9ab2848b3b4f61ac1da))
- @ljharb: `mount`: `state` and `setState` should throw an explicit error message when called on an SFC ([commit](https://github.com/enzymejs/enzyme/commit/8feee5a89e9091636e9ec0ec3814d287ced20136))
## 3.4.2
### Fixes
- @koba04: `shallow`: call cDU when an instance calls setState ([#1742](https://github.com/enzymejs/enzyme/pull/1742))
- @ReactiveRaven: `selectors`: fix descendant selector ([#1680](https://github.com/enzymejs/enzyme/pull/1680))
## 3.4.1
### Fixes
- @ljharb: `shallow`: `setProps`: merge instead of replace props ([commit](https://github.com/enzymejs/enzyme/commit/9b4d0276f57e54be06aca6c3636120b3c4053310))
### Documentation
- @koba04: Fix an adapter table style in README.md and a migration guide ([#1734](https://github.com/enzymejs/enzyme/pull/1734))
## 3.4.0
### New Stuff
- @madicap: `shallow`/`mount`: account for React.Fragment nodes ([#1733](https://github.com/enzymejs/enzyme/pull/1733))
- @jquense: Debug: `debugNode` now returns `[function]` for function children ([commit](https://github.com/enzymejs/enzyme/commit/9745de0bf25e826186be07e7846f4ecd7c685592))
- @ljharb: `mount`: add `hydrateIn` option ([#1707](https://github.com/enzymejs/enzyme/pull/1707))
- @ljharb: `shallow`: add “lifecycles” adapter option ([#1696](https://github.com/enzymejs/enzyme/pull/1696))
- @krawaller: `shallow`/`mount`: allow `.exists()` to take an optional selector ([#1695](https://github.com/enzymejs/enzyme/pull/1695))
- @koba04: `shallow`: Add getSnapshotBeforeUpdate support ([#1657](https://github.com/enzymejs/enzyme/pull/1657))
- @jquense: `shallow`/`mount`: Add support for some pseudo selectors ([#1537](https://github.com/enzymejs/enzyme/pull/1537))
- @blainekasten: `debug`: Implement verbose debug output ([#1547](https://github.com/enzymejs/enzyme/pull/1547))
- @jquense/@ljharb: `Debug`: `typeName` now calls the adapter’s `displayNameOfNode` if available ([#1701](https://github.com/enzymejs/enzyme/pull/1701))
- @jquense/@ljharb: `mount`/`shallow`: `.name()`: call into adapter’s `displayNameOfNode`, if present ([#1701](https://github.com/enzymejs/enzyme/pull/1701))
- @jquense/@ljharb: `Utils`: `nodeHasType`: call into adapter’s `displayNameOfNode`, if present ([#1701](https://github.com/enzymejs/enzyme/pull/1701))
- @jquense/@ljharb: `selectors`: `buildPredicate`: call into adapter’s `isValidElementType`, if present ([#1701](https://github.com/enzymejs/enzyme/pull/1701))
- @emuraton/@ljharb: `shallow`: `setProps()`: Add callback argument ([#1721](https://github.com/enzymejs/enzyme/pull/1721))
- @ljharb: `mount`: add `.equals()` ([commit](https://github.com/enzymejs/enzyme/commit/dcc8ab10fde06a963364f6cc79b89aa967d9bef2))
- @madicap: Extract `getAdapter` from `Utils` into its own file ([#1732](https://github.com/enzymejs/enzyme/pull/1732))
### Fixes
- @ljharb: `shallow`/`mount`: `matchesElement`/`containsMatchingElement`: get adapter with options ([commit](https://github.com/enzymejs/enzyme/commit/e954e4610d1ad89ae94b8f7c7baa8835cd331662))
- @ljharb: `RSTTraversal`: remove `nodeHasProperty` export; broken since #1157 ([commit](https://github.com/enzymejs/enzyme/commit/edabb1b6b4648fb6469da43feb1d15c1b55666f7))
- @ljharb/@KordonDev: `shallow`: `.at()`: return an empty wrapper when an index does not exist ([#1478](https://github.com/enzymejs/enzyme/pull/1478))
- @ljharb: `shallow`: `.equals()`: flatten children when comparing ([commit](https://github.com/enzymejs/enzyme/commit/18de4ed2e68c25f9fff9983d996b024704183801))
- @ljharb: `mount`/`shallow`: do not dedupe in flatMap ([commit](https://github.com/enzymejs/enzyme/commit/72341740e1e650b16ca2e377fa4e3e144b35a558))
- @ljharb: `shallow`: `.closest()`: ensure an empty wrapper is returned for no match ([commit](https://github.com/enzymejs/enzyme/commit/ce1e1132d080948265567e88417dface9c0c45e7))
- @krawaller: `selectors`: make general sibling not throw on root ([#1698](https://github.com/enzymejs/enzyme/pull/1698))
- @ljharb/@angelikatyborska : `mount`: `text()`: null nodes return null ([#1582](https://github.com/enzymejs/enzyme/pull/1582))
- @ljharb: `shallow`: `simulate`: ensure it returns itself ([commit](https://github.com/enzymejs/enzyme/commit/1c2c58b4e554f3b0c5f862f8de79f15a62bef5cf))
- @koba04: `shallow`: ShallowWrapper calls update() automatically ([#1499](https://github.com/enzymejs/enzyme/pull/1499))
- @bdwain: `mount`/`shallow`: return null for missing keys ([#1536](https://github.com/enzymejs/enzyme/pull/1536))
- @vsiao: Fix ShallowWrapper for array-rendering components ([#1498](https://github.com/enzymejs/enzyme/pull/1498))
- @koba04: Call `setState` callback after finishing the render ([#1453](https://github.com/enzymejs/enzyme/pull/1453))
- @eddyerburgh: Convert nodes to RST nodes before comparing ([#1423](https://github.com/enzymejs/enzyme/pull/1423))
- @ljharb: improve "bad adapter" error message ([#1477](https://github.com/enzymejs/enzyme/pull/1477))
- @ljharb: `shallow`/`mount`: default iterator should be iterable ([commit](https://github.com/enzymejs/enzyme/commit/cfc5a3e47efa812f7a2c4fa5ad2b0687daacd280))
### Refactors
- @ReactiveRaven: `selectors`: fix typos; avoid reusing variable unnecessarily ([#1681](https://github.com/enzymejs/enzyme/pull/1681))
- @koba04/@ljharb: `shallow`: Use `spyMethod` to inspect the result of `shouldComponentUpdate`/`getSnapshotBeforeUpdate` ([#1192](https://github.com/enzymejs/enzyme/pull/1192))
- @ljharb: `Utils`: `configuration`: change to named exports. ([commit](https://github.com/enzymejs/enzyme/commit/d7f32617e6ea93b739f4e4c3f6228a8e382aeb06))
- @ljharb: use `array.prototype.flat` ([commit](https://github.com/enzymejs/enzyme/commit/e52a02ddac0fab0d1d93fd57d7f073f8bdc850bf))
### Documentation
- @jack-lewin: Clarify dev workflow in CONTRIBUTING.md ([#1207](https://github.com/enzymejs/enzyme/pull/1207))
- @robrichard: Provide migration instructions for `ref(refName)` ([#1470](https://github.com/enzymejs/enzyme/pull/1470))
- @DannyDelott: `shallow`/`mount`: Add callback arg to setProps header ([#1361](https://github.com/enzymejs/enzyme/pull/1361))
- @conor-cafferkey-sociomantic: `mount`: Updated docs for ReactWrapper.instance(); remove docs for v2's `getNode()`/`getNodes()` ([#1714](https://github.com/enzymejs/enzyme/pull/1714))
- @koba04: Make clearer the docs for .mount() ([#1540](https://github.com/enzymejs/enzyme/pull/1540))
- @ialexryan: Update signature of .type() in shallow.md (#1492]([https://github.com/enzymejs/enzyme/pull/1492))
### Meta Stuff
- @ljharb: ensure a license and readme is present in all packages when published
- @ljharb: [meta] fix package.json scripts
## 3.3.0
### New Stuff
- @ljharb/@joeldenning: `debug`: handle boxed primitives ([#1450](https://github.com/enzymejs/enzyme/pull/1450))
### Refactors
- @eddyerburgh: Use RSTTraversal childrenOfNode in Utils ([#1381](https://github.com/enzymejs/enzyme/pull/1381))
### Fixes
- @nicoder: Fix typo in error message ([#1379](https://github.com/enzymejs/enzyme/pull/1379))
## 3.2.0
### New Stuff
- @aweary: Support all attribute selector operators ([#1157](https://github.com/enzymejs/enzyme/pull/1157))
### Fixes
- @idanilt: Change ShallowWrapper.text() trim spaces with same behavior as ReactWrapper.text() ([#1350](https://github.com/enzymejs/enzyme/pull/1350))
## 3.1.1
### Fixes
- @koba04: Fix to call componentDidUpdate on setState of React v16 ([#1261](https://github.com/enzymejs/enzyme/pull/1261))
## 3.1.0
### New Stuff
- @FezVrasta: Added hostNodes method to ReactWrapper ([#1179](https://github.com/enzymejs/enzyme/pull/1179))
### Fixes
- @lelandrichardson: Add an npmignore file to all packages ([#1204](https://github.com/enzymejs/enzyme/pull/1204))
- @neoziro: Fix node resolving in React 16 adapter ([#100](https://github.com/enzymejs/enzyme/pull/100))
- @graingert: upgrade to rst-selector-parser@^2.2.2 ([#1146](https://github.com/enzymejs/enzyme/pull/1146))
### Documentation
- @lelandrichardson: Symlink readme to all packages ([#1205](https://github.com/enzymejs/enzyme/pull/1205))
- @AndersDJohnson: fix some typos ([#1165](https://github.com/enzymejs/enzyme/pull/1165))
- @dubbha: ES5 setup file correction ([#1194](https://github.com/enzymejs/enzyme/pull/1194))
- @morrowr08: updated component name being used in example ([#1180](https://github.com/enzymejs/enzyme/pull/1180))
- @apandichi: Fixing a few typos... ([#1171](https://github.com/enzymejs/enzyme/pull/1171))
- @nuc: Fix typo ([#1142](https://github.com/enzymejs/enzyme/pull/1142))
## 3.0.0
### Breaking Changes
Enzyme has several breaking changes from v2 to v3. Please check out our [migration guide](/docs/guides/migration-from-2-to-3.md) for more info. Since there was a rewrite of the core
library from v2 to v3, it is hard to categorize changes in terms of sem
- @lelandrichardson: Refactor enzyme to use Adapters, initial React 16 support ([#1007](https://github.com/enzymejs/enzyme/pull/1007))
- @lelandrichardson: Make private properties more private and harder to use ([#1083](https://github.com/enzymejs/enzyme/pull/1083))
- @ljharb: [breaking] update `cheerio` to v1 ([#1093](https://github.com/enzymejs/enzyme/pull/1093))
- @aweary: Integrate with a CSS parser for selector parsing ([#1086](https://github.com/enzymejs/enzyme/pull/1086))
- @vadimdemedes: Skip undefined props when comparing nodes ([#662](https://github.com/enzymejs/enzyme/pull/662))
- @koba04: Breaking: lifecycleExperimental by default ([#1140](https://github.com/enzymejs/enzyme/pull/1140))
### New Stuff
- @lelandrichardson: Move to lerna repo structure, multiple modules ([#1074](https://github.com/enzymejs/enzyme/pull/1074))
- @lelandrichardson: Remove all React dependencies from enzyme ([#1084](https://github.com/enzymejs/enzyme/pull/1084))
- @lelandrichardson: Add public root method ([#1127](https://github.com/enzymejs/enzyme/pull/1127))
### Fixes
- @aweary: Remove isFunctionalComponent, use nodeType instead ([#1076](https://github.com/enzymejs/enzyme/pull/1076))
- @LarsHassler: props not merged when shallow rendering in lifecycleExperimental ([#1088](https://github.com/enzymejs/enzyme/pull/1088))
- @ljharb: [Fix] `mount`: do not mutate `Component.contextTypes` ([#1099](https://github.com/enzymejs/enzyme/pull/1099))
- @ljharb: [Fix] `reduce`/`reduceRight`: follow `Array#reduce` when omitting initialValue ([#673](https://github.com/enzymejs/enzyme/pull/673))
- @koba04: Fix componentDidUpdate when updating by setState on v16 ([#1133](https://github.com/enzymejs/enzyme/pull/1133))
- @koba04: Fix componentDidUpdate no longer receives prevContext on React v16 ([#1139](https://github.com/enzymejs/enzyme/pull/1139))
### Documentation
- @ghost: added sinon to mocha guide ([#1075](https://github.com/enzymejs/enzyme/pull/1075))
- @samit4me: Update to GitBook 3 ([#1039](https://github.com/enzymejs/enzyme/pull/1039))
- @therewillbecode: Removed extraneous brackets from example in readme ([#1117](https://github.com/enzymejs/enzyme/pull/1117))
- @silvenon: Add note that mount() requires cleanup ([#1043](https://github.com/enzymejs/enzyme/pull/1043))
- @lelandrichardson: Add docs reflecting v3 ([#1121](https://github.com/enzymejs/enzyme/pull/1121))
## 2.9.1
### Fixes
- [Deps] Require uuid at least 3.0.1 ([#1001](https://github.com/enzymejs/enzyme/pull/1001))
## 2.9.0
### New Stuff
- `mount`/`shallow`: `debug`: add `ignoreProps` option ([#960](https://github.com/enzymejs/enzyme/pull/960))
### Fixes
- `shallow`: debug: fix indentation ([#926](https://github.com/enzymejs/enzyme/pull/926))
- react-compat: Make sure dependency error reporting always work ([#929](https://github.com/enzymejs/enzyme/pull/929))
- react-compat: correct error message ([#904](https://github.com/enzymejs/enzyme/pull/904))
### Documentation
- lint our markdown ([#988](https://github.com/enzymejs/enzyme/pull/988))
- correct `nvm` install instructions (never install it with homebrew) ([#988](https://github.com/enzymejs/enzyme/pull/988))
- fix typos ([#979](https://github.com/enzymejs/enzyme/pull/979)), ([#983](https://github.com/enzymejs/enzyme/pull/983))
- Added missing isEmptyRender() docs
- update jsdom guides for v10 and later ([#921](https://github.com/enzymejs/enzyme/pull/921))
### Refactors
- `shallow`/`mount`: Make all references to the wrapper `class` call into `this.wrap`
- update `uuid` from v2 to v3 ([#998](https://github.com/enzymejs/enzyme/pull/998))
## 2.8.2
### Fixes
- Loosen react-compat implicit dependency logic for React 15.4 ([#896](https://github.com/enzymejs/enzyme/pull/896))
### Documentation
- Update docs to use `prop-types` ([#894](https://github.com/enzymejs/enzyme/pull/894), [#890](https://github.com/enzymejs/enzyme/issues/890))
## 2.8.1
### Fixes
- support React@15.5 ([#876](https://github.com/enzymejs/enzyme/pull/876))
- no longer depend on `React.createClass` ([#877](https://github.com/enzymejs/enzyme/pull/877))
- Throw for malformed compound selectors ([#868](https://github.com/enzymejs/enzyme/pull/868))
## 2.8.0
### New Stuff
- add disableLifecycleMethods for shallow ([#789](https://github.com/enzymejs/enzyme/pull/789))
- Match children before and after interpolation ([#512](https://github.com/enzymejs/enzyme/pull/512))
- Supporting passing context to static rendering ([#429](https://github.com/enzymejs/enzyme/pull/429))
### Fixes
- Fix an issue w/ cleaning up global.document ([#855](https://github.com/enzymejs/enzyme/pull/855))
- Update props when shouldComponentUpdate returns `false` and `lifecycleExperimental` is on ([#807](https://github.com/enzymejs/enzyme/pull/807))
- Properly pass along options in `dive` ([#771](https://github.com/enzymejs/enzyme/pull/771))
## 2.7.1 (January 22, 2017)
### Fixes
- `mount`: Fix bug from ([#677](https://github.com/enzymejs/enzyme/pull/677) ([#680](https://github.com/enzymejs/enzyme/pull/680))
- `mount`: ignore text nodes in childrenOfInst ([#604](https://github.com/enzymejs/enzyme/pull/604))
### Documentation
- Update Docs for .getNode and .getNodes ([#743](https://github.com/enzymejs/enzyme/pull/743))
- Add a link for `ShallowWrapper#dive()` ([#759](https://github.com/enzymejs/enzyme/pull/759)
- Fix alphabetical order of API lists ([#761](https://github.com/enzymejs/enzyme/pull/761))
## 2.7.0 (December 21, 2016)
### New Stuff
- `shallow`/`mount`: Add `.slice()` method ([#661](https://github.com/enzymejs/enzyme/pull/661))
- `mount`: implement ReactWrapper#getDOMNode ([#679](https://github.com/enzymejs/enzyme/pull/679))
- `shallow`/`mount`: Add `exists`; deprecate isEmpty() ([#722](https://github.com/enzymejs/enzyme/pull/722))
### Fixes
- `mount`: extract MountedTraversal.hasClassName from MountedTraversal.instHasClassName, which allows ReactWrapper.hasClass to bypass the !isDOMComponent(inst) call ([#677](https://github.com/enzymejs/enzyme/pull/677))
- `withDom`: Display a useful error when `withDom` fails to find "jsdom" ([#686](https://github.com/enzymejs/enzyme/pull/686))
- `mount`: ensure that `react-text` comment nodes don’t break `.find` ([#691](https://github.com/enzymejs/enzyme/pull/691))
- `mount`: `.parents()` now filters out sibling path trees ([#713](https://github.com/enzymejs/enzyme/pull/713))
## 2.6.0 (November 9, 2016)
### New Stuff
- ensure ShallowWrapper render output can't get stale ([#490](https://github.com/enzymejs/enzyme/pull/490))
### Fixes
- Use shim to detect constructor function name ([#659](https://github.com/enzymejs/enzyme/pull/659))
- `mount`/`shallow`: fix ID selectors ([#670](https://github.com/enzymejs/enzyme/pull/670))
## 2.5.2 (November 9, 2016)
### Fixes
- Use shim to detect constructor function name ([#659](https://github.com/enzymejs/enzyme/pull/659))
- `mount`/`shallow`: fix ID selectors ([#670](https://github.com/enzymejs/enzyme/pull/670))
## 2.5.1 (October 17, 2016)
### Patches
- continue to support one-argument `single` ([#632](https://github.com/enzymejs/enzyme/pull/632))
## 2.5.0 (October 17, 2016)
### Minor Changes
- pass callback on setState and setProps ([#617](https://github.com/enzymejs/enzyme/pull/617))
- Make ReactWrapper and ShallowWrapper iterable ([#594](https://github.com/enzymejs/enzyme/pull/594))
- add `.dive()` method to `shallow` ([#618](https://github.com/enzymejs/enzyme/pull/618))
### Patches
- Warn if selector contains a pseudo-class ([#591](https://github.com/enzymejs/enzyme/pull/591))
- change isCompoundSelector to not match prop selector ([#595](https://github.com/enzymejs/enzyme/pull/595))
- fixed hasClassName in case className is not a string and has toString method ([#518](https://github.com/enzymejs/enzyme/pull/518))
- Throw if some() is called on a root wrapper ([#523](https://github.com/enzymejs/enzyme/pull/523))
- Fix valid + falsy propvalues ([#563](https://github.com/enzymejs/enzyme/pull/563))
## 2.4.2 (November 9, 2016)
### Fixes
- Use shim to detect constructor function name ([#659](https://github.com/enzymejs/enzyme/pull/659))
- `mount`/`shallow`: fix ID selectors ([#670](https://github.com/enzymejs/enzyme/pull/670))
## 2.4.1 (July 8, 2016)
### Patches
- Fix backwards incompatible `shouldComponentUpdate` call ([#491](https://github.com/enzymejs/enzyme/pull/491))
## 2.4.0 (July 7, 2016)
### Minor Changes
- Support all Component Lifecycle methods in ShallowRenderer (behind an experimental flag) ([#318](https://github.com/enzymejs/enzyme/pull/318))
- Add an `isEmptyRender()` method to both `ShallowWrapper` and `ReactWrapper` ([#339](https://github.com/enzymejs/enzyme/pull/339))
- Add support for batched updates with `ShallowRender.simulate` ([#342](https://github.com/enzymejs/enzyme/pull/342))
### Patches
- Switch to using classList instead of className ([#448](https://github.com/enzymejs/enzyme/pull/448))
- fixes mount().debug() output with mixed children ([#476](https://github.com/enzymejs/enzyme/pull/476))
- Support additional characters in attribute selectors ([#412](https://github.com/enzymejs/enzyme/pull/412))
- fix id selector not working when combined with a tag selector ([#387](https://github.com/enzymejs/enzyme/pull/387))
- Support spaces in attribute selector values ([#427](https://github.com/enzymejs/enzyme/pull/427))
## 2.3.0 (May 9, 2016)
### Minor Changes
- add `.tap()` method to `ShallowWrapper` and `ReactWrapper` ([#299](https://github.com/enzymejs/enzyme/pull/299))
- add `.key()` method to `ShallowWrapper` and `ReactWrapper` ([#327](https://github.com/enzymejs/enzyme/pull/327))
- add support for descendent selectors, `>`, `~` and `+` ([#217](https://github.com/enzymejs/enzyme/pull/217))
- new `containsMatchingElement`, `containsAllMatchingElements`, and `containsAnyMatchingElements` APIs ([#362](https://github.com/enzymejs/enzyme/pull/362))
- new `.name()` method ([#335](https://github.com/enzymejs/enzyme/pull/335))
### Patches
- add `dblclick` to eventType map for simulate ([#317](https://github.com/enzymejs/enzyme/pull/317))
- fix `pathToNode` bug with child-containing children ([#296](https://github.com/enzymejs/enzyme/pull/296))
- prioritize `displayName` over `name` for consistency in `.debug()` ([#332](https://github.com/enzymejs/enzyme/pull/332))
- handle insignificant whitespace in className ([#348](https://github.com/enzymejs/enzyme/pull/348))
- fix handling of SFC components and `.instance()` ([#359](https://github.com/enzymejs/enzyme/pull/359))
- reduce false positives by using argument validation for `.contains` ([#259](https://github.com/enzymejs/enzyme/pull/259))
- fix equality algorithm so that non-renderable nodes are equivalent ([#192](https://github.com/enzymejs/enzyme/pull/192))
- add better error handling for `state`, `setState`, and `context` ([#373](https://github.com/enzymejs/enzyme/pull/373))
## 2.2.0 (March 21, 2016)
### Minor Changes
- add `options` param to `ShallowWrapper::shallow` ([#275](https://github.com/enzymejs/enzyme/pull/275))
### Patches
- make enzyme compatible with all React 15 RCs ([#272](https://github.com/enzymejs/enzyme/pull/272))
- increase coverage for Stateless Functional Components ([#267](https://github.com/enzymejs/enzyme/pull/267))
- improve context support for Stateless Functional Components ([#256](https://github.com/enzymejs/enzyme/pull/256))
- fix tree traversal for Stateless Functional Components ([#257](https://github.com/enzymejs/enzyme/pull/257))
- fix `.find` for nested Stateless Functional Components ([#274](https://github.com/enzymejs/enzyme/pull/274))
- fix `.props()` and `.debug()` methods for Stateless Functional Components ([#255](https://github.com/enzymejs/enzyme/pull/255))
- prevent falsy nodes from being counted as children ([#251](https://github.com/enzymejs/enzyme/pull/251))
## 2.1.0 (March 10, 2016)
### Minor Changes
- add support for React 15.0.0-rc.1 ([#240](https://github.com/enzymejs/enzyme/pull/240))
- add `.unmount()` method for ShallowWrapper ([#215](https://github.com/enzymejs/enzyme/pull/215))
- add direct imports for `mount`, `shallow`, and `render` ([#198](https://github.com/enzymejs/enzyme/pull/198))
- add a `.childAt(n)` shorthand method ([#187](https://github.com/enzymejs/enzyme/pull/187))
### Patches
- fix bug in .contains() for matching sub-arrays ([#226](https://github.com/enzymejs/enzyme/pull/226))
- fix bug in matching by type displayName ([#230](https://github.com/enzymejs/enzyme/pull/230))
- add more useful warnings for missing implicit dependencies ([#228](https://github.com/enzymejs/enzyme/pull/228))
- improve SFC support for `.type()` ([#196](https://github.com/enzymejs/enzyme/pull/196))
- fix null handling for `.html()` and `.render()` ([#196](https://github.com/enzymejs/enzyme/pull/196))
- moved from `underscore` to `lodash` ([#189](https://github.com/enzymejs/enzyme/pull/189))
## 2.0.0 (February 10, 2016)
### Major Changes (breaking)
- removed `describeWithDOM` utility ([#159](https://github.com/enzymejs/enzyme/pull/159))
- removed `useSinon`, `spyPrototype` and `spyLifecycle` utilities ([#159](https://github.com/enzymejs/enzyme/pull/159))
- removed `sinon` dependency ([#159](https://github.com/enzymejs/enzyme/pull/159))
- removed `jsdom` dependency ([#159](https://github.com/enzymejs/enzyme/pull/159))
## 1.6.0 (February 10, 2016)
### Minor Changes
- add option for childContextTypes of `ReactWrapper` ([#171](https://github.com/enzymejs/enzyme/pull/171))
### Patches
- Prevent null or false nodes from being passed into tree traversal ([#174](https://github.com/enzymejs/enzyme/pull/174))
- setProps no longer swallows exceptions ([#170](https://github.com/enzymejs/enzyme/pull/170))
- `.type()` and `.props()` should not fail on null now ([#162](https://github.com/enzymejs/enzyme/pull/162))
## 1.5.0 (February 2, 2016)
### Minor Changes
- Add `attachTo` option to `mount` to mount to a specific element ([#160](https://github.com/enzymejs/enzyme/pull/160))
- Add `.debug()` method to `ReactWrapper` ([#158](https://github.com/enzymejs/enzyme/pull/158))
- Add `.mount()` and `.unmount()` APIs to `ReactWrapper` ([#155](https://github.com/enzymejs/enzyme/pull/155))
- Add `.render()` method to `ReactWrapper` ([#156](https://github.com/enzymejs/enzyme/pull/156))
- Allow `.contains()` to accept an array of nodes ([#154](https://github.com/enzymejs/enzyme/pull/154))
- Add `.context()` method to `ReactWrapper` and `ShallowWrapper` ([#152](https://github.com/enzymejs/enzyme/pull/152))
### Patches
- Fixed some behavior with `.contains()` matching on strings ([#148](https://github.com/enzymejs/enzyme/pull/148))
- Fixed `.debug()`'s output for numeric children ([#149](https://github.com/enzymejs/enzyme/pull/149))
- Documentation fixes
- Update versions of dependencies
## 1.4.1 (January 24, 2016)
### Patches
- Upgrade to babel 6 ([#81](https://github.com/enzymejs/enzyme/pull/81))
- Fix event naming bug in ShallowWrapper ([#135](https://github.com/enzymejs/enzyme/pull/135))
- Documentation fixes
## 1.4.0 (January 21, 2016)
### Minor Changes
- `describeWithDOM` enhancement ([#126](https://github.com/enzymejs/enzyme/pull/126))
- add `.equals()` method to `ShallowWrapper` ([#124](https://github.com/enzymejs/enzyme/pull/124))
- add object selector syntax ([#110](https://github.com/enzymejs/enzyme/pull/110))
### Patches
- Fixed confusing behavior of prop selector syntax ([#130](https://github.com/enzymejs/enzyme/pull/130))
- Documentation fixes
## 1.3.1 (January 15, 2016)
### Patches
- Fix setProps not passing old context ([#121](https://github.com/enzymejs/enzyme/pull/121))
- Map lowercase mouse events in simulate ([#77](https://github.com/enzymejs/enzyme/pull/77))
## 1.3.0 (January 13, 2016)
### Minor Changes
- Added `.html()` method to `ReactWrapper` ([#71](https://github.com/enzymejs/enzyme/pull/71))
- Support property selector (i.e. `[prop="foo"]`) ([#70](https://github.com/enzymejs/enzyme/pull/70))
- jsdom dependency now allows a range of supported versions ([#95](https://github.com/enzymejs/enzyme/pull/95))
### Patches
- Normalized `setProps()` behavior between `mount`/`shallow` to merge props ([#103](https://github.com/enzymejs/enzyme/pull/103))
- Exclude `_book` from published package ([#85](https://github.com/enzymejs/enzyme/pull/85))
- Various documentation, tests, and style changes
## 1.2.0 (December 10, 2015)
### Minor Changes
- Support for context ([#62](https://github.com/enzymejs/enzyme/pull/62))
### Patches
- `nodeHasId` fix for some 0.14 corner cases ([#65](https://github.com/enzymejs/enzyme/pull/65))
## 1.1.0 (December 7, 2015)
### Minor Changes
- Support for Stateless Functional Components ([#53](https://github.com/enzymejs/enzyme/pull/53))
### Patches
- Tweak `describeWithDOM` messaging ([#48](https://github.com/enzymejs/enzyme/pull/48))
- Documentation Fixes
## 1.0.0 (December 3, 2015)
- Official Release!
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing Guide
Contributions are welcome and are greatly appreciated! Every little bit helps, and credit will
always be given.
## Setting up your environment
After forking enzyme to your own github org, do the following steps to get started:
```bash
# clone your fork to your local machine
git clone https://github.com/enzymejs/enzyme.git
# step into local repo
cd enzyme
# install dependencies (use `react 13` if you want to use React 0.13)
npm install
# install react version
# accepts `13` for v0.13, `14` for v0.14, and for versions 15+,
# accepts either a major (`15`, `16`) or a minor (`15.4`, `16.8`)
npm run react 16
```
### Switching between React 16, React 15, React 0.14 and React 0.13
```bash
# switch to React 0.13
npm run react 13
```
```bash
# switch to React 0.14
npm run react 14
```
```bash
# switch to React 15
npm run react 15
```
```bash
# switch to React 16
npm run react 16
```
Specific versions can also be specified
```bash
# switch to React 16.5
npm run react 16.5
```
### Running Tests
The test suite runs on *built* Enzyme.
```bash
# build Enzyme locally before testing
npm run build
# run tests on whatever version of React is currently installed
npm test
```
```bash
# run tests on all supported versions of React
npm run test:all
```
If you are actively developing, Enzyme will always need to be built with the latest changes.
For this, the recommended workflow is to have the build and tests watching for changes in separate terminals. This should provide you with ~realtime feedback:
```bash
# build Enzyme locally upon save
npm run build:watch
# faster feedback for TDD
npm run test:watch
```
### Tests for functionality shared between `shallow` and `mount`
Tests for a method "foo" are stored in `packages/enzyme-test-suite/test/shared/methods/foo`. The file default exports a function that receives an injected object argument, containing the following properties:
- `Wrap`: e.g. `shallow`, `mount`
- `WrapRendered`: this abstracts around the differences between `shallow` and `mount` - e.g., that the root of a shallow wrapper around `Foo` is what `Foo` *renders*, where the root of a mount wrapper around `Foo` is `Foo` itself. Thus, this function produces a wrapper around what `Foo` renders, regardless of the `Wrap` method used.
- `Wrapper`: e.g. `ShallowWrapper`, `ReactWrapper`
- `WrapperName`: e.g. `"ShallowWrapper"`, `"ReactWrapper"`
- `isShallow`: true if `shallow`. note: needing to use this is a code smell, please avoid.
- `isMount`: true if `mount`. note: needing to use this is a code smell, please avoid.
- `makeDOMElement`: in `mount`, makes a real DOM element; in `shallow`, makes a mock object.
These tests are ran via an explicit list in a `describeMethods` call in the ReactWrapper and ShallowWrapper test files. If you add a new test file for a shared method, you'll need to add its name to both calls.
### Style & Linting
This codebase adheres to the [Airbnb Styleguide](https://github.com/airbnb/javascript) and is
enforced using [ESLint](https://eslint.org).
As with the test suite, the linter will not fully pass unless it is running on *built* Enzyme. This is because the ESLint `import/*` rules rely on finding the target files in the filesystem (which won't be there unless they've been built).
It is recommended that you install an ESLint plugin for your editor of choice when working on this
codebase, however you can always check to see if the source code is compliant by running:
```bash
# build Enzyme locally before linting
npm run build
npm run lint
```
### Publishing
Enzyme uses [lerna](https://github.com/lerna/lerna) to structure its repo, and has multiple packages
to publish out of this one repo. We use lerna's "independent" mode, which means that the versioning
of each package in the repo is versioned independently.
We are waiting on [this issue](https://github.com/lerna/lerna/issues/955) to be fixed, so that
`peerDependencies` do not get updated with patch updates.
Until this issue is fixed, we will publish each package manually instead of with `lerna publish`. In
order to do this, we will:
For enzyme:
```bash
# ... update version in enzyme/package.json, make changes to CHANGELOG, etc.
cd packages/enzyme
git commit -m v{version}
git tag -a -m v{version}
git push --follow-tags
npm publish
```
For other packages
```bash
# ... update version in {package}/package.json, make changes to CHANGELOG, etc.
cd packages/{package}
git commit -m "{package}: v{version}"
git tag -a -m "{package}: v{version}"
git push --follow-tags
npm publish
```
Once we are able to use `lerna publish`, the process will be as follows:
Lerna by default will only publish packages that have changed since the last release. It will also
create a tagged commit for each release.
To publish, run:
```bash
lerna publish -m "{tag name}"
```
The tag name is determined by the `-m` CLI option. If `enzyme` is one of the packages that has
updates, we default to just using that version as the tag name. For instance, when publishing
`enzyme@3.1.1` and `enzyme-adapter-react-16@1.2.3` we would run:
```bash
lerna publish -m "v3.1.1"
```
If `enzyme` is *not* one of the packages being updated, use the other package's name and the version:
```bash
lerna publish -m "enzyme-adapter-react-16: v1.2.3"
```
The `lerna publish` command will present interactive prompts asking which version to use for each
package independently. Just choose whichever
### Building Docs
Building the docs locally is extremely simple. First execute the following command:
```bash
npm run docs:watch
```
After this, you can open up your browser to the specified port (usually http://localhost:4000 )
The browser will automatically refresh when there are changes to any of the source files.
## Pull Request Guidelines
Before you submit a pull request from your forked repo, check that it meets these guidelines:
1. If the pull request fixes a bug, it should include tests that fail without the changes, and pass
with them.
1. If the pull request adds functionality, the docs should be updated as part of the same PR.
1. The pull request should work for React 15, React 0.14 and React 0.13. The CI server should run the
tests in all versions automatically when you push the PR, but if you'd like to check locally, you
can do so (see above).
1. Please rebase and resolve all conflicts before submitting.
================================================
FILE: INTHEWILD.md
================================================
Please use [pull requests](https://github.com/enzymejs/enzyme/pull/new/master) to add your organization and/or project to this document!
Organizations
----------
- [Airbnb](https://github.com/airbnb)
- [Cerner](https://github.com/cerner)
- [OpenGov](https://github.com/opengov)
- [Pinterest](https://github.com/pinterest)
- [Product Hunt](https://github.com/producthunt)
- [Walmart Labs](https://github.com/walmartlabs)
- [Hudl](http://hudl.github.io/)
- [NET-A-PORTER](https://github.com/NET-A-PORTER)
- [Rangle.io](https://github.com/rangle)
- [GoDaddy](https://github.com/godaddy)
- [Airware](https://github.com/airware)
- [Flatiron School](https://github.com/flatiron-labs)
- [Outreach.io](https://github.com/getoutreach)
- [crowdSPRING](https://crowdspring.com)
- [nteract](https://nteract.io)
- [Brave](https://brave.com)
- [Simple](https://github.com/simplefinance)
- [Grab](https://github.com/grab)
- [Megalytic](https://megalytic.com/)
- [Chroma](https://www.chromatic.com)
- [Mavens](https://github.com/mavens)
- [Cucumber](https://cucumber.io)
- [Genoa Telepsychiatry](https://genoatelepsychiatry.com)
- [IBM X-Force Exchange](https://exchange.xforce.ibmcloud.com)
- [Zendesk](https://zendesk.com/)
- [idealo](https://www.idealo.de/)
- [LendingHome](https://www.lendinghome.com)
- [Diffia](https://diffia.com)
- [MinuteMedia](https://www.minutemedia.com)
- [Webex Teams](https://www.webex.com/team-collaboration.html)
- [reformma](https://www.reformma.com)
Projects
----------
- [Rheostat](https://github.com/airbnb/rheostat)
- [React Boilerplate](https://github.com/mxstbr/react-boilerplate/tree/v3.0.0)
- [Reactstrap](https://github.com/reactstrap/reactstrap)
- [Recompose](https://github.com/acdlite/recompose)
- [Reapop](https://github.com/LouisBarranqueiro/reapop)
- [React Dates](https://github.com/airbnb/react-dates)
- [nteract notebook](https://github.com/nteract/nteract)
================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)
Copyright (c) 2015 Airbnb, Inc. and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: MAINTAINERS
================================================
ljharb
lelandrichardson
blainekasten
Aweary
nfcampos
================================================
FILE: README.md
================================================
Enzyme
=======
[](https://gitter.im/enzymejs/enzyme?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://www.npmjs.com/package/enzyme) [](https://github.com/enzymejs/enzyme/blob/master/LICENSE.md) [](https://travis-ci.org/enzymejs/enzyme) [](https://codecov.io/gh/enzymejs/enzyme/branch/master)
Enzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output.
You can also manipulate, traverse, and in some ways simulate runtime given the output.
Enzyme's API is meant to be intuitive and flexible by mimicking jQuery's API for DOM manipulation
and traversal.
Upgrading from Enzyme 2.x or React < 16
===========
Are you here to check whether or not Enzyme is compatible with React 16? Are you currently using
Enzyme 2.x? Great! Check out our [migration guide](/docs/guides/migration-from-2-to-3.md) for help
moving on to Enzyme v3 where React 16 is supported.
### [Installation](/docs/installation/README.md)
To get started with enzyme, you can simply install it via npm. You will need to install enzyme
along with an Adapter corresponding to the version of react (or other UI Component library) you
are using. For instance, if you are using enzyme with React 16, you can run:
```bash
npm i --save-dev enzyme enzyme-adapter-react-16
```
Each adapter may have additional peer dependencies which you will need to install as well. For instance,
`enzyme-adapter-react-16` has peer dependencies on `react` and `react-dom`.
At the moment, Enzyme has adapters that provide compatibility with `React 16.x`, `React 15.x`,
`React 0.14.x` and `React 0.13.x`.
The following adapters are officially provided by enzyme, and have the following compatibility with
React:
| Enzyme Adapter Package | React semver compatibility |
| --- | --- |
| `enzyme-adapter-react-16` | `^16.4.0-0` |
| `enzyme-adapter-react-16.3` | `~16.3.0-0` |
| `enzyme-adapter-react-16.2` | `~16.2` |
| `enzyme-adapter-react-16.1` | ~16.0.0-0 || ~16.1 |
| `enzyme-adapter-react-15` | `^15.5.0` |
| `enzyme-adapter-react-15.4` | `15.0.0-0 - 15.4.x` |
| `enzyme-adapter-react-14` | `^0.14.0` |
| `enzyme-adapter-react-13` | `^0.13.0` |
Finally, you need to configure enzyme to use the adapter you want it to use. To do this, you can use
the top level `configure(...)` API.
```js
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
```
3rd Party Adapters
=============
It is possible for the community to create additional (non-official) adapters that will make enzyme
work with other libraries. If you have made one and it's not included in the list below, feel free
to make a PR to this README and add a link to it! The known 3rd party adapters are:
| Adapter Package | For Library | Status |
| --- | --- | --- |
| [`enzyme-adapter-preact-pure`](https://github.com/preactjs/enzyme-adapter-preact-pure) | [`preact`](https://github.com/developit/preact) | (stable) |
|[`enzyme-adapter-inferno`](https://github.com/bbc/enzyme-adapter-inferno)|[`inferno`](https://github.com/infernojs/inferno)|(work in progress)|
Running Enzyme Tests
===========
Enzyme is unopinionated regarding which test runner or assertion library you use, and should be
compatible with all major test runners and assertion libraries out there. The documentation and
examples for enzyme use [Mocha](https://mochajs.org) and [Chai](https://chaijs.com), but you
should be able to extrapolate to your framework of choice.
If you are interested in using enzyme with custom assertions and convenience functions for
testing your React components, you can consider using:
* [`chai-enzyme`](https://github.com/producthunt/chai-enzyme) with Mocha/Chai.
* [`jasmine-enzyme`](https://github.com/FormidableLabs/enzyme-matchers/tree/master/packages/jasmine-enzyme) with Jasmine.
* [`jest-enzyme`](https://github.com/FormidableLabs/enzyme-matchers/tree/master/packages/jest-enzyme) with Jest.
* [`should-enzyme`](https://github.com/rkotze/should-enzyme) for should.js.
* [`expect-enzyme`](https://github.com/PsychoLlama/expect-enzyme) for expect.
[Using Enzyme with Mocha](/docs/guides/mocha.md)
[Using Enzyme with Karma](/docs/guides/karma.md)
[Using Enzyme with Browserify](/docs/guides/browserify.md)
[Using Enzyme with SystemJS](/docs/guides/systemjs.md)
[Using Enzyme with Webpack](/docs/guides/webpack.md)
[Using Enzyme with JSDOM](/docs/guides/jsdom.md)
[Using Enzyme with React Native](/docs/guides/react-native.md)
[Using Enzyme with Jest](/docs/guides/jest.md)
[Using Enzyme with Lab](/docs/guides/lab.md)
[Using Enzyme with Tape and AVA](/docs/guides/tape-ava.md)
Basic Usage
===========
## [Shallow Rendering](/docs/api/shallow.md)
```javascript
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import sinon from 'sinon';
import MyComponent from './MyComponent';
import Foo from './Foo';
describe('', () => {
it('renders three components', () => {
const wrapper = shallow();
expect(wrapper.find(Foo)).to.have.lengthOf(3);
});
it('renders an `.icon-star`', () => {
const wrapper = shallow();
expect(wrapper.find('.icon-star')).to.have.lengthOf(1);
});
it('renders children when passed in', () => {
const wrapper = shallow((
));
expect(wrapper.contains(
)).to.equal(true);
});
it('simulates click events', () => {
const onButtonClick = sinon.spy();
const wrapper = shallow();
wrapper.find('button').simulate('click');
expect(onButtonClick).to.have.property('callCount', 1);
});
});
```
Read the full [API Documentation](/docs/api/shallow.md)
## [Full DOM Rendering](/docs/api/mount.md)
```javascript
import React from 'react';
import sinon from 'sinon';
import { expect } from 'chai';
import { mount } from 'enzyme';
import Foo from './Foo';
describe('', () => {
it('allows us to set props', () => {
const wrapper = mount();
expect(wrapper.props().bar).to.equal('baz');
wrapper.setProps({ bar: 'foo' });
expect(wrapper.props().bar).to.equal('foo');
});
it('simulates click events', () => {
const onButtonClick = sinon.spy();
const wrapper = mount((
));
wrapper.find('button').simulate('click');
expect(onButtonClick).to.have.property('callCount', 1);
});
it('calls componentDidMount', () => {
sinon.spy(Foo.prototype, 'componentDidMount');
const wrapper = mount();
expect(Foo.prototype.componentDidMount).to.have.property('callCount', 1);
Foo.prototype.componentDidMount.restore();
});
});
```
Read the full [API Documentation](/docs/api/mount.md)
## [Static Rendered Markup](/docs/api/render.md)
```javascript
import React from 'react';
import { expect } from 'chai';
import { render } from 'enzyme';
import Foo from './Foo';
describe('', () => {
it('renders three `.foo-bar`s', () => {
const wrapper = render();
expect(wrapper.find('.foo-bar')).to.have.lengthOf(3);
});
it('renders the title', () => {
const wrapper = render();
expect(wrapper.text()).to.contain('unique');
});
});
```
Read the full [API Documentation](/docs/api/render.md)
### React Hooks support
Enzyme supports [react hooks](https://reactjs.org/docs/hooks-intro.html) with some limitations in [`.shallow()`](https://enzymejs.github.io/enzyme/docs/api/shallow.html) due to upstream issues in React's shallow renderer:
* `useEffect()` and `useLayoutEffect()` don't get called in the React shallow renderer. [Related issue](https://github.com/facebook/react/issues/15275)
* `useCallback()` doesn't memoize callback in React shallow renderer. [Related issue](https://github.com/facebook/react/issues/15774)
#### [`ReactTestUtils.act()`](https://reactjs.org/docs/test-utils.html#act) wrap
If you're using React 16.8+ and `.mount()`, Enzyme will wrap apis including [`.simulate()`](https://enzymejs.github.io/enzyme/docs/api/ReactWrapper/simulate.html), [`.setProps()`](https://enzymejs.github.io/enzyme/docs/api/ReactWrapper/setProps.html), [`.setContext()`](https://enzymejs.github.io/enzyme/docs/api/ReactWrapper/setContext.html), [`.invoke()`](https://enzymejs.github.io/enzyme/docs/api/ReactWrapper/invoke.html) with [`ReactTestUtils.act()`](https://reactjs.org/docs/test-utils.html#act) so you don't need to manually wrap it.
A common pattern to trigger handlers with `.act()` and assert is:
```javascript
const wrapper = mount();
act(() => wrapper.prop('handler')());
wrapper.update();
expect(/* ... */);
```
We cannot wrap the result of `.prop()` (or `.props()`) with `.act()` in Enzyme internally since it will break the equality of the returned value.
However, you could use `.invoke()` to simplify the code:
```javascript
const wrapper = mount();
wrapper.invoke('handler')();
expect(/* ... */);
```
### Future
[Enzyme Future](/docs/future.md)
### Contributing
See the [Contributors Guide](/CONTRIBUTING.md)
### In the wild
Organizations and projects using `enzyme` can list themselves [here](INTHEWILD.md).
### License
[MIT](/LICENSE.md)
================================================
FILE: SUMMARY.md
================================================
## Table of Contents
* [Introduction](/README.md)
* [Guides](/docs/guides.md)
* [Migration from 2.x to 3.x](/docs/guides/migration-from-2-to-3.md)
* [Browserify](/docs/guides/browserify.md)
* [SystemJS](/docs/guides/systemjs.md)
* [Webpack](/docs/guides/webpack.md)
* [JSDOM](/docs/guides/jsdom.md)
* [Jest](/docs/guides/jest.md)
* [Karma](/docs/guides/karma.md)
* [Mocha](/docs/guides/mocha.md)
* [React Native](/docs/guides/react-native.md)
* [Lab](/docs/guides/lab.md)
* [Tape and AVA](/docs/guides/tape-ava.md)
* [Installation](/docs/installation/README.md)
* [Working with React 16.x](/docs/installation/react-16.md)
* [Working with React 15.x](/docs/installation/react-15.md)
* [Working with React 0.14.x](/docs/installation/react-014.md)
* [Working with React 0.13.x](/docs/installation/react-013.md)
* [API Reference](/docs/api/README.md)
* [Shallow Rendering](/docs/api/shallow.md)
* [at(index)](/docs/api/ShallowWrapper/at.md)
* [childAt()](/docs/api/ShallowWrapper/childAt.md)
* [children()](/docs/api/ShallowWrapper/children.md)
* [closest(selector)](/docs/api/ShallowWrapper/closest.md)
* [contains(nodeOrNodes)](/docs/api/ShallowWrapper/contains.md)
* [containsAllMatchingElements(nodes)](/docs/api/ShallowWrapper/containsAllMatchingElements.md)
* [containsAnyMatchingElements(nodes)](/docs/api/ShallowWrapper/containsAnyMatchingElements.md)
* [containsMatchingElement(node)](/docs/api/ShallowWrapper/containsMatchingElement.md)
* [context([key])](/docs/api/ShallowWrapper/context.md)
* [debug()](/docs/api/ShallowWrapper/debug.md)
* [dive()](/docs/api/ShallowWrapper/dive.md)
* [equals(node)](/docs/api/ShallowWrapper/equals.md)
* [every(selector)](/docs/api/ShallowWrapper/every.md)
* [everyWhere(predicate)](/docs/api/ShallowWrapper/everyWhere.md)
* [exists([selector])](/docs/api/ShallowWrapper/exists.md)
* [filter(selector)](/docs/api/ShallowWrapper/filter.md)
* [filterWhere(predicate)](/docs/api/ShallowWrapper/filterWhere.md)
* [find(selector)](/docs/api/ShallowWrapper/find.md)
* [findWhere(predicate)](/docs/api/ShallowWrapper/findWhere.md)
* [first()](/docs/api/ShallowWrapper/first.md)
* [forEach(fn)](/docs/api/ShallowWrapper/forEach.md)
* [get(index)](/docs/api/ShallowWrapper/get.md)
* [getWrappingComponent()](/docs/api/ShallowWrapper/getWrappingComponent.md)
* [getElement(index)](/docs/api/ShallowWrapper/getElement.md)
* [getElements(index)](/docs/api/ShallowWrapper/getElements.md)
* [hasClass(className)](/docs/api/ShallowWrapper/hasClass.md)
* [hostNodes()](/docs/api/ShallowWrapper/hostNodes.md)
* [html()](/docs/api/ShallowWrapper/html.md)
* [instance()](/docs/api/ShallowWrapper/instance.md)
* [invoke(propName)](/docs/api/ShallowWrapper/invoke.md)
* [is(selector)](/docs/api/ShallowWrapper/is.md)
* [isEmpty()](/docs/api/ShallowWrapper/isEmpty.md)
* [isEmptyRender()](/docs/api/ShallowWrapper/isEmptyRender.md)
* [key()](/docs/api/ShallowWrapper/key.md)
* [last()](/docs/api/ShallowWrapper/last.md)
* [map(fn)](/docs/api/ShallowWrapper/map.md)
* [matchesElement(node)](/docs/api/ShallowWrapper/matchesElement.md)
* [name()](/docs/api/ShallowWrapper/name.md)
* [not(selector)](/docs/api/ShallowWrapper/not.md)
* [parent()](/docs/api/ShallowWrapper/parent.md)
* [parents()](/docs/api/ShallowWrapper/parents.md)
* [prop(key)](/docs/api/ShallowWrapper/prop.md)
* [props()](/docs/api/ShallowWrapper/props.md)
* [reduce(fn[, initialValue])](/docs/api/ShallowWrapper/reduce.md)
* [reduceRight(fn[, initialValue])](/docs/api/ShallowWrapper/reduceRight.md)
* [render()](/docs/api/ShallowWrapper/render.md)
* [renderProp(key)](/docs/api/ShallowWrapper/renderProp.md)
* [setContext(context)](/docs/api/ShallowWrapper/setContext.md)
* [setProps(nextProps)](/docs/api/ShallowWrapper/setProps.md)
* [setState(nextState[, callback])](/docs/api/ShallowWrapper/setState.md)
* [shallow([options])](/docs/api/ShallowWrapper/shallow.md)
* [simulate(event[, data])](/docs/api/ShallowWrapper/simulate.md)
* [simulateError(error)](/docs/api/ShallowWrapper/simulateError.md)
* [slice([begin[, end]])](/docs/api/ShallowWrapper/slice.md)
* [some(selector)](/docs/api/ShallowWrapper/some.md)
* [someWhere(predicate)](/docs/api/ShallowWrapper/someWhere.md)
* [state([key])](/docs/api/ShallowWrapper/state.md)
* [tap(intercepter)](/docs/api/ShallowWrapper/tap.md)
* [text()](/docs/api/ShallowWrapper/text.md)
* [type()](/docs/api/ShallowWrapper/type.md)
* [unmount()](/docs/api/ShallowWrapper/unmount.md)
* [update()](/docs/api/ShallowWrapper/update.md)
* [Full DOM Rendering](/docs/api/mount.md)
* [at(index)](/docs/api/ReactWrapper/at.md)
* [childAt()](/docs/api/ReactWrapper/childAt.md)
* [children()](/docs/api/ReactWrapper/children.md)
* [contains(nodeOrNodes)](/docs/api/ReactWrapper/contains.md)
* [containsAllMatchingElements(nodes)](/docs/api/ReactWrapper/containsAllMatchingElements.md)
* [containsAnyMatchingElements(nodes)](/docs/api/ReactWrapper/containsAnyMatchingElements.md)
* [containsMatchingElement(node)](/docs/api/ReactWrapper/containsMatchingElement.md)
* [closest(selector)](/docs/api/ReactWrapper/closest.md)
* [context([key])](/docs/api/ReactWrapper/context.md)
* [debug()](/docs/api/ReactWrapper/debug.md)
* [detach()](/docs/api/ReactWrapper/detach.md)
* [equals(node)](/docs/api/ReactWrapper/equals.md)
* [every(selector)](/docs/api/ReactWrapper/every.md)
* [everyWhere(predicate)](/docs/api/ReactWrapper/everyWhere.md)
* [exists([selector])](/docs/api/ReactWrapper/exists.md)
* [filter(selector)](/docs/api/ReactWrapper/filter.md)
* [filterWhere(predicate)](/docs/api/ReactWrapper/filterWhere.md)
* [find(selector)](/docs/api/ReactWrapper/find.md)
* [findWhere(predicate)](/docs/api/ReactWrapper/findWhere.md)
* [first()](/docs/api/ReactWrapper/first.md)
* [forEach(fn)](/docs/api/ReactWrapper/forEach.md)
* [get(index)](/docs/api/ReactWrapper/get.md)
* [getDOMNode()](/docs/api/ReactWrapper/getDOMNode.md)
* [getWrappingComponent()](/docs/api/ReactWrapper/getWrappingComponent.md)
* [hasClass(className)](/docs/api/ReactWrapper/hasClass.md)
* [hostNodes()](/docs/api/ReactWrapper/hostNodes.md)
* [html()](/docs/api/ReactWrapper/html.md)
* [instance()](/docs/api/ReactWrapper/instance.md)
* [invoke(propName)](/docs/api/ReactWrapper/invoke.md)
* [is(selector)](/docs/api/ReactWrapper/is.md)
* [isEmpty()](/docs/api/ReactWrapper/isEmpty.md)
* [isEmptyRender()](/docs/api/ReactWrapper/isEmptyRender.md)
* [key()](/docs/api/ReactWrapper/key.md)
* [last()](/docs/api/ReactWrapper/last.md)
* [map(fn)](/docs/api/ReactWrapper/map.md)
* [matchesElement(node)](/docs/api/ReactWrapper/matchesElement.md)
* [mount()](/docs/api/ReactWrapper/mount.md)
* [name()](/docs/api/ReactWrapper/name.md)
* [not(selector)](/docs/api/ReactWrapper/not.md)
* [parent()](/docs/api/ReactWrapper/parent.md)
* [parents()](/docs/api/ReactWrapper/parents.md)
* [prop(key)](/docs/api/ReactWrapper/prop.md)
* [props()](/docs/api/ReactWrapper/props.md)
* [reduce(fn[, initialValue])](/docs/api/ReactWrapper/reduce.md)
* [reduceRight(fn[, initialValue])](/docs/api/ReactWrapper/reduceRight.md)
* [ref(refName)](/docs/api/ReactWrapper/ref.md)
* [render()](/docs/api/ReactWrapper/render.md)
* [renderProp(key)](/docs/api/ReactWrapper/renderProp.md)
* [setContext(context)](/docs/api/ReactWrapper/setContext.md)
* [setProps(nextProps[, callback])](/docs/api/ReactWrapper/setProps.md)
* [setState(nextState[, callback])](/docs/api/ReactWrapper/setState.md)
* [simulate(event[, data])](/docs/api/ReactWrapper/simulate.md)
* [simulateError(error)](/docs/api/ReactWrapper/simulateError.md)
* [slice([begin[, end]])](/docs/api/ReactWrapper/slice.md)
* [some(selector)](/docs/api/ReactWrapper/some.md)
* [someWhere(predicate)](/docs/api/ReactWrapper/someWhere.md)
* [state([key])](/docs/api/ReactWrapper/state.md)
* [tap(intercepter)](/docs/api/ReactWrapper/tap.md)
* [text()](/docs/api/ReactWrapper/text.md)
* [type()](/docs/api/ReactWrapper/type.md)
* [unmount()](/docs/api/ReactWrapper/unmount.md)
* [update()](/docs/api/ReactWrapper/update.md)
* [Static Rendering](/docs/api/render.md)
* [Selectors](/docs/api/selector.md)
* [Change Log](/CHANGELOG.md)
* [Future](/docs/future.md)
* [Contributing Guide](/CONTRIBUTING.md)
================================================
FILE: book.json
================================================
{
"gitbook": "3.2.2",
"title": "Enzyme",
"description": "React Testing",
"plugins": [
"edit-link",
"github",
"-search",
"codeblock-disable-glossary",
"collapsible-menu",
"anchors"
],
"pluginsConfig": {
"edit-link": {
"base": "https://github.com/enzymejs/enzyme/tree/master",
"label": "Edit This Page"
},
"github": {
"url": "https://github.com/enzymejs/enzyme/"
}
}
}
================================================
FILE: docs/GLOSSARY.md
================================================
# selector
A Selector in enzyme is similar to a CSS selector, but can be a number of other things as well in
order to easily specify a criteria by which you want to find nodes in an enzyme wrapper. See the
[Selector page](/docs/api/selector.md) for more information.
# wrapper
A wrapper refers to the enzyme wrapper class that provides the API.
# predicate
A function that returns true or false
================================================
FILE: docs/api/README.md
================================================
# API Reference
### [Shallow Rendering](shallow.md)
```jsx
import { shallow } from 'enzyme';
const wrapper = shallow();
// ...
```
### [Full Rendering](mount.md)
```jsx
import { mount } from 'enzyme';
const wrapper = mount();
// ...
```
### [Static Rendering](render.md)
```jsx
import { render } from 'enzyme';
const wrapper = render();
// ...
```
================================================
FILE: docs/api/ReactWrapper/at.md
================================================
# `.at(index) => ReactWrapper`
Returns a wrapper around the node at a given index of the current wrapper.
#### Arguments
1. `index` (`Number`): A zero-based integer indicating which node to retrieve.
#### Returns
`ReactWrapper`: A new wrapper that wraps the retrieved node.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find(Foo).at(0).props().foo).to.equal('bar');
```
#### Related Methods
- [`.get(index) => ReactElement`](get.md) - same, but returns the React node itself, with no wrapper.
- [`.first() => ReactWrapper`](first.md) - same as at(0)
- [`.last() => ReactWrapper`](last.md)
================================================
FILE: docs/api/ReactWrapper/childAt.md
================================================
# `.childAt(index) => ReactWrapper`
Returns a new wrapper with child at the specified index.
#### Arguments
1. `index` (`number`): A zero-based integer indicating which node to retrieve.
#### Returns
`ReactWrapper`: A new wrapper that wraps the resulting node.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find('ul').childAt(0).type()).to.equal('li');
```
#### Related Methods
- [`.parents([selector]) => ReactWrapper`](parents.md)
- [`.parent() => ReactWrapper`](parent.md)
- [`.closest(selector) => ReactWrapper`](closest.md)
- [`.children([selector]) => ReactWrapper`](children.md)
================================================
FILE: docs/api/ReactWrapper/children.md
================================================
# `.children([selector]) => ReactWrapper`
Returns a new wrapper with all of the children of the node(s) in the current wrapper. Optionally, a
selector can be provided and it will filter the children by this selector
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md) [optional]): A selector to filter the children by.
#### Returns
`ReactWrapper`: A new wrapper that wraps the resulting nodes.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find('ul').children()).to.have.lengthOf(items.length);
```
#### Related Methods
- [`.parents([selector]) => ReactWrapper`](parents.md)
- [`.parent() => ReactWrapper`](parent.md)
- [`.closest(selector) => ReactWrapper`](closest.md)
================================================
FILE: docs/api/ReactWrapper/closest.md
================================================
# `.closest(selector) => ReactWrapper`
Returns a wrapper of the first element that matches the selector by traversing up through the
wrapped node's ancestors in the tree, starting with itself. It must be a single-node wrapper.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`ReactWrapper`: A new wrapper that wraps the resulting node.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find(Foo).closest('.bar')).to.have.lengthOf(1);
```
#### Related Methods
- [`.children([selector]) => ReactWrapper`](children.md)
- [`.parent() => ReactWrapper`](parent.md)
- [`.parents([selector]) => ReactWrapper`](parents.md)
================================================
FILE: docs/api/ReactWrapper/contains.md
================================================
# `.contains(nodeOrNodes) => Boolean`
Returns whether or not all given react elements match elements in the render tree.
It will determine if an element in the wrapper matches the expected element by checking if the expected element has the same props as the wrapper's element and share the same values.
#### Arguments
1. `nodeOrNodes` (`ReactElement|Array`): The node or array of nodes whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has nodes anywhere in its render tree that match
the ones passed in.
#### Example
```jsx
const wrapper = mount((
,
])).to.equal(false);
```
#### Common Gotchas
- `.contains()` expects a ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with a ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
- Every attribute of the wrapped element must be matched by the element you're checking. To permit (and ignore) additional attributes on the wrapped element, use containsMatchingElement() instead.
================================================
FILE: docs/api/ReactWrapper/containsAllMatchingElements.md
================================================
# `.containsAllMatchingElements(patternNodes) => Boolean`
Returns whether or not all of the given react elements in `patternNodes` match an element in the wrapper's render tree. Every single element of `patternNodes` must be matched one or more times. Matching follows the rules for `containsMatchingElement`.
#### Arguments
1. `patternNodes` (`Array`): The array of nodes whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has nodes anywhere in its render tree that looks
like the nodes passed in.
#### Example
```jsx
const style = { fontSize: 13 };
const wrapper = mount((
,
])).to.equal(true);
```
#### Common Gotchas
- `.containsAllMatchingElements()` expects an array of ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with an array of ReactElement or a JSX expression.
- Keep in mind that this method determines matching based on the matching of the node's children as
well.
#### Related Methods
- [`.matchesElement() => ReactWrapper`](matchesElement.md) - rules for matching each node
- [`.containsMatchingElement() => ReactWrapper`](containsMatchingElement.md) - rules for matching whole wrapper
- [`.containsAnyMatchingElements() => ReactWrapper`](containsAnyMatchingElements.md) - must match at least one in patternNodes
================================================
FILE: docs/api/ReactWrapper/containsAnyMatchingElements.md
================================================
# `.containsAnyMatchingElements(patternNodes) => Boolean`
Returns whether or not at least one of the given react elements in `patternNodes` matches an element in the wrapper's render tree. One or more elements of `patternNodes` must be matched one or more times. Matching follows the rules for `containsMatchingElement`.
#### Arguments
1. `patternNodes` (`Array`): The array of nodes whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has a node anywhere in its render tree that looks
like one of the array passed in.
#### Example
```jsx
const style = { fontSize: 13 };
const wrapper = mount((
,
])).to.equal(true);
```
#### Common Gotchas
- `.containsAnyMatchingElements()` expects an array of ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with an array ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
#### Related Methods
- [`.matchesElement() => ReactWrapper`](matchesElement.md) - rules for matching each node
- [`.containsMatchingElement() => ReactWrapper`](containsMatchingElement.md) - rules for matching whole wrapper
- [`.containsAllMatchingElements() => ReactWrapper`](containsAllMatchingElements.md) - must match all nodes in patternNodes
================================================
FILE: docs/api/ReactWrapper/containsMatchingElement.md
================================================
# `.containsMatchingElement(patternNode) => Boolean`
Returns whether or not a `patternNode` react element matches any element in the render tree.
* the matches can happen anywhere in the wrapper's contents
* the wrapper can contain more than one node; all are searched
Otherwise, the match follows the same rules as `matchesElement`.
#### Arguments
1. `patternNode` (`ReactElement`): The node whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has a node anywhere in its render tree that matches
the one passed in.
#### Example
```jsx
const wrapper = mount((
)).to.equal(false);
expect(wrapper.containsMatchingElement()).to.equal(false);
```
#### Common Gotchas
- `.containsMatchingElement()` expects a ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with a ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
#### Related Methods
- [`.containsAllMatchingElements() => ReactWrapper`](containsAllMatchingElements.md) - must match all nodes in patternNodes
- [`.containsAnyMatchingElements() => ReactWrapper`](containsAnyMatchingElements.md) - must match at least one in patternNodes
================================================
FILE: docs/api/ReactWrapper/context.md
================================================
# `.context([key]) => Any`
Returns the context hash for the root node of the wrapper. Optionally pass in a prop name and it
will return just that value.
#### Arguments
1. `key` (`String` [optional]): If provided, the return value will be the `this.context[key]` of the
root component instance.
#### Example
```jsx
const wrapper = mount(
,
{ context: { foo: 10 } },
);
expect(wrapper.context().foo).to.equal(10);
expect(wrapper.context('foo')).to.equal(10);
```
#### Related Methods
- [`.state([key]) => Any`](state.md)
- [`.props() => Object`](props.md)
- [`.prop(key) => Any`](prop.md)
================================================
FILE: docs/api/ReactWrapper/debug.md
================================================
# `.debug([options]) => String`
Returns an HTML-like string of the wrapper for debugging purposes. Useful to print out to the
console when tests are not passing when you expect them to.
#### Arguments
`options` (`Object` [optional]):
- `options.ignoreProps`: (`Boolean` [optional]): Whether props should be omitted in the resulting string. Props are included by default.
- `options.verbose`: (`Boolean` [optional]): Whether arrays and objects passed as props should be verbosely printed.
#### Returns
`String`: The resulting string.
#### Examples
Say we have the following components:
```jsx
function Foo() {
return (
Foo
);
}
function Bar() {
return (
Non-Foo
);
}
```
In this case, running:
```jsx
console.log(mount().debug());
```
Would output the following to the console:
```text
Non-Foo
Foo
```
Likewise, running:
```jsx
console.log(mount().find(Foo).debug());
```
Would output the following to the console:
```text
Foo
```
and:
```jsx
console.log(mount().find(Foo).debug({ ignoreProps: true }));
```
Would output the following to the console:
```text
Foo
```
and:
```jsx
console.log(mount().find(Foo).debug({ verbose: true }));
```
Would output the following to the console:
```text
Foo
```
================================================
FILE: docs/api/ReactWrapper/detach.md
================================================
# `.detach() => void`
Detaches the react tree from the DOM. Runs `ReactDOM.unmountComponentAtNode()` under the hood.
This method will most commonly be used as a "cleanup" method if you decide to use the
`attachTo` or `hydrateIn` option in `mount(node, options)`.
The method is intentionally not "fluent" (in that it doesn't return `this`) because you should
not be doing anything with this wrapper after this method is called.
Using `attachTo`/`hydrateIn` is not generally recommended unless it is absolutely necessary to test
something. It is your responsibility to clean up after yourself at the end of the test if you do
decide to use it, though.
#### Examples
With the `attachTo` option, you can mount components to attached DOM elements:
```jsx
// render a component directly into document.body
const wrapper = mount(, { attachTo: document.body });
// Or, with the `hydrateIn` option, you can mount components on top of existing DOM elements:
// hydrate a component directly onto document.body
const hydratedWrapper = mount(, { hydrateIn: document.body });
// we can see that the component is rendered into the document
expect(wrapper.find('.in-bar')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(1);
// detach it to clean up after yourself
wrapper.detach();
// now we can see that
expect(document.body.childNodes).to.have.lengthOf(0);
```
Similarly, if you want to create some one-off elements for your test to mount into:
```jsx
// create a div in the document to mount into
const div = global.document.createElement('div');
global.document.body.appendChild(div);
// div is empty. body has the div attached.
expect(document.body.childNodes).to.have.lengthOf(1);
expect(div.childNodes).to.have.lengthOf(0);
// mount a component passing div into the `attachTo` option
const wrapper = mount(, { attachTo: div });
// or, mount a component passing div into the `hydrateIn` option
const hydratedWrapper = mount(, { hydrateIn: div });
// we can see now the component is rendered into the document
expect(wrapper.find('.in-foo')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(1);
expect(div.childNodes).to.have.lengthOf(1);
// call detach to clean up
wrapper.detach();
// div is now empty, but still attached to the document
expect(document.body.childNodes).to.have.lengthOf(1);
expect(div.childNodes).to.have.lengthOf(0);
// remove div if you want
global.document.body.removeChild(div);
expect(document.body.childNodes).to.have.lengthOf(0);
expect(div.childNodes).to.have.lengthOf(0);
```
================================================
FILE: docs/api/ReactWrapper/equals.md
================================================
# `.equals(node) => Boolean`
Returns whether or not the current wrapper root node render tree looks like the one passed in.
#### Arguments
1. `node` (`ReactElement`): The node whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has a node anywhere in it's render tree that looks
like the one passed in.
#### Example
```jsx
function MyComponent() {
return ;
}
const wrapper = mount().childAt(0);
expect(wrapper.equals()).to.equal(true);
```
#### Common Gotchas
- `.equals()` expects a ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with a ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
- Following React's behavior, `.equals()` ignores properties whose values are `undefined`.
================================================
FILE: docs/api/ReactWrapper/every.md
================================================
# `.every(selector) => Boolean`
Returns whether or not all of the nodes in the wrapper match the provided selector.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`Boolean`: True if every node in the current wrapper matched the provided selector.
#### Examples
```jsx
const wrapper = mount((
));
expect(wrapper.find('.foo').every('.foo')).to.equal(true);
expect(wrapper.find('.foo').every('.qoo')).to.equal(false);
expect(wrapper.find('.foo').every('.bar')).to.equal(false);
```
#### Related Methods
- [`.someWhere(predicate) => Boolean`](someWhere.md)
- [`.everyWhere(predicate) => Boolean`](everyWhere.md)
================================================
FILE: docs/api/ReactWrapper/everyWhere.md
================================================
# `.everyWhere(fn) => Boolean`
Returns whether or not all of the nodes in the wrapper pass the provided predicate function.
#### Arguments
1. `predicate` (`ReactWrapper => Boolean`): A predicate function to match the nodes.
#### Returns
`Boolean`: True if every node in the current wrapper passed the predicate function.
#### Example
```jsx
const wrapper = mount((
));
expect(wrapper.find('.foo').everyWhere((n) => n.hasClass('foo'))).to.equal(true);
expect(wrapper.find('.foo').everyWhere((n) => n.hasClass('qoo'))).to.equal(false);
expect(wrapper.find('.foo').everyWhere((n) => n.hasClass('bar'))).to.equal(false);
```
#### Related Methods
- [`.some(selector) => Boolean`](some.md)
- [`.every(selector) => Boolean`](every.md)
================================================
FILE: docs/api/ReactWrapper/exists.md
================================================
# `.exists([selector]) => Boolean`
Returns whether or not any nodes exist in the wrapper. Or, if a selector is passed in, whether that selector has any matches in the wrapper.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md) [optional]): The selector to check existence for.
#### Returns
`Boolean`: whether or not any nodes are on the list, or the selector had any matches.
#### Example
```jsx
const wrapper = mount();
expect(wrapper.exists('.some-class')).to.equal(true);
expect(wrapper.find('.other-class').exists()).to.equal(false);
```
================================================
FILE: docs/api/ReactWrapper/filter.md
================================================
# `.filter(selector) => ReactWrapper`
Returns a new wrapper with only the nodes of the current wrapper that match the provided selector.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`ReactWrapper`: A new wrapper that wraps the filtered nodes.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find('.foo').filter('.bar')).to.have.lengthOf(1);
```
#### Related Methods
- [`.filterWhere(predicate) => ReactWrapper`](filterWhere.md)
================================================
FILE: docs/api/ReactWrapper/filterWhere.md
================================================
# `.filterWhere(fn) => ReactWrapper`
Returns a new wrapper with only the nodes of the current wrapper that, when passed into the
provided predicate function, return true.
#### Arguments
1. `predicate` (`ReactWrapper => Boolean`): A predicate function that is passed a wrapped node.
#### Returns
`ReactWrapper`: A new wrapper that wraps the filtered nodes.
#### Example
```jsx
const wrapper = mount();
const complexComponents = wrapper.find('.foo').filterWhere((n) => typeof n.type() !== 'string');
expect(complexComponents).to.have.lengthOf(4);
```
#### Related Methods
- [`.filter(selector) => ReactWrapper`](filter.md)
================================================
FILE: docs/api/ReactWrapper/find.md
================================================
# `.find(selector) => ReactWrapper`
Finds every node in the render tree of the current wrapper that matches the provided selector.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`ReactWrapper`: A new wrapper that wraps the found nodes.
#### Examples
CSS Selectors:
```jsx
const wrapper = mount();
expect(wrapper.find('.foo')).to.have.lengthOf(1);
expect(wrapper.find('.bar')).to.have.lengthOf(3);
// compound selector
expect(wrapper.find('div.some-class')).to.have.lengthOf(3);
// CSS id selector
expect(wrapper.find('#foo')).to.have.lengthOf(1);
// property selector
expect(wrapper.find('[htmlFor="checkbox"]')).to.have.lengthOf(1);
```
Component Constructors:
```jsx
import Foo from '../components/Foo';
const wrapper = mount();
expect(wrapper.find(Foo)).to.have.lengthOf(1);
```
Component Display Name:
```jsx
const wrapper = mount();
expect(wrapper.find('Foo')).to.have.lengthOf(1);
```
Object Property Selector:
```jsx
const wrapper = mount();
expect(wrapper.find({ prop: 'value' })).to.have.lengthOf(1);
```
#### Related Methods
- [`.findWhere(predicate) => ReactWrapper`](findWhere.md)
================================================
FILE: docs/api/ReactWrapper/findWhere.md
================================================
# `.findWhere(fn) => ReactWrapper`
Finds every node in the render tree that returns true for the provided predicate function.
#### Arguments
1. `predicate` (`ReactWrapper => Boolean`): A predicate function called with the passed in wrapped
nodes.
#### Returns
`ReactWrapper`: A new wrapper that wraps the found nodes.
#### Example
```jsx
const wrapper = mount();
const complexComponents = wrapper.findWhere((n) => typeof n.type() !== 'string');
expect(complexComponents).to.have.lengthOf(8);
```
#### Related Methods
- [`.find(selector) => ReactWrapper`](find.md)
================================================
FILE: docs/api/ReactWrapper/first.md
================================================
# `.first() => ReactWrapper`
Reduce the set of matched nodes to the first in the set, just like `.at(0)`.
#### Returns
`ReactWrapper`: A new wrapper that wraps the first node in the set.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find(Foo).first().props().foo).to.equal('bar');
```
#### Related Methods
- [`.at(index) => ReactWrapper`](at.md) - retrieve a wrapper node at given index
- [`.last() => ReactWrapper`](last.md)
================================================
FILE: docs/api/ReactWrapper/forEach.md
================================================
# `.forEach(fn) => Self`
Iterates through each node of the current wrapper and executes the provided function with a
wrapper around the corresponding node passed in as the first argument.
#### Arguments
1. `fn` (`Function ( ReactWrapper node, Number index )`): A callback to be run for every node in the collection.
Should expect a ReactWrapper as the first argument, and will be run with a context of the original
instance.
#### Returns
`ReactWrapper`: Returns itself.
#### Example
```jsx
const wrapper = mount((
));
wrapper.find('.foo').forEach((node) => {
expect(node.hasClass('foo')).to.equal(true);
});
```
#### Related Methods
- [`.map(fn) => ReactWrapper`](map.md)
================================================
FILE: docs/api/ReactWrapper/get.md
================================================
# `.get(index) => ReactElement`
Returns the node at a given index of the current wrapper.
#### Arguments
1. `index` (`Number`): A zero-based integer indicating which node to retrieve.
#### Returns
`ReactElement`: The retrieved node.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find(Foo).get(0).props.foo).to.equal('bar');
```
#### Related Methods
- [`.at(index) => ReactWrapper`](at.md) - same, but returns the React node in a single-node wrapper.
================================================
FILE: docs/api/ReactWrapper/getDOMNode.md
================================================
# `.getDOMNode() => DOMComponent`
Returns the outer most DOMComponent of the current wrapper.
Notes:
- can only be called on a wrapper of a single node.
- will raise if called on a wrapper of a stateless functional component.
#### Returns
`DOMComponent`: The retrieved DOM component.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.getDOMNode()).to.have.property('className');
```
================================================
FILE: docs/api/ReactWrapper/getElement.md
================================================
# `.getElement() => ReactElement`
Returns the wrapped ReactElement.
If the current wrapper is wrapping the root component, returns the root component's latest render output.
#### Returns
`ReactElement`: The retrieved ReactElement.
#### Examples
```jsx
const element = (
);
function MyComponent() {
return element;
}
const wrapper = mount();
expect(wrapper.getElement()).to.equal(element);
```
#### Related Methods
- [`.getElements() => Array`](getElements.md)
================================================
FILE: docs/api/ReactWrapper/getElements.md
================================================
# `.getElements() => Array`
Returns the wrapped ReactElements
If the current wrapper is wrapping the root component, returns the root component's latest render output wrapped in an array.
#### Returns
`Array`: The retrieved ReactElements.
#### Examples
```jsx
const one = ;
const two = ;
function Test() {
return (
{one}
{two}
);
}
const wrapper = mount();
expect(wrapper.find('span').getElements()).to.deep.equal([one, two]);
```
#### Related Methods
- [`.getElement() => ReactElement`](getElement.md)
================================================
FILE: docs/api/ReactWrapper/getWrappingComponent.md
================================================
# `.getWrappingComponent() => ReactWrapper`
If a `wrappingComponent` was passed in `options`, this methods returns a `ReactWrapper` around the rendered `wrappingComponent`. This `ReactWrapper` can be used to update the `wrappingComponent`'s props, state, etc.
#### Returns
`ReactWrapper`: A `ReactWrapper` around the rendered `wrappingComponent`
#### Examples
```jsx
import { Provider } from 'react-redux';
import { Router } from 'react-router';
import store from './my/app/store';
import mockStore from './my/app/mockStore';
function MyProvider(props) {
const { children, customStore } = props;
return (
{children}
);
}
MyProvider.propTypes = {
children: PropTypes.node,
customStore: PropTypes.shape({}),
};
MyProvider.defaultProps = {
children: null,
customStore: null,
};
const wrapper = mount(, {
wrappingComponent: MyProvider,
});
const provider = wrapper.getWrappingComponent();
provider.setProps({ customStore: mockStore });
```
================================================
FILE: docs/api/ReactWrapper/hasClass.md
================================================
# `.hasClass(className) => Boolean`
Returns whether or not the wrapped node has a `className` prop including the passed in class name. It must be a single-node wrapper.
#### Arguments
1. `className` (`String` | `RegExp`): A single class name or a regex expression.
#### Returns
`Boolean`: whether or not the wrapped node has found the class name.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find('.my-button').hasClass('disabled')).to.equal(true);
```
```jsx
// Searching using RegExp works fine when classes were injected by a jss decorator
const wrapper = mount();
expect(wrapper.find('.my-button').hasClass(/(ComponentName)-(other)-(\d+)/)).to.equal(true);
```
### Common Gotchas
- `.hasClass()` expects a class name, NOT a CSS selector. `.hasClass('.foo')` should be
`.hasClass('foo')`
================================================
FILE: docs/api/ReactWrapper/hostNodes.md
================================================
# `.hostNodes() => ReactWrapper`
Returns a new wrapper with only host nodes.
When using `react-dom`, host nodes are HTML elements rather than custom React components, e.g. `
` versus ``.
#### Returns
`ReactWrapper`: A new wrapper that wraps the filtered nodes.
#### Examples
The following code takes a wrapper with two nodes, one a `` React component, and the other a ``, and filters out the React component.
```jsx
const wrapper = mount((
));
const twoNodes = wrapper.find('.foo');
expect(twoNodes.hostNodes()).to.have.lengthOf(1);
```
================================================
FILE: docs/api/ReactWrapper/html.md
================================================
# `.html() => String`
Returns a string of the rendered HTML markup of the current render tree. See also [`.debug()`](debug.md)
Note: can only be called on a wrapper of a single node.
#### Returns
`String`: The resulting HTML string
#### Examples
```jsx
function Foo() {
return ();
}
```
```jsx
function Bar() {
return (
');
```
#### Related Methods
[`.text() => String`](text.md)
================================================
FILE: docs/api/ReactWrapper/instance.md
================================================
# `.instance() => ReactComponent`
Returns the single-node wrapper's node's underlying class instance; `this` in its methods. It must be a single-node wrapper.
NOTE: can only be called on a wrapper instance that is also the root instance. With React `16` and above, `instance()` returns `null` for functional components, regardless of [hooks](https://reactjs.org/docs/hooks-intro.html) usage.
#### Returns
`ReactComponent|DOMComponent`: The retrieved instance.
#### Example
```jsx
function SFC() {
return
MyFunction
;
}
class Stateful extends React.Component {
render() {
return
MyClass
;
}
}
```
#### React 16.x
```jsx
test('wrapper instance is null', () => {
const wrapper = mount();
const instance = wrapper.instance();
expect(instance).to.equal(null);
});
test('wrapper instance is not null', () => {
const wrapper = mount();
const instance = wrapper.instance();
expect(instance).to.be.instanceOf(MyCStatefullass);
});
```
#### React 15.x
```jsx
test('wrapper instance is not null', () => {
const wrapper = mount();
const instance = wrapper.instance();
expect(instance).to.be.instanceOf(SFC);
});
test('wrapper instance is not null', () => {
const wrapper = mount();
const instance = wrapper.instance();
expect(instance).to.be.instanceOf(Stateful);
});
```
================================================
FILE: docs/api/ReactWrapper/invoke.md
================================================
# `.invoke(propName)(...args) => Any`
Invokes a function prop.
Note that in React 16.8+, `.invoke` will wrap your handler with [`ReactTestUtils.act`](https://reactjs.org/docs/test-utils.html#act) and call `.update()` automatically.
#### Arguments
1. `propName` (`String`): The function prop that is invoked
2. `...args` (`Any` [optional]): Arguments that is passed to the prop function
#### Returns
`Any`: Returns the value from the prop function
#### Example
```jsx
class Foo extends React.Component {
loadData() {
return fetch();
}
render() {
return (
);
}
}
const wrapper = mount();
wrapper.find('button').invoke('onClick')().then(() => {
// expect()
});
```
================================================
FILE: docs/api/ReactWrapper/is.md
================================================
# `.is(selector) => Boolean`
Returns whether or not the single wrapped node matches the provided selector. It must be a single-node wrapper.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`Boolean`: whether or not the wrapped node matches the provided selector.
#### Example
```jsx
const wrapper = mount();
expect(wrapper.is('.some-class')).to.equal(true);
```
================================================
FILE: docs/api/ReactWrapper/isEmpty.md
================================================
# `.isEmpty() => Boolean`
**Deprecated**: Use [`.exists()`](exists.md) instead.
Returns whether or not the wrapper is empty.
#### Returns
`Boolean`: whether or not the wrapper is empty.
#### Example
```jsx
const wrapper = mount();
expect(wrapper.find('.other-class').isEmpty()).to.equal(true);
```
================================================
FILE: docs/api/ReactWrapper/isEmptyRender.md
================================================
# `.isEmptyRender() => Boolean`
Returns whether or not the wrapper would ultimately render only the allowed falsy values: `false` or `null`.
#### Returns
`Boolean`: whether the return is falsy
#### Example
```jsx
function Foo() {
return null;
}
const wrapper = mount();
expect(wrapper.isEmptyRender()).to.equal(true);
```
================================================
FILE: docs/api/ReactWrapper/key.md
================================================
# `.key() => String`
Returns the key value for the node of the current wrapper. It must be a single-node wrapper.
#### Example
```jsx
const wrapper = mount((
{['foo', 'bar'].map((s) =>
{s}
)}
)).find('li');
expect(wrapper.at(0).key()).to.equal('foo');
expect(wrapper.at(1).key()).to.equal('bar');
```
================================================
FILE: docs/api/ReactWrapper/last.md
================================================
# `.last() => ReactWrapper`
Reduce the set of matched nodes to the last in the set, just like `.at(length - 1)`.
#### Returns
`ReactWrapper`: A new wrapper that wraps the last node in the set.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find(Foo).last().props().foo).to.equal('bar');
```
#### Related Methods
- [`.at(index) => ReactWrapper`](at.md) - retrieve a wrapper node by index
- [`.first() => ReactWrapper`](first.md)
================================================
FILE: docs/api/ReactWrapper/length.md
================================================
# `.length => number`
Returns the number of React nodes enclosed in this wrapper.
#### Returns
`Number`: count of nodes in the list in this wrapper.
#### Example
```jsx
const wrapper = mount();
expect(wrapper.length).to.equal(1);
```
================================================
FILE: docs/api/ReactWrapper/map.md
================================================
# `.map(fn) => Array`
Maps the current array of nodes to another array. Each node is passed in as a `ReactWrapper`
to the map function.
#### Arguments
1. `fn` (`Function ( ReactWrapper node, Number index ) => Any`): A mapping function to be run for every node in
the collection, the results of which will be mapped to the returned array. Should expect a ReactWrapper as the first argument, and will be run with a context of
the original instance.
#### Returns
`Array`: Returns an array of the returned values from the mapping function..
#### Example
```jsx
const wrapper = mount((
bax
bar
baz
));
const texts = wrapper.find('.foo').map((node) => node.text());
expect(texts).to.eql(['bax', 'bar', 'baz']);
```
#### Related Methods
- [`.forEach(fn) => ReactWrapper`](forEach.md)
- [`.reduce(fn[, initialValue]) => Any`](reduce.md)
- [`.reduceRight(fn[, initialValue]) => Any`](reduceRight.md)
================================================
FILE: docs/api/ReactWrapper/matchesElement.md
================================================
# `.matchesElement(patternNode) => Boolean`
Returns whether or not a given react element `patternNode` matches the wrapper's render tree. It must be a single-node wrapper, and only the root node is checked.
The `patternNode` acts like a wildcard. For it to match a node in the wrapper:
* tag names must match
* contents must match: In text nodes, leading and trailing spaces are ignored, but not space in the middle. Child elements must match according to these rules, recursively.
* `patternNode` props (attributes) must appear in the wrapper's nodes, but not the other way around. Their values must match if they do appear.
* `patternNode` style CSS properties must appear in the wrapper's node's style, but not the other way around. Their values must match if they do appear.
#### Arguments
1. `patternNode` (`ReactElement`): The node whose presence you are detecting in the wrapper's single node.
#### Returns
`Boolean`: whether or not the current wrapper match the one passed in.
#### Example
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// ...
}
render() {
return (
);
}
}
const wrapper = mount().childAt(0);
expect(wrapper.matchesElement()).to.equal(true);
expect(wrapper.matchesElement()).to.equal(true);
```
#### Common Gotchas
- `.matchesElement()` expects a ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with a ReactElement or a JSX expression.
- Keep in mind that this method determines matching based on the matching of the node's children as
well.
#### Related Methods
- [`.containsMatchingElement() => ReactWrapper`](containsMatchingElement.md) - searches all nodes in the wrapper, and searches their entire depth
================================================
FILE: docs/api/ReactWrapper/mount.md
================================================
# `.mount() => Self`
A method that re-mounts the component, if it is not currently mounted. This can be used to simulate a component going through
an unmount/mount lifecycle.
No equivalent for ShallowWrappers.
#### Returns
`ReactWrapper`: Returns itself.
#### Example
```jsx
import PropTypes from 'prop-types';
import sinon from 'sinon';
const willMount = sinon.spy();
const didMount = sinon.spy();
const willUnmount = sinon.spy();
class Foo extends React.Component {
constructor(props) {
super(props);
this.componentWillUnmount = willUnmount;
this.componentWillMount = willMount;
this.componentDidMount = didMount;
}
render() {
const { id } = this.props;
return (
{id}
);
}
}
Foo.propTypes = {
id: PropTypes.string.isRequired,
};
const wrapper = mount();
expect(willMount).to.have.property('callCount', 1);
expect(didMount).to.have.property('callCount', 1);
expect(willUnmount).to.have.property('callCount', 0);
wrapper.unmount();
expect(willMount).to.have.property('callCount', 1);
expect(didMount).to.have.property('callCount', 1);
expect(willUnmount).to.have.property('callCount', 1);
wrapper.mount();
expect(willMount).to.have.property('callCount', 2);
expect(didMount).to.have.property('callCount', 2);
expect(willUnmount).to.have.property('callCount', 1);
```
#### Related Methods
- [`.unmount() => Self`](unmount.md)
================================================
FILE: docs/api/ReactWrapper/name.md
================================================
# `.name() => String|null`
Returns the name of the current node of this wrapper. If it's a composite component, this will be
the name of the component. If it's a native DOM node, it will be a string of the tag name. If it's
`null`, it will be `null`.
The order of precedence on returning the name is: `type.displayName` -> `type.name` -> `type`.
Note: can only be called on a wrapper of a single node.
#### Returns
`String|null`: The name of the current node
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.name()).to.equal('div');
```
```jsx
const wrapper = mount();
expect(wrapper.name()).to.equal('Foo');
```
```jsx
Foo.displayName = 'A cool custom name';
const wrapper = mount();
expect(wrapper.name()).to.equal('A cool custom name');
```
================================================
FILE: docs/api/ReactWrapper/not.md
================================================
# `.not(selector) => ReactWrapper`
Returns a new wrapper with only the nodes of the current wrapper that don't match the provided
selector.
This method is effectively the negation or inverse of [`filter`](filter.md).
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`ReactWrapper`: A new wrapper that wraps the filtered nodes.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find('.foo').not('.bar')).to.have.lengthOf(1);
```
#### Related Methods
- [`.filterWhere(predicate) => ReactWrapper`](filterWhere.md)
- [`.filter(selector) => ReactWrapper`](filter.md)
================================================
FILE: docs/api/ReactWrapper/parent.md
================================================
# `.parent() => ReactWrapper`
Returns a wrapper with the direct parent of the node in the current wrapper.
#### Returns
`ReactWrapper`: A new wrapper that wraps the resulting nodes.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find('ul').parent().is('div')).to.equal(true);
```
#### Related Methods
- [`.parents([selector]) => ReactWrapper`](parents.md)
- [`.children([selector]) => ReactWrapper`](children.md)
- [`.closest(selector) => ReactWrapper`](closest.md)
================================================
FILE: docs/api/ReactWrapper/parents.md
================================================
# `.parents([selector]) => ReactWrapper`
Returns a wrapper around all of the parents/ancestors of the single node in the wrapper. Does not include the node itself.
Optionally, a selector can be provided and it will filter the parents by this selector. It must be a single-node wrapper.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md) [optional]): The selector to filter the parents by.
#### Returns
`ReactWrapper`: A new wrapper that wraps the resulting nodes.
#### Examples
```jsx
const wrapper = mount();
expect(wrapper.find('ul').parents()).to.have.lengthOf(2);
```
#### Related Methods
- [`.children([selector]) => ReactWrapper`](children.md)
- [`.parent() => ReactWrapper`](parent.md)
- [`.closest(selector) => ReactWrapper`](closest.md)
================================================
FILE: docs/api/ReactWrapper/prop.md
================================================
# `.prop(key) => Any`
Returns the prop value for the root node of the wrapper with the provided key. It must be a single-node wrapper.
#### Arguments
1. `key` (`String`): The prop name, that is, `this.props[key]` or `props[key]` for the root node of the wrapper.
#### Example
```jsx
const wrapper = mount();
expect(wrapper.prop('foo')).to.equal(10);
```
#### Related Methods
- [`.props() => Object`](props.md)
- [`.state([key]) => Any`](state.md)
- [`.context([key]) => Any`](context.md)
================================================
FILE: docs/api/ReactWrapper/props.md
================================================
# `.props() => Object`
Returns the props object for the root node of the wrapper. It must be a single-node wrapper.
This method is a reliable way of accessing the props of a node; `wrapper.instance().props` will work as well, but in React 16+, stateless functional components do not have an instance. See [`.instance() => ReactComponent`](instance.md)
#### Example
```jsx
import PropTypes from 'prop-types';
function MyComponent(props) {
const { includedProp } = props;
return (
Hello
);
}
MyComponent.propTypes = {
includedProp: PropTypes.string.isRequired,
};
const wrapper = mount();
expect(wrapper.props().includedProp).to.equal('Success!');
// Warning: .props() only returns props that are passed to the root node,
// which does not include excludedProp in this example.
// See the note above about wrapper.instance().props.
console.log(wrapper.props());
// {children: "Hello", className: "foo bar", includedProp="Success!"}
console.log(wrapper.instance().props); // React 15.x - working as expected
// {children: "Hello", className: "foo bar", includedProp:"Success!", excludedProp: "I'm not included"}
console.log(wrapper.instance().props);
// React 16.* - Uncaught TypeError: Cannot read property 'props' of null
```
#### Related Methods
- [`.prop(key) => Any`](prop.md)
- [`.state([key]) => Any`](state.md)
- [`.context([key]) => Any`](context.md)
================================================
FILE: docs/api/ReactWrapper/reduce.md
================================================
# `.reduce(fn[, initialValue]) => Any`
Applies the provided reducing function to every node in the wrapper to reduce to a single value.
Each node is passed in as a `ReactWrapper`, and is processed from left to right.
#### Arguments
1. `fn` (`Function`): A reducing function to be run for every node in the collection, with the
following arguments:
- `value` (`T`): The value returned by the previous invocation of this function
- `node` (`ReactWrapper`): A wrapper around the node being processed
- `index` (`Number`): The index of the node being processed
2. `initialValue` (`T` [optional]): If provided, this will be passed in as the first argument to the first invocation of the reducing function. If omitted, the first `node` will be provided and the iteration will begin on the second node in the collection.
#### Returns
`T`: Returns an array of the returned values from the mapping function...
#### Example
```jsx
function Foo() {
return (
);
}
```
```jsx
const wrapper = mount();
const total = wrapper.find(Bar).reduce((amount, n) => amount + n.prop('amount'), 0);
expect(total).to.equal(14);
```
#### Related Methods
- [`.reduceRight(fn[, initialValue]) => Any`](reduceRight.md)
- [`.forEach(fn) => ReactWrapper`](forEach.md)
- [`.map(fn) => Array`](map.md)
================================================
FILE: docs/api/ReactWrapper/reduceRight.md
================================================
# `.reduceRight(fn[, initialValue]) => Any`
Applies the provided reducing function to every node in the wrapper to reduce to a single value.
Each node is passed in as a `ReactWrapper`, and is processed from right to left.
#### Arguments
1. `fn` (`Function`): A reducing function to be run for every node in the collection, with the
following arguments:
- `value` (`T`): The value returned by the previous invocation of this function
- `node` (`ReactWrapper`): A single-node wrapper around the node being processed
- `index` (`Number`): The index of the node being processed
2. `initialValue` (`T` [optional]): If provided, this will be passed in as the first argument to the first invocation of the reducing function. If omitted, the first `node` will be provided and the iteration will begin on the second node in the collection.
#### Returns
`T`: Returns an array of the returned values from the mapping function...
#### Example
```jsx
function Foo() {
return (
);
}
```
```jsx
const wrapper = mount();
const total = wrapper.find(Bar).reduceRight((amount, n) => amount + n.prop('amount'), 0);
expect(total).to.equal(14);
```
#### Related Methods
- [`.reduce(fn[, initialValue]) => Any`](reduce.md)
- [`.forEach(fn) => ReactWrapper`](forEach.md)
- [`.map(fn) => Array`](map.md)
================================================
FILE: docs/api/ReactWrapper/ref.md
================================================
# `.ref(refName) => ReactComponent | HTMLElement`
Returns the node that matches the provided reference name.
NOTE: can only be called on a wrapper instance that is also the root instance.
#### Arguments
1. `refName` (`String`): The ref attribute of the node
#### Returns
`ReactComponent | HTMLElement`: The node that matches the provided reference name. This can be a react component instance, or an HTML element instance.
#### Examples
```jsx
class Foo extends React.Component {
render() {
return (
FirstSecondThird
);
}
}
```
```jsx
const wrapper = mount();
expect(wrapper.ref('secondRef').innerText).to.equal('Second');
```
#### Related Methods
- [`.find(selector) => ReactWrapper`](find.md)
- [`.findWhere(predicate) => ReactWrapper`](findWhere.md)
================================================
FILE: docs/api/ReactWrapper/render.md
================================================
# `.render() => CheerioWrapper`
Returns a CheerioWrapper around the rendered HTML of the single node's subtree.
It must be a single-node wrapper.
#### Returns
`CheerioWrapper`: The resulting Cheerio object
#### Examples
```jsx
function Foo() {
return ();
}
```
```jsx
function Bar() {
return (
);
}
```
```jsx
const wrapper = mount();
expect(wrapper.find('.in-foo')).to.have.lengthOf(1);
expect(wrapper.render().find('.in-foo')).to.have.lengthOf(1);
```
================================================
FILE: docs/api/ReactWrapper/renderProp.md
================================================
# `.renderProp(propName)(...args) => ReactWrapper`
Returns a function that, when called with arguments `args`, will return a new wrapper based on the render prop in the original wrapper's prop `propName`.
NOTE: can only be called on wrapper of a single non-DOM component element node.
#### Arguments
1. `propName` (`String`):
1. `...args` (`Array`):
This essentially calls `wrapper.prop(propName)(...args)`.
#### Returns
`ReactWrapper`: A new wrapper that wraps the node returned from the render prop.
#### Examples
##### Test Setup
```jsx
class Mouse extends React.Component {
constructor() {
super();
this.state = { x: 0, y: 0 };
}
render() {
const { render } = this.props;
return (
)).to.equal(true);
```
================================================
FILE: docs/api/ReactWrapper/setContext.md
================================================
# `.setContext(context) => Self`
A method that sets the context of the root component, and re-renders. Useful for when you are
wanting to test how the component behaves over time with changing contexts.
NOTE: can only be called on a wrapper instance that is also the root instance.
#### Arguments
1. `context` (`Object`): An object containing new props to merge in with the current state
#### Returns
`ReactWrapper`: Returns itself.
#### Example
```jsx
import React from 'react';
import PropTypes from 'prop-types';
function SimpleComponent(props, context) {
const { name } = context;
return
{name}
;
}
SimpleComponent.contextTypes = {
name: PropTypes.string,
};
```
```jsx
const context = { name: 'foo' };
const wrapper = mount(, { context });
expect(wrapper.text()).to.equal('foo');
wrapper.setContext({ name: 'bar' });
expect(wrapper.text()).to.equal('bar');
wrapper.setContext({ name: 'baz' });
expect(wrapper.text()).to.equal('baz');
```
#### Common Gotchas
- `.setContext()` can only be used on a wrapper that was initially created with a call to `mount()`
that includes a `context` specified in the options argument.
- The root component you are rendering must have a `contextTypes` static property.
#### Related Methods
- [`.setState(state[, callback]) => Self`](setState.md)
- [`.setProps(props[, callback]) => Self`](setProps.md)
================================================
FILE: docs/api/ReactWrapper/setProps.md
================================================
# `.setProps(nextProps[, callback]) => Self`
A method that sets the props of the root component, and re-renders. Useful for when you are
wanting to test how the component behaves over time with changing props. Calling this, for
instance, will call the `componentWillReceiveProps` lifecycle method.
Similar to `setState`, this method accepts a props object and will merge it in with the already
existing props.
NOTE: can only be called on a wrapper instance that is also the root instance.
#### Arguments
1. `nextProps` (`Object`): An object containing new props to merge in with the current props
2. `callback` (`Function` [optional]): If provided, the callback function will be executed once setProps has completed
#### Returns
`ReactWrapper`: Returns itself.
#### Example
```jsx
import React from 'react';
import PropTypes from 'prop-types';
function Foo({ name }) {
return (
);
}
Foo.propTypes = {
name: PropTypes.string.isRequired,
};
```
```jsx
const wrapper = mount();
expect(wrapper.find('.foo')).to.have.lengthOf(1);
expect(wrapper.find('.bar')).to.have.lengthOf(0);
wrapper.setProps({ name: 'bar' });
expect(wrapper.find('.foo')).to.have.lengthOf(0);
expect(wrapper.find('.bar')).to.have.lengthOf(1);
```
```jsx
import sinon from 'sinon';
const spy = sinon.spy(MyComponent.prototype, 'componentWillReceiveProps');
const wrapper = mount();
expect(spy).to.have.property('callCount', 0);
wrapper.setProps({ foo: 'foo' });
expect(spy).to.have.property('callCount', 1);
```
#### Related Methods
- [`.setState(state) => Self`](setState.md)
- [`.setContext(context) => Self`](setContext.md)
================================================
FILE: docs/api/ReactWrapper/setState.md
================================================
# `.setState(nextState[, callback]) => Self`
A method to invoke `setState()` on the root component instance, similar to how you might in the
methods of the component, and re-renders. This method is useful for testing your component
in hard-to-achieve states, however should be used sparingly. If possible, you should utilize
your component's external API (which is often accessible via [`.instance()`](instance.md)) in order
to get it into whatever state you want to test, in order to be as accurate of a test as possible.
This is not always practical, however.
NOTE: Prior to v3.8.0 of enzyme, can only be called on a wrapper instance that is also the root instance.
#### Arguments
1. `nextState` (`Object`): An object containing new state to merge in with the current state
2. `callback` (`Function` [optional]): If provided, the callback function will be executed once setState has completed
#### Returns
`ReactWrapper`: Returns itself.
#### Example
```jsx
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = { name: 'foo' };
}
render() {
const { name } = this.state;
return (
);
}
}
```
```jsx
const wrapper = mount();
expect(wrapper.find('.foo')).to.have.lengthOf(1);
expect(wrapper.find('.bar')).to.have.lengthOf(0);
wrapper.setState({ name: 'bar' });
expect(wrapper.find('.foo')).to.have.lengthOf(0);
expect(wrapper.find('.bar')).to.have.lengthOf(1);
```
#### Related Methods
- [`.setProps(props[, callback]) => Self`](setProps.md)
- [`.setContext(context) => Self`](setContext.md)
================================================
FILE: docs/api/ReactWrapper/simulate.md
================================================
# `.simulate(event[, mock]) => Self`
Simulate events on the root node in the wrapper. It must be a single-node wrapper.
#### Arguments
1. `event` (`String`): The event name to be simulated
2. `mock` (`Object` [optional]): A mock event object that will be merged with the event object passed to the handlers.
#### Returns
`ReactWrapper`: Returns itself.
#### Example `class component`
```jsx
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
const { count } = this.state;
return (
);
}
Foo.propTypes = {
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
onChange: PropTypes.func.isRequired,
};
const testState = { width: 10, height: 20 };
const wrapper = mount((
{
testState[e.target.name] = e.target.value;
}}
/>
));
expect(wrapper.find('input').at(0).props().value).to.equal(10);
expect(wrapper.find('input').at(1).props().value).to.equal(20);
wrapper.find('input').at(0).simulate('change', { target: { name: 'width', value: 50 } });
wrapper.find('input').at(1).simulate('change', { target: { name: 'height', value: 70 } });
expect(testState.width).to.equal(50);
expect(testState.height).to.equal(70);
```
#### Common Gotchas
- As noted in the function signature above passing a mock event is optional. It is worth noting that `ReactWrapper` will pass a `SyntheticEvent` object to the event handler in your code. Keep in mind that if the code you are testing uses properties that are not included in the `SyntheticEvent`, for instance `event.target.value`, you will need to provide a mock event like so `.simulate("change", { target: { value: "foo" }})` for it to work.
================================================
FILE: docs/api/ReactWrapper/simulateError.md
================================================
# `.simulateError(error) => Self`
Simulate a component throwing an error as part of its rendering lifecycle.
This is particularly useful in combination with React 16 error boundaries (ie, the `componentDidCatch` and `static getDerivedStateFromError` lifecycle methods).
#### Arguments
1. `error` (`Any`): The error to throw.
#### Returns
`ReactWrapper`: Returns itself.
#### Example
```jsx
function Something() {
// this is just a placeholder
return null;
}
class ErrorBoundary extends React.Component {
static getDerivedStateFromError(error) {
return {
hasError: true,
};
}
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
const { spy } = this.props;
spy(error, info);
}
render() {
const { children } = this.props;
const { hasError } = this.state;
return (
{hasError ? 'Error' : children}
);
}
}
ErrorBoundary.propTypes = {
children: PropTypes.node.isRequired,
spy: PropTypes.func.isRequired,
};
const spy = sinon.spy();
const wrapper = mount();
const error = new Error('hi!');
wrapper.find(Something).simulateError(error);
expect(wrapper.state()).to.have.property('hasError', true);
expect(spy).to.have.property('callCount', 1);
expect(spy.args).to.deep.equal([
error,
{
componentStack: `
in Something (created by ErrorBoundary)
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent`,
},
]);
```
================================================
FILE: docs/api/ReactWrapper/slice.md
================================================
# `.slice([begin[, end]]) => ReactWrapper`
Returns a new wrapper with a subset of the nodes of the original wrapper, according to the rules of `Array#slice`.
#### Arguments
1. `begin` (`Number` [optional]): Index from which to slice (defaults to `0`). If negative, this is treated as `length+begin`.
1. `end` (`Number` [optional]): Index at which to end slicing (defaults to `length`). If negative, this is treated as `length+end`.
#### Returns
`ReactWrapper`: A new wrapper with the subset of nodes specified.
#### Examples
```jsx
const wrapper = mount((
));
expect(wrapper.find('.foo').slice(1, 2)).to.have.lengthOf(1);
expect(wrapper.find('.foo').slice(1, 2).at(0).hasClass('bar')).to.equal(true);
```
================================================
FILE: docs/api/ReactWrapper/some.md
================================================
# `.some(selector) => Boolean`
Returns whether or not any of the nodes in the wrapper match the provided selector.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`Boolean`: True if at least one of the nodes in the current wrapper matched the provided selector.
#### Examples
```jsx
const wrapper = mount((
));
expect(wrapper.find('.foo').some('.qoo')).to.equal(true);
expect(wrapper.find('.foo').some('.foo')).to.equal(true);
expect(wrapper.find('.foo').some('.bar')).to.equal(false);
```
#### Related Methods
- [`.someWhere(predicate) => Boolean`](someWhere.md)
- [`.every(selector) => Boolean`](every.md)
- [`.everyWhere(predicate) => Boolean`](everyWhere.md)
================================================
FILE: docs/api/ReactWrapper/someWhere.md
================================================
# `.someWhere(fn) => Boolean`
Returns whether or not any of the nodes in the wrapper pass the provided predicate function.
#### Arguments
1. `predicate` (`ReactWrapper => Boolean`): A predicate function to match the nodes.
#### Returns
`Boolean`: True if at least one of the nodes in the current wrapper passed the predicate function.
#### Example
```jsx
const wrapper = mount((
));
expect(wrapper.find('.foo').someWhere((n) => n.hasClass('qoo'))).to.equal(true);
expect(wrapper.find('.foo').someWhere((n) => n.hasClass('foo'))).to.equal(true);
expect(wrapper.find('.foo').someWhere((n) => n.hasClass('bar'))).to.equal(false);
```
#### Related Methods
- [`.some(selector) => Boolean`](some.md)
- [`.every(selector) => Boolean`](every.md)
- [`.everyWhere(predicate) => Boolean`](everyWhere.md)
================================================
FILE: docs/api/ReactWrapper/state.md
================================================
# `.state([key]) => Any`
Returns the state hash for the root node of the wrapper. Optionally pass in a prop name and it
will return just that value.
#### Arguments
1. `key` (`String` [optional]): If provided, the return value will be the `this.state[key]` of the
root component instance.
#### Example
```jsx
const wrapper = mount();
expect(wrapper.state().foo).to.equal(10);
expect(wrapper.state('foo')).to.equal(10);
```
#### Related Methods
- [`.props() => Object`](props.md)
- [`.prop(key) => Any`](prop.md)
- [`.context([key]) => Any`](context.md)
================================================
FILE: docs/api/ReactWrapper/tap.md
================================================
# `.tap(intercepter) => Self`
Invokes intercepter and returns itself. intercepter is called with itself.
This is helpful when debugging nodes in method chains.
#### Arguments
1. `intercepter` (`Self`): the current ReactWrapper instance.
#### Returns
`Self`: the current ReactWrapper instance.
#### Example
```jsx
const result = mount((
xxx
yyy
zzz
)).find('li')
.tap((n) => console.log(n.debug()))
.map((n) => n.text());
```
================================================
FILE: docs/api/ReactWrapper/text.md
================================================
# `.text() => String`
Returns a string of the rendered text of the current render tree. This function should be
looked at with skepticism if being used to test what the actual HTML output of the component
will be. If that is what you would like to test, use enzyme's `render` function instead.
Note: can only be called on a wrapper of a single node.
#### Returns
`String`: The resulting string
#### Examples
```jsx
const wrapper = mount(
important
);
expect(wrapper.text()).to.equal('important');
```
```jsx
function Foo() {
return
This is
;
}
const wrapper = mount(
really important
);
expect(wrapper.text()).to.equal('This is really important');
```
#### Related Methods
[`.html() => String`](html.md)
================================================
FILE: docs/api/ReactWrapper/type.md
================================================
# `.type() => String | Function | null`
Returns the type of the only node of this wrapper.
If it's a React component, this will be the component constructor.
If it's a native DOM node, it will be a string with the tag name.
If it's `null`, it will be `null`. It must be a single-node wrapper.
#### Returns
`String | Function | null`: The type of the node
#### Examples
```jsx
function Foo() {
return ;
}
const wrapper = mount().childAt(0);
expect(wrapper.type()).to.equal('div');
```
```jsx
function Foo() {
return (
);
}
const wrapper = mount();
expect(wrapper.find('.btn').type()).to.equal('button');
```
```jsx
function Foo() {
return ;
}
const wrapper = mount();
expect(wrapper.type()).to.equal(Foo);
expect(wrapper.childAt(0).type()).to.equal(Bar);
```
```jsx
function Null() {
return null;
}
const wrapper = mount();
expect(wrapper.type()).to.equal(null);
```
================================================
FILE: docs/api/ReactWrapper/unmount.md
================================================
# `.unmount() => Self`
A method that unmounts the component. This can be used to simulate a component going through
an unmount/mount lifecycle.
#### Returns
`ReactWrapper`: Returns itself.
#### Example
```jsx
import PropTypes from 'prop-types';
import sinon from 'sinon';
const willMount = sinon.spy();
const didMount = sinon.spy();
const willUnmount = sinon.spy();
class Foo extends React.Component {
constructor(props) {
super(props);
this.componentWillUnmount = willUnmount;
this.componentWillMount = willMount;
this.componentDidMount = didMount;
}
render() {
const { id } = this.props;
return (
{id}
);
}
}
Foo.propTypes = {
id: PropTypes.string.isRequired,
};
const wrapper = mount();
expect(willMount).to.have.property('callCount', 1);
expect(didMount).to.have.property('callCount', 1);
expect(willUnmount).to.have.property('callCount', 0);
wrapper.unmount();
expect(willMount).to.have.property('callCount', 1);
expect(didMount).to.have.property('callCount', 1);
expect(willUnmount).to.have.property('callCount', 1);
```
#### Related Methods
- [`.mount() => Self`](mount.md)
================================================
FILE: docs/api/ReactWrapper/update.md
================================================
# `.update() => Self`
Syncs the enzyme component tree snapshot with the react component tree. Useful to run before checking the render output if something external
may be updating the state of the component somewhere.
NOTE: no matter what instance this is called on, it will always update the root.
NOTE: only updates Enzyme's representation of rendered tree.
NOTE: this does not force a re-render. Use `wrapper.setProps({})` to force a re-render.
#### Returns
`ReactWrapper`: Returns itself.
#### Example
```jsx
class UpdateEnzyme extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
this.increment = this.increment.bind(this);
}
increment() {
const { count } = this.state;
this.setState({ count: count + 1 });
}
render() {
const { count } = this.state;
return ;
}
}
```
```jsx
const wrapper = mount();
expect(wrapper.find('button.increment').text()).to.equal('0');
wrapper.instance().increment();
// Update Enzyme's view of output
wrapper.update();
expect(wrapper.find('button.increment').text()).to.equal('1');
```
================================================
FILE: docs/api/ShallowWrapper/at.md
================================================
# `.at(index) => ShallowWrapper`
Returns a wrapper around the node at a given index of the current wrapper.
#### Arguments
1. `index` (`Number`): A zero-based integer indicating which node to retrieve.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the retrieved node.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find(Foo).at(0).props().foo).to.equal('bar');
```
#### Related Methods
- [`.get(index) => ReactElement`](get.md) - same, but returns the React node itself, with no wrapper.
- [`.first() => ShallowWrapper`](first.md) - same as at(0)
- [`.last() => ShallowWrapper`](last.md)
================================================
FILE: docs/api/ShallowWrapper/childAt.md
================================================
# `.childAt(index) => ShallowWrapper`
Returns a new wrapper with child at the specified index.
#### Arguments
1. `index` (`number`): A zero-based integer indicating which node to retrieve.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the resulting node.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find('ul').childAt(0).type()).to.equal('li');
```
#### Related Methods
- [`.parents([selector]) => ShallowWrapper`](parents.md)
- [`.parent() => ShallowWrapper`](parent.md)
- [`.closest(selector) => ShallowWrapper`](closest.md)
- [`.children([selector]) => ShallowWrapper`](children.md)
================================================
FILE: docs/api/ShallowWrapper/children.md
================================================
# `.children([selector]) => ShallowWrapper`
Returns a new wrapper with all of the children of the node(s) in the current wrapper. Optionally, a
selector can be provided and it will filter the children by this selector
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md) [optional]): A selector to filter the children by.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the resulting nodes.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find('ul').children()).to.have.lengthOf(items.length);
```
#### Related Methods
- [`.parents([selector]) => ShallowWrapper`](parents.md)
- [`.parent() => ShallowWrapper`](parent.md)
- [`.closest(selector) => ShallowWrapper`](closest.md)
================================================
FILE: docs/api/ShallowWrapper/closest.md
================================================
# `.closest(selector) => ShallowWrapper`
Returns a wrapper of the first element that matches the selector by traversing up through the
wrapped node's ancestors in the tree, starting with itself. It must be a single-node wrapper.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the resulting node.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find(Foo).closest('.bar')).to.have.lengthOf(1);
```
#### Related Methods
- [`.children([selector]) => ShallowWrapper`](children.md)
- [`.parent() => ShallowWrapper`](parent.md)
- [`.parents([selector]) => ShallowWrapper`](parents.md)
================================================
FILE: docs/api/ShallowWrapper/contains.md
================================================
# `.contains(nodeOrNodes) => Boolean`
Returns whether or not all given react elements match elements in the render tree.
It will determine if an element in the wrapper matches the expected element by checking if the expected element has the same props as the wrapper's element and share the same values.
#### Arguments
1. `nodeOrNodes` (`ReactElement|Array`): The node or array of nodes whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has nodes anywhere in its render tree that match
the ones passed in.
#### Example
```jsx
const wrapper = shallow((
)).to.equal(true);
```
#### Common Gotchas
- `.contains()` expects a ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with a ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
================================================
FILE: docs/api/ShallowWrapper/containsAllMatchingElements.md
================================================
# `.containsAllMatchingElements(patternNodes) => Boolean`
Returns whether or not all of the given react elements in `patternNodes` match an element in the wrapper's render tree. Every single element of `patternNodes` must be matched one or more times. Matching follows the rules for `containsMatchingElement`.
#### Arguments
1. `patternNodes` (`Array`): The array of nodes whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has nodes anywhere in its render tree that looks
like the nodes passed in.
#### Example
```jsx
const style = { fontSize: 13 };
const wrapper = shallow((
,
])).to.equal(true);
```
#### Common Gotchas
- `.containsAllMatchingElements()` expects an array of ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with an array of ReactElement or a JSX expression.
- Keep in mind that this method determines matching based on the matching of the node's children as
well.
#### Related Methods
- [`.matchesElement() => ShallowWrapper`](matchesElement.md) - rules for matching each node
- [`.containsMatchingElement() => ShallowWrapper`](containsMatchingElement.md) - rules for matching whole wrapper
- [`.containsAnyMatchingElements() => ShallowWrapper`](containsAnyMatchingElements.md) - must match at least one in patternNodes
================================================
FILE: docs/api/ShallowWrapper/containsAnyMatchingElements.md
================================================
# `.containsAnyMatchingElements(patternNodes) => Boolean`
Returns whether or not at least one of the given react elements in `patternNodes` matches an element in the wrapper's render tree. One or more elements of `patternNodes` must be matched one or more times. Matching follows the rules for `containsMatchingElement`.
#### Arguments
1. `patternNodes` (`Array`): The array of nodes whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has a node anywhere in its render tree that looks
like one of the array passed in.
#### Example
```jsx
const style = { fontSize: 13 };
const wrapper = shallow((
,
])).to.equal(true);
```
#### Common Gotchas
- `.containsAnyMatchingElements()` expects an array of ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with an array ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
#### Related Methods
- [`.matchesElement() => ShallowWrapper`](matchesElement.md) - rules for matching each node
- [`.containsMatchingElement() => ShallowWrapper`](containsMatchingElement.md) - rules for matching whole wrapper
- [`.containsAllMatchingElements() => ShallowWrapper`](containsAllMatchingElements.md) - must match all nodes in patternNodes
================================================
FILE: docs/api/ShallowWrapper/containsMatchingElement.md
================================================
# `.containsMatchingElement(patternNode) => Boolean`
Returns whether or not a `patternNode` react element matches any element in the render tree.
* the matches can happen anywhere in the wrapper's contents
* the wrapper can contain more than one node; all are searched
Otherwise, the match follows the same rules as `matchesElement`.
#### Arguments
1. `patternNode` (`ReactElement`): The node whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has a node anywhere in its render tree that matches
the one passed in.
#### Example
```jsx
const wrapper = shallow((
)).to.equal(false);
expect(wrapper.containsMatchingElement()).to.equal(false);
```
#### Common Gotchas
- `.containsMatchingElement()` expects a ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with a ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
#### Related Methods
- [`.containsAllMatchingElements() => ShallowWrapper`](containsAllMatchingElements.md) - must match all nodes in patternNodes
- [`.containsAnyMatchingElements() => ShallowWrapper`](containsAnyMatchingElements.md) - must match at least one in patternNodes
================================================
FILE: docs/api/ShallowWrapper/context.md
================================================
# `.context([key]) => Any`
Returns the context hash for the root node of the wrapper. Optionally pass in a prop name and it
will return just that value.
#### Arguments
1. `key` (`String` [optional]): If provided, the return value will be the `this.context[key]` of the
root component instance.
#### Example
```jsx
const wrapper = shallow(
,
{ context: { foo: 10 } },
);
expect(wrapper.context().foo).to.equal(10);
expect(wrapper.context('foo')).to.equal(10);
```
#### Related Methods
- [`.props() => Object`](props.md)
- [`.prop(key) => Any`](prop.md)
- [`.state([key]) => Any`](state.md)
================================================
FILE: docs/api/ShallowWrapper/debug.md
================================================
# `.debug([options]) => String`
Returns an HTML-like string of the wrapper for debugging purposes. Useful to print out to the
console when tests are not passing when you expect them to.
#### Arguments
`options` (`Object` [optional]):
- `options.ignoreProps`: (`Boolean` [optional]): Whether props should be omitted in the resulting string. Props are included by default.
- `options.verbose`: (`Boolean` [optional]): Whether arrays and objects passed as props should be verbosely printed.
#### Returns
`String`: The resulting string.
#### Examples
```jsx
function Book({ title, pages }) {
return (
```
================================================
FILE: docs/api/ShallowWrapper/dive.md
================================================
# `.dive([options]) => ShallowWrapper`
Shallow render the one non-DOM child of the current wrapper, and return a wrapper around the result. It must be a single-node wrapper, and the node must be a React component.
There is no corresponding `dive` method for ReactWrappers.
NOTE: can only be called on a wrapper of a single non-DOM component element node, otherwise it will throw an error. If you have to shallow-wrap a wrapper with multiple child nodes, use [`.shallow()`](shallow.md).
#### Arguments
1. `options` (`Object` [optional]):
- `options.context`: (`Object` [optional]): Context to be passed into the component
#### Returns
`ShallowWrapper`: A new wrapper that wraps the current node after it's been shallow rendered.
#### Examples
```jsx
function Bar() {
return (
);
}
```
```jsx
function Foo() {
return (
);
}
```
```jsx
const wrapper = shallow();
expect(wrapper.find('.in-bar')).to.have.lengthOf(0);
expect(wrapper.find(Bar)).to.have.lengthOf(1);
expect(wrapper.find(Bar).dive().find('.in-bar')).to.have.lengthOf(1);
```
================================================
FILE: docs/api/ShallowWrapper/equals.md
================================================
# `.equals(node) => Boolean`
Returns whether or not the current wrapper root node render tree looks like the one passed in.
#### Arguments
1. `node` (`ReactElement`): The node whose presence you are detecting in the current instance's
render tree.
#### Returns
`Boolean`: whether or not the current wrapper has a node anywhere in it's render tree that looks
like the one passed in.
#### Example
```jsx
function MyComponent() {
return ;
}
const wrapper = shallow();
expect(wrapper.equals()).to.equal(true);
```
#### Common Gotchas
- `.equals()` expects a ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with a ReactElement or a JSX expression.
- Keep in mind that this method determines equality based on the equality of the node's children as
well.
- Following React's behavior, `.equals()` ignores properties whose values are `undefined`.
================================================
FILE: docs/api/ShallowWrapper/every.md
================================================
# `.every(selector) => Boolean`
Returns whether or not all of the nodes in the wrapper match the provided selector.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`Boolean`: True if every node in the current wrapper matched the provided selector.
#### Examples
```jsx
const wrapper = shallow((
));
expect(wrapper.find('.foo').every('.foo')).to.equal(true);
expect(wrapper.find('.foo').every('.qoo')).to.equal(false);
expect(wrapper.find('.foo').every('.bar')).to.equal(false);
```
#### Related Methods
- [`.someWhere(predicate) => Boolean`](someWhere.md)
- [`.everyWhere(predicate) => Boolean`](everyWhere.md)
================================================
FILE: docs/api/ShallowWrapper/everyWhere.md
================================================
# `.everyWhere(fn) => Boolean`
Returns whether or not all of the nodes in the wrapper pass the provided predicate function.
#### Arguments
1. `predicate` (`ShallowWrapper => Boolean`): A predicate function to match the nodes.
#### Returns
`Boolean`: True if every node in the current wrapper passed the predicate function.
#### Example
```jsx
const wrapper = shallow((
));
expect(wrapper.find('.foo').everyWhere((n) => n.hasClass('foo'))).to.equal(true);
expect(wrapper.find('.foo').everyWhere((n) => n.hasClass('qoo'))).to.equal(false);
expect(wrapper.find('.foo').everyWhere((n) => n.hasClass('bar'))).to.equal(false);
```
#### Related Methods
- [`.some(selector) => Boolean`](some.md)
- [`.every(selector) => Boolean`](every.md)
- [`.everyWhere(predicate) => Boolean`](everyWhere.md)
================================================
FILE: docs/api/ShallowWrapper/exists.md
================================================
# `.exists([selector]) => Boolean`
Returns whether or not any nodes exist in the wrapper. Or, if a selector is passed in, whether that selector has any matches in the wrapper.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md) [optional]): The selector to check existence for.
#### Returns
`Boolean`: whether or not any nodes are on the list, or the selector had any matches.
#### Example
```jsx
const wrapper = shallow();
expect(wrapper.exists('.some-class')).to.equal(true);
expect(wrapper.find('.other-class').exists()).to.equal(false);
```
================================================
FILE: docs/api/ShallowWrapper/filter.md
================================================
# `.filter(selector) => ShallowWrapper`
Returns a new wrapper with only the nodes of the current wrapper that match the provided selector.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the filtered nodes.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find('.foo').filter('.bar')).to.have.lengthOf(1);
```
#### Related Methods
- [`.filterWhere(predicate) => ShallowWrapper`](filterWhere.md)
================================================
FILE: docs/api/ShallowWrapper/filterWhere.md
================================================
# `.filterWhere(fn) => ShallowWrapper`
Returns a new wrapper with only the nodes of the current wrapper that, when passed into the
provided predicate function, return true.
#### Arguments
1. `predicate` (`ShallowWrapper => Boolean`): A predicate function that is passed a wrapped node.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the filtered nodes.
#### Example
```jsx
const wrapper = shallow();
const complexFoo = wrapper.find('.foo').filterWhere((n) => typeof n.type() !== 'string');
expect(complexFoo).to.have.lengthOf(4);
```
#### Related Methods
- [`.filter(selector) => ShallowWrapper`](filter.md)
================================================
FILE: docs/api/ShallowWrapper/find.md
================================================
# `.find(selector) => ShallowWrapper`
Finds every node in the render tree of the current wrapper that matches the provided selector.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the found nodes.
#### Examples
CSS Selectors:
```jsx
const wrapper = shallow();
expect(wrapper.find('.foo')).to.have.lengthOf(1);
expect(wrapper.find('.bar')).to.have.lengthOf(3);
// compound selector
expect(wrapper.find('div.some-class')).to.have.lengthOf(3);
// CSS id selector
expect(wrapper.find('#foo')).to.have.lengthOf(1);
```
Component Constructors:
```jsx
import Foo from '../components/Foo';
const wrapper = shallow();
expect(wrapper.find(Foo)).to.have.lengthOf(1);
```
Component Display Name:
```jsx
const wrapper = shallow();
expect(wrapper.find('Foo')).to.have.lengthOf(1);
```
Object Property Selector:
```jsx
const wrapper = shallow();
expect(wrapper.find({ prop: 'value' })).to.have.lengthOf(1);
```
#### Related Methods
- [`.findWhere(predicate) => ShallowWrapper`](findWhere.md)
================================================
FILE: docs/api/ShallowWrapper/findWhere.md
================================================
# `.findWhere(fn) => ShallowWrapper`
Finds every node in the render tree that returns true for the provided predicate function.
#### Arguments
1. `predicate` (`ShallowWrapper => Boolean`): A predicate function called with the passed in wrapped
nodes.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the found nodes.
#### Example
```jsx
const wrapper = shallow();
const complexComponents = wrapper.findWhere((n) => n.type() !== 'string');
expect(complexComponents).to.have.lengthOf(8);
```
#### Related Methods
- [`.find(selector) => ShallowWrapper`](find.md)
================================================
FILE: docs/api/ShallowWrapper/first.md
================================================
# `.first() => ShallowWrapper`
Reduce the set of matched nodes to the first in the set, just like `.at(0)`.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the first node in the set.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find(Foo).first().props().foo).to.equal('bar');
```
#### Related Methods
- [`.at(index) => ShallowWrapper`](at.md) - retrieve a wrapper node at given index
- [`.last() => ShallowWrapper`](last.md)
================================================
FILE: docs/api/ShallowWrapper/forEach.md
================================================
# `.forEach(fn) => Self`
Iterates through each node of the current wrapper and executes the provided function with a
wrapper around the corresponding node passed in as the first argument.
#### Arguments
1. `fn` (`Function ( ShallowWrapper node, Number index )`): A callback to be run for every node in the collection.
Should expect a ShallowWrapper as the first argument, and will be run with a context of the original
instance.
#### Returns
`ShallowWrapper`: Returns itself.
#### Example
```jsx
const wrapper = shallow((
));
wrapper.find('.foo').forEach((node) => {
expect(node.hasClass('foo')).to.equal(true);
});
```
#### Related Methods
- [`.map(fn) => ShallowWrapper`](map.md)
================================================
FILE: docs/api/ShallowWrapper/get.md
================================================
# `.get(index) => ReactElement`
Returns the node at a given index of the current wrapper.
#### Arguments
1. `index` (`Number`): A zero-based integer indicating which node to retrieve.
#### Returns
`ReactElement`: The retrieved node.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find(Foo).get(0).props.foo).to.equal('bar');
```
#### Related Methods
- [`.at(index) => ShallowWrapper`](at.md) - same, but returns the React node in a single-node wrapper.
================================================
FILE: docs/api/ShallowWrapper/getElement.md
================================================
# `.getElement() => ReactElement`
Returns the wrapped ReactElement.
If the current wrapper is wrapping the root component, returns the root component's latest render output.
#### Returns
`ReactElement`: The retrieved ReactElement.
#### Examples
```jsx
const element = (
);
function MyComponent() {
return element;
}
const wrapper = shallow();
expect(wrapper.getElement()).to.equal(element);
```
#### Related Methods
- [`.getElements() => Array`](getElements.md)
================================================
FILE: docs/api/ShallowWrapper/getElements.md
================================================
# `.getElements() => Array`
Returns the wrapped ReactElements
If the current wrapper is wrapping the root component, returns the root component's latest render output wrapped in an array.
#### Returns
`Array`: The retrieved ReactElements.
#### Examples
```jsx
const one = ;
const two = ;
function Test() {
return (
{one}
{two}
);
}
const wrapper = shallow();
expect(wrapper.find('span').getElements()).to.deep.equal([one, two]);
```
#### Related Methods
- [`.getElement() => ReactElement`](getElement.md)
================================================
FILE: docs/api/ShallowWrapper/getWrappingComponent.md
================================================
# `.getWrappingComponent() => ShallowWrapper`
If a `wrappingComponent` was passed in `options`, this methods returns a `ShallowWrapper` around the rendered `wrappingComponent`. This `ShallowWrapper` can be used to update the `wrappingComponent`'s props, state, etc.
#### Returns
`ShallowWrapper`: A `ShallowWrapper` around the rendered `wrappingComponent`
#### Examples
```jsx
import { Provider } from 'react-redux';
import { Router } from 'react-router';
import store from './my/app/store';
import mockStore from './my/app/mockStore';
function MyProvider(props) {
const { children, customStore } = props;
return (
{children}
);
}
MyProvider.propTypes = {
children: PropTypes.node,
customStore: PropTypes.shape({}),
};
MyProvider.defaultProps = {
children: null,
customStore: null,
};
const wrapper = shallow(, {
wrappingComponent: MyProvider,
});
const provider = wrapper.getWrappingComponent();
provider.setProps({ customStore: mockStore });
```
================================================
FILE: docs/api/ShallowWrapper/hasClass.md
================================================
# `.hasClass(className) => Boolean`
Returns whether or not the wrapped node has a `className` prop including the passed in class name. It must be a single-node wrapper.
#### Arguments
1. `className` (`String` | `RegExp`): A single class name or a regex expression.
#### Returns
`Boolean`: whether or not the wrapped node has the class.
#### Example
```jsx
const wrapper = shallow();
expect(wrapper.find('.my-button').hasClass('disabled')).to.equal(true);
```
```jsx
// Searching using RegExp works fine when classes were injected by a jss decorator
const wrapper = shallow();
expect(wrapper.find('.my-button').hasClass(/(ComponentName)-(other)-(\d+)/)).to.equal(true);
```
### Common Gotchas
- `.hasClass()` expects a class name, NOT a CSS selector. `.hasClass('.foo')` should be
`.hasClass('foo')`
================================================
FILE: docs/api/ShallowWrapper/hostNodes.md
================================================
# `.hostNodes() => ShallowWrapper`
Returns a new wrapper with only host nodes.
When using `react-dom`, host nodes are HTML elements rather than custom React components, e.g. `
` versus ``.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the filtered nodes.
#### Examples
The following code takes a wrapper with two nodes, one a `` React component, and the other a ``, and filters out the React component.
```jsx
const wrapper = shallow((
));
const twoNodes = wrapper.find('.foo');
expect(twoNodes.hostNodes()).to.have.lengthOf(1);
```
================================================
FILE: docs/api/ShallowWrapper/html.md
================================================
# `.html() => String`
Returns a string of the rendered HTML markup of the entire current render tree (not just the shallow-rendered part). It uses [static rendering](../render.md) internally. To see only the shallow-rendered part use [`.debug()`](debug.md).
Note: can only be called on a wrapper of a single node.
#### Returns
`String`: The resulting HTML string
#### Examples
```jsx
function Foo() {
return ();
}
```
```jsx
function Bar() {
return (
');
```
#### Related Methods
- [`.text() => String`](text.md)
- [`.debug() => String`](debug.md)
================================================
FILE: docs/api/ShallowWrapper/instance.md
================================================
# `.instance() => ReactComponent`
Returns the single-node wrapper's node's underlying class instance; `this` in its methods. It must be a single-node wrapper.
NOTE: can only be called on a wrapper instance that is also the root instance. With React `16` and above, `instance()` returns `null` for functional components, regardless of [hooks](https://reactjs.org/docs/hooks-intro.html) usage.
#### Returns
`ReactComponent|DOMComponent`: The retrieved instance.
#### Example
```jsx
function SFC() {
return
MyFunction
;
}
class Stateful extends React.Component {
render() {
return
MyClass
;
}
}
```
#### React 16.x
```jsx
test('wrapper instance is null', () => {
const wrapper = shallow();
const instance = wrapper.instance();
expect(instance).to.equal(null);
});
test('wrapper instance is not null', () => {
const wrapper = shallow();
const instance = wrapper.instance();
expect(instance).to.be.instanceOf(MyCStatefullass);
});
```
#### React 15.x
```jsx
test('wrapper instance is not null', () => {
const wrapper = shallow();
const instance = wrapper.instance();
expect(instance).to.be.instanceOf(SFC);
});
test('wrapper instance is not null', () => {
const wrapper = shallow();
const instance = wrapper.instance();
expect(instance).to.be.instanceOf(Stateful);
});
```
================================================
FILE: docs/api/ShallowWrapper/invoke.md
================================================
# `.invoke(invokePropName)(...args) => Any`
Invokes a function prop.
#### Arguments
1. `propName` (`String`): The function prop that is invoked
2. `...args` (`Any` [optional]): Arguments that is passed to the prop function
This essentially calls wrapper.prop(propName)(...args).
#### Returns
`Any`: Returns the value from the prop function
#### Example
```jsx
class Foo extends React.Component {
loadData() {
return fetch();
}
render() {
return (
);
}
}
const wrapper = shallow();
wrapper.find('button').invoke('onClick')().then(() => {
// expect()
});
```
================================================
FILE: docs/api/ShallowWrapper/is.md
================================================
# `.is(selector) => Boolean`
Returns whether or not the single wrapped node matches the provided selector. It must be a single-node wrapper.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`Boolean`: whether or not the wrapped node matches the provided selector.
#### Example
```jsx
const wrapper = shallow();
expect(wrapper.is('.some-class')).to.equal(true);
```
================================================
FILE: docs/api/ShallowWrapper/isEmpty.md
================================================
# `.isEmpty() => Boolean`
**Deprecated**: Use [`.exists()`](exists.md) instead.
Returns whether or not the wrapper is empty.
#### Returns
`Boolean`: whether or not the wrapper is empty.
#### Example
```jsx
const wrapper = shallow();
expect(wrapper.find('.other-class').isEmpty()).to.equal(true);
```
================================================
FILE: docs/api/ShallowWrapper/isEmptyRender.md
================================================
# `.isEmptyRender() => Boolean`
Returns whether or not the wrapper would ultimately render only the allowed falsy values: `false` or `null`.
#### Returns
`Boolean`: whether the return is falsy
#### Example
```jsx
function Foo() {
return null;
}
const wrapper = shallow();
expect(wrapper.isEmptyRender()).to.equal(true);
```
================================================
FILE: docs/api/ShallowWrapper/key.md
================================================
# `.key() => String`
Returns the key value for the node of the current wrapper. It must be a single-node wrapper.
#### Example
```jsx
const wrapper = shallow((
{['foo', 'bar'].map((s) =>
{s}
)}
)).find('li');
expect(wrapper.at(0).key()).to.equal('foo');
expect(wrapper.at(1).key()).to.equal('bar');
```
================================================
FILE: docs/api/ShallowWrapper/last.md
================================================
# `.last() => ShallowWrapper`
Reduce the set of matched nodes to the last in the set, just like `.at(length - 1)`.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the last node in the set.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find(Foo).last().props().foo).to.equal('bar');
```
#### Related Methods
- [`.at(index) => ShallowWrapper`](at.md) - retrieve a wrapper node by index
- [`.first() => ShallowWrapper`](first.md)
================================================
FILE: docs/api/ShallowWrapper/length.md
================================================
# `.length => number`
Returns the number of React nodes enclosed in this wrapper.
#### Returns
`Number`: count of nodes in the list in this wrapper.
#### Example
```jsx
const wrapper = shallow();
expect(wrapper.length).to.equal(1);
```
================================================
FILE: docs/api/ShallowWrapper/map.md
================================================
# `.map(fn) => Array`
Maps the current array of nodes to another array. Each node is passed in as a `ShallowWrapper`
to the map function.
#### Arguments
1. `fn` (`Function ( ShallowWrapper node, Number index ) => Any`): A mapping function to be run for every node in
the collection, the results of which will be mapped to the returned array. Should expect a ShallowWrapper as the first argument, and will be run with a context of
the original instance.
#### Returns
`Array`: Returns an array of the returned values from the mapping function..
#### Example
```jsx
const wrapper = shallow((
bax
bar
baz
));
const texts = wrapper.find('.foo').map((node) => node.text());
expect(texts).to.eql(['bax', 'bar', 'baz']);
```
#### Related Methods
- [`.forEach(fn) => ShallowWrapper`](forEach.md)
- [`.reduce(fn[, initialValue]) => Any`](reduce.md)
- [`.reduceRight(fn[, initialValue]) => Any`](reduceRight.md)
================================================
FILE: docs/api/ShallowWrapper/matchesElement.md
================================================
# `.matchesElement(patternNode) => Boolean`
Returns whether or not a given react element `patternNode` matches the wrapper's render tree. It must be a single-node wrapper, and only the root node is checked.
The `patternNode` acts like a wildcard. For it to match a node in the wrapper:
* tag names must match
* contents must match: In text nodes, leading and trailing spaces are ignored, but not space in the middle. Child elements must match according to these rules, recursively.
* `patternNode` props (attributes) must appear in the wrapper's nodes, but not the other way around. Their values must match if they do appear.
* `patternNode` style CSS properties must appear in the wrapper's node's style, but not the other way around. Their values must match if they do appear.
#### Arguments
1. `patternNode` (`ReactElement`): The node whose presence you are detecting in the wrapper's single node.
#### Returns
`Boolean`: whether or not the current wrapper match the one passed in.
#### Example
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// ...
}
render() {
return (
);
}
}
const wrapper = shallow();
expect(wrapper.matchesElement()).to.equal(true);
expect(wrapper.matchesElement()).to.equal(true);
```
#### Common Gotchas
- `.matchesElement()` expects a ReactElement, not a selector (like many other methods). Make sure that
when you are calling it you are calling it with a ReactElement or a JSX expression.
- Keep in mind that this method determines matching based on the matching of the node's children as
well.
#### Related Methods
- [`.containsMatchingElement() => ShallowWrapper`](containsMatchingElement.md) - searches all nodes in the wrapper, and searches their entire depth
================================================
FILE: docs/api/ShallowWrapper/name.md
================================================
# `.name() => String|null`
Returns the name of the current node of this wrapper. If it's a composite component, this will be
the name of the top-most rendered component. If it's a native DOM node, it will be a string of the
tag name. If it's `null`, it will be `null`.
The order of precedence on returning the name is: `type.displayName` -> `type.name` -> `type`.
Note: can only be called on a wrapper of a single node.
#### Returns
`String|null`: The name of the current node
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.name()).to.equal('div');
```
```jsx
function SomeWrappingComponent() {
return ;
}
const wrapper = shallow();
expect(wrapper.name()).to.equal('Foo');
```
```jsx
Foo.displayName = 'A cool custom name';
function SomeWrappingComponent() {
return ;
}
const wrapper = shallow();
expect(wrapper.name()).to.equal('A cool custom name');
```
================================================
FILE: docs/api/ShallowWrapper/not.md
================================================
# `.not(selector) => ShallowWrapper`
Returns a new wrapper with only the nodes of the current wrapper that don't match the provided
selector.
This method is effectively the negation or inverse of [`filter`](filter.md).
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the filtered nodes.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find('.foo').not('.bar')).to.have.lengthOf(1);
```
#### Related Methods
- [`.filterWhere(predicate) => ShallowWrapper`](filterWhere.md)
- [`.filter(selector) => ShallowWrapper`](filter.md)
================================================
FILE: docs/api/ShallowWrapper/parent.md
================================================
# `.parent() => ShallowWrapper`
Returns a wrapper with the direct parent of the node in the current wrapper.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the resulting nodes.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find('ul').parent().is('div')).to.equal(true);
```
#### Related Methods
- [`.parents([selector]) => ShallowWrapper`](parents.md)
- [`.children([selector]) => ShallowWrapper`](children.md)
- [`.closest(selector) => ShallowWrapper`](closest.md)
================================================
FILE: docs/api/ShallowWrapper/parents.md
================================================
# `.parents([selector]) => ShallowWrapper`
Returns a wrapper around all of the parents/ancestors of the single node in the wrapper. Does not include the node itself.
Optionally, a selector can be provided and it will filter the parents by this selector. It must be a single-node wrapper.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md) [optional]): The selector to filter the parents by.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the resulting nodes.
#### Examples
```jsx
const wrapper = shallow();
expect(wrapper.find('ul').parents()).to.have.lengthOf(2);
```
#### Related Methods
- [`.children([selector]) => ShallowWrapper`](children.md)
- [`.parent() => ShallowWrapper`](parent.md)
- [`.closest(selector) => ShallowWrapper`](closest.md)
================================================
FILE: docs/api/ShallowWrapper/prop.md
================================================
# `.prop(key) => Any`
Returns the prop value for the root node of the wrapper with the provided key. It must be a single-node wrapper.
NOTE: When called on a shallow wrapper, `.prop(key)` will return values for
props on the root node that the component *renders*, not the component itself.
To return the props for the entire React component, use `wrapper.instance().props`.
See [`.instance() => ReactComponent`](instance.md)
#### Arguments
1. `key` (`String`): The prop name, that is, `this.props[key]` or `props[key]` for the root node of the wrapper.
#### Example
```jsx
import PropTypes from 'prop-types';
import ValidateNumberInputComponent from './ValidateNumberInputComponent';
class MyComponent extends React.Component {
constructor(...args) {
super(...args);
this.state = {
number: 0,
};
this.onValidNumberInput = this.onValidNumberInput.bind(this);
}
onValidNumberInput(e) {
const number = e.target.value;
if (!number || typeof number === 'number') {
this.setState({ number });
}
}
render() {
const { includedProp } = this.props;
const { number } = this.state;
return (
);
}
}
MyComponent.propTypes = {
includedProp: PropTypes.string.isRequired,
};
const wrapper = shallow();
expect(wrapper.prop('includedProp')).to.equal('Success!');
const validInput = 1;
wrapper.find('ValidateNumberInputComponent').prop('onChangeHandler')(validInput);
expect(wrapper.state('number')).to.equal(validInput);
const invalidInput = 'invalid input';
wrapper.find('ValidateNumberInputComponent').prop('onChangeHandler')(invalidInput);
expect(wrapper.state('number')).to.equal(0);
// Warning: .prop(key) only returns values for props that exist in the root node.
// See the note above about wrapper.instance().props to return all props in the React component.
console.log(wrapper.prop('includedProp'));
// "Success!"
console.log(wrapper.prop('excludedProp'));
// undefined
console.log(wrapper.instance().props.excludedProp);
// "I'm not included"
```
#### Related Methods
- [`.props() => Object`](props.md)
- [`.state([key]) => Any`](state.md)
- [`.context([key]) => Any`](context.md)
================================================
FILE: docs/api/ShallowWrapper/props.md
================================================
# `.props() => Object`
Returns the props object for the root node of the wrapper. It must be a single-node wrapper.
NOTE: When called on a shallow wrapper, `.props()` will return values for props on the root node that the component *renders*, not the component itself.
This method is a reliable way of accessing the props of a node; `wrapper.instance().props` will work as well, but in React 16+, stateless functional components do not have an instance. See [`.instance() => ReactComponent`](instance.md)
#### Example
```jsx
import PropTypes from 'prop-types';
function MyComponent(props) {
const { includedProp } = props;
return (
Hello
);
}
MyComponent.propTypes = {
includedProp: PropTypes.string.isRequired,
};
const wrapper = shallow();
expect(wrapper.props().includedProp).to.equal('Success!');
// Warning: .props() only returns props that are passed to the root node,
// which does not include excludedProp in this example.
// See the note above about wrapper.instance().props.
console.log(wrapper.props());
// {children: "Hello", className: "foo bar", includedProp="Success!"}
console.log(wrapper.instance().props); // React 15.x - working as expected
// {children: "Hello", className: "foo bar", includedProp:"Success!", excludedProp: "I'm not included"}
console.log(wrapper.instance().props);
// React 16.* - Uncaught TypeError: Cannot read property 'props' of null
```
#### Related Methods
- [`.prop(key) => Any`](prop.md)
- [`.state([key]) => Any`](state.md)
- [`.context([key]) => Any`](context.md)
================================================
FILE: docs/api/ShallowWrapper/reduce.md
================================================
# `.reduce(fn[, initialValue]) => Any`
Applies the provided reducing function to every node in the wrapper to reduce to a single value.
Each node is passed in as a `ShallowWrapper`, and is processed from left to right.
#### Arguments
1. `fn` (`Function`): A reducing function to be run for every node in the collection, with the
following arguments:
- `value` (`T`): The value returned by the previous invocation of this function
- `node` (`ShallowWrapper`): A wrapper around the node being processed
- `index` (`Number`): The index of the node being processed
2. `initialValue` (`T` [optional]): If provided, this will be passed in as the first argument to the first invocation of the reducing function. If omitted, the first `node` will be provided and the iteration will begin on the second node in the collection.
#### Returns
`T`: Returns an array of the returned values from the mapping function...
#### Example
```jsx
function Foo() {
return (
);
}
```
```jsx
const wrapper = shallow();
const total = wrapper.find(Bar).reduce((amount, n) => amount + n.prop('amount'), 0);
expect(total).to.equal(14);
```
#### Related Methods
- [`.reduceRight(fn[, initialValue]) => Any`](reduceRight.md)
- [`.forEach(fn) => ShallowWrapper`](forEach.md)
- [`.map(fn) => Array`](map.md)
================================================
FILE: docs/api/ShallowWrapper/reduceRight.md
================================================
# `.reduceRight(fn[, initialValue]) => Any`
Applies the provided reducing function to every node in the wrapper to reduce to a single value.
Each node is passed in as a `ShallowWrapper`, and is processed from right to left.
#### Arguments
1. `fn` (`Function`): A reducing function to be run for every node in the collection, with the
following arguments:
- `value` (`T`): The value returned by the previous invocation of this function
- `node` (`ShallowWrapper`): A single-node wrapper around the node being processed
- `index` (`Number`): The index of the node being processed
2. `initialValue` (`T` [optional]): If provided, this will be passed in as the first argument to the first invocation of the reducing function. If omitted, the first `node` will be provided and the iteration will begin on the second node in the collection.
#### Returns
`T`: Returns an array of the returned values from the mapping function...
#### Example
```jsx
function Foo() {
return (
);
}
```
```jsx
const wrapper = shallow();
const total = wrapper.find(Bar).reduceRight((amount, n) => amount + n.prop('amount'), 0);
expect(total).to.equal(14);
```
#### Related Methods
- [`.reduce(fn[, initialValue]) => Any`](reduce.md)
- [`.forEach(fn) => ShallowWrapper`](forEach.md)
- [`.map(fn) => Array`](map.md)
================================================
FILE: docs/api/ShallowWrapper/render.md
================================================
# `.render() => CheerioWrapper`
Returns a CheerioWrapper around the rendered HTML of the single node's subtree.
It must be a single-node wrapper.
#### Returns
`CheerioWrapper`: The resulting Cheerio object
#### Examples
```jsx
function Foo() {
return ();
}
```
```jsx
function Bar() {
return (
);
}
```
```jsx
const wrapper = shallow();
expect(wrapper.find('.in-foo')).to.have.lengthOf(0);
expect(wrapper.render().find('.in-foo')).to.have.lengthOf(1);
```
================================================
FILE: docs/api/ShallowWrapper/renderProp.md
================================================
# `.renderProp(propName)(...args) => ShallowWrapper`
Returns a function that, when called with arguments `args`, will return a new wrapper based on the render prop in the original wrapper's prop `propName`.
NOTE: can only be called on wrapper of a single non-DOM component element node.
#### Arguments
1. `propName` (`String`):
1. `...args` (`Array`):
This essentially calls `wrapper.prop(propName)(...args)`.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the node returned from the render prop.
#### Examples
##### Test Setup
```jsx
class Mouse extends React.Component {
constructor() {
super();
this.state = { x: 0, y: 0 };
}
render() {
const { render } = this.props;
return (
)).to.equal(true);
```
================================================
FILE: docs/api/ShallowWrapper/setContext.md
================================================
# `.setContext(context) => Self`
A method that sets the context of the root component, and re-renders. Useful for when you are
wanting to test how the component behaves over time with changing contexts.
NOTE: can only be called on a wrapper instance that is also the root instance.
#### Arguments
1. `context` (`Object`): An object containing new props to merge in with the current state
#### Returns
`ShallowWrapper`: Returns itself.
#### Example
```jsx
import React from 'react';
import PropTypes from 'prop-types';
function SimpleComponent(props, context) {
const { name } = context;
return
{name}
;
}
SimpleComponent.contextTypes = {
name: PropTypes.string,
};
```
```jsx
const context = { name: 'foo' };
const wrapper = shallow(, { context });
expect(wrapper.text()).to.equal('foo');
wrapper.setContext({ name: 'bar' });
expect(wrapper.text()).to.equal('bar');
wrapper.setContext({ name: 'baz' });
expect(wrapper.text()).to.equal('baz');
```
#### Common Gotchas
- `.setContext()` can only be used on a wrapper that was initially created with a call to `shallow()`
that includes a `context` specified in the options argument.
- The root component you are rendering must have a `contextTypes` static property.
#### Related Methods
- [`.setState(state[, callback]) => Self`](setState.md)
- [`.setProps(props[, callback]) => Self`](setProps.md)
================================================
FILE: docs/api/ShallowWrapper/setProps.md
================================================
# `.setProps(nextProps[, callback]) => Self`
A method that sets the props of the root component, and re-renders. Useful for when you are
wanting to test how the component behaves over time with changing props. Calling this, for
instance, will call the `componentWillReceiveProps` lifecycle method.
Similar to `setState`, this method accepts a props object and will merge it in with the already
existing props.
NOTE: can only be called on a wrapper instance that is also the root instance.
#### Arguments
1. `nextProps` (`Object`): An object containing new props to merge in with the current props
2. `callback` (`Function` [optional]): If provided, the callback function will be executed once setProps has completed
#### Returns
`ShallowWrapper`: Returns itself.
#### Example
```jsx
import React from 'react';
import PropTypes from 'prop-types';
function Foo({ name }) {
return (
);
}
Foo.propTypes = {
name: PropTypes.string.isRequired,
};
```
```jsx
const wrapper = shallow();
expect(wrapper.find('.foo')).to.have.lengthOf(1);
expect(wrapper.find('.bar')).to.have.lengthOf(0);
wrapper.setProps({ name: 'bar' });
expect(wrapper.find('.foo')).to.have.lengthOf(0);
expect(wrapper.find('.bar')).to.have.lengthOf(1);
```
```jsx
import sinon from 'sinon';
const spy = sinon.spy(MyComponent.prototype, 'componentWillReceiveProps');
const wrapper = shallow();
expect(spy).to.have.property('callCount', 0);
wrapper.setProps({ foo: 'foo' });
expect(spy).to.have.property('callCount', 1);
```
#### Related Methods
- [`.setState(state) => Self`](setState.md)
- [`.setContext(context) => Self`](setContext.md)
================================================
FILE: docs/api/ShallowWrapper/setState.md
================================================
# `.setState(nextState[, callback]) => Self`
A method to invoke `setState()` on the root component instance, similar to how you might in the
methods of the component, and re-renders. This method is useful for testing your component
in hard-to-achieve states, however should be used sparingly. If possible, you should utilize
your component's external API (which is often accessible via [`.instance()`](instance.md)) in order
to get it into whatever state you want to test, in order to be as accurate of a test as possible.
This is not always practical, however.
NOTE: can only be called on a wrapper instance that is also the root instance.
#### Arguments
1. `nextState` (`Object`): An object containing new state to merge in with the current state
2. `callback` (`Function` [optional]): If provided, the callback function will be executed once setState has completed
#### Returns
`ShallowWrapper`: Returns itself.
#### Example
```jsx
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = { name: 'foo' };
}
render() {
const { name } = this.state;
return (
);
}
}
```
```jsx
const wrapper = shallow();
expect(wrapper.find('.foo')).to.have.lengthOf(1);
expect(wrapper.find('.bar')).to.have.lengthOf(0);
wrapper.setState({ name: 'bar' });
expect(wrapper.find('.foo')).to.have.lengthOf(0);
expect(wrapper.find('.bar')).to.have.lengthOf(1);
```
#### Related Methods
- [`.setProps(props[, callback]) => Self`](setProps.md)
- [`.setContext(context) => Self`](setContext.md)
================================================
FILE: docs/api/ShallowWrapper/shallow.md
================================================
# `.shallow([options]) => ShallowWrapper`
Shallow renders the root node and returns a shallow wrapper around it.
It must be a single-node wrapper.
#### Arguments
1. `options` (`Object` [optional]):
- `options.context`: (`Object` [optional]): Context to be passed into the component
- `options.disableLifecycleMethods`: (`Boolean` [optional]): If set to true, `componentDidMount`
is not called on the component, and `componentDidUpdate` is not called after
[`setProps`](ShallowWrapper/setProps.md) and [`setContext`](ShallowWrapper/setContext.md). Default to `false`.
#### Returns
`ShallowWrapper`: A new wrapper that wraps the node after it's been shallow rendered.
#### Examples
```jsx
function Bar() {
return (
);
}
```
```jsx
function Foo() {
return (
);
}
```
```jsx
const wrapper = shallow();
expect(wrapper.find('.in-bar')).to.have.lengthOf(0);
expect(wrapper.find(Bar)).to.have.lengthOf(1);
expect(wrapper.find(Bar).shallow().find('.in-bar')).to.have.lengthOf(1);
```
================================================
FILE: docs/api/ShallowWrapper/simulate.md
================================================
# `.simulate(event[, ...args]) => Self`
Simulate events on the root node in the wrapper. It must be a single-node wrapper.
#### Arguments
1. `event` (`String`): The event name to be simulated
2. `...args` (`Any` [optional]): A mock event object that will get passed through to the event handlers.
#### Returns
`ShallowWrapper`: Returns itself.
#### Example `class component`
```jsx
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
const { count } = this.state;
return (
);
}
Foo.propTypes = {
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
onChange: PropTypes.func.isRequired,
};
const testState = { width: 10, height: 20 };
const wrapper = shallow((
{
testState[e.target.name] = e.target.value;
}}
/>
));
expect(wrapper.find('input').at(0).prop('value')).toEqual(10);
expect(wrapper.find('input').at(1).prop('value')).toEqual(20);
wrapper.find('input').at(0).simulate('change', { target: { name: 'width', value: 50 } });
wrapper.find('input').at(1).simulate('change', { target: { name: 'height', value: 70 } });
expect(testState.width).toEqual(50);
expect(testState.height).toEqual(70);
```
#### Common Gotchas
- Currently, event simulation for the shallow renderer does not propagate as one would normally
expect in a real environment. As a result, one must call `.simulate()` on the actual node that has
the event handler set.
- Even though the name would imply this simulates an actual event, `.simulate()` will in fact
target the component's prop based on the event you give it. For example, `.simulate('click')` will
actually get the `onClick` prop and call it.
- As noted in the function signature above passing a mock event is optional. Keep in mind that if the code you are testing uses the event for something like, calling `event.preventDefault()` or accessing any of its properties you must provide a mock event object with the properties your code requires.
================================================
FILE: docs/api/ShallowWrapper/simulateError.md
================================================
# `.simulateError(error) => Self`
Simulate a component throwing an error as part of its rendering lifecycle.
This is particularly useful in combination with React 16 error boundaries (ie, the `componentDidCatch` and `static getDerivedStateFromError` lifecycle methods).
#### Arguments
1. `error` (`Any`): The error to throw.
#### Returns
`ShallowWrapper`: Returns itself.
#### Example
```jsx
function Something() {
// this is just a placeholder
return null;
}
class ErrorBoundary extends React.Component {
static getDerivedStateFromError(error) {
return {
hasError: true,
};
}
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
const { spy } = this.props;
spy(error, info);
}
render() {
const { children } = this.props;
const { hasError } = this.state;
return (
{hasError ? 'Error' : children}
);
}
}
ErrorBoundary.propTypes = {
children: PropTypes.node.isRequired,
spy: PropTypes.func.isRequired,
};
const spy = sinon.spy();
const wrapper = shallow();
const error = new Error('hi!');
wrapper.find(Something).simulateError(error);
expect(wrapper.state()).to.have.property('hasError', true);
expect(spy).to.have.property('callCount', 1);
expect(spy.args).to.deep.equal([
error,
{
componentStack: `
in Something (created by ErrorBoundary)
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent`,
},
]);
```
================================================
FILE: docs/api/ShallowWrapper/slice.md
================================================
# `.slice([begin[, end]]) => ShallowWrapper`
Returns a new wrapper with a subset of the nodes of the original wrapper, according to the rules of `Array#slice`.
#### Arguments
1. `begin` (`Number` [optional]): Index from which to slice (defaults to `0`). If negative, this is treated as `length+begin`.
1. `end` (`Number` [optional]): Index at which to end slicing (defaults to `length`). If negative, this is treated as `length+end`.
#### Returns
`ShallowWrapper`: A new wrapper with the subset of nodes specified.
#### Examples
```jsx
const wrapper = shallow((
));
expect(wrapper.find('.foo').slice(1, 2)).to.have.lengthOf(1);
expect(wrapper.find('.foo').slice(1, 2).at(0).hasClass('bar')).to.equal(true);
```
================================================
FILE: docs/api/ShallowWrapper/some.md
================================================
# `.some(selector) => Boolean`
Returns whether or not any of the nodes in the wrapper match the provided selector.
#### Arguments
1. `selector` ([`EnzymeSelector`](../selector.md)): The selector to match.
#### Returns
`Boolean`: True if at least one of the nodes in the current wrapper matched the provided selector.
#### Examples
```jsx
const wrapper = shallow((
));
expect(wrapper.find('.foo').some('.qoo')).to.equal(true);
expect(wrapper.find('.foo').some('.foo')).to.equal(true);
expect(wrapper.find('.foo').some('.bar')).to.equal(false);
```
#### Related Methods
- [`.someWhere(predicate) => Boolean`](someWhere.md)
- [`.every(selector) => Boolean`](every.md)
- [`.everyWhere(predicate) => Boolean`](everyWhere.md)
================================================
FILE: docs/api/ShallowWrapper/someWhere.md
================================================
# `.someWhere(fn) => Boolean`
Returns whether or not any of the nodes in the wrapper pass the provided predicate function.
#### Arguments
1. `predicate` (`ShallowWrapper => Boolean`): A predicate function to match the nodes.
#### Returns
`Boolean`: True if at least one of the nodes in the current wrapper passed the predicate function.
#### Example
```jsx
const wrapper = shallow((
));
expect(wrapper.find('.foo').someWhere((n) => n.hasClass('qoo'))).to.equal(true);
expect(wrapper.find('.foo').someWhere((n) => n.hasClass('foo'))).to.equal(true);
expect(wrapper.find('.foo').someWhere((n) => n.hasClass('bar'))).to.equal(false);
```
#### Related Methods
- [`.some(selector) => Boolean`](some.md)
- [`.every(selector) => Boolean`](every.md)
- [`.everyWhere(predicate) => Boolean`](everyWhere.md)
================================================
FILE: docs/api/ShallowWrapper/state.md
================================================
# `.state([key]) => Any`
Returns the state hash for the root node of the wrapper. Optionally pass in a prop name and it
will return just that value.
#### Arguments
1. `key` (`String` [optional]): If provided, the return value will be the `this.state[key]` of the
root component instance.
#### Example
```jsx
const wrapper = shallow();
expect(wrapper.state().foo).to.equal(10);
expect(wrapper.state('foo')).to.equal(10);
```
#### Related Methods
- [`.props() => Object`](props.md)
- [`.prop(key) => Any`](prop.md)
- [`.context([key]) => Any`](context.md)
================================================
FILE: docs/api/ShallowWrapper/tap.md
================================================
# `.tap(intercepter) => Self`
Invokes intercepter and returns itself. intercepter is called with itself.
This is helpful when debugging nodes in method chains.
#### Arguments
1. `intercepter` (`Self`): the current ShallowWrapper instance.
#### Returns
`Self`: the current ShallowWrapper instance.
#### Example
```jsx
const result = shallow((
xxx
yyy
zzz
)).find('li')
.tap((n) => console.log(n.debug()))
.map((n) => n.text());
```
================================================
FILE: docs/api/ShallowWrapper/text.md
================================================
# `.text() => String`
Returns a string of the rendered text of the current render tree. This function should be
looked at with skepticism if being used to test what the actual HTML output of the component
will be. If that is what you would like to test, use enzyme's `render` function instead.
Note: can only be called on a wrapper of a single node.
#### Returns
`String`: The resulting string
#### Examples
```jsx
const wrapper = shallow(
);
expect(wrapper.text()).to.equal('important');
```
#### Related Methods
[`.html() => String`](html.md)
================================================
FILE: docs/api/ShallowWrapper/type.md
================================================
# `.type() => String | Function | null`
Returns the type of the only node of this wrapper.
If it's a React component, this will be the component constructor.
If it's a native DOM node, it will be a string with the tag name.
If it's `null`, it will be `null`. It must be a single-node wrapper.
#### Returns
`String | Function | null`: The type of the node
#### Examples
```jsx
function Foo() {
return ;
}
const wrapper = shallow();
expect(wrapper.type()).to.equal('div');
```
```jsx
function Foo() {
return (
);
}
const wrapper = shallow();
expect(wrapper.find('.btn').type()).to.equal('button');
```
```jsx
function Foo() {
return ;
}
const wrapper = shallow();
expect(wrapper.type()).to.equal(Bar);
```
```jsx
function Null() {
return null;
}
const wrapper = shallow();
expect(wrapper.type()).to.equal(null);
```
================================================
FILE: docs/api/ShallowWrapper/unmount.md
================================================
# `.unmount() => Self`
A method that unmounts the component. This can be used to simulate a component going through
an unmount/mount lifecycle.
#### Returns
`ShallowWrapper`: Returns itself.
#### Example
```jsx
import PropTypes from 'prop-types';
import sinon from 'sinon';
const spy = sinon.spy();
class Foo extends React.Component {
constructor(props) {
super(props);
this.componentWillUnmount = spy;
}
render() {
const { id } = this.props;
return (
{id}
);
}
}
Foo.propTypes = {
id: PropTypes.string.isRequired,
};
const wrapper = shallow();
expect(spy).to.have.property('callCount', 0);
wrapper.unmount();
expect(spy).to.have.property('callCount', 1);
```
================================================
FILE: docs/api/ShallowWrapper/update.md
================================================
# `.update() => Self`
Syncs the enzyme component tree snapshot with the react component tree. Useful to run before checking the render output if something external
may be updating the state of the component somewhere.
NOTE: no matter what instance this is called on, it will always update the root.
NOTE: only updates Enzyme's representation of rendered tree.
NOTE: this does not force a re-render. Use `wrapper.setProps({})` to force a re-render.
#### Returns
`ReactWrapper`: Returns itself.
#### Example
```jsx
class UpdateEnzyme extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
this.increment = this.increment.bind(this);
}
increment() {
const { count } = this.state;
this.setState({ count: count + 1 });
}
render() {
const { count } = this.state;
return ;
}
}
```
```jsx
const wrapper = shallow();
expect(wrapper.find('button.increment').text()).to.equal('0');
wrapper.instance().increment();
// Update Enzyme's view of output
wrapper.update();
expect(wrapper.find('button.increment').text()).to.equal('1');
```
================================================
FILE: docs/api/mount.md
================================================
# Full Rendering API (`mount(...)`)
Full DOM rendering is ideal for use cases where you have components that may interact with DOM APIs or need to test components that are wrapped in higher order components.
Full DOM rendering requires that a full DOM API be available at the global scope. This means that
it must be run in an environment that at least “looks like” a browser environment. If you do not
want to run your tests inside of a browser, the recommended approach to using `mount` is to depend
on a library called [jsdom](https://github.com/jsdom/jsdom) which is essentially a headless browser
implemented completely in JS.
**Note**: unlike shallow or static rendering, full rendering actually mounts the component in the DOM, which means that tests can affect each other if they are all using the same DOM. Keep that in mind while writing your tests and, if necessary, use [`.unmount()`](ReactWrapper/unmount.md) or something similar as cleanup.
```jsx
import { mount } from 'enzyme';
import sinon from 'sinon';
import Foo from './Foo';
describe('', () => {
it('calls componentDidMount', () => {
sinon.spy(Foo.prototype, 'componentDidMount');
const wrapper = mount();
expect(Foo.prototype.componentDidMount).to.have.property('callCount', 1);
});
it('allows us to set props', () => {
const wrapper = mount();
expect(wrapper.props().bar).to.equal('baz');
wrapper.setProps({ bar: 'foo' });
expect(wrapper.props().bar).to.equal('foo');
});
it('simulates click events', () => {
const onButtonClick = sinon.spy();
const wrapper = mount((
));
wrapper.find('button').simulate('click');
expect(onButtonClick).to.have.property('callCount', 1);
});
});
```
## `mount(node[, options]) => ReactWrapper`
#### Arguments
1. `node` (`ReactElement`): The node to render
2. `options` (`Object` [optional]):
- `options.context`: (`Object` [optional]): Context to be passed into the component
- `options.attachTo`: (`DOMElement` [optional]): DOM Element to attach the component to.
- `options.childContextTypes`: (`Object` [optional]): Merged contextTypes for all children of the wrapper.
- `options.wrappingComponent`: (`ComponentType` [optional]): A component that will render as a parent of the `node`. It can be used to provide context to the `node`, among other things. See the [`getWrappingComponent()` docs](ReactWrapper/getWrappingComponent.md) for an example. **Note**: `wrappingComponent` _must_ render its children.
- `options.wrappingComponentProps`: (`Object` [optional]): Initial props to pass to the `wrappingComponent` if it is specified.
#### Returns
`ReactWrapper`: The wrapper instance around the rendered output.
## ReactWrapper API
#### [`.find(selector) => ReactWrapper`](ReactWrapper/find.md)
Find every node in the render tree that matches the provided selector.
#### [`.findWhere(predicate) => ReactWrapper`](ReactWrapper/findWhere.md)
Find every node in the render tree that returns true for the provided predicate function.
#### [`.filter(selector) => ReactWrapper`](ReactWrapper/filter.md)
Remove nodes in the current wrapper that do not match the provided selector.
#### [`.filterWhere(predicate) => ReactWrapper`](ReactWrapper/filterWhere.md)
Remove nodes in the current wrapper that do not return true for the provided predicate function.
#### [`.hostNodes() => ReactWrapper`](ReactWrapper/hostNodes.md)
Removes nodes that are not host nodes; e.g., this will only return HTML nodes.
#### [`.contains(nodeOrNodes) => Boolean`](ReactWrapper/contains.md)
Returns whether or not a given node or array of nodes exists in the render tree.
#### [`.containsMatchingElement(node) => Boolean`](ReactWrapper/containsMatchingElement.md)
Returns whether or not a given react element exists in the render tree.
#### [`.containsAllMatchingElements(nodes) => Boolean`](ReactWrapper/containsAllMatchingElements.md)
Returns whether or not all the given react elements exist in the render tree.
#### [`.containsAnyMatchingElements(nodes) => Boolean`](ReactWrapper/containsAnyMatchingElements.md)
Returns whether or not one of the given react elements exist in the render tree.
#### [`.equals(node) => Boolean`](ReactWrapper/equals.md)
Returns whether or not the current wrapper root node render tree looks like the one passed in.
#### [`.hasClass(className) => Boolean`](ReactWrapper/hasClass.md)
Returns whether or not the current root node has the given class name or not.
#### [`.is(selector) => Boolean`](ReactWrapper/is.md)
Returns whether or not the current node matches a provided selector.
#### [`.exists([selector]) => Boolean`](ReactWrapper/exists.md)
Returns whether or not the current node exists, or, if given a selector, whether that selector has any matching results.
#### [`.isEmpty() => Boolean`](ReactWrapper/isEmpty.md)
*Deprecated*: Use [`.exists()`](ReactWrapper/exists.md) instead.
#### [`.isEmptyRender() => Boolean`](ReactWrapper/isEmptyRender.md)
Returns whether or not the current component returns a falsy value.
#### [`.not(selector) => ReactWrapper`](ReactWrapper/not.md)
Remove nodes in the current wrapper that match the provided selector. (inverse of `.filter()`)
#### [`.children([selector]) => ReactWrapper`](ReactWrapper/children.md)
Get a wrapper with all of the children nodes of the current wrapper.
#### [`.childAt(index) => ReactWrapper`](ReactWrapper/childAt.md)
Returns a new wrapper with child at the specified index.
#### [`.parents([selector]) => ReactWrapper`](ReactWrapper/parents.md)
Get a wrapper with all of the parents (ancestors) of the current node.
#### [`.parent() => ReactWrapper`](ReactWrapper/parent.md)
Get a wrapper with the direct parent of the current node.
#### [`.closest(selector) => ReactWrapper`](ReactWrapper/closest.md)
Get a wrapper with the first ancestor of the current node to match the provided selector.
#### [`.render() => CheerioWrapper`](ReactWrapper/render.md)
Returns a CheerioWrapper of the current node's subtree.
#### [`.renderProp(key)() => ReactWrapper`](ReactWrapper/renderProp.md)
Returns a wrapper of the node rendered by the provided render prop.
#### [`.text() => String`](ReactWrapper/text.md)
Returns a string representation of the text nodes in the current render tree.
#### [`.html() => String`](ReactWrapper/html.md)
Returns a static HTML rendering of the current node.
#### [`.get(index) => ReactElement`](ReactWrapper/get.md)
Returns the node at the provided index of the current wrapper.
#### [`.getDOMNode() => DOMComponent`](ReactWrapper/getDOMNode.md)
Returns the outer most DOMComponent of the current wrapper.
#### [`.getElement() => ReactElement`](ReactWrapper/getElement.md)
Returns the wrapped ReactElement.
#### [`.getElements() => Array`](ReactWrapper/getElements.md)
Returns the wrapped ReactElements.
#### [`.at(index) => ReactWrapper`](ReactWrapper/at.md)
Returns a wrapper of the node at the provided index of the current wrapper.
#### [`.first() => ReactWrapper`](ReactWrapper/first.md)
Returns a wrapper of the first node of the current wrapper.
#### [`.last() => ReactWrapper`](ReactWrapper/last.md)
Returns a wrapper of the last node of the current wrapper.
#### [`.state([key]) => Any`](ReactWrapper/state.md)
Returns the state of the root component.
#### [`.context([key]) => Any`](ReactWrapper/context.md)
Returns the context of the root component.
#### [`.props() => Object`](ReactWrapper/props.md)
Returns the props of the root component.
#### [`.prop(key) => Any`](ReactWrapper/prop.md)
Returns the named prop of the root component.
#### [`.invoke(propName)(...args) => Any`](ReactWrapper/invoke.md)
Invokes a prop function on the current node and returns the function's return value.
#### [`.key() => String`](ReactWrapper/key.md)
Returns the key of the root component.
#### [`.simulate(event[, mock]) => ReactWrapper`](ReactWrapper/simulate.md)
Simulates an event on the current node.
#### [`.setState(nextState) => ReactWrapper`](ReactWrapper/setState.md)
Manually sets state of the root component.
#### [`.setProps(nextProps[, callback]) => ReactWrapper`](ReactWrapper/setProps.md)
Manually sets props of the root component.
#### [`.setContext(context) => ReactWrapper`](ReactWrapper/setContext.md)
Manually sets context of the root component.
#### [`.instance() => ReactComponent|DOMComponent`](ReactWrapper/instance.md)
Returns the wrapper's underlying instance.
#### [`.getWrappingComponent() => ReactWrapper`](ReactWrapper/getWrappingComponent.md)
Returns a wrapper representing the `wrappingComponent`, if one was passed.
#### [`.unmount() => ReactWrapper`](ReactWrapper/unmount.md)
A method that un-mounts the component.
#### [`.mount() => ReactWrapper`](ReactWrapper/mount.md)
A method that re-mounts the component.
#### [`.update() => ReactWrapper`](ReactWrapper/update.md)
Syncs the enzyme component tree snapshot with the react component tree.
#### [`.debug() => String`](ReactWrapper/debug.md)
Returns a string representation of the current render tree for debugging purposes.
#### [`.type() => String|Function`](ReactWrapper/type.md)
Returns the type of the current node of the wrapper.
#### [`.name() => String`](ReactWrapper/name.md)
Returns the name of the current node of the wrapper.
#### [`.forEach(fn) => ReactWrapper`](ReactWrapper/forEach.md)
Iterates through each node of the current wrapper and executes the provided function
#### [`.map(fn) => Array`](ReactWrapper/map.md)
Maps the current array of nodes to another array.
#### [`.matchesElement(node) => Boolean`](ReactWrapper/matchesElement.md)
Returns whether or not a given react element matches the current render tree.
#### [`.reduce(fn[, initialValue]) => Any`](ReactWrapper/reduce.md)
Reduces the current array of nodes to a value
#### [`.reduceRight(fn[, initialValue]) => Any`](ReactWrapper/reduceRight.md)
Reduces the current array of nodes to a value, from right to left.
#### [`.slice([begin[, end]]) => ReactWrapper`](ReactWrapper/slice.md)
Returns a new wrapper with a subset of the nodes of the original wrapper, according to the rules of `Array#slice`.
#### [`.tap(intercepter) => Self`](ReactWrapper/tap.md)
Taps into the wrapper method chain. Helpful for debugging.
#### [`.some(selector) => Boolean`](ReactWrapper/some.md)
Returns whether or not any of the nodes in the wrapper match the provided selector.
#### [`.someWhere(predicate) => Boolean`](ReactWrapper/someWhere.md)
Returns whether or not any of the nodes in the wrapper pass the provided predicate function.
#### [`.every(selector) => Boolean`](ReactWrapper/every.md)
Returns whether or not all of the nodes in the wrapper match the provided selector.
#### [`.everyWhere(predicate) => Boolean`](ReactWrapper/everyWhere.md)
Returns whether or not all of the nodes in the wrapper pass the provided predicate function.
#### [`.ref(refName) => ReactComponent | HTMLElement`](ReactWrapper/ref.md)
Returns the node that matches the provided reference name.
#### [`.detach() => void`](ReactWrapper/detach.md)
Unmount the component from the DOM node it's attached to.
================================================
FILE: docs/api/render.md
================================================
# Static Rendering API
Use enzyme's `render` function to generate HTML from your React tree, and analyze the resulting HTML structure.
`render` returns a wrapper very similar to the other renderers in enzyme, [`mount`](mount.md) and
[`shallow`](shallow.md); however, `render` uses a third party HTML parsing and traversal library
[Cheerio](https://cheerio.js.org). We believe that Cheerio handles parsing and
traversing HTML extremely well, and duplicating this functionality ourselves would be a
disservice.
For the purposes of this documentation, we will refer to Cheerio's constructor as
`CheerioWrapper`, which is to say that it is analogous to our `ReactWrapper` and `ShallowWrapper`
constructors. You can reference the [Cheerio API docs](https://github.com/cheeriojs/cheerio#api) for methods available on a `CheerioWrapper` instance.
### Example Usage
```jsx
import React from 'react';
import { render } from 'enzyme';
import PropTypes from 'prop-types';
describe('', () => {
it('renders three `.foo-bar`s', () => {
const wrapper = render();
expect(wrapper.find('.foo-bar')).to.have.lengthOf(3);
});
it('rendered the title', () => {
const wrapper = render();
expect(wrapper.text()).to.contain('unique');
});
it('renders a div', () => {
const wrapper = render();
expect(wrapper.html()).to.contain('div');
});
it('can pass in context', () => {
function SimpleComponent(props, context) {
const { name } = context;
return
{name}
;
}
SimpleComponent.contextTypes = {
name: PropTypes.string,
};
const context = { name: 'foo' };
const wrapper = render(, { context });
expect(wrapper.text()).to.equal('foo');
});
});
```
================================================
FILE: docs/api/selector.md
================================================
# enzyme Selectors
Many methods in enzyme’s API accept a *selector* as an argument.
You can select several different ways:
### 1. A Valid CSS Selector
enzyme supports a subset of valid CSS selectors to find nodes inside a render tree. Support is as
follows:
- class syntax (`.foo`, `.foo-bar`, etc.)
- element tag name syntax (`input`, `div`, `span`, etc.)
- id syntax (`#foo`, `#foo-bar`, etc.)
- attribute syntax (`[href="foo"]`, `[type="text"]`, and the other attribute selectors listed [here](https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Attribute_selectors).)
- universal syntax (`*`)
- React component name and props (`Button`, `Button[type="submit"]`, etc) - however, please note that it is strongly encouraged to find by component constructor/function and not by display name.
The attribute syntax also works by value, rather than by string. Strings, numbers, and boolean property values are supported. Example:
```js
const wrapper = mount((
));
```
The selector `[anum=3]` will select the first but not the second, because there's no quotes surrounding the 3. The selector `[anum="3"]` will select the second, because it's explicitly looking for a string because of the quotes surrounding 3. The same goes for the boolean; [abool=false] will select the first but not the second, etc.
Further, enzyme supports combining any of those supported syntaxes together, as with CSS:
```css
div.foo.bar
input#input-name
a[href="foo"]
.foo .bar
.foo > .bar
.foo + .bar
.foo ~ .bar
.foo input
```
**React Key and Ref Props**
While in most cases, any React prop can be used, there are exceptions.
The `key` and `ref` props will never work; React uses these props internally.
**Want more CSS support?**
PRs implementing more support for CSS selectors will be accepted and is an area of development for
enzyme that will likely be focused on in the future.
### 2. A React Component Constructor
enzyme allows you to find React components based on their constructor. You can pass in the reference to
the component’s constructor.
Of course, this kind of selector only checks the component type; it ignores props and children.
```jsx
function MyComponent() {
return ;
}
// find instances of MyComponent
const myComponents = wrapper.find(MyComponent);
```
### 3. A React Component’s displayName
enzyme allows you to find components based on a component’s `displayName`. If a component exists
in a render tree where its `displayName` is set and has its first character as a capital letter,
you can use a string to find it:
```jsx
function MyComponent() {
return ;
}
MyComponent.displayName = 'My Component';
// find instances of MyComponent
const myComponents = wrapper.find('My Component');
```
NOTE: This will *only* work if the selector (and thus the component’s `displayName`) is a string
starting with a capital letter. Strings starting with lower case letters will be assumed to be a CSS
selector (therefore a tag name).
Selecting a HOC-wrapped component, or a component with a custom `displayName`, even with lowercase letters (for example, `withHOC(MyComponent)`) will work as well.
### 4. Object Property Selector
enzyme allows you to find components and nodes based on a subset of their properties:
```jsx
const wrapper = mount((
));
wrapper.find({ foo: 3 });
wrapper.find({ bar: false });
wrapper.find({ title: 'baz' });
```
**Undefined Properties**
Undefined properties are not allowed in the object property selector and will cause an error:
```jsx
wrapper.find({ foo: 3, bar: undefined });
// => TypeError: Enzyme::Props can't have 'undefined' values. Try using 'findWhere()' instead.
```
If you have to search by `undefined` property value, use [`.findWhere()`](ShallowWrapper/findWhere.md).
================================================
FILE: docs/api/shallow.md
================================================
# Shallow Rendering API
Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure
that your tests aren't indirectly asserting on behavior of child components.
As of Enzyme v3, the `shallow` API does call React lifecycle methods such as `componentDidMount` and `componentDidUpdate`. You can read more about this in the [version 3 migration guide](../guides/migration-from-2-to-3.md#lifecycle-methods).
```jsx
import { shallow } from 'enzyme';
import sinon from 'sinon';
import Foo from './Foo';
describe('', () => {
it('renders three components', () => {
const wrapper = shallow();
expect(wrapper.find(Foo)).to.have.lengthOf(3);
});
it('renders an `.icon-star`', () => {
const wrapper = shallow();
expect(wrapper.find('.icon-star')).to.have.lengthOf(1);
});
it('renders children when passed in', () => {
const wrapper = shallow((
));
expect(wrapper.contains()).to.equal(true);
});
it('simulates click events', () => {
const onButtonClick = sinon.spy();
const wrapper = shallow();
wrapper.find('button').simulate('click');
expect(onButtonClick).to.have.property('callCount', 1);
});
});
```
## `shallow(node[, options]) => ShallowWrapper`
#### Arguments
1. `node` (`ReactElement`): The node to render
2. `options` (`Object` [optional]):
- `options.context`: (`Object` [optional]): Context to be passed into the component
- `options.disableLifecycleMethods`: (`Boolean` [optional]): If set to true, `componentDidMount`
is not called on the component, and `componentDidUpdate` is not called after
[`setProps`](ShallowWrapper/setProps.md) and [`setContext`](ShallowWrapper/setContext.md). Default to `false`.
- `options.wrappingComponent`: (`ComponentType` [optional]): A component that will render as a parent of the `node`. It can be used to provide context to the `node`, among other things. See the [`getWrappingComponent()` docs](ShallowWrapper/getWrappingComponent.md) for an example. **Note**: `wrappingComponent` _must_ render its children.
- `options.wrappingComponentProps`: (`Object` [optional]): Initial props to pass to the `wrappingComponent` if it is specified.
- `options.suspenseFallback`: (`Boolean` [optional]): If set to true, when rendering `Suspense` enzyme will replace all the lazy components in children with `fallback` element prop. Otherwise it won't handle fallback of lazy component. Default to `true`. Note: not supported in React < 16.6.
#### Returns
`ShallowWrapper`: The wrapper instance around the rendered output.
## ShallowWrapper API
#### [`.find(selector) => ShallowWrapper`](ShallowWrapper/find.md)
Find every node in the render tree that matches the provided selector.
#### [`.findWhere(predicate) => ShallowWrapper`](ShallowWrapper/findWhere.md)
Find every node in the render tree that returns true for the provided predicate function.
#### [`.filter(selector) => ShallowWrapper`](ShallowWrapper/filter.md)
Remove nodes in the current wrapper that do not match the provided selector.
#### [`.filterWhere(predicate) => ShallowWrapper`](ShallowWrapper/filterWhere.md)
Remove nodes in the current wrapper that do not return true for the provided predicate function.
#### [`.hostNodes() => ShallowWrapper`](ShallowWrapper/hostNodes.md)
Removes nodes that are not host nodes; e.g., this will only return HTML nodes.
#### [`.contains(nodeOrNodes) => Boolean`](ShallowWrapper/contains.md)
Returns whether or not a given node or array of nodes is somewhere in the render tree.
#### [`.containsMatchingElement(node) => Boolean`](ShallowWrapper/containsMatchingElement.md)
Returns whether or not a given react element exists in the shallow render tree.
#### [`.containsAllMatchingElements(nodes) => Boolean`](ShallowWrapper/containsAllMatchingElements.md)
Returns whether or not all the given react elements exist in the shallow render tree.
#### [`.containsAnyMatchingElements(nodes) => Boolean`](ShallowWrapper/containsAnyMatchingElements.md)
Returns whether or not one of the given react elements exists in the shallow render tree.
#### [`.equals(node) => Boolean`](ShallowWrapper/equals.md)
Returns whether or not the current render tree is equal to the given node, based on the expected value.
#### [`.matchesElement(node) => Boolean`](ShallowWrapper/matchesElement.md)
Returns whether or not a given react element matches the shallow render tree.
#### [`.hasClass(className) => Boolean`](ShallowWrapper/hasClass.md)
Returns whether or not the current node has the given class name or not.
#### [`.is(selector) => Boolean`](ShallowWrapper/is.md)
Returns whether or not the current node matches a provided selector.
#### [`.exists([selector]) => Boolean`](ShallowWrapper/exists.md)
Returns whether or not the current node exists, or, if given a selector, whether that selector has any matching results.
#### [`.isEmpty() => Boolean`](ShallowWrapper/isEmpty.md)
*Deprecated*: Use [`.exists()`](ShallowWrapper/exists.md) instead.
#### [`.isEmptyRender() => Boolean`](ShallowWrapper/isEmptyRender.md)
Returns whether or not the current component returns a falsy value.
#### [`.not(selector) => ShallowWrapper`](ShallowWrapper/not.md)
Remove nodes in the current wrapper that match the provided selector. (inverse of `.filter()`)
#### [`.children([selector]) => ShallowWrapper`](ShallowWrapper/children.md)
Get a wrapper with all of the children nodes of the current wrapper.
#### [`.childAt(index) => ShallowWrapper`](ShallowWrapper/childAt.md)
Returns a new wrapper with child at the specified index.
#### [`.parents([selector]) => ShallowWrapper`](ShallowWrapper/parents.md)
Get a wrapper with all of the parents (ancestors) of the current node.
#### [`.parent() => ShallowWrapper`](ShallowWrapper/parent.md)
Get a wrapper with the direct parent of the current node.
#### [`.closest(selector) => ShallowWrapper`](ShallowWrapper/closest.md)
Get a wrapper with the first ancestor of the current node to match the provided selector.
#### [`.shallow([options]) => ShallowWrapper`](ShallowWrapper/shallow.md)
Shallow renders the current node and returns a shallow wrapper around it.
#### [`.render() => CheerioWrapper`](ShallowWrapper/render.md)
Returns a CheerioWrapper of the current node's subtree.
#### [`.renderProp(key)() => ShallowWrapper`](ShallowWrapper/renderProp.md)
Returns a wrapper of the node rendered by the provided render prop.
#### [`.unmount() => ShallowWrapper`](ShallowWrapper/unmount.md)
A method that un-mounts the component.
#### [`.text() => String`](ShallowWrapper/text.md)
Returns a string representation of the text nodes in the current render tree.
#### [`.html() => String`](ShallowWrapper/html.md)
Returns a static HTML rendering of the current node.
#### [`.get(index) => ReactElement`](ShallowWrapper/get.md)
Returns the node at the provided index of the current wrapper.
#### [`.getElement() => ReactElement`](ShallowWrapper/getElement.md)
Returns the wrapped ReactElement.
#### [`.getElements() => Array`](ShallowWrapper/getElements.md)
Returns the wrapped ReactElements.
#### [`.at(index) => ShallowWrapper`](ShallowWrapper/at.md)
Returns a wrapper of the node at the provided index of the current wrapper.
#### [`.first() => ShallowWrapper`](ShallowWrapper/first.md)
Returns a wrapper of the first node of the current wrapper.
#### [`.last() => ShallowWrapper`](ShallowWrapper/last.md)
Returns a wrapper of the last node of the current wrapper.
#### [`.state([key]) => Any`](ShallowWrapper/state.md)
Returns the state of the root component.
#### [`.context([key]) => Any`](ShallowWrapper/context.md)
Returns the context of the root component.
#### [`.props() => Object`](ShallowWrapper/props.md)
Returns the props of the current node.
#### [`.prop(key) => Any`](ShallowWrapper/prop.md)
Returns the named prop of the current node.
#### [`.key() => String`](ShallowWrapper/key.md)
Returns the key of the current node.
#### [`.invoke(propName)(...args) => Any`](ShallowWrapper/invoke.md)
Invokes a prop function on the current node and returns the function's return value.
#### [`.simulate(event[, data]) => ShallowWrapper`](ShallowWrapper/simulate.md)
Simulates an event on the current node.
#### [`.setState(nextState) => ShallowWrapper`](ShallowWrapper/setState.md)
Manually sets state of the root component.
#### [`.setProps(nextProps[, callback]) => ShallowWrapper`](ShallowWrapper/setProps.md)
Manually sets props of the root component.
#### [`.setContext(context) => ShallowWrapper`](ShallowWrapper/setContext.md)
Manually sets context of the root component.
#### [`.getWrappingComponent() => ShallowWrapper`](ShallowWrapper/getWrappingComponent.md)
Returns a wrapper representing the `wrappingComponent`, if one was passed.
#### [`.instance() => ReactComponent`](ShallowWrapper/instance.md)
Returns the instance of the root component.
#### [`.update() => ShallowWrapper`](ShallowWrapper/update.md)
Syncs the enzyme component tree snapshot with the react component tree.
#### [`.debug() => String`](ShallowWrapper/debug.md)
Returns a string representation of the current shallow render tree for debugging purposes.
#### [`.type() => String|Function|null`](ShallowWrapper/type.md)
Returns the type of the current node of the wrapper.
#### [`.name() => String`](ShallowWrapper/name.md)
Returns the name of the current node of the wrapper.
#### [`.forEach(fn) => ShallowWrapper`](ShallowWrapper/forEach.md)
Iterates through each node of the current wrapper and executes the provided function
#### [`.map(fn) => Array`](ShallowWrapper/map.md)
Maps the current array of nodes to another array.
#### [`.reduce(fn[, initialValue]) => Any`](ShallowWrapper/reduce.md)
Reduces the current array of nodes to a value
#### [`.reduceRight(fn[, initialValue]) => Any`](ShallowWrapper/reduceRight.md)
Reduces the current array of nodes to a value, from right to left.
#### [`.slice([begin[, end]]) => ShallowWrapper`](ShallowWrapper/slice.md)
Returns a new wrapper with a subset of the nodes of the original wrapper, according to the rules of `Array#slice`.
#### [`.tap(intercepter) => Self`](ShallowWrapper/tap.md)
Taps into the wrapper method chain. Helpful for debugging.
#### [`.some(selector) => Boolean`](ShallowWrapper/some.md)
Returns whether or not any of the nodes in the wrapper match the provided selector.
#### [`.someWhere(predicate) => Boolean`](ShallowWrapper/someWhere.md)
Returns whether or not any of the nodes in the wrapper pass the provided predicate function.
#### [`.every(selector) => Boolean`](ShallowWrapper/every.md)
Returns whether or not all of the nodes in the wrapper match the provided selector.
#### [`.everyWhere(predicate) => Boolean`](ShallowWrapper/everyWhere.md)
Returns whether or not all of the nodes in the wrapper pass the provided predicate function.
#### [`.dive([options]) => ShallowWrapper`](ShallowWrapper/dive.md)
Shallow render the one non-DOM child of the current wrapper, and return a wrapper around the result.
================================================
FILE: docs/common-issues.md
================================================
# Common Issues
This list aims to be comprehensive. If you find an issue that has been frequently brought up in GitHub *Issues* that is not here, please open a PR to add it.
### Query Selector fails
###### Reason
This could be due to a regression, or the feature is not yet implemented. If you are wanting to use a
certain query syntax, make sure it is implemented first before raising an issue. Here is the list of
selectors we currently support: https://github.com/enzymejs/enzyme/blob/master/docs/api/selector.md
### Nested component may not be updated after wrapper updates
Assume we have a simple component with an `` and a ``);
});
it('shows nested portal children in debug tree', () => {
const Bar = () => null;
const containerDiv = global.document.createElement('div');
const Foo = () => (
);
}
}
class TestZero extends React.Component {
render() {
return ;
}
}
it('returns the outermost DOMComponent of the root wrapper', () => {
const wrapper = mount();
expect(wrapper.getDOMNode()).to.have.property('className', 'outer');
});
it('returns the outermost DOMComponent of the inner div wrapper', () => {
const wrapper = mount();
expect(wrapper.find('.inner').getDOMNode()).to.have.property('className', 'inner');
});
it('throws when wrapping multiple elements', () => {
const wrapper = mount().find('span');
expect(() => wrapper.getDOMNode()).to.throw(
Error,
'Method “getDOMNode” is meant to be run on 1 node. 2 found instead.',
);
});
it('throws when wrapping zero elements', () => {
const wrapper = mount().find('span');
expect(() => wrapper.getDOMNode()).to.throw(
Error,
'Method “getDOMNode” is meant to be run on 1 node. 0 found instead.',
);
});
it('throws when wrapping zero elements', () => {
const wrapper = mount().find('span');
expect(() => wrapper.getDOMNode()).to.throw(
Error,
'Method “getDOMNode” is meant to be run on 1 node. 0 found instead.',
);
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
const SFC = () => (
);
it('returns the outermost DOMComponent of the root wrapper', () => {
const wrapper = mount();
expect(wrapper.getDOMNode()).to.have.property('className', 'outer');
});
it('returns the outermost DOMComponent of the inner div wrapper', () => {
const wrapper = mount();
expect(wrapper.find('.inner').getDOMNode()).to.have.property('className', 'inner');
});
it('throws when wrapping multiple elements', () => {
const wrapper = mount().find('span');
expect(() => wrapper.getDOMNode()).to.throw(
Error,
'Method “getDOMNode” is meant to be run on 1 node. 2 found instead.',
);
});
});
it('lets you read the value of an input', () => {
const wrapper = mount();
const inputNode = wrapper.find('input').getDOMNode();
expect(inputNode.value).to.equal('0');
});
});
describe('.ref(refName)', () => {
class WithoutRef extends React.Component {
render() { return ; }
}
class WithRef extends React.Component {
render() { return ; }
}
class RendersWithRef extends React.Component {
render() { return ; }
}
it('throws when called on not the root', () => {
const wrapper = mount();
const found = wrapper.find(WithRef);
expect(found).to.have.lengthOf(1);
expect(() => found.ref('ref')).to.throw(
Error,
'ReactWrapper::ref(refname) can only be called on the root',
);
});
it('unavailable ref should return undefined', () => {
const wrapper = mount();
const ref = wrapper.ref('not-a-ref');
expect(ref).to.equal(undefined);
});
it('gets a wrapper of the node matching the provided refName', () => {
class Foo extends React.Component {
render() {
return (
FirstSecondThird
);
}
}
const wrapper = mount();
// React 13 and 14 return instances whereas 15+ returns actual DOM nodes. In this case,
// the public API of enzyme is to just return what `this.refs[refName]` would be expected
// to return for the version of react you're using.
if (is('< 15')) {
expect(wrapper.ref('secondRef').getDOMNode().getAttribute('data-amount')).to.equal('4');
expect(wrapper.ref('secondRef').getDOMNode().textContent).to.equal('Second');
} else {
expect(wrapper.ref('secondRef').getAttribute('data-amount')).to.equal('4');
expect(wrapper.ref('secondRef').textContent).to.equal('Second');
}
});
});
describe('.detach', () => {
class Comp extends React.Component {
render() {
return
hi
;
}
}
it('throws on non-root', () => {
const div = global.document.createElement('div');
global.document.body.appendChild(div);
const wrapper = mount(, { attachTo: div });
const span = wrapper.find('span');
expect(span).to.have.lengthOf(1);
expect(() => span.detach()).to.throw(
Error,
'ReactWrapper::detach() can only be called on the root',
);
});
it('throws without the attachTo option', () => {
const wrapper = mount();
expect(() => wrapper.detach()).to.throw(
Error,
'ReactWrapper::detach() can only be called on when the `attachTo` option was passed into `mount()`.',
);
});
});
describe('attachTo option', () => {
it('attaches and stuff', () => {
class Foo extends React.Component {
render() {
return ();
}
}
const div = global.document.createElement('div');
const initialBodyChildren = document.body.childNodes.length;
global.document.body.appendChild(div);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(0);
const wrapper = mount(, { attachTo: div });
expect(wrapper.find('.in-foo')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(1);
wrapper.detach();
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(0);
global.document.body.removeChild(div);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren);
expect(div.childNodes).to.have.lengthOf(0);
});
it('allows for multiple attaches/detaches on same node', () => {
class Foo extends React.Component {
render() {
return ();
}
}
class Bar extends React.Component {
render() {
return ();
}
}
let wrapper;
const div = global.document.createElement('div');
const initialBodyChildren = document.body.childNodes.length;
global.document.body.appendChild(div);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(0);
wrapper = mount(, { attachTo: div });
expect(wrapper.find('.in-foo')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(1);
wrapper.detach();
wrapper = mount(, { attachTo: div });
expect(wrapper.find('.in-bar')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(1);
wrapper.detach();
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(0);
global.document.body.removeChild(div);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren);
expect(div.childNodes).to.have.lengthOf(0);
});
it('will attach to the body successfully', () => {
class Bar extends React.Component {
render() {
return ();
}
}
const wrapper = mount(, { attachTo: document.body });
expect(wrapper.find('.in-bar')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(1);
wrapper.detach();
expect(document.body.childNodes).to.have.lengthOf(0);
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
it('attaches and stuff', () => {
const Foo = () => ;
const div = global.document.createElement('div');
const initialBodyChildren = document.body.childNodes.length;
global.document.body.appendChild(div);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(0);
const wrapper = mount(, { attachTo: div });
expect(wrapper.find('.in-foo')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(1);
wrapper.detach();
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(0);
global.document.body.removeChild(div);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren);
expect(div.childNodes).to.have.lengthOf(0);
});
it('allows for multiple attaches/detaches on same node', () => {
const Foo = () => ;
const Bar = () => ;
let wrapper;
const div = global.document.createElement('div');
const initialBodyChildren = document.body.childNodes.length;
global.document.body.appendChild(div);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(0);
wrapper = mount(, { attachTo: div });
expect(wrapper.find('.in-foo')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(1);
wrapper.detach();
wrapper = mount(, { attachTo: div });
expect(wrapper.find('.in-bar')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(1);
wrapper.detach();
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 1);
expect(div.childNodes).to.have.lengthOf(0);
global.document.body.removeChild(div);
expect(document.body.childNodes).to.have.lengthOf(initialBodyChildren + 0);
expect(div.childNodes).to.have.lengthOf(0);
});
it('will attach to the body successfully', () => {
const Bar = () => ;
const wrapper = mount(, { attachTo: document.body });
expect(wrapper.find('.in-bar')).to.have.lengthOf(1);
expect(document.body.childNodes).to.have.lengthOf(1);
wrapper.detach();
expect(document.body.childNodes).to.have.lengthOf(0);
});
});
});
it('works with class components that return null', () => {
class Foo extends React.Component {
render() {
return null;
}
}
const wrapper = mount();
expect(wrapper).to.have.lengthOf(1);
expect(wrapper.type()).to.equal(Foo);
expect(wrapper.html()).to.equal(null);
const rendered = wrapper.render();
expect(rendered).to.have.lengthOf(0);
expect(rendered.html()).to.equal(null);
});
itIf(is('>= 16'), 'works with class components that return arrays', () => {
class Foo extends React.Component {
render() {
return [, ];
}
}
const wrapper = mount();
expect(wrapper).to.have.lengthOf(1);
expect(wrapper.type()).to.equal(Foo);
expect(wrapper.children()).to.have.lengthOf(2);
expect(wrapper.find('div')).to.have.lengthOf(2);
});
itIf(is('>=15 || ^16.0.0-alpha'), 'works with SFCs that return null', () => {
const Foo = () => null;
const wrapper = mount();
expect(wrapper).to.have.lengthOf(1);
expect(wrapper.type()).to.equal(Foo);
expect(wrapper.html()).to.equal(null);
const rendered = wrapper.render();
expect(rendered).to.have.lengthOf(0);
expect(rendered.html()).to.equal(null);
});
describe('out-of-band state updates', () => {
class Child extends React.Component {
render() {
return ;
}
}
class Test extends React.Component {
componentWillMount() {
this.state = {};
}
safeSetState(newState) {
withSetStateAllowed(() => {
this.setState(newState);
});
}
asyncSetState() {
setImmediate(() => {
this.safeSetState({ showSpan: true });
});
}
callbackSetState() {
this.safeSetState({ showSpan: true });
}
render() {
/* eslint-disable react/destructuring-assignment */
return (
);
/* eslint-enable react/destructuring-assignment */
}
}
// FIXME: figure out why this fails on 15.0 and 15.1
itIf(!is('~15.0 || ~15.1'), 'has updated output after an asynchronous setState', () => {
const wrapper = mount();
wrapper.find('.async-btn').simulate('click');
return new Promise((resolve) => {
setImmediate(() => {
wrapper.update();
resolve();
});
}).then(() => {
expect(wrapper.find('.show-me')).to.have.lengthOf(1);
});
});
it('has updated output after child prop callback invokes setState', () => {
const wrapper = mount();
wrapper.find(Child).props().callback();
wrapper.update();
expect(wrapper.find('.show-me')).to.have.lengthOf(1);
});
});
describe('setState through a props method', () => {
class Child extends React.Component {
render() {
const { onClick } = this.props;
return click;
}
}
// FIXME: figure out why this fails on 15.0 and 15.1
itIf(!is('~15.0 || ~15.1'), 'is able to get the latest state value', () => {
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
onIncrement() {
this.setState({
count: this.state.count + 1, // eslint-disable-line react/destructuring-assignment
});
}
render() {
const { count } = this.state;
return (
this.onIncrement()} />
{count}
);
}
}
const wrapper = mount();
const p = wrapper.find('p');
expect(wrapper.find('p').text()).to.equal('0');
wrapper.find(Child).prop('onClick')();
// TODO: this is a difference between mount and shallow
// this is 1, because the wrapper has updated
expect(p.text()).to.equal('1');
expect(wrapper.find('p').text()).to.equal('1');
});
});
describe('setState through a props method in async', () => {
class Child extends React.Component {
render() {
const { onClick } = this.props;
return click;
}
}
// FIXME: figure out why this fails on 15.0 and 15.1
itIf(!is('~15.0 || ~15.1'), 'is able to get the latest state value', () => {
let App;
const promise = new Promise((resolve) => {
App = class extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
onIncrement() {
setTimeout(() => {
this.setState({
count: this.state.count + 1, // eslint-disable-line react/destructuring-assignment
}, resolve);
});
}
render() {
const { count } = this.state;
return (
);
SimpleComponent.contextTypes = { name: PropTypes.string };
const wrapper = shallow(, { context });
expect(() => wrapper.context()).to.throw(
Error,
'ShallowWrapper::context() can only be called on wrapped nodes that have a non-null instance',
);
expect(() => wrapper.context('name')).to.throw(
Error,
'ShallowWrapper::context() can only be called on wrapped nodes that have a non-null instance',
);
});
});
describe('getChildContext()', () => {
class FooProvider extends React.Component {
getChildContext() {
const { value } = this.props;
return { foo: value };
}
render() {
const { children } = this.props;
return children;
}
}
FooProvider.childContextTypes = {
foo: PropTypes.string,
};
class BarProvider extends React.Component {
constructor(...args) {
super(...args);
this.state = { value: 'love' };
}
getChildContext() {
const { value } = this.state;
return { bar: value };
}
render() {
const { children } = this.props;
return children;
}
}
BarProvider.childContextTypes = {
bar: PropTypes.string,
};
class FooBarBazConsumer extends React.Component {
render() {
return ;
}
}
FooBarBazConsumer.contextTypes = {
foo: PropTypes.string,
bar: PropTypes.string,
baz: PropTypes.string,
};
class TestComponent extends React.Component {
render() {
return (
);
}
}
let fooProviderSpy;
let barProviderSpy;
beforeEach(() => {
fooProviderSpy = sinon.spy(FooProvider.prototype, 'getChildContext');
barProviderSpy = sinon.spy(BarProvider.prototype, 'getChildContext');
});
afterEach(() => {
fooProviderSpy.restore();
barProviderSpy.restore();
});
describeIf(is('<= 0.13'), 'owner-based context', () => {
it('is not implemented', () => {
const wrapper = shallow(, { context: { baz: 'enzyme' } });
const fooProvider = wrapper.find(FooProvider).dive();
const barProvider = fooProvider.find(BarProvider).dive();
const consumer = barProvider.find(FooBarBazConsumer).dive();
const expectedContext = { baz: 'enzyme', foo: undefined, bar: undefined };
expect(consumer.context()).to.eql(expectedContext);
});
});
describeIf(is('>= 0.14'), 'parent-based context', () => {
const adapter = getAdapter();
const {
createShallowRenderer: realCreateShallowRenderer,
options: realAdapterOptions,
} = adapter;
wrap()
.withOverride(() => adapter, 'options', () => {
const {
legacyContextMode, // omit legacyContextMode
lifecycles: {
getChildContext, // omit getChildContext
...lifecycles
},
...options
} = realAdapterOptions;
return {
...options,
lifecycles,
};
})
.describe('with older adapters', () => {
it('still supports the context option', () => {
const wrapper = shallow(, { context: { baz: 'enzyme' } });
const fooProvider = wrapper.find(FooProvider).dive();
const barProvider = fooProvider.find(BarProvider).dive();
const consumer = barProvider.find(FooBarBazConsumer).dive();
const expectedContext = { baz: 'enzyme', foo: undefined, bar: undefined };
expect(consumer.context()).to.eql(expectedContext);
});
});
it('is called on mount', () => {
const wrapper = shallow(, { context: { baz: 'enzyme' } });
const fooProvider = wrapper.find(FooProvider).dive();
const barProvider = fooProvider.find(BarProvider).dive();
const consumer = barProvider.find(FooBarBazConsumer).dive();
const expectedContext = { foo: 'i', bar: 'love', baz: 'enzyme' };
expect(consumer.context()).to.eql(expectedContext);
expect(fooProviderSpy).to.have.property('callCount', 1);
});
it('is called when the component re-renders', () => {
const wrapper = shallow(, { context: { baz: 'enzyme' } });
const fooProvider = wrapper.find(FooProvider).dive();
fooProvider.setProps({ value: 'we' });
const barProvider = fooProvider.find(BarProvider).dive();
barProvider.setState({ value: 'like' });
const consumer = barProvider.find(FooBarBazConsumer).dive();
expect(fooProviderSpy).to.have.property('callCount', 2);
expect(barProviderSpy).to.have.property('callCount', 2);
const expectedContext = { foo: 'we', bar: 'like', baz: 'enzyme' };
expect(consumer.context()).to.eql(expectedContext);
});
it('propagates updates to rendered children', () => {
const wrapper = shallow(, { context: { baz: 'enzyme' } });
const fooProvider = wrapper.find(FooProvider).dive();
const barProvider = fooProvider.find(BarProvider).dive();
const consumer = barProvider.find(FooBarBazConsumer).dive();
expect(consumer.context()).to.eql({ foo: 'i', bar: 'love', baz: 'enzyme' });
fooProvider.setProps({ value: 'we' });
const nextBarProvider = fooProvider.find(BarProvider).dive();
nextBarProvider.setState({ value: 'maintain' });
const nextConsumer = nextBarProvider.find(FooBarBazConsumer).dive();
const expectedContext = { foo: 'we', bar: 'maintain', baz: 'enzyme' };
expect(nextConsumer.context()).to.eql(expectedContext);
});
it('does nothing if disableLifecycleMethods is true', () => {
const wrapper = shallow(, {
context: { baz: 'enzyme' },
disableLifecycleMethods: true,
});
const fooProvider = wrapper.find(FooProvider).dive();
const consumer = () => {
const barProvider = fooProvider.find(BarProvider).dive();
return barProvider.find(FooBarBazConsumer).dive();
};
const expectedContext = { baz: 'enzyme', foo: undefined, bar: undefined };
expect(consumer().context()).to.eql(expectedContext);
fooProvider.setProps({ value: 'we' });
expect(consumer().context()).to.eql(expectedContext);
});
it('throws like react if a child context is returned and there is no propType', () => {
class FaultyFooProvider extends React.Component {
getChildContext() {
const { value } = this.props;
return { foo: value };
}
render() {
const { children } = this.props;
return children;
}
}
FaultyFooProvider.childContextTypes = {};
expect(() => shallow((
))).to.throw('FaultyFooProvider.getChildContext(): key "foo" is not defined in childContextTypes');
});
it('allows overriding context with the context option', () => {
const wrapper = shallow();
const fooProvider = wrapper.find(FooProvider).dive();
const barProvider = fooProvider.find(BarProvider).dive();
const consumer = barProvider.find(FooBarBazConsumer).dive({ context: { foo: 'you' } });
const expectedContext = { foo: 'you', bar: undefined, baz: undefined };
expect(consumer.context()).to.eql(expectedContext);
});
class Provider extends React.Component {
getChildContext() {
return {
foo: 'foo!',
bar: 'bar!',
};
}
render() {
const { children } = this.props;
return children;
}
}
class Receiver extends React.Component {
render() {
return
{inspect(this.context)}
;
}
}
// react 0.14 and 15 throw an invariant exception in this case
itIf(is('0.13 || > 15'), 'warns and works but provides no context, without childContextTypes', () => {
const stub = sinon.stub(console, 'warn');
const wrapper = shallow().dive();
expect(wrapper.debug()).to.equal(`
{}
`);
expect(stub).to.have.property('callCount', 1);
expect(stub.args).to.eql([['Provider.getChildContext(): childContextTypes must be defined in order to use getChildContext().']]);
});
wrap()
.withConsoleThrows()
.it('warns if childContextTypes is not defined', () => {
class FaultyFooProvider extends React.Component {
getChildContext() {
const { value } = this.props;
return {
foo: value,
};
}
render() {
return null;
}
}
expect(() => shallow((
))).to.throw('FaultyFooProvider.getChildContext(): childContextTypes must be defined in order to use getChildContext().');
});
wrap()
.withConsoleThrows()
.describe('checks', () => {
// FIXME: figure out why this fails on 15.0 and 15.1
itIf(!is('~15.0 || ~15.1 || ~15.2'), 'prop types', () => {
try {
shallow();
throw new EvalError('shallow() did not throw!');
} catch (error) {
expect(error.message).to.contain('`foo` of type `number` supplied to `FooProvider`, expected `string`');
expect(error.message).to.match(/context/i);
}
});
});
wrap()
.withOverride(() => getAdapter(), 'createShallowRenderer', () => (...args) => {
const renderer = realCreateShallowRenderer(...args);
delete renderer.checkPropTypes;
return renderer;
})
.it('if the adapter can‘t check propTypes, it works, but does not check prop types', () => {
expect(() => {
const wrapper = shallow(, { context: { baz: 'enzyme' } });
const fooProvider = wrapper.find(FooProvider).dive();
const barProvider = fooProvider.find(BarProvider).dive();
return barProvider.find(FooBarBazConsumer).dive();
}).not.to.throw();
});
});
});
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
it('works with SFCs', () => {
const Foo = ({ foo }) => (
);
const context = { name: 'foo' };
const wrapper = shallow();
expect(wrapper.find(Bar).shallow({ context }).text()).to.equal('foo');
});
it('does not throw if context is passed in but contextTypes is missing', () => {
const Bar = (props, { name }) => (
);
const context = { name: 'foo' };
const wrapper = shallow().find(Bar).shallow({ context });
expect(() => wrapper.context()).to.throw(
Error,
'ShallowWrapper::context() can only be called on wrapped nodes that have a non-null instance',
);
expect(() => wrapper.context('name')).to.throw(
Error,
'ShallowWrapper::context() can only be called on wrapped nodes that have a non-null instance',
);
});
});
});
});
describe('.dive()', () => {
class RendersDOM extends React.Component {
render() {
return
;
}
const wrapper = Wrap();
expect(wrapper.find('div').length).to.equal(1);
expect(wrapper.find('div').text()).to.equal('0');
});
it('handles setState returned from useState', () => {
function ComponentUsingStateHook() {
const [count, setCount] = useState(0);
return
setCount(count + 1)}>{count}
;
}
const wrapper = Wrap();
const div = wrapper.find('div');
const setCount = div.prop('onClick');
setCount();
wrapper.update();
expect(wrapper.find('div').text()).to.equal('1');
});
describe('useState with willReceive prop effect / simulate getDerivedStateFromProp', () => {
const newPropCount = 10;
function FooCounterWithEffect({ initialCount: initial = 0 }) {
const [count, setCount] = useState(+initial);
useEffect(() => {
setCount(initial);
}, [initial]);
return (
{count}
);
}
// TODO: fixme when useEffect works in the shallow renderer, see https://github.com/facebook/react/issues/15275
itIf(!isShallow, 'initial render & new Props', () => {
const wrapper = Wrap();
expect(wrapper.find('.counter').text()).to.equal(String(initialCount));
wrapper.setProps({ initialCount: newPropCount });
expect(wrapper.find('.counter').text()).to.equal(String(newPropCount));
});
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/lifecycles/componentDidCatch.jsx
================================================
import React from 'react';
import sinon from 'sinon-sandbox';
import { expect } from 'chai';
import { is } from '../../_helpers/version';
import {
describeIf,
itIf,
} from '../../_helpers';
import {
Fragment,
} from '../../_helpers/react-compat';
export default function describeCDC({
Wrap,
isShallow,
}) {
describeIf(is('>= 16'), 'componentDidCatch', () => {
describe('errors inside an error boundary', () => {
const errorToThrow = new EvalError('threw an error!');
// in React 16.0 - 16.2 and 16.9+, and some older nodes, the actual error thrown isn't reported.
const reactError = new Error('An error was thrown inside one of your components, but React doesn\'t know what it was. This is likely due to browser flakiness. React does its best to preserve the "Pause on exceptions" behavior of the DevTools, which requires some DEV-mode only tricks. It\'s possible that these don\'t work in your browser. Try triggering the error in production mode, or switching to a modern browser. If you suspect that this is actually an issue with React, please file an issue.');
const properErrorMessage = (error) => error instanceof Error && (
error.message === errorToThrow.message
|| error.message === reactError.message
);
const hasFragments = is('>= 16.2');
const MaybeFragment = hasFragments ? Fragment : 'main';
function Thrower({ throws }) {
if (throws) {
throw errorToThrow;
}
return null;
}
class ErrorBoundary extends React.Component {
constructor(...args) {
super(...args);
this.state = {
throws: false,
didThrow: false,
};
}
componentDidCatch(error, info) {
const { spy } = this.props;
spy(error, info);
this.setState({
throws: false,
didThrow: true,
});
}
render() {
const { ThrowerComponent } = this.props;
const {
didThrow,
throws,
} = this.state;
return (
{}
{didThrow ? 'HasThrown' : 'HasNotThrown'}
);
}
}
ErrorBoundary.defaultProps = {
ThrowerComponent: Thrower,
};
function ErrorSFC(props) {
return ;
}
describe('Thrower', () => {
it('does not throw when `throws` is `false`', () => {
expect(() => Wrap()).not.to.throw();
});
itIf(isShallow, 'throws when `throws` is `true`', () => {
expect(() => Wrap()).to.throw(errorToThrow);
});
itIf(!isShallow, 'throws when `throws` is `true`', () => {
expect(() => Wrap()).to.throw();
try {
Wrap();
expect(true).to.equal(false, 'this line should not be reached');
} catch (e) {
expect(e).to.satisfy(properErrorMessage);
}
});
});
it('catches a simulated error', () => {
const spy = sinon.spy();
const wrapper = Wrap();
expect(spy).to.have.property('callCount', 0);
expect(() => wrapper.find(Thrower).simulateError(errorToThrow)).not.to.throw();
expect(spy).to.have.property('callCount', 1);
expect(spy.args).to.be.an('array').and.have.lengthOf(1);
const [[actualError, info]] = spy.args;
expect(() => { throw actualError; }).to.throw(errorToThrow);
expect(info).to.deep.equal({
componentStack: `
in Thrower (created by ErrorBoundary)
in span (created by ErrorBoundary)${hasFragments ? '' : `
in main (created by ErrorBoundary)`}
in div (created by ErrorBoundary)
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent`,
});
});
itIf(
is('>= 16.6'),
'catches a simulated error on memo() component',
() => {
const MemoThrower = React.memo(Thrower);
const spy = sinon.spy();
const wrapper = Wrap(
,
);
expect(spy).to.have.property('callCount', 0);
expect(() => wrapper.find(Thrower).simulateError(errorToThrow)).not.to.throw();
expect(spy).to.have.property('callCount', 1);
expect(spy.args).to.be.an('array').and.have.lengthOf(1);
const [[actualError, info]] = spy.args;
expect(() => {
throw actualError;
}).to.throw(errorToThrow);
expect(info).to.deep.equal({
componentStack: `
in Memo(Thrower) (created by ErrorBoundary)
in span (created by ErrorBoundary)${hasFragments ? '' : `
in main (created by ErrorBoundary)`}
in div (created by ErrorBoundary)
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent`,
});
},
);
it('rerenders on a simulated error', () => {
const wrapper = Wrap();
expect(wrapper.find({ children: 'HasThrown' })).to.have.lengthOf(0);
expect(wrapper.find({ children: 'HasNotThrown' })).to.have.lengthOf(1);
expect(() => wrapper.find(Thrower).simulateError(errorToThrow)).not.to.throw();
expect(wrapper.find({ children: 'HasThrown' })).to.have.lengthOf(1);
expect(wrapper.find({ children: 'HasNotThrown' })).to.have.lengthOf(0);
});
itIf(isShallow, 'does not catch errors during Wrapper render', () => {
const spy = sinon.spy();
const wrapper = Wrap();
expect(spy).to.have.property('callCount', 0);
wrapper.setState({ throws: true });
expect(spy).to.have.property('callCount', 0);
const thrower = wrapper.find(Thrower);
expect(thrower).to.have.lengthOf(1);
expect(thrower.props()).to.have.property('throws', true);
expect(() => thrower.dive()).to.throw(errorToThrow);
expect(spy).to.have.property('callCount', 0);
expect(wrapper.find({ children: 'HasThrown' })).to.have.lengthOf(0);
expect(wrapper.find({ children: 'HasNotThrown' })).to.have.lengthOf(1);
});
describeIf(!isShallow, 'descendant components', () => {
it('rerenders on a simulated error with an SFC root', () => {
const wrapper = Wrap();
expect(wrapper.find({ children: 'HasThrown' })).to.have.lengthOf(0);
expect(wrapper.find({ children: 'HasNotThrown' })).to.have.lengthOf(1);
expect(() => wrapper.find(Thrower).simulateError(errorToThrow)).not.to.throw();
expect(wrapper.find({ children: 'HasThrown' })).to.have.lengthOf(1);
expect(wrapper.find({ children: 'HasNotThrown' })).to.have.lengthOf(0);
});
it('catches errors during render', () => {
const spy = sinon.spy();
const wrapper = Wrap();
expect(spy).to.have.property('callCount', 0);
wrapper.setState({ throws: true });
expect(spy).to.have.property('callCount', 1);
expect(spy.args).to.be.an('array').and.have.lengthOf(1);
const [[actualError, info]] = spy.args;
expect(actualError).to.satisfy(properErrorMessage);
expect(info).to.deep.equal({
componentStack: `
in Thrower (created by ErrorBoundary)
in span (created by ErrorBoundary)${hasFragments ? '' : `
in main (created by ErrorBoundary)`}
in div (created by ErrorBoundary)
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent`,
});
});
it('works when the root is an SFC', () => {
const spy = sinon.spy();
const wrapper = Wrap();
expect(spy).to.have.property('callCount', 0);
wrapper.find(ErrorBoundary).setState({ throws: true });
expect(spy).to.have.property('callCount', 1);
expect(spy.args).to.be.an('array').and.have.lengthOf(1);
const [[actualError, info]] = spy.args;
expect(actualError).to.satisfy(properErrorMessage);
expect(info).to.deep.equal({
componentStack: `
in Thrower (created by ErrorBoundary)
in span (created by ErrorBoundary)${hasFragments ? '' : `
in main (created by ErrorBoundary)`}
in div (created by ErrorBoundary)
in ErrorBoundary (created by ErrorSFC)
in ErrorSFC (created by WrapperComponent)
in WrapperComponent`,
});
});
});
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/lifecycles/componentDidMount.jsx
================================================
import React from 'react';
import sinon from 'sinon-sandbox';
import { expect } from 'chai';
export default function describeCDM({
Wrap,
}) {
describe('componentDidUpdate()', () => {
it('does not call `componentDidMount` twice when a child component is created', () => {
const spy = sinon.spy();
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = {
foo: 'init',
};
}
componentDidMount() {
spy('componentDidMount');
}
render() {
spy('render');
const { foo } = this.state;
return (
this.setState({ foo: 'update2' })}>
click
{foo}
);
}
}
const wrapper = Wrap();
expect(spy.args).to.eql([
['render'],
['componentDidMount'],
]);
spy.resetHistory();
wrapper.find('button').prop('onClick')();
expect(spy).to.have.property('callCount', 1);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/lifecycles/componentDidUpdate.jsx
================================================
import React from 'react';
import sinon from 'sinon-sandbox';
import { expect } from 'chai';
import isEqual from 'lodash.isequal';
import {
PureComponent,
} from '../../_helpers/react-compat';
import {
describeIf,
argSpy,
expectArgs,
} from '../../_helpers';
import {
is,
} from '../../_helpers/version';
export default function describeCDU({
Wrap,
isShallow,
}) {
describe('componentDidUpdate()', () => {
it('calls `componentDidUpdate` when component’s `setState` is called', () => {
const spy = sinon.spy();
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = {
foo: 'init',
};
}
componentDidUpdate() {
spy('componentDidUpdate');
}
onChange() {
// enzyme can't handle the update because `this` is a ReactComponent instance,
// not a ShallowWrapper instance.
this.setState({ foo: 'onChange update' });
}
render() {
spy('render');
const { foo } = this.state;
return
{foo}
;
}
}
const wrapper = Wrap();
spy.resetHistory();
wrapper.setState({ foo: 'wrapper setState update' });
expect(wrapper.state('foo')).to.equal('wrapper setState update');
expect(spy.args).to.eql([
['render'],
['componentDidUpdate'],
]);
spy.resetHistory();
wrapper.instance().onChange();
expect(wrapper.state('foo')).to.equal('onChange update');
expect(spy.args).to.eql([
['render'],
['componentDidUpdate'],
]);
});
it('calls `componentDidUpdate` when component’s `setState` is called through a bound method', () => {
const spy = sinon.spy();
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = {
foo: 'init',
};
this.onChange = this.onChange.bind(this);
}
componentDidUpdate() {
spy('componentDidUpdate');
}
onChange() {
// enzyme can't handle the update because `this` is a ReactComponent instance,
// not a ShallowWrapper instance.
this.setState({ foo: 'onChange update' });
}
render() {
spy('render');
const { foo } = this.state;
return (
;
}
}
const wrapper = Wrap();
wrapper.unmount();
expect(spy.args).to.deep.equal([
['render'],
['componentWillUnmount'],
]);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/lifecycles/getDerivedStateFromError.jsx
================================================
import React from 'react';
import sinon from 'sinon-sandbox';
import { expect } from 'chai';
import { is } from '../../_helpers/version';
import {
describeIf,
itIf,
} from '../../_helpers';
import {
Fragment,
} from '../../_helpers/react-compat';
export default function describeCDC({
Wrap,
isShallow,
}) {
describeIf(is('>= 16.6'), 'getDerivedStateFromError', () => {
const errorToThrow = new EvalError('threw an error!');
// in React 16.0 - 16.2 and 16.9+, and some older nodes, the actual error thrown isn't reported.
const reactError = new Error('An error was thrown inside one of your components, but React doesn\'t know what it was. This is likely due to browser flakiness. React does its best to preserve the "Pause on exceptions" behavior of the DevTools, which requires some DEV-mode only tricks. It\'s possible that these don\'t work in your browser. Try triggering the error in production mode, or switching to a modern browser. If you suspect that this is actually an issue with React, please file an issue.');
const properErrorMessage = (error) => error instanceof Error && (
error.message === errorToThrow.message
|| error.message === reactError.message
);
describe('errors inside an error boundary', () => {
function Thrower({ throws }) {
if (throws) {
throw errorToThrow;
}
return null;
}
function getErrorBoundary() {
return class ErrorBoundary extends React.Component {
static getDerivedStateFromError() {
return {
throws: false,
didThrow: true,
};
}
constructor(props) {
super(props);
this.state = {
throws: false,
didThrow: false,
};
}
render() {
const {
didThrow,
throws,
} = this.state;
return (
);
}
}
const wrapper = Wrap();
expectArgs(spy, 1, [
['render'],
['componentDidMount'],
]);
wrapper.find('button').prop('onClick')();
expectArgs(spy, 2, [
['render'],
]);
});
describeIf(is('>= 16.6'), 'getDerivedStateFromError and componentDidCatch combined', () => {
const errorToThrow = new EvalError('threw an error!');
// in React 16.0 - 16.2 and 16.9+, and some older nodes, the actual error thrown isn't reported.
const reactError = new Error('An error was thrown inside one of your components, but React doesn\'t know what it was. This is likely due to browser flakiness. React does its best to preserve the "Pause on exceptions" behavior of the DevTools, which requires some DEV-mode only tricks. It\'s possible that these don\'t work in your browser. Try triggering the error in production mode, or switching to a modern browser. If you suspect that this is actually an issue with React, please file an issue.');
const properErrorMessage = (error) => error instanceof Error && (
error.message === errorToThrow.message
|| error.message === reactError.message
);
const expectedInfo = {
componentStack: `
in Thrower (created by ErrorBoundary)
in div (created by ErrorBoundary)
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent`,
};
function Thrower({ throws }) {
if (throws) {
throw errorToThrow;
}
return null;
}
describe('errors inside error boundary when getDerivedStateFromProps returns update', () => {
let lifecycleSpy;
let stateSpy;
beforeEach(() => {
lifecycleSpy = sinon.spy();
stateSpy = sinon.spy();
});
class ErrorBoundary extends React.Component {
static getDerivedStateFromError(error) {
lifecycleSpy('getDerivedStateFromError', error);
return {
didThrow: true,
throws: false,
};
}
constructor(props) {
super(props);
this.state = {
didThrow: false,
throws: false,
};
lifecycleSpy('constructor');
}
componentDidCatch(error, info) {
lifecycleSpy('componentDidCatch', error, info);
stateSpy({ ...this.state });
}
render() {
lifecycleSpy('render');
const {
throws,
} = this.state;
return (
);
}
}
const wrapper = Wrap();
const iter = wrapper[ITERATOR_SYMBOL]();
expect(iter).to.have.property(ITERATOR_SYMBOL).and.be.a('function');
expect(iter[ITERATOR_SYMBOL]()).to.equal(iter);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/_method.template
================================================
import React from 'react';
import PropTypes from 'prop-types';
import { expect } from 'chai';
import wrap from 'mocha-wrap';
import sinon from 'sinon-sandbox';
import { Portal } from 'react-is';
import { render } from 'enzyme';
import getAdapter from 'enzyme/build/getAdapter';
import {
ITERATOR_SYMBOL,
sym,
} from 'enzyme/build/Utils';
import {
describeIf,
itIf,
} from '../../_helpers';
import realArrowFunction from '../../_helpers/realArrowFunction';
import { getElementPropSelector, getWrapperPropSelector } from '../../_helpers/selectors';
import {
is,
REACT16,
} from '../../_helpers/version';
import {
createClass,
createPortal,
createRef,
Fragment,
} from '../../_helpers/react-compat';
export default function describe$Method({
Wrap,
WrapRendered,
Wrapper,
WrapperName,
isShallow,
isMount,
makeDOMElement,
}) {
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/at.jsx
================================================
import React from 'react';
import { expect } from 'chai';
export default function describeAt({
Wrap,
}) {
describe('.at(index)', () => {
it('gets a wrapper of the node at the specified index', () => {
const wrapper = Wrap((
));
const bar = wrapper.find('.bar');
expect(bar.at(0).hasClass('foo')).to.equal(true);
expect(bar.at(1).hasClass('bax')).to.equal(true);
expect(bar.at(2).hasClass('bux')).to.equal(true);
expect(bar.at(3).hasClass('baz')).to.equal(true);
});
it('`.at()` does not affect the results of `.exists()`', () => {
const wrapper = Wrap((
));
const bar = wrapper.find('.bar');
expect(bar.exists()).to.equal(false);
expect(bar.at(0).exists()).to.equal(false);
const foo = wrapper.find('.foo');
expect(foo.exists()).to.equal(true);
expect(foo.at(0).exists()).to.equal(true);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/childAt.jsx
================================================
import React from 'react';
import { expect } from 'chai';
export default function describeChildAt({
Wrap,
}) {
describe('.childAt(index)', () => {
it('gets a wrapped node at the specified index', () => {
const wrapper = Wrap((
));
expect(wrapper.childAt(0).hasClass('bar')).to.equal(true);
expect(wrapper.childAt(1).hasClass('baz')).to.equal(true);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/children.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import {
describeIf,
} from '../../_helpers';
import { is } from '../../_helpers/version';
export default function describeChildren({
Wrap,
WrapRendered,
isShallow,
}) {
describe('.children([selector])', () => {
it('returns empty wrapper for node with no children', () => {
const wrapper = Wrap();
expect(wrapper.children()).to.have.lengthOf(0);
});
it('includes text nodes', () => {
const wrapper = Wrap(
BC
).children();
expect(wrapper).to.have.lengthOf(3);
});
it('does not attempt to get an instance for text nodes', () => {
const wrapper = WrapRendered(
));
expect(wrapper.childAt(0).children()).to.have.lengthOf(1);
expect(wrapper.childAt(1).children()).to.have.lengthOf(1);
expect(wrapper.childAt(2).children()).to.have.lengthOf(1);
});
it('returns the children nodes of the root', () => {
const wrapper = Wrap((
));
expect(wrapper.children()).to.have.lengthOf(3);
expect(wrapper.children().at(0).hasClass('foo')).to.equal(true);
expect(wrapper.children().at(1).hasClass('bar')).to.equal(true);
expect(wrapper.children().at(2).hasClass('baz')).to.equal(true);
});
it('does not return any of the children of children', () => {
const wrapper = Wrap((
));
expect(wrapper.children()).to.have.lengthOf(2);
expect(wrapper.children().at(0).hasClass('foo')).to.equal(true);
expect(wrapper.children().at(1).hasClass('baz')).to.equal(true);
});
it('handles mixed children with and without arrays', () => {
class Foo extends React.Component {
render() {
const { items } = this.props;
return (
)).to.equal(true);
});
it('does something with arrays of nodes', () => {
const wrapper = Wrap((
Hello
Goodbye
More
));
const fails = [
wrong,
Goodbye
,
];
const passes1 = [
Hello,
Goodbye
,
];
const passes2 = [
Goodbye
,
More,
];
expect(wrapper.contains(fails)).to.equal(false);
expect(wrapper.contains(passes1)).to.equal(true);
expect(wrapper.contains(passes2)).to.equal(true);
});
// FIXME: fix on mount
itIf(!isMount, 'throws on invalid argument', () => {
const wrapper = Wrap();
expect(() => wrapper.contains({})).to.throw(
Error,
`${WrapperName}::contains() can only be called with a ReactElement (or an array of them), a string, or a number as an argument.`,
);
expect(() => wrapper.contains(() => ({}))).to.throw(
Error,
`${WrapperName}::contains() can only be called with a ReactElement (or an array of them), a string, or a number as an argument.`,
);
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
it('matches composite components', () => {
function Foo() {
return ;
}
const wrapper = Wrap((
));
const b = ;
expect(wrapper.contains(b)).to.equal(true);
});
it('matches composite components if rendered by function', () => {
function Foo() {
return ;
}
const renderStatelessComponent = () => ;
const wrapper = Wrap((
{renderStatelessComponent()}
));
const b = ;
expect(wrapper.contains(b)).to.equal(true);
});
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/containsAllMatchingElements.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
export default function describeContainsAllMatchingElements({
Wrap,
}) {
describe('.containsAllMatchingElements(nodes)', () => {
it('throws TypeError if non-array passed in', () => {
const wrapper = Wrap((
))).to.throw(TypeError, 'nodes should be an Array');
});
it('matches on array of nodes that each look like rendered nodes, with nested elements', () => {
const wrapper = Wrap((
Hello
Goodbye
));
expect(wrapper.containsAllMatchingElements([
Hello
,
Goodbye
,
])).to.equal(true);
});
it('matches on an array of nodes that all look like one of the rendered nodes', () => {
const spy1 = sinon.spy();
const spy2 = sinon.spy();
const wrapper = Wrap((
,
])).to.equal(true);
expect(spy1).to.have.property('callCount', 0);
expect(spy2).to.have.property('callCount', 0);
});
it('does not match on nodes that do not all look like one of the rendered nodes', () => {
const spy1 = sinon.spy();
const spy2 = sinon.spy();
const wrapper = Wrap((
Hello World
Goodbye World
));
expect(wrapper.containsAllMatchingElements([
Hello World
,
Bonjour le monde
,
Goodbye World
,
])).to.equal(false);
expect(spy1).to.have.property('callCount', 0);
expect(spy2).to.have.property('callCount', 0);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/containsAnyMatchingElements.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
export default function describeContainsAnyMatchingElements({
Wrap,
}) {
describe('.containsAnyMatchingElements(nodes)', () => {
it('matches on an array with at least one node that looks like a rendered node', () => {
const spy1 = sinon.spy();
const spy2 = sinon.spy();
const wrapper = Wrap((
,
])).to.equal(true);
expect(spy1).to.have.property('callCount', 0);
expect(spy2).to.have.property('callCount', 0);
});
it('does not match on an array with no nodes that look like a rendered node', () => {
const spy1 = sinon.spy();
const spy2 = sinon.spy();
const wrapper = Wrap((
Hello World
Goodbye World
));
expect(wrapper.containsAnyMatchingElements([
Bonjour le monde
,
Au revoir le monde
,
])).to.equal(false);
expect(spy1).to.have.property('callCount', 0);
expect(spy2).to.have.property('callCount', 0);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/containsMatchingElement.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
export default function describeContainsMatchingElement({
Wrap,
}) {
describe('.containsMatchingElement(node)', () => {
it('matches a root node that looks like the rendered one', () => {
const spy1 = sinon.spy();
const spy2 = sinon.spy();
const wrapper = Wrap((
))).to.equal(true);
expect(spy1).to.have.property('callCount', 0);
expect(spy2).to.have.property('callCount', 0);
});
it('does not match on a single node that doesn‘t looks like a rendered one', () => {
const spy1 = sinon.spy();
const spy2 = sinon.spy();
const wrapper = Wrap((
));
expect(wrapper.containsMatchingElement( All Operations )).to.equal(true);
});
it('works with leading and trailing newlines', () => {
const wrapper = Wrap((
));
expect(wrapper.containsMatchingElement( All Operations )).to.equal(true);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/context.jsx
================================================
import React from 'react';
import PropTypes from 'prop-types';
import { expect } from 'chai';
import {
itIf,
} from '../../_helpers';
import {
is,
} from '../../_helpers/version';
import {
createClass,
} from '../../_helpers/react-compat';
export default function describeContext({
Wrap,
WrapperName,
isShallow,
}) {
describe('.context()', () => {
const contextTypes = {
name: PropTypes.string,
};
const SimpleComponent = createClass({
contextTypes,
render() {
const { name } = this.context;
return
{name}
;
},
});
function SimpleComponentSFC(props, { name }) {
return
{name}
;
}
SimpleComponentSFC.contextTypes = contextTypes;
it('throws when not called on the root', () => {
const context = { name: };
const wrapper = Wrap(, { context });
const main = wrapper.find('main');
expect(main).to.have.lengthOf(1);
expect(() => main.context()).to.throw(
Error,
`${WrapperName}::context() can only be called on the root`,
);
});
itIf(isShallow, 'throws if it is called when wrapper didn’t include context', () => {
const wrapper = Wrap(, { context: false });
expect(() => wrapper.context()).to.throw(
Error,
`${WrapperName}::context() can only be called on a wrapper that was originally passed a context option`,
);
});
itIf(is('>= 16'), 'throws on SFCs that lack an instance', () => {
const context = { name: 'bob' };
const wrapper = Wrap(, { context });
expect(() => wrapper.context()).to.throw(
Error,
`${WrapperName}::context() can only be called on wrapped nodes that have a non-null instance`,
);
});
it('works with no arguments', () => {
const context = { name: 'foo' };
const wrapper = Wrap(, { context });
expect(wrapper.context()).to.eql(context);
});
it('works with a key name', () => {
const context = { name: 'foo' };
const wrapper = Wrap(, { context });
expect(wrapper.context('name')).to.equal(context.name);
});
class RendersHTML extends React.Component {
render() {
return
`);
});
it('applies defaultProps to the memoized component', () => {
const wrapper = WrapRendered();
expect(wrapper.debug()).to.equal(`
undefined
|
2
|
3
`);
});
it('applies defaultProps to the memoized component and does not override real props', () => {
const wrapper = WrapRendered();
expect(wrapper.debug()).to.equal(`
10
|
20
|
3
`);
});
describeIf(is('>= 16.8'), 'full tree', () => {
function TransitionGroup({ children }) { return children; }
function CSSTransition({ children }) { return children; }
function Body({ imageToShow, switchImage }) {
const handlerClick = useCallback(
() => {
if (imageToShow === 1) {
return switchImage(2);
}
return switchImage(1);
},
[imageToShow, switchImage],
);
return (
`);
});
});
});
describe('defaultProps vs no defaultProps', () => {
function Child({ children }) {
return {children};
}
function LazyC({ type }) {
return (
));
expect(wrapper.find('.foo').filter('.bar')).to.have.lengthOf(3);
expect(wrapper.find('.bar').filter('.foo')).to.have.lengthOf(3);
expect(wrapper.find('.bar').filter('.bax')).to.have.lengthOf(0);
expect(wrapper.find('.foo').filter('.baz.bar')).to.have.lengthOf(2);
});
it('only looks in the current wrappers nodes, not their children', () => {
const wrapper = Wrap((
));
expect(wrapper.find('.foo').filter('.bar')).to.have.lengthOf(1);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/filterWhere.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
export default function describeFilterWhere({
Wrap,
Wrapper,
}) {
describe('.filterWhere(predicate)', () => {
it('filters only the nodes of the wrapper', () => {
const wrapper = Wrap((
));
const stub = sinon.stub();
stub.onCall(0).returns(false);
stub.onCall(1).returns(true);
stub.onCall(2).returns(false);
const baz = wrapper.find('.foo').filterWhere(stub);
expect(baz).to.have.lengthOf(1);
expect(baz.hasClass('baz')).to.equal(true);
});
it('calls the predicate with the wrapped node as the first argument', () => {
const wrapper = Wrap((
));
const stub = sinon.stub();
stub.returns(true);
const spy = sinon.spy(stub);
wrapper.find('.foo').filterWhere(spy);
expect(spy).to.have.property('callCount', 3);
expect(spy.args[0][0]).to.be.instanceOf(Wrapper);
expect(spy.args[1][0]).to.be.instanceOf(Wrapper);
expect(spy.args[2][0]).to.be.instanceOf(Wrapper);
expect(spy.args[0][0].hasClass('bar')).to.equal(true);
expect(spy.args[1][0].hasClass('baz')).to.equal(true);
expect(spy.args[2][0].hasClass('bux')).to.equal(true);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/find.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import wrap from 'mocha-wrap';
import getData from 'html-element-map/getData';
import getAdapter from 'enzyme/build/getAdapter';
import {
describeIf,
describeWithDOM,
itIf,
} from '../../_helpers';
import { is } from '../../_helpers/version';
import {
createPortal,
Fragment,
forwardRef,
memo,
useState,
} from '../../_helpers/react-compat';
export default function describeFind({
Wrap,
WrapRendered,
isShallow,
isMount,
hasDOM,
makeDOMElement,
}) {
describe('.find(selector)', () => {
it('matches the root DOM element', () => {
const wrapper = Wrap(
hello
);
expect(wrapper.find('#ttt')).to.have.lengthOf(1);
expect(wrapper.find('.ttt')).to.have.lengthOf(1);
});
it('finds an element based on a class name', () => {
const wrapper = Wrap((
));
expect(wrapper.find('.foo').type()).to.equal('input');
});
it('finds an SVG element based on a class name', () => {
const wrapper = Wrap((
));
expect(wrapper.find('.foo').type()).to.equal('svg');
});
it('finds an element that has dot in attribute', () => {
const wrapper = Wrap((
));
const elements = wrapper.find('[data-baz="foo.bar"]');
expect(elements).to.have.lengthOf(1);
});
it('finds an element based on a tag name', () => {
const wrapper = Wrap((
Button
));
expect(wrapper.find('input').props()).to.eql({ className: 'foo' });
expect(wrapper.find('button').props()).to.eql({
className: 'bar',
children: 'Button',
type: 'button',
});
expect(wrapper.find('textarea').props()).to.eql({ className: 'magic' });
expect(wrapper.find('select').props()).to.eql({ className: 'reality' });
});
it('finds an element based on a tag name and class name', () => {
const wrapper = Wrap((
));
expect(wrapper.find('input.foo')).to.have.lengthOf(1);
});
it('finds an element based on a tag name and id', () => {
const wrapper = Wrap((
));
expect(wrapper.find('input#foo')).to.have.lengthOf(1);
});
it('finds an element based on a tag name, id, and class name', () => {
const wrapper = Wrap((
));
expect(wrapper.find('input#foo.bar')).to.have.lengthOf(1);
});
it('finds an element that with class and attribute', () => {
const wrapper = Wrap((
));
const elements = wrapper.find('.classBar[data-baz="bar"]');
expect(elements).to.have.lengthOf(1);
});
it('finds an element that with multiple classes and one attribute', () => {
const wrapper = Wrap((
));
const elements = wrapper.find('.classBar.classFoo[data-baz="bar"]');
expect(elements).to.have.lengthOf(1);
});
it('finds an element that with class and class with hyphen', () => {
const wrapper = Wrap((
));
const elements = wrapper.find('.classBar.class-Foo');
expect(elements).to.have.lengthOf(1);
});
it('finds a component based on a constructor', () => {
class Foo extends React.Component {
render() { return ; }
}
const wrapper = Wrap((
));
expect(() => wrapper.find(Foo)).to.throw(
TypeError,
'Enzyme::Selector expects a string, object, or valid element type (Component Constructor)',
);
});
wrap()
.withOverride(() => getAdapter(), 'isValidElementType', () => {})
.it('works when an adapter’s `isValidElementType` does not exist', () => {
class Foo extends React.Component {
render() { return ; }
}
const wrapper = Wrap((
));
expect(wrapper.find(Foo)).to.have.lengthOf(1);
});
it('finds a component based on a component function name', () => {
class Foo extends React.Component {
render() { return ; }
}
const wrapper = Wrap((
));
expect(wrapper.find('Foo').type()).to.equal(Foo);
});
it('finds a component based on a component displayName', () => {
class Foo extends React.Component {
render() { return ; }
}
Foo.displayName = 'Bar';
const wrapper = Wrap((
));
expect(wrapper.find('Bar').type()).to.equal(Foo);
});
it('finds multiple elements based on a class name', () => {
const wrapper = Wrap((
));
expect(wrapper.find('.foo')).to.have.lengthOf(2);
});
it('finds multiple elements based on a tag name', () => {
const wrapper = Wrap((
));
expect(wrapper.find('input')).to.have.lengthOf(2);
expect(wrapper.find('button')).to.have.lengthOf(1);
});
it('finds multiple elements based on a constructor', () => {
class Foo extends React.Component {
render() {
return ;
}
}
class Bar extends React.Component {
render() {
return ;
}
}
const wrapper = Wrap((
));
expect(wrapper.find(Foo)).to.have.lengthOf(2);
expect(wrapper.find(Bar)).to.have.lengthOf(1);
});
it('finds multiple elements based on a string prop', () => {
const wrapper = Wrap((
));
expect(wrapper.find('[htmlFor="foo"]')).to.have.lengthOf(1);
expect(wrapper.find('[htmlFor]')).to.have.lengthOf(2);
expect(wrapper.find('[title="foo"]')).to.have.lengthOf(1);
expect(wrapper.find('[title]')).to.have.lengthOf(1);
});
it('finds multiple elements with multiple matching react props', () => {
function noop() {}
const wrapper = Wrap((
));
expect(() => wrapper.find({})).to.throw(
TypeError,
'Enzyme::Selector does not support an array, null, or empty object as a selector',
);
expect(() => wrapper.find([])).to.throw(
TypeError,
'Enzyme::Selector does not support an array, null, or empty object as a selector',
);
expect(() => wrapper.find(null)).to.throw(
TypeError,
'Enzyme::Selector does not support an array, null, or empty object as a selector',
);
});
it('queries attributes with spaces in their values', () => {
const wrapper = Wrap((
Hello
World
));
expect(wrapper.find('[data-foo]')).to.have.lengthOf(2);
expect(wrapper.find('[data-foo="foo bar"]')).to.have.lengthOf(1);
expect(wrapper.find('[data-foo="bar baz quz"]')).to.have.lengthOf(1);
expect(wrapper.find('[data-foo="bar baz"]')).to.have.lengthOf(0);
expect(wrapper.find('[data-foo="foo bar"]')).to.have.lengthOf(0);
expect(wrapper.find('[data-foo="bar baz quz"]')).to.have.lengthOf(0);
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
it('finds a component based on a constructor', () => {
const Foo = () => ();
const wrapper = Wrap((
));
expect(wrapper.find(Foo).type()).to.equal(Foo);
});
it('finds a component based on a function name', () => {
const Foo = () => ();
const wrapper = Wrap((
));
expect(wrapper.find('Foo').type()).to.equal(Foo);
});
it('finds a component based on a displayName', () => {
const Foo = () => ();
Foo.displayName = 'Bar';
const wrapper = Wrap((
));
expect(wrapper.find('Bar').type()).to.equal(Foo);
});
itIf(!isShallow, 'finds a stateless component based on a component displayName if rendered by function', () => {
const Foo = () => ;
const renderStatelessComponent = () => ;
const wrapper = Wrap((
));
});
it('works with an ID', () => {
expect(wrapper.find('a#test')).to.have.lengthOf(1);
});
it('works with a normal attribute', () => {
expect(wrapper.find('a[href="/page"]')).to.have.lengthOf(1);
});
it('works with an attribute with a #', () => {
expect(wrapper.find('a[href="/page#anchor"]')).to.have.lengthOf(1);
});
});
describe('works with data- attributes', () => {
class Foo extends React.Component {
render() {
return (
);
}
}
it('finds elements by data attribute', () => {
const wrapper = WrapRendered();
expect(wrapper.html()).to.contain('data-custom-tag="bookIcon"'); // sanity check
const elements = wrapper.find('[data-custom-tag="bookIcon"]');
expect(elements).to.have.lengthOf(2);
expect(elements.filter('i')).to.have.lengthOf(2);
});
});
describeIf(is('>= 16.2'), 'works with Fragments', () => {
const NestedFragmentComponent = () => (
', true], // second div
['foo bar', null], // second div's contents
];
expect(hasElements).to.eql(expected);
// the root, plus the 2 renderable children, plus the grandchild text
expect(stub).to.have.property('callCount', 4);
});
it('does not pass in null or false nodes', () => {
const wrapper = Wrap((
);
class ClassChild extends React.Component {
render() {
return
Class child
;
}
}
function SFCChild() {
return
SFC child
;
}
class FragmentWithCustomChildClass extends React.Component {
render() {
return (
);
}
}
it('correctly renders html for both children for class', () => {
const classWrapper = Wrap();
expect(classWrapper.html()).to.equal('
Foo
Bar
');
});
it('correctly renders html for both children for const', () => {
const constWrapper = Wrap();
expect(constWrapper.html()).to.equal('
Foo
Bar
');
});
it('correctly renders html for custom component children', () => {
const withChildrenWrapper = Wrap();
expect(withChildrenWrapper.html()).to.equal('
Class child
SFC child
');
});
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/instance.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import {
describeIf,
itIf,
} from '../../_helpers';
import { is } from '../../_helpers/version';
export default function describeInstance({
Wrap,
WrapperName,
isShallow,
}) {
describe('.instance()', () => {
it('returns the component instance', () => {
class Foo extends React.Component {
render() { return ; }
}
const wrapper = Wrap();
expect(wrapper.instance()).to.be.instanceof(Foo);
expect(wrapper.instance().render).to.equal(Foo.prototype.render);
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
function SFC() {
return ;
}
itIf(is('>= 16'), 'has no instance', () => {
const wrapper = Wrap();
expect(wrapper.instance()).to.equal(null);
});
itIf(is('< 16'), 'has an instance', () => {
const wrapper = Wrap();
expect(wrapper.instance()).not.to.equal(null);
});
});
itIf(!isShallow, 'throws when wrapping multiple elements', () => {
class Test extends React.Component {
render() {
return (
);
}
}
const wrapper = Wrap().find('span');
expect(() => wrapper.instance()).to.throw(
Error,
'Method “instance” is meant to be run on 1 node. 2 found instead.',
);
});
itIf(isShallow, 'throws if called on something other than the root node', () => {
class Foo extends React.Component {
render() { return
; }
}
const wrapper = Wrap();
const div = wrapper.find('div');
expect(() => div.instance()).to.throw(
Error,
`${WrapperName}::instance() can only be called on the root`,
);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/invoke.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
import {
itIf,
} from '../../_helpers';
import {
is,
} from '../../_helpers/version';
import {
useEffect,
useState,
} from '../../_helpers/react-compat';
export default function describeInvoke({
Wrap,
WrapperName,
isShallow,
}) {
describe('.invoke(propName)(..args)', () => {
class CounterButton extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
const { count } = this.state;
return (
);
}
}
it('throws when pointing to a non-function prop', () => {
const wrapper = Wrap();
expect(() => wrapper.invoke('data-a')).to.throw(
TypeError,
`${WrapperName}::invoke() requires the name of a prop whose value is a function`,
);
expect(() => wrapper.invoke('does not exist')).to.throw(
TypeError,
`${WrapperName}::invoke() requires the name of a prop whose value is a function`,
);
});
it('can update the state value', () => {
const wrapper = Wrap();
expect(wrapper.state('count')).to.equal(0);
wrapper.find('button').invoke('onClick')();
expect(wrapper.state('count')).to.equal(1);
});
it('can return the handlers’ return value', () => {
const sentinel = {};
const spy = sinon.stub().returns(sentinel);
const wrapper = Wrap();
const value = wrapper.find('a').invoke('onClick')();
expect(value).to.equal(sentinel);
expect(spy).to.have.property('callCount', 1);
});
it('can pass in arguments', () => {
const spy = sinon.spy();
const wrapper = Wrap();
const a = {};
const b = {};
wrapper.find('a').invoke('onClick')(a, b);
expect(spy).to.have.property('callCount', 1);
const [[arg1, arg2]] = spy.args;
expect(arg1).to.equal(a);
expect(arg2).to.equal(b);
});
// TODO: enable when the shallow renderer fixes its bug
itIf(!isShallow && is('>= 16.8'), 'works without explicit `act` wrapper', () => {
function App() {
const [counter, setCounter] = useState(0);
const [result, setResult] = useState(0);
useEffect(
() => setResult(counter * 2),
[counter],
);
return (
setCounter((input) => input + 1)}>{result}
);
}
const wrapper = Wrap();
const expected = ['0', '2', '4', '6'];
const actual = [wrapper.find('button').text()]
.concat(Array.from({ length: 3 }, () => {
wrapper.find('button').invoke('onClick')();
wrapper.update();
return wrapper.find('button').text();
}));
expect(actual).to.eql(expected);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/is.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import {
describeIf,
} from '../../_helpers';
import { is } from '../../_helpers/version';
import {
memo,
forwardRef,
} from '../../_helpers/react-compat';
export default function describeIs({
Wrap,
WrapRendered,
}) {
describe('.is(selector)', () => {
it('returns true when selector matches current element', () => {
const wrapper = Wrap();
expect(wrapper.is('.foo')).to.equal(true);
});
it('allows for compound selectors', () => {
const wrapper = Wrap();
expect(wrapper.is('.foo.bar')).to.equal(true);
});
it('ignores insignificant whitespace', () => {
const className = `
foo
`;
const wrapper = Wrap();
expect(wrapper.is('.foo')).to.equal(true);
});
it('handles all significant whitespace', () => {
const className = `foo
bar
baz`;
const wrapper = Wrap();
expect(wrapper.is('.foo.bar.baz')).to.equal(true);
});
it('returns false when selector does not match', () => {
const wrapper = Wrap();
expect(wrapper.is('.foo')).to.equal(false);
});
class RendersDiv extends React.Component {
render() {
return ;
}
}
const Memoized = memo && memo(RendersDiv);
const ForwardRef = forwardRef && forwardRef(() => );
const MemoForwardRef = memo && memo(() => );
class RendersChildren extends React.Component {
render() {
const { children } = this.props;
return children;
}
}
it('recognizes nonmemoized', () => {
const wrapper = WrapRendered();
expect(wrapper.is(RendersDiv)).to.equal(true);
});
describeIf(is('>= 16.3'), 'forwardRef', () => {
it('recognizes forwardRef', () => {
const wrapper = WrapRendered();
expect(wrapper.is(ForwardRef)).to.equal(true);
});
});
describeIf(is('>= 16.6'), 'React.memo', () => {
it('recognizes memoized and inner', () => {
const wrapper = WrapRendered();
expect(wrapper.is(Memoized)).to.equal(true);
// expect(wrapper.is(RendersDiv)).to.equal(true);
});
it('recognizes memoized forwardRef and inner', () => {
const wrapper = WrapRendered();
expect(wrapper.is(MemoForwardRef)).to.equal(true);
});
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/isEmpty.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
export default function describeLast({
Wrap,
}) {
describe('.isEmpty()', () => {
let warningStub;
let fooNode;
let missingNode;
beforeEach(() => {
warningStub = sinon.stub(console, 'warn');
const wrapper = Wrap();
fooNode = wrapper.find('.foo');
missingNode = wrapper.find('.missing');
});
afterEach(() => {
warningStub.restore();
});
it('displays a deprecation warning', () => {
fooNode.isEmpty();
expect(warningStub.calledWith('Enzyme::Deprecated method isEmpty() called, use exists() instead.')).to.equal(true);
});
it('calls exists() instead', () => {
const existsSpy = sinon.spy();
fooNode.exists = existsSpy;
expect(fooNode.isEmpty()).to.equal(true);
expect(existsSpy).to.have.property('called', true);
});
it('returns true if wrapper is empty', () => {
expect(fooNode.isEmpty()).to.equal(false);
expect(missingNode.isEmpty()).to.equal(true);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/isEmptyRender.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import {
describeIf,
itIf,
itWithData,
generateEmptyRenderData,
} from '../../_helpers';
import { is } from '../../_helpers/version';
import {
createClass,
memo,
} from '../../_helpers/react-compat';
export default function describeIsEmptyRender({
Wrap,
WrapRendered,
isShallow,
}) {
describe('.isEmptyRender()', () => {
class RenderChildren extends React.Component {
render() {
const { children } = this.props;
return children;
}
}
class RenderNull extends React.Component {
render() {
return null;
}
}
const emptyRenderValues = generateEmptyRenderData();
itWithData(emptyRenderValues, 'when a React createClass component returns: ', (data) => {
const Foo = createClass({
render() {
return data.value;
},
});
const wrapper = Wrap();
expect(wrapper.isEmptyRender()).to.equal(data.expectResponse);
});
itWithData(emptyRenderValues, 'when an ES2015 class component returns: ', (data) => {
class Foo extends React.Component {
render() {
return data.value;
}
}
const wrapper = Wrap();
expect(wrapper.isEmptyRender()).to.equal(data.expectResponse);
});
describe('nested nodes', () => {
it(`returns ${!isShallow} for nested elements that return null`, () => {
const wrapper = Wrap((
));
expect(wrapper.isEmptyRender()).to.equal(!isShallow);
});
it('returns false for multiple nested elements that all return null', () => {
const wrapper = Wrap((
));
expect(wrapper.isEmptyRender()).to.equal(false);
});
it('returns false for multiple nested elements where one fringe returns a non null value', () => {
const wrapper = Wrap((
Hello
));
expect(wrapper.isEmptyRender()).to.equal(false);
});
itIf(is('>= 16'), 'returns false for multiple nested elements that all return null', () => {
const wrapper = Wrap((
));
expect(wrapper.isEmptyRender()).to.equal(false);
});
itIf(is('>= 16'), 'returns false for multiple nested elements where one fringe returns a non null value', () => {
const wrapper = Wrap((
Hello
));
expect(wrapper.isEmptyRender()).to.equal(false);
});
itIf(is('>= 16'), `returns ${!isShallow} for multiple nested elements where all values are null`, () => {
const wrapper = Wrap((
));
expect(wrapper.isEmptyRender()).to.equal(!isShallow);
});
});
it('does not return true for HTML elements', () => {
const wrapper = Wrap();
expect(wrapper.isEmptyRender()).to.equal(false);
});
describeIf(is('>=15 || ^16.0.0-alpha'), 'stateless function components (SFCs)', () => {
itWithData(emptyRenderValues, 'when a component returns: ', (data) => {
function Foo() {
return data.value;
}
const wrapper = Wrap();
expect(wrapper.isEmptyRender()).to.equal(data.expectResponse);
});
});
it(`returns ${!isShallow} for > 1 elements`, () => {
class RendersThree extends React.Component {
render() {
return (
);
}
}
const wrapper = WrapRendered();
const elements = wrapper.find(RenderNull);
expect(elements).to.have.lengthOf(3);
expect(elements.isEmptyRender()).to.equal(!isShallow);
});
itIf(!!memo, 'works on a memoized functional component', () => {
const Component = memo(() => null);
const wrapper = Wrap();
expect(wrapper.debug()).to.equal(isShallow ? '' : '');
expect(wrapper.isEmptyRender()).to.equal(true);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/key.jsx
================================================
import React from 'react';
import { expect } from 'chai';
export default function describeKey({
Wrap,
}) {
describe('.key()', () => {
it('returns the key of the node', () => {
const wrapper = Wrap((
{['foo', 'bar', ''].map((s) =>
{s}
)}
)).find('li');
expect(wrapper.at(0).key()).to.equal('foo');
expect(wrapper.at(1).key()).to.equal('bar');
expect(wrapper.at(2).key()).to.equal('');
});
it('returns null when no key is specified', () => {
const wrapper = Wrap((
foo
)).find('li');
expect(wrapper.key()).to.equal(null);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/last.jsx
================================================
import React from 'react';
import { expect } from 'chai';
export default function describeLast({
Wrap,
}) {
describe('.last()', () => {
it('returns the last node in the current set', () => {
const wrapper = Wrap((
));
expect(wrapper.find('.bar').last().hasClass('baz')).to.equal(true);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/map.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
export default function describeMap({
Wrap,
Wrapper,
}) {
describe('.map(fn)', () => {
it('calls a function with a wrapper for each node in the wrapper', () => {
const wrapper = Wrap((
))).to.equal(true);
expect(spy).to.have.property('callCount', 0);
});
it('does not match on a root node that doesn’t looks like the rendered one', () => {
const spy = sinon.spy();
const spy2 = sinon.spy();
const wrapper = Wrap((
));
const parents = wrapper.find('.baz').parents('.foo');
expect(parents).to.have.lengthOf(2);
expect(parents.at(0).hasClass('foo')).to.equal(true);
expect(parents.at(1).hasClass('bax')).to.equal(true);
});
it('works when called sequentially on two sibling nodes', () => {
class Test extends React.Component {
render() {
return (
));
const result = wrapper.find('.foo').reduce((obj, n) => {
obj[n.prop('id')] = n.prop('className');
return obj;
}, {});
expect(result).to.eql({
bax: 'foo qoo',
bar: 'foo boo',
baz: 'foo hoo',
});
});
it('allows the initialValue to be omitted', () => {
const one = ();
const two = ();
const three = ();
const wrapper = Wrap((
{one}
{two}
{three}
));
const counter = ();
const result = wrapper
.find('.foo')
.reduce((acc, n) => [].concat(acc, n, new Wrapper(counter)))
.map(getWrapperPropSelector('id'));
expect(result).to.eql([one, two, counter, three, counter].map(getElementPropSelector('id')));
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/reduceRight.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
import { getElementPropSelector, getWrapperPropSelector } from '../../_helpers/selectors';
export default function describeReduceRight({
Wrap,
Wrapper,
}) {
describe('.reduceRight(fn[, initialValue])', () => {
it('has the right length', () => {
expect(Wrapper.prototype.reduceRight).to.have.lengthOf(1);
});
it('calls a function with a wrapper for each node in the wrapper in reverse', () => {
const wrapper = Wrap((
));
const result = wrapper.find('.foo').reduceRight((obj, n) => {
obj[n.prop('id')] = n.prop('className');
return obj;
}, {});
expect(result).to.eql({
bax: 'foo qoo',
bar: 'foo boo',
baz: 'foo hoo',
});
});
it('allows the initialValue to be omitted', () => {
const one = ();
const two = ();
const three = ();
const wrapper = Wrap((
{one}
{two}
{three}
));
const counter = ();
const result = wrapper
.find('.foo')
.reduceRight((acc, n) => [].concat(acc, n, new Wrapper(counter)))
.map(getWrapperPropSelector('id'));
expect(result).to.eql([three, two, counter, one, counter].map(getElementPropSelector('id')));
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/render.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import {
describeIf, itIf,
} from '../../_helpers';
import { is } from '../../_helpers/version';
export default function describeRender({
Wrap,
}) {
describe('.render()', () => {
// FIXME: figure out why this fails on 15.0 and 15.1
itIf(!is('~15.0 || ~15.1'), 'returns a cheerio wrapper around the current node', () => {
class Foo extends React.Component {
render() {
return ();
}
}
class Bar extends React.Component {
render() {
return (
);
}
}
const wrapper = Wrap();
expect(wrapper.render().find('.in-foo')).to.have.lengthOf(1);
const rendered = wrapper.render();
expect(rendered.is('.in-bar')).to.equal(true);
expect(rendered).to.have.lengthOf(1);
const renderedFoo = wrapper.find(Foo).render();
expect(renderedFoo.is('.in-foo')).to.equal(true);
expect(renderedFoo.is('.in-bar')).to.equal(false);
expect(renderedFoo.find('.in-bar')).to.have.lengthOf(0);
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
// FIXME: figure out why this fails on 15.0 and 15.1
itIf(!is('~15.0 || ~15.1'), 'returns a cheerio wrapper around the current node', () => {
const Foo = () => (
);
const Bar = () => (
);
const wrapper = Wrap();
expect(wrapper.render().find('.in-foo')).to.have.lengthOf(1);
expect(wrapper.render().is('.in-bar')).to.equal(true);
const renderedFoo = wrapper.find(Foo).render();
expect(renderedFoo.is('.in-foo')).to.equal(true);
expect(renderedFoo.is('.in-bar')).to.equal(false);
expect(renderedFoo.find('.in-bar')).to.have.lengthOf(0);
});
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/renderProp.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import wrap from 'mocha-wrap';
import sinon from 'sinon-sandbox';
import getAdapter from 'enzyme/build/getAdapter';
import {
describeIf,
} from '../../_helpers';
import { is } from '../../_helpers/version';
export default function describeRenderProp({
Wrap,
WrapRendered,
WrapperName,
}) {
wrap()
.withConsoleThrows()
.describe('.renderProp()', () => {
class Foo extends React.Component {
render() {
return ;
}
}
class Bar extends React.Component {
render() {
const { render: r } = this.props;
return
{typeof r === 'function' && r()}
;
}
}
class RendersBar extends React.Component {
render() {
return ;
}
}
it('returns a wrapper around the node returned from the render prop', () => {
const wrapperA = Wrap(
);
stub.resetHistory();
wrapperC.find(Bar).renderProp('render')('one', 'two');
expect(stub.args).to.deep.equal([['one', 'two']]);
});
it('throws on a non-string prop name', () => {
const wrapper = Wrap( {}} />);
expect(() => wrapper.renderProp()).to.throw(
TypeError,
`${WrapperName}::renderProp(): \`propName\` must be a string`,
);
});
it('throws on a missing prop', () => {
const wrapper = Wrap( {}} />);
expect(() => wrapper.renderProp('nope')).to.throw(
Error,
`${WrapperName}::renderProp(): no prop called “nope“ found`,
);
});
it('throws on a non-function render prop value', () => {
const wrapper = Wrap();
expect(() => wrapper.renderProp('render')).to.throw(
TypeError,
`${WrapperName}::renderProp(): expected prop “render“ to contain a function, but it holds “object“`,
);
});
it('throws on host elements', () => {
class Div extends React.Component {
render() {
const { children } = this.props;
return
{children}
;
}
}
const wrapper = WrapRendered();
expect(wrapper.is('div')).to.equal(true);
expect(() => wrapper.renderProp('foo')).to.throw();
});
wrap()
.withOverride(() => getAdapter(), 'wrap', () => undefined)
.it('throws with a react adapter that lacks a `.wrap`', () => {
const wrapper = Wrap(
} />
);
expect(() => wrapper.find(Bar).renderProp('render')).to.throw(RangeError);
});
describeIf(is('>= 16'), 'allows non-nodes', () => {
function MyComponent({ val }) {
return x} />;
}
function ComponentWithRenderProp({ val, r }) {
return r(val);
}
it('works with strings', () => {
const wrapper = Wrap();
wrapper.find(ComponentWithRenderProp).renderProp('r')('foo');
wrapper.find(ComponentWithRenderProp).renderProp('r')('');
});
it('works with numbers', () => {
const wrapper = Wrap();
wrapper.find(ComponentWithRenderProp).renderProp('r')(42);
wrapper.find(ComponentWithRenderProp).renderProp('r')(0);
wrapper.find(ComponentWithRenderProp).renderProp('r')(NaN);
});
it('works with null', () => {
const wrapper = Wrap();
wrapper.find(ComponentWithRenderProp).renderProp('r')(null);
});
// FIXME: figure out how to test this reliably
it.skip('throws with undefined', () => {
const wrapper = Wrap();
expect(() => wrapper.find(ComponentWithRenderProp).renderProp('r')(undefined)).to.throw();
});
it('works with arrays', () => {
const wrapper = Wrap();
wrapper.find(ComponentWithRenderProp).renderProp('r')([]);
wrapper.find(ComponentWithRenderProp).renderProp('r')(['a']);
wrapper.find(ComponentWithRenderProp).renderProp('r')([Infinity]);
});
it('works with false', () => {
const wrapper = Wrap();
wrapper.find(ComponentWithRenderProp).renderProp('r')(false);
});
it('throws with true', () => {
const wrapper = Wrap();
expect(() => wrapper.find(ComponentWithRenderProp).renderProp('r')(true).Wrap()).to.throw();
});
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/root.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import {
itIf,
} from '../../_helpers';
export default function describeRoot({
Wrap,
isMount,
}) {
describe('.root()', () => {
class Fixture extends React.Component {
render() {
return
;
}
}
itIf(isMount, 'returns the root component instance', () => {
const wrapper = Wrap();
const root = wrapper.root();
expect(root.is(Fixture)).to.equal(true);
expect(root.childAt(0).children().debug()).to.equal('\n\n\n');
expect(wrapper.find('span').root()).to.equal(root);
});
itIf(!isMount, 'returns the root rendered node', () => {
const wrapper = Wrap();
const root = wrapper.root();
expect(root.is('div')).to.equal(true);
expect(root.children().debug()).to.equal('\n\n\n');
expect(wrapper.find('span').root()).to.equal(root);
});
it('returns the root wrapper from a child', () => {
const wrapper = Wrap();
const root = wrapper.root();
expect(wrapper.find('span').root()).to.equal(root);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/setContext.jsx
================================================
import React from 'react';
import PropTypes from 'prop-types';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
import {
describeIf,
itIf,
} from '../../_helpers';
import { is } from '../../_helpers/version';
import {
createClass,
} from '../../_helpers/react-compat';
export default function describeSetContext({
Wrap,
WrapperName,
isShallow,
}) {
describe('.setContext(newContext)', () => {
const SimpleComponent = createClass({
contextTypes: {
name: PropTypes.string,
},
render() {
const { name } = this.context;
return
{name}
;
},
});
it('sets context for a component multiple times', () => {
const context = { name: 'foo' };
const wrapper = Wrap(, { context });
expect(wrapper.text()).to.equal('foo');
wrapper.setContext({ name: 'bar' });
expect(wrapper.text()).to.equal('bar');
wrapper.setContext({ name: 'baz' });
expect(wrapper.text()).to.equal('baz');
});
it('throws if it is called when wrapper didn’t include context', () => {
const wrapper = Wrap();
expect(() => wrapper.setContext({ name: 'bar' })).to.throw(
Error,
`${WrapperName}::setContext() can only be called on a wrapper that was originally passed a context option`,
);
});
it('throws when not called on the root', () => {
const context = { name: };
const wrapper = Wrap(, { context });
const main = wrapper.find('main');
expect(main).to.have.lengthOf(1);
expect(() => main.setContext()).to.throw(
Error,
`${WrapperName}::setContext() can only be called on the root`,
);
});
describeIf(is('> 0.13'), 'stateless functional components', () => {
const SFC = (props, { name }) => (
{name}
);
SFC.contextTypes = { name: PropTypes.string };
it('sets context for a component multiple times', () => {
const context = { name: 'foo' };
const wrapper = Wrap(, { context });
expect(wrapper.text()).to.equal('foo');
wrapper.setContext({ name: 'bar' });
expect(wrapper.text()).to.equal('bar');
wrapper.setContext({ name: 'baz' });
expect(wrapper.text()).to.equal('baz');
});
it('throws if it is called when shallow didn’t include context', () => {
const wrapper = Wrap();
expect(() => wrapper.setContext({ name: 'bar' })).to.throw(
Error,
`${WrapperName}::setContext() can only be called on a wrapper that was originally passed a context option`,
);
});
});
it('calls componentWillReceiveProps when context is updated', () => {
const spy = sinon.spy();
const updatedProps = { foo: 'baz' };
class Foo extends React.Component {
componentWillReceiveProps() {
spy('componentWillReceiveProps');
}
render() {
spy('render');
const { foo } = this.context;
return
);
const wrapper = Wrap();
expect(() => wrapper.state()).to.throw(
Error,
`${WrapperName}::state() can only be called on class components`,
);
});
it('throws when trying to set state', () => {
const Foo = () => (
abc
);
const wrapper = Wrap();
expect(() => wrapper.setState({ a: 1 })).to.throw(
Error,
`${WrapperName}::setState() can only be called on class components`,
);
});
});
it('throws an error when cb is not a function', () => {
const wrapper = Wrap();
expect(wrapper.state()).to.eql({ id: 'foo' });
expect(() => wrapper.setState({ id: 'bar' }, 1)).to.throw(Error);
expect(() => wrapper.instance().setBadState()).to.throw(Error);
});
it('does not throw with a null/undefined callback', () => {
class Foo extends React.Component {
constructor() {
super();
this.state = {};
}
setStateWithNullishCallback() {
this.setState({}, null);
this.setState({}, undefined);
}
render() {
return null;
}
}
const wrapper = Wrap();
expect(() => wrapper.instance().setStateWithNullishCallback()).not.to.throw();
});
it('preserves the receiver', () => {
class Comp extends React.Component {
constructor(...args) {
super(...args);
this.state = {
key: '',
};
this.instanceFunction = () => this.setState(() => ({ key: 'value' }));
}
componentDidMount() {
this.instanceFunction();
}
render() {
const { key } = this.state;
// FIXME: is this right?
return key ? null : null;
}
}
expect(Wrap().debug()).to.equal(isShallow ? '' : '');
});
describe('child components', () => {
class Child extends React.Component {
constructor(...args) {
super(...args);
this.state = { state: 'a' };
}
render() {
const { prop } = this.props;
const { state } = this.state;
return (
`;
expect(wrapper.debug()).to.equal(expectedPostDebug);
resolve();
});
});
});
itIf(isShallow, 'can not set the state of the stateful child of a stateful root', () => {
const wrapper = Wrap();
expect(wrapper.debug()).to.equal('');
const child = wrapper.find(Child);
expect(() => child.setState({ state: 'b' })).to.throw(
Error,
`${WrapperName}::setState() can only be called on the root`,
);
});
itIf(!isShallow, 'sets the state of the stateful child of a stateful root', () => {
const wrapper = Wrap();
expect(wrapper.text().trim()).to.equal('1 - a');
const child = wrapper.find(Child);
return new Promise((resolve) => {
child.setState({ state: 'b' }, () => {
expect(wrapper.text().trim()).to.equal('1 - b');
resolve();
});
});
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
function SFC(props) {
return ;
}
itIf(isShallow, 'can not set the state of the stateful child of a stateless root', () => {
const wrapper = Wrap();
expect(wrapper.text().trim()).to.equal('');
const child = wrapper.find(Child);
expect(() => child.setState({ state: 'b' })).to.throw(
Error,
`${WrapperName}::setState() can only be called on the root`,
);
});
itIf(!isShallow, 'sets the state of the stateful child of a stateless root', () => {
const wrapper = Wrap();
expect(wrapper.text().trim()).to.equal('1 - a');
const child = wrapper.find(Child);
return new Promise((resolve) => {
child.setState({ state: 'b' }, () => {
expect(wrapper.text().trim()).to.equal('1 - b');
resolve();
});
});
});
});
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/simulate.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
import {
describeIf,
itIf,
} from '../../_helpers';
import {
is,
REACT16,
} from '../../_helpers/version';
import {
memo,
useEffect,
useState,
} from '../../_helpers/react-compat';
export default function describeSimulate({
Wrap,
WrapperName,
isShallow,
isMount,
}) {
// The shallow renderer in react 16 does not yet support batched updates. When it does,
// we should be able to go un-skip all of the tests that are skipped with this flag.
// FIXME: fix this
const BATCHING = !isShallow || !REACT16;
describe('.simulate(eventName, data)', () => {
it('simulates events', () => {
class ClickCounter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.incrementCount = this.incrementCount.bind(this);
}
incrementCount() {
this.setState(({ count }) => ({ count: count + 1 }));
}
render() {
const { count } = this.state;
return (
foo
);
}
}
const wrapper = Wrap();
expect(wrapper.find('a').prop('data-count')).to.have.equal(0);
wrapper.simulate('click');
expect(wrapper.find('a').prop('data-count')).to.have.equal(1);
});
itIf(!isShallow, 'throws a descriptive error for invalid events', () => {
const wrapper = Wrap(
).children();
expect(wrapper).to.have.lengthOf(2);
expect(() => wrapper.single('name!')).to.throw(
Error,
'Method “name!” is meant to be run on 1 node. 2 found instead.',
);
});
it('throws if run on zero nodes', () => {
const wrapper = Wrap().children();
expect(wrapper).to.have.lengthOf(0);
expect(() => wrapper.single('name!')).to.throw(
Error,
'Method “name!” is meant to be run on 1 node. 0 found instead.',
);
});
it('works with a name', () => {
const wrapper = Wrap();
wrapper.single('foo', (node) => {
expect(node).to.equal(wrapper[sym('__node__')]);
});
});
it('works without a name', () => {
const wrapper = Wrap();
wrapper.single((node) => {
expect(node).to.equal(wrapper[sym('__node__')]);
});
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/slice.jsx
================================================
import React from 'react';
import { expect } from 'chai';
export default function describeSlice({
Wrap,
}) {
describe('.slice([begin[, end]])', () => {
it('returns an identical wrapper if no params are set', () => {
const wrapper = Wrap((
));
const slice = wrapper.find('.foo').slice();
expect(slice).to.have.lengthOf(3);
expect(slice.at(0).hasClass('bax')).to.equal(true);
expect(slice.at(1).hasClass('bar')).to.equal(true);
expect(slice.at(2).hasClass('baz')).to.equal(true);
});
it('returns a new wrapper if begin is set', () => {
const wrapper = Wrap((
));
const slice = wrapper.find('.foo').slice(1);
expect(slice).to.have.lengthOf(2);
expect(slice.at(0).hasClass('bar')).to.equal(true);
expect(slice.at(1).hasClass('baz')).to.equal(true);
});
it('returns a new wrapper if begin and end are set', () => {
const wrapper = Wrap((
));
const slice = wrapper.find('.foo').slice(1, 2);
expect(slice).to.have.lengthOf(1);
expect(slice.at(0).hasClass('bar')).to.equal(true);
});
it('returns a new wrapper if begin and end are set (negative)', () => {
const wrapper = Wrap((
));
const slice = wrapper.find('.foo').slice(-2, -1);
expect(slice).to.have.lengthOf(1);
expect(slice.at(0).hasClass('bar')).to.equal(true);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/some.jsx
================================================
import React from 'react';
import { expect } from 'chai';
export default function describeSome({
Wrap,
WrapperName,
}) {
describe('.some(selector)', () => {
it('returns if a node matches a selector', () => {
const wrapper = Wrap((
));
const foo = wrapper.find('.foo');
expect(foo.some('.qoo')).to.equal(true);
expect(foo.some('.foo')).to.equal(true);
expect(foo.some('.bar')).to.equal(false);
});
it('throws if called on root', () => {
const wrapper = Wrap((
));
expect(() => wrapper.some('.foo')).to.throw(
Error,
`${WrapperName}::some() can not be called on the root`,
);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/someWhere.jsx
================================================
import React from 'react';
import { expect } from 'chai';
export default function describeSomeWhere({
Wrap,
}) {
describe('.someWhere(predicate)', () => {
it('returns if a node matches a predicate', () => {
const wrapper = Wrap((
;
}
}
it('returns the state object', () => {
const wrapper = Wrap();
expect(wrapper.state()).to.eql({ foo: 'foo' });
});
it('returns the current state after state transitions', () => {
const wrapper = Wrap();
wrapper.setState({ foo: 'bar' });
expect(wrapper.state()).to.eql({ foo: 'bar' });
});
it('allows a state property name be passed in as an argument', () => {
const wrapper = Wrap();
expect(wrapper.state('foo')).to.equal('foo');
});
it('throws on host nodes', () => {
const wrapper = Wrap(
);
expect(() => wrapper.state()).to.throw(Error, `${WrapperName}::state() can only be called on class components`);
});
itIf(is('>= 16'), 'throws on Portals', () => {
const containerDiv = makeDOMElement();
const portal = createPortal(
,
containerDiv,
);
const wrapper = Wrap(
{portal}
);
expect(() => wrapper.state()).to.throw(Error, `${WrapperName}::state() can only be called on class components`);
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
it('throws on SFCs', () => {
function FooSFC() {
return ;
}
const wrapper = Wrap();
expect(() => wrapper.state()).to.throw(Error, `${WrapperName}::state() can only be called on class components`);
});
});
describe('child components', () => {
class Child extends React.Component {
constructor(...args) {
super(...args);
this.state = { state: 'a' };
}
render() {
const { prop } = this.props;
const { state } = this.state;
return (
{prop} - {state}
);
}
}
class Parent extends React.Component {
constructor(...args) {
super(...args);
this.state = { childProp: 1 };
}
render() {
const { childProp } = this.state;
return ;
}
}
it('gets the state of a stateful parent', () => {
const wrapper = Wrap();
expect(wrapper.state()).to.eql({ childProp: 1 });
});
itIf(isShallow, 'can not get the state of the stateful child of a stateful root', () => {
const wrapper = Wrap();
const child = wrapper.find(Child);
expect(() => child.state()).to.throw(Error, `${WrapperName}::state() can only be called on the root`);
});
itIf(!isShallow, 'gets the state of the stateful child of a stateful root', () => {
const wrapper = Wrap();
const child = wrapper.find(Child);
expect(child.state()).to.eql({ state: 'a' });
});
describeIf(is('> 0.13'), 'stateless function components (SFCs)', () => {
function StatelessParent(props) {
return ;
}
itIf(isShallow, 'can not get the state of the stateful child of a stateless root', () => {
const wrapper = Wrap();
const child = wrapper.find(Child);
expect(() => child.state()).to.throw(Error, `${WrapperName}::state() can only be called on the root`);
});
itIf(!isShallow, 'gets the state of the stateful child of a stateless root', () => {
const wrapper = Wrap();
const child = wrapper.find(Child);
expect(child.state()).to.eql({ state: 'a' });
});
});
});
it('throws when called on a wrapper of multiple nodes', () => {
const wrapper = Wrap((
));
const spans = wrapper.find('span');
expect(spans).to.have.lengthOf(3);
expect(() => spans.state()).to.throw(
Error,
isShallow
? 'ShallowWrapper::state() can only be called on the root'
: `${WrapperName}::getNode() can only be called when wrapping one node`,
);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/tap.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon-sandbox';
export default function describeTap({
Wrap,
}) {
describe('.tap()', () => {
it('calls the passed function with current Wrapper and returns itself', () => {
const spy = sinon.spy();
const wrapper = Wrap((
xxx
yyy
zzz
)).find('li');
const result = wrapper.tap(spy);
expect(spy.calledWith(wrapper)).to.equal(true);
expect(result).to.equal(wrapper);
});
});
}
================================================
FILE: packages/enzyme-test-suite/test/shared/methods/text.jsx
================================================
import React from 'react';
import { expect } from 'chai';
import { render } from 'enzyme';
import {
describeIf,
itIf,
} from '../../_helpers';
import { is } from '../../_helpers/version';
import {
Fragment,
memo,
} from '../../_helpers/react-compat';
export default function describeText({
Wrap,
isShallow,
}) {
describe('.text()', () => {
const matchesRender = function matchesRender(node) {
const actual = Wrap(node).text();
const expected = render(node).text();
expect(expected).to.equal(actual);
};
it('handles simple text nodes', () => {
const wrapper = Wrap((
');
expect(String(children)).to.equal('foo');
});
it('does not throw if context is passed in but contextTypes is missing', () => {
const SimpleComponent = createClass({
render() {
const { name } = this.context;
return