Skip to content

Commit

Permalink
Little optimization
Browse files Browse the repository at this point in the history
Also errors output original key and value
  • Loading branch information
Kikobeats committed Jan 29, 2017
1 parent f0b1523 commit 19500e4
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 20 deletions.
48 changes: 28 additions & 20 deletions index.js
Expand Up @@ -25,22 +25,23 @@ function addRule (globalRules, schema, blueprint, name) {
return schema
}

function createTypeError (message, field) {
function createTypeError (message, key, value) {
const error = new TypeError(message)
error.field = field
error.key = key
error.value = value
return error
}

function throwTypeError (name, type, message) {
if (!message || isBoolean(message)) message = `Expected {${type}} for '${name}'.`
throw createTypeError(message, name)
function throwTypeError (key, value, type, message) {
if (!message || isBoolean(message)) message = `Expected {${type}} for '${key}'.`
throw createTypeError(message, key, value)
}

function throwValidationError (name, value, description) {
function throwValidationError (key, value, description) {
let message
if (description) message = description.replace('{VALUE}', value)
else message = `Fail '${value}' validation for '${name}'.`
throw createTypeError(message, name)
else message = `Fail '${value}' validation for '${key}'.`
throw createTypeError(message, key, value)
}

function getValidator (rule) {
Expand Down Expand Up @@ -73,28 +74,35 @@ function Osom (schemaBlueprint, globalRules) {
obj = obj || {}

return reduce(schema, function applyRule (objSchema, rule, name) {
let value = obj[name]
const value = obj[name]
const hasValue = exists(value)
const isMissing = rule.required && !hasValue
if (isMissing) throwTypeError(name, schemaTypes[name], rule.required)
const isRequired = rule.required
const isMissing = isRequired && !hasValue
const expectedValue = schemaTypes[name]

const isCastingDisabled = hasValue && !rule.casting
const isSameType = type(value) === schemaTypes[name]
if (isMissing) throwTypeError(name, value, expectedValue, isRequired)

const isCasting = rule.casting
const isCastingDisabled = hasValue && !isCasting
const isSameType = type(value) === expectedValue
const isInvalidType = isCastingDisabled && !isSameType
if (isInvalidType) throwTypeError(name, schemaTypes[name], rule.required)
if (isInvalidType) throwTypeError(name, value, expectedValue, isRequired)

if (hasValue) value = rule.casting ? rule.type(obj[name]) : obj[name]
else if (rule.default) value = !isFunction(rule.default) ? rule.default : rule.default()
let TypedValue
const defaultValue = rule.default
const validate = rule.validate
if (hasValue) TypedValue = isCasting ? rule.type(value) : value
else if (defaultValue) TypedValue = !isFunction(defaultValue) ? defaultValue : defaultValue()

// lodash.flow is buggy, this is a workaround (and dep-free)
value = reduce(rule.transform, (acc, fn) => fn(acc), value)
TypedValue = reduce(rule.transform, (acc, fn) => fn(acc), TypedValue)

if (hasValue && rule.validate) {
if (hasValue && validate) {
const validator = getValidator(rule)
if (!validator(value)) throwValidationError(name, value, rule.validate.message)
if (!validator(TypedValue)) throwValidationError(name, value, validate.message)
}

if (exists(value)) objSchema[name] = value
if (exists(TypedValue)) objSchema[name] = TypedValue
return objSchema
}, {})
}
Expand Down
25 changes: 25 additions & 0 deletions test/index.js
Expand Up @@ -249,6 +249,31 @@ describe('schema defintion', function () {
})
})

describe('error', function () {
it('attach key and value into error object', function () {
var schema = {
age: {
type: String,
validate: {
validator: function (v) {
return v === '23'
},
message: 'expected a millenial value instead of {VALUE}!'
}
}
}

var validator = osom(schema)

try {
validator({age: 25})
} catch (err) {
err.key.should.be.equal('age')
err.value.should.be.equal(25)
}
})
})

describe('behavior', function () {
it('custom global values', function () {
function trim (str) {
Expand Down

0 comments on commit 19500e4

Please sign in to comment.