Validate solcoverjs with json schema (#403)
parent
556d2d2e58
commit
ee72e8d66d
@ -0,0 +1,72 @@ |
|||||||
|
const Validator = require('jsonschema').Validator; |
||||||
|
const AppUI = require('./ui').AppUI; |
||||||
|
const util = require('util') |
||||||
|
|
||||||
|
|
||||||
|
function isFunction(input){ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
Validator.prototype.customFormats.isFunction = function(input) { |
||||||
|
return typeof input === "function" |
||||||
|
}; |
||||||
|
|
||||||
|
const configSchema = { |
||||||
|
id: "/solcoverjs", |
||||||
|
type: "object", |
||||||
|
properties: { |
||||||
|
|
||||||
|
client: {type: "object"}, |
||||||
|
cwd: {type: "string"}, |
||||||
|
host: {type: "string"}, |
||||||
|
|
||||||
|
|
||||||
|
originalContractsDir: {type: "string"}, |
||||||
|
port: {type: "number"}, |
||||||
|
providerOptions: {type: "object"}, |
||||||
|
silent: {type: "boolean"}, |
||||||
|
|
||||||
|
// Hooks:
|
||||||
|
onServerReady: {type: "function", format: "isFunction"}, |
||||||
|
onTestComplete: {type: "function", format: "isFunction"}, |
||||||
|
onIstanbulComplete: {type: "function", format: "isFunction"}, |
||||||
|
|
||||||
|
// Arrays
|
||||||
|
skipFiles: { |
||||||
|
type: "array", |
||||||
|
items: {type: "string"} |
||||||
|
}, |
||||||
|
|
||||||
|
istanbulReporter: { |
||||||
|
type: "array", |
||||||
|
items: {type: "string"} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
class ConfigValidator { |
||||||
|
constructor(){ |
||||||
|
this.validator = new Validator(); |
||||||
|
this.validator.addSchema(configSchema); |
||||||
|
this.ui = new AppUI(); |
||||||
|
} |
||||||
|
|
||||||
|
validate(config){ |
||||||
|
let result = this.validator.validate(config, configSchema); |
||||||
|
|
||||||
|
if (result.errors.length){ |
||||||
|
let msg; |
||||||
|
const option = `"${result.errors[0].property.replace('instance.', '')}"`; |
||||||
|
|
||||||
|
(result.errors[0].argument === 'isFunction') |
||||||
|
? msg = `${option} is not a function` |
||||||
|
: msg = `${option} ${result.errors[0].message}`; |
||||||
|
|
||||||
|
throw new Error(this.ui.generate('config-fail', [msg])); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = ConfigValidator; |
@ -0,0 +1,137 @@ |
|||||||
|
const assert = require('assert'); |
||||||
|
const util = require('util'); |
||||||
|
const ConfigValidator = require('./../../lib/validator'); |
||||||
|
|
||||||
|
describe('config validation', () => { |
||||||
|
let validator; |
||||||
|
let solcoverjs; |
||||||
|
|
||||||
|
before(() => validator = new ConfigValidator()); |
||||||
|
beforeEach(() => solcoverjs = {}); |
||||||
|
|
||||||
|
it('validates an empty config', function() { |
||||||
|
assert(validator.validate(solcoverjs), '{} should be valid'); |
||||||
|
}) |
||||||
|
|
||||||
|
it('validates config with unknown options', function(){ |
||||||
|
solcoverjs.unknown_option = 'hello'; |
||||||
|
assert(validator.validate(solcoverjs), '.cwd string should be valid') |
||||||
|
}) |
||||||
|
|
||||||
|
it('validates the "string" options', function(){ |
||||||
|
const options = [ |
||||||
|
"cwd", |
||||||
|
"host", |
||||||
|
"originalContractsDir", |
||||||
|
] |
||||||
|
|
||||||
|
options.forEach(name => { |
||||||
|
// Pass
|
||||||
|
solcoverjs = {}; |
||||||
|
solcoverjs[name] = "a_string"; |
||||||
|
assert(validator.validate(solcoverjs), `${name} string should be valid`) |
||||||
|
|
||||||
|
// Fail
|
||||||
|
solcoverjs[name] = 0; |
||||||
|
try { |
||||||
|
validator.validate(solcoverjs); |
||||||
|
assert.fail() |
||||||
|
} catch (err){ |
||||||
|
assert(err.message.includes(`"${name}" is not of a type(s) string`), err.message); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('validates the "object" options', function(){ |
||||||
|
const options = [ |
||||||
|
"client", |
||||||
|
"providerOptions", |
||||||
|
] |
||||||
|
|
||||||
|
options.forEach(name => { |
||||||
|
// Pass
|
||||||
|
solcoverjs = {}; |
||||||
|
solcoverjs[name] = {a_property: 'a'}; |
||||||
|
assert(validator.validate(solcoverjs), `${name} object should be valid`) |
||||||
|
|
||||||
|
// Fail
|
||||||
|
solcoverjs[name] = 0; |
||||||
|
try { |
||||||
|
validator.validate(solcoverjs); |
||||||
|
assert.fail() |
||||||
|
} catch (err){ |
||||||
|
assert(err.message.includes(`"${name}" is not of a type(s) object`), err.message); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('validates the "number" options', function(){ |
||||||
|
const options = [ |
||||||
|
"port", |
||||||
|
] |
||||||
|
|
||||||
|
options.forEach(name => { |
||||||
|
// Pass
|
||||||
|
solcoverjs = {}; |
||||||
|
solcoverjs[name] = 0; |
||||||
|
assert(validator.validate(solcoverjs), `${name} number should be valid`) |
||||||
|
|
||||||
|
// Fail
|
||||||
|
solcoverjs[name] = "a_string"; |
||||||
|
try { |
||||||
|
validator.validate(solcoverjs); |
||||||
|
assert.fail() |
||||||
|
} catch (err){ |
||||||
|
assert(err.message.includes(`"${name}" is not of a type(s) number`), err.message); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('validates string array options', function(){ |
||||||
|
const options = [ |
||||||
|
"skipFiles", |
||||||
|
"istanbulReporter", |
||||||
|
] |
||||||
|
|
||||||
|
options.forEach(name => { |
||||||
|
// Pass
|
||||||
|
solcoverjs = {}; |
||||||
|
solcoverjs[name] = ['a_string']; |
||||||
|
assert(validator.validate(solcoverjs), `${name} string array should be valid`) |
||||||
|
|
||||||
|
// Fail
|
||||||
|
solcoverjs[name] = "a_string"; |
||||||
|
try { |
||||||
|
validator.validate(solcoverjs); |
||||||
|
assert.fail() |
||||||
|
} catch (err){ |
||||||
|
assert(err.message.includes(`"${name}" is not of a type(s) array`), err.message); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
it('validates function options', function(){ |
||||||
|
|
||||||
|
const options = [ |
||||||
|
"onServerReady", |
||||||
|
"onTestComplete", |
||||||
|
"onIstanbulComplete", |
||||||
|
] |
||||||
|
|
||||||
|
options.forEach(name => { |
||||||
|
// Pass
|
||||||
|
solcoverjs = {}; |
||||||
|
solcoverjs[name] = async (a,b) => {}; |
||||||
|
assert(validator.validate(solcoverjs), `${name} string array should be valid`) |
||||||
|
|
||||||
|
// Fail
|
||||||
|
solcoverjs[name] = "a_string"; |
||||||
|
try { |
||||||
|
validator.validate(solcoverjs); |
||||||
|
assert.fail() |
||||||
|
} catch (err){ |
||||||
|
assert(err.message.includes(`"${name}" is not a function`), err.message); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
Loading…
Reference in new issue