flagpole
Version:
Simple and fast DOM integration, headless or headful browser, and REST API testing framework.
441 lines • 18 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const value_1 = require("./value");
const assertionresult_1 = require("./logging/assertionresult");
const assertionschema_1 = require("./assertionschema");
const Ajv = require("ajv");
const util_1 = require("./util");
const util_2 = require("util");
class Assertion {
constructor(context, thisValue, message) {
this._not = false;
this._optional = false;
this._result = null;
this._finishedResolver = () => { };
this._statement = null;
this._assertionMade = false;
this._context = context;
this._input = thisValue;
;
this._message = typeof message == 'undefined' ? null : message;
this._finishedPromise = new Promise((resolve) => {
this._finishedResolver = resolve;
});
}
get and() {
this._resolveAssertion();
const assertion = new Assertion(this._context, this._input, this._message ? `&& ${this._message}` : null);
this._not && assertion.not;
this._optional && assertion.optional;
return assertion;
}
get type() {
this._resolveAssertion();
const type = new value_1.Value(util_1.toType(this._getCompareValue(this._input)), this._context, `Type of ${this._getSubject()}`);
const assertion = new Assertion(this._context, type, this._message);
this._not && assertion.not;
this._optional && assertion.optional;
return assertion;
}
get length() {
this._resolveAssertion();
const length = (() => {
const thisValue = this._getCompareValue(this._input);
return thisValue && thisValue.length ?
thisValue.length : 0;
})();
const assertion = new Assertion(this._context, new value_1.Value(length, this._context, `Length of ${this._getSubject()}`), this._message);
this._not && assertion.not;
this._optional && assertion.optional;
return assertion;
}
get not() {
this._not = true;
return this;
}
get optional() {
this._optional = true;
return this;
}
get result() {
return this._finishedPromise;
}
get assertionMade() {
return (this._assertionMade || this._finishedPromise.isResolved());
}
get name() {
return this._message || String(this._input);
}
static create(context, thisValue, message) {
return __awaiter(this, void 0, void 0, function* () {
return new Assertion(context, thisValue, message);
});
}
exactly(value) {
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
const bool = this._eval(thisValue === thatValue);
this._assert(bool, this._not ?
`${this._getSubject()} is not exactly ${thatValue}` :
`${this._getSubject()} is exactly ${thatValue}`, thatValue);
return this;
}
equals(value) {
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
const bool = this._eval(thisValue == thatValue);
this._assert(bool, this._not ?
`${this._getSubject()} does not equal ${thatValue}` :
`${this._getSubject()} equals ${thatValue}`, thisValue);
return this;
}
like(value) {
const thisVal = String(this._getCompareValue(this._input)).toLowerCase().trim();
const thatVal = String(this._getCompareValue(value)).toLowerCase().trim();
const bool = this._eval(thisVal == thatVal);
this._assert(bool, this._not ?
`${this._getSubject()} is not like ${thatVal}` :
`${this._getSubject()} is like ${thatVal}`, thisVal);
return this;
}
greaterThan(value) {
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
const bool = this._eval(parseFloat(thisValue) > parseFloat(thatValue));
this._assert(bool, this._not ?
`${this._getSubject()} is not greater than ${thatValue}` :
`${this._getSubject()} is greater than ${thatValue}`, thisValue);
return this;
}
greaterThanOrEquals(value) {
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
const bool = this._eval(parseFloat(thisValue) >= parseFloat(thatValue));
this._assert(bool, this._not ?
`${this._getSubject()} is not greater than or equal to ${thatValue}` :
`${this._getSubject()} is greater than or equal to ${thatValue}`, thisValue);
return this;
}
lessThan(value) {
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
const bool = this._eval(parseFloat(thisValue) < parseFloat(thatValue));
this._assert(bool, this._not ?
`${this._getSubject()} is not less than ${thatValue}` :
`${this._getSubject()} is less than ${thatValue}`, thisValue);
return this;
}
lessThanOrEquals(value) {
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
const bool = this._eval(parseFloat(thisValue) <= parseFloat(thatValue));
this._assert(bool, this._not ?
`${this._getSubject()} is not less than or equal to ${thatValue}` :
`${this._getSubject()} is less than or equal to ${thatValue}`, thisValue);
return this;
}
between(min, max) {
const thisValue = this._getCompareValue(this._input);
const thatMin = parseFloat(this._getCompareValue(min));
const thatMax = parseFloat(this._getCompareValue(max));
const bool = this._eval(parseFloat(thisValue) >= thatMin &&
parseFloat(thisValue) <= thatMax);
this._assert(bool, this._not ?
`${this._getSubject()} is not between ${min} and ${max}` :
`${this._getSubject()} is between ${min} and ${max}`, thisValue);
return this;
}
matches(value) {
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
const pattern = util_1.toType(value) == 'regexp' ? thatValue : new RegExp(value);
const bool = this._eval(pattern.test(thisValue));
this._assert(bool, this._not ?
`${this._getSubject()} does not match ${String(pattern)}` :
`${this._getSubject()} matches ${String(pattern)}`, thisValue);
return this;
}
contains(value) {
let bool = false;
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
if (util_2.isNullOrUndefined(this._input)) {
bool = this._eval(thisValue === thatValue);
}
else if (util_1.toType(this._input) == 'array') {
bool = this._eval(thisValue.indexOf(thatValue) >= 0);
}
else if (util_1.toType(this._input) == 'object') {
bool = this._eval(typeof this._input[thatValue] !== 'undefined');
}
else {
bool = this._eval(String(this._input).indexOf(thatValue) >= 0);
}
this._assert(bool, this._not ?
`${this._getSubject()} does not contain ${thatValue}` :
`${this._getSubject()} contains ${thatValue}`, thisValue);
return this;
}
startsWith(value) {
let bool = false;
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
if (util_1.toType(thisValue) == 'array') {
bool = this._eval(thisValue[0] == value);
}
if (!util_2.isNullOrUndefined(thisValue)) {
bool = this._eval(String(thisValue).indexOf(thatValue) === 0);
}
this._assert(bool, this._not ?
`${this._getSubject()} does not start with ${thatValue}` :
`${this._getSubject()} starts with ${thatValue}`, String(thisValue));
return this;
}
endsWith(value) {
let bool = false;
const thisValue = this._getCompareValue(this._input);
const thatValue = this._getCompareValue(value);
if (util_1.toType(thisValue) == 'array') {
bool = this._eval(thisValue[thisValue.length - 1] == thatValue);
}
if (!util_2.isNullOrUndefined(thisValue)) {
bool = this._eval(String(thisValue).substr(0, String(thisValue).length - String(thatValue).length) == thatValue);
}
this._assert(bool, this._not ?
`${this._getSubject()} does not end with ${thatValue}` :
`${this._getSubject()} ends with ${thatValue}`, String(this._input));
return this;
}
in(values) {
const thisValue = this._getCompareValue(this._input);
let bool = this._eval(values.indexOf(thisValue) >= 0);
this._assert(bool, this._not ?
`${this._getSubject()} is not in list: ${values.join(', ')}` :
`${this._getSubject()} is in list: ${values.join(', ')}`, thisValue);
return this;
}
includes(value) {
const thisValue = this._getCompareValue(this._input);
const thatValue = String(this._getCompareValue(value));
let bool = this._eval(thisValue && thisValue.indexOf &&
thisValue.indexOf(thatValue) >= 0);
this._assert(bool, this._not ?
`${this._getSubject()} does not include ${thatValue}` :
`${this._getSubject()} includes ${thatValue}`, thisValue);
return this;
}
exists() {
const thisValue = this._getCompareValue(this._input);
const bool = this._eval(!util_2.isNullOrUndefined(thisValue));
this._assert(bool, this._not ?
`${this._getSubject()} does not exist` :
`${this._getSubject()} exists`, thisValue);
return this;
}
resolves(continueOnReject = false) {
const assertion = this;
const thisValue = this._getCompareValue(this._input);
return new Promise((resolve, reject) => {
const result = (bool) => {
this._assert(this._eval(bool), this._not ?
`${this._getSubject()} was not resolved` :
`${this._getSubject()} was resolved`, bool);
if (bool) {
resolve(assertion);
}
else {
continueOnReject ? resolve(assertion) : reject();
}
};
if (util_1.toType(thisValue) == 'promise') {
thisValue
.then(() => { result(true); })
.catch(() => { result(false); });
}
else {
result(false);
}
});
}
rejects(continueOnReject = false) {
const assertion = this;
const thisValue = this._getCompareValue(this._input);
return new Promise((resolve, reject) => {
const result = (bool) => {
this._assert(this._eval(bool), this._not ?
`${this._getSubject()} was not rejected` :
`${this._getSubject()} was rejected`, bool);
if (bool) {
resolve(assertion);
}
else {
continueOnReject ? resolve(assertion) : reject();
}
};
if (util_1.toType(thisValue) == 'promise') {
thisValue
.then(() => { result(false); })
.catch(() => { result(true); });
}
else {
result(false);
}
});
}
none(callback) {
let bool = false;
const thisValue = this._getCompareValue(this._input);
if (util_1.toType(thisValue) == 'array') {
const arr = thisValue;
bool = arr.every((value, index, array) => {
return !callback(value, index, array);
});
}
this._assert(this._eval(bool), this._not ?
`${this._getSubject()} some were true` :
`${this._getSubject()} none were true`, thisValue);
return this;
}
every(callback) {
let bool = false;
const thisValue = this._getCompareValue(this._input);
if (util_1.toType(thisValue) == 'array') {
const arr = thisValue;
bool = arr.every((value, index, array) => {
return callback(value, index, array);
});
}
this._assert(this._eval(bool), this._not ?
`${this._getSubject()} not all were true` :
`${this._getSubject()} all were true`, thisValue);
return this;
}
some(callback) {
let bool = false;
const thisValue = this._getCompareValue(this._input);
if (util_1.toType(thisValue) == 'array') {
const arr = thisValue;
bool = arr.some((value, index, array) => {
return callback(value, index, array);
});
}
this._assert(this._eval(bool), this._not ?
`${this._getSubject()} none were true` :
`${this._getSubject()} some were true`, thisValue);
return this;
}
schema(schema, simple = false) {
return __awaiter(this, void 0, void 0, function* () {
const validator = simple ? new assertionschema_1.AssertionSchema() : yield this._loadSchemaValidator();
const isValid = yield validator.validate(schema, this._getCompareValue(this._input));
const errors = validator.errors;
let error = '';
if (typeof errors != 'undefined' && errors !== null) {
errors.forEach((err) => {
error += err.message + ' ';
});
}
return this._assert(this._eval(isValid), this._not ?
`${this._getSubject()} does not match schema` :
`${this._getSubject()} matches schema`, error);
});
}
_loadSchemaValidator() {
return __awaiter(this, void 0, void 0, function* () {
if (typeof this._ajv == 'undefined') {
return Promise.resolve().then(() => require('ajv')).then(ajv => {
this._ajv = new Ajv();
return this._ajv;
})
.catch((e) => {
this._ajv = new assertionschema_1.AssertionSchema();
return this._ajv;
});
}
else {
return this._ajv;
}
});
}
_assert(statement, defaultMessage, actualValue) {
return __awaiter(this, void 0, void 0, function* () {
if (this._result !== null || this._statement !== null) {
throw new Error('Assertion result is immutable.');
}
this._statement = statement;
const message = this._message || defaultMessage;
if (!!statement) {
this._result = new assertionresult_1.AssertionPass(message);
}
else {
const source = (this._input && this._input.sourceCode) ?
this._input.sourceCode : '';
const highlight = (this._input && this._input.highlight) ?
this._input.highlight : String(actualValue);
let details = `Actual value: ${String(actualValue)}`;
this._result = this._optional ?
new assertionresult_1.AssertionFailOptional(message, details) :
new assertionresult_1.AssertionFail(message, details, source, highlight);
}
this._context.scenario.result(this._result);
this._finishedResolver(this._result);
return this;
});
}
_getCompareValue(value) {
this._assertionMade = true;
if (util_1.toType(value) == 'value') {
return value.$;
}
else {
return value;
}
}
_getSubject() {
const type = util_1.toType(this._input);
let name;
if (this._input && this._input.name) {
name = this._input.name;
}
else if (type == 'array') {
name = 'Array';
}
else if (type == 'object') {
name = 'Object';
}
else if (type == 'domelement') {
name = 'DOM Element';
}
else if (type == 'cssrule') {
name = 'CSS Rule';
}
else {
name = String(this._input);
}
if (String(name).length > 64) {
name = name.substr(0, 61) + '...';
}
return (util_2.isNullOrUndefined(name) || String(name).length == 0) ?
'It' : String(name);
}
_eval(bool) {
this._not && (bool = !bool);
return bool;
}
_resolveAssertion() {
if (this._statement === null) {
this._statement = false;
this._finishedResolver(null);
}
}
}
exports.Assertion = Assertion;
//# sourceMappingURL=assertion.js.map