Skip to content

Commit

Permalink
Merge pull request #158 from schemepunk/filter-values
Browse files Browse the repository at this point in the history
feat(transform): offer array and object value filtering
  • Loading branch information
thebruce authored Jun 17, 2019
2 parents e4d2aeb + 125d8f3 commit e24713f
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 9 deletions.
78 changes: 78 additions & 0 deletions __tests__/plugins/transform/filterValues.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'use strict';

const FilterValues = require('../../../lib/plugins/transform/filterValues');

class BaseXform {
constructor(options) {
this.options = options;
}

async transform(value) { // eslint-disable-line class-methods-use-this
return value;
}

async getHoldOvers() {
return Promise.resolve(this.holdOvers);
}
}
const filterValues = new (FilterValues(BaseXform))();

let value;
let value2;

describe('Delimit Values tests', () => {
beforeEach(() => {
filterValues.options = {
filterItems: [
2,
4
],
};
// Test case value.
value = {
attribute1: 1,
attribute2: 2,
attribute3: 3,
attribute4: 4
};
value2 = [1, 2, 3, 4];
});

test('Filter out.', async () => {
filterValues.options.filterBias = 'out';
expect(await filterValues.transform(value)).toEqual({
attribute1: 1,
attribute3: 3
});
});
test('Filter in.', async () => {
filterValues.options.filterBias = 'in';
expect(await filterValues.transform(value)).toEqual({
attribute2: 2,
attribute4: 4
});
});
test('Filter out array.', async () => {
filterValues.options.filterBias = 'out';
expect(await filterValues.transform(value2)).toEqual([
1,
3
]);
});
test('Filter in array.', async () => {
filterValues.options.filterBias = 'in';
expect(await filterValues.transform(value2)).toEqual([
2,
4
]);
});
test('Non array or object will throw.', async () => {
filterValues.options.filterBias = 'in';
try {
await filterValues.transform('this value');
}
catch (error) {
expect(error.message).toBe('Value must be an object or an array to filter.');
}
});
});
7 changes: 7 additions & 0 deletions lib/molotov.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@
"typeAdapter",
"filterObjects"
],
"filterValues": [
"filterValues"
],
"filterValuesMulti": [
"typeAdapter",
"filterValues"
],
"objectKeysTransform": [
"objectKeysTransform"
],
Expand Down
2 changes: 2 additions & 0 deletions lib/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const appendValues = require('./transform/appendValues');
const delimitValues = require('./transform/delimitValues');
const filterAttributes = require('./transform/filterAttributes');
const filterObjects = require('./transform/filterObjects');
const filterValues = require('./transform/filterValues');
const objectKeysTransform = require('./transform/objectKeysTransform');
const prependValues = require('./transform/prependValues');
const regexWordBoundariesValues = require('./transform/regexWordBoundariesValues');
Expand All @@ -40,6 +41,7 @@ const plugins = {
delimitValues,
filterAttributes,
filterObjects,
filterValues,
objectKeysTransform,
prependValues,
regexWordBoundariesValues,
Expand Down
12 changes: 5 additions & 7 deletions lib/plugins/transform/filterAttributes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const _ = require('lodash');
const filterByBias = require('./helpers/filterByBias');
/**
* This is a transformation mixin for SchemePunk.
* SchemePunk mixins follow the formula for mixins described at:
Expand All @@ -21,13 +22,10 @@ module.exports = superclass => class extends superclass {
// This is the bias.
const filterBias = _.get(this, 'options.filterBias', 'out');

const tempValueKeys = _.filter(Object.keys(value), (item) => {
if (filterBias !== 'out') {
// We want to return only the filter items
return filterItems.indexOf(item) > -1;
}
return filterItems.indexOf(item) === -1;
});
const tempValueKeys = _.filter(
Object.keys(value),
item => filterByBias(item, filterItems, filterBias)
);

const tempValue = _.pick(value, tempValueKeys);
// Call super.transform and pass along the new value to honor composition.
Expand Down
43 changes: 43 additions & 0 deletions lib/plugins/transform/filterValues.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

const _ = require('lodash');
const filterByBias = require('./helpers/filterByBias');
/**
* This is a transformation mixin for SchemePunk.
* SchemePunk mixins follow the formula for mixins described at:
* http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/
* More info in the README.
*
*/
module.exports = superclass => class extends superclass {
/**
* Function to transform an array or object by filtering on its values.
* @param value
* A value to perform a transformation upon.
*/
async transform(value) {
if (typeof value !== 'object') {
throw new Error(
'Value must be an object or an array to filter.'
);
}
let tempValues;
// These are the items we will filter out or for.
const filterItems = _.get(this, 'options.filterItems', []);
// This is the bias.
const filterBias = _.get(this, 'options.filterBias', 'out');
if (_.isArray(value)) {
tempValues = _.filter(value, item => filterByBias(item, filterItems, filterBias));
}
else {
tempValues = _.pickBy(value, (val) => {
if (filterBias !== 'out') {
return _.includes(filterItems, val);
}
return !_.includes(filterItems, val);
});
}

return super.transform(tempValues);
}
};
25 changes: 25 additions & 0 deletions lib/plugins/transform/helpers/filterByBias.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';


/**
* Filters a collection based on the value of an item
*
* @param {*} item
* The value we are seeking to assert as included or excluded.
* @param {array<*>} items
* An array of values.
* @param {string} filterBias
* Designates whether to return true based on the inclusion or exclusion of
* an itemToFilterFor within the passed items. Can be "in" or "out".
* @returns {boolean}
* Returns true if the value meets our filter.
*/
function filterByBias(itemToFilterFor, items, filterBias) {
if (filterBias !== 'out') {
// We want to return only the filter items
return items.indexOf(itemToFilterFor) > -1;
}
return items.indexOf(itemToFilterFor) === -1;
}

module.exports = filterByBias;
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"name": "@schemepunk/scheme-punk",
"version": "6.0.0",
"description": "Transformation tool with pluggable sources, transformations, and destinations.",
"scripts": {
"commitmsg": "commitlint -e $GIT_PARAMS",
Expand Down Expand Up @@ -74,7 +73,6 @@
"node": ">=8"
},
"readme": "ERROR: No README data found!",
"_id": "@schemepunk/[email protected]",
"husky": {
"hooks": {
"pre-commit": "npm run lint",
Expand Down

0 comments on commit e24713f

Please sign in to comment.