Skip to content

Commit

Permalink
Add tests for util modules. Add refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
tormozz48 committed Dec 31, 2015
1 parent 4b35840 commit 2446273
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 80 deletions.
2 changes: 1 addition & 1 deletion .jscsrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"excludeFiles": [
".git",
"node_modules",
"/coverage"
"/coverage/"
],
"requireCurlyBraces": [
"if",
Expand Down
4 changes: 2 additions & 2 deletions .jshintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
node_modules
/coverage
node_modules/
coverage/
12 changes: 8 additions & 4 deletions cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ var _ = require('lodash'),
find = require('./lib/find'),
getView = require('./lib/view');

/**
* Executes find process with given cli options and arguments
* @param {Object} opts - cli options
* @param {Object} args - cli arguments
*/
function execute(opts, args) {
var criterias = util.criteriasFromBEMItems(args.entity);
criterias.push(util.criteriaFromOptions(opts));
var conditions = util.conditionsFromBEMItems(args.entity);
conditions.push(util.conditionsFromOptions(opts));

opts = util.normalizeCliOptions(opts);
find(criterias)
find(conditions)
.pipe(getView(opts.view)())
.pipe(process.stdout);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/find.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'use strict';
var bemWalk = require('bem-walk'),
bemConfig = require('bem-config'),
streamFilter = require('through2-filter'),
utils = require('./util');

module.exports = function(conditions) {
var filters = utils.getFiltersForConditions(conditions),
config = utils.initializeConfig();
config = utils.initializeConfig(bemConfig());

return bemWalk(config.getLevels(), config.getSchema()).pipe(streamFilter.obj(filters.apply));
};
73 changes: 44 additions & 29 deletions lib/util.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
'use strict';

var _ = require('lodash'),
bemConfig = require('bem-config'),
Filter = require('./filter'),
var Filter = require('./filter'),
Criteria = require('./criteria/criteria'),
CriteriaCollection = require('./criteria/criteria-collection');

exports.normalizeCliOptions = function(options) {
options = options || {};

['block', 'element', 'modifier', 'tech'].forEach(function(key) {
delete options[key];
});

return _.defaults(options, {
view: 'plain',
cli: false
});
};

exports.criteriaFromOptions = function(options) {
/**
* Makes conditions model from given options
* @param options
* @returns {Object}
*/
exports.conditionsFromOptions = function(options) {
return {
blocks: options.block || [],
elements: options.element || [],
Expand All @@ -28,26 +18,49 @@ exports.criteriaFromOptions = function(options) {
};
};

exports.criteriasFromBEMItems = function(items) {
/**
* Makes conditions model from parsed BEM items
* @param {Array} items - array of BEM items parsed by bem-naming tool
* @see https://npmjs.org/package/bem-naming
* @returns {Array}
*/
exports.conditionsFromBEMItems = function(items) {
items = items || [];

function get(item, field) {
return item[field]? [item[field]] : [];
}

return items.map(function(item) {
return {
blocks: item.block? [item.block] : [],
elements: item.elem? [item.elem] : [],
modifiers: item.modName? [item.modName] : [],
blocks: get(item, 'block'),
elements: get(item, 'elem'),
modifiers: get(item, 'modName'),
techs: []
};
});
};

exports.initializeConfig = function() {
var config = bemConfig().extended;
/**
* Initialize config from given bem-config with all necessary fall-backs
* @param {Object} config - received by bem-config tool
* @returns {Object}
*/
exports.initializeConfig = function(config) {
config = config.extended;

/**
* Returns list of levels
* @returns {String[]}
*/
function getLevels() {
return config.levels || ['.'];
}

/**
* Return schema object for levels
* @returns {{levels: *}}
*/
function getSchema() {
return {
levels: getLevels().reduce(function(prev, level) {
Expand All @@ -61,6 +74,7 @@ exports.initializeConfig = function() {
}

return {
getConfig: config,
getLevels: getLevels,
getSchema: getSchema
};
Expand All @@ -76,11 +90,12 @@ exports.getFiltersForConditions = function(conditions) {
})),
filters = collection.getFilterCriteria().map(function(criteria) {
return new Filter(criteria);
});
}),
apply = function(item) {
return filters.some(function(filter) {
return filter.apply(item);
});
};

return {apply: function(item) {
return filters.some(function(filter) {
return filter.apply(item);
});
}};
return {apply: apply};
};
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"pretest": "npm run lint",
"lint": "jshint . && jscs .",
"test": "istanbul test _mocha -- --recursive test/",
"cover": "npm run test --cover"
"cover": "istanbul cover _mocha -- --recursive test/"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -57,6 +57,7 @@
"istanbul": "^0.4.1",
"jscs": "^2.7.0",
"jshint": "^2.9.1-rc1",
"mocha": "^2.3.4"
"mocha": "^2.3.4",
"sinon": "^1.17.2"
}
}
160 changes: 119 additions & 41 deletions test/lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,7 @@ var _ = require('lodash'),
util = require('../../lib/util');

describe('util', function() {
describe('normalizeCliOptions', function() {
var expected = {view: 'plain', cli: false};

it('should use empty options and set defaults if options were not set', function() {
assert.deepEqual(util.normalizeCliOptions(), expected);
});

it('should override view option', function() {
assert.deepEqual(util.normalizeCliOptions({view: 'table'}), {view: 'table', cli: false});
});

it('should override cli option', function() {
assert.deepEqual(util.normalizeCliOptions({cli: true}), {view: 'plain', cli: true});
});

it('should remove "block" option field', function() {
assert.deepEqual(util.normalizeCliOptions({block: 'some-block'}), expected);
});

it('should remove "element" field', function() {
assert.deepEqual(util.normalizeCliOptions({element: 'some-element'}), expected);
});

it('should remove "modifier" field', function() {
assert.deepEqual(util.normalizeCliOptions({modifier: 'some-modifier'}), expected);
});

it('should remove "tech" option field', function() {
assert.deepEqual(util.normalizeCliOptions({element: 'some-element'}), expected);
});
});

describe('criteriaFromOptions', function() {
describe('conditionsFromOptions', function() {
var baseExpected = {
blocks: [],
elements: [],
Expand All @@ -45,39 +13,149 @@ describe('util', function() {
};

it('should use given block option', function() {
assert.deepEqual(util.criteriaFromOptions({block: 'some-block'}),
assert.deepEqual(util.conditionsFromOptions({block: 'some-block'}),
_.extend({}, baseExpected, {blocks: 'some-block'}));
});

it('should use empty array if block field was not set', function() {
assert.deepEqual(util.criteriaFromOptions({}), _.extend({}, baseExpected));
assert.deepEqual(util.conditionsFromOptions({}), _.extend({}, baseExpected));
});

it('should use given element option', function() {
assert.deepEqual(util.criteriaFromOptions({element: 'some-elem'}),
assert.deepEqual(util.conditionsFromOptions({element: 'some-elem'}),
_.extend({}, baseExpected, {elements: 'some-elem'}));
});

it('should use empty array if element field was not set', function() {
assert.deepEqual(util.criteriaFromOptions({}), _.extend({}, baseExpected));
assert.deepEqual(util.conditionsFromOptions({}), _.extend({}, baseExpected));
});

it('should use given modifier option', function() {
assert.deepEqual(util.criteriaFromOptions({modifier: 'some-mod'}),
assert.deepEqual(util.conditionsFromOptions({modifier: 'some-mod'}),
_.extend({}, baseExpected, {modifiers: 'some-mod'}));
});

it('should use empty array if modifier field was not set', function() {
assert.deepEqual(util.criteriaFromOptions({}), _.extend({}, baseExpected));
assert.deepEqual(util.conditionsFromOptions({}), _.extend({}, baseExpected));
});

it('should use given tech option', function() {
assert.deepEqual(util.criteriaFromOptions({tech: 'some-tech'}),
assert.deepEqual(util.conditionsFromOptions({tech: 'some-tech'}),
_.extend({}, baseExpected, {techs: 'some-tech'}));
});

it('should use empty array if tech field was not set', function() {
assert.deepEqual(util.criteriaFromOptions({}), _.extend({}, baseExpected));
assert.deepEqual(util.conditionsFromOptions({}), _.extend({}, baseExpected));
});
});

describe('conditionsFromBEMItems', function() {
it('should return empty conditions model if items were not set', function() {
assert.deepEqual(util.conditionsFromBEMItems(), []);
});

it('should use given block name from BEM entity item', function() {
var input = [{block: 'some-block'}],
expected = [{
blocks: ['some-block'],
elements: [],
modifiers: [],
techs: []
}];
assert.deepEqual(util.conditionsFromBEMItems(input), expected);
});

it('should use given block element name from BEM entity item', function() {
var input = [{elem: 'some-element'}],
expected = [{
blocks: [],
elements: ['some-element'],
modifiers: [],
techs: []
}];
assert.deepEqual(util.conditionsFromBEMItems(input), expected);
});

it('should use given block modifier name from BEM entity item', function() {
var input = [{modName: 'some-modifier'}],
expected = [{
blocks: [],
elements: [],
modifiers: ['some-modifier'],
techs: []
}];
assert.deepEqual(util.conditionsFromBEMItems(input), expected);
});
});

describe('initializeConfig', function() {
it('should return object with "getLevel" function', function() {
var config = util.initializeConfig({extended: {}});
assert.instanceOf(config.getLevels, Function);
});

it('should return object with "getShema" function', function() {
var config = util.initializeConfig({extended: {}});
assert.instanceOf(config.getSchema, Function);
});

it('should use [\'.\'] as default set of levels', function() {
var config = util.initializeConfig({extended: {}});
assert.deepEqual(config.getLevels(), ['.']);
});

it('should use given levels as default set of levels', function() {
var config = util.initializeConfig({extended: {levels: ['level1', 'level2']}});
assert.deepEqual(config.getLevels(), ['level1', 'level2']);
});

it('should use default schema level options for given levels if levelOpts was not set', function() {
var config = util.initializeConfig({extended: {levels: ['level1']}});
assert.deepEqual(config.getSchema(), {
levels: {
level1: {scheme: 'nested'}
}
});
});

it('should use default schema for level if levelOpts for it were not set', function() {
var config = util.initializeConfig({extended: {levels: ['level1'], levelOpts: {}}});
assert.deepEqual(config.getSchema(), {
levels: {
level1: {scheme: 'nested'}
}
});
});

it('should use default schema for level if levelOpts for it has not "schema" field', function() {
var config = util.initializeConfig({extended: {levels: ['level1'], levelOpts: {}}});
assert.deepEqual(config.getSchema(), {
levels: {
level1: {scheme: 'nested'}
}
});
});

it('should use given schema for level', function() {
var config = util.initializeConfig({extended: {
levels: ['level1'],
levelOpts: {
level1: {
scheme: 'flat'
}
}
}});
assert.deepEqual(config.getSchema(), {
levels: {
level1: {scheme: 'flat'}
}
});
});
});

describe('getFiltersForConditions', function() {
it('should return result with apply function', function() {
assert.instanceOf(util.getFiltersForConditions().apply, Function);
});
});
});
1 change: 1 addition & 0 deletions test/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

var chai = require('chai');
global.assert = chai.assert;
global.sinon = require('sinon');

0 comments on commit 2446273

Please sign in to comment.