57%
core.js
'use strict';
Function _classCallCheck
✓ Was called
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
Branch IfStatement
✗ Positive was not executed (if)
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
✓ Negative was executed (else)
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
require('babel/polyfill');
var fs = require('fs');
var gonzales = require('gonzales-pe');
var minimatch = require('minimatch');
var Errors = require('./errors');
var Plugin = require('./plugin');
var vow = require('vow');
var vfs = require('vow-fs');
var Comb = (function () {
Function Comb
✓ Was called
function Comb() {···
_classCallCheck(this, Comb);

this.config = {};
this.exclude = [];
// Whether lint mode is on.
this.lint = false;
// List of file paths that should be excluded from processing.
this.pathsToExclude = null;
// List of used plugins.
this.plugins = [];
this.pluginsDependencies = {};
// List of supported syntaxes.
this.supportedSyntaxes = new Set();
// Whether verbose mode is on.
this.verbose = false;
}
function Comb() {
_classCallCheck(this, Comb);
this.config = {};
this.exclude = [];
// Whether lint mode is on.
this.lint = false;
// List of file paths that should be excluded from processing.
this.pathsToExclude = null;
// List of used plugins.
this.plugins = [];
this.pluginsDependencies = {};
// List of supported syntaxes.
this.supportedSyntaxes = new Set();
// Whether verbose mode is on.
this.verbose = false;
}
Function configure
✓ Was called
Comb.prototype.configure = function configure(config) {···
if (typeof config !== 'object')
// TODO: throw error
throw new Error();

this.lint = config.lint;
this.verbose = config.verbose;
if (config.exclude) this.exclude = config.exclude.map(function (pattern) {
return new minimatch.Minimatch(pattern);
});

for (var i = 0, l = this.plugins.length; i < l; i++) {
var plugin = this.plugins[i];
var _name = plugin.name;
if (!config.hasOwnProperty(_name)) continue;

try {
plugin.value = config[_name];
this.config[_name] = plugin.value;
} catch (e) {}
}

// Chaining.
return this;
};
Comb.prototype.configure = function configure(config) {
Branch IfStatement
✓ Positive was executed (if)
throw new Error();
✓ Negative was executed (else)
throw new Error();···

this.lint = config.lint;
if (typeof config !== 'object')
// TODO: throw error
throw new Error();
this.lint = config.lint;
this.verbose = config.verbose;
Function (anonymous_5)
✓ Was called
if (config.exclude) this.exclude = config.exclude.map(function (pattern) {···
return new minimatch.Minimatch(pattern);
});
Branch IfStatement
✓ Positive was executed (if)
if (config.exclude) this.exclude = config.exclude.map(function (pattern) {···
return new minimatch.Minimatch(pattern);
});
✓ Negative was executed (else)
});···

for (var i = 0, l = this.plugins.length; i < l; i++) {
if (config.exclude) this.exclude = config.exclude.map(function (pattern) {
return new minimatch.Minimatch(pattern);
});
for (var i = 0, l = this.plugins.length; i < l; i++) {
var plugin = this.plugins[i];
var _name = plugin.name;
Branch IfStatement
✗ Positive was not executed (if)
if (!config.hasOwnProperty(_name)) continue;
✓ Negative was executed (else)
if (!config.hasOwnProperty(_name)) continue;···

try {
if (!config.hasOwnProperty(_name)) continue;
try {
plugin.value = config[_name];
this.config[_name] = plugin.value;
} catch (e) {}
}
// Chaining.
return this;
};
Function getAcceptableFilesFromDirectory
✓ Was called
Comb.prototype.getAcceptableFilesFromDirectory = function getAcceptableFilesFromDirectory(path) {···
if (!this.shouldProcess(path)) return;

var files = [];
var filesInThisDir = fs.readdirSync(path);

for (var i = 0, fl = filesInThisDir.length; i < fl; i++) {
var fullname = path + '/' + filesInThisDir[i];
var stat = fs.statSync(fullname);
if (stat.isDirectory() && this.shouldProcess(fullname)) files = files.concat(this.getAcceptableFilesFromDirectory(fullname));else if (this.shouldProcessFile(fullname)) files.push(fullname);
}

return files;
};
Comb.prototype.getAcceptableFilesFromDirectory = function getAcceptableFilesFromDirectory(path) {
Branch IfStatement
✗ Positive was not executed (if)
if (!this.shouldProcess(path)) return;
✓ Negative was executed (else)
if (!this.shouldProcess(path)) return;···

var files = [];
if (!this.shouldProcess(path)) return;
var files = [];
var filesInThisDir = fs.readdirSync(path);
for (var i = 0, fl = filesInThisDir.length; i < fl; i++) {
var fullname = path + '/' + filesInThisDir[i];
var stat = fs.statSync(fullname);
Branch IfStatement
✓ Positive was executed (if)
if (stat.isDirectory() && this.shouldProcess(fullname)) files = files.concat(this.getAcceptableFilesFromDirectory(fullname));else if (this.shouldProcessFile(fullname)) files.push(fullname);
✓ Negative was executed (else)
if (stat.isDirectory() && this.shouldProcess(fullname)) files = files.concat(this.getAcceptableFilesFromDirectory(fullname));else if (this.shouldProcessFile(fullname)) files.push(fullname);
Branch LogicalExpression
✓ Was returned
if (stat.isDirectory() && this.shouldProcess(fullname)) files = files.concat(this.getAcceptableFilesFromDirectory(fullname));else if (this.shouldProcessFile(fullname)) files.push(fullname);
✓ Was returned
if (stat.isDirectory() && this.shouldProcess(fullname)) files = files.concat(this.getAcceptableFilesFromDirectory(fullname));else if (this.shouldProcessFile(fullname)) files.push(fullname);
Branch IfStatement
✓ Positive was executed (if)
if (stat.isDirectory() && this.shouldProcess(fullname)) files = files.concat(this.getAcceptableFilesFromDirectory(fullname));else if (this.shouldProcessFile(fullname)) files.push(fullname);
✓ Negative was executed (else)
if (stat.isDirectory() && this.shouldProcess(fullname)) files = files.concat(this.getAcceptableFilesFromDirectory(fullname));else if (this.shouldProcessFile(fullname)) files.push(fullname);···
}
if (stat.isDirectory() && this.shouldProcess(fullname)) files = files.concat(this.getAcceptableFilesFromDirectory(fullname));else if (this.shouldProcessFile(fullname)) files.push(fullname);
}
return files;
};
/**
* @param {String} path
* @returns {Promise}
*/
Function lintDirectory
✓ Was called
Comb.prototype.lintDirectory = function lintDirectory(path) {···
var _this = this;

var files = this.getAcceptableFilesFromDirectory(path);
var promises = files.map(function (file) {
return _this.lintFile(file);
});
return Promise.all(promises);
};
Comb.prototype.lintDirectory = function lintDirectory(path) {
var _this = this;
var files = this.getAcceptableFilesFromDirectory(path);
Function (anonymous_8)
✓ Was called
var promises = files.map(function (file) {···
return _this.lintFile(file);
});
var promises = files.map(function (file) {
return _this.lintFile(file);
});
return Promise.all(promises);
};
/**
* @param {String} path
* @returns {Promise}
*/
Function lintFile
✓ Was called
Comb.prototype.lintFile = function lintFile(path) {···
var _this2 = this;

var syntax = path.split('.').pop();
return this.readFile(path).then(function (string) {
return _this2.lintString(string, { syntax: syntax, filename: path });
});
};
Comb.prototype.lintFile = function lintFile(path) {
var _this2 = this;
var syntax = path.split('.').pop();
Function (anonymous_10)
✓ Was called
return this.readFile(path).then(function (string) {···
return _this2.lintString(string, { syntax: syntax, filename: path });
});
return this.readFile(path).then(function (string) {
return _this2.lintString(string, { syntax: syntax, filename: path });
});
};
/**
* @param {String} path
*/
Function lintPath
✓ Was called
Comb.prototype.lintPath = function lintPath(path) {···
path = path.replace(/\/$/, '');
return fs.statSync(path).isDirectory() ? this.lintDirectory(path) : this.lintFile(path);
};
Comb.prototype.lintPath = function lintPath(path) {
path = path.replace(/\/$/, '');
Branch ConditionalExpression
✓ Positive was returned (? ...)
return fs.statSync(path).isDirectory() ? this.lintDirectory(path) : this.lintFile(path);
✓ Negative was returned (: ...)
return fs.statSync(path).isDirectory() ? this.lintDirectory(path) : this.lintFile(path);
return fs.statSync(path).isDirectory() ? this.lintDirectory(path) : this.lintFile(path);
};
/**
* @param {String} text
* @param {{context: String, filename: String, syntax: String}} options
* @returns {Promise} Resolves with <Array> list of found errors.
*/
Function lintString
✓ Was called
Comb.prototype.lintString = function lintString(text, options) {···
return this.parseString(text, options).then(this.lintTree.bind(this));
};
Comb.prototype.lintString = function lintString(text, options) {
return this.parseString(text, options).then(this.lintTree.bind(this));
};
/**
* @param {Node} ast
* @param {String=} filename
* @return {Promise} Resolves with <Array> list of errors.
*/
Function lintTree
✓ Was called
Comb.prototype.lintTree = function lintTree(ast, filename) {···
var _this3 = this;

var errors = [];
var config = this.config;

return new Promise(function (resolve) {
_this3.plugins.filter(function (plugin) {
return typeof plugin.value !== null && typeof plugin.lint === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
}).forEach(function (plugin) {
var e = plugin.lint(ast, config);
errors = errors.concat(e);
});

if (filename) {
errors.map(function (error) {
error.filename = filename;
return error;
});
}

resolve(errors);
});
};
Comb.prototype.lintTree = function lintTree(ast, filename) {
var _this3 = this;
var errors = [];
var config = this.config;
Function (anonymous_14)
✓ Was called
return new Promise(function (resolve) {···
_this3.plugins.filter(function (plugin) {
return typeof plugin.value !== null && typeof plugin.lint === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
}).forEach(function (plugin) {
var e = plugin.lint(ast, config);
errors = errors.concat(e);
});

if (filename) {
errors.map(function (error) {
error.filename = filename;
return error;
});
}

resolve(errors);
});
return new Promise(function (resolve) {
Function (anonymous_15)
✓ Was called
_this3.plugins.filter(function (plugin) {···
return typeof plugin.value !== null && typeof plugin.lint === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
}).forEach(function (plugin) {
_this3.plugins.filter(function (plugin) {
Branch LogicalExpression
✓ Was returned
return typeof plugin.value !== null && typeof plugin.lint === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
✗ Was not returned
return typeof plugin.value !== null && typeof plugin.lint === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
Branch LogicalExpression
✓ Was returned
return typeof plugin.value !== null && typeof plugin.lint === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
✗ Was not returned
return typeof plugin.value !== null && typeof plugin.lint === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
return typeof plugin.value !== null && typeof plugin.lint === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
Function (anonymous_16)
✓ Was called
}).forEach(function (plugin) {···
var e = plugin.lint(ast, config);
errors = errors.concat(e);
});
}).forEach(function (plugin) {
var e = plugin.lint(ast, config);
errors = errors.concat(e);
});
Branch IfStatement
✓ Positive was executed (if)
if (filename) {···
errors.map(function (error) {
error.filename = filename;
return error;
});
}
✓ Negative was executed (else)
}···

resolve(errors);
if (filename) {
Function (anonymous_17)
✓ Was called
errors.map(function (error) {···
error.filename = filename;
return error;
});
errors.map(function (error) {
error.filename = filename;
return error;
});
}
resolve(errors);
});
};
Function parseString
✓ Was called
Comb.prototype.parseString = function parseString(text, options) {···
var syntax = options && options.syntax;
var filename = options && options.filename || '';
var context = options && options.context;
var tree = undefined;

if (!text) return this.lint ? [] : text;

if (!syntax) syntax = 'css';
this.syntax = syntax;

return new Promise(function (resolve) {
try {
tree = gonzales.parse(text, { syntax: syntax, rule: context });
resolve(tree, filename);
} catch (e) {
var version = require('../package.json').version;
var message = filename ? [filename] : [];
message.push(e.message);
message.push('CSScomb Core version: ' + version);
e.stack = e.message = message.join('\n');
throw e;
}
});
};
Comb.prototype.parseString = function parseString(text, options) {
Branch LogicalExpression
✓ Was returned
var syntax = options && options.syntax;
✓ Was returned
var syntax = options && options.syntax;
var syntax = options && options.syntax;
Branch LogicalExpression
✓ Was returned
var filename = options && options.filename || '';
✓ Was returned
var filename = options && options.filename || '';
Branch LogicalExpression
✓ Was returned
var filename = options && options.filename || '';
✓ Was returned
var filename = options && options.filename || '';
var filename = options && options.filename || '';
Branch LogicalExpression
✓ Was returned
var context = options && options.context;
✓ Was returned
var context = options && options.context;
var context = options && options.context;
var tree = undefined;
Branch IfStatement
✗ Positive was not executed (if)
if (!text) return this.lint ? [] : text;
✓ Negative was executed (else)
if (!text) return this.lint ? [] : text;···

if (!syntax) syntax = 'css';
Branch ConditionalExpression
✗ Positive was not returned (? ...)
if (!text) return this.lint ? [] : text;
✗ Negative was not returned (: ...)
if (!text) return this.lint ? [] : text;
if (!text) return this.lint ? [] : text;
Branch IfStatement
✓ Positive was executed (if)
if (!syntax) syntax = 'css';
✓ Negative was executed (else)
if (!syntax) syntax = 'css';···
this.syntax = syntax;
if (!syntax) syntax = 'css';
this.syntax = syntax;
Function (anonymous_19)
✓ Was called
return new Promise(function (resolve) {···
try {
tree = gonzales.parse(text, { syntax: syntax, rule: context });
resolve(tree, filename);
} catch (e) {
var version = require('../package.json').version;
var message = filename ? [filename] : [];
message.push(e.message);
message.push('CSScomb Core version: ' + version);
e.stack = e.message = message.join('\n');
throw e;
}
});
return new Promise(function (resolve) {
try {
tree = gonzales.parse(text, { syntax: syntax, rule: context });
resolve(tree, filename);
} catch (e) {
var version = require('../package.json').version;
Branch ConditionalExpression
✗ Positive was not returned (? ...)
var message = filename ? [filename] : [];
✗ Negative was not returned (: ...)
var message = filename ? [filename] : [];
var message = filename ? [filename] : [];
message.push(e.message);
message.push('CSScomb Core version: ' + version);
e.stack = e.message = message.join('\n');
throw e;
}
});
};
Function pluginAlreadyUsed
✓ Was called
Comb.prototype.pluginAlreadyUsed = function pluginAlreadyUsed(name) {···
return this.pluginIndex(name) !== -1;
};
Comb.prototype.pluginAlreadyUsed = function pluginAlreadyUsed(name) {
return this.pluginIndex(name) !== -1;
};
Function pluginIndex
✓ Was called
Comb.prototype.pluginIndex = function pluginIndex(name) {···
var index = -1;
this.plugins.some(function (plugin, i) {
if (plugin.name === name) {
index = i;
return true;
}
});
return index;
};
Comb.prototype.pluginIndex = function pluginIndex(name) {
var index = -1;
Function (anonymous_22)
✗ Was not called
this.plugins.some(function (plugin, i) {···
if (plugin.name === name) {
index = i;
return true;
}
});
this.plugins.some(function (plugin, i) {
Branch IfStatement
✗ Positive was not executed (if)
if (plugin.name === name) {···
index = i;
return true;
}
✗ Negative was not executed (else)
}···
});
if (plugin.name === name) {
index = i;
return true;
}
});
return index;
};
/**
* Processes directory recursively.
*
* @param {String} path
* @returns {Promise}
*/
Function processDirectory
✗ Was not called
Comb.prototype.processDirectory = function processDirectory(path) {···
var that = this;

return vfs.listDir(path).then(function (filenames) {
return vow.all(filenames.map(function (filename) {
var fullname = path + '/' + filename;
return vfs.stat(fullname).then(function (stat) {
if (stat.isDirectory() && that.shouldProcess(fullname)) {
return that.processDirectory(fullname);
} else {
return that.processFile(fullname);
}
});
})).then(function (results) {
return [].concat.apply([], results);
});
});
};
Comb.prototype.processDirectory = function processDirectory(path) {
var that = this;
Function (anonymous_24)
✗ Was not called
return vfs.listDir(path).then(function (filenames) {···
return vow.all(filenames.map(function (filename) {
var fullname = path + '/' + filename;
return vfs.stat(fullname).then(function (stat) {
if (stat.isDirectory() && that.shouldProcess(fullname)) {
return that.processDirectory(fullname);
} else {
return that.processFile(fullname);
}
});
})).then(function (results) {
return [].concat.apply([], results);
});
});
return vfs.listDir(path).then(function (filenames) {
Function (anonymous_25)
✗ Was not called
return vow.all(filenames.map(function (filename) {···
var fullname = path + '/' + filename;
return vfs.stat(fullname).then(function (stat) {
if (stat.isDirectory() && that.shouldProcess(fullname)) {
return that.processDirectory(fullname);
} else {
return that.processFile(fullname);
}
});
})).then(function (results) {
return vow.all(filenames.map(function (filename) {
var fullname = path + '/' + filename;
Function (anonymous_26)
✗ Was not called
return vfs.stat(fullname).then(function (stat) {···
if (stat.isDirectory() && that.shouldProcess(fullname)) {
return that.processDirectory(fullname);
} else {
return that.processFile(fullname);
}
});
return vfs.stat(fullname).then(function (stat) {
Branch IfStatement
✗ Positive was not executed (if)
if (stat.isDirectory() && that.shouldProcess(fullname)) {···
return that.processDirectory(fullname);
} else {
✗ Negative was not executed (else)
} else {···
return that.processFile(fullname);
}
Branch LogicalExpression
✗ Was not returned
if (stat.isDirectory() && that.shouldProcess(fullname)) {
✗ Was not returned
if (stat.isDirectory() && that.shouldProcess(fullname)) {
if (stat.isDirectory() && that.shouldProcess(fullname)) {
return that.processDirectory(fullname);
} else {
return that.processFile(fullname);
}
});
Function (anonymous_27)
✗ Was not called
})).then(function (results) {···
return [].concat.apply([], results);
});
})).then(function (results) {
return [].concat.apply([], results);
});
});
};
/**
* Processes single file.
*
* @param {String} path
* @returns {Promise}
*/
Function processFile
✗ Was not called
Comb.prototype.processFile = function processFile(path) {···
var that = this;

if (!this.shouldProcessFile(path)) return;

return vfs.read(path, 'utf8').then(function (data) {
var syntax = path.split('.').pop();
var processedData = that.processString(data, {
syntax: syntax,
filename: path
});

if (that.lint) return processedData;

if (data === processedData) {
if (that.verbose) console.log(' ', path);
return 0;
}

return vfs.write(path, processedData, 'utf8').then(function () {
if (that.verbose) console.log('✓', path);
return 1;
});
});
};
Comb.prototype.processFile = function processFile(path) {
var that = this;
Branch IfStatement
✗ Positive was not executed (if)
if (!this.shouldProcessFile(path)) return;
✗ Negative was not executed (else)
if (!this.shouldProcessFile(path)) return;···

return vfs.read(path, 'utf8').then(function (data) {
if (!this.shouldProcessFile(path)) return;
Function (anonymous_29)
✗ Was not called
return vfs.read(path, 'utf8').then(function (data) {···
var syntax = path.split('.').pop();
var processedData = that.processString(data, {
syntax: syntax,
filename: path
});

if (that.lint) return processedData;

if (data === processedData) {
if (that.verbose) console.log(' ', path);
return 0;
}

return vfs.write(path, processedData, 'utf8').then(function () {
if (that.verbose) console.log('✓', path);
return 1;
});
});
return vfs.read(path, 'utf8').then(function (data) {
var syntax = path.split('.').pop();
var processedData = that.processString(data, {
syntax: syntax,
filename: path
});
Branch IfStatement
✗ Positive was not executed (if)
if (that.lint) return processedData;
✗ Negative was not executed (else)
if (that.lint) return processedData;···

if (data === processedData) {
if (that.lint) return processedData;
Branch IfStatement
✗ Positive was not executed (if)
if (data === processedData) {···
if (that.verbose) console.log(' ', path);
return 0;
}
✗ Negative was not executed (else)
}···

return vfs.write(path, processedData, 'utf8').then(function () {
if (data === processedData) {
Branch IfStatement
✗ Positive was not executed (if)
if (that.verbose) console.log(' ', path);
✗ Negative was not executed (else)
if (that.verbose) console.log(' ', path);···
return 0;
if (that.verbose) console.log(' ', path);
return 0;
}
Function (anonymous_30)
✗ Was not called
return vfs.write(path, processedData, 'utf8').then(function () {···
if (that.verbose) console.log('✓', path);
return 1;
});
return vfs.write(path, processedData, 'utf8').then(function () {
Branch IfStatement
✗ Positive was not executed (if)
if (that.verbose) console.log('✓', path);
✗ Negative was not executed (else)
if (that.verbose) console.log('✓', path);···
return 1;
if (that.verbose) console.log('✓', path);
return 1;
});
});
};
Function readFile
✓ Was called
Comb.prototype.readFile = function readFile(path) {···
var _this4 = this;

return new Promise(function (resolve, reject) {
if (!_this4.shouldProcessFile(path)) reject();

fs.readFile(path, 'utf8', function (e, string) {
if (e) reject();
resolve(string);
});
});
};
Comb.prototype.readFile = function readFile(path) {
var _this4 = this;
Function (anonymous_32)
✓ Was called
return new Promise(function (resolve, reject) {···
if (!_this4.shouldProcessFile(path)) reject();

fs.readFile(path, 'utf8', function (e, string) {
if (e) reject();
resolve(string);
});
});
return new Promise(function (resolve, reject) {
Branch IfStatement
✓ Positive was executed (if)
if (!_this4.shouldProcessFile(path)) reject();
✓ Negative was executed (else)
if (!_this4.shouldProcessFile(path)) reject();···

fs.readFile(path, 'utf8', function (e, string) {
if (!_this4.shouldProcessFile(path)) reject();
Function (anonymous_33)
✓ Was called
fs.readFile(path, 'utf8', function (e, string) {···
if (e) reject();
resolve(string);
});
fs.readFile(path, 'utf8', function (e, string) {
Branch IfStatement
✗ Positive was not executed (if)
if (e) reject();
✓ Negative was executed (else)
if (e) reject();···
resolve(string);
if (e) reject();
resolve(string);
});
});
};
/**
* Processes directory or file.
*
* @returns {Promise}
*/
Function processPath
✗ Was not called
Comb.prototype.processPath = function processPath(path) {···
var that = this;
path = path.replace(/\/$/, '');

return vfs.stat(path).then(function (stat) {
if (stat.isDirectory()) {
return that.processDirectory(path);
} else {
return that.processFile(path);
}
});
};
Comb.prototype.processPath = function processPath(path) {
var that = this;
path = path.replace(/\/$/, '');
Function (anonymous_35)
✗ Was not called
return vfs.stat(path).then(function (stat) {···
if (stat.isDirectory()) {
return that.processDirectory(path);
} else {
return that.processFile(path);
}
});
return vfs.stat(path).then(function (stat) {
Branch IfStatement
✗ Positive was not executed (if)
if (stat.isDirectory()) {···
return that.processDirectory(path);
} else {
✗ Negative was not executed (else)
} else {···
return that.processFile(path);
}
if (stat.isDirectory()) {
return that.processDirectory(path);
} else {
return that.processFile(path);
}
});
};
/**
* Processes a string.
*
* @param {String} text
* @param {{context: String, filename: String, syntax: String}} options
* @returns {String} Processed string
*/
Function processString
✓ Was called
Comb.prototype.processString = function processString(text, options) {···
return this.parseString(text, options).then(this.processTree.bind(this)).then(function (ast) {
return ast.toString();
});
};
Comb.prototype.processString = function processString(text, options) {
Function (anonymous_37)
✓ Was called
return this.parseString(text, options).then(this.processTree.bind(this)).then(function (ast) {···
return ast.toString();
});
return this.parseString(text, options).then(this.processTree.bind(this)).then(function (ast) {
return ast.toString();
});
};
/**
* @param {Node} ast
* @return {Node} Transformed AST
*/
Function processTree
✓ Was called
Comb.prototype.processTree = function processTree(ast) {···
var _this5 = this;

var config = this.config;

return new Promise(function (resolve) {
_this5.plugins.filter(function (plugin) {
return plugin.value !== null && typeof plugin.process === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
}).forEach(function (plugin) {
plugin.process(ast, config);
});

resolve(ast);
});
};
Comb.prototype.processTree = function processTree(ast) {
var _this5 = this;
var config = this.config;
Function (anonymous_39)
✓ Was called
return new Promise(function (resolve) {···
_this5.plugins.filter(function (plugin) {
return plugin.value !== null && typeof plugin.process === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
}).forEach(function (plugin) {
plugin.process(ast, config);
});

resolve(ast);
});
return new Promise(function (resolve) {
Function (anonymous_40)
✓ Was called
_this5.plugins.filter(function (plugin) {···
return plugin.value !== null && typeof plugin.process === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
}).forEach(function (plugin) {
_this5.plugins.filter(function (plugin) {
Branch LogicalExpression
✓ Was returned
return plugin.value !== null && typeof plugin.process === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
✗ Was not returned
return plugin.value !== null && typeof plugin.process === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
Branch LogicalExpression
✓ Was returned
return plugin.value !== null && typeof plugin.process === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
✗ Was not returned
return plugin.value !== null && typeof plugin.process === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
return plugin.value !== null && typeof plugin.process === 'function' && plugin.syntax.indexOf(ast.syntax) !== -1;
Function (anonymous_41)
✓ Was called
}).forEach(function (plugin) {···
plugin.process(ast, config);
});
}).forEach(function (plugin) {
plugin.process(ast, config);
});
resolve(ast);
});
};
/**
* Checks if path is not present in `exclude` list.
*
* @param {String} path
* @returns {Boolean} False if specified path is present in `exclude` list.
* Otherwise returns true.
*/
Function shouldProcess
✓ Was called
Comb.prototype.shouldProcess = function shouldProcess(path) {···
path = path.replace(/\/$/, '');
if (!fs.existsSync(path)) {
console.warn('Path ' + path + ' was not found.');
return false;
}

path = path.replace(/^\.\//, '');
return this.exclude.every(function (e) {
return !e.match(path);
});
};
Comb.prototype.shouldProcess = function shouldProcess(path) {
path = path.replace(/\/$/, '');
Branch IfStatement
✗ Positive was not executed (if)
if (!fs.existsSync(path)) {···
console.warn('Path ' + path + ' was not found.');
return false;
}
✓ Negative was executed (else)
}···

path = path.replace(/^\.\//, '');
if (!fs.existsSync(path)) {
console.warn('Path ' + path + ' was not found.');
return false;
}
path = path.replace(/^\.\//, '');
Function (anonymous_43)
✗ Was not called
return this.exclude.every(function (e) {···
return !e.match(path);
});
return this.exclude.every(function (e) {
return !e.match(path);
});
};
/**
* Checks if specified path is not present in `exclude` list and it has one of
* acceptable extensions.
*
* @param {String} path
* @returns {Boolean} False if the path either has unacceptable extension or
* is present in `exclude` list. True if everything is ok.
*/
Function shouldProcessFile
✓ Was called
Comb.prototype.shouldProcessFile = function shouldProcessFile(path) {···
// Get file's extension:
var syntax = path.split('.').pop();

// Check if syntax is supported. If not, ignore the file:
if (!this.supportedSyntaxes.has(syntax)) return false;

return this.shouldProcess(path);
};
Comb.prototype.shouldProcessFile = function shouldProcessFile(path) {
// Get file's extension:
var syntax = path.split('.').pop();
// Check if syntax is supported. If not, ignore the file:
Branch IfStatement
✓ Positive was executed (if)
if (!this.supportedSyntaxes.has(syntax)) return false;
✓ Negative was executed (else)
if (!this.supportedSyntaxes.has(syntax)) return false;···

return this.shouldProcess(path);
if (!this.supportedSyntaxes.has(syntax)) return false;
return this.shouldProcess(path);
};
/**
* Add a plugin.
* @param {Object} options
* @return {Comb}
*/
Function use
✓ Was called
Comb.prototype.use = function use(options) {···
// Check whether plugin with the same is already used.
var pluginName = options.name;
if (this.pluginAlreadyUsed(pluginName)) {
if (this.verbose) console.warn(Errors.twoPluginsWithSameName(pluginName));
return;
}

var plugin = new Plugin(options);

plugin.syntax.forEach(function (s) {
this.supportedSyntaxes.add(s);
}, this);

// Sort plugins.
var pluginToRunBefore = plugin.runBefore;

if (!pluginToRunBefore) {
this.plugins.push(plugin);
} else {
if (this.pluginAlreadyUsed(pluginToRunBefore)) {
var i = this.pluginIndex(pluginToRunBefore);
this.plugins.splice(i, 0, plugin);
} else {
this.plugins.push(plugin);
if (!this.pluginsDependencies[pluginToRunBefore]) this.pluginsDependencies[pluginToRunBefore] = [];
this.pluginsDependencies[pluginToRunBefore].push(pluginName);
}
}

var dependents = this.pluginsDependencies[pluginName];
if (!dependents) return this;

for (var i = 0, l = dependents.length; i < l; i++) {
var _name2 = dependents[i];
var x = this.pluginIndex(_name2);
var _plugin = this.plugins[x];
this.plugins.splice(x, 1);
this.plugins.splice(-1, 0, _plugin);
}

// Chaining.
return this;
};
Comb.prototype.use = function use(options) {
// Check whether plugin with the same is already used.
var pluginName = options.name;
Branch IfStatement
✗ Positive was not executed (if)
if (this.pluginAlreadyUsed(pluginName)) {···
if (this.verbose) console.warn(Errors.twoPluginsWithSameName(pluginName));
return;
}
✓ Negative was executed (else)
}···

var plugin = new Plugin(options);
if (this.pluginAlreadyUsed(pluginName)) {
Branch IfStatement
✗ Positive was not executed (if)
if (this.verbose) console.warn(Errors.twoPluginsWithSameName(pluginName));
✗ Negative was not executed (else)
if (this.verbose) console.warn(Errors.twoPluginsWithSameName(pluginName));···
return;
if (this.verbose) console.warn(Errors.twoPluginsWithSameName(pluginName));
return;
}
var plugin = new Plugin(options);
Function (anonymous_46)
✓ Was called
plugin.syntax.forEach(function (s) {···
this.supportedSyntaxes.add(s);
}, this);
plugin.syntax.forEach(function (s) {
this.supportedSyntaxes.add(s);
}, this);
// Sort plugins.
var pluginToRunBefore = plugin.runBefore;
Branch IfStatement
✓ Positive was executed (if)
if (!pluginToRunBefore) {···
this.plugins.push(plugin);
} else {
✗ Negative was not executed (else)
} else {···
if (this.pluginAlreadyUsed(pluginToRunBefore)) {
var i = this.pluginIndex(pluginToRunBefore);
this.plugins.splice(i, 0, plugin);
} else {
this.plugins.push(plugin);
if (!this.pluginsDependencies[pluginToRunBefore]) this.pluginsDependencies[pluginToRunBefore] = [];
this.pluginsDependencies[pluginToRunBefore].push(pluginName);
}
}
if (!pluginToRunBefore) {
this.plugins.push(plugin);
} else {
Branch IfStatement
✗ Positive was not executed (if)
if (this.pluginAlreadyUsed(pluginToRunBefore)) {···
var i = this.pluginIndex(pluginToRunBefore);
this.plugins.splice(i, 0, plugin);
} else {
✗ Negative was not executed (else)
} else {···
this.plugins.push(plugin);
if (!this.pluginsDependencies[pluginToRunBefore]) this.pluginsDependencies[pluginToRunBefore] = [];
this.pluginsDependencies[pluginToRunBefore].push(pluginName);
}
if (this.pluginAlreadyUsed(pluginToRunBefore)) {
var i = this.pluginIndex(pluginToRunBefore);
this.plugins.splice(i, 0, plugin);
} else {
this.plugins.push(plugin);
Branch IfStatement
✗ Positive was not executed (if)
if (!this.pluginsDependencies[pluginToRunBefore]) this.pluginsDependencies[pluginToRunBefore] = [];
✗ Negative was not executed (else)
if (!this.pluginsDependencies[pluginToRunBefore]) this.pluginsDependencies[pluginToRunBefore] = [];···
this.pluginsDependencies[pluginToRunBefore].push(pluginName);
if (!this.pluginsDependencies[pluginToRunBefore]) this.pluginsDependencies[pluginToRunBefore] = [];
this.pluginsDependencies[pluginToRunBefore].push(pluginName);
}
}
var dependents = this.pluginsDependencies[pluginName];
Branch IfStatement
✓ Positive was executed (if)
if (!dependents) return this;
✗ Negative was not executed (else)
if (!dependents) return this;···

for (var i = 0, l = dependents.length; i < l; i++) {
if (!dependents) return this;
for (var i = 0, l = dependents.length; i < l; i++) {
var _name2 = dependents[i];
var x = this.pluginIndex(_name2);
var _plugin = this.plugins[x];
this.plugins.splice(x, 1);
this.plugins.splice(-1, 0, _plugin);
}
// Chaining.
return this;
};
return Comb;
})();
module.exports = Comb;
// TODO: throw error
errors.js
'use strict';
var format = require('./format');
module.exports = {
Function implementSetValue
✓ Was called
implementSetValue: function implementSetValue(valueType) {···
if (typeof valueType === 'undefined') throw new Error();

return format('If you see this message and you are not\n a developer adding a new option, please open an issue here:\n https://github.com/csscomb/core/issues/new\n\n For option to accept values of type "' + valueType + '"\n you need to implement custom `setValue()` method.');
},
implementSetValue: function implementSetValue(valueType) {
Branch IfStatement
✓ Positive was executed (if)
if (typeof valueType === 'undefined') throw new Error();
✓ Negative was executed (else)
if (typeof valueType === 'undefined') throw new Error();···

return format('If you see this message and you are not\n a developer adding a new option, please open an issue here:\n https://github.com/csscomb/core/issues/new\n\n For option to accept values of type "' + valueType + '"\n you need to implement custom `setValue()` method.');
if (typeof valueType === 'undefined') throw new Error();
return format('If you see this message and you are not\n a developer adding a new option, please open an issue here:\n https://github.com/csscomb/core/issues/new\n\n For option to accept values of type "' + valueType + '"\n you need to implement custom `setValue()` method.');
},
Function missingName
✓ Was called
missingName: function missingName() {···
return 'Plugin must have a valid `name` property.';
},
missingName: function missingName() {
return 'Plugin must have a valid `name` property.';
},
Function missingSetValue
✓ Was called
missingSetValue: function missingSetValue() {···
return format('Plugin must either implemet `setValue()` method\n or provide `accepts` object with acceptable values.');
},
missingSetValue: function missingSetValue() {
return format('Plugin must either implemet `setValue()` method\n or provide `accepts` object with acceptable values.');
},
Function missingSyntax
✓ Was called
missingSyntax: function missingSyntax() {···
return 'Plugin must list supported syntaxes.';
},
missingSyntax: function missingSyntax() {
return 'Plugin must list supported syntaxes.';
},
Function twoPluginsWithSameName
✓ Was called
twoPluginsWithSameName: function twoPluginsWithSameName(pluginName) {···
if (typeof pluginName === 'undefined') throw new Error();

return format('You\'re trying to use one plugin twice:\n ' + pluginName + '. Please make sure there are not two different\n plugins with the same name.');
},
twoPluginsWithSameName: function twoPluginsWithSameName(pluginName) {
Branch IfStatement
✓ Positive was executed (if)
if (typeof pluginName === 'undefined') throw new Error();
✓ Negative was executed (else)
if (typeof pluginName === 'undefined') throw new Error();···

return format('You\'re trying to use one plugin twice:\n ' + pluginName + '. Please make sure there are not two different\n plugins with the same name.');
if (typeof pluginName === 'undefined') throw new Error();
return format('You\'re trying to use one plugin twice:\n ' + pluginName + '. Please make sure there are not two different\n plugins with the same name.');
},
Function unacceptableBoolean
✓ Was called
unacceptableBoolean: function unacceptableBoolean(pattern) {···
if (typeof pattern === 'undefined') throw new Error();

return 'Value must be one of the following: ' + pattern.join(', ') + '.';
},
unacceptableBoolean: function unacceptableBoolean(pattern) {
Branch IfStatement
✓ Positive was executed (if)
if (typeof pattern === 'undefined') throw new Error();
✓ Negative was executed (else)
if (typeof pattern === 'undefined') throw new Error();···

return 'Value must be one of the following: ' + pattern.join(', ') + '.';
if (typeof pattern === 'undefined') throw new Error();
return 'Value must be one of the following: ' + pattern.join(', ') + '.';
},
Function unacceptableNumber
✓ Was called
unacceptableNumber: function unacceptableNumber() {···
return 'Value must be an integer.';
},
unacceptableNumber: function unacceptableNumber() {
return 'Value must be an integer.';
},
Function unacceptableString
✓ Was called
unacceptableString: function unacceptableString(pattern) {···
if (typeof pattern === 'undefined') throw new Error();

return 'Value must match pattern ' + pattern + '.';
},
unacceptableString: function unacceptableString(pattern) {
Branch IfStatement
✓ Positive was executed (if)
if (typeof pattern === 'undefined') throw new Error();
✓ Negative was executed (else)
if (typeof pattern === 'undefined') throw new Error();···

return 'Value must match pattern ' + pattern + '.';
if (typeof pattern === 'undefined') throw new Error();
return 'Value must match pattern ' + pattern + '.';
},
Function unacceptableValueType
✓ Was called
unacceptableValueType: function unacceptableValueType(valueType, accepts) {···
if (typeof valueType === 'undefined' || typeof accepts === 'undefined') throw new Error();

return format('The option does not accept values of type\n ' + valueType + '.\nValue\'s type must be one the following:\n ' + Object.keys(accepts).join(', ') + '.');
}
unacceptableValueType: function unacceptableValueType(valueType, accepts) {
Branch IfStatement
✓ Positive was executed (if)
if (typeof valueType === 'undefined' || typeof accepts === 'undefined') throw new Error();
✓ Negative was executed (else)
if (typeof valueType === 'undefined' || typeof accepts === 'undefined') throw new Error();···

return format('The option does not accept values of type\n ' + valueType + '.\nValue\'s type must be one the following:\n ' + Object.keys(accepts).join(', ') + '.');
Branch LogicalExpression
✓ Was returned
if (typeof valueType === 'undefined' || typeof accepts === 'undefined') throw new Error();
✓ Was returned
if (typeof valueType === 'undefined' || typeof accepts === 'undefined') throw new Error();
if (typeof valueType === 'undefined' || typeof accepts === 'undefined') throw new Error();
return format('The option does not accept values of type\n ' + valueType + '.\nValue\'s type must be one the following:\n ' + Object.keys(accepts).join(', ') + '.');
}
};
format.js
'use strict';
Function (anonymous_56)
✓ Was called
module.exports = function (string) {···
return string.replace(/\n\s*/gm, ' ');
};
module.exports = function (string) {
return string.replace(/\n\s*/gm, ' ');
};
plugin.js
'use strict';
var Errors = require('./errors');
Function Plugin
✗ Was not called
var Plugin = function Plugin(methods) {···
for (var method in methods) {
this[method] = typeof method === 'function' ? methods[method].bind(this) : methods[method];
}

this.validate();
};
var Plugin = function Plugin(methods) {
for (var method in methods) {
Branch ConditionalExpression
✗ Positive was not returned (? ...)
this[method] = typeof method === 'function' ? methods[method].bind(this) : methods[method];
✗ Negative was not returned (: ...)
this[method] = typeof method === 'function' ? methods[method].bind(this) : methods[method];
this[method] = typeof method === 'function' ? methods[method].bind(this) : methods[method];
}
this.validate();
};
Plugin.prototype = Object.defineProperties({
/**
* Plugin's name.
* @type {String}
*/
name: null,
/**
* List of supported syntaxes.
* @type {Array}
*/
syntax: null,
/**
* @type {Object}
*/
accepts: null,
/**
* @type {Function}
*/
process: null,
/**
* @type {Function}
*/
lint: null,
value_: null,
Function validate
✗ Was not called
validate: function validate() {···
if (typeof this.name !== 'string' || !this.name) throw new Error(Errors.missingName());

if (!Array.isArray(this.syntax) || this.syntax.length === 0) throw new Error(Errors.missingSyntax());

if (typeof this.accepts !== 'object' && typeof this.setValue !== 'function') throw new Error(Errors.missingSetValue());
}
validate: function validate() {
Branch IfStatement
✗ Positive was not executed (if)
if (typeof this.name !== 'string' || !this.name) throw new Error(Errors.missingName());
✗ Negative was not executed (else)
if (typeof this.name !== 'string' || !this.name) throw new Error(Errors.missingName());···

if (!Array.isArray(this.syntax) || this.syntax.length === 0) throw new Error(Errors.missingSyntax());
Branch LogicalExpression
✗ Was not returned
if (typeof this.name !== 'string' || !this.name) throw new Error(Errors.missingName());
✗ Was not returned
if (typeof this.name !== 'string' || !this.name) throw new Error(Errors.missingName());
if (typeof this.name !== 'string' || !this.name) throw new Error(Errors.missingName());
Branch IfStatement
✗ Positive was not executed (if)
if (!Array.isArray(this.syntax) || this.syntax.length === 0) throw new Error(Errors.missingSyntax());
✗ Negative was not executed (else)
if (!Array.isArray(this.syntax) || this.syntax.length === 0) throw new Error(Errors.missingSyntax());···

if (typeof this.accepts !== 'object' && typeof this.setValue !== 'function') throw new Error(Errors.missingSetValue());
Branch LogicalExpression
✗ Was not returned
if (!Array.isArray(this.syntax) || this.syntax.length === 0) throw new Error(Errors.missingSyntax());
✗ Was not returned
if (!Array.isArray(this.syntax) || this.syntax.length === 0) throw new Error(Errors.missingSyntax());
if (!Array.isArray(this.syntax) || this.syntax.length === 0) throw new Error(Errors.missingSyntax());
Branch IfStatement
✗ Positive was not executed (if)
if (typeof this.accepts !== 'object' && typeof this.setValue !== 'function') throw new Error(Errors.missingSetValue());
✗ Negative was not executed (else)
if (typeof this.accepts !== 'object' && typeof this.setValue !== 'function') throw new Error(Errors.missingSetValue());···
}
Branch LogicalExpression
✗ Was not returned
if (typeof this.accepts !== 'object' && typeof this.setValue !== 'function') throw new Error(Errors.missingSetValue());
✗ Was not returned
if (typeof this.accepts !== 'object' && typeof this.setValue !== 'function') throw new Error(Errors.missingSetValue());
if (typeof this.accepts !== 'object' && typeof this.setValue !== 'function') throw new Error(Errors.missingSetValue());
}
}, {
value: {
Function (anonymous_59)
✗ Was not called
get: function () {···
return this.value_;
},
get: function () {
return this.value_;
},
Function (anonymous_60)
✗ Was not called
set: function (value) {···
var valueType = typeof value;
var pattern = this.accepts && this.accepts[valueType];

if (this.setValue) {
this.value_ = this.setValue(value);
return this.value_;
}

if (!pattern) throw new Error(Errors.unacceptableValueType(valueType, this.accepts));

if (valueType === 'boolean') {
if (pattern.indexOf(value) < 0) throw new Error(Errors.unacceptableBoolean(pattern));
this.value_ = value;
return this.value_;
}

if (valueType === 'number') {
if (value !== parseInt(value)) throw new Error(Errors.unacceptableNumber());
this.value_ = new Array(value + 1).join(' ');
return this.value_;
}

if (valueType = 'string') {
if (!value.match(pattern)) throw new Error(Errors.unacceptableString(pattern));
this.value_ = value;
return this.value_;
}

throw new Error(Errors.implementSetValue(valueType));
},
set: function (value) {
var valueType = typeof value;
Branch LogicalExpression
✗ Was not returned
var pattern = this.accepts && this.accepts[valueType];
✗ Was not returned
var pattern = this.accepts && this.accepts[valueType];
var pattern = this.accepts && this.accepts[valueType];
Branch IfStatement
✗ Positive was not executed (if)
if (this.setValue) {···
this.value_ = this.setValue(value);
return this.value_;
}
✗ Negative was not executed (else)
}···

if (!pattern) throw new Error(Errors.unacceptableValueType(valueType, this.accepts));
if (this.setValue) {
this.value_ = this.setValue(value);
return this.value_;
}
Branch IfStatement
✗ Positive was not executed (if)
if (!pattern) throw new Error(Errors.unacceptableValueType(valueType, this.accepts));
✗ Negative was not executed (else)
if (!pattern) throw new Error(Errors.unacceptableValueType(valueType, this.accepts));···

if (valueType === 'boolean') {
if (!pattern) throw new Error(Errors.unacceptableValueType(valueType, this.accepts));
Branch IfStatement
✗ Positive was not executed (if)
if (valueType === 'boolean') {···
if (pattern.indexOf(value) < 0) throw new Error(Errors.unacceptableBoolean(pattern));
this.value_ = value;
return this.value_;
}
✗ Negative was not executed (else)
}···

if (valueType === 'number') {
if (valueType === 'boolean') {
Branch IfStatement
✗ Positive was not executed (if)
if (pattern.indexOf(value) < 0) throw new Error(Errors.unacceptableBoolean(pattern));
✗ Negative was not executed (else)
if (pattern.indexOf(value) < 0) throw new Error(Errors.unacceptableBoolean(pattern));···
this.value_ = value;
if (pattern.indexOf(value) < 0) throw new Error(Errors.unacceptableBoolean(pattern));
this.value_ = value;
return this.value_;
}
Branch IfStatement
✗ Positive was not executed (if)
if (valueType === 'number') {···
if (value !== parseInt(value)) throw new Error(Errors.unacceptableNumber());
this.value_ = new Array(value + 1).join(' ');
return this.value_;
}
✗ Negative was not executed (else)
}···

if (valueType = 'string') {
if (valueType === 'number') {
Branch IfStatement
✗ Positive was not executed (if)
if (value !== parseInt(value)) throw new Error(Errors.unacceptableNumber());
✗ Negative was not executed (else)
if (value !== parseInt(value)) throw new Error(Errors.unacceptableNumber());···
this.value_ = new Array(value + 1).join(' ');
if (value !== parseInt(value)) throw new Error(Errors.unacceptableNumber());
this.value_ = new Array(value + 1).join(' ');
return this.value_;
}
Branch IfStatement
✗ Positive was not executed (if)
if (valueType = 'string') {···
if (!value.match(pattern)) throw new Error(Errors.unacceptableString(pattern));
this.value_ = value;
return this.value_;
}
✗ Negative was not executed (else)
}···

throw new Error(Errors.implementSetValue(valueType));
if (valueType = 'string') {
Branch IfStatement
✗ Positive was not executed (if)
if (!value.match(pattern)) throw new Error(Errors.unacceptableString(pattern));
✗ Negative was not executed (else)
if (!value.match(pattern)) throw new Error(Errors.unacceptableString(pattern));···
this.value_ = value;
if (!value.match(pattern)) throw new Error(Errors.unacceptableString(pattern));
this.value_ = value;
return this.value_;
}
throw new Error(Errors.implementSetValue(valueType));
},
configurable: true,
enumerable: true
}
});
module.exports = Plugin;