UNPKG

alsatian-fluent-assertions

Version:

Fluent assertions extension to Alsatian xUnit framework.

266 lines 12.5 kB
"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 deepEqual = require("deep-equal"); const alsatian_1 = require("alsatian"); const operators_1 = require("./operators"); class SimpleMatcher extends operators_1.Operators { constructor(actualValue, nextValue, initial, prevCore, ctxt) { super(actualValue, nextValue, initial, prevCore, ctxt); } contains(expected, location = "anywhere" /* anywhere */) { this.setCurrentNode(this.contains.name, location); if (typeof expected !== "string") { throw new TypeError(`Parameter 'expected' should be a string, but was a ${typeof expected}.`); } if (typeof this.actualValue !== "string") { throw new TypeError(`Actual value should be a string, but was a ${typeof this.actualValue}.`); } if (["anywhere" /* anywhere */, "end" /* end */, "start" /* start */].indexOf(location) < 0) { throw new TypeError(`Location parameter should be one of: start, end, anywhere. Was: ${location}.`); } const ops = { "start": (pos) => pos !== 0, "end": (pos) => pos !== this.actualValue.length - expected.length, "anywhere": (pos) => pos < 0 }; const pos = this.actualValue.indexOf(expected); if (this.maybeInvert(ops[location](pos))) { this.specError(`should${this.negation}contain string (position: ${location})`, expected, this.actualValue); } return this.generateFluentState(this.actualValue, null, false); } strictlyEquals(expected) { this.setCurrentNode(this.strictlyEquals.name, typeof expected); if (this.maybeInvert(this.actualValue !== expected)) { this.specError("should strictly (===) equal", expected, this.actualValue); } return this.generateFluentState(this.actualValue, null, false); } looselyEquals(expected) { this.setCurrentNode(this.looselyEquals.name, typeof expected); /*tslint:disable:triple-equals*/ if (this.maybeInvert(this.actualValue != expected)) { /*tslint:enable:triple-equals*/ this.specError("should loosely (==) equal", expected, this.actualValue); } return this.generateFluentState(this.actualValue, null, false); } deeplyEquals(expected, eqType = "strictly" /* strictly */) { this.setCurrentNode(this.deeplyEquals.name, typeof expected + ", " + eqType); const equal = this._deeplyEquals(this.actualValue, expected, eqType); if (this.maybeInvert(!equal)) { this.specError(`should${this.negation}deeply equal (${eqType})`, expected, this.actualValue); } return this.generateFluentState(this.actualValue, null, false); } deepStrictlyEquals(expected) { this.setCurrentNode(this.deepStrictlyEquals.name, typeof expected); return this.deeplyEquals(expected, "strictly" /* strictly */); } deepLooselyEquals(expected) { this.setCurrentNode(this.deepLooselyEquals.name, typeof expected); return this.deeplyEquals(expected, "loosely" /* loosely */); } isDefined() { this.setCurrentNode(this.isDefined.name, null); if (this.maybeInvert(typeof this.actualValue === "undefined")) { this.specError(`should${this.negation}be defined`, `${this.negation}defined`, `${this.actualValue}`); } return this.generateFluentState(this.actualValue, null, false); } isNull() { this.setCurrentNode(this.isNull.name, null); if (this.maybeInvert(this.actualValue !== null)) { this.specError(`should${this.negation}be null`, `${this.negation}null`, `${this.actualValue}`); } return this.generateFluentState(this.actualValue, null, false); } matches(matcher) { this.setCurrentNode(this.matches.name, `${matcher}`); this._match(matcher); return this.generateFluentState(this.actualValue, null, false); } hasMatch(matcher) { this.setCurrentNode(this.hasMatch.name, `${matcher}`); this._match(matcher); const matches = this.actualValue.match(matcher); return this.generateFluentState(this.actualValue, matches, false, true); } throws(errorType) { this.setCurrentNode(this.throws.name, errorType ? typeof errorType : null); let threw = null; this._assertActualFunction(); try { this.actualValue(); } catch (err) { threw = err; } this._assertThrew(threw, errorType); return this.generateFluentState(this.actualValue, threw, false, true); } throwsAsync(errorType) { return __awaiter(this, void 0, void 0, function* () { this.setCurrentNode(this.throwsAsync.name, errorType ? typeof errorType : null); this._assertActualFunction(); let threw = null; try { // make sure its a promise and wait. yield Promise.resolve(this.actualValue()); } catch (err) { threw = err; } this._assertThrew(threw, errorType); return this.generateFluentState(this.actualValue, threw, false, true); }); } satisfies(predicate) { this.setCurrentNode(this.satisfies.name, null); if (!(predicate instanceof Function)) { this.specError("predicate in satisfies(predicate) should be a function", "[a function]", this.id(predicate)); } if (this.maybeInvert(!predicate(this.actualValue))) { this.specError(`should${this.negation}match lambda`, this.getFnString(predicate), this.actualValue); } return this.generateFluentState(this.actualValue, null, false); } is(expectedType) { const eActualName = (expectedType || {}).name; this.setCurrentNode(this.is.name, eActualName); if (typeof expectedType !== "function") { throw new TypeError(`Expected type 'function' for instance check, but got type '${typeof expectedType}'.`); } if (this.maybeInvert(!(this.actualValue instanceof expectedType))) { const ename = eActualName || `(Unnamed type; JS type: ${typeof expectedType})`; const aname = (this.actualValue || {}).name || `(Unnamed type; JS type: ${typeof this.actualValue})`; this.specError(`should${this.negation}be of type`, ename, aname); } return this.generateFluentState(this.actualValue, null, false); } hasProperty(expected) { this.setCurrentNode(this.hasProperty.name, null); let selected; let expDescrip; if (this.nullOrUndefined(this.actualValue)) { if (!this.invertedContext) { this.specError(`contextual value should be defined`, "[an object]", "undefined"); } return; // .not.hasProperty always passes when target not defined. } if (typeof expected === "string") { selected = this.actualValue[expected]; expDescrip = expected; } else if (expected instanceof Function) { selected = expected(this.actualValue); expDescrip = this.getFnString(expected); } else { this.specError("Provided selector was not a function or key type.", undefined, undefined); } if (this.maybeInvert(typeof selected === "undefined")) { this.specError(`property should${this.negation}be defined`, expDescrip, this.actualValue); } return this.generateFluentState(this.actualValue, selected, false, true); } hasSingle() { this.setCurrentNode(this.hasSingle.name, null); if (!(this.actualValue instanceof Array || typeof this.actualValue === "string")) { throw new TypeError("Expected type is not an array or string."); } if (this.maybeInvert(this.actualValue.length !== 1)) { this.specError(`should${this.negation}have single element or character`, "single element", this.actualValue); } return this.generateFluentState(this.actualValue, this.actualValue[0], false, true); } isEmpty() { this.setCurrentNode(this.isEmpty.name, null); if (!(typeof this.actualValue === "object" || typeof this.actualValue === "string")) { throw new TypeError("Expected type is not an array, string, or object."); } const isObject = !(typeof this.actualValue === "string" || this.actualValue instanceof Array); let length; if (isObject) { length = Object.keys(this.actualValue).length; } else { length = this.actualValue.length; } if (this.maybeInvert(length !== 0)) { this.specError(`should${this.negation}be empty`, "[an empty array, string, or object]", this.actualValue); } return this.generateFluentState(this.actualValue, null, false); } isTruthy() { return this._assertBooly(!this.actualValue, this.isTruthy.name, "truthy"); } isFalsy() { return this._assertBooly(!!this.actualValue, this.isFalsy.name, "falsy"); } converted(lambda) { this.setCurrentNode(this.converted.name); if (typeof lambda !== "function") { throw new TypeError(`Given value is not a function, but a ${typeof lambda}.`); } const r = lambda(this.actualValue); return this.generateFluentState(r, null, false); } _assertActualFunction() { if (!(this.actualValue instanceof Function)) { this.specError(`should be a function`, "[a function]", this.id(this.actualValue)); } } _assertBooly(val, name, expVal) { this.setCurrentNode(name, `${!!this.actualValue}`); if (this.maybeInvert(val)) { this.specError(`should${this.negation}be ${expVal}`, `[any ${expVal} value]`, this.actualValue); } return this.generateFluentState(this.actualValue, null, false); } _assertThrew(threw, errorType) { if (this.maybeInvert(!threw)) { const expMsg = this.invertedContext ? "[no error thrown]" : (errorType || Error).name; this.specError(`should${this.negation}throw`, expMsg, this.formatShortError(threw)); } else if (errorType && this.maybeInvert(!(threw instanceof errorType))) { const tname = errorType.name; const taname = threw.name || "[Unnamed error]"; this.specError(`should${this.negation}throw type ${tname} but threw ${taname}`, tname, this.formatShortError(threw)); } } // tslint:disable-next-line /** Convert to lib's deep equals. */ _deeplyEquals(actual, expected, eqType) { return deepEqual(expected, actual, { strict: eqType === "strictly" /* strictly */ }); } _match(matcher) { if (typeof this.actualValue !== "string") { throw new alsatian_1.MatchError("actual value type was not a string"); } if (!(matcher instanceof RegExp)) { this.specError(`matcher should be a regular expression`, "[a RegExp]", this.id(matcher)); } if (this.maybeInvert(!matcher.test(this.actualValue))) { this.specError(`should${this.negation}match`, matcher.toString(), this.actualValue); } } } exports.SimpleMatcher = SimpleMatcher; //# sourceMappingURL=simple-matcher.js.map