0
# BDD Assertions
1
2
Behavior-driven development style assertions using Should.js configured in as-function mode with enhanced TypeScript support and chai-like syntax.
3
4
## Capabilities
5
6
### Expect Function
7
8
The main assertion interface providing Should.js functionality in as-function mode.
9
10
```typescript { .api }
11
/**
12
* Should.js assertion interface configured in as-function mode
13
* Provides BDD-style assertions with TypeScript support
14
* @param obj - The object to assert against
15
* @returns ShouldAssertion for chaining assertions
16
*/
17
const expect: Internal;
18
19
interface Internal extends ShouldInternal {
20
(obj: any): ShouldAssertion;
21
use(fn: (should: Internal, Assertion: Assertion) => void): Internal;
22
23
// Node.js assert function equivalents
24
fail(actual: any, expected: any, message: string, operator: string): void;
25
assert(value: any, message: string): void;
26
ok(value: any, message?: string): void;
27
equal(actual: any, expected: any, message?: string): void;
28
notEqual(actual: any, expected: any, message?: string): void;
29
deepEqual(actual: any, expected: any, message?: string): void;
30
notDeepEqual(actual: any, expected: any, message?: string): void;
31
strictEqual(actual: any, expected: any, message?: string): void;
32
notStrictEqual(actual: any, expected: any, message?: string): void;
33
throws(block: any, error?: any, message?: string): void;
34
doesNotThrow(block: any, message?: string): void;
35
ifError(value: any): void;
36
inspect(value: any, obj: any): any;
37
}
38
39
interface ShouldInternal {
40
exist(actual: any, msg?: string): void;
41
exists(actual: any, msg?: string): void;
42
not: ShouldInternal;
43
}
44
```
45
46
**Usage Examples:**
47
48
```typescript
49
import { expect } from "@loopback/testlab";
50
51
// Basic assertions
52
expect(5).to.be.greaterThan(3);
53
expect("hello").to.equal("hello");
54
expect(true).to.be.true();
55
expect([1, 2, 3]).to.have.lengthOf(3);
56
57
// Object assertions
58
expect({name: "Alice", age: 30}).to.have.property("name", "Alice");
59
expect({a: 1, b: 2}).to.have.properties(["a", "b"]);
60
expect({}).to.be.empty();
61
62
// Array assertions
63
expect([1, 2, 3]).to.containEql(2);
64
expect([1, 2, 3]).to.match([1, 2, 3]);
65
expect(["a", "b", "c"]).to.have.lengthOf(3);
66
67
// Type assertions
68
expect("hello").to.be.a.String();
69
expect(42).to.be.a.Number();
70
expect([]).to.be.an.Array();
71
expect({}).to.be.an.Object();
72
73
// Promise assertions
74
await expect(Promise.resolve("success")).to.be.fulfilledWith("success");
75
await expect(Promise.reject(new Error("fail"))).to.be.rejected();
76
```
77
78
### Should Assertion Interface
79
80
The comprehensive assertion interface providing all Should.js capabilities.
81
82
```typescript { .api }
83
interface ShouldAssertion {
84
// Basic grammar for fluent assertions
85
a: ShouldAssertion;
86
an: ShouldAssertion;
87
and: ShouldAssertion;
88
be: ShouldAssertion;
89
has: ShouldAssertion;
90
have: ShouldAssertion;
91
is: ShouldAssertion;
92
it: ShouldAssertion;
93
with: ShouldAssertion;
94
which: ShouldAssertion;
95
the: ShouldAssertion;
96
of: ShouldAssertion;
97
not: ShouldAssertion;
98
to: ShouldAssertion; // chai-like expect().to syntax
99
100
// Type validators
101
arguments(): ShouldAssertion;
102
empty(): ShouldAssertion;
103
ok(): ShouldAssertion;
104
true(): ShouldAssertion;
105
false(): ShouldAssertion;
106
NaN(): ShouldAssertion;
107
Infinity(): ShouldAssertion;
108
Array(): ShouldAssertion;
109
Object(): ShouldAssertion;
110
String(): ShouldAssertion;
111
Boolean(): ShouldAssertion;
112
Number(): ShouldAssertion;
113
Error(): ShouldAssertion;
114
Function(): ShouldAssertion;
115
Date(): ShouldAssertion;
116
Class(): ShouldAssertion;
117
Undefined(): ShouldAssertion;
118
Null(): ShouldAssertion;
119
Promise(): ShouldAssertion;
120
generator(): ShouldAssertion;
121
iterable(): ShouldAssertion;
122
iterator(): ShouldAssertion;
123
124
// Value comparisons
125
eql(expected: any, description?: string): ShouldAssertion;
126
equal(expected: any, description?: string): ShouldAssertion;
127
equalOneOf(...values: any[]): ShouldAssertion;
128
within(start: number, finish: number, description?: string): ShouldAssertion;
129
approximately(value: number, delta: number, description?: string): ShouldAssertion;
130
type(expected: any, description?: string): ShouldAssertion;
131
instanceof(constructor: Function, description?: string): ShouldAssertion;
132
133
// Numeric comparisons
134
above(n: number, description?: string): ShouldAssertion;
135
below(n: number, description?: string): ShouldAssertion;
136
aboveOrEqual(n: number, description?: string): ShouldAssertion;
137
greaterThanOrEqual(n: number, description?: string): ShouldAssertion;
138
belowOrEqual(n: number, description?: string): ShouldAssertion;
139
lessThanOrEqual(n: number, description?: string): ShouldAssertion;
140
141
// Pattern matching
142
match(other: {} | ((val: any) => any) | RegExp | any, description?: string): ShouldAssertion;
143
matchEach(other: {} | ((val: any) => any) | RegExp | any, description?: string): ShouldAssertion;
144
matchAny(other: {} | ((val: any) => any) | RegExp | any, description?: string): ShouldAssertion;
145
146
// Object/Array properties
147
length(n: number, description?: string): ShouldAssertion;
148
property(name: string, description?: string): ShouldAssertion;
149
property(name: string, val: any, description?: string): ShouldAssertion;
150
properties(names: string[] | string | any): ShouldAssertion;
151
properties(...properties: string[]): ShouldAssertion;
152
propertyByPath(...properties: string[]): ShouldAssertion;
153
propertyWithDescriptor(name: string, descriptor: PropertyDescriptor): ShouldAssertion;
154
oneOf(...values: any[]): ShouldAssertion;
155
ownProperty(name: string, description?: string): ShouldAssertion;
156
containEql(obj: any): ShouldAssertion;
157
containDeep(obj: any): ShouldAssertion;
158
containDeepOrdered(obj: any): ShouldAssertion;
159
keys(...allKeys: string[]): ShouldAssertion;
160
keys(allKeys: string[]): ShouldAssertion;
161
enumerable(property: string, value?: any): ShouldAssertion;
162
enumerables(...properties: string[]): ShouldAssertion;
163
164
// String operations
165
startWith(expected: string, message?: any): ShouldAssertion;
166
endWith(expected: string, message?: any): ShouldAssertion;
167
168
// Exception handling
169
throw(properties?: {}): ShouldAssertion;
170
throw(message: Function | string | RegExp, properties?: {}): ShouldAssertion;
171
172
// Promise assertions
173
eventually: ShouldAssertion;
174
finally: ShouldAssertion;
175
fulfilled(): Promise<any>;
176
fulfilledWith(value: any): Promise<any>;
177
rejected(): Promise<any>;
178
rejectedWith(err: Function | string | RegExp, properties?: {}): Promise<any>;
179
rejectedWith(properties: {}): Promise<any>;
180
181
// HTTP assertions
182
header(field: string, val?: string): ShouldAssertion;
183
status(code: number): ShouldAssertion;
184
json(): ShouldAssertion;
185
html(): ShouldAssertion;
186
187
// Stub/spy assertions (Sinon integration)
188
alwaysCalledOn(thisTarget: any): ShouldAssertion;
189
alwaysCalledWith(...arguments: any[]): ShouldAssertion;
190
alwaysCalledWithExactly(...arguments: any[]): ShouldAssertion;
191
alwaysCalledWithMatch(...arguments: any[]): ShouldAssertion;
192
alwaysCalledWithNew(): ShouldAssertion;
193
alwaysThrew(exception?: any): ShouldAssertion;
194
callCount(count: number): ShouldAssertion;
195
called(): ShouldAssertion;
196
calledOn(thisTarget: any): ShouldAssertion;
197
calledOnce(): ShouldAssertion;
198
calledTwice(): ShouldAssertion;
199
calledThrice(): ShouldAssertion;
200
calledWith(...arguments: any[]): ShouldAssertion;
201
calledWithExactly(...arguments: any[]): ShouldAssertion;
202
calledWithMatch(...arguments: any[]): ShouldAssertion;
203
calledWithNew(): ShouldAssertion;
204
neverCalledWith(...arguments: any[]): ShouldAssertion;
205
neverCalledWithMatch(...arguments: any[]): ShouldAssertion;
206
threw(exception?: any): ShouldAssertion;
207
}
208
```
209
210
### Assertion Extension
211
212
Interface for extending the assertion functionality.
213
214
```typescript { .api }
215
interface Assertion {
216
/**
217
* Add a new assertion method
218
* @param name - Name of the assertion method
219
* @param func - Function implementing the assertion
220
*/
221
add(name: string, func: Function): void;
222
223
/**
224
* Add a new chainable property
225
* @param name - Name of the chainable property
226
* @param onCall - Optional function to call when property is accessed
227
*/
228
addChain(name: string, onCall?: Function): void;
229
230
/**
231
* Create an alias for an existing assertion
232
* @param from - Existing assertion name
233
* @param to - New alias name
234
*/
235
alias(from: string, to: string): void;
236
}
237
```
238
239
**Usage Examples:**
240
241
```typescript
242
import { expect } from "@loopback/testlab";
243
244
// Extending assertions
245
expect.use((should, Assertion) => {
246
Assertion.add('customAssertion', function() {
247
// Custom assertion logic
248
});
249
250
Assertion.addChain('customChain', function() {
251
// Custom chain logic
252
});
253
});
254
255
// Using Node.js assert-style functions
256
expect.ok(true);
257
expect.equal(5, 5);
258
expect.deepEqual({a: 1}, {a: 1});
259
expect.throws(() => { throw new Error("test"); });
260
```