├── .yarnrc ├── .eslintignore ├── .gitignore ├── babel-jest-root-mode-wrapper.js ├── lerna.json ├── packages ├── jasmine-enzyme │ ├── spec │ │ ├── helpers │ │ │ └── setup.js │ │ ├── support │ │ │ └── jasmine.json │ │ ├── fixtures │ │ │ ├── toBeEmptyRender.fixture.js │ │ │ ├── toExist.fixture.js │ │ │ ├── toIncludeText.fixture.js │ │ │ ├── toMatchSelector.fixture.js │ │ │ ├── toHaveHTML.fixture.js │ │ │ ├── toHaveText.fixture.js │ │ │ ├── toHaveClassName.fixture.js │ │ │ ├── toBeDisabled.fixture.js │ │ │ ├── toHaveDisplayName.fixture.js │ │ │ ├── toHaveStyle.fixture.js │ │ │ ├── toHaveValue.fixture.js │ │ │ ├── toHaveProp.fixture.js │ │ │ ├── toBeChecked.fixture.js │ │ │ ├── toContainReact.fixture.js │ │ │ └── toHaveState.fixture.js │ │ └── ensure-matchers-are-added--spec.js │ ├── .eslintrc │ ├── src │ │ ├── __tests__ │ │ │ └── should-throw-for-jest--tests.js │ │ ├── addMatcher.js │ │ └── index.js │ └── package.json ├── jest-environment-enzyme │ ├── src │ │ ├── index.d.ts │ │ ├── index.js │ │ └── setup.js │ ├── package.json │ └── README.md ├── jest-enzyme │ ├── .eslintrc │ ├── src │ │ ├── __tests__ │ │ │ ├── snapshots.test.js │ │ │ ├── __snapshots__ │ │ │ │ ├── snapshots.test.js.snap │ │ │ │ └── snapshots2.test.js.snap │ │ │ ├── automatically-injects.test.js │ │ │ ├── snapshots2.test.js │ │ │ └── asymmetric-matchers.test.js │ │ ├── __failing_tests__ │ │ │ ├── toHaveDisplayName.test.js │ │ │ ├── toHaveText.test.js │ │ │ ├── toHaveHTML.test.js │ │ │ ├── toHaveValue.test.js │ │ │ ├── toHaveClassName.test.js │ │ │ ├── toMatchSelector.test.js │ │ │ ├── toHaveRef.test.js │ │ │ ├── toHaveStyle.test.js │ │ │ ├── toExist.test.js │ │ │ ├── toHaveProp.test.js │ │ │ ├── toBeDisabled.test.js │ │ │ ├── toBeEmptyRender.test.js │ │ │ ├── toBeChecked.test.js │ │ │ ├── toContainReact.test.js │ │ │ └── toHaveState.test.js │ │ ├── index.d.ts │ │ └── index.js │ └── package.json ├── enzyme-matchers │ ├── src │ │ ├── types │ │ │ ├── EnzymeObject.js │ │ │ ├── Assertion.js │ │ │ ├── MatcherMethods.js │ │ │ ├── ToMatchElementOptions.js │ │ │ ├── index.js │ │ │ ├── Matcher.js │ │ │ └── ObjectReductionResponse.js │ │ ├── utils │ │ │ ├── getConsoleObject.js │ │ │ ├── instance.js │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── single.test.js.snap │ │ │ │ │ └── stringify.test.js.snap │ │ │ │ ├── stringify.test.js │ │ │ │ ├── isShallowWrapper.test.js │ │ │ │ ├── protectAssertion.test.js │ │ │ │ ├── single.test.js │ │ │ │ ├── html.test.js │ │ │ │ ├── name.test.js │ │ │ │ └── reduceAssertionObject.test.js │ │ │ ├── displayName.js │ │ │ ├── isShallowWrapper.js │ │ │ ├── deprecate.js │ │ │ ├── colors.js │ │ │ ├── protectAssertion.js │ │ │ ├── single.js │ │ │ ├── reduceAssertionObject.js │ │ │ ├── html.js │ │ │ ├── stringify.js │ │ │ └── name.js │ │ ├── assertions │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── toBeChecked.test.js.snap │ │ │ │ │ ├── toBeDisabled.test.js.snap │ │ │ │ │ ├── toBeEmptyRender.test.js.snap │ │ │ │ │ ├── toExist.test.js.snap │ │ │ │ │ ├── toContainReact.test.js.snap │ │ │ │ │ ├── toHaveRef.test.js.snap │ │ │ │ │ ├── toHaveText.test.js.snap │ │ │ │ │ ├── toHaveValue.test.js.snap │ │ │ │ │ ├── toIncludeText.test.js.snap │ │ │ │ │ ├── toMatchSelector.test.js.snap │ │ │ │ │ ├── toHaveHTML.test.js.snap │ │ │ │ │ ├── toHaveClassName.test.js.snap │ │ │ │ │ ├── toContainExactlyOneMatchingElement.test.js.snap │ │ │ │ │ ├── toContainMatchingElement.test.js.snap │ │ │ │ │ ├── toHaveProp.test.js.snap │ │ │ │ │ ├── toHaveState.test.js.snap │ │ │ │ │ ├── toHaveStyle.test.js.snap │ │ │ │ │ ├── toContainMatchingElements.test.js.snap │ │ │ │ │ ├── toHaveDisplayName.test.js.snap │ │ │ │ │ └── toMatchElement.test.js.snap │ │ │ │ ├── toBeDisabled.test.js │ │ │ │ ├── toHaveRef.test.js │ │ │ │ ├── toHaveText.test.js │ │ │ │ ├── toIncludeText.test.js │ │ │ │ ├── toMatchSelector.test.js │ │ │ │ ├── toContainReact.test.js │ │ │ │ ├── toExist.test.js │ │ │ │ ├── toBeEmptyRender.test.js │ │ │ │ ├── toBeChecked.test.js │ │ │ │ ├── toHaveValue.test.js │ │ │ │ ├── toHaveHTML.test.js │ │ │ │ ├── toHaveClassName.test.js │ │ │ │ ├── toHaveDisplayName.test.js │ │ │ │ ├── toContainMatchingElement.test.js │ │ │ │ ├── toContainExactlyOneMatchingElement.test.js │ │ │ │ ├── toContainMatchingElements.test.js │ │ │ │ ├── toMatchElement.test.js │ │ │ │ ├── toHaveState.test.js │ │ │ │ ├── toHaveProp.test.js │ │ │ │ └── toHaveStyle.test.js │ │ │ ├── toHaveTagName.js │ │ │ ├── toContainExactlyOneMatchingElement.js │ │ │ ├── toBeDisabled.js │ │ │ ├── toExist.js │ │ │ ├── toBeEmptyRender.js │ │ │ ├── toMatchSelector.js │ │ │ ├── toHaveDisplayName.js │ │ │ ├── toHaveRef.js │ │ │ ├── toContainMatchingElement.js │ │ │ ├── toContainReact.js │ │ │ ├── toHaveHTML.js │ │ │ ├── toIncludeText.js │ │ │ ├── toContainMatchingElements.js │ │ │ ├── toHaveValue.js │ │ │ ├── toBeChecked.js │ │ │ ├── toMatchElement.js │ │ │ ├── toHaveText.js │ │ │ ├── toHaveClassName.js │ │ │ ├── toHaveProp.js │ │ │ ├── toHaveState.js │ │ │ └── toHaveStyle.js │ │ └── index.js │ ├── README.md │ └── package.json └── eslint-config-jest-enzyme │ ├── package.json │ ├── README.md │ └── index.js ├── .travis.yml ├── SECURITY.md ├── .flowconfig ├── babel.config.js ├── scripts └── jest.js ├── .eslintrc ├── LICENSE ├── README.md └── package.json /.yarnrc: -------------------------------------------------------------------------------- 1 | workspaces-experimental true 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/node_modules/** 2 | **/lib/** 3 | **/*.fixture.js 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | *.log 4 | package-lock.json 5 | .DS_Store 6 | .idea 7 | -------------------------------------------------------------------------------- /babel-jest-root-mode-wrapper.js: -------------------------------------------------------------------------------- 1 | module.exports = require('babel-jest').createTransformer({ 2 | rootMode: 'upward', 3 | }); 4 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "7.1.2", 3 | "npmClient": "yarn", 4 | "useWorkspaces": true, 5 | "lerna": "2.9.0", 6 | "packages": [ 7 | "packages/*" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/helpers/setup.js: -------------------------------------------------------------------------------- 1 | const { configure } = require('enzyme'); 2 | const Adapter = require('enzyme-adapter-react-16'); 3 | 4 | configure({ adapter: new Adapter() }); 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | 5 | install: 6 | - yarn 7 | - lerna bootstrap 8 | 9 | script: 10 | - lerna run lint 11 | - yarn test 12 | - yarn run typecheck 13 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "import/resolver": { 4 | "alias": [ 5 | ["enzyme-matchers", "../enzyme-matchers/src"] 6 | ] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security contact information 2 | 3 | To report a security vulnerability, please use the 4 | [Tidelift security contact](https://tidelift.com/security). 5 | Tidelift will coordinate the fix and disclosure. 6 | -------------------------------------------------------------------------------- /packages/jest-environment-enzyme/src/index.d.ts: -------------------------------------------------------------------------------- 1 | import * as Enzyme from 'enzyme'; 2 | 3 | declare global { 4 | var shallow: typeof Enzyme.shallow; 5 | var mount: typeof Enzyme.mount; 6 | var render: typeof Enzyme.render; 7 | } 8 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/support/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "spec", 3 | "spec_files": [ 4 | "**/*[sS]pec.js" 5 | ], 6 | "helpers": [ 7 | "helpers/**/*.js" 8 | ], 9 | "stopSpecOnExpectationFailure": false, 10 | "random": false 11 | } 12 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | [include] 4 | 5 | [libs] 6 | 7 | [options] 8 | module.name_mapper='^enzyme-matchers$' -> '/packages/enzyme-matchers/src' 9 | module.name_mapper='^jest-environment-enzyme/lib' -> '/packages/jest-environment-enzyme/src' 10 | -------------------------------------------------------------------------------- /packages/jest-enzyme/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "import/resolver": { 4 | "alias": [ 5 | ["enzyme-matchers", "../enzyme-matchers/src"], 6 | ["jest-environment-enzyme/lib", "../jest-environment-enzyme/src"] 7 | ] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toBeEmptyRender.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return null; 11 | } 12 | module.exports = exports['default']; 13 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/src/__tests__/should-throw-for-jest--tests.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | // this is a migration step. 3 | 4 | describe('jest', () => { 5 | it('should throw an error', () => { 6 | const jasmineEnzyme = require('../'); 7 | 8 | expect(jasmineEnzyme).toThrow(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/types/EnzymeObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule EnzymeObject 6 | * @flow 7 | */ 8 | 9 | // TODO: implement type 10 | export type EnzymeObject = Object; 11 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/getConsoleObject.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | /* eslint-disable no-console */ 3 | 4 | export default function getConsoleObject(): Object { 5 | try { 6 | return console; 7 | } catch (e) { 8 | // If no global console object is available, set consoleObject to a dummy object. 9 | return {}; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__tests__/snapshots.test.js: -------------------------------------------------------------------------------- 1 | describe('snapshotting', () => { 2 | [mount, shallow].forEach(builder => { 3 | it(`serializes enzyme objects (${builder.name})`, () => { 4 | const wrapper = builder(
Hi
); 5 | 6 | expect(wrapper).toMatchSnapshot(); 7 | }); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | const presets = [ 2 | [ 3 | '@babel/preset-env', 4 | { 5 | targets: { 6 | node: 'current', 7 | }, 8 | }, 9 | ], 10 | '@babel/preset-react', 11 | '@babel/preset-flow', 12 | ]; 13 | 14 | const plugins = [ 15 | 'add-module-exports', 16 | ]; 17 | 18 | module.exports = { 19 | presets, 20 | plugins, 21 | }; 22 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/instance.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | function internalInstanceKey(node) { 4 | return Object.keys(Object(node)).filter(key => 5 | key.match(/^__reactInternalInstance\$/) 6 | )[0]; 7 | } 8 | 9 | export default function internalInstance(inst: Object) { 10 | return inst._reactInternalInstance || inst[internalInstanceKey(inst)]; 11 | } 12 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/types/Assertion.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule Assertion 6 | * @flow 7 | */ 8 | import type { EnzymeObject, Matcher } from './'; 9 | 10 | export type Assertion = (EnzymeObject, ...args: any) => Matcher; 11 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/types/MatcherMethods.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule MatcherMethods 6 | * @flow 7 | */ 8 | 9 | export type MatcherMethods = { 10 | [matcherName: string]: { 11 | compare: Function, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/types/ToMatchElementOptions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule ToMatchElementOptions 6 | * @flow 7 | */ 8 | 9 | export type ToMatchElementOptions = { 10 | ignoreProps?: boolean, 11 | verbose?: boolean, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toHaveDisplayName.test.js: -------------------------------------------------------------------------------- 1 | describe('failing test', () => { 2 | const Fixture = () =>
; 3 | 4 | it('fails toHaveDisplayName', () => { 5 | expect(mount()).toHaveDisplayName('span'); 6 | }); 7 | 8 | it('fails NOT toHaveDisplayName', () => { 9 | expect(shallow()).not.toHaveDisplayName('div'); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__tests__/__snapshots__/snapshots.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`snapshotting serializes enzyme objects (mount) 1`] = ` 4 |
7 | Hi 8 |
9 | `; 10 | 11 | exports[`snapshotting serializes enzyme objects (shallow) 1`] = ` 12 |
15 | Hi 16 |
17 | `; 18 | -------------------------------------------------------------------------------- /scripts/jest.js: -------------------------------------------------------------------------------- 1 | var execSync = require('child_process').execSync; 2 | 3 | // let it only run once 4 | console.log('> Building files (lerna).') 5 | 6 | try { 7 | execSync( 8 | 'lerna run build', 9 | (error, stdout) => console.log(stdout, error) 10 | ); 11 | } catch(e) { 12 | console.error(e.stdout.toString('utf8')); 13 | process.exit(1); 14 | } 15 | 16 | console.log(' Done.') 17 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/types/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | export type { Assertion } from './Assertion'; 4 | export type { EnzymeObject } from './EnzymeObject'; 5 | export type { Matcher } from './Matcher'; 6 | export type { MatcherMethods } from './MatcherMethods'; 7 | export type { ObjectReductionResponse } from './ObjectReductionResponse'; 8 | export type { ToMatchElementOptions } from './ToMatchElementOptions'; 9 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/__tests__/__snapshots__/single.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`single gives a useful message 1`] = ` 4 | Object { 5 | "contextualInformation": Object {}, 6 | "message": " must be called on a single node, not multiple nodes.", 7 | "negatedMessage": " must be called on a single node, not multiple nodes.", 8 | "pass": false, 9 | } 10 | `; 11 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__tests__/__snapshots__/snapshots2.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`snapshotting second time serializes enzyme objects (mount) 1`] = ` 4 |
7 | Hi 8 |
9 | `; 10 | 11 | exports[`snapshotting second time serializes enzyme objects (shallow) 1`] = ` 12 |
15 | Hi 16 |
17 | `; 18 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__tests__/automatically-injects.test.js: -------------------------------------------------------------------------------- 1 | import enzymeMatchers from 'enzyme-matchers'; 2 | 3 | const matchers = Object.keys(enzymeMatchers); 4 | 5 | describe('jest-enzyme', () => { 6 | it('automatically adds the methods', () => { 7 | matchers.forEach(matcher => { 8 | const matcherFn = expect('foo')[matcher]; 9 | expect(matcherFn).toBeDefined(); 10 | }); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/displayName.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | export default function getDisplayName(Component: Function | string): string { 4 | if (typeof Component === 'string') { 5 | return Component; 6 | } 7 | if (!Component) { 8 | // Should never actually reach here, Function cannot be falsy. 9 | return 'undefined'; 10 | } 11 | return Component.displayName || Component.name || 'Component'; 12 | } 13 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toExist.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('span', { className: 'matches' }) 14 | ); 15 | } 16 | module.exports = exports['default']; 17 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toHaveText.test.js: -------------------------------------------------------------------------------- 1 | describe('failing Text', () => { 2 | const Fixture = () => 3 |
4 | foo 5 |
; 6 | 7 | it('fails toHaveText', () => { 8 | expect(shallow().find('span')).toHaveText('bar'); 9 | }); 10 | 11 | it('fails NOT toHaveText', () => { 12 | expect(shallow().find('span')).toHaveText('foo'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toIncludeText.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('p', { id: 'full' }, 'Some important text') 14 | ); 15 | } 16 | module.exports = exports['default']; 17 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toMatchSelector.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('span', { id: 'child', className: 'foo' }) 14 | ); 15 | } 16 | module.exports = exports['default']; 17 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__tests__/snapshots2.test.js: -------------------------------------------------------------------------------- 1 | // this test ensures that the global `addSnapshotSerializer` works for multiple test files 2 | describe('snapshotting second time', () => { 3 | [mount, shallow].forEach(builder => { 4 | it(`serializes enzyme objects (${builder.name})`, () => { 5 | const wrapper = builder(
Hi
); 6 | 7 | expect(wrapper).toMatchSnapshot(); 8 | }); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/jest-environment-enzyme/src/index.js: -------------------------------------------------------------------------------- 1 | import JSDOMEnvironment from 'jest-environment-jsdom'; 2 | 3 | export default class EnzymeEnvironment extends JSDOMEnvironment { 4 | constructor(config) { 5 | super(config); 6 | const testEnvironmentOptions = config.testEnvironmentOptions || {}; 7 | this.global.enzymeAdapterDescriptor = testEnvironmentOptions.enzymeAdapter; 8 | this.global.bootstrapEnzymeEnvironment = true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/types/Matcher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule Matcher 6 | * @flow 7 | */ 8 | 9 | export type Matcher = { 10 | pass: boolean, 11 | message: string, 12 | negatedMessage: string, 13 | contextualInformation: { 14 | actual?: string, 15 | expected?: string, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toHaveHTML.test.js: -------------------------------------------------------------------------------- 1 | describe('failing test', () => { 2 | const Fixture = () => 3 |
4 | 5 | 6 | 7 |
; 8 | 9 | it('fails toHaveHTML', () => { 10 | expect(shallow()).toHaveHTML('
'); 11 | }); 12 | 13 | it('fails NOT toHaveHTML', () => { 14 | expect(shallow()).not.toHaveHTML('
'); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toHaveHTML.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.Fixture = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | { id: 'root' }, 13 | React.createElement('span', { id: 'child' }, 'Test') 14 | ); 15 | } 16 | 17 | var html = (exports.html = 'Test'); 18 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toHaveText.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('p', { id: 'full' }, 'Test'), 14 | React.createElement('p', { id: 'empty' }) 15 | ); 16 | } 17 | module.exports = exports['default']; 18 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toHaveClassName.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('span', { className: 'foo' }), 14 | React.createElement('span', { className: 'bar baz' }) 15 | ); 16 | } 17 | module.exports = exports['default']; 18 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toBeDisabled.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('input', { id: 'disabled', disabled: true }), 14 | React.createElement('input', { id: 'not' }) 15 | ); 16 | } 17 | module.exports = exports['default']; 18 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/types/ObjectReductionResponse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule ObjectReductionResponse 6 | * @flow 7 | */ 8 | 9 | export type ObjectReductionResponse = { 10 | actual: { [key: string]: any }, 11 | expected: { [key: string]: any }, 12 | pass: boolean, 13 | missingKeys: Array, 14 | unmatchedKeys: Array, 15 | }; 16 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toHaveDisplayName.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('span', { id: 'span' }), 14 | React.createElement('span', null), 15 | React.createElement('a', { id: 'a' }) 16 | ); 17 | } 18 | module.exports = exports['default']; 19 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toHaveStyle.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('span', { id: 'style1', style: { height: '100%' } }), 14 | React.createElement('span', { id: 'style2', style: { flex: 8 } }) 15 | ); 16 | } 17 | module.exports = exports['default']; 18 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toHaveValue.test.js: -------------------------------------------------------------------------------- 1 | describe('failing Value', () => { 2 | const Fixture = () => 3 |
4 | {}} /> 5 | 6 |
; 7 | 8 | it('fails toHaveValue', () => { 9 | expect(shallow().find('input[value]')).toHaveValue(false); 10 | }); 11 | 12 | it('fails NOT toHaveValue', () => { 13 | expect(shallow().find('input[defaultValue]')).not.toHaveValue( 14 | true 15 | ); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/isShallowWrapper.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import type { EnzymeObject } from '../types'; 4 | 5 | const SHALLOW_WRAPPER_CONSTRUCTOR = 'ShallowWrapper'; 6 | 7 | export default function isShallowWrapper(wrapper: EnzymeObject): boolean { 8 | let isShallow; 9 | if (wrapper.constructor.name !== undefined) { 10 | isShallow = wrapper.constructor.name === SHALLOW_WRAPPER_CONSTRUCTOR; 11 | } else { 12 | isShallow = !!`${wrapper.constructor}`.match(/^function ShallowWrapper\(/); 13 | } 14 | return isShallow; 15 | } 16 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toHaveClassName.test.js: -------------------------------------------------------------------------------- 1 | describe('failing test', () => { 2 | const Fixture = () => 3 |
4 | 5 | 6 | 7 |
; 8 | 9 | it('fails toHaveClassName', () => { 10 | expect(shallow().find('.bar')).not.toHaveClassName('foo'); 11 | }); 12 | 13 | it('fails NOT toHaveClassName', () => { 14 | expect(shallow().find('.foo')).toHaveClassName('baz'); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toMatchSelector.test.js: -------------------------------------------------------------------------------- 1 | describe('failing Value', () => { 2 | const Fixture = () => 3 |
4 | {}} /> 5 | 6 |
; 7 | 8 | it('fails toMatchSelector', () => { 9 | expect(shallow().find('input[value]')).toMatchSelector('span'); 10 | }); 11 | 12 | it('fails NOT toMatchSelector', () => { 13 | expect( 14 | shallow().find('input[defaultValue]') 15 | ).not.toMatchSelector('input'); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toHaveValue.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('input', { defaultValue: 'test' }), 14 | React.createElement('input', { 15 | defaultValue: 'foo', 16 | value: 'bar', 17 | onChange: function noop() {}, 18 | }) 19 | ); 20 | } 21 | module.exports = exports['default']; 22 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toHaveRef.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/no-string-refs */ 2 | describe('failing test', () => { 3 | class Fixture extends React.Component { 4 | render() { 5 | return ( 6 |
7 | 8 | 9 | 10 |
11 | ); 12 | } 13 | } 14 | 15 | it('fails toHaveRef', () => { 16 | expect(mount()).toHaveRef('baz'); 17 | }); 18 | 19 | it('fails NOT toHaveRef', () => { 20 | expect(mount()).not.toHaveRef('foo'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toHaveStyle.test.js: -------------------------------------------------------------------------------- 1 | describe('failing test', () => { 2 | const Fixture = () => 3 |
4 | 5 |
; 6 | 7 | it('fails toHaveStyle', () => { 8 | expect(shallow().find('span')).toHaveStyle('fontSize'); 9 | 10 | expect(shallow().find('span')).toHaveStyle('fontSize', 5); 11 | }); 12 | 13 | it('fails NOT toHaveStyle', () => { 14 | expect(shallow().find('span')).not.toHaveStyle( 15 | 'background', 16 | 'blue' 17 | ); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toExist.test.js: -------------------------------------------------------------------------------- 1 | describe('failing test', () => { 2 | const Fixture = () =>
; 3 | 4 | it('fails toExist', () => { 5 | expect(shallow().find('foobar')).toExist(); 6 | }); 7 | 8 | it('fails NOT toExist', () => { 9 | expect(shallow()).not.toExist(); 10 | }); 11 | 12 | it('fails NOT toExist multiple nodes', () => { 13 | const nodes = ( 14 |
15 | 16 | 17 |
18 | ); 19 | 20 | expect(shallow(nodes).find('span')).not.toExist(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toBeChecked.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toBeChecked provides contextual information for the message 1`] = ` 4 | Object { 5 | "actual": "Node HTML output: ", 6 | } 7 | `; 8 | 9 | exports[`toBeChecked returns the message with the proper pass verbage 1`] = `"Expected \\"input\\" to be checked but it wasn't."`; 10 | 11 | exports[`toBeChecked returns the negatedMessage with the proper fail verbage 1`] = `"Expected \\"input\\" not to be checked but it was."`; 12 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toBeDisabled.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toBeDisabled provides contextual information for the message 1`] = ` 4 | Object { 5 | "expected": "Node HTML output: ", 6 | } 7 | `; 8 | 9 | exports[`toBeDisabled returns the message with the proper pass verbage 1`] = `"Expected node (input) to be \\"disabled\\" but it wasn't."`; 10 | 11 | exports[`toBeDisabled returns the message with the proper pass verbage 2`] = `"Expected node (input) not to be \\"disabled\\" but it was"`; 12 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toBeEmptyRender.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toBeEmptyRender provides contextual information for the message 1`] = ` 4 | Object { 5 | "actual": "Found Nodes HTML output:
", 6 | } 7 | `; 8 | 9 | exports[`toBeEmptyRender returns the message with the proper pass verbage 1`] = `"Expected to be empty render (false or null), but it was not"`; 10 | 11 | exports[`toBeEmptyRender returns the message with the proper pass verbage 2`] = `"Expected not to be empty render (false or null), but it was"`; 12 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toExist.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toExist provides contextual information for the message 1`] = ` 4 | Object { 5 | "actual": "Found Nodes: ", 6 | } 7 | `; 8 | 9 | exports[`toExist provides contextual information for the message 2`] = `Object {}`; 10 | 11 | exports[`toExist returns the message with the proper fail verbage 1`] = `"Expected \\"span\\" not to exist. Instead found 1 nodes."`; 12 | 13 | exports[`toExist returns the message with the proper pass verbage 1`] = `"Expected \\"span\\" to exist."`; 14 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/deprecate.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import type { EnzymeObject } from '../types'; 4 | import colors from './colors'; 5 | 6 | export default function deprecate( 7 | matcherFn: Function, 8 | message: string 9 | ): Function { 10 | let shouldWarn = true; 11 | return function deprecateWrapper( 12 | enzymeWrapper: EnzymeObject, 13 | ...args: Array 14 | ) { 15 | if (shouldWarn) { 16 | // eslint-disable-next-line no-console 17 | console.warn(colors.yellow(message)); 18 | shouldWarn = false; 19 | } 20 | 21 | return matcherFn.call(this, enzymeWrapper, ...args); 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toHaveProp.test.js: -------------------------------------------------------------------------------- 1 | describe('failing test', () => { 2 | const Fixture = () => 3 |
4 | 5 | 6 | 7 |
; 8 | 9 | it('fails toHaveProp', () => { 10 | expect(shallow()).toHaveProp('enabled'); 11 | }); 12 | 13 | it('fails NOT toHaveProp', () => { 14 | expect(shallow()).not.toHaveProp('disabled', true); 15 | }); 16 | 17 | it('fails toHaveProp undefined value', () => { 18 | expect(shallow()).toHaveProp( 19 | 'enabled', 20 | undefined 21 | ); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toHaveProp.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | var PropTypes = require('prop-types'); 9 | 10 | function User(props) { 11 | return React.createElement('div', null, props.name); 12 | } 13 | 14 | User.propTypes = { 15 | name: PropTypes.string, 16 | }; 17 | 18 | function Fixture() { 19 | return React.createElement( 20 | 'div', 21 | null, 22 | React.createElement(User, { 23 | name: 'blaine', 24 | }) 25 | ); 26 | } 27 | module.exports = exports['default']; 28 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toHaveTagName.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import type { EnzymeObject, Matcher } from '../types'; 3 | import deprecate from '../utils/deprecate'; 4 | import toHaveDisplayName from './toHaveDisplayName'; 5 | import colors from '../utils/colors'; 6 | 7 | const toHaveTagName = deprecate( 8 | (enzymeWrapper: EnzymeObject, tag: string): Matcher => 9 | toHaveDisplayName(enzymeWrapper, tag), 10 | `Matcher ${colors.red( 11 | 'toHaveTagName' 12 | )} is deprecated and will be removed in a future release. ` + 13 | `Use the replacement, ${colors.blue('toHaveDisplayName')} instead.` 14 | ); 15 | 16 | export default toHaveTagName; 17 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toBeChecked.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.default = Fixture; 7 | var React = require('react'); 8 | 9 | function Fixture() { 10 | return React.createElement( 11 | 'div', 12 | null, 13 | React.createElement('input', { id: 'checked', defaultChecked: true }), 14 | React.createElement('input', { id: 'not', defaultChecked: false }), 15 | React.createElement('input', { 16 | id: 'tertiary', 17 | defaultChecked: true, 18 | checked: false, 19 | }) 20 | ); 21 | } 22 | module.exports = exports['default']; 23 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toContainReact.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toContainReact provides contextual information for the message 1`] = ` 4 | Object { 5 | "actual": "HTML Output of
: 6 |
", 7 | } 8 | `; 9 | 10 | exports[`toContainReact returns the message with the proper fail verbage 1`] = `"Expected
not to contain User 1 but it does."`; 11 | 12 | exports[`toContainReact returns the message with the proper pass verbage 1`] = `"Expected
to contain User 1 but it was not found."`; 13 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toContainExactlyOneMatchingElement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toContainExactlyOneMatchingElement 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import toContainMatchingElements from './toContainMatchingElements'; 11 | 12 | function toContainExactlyOneMatchingElement( 13 | enzymeWrapper: EnzymeObject, 14 | selector: string 15 | ): Matcher { 16 | return toContainMatchingElements(enzymeWrapper, 1, selector); 17 | } 18 | 19 | export default toContainExactlyOneMatchingElement; 20 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toBeDisabled.test.js: -------------------------------------------------------------------------------- 1 | const PropTypes = require('prop-types'); 2 | 3 | describe('failing test', () => { 4 | [shallow, mount].forEach(builder => { 5 | describe(builder.name, () => { 6 | const Fixture = props => ; 7 | Fixture.propTypes = { disabled: PropTypes.bool }; 8 | Fixture.defaultProps = { disabled: false }; 9 | 10 | it('fails toBeDisabled', () => { 11 | expect(builder().find('input')).toBeDisabled(); 12 | }); 13 | 14 | it('fails NOT toBeDisabled', () => { 15 | expect(builder().find('input')).not.toBeDisabled(); 16 | }); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toBeEmptyRender.test.js: -------------------------------------------------------------------------------- 1 | describe('failing test', () => { 2 | [shallow, mount].forEach(builder => { 3 | describe(builder.name, () => { 4 | const EmptyRenderFixture = () => null; 5 | 6 | const NonEmptyRenderFixture = () => 7 |
8 | 9 |
; 10 | 11 | it('fails toBeEmptyRender', () => { 12 | expect(builder()).toBeEmptyRender(); 13 | }); 14 | 15 | it('fails NOT toBeEmptyRender', () => { 16 | expect( 17 | builder().find('EmptyRenderFixture') 18 | ).not.toBeEmptyRender(); 19 | }); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/README.md: -------------------------------------------------------------------------------- 1 | # enzyme-matchers 2 | 3 | [![npm version](https://img.shields.io/npm/v/enzyme-matchers.svg)](https://www.npmjs.com/package/enzyme-matchers) 4 | ![License](https://img.shields.io/npm/l/chai-enzyme.svg) 5 | 6 | This package is primarily meant to be consumed by framework integrations within [this monorepo](https://github.com/blainekasten/enzyme-matchers). Though it can be used standalone. Look at the source if you want to see how it's used. 7 | 8 | ### Installation 9 | 10 | We suggest using [yarn](https://github.com/yarnpkg/yarn) for installations. 11 | 12 | ``` 13 | yarn add enzyme-matchers --dev 14 | ``` 15 | 16 | But npm works too! 17 | 18 | ``` 19 | $ npm install enzyme-matchers --save-dev 20 | ``` 21 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/colors.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | const colorValues = { 4 | blue: [34, 39], 5 | gray: [90, 39], 6 | green: [32, 39], 7 | red: [31, 39], 8 | yellow: [33, 39], 9 | }; 10 | 11 | const colorFns = {}; 12 | 13 | const matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; 14 | 15 | Object.keys(colorValues).forEach(color => { 16 | const colorValue = colorValues[color]; 17 | colorFns[color] = (str: string) => { 18 | const open = `\u001b[${colorValue[0]}m`; 19 | const close = `\u001b[${colorValue[1]}m`; 20 | const regex = new RegExp(close.replace(matchOperatorsRe, '\\$&'), 'g'); 21 | const regStr = `${str}`.replace(regex, open); 22 | return `${open}${regStr}${close}`; 23 | }; 24 | }); 25 | 26 | export default colorFns; 27 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/__tests__/stringify.test.js: -------------------------------------------------------------------------------- 1 | const stringify = require('../stringify'); 2 | 3 | describe('stringify', () => { 4 | it('works with circular structs', () => { 5 | const proof = {}; 6 | proof.falsy = false; 7 | proof.truthy = true; 8 | proof.string = 'string'; 9 | proof.null = null; 10 | proof.circular = proof; 11 | proof.class = Promise; 12 | proof.arry = Object.keys(proof).map(k => proof[k]); // includes all other proofs 13 | 14 | expect(stringify(proof)).toMatchSnapshot(); 15 | }); 16 | 17 | it('does not mutate an array inside an object', () => { 18 | const anObject = { array: [1, 2, 3] }; 19 | stringify(anObject); 20 | expect(anObject.array).toEqual([1, 2, 3]); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/__tests__/isShallowWrapper.test.js: -------------------------------------------------------------------------------- 1 | import { shallow, mount, render } from 'enzyme'; 2 | import isShallowWrapper from '../isShallowWrapper'; 3 | 4 | const Fixture = () =>
; 5 | 6 | describe('isShallowWrapper', () => { 7 | it('is true for shallow components', () => { 8 | const wrapper = shallow(); 9 | 10 | expect(isShallowWrapper(wrapper)).toBeTruthy(); 11 | }); 12 | 13 | it('is false for mounted components', () => { 14 | const wrapper = mount(); 15 | 16 | expect(isShallowWrapper(wrapper)).toBeFalsy(); 17 | }); 18 | 19 | it('is false for rendered components', () => { 20 | const wrapper = render(); 21 | 22 | expect(isShallowWrapper(wrapper)).toBeFalsy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/eslint-config-jest-enzyme/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-jest-enzyme", 3 | "version": "7.1.2", 4 | "description": "Eslint Config for allowing jest-environment-enzyme globals", 5 | "main": "index.js", 6 | "author": "Blaine Kasten ", 7 | "license": "MIT", 8 | "homepage": "https://github.com/FormidableLabs/enzyme-matchers/blob/master/packages/eslint-config-jest-enzyme#readme", 9 | "files": [ 10 | "index.js" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/FormidableLabs/enzyme-matchers.git" 15 | }, 16 | "keywords": [ 17 | "eslint", 18 | "jest", 19 | "enzyme" 20 | ], 21 | "bugs": { 22 | "url": "https://github.com/FormidableLabs/enzyme-matchers/issues" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/eslint-config-jest-enzyme/README.md: -------------------------------------------------------------------------------- 1 | # eslint-config-jest-enzyme 2 | 3 | [![npm version](https://img.shields.io/npm/v/eslint-config-jest-enzyme.svg)](https://www.npmjs.com/package/eslint-config-jest-enzyme) 4 | ![License](https://img.shields.io/npm/l/chai-enzyme.svg) 5 | 6 | ### Overview 7 | 8 | This library is only useful if you are using [`jest-environment-enzyme`](/packages/jest-environment-enzyme). When you are using that library, React and enzyme specific variables are globalized. This lint config lets eslint know about those globals and not warn about them. 9 | 10 | ### Setup 11 | 12 | Add this extend to your eslint file: 13 | 14 | ```js 15 | { 16 | "extends": [ 17 | "jest-enzyme" 18 | ] 19 | } 20 | ``` 21 | 22 | This configuration only applies to test files that end in `*.test.js`. 23 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "babel-eslint", 4 | "extends": [ 5 | "airbnb", 6 | "prettier", 7 | "./packages/eslint-config-jest-enzyme/index.js" 8 | ], 9 | "env": { 10 | "jasmine": true, 11 | "jest": true 12 | }, 13 | "rules": { 14 | "import/no-extraneous-dependencies": 0, 15 | "jsx-a11y/anchor-has-content": 0, 16 | "jsx-a11y/anchor-is-valid": 0, 17 | "max-len": 0, 18 | "no-case-declarations": 0, 19 | "no-underscore-dangle": 0, 20 | "no-prototype-builtins": 0, 21 | "react/jsx-filename-extension": 0, 22 | "react/jsx-indent": 0, 23 | "react/jsx-wrap-multilines": 0, 24 | "react/no-unused-state": 0, 25 | "react/no-string-refs": 0, 26 | "react/require-default-props": 0, 27 | "react/forbid-prop-types": 0 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/__tests__/__snapshots__/stringify.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`stringify works with circular structs 1`] = ` 4 | "falsy: false 5 | truthy: true 6 | string: \\"string\\" 7 | null: null 8 | circular: [Circular] 9 | class: function Promise() { [native code] } 10 | arry: [ 11 | false 12 | true 13 | \\"string\\" 14 | null 15 | [Circular] 16 | function Promise() { [native code] } 17 | ]" 18 | `; 19 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/spec/fixtures/toContainReact.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true, 5 | }); 6 | exports.User = User; 7 | exports.Fixture = Fixture; 8 | var React = require('react'); 9 | var PropTypes = require('prop-types'); 10 | 11 | function User(props) { 12 | return React.createElement('span', null, 'User ', props.index); 13 | } 14 | 15 | User.propTypes = { 16 | index: PropTypes.number.isRequired, 17 | }; 18 | 19 | function Fixture() { 20 | return React.createElement( 21 | 'div', 22 | null, 23 | React.createElement( 24 | 'ul', 25 | null, 26 | React.createElement('li', null, React.createElement(User, { index: 1 })), 27 | React.createElement('li', null, React.createElement(User, { index: 2 })) 28 | ) 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toBeChecked.test.js: -------------------------------------------------------------------------------- 1 | const PropTypes = require('prop-types'); 2 | 3 | describe('failing test', () => { 4 | [shallow, mount].forEach(builder => { 5 | describe(builder.name, () => { 6 | const Fixture = props => ; 7 | Fixture.propTypes = { defaultChecked: PropTypes.bool }; 8 | Fixture.defaultProps = { defaultChecked: false }; 9 | 10 | it('fails toBeChecked', () => { 11 | expect(builder().find('input')).toBeChecked(); 12 | }); 13 | 14 | it('fails NOT toBeChecked', () => { 15 | expect( 16 | builder().find('input') 17 | ).not.toBeChecked(); 18 | }); 19 | 20 | it('non-enzyme data', () => { 21 | expect([]).toBeChecked(); 22 | }); 23 | }); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toContainReact.test.js: -------------------------------------------------------------------------------- 1 | describe('failing test', () => { 2 | const Fixture = () => 3 |
4 | 5 |
; 6 | 7 | [shallow, mount].forEach(builder => { 8 | describe(builder.name, () => { 9 | it('fails toContainReact', () => { 10 | expect(builder()).toContainReact(); 11 | }); 12 | 13 | it('fails NOT toContainReact', () => { 14 | expect(builder()).not.toContainReact(); 15 | }); 16 | 17 | it('fails NOT toContainReact multiple nodes', () => { 18 | const nodes = ( 19 |
20 | 21 | 22 |
23 | ); 24 | 25 | expect(builder(nodes).find('span')).toContainReact( 26 | 27 | ); 28 | }); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/eslint-config-jest-enzyme/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | overrides: [ 3 | { 4 | files: [ 5 | '**/*.test.js', 6 | '**/*.test.jsx', 7 | '**/*.test.ts', 8 | '**/*.test.tsx', 9 | '**/*.spec.js', 10 | '**/*.spec.jsx', 11 | '**/*.spec.ts', 12 | '**/*.spec.tsx', 13 | '**/__tests__/**/*.test.js', 14 | '**/__tests__/**/*.test.jsx', 15 | '**/__tests__/**/*.test.ts', 16 | '**/__tests__/**/*.test.tsx', 17 | '**/__tests__/**/*.spec.js', 18 | '**/__tests__/**/*.spec.jsx', 19 | '**/__tests__/**/*.spec.ts', 20 | '**/__tests__/**/*.spec.tsx', 21 | '**/__tests__/**/*.js', 22 | '**/__tests__/**/*.jsx', 23 | '**/__tests__/**/*.ts', 24 | '**/__tests__/**/*.tsx', 25 | ], 26 | globals: { 27 | React: true, 28 | mount: true, 29 | shallow: true, 30 | render: true, 31 | }, 32 | }, 33 | ], 34 | }; 35 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/src/addMatcher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule addMatcher 6 | * @flow 7 | */ 8 | 9 | import type { MatcherMethods } from 'enzyme-matchers'; 10 | 11 | declare var jasmine: Object; 12 | 13 | const coreMatchers = jasmine.matchers; 14 | let errorThrown = false; 15 | 16 | export default function addMatcher(matcher: MatcherMethods): void { 17 | const matcherName = Object.keys(matcher)[0]; 18 | 19 | /* 20 | * only throw one error so the console doesn't 21 | * become redunant errors 22 | */ 23 | if (coreMatchers[matcherName] && !errorThrown) { 24 | errorThrown = true; 25 | throw new Error(`JasmineEnzyme: Added matcher "${matcherName}" is over-riding 26 | jasmine-core matcher. You must rename the function to 27 | not over-ride anything core.`); 28 | } 29 | 30 | jasmine.addMatchers(matcher); 31 | } 32 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__failing_tests__/toHaveState.test.js: -------------------------------------------------------------------------------- 1 | describe('failing test', () => { 2 | class Fixture extends React.Component { 3 | constructor() { 4 | super(); 5 | this.state = { 6 | foo: true, 7 | }; 8 | } 9 | render() { 10 | return ( 11 |
12 | 13 | {this.state.foo} 14 | 15 | 16 |
17 | ); 18 | } 19 | } 20 | 21 | it('fails toHaveState', () => { 22 | expect(shallow()).toHaveState('baz'); 23 | 24 | expect(shallow()).toHaveState('baz', true); 25 | }); 26 | 27 | it('fails NOT toHaveState', () => { 28 | expect(shallow()).not.toHaveState('foo'); 29 | 30 | expect(shallow()).not.toHaveState('foo', true); 31 | }); 32 | 33 | it('fails toHaveState undefined value', () => { 34 | expect(shallow()).toHaveState('foo', undefined); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toHaveRef.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toHaveRef mount provides contextual information for the message (mount) 1`] = `Object {}`; 4 | 5 | exports[`toHaveRef mount returns the message with the proper fail verbage (mount) 1`] = `"Expected not to find a ref named \\"child\\" on , but did."`; 6 | 7 | exports[`toHaveRef mount returns the message with the proper pass verbage (mount) 1`] = `"Expected to find a ref named \\"child\\" on , but didn't."`; 8 | 9 | exports[`toHaveRef shallow provides contextual information for the message (shallow) 1`] = `Object {}`; 10 | 11 | exports[`toHaveRef shallow returns the message with the proper fail verbage (shallow) 1`] = `"Expected not to find a ref named \\"child\\" on , but did."`; 12 | 13 | exports[`toHaveRef shallow returns the message with the proper pass verbage (shallow) 1`] = `"Expected to find a ref named \\"child\\" on , but didn't."`; 14 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toBeDisabled.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toBeDisabledAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import html from '../utils/html'; 11 | import getNodeName from '../utils/name'; 12 | import single from '../utils/single'; 13 | 14 | function toBeDisabled(enzymeWrapper: EnzymeObject): Matcher { 15 | const pass = !!enzymeWrapper.prop('disabled'); 16 | 17 | return { 18 | pass, 19 | message: `Expected node (${getNodeName( 20 | enzymeWrapper 21 | )}) to be "disabled" but it wasn't.`, 22 | negatedMessage: `Expected node (${getNodeName( 23 | enzymeWrapper 24 | )}) not to be "disabled" but it was`, 25 | contextualInformation: { 26 | expected: `Node HTML output: ${html(enzymeWrapper)}`, 27 | }, 28 | }; 29 | } 30 | 31 | export default single(toBeDisabled); 32 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toExist.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toBePresentAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import html from '../utils/html'; 11 | import getNodeName from '../utils/name'; 12 | 13 | export default function toExist(enzymeWrapper: EnzymeObject): Matcher { 14 | const pass = enzymeWrapper.exists(); 15 | 16 | const contextualInformation = {}; 17 | 18 | if (enzymeWrapper.getElements().length) { 19 | contextualInformation.actual = `Found Nodes: ${html(enzymeWrapper)}`; 20 | } 21 | 22 | const nodeName = getNodeName(enzymeWrapper); 23 | 24 | return { 25 | pass, 26 | message: `Expected "${nodeName}" to exist.`, 27 | negatedMessage: `Expected "${nodeName}" not to exist. Instead found ${enzymeWrapper.getElements() 28 | .length} nodes.`, 29 | contextualInformation, 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toBeEmptyRender.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toBeEmptyRenderAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import name from '../utils/name'; 11 | import html from '../utils/html'; 12 | import single from '../utils/single'; 13 | 14 | function toBeEmptyRender(enzymeWrapper: EnzymeObject): Matcher { 15 | const pass = enzymeWrapper.isEmptyRender(); 16 | 17 | return { 18 | pass, 19 | message: `Expected <${name( 20 | enzymeWrapper 21 | )}> to be empty render (false or null), but it was not`, 22 | negatedMessage: `Expected <${name( 23 | enzymeWrapper 24 | )}> not to be empty render (false or null), but it was`, 25 | contextualInformation: { 26 | actual: `Found Nodes HTML output: ${html(enzymeWrapper)}`, 27 | }, 28 | }; 29 | } 30 | 31 | export default single(toBeEmptyRender); 32 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toBeDisabled.test.js: -------------------------------------------------------------------------------- 1 | const toBeDisabled = require('../toBeDisabled'); 2 | 3 | function Fixture() { 4 | return ( 5 |
6 | 7 | 8 |
9 | ); 10 | } 11 | 12 | describe('toBeDisabled', () => { 13 | const wrapper = shallow(); 14 | const truthyResults = toBeDisabled(wrapper.find('#disabled')); 15 | const falsyResults = toBeDisabled(wrapper.find('#not')); 16 | 17 | it('returns the pass flag properly', () => { 18 | expect(truthyResults.pass).toBe(true); 19 | expect(falsyResults.pass).toBe(false); 20 | }); 21 | 22 | it('returns the message with the proper pass verbage', () => { 23 | expect(truthyResults.message).toMatchSnapshot(); 24 | }); 25 | 26 | it('returns the message with the proper pass verbage', () => { 27 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 28 | }); 29 | 30 | it('provides contextual information for the message', () => { 31 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toMatchSelector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toMatchSelectorAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import name from '../utils/name'; 11 | import html from '../utils/html'; 12 | import single from '../utils/single'; 13 | 14 | function toMatchSelector( 15 | enzymeWrapper: EnzymeObject, 16 | selector: string 17 | ): Matcher { 18 | const pass = enzymeWrapper.is(selector); 19 | const wrapperName = `<${name(enzymeWrapper)}>`; 20 | const wrapperHtml = html(enzymeWrapper); 21 | 22 | return { 23 | pass, 24 | message: `Expected ${wrapperName} component to match the selector "${selector}", but it didn't.`, 25 | negatedMessage: `Expected ${wrapperName} component not to match the selector "${selector}", but it did.`, 26 | contextualInformation: { 27 | actual: wrapperHtml, 28 | }, 29 | }; 30 | } 31 | 32 | export default single(toMatchSelector); 33 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toHaveDisplayName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toHaveTagNameAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import name from '../utils/name'; 11 | import html from '../utils/html'; 12 | import single from '../utils/single'; 13 | 14 | function toHaveDisplayName(enzymeWrapper: EnzymeObject, tag: string): Matcher { 15 | const wrapperHtml = html(enzymeWrapper); 16 | const actualTag = enzymeWrapper.name(); 17 | const pass = actualTag === tag; 18 | 19 | const wrapperName = `<${name(enzymeWrapper)}>`; 20 | 21 | return { 22 | pass, 23 | message: `Expected ${wrapperName} to have display name "${tag}" but it had display name "${actualTag}".`, 24 | negatedMessage: `Expected ${wrapperName} to not have display name "${tag}" but it did.`, 25 | contextualInformation: { 26 | actual: wrapperHtml, 27 | }, 28 | }; 29 | } 30 | 31 | export default single(toHaveDisplayName); 32 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toHaveRef.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toHaveRefAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import name from '../utils/name'; 11 | import single from '../utils/single'; 12 | 13 | function toHaveRef(enzymeWrapper: EnzymeObject, refName: string): Matcher { 14 | if (typeof enzymeWrapper.ref !== 'function') { 15 | throw new Error( 16 | 'EnzymeMatchers::toHaveRef can not be called on a shallow wrapper' 17 | ); 18 | } 19 | 20 | const node = enzymeWrapper.ref(refName); 21 | const pass = !!node; 22 | 23 | return { 24 | pass, 25 | message: `Expected to find a ref named "${refName}" on <${name( 26 | enzymeWrapper 27 | )}>, but didn't.`, 28 | negatedMessage: `Expected not to find a ref named "${refName}" on <${name( 29 | enzymeWrapper 30 | )}>, but did.`, 31 | contextualInformation: {}, 32 | }; 33 | } 34 | 35 | export default single(toHaveRef); 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Blaine Kasten 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toHaveText.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toHaveText mount provides contextual information for the message (mount) 1`] = ` 4 | Object { 5 | "actual": "Actual HTML: \\"Test\\"", 6 | "expected": "Expected HTML: \\"Test\\"", 7 | } 8 | `; 9 | 10 | exports[`toHaveText mount returns the message with the proper fail verbage (mount) 1`] = `"Expected

components text not to match (using ===), but it did."`; 11 | 12 | exports[`toHaveText mount returns the message with the proper pass verbage (mount) 1`] = `"Expected

components text to match (using ===), but it did not."`; 13 | 14 | exports[`toHaveText shallow provides contextual information for the message (shallow) 1`] = ` 15 | Object { 16 | "actual": "Actual HTML: \\"Test\\"", 17 | "expected": "Expected HTML: \\"Test\\"", 18 | } 19 | `; 20 | 21 | exports[`toHaveText shallow returns the message with the proper fail verbage (shallow) 1`] = `"Expected

components text not to match (using ===), but it did."`; 22 | 23 | exports[`toHaveText shallow returns the message with the proper pass verbage (shallow) 1`] = `"Expected

components text to match (using ===), but it did not."`; 24 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toHaveValue.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toHaveValue mount provides contextual information for the message (mount) 1`] = ` 4 | Object { 5 | "actual": "", 6 | } 7 | `; 8 | 9 | exports[`toHaveValue mount returns the message with the proper fail verbage (mount) 1`] = `"Expected component not to have the value of \\"test\\" (using ===), but it did."`; 10 | 11 | exports[`toHaveValue mount returns the message with the proper pass verbage (mount) 1`] = `"Expected component to have the value of \\"test\\" (using ===), but it didn't."`; 12 | 13 | exports[`toHaveValue shallow provides contextual information for the message (shallow) 1`] = ` 14 | Object { 15 | "actual": "", 16 | } 17 | `; 18 | 19 | exports[`toHaveValue shallow returns the message with the proper fail verbage (shallow) 1`] = `"Expected component not to have the value of \\"test\\" (using ===), but it did."`; 20 | 21 | exports[`toHaveValue shallow returns the message with the proper pass verbage (shallow) 1`] = `"Expected component to have the value of \\"test\\" (using ===), but it didn't."`; 22 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toIncludeText.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toIncludeText mount provides contextual information for the message (mount) 1`] = ` 4 | Object { 5 | "actual": "Actual HTML: \\"Some important text\\"", 6 | "expected": "Expected HTML: \\"important\\"", 7 | } 8 | `; 9 | 10 | exports[`toIncludeText mount returns the message with the proper fail verbage (mount) 1`] = `"Expected

not to contain \\"important\\" but it did."`; 11 | 12 | exports[`toIncludeText mount returns the message with the proper pass verbage (mount) 1`] = `"Expected

to contain \\"important\\" but it did not."`; 13 | 14 | exports[`toIncludeText shallow provides contextual information for the message (shallow) 1`] = ` 15 | Object { 16 | "actual": "Actual HTML: \\"Some important text\\"", 17 | "expected": "Expected HTML: \\"important\\"", 18 | } 19 | `; 20 | 21 | exports[`toIncludeText shallow returns the message with the proper fail verbage (shallow) 1`] = `"Expected

not to contain \\"important\\" but it did."`; 22 | 23 | exports[`toIncludeText shallow returns the message with the proper pass verbage (shallow) 1`] = `"Expected

to contain \\"important\\" but it did not."`; 24 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toMatchSelector.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toMatchSelector mount provides contextual information for the message (mount) 1`] = ` 4 | Object { 5 | "actual": "", 6 | } 7 | `; 8 | 9 | exports[`toMatchSelector mount returns the message with the proper fail verbage (mount) 1`] = `"Expected component not to match the selector \\"#child\\", but it did."`; 10 | 11 | exports[`toMatchSelector mount returns the message with the proper pass verbage (mount) 1`] = `"Expected component to match the selector \\"#child\\", but it didn't."`; 12 | 13 | exports[`toMatchSelector shallow provides contextual information for the message (shallow) 1`] = ` 14 | Object { 15 | "actual": "", 16 | } 17 | `; 18 | 19 | exports[`toMatchSelector shallow returns the message with the proper fail verbage (shallow) 1`] = `"Expected component not to match the selector \\"#child\\", but it did."`; 20 | 21 | exports[`toMatchSelector shallow returns the message with the proper pass verbage (shallow) 1`] = `"Expected component to match the selector \\"#child\\", but it didn't."`; 22 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toContainMatchingElement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toContainMatchingElement 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import html from '../utils/html'; 11 | import getDisplayName from '../utils/displayName'; 12 | import getNodeName from '../utils/name'; 13 | 14 | function toContainMatchingElement( 15 | enzymeWrapper: EnzymeObject, 16 | selector: string 17 | ): Matcher { 18 | const matches = enzymeWrapper.find(selector); 19 | const pass = matches.length > 0; 20 | const nodeName = getNodeName(enzymeWrapper); 21 | 22 | return { 23 | pass, 24 | message: 25 | `Expected <${nodeName}> to contain at least one element matching ` + 26 | `"${getDisplayName(selector)}" but none were found.`, 27 | negatedMessage: 28 | `Expected <${nodeName}> to not contain an element matching ` + 29 | `"${getDisplayName(selector)}" but it did.`, 30 | contextualInformation: { 31 | actual: `HTML Output of <${nodeName}>:\n ${html(enzymeWrapper)}`, 32 | }, 33 | }; 34 | } 35 | 36 | export default toContainMatchingElement; 37 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toContainReact.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toContainReactAssertion 6 | * @flow 7 | */ 8 | 9 | import { shallow } from 'enzyme'; 10 | import type { EnzymeObject, Matcher } from '../types'; 11 | import html from '../utils/html'; 12 | import getNodeName from '../utils/name'; 13 | import single from '../utils/single'; 14 | 15 | function toContainReact( 16 | enzymeWrapper: EnzymeObject, 17 | reactInstance: Object 18 | ): Matcher { 19 | const wrappedInstance: EnzymeObject = shallow(reactInstance); 20 | const pass = enzymeWrapper.contains(reactInstance); 21 | 22 | return { 23 | pass, 24 | message: `Expected <${getNodeName(enzymeWrapper)}> to contain ${html( 25 | wrappedInstance 26 | )} but it was not found.`, 27 | negatedMessage: `Expected <${getNodeName( 28 | enzymeWrapper 29 | )}> not to contain ${html(wrappedInstance)} but it does.`, 30 | contextualInformation: { 31 | actual: `HTML Output of <${getNodeName(enzymeWrapper)}>:\n ${html( 32 | enzymeWrapper 33 | )}`, 34 | }, 35 | }; 36 | } 37 | 38 | export default single(toContainReact); 39 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toHaveRef.test.js: -------------------------------------------------------------------------------- 1 | const toHaveRef = require('../toHaveRef'); 2 | 3 | class Fixture extends React.Component { 4 | render() { 5 | return ( 6 |

7 | 8 |
9 | ); 10 | } 11 | } 12 | 13 | describe('toHaveRef', () => { 14 | [shallow, mount].forEach(builder => { 15 | describe(builder.name, () => { 16 | const wrapper = mount(); 17 | const truthyResults = toHaveRef(wrapper, 'child'); 18 | const falsyResults = toHaveRef(wrapper, 'dad'); 19 | 20 | it('returns the pass flag properly', () => { 21 | expect(truthyResults.pass).toBe(true); 22 | expect(falsyResults.pass).toBe(false); 23 | }); 24 | 25 | it(`returns the message with the proper pass verbage (${builder.name})`, () => { 26 | expect(truthyResults.message).toMatchSnapshot(); 27 | }); 28 | 29 | it(`returns the message with the proper fail verbage (${builder.name})`, () => { 30 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 31 | }); 32 | 33 | it(`provides contextual information for the message (${builder.name})`, () => { 34 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 35 | }); 36 | }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toHaveText.test.js: -------------------------------------------------------------------------------- 1 | const toHaveText = require('../toHaveText'); 2 | 3 | function Fixture() { 4 | return ( 5 |
6 |

Test

7 |

8 |

9 | ); 10 | } 11 | 12 | describe('toHaveText', () => { 13 | [shallow, mount].forEach(builder => { 14 | describe(builder.name, () => { 15 | const wrapper = builder().find('#full'); 16 | const truthyResults = toHaveText(wrapper, 'Test'); 17 | const falsyResults = toHaveText(wrapper, 'Turdz'); 18 | 19 | it('returns the pass flag properly', () => { 20 | expect(truthyResults.pass).toBe(true); 21 | expect(falsyResults.pass).toBe(false); 22 | }); 23 | 24 | it(`returns the message with the proper pass verbage (${builder.name})`, () => { 25 | expect(truthyResults.message).toMatchSnapshot(); 26 | }); 27 | 28 | it(`returns the message with the proper fail verbage (${builder.name})`, () => { 29 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 30 | }); 31 | 32 | it(`provides contextual information for the message (${builder.name})`, () => { 33 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 34 | }); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toIncludeText.test.js: -------------------------------------------------------------------------------- 1 | const toIncludeText = require('../toIncludeText'); 2 | 3 | function Fixture() { 4 | return ( 5 |
6 |

Some important text

7 |
8 | ); 9 | } 10 | 11 | describe('toIncludeText', () => { 12 | [shallow, mount].forEach(builder => { 13 | describe(builder.name, () => { 14 | const wrapper = builder().find('p'); 15 | const truthyResults = toIncludeText(wrapper, 'important'); 16 | const falsyResults = toIncludeText(wrapper, 'nope'); 17 | 18 | it('returns the pass flag properly', () => { 19 | expect(truthyResults.pass).toBe(true); 20 | expect(falsyResults.pass).toBe(false); 21 | }); 22 | 23 | it(`returns the message with the proper pass verbage (${builder.name})`, () => { 24 | expect(truthyResults.message).toMatchSnapshot(); 25 | }); 26 | 27 | it(`returns the message with the proper fail verbage (${builder.name})`, () => { 28 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 29 | }); 30 | 31 | it(`provides contextual information for the message (${builder.name})`, () => { 32 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 33 | }); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toHaveHTML.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toHaveHTML mount provides contextual information for the message (mount) 1`] = ` 4 | Object { 5 | "actual": "Actual HTML: Test", 6 | "expected": "Expected HTML: Test", 7 | } 8 | `; 9 | 10 | exports[`toHaveHTML mount returns the message with the proper fail verbage (mount) 1`] = `"Expected html not to match the expected, but it did."`; 11 | 12 | exports[`toHaveHTML mount returns the message with the proper pass verbage (mount) 1`] = `"Expected html to match the expected, but it didn't."`; 13 | 14 | exports[`toHaveHTML shallow provides contextual information for the message (shallow) 1`] = ` 15 | Object { 16 | "actual": "Actual HTML: Test", 17 | "expected": "Expected HTML: Test", 18 | } 19 | `; 20 | 21 | exports[`toHaveHTML shallow returns the message with the proper fail verbage (shallow) 1`] = `"Expected html not to match the expected, but it did."`; 22 | 23 | exports[`toHaveHTML shallow returns the message with the proper pass verbage (shallow) 1`] = `"Expected html to match the expected, but it didn't."`; 24 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toMatchSelector.test.js: -------------------------------------------------------------------------------- 1 | const toMatchSelector = require('../toMatchSelector'); 2 | 3 | function Fixture() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | 11 | describe('toMatchSelector', () => { 12 | [shallow, mount].forEach(builder => { 13 | describe(builder.name, () => { 14 | const wrapper = builder().find('#child'); 15 | const truthyResults = toMatchSelector(wrapper, '#child'); 16 | const falsyResults = toMatchSelector(wrapper, '.doesnt-match'); 17 | 18 | it('returns the pass flag properly', () => { 19 | expect(truthyResults.pass).toBe(true); 20 | expect(falsyResults.pass).toBe(false); 21 | }); 22 | 23 | it(`returns the message with the proper pass verbage (${builder.name})`, () => { 24 | expect(truthyResults.message).toMatchSnapshot(); 25 | }); 26 | 27 | it(`returns the message with the proper fail verbage (${builder.name})`, () => { 28 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 29 | }); 30 | 31 | it(`provides contextual information for the message (${builder.name})`, () => { 32 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 33 | }); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toHaveHTML.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toHaveHTMLAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import name from '../utils/name'; 11 | import single from '../utils/single'; 12 | 13 | function toHaveHTML(enzymeWrapper: EnzymeObject, html: string): Matcher { 14 | const wrapperHTML = enzymeWrapper.html(); 15 | 16 | // normalize quotes 17 | const useSingleQuotes = html.search("'") !== -1; 18 | 19 | const actualHTML = wrapperHTML.replace(/("|')/g, useSingleQuotes ? "'" : '"'); 20 | const expectedHTML = html 21 | .replace(/("|')/g, useSingleQuotes ? "'" : '"') 22 | .replace(/>[\n\t ]+<'); 23 | 24 | const pass = actualHTML === expectedHTML; 25 | 26 | return { 27 | pass, 28 | message: `Expected <${name( 29 | enzymeWrapper 30 | )}> html to match the expected, but it didn't.`, 31 | negatedMessage: `Expected <${name( 32 | enzymeWrapper 33 | )}> html not to match the expected, but it did.`, 34 | contextualInformation: { 35 | actual: `Actual HTML: ${actualHTML}`, 36 | expected: `Expected HTML: ${expectedHTML}`, 37 | }, 38 | }; 39 | } 40 | 41 | export default single(toHaveHTML); 42 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/__tests__/asymmetric-matchers.test.js: -------------------------------------------------------------------------------- 1 | const complexValue = { 2 | simple1: 'value1', 3 | simple2: 'value2', 4 | nested: { prop1: 'value1' }, 5 | }; 6 | 7 | class Fixture extends React.Component { 8 | constructor() { 9 | super(); 10 | this.state = { state1: complexValue }; 11 | } 12 | 13 | render() { 14 | return ( 15 |
16 | {this.state.state1} 17 |
18 | ); 19 | } 20 | } 21 | 22 | describe('Jest-enzyme supports asymmetric matcher', () => { 23 | it('in toHaveProp', () => { 24 | const wrapper = shallow(
Hi
); 25 | 26 | expect(wrapper).toHaveProp('prop1', complexValue); 27 | expect(wrapper).toHaveProp( 28 | 'prop1', 29 | expect.objectContaining({ simple1: 'value1' }) 30 | ); 31 | }); 32 | 33 | it('in toHaveState', () => { 34 | const wrapper = shallow(); 35 | 36 | expect(wrapper).toHaveState('state1', complexValue); 37 | expect(wrapper).toHaveState( 38 | 'state1', 39 | expect.objectContaining({ simple1: 'value1' }) 40 | ); 41 | }); 42 | 43 | it('in toHaveStyle', () => { 44 | const wrapper = shallow(
Hi
); 45 | 46 | expect(wrapper).toHaveStyle('height', '100%'); 47 | expect(wrapper).toHaveStyle('height', expect.stringContaining('%')); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toIncludeText.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toIncludeTextAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import name from '../utils/name'; 11 | import single from '../utils/single'; 12 | 13 | function toIncludeText(enzymeWrapper: EnzymeObject, text: string): Matcher { 14 | const actualText = enzymeWrapper.text(); 15 | 16 | if (text === undefined) { 17 | const message = `Expected ".toIncludeText(null)" to be given some text. 18 | If you are trying to assert this component has _some_ text, use the ".toHaveText()" matcher`; 19 | return { 20 | pass: false, 21 | message, 22 | negatedMessage: message, 23 | contextualInformation: {}, 24 | }; 25 | } 26 | 27 | const pass = actualText.includes(text); 28 | const wrapperName = `<${name(enzymeWrapper)}>`; 29 | 30 | return { 31 | pass, 32 | message: `Expected ${wrapperName} to contain "${text}" but it did not.`, 33 | negatedMessage: `Expected ${wrapperName} not to contain "${text}" but it did.`, 34 | contextualInformation: { 35 | expected: `Expected HTML: "${text}"`, 36 | actual: `Actual HTML: "${actualText}"`, 37 | }, 38 | }; 39 | } 40 | 41 | export default single(toIncludeText); 42 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toContainMatchingElements.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toContainMatchingElements 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import html from '../utils/html'; 11 | import getDisplayName from '../utils/displayName'; 12 | import getNodeName from '../utils/name'; 13 | 14 | function toContainMatchingElements( 15 | enzymeWrapper: EnzymeObject, 16 | n: number, 17 | selector: string 18 | ): Matcher { 19 | const matches = enzymeWrapper.find(selector); 20 | const pass = matches.length === n; 21 | const nodeName = getNodeName(enzymeWrapper); 22 | 23 | return { 24 | pass, 25 | message: 26 | `Expected <${nodeName}> to contain ${n} element${n === 1 27 | ? '' 28 | : 's'} matching ` + 29 | `"${getDisplayName(selector)}" but ${matches.length} ${matches.length === 30 | 1 31 | ? 'was' 32 | : 'were'} found.`, 33 | negatedMessage: `Expected <${nodeName}> to not contain ${n} element${n === 1 34 | ? '' 35 | : 's'} matching "${getDisplayName(selector)}" but it did.`, 36 | contextualInformation: { 37 | actual: `HTML Output of <${nodeName}>:\n ${html(enzymeWrapper)}`, 38 | }, 39 | }; 40 | } 41 | 42 | export default toContainMatchingElements; 43 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toHaveValue.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toHaveValueAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import name from '../utils/name'; 11 | import html from '../utils/html'; 12 | import single from '../utils/single'; 13 | 14 | function toHaveValue(enzymeWrapper: EnzymeObject, expectedValue: any): Matcher { 15 | let pass = false; 16 | 17 | const props = enzymeWrapper.props(); 18 | const wrapperName = `<${name(enzymeWrapper)}>`; 19 | const wrapperHtml = html(enzymeWrapper); 20 | 21 | // set to the default checked 22 | if (props.hasOwnProperty('defaultValue')) { 23 | pass = props.defaultValue === expectedValue; 24 | } 25 | 26 | // if it has the `value` property, CHECK that 27 | if (props.hasOwnProperty('value')) { 28 | pass = props.value === expectedValue; 29 | } 30 | 31 | return { 32 | pass, 33 | message: `Expected ${wrapperName} component to have the value of "${expectedValue}" (using ===), but it didn't.`, 34 | negatedMessage: `Expected ${wrapperName} component not to have the value of "${expectedValue}" (using ===), but it did.`, 35 | contextualInformation: { 36 | actual: wrapperHtml, 37 | }, 38 | }; 39 | } 40 | 41 | export default single(toHaveValue); 42 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare namespace jest { 4 | interface ToMatchElementOptions { 5 | ignoreProps?: boolean; 6 | } 7 | interface Matchers { 8 | toBeChecked(): void; 9 | toBeDisabled(): void; 10 | toBeEmptyRender(): void; 11 | toContainMatchingElement(selector: string): void; 12 | toContainMatchingElements(n: number, selector: string): void; 13 | toContainExactlyOneMatchingElement(selector: string): void; 14 | toContainReact(component: React.ReactElement): void; 15 | toExist(): void; 16 | toHaveClassName(className: string): void; 17 | toHaveDisplayName(tagName: string): void; 18 | toHaveHTML(html: string): void; 19 | toHaveProp(propKey: object|string, propValue?: any): void; 20 | toHaveRef(refName: string): void; 21 | toHaveState(stateKey: object|string, stateValue?: any): void; 22 | toHaveStyle(styleKey: object|string, styleValue?: any): void; 23 | toHaveTagName(tagName: string): void; 24 | toHaveText(text: string): void; 25 | toHaveValue(value: any): void; 26 | toIncludeText(text: string): void; 27 | toMatchElement( 28 | element: React.ReactElement, 29 | options?: ToMatchElementOptions, 30 | ): void; 31 | toMatchSelector(selector: string): void; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/protectAssertion.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function protectAssertion 3 | * 4 | * This should wrap every assertion this library outputs. 5 | * It is intended to help with developers to understand errors 6 | * when an enzyme-matchers assertion is used with a non-enzyme object. 7 | * 8 | * @flow 9 | */ 10 | 11 | import type { Assertion, EnzymeObject, Matcher } from '../types'; 12 | 13 | function heuristicCheck(arg: any): boolean { 14 | try { 15 | const shouldBeEmptyEnzyme = arg.find('asjdfsaf'); 16 | return shouldBeEmptyEnzyme.length === 0; 17 | } catch (e) { 18 | return false; 19 | } 20 | } 21 | 22 | const ERROR_MESSAGE = assertion => 23 | `The test assertion ${assertion.name} is part of the enzyme-matcher suite. 24 | It appears you tried calling this matcher with a non-enzyme object. 25 | This assertion must be called against a shallow, mount, or render-ed react component. 26 | `; 27 | 28 | const protectAssertion = (assertion: Assertion): Assertion => 29 | function assertionWrapper(enzymeWrapper: EnzymeObject, ...args): Matcher { 30 | if (heuristicCheck(enzymeWrapper) === false) { 31 | throw new Error(ERROR_MESSAGE(assertion)); 32 | } 33 | 34 | // Using `.call` to make sure we bind the runtime environment into the Matcher 35 | // so we can use asymmetric equalities. 36 | return assertion.call(this, enzymeWrapper, ...args); 37 | }; 38 | 39 | export default protectAssertion; 40 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toBeChecked.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toBeCheckedAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import getNodeName from '../utils/name'; 11 | import html from '../utils/html'; 12 | import single from '../utils/single'; 13 | 14 | function toBeChecked(enzymeWrapper: EnzymeObject): Matcher { 15 | let pass: boolean = false; 16 | 17 | const props: Object = enzymeWrapper.props(); 18 | 19 | // Use `defaultChecked` if present. 20 | if ( 21 | props.hasOwnProperty('defaultChecked') && 22 | typeof props.defaultChecked === 'boolean' 23 | ) { 24 | pass = props.defaultChecked; 25 | } 26 | 27 | // Use `checked` if present, will take precedence over `defaultChecked`. 28 | if (props.hasOwnProperty('checked') && typeof props.checked === 'boolean') { 29 | pass = props.checked; 30 | } 31 | 32 | return { 33 | pass, 34 | message: `Expected "${getNodeName( 35 | enzymeWrapper 36 | )}" to be checked but it wasn't.`, 37 | negatedMessage: `Expected "${getNodeName( 38 | enzymeWrapper 39 | )}" not to be checked but it was.`, 40 | contextualInformation: { 41 | actual: `Node HTML output: ${html(enzymeWrapper)}`, 42 | }, 43 | }; 44 | } 45 | 46 | export default single(toBeChecked); 47 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toContainReact.test.js: -------------------------------------------------------------------------------- 1 | const PropTypes = require('prop-types'); 2 | 3 | const toContainReact = require('../toContainReact'); 4 | 5 | function User(props) { 6 | return ( 7 | 8 | User {props.index} 9 | 10 | ); 11 | } 12 | 13 | User.propTypes = { 14 | index: PropTypes.number.isRequired, 15 | }; 16 | 17 | function Fixture() { 18 | return ( 19 |
20 |
    21 |
  • 22 | 23 |
  • 24 |
  • 25 | 26 |
  • 27 |
28 |
29 | ); 30 | } 31 | 32 | describe('toContainReact', () => { 33 | const wrapper = shallow(); 34 | const truthyResults = toContainReact(wrapper, ); 35 | const falsyResults = toContainReact(wrapper, ); 36 | 37 | it('returns the pass flag properly', () => { 38 | expect(truthyResults.pass).toBe(true); 39 | expect(falsyResults.pass).toBe(false); 40 | }); 41 | 42 | it('returns the message with the proper pass verbage', () => { 43 | expect(truthyResults.message).toMatchSnapshot(); 44 | }); 45 | 46 | it('returns the message with the proper fail verbage', () => { 47 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 48 | }); 49 | 50 | it('provides contextual information for the message', () => { 51 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toMatchElement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toMatchElementAssertion 6 | * @flow 7 | */ 8 | 9 | import { shallow, mount } from 'enzyme'; 10 | import type { EnzymeObject, Matcher, ToMatchElementOptions } from '../types'; 11 | import isShallowWrapper from '../utils/isShallowWrapper'; 12 | import single from '../utils/single'; 13 | 14 | function toMatchElement( 15 | actualEnzymeWrapper: EnzymeObject, 16 | reactInstance: Object, 17 | options: ToMatchElementOptions = { ignoreProps: true } 18 | ): Matcher { 19 | let expectedWrapper: EnzymeObject; 20 | if (!isShallowWrapper(actualEnzymeWrapper)) { 21 | expectedWrapper = mount(reactInstance); 22 | } else { 23 | expectedWrapper = shallow(reactInstance); 24 | } 25 | 26 | const actual = actualEnzymeWrapper.debug({ verbose: true, ...options }); 27 | const expected = expectedWrapper.debug({ verbose: true, ...options }); 28 | const pass = actual === expected; 29 | 30 | return { 31 | pass, 32 | message: 'Expected actual value to match the expected value.', 33 | negatedMessage: 'Did not expect actual value to match the expected value.', 34 | contextualInformation: { 35 | actual: `Actual:\n ${actual}`, 36 | expected: `Expected:\n ${expected}`, 37 | }, 38 | }; 39 | } 40 | 41 | export default single(toMatchElement); 42 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toExist.test.js: -------------------------------------------------------------------------------- 1 | const React = require('react'); 2 | const toExist = require('../toExist'); 3 | 4 | function Fixture() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | 12 | describe('toExist', () => { 13 | const wrapper = shallow(); 14 | const truthyResults = toExist(wrapper.find('.matches')); 15 | const falsyResults = toExist(wrapper.find('.doesnt-matches')); 16 | 17 | it('returns the pass flag properly', () => { 18 | expect(truthyResults.pass).toBe(true); 19 | expect(falsyResults.pass).toBe(false); 20 | }); 21 | 22 | it('returns the message with the proper pass verbage', () => { 23 | expect(truthyResults.message).toMatchSnapshot(); 24 | }); 25 | 26 | it('returns the message with the proper fail verbage', () => { 27 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 28 | }); 29 | 30 | it('provides contextual information for the message', () => { 31 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 32 | expect(falsyResults.contextualInformation).toMatchSnapshot(); 33 | }); 34 | 35 | it('works for Fragments', () => { 36 | function Test() { 37 | return ( 38 | 39 |
1
40 |
2
41 |
42 | ); 43 | } 44 | 45 | const result = toExist(shallow()); 46 | expect(result.pass).toBe(true); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toBeEmptyRender.test.js: -------------------------------------------------------------------------------- 1 | const toBeEmptyRender = require('../toBeEmptyRender'); 2 | 3 | function EmptyRenderFixture() { 4 | return null; 5 | } 6 | 7 | function NonEmptyRenderFixture() { 8 | return ( 9 |
10 | 11 |
12 | ); 13 | } 14 | 15 | describe('toBeEmptyRender', () => { 16 | const wrapper = mount(); 17 | 18 | const truthyResults = toBeEmptyRender(wrapper.find('EmptyRenderFixture')); 19 | 20 | const falsyResults = toBeEmptyRender(wrapper); 21 | 22 | it('returns the pass flag properly', () => { 23 | expect(truthyResults.pass).toBe(true); 24 | expect(falsyResults.pass).toBe(false); 25 | }); 26 | 27 | it('returns the message with the proper pass verbage', () => { 28 | expect(truthyResults.message).toMatchSnapshot(); 29 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 30 | }); 31 | 32 | it('provides contextual information for the message', () => { 33 | expect(falsyResults.contextualInformation).toMatchSnapshot(); 34 | }); 35 | 36 | it('considers both false and null to be empty renders', () => { 37 | const NullRenderer = () => null; 38 | const nullWrapper = shallow(); 39 | expect(toBeEmptyRender(nullWrapper).pass).toBe(true); 40 | 41 | const FalseRenderer = () => false; 42 | const falseWrapper = shallow(); 43 | expect(toBeEmptyRender(falseWrapper).pass).toBe(true); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toHaveText.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toHaveTextAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import name from '../utils/name'; 11 | import html from '../utils/html'; 12 | import single from '../utils/single'; 13 | 14 | function toHaveText(enzymeWrapper: EnzymeObject, text: string): Matcher { 15 | const actualText = enzymeWrapper.text(); 16 | const wrapperName = `<${name(enzymeWrapper)}>`; 17 | const wrapperHtml = html(enzymeWrapper); 18 | let pass; 19 | 20 | if (text === undefined) { 21 | pass = actualText.length > 0; 22 | return { 23 | pass, 24 | message: `Expected ${wrapperName} node to have text, but it did not.`, 25 | negatedMessage: `Expected ${wrapperName} node not to have text, but it did`, 26 | contextualInformation: { 27 | actual: `Actual HTML: "${wrapperHtml}"`, 28 | }, 29 | }; 30 | } 31 | 32 | pass = actualText === text; 33 | 34 | return { 35 | pass, 36 | message: `Expected ${wrapperName} components text to match (using ===), but it did not.`, 37 | negatedMessage: `Expected ${wrapperName} components text not to match (using ===), but it did.`, 38 | contextualInformation: { 39 | actual: `Actual HTML: "${actualText}"`, 40 | expected: `Expected HTML: "${text}"`, 41 | }, 42 | }; 43 | } 44 | 45 | export default single(toHaveText); 46 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/__tests__/protectAssertion.test.js: -------------------------------------------------------------------------------- 1 | import protectAssertion from '../protectAssertion'; 2 | 3 | describe('protectAssertion', () => { 4 | const typesToCheck = [ 5 | [], 6 | {}, 7 | 1, 8 | 'string', 9 | new Promise(jest.fn), 10 | class Foo {}, 11 | mount, 12 | shallow, 13 | true, 14 | { find: jest.fn() }, 15 | ]; 16 | 17 | typesToCheck.forEach(type => { 18 | it(`throws an error if the first argument is like ${type}`, () => { 19 | const assertion = jest.fn(); 20 | const protectedAssertion = protectAssertion(assertion); 21 | 22 | expect(() => protectedAssertion(type)).toThrow(); 23 | }); 24 | }); 25 | 26 | [mount, shallow].forEach(builder => { 27 | it(`(${builder.name}) calls the underlying matcher if given an enzyme object`, () => { 28 | const assertion = jest.fn(); 29 | const protectedAssertion = protectAssertion(assertion); 30 | const wrapper = builder(
); 31 | 32 | protectedAssertion(wrapper); 33 | expect(assertion).toBeCalledWith(wrapper); 34 | }); 35 | }); 36 | 37 | it('prints a helpful error message', () => { 38 | function testAssertion() {} 39 | const protectedAssertion = protectAssertion(testAssertion); 40 | 41 | expect(() => protectedAssertion()).toThrow( 42 | `The test assertion testAssertion is part of the enzyme-matcher suite. 43 | It appears you tried calling this matcher with a non-enzyme object. 44 | This assertion must be called against a shallow, mount, or render-ed react component. 45 | ` 46 | ); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toBeChecked.test.js: -------------------------------------------------------------------------------- 1 | const toBeChecked = require('../toBeChecked'); 2 | 3 | function Fixture() { 4 | return ( 5 |
6 | 7 | 8 | 9 | 10 |
11 | ); 12 | } 13 | 14 | describe('toBeChecked', () => { 15 | const wrapper = shallow(); 16 | const truthyResults = toBeChecked(wrapper.find('#checked')); 17 | const falsyResults = toBeChecked(wrapper.find('#not')); 18 | 19 | it('returns the pass flag properly', () => { 20 | expect(truthyResults.pass).toBe(true); 21 | expect(falsyResults.pass).toBe(false); 22 | }); 23 | 24 | it('returns the message with the proper pass verbage', () => { 25 | expect(truthyResults.message).toMatchSnapshot(); 26 | }); 27 | 28 | it('returns the negatedMessage with the proper fail verbage', () => { 29 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 30 | }); 31 | 32 | it('provides contextual information for the message', () => { 33 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 34 | }); 35 | 36 | it('`checked` should take precedence over `defaultChecked`', () => { 37 | const result = toBeChecked(wrapper.find('#precedence')); 38 | 39 | expect(result.pass).toBe(true); 40 | }); 41 | 42 | it('should not fail on undefined values', () => { 43 | const result = toBeChecked(wrapper.find('#safe')); 44 | 45 | expect(result.pass).toBe(false); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/__tests__/single.test.js: -------------------------------------------------------------------------------- 1 | const single = require('../single'); 2 | 3 | describe('single', () => { 4 | const matcherFn = jest.fn(() => 0x3); 5 | 6 | beforeEach(matcherFn.mockClear); 7 | 8 | it('Returns an error when called with 0 nodes', () => { 9 | const results = single(matcherFn)({ 10 | getElements() { 11 | return []; 12 | }, 13 | }); 14 | 15 | expect(results.pass).toBeFalsy(); 16 | expect(matcherFn).not.toBeCalled(); 17 | }); 18 | 19 | it('Returns an error when called with 2+ nodes', () => { 20 | const results = single(matcherFn)({ 21 | getElements() { 22 | return [1, 2, 3]; 23 | }, 24 | }); 25 | 26 | expect(results.pass).toBeFalsy(); 27 | expect(matcherFn).not.toBeCalled(); 28 | }); 29 | 30 | it('calls the matcherFn and returns the results when only 1 node', () => { 31 | const results = single(matcherFn)({ 32 | getElements() { 33 | return [1]; 34 | }, 35 | }); 36 | 37 | expect(results).toBe(0x3); 38 | expect(matcherFn).toBeCalled(); 39 | }); 40 | 41 | it('gives a useful message', () => { 42 | const results = single(matcherFn)({ 43 | getElements() { 44 | return [1, 2, 3]; 45 | }, 46 | }); 47 | 48 | // This helps the snapshot be compatible accross different environments 49 | results.message = results.message.replace('mockConstructor', ''); 50 | results.negatedMessage = results.negatedMessage.replace( 51 | 'mockConstructor', 52 | '' 53 | ); 54 | 55 | expect(results).toMatchSnapshot(); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /packages/jest-environment-enzyme/src/setup.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | 3 | // eslint-disable-next-line import/prefer-default-export 4 | export const exposeGlobals = () => { 5 | let dep; 6 | switch (global.enzymeAdapterDescriptor) { 7 | case 'react13': 8 | dep = 'enzyme-adapter-react-13'; 9 | break; 10 | case 'react14': 11 | dep = 'enzyme-adapter-react-14'; 12 | break; 13 | case 'react15': 14 | dep = 'enzyme-adapter-react-15'; 15 | break; 16 | case 'react15.4': 17 | dep = 'enzyme-adapter-react-15.4'; 18 | break; 19 | case 'react16': 20 | default: 21 | dep = 'enzyme-adapter-react-16'; 22 | } 23 | 24 | let Adapter; 25 | try { 26 | // eslint-disable-next-line import/no-dynamic-require 27 | Adapter = require(dep); 28 | } catch (e) { 29 | // eslint-disable-next-line no-console 30 | console.error( 31 | ` 32 | Requiring the proper enzyme-adapter during jest-enzyme setup failed. 33 | This most likely happens when your application does not properly list the 34 | adapter in your devDependencies. Run this line to add the correct adapter: 35 | 36 | > yarn add --dev ${dep} 37 | 38 | or with npm 39 | 40 | > npm i --save-dev ${dep} 41 | `, e, 42 | ); 43 | return; 44 | } 45 | 46 | const { configure, mount, render, shallow } = require('enzyme'); 47 | // Setup Enzyme Adapter 48 | configure({ adapter: new Adapter() }); 49 | global.shallow = shallow; 50 | global.mount = mount; 51 | global.render = render; 52 | global.React = require('react'); 53 | }; 54 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toHaveValue.test.js: -------------------------------------------------------------------------------- 1 | const toHaveValue = require('../toHaveValue'); 2 | 3 | function Fixture() { 4 | return ( 5 |
6 | 7 | 8 |
9 | ); 10 | } 11 | 12 | describe('toHaveValue', () => { 13 | [shallow, mount].forEach(builder => { 14 | describe(builder.name, () => { 15 | const wrapper = builder().find('input').first(); 16 | const truthyResults = toHaveValue(wrapper, 'test'); 17 | const falsyResults = toHaveValue(wrapper, 'Turdz'); 18 | 19 | it('returns the pass flag properly', () => { 20 | expect(truthyResults.pass).toBe(true); 21 | expect(falsyResults.pass).toBe(false); 22 | }); 23 | 24 | it(`returns the message with the proper pass verbage (${builder.name})`, () => { 25 | expect(truthyResults.message).toMatchSnapshot(); 26 | }); 27 | 28 | it(`returns the message with the proper fail verbage (${builder.name})`, () => { 29 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 30 | }); 31 | 32 | it(`provides contextual information for the message (${builder.name})`, () => { 33 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 34 | }); 35 | }); 36 | 37 | it('prioritizes `value` over `defaultValue`', () => { 38 | const _wrapper = shallow().find('input').at(1); 39 | expect(toHaveValue(_wrapper, 'bar').pass).toBe(true); 40 | 41 | expect(toHaveValue(_wrapper, 'foo').pass).toBe(false); 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /packages/jest-environment-enzyme/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jest-environment-enzyme", 3 | "version": "7.1.2", 4 | "description": "Runtime Environment for enzyme tests in jest", 5 | "main": "lib/index.js", 6 | "author": "Blaine Kasten ", 7 | "license": "MIT", 8 | "homepage": "https://github.com/FormidableLabs/enzyme-matchers/blob/master/packages/jest-environment-enzyme#readme", 9 | "scripts": { 10 | "lint": "eslint ./src", 11 | "clean": "rm -rf ./lib", 12 | "build:js": "babel --root-mode upward src --out-dir lib --ignore '**/__tests__/*.js'", 13 | "copy-dts": "cpy src/index.d.ts lib", 14 | "build": "npm run clean && npm run build:js && npm run copy-dts", 15 | "prepublish": "npm run build" 16 | }, 17 | "files": [ 18 | "lib" 19 | ], 20 | "types": "lib/index.d.ts", 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/FormidableLabs/enzyme-matchers.git" 24 | }, 25 | "keywords": [ 26 | "javascript", 27 | "shallow rendering", 28 | "shallowRender", 29 | "test", 30 | "reactjs", 31 | "react", 32 | "flux", 33 | "testing", 34 | "test utils", 35 | "assertion helpers", 36 | "tdd", 37 | "jest", 38 | "enzyme" 39 | ], 40 | "bugs": { 41 | "url": "https://github.com/FormidableLabs/enzyme-matchers/issues" 42 | }, 43 | "peerDependencies": { 44 | "enzyme": "3.x", 45 | "jest": ">=22.0.0", 46 | "react": "^0.13.0 || ^0.14.0 || ^15.0.0 || >=16.x" 47 | }, 48 | "devDependencies": { 49 | "cpy-cli": "^2.0.0" 50 | }, 51 | "dependencies": { 52 | "jest-environment-jsdom": "^25.2.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/jest-enzyme/src/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | /** 3 | * This source code is licensed under the MIT-style license found in the 4 | * LICENSE file in the root directory of this source tree. * 5 | * 6 | * @providesModule setupFilesAfterEnv 7 | * @flow 8 | */ 9 | 10 | import enzymeMatchers from 'enzyme-matchers'; 11 | import serializer from 'enzyme-to-json/serializer'; 12 | 13 | declare var expect: Function; 14 | 15 | if (global.bootstrapEnzymeEnvironment) { 16 | const { exposeGlobals } = require('jest-environment-enzyme/lib/setup'); 17 | 18 | exposeGlobals(); 19 | } 20 | 21 | // add the snapshot serializer for Enzyme wrappers 22 | expect.addSnapshotSerializer(serializer); 23 | 24 | // add methods! 25 | const matchers = {}; 26 | 27 | Object.keys(enzymeMatchers).forEach(matcherKey => { 28 | const matcher = { 29 | [matcherKey](wrapper, ...args) { 30 | const result = enzymeMatchers[matcherKey].call(this, wrapper, ...args); 31 | 32 | let message = this.isNot ? result.negatedMessage : result.message; 33 | 34 | if (result.contextualInformation.expected) { 35 | message += `\n${this.utils.RECEIVED_COLOR( 36 | result.contextualInformation.expected 37 | )}`; 38 | } 39 | 40 | if (result.contextualInformation.actual) { 41 | message += `\n${this.utils.EXPECTED_COLOR( 42 | result.contextualInformation.actual 43 | )}`; 44 | } 45 | 46 | return { 47 | ...result, 48 | message: () => message, 49 | }; 50 | }, 51 | }[matcherKey]; 52 | 53 | matchers[matcherKey] = matcher; 54 | }); 55 | 56 | expect.extend(matchers); 57 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toHaveHTML.test.js: -------------------------------------------------------------------------------- 1 | const toHaveHTML = require('../toHaveHTML'); 2 | 3 | function Fixture() { 4 | return ( 5 |
6 | 7 | Test 8 | 9 |
10 | ); 11 | } 12 | 13 | const html = 'Test'; 14 | 15 | const multilineHtml = ` 16 | Test 17 | `; 18 | 19 | describe('toHaveHTML', () => { 20 | [shallow, mount].forEach(builder => { 21 | describe(builder.name, () => { 22 | const wrapper = builder(); 23 | const truthyResults = toHaveHTML(wrapper.find('#child'), html); 24 | const truthyMultilineResults = toHaveHTML( 25 | wrapper.find('#child'), 26 | multilineHtml 27 | ); 28 | const falsyResults = toHaveHTML(wrapper.find('#child'), 'foo'); 29 | 30 | it('returns the pass flag properly', () => { 31 | expect(truthyResults.pass).toBe(true); 32 | expect(truthyMultilineResults.pass).toBe(true); 33 | expect(falsyResults.pass).toBe(false); 34 | }); 35 | 36 | it(`returns the message with the proper pass verbage (${builder.name})`, () => { 37 | expect(truthyResults.message).toMatchSnapshot(); 38 | }); 39 | 40 | it(`returns the message with the proper fail verbage (${builder.name})`, () => { 41 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 42 | }); 43 | 44 | it(`provides contextual information for the message (${builder.name})`, () => { 45 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 46 | }); 47 | }); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toHaveClassName.test.js: -------------------------------------------------------------------------------- 1 | const toHaveClassName = require('../toHaveClassName'); 2 | 3 | function Fixture() { 4 | return ( 5 |
6 | 7 | 8 | 9 | 10 |
11 | ); 12 | } 13 | 14 | describe('toHaveClassName', () => { 15 | [shallow, mount].forEach(builder => { 16 | describe(builder.name, () => { 17 | const wrapper = builder(); 18 | const truthyResults = toHaveClassName(wrapper.find('.bar'), 'bar'); 19 | const falsyResults = toHaveClassName(wrapper.find('.bar'), 'asldfkj'); 20 | 21 | it('returns the pass flag properly', () => { 22 | expect(truthyResults.pass).toBe(true); 23 | expect(falsyResults.pass).toBe(false); 24 | }); 25 | 26 | it(`returns the message with the proper pass verbage (${builder.name})`, () => { 27 | expect(truthyResults.message).toMatchSnapshot(); 28 | }); 29 | 30 | it(`returns the message with the proper fail verbage (${builder.name})`, () => { 31 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 32 | }); 33 | 34 | it(`provides contextual information for the message (${builder.name})`, () => { 35 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 36 | }); 37 | 38 | it(`works for multiple nodes (${builder.name})`, () => { 39 | const multipleNodes = wrapper.find('.baux'); 40 | 41 | const results = toHaveClassName(multipleNodes, 'baux'); 42 | 43 | expect(results).toMatchSnapshot(); 44 | }); 45 | }); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/single.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 hudl 3 | * All rights reserved. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * @providesModule single 18 | * @flow 19 | * 20 | * This ensures a matcher can only be called with a single enzymeWrapper 21 | */ 22 | 23 | import type { EnzymeObject } from '../types'; 24 | 25 | export default function single(matcherFn: Function) { 26 | return function singleWrapper( 27 | enzymeWrapper: EnzymeObject, 28 | ...args: Array 29 | ) { 30 | let message; 31 | switch (enzymeWrapper.getElements().length) { 32 | case 0: 33 | message = `${matcherFn.name} must be called on a single node, not an empty node.`; 34 | break; 35 | case 1: 36 | break; 37 | default: 38 | message = `${matcherFn.name} must be called on a single node, not multiple nodes.`; 39 | } 40 | 41 | if (message) { 42 | return { 43 | pass: false, 44 | message, 45 | negatedMessage: message, 46 | contextualInformation: {}, 47 | }; 48 | } 49 | 50 | return matcherFn.call(this, enzymeWrapper, ...args); // Preserve utilities set inside this for the matchers 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /packages/jest-environment-enzyme/README.md: -------------------------------------------------------------------------------- 1 | # jest-environment-enzyme 2 | 3 | [![npm version](https://img.shields.io/npm/v/jest-environment-enzyme.svg)](https://www.npmjs.com/package/jest-environment-enzyme) 4 | ![License](https://img.shields.io/npm/l/chai-enzyme.svg) 5 | 6 | ### Overview 7 | 8 | Setting up Enzyme with Jest and React is a somewhat complicated process. There are a lot of dependencies, configuring adapters, etc. This module will take lessen that setup and make it more declarative. 9 | This package will also simplify your test files by declaring React, and enzyme wrappers in the global scope. This means that all of your test files don't need to include imports for React or enzyme. 10 | 11 | The setup can be as simple as this: 12 | 13 | ``` 14 | yarn add jest-environment-enzyme jest-enzyme enzyme-adapter-react-* --dev 15 | ``` 16 | 17 | > (Where * is your app's adapter that matches your React version) 18 | 19 | For example, if you are using react-16, it should look like: 20 | 21 | ``` 22 | yarn add jest-environment-enzyme jest-enzyme enzyme-adapter-react-16 --dev 23 | ``` 24 | 25 | ```js 26 | // package.json 27 | "jest": { 28 | "setupFilesAfterEnv": ["jest-enzyme"], 29 | "testEnvironment": "enzyme" 30 | } 31 | ``` 32 | 33 | Additionally, you can specify which enzyme adapter you want to use through the `testEnvironmentOptions.enzymeAdapter`. 34 | 35 | Valid options are: 36 | 37 | * `react13` 38 | * `react14` 39 | * `react15` 40 | * `react15.4` 41 | * `react16` (default) 42 | 43 | ```js 44 | // package.json 45 | "jest": { 46 | "setupFilesAfterEnv": ["jest-enzyme"], 47 | "testEnvironment": "enzyme", 48 | "testEnvironmentOptions": { 49 | "enzymeAdapter": "react16" 50 | } 51 | } 52 | ``` 53 | 54 | *Lastly, and _most importantly_*, this library has a hard requirement on `jest-enzyme`. 55 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/__tests__/html.test.js: -------------------------------------------------------------------------------- 1 | const html = require('../html'); 2 | 3 | describe('html', () => { 4 | const inputStrings = { 5 | shallow: '', 6 | mount: '', 7 | }; 8 | 9 | [shallow, mount].forEach(builder => { 10 | describe(builder.name, () => { 11 | it(`prints the html for a single node (${builder.name})`, () => { 12 | expect(html(builder())).toBe(inputStrings[builder.name]); 13 | }); 14 | 15 | it(`prints the html for multiple nodes (${builder.name})`, () => { 16 | const Fixture = () => 17 |
18 | 19 | 20 |
; 21 | 22 | expect(html(builder().find('i'))).toBe(`Multiple nodes found: 23 | 0: 24 | 1: 25 | `); 26 | }); 27 | 28 | it('prints props with nodes', () => { 29 | const Fixture = () => 30 |
31 | 32 | 33 |
; 34 | 35 | expect(html(builder().find('i'))).toBe(`Multiple nodes found: 36 | 0: 37 | 1: 38 | `); 39 | }); 40 | }); 41 | }); 42 | 43 | describe('isShallowWrapper', () => { 44 | it('still correctly identifies ShallowWrapper instances if function.name is unavailable', () => { 45 | const Foo = () => 46 |
47 | 48 |
; 49 | const Bar = () => 50 |
51 | 52 |
; 53 | const wrapper = shallow(); 54 | // simulate platforms where function.name is undefined 55 | wrapper.constructor = { toString: () => 'function ShallowWrapper() {}' }; 56 | expect(html(wrapper)).toBe('
'); 57 | }); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "enzyme-matchers", 3 | "version": "7.1.2", 4 | "description": "Testing Matchers for Enzyme", 5 | "main": "lib/index.js", 6 | "homepage": "https://github.com/FormidableLabs/enzyme-matchers/packages/enzyme-matchers#readme", 7 | "author": "Blaine Kasten ", 8 | "license": "MIT", 9 | "scripts": { 10 | "pretest": "node ../../scripts/jest.js", 11 | "test": "node ../../node_modules/jest-cli/bin/jest.js", 12 | "jest": "node ../../node_modules/jest-cli/bin/jest.js", 13 | "lint": "eslint ./src", 14 | "clean": "rm -rf ./lib", 15 | "build:js": "babel --root-mode upward src --out-dir lib --ignore '**/__tests__/*.js'", 16 | "build:flow": "flow-copy-source -v -i '**/__tests__/*.js' src lib", 17 | "build": "npm run clean && npm run build:js && npm run build:flow", 18 | "prepublish": "npm run build" 19 | }, 20 | "files": [ 21 | "lib" 22 | ], 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/FormidableLabs/enzyme-matchers.git" 26 | }, 27 | "bugs": { 28 | "url": "https://github.com/FormidableLabs/enzyme-matchers/issues" 29 | }, 30 | "peerDependencies": { 31 | "enzyme": ">=3.4.0" 32 | }, 33 | "dependencies": { 34 | "circular-json-es6": "^2.0.1", 35 | "deep-equal-ident": "^1.1.1" 36 | }, 37 | "devDependencies": { 38 | "enzyme": "^3.4.0", 39 | "flow-bin": "^0.105.2" 40 | }, 41 | "jest": { 42 | "transform": { 43 | "^.+\\.js$": "../../babel-jest-root-mode-wrapper.js" 44 | }, 45 | "roots": [ 46 | "/src" 47 | ], 48 | "setupFilesAfterEnv": [ 49 | "../jest-enzyme/lib/index.js" 50 | ], 51 | "testEnvironment": "../jest-environment-enzyme/lib/index.js", 52 | "testEnvironmentOptions": { 53 | "adapter": "react16" 54 | }, 55 | "verbose": true 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/toHaveClassName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source code is licensed under the MIT-style license found in the 3 | * LICENSE file in the root directory of this source tree. * 4 | * 5 | * @providesModule toHaveClassNameAssertion 6 | * @flow 7 | */ 8 | 9 | import type { EnzymeObject, Matcher } from '../types'; 10 | import name from '../utils/name'; 11 | import html from '../utils/html'; 12 | 13 | export default function toHaveClassName( 14 | enzymeWrapper: EnzymeObject, 15 | className: string 16 | ): Matcher { 17 | let normalizedClassName = className.split(' ').join('.'); 18 | let actualClassName = '(none)'; 19 | let pass = false; 20 | 21 | if (normalizedClassName[0] !== '.') { 22 | normalizedClassName = `.${normalizedClassName}`; 23 | } 24 | 25 | // handle different lengths of enzymeWrappers 26 | switch (enzymeWrapper.getElements().length) { 27 | case 0: 28 | break; // this will and should fail the test 29 | case 1: 30 | pass = enzymeWrapper.is(normalizedClassName); 31 | actualClassName = enzymeWrapper.prop('className'); 32 | break; 33 | default: 34 | let allMatch = true; 35 | 36 | enzymeWrapper.forEach(node => { 37 | if (!node.is(normalizedClassName)) { 38 | allMatch = false; 39 | } 40 | actualClassName = node.prop('className'); 41 | }); 42 | 43 | pass = allMatch; 44 | } 45 | 46 | return { 47 | pass, 48 | message: `Expected <${name( 49 | enzymeWrapper 50 | )}> to have className of "${normalizedClassName}" but instead found "${actualClassName}"`, // eslint-disable-line max-len 51 | negatedMessage: `Expected <${name( 52 | enzymeWrapper 53 | )}> not to contain "${normalizedClassName}" in its className`, 54 | contextualInformation: { 55 | actual: `Found node output: ${html(enzymeWrapper)}`, 56 | }, 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/reduceAssertionObject.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @flow 3 | */ 4 | 5 | import deepEqualIdent from 'deep-equal-ident'; 6 | import type { ObjectReductionResponse } from '../types'; 7 | 8 | type ObjectKey = Object | string; 9 | 10 | export default function reduceAssertionObject( 11 | componentDetails: Object, 12 | objectOrKey: ObjectKey, 13 | potentialValue?: any 14 | ): ObjectReductionResponse { 15 | const matcherDetails = 16 | typeof objectOrKey === 'object' && !Array.isArray(objectOrKey) 17 | ? objectOrKey 18 | : { [objectOrKey]: potentialValue }; 19 | 20 | const equals = this && this.equals ? this.equals : deepEqualIdent; 21 | 22 | return Object.keys(matcherDetails).reduce( 23 | (prevVal: ObjectReductionResponse, key: string) => { 24 | const retVal = { ...prevVal }; 25 | const match = equals(componentDetails[key], matcherDetails[key]); 26 | retVal.actual[key] = componentDetails[key]; 27 | retVal.expected[key] = matcherDetails[key]; 28 | 29 | /* 30 | * This check helps us give better error messages when the componentDetails doesnt 31 | * include a specific key at all. 32 | */ 33 | if (!componentDetails.hasOwnProperty(key)) { 34 | retVal.missingKeys.push(key); 35 | retVal.pass = false; 36 | return retVal; 37 | } 38 | 39 | /* 40 | * This is just a list of anything that fails to match. 41 | */ 42 | if (!match) { 43 | retVal.unmatchedKeys.push(key); 44 | } 45 | 46 | /* 47 | * We only want to update if it was previous pass. 48 | * If one fails, its all a fail 49 | */ 50 | if (retVal.pass) { 51 | retVal.pass = match; 52 | } 53 | 54 | return retVal; 55 | }, 56 | { 57 | actual: {}, 58 | expected: {}, 59 | pass: true, 60 | missingKeys: [], 61 | unmatchedKeys: [], 62 | } 63 | ); 64 | } 65 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/html.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import instance from './instance'; 4 | import isShallowWrapper from './isShallowWrapper'; 5 | import getConsoleObject from './getConsoleObject'; 6 | import type { EnzymeObject } from '../types'; 7 | 8 | const consoleObject = getConsoleObject(); 9 | const noop = () => {}; 10 | 11 | function mapWrappersHTML(wrapper: EnzymeObject): Array { 12 | return wrapper.getElements().map(node => { 13 | const inst = instance(node); 14 | const type = node.type || inst._tag; 15 | 16 | const { error } = consoleObject; 17 | consoleObject.error = noop; 18 | const { children, ...props } = node.props 19 | ? node.props 20 | : inst._currentElement.props; 21 | consoleObject.error = error; 22 | 23 | const transformedProps = Object.keys(props).map(key => { 24 | try { 25 | return `${key}="${props[key].toString()}"`; 26 | } catch (e) { 27 | return `${key}="[object Object]"`; 28 | } 29 | }); 30 | let stringifiedNode = `<${type} ${transformedProps.join(' ')}`; 31 | 32 | if (children) { 33 | stringifiedNode += `>[..children..]'; 36 | } 37 | 38 | return stringifiedNode; 39 | }); 40 | } 41 | 42 | export default function printHTMLForWrapper(wrapper: EnzymeObject): string { 43 | switch (wrapper.getElements().length) { 44 | case 0: { 45 | return '[empty set]'; 46 | } 47 | case 1: { 48 | if (isShallowWrapper(wrapper)) { 49 | // This is used to clean up in any awkward spacing in the debug output. 50 | //
=>
51 | return wrapper.debug().replace(/\n(\s*)/g, ''); 52 | } 53 | 54 | return wrapper.html(); 55 | } 56 | default: { 57 | const nodes = mapWrappersHTML(wrapper).reduce( 58 | (acc, curr, index) => `${acc}${index}: ${curr}\n`, 59 | '' 60 | ); 61 | 62 | return `Multiple nodes found:\n${nodes}`; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/utils/stringify.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import CircularJSON from 'circular-json-es6'; 4 | import colors from './colors'; 5 | 6 | function stringifySingle(key: string, value: any): Array { 7 | let stringifyingValue = value; 8 | let skipCircularCheck = false; 9 | if (Array.isArray(value)) { 10 | const values = value.map(v => stringifySingle('', v)[1]); 11 | 12 | // Skip circular check because we have already safely dealt with it above 13 | skipCircularCheck = true; 14 | 15 | let joined = values.join(' '); 16 | let initialBracket = colors.gray('['); 17 | const endingBracket = colors.gray(']'); 18 | 19 | if (joined.length > 20) { 20 | const pad = '\n '; 21 | joined = `${values.join(pad)}\n`; 22 | initialBracket += pad; 23 | } 24 | 25 | stringifyingValue = colors.gray( 26 | `${initialBracket}${joined}${endingBracket}` 27 | ); 28 | } else if (value === null) { 29 | stringifyingValue = colors.gray(value); 30 | } else if (typeof value === 'object') { 31 | stringifyingValue = colors.gray(CircularJSON.stringify(value)); 32 | } else if (typeof value === 'string') { 33 | stringifyingValue = colors.gray(`"${value}"`); 34 | } else if (typeof value === 'number') { 35 | stringifyingValue = colors.blue(value); 36 | } else if (value) { 37 | stringifyingValue = colors.green(value); 38 | } else if (!value) { 39 | stringifyingValue = colors.red(value); 40 | } 41 | 42 | try { 43 | // circular if you cant stringify 44 | if (!skipCircularCheck) { 45 | JSON.stringify({ [key]: value }); 46 | } 47 | 48 | return [key, stringifyingValue]; 49 | } catch (e) { 50 | return [key, colors.gray('[Circular]')]; 51 | } 52 | } 53 | 54 | function color([key, value]): string { 55 | return `${colors.yellow(key)}${colors.gray(':')} ${colors.yellow(value)}`; 56 | } 57 | 58 | export default function stringify(object: Object): string { 59 | const keys = Object.keys(object); 60 | 61 | return keys.map(key => color(stringifySingle(key, object[key]))).join('\n'); 62 | } 63 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toHaveDisplayName.test.js: -------------------------------------------------------------------------------- 1 | const toHaveDisplayName = require('../toHaveDisplayName'); 2 | 3 | function Fixture() { 4 | return ( 5 |
6 | 7 | 8 | 9 |
10 | ); 11 | } 12 | 13 | describe('toHaveDisplayName', () => { 14 | [shallow, mount].forEach(builder => { 15 | describe(builder.name, () => { 16 | const wrapper = builder().find('a'); 17 | const truthyResults = toHaveDisplayName(wrapper, 'a'); 18 | const falsyResults = toHaveDisplayName(wrapper, 'span'); 19 | 20 | it('returns the pass flag properly', () => { 21 | expect(truthyResults.pass).toBe(true); 22 | expect(falsyResults.pass).toBe(false); 23 | }); 24 | 25 | it(`returns the message with the proper pass verbage (${builder.name})`, () => { 26 | expect(truthyResults.message).toMatchSnapshot(); 27 | }); 28 | 29 | it(`returns the message with the proper fail verbage (${builder.name})`, () => { 30 | expect(truthyResults.negatedMessage).toMatchSnapshot(); 31 | }); 32 | 33 | it(`provides contextual information for the message (${builder.name})`, () => { 34 | expect(truthyResults.contextualInformation).toMatchSnapshot(); 35 | }); 36 | 37 | it('provides the right info for when this method is called with multiple nodes', () => { 38 | const nwrapper = builder( 39 |
40 | 41 | 42 |
43 | ).find('span'); 44 | const nfalsyResults = toHaveDisplayName(nwrapper, 'span'); 45 | 46 | expect(nfalsyResults).toMatchSnapshot(); 47 | }); 48 | 49 | it('works on composite functions', () => { 50 | const nwrapper = builder(); 51 | const ntruthyResults = toHaveDisplayName(nwrapper, 'Fixture'); 52 | const nfalsyResults = toHaveDisplayName(nwrapper, 'a'); 53 | 54 | expect(ntruthyResults).toMatchSnapshot(); 55 | expect(nfalsyResults).toMatchSnapshot(); 56 | }); 57 | }); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toContainMatchingElement.test.js: -------------------------------------------------------------------------------- 1 | const PropTypes = require('prop-types'); 2 | 3 | const toContainMatchingElement = require('../toContainMatchingElement'); 4 | 5 | function User(props) { 6 | return ( 7 | 8 | User {props.index} 9 | 10 | ); 11 | } 12 | 13 | User.propTypes = { 14 | index: PropTypes.number.isRequired, 15 | className: PropTypes.string, 16 | }; 17 | 18 | function Fixture() { 19 | return ( 20 |
21 |
    22 |
  • 23 | 24 |
  • 25 |
  • 26 | 27 |
  • 28 |
29 |
30 | ); 31 | } 32 | 33 | describe('toContainMatchingElement', () => { 34 | const wrapper = shallow(); 35 | const truthyResults = [ 36 | toContainMatchingElement(wrapper, 'User'), 37 | toContainMatchingElement(wrapper, '[index=1]'), 38 | toContainMatchingElement(wrapper, '[index]'), 39 | toContainMatchingElement(wrapper.find('ul'), '[index]'), 40 | ]; 41 | const falsyResults = [ 42 | toContainMatchingElement(wrapper, 'Foo'), 43 | toContainMatchingElement(wrapper, '.userThree'), 44 | toContainMatchingElement(wrapper.find('ul'), 'Bar'), 45 | ]; 46 | 47 | it('returns the pass flag properly', () => { 48 | truthyResults.forEach(truthyResult => { 49 | expect(truthyResult.pass).toBe(true); 50 | }); 51 | falsyResults.forEach(falsyResult => { 52 | expect(falsyResult.pass).toBe(false); 53 | }); 54 | }); 55 | 56 | it('returns the message with the proper pass verbage', () => { 57 | truthyResults.forEach(truthyResult => { 58 | expect(truthyResult.message).toMatchSnapshot(); 59 | }); 60 | }); 61 | 62 | it('returns the message with the proper fail verbage', () => { 63 | falsyResults.forEach(falsyResult => { 64 | expect(falsyResult.negatedMessage).toMatchSnapshot(); 65 | }); 66 | }); 67 | 68 | it('provides contextual information for the message', () => { 69 | truthyResults.forEach(truthyResult => { 70 | expect(truthyResult.contextualInformation).toMatchSnapshot(); 71 | }); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /packages/jasmine-enzyme/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jasmine-enzyme", 3 | "version": "7.1.2", 4 | "description": "Jasmine assertions for enzyme", 5 | "main": "lib/index.js", 6 | "homepage": "https://github.com/FormidableLabs/enzyme-matchers/packages/jasmine-enzyme#readme", 7 | "author": "Blaine Kasten", 8 | "license": "MIT", 9 | "scripts": { 10 | "pretest": "node ../../scripts/jest.js", 11 | "test": "npm run jest && npm run jasmine", 12 | "jest": "node ../../node_modules/jest-cli/bin/jest.js", 13 | "jasmine": "../../node_modules/jasmine/bin/jasmine.js", 14 | "lint": "eslint ./src", 15 | "clean": "rm -rf ./lib", 16 | "build:js": "babel --root-mode upward src --out-dir lib --ignore '**/__tests__/*.js'", 17 | "build:flow": "flow-copy-source -v -i '**/__tests__/*.js' src lib", 18 | "build": "npm run clean && npm run build:js && npm run build:flow", 19 | "prepublish": "npm run build" 20 | }, 21 | "files": [ 22 | "lib" 23 | ], 24 | "repository": { 25 | "type": "git", 26 | "url": "https://github.com/FormidableLabs/enzyme-matchers.git" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/FormidableLabs/enzyme-matchers/issues" 30 | }, 31 | "keywords": [ 32 | "javascript", 33 | "shallow rendering", 34 | "shallowRender", 35 | "test", 36 | "reactjs", 37 | "react", 38 | "flux", 39 | "testing", 40 | "test utils", 41 | "assertion helpers", 42 | "tdd", 43 | "jasmine", 44 | "enzyme" 45 | ], 46 | "peerDependencies": { 47 | "enzyme": ">=3.4.0" 48 | }, 49 | "dependencies": { 50 | "enzyme-matchers": "^7.1.2" 51 | }, 52 | "jest": { 53 | "transform": { 54 | "^.+\\.js$": "../../babel-jest-root-mode-wrapper.js" 55 | }, 56 | "setupFilesAfterEnv": [ 57 | "jest-enzyme/src/index.js" 58 | ], 59 | "testEnvironment": "enzyme", 60 | "roots": [ 61 | "/src" 62 | ], 63 | "transformIgnorePatterns": [ 64 | "node_modules/(?!enzyme-matchers)" 65 | ], 66 | "verbose": true 67 | }, 68 | "devDependencies": { 69 | "jasmine": "^2.8.0", 70 | "jest-environment-enzyme": "^7.1.2", 71 | "jest-enzyme": "^7.1.2", 72 | "jsdom": "^9.12.0" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toHaveClassName.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toHaveClassName mount provides contextual information for the message (mount) 1`] = ` 4 | Object { 5 | "actual": "Found node output: ", 6 | } 7 | `; 8 | 9 | exports[`toHaveClassName mount returns the message with the proper fail verbage (mount) 1`] = `"Expected not to contain \\".bar\\" in its className"`; 10 | 11 | exports[`toHaveClassName mount returns the message with the proper pass verbage (mount) 1`] = `"Expected to have className of \\".bar\\" but instead found \\"bar baz\\""`; 12 | 13 | exports[`toHaveClassName mount works for multiple nodes (mount) 1`] = ` 14 | Object { 15 | "contextualInformation": Object { 16 | "actual": "Found node output: Multiple nodes found: 17 | 0: 18 | 1: 19 | ", 20 | }, 21 | "message": "Expected <2 span nodes found> to have className of \\".baux\\" but instead found \\"baux\\"", 22 | "negatedMessage": "Expected <2 span nodes found> not to contain \\".baux\\" in its className", 23 | "pass": true, 24 | } 25 | `; 26 | 27 | exports[`toHaveClassName shallow provides contextual information for the message (shallow) 1`] = ` 28 | Object { 29 | "actual": "Found node output: ", 30 | } 31 | `; 32 | 33 | exports[`toHaveClassName shallow returns the message with the proper fail verbage (shallow) 1`] = `"Expected not to contain \\".bar\\" in its className"`; 34 | 35 | exports[`toHaveClassName shallow returns the message with the proper pass verbage (shallow) 1`] = `"Expected to have className of \\".bar\\" but instead found \\"bar baz\\""`; 36 | 37 | exports[`toHaveClassName shallow works for multiple nodes (shallow) 1`] = ` 38 | Object { 39 | "contextualInformation": Object { 40 | "actual": "Found node output: Multiple nodes found: 41 | 0: 42 | 1: 43 | ", 44 | }, 45 | "message": "Expected <2 span nodes found> to have className of \\".baux\\" but instead found \\"baux\\"", 46 | "negatedMessage": "Expected <2 span nodes found> not to contain \\".baux\\" in its className", 47 | "pass": true, 48 | } 49 | `; 50 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/toContainExactlyOneMatchingElement.test.js: -------------------------------------------------------------------------------- 1 | const PropTypes = require('prop-types'); 2 | 3 | const toContainExactlyOneMatchingElement = require('../toContainExactlyOneMatchingElement'); 4 | 5 | function User(props) { 6 | return ( 7 | 8 | User {props.index} 9 | 10 | ); 11 | } 12 | 13 | User.propTypes = { 14 | index: PropTypes.number.isRequired, 15 | }; 16 | 17 | function Fixture() { 18 | return ( 19 |
20 |
    21 |
  • 22 | 23 |
  • 24 |
  • 25 | 26 |
  • 27 |
28 |
29 | ); 30 | } 31 | 32 | describe('toContainExactlyOneMatchingElement', () => { 33 | const wrapper = shallow(); 34 | const truthyResults = [ 35 | toContainExactlyOneMatchingElement(wrapper, '.userOne'), 36 | toContainExactlyOneMatchingElement(wrapper, '[index=1]'), 37 | toContainExactlyOneMatchingElement(wrapper.find('ul'), '[index=1]'), 38 | ]; 39 | const falsyResults = [ 40 | toContainExactlyOneMatchingElement(wrapper, 'User'), 41 | toContainExactlyOneMatchingElement(wrapper, '.userThree'), 42 | toContainExactlyOneMatchingElement(wrapper, '[index]'), 43 | toContainExactlyOneMatchingElement(wrapper.find('ul'), '[index]'), 44 | ]; 45 | 46 | it('returns the pass flag properly', () => { 47 | truthyResults.forEach(truthyResult => { 48 | expect(truthyResult.pass).toBe(true); 49 | }); 50 | falsyResults.forEach(falsyResult => { 51 | expect(falsyResult.pass).toBe(false); 52 | }); 53 | }); 54 | 55 | it('returns the message with the proper pass verbage', () => { 56 | truthyResults.forEach(truthyResult => { 57 | expect(truthyResult.message).toMatchSnapshot(); 58 | }); 59 | }); 60 | 61 | it('returns the message with the proper fail verbage', () => { 62 | falsyResults.forEach(falsyResult => { 63 | expect(falsyResult.negatedMessage).toMatchSnapshot(); 64 | }); 65 | }); 66 | 67 | it('provides contextual information for the message', () => { 68 | truthyResults.forEach(truthyResult => { 69 | expect(truthyResult.contextualInformation).toMatchSnapshot(); 70 | }); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /packages/enzyme-matchers/src/assertions/__tests__/__snapshots__/toContainExactlyOneMatchingElement.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`toContainExactlyOneMatchingElement provides contextual information for the message 1`] = ` 4 | Object { 5 | "actual": "HTML Output of
: 6 |
", 7 | } 8 | `; 9 | 10 | exports[`toContainExactlyOneMatchingElement provides contextual information for the message 2`] = ` 11 | Object { 12 | "actual": "HTML Output of
: 13 |
", 14 | } 15 | `; 16 | 17 | exports[`toContainExactlyOneMatchingElement provides contextual information for the message 3`] = ` 18 | Object { 19 | "actual": "HTML Output of