Skip to content

Commit

Permalink
Merge pull request #670 from ljharb/fix_id_selectors
Browse files Browse the repository at this point in the history
[Fix] `mount`/`shallow`: fix ID selectors

Fixes #495.
  • Loading branch information
ljharb committed Nov 9, 2016
1 parent 36a3740 commit fe3a7ef
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@
"is-subset": "^0.1.1",
"lodash": "^4.13.1",
"object-is": "^1.0.1",
"object.assign": "^4.0.3",
"object.values": "^1.0.3"
"object.assign": "^4.0.4",
"object.entries": "^1.0.3",
"object.values": "^1.0.3",
"uuid": "^2.0.3"
},
"devDependencies": {
"babel-cli": "^6.10.1",
Expand Down
24 changes: 22 additions & 2 deletions src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import isEqual from 'lodash/isEqual';
import React from 'react';
import is from 'object-is';
import uuid from 'uuid';
import entries from 'object.entries';
import assign from 'object.assign';
import functionName from 'function.prototype.name';
import {
isDOMComponent,
Expand Down Expand Up @@ -164,7 +167,24 @@ export function withSetStateAllowed(fn) {
}

export function splitSelector(selector) {
return selector.split(/(?=\.|\[.*\])|(?=#|\[#.*\])/);
// step 1: make a map of all quoted strings with a uuid
const quotedSegments = selector.split(/[^" ]+|("[^"]*")|.*/g)
.filter(Boolean)
.reduce((obj, match) => assign({}, obj, { [match]: uuid.v4() }), {});

return selector
// step 2: replace all quoted strings with the uuid, so we don't have to properly parse them
.replace(/[^" ]+|("[^"]*")|.*/g, x => quotedSegments[x] || x)
// step 3: split as best we can without a proper parser
.split(/(?=\.|\[.*])|(?=#|\[#.*])/)
// step 4: restore the quoted strings by swapping back the uuid's for the original segments
.map((selectorSegment) => {
let restoredSegment = selectorSegment;
entries(quotedSegments).forEach(([k, v]) => {
restoredSegment = restoredSegment.replace(v, k);
});
return restoredSegment;
});
}

export function isSimpleSelector(selector) {
Expand All @@ -178,7 +198,7 @@ export function selectorError(selector) {
);
}

export const isCompoundSelector = /([a-z]\.[a-z]|[a-z]\[.*\]|[a-z]#[a-z])/i;
export const isCompoundSelector = /^[\.#]?-?[_a-z]+[_a-z0-9-]*[\.\[#]/i;

const isPropSelector = /^\[.*\]$/;

Expand Down
24 changes: 24 additions & 0 deletions test/ReactWrapper-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,30 @@ describeWithDOM('mount', () => {
expect(wrapper.find('[key]')).to.have.length(0);
});
});

describe('works with attribute selectors containing #', () => {
let wrapper;
beforeEach(() => {
wrapper = mount(
<div>
<a id="test" href="/page">Hello</a>
<a href="/page#anchor">World</a>
</div>
);
});

it('works with an ID', () => {
expect(wrapper.find('a#test')).to.have.lengthOf(1);
});

it('works with a normal attribute', () => {
expect(wrapper.find('a[href="/page"]')).to.have.lengthOf(1);
});

it('works with an attribute with a #', () => {
expect(wrapper.find('a[href="/page#anchor"]')).to.have.lengthOf(1);
});
});
});

describe('.findWhere(predicate)', () => {
Expand Down
24 changes: 24 additions & 0 deletions test/ShallowWrapper-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,30 @@ describe('shallow', () => {
expect(wrapper.find('Foo').type()).to.equal(Foo);
});
});

describe('works with attribute selectors containing #', () => {
let wrapper;
beforeEach(() => {
wrapper = shallow(
<div>
<a id="test" href="/page">Hello</a>
<a href="/page#anchor">World</a>
</div>
);
});

it('works with an ID', () => {
expect(wrapper.find('a#test')).to.have.lengthOf(1);
});

it('works with a normal attribute', () => {
expect(wrapper.find('a[href="/page"]')).to.have.lengthOf(1);
});

it('works with an attribute with a #', () => {
expect(wrapper.find('a[href="/page#anchor"]')).to.have.lengthOf(1);
});
});
});

describe('.findWhere(predicate)', () => {
Expand Down

0 comments on commit fe3a7ef

Please sign in to comment.