A collection of test utilities specifically designed for LoopBack 4 applications and TypeScript testing
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Behavior-driven development style assertions using Should.js configured in as-function mode with enhanced TypeScript support and chai-like syntax.
The main assertion interface providing Should.js functionality in as-function mode.
/**
* Should.js assertion interface configured in as-function mode
* Provides BDD-style assertions with TypeScript support
* @param obj - The object to assert against
* @returns ShouldAssertion for chaining assertions
*/
const expect: Internal;
interface Internal extends ShouldInternal {
(obj: any): ShouldAssertion;
use(fn: (should: Internal, Assertion: Assertion) => void): Internal;
// Node.js assert function equivalents
fail(actual: any, expected: any, message: string, operator: string): void;
assert(value: any, message: string): void;
ok(value: any, message?: string): void;
equal(actual: any, expected: any, message?: string): void;
notEqual(actual: any, expected: any, message?: string): void;
deepEqual(actual: any, expected: any, message?: string): void;
notDeepEqual(actual: any, expected: any, message?: string): void;
strictEqual(actual: any, expected: any, message?: string): void;
notStrictEqual(actual: any, expected: any, message?: string): void;
throws(block: any, error?: any, message?: string): void;
doesNotThrow(block: any, message?: string): void;
ifError(value: any): void;
inspect(value: any, obj: any): any;
}
interface ShouldInternal {
exist(actual: any, msg?: string): void;
exists(actual: any, msg?: string): void;
not: ShouldInternal;
}Usage Examples:
import { expect } from "@loopback/testlab";
// Basic assertions
expect(5).to.be.greaterThan(3);
expect("hello").to.equal("hello");
expect(true).to.be.true();
expect([1, 2, 3]).to.have.lengthOf(3);
// Object assertions
expect({name: "Alice", age: 30}).to.have.property("name", "Alice");
expect({a: 1, b: 2}).to.have.properties(["a", "b"]);
expect({}).to.be.empty();
// Array assertions
expect([1, 2, 3]).to.containEql(2);
expect([1, 2, 3]).to.match([1, 2, 3]);
expect(["a", "b", "c"]).to.have.lengthOf(3);
// Type assertions
expect("hello").to.be.a.String();
expect(42).to.be.a.Number();
expect([]).to.be.an.Array();
expect({}).to.be.an.Object();
// Promise assertions
await expect(Promise.resolve("success")).to.be.fulfilledWith("success");
await expect(Promise.reject(new Error("fail"))).to.be.rejected();The comprehensive assertion interface providing all Should.js capabilities.
interface ShouldAssertion {
// Basic grammar for fluent assertions
a: ShouldAssertion;
an: ShouldAssertion;
and: ShouldAssertion;
be: ShouldAssertion;
has: ShouldAssertion;
have: ShouldAssertion;
is: ShouldAssertion;
it: ShouldAssertion;
with: ShouldAssertion;
which: ShouldAssertion;
the: ShouldAssertion;
of: ShouldAssertion;
not: ShouldAssertion;
to: ShouldAssertion; // chai-like expect().to syntax
// Type validators
arguments(): ShouldAssertion;
empty(): ShouldAssertion;
ok(): ShouldAssertion;
true(): ShouldAssertion;
false(): ShouldAssertion;
NaN(): ShouldAssertion;
Infinity(): ShouldAssertion;
Array(): ShouldAssertion;
Object(): ShouldAssertion;
String(): ShouldAssertion;
Boolean(): ShouldAssertion;
Number(): ShouldAssertion;
Error(): ShouldAssertion;
Function(): ShouldAssertion;
Date(): ShouldAssertion;
Class(): ShouldAssertion;
Undefined(): ShouldAssertion;
Null(): ShouldAssertion;
Promise(): ShouldAssertion;
generator(): ShouldAssertion;
iterable(): ShouldAssertion;
iterator(): ShouldAssertion;
// Value comparisons
eql(expected: any, description?: string): ShouldAssertion;
equal(expected: any, description?: string): ShouldAssertion;
equalOneOf(...values: any[]): ShouldAssertion;
within(start: number, finish: number, description?: string): ShouldAssertion;
approximately(value: number, delta: number, description?: string): ShouldAssertion;
type(expected: any, description?: string): ShouldAssertion;
instanceof(constructor: Function, description?: string): ShouldAssertion;
// Numeric comparisons
above(n: number, description?: string): ShouldAssertion;
below(n: number, description?: string): ShouldAssertion;
aboveOrEqual(n: number, description?: string): ShouldAssertion;
greaterThanOrEqual(n: number, description?: string): ShouldAssertion;
belowOrEqual(n: number, description?: string): ShouldAssertion;
lessThanOrEqual(n: number, description?: string): ShouldAssertion;
// Pattern matching
match(other: {} | ((val: any) => any) | RegExp | any, description?: string): ShouldAssertion;
matchEach(other: {} | ((val: any) => any) | RegExp | any, description?: string): ShouldAssertion;
matchAny(other: {} | ((val: any) => any) | RegExp | any, description?: string): ShouldAssertion;
// Object/Array properties
length(n: number, description?: string): ShouldAssertion;
property(name: string, description?: string): ShouldAssertion;
property(name: string, val: any, description?: string): ShouldAssertion;
properties(names: string[] | string | any): ShouldAssertion;
properties(...properties: string[]): ShouldAssertion;
propertyByPath(...properties: string[]): ShouldAssertion;
propertyWithDescriptor(name: string, descriptor: PropertyDescriptor): ShouldAssertion;
oneOf(...values: any[]): ShouldAssertion;
ownProperty(name: string, description?: string): ShouldAssertion;
containEql(obj: any): ShouldAssertion;
containDeep(obj: any): ShouldAssertion;
containDeepOrdered(obj: any): ShouldAssertion;
keys(...allKeys: string[]): ShouldAssertion;
keys(allKeys: string[]): ShouldAssertion;
enumerable(property: string, value?: any): ShouldAssertion;
enumerables(...properties: string[]): ShouldAssertion;
// String operations
startWith(expected: string, message?: any): ShouldAssertion;
endWith(expected: string, message?: any): ShouldAssertion;
// Exception handling
throw(properties?: {}): ShouldAssertion;
throw(message: Function | string | RegExp, properties?: {}): ShouldAssertion;
// Promise assertions
eventually: ShouldAssertion;
finally: ShouldAssertion;
fulfilled(): Promise<any>;
fulfilledWith(value: any): Promise<any>;
rejected(): Promise<any>;
rejectedWith(err: Function | string | RegExp, properties?: {}): Promise<any>;
rejectedWith(properties: {}): Promise<any>;
// HTTP assertions
header(field: string, val?: string): ShouldAssertion;
status(code: number): ShouldAssertion;
json(): ShouldAssertion;
html(): ShouldAssertion;
// Stub/spy assertions (Sinon integration)
alwaysCalledOn(thisTarget: any): ShouldAssertion;
alwaysCalledWith(...arguments: any[]): ShouldAssertion;
alwaysCalledWithExactly(...arguments: any[]): ShouldAssertion;
alwaysCalledWithMatch(...arguments: any[]): ShouldAssertion;
alwaysCalledWithNew(): ShouldAssertion;
alwaysThrew(exception?: any): ShouldAssertion;
callCount(count: number): ShouldAssertion;
called(): ShouldAssertion;
calledOn(thisTarget: any): ShouldAssertion;
calledOnce(): ShouldAssertion;
calledTwice(): ShouldAssertion;
calledThrice(): ShouldAssertion;
calledWith(...arguments: any[]): ShouldAssertion;
calledWithExactly(...arguments: any[]): ShouldAssertion;
calledWithMatch(...arguments: any[]): ShouldAssertion;
calledWithNew(): ShouldAssertion;
neverCalledWith(...arguments: any[]): ShouldAssertion;
neverCalledWithMatch(...arguments: any[]): ShouldAssertion;
threw(exception?: any): ShouldAssertion;
}Interface for extending the assertion functionality.
interface Assertion {
/**
* Add a new assertion method
* @param name - Name of the assertion method
* @param func - Function implementing the assertion
*/
add(name: string, func: Function): void;
/**
* Add a new chainable property
* @param name - Name of the chainable property
* @param onCall - Optional function to call when property is accessed
*/
addChain(name: string, onCall?: Function): void;
/**
* Create an alias for an existing assertion
* @param from - Existing assertion name
* @param to - New alias name
*/
alias(from: string, to: string): void;
}Usage Examples:
import { expect } from "@loopback/testlab";
// Extending assertions
expect.use((should, Assertion) => {
Assertion.add('customAssertion', function() {
// Custom assertion logic
});
Assertion.addChain('customChain', function() {
// Custom chain logic
});
});
// Using Node.js assert-style functions
expect.ok(true);
expect.equal(5, 5);
expect.deepEqual({a: 1}, {a: 1});
expect.throws(() => { throw new Error("test"); });