Skip to content

Commit

Permalink
Warn if selector contains a psuedo-class
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon Dail authored and Brandon Dail committed Sep 12, 2016
1 parent 5049574 commit 4663aaa
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 30 deletions.
30 changes: 25 additions & 5 deletions src/Utils.js
Expand Up @@ -165,14 +165,31 @@ export function splitSelector(selector) {
return selector.split(/(?=\.|\[.*\])|(?=#|\[#.*\])/);
}

export function isSimpleSelector(selector) {
// any of these characters pretty much guarantee it's a complex selector
return !/[~\s:>]/.test(selector);

const containsQuotes = /'|"/;
const containsColon = /:/;


export function isPsuedoClassSelector(selector) {
if (containsColon.test(selector)) {
if (!containsQuotes.test(selector)) {
return true;
}
const tokens = selector.split(containsQuotes);
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
if (containsColon.test(token) && i % 2 === 0) {
return true;
}
}
return false;
}
return false;
}

export function selectorError(selector) {
export function selectorError(selector, type = '') {
return new TypeError(
`Enzyme received a complex CSS selector ('${selector}') that it does not currently support`
`Enzyme received a ${type} CSS selector ('${selector}') that it does not currently support`
);
}

Expand All @@ -187,6 +204,9 @@ export const SELECTOR = {
};

export function selectorType(selector) {
if (isPsuedoClassSelector(selector)) {
throw selectorError(selector, 'psudo-class');
}
if (selector[0] === '.') {
return SELECTOR.CLASS_TYPE;
} else if (selector[0] === '#') {
Expand Down
4 changes: 2 additions & 2 deletions test/ReactWrapper-spec.jsx
Expand Up @@ -390,12 +390,12 @@ describeWithDOM('mount', () => {
React.createElement('div', null, React.createElement('span', {
'123-foo': 'bar',
'-foo': 'bar',
':foo': 'bar',
'+foo': 'bar',
}))
);

expect(wrapper.find('[-foo]')).to.have.length(0, '-foo');
expect(wrapper.find('[:foo]')).to.have.length(0, ':foo');
expect(wrapper.find('[+foo]')).to.have.length(0, '+foo');
expect(wrapper.find('[123-foo]')).to.have.length(0, '123-foo');
});

Expand Down
50 changes: 27 additions & 23 deletions test/Utils-spec.jsx
Expand Up @@ -9,7 +9,7 @@ import {
coercePropValue,
getNode,
nodeEqual,
isSimpleSelector,
isPsuedoClassSelector,
propFromEvent,
SELECTOR,
selectorType,
Expand Down Expand Up @@ -246,39 +246,43 @@ describe('Utils', () => {
});


describe('isSimpleSelector', () => {
describe('isPsuedoClassSelector', () => {


describe('prohibited selectors', () => {
function isComplex(selector) {
function isNotPsuedo(selector) {
it(selector, () => {
expect(isSimpleSelector(selector)).to.equal(false);
expect(isPsuedoClassSelector(selector)).to.equal(false);
});
}

isComplex('.foo .bar');
isComplex(':visible');
isComplex('.foo>.bar');
isComplex('.foo > .bar');
isComplex('.foo~.bar');

isNotPsuedo('.foo');
isNotPsuedo('div');
isNotPsuedo('.foo .bar');
isNotPsuedo('[hover]');
isNotPsuedo('[checked=""]');
isNotPsuedo('[checked=":checked"]');
isNotPsuedo('[checked=\':checked\']');
isNotPsuedo('.foo>.bar');
isNotPsuedo('.foo > .bar');
isNotPsuedo('.foo~.bar');
isNotPsuedo('#foo');
});

describe('allowed selectors', () => {
function isSimple(selector) {
function isPsuedo(selector) {
it(selector, () => {
expect(isSimpleSelector(selector)).to.equal(true);
expect(isPsuedoClassSelector(selector)).to.equal(true);
});
}

isSimple('.foo');
isSimple('.foo-and-foo');
isSimple('input[foo="bar"]');
isSimple('input[foo="bar"][bar="baz"][baz="foo"]');
isSimple('.FoOaNdFoO');
isSimple('tag');
isSimple('.foo.bar');
isSimple('input.foo');

isPsuedo(':checked');
isPsuedo(':focus');
isPsuedo(':hover');
isPsuedo(':disabled');
isPsuedo(':any');
isPsuedo(':last-child');
isPsuedo(':nth-child(1)');
isPsuedo('div:checked');
isPsuedo('[data-foo=":hover"]:hover');
});

});
Expand Down

0 comments on commit 4663aaa

Please sign in to comment.