Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Commit

Permalink
Configuration: add ability to load external presets
Browse files Browse the repository at this point in the history
Fixes #109
Closes #1083
  • Loading branch information
markelog committed Jun 5, 2015
1 parent e339ef1 commit 99d79cc
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 19 deletions.
46 changes: 36 additions & 10 deletions lib/config/configuration.js
Expand Up @@ -62,6 +62,7 @@ Configuration.prototype.load = function(config) {
var ruleSettings = this._processConfig(currentConfig);

this._loadRules(ruleSettings);
this._useRules();
};

/**
Expand Down Expand Up @@ -372,23 +373,39 @@ Configuration.prototype._loadPlugin = function(plugin) {
* @protected
*/
Configuration.prototype._loadRules = function(ruleSettings) {
this._configuredRules = [];

Object.keys(ruleSettings).forEach(function(optionName) {
var rule = this._rules[optionName];
if (rule) {
if (this._rules[optionName]) {
var optionValue = ruleSettings[optionName];
if (optionValue !== null) {
rule.configure(ruleSettings[optionName]);
this._configuredRules.push(rule);
this._ruleSettings[optionName] = ruleSettings[optionName];

this._ruleSettings[optionName] = ruleSettings[optionName]
}
} else {
if (!~this._unsupportedRuleNames.indexOf(optionName)) {
this._unsupportedRuleNames.push(optionName);
} else {
delete this._ruleSettings[optionName];
}

} else if (this._unsupportedRuleNames.indexOf(optionName) === -1) {
this._unsupportedRuleNames.push(optionName);
}

}, this);
}
};

/**
* Apply the rules
* @protected
*/
Configuration.prototype._useRules = function() {
this._configuredRules = [];

Object.keys(this._ruleSettings).forEach(function(optionName) {
var rule = this._rules[optionName];
rule.configure(this._ruleSettings[optionName]);
this._configuredRules.push(rule);

}, this);
};

/**
* Loads an error filter.
Expand Down Expand Up @@ -577,6 +594,15 @@ Configuration.prototype.hasPreset = function(presetName) {
return this._presets.hasOwnProperty(presetName);
};

/**
* Returns name of the active preset.
*
* @return {String}
*/
Configuration.prototype.getPresetName = function() {
return this._presetName;
};

/**
* Registers built-in Code Style cheking rules.
*/
Expand Down
26 changes: 25 additions & 1 deletion lib/config/node-configuration.js
Expand Up @@ -82,6 +82,30 @@ NodeConfiguration.prototype._loadPlugin = function(plugin) {
return Configuration.prototype._loadPlugin.call(this, plugin);
};

/**
* Loads preset.
*
* @param {String|null} preset
* @private
*/
NodeConfiguration.prototype._loadPreset = function(preset) {
var registeredPresets = this.getRegisteredPresets();

if (preset in registeredPresets) {
Configuration.prototype._loadPreset.call(this, preset);

} else {
var name = path.basename(preset).split('.')[0];

// Suppress it, since missing preset error will be handled by the caller
try {
this.registerPreset(name, this.loadExternal(preset, 'preset'));
} catch (e) {}

Configuration.prototype._loadPreset.call(this, name);
}
};

/**
* Loads an error filter module.
*
Expand Down Expand Up @@ -116,7 +140,7 @@ NodeConfiguration.prototype._loadEsprima = function(esprima) {
*/
NodeConfiguration.prototype._loadAdditionalRule = function(additionalRule) {
if (typeof additionalRule === 'string') {
if(glob.hasMagic(additionalRule)) {
if (glob.hasMagic(additionalRule)) {
glob.sync(path.resolve(this._basePath, additionalRule)).forEach(function(path) {
var Rule = require(path);
Configuration.prototype._loadAdditionalRule.call(this, new Rule());
Expand Down
2 changes: 1 addition & 1 deletion test/specs/cli.js
Expand Up @@ -81,7 +81,7 @@ describe('modules/cli', function() {
preset: 'not-exist'
});

return result.promise.fail(function() {
return result.promise.always(function() {
assert.equal(console.error.getCall(0).args[0], 'Preset "not-exist" does not exist');
console.error.restore();
});
Expand Down
23 changes: 20 additions & 3 deletions test/specs/config/configuration.js
Expand Up @@ -38,6 +38,10 @@ describe('modules/config/configuration', function() {
it('should have no default maximal error count', function() {
assert(configuration.getMaxErrors() === null);
});

it('should have no default preset', function() {
assert(configuration.getPresetName() === null);
});
});

describe('registerRule', function() {
Expand Down Expand Up @@ -363,9 +367,23 @@ describe('modules/config/configuration', function() {
assert(configuration.getProcessedConfig().preset === 'test2');
assert(configuration.getProcessedConfig().maxErrors === 1);
assert(configuration.getProcessedConfig().es3);

assert(configuration.getConfiguredRules()[0].exceptUndefined);
});

it('should load nullify rule from the preset', function() {
configuration.registerDefaultRules();
configuration.registerPreset('test', {
disallowMultipleVarDecl: true
});
configuration.load({
preset: 'test',
disallowMultipleVarDecl: null
});
assert(configuration.getProcessedConfig().preset === 'test');
assert.equal(configuration.getConfiguredRules().length, 0);
});

it('should not add duplicative values to list of unsupported rules', function() {
configuration.registerPreset('test1', {
es3: true,
Expand Down Expand Up @@ -412,15 +430,14 @@ describe('modules/config/configuration', function() {

it('should handle preset with custom rule which is not included', function() {
configuration.registerPreset('test', {
es3: true,
ruleName: 'test',
ruleName: 'test'
});

configuration.load({
preset: 'test'
});

assert(configuration.getUnsupportedRuleNames()[ 0 ], 'ruleName')
assert(configuration.getUnsupportedRuleNames()[ 0 ], 'ruleName');
assert(!('ruleName' in configuration.getProcessedConfig()));
});

Expand Down
72 changes: 68 additions & 4 deletions test/specs/config/node-configuration.js
Expand Up @@ -22,7 +22,7 @@ describe('modules/config/node-configuration', function() {
it('should check type', function() {
assert.throws(
configuration.loadExternal.bind(configuration, 'test', 1),
"test option requires a string or null value"
'test option requires a string or null value'
);
});

Expand All @@ -33,7 +33,7 @@ describe('modules/config/node-configuration', function() {
it('should load relative path', function() {
assert.equal(
typeof configuration.loadExternal('./test/data/plugin/plugin'),
"function"
'function'
);
});

Expand All @@ -42,14 +42,14 @@ describe('modules/config/node-configuration', function() {
typeof configuration.loadExternal(
path.resolve('./test/data/plugin/plugin')
),
"function"
'function'
);
});

it('should load node module', function() {
assert.equal(
typeof configuration.loadExternal('path'),
"object"
'object'
);
});
});
Expand Down Expand Up @@ -90,6 +90,70 @@ describe('modules/config/node-configuration', function() {
});

describe('load', function() {
it('should load existed preset', function() {
configuration.registerDefaultRules();
configuration.registerPreset('test', {
disallowMultipleVarDecl: 'exceptUndefined'
});
configuration.load({preset: 'test'});

assert(configuration.getRegisteredRules()[0].getOptionName(), 'exceptUndefined');
});

it('should load external preset', function() {
configuration.registerDefaultRules();

configuration.load({
preset: path.resolve(__dirname + '/../../../presets/jquery.json')
});

assert.equal(
configuration.getRegisteredRules()[0].getOptionName(),
'requireCurlyBraces'
);
assert.equal(configuration.getPresetName(), 'jquery');
});

it('should try to load preset from node', function() {
configuration.registerDefaultRules();
configuration.load({
preset: 'path'
});

assert.equal(configuration.getPresetName(), 'path');
assert(configuration.getUnsupportedRuleNames().indexOf('resolve') > -1);
});

it('should try to load preset from node_modules', function() {
configuration.registerDefaultRules();
configuration.load({
preset: 'sinon'
});

assert.equal(configuration.getPresetName(), 'sinon');
assert(configuration.getUnsupportedRuleNames().indexOf('spy') > -1);
});

it('should throw if preset is missing', function() {
configuration.registerDefaultRules();
assert.throws(
configuration.load.bind(configuration, {
preset: 'not-exist'
}),
'Preset "not-exist" does not exist'
);
});

it('should try to load preset from node_modules', function() {
configuration.registerDefaultRules();
configuration.load({
preset: 'sinon'
});

assert.equal(configuration.getPresetName(), 'sinon');
assert(configuration.getUnsupportedRuleNames().indexOf('spy') > -1);
});

it('should accept `additionalRules` to register rule instances', function() {
var rule = {
getOptionName: function() {
Expand Down

0 comments on commit 99d79cc

Please sign in to comment.