Skip to content

Commit

Permalink
Add 'dependencies' parameter and index argument to the filter method (
Browse files Browse the repository at this point in the history
  • Loading branch information
inikulin authored and AlexanderMoskovkin committed Dec 12, 2016
1 parent 9df62eb commit 60a22a1
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 41 deletions.
92 changes: 52 additions & 40 deletions src/client-functions/selector-builder/add-api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { assign } from 'lodash';
import clientFunctionBuilderSymbol from '../builder-symbol';
import { ELEMENT_SNAPSHOT_PROPERTIES, NODE_SNAPSHOT_PROPERTIES } from './snapshot-properties';
import { CantObtainInfoForElementSpecifiedBySelectorError } from '../../errors/test-run';
import getCallsite from '../../errors/get-callsite';
Expand Down Expand Up @@ -36,7 +37,7 @@ var filterNodes = (new ClientFunctionBuilder((nodes, filter, querySelectorRoot)

if (typeof filter === 'function') {
for (var j = 0; j < nodes.length; j++) {
if (filter(nodes[j]))
if (filter(nodes[j], j))
result.push(nodes[j]);
}
}
Expand Down Expand Up @@ -178,6 +179,34 @@ function addCounterProperties (obj, getSelector, SelectorBuilder) {
});
}

function convertFilterToClientFunctionIfNecessary (callsiteName, filter, dependencies) {
if (typeof filter === 'function') {
var builder = filter[clientFunctionBuilderSymbol];
var fn = builder ? builder.fn : filter;
var options = builder ? assign({}, builder.options, { dependencies }) : { dependencies };

return (new ClientFunctionBuilder(fn, options, { instantiation: callsiteName })).getFunction();
}

return filter;
}

function createDerivativeSelectorWithFilter (getSelector, SelectorBuilder, selectorFn, filter, additionalDependencies) {
var collectionModeSelectorBuilder = new SelectorBuilder(getSelector(), { collectionMode: true });

var dependencies = {
selector: collectionModeSelectorBuilder.getFunction(),
filter: filter,
filterNodes: filterNodes
};

dependencies = assign(dependencies, additionalDependencies);

var builder = new SelectorBuilder(selectorFn, { dependencies }, { instantiation: 'Selector' });

return builder.getFunction();
}

function addFilterMethods (obj, getSelector, SelectorBuilder) {
obj.nth = index => {
assertNonNegativeNumber('nth', '"index" argument', index);
Expand All @@ -195,9 +224,11 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) {
return builder.getFunction();
};

obj.filter = filter => {
obj.filter = (filter, dependencies) => {
assertFunctionOrString('filter', '"filter" argument', filter);

filter = convertFilterToClientFunctionIfNecessary('filter', filter, dependencies);

var selectorFn = () => {
/* eslint-disable no-undef */
var nodes = selector();
Expand All @@ -209,41 +240,17 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) {
/* eslint-enable no-undef */
};

var collectionModeSelectorBuilder = new SelectorBuilder(getSelector(), { collectionMode: true });

var dependencies = {
selector: collectionModeSelectorBuilder.getFunction(),
filter: filter,
filterNodes: filterNodes
};

var builder = new SelectorBuilder(selectorFn, { dependencies }, { instantiation: 'Selector' });

return builder.getFunction();
};
}

function createHierachicalSelector (getSelector, SelectorBuilder, selectorFn, filter, additionalDependencies) {
var collectionModeSelectorBuilder = new SelectorBuilder(getSelector(), { collectionMode: true });

var dependencies = {
selector: collectionModeSelectorBuilder.getFunction(),
filter: filter,
expandSelectorResults: expandSelectorResults
return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter);
};

dependencies = assign(dependencies, additionalDependencies);

var builder = new SelectorBuilder(selectorFn, { dependencies }, { instantiation: 'Selector' });

return builder.getFunction();
}

function addHierachicalSelectors (obj, getSelector, SelectorBuilder) {
// Find
obj.find = filter => {
obj.find = (filter, dependencies) => {
assertFunctionOrString('find', '"filter" argument', filter);

filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);

var selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
Expand All @@ -261,28 +268,29 @@ function addHierachicalSelectors (obj, getSelector, SelectorBuilder) {
for (var i = 0; i < cnLength; i++) {
var child = currentNode.childNodes[i];

if (filter(child))
results.push(child);
results.push(child);

visitNode(child);
}
};

visitNode(node);

return results;
return filterNodes(results, filter, null);
});
/* eslint-enable no-undef */
};

return createHierachicalSelector(getSelector, SelectorBuilder, selectorFn, filter);
return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults });
};

// Parent
obj.parent = filter => {
obj.parent = (filter, dependencies) => {
if (filter !== void 0)
assertFunctionOrStringOnNonNegativeNumber('parent', '"filter" argument', filter);

filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);

var selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
Expand All @@ -296,14 +304,16 @@ function addHierachicalSelectors (obj, getSelector, SelectorBuilder) {
/* eslint-enable no-undef */
};

return createHierachicalSelector(getSelector, SelectorBuilder, selectorFn, filter, { filterNodes });
return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults });
};

// Child
obj.child = filter => {
obj.child = (filter, dependencies) => {
if (filter !== void 0)
assertFunctionOrStringOnNonNegativeNumber('child', '"filter" argument', filter);

filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);

var selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
Expand All @@ -322,14 +332,16 @@ function addHierachicalSelectors (obj, getSelector, SelectorBuilder) {
/* eslint-enable no-undef */
};

return createHierachicalSelector(getSelector, SelectorBuilder, selectorFn, filter, { filterNodes });
return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults });
};

// Sibling
obj.sibling = filter => {
obj.sibling = (filter, dependencies) => {
if (filter !== void 0)
assertFunctionOrStringOnNonNegativeNumber('sibling', '"filter" argument', filter);

filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies);

var selectorFn = () => {
/* eslint-disable no-undef */
return expandSelectorResults(selector, node => {
Expand All @@ -353,7 +365,7 @@ function addHierachicalSelectors (obj, getSelector, SelectorBuilder) {
/* eslint-enable no-undef */
};

return createHierachicalSelector(getSelector, SelectorBuilder, selectorFn, filter, { filterNodes });
return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults });
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@
<div id="el4" class="idxEl">This <script>var yo = 3;</script>is element 4.</div>
</section>
<a><b><c></c></b><d>e</d><f><g>h</g></f></a>
</body>

<div id="p2" class="parent2">
<div id="p1" class="parent1">
Expand All @@ -120,4 +119,6 @@
<div>
<div id="common2" class="common class1"></div>
</div>
<div class="find-parent"><div id="find-child1"><div id="find-child2"></div></div><div id="find-child3"></div><div id="find-child4"></div></div>
</body>
</html>
4 changes: 4 additions & 0 deletions test/functional/fixtures/api/es-next/selector/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ describe('[API] Selector', function () {
return runTests('./testcafe-fixtures/selector-test.js', 'Selector "count" and "exists" properties');
});

it('Should provide dependencies and index argument to selector filter', function () {
return runTests('./testcafe-fixtures/selector-test.js', 'Selector filter dependencies and index argument', { only: 'chrome' });
});

describe('Errors', function () {
it('Should handle errors in Selector code', function () {
return runTests('./testcafe-fixtures/selector-test.js', 'Error in code', { shouldFail: true })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -849,3 +849,16 @@ test('Snapshot "count" property - selector error', async () => {
test('Snapshot "exists" property - selector error', async () => {
await Selector(() => [].someUndefMethod()).exists;
});

test('Selector filter dependencies and index argument', async t => {
const isOne = ClientFunction(i => i === 1);
const isTwo = ClientFunction(i => i === 2);
const firstNode = ClientFunction((node, i) => isOne(i));

await t
.expect(Selector('.idxEl').filter((node, i) => isTwo(i), { isTwo }).id).eql('el3')
.expect(Selector('.find-parent').find((node, i) => isOne(i), { isOne }).id).eql('find-child2')
.expect(Selector('#childDiv').parent((node, i) => isTwo(i), { isTwo }).id).eql('p2')
.expect(Selector('.find-parent').child((node, i) => isOne(i), { isOne }).id).eql('find-child3')
.expect(Selector('#find-child1').sibling(firstNode, { isOne }).id).eql('find-child4');
});

0 comments on commit 60a22a1

Please sign in to comment.