-
-
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
Integrate with a CSS parser for selector parsing #1086
Changes from all commits
8177e26
0d4a7eb
51ff0e7
26bf200
fa80c0e
b18cfe4
5dde9c6
f20b0c4
d7abfbe
8bffb8a
10019da
5efaf08
83c6f04
8b3e008
1a73724
36e10d2
ae733ee
60b6a86
2c3227b
d0d810e
459108a
188ed1c
17f366d
aadbc4a
a79e150
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,9 +2,6 @@ import './_helpers/setupAdapters'; | |
import React from 'react'; | ||
import sinon from 'sinon'; | ||
import { expect } from 'chai'; | ||
import { | ||
splitSelector, | ||
} from 'enzyme/build/Utils'; | ||
import { elementToTree } from 'enzyme-adapter-utils'; | ||
import { | ||
hasClassName, | ||
|
@@ -13,39 +10,13 @@ import { | |
treeFilter, | ||
pathToNode, | ||
getTextFromNode, | ||
buildPredicate, | ||
} from 'enzyme/build/RSTTraversal'; | ||
import { describeIf } from './_helpers'; | ||
import { REACT013 } from './_helpers/version'; | ||
|
||
const $ = elementToTree; | ||
|
||
describe('RSTTraversal', () => { | ||
describe('splitSelector', () => { | ||
const fn = splitSelector; | ||
it('splits multiple class names', () => { | ||
expect(fn('.foo.bar')).to.eql(['.foo', '.bar']); | ||
expect(fn('.foo.bar.baz')).to.eql(['.foo', '.bar', '.baz']); | ||
}); | ||
|
||
it('splits tag names and class names', () => { | ||
expect(fn('input.bar')).to.eql(['input', '.bar']); | ||
expect(fn('div.bar.baz')).to.eql(['div', '.bar', '.baz']); | ||
expect(fn('Foo.bar')).to.eql(['Foo', '.bar']); | ||
}); | ||
|
||
it('splits tag names and attributes', () => { | ||
expect(fn('input[type="text"]')).to.eql(['input', '[type="text"]']); | ||
expect( | ||
fn('div[title="title"][data-value="foo"]'), | ||
).to.eql(['div', '[title="title"]', '[data-value="foo"]']); | ||
}); | ||
|
||
it('throws for malformed selectors', () => { | ||
expect(() => fn('div[data-name="xyz"')).to.throw(/Enzyme::Selector received what appears to be a malformed string selector/); | ||
}); | ||
}); | ||
|
||
describe('hasClassName', () => { | ||
|
||
it('should work for standalone classNames', () => { | ||
|
@@ -82,13 +53,13 @@ describe('RSTTraversal', () => { | |
const node = $(<div onChange={noop} title="foo" />); | ||
|
||
expect(nodeHasProperty(node, 'onChange')).to.equal(true); | ||
expect(nodeHasProperty(node, 'title', '"foo"')).to.equal(true); | ||
expect(nodeHasProperty(node, 'title', 'foo')).to.equal(true); | ||
}); | ||
|
||
it('should not match on html attributes', () => { | ||
const node = $(<div htmlFor="foo" />); | ||
|
||
expect(nodeHasProperty(node, 'for', '"foo"')).to.equal(false); | ||
expect(nodeHasProperty(node, 'for', 'foo')).to.equal(false); | ||
}); | ||
|
||
it('should not find undefined properties', () => { | ||
|
@@ -97,71 +68,73 @@ describe('RSTTraversal', () => { | |
expect(nodeHasProperty(node, 'title')).to.equal(false); | ||
}); | ||
|
||
it('should parse false as a literal', () => { | ||
const node = $(<div foo={false} />); | ||
|
||
expect(nodeHasProperty(node, 'foo', 'false')).to.equal(true); | ||
it('should parse booleans', () => { | ||
expect(nodeHasProperty(<div foo />, 'foo', true)).to.equal(true); | ||
expect(nodeHasProperty(<div foo />, 'foo', false)).to.equal(false); | ||
expect(nodeHasProperty(<div foo />, 'foo', 'true')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={false} />, 'foo', false)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={false} />, 'foo', true)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={false} />, 'foo', 'false')).to.equal(false); | ||
}); | ||
|
||
it('should parse false as a literal', () => { | ||
const node = $(<div foo />); | ||
|
||
expect(nodeHasProperty(node, 'foo', 'true')).to.equal(true); | ||
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. should this test not still be valid for 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 should, I'll add that case. 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. Added test case for booleans: https://github.com/airbnb/enzyme/pull/1086/files#diff-67b0df7735c607bdef49d8a20292e57aR71 |
||
}); | ||
|
||
it('should parse numbers as numeric literals', () => { | ||
expect(nodeHasProperty(<div foo={2.3} />, 'foo', '2.3')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={2} />, 'foo', '2')).to.equal(true); | ||
expect(() => nodeHasProperty(<div foo={2} />, 'foo', '2abc')).to.throw(); | ||
expect(() => nodeHasProperty(<div foo={2} />, 'foo', 'abc2')).to.throw(); | ||
expect(nodeHasProperty(<div foo={-2} />, 'foo', '-2')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={2e8} />, 'foo', '2e8')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={Infinity} />, 'foo', 'Infinity')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={-Infinity} />, 'foo', '-Infinity')).to.equal(true); | ||
it('should parse numeric literals', () => { | ||
expect(nodeHasProperty(<div foo={2.3} />, 'foo', 2.3)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={2} />, 'foo', 2)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={2} />, 'foo', '2abc')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={2} />, 'foo', 'abc2')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={-2} />, 'foo', -2)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={2e8} />, 'foo', 2e8)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={Infinity} />, 'foo', Infinity)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={-Infinity} />, 'foo', -Infinity)).to.equal(true); | ||
}); | ||
|
||
it('should parse zeroes properly', () => { | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', '0')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={-0} />, 'foo', '-0')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={1} />, 'foo', '0')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={2} />, 'foo', '-0')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', 0)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', +0)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={-0} />, 'foo', -0)).to.equal(true); | ||
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. can we add test cases that 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. Done. |
||
expect(nodeHasProperty(<div foo={-0} />, 'foo', 0)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', -0)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={1} />, 'foo', 0)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={2} />, 'foo', -0)).to.equal(false); | ||
}); | ||
|
||
it('should work with empty strings', () => { | ||
expect(nodeHasProperty(<div foo="" />, 'foo', '')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={''} />, 'foo', '')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={''} />, 'foo', '""')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={'bar'} />, 'foo', '')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={'bar'} />, 'foo', '""')).to.equal(false); | ||
}); | ||
|
||
it('should work with NaN', () => { | ||
expect(nodeHasProperty(<div foo={NaN} />, 'foo', 'NaN')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', 'NaN')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={NaN} />, 'foo', NaN)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', NaN)).to.equal(false); | ||
}); | ||
|
||
it('should work with null', () => { | ||
expect(nodeHasProperty(<div foo={null} />, 'foo', 'null')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', 'null')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={null} />, 'foo', null)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', null)).to.equal(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. Let's also add a pair of assertions that null won't equal undefined? 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. What's the expected behavior with Is that expected? 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.
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. Right now 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. ping @ljharb ^ I think that's the last point of clarification I need before this is good to go. 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. In the interest of time, i'm going to move forward w/ this PR. I've verified that this is the current behavior. If we would like to clarify it / change it in an upcoming PR, i'm fine with that. @aweary thanks for being so thorough here. |
||
}); | ||
|
||
it('should work with false', () => { | ||
expect(nodeHasProperty(<div foo={false} />, 'foo', 'false')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', 'false')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={false} />, 'foo', false)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', false)).to.equal(false); | ||
}); | ||
|
||
it('should work with ±Infinity', () => { | ||
expect(nodeHasProperty(<div foo={Infinity} />, 'foo', 'Infinity')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', 'Infinity')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={-Infinity} />, 'foo', '-Infinity')).to.equal(true); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', '-Infinity')).to.equal(false); | ||
}); | ||
|
||
it('should throw when un unquoted string is passed in', () => { | ||
const node = $(<div title="foo" />); | ||
|
||
expect(() => nodeHasProperty(node, 'title', 'foo')).to.throw(); | ||
expect(nodeHasProperty(<div foo={Infinity} />, 'foo', Infinity)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={Infinity} />, 'foo', +Infinity)).to.equal(true); | ||
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. let's add a case where 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. Done. 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'd also be good to ensure NaN and Infinity don't equate, since both are not finite |
||
expect(nodeHasProperty(<div foo={Infinity} />, 'foo', -Infinity)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={Infinity} />, 'foo', 'Infinity')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={Infinity} />, 'foo', NaN)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', Infinity)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={-Infinity} />, 'foo', -Infinity)).to.equal(true); | ||
expect(nodeHasProperty(<div foo={-Infinity} />, 'foo', Infinity)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={-Infinity} />, 'foo', Infinity)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={-Infinity} />, 'foo', '-Infinity')).to.equal(false); | ||
expect(nodeHasProperty(<div foo={-Infinity} />, 'foo', NaN)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={NaN} />, 'foo', Infinity)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={NaN} />, 'foo', -Infinity)).to.equal(false); | ||
expect(nodeHasProperty(<div foo={0} />, 'foo', -Infinity)).to.equal(false); | ||
}); | ||
|
||
}); | ||
|
||
describe('treeForEach', () => { | ||
|
@@ -367,12 +340,4 @@ describe('RSTTraversal', () => { | |
}); | ||
}); | ||
}); | ||
|
||
describe('buildPredicate', () => { | ||
it('should throw expected error', () => { | ||
const intSelector = 10; | ||
const func = buildPredicate.bind(this, intSelector); | ||
expect(func).to.throw(TypeError, 'Enzyme::Selector expects a string, object, or Component Constructor'); | ||
}); | ||
}); | ||
}); |
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.
does this no longer throw (somewhere)? it's a malformed selector.
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.
It does throw, but since the new
rst-selector-parser
manages all parsing this should be covered by the unit tests for the package. I figure at this point we'd be testing the behavior of a dependency with its own tests.But I'll add back a test that ensures that we catch the general parsing error and re-throw something more specific. Then I think it's safe to assume invalid selectors will throw, and if the
rst-selector-parser
coverage is missing a case we can add it there.On that note, I'd be happy to include
rst-selector-parser
as part of this monorepo if we want to.