Skip to content

Commit

Permalink
feat(config): validate config after load_config (#4381)
Browse files Browse the repository at this point in the history
* feat(config): validate config after load_config
* feat(config): update validation message
* refactor(config): validate config before modify it
* test(config): add should#fail for test cases
* refactor(vlidata_config): update error message
  • Loading branch information
SukkaW authored Jul 10, 2020
1 parent 73477f6 commit cb4a6f3
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/hexo/load_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const Source = require('./source');
const { exists, readdir } = require('hexo-fs');
const { magenta } = require('chalk');
const { deepMerge } = require('hexo-util');
const validateConfig = require('./validate_config');

module.exports = async ctx => {
if (!ctx.env.init) return;
Expand All @@ -26,6 +27,8 @@ module.exports = async ctx => {
ctx.config = deepMerge(ctx.config, config);
config = ctx.config;

validateConfig(ctx);

ctx.config_path = configPath;

config.root = config.root.replace(/\/*$/, '/');
Expand Down
33 changes: 33 additions & 0 deletions lib/hexo/validate_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

module.exports = ctx => {
const { config, log } = ctx;

log.info('Validating config');

// Validation for config.url && config.root
if (typeof config.url !== 'string') {
throw new TypeError(`Invalid config detected: "url" should be string, not ${typeof config.url}!`);
}
if (config.url.trim().length <= 0) {
throw new TypeError('Invalid config detected: "url" should not be empty!');
}

if (typeof config.root !== 'string') {
throw new TypeError(`Invalid config detected: "root" should be string, not ${typeof config.root}!`);
}
if (config.root.trim().length <= 0) {
throw new TypeError('Invalid config detected: "root" should not be empty!');
}

// Soft deprecate use_date_for_updated
if (typeof config.use_date_for_updated === 'boolean') {
log.warn('Deprecated config detected: "use_date_for_updated" is deprecated, please use "updated_option" instead. See https://hexo.io/docs/configuration for more details.');
}

// Soft deprecate external_link Boolean
if (typeof config.external_link === 'boolean') {
log.warn('Deprecated config detected: "external_link" with a Boolean value is deprecated. See https://hexo.io/docs/configuration for more details.');
}
};

1 change: 1 addition & 0 deletions test/scripts/hexo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
describe('Core', () => {
require('./hexo');
require('./load_config');
require('./validate_config');
require('./load_database');
require('./load_plugins');
require('./load_theme_config');
Expand Down
108 changes: 108 additions & 0 deletions test/scripts/hexo/validate_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
'use strict';

const { spy } = require('sinon');

describe('Validate config', () => {
const Hexo = require('../../../lib/hexo');
const hexo = new Hexo();
const validateConfig = require('../../../lib/hexo/validate_config');
const defaultConfig = require('../../../lib/hexo/default_config');
let logSpy;

beforeEach(() => {
logSpy = spy();
hexo.config = JSON.parse(JSON.stringify(defaultConfig));
hexo.log.warn = logSpy;
hexo.log.info = spy();
});

it('config.url - undefined', () => {
delete hexo.config.url;

try {
validateConfig(hexo);
should.fail();
} catch (e) {
e.name.should.eql('TypeError');
e.message.should.eql('Invalid config detected: "url" should be string, not undefined!');
}
});

it('config.url - wrong type', () => {
hexo.config.url = true;

try {
validateConfig(hexo);
should.fail();
} catch (e) {
e.name.should.eql('TypeError');
e.message.should.eql('Invalid config detected: "url" should be string, not boolean!');
}
});

it('config.url - empty', () => {
hexo.config.url = ' ';

try {
validateConfig(hexo);
should.fail();
} catch (e) {
e.name.should.eql('TypeError');
e.message.should.eql('Invalid config detected: "url" should not be empty!');
}
});

it('config.root - undefined', () => {
delete hexo.config.root;

try {
validateConfig(hexo);
should.fail();
} catch (e) {
e.name.should.eql('TypeError');
e.message.should.eql('Invalid config detected: "root" should be string, not undefined!');
}
});

it('config.root - wrong type', () => {
hexo.config.root = true;

try {
validateConfig(hexo);
should.fail();
} catch (e) {
e.name.should.eql('TypeError');
e.message.should.eql('Invalid config detected: "root" should be string, not boolean!');
}
});

it('config.root - empty', () => {
hexo.config.root = ' ';

try {
validateConfig(hexo);
should.fail();
} catch (e) {
e.name.should.eql('TypeError');
e.message.should.eql('Invalid config detected: "root" should not be empty!');
}
});

it('config.use_date_for_updated - depreacte', () => {
hexo.config.use_date_for_updated = true;

validateConfig(hexo);

logSpy.calledOnce.should.be.true;
logSpy.calledWith('Deprecated config detected: "use_date_for_updated" is deprecated, please use "updated_option" instead. See https://hexo.io/docs/configuration for more details.').should.be.true;
});

it('config.external_link - depreacte Boolean value', () => {
hexo.config.external_link = false;

validateConfig(hexo);

logSpy.calledOnce.should.be.true;
logSpy.calledWith('Deprecated config detected: "external_link" with a Boolean value is deprecated. See https://hexo.io/docs/configuration for more details.').should.be.true;
});
});

0 comments on commit cb4a6f3

Please sign in to comment.