Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

detailed-xml-validator

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

detailed-xml-validator - npm Package Compare versions

Comparing version
0.0.7
to
1.0.0
+135
specs/checkBy.spec.js
const { assert, expect } = require('chai');
const Validator = require("../src/validator");
describe("XML validator with checkBy", function() {
it("custom validator should be called", function(){
const xmlData = `
<root>
<a>0</a>
<c>3.2</c>
<d>3.2</d>
<f>
<a>1</a>
<b>1</b>
</f>
<f>
<a>2</a>
<b>3</b>
</f>
<f>
<a>6</a>
</f>
<f>
<a>4</a>
<b>5</b>
<c>6</c>
</f>
</root>`;
const rules = `
<root>
<a type="positiveInteger" min="3"></a>
<c type="decimal" min="1.2"></c>
<d type="number" min="1.2" max="1.5"></d>
<f repeatable checkBy="fValidator"></f>
</root>`;
let calls = [];
const validator = new Validator(rules);
validator.register("fValidator", (f,path) => {
calls.push("fValidator");
if(f.a==1 && f.b== 1) return;
else if(f.a==2 && f.b== 3) return;
else if(f.a==4 && f.b== 5 && f.c != undefined) return;
return {
code: "I dont know",
path: path,
}
})
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'min', path: 'root.a', actual: 0, expected: 3 },
{ code: 'max', path: 'root.d', actual: 3.2, expected: 1.5 },
{ code: 'I dont know', path: 'root.f[2]' }
]);
expect(calls.length).to.eq(4);
});
it("custom validator should not stop validations on nested element", function(){
const xmlData = `
<root>
<f>
<a>1</a>
<b>1</b>
</f>
<f>
<a>2</a>
<b>3</b>
</f>
<f>
<a>6</a>
</f>
<f>
<a>4</a>
<b>5</b>
<c>6</c>
</f>
</root>`;
const rules = `
<root>
<f repeatable checkBy="fValidator">
<a pattern="1|2|4"/>
</f>
</root>`;
const validator = new Validator(rules);
validator.register("fValidator", (f,path) => {
if(f.a==1 && f.b== 1) return;
else if(f.a==2 && f.b== 3) return;
else if(f.a==4 && f.b== 5 && f.c != undefined) return;
return {
code: "I dont know",
path: path,
}
})
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'I dont know', path: 'root.f[2]' },
{
code: 'pattern',
path: 'root.f[2].a',
actual: '6',
expected: '1|2|4'
}
]);
});
it("custom validator should be called for leaf tag", function(){
const xmlData = `
<root>
<f>value</f>
</root>`;
const rules = `
<root>
<f checkBy="fValidator"></f>
</root>`;
const validator = new Validator(rules);
validator.register("fValidator", (f,path) => {
return {
code: "I dont know",
path: path,
}
})
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'I dont know', path: 'root.f' }
]);
});
});
const { assert, expect } = require('chai');
const Validator = require("../src/validator");
const fs = require("fs");
const path = require("path");
describe("XML validator with Number", function() {
//type:string
it("when string length cross the boundary", function(){
const xmlData = `
<root>
<a>amit</a>
<b>kumar</b>
<c>gupta</c>
</root>`;
const rules = `
<root>
<a type="string" minLength="3"></a>
<b length="4"></b>
<c minLength="2" maxLength="5" ></c>
</root>`;
const validator = new Validator(rules);
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'length', path: 'root.b', actual: 'kumar', expected: 4 }
]);
});
it("when pattern doesn't match", function(){
const xmlData = `
<root>
<a>0</a>
<a>amitguptagmail.com</a>
<a>amit@gmail.com</a>
<a>amitgupta@gmail.com</a>
</root>`;
const rules = `
<root>
<a repeatable pattern="[a-z]+@gmail.com" minLength="15"></a>
</root>`;
const validator = new Validator(rules);
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'minLength', path: 'root.a[0]', actual: '0', expected: 15 },
{
code: 'pattern',
path: 'root.a[0]',
actual: '0',
expected: '[a-z]+@gmail.com'
},
{
code: 'pattern',
path: 'root.a[1]',
actual: 'amitguptagmail.com',
expected: '[a-z]+@gmail.com'
},
{
code: 'minLength',
path: 'root.a[2]',
actual: 'amit@gmail.com',
expected: 15
}
]);
});
it("when pattern doesn't match with modifier", function(){
const xmlData = `
<root>
<a>0</a>
<a>amitguptagmail.com</a>
<a>amit@gmail.com</a>
<a>amitgupta@gmail.com</a>
<a>AmitGupta@Gmail.com</a>
</root>`;
const rules = `
<root>
<a repeatable pattern_i="[a-z]+@gmail.com" minLength="15"></a>
</root>`;
const validator = new Validator(rules);
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'minLength', path: 'root.a[0]', actual: '0', expected: 15 },
{
code: 'pattern',
path: 'root.a[0]',
actual: '0',
expected: '[a-z]+@gmail.com'
},
{
code: 'pattern',
path: 'root.a[1]',
actual: 'amitguptagmail.com',
expected: '[a-z]+@gmail.com'
},
{
code: 'minLength',
path: 'root.a[2]',
actual: 'amit@gmail.com',
expected: 15
}
]);
});
it("when a fixed string is given", function(){
const xmlData = `
<root>
<a>amit</a>
<b>kumar</b>
<c>gupta</c>
</root>`;
const rules = `
<root>
<a type="string" minLength="3" fixed="amit"></a>
<b length="4" fixed="-"></b>
<c minLength="2" maxLength="5" ></c>
</root>`;
const validator = new Validator(rules);
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'length', path: 'root.b', actual: 'kumar', expected: 4 },
{ code: 'fixed', path: 'root.b', actual: 'kumar', expected: '-' }
]);
});
it("when a list of strings are given for repeatable tags", function(){
const xmlData = `
<root>
<a>amit</a>
<b>kumar</b>
<b>-</b>
<b>middle</b>
<c>gupta</c>
</root>`;
const rules = `
<root>
<a type="string" minLength="3" fixed="amit"></a>
<b repeatable in="-,kumar"></b>
<c minLength="2" maxLength="5" ></c>
</root>`;
const validator = new Validator(rules);
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'in', path: 'root.b[2]', actual: 'middle', expected: '-,kumar' }
]);
});
it("when a list of strings are given for leaf tag", function(){
const xmlData = `
<root>
<a>amit</a>
<b>middle</b>
<c>gupta</c>
</root>`;
const rules = `
<root>
<a type="string" minLength="3" fixed="amit"></a>
<b in="-,kumar"></b>
<c minLength="2" maxLength="5" ></c>
</root>`;
const validator = new Validator(rules);
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'in', path: 'root.b', actual: 'middle', expected: '-,kumar' }
]);
});
});
const { assert, expect } = require('chai');
const Validator = require("../src/validator");
describe("XML validator with checkBy", function() {
it("custom validator should be called", function(){
const xmlData = `
<root>
<a>0</a>
<c>3.2</c>
<d>3.2</d>
<f>
<a>1</a>
<b>1</b>
</f>
<f>
<a>2</a>
<b>3</b>
</f>
<f>
<a>6</a>
</f>
<f>
<a>4</a>
<b>5</b>
<c>6</c>
</f>
</root>`;
const rules = `
<root>
<a type="positiveInteger" min="3"></a>
<c type="decimal" min="1.2"></c>
<d type="number" min="1.2" max="1.5"></d>
<f repeatable checkBy="fValidator"></f>
</root>`;
let calls = [];
const validator = new Validator(rules);
validator.register("fValidator", (f,path) => {
calls.push("fValidator");
if(f.a==1 && f.b== 1) return;
else if(f.a==2 && f.b== 3) return;
else if(f.a==4 && f.b== 5 && f.c != undefined) return;
return {
code: "I dont know",
path: path,
}
})
const actual = validator.validate(xmlData);
// console.log(actual);
expect(actual).to.deep.equal([
{ code: 'min', path: 'root.a', actual: 0, expected: 3 },
{ code: 'max', path: 'root.d', actual: 3.2, expected: 1.5 },
{ code: 'I dont know', path: 'root.f[2]' }
]);
expect(calls.length).to.eq(4);
});
});
+1
-1
{
"name": "detailed-xml-validator",
"version": "0.0.7",
"version": "1.0.0",
"description": "Validate for XML schema and returns all the possible failures",

@@ -5,0 +5,0 @@ "main": "./src/validator.js",

@@ -27,7 +27,9 @@ # detailed-xml-validator

<marks>
<subject repeatable minOccurs="5" maxOccurs="6" >
<subject repeatable minOccurs="5" maxOccurs="6" checkBy="subjectValidator">
<name pattern="math|hindi|english|science|history"></name>
<!-- <name in="math,hindi,english,science,history"></name> -->
<score type="positiveDecimal"></score>
</subject>
</marks>
</student>

@@ -58,7 +60,11 @@ </students>

* **length**:
* **pattern**: regex
* **in**: comma separated string for exact match (from v1.0.0)
* **fixed**: exact match (from v1.0.0)
* **pattern**: regex match
* **pattern_i**: regex (case insensitive)
* **pattern_m**: regex (multiline)
* **pattern_im**: regex (case insencitive and multiline)
* **checkBy**: (from v1.0.0) Give the name of validator that you registered with validator. This validator will be called with an object of nested tags (or value if it is a leaf node) and path.
Sample code

@@ -74,2 +80,7 @@ ```js

const validator = new Validator(rules, options);
validator.register("subjectValidator", (obj, path) => { //From v1.0.0
//return; //if no error
//return {} //return an error msg object
})
const failures = validator.validate(xmlStringData);

@@ -76,0 +87,0 @@ const originalXmlJsObj = validator.data;

@@ -9,5 +9,6 @@ /// @ts-check

class Traverser{
constructor(options){
constructor(options, validators){
this.options = options;
this.failures = [];
this.validators=validators;
}

@@ -50,5 +51,15 @@

}
this.applyCustomValidators(ele, rules, path);
}
}
applyCustomValidators(ele, rules, path){
if(rules['@rules'] && rules['@rules'].checkBy && typeof this.validators[rules['@rules'].checkBy] === "function"){
let res = this.validators[rules['@rules'].checkBy](ele, path.substr(1));
if(typeof res === "object"){
this.failures.push(res);
}
}
}
callForCommonProperties(ele, rules, path){

@@ -62,2 +73,3 @@ const tags = Object.keys(ele);

this.applyCustomValidators(ele, rules, path);
sets.common.forEach(key => {

@@ -203,2 +215,10 @@ const newpath = path + "." + key;

});
["fixed","in"].forEach( rule => {
if(rules[rule] !== undefined){
const expected = rules[rule];
if( !validations.string[rule](expected, actual) ){
this.setInvalidValueError(rule, newpath, actual, expected);
};
}
});
// if(rules.pattern){

@@ -205,0 +225,0 @@ // const expected = rules[rule];

@@ -14,2 +14,8 @@ module.exports.string = {

return regxp.test(actual);
},
fixed: function(expected, actual){
return expected === actual;
},
in: function(expected, actual){
return expected.split(",").indexOf(actual) > -1
}

@@ -26,3 +32,2 @@ }

module.exports.list = {
minOccurs: function(expected, actual){

@@ -29,0 +34,0 @@ return actual >= expected;

@@ -20,4 +20,8 @@ /// @ts-check

this.options = Object.assign({}, defaultOptions, options);
this.validators={};
}
register(validator, fn){
this.validators[validator] = fn;
}
validate(xmldata){

@@ -32,3 +36,3 @@ validateXMlData(xmldata);

this.data = xmlObj;
const traverser = new Traverser(this.options);
const traverser = new Traverser(this.options,this.validators);
traverser.traverse (xmlObj, "", this.rules, "");

@@ -35,0 +39,0 @@ return traverser.failures;