flagpole
Version:
Simple and fast DOM integration, headless or headful browser, and REST API testing framework.
151 lines • 5.47 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const util_1 = require("./util");
class AssertionSchema {
constructor() {
this._errors = [];
this._root = null;
}
get errors() {
return this._errors;
}
validate(schema, root) {
this._errors = [];
this._schema = schema;
this._root = root;
return new Promise((resolve) => {
resolve(this._isValid(this._schema, this._root, '$'));
});
}
_logError(message) {
const err = new Error(message);
this._errors.push(err);
}
_matchesType(schema, document, path) {
const schemaType = util_1.toType(schema);
const docType = util_1.toType(document);
if (schemaType != 'undefined') {
if (schemaType == 'string') {
if (docType != schema) {
this._logError(`typeOf ${path} was ${docType}, which did not match ${schema}`);
return false;
}
}
else if (schemaType == 'array') {
const allowedTypes = schema;
if (allowedTypes.indexOf(docType) < 0) {
this._logError(`${path} was ${docType}, which did not match ${allowedTypes.join(' | ')}`);
return false;
}
}
}
return true;
}
_matchesEnum(schema, document, path) {
if (util_1.toType(schema) == 'array') {
if (schema.indexOf(document) < 0) {
this._logError(`${path} value ${document} is not in enum ${schema.join(', ')}`);
return false;
}
}
return true;
}
_matchesPattern(schema, document, path) {
const schemaType = util_1.toType(schema);
if (schemaType != 'undefined' && !(new RegExp(schema).test(String(document)))) {
this._logError(`${path} value ${document} did not match ${String(schema)}`);
return false;
}
return true;
}
_matchesTest(schema, document, path) {
const schemaType = util_1.toType(schema);
if (schemaType == 'function') {
let opts = {
path: path,
parent: document,
root: this._root
};
if (!schema(document, opts)) {
this._logError(`${path} did not pass the test`);
return false;
}
}
return true;
}
_matchesItems(schema, document, path) {
const schemaType = util_1.toType(schema);
const docType = util_1.toType(document);
if (schemaType != 'undefined') {
if (docType != 'array') {
this._logError(`${path} was not an array, but schema defines items.`);
return false;
}
return document.every((subItem, index) => {
if (schemaType == 'string' || schemaType == 'array') {
return this._matchesType(schema, subItem, `${path}[${index}]`);
}
else if (schemaType == 'object') {
return this._isValid(schema, subItem, `${path}[${index}]`);
}
return true;
});
}
return true;
}
_matchesProperties(schema, document, path) {
const schemaType = util_1.toType(schema);
const docType = util_1.toType(document);
if (schemaType != 'undefined') {
if (docType != 'object') {
this._logError(`${path} was not an object, but schema defines properties.`);
return false;
}
if (schemaType == 'string' || schemaType == 'array') {
return Object.keys(document).every((key) => {
return this._matchesType(schema, document[key], `${path}.${key}`);
});
}
if (schemaType == 'object') {
return Object.keys(schema).every((key) => {
return this._isValid(schema[key], document[key], `${path}.${key}`);
});
}
}
return true;
}
_isValid(schema, document, path) {
const schemaType = util_1.toType(schema);
const docType = util_1.toType(document);
if (schemaType == 'string' || schemaType == 'array') {
if (!this._matchesType(schema, document, path)) {
return false;
}
}
else if (schemaType == 'object') {
if (!this._matchesType(schema.type, document, path)) {
if (!schema.optional || typeof document != 'undefined') {
return false;
}
}
if (!this._matchesEnum(schema.enum, document, path)) {
return false;
}
if (!this._matchesPattern(schema.matches, document, path)) {
return false;
}
if (!this._matchesTest(schema.test, document, path)) {
return false;
}
if (!this._matchesItems(schema.items, document, path)) {
return false;
}
if (!this._matchesProperties(schema.properties, document, path)) {
return false;
}
}
return true;
}
}
exports.AssertionSchema = AssertionSchema;
//# sourceMappingURL=assertionschema.js.map