Parent nodes now display an error when a child node is invalid
This commit is contained in:
parent
e21aad3e69
commit
4b5ac7434f
|
@ -109,6 +109,21 @@ Node.prototype.findNode = function (jsonPath) {
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all parents of this node. The parents are ordered from root node towards
|
||||||
|
* the original node.
|
||||||
|
* @return {Array.<Node>}
|
||||||
|
*/
|
||||||
|
Node.prototype.findParents = function () {
|
||||||
|
var parents = [];
|
||||||
|
var parent = this.parent;
|
||||||
|
while (parent) {
|
||||||
|
parents.unshift(parent);
|
||||||
|
parent = parent.parent;
|
||||||
|
}
|
||||||
|
return parents;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {{dataPath: string, keyword: string, message: string, params: Object, schemaPath: string} | null} error
|
* @param {{dataPath: string, keyword: string, message: string, params: Object, schemaPath: string} | null} error
|
||||||
|
|
|
@ -370,17 +370,38 @@ treemode.validate = function () {
|
||||||
// apply all new errors
|
// apply all new errors
|
||||||
var root = this.node;
|
var root = this.node;
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
this.errorNodes = this._validate.errors
|
this.errorNodes = this._validate.errors
|
||||||
.map(function (error) {
|
.map(function findNode (error) {
|
||||||
var node = root.findNode(error.dataPath);
|
return {
|
||||||
if (node) {
|
node: root.findNode(error.dataPath),
|
||||||
node.setError(error);
|
error: error
|
||||||
}
|
}
|
||||||
return node;
|
})
|
||||||
})
|
.filter(function hasNode (entry) {
|
||||||
.filter(function (node) {
|
return entry.node != null
|
||||||
return node != null
|
})
|
||||||
});
|
.reduce(function expandParents (all, entry) {
|
||||||
|
// expand parents, then merge such that parents come first and
|
||||||
|
// original entries last
|
||||||
|
return entry.node
|
||||||
|
.findParents()
|
||||||
|
.map(function (parent) {
|
||||||
|
return {
|
||||||
|
node: parent,
|
||||||
|
error: {
|
||||||
|
message: parent.type === 'object'
|
||||||
|
? 'Contains invalid properties' // object
|
||||||
|
: 'Contains invalid items' // array
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.concat(all, [entry]);
|
||||||
|
}, [])
|
||||||
|
// TODO: dedupe
|
||||||
|
.map(function setError (entry) {
|
||||||
|
entry.node.setError(entry.error);
|
||||||
|
return entry.node;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.errorNodes = [];
|
this.errorNodes = [];
|
||||||
|
|
|
@ -57,5 +57,27 @@ describe('util', function () {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('jsonPath', function () {
|
||||||
|
|
||||||
|
it ('should parse a json path', function () {
|
||||||
|
assert.deepEqual(util.parsePath(''), []);
|
||||||
|
assert.deepEqual(util.parsePath('.foo'), ['foo']);
|
||||||
|
assert.deepEqual(util.parsePath('.foo.bar'), ['foo', 'bar']);
|
||||||
|
assert.deepEqual(util.parsePath('.foo[2]'), ['foo', 2]);
|
||||||
|
assert.deepEqual(util.parsePath('.foo[2].bar'), ['foo', 2, 'bar']);
|
||||||
|
assert.deepEqual(util.parsePath('.foo["prop with spaces"]'), ['foo', 'prop with spaces']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it ('should throw an exception in case of an invalid path', function () {
|
||||||
|
assert.throws(function () {util.parsePath('.')}, /Error/);
|
||||||
|
assert.throws(function () {util.parsePath('[')}, /Error/);
|
||||||
|
assert.throws(function () {util.parsePath('[]')}, /Error/);
|
||||||
|
assert.throws(function () {util.parsePath('.[]')}, /Error/);
|
||||||
|
assert.throws(function () {util.parsePath('["23]')}, /Error/);
|
||||||
|
assert.throws(function () {util.parsePath('.foo bar')}, /Error/);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: thoroughly test all util methods
|
// TODO: thoroughly test all util methods
|
||||||
});
|
});
|
Loading…
Reference in New Issue