From 2b04cd307c8af9195bcaa5db88e26c4f594c3c9d Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 18 Mar 2019 22:12:44 -0700 Subject: [PATCH 1/3] [Docs] `shallow`: `.hasClass`: fix use of `mount` --- docs/api/ShallowWrapper/hasClass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/ShallowWrapper/hasClass.md b/docs/api/ShallowWrapper/hasClass.md index 4f61b9841..f22e45f0a 100644 --- a/docs/api/ShallowWrapper/hasClass.md +++ b/docs/api/ShallowWrapper/hasClass.md @@ -23,7 +23,7 @@ expect(wrapper.find('.my-button').hasClass('disabled')).to.equal(true); ```jsx // Searching using RegExp works fine when classes were injected by a jss decorator -const wrapper = mount(); +const wrapper = shallow(); expect(wrapper.find('.my-button').hasClass(/(ComponentName)-(other)-(\d+)/)).to.equal(true); ``` From 4196bae99c5bf81530493970756c938dc3bb007f Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 18 Mar 2019 22:13:10 -0700 Subject: [PATCH 2/3] [Tests] `.hasClass`: make `shallow`/`mount` tests consistent --- .../test/ReactWrapper-spec.jsx | 14 ++-- .../test/ShallowWrapper-spec.jsx | 80 ++++++++++++++++++- 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx index d029e0083..ed423c517 100644 --- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx @@ -4663,7 +4663,7 @@ describeWithDOM('mount', () => { }); describe('.hasClass(className)', () => { - context('When using a DOM component', () => { + context('when using a DOM component', () => { it('returns whether or not node has a certain class', () => { const wrapper = mount(
); @@ -4697,7 +4697,7 @@ describeWithDOM('mount', () => { }); }); - context('When using a Composite class component', () => { + context('when using a Composite class component', () => { it('returns whether or not node has a certain class', () => { class Foo extends React.Component { render() { @@ -4722,7 +4722,7 @@ describeWithDOM('mount', () => { }); }); - context('When using nested composite components', () => { + context('when using nested composite components', () => { it('returns whether or not node has a certain class', () => { class Foo extends React.Component { render() { @@ -4754,7 +4754,7 @@ describeWithDOM('mount', () => { }); }); - context('When using a Composite component that renders null', () => { + context('when using a Composite component that renders null', () => { it('returns whether or not node has a certain class', () => { class Foo extends React.Component { render() { @@ -4773,8 +4773,12 @@ describeWithDOM('mount', () => { return
; } } - const wrapper = mount(); + const obj = { classA: true, classB: false }; + const wrapper = mount(); expect(wrapper.hasClass('foo')).to.equal(false); + expect(wrapper.hasClass('classA')).to.equal(false); + expect(wrapper.hasClass('classB')).to.equal(false); + expect(wrapper.hasClass(String(obj))).to.equal(true); }); }); diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx index 245aa41f0..560006e68 100644 --- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx @@ -4628,6 +4628,65 @@ describe('shallow', () => { }); describe('.hasClass(className)', () => { + context('when using a DOM component', () => { + it('returns whether or not node has a certain class', () => { + const wrapper = shallow(
); + + expect(wrapper.hasClass('foo')).to.equal(true); + expect(wrapper.hasClass('bar')).to.equal(true); + expect(wrapper.hasClass('baz')).to.equal(true); + expect(wrapper.hasClass('some-long-string')).to.equal(true); + expect(wrapper.hasClass('FoOo')).to.equal(true); + expect(wrapper.hasClass('doesnt-exist')).to.equal(false); + }); + }); + + describeIf(is('> 0.13'), 'with stateless function components (SFCs)', () => { + it('returns whether or not node has a certain class', () => { + const Foo = () =>
; + const wrapper = shallow(); + + expect(wrapper.hasClass('foo')).to.equal(false); + expect(wrapper.hasClass('bar')).to.equal(false); + expect(wrapper.hasClass('baz')).to.equal(false); + expect(wrapper.hasClass('some-long-string')).to.equal(false); + expect(wrapper.hasClass('FoOo')).to.equal(false); + expect(wrapper.hasClass('doesnt-exist')).to.equal(false); + + expect(wrapper.children().hasClass('foo')).to.equal(true); + expect(wrapper.children().hasClass('bar')).to.equal(true); + expect(wrapper.children().hasClass('baz')).to.equal(true); + expect(wrapper.children().hasClass('some-long-string')).to.equal(true); + expect(wrapper.children().hasClass('FoOo')).to.equal(true); + expect(wrapper.children().hasClass('doesnt-exist')).to.equal(false); + }); + }); + + context('when using a Composite class component', () => { + it('returns whether or not node has a certain class', () => { + class Foo extends React.Component { + render() { + return (
); + } + } + const wrapper = shallow(); + + expect(wrapper.hasClass('foo')).to.equal(false); + expect(wrapper.hasClass('bar')).to.equal(false); + expect(wrapper.hasClass('baz')).to.equal(false); + expect(wrapper.hasClass('some-long-string')).to.equal(false); + expect(wrapper.hasClass('FoOo')).to.equal(false); + expect(wrapper.hasClass('doesnt-exist')).to.equal(false); + + expect(wrapper.children().hasClass('foo')).to.equal(true); + expect(wrapper.children().hasClass('bar')).to.equal(true); + expect(wrapper.children().hasClass('baz')).to.equal(true); + expect(wrapper.children().hasClass('some-long-string')).to.equal(true); + expect(wrapper.children().hasClass('FoOo')).to.equal(true); + expect(wrapper.children().hasClass('doesnt-exist')).to.equal(false); + }); + }); + it('returns whether or not node has a certain class', () => { const wrapper = shallow((
@@ -4641,14 +4700,31 @@ describe('shallow', () => { expect(wrapper.hasClass('doesnt-exist')).to.equal(false); }); + context('when using a Composite component that renders null', () => { + it('returns whether or not node has a certain class', () => { + class Foo extends React.Component { + render() { + return null; + } + } + const wrapper = shallow(); + + expect(wrapper.hasClass('foo')).to.equal(false); + }); + }); + it('works with a non-string `className` prop', () => { class Foo extends React.Component { render() { - return ; + return
; } } - const wrapper = shallow(); + const obj = { classA: true, classB: false }; + const wrapper = shallow(); expect(wrapper.hasClass('foo')).to.equal(false); + expect(wrapper.hasClass('classA')).to.equal(false); + expect(wrapper.hasClass('classB')).to.equal(false); + expect(wrapper.hasClass(String(obj))).to.equal(true); }); }); From 1cf510ddd32b5b1f3c75630e31945b53955021d8 Mon Sep 17 00:00:00 2001 From: Aleksandr Terentev Date: Mon, 18 Mar 2019 19:29:39 +0300 Subject: [PATCH 3/3] [Fix] `shallow`/`mount`: `hasClass`: avoid a crash with a non-string argument --- .../test/ReactWrapper-spec.jsx | 18 ++++++++++++++++++ .../test/ShallowWrapper-spec.jsx | 18 ++++++++++++++++++ packages/enzyme/src/ReactWrapper.js | 2 +- packages/enzyme/src/ShallowWrapper.js | 2 +- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx index ed423c517..fa91fc33c 100644 --- a/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ReactWrapper-spec.jsx @@ -4780,6 +4780,24 @@ describeWithDOM('mount', () => { expect(wrapper.hasClass('classB')).to.equal(false); expect(wrapper.hasClass(String(obj))).to.equal(true); }); + + it('allows hyphens', () => { + const wrapper = mount(
); + expect(wrapper.hasClass('foo-bar')).to.equal(true); + }); + + it('works if className has a function in toString property', () => { + function classes() {} + classes.toString = () => 'foo-bar'; + const wrapper = mount(
); + expect(wrapper.hasClass('foo-bar')).to.equal(true); + }); + + it('works if searching with a RegExp', () => { + const wrapper = mount(
); + expect(wrapper.hasClass(/(ComponentName)-(classname)-(\d+)/)).to.equal(true); + expect(wrapper.hasClass(/(ComponentName)-(other)-(\d+)/)).to.equal(false); + }); }); describe('.forEach(fn)', () => { diff --git a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx index 560006e68..e66808fa1 100644 --- a/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx +++ b/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx @@ -4726,6 +4726,24 @@ describe('shallow', () => { expect(wrapper.hasClass('classB')).to.equal(false); expect(wrapper.hasClass(String(obj))).to.equal(true); }); + + it('allows hyphens', () => { + const wrapper = shallow(
); + expect(wrapper.hasClass('foo-bar')).to.equal(true); + }); + + it('works if className has a function in toString property', () => { + function classes() {} + classes.toString = () => 'foo-bar'; + const wrapper = shallow(
); + expect(wrapper.hasClass('foo-bar')).to.equal(true); + }); + + it('works if searching with a RegExp', () => { + const wrapper = shallow(
); + expect(wrapper.hasClass(/(ComponentName)-(classname)-(\d+)/)).to.equal(true); + expect(wrapper.hasClass(/(ComponentName)-(other)-(\d+)/)).to.equal(false); + }); }); describe('.forEach(fn)', () => { diff --git a/packages/enzyme/src/ReactWrapper.js b/packages/enzyme/src/ReactWrapper.js index d634200a9..4a2d60ed6 100644 --- a/packages/enzyme/src/ReactWrapper.js +++ b/packages/enzyme/src/ReactWrapper.js @@ -855,7 +855,7 @@ class ReactWrapper { * @returns {Boolean} */ hasClass(className) { - if (className && className.indexOf('.') !== -1) { + if (typeof className === 'string' && className.indexOf('.') !== -1) { // eslint-disable-next-line no-console console.warn('It looks like you\'re calling `ReactWrapper::hasClass()` with a CSS selector. hasClass() expects a class name, not a CSS selector.'); } diff --git a/packages/enzyme/src/ShallowWrapper.js b/packages/enzyme/src/ShallowWrapper.js index 7885e5d12..68fe38ffb 100644 --- a/packages/enzyme/src/ShallowWrapper.js +++ b/packages/enzyme/src/ShallowWrapper.js @@ -1253,7 +1253,7 @@ class ShallowWrapper { * @returns {Boolean} */ hasClass(className) { - if (className && className.indexOf('.') !== -1) { + if (typeof className === 'string' && className.indexOf('.') !== -1) { // eslint-disable-next-line no-console console.warn('It looks like you\'re calling `ShallowWrapper::hasClass()` with a CSS selector. hasClass() expects a class name, not a CSS selector.'); }