1 | 'use strict';
|
2 |
|
3 | const assert = require('assert').strict;
|
4 | const { resolve, resolves } = require('./utils');
|
5 |
|
6 | const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
|
7 |
|
8 |
|
9 |
|
10 | function Expectation (value) {
|
11 | this.value = value;
|
12 | this.negated = false;
|
13 |
|
14 |
|
15 | this.a = this;
|
16 | this.an = this;
|
17 | this.and = this;
|
18 | this.be = this;
|
19 | this.been = this;
|
20 | this.has = this;
|
21 | this.have = this;
|
22 | this.is = this;
|
23 | this.of = this;
|
24 | this.the = this;
|
25 | this.to = this;
|
26 | this.with = this;
|
27 |
|
28 |
|
29 |
|
30 | Object.defineProperty(this, 'not', {
|
31 | get () {
|
32 | this.negated = !this.negated;
|
33 | return this;
|
34 | },
|
35 | });
|
36 |
|
37 | Object.defineProperty(this, 'which', {
|
38 | get () {
|
39 | this.value = this.next !== undefined ? this.next : this.value;
|
40 | this.negated = false;
|
41 | return this;
|
42 | },
|
43 | });
|
44 | }
|
45 |
|
46 |
|
47 |
|
48 | Expectation.prototype.deepStrictEqual = function (actual, expected, message) {
|
49 | if (this.negated) {
|
50 | assert.notDeepStrictEqual(actual, expected, message);
|
51 | } else {
|
52 | assert.deepStrictEqual(actual, expected, message);
|
53 | }
|
54 | };
|
55 |
|
56 | Expectation.prototype.strictEqual = function (actual, expected, message) {
|
57 | if (this.negated) {
|
58 | assert.notStrictEqual(actual, expected, message);
|
59 | } else {
|
60 | assert.strictEqual(actual, expected, message);
|
61 | }
|
62 | };
|
63 |
|
64 |
|
65 |
|
66 | Expectation.prototype.equal = function (value) {
|
67 | this.deepStrictEqual(this.value, value);
|
68 | return this;
|
69 | };
|
70 | Expectation.prototype.equals = Expectation.prototype.equal;
|
71 |
|
72 | Expectation.prototype.true = function () {
|
73 | this.strictEqual(this.value, true);
|
74 | return this;
|
75 | };
|
76 |
|
77 | Expectation.prototype.truthy = function () {
|
78 | this.strictEqual(Boolean(this.value), true);
|
79 | return this;
|
80 | };
|
81 |
|
82 | Expectation.prototype.ok = function () {
|
83 | this.strictEqual(Boolean(this.value), true);
|
84 | return this;
|
85 | };
|
86 |
|
87 | Expectation.prototype.false = function () {
|
88 | this.strictEqual(this.value, false);
|
89 | return this;
|
90 | };
|
91 |
|
92 | Expectation.prototype.falsey = function () {
|
93 | this.strictEqual(Boolean(this.value), false);
|
94 | return this;
|
95 | };
|
96 |
|
97 | Expectation.prototype.null = function () {
|
98 | this.strictEqual(this.value, null);
|
99 | return this;
|
100 | };
|
101 |
|
102 | Expectation.prototype.undefined = function () {
|
103 | this.strictEqual(this.value, undefined);
|
104 | return this;
|
105 | };
|
106 |
|
107 | Expectation.prototype.finite = function () {
|
108 | this.strictEqual(Number.isFinite(this.value), true);
|
109 | return this;
|
110 | };
|
111 |
|
112 | Expectation.prototype.infinite = function () {
|
113 | this.strictEqual(this.value === Infinity, true);
|
114 | return this;
|
115 | };
|
116 | Expectation.prototype.infinity = Expectation.prototype.infinite;
|
117 | Expectation.prototype.Infinity = Expectation.prototype.infinite;
|
118 |
|
119 | Expectation.prototype.nan = function () {
|
120 | this.strictEqual(Number.isNaN(this.value), true);
|
121 | return this;
|
122 | };
|
123 | Expectation.prototype.NaN = Expectation.prototype.nan;
|
124 |
|
125 | Expectation.prototype.instanceof = function (constructor) {
|
126 | this.strictEqual(this.value instanceof constructor, true);
|
127 | return this;
|
128 | };
|
129 | Expectation.prototype.instanceOf = Expectation.prototype.instanceof;
|
130 |
|
131 | Expectation.prototype.typeof = function (type) {
|
132 | this.strictEqual(typeof this.value === type, true);
|
133 | return this;
|
134 | };
|
135 | Expectation.prototype.typeOf = Expectation.prototype.typeof;
|
136 | Expectation.prototype.type = Expectation.prototype.typeof;
|
137 |
|
138 | Expectation.prototype.class = function () {
|
139 | this.strictEqual(this.value.toString().startsWith('class '), true);
|
140 | return this;
|
141 | };
|
142 |
|
143 | Expectation.prototype.Array = function () {
|
144 | this.strictEqual(Array.isArray(this.value), true);
|
145 | return this;
|
146 | };
|
147 |
|
148 | Expectation.prototype.Boolean = function () {
|
149 | this.strictEqual(this.value instanceof Boolean || typeof this.value === 'boolean', true);
|
150 | return this;
|
151 | };
|
152 |
|
153 | Expectation.prototype.Buffer = function () {
|
154 | this.strictEqual(Buffer.isBuffer(this.value), true);
|
155 | return this;
|
156 | };
|
157 |
|
158 | Expectation.prototype.Date = function () {
|
159 | this.strictEqual(this.value instanceof Date, true);
|
160 | return this;
|
161 | };
|
162 |
|
163 | Expectation.prototype.Error = function () {
|
164 | this.strictEqual(this.value instanceof Error, true);
|
165 | return this;
|
166 | };
|
167 |
|
168 | Expectation.prototype.Function = function () {
|
169 | this.strictEqual(this.value instanceof Function || typeof this.value === 'function', true);
|
170 | return this;
|
171 | };
|
172 |
|
173 | Expectation.prototype.AsyncFunction = function () {
|
174 | this.strictEqual(this.value instanceof AsyncFunction, true);
|
175 | return this;
|
176 | };
|
177 |
|
178 | Expectation.prototype.Map = function () {
|
179 | this.strictEqual(this.value instanceof Map, true);
|
180 | return this;
|
181 | };
|
182 |
|
183 | Expectation.prototype.Number = function () {
|
184 | this.strictEqual(this.value instanceof Number || typeof this.value === 'number', true);
|
185 | return this;
|
186 | };
|
187 |
|
188 | Expectation.prototype.Object = function () {
|
189 | this.strictEqual(this.value instanceof Object || typeof this.value === 'object', true);
|
190 | return this;
|
191 | };
|
192 |
|
193 | Expectation.prototype.Promise = function () {
|
194 | this.strictEqual(this.value instanceof Promise, true);
|
195 | return this;
|
196 | };
|
197 |
|
198 | Expectation.prototype.RegExp = function () {
|
199 | this.strictEqual(this.value instanceof RegExp, true);
|
200 | return this;
|
201 | };
|
202 |
|
203 | Expectation.prototype.Set = function () {
|
204 | this.strictEqual(this.value instanceof Set, true);
|
205 | return this;
|
206 | };
|
207 |
|
208 | Expectation.prototype.String = function () {
|
209 | this.strictEqual(this.value instanceof String || typeof this.value === 'string', true);
|
210 | return this;
|
211 | };
|
212 |
|
213 | Expectation.prototype.Symbol = function () {
|
214 | this.strictEqual(this.value instanceof Symbol, true);
|
215 | return this;
|
216 | };
|
217 |
|
218 | Expectation.prototype.WeakMap = function () {
|
219 | this.strictEqual(this.value instanceof WeakMap, true);
|
220 | return this;
|
221 | };
|
222 |
|
223 | Expectation.prototype.WeakSet = function () {
|
224 | this.strictEqual(this.value instanceof WeakSet, true);
|
225 | return this;
|
226 | };
|
227 |
|
228 | Expectation.prototype.has = function (value) {
|
229 | this.strictEqual(this.value instanceof Map || this.value instanceof Set ||
|
230 | this.value instanceof WeakMap || this.value instanceof WeakSet, true);
|
231 | this.strictEqual(this.value.has(value), true);
|
232 | return this;
|
233 | };
|
234 |
|
235 | Expectation.prototype.includes = function (value) {
|
236 | this.strictEqual(typeof this.value === 'string' || Array.isArray(this.value), true);
|
237 | this.strictEqual(this.value.includes(value), true);
|
238 | return this;
|
239 | };
|
240 | Expectation.prototype.include = Expectation.prototype.includes;
|
241 |
|
242 | Expectation.prototype.in = function (...args) {
|
243 | const array = args.length === 1 ? args[0] : args;
|
244 | this.strictEqual(array.includes(this.value), true);
|
245 | return this;
|
246 | };
|
247 |
|
248 | Expectation.prototype.within = function (lower, upper, inclusive = true) {
|
249 | if (inclusive) {
|
250 | this.strictEqual(this.value >= lower, true);
|
251 | this.strictEqual(this.value <= upper, true);
|
252 | } else {
|
253 | this.strictEqual(this.value > lower, true);
|
254 | this.strictEqual(this.value < upper, true);
|
255 | }
|
256 | return this;
|
257 | };
|
258 |
|
259 | Expectation.prototype.above = function (value, inclusive = true) {
|
260 | if (inclusive) {
|
261 | this.strictEqual(this.value >= value, true);
|
262 | } else {
|
263 | this.strictEqual(this.value > value, true);
|
264 | }
|
265 | return this;
|
266 | };
|
267 |
|
268 | Expectation.prototype.below = function (value, inclusive = true) {
|
269 | if (inclusive) {
|
270 | this.strictEqual(this.value <= value, true);
|
271 | } else {
|
272 | this.strictEqual(this.value < value, true);
|
273 | }
|
274 | return this;
|
275 | };
|
276 |
|
277 | Expectation.prototype.approximately = function (value, tolerance = 0.00005) {
|
278 | this.strictEqual(Math.abs(value - this.value) <= tolerance, true);
|
279 | return this;
|
280 | };
|
281 |
|
282 | Expectation.prototype.startWith = function (string) {
|
283 | this.strictEqual(typeof this.value === 'string', true);
|
284 | this.strictEqual(this.value.startsWith(string), true);
|
285 | return this;
|
286 | };
|
287 | Expectation.prototype.startsWith = Expectation.prototype.startWith;
|
288 |
|
289 | Expectation.prototype.endWith = function (string) {
|
290 | this.strictEqual(typeof this.value === 'string', true);
|
291 | this.strictEqual(this.value.endsWith(string), true);
|
292 | return this;
|
293 | };
|
294 | Expectation.prototype.endsWith = Expectation.prototype.endWith;
|
295 |
|
296 |
|
297 |
|
298 | Expectation.prototype.property = function (...args) {
|
299 | const property = args[0];
|
300 |
|
301 | this.strictEqual(resolves(this.value, property), true);
|
302 | if (args.length === 2) {
|
303 | const value = args[1];
|
304 | this.strictEqual(resolve(this.value, property), value);
|
305 | }
|
306 |
|
307 | this.next = resolve(this.value, property);
|
308 | return this;
|
309 | };
|
310 |
|
311 |
|
312 |
|
313 | module.exports = function (value) {
|
314 | return new Expectation(value);
|
315 | };
|