-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support all attribute selector operators #1157
Changes from all commits
b88114b
4c19481
de3069d
11663db
94011e2
9751ed8
6573ebe
ead8641
d64abf3
45a1a7d
e8dd8d9
dec1505
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,8 +21,16 @@ const tests = [ | |
}, | ||
]; | ||
|
||
let expectAttributeMatch; | ||
|
||
describe('selectors', () => { | ||
tests.forEach(({ describeMethod, name, renderMethod }) => { | ||
before(() => { | ||
expectAttributeMatch = (element, selector, expected) => { | ||
const wrapper = renderMethod(element); | ||
expect(wrapper.is(selector)).to.equal(expected); | ||
}; | ||
}); | ||
describeMethod(name, () => { | ||
it('simple descendent', () => { | ||
const wrapper = renderMethod(( | ||
|
@@ -350,6 +358,124 @@ describe('selectors', () => { | |
expect(wrapper.find('Wrapped(Foo)')).to.have.lengthOf(1); | ||
expect(wrapper.find('Wrapped(Twice(Bar))')).to.have.lengthOf(1); | ||
}); | ||
|
||
it('should parse booleans', () => { | ||
expectAttributeMatch(<div hidden />, '[hidden=true]', true); | ||
expectAttributeMatch(<div hidden />, '[hidden=false]', false); | ||
expectAttributeMatch(<div hidden />, '[hidden="true"]', false); | ||
expectAttributeMatch(<div hidden={false} />, '[hidden=false]', true); | ||
expectAttributeMatch(<div hidden={false} />, '[hidden=true]', false); | ||
expectAttributeMatch(<div hidden={false} />, '[hidden="false"]', false); | ||
}); | ||
|
||
it('should parse numeric literals', () => { | ||
expectAttributeMatch(<div data-foo={2.3} />, '[data-foo=2.3]', true); | ||
expectAttributeMatch(<div data-foo={2} />, '[data-foo=2]', true); | ||
expectAttributeMatch(<div data-foo={2} />, '[data-foo="2abc"]', false); | ||
expectAttributeMatch(<div data-foo={2} />, '[data-foo="abc2"]', false); | ||
expectAttributeMatch(<div data-foo={-2} />, '[data-foo=-2]', true); | ||
// @TODO this is failing due to a parser issue | ||
// expectAttributeMatch(<div data-foo={2e8} />, '[data-foo=2e8]', true); | ||
expectAttributeMatch(<div data-foo={Infinity} />, '[data-foo=Infinity]', true); | ||
expectAttributeMatch(<div data-foo={Infinity} />, '[data-foo=-Infinity]', false); | ||
expectAttributeMatch(<div data-foo={-Infinity} />, '[data-foo=-Infinity]', true); | ||
expectAttributeMatch(<div data-foo={-Infinity} />, '[data-foo=Infinity]', false); | ||
}); | ||
|
||
it('should parse zeroes properly', () => { | ||
expectAttributeMatch(<div data-foo={0} />, '[data-foo=0]', true); | ||
expectAttributeMatch(<div data-foo={0} />, '[data-foo=+0]', true); | ||
expectAttributeMatch(<div data-foo={-0} />, '[data-foo=-0]', true); | ||
expectAttributeMatch(<div data-foo={-0} />, '[data-foo=0]', false); | ||
expectAttributeMatch(<div data-foo={0} />, '[data-foo=-0]', false); | ||
expectAttributeMatch(<div data-foo={1} />, '[data-foo=0]', false); | ||
expectAttributeMatch(<div data-foo={2} />, '[data-foo=-0]', false); | ||
}); | ||
|
||
it('should work with empty strings', () => { | ||
expectAttributeMatch(<div className="" />, '[className=""]', true); | ||
expectAttributeMatch(<div className={''} />, '[className=""]', true); | ||
expectAttributeMatch(<div className={'bar'} />, '[className=""]', false); | ||
}); | ||
|
||
it('should work with NaN', () => { | ||
expectAttributeMatch(<div data-foo={NaN} />, '[data-foo=NaN]', true); | ||
expectAttributeMatch(<div data-foo={0} />, '[data-foo=NaN]', false); | ||
}); | ||
|
||
it('should work with null', () => { | ||
expectAttributeMatch(<div data-foo={null} />, '[data-foo=null]', true); | ||
expectAttributeMatch(<div data-foo={0} />, '[data-foo=null]', false); | ||
}); | ||
|
||
it('should work with false', () => { | ||
expectAttributeMatch(<div data-foo={false} />, '[data-foo=false]', true); | ||
expectAttributeMatch(<div data-foo={0} />, '[data-foo=false]', false); | ||
}); | ||
it('should work with ±Infinity', () => { | ||
expectAttributeMatch(<div data-foo={Infinity} />, '[data-foo=Infinity]', true); | ||
expectAttributeMatch(<div data-foo={Infinity} />, '[data-foo=+Infinity]', true); | ||
expectAttributeMatch(<div data-foo={Infinity} />, '[data-foo=-Infinity]', false); | ||
expectAttributeMatch(<div data-foo={Infinity} />, '[data-foo=NaN]', false); | ||
expectAttributeMatch(<div data-foo={0} />, '[data-foo=Infinity]', false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like this test is duplicated at the bottom of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think so, thanks! |
||
expectAttributeMatch(<div data-foo={0} />, '[data-foo=-Infinity]', false); | ||
expectAttributeMatch(<div data-foo={-Infinity} />, '[data-foo=-Infinity]', true); | ||
expectAttributeMatch(<div data-foo={-Infinity} />, '[data-foo=Infinity]', false); | ||
expectAttributeMatch(<div data-foo={-Infinity} />, '[data-foo="-Infinity"]', false); | ||
expectAttributeMatch(<div data-foo={-Infinity} />, '[data-foo=NaN]', false); | ||
expectAttributeMatch(<div data-foo={NaN} />, '[data-foo=Infinity]', false); | ||
expectAttributeMatch(<div data-foo={NaN} />, '[data-foo=-Infinity]', false); | ||
}); | ||
|
||
it('whitespace list attribute selector', () => { | ||
expectAttributeMatch(<div rel="foo bar baz" />, '[rel~="bar"]', true); | ||
expectAttributeMatch(<div rel="foo bar baz" />, '[rel~="baz"]', true); | ||
expectAttributeMatch(<div rel="foo bar baz" />, '[rel~="foo"]', true); | ||
expectAttributeMatch(<div rel="foo bar baz" />, '[rel~="foo bar"]', false); | ||
expectAttributeMatch(<div rel={1} />, '[rel~=1]', false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct me if I'm wrong - shouldn't this return true? I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jack-lewin this implementation only supports matching strings with these partial match operators, so all other types will return |
||
expectAttributeMatch(<div rel="1" />, '[rel~=1]', false); | ||
}); | ||
|
||
it('hypen attribute selector', () => { | ||
expectAttributeMatch(<a hrefLang="en-US" />, '[hrefLang|="en"]', true); | ||
expectAttributeMatch(<a hrefLang="en-US" />, '[hrefLang|="en-US"]', true); | ||
expectAttributeMatch(<a hrefLang="en-US" />, '[hrefLang|="US"]', false); | ||
expectAttributeMatch(<a hrefLang="en-US" />, '[hrefLang|="enUS"]', false); | ||
expectAttributeMatch(<a hrefLang={1} />, '[hrefLang|=1]', false); | ||
expectAttributeMatch(<a hrefLang="1" />, '[hrefLang|=1]', false); | ||
}); | ||
|
||
it('prefix attribute operator', () => { | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src^="foo"]', true); | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src^="foo-bar"]', true); | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src^="foo-bar.jpg"]', true); | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src^="bar"]', false); | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src^=""]', false); | ||
expectAttributeMatch(<img alt="" src={1} />, '[src^=1]', false); | ||
expectAttributeMatch(<img alt="" src="1" />, '[src^=1]', false); | ||
}); | ||
|
||
it('suffix attribute operator', () => { | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src$=".jpg"]', true); | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src$="bar.jpg"]', true); | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src$="foo-bar.jpg"]', true); | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src$="foo"]', false); | ||
expectAttributeMatch(<img alt="" src="foo-bar.jpg" />, '[src$=""]', false); | ||
expectAttributeMatch(<img alt="" src={1} />, '[src$=1]', false); | ||
expectAttributeMatch(<img alt="" src="1" />, '[src$=1]', false); | ||
}); | ||
|
||
it('substring attribute operator', () => { | ||
expectAttributeMatch(<div id="foo bar baz" />, '[id*="foo"]', true); | ||
expectAttributeMatch(<div id="foo bar baz" />, '[id*="foo bar"]', true); | ||
expectAttributeMatch(<div id="foo bar baz" />, '[id*="foo bar baz"]', true); | ||
expectAttributeMatch(<div id="foo bar baz" />, '[id*="foo "]', true); | ||
expectAttributeMatch(<div id="foo bar baz" />, '[id*="fo"]', true); | ||
expectAttributeMatch(<div id="foo bar baz" />, '[id*="foz"]', false); | ||
expectAttributeMatch(<div id="foo bar baz" />, '[id*=1]', false); | ||
expectAttributeMatch(<div id={1} />, '[id*=1]', false); | ||
expectAttributeMatch(<div id="1" />, '[id*=1]', false); | ||
}); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is "before all"; could we use
beforeEach
instead?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could, but "before all" is the intention here, since
expectAttributeMatch
only needs to be initialized once perrenderMethod
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair; beforeAll tends to cause test flakiness in my experience