UNPKG

consys

Version:

consys is a flexible tool to evaluate models using generic and readable constraints.

93 lines (92 loc) 3.67 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Util_1 = require("./Util"); const Lexer_1 = __importDefault(require("./dsl/Lexer")); const Parser_1 = __importDefault(require("./dsl/Parser")); const Emitter_1 = __importDefault(require("./dsl/Emitter")); const FunctionGenerator_1 = __importDefault(require("./ignoreCoverage/FunctionGenerator")); const TextProcessor_1 = __importDefault(require("./dsl/TextProcessor")); /** * Represents a single constraint, with specified model and state data types. */ class Constraint { /** * Create a new constraint from constraint data. * * @param resource constraint data */ constructor(resource) { this.resource = resource; const tokens = new Lexer_1.default(resource.constraint).scan(); this.ast = new Parser_1.default(resource.constraint, tokens).parse(); const js = new Emitter_1.default(this.ast).emit(); this.assertionFunction = FunctionGenerator_1.default.generateFromString(js); } /** * Returns a map of the number of occurrences for each key of the model. */ getModelVarOccurrences() { return this.ast.statistics.counts.model; } /** * Returns a map of the number of occurrences for each key of the state. */ getStateVarOccurrences() { return this.ast.statistics.counts.state; } /** * Evaluate this constraint with a given model and state, along with custom functions. * * @param data data to evaluate, along with functions * @param rescan determine if the text processor should rescan if something has changed */ evaluate(data, rescan) { if (!this.textProcessor) { this.textProcessor = new TextProcessor_1.default(!!this.resource.message ? this.resource.message : '', data.functions); } try { const consistent = this.isConsistent(data); return { consistent: consistent, message: consistent || !this.resource.message ? '' : this.textProcessor.process(data.model, data.state, data.functions, rescan), resource: this.resource, }; } catch (error) { const errorVariable = error.message; const variable = errorVariable.substring(1); const isModel = errorVariable.startsWith('$'); const type = isModel ? 'model' : 'state'; const provided = isModel ? data.model : data.state; const position = this.resource.constraint.indexOf(variable); Util_1.Log.reportError('Evaluation', this.resource.constraint, `Attribute '${variable}' not found in ${type}: ${JSON.stringify(provided)}`, position); return { consistent: false, message: !this.resource.message ? '' : this.textProcessor.process(data.model, data.state, data.functions, rescan), resource: this.resource, }; } } /** * Checks if this constraint is consistent with given model, state and functions. * * @param data data to evaluate, along with functions */ isConsistent(data) { return this.assertionFunction.apply(data, null); } /** * Returns the original resource that was used to generate this constraint. */ getResource() { return this.resource; } } exports.default = Constraint;