Skip to content
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

hasAttributes filter method supports attributes with omitted boolean values #277

Merged
merged 1 commit into from
Dec 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
430 changes: 415 additions & 15 deletions docs/Collection.html

Large diffs are not rendered by default.

70 changes: 47 additions & 23 deletions docs/Collection.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ <h1 class="page-title">Source: Collection.js</h1>

'use strict';

var assert = require('assert');
var recast = require('recast');
var _ = require('lodash');
const assert = require('assert');
const recast = require('recast');
const _ = require('lodash');

var astTypes = recast.types;
const astTypes = recast.types;
var types = astTypes.namedTypes;
var NodePath = astTypes.NodePath;
var Node = types.Node;
const NodePath = astTypes.NodePath;
const Node = types.Node;

/**
* This represents a generic collection of node paths. It only has a generic
Expand Down Expand Up @@ -106,6 +106,30 @@ <h1 class="page-title">Source: Collection.js</h1>
return this;
}

/**
* Tests whether at-least one path passes the test implemented by the provided callback.
*
* @param {function} callback
* @return {boolean}
*/
some(callback) {
return this.__paths.some(
(path, i, paths) => callback.call(path, path, i, paths)
);
}

/**
* Tests whether all paths pass the test implemented by the provided callback.
*
* @param {function} callback
* @return {boolean}
*/
every(callback) {
return this.__paths.every(
(path, i, paths) => callback.call(path, path, i, paths)
);
}

/**
* Executes the callback for every path in the collection and returns a new
* collection from the return values (which must be paths).
Expand All @@ -120,15 +144,15 @@ <h1 class="page-title">Source: Collection.js</h1>
* @param {Type} type Force the new collection to be of a specific type
*/
map(callback, type) {
var paths = [];
const paths = [];
this.forEach(function(path) {
/*jshint eqnull:true*/
var result = callback.apply(path, arguments);
let result = callback.apply(path, arguments);
if (result == null) return;
if (!Array.isArray(result)) {
result = [result];
}
for (var i = 0; i &lt; result.length; i++) {
for (let i = 0; i &lt; result.length; i++) {
if (paths.indexOf(result[i]) === -1) {
paths.push(result[i]);
}
Expand Down Expand Up @@ -213,7 +237,7 @@ <h1 class="page-title">Source: Collection.js</h1>
* @param {string|number} ...fields
*/
get() {
var path = this.__paths[0];
const path = this.__paths[0];
if (!path) {
throw Error(
'You cannot call "get" on a collection with no paths. ' +
Expand Down Expand Up @@ -251,11 +275,11 @@ <h1 class="page-title">Source: Collection.js</h1>
* @return {Type} type An AST type
*/
function _inferTypes(paths) {
var _types = [];
let _types = [];

if (paths.length > 0 &amp;&amp; Node.check(paths[0].node)) {
var nodeType = types[paths[0].node.type];
var sameType = paths.length === 1 ||
const nodeType = types[paths[0].node.type];
const sameType = paths.length === 1 ||
paths.every(path => nodeType.check(path.node));

if (sameType) {
Expand Down Expand Up @@ -336,7 +360,7 @@ <h1 class="page-title">Source: Collection.js</h1>
);
}

var CPt = Collection.prototype;
const CPt = Collection.prototype;

/**
* This function adds the provided methods to the prototype of the corresponding
Expand All @@ -347,12 +371,12 @@ <h1 class="page-title">Source: Collection.js</h1>
* @param {Type=} type Optional type to add the methods to
*/
function registerMethods(methods, type) {
for (var methodName in methods) {
for (const methodName in methods) {
if (!methods.hasOwnProperty(methodName)) {
return;
}
if (hasConflictingRegistration(methodName, type)) {
var msg = `There is a conflicting registration for method with name "${methodName}".\nYou tried to register an additional method with `;
let msg = `There is a conflicting registration for method with name "${methodName}".\nYou tried to register an additional method with `;

if (type) {
msg += `type "${type.toString()}".`
Expand All @@ -362,7 +386,7 @@ <h1 class="page-title">Source: Collection.js</h1>

msg += '\nThere are existing registrations for that method with ';

var conflictingRegistrations = CPt[methodName].typedRegistrations;
const conflictingRegistrations = CPt[methodName].typedRegistrations;

if (conflictingRegistrations) {
msg += `type ${Object.keys(conflictingRegistrations).join(', ')}.`;
Expand Down Expand Up @@ -393,13 +417,13 @@ <h1 class="page-title">Source: Collection.js</h1>
throw new Error(`Internal Error: "${methodName}" method is already installed`);
}

var registrations = {};
const registrations = {};

function typedMethod() {
var types = Object.keys(registrations);
const types = Object.keys(registrations);

for (var i = 0; i &lt; types.length; i++) {
var currentType = types[i];
for (let i = 0; i &lt; types.length; i++) {
const currentType = types[i];
if (registrations[currentType] &amp;&amp; this.isOfType(currentType)) {
return registrations[currentType].apply(this, arguments);
}
Expand All @@ -425,7 +449,7 @@ <h1 class="page-title">Source: Collection.js</h1>
return false;
}

var registrations = CPt[methodName] &amp;&amp; CPt[methodName].typedRegistrations;
const registrations = CPt[methodName] &amp;&amp; CPt[methodName].typedRegistrations;

if (!registrations) {
return true;
Expand Down Expand Up @@ -477,7 +501,7 @@ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-js
<br class="clear">

<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.1</a> on Wed Sep 21 2016 16:53:09 GMT-0400 (EDT)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue Oct 09 2018 21:58:15 GMT-0400 (EDT)
</footer>

<script> prettyPrint(); </script>
Expand Down
76 changes: 42 additions & 34 deletions docs/collections_JSXElement.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,32 +38,32 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>

'use strict';

var _ = require('lodash');
var Collection = require('../Collection');
var NodeCollection = require('./Node');
const _ = require('lodash');
const Collection = require('../Collection');
const NodeCollection = require('./Node');

var assert = require('assert');
var recast = require('recast');
var requiresModule = require('./VariableDeclarator').filters.requiresModule;
const assert = require('assert');
const recast = require('recast');
const requiresModule = require('./VariableDeclarator').filters.requiresModule;

var types = recast.types.namedTypes;
var JSXElement = types.JSXElement;
var JSXAttribute = types.JSXAttribute;
var Literal = types.Literal;
const types = recast.types.namedTypes;
const JSXElement = types.JSXElement;
const JSXAttribute = types.JSXAttribute;
const Literal = types.Literal;

/**
* Contains filter methods and mutation methods for processing JSXElements.
* @mixin
*/
var globalMethods = {
const globalMethods = {
/**
* Finds all JSXElements optionally filtered by name
*
* @param {string} name
* @return {Collection}
*/
findJSXElements: function(name) {
var nameFilter = name &amp;&amp; {openingElement: {name: {name: name}}};
const nameFilter = name &amp;&amp; {openingElement: {name: {name: name}}};
return this.find(JSXElement, nameFilter);
},

Expand All @@ -85,7 +85,7 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
return this.find(types.VariableDeclarator)
.filter(requiresModule(moduleName))
.map(function(path) {
var id = path.value.id.name;
const id = path.value.id.name;
if (id) {
return Collection.fromPaths([path])
.closestScope()
Expand All @@ -96,7 +96,7 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
}
};

var filterMethods = {
const filterMethods = {

/**
* Filter method for attributes.
Expand All @@ -105,12 +105,12 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
* @return {function}
*/
hasAttributes: function(attributeFilter) {
var attributeNames = Object.keys(attributeFilter);
const attributeNames = Object.keys(attributeFilter);
return function filter(path) {
if (!JSXElement.check(path.value)) {
return false;
}
var elementAttributes = Object.create(null);
const elementAttributes = Object.create(null);
path.value.openingElement.attributes.forEach(function(attr) {
if (!JSXAttribute.check(attr) ||
!(attr.name.name in attributeFilter)) {
Expand All @@ -123,15 +123,23 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
if (!(name in elementAttributes) ){
return false;
}
var value = elementAttributes[name].value;
var expected = attributeFilter[name];
var actual = Literal.check(value) ? value.value : value.expression;

const value = elementAttributes[name].value;
const expected = attributeFilter[name];

// Only when value is truthy access it's properties
const actual = !value
? value
: Literal.check(value)
? value.value
: value.expression;

if (typeof expected === 'function') {
return expected(actual);
} else {
// Literal attribute values are always strings
return String(expected) === actual;
}

// Literal attribute values are always strings
return String(expected) === actual;
});
};
},
Expand All @@ -156,19 +164,19 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
/**
* @mixin
*/
var traversalMethods = {
const traversalMethods = {

/**
* Returns all child nodes, including literals and expressions.
*
* @return {Collection}
*/
childNodes: function() {
var paths = [];
const paths = [];
this.forEach(function(path) {
var children = path.get('children');
var l = children.value.length;
for (var i = 0; i &lt; l; i++) {
const children = path.get('children');
const l = children.value.length;
for (let i = 0; i &lt; l; i++) {
paths.push(children.get(i));
}
});
Expand All @@ -181,11 +189,11 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
* @return {JSXElementCollection}
*/
childElements: function() {
var paths = [];
const paths = [];
this.forEach(function(path) {
var children = path.get('children');
var l = children.value.length;
for (var i = 0; i &lt; l; i++) {
const children = path.get('children');
const l = children.value.length;
for (let i = 0; i &lt; l; i++) {
if (types.JSXElement.check(children.value[i])) {
paths.push(children.get(i));
}
Expand All @@ -195,7 +203,7 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
},
};

var mappingMethods = {
const mappingMethods = {
/**
* Given a JSXElement, returns its "root" name. E.g. it would return "Foo" for
* both &lt;Foo /> and &lt;Foo.Bar />.
Expand All @@ -204,7 +212,7 @@ <h1 class="page-title">Source: collections/JSXElement.js</h1>
* @return {string}
*/
getRootName: function(path) {
var name = path.value.openingElement.name;
let name = path.value.openingElement.name;
while (types.JSXMemberExpression.check(name)) {
name = name.object;
}
Expand Down Expand Up @@ -238,7 +246,7 @@ <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-js
<br class="clear">

<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.1</a> on Wed Sep 21 2016 16:53:09 GMT-0400 (EDT)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue Oct 09 2018 21:58:15 GMT-0400 (EDT)
</footer>

<script> prettyPrint(); </script>
Expand Down
Loading