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