@gjsify/unit 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -68
- package/lib/esm/index.js +293 -34
- package/lib/types/index.d.ts +55 -10
- package/package.json +16 -20
- package/src/index.spec.ts +47 -1
- package/src/index.ts +329 -33
- package/tsconfig.json +25 -7
- package/lib/cjs/index.js +0 -360
- package/lib/cjs/spy.js +0 -139
- package/test.gjs.mjs +0 -35632
- package/test.node.mjs +0 -1219
- package/tsconfig.types.json +0 -8
package/lib/cjs/index.js
DELETED
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
import "@girs/gjs";
|
|
2
|
-
export * from "./spy.js";
|
|
3
|
-
import nodeAssert from "assert";
|
|
4
|
-
const mainloop = globalThis?.imports?.mainloop;
|
|
5
|
-
let countTestsOverall = 0;
|
|
6
|
-
let countTestsFailed = 0;
|
|
7
|
-
let countTestsIgnored = 0;
|
|
8
|
-
let runtime = "";
|
|
9
|
-
const RED = "\x1B[31m";
|
|
10
|
-
const GREEN = "\x1B[32m";
|
|
11
|
-
const BLUE = "\x1B[34m";
|
|
12
|
-
const GRAY = "\x1B[90m";
|
|
13
|
-
const RESET = "\x1B[39m";
|
|
14
|
-
const print = globalThis.print || console.log;
|
|
15
|
-
class MatcherFactory {
|
|
16
|
-
constructor(actualValue, positive, negated) {
|
|
17
|
-
this.actualValue = actualValue;
|
|
18
|
-
this.positive = positive;
|
|
19
|
-
if (negated) {
|
|
20
|
-
this.not = negated;
|
|
21
|
-
} else {
|
|
22
|
-
this.not = new MatcherFactory(actualValue, !positive, this);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
not;
|
|
26
|
-
triggerResult(success, msg) {
|
|
27
|
-
if (success && !this.positive || !success && this.positive) {
|
|
28
|
-
++countTestsFailed;
|
|
29
|
-
throw new Error(msg);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
to(callback) {
|
|
33
|
-
this.triggerResult(
|
|
34
|
-
callback(this.actualValue),
|
|
35
|
-
` Expected callback to validate`
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
toBe(expectedValue) {
|
|
39
|
-
this.triggerResult(
|
|
40
|
-
this.actualValue === expectedValue,
|
|
41
|
-
` Expected values to match using ===
|
|
42
|
-
Expected: ${expectedValue} (${typeof expectedValue})
|
|
43
|
-
Actual: ${this.actualValue} (${typeof this.actualValue})`
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
toEqual(expectedValue) {
|
|
47
|
-
this.triggerResult(
|
|
48
|
-
this.actualValue == expectedValue,
|
|
49
|
-
` Expected values to match using ==
|
|
50
|
-
Expected: ${expectedValue} (${typeof expectedValue})
|
|
51
|
-
Actual: ${this.actualValue} (${typeof this.actualValue})`
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
toEqualArray(expectedValue) {
|
|
55
|
-
let success = Array.isArray(this.actualValue) && Array.isArray(expectedValue) && this.actualValue.length === expectedValue.length;
|
|
56
|
-
for (let i = 0; i < this.actualValue.length; i++) {
|
|
57
|
-
const actualVal = this.actualValue[i];
|
|
58
|
-
const expectedVal = expectedValue[i];
|
|
59
|
-
success = actualVal == expectedVal;
|
|
60
|
-
if (!success)
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
this.triggerResult(
|
|
64
|
-
success,
|
|
65
|
-
` Expected array items to match using ==
|
|
66
|
-
Expected: ${expectedValue} (${typeof expectedValue})
|
|
67
|
-
Actual: ${this.actualValue} (${typeof this.actualValue})`
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
toMatch(expectedValue) {
|
|
71
|
-
if (typeof this.actualValue.match !== "function") {
|
|
72
|
-
throw new Error(`You can not use toMatch on type ${typeof this.actualValue}`);
|
|
73
|
-
}
|
|
74
|
-
this.triggerResult(
|
|
75
|
-
!!this.actualValue.match(expectedValue),
|
|
76
|
-
" Expected values to match using regular expression\n Expression: " + expectedValue + "\n Actual: " + this.actualValue
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
toBeDefined() {
|
|
80
|
-
this.triggerResult(
|
|
81
|
-
typeof this.actualValue !== "undefined",
|
|
82
|
-
` Expected value to be defined`
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
toBeUndefined() {
|
|
86
|
-
this.triggerResult(
|
|
87
|
-
typeof this.actualValue === "undefined",
|
|
88
|
-
` Expected value to be undefined`
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
toBeNull() {
|
|
92
|
-
this.triggerResult(
|
|
93
|
-
this.actualValue === null,
|
|
94
|
-
` Expected value to be null`
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
toBeTruthy() {
|
|
98
|
-
this.triggerResult(
|
|
99
|
-
this.actualValue,
|
|
100
|
-
` Expected value to be truthy`
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
toBeFalsy() {
|
|
104
|
-
this.triggerResult(
|
|
105
|
-
!this.actualValue,
|
|
106
|
-
` Expected value to be falsy`
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
toContain(needle) {
|
|
110
|
-
this.triggerResult(
|
|
111
|
-
this.actualValue instanceof Array && this.actualValue.indexOf(needle) !== -1,
|
|
112
|
-
` Expected ` + this.actualValue + ` to contain ` + needle
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
toBeLessThan(greaterValue) {
|
|
116
|
-
this.triggerResult(
|
|
117
|
-
this.actualValue < greaterValue,
|
|
118
|
-
` Expected ` + this.actualValue + ` to be less than ` + greaterValue
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
toBeGreaterThan(smallerValue) {
|
|
122
|
-
this.triggerResult(
|
|
123
|
-
this.actualValue > smallerValue,
|
|
124
|
-
` Expected ` + this.actualValue + ` to be greater than ` + smallerValue
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
toBeCloseTo(expectedValue, precision) {
|
|
128
|
-
const shiftHelper = Math.pow(10, precision);
|
|
129
|
-
this.triggerResult(
|
|
130
|
-
Math.round(this.actualValue * shiftHelper) / shiftHelper === Math.round(expectedValue * shiftHelper) / shiftHelper,
|
|
131
|
-
` Expected ` + this.actualValue + ` with precision ` + precision + ` to be close to ` + expectedValue
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
toThrow(ErrorType) {
|
|
135
|
-
let errorMessage = "";
|
|
136
|
-
let didThrow = false;
|
|
137
|
-
let typeMatch = true;
|
|
138
|
-
try {
|
|
139
|
-
this.actualValue();
|
|
140
|
-
didThrow = false;
|
|
141
|
-
} catch (e) {
|
|
142
|
-
errorMessage = e.message || "";
|
|
143
|
-
didThrow = true;
|
|
144
|
-
if (ErrorType) {
|
|
145
|
-
typeMatch = e instanceof ErrorType;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
const functionName = this.actualValue.name || typeof this.actualValue === "function" ? "[anonymous function]" : this.actualValue.toString();
|
|
149
|
-
this.triggerResult(
|
|
150
|
-
didThrow,
|
|
151
|
-
` Expected ${functionName} to ${this.positive ? "throw" : "not throw"} an exception ${!this.positive && errorMessage ? `, but an error with the message "${errorMessage}" was thrown` : ""}`
|
|
152
|
-
);
|
|
153
|
-
if (ErrorType) {
|
|
154
|
-
this.triggerResult(
|
|
155
|
-
typeMatch,
|
|
156
|
-
` Expected Error type '${ErrorType.name}', but the error is not an instance of it`
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
const describe = async function(moduleName, callback) {
|
|
162
|
-
print("\n" + moduleName);
|
|
163
|
-
await callback();
|
|
164
|
-
beforeEachCb = null;
|
|
165
|
-
afterEachCb = null;
|
|
166
|
-
};
|
|
167
|
-
const runtimeMatch = async function(onRuntime, version) {
|
|
168
|
-
const currRuntime = await getRuntime();
|
|
169
|
-
const foundRuntime = onRuntime.find((r) => currRuntime.includes(r));
|
|
170
|
-
if (!foundRuntime) {
|
|
171
|
-
return {
|
|
172
|
-
matched: false
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
if (typeof version === "string") {
|
|
176
|
-
if (!currRuntime.includes(version)) {
|
|
177
|
-
return {
|
|
178
|
-
matched: false
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return {
|
|
183
|
-
matched: true,
|
|
184
|
-
runtime: foundRuntime,
|
|
185
|
-
version
|
|
186
|
-
};
|
|
187
|
-
};
|
|
188
|
-
const on = async function(onRuntime, version, callback) {
|
|
189
|
-
if (typeof onRuntime === "string") {
|
|
190
|
-
onRuntime = [onRuntime];
|
|
191
|
-
}
|
|
192
|
-
if (typeof version === "function") {
|
|
193
|
-
callback = version;
|
|
194
|
-
version = void 0;
|
|
195
|
-
}
|
|
196
|
-
const { matched } = await runtimeMatch(onRuntime, version);
|
|
197
|
-
if (!matched) {
|
|
198
|
-
++countTestsIgnored;
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
print(`
|
|
202
|
-
On ${onRuntime.join(", ")}${version ? " " + version : ""}`);
|
|
203
|
-
await callback();
|
|
204
|
-
};
|
|
205
|
-
let beforeEachCb;
|
|
206
|
-
let afterEachCb;
|
|
207
|
-
const beforeEach = function(callback) {
|
|
208
|
-
beforeEachCb = callback;
|
|
209
|
-
};
|
|
210
|
-
const afterEach = function(callback) {
|
|
211
|
-
afterEachCb = callback;
|
|
212
|
-
};
|
|
213
|
-
const it = async function(expectation, callback) {
|
|
214
|
-
try {
|
|
215
|
-
if (typeof beforeEachCb === "function") {
|
|
216
|
-
await beforeEachCb();
|
|
217
|
-
}
|
|
218
|
-
await callback();
|
|
219
|
-
if (typeof afterEachCb === "function") {
|
|
220
|
-
await afterEachCb();
|
|
221
|
-
}
|
|
222
|
-
print(` ${GREEN}\u2714${RESET} ${GRAY}${expectation}${RESET}`);
|
|
223
|
-
} catch (e) {
|
|
224
|
-
print(` ${RED}\u274C${RESET} ${GRAY}${expectation}${RESET}`);
|
|
225
|
-
print(`${RED}${e.message}${RESET}`);
|
|
226
|
-
if (e.stack)
|
|
227
|
-
print(e.stack);
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
const expect = function(actualValue) {
|
|
231
|
-
++countTestsOverall;
|
|
232
|
-
const expecter = new MatcherFactory(actualValue, true);
|
|
233
|
-
return expecter;
|
|
234
|
-
};
|
|
235
|
-
const assert = function(success, message) {
|
|
236
|
-
++countTestsOverall;
|
|
237
|
-
if (!success) {
|
|
238
|
-
++countTestsFailed;
|
|
239
|
-
}
|
|
240
|
-
nodeAssert(success, message);
|
|
241
|
-
};
|
|
242
|
-
assert.strictEqual = function(actual, expected, message) {
|
|
243
|
-
++countTestsOverall;
|
|
244
|
-
try {
|
|
245
|
-
nodeAssert.strictEqual(actual, expected, message);
|
|
246
|
-
} catch (error) {
|
|
247
|
-
++countTestsFailed;
|
|
248
|
-
throw error;
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
assert.throws = function(promiseFn, ...args) {
|
|
252
|
-
++countTestsOverall;
|
|
253
|
-
let error;
|
|
254
|
-
try {
|
|
255
|
-
promiseFn();
|
|
256
|
-
} catch (e) {
|
|
257
|
-
error = e;
|
|
258
|
-
}
|
|
259
|
-
if (!error)
|
|
260
|
-
++countTestsFailed;
|
|
261
|
-
nodeAssert.throws(() => {
|
|
262
|
-
if (error)
|
|
263
|
-
throw error;
|
|
264
|
-
}, args[0], args[1]);
|
|
265
|
-
};
|
|
266
|
-
assert.deepStrictEqual = function(actual, expected, message) {
|
|
267
|
-
++countTestsOverall;
|
|
268
|
-
try {
|
|
269
|
-
nodeAssert.deepStrictEqual(actual, expected, message);
|
|
270
|
-
} catch (error) {
|
|
271
|
-
++countTestsFailed;
|
|
272
|
-
throw error;
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
const runTests = async function(namespaces) {
|
|
276
|
-
for (const subNamespace in namespaces) {
|
|
277
|
-
const namespace = namespaces[subNamespace];
|
|
278
|
-
if (typeof namespace === "function") {
|
|
279
|
-
await namespace();
|
|
280
|
-
} else if (typeof namespace === "object") {
|
|
281
|
-
await runTests(namespace);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
};
|
|
285
|
-
const printResult = () => {
|
|
286
|
-
if (countTestsIgnored) {
|
|
287
|
-
print(`
|
|
288
|
-
${BLUE}\u2714 ${countTestsIgnored} ignored test${countTestsIgnored > 1 ? "s" : ""}${RESET}`);
|
|
289
|
-
}
|
|
290
|
-
if (countTestsFailed) {
|
|
291
|
-
print(`
|
|
292
|
-
${RED}\u274C ${countTestsFailed} of ${countTestsOverall} tests failed${RESET}`);
|
|
293
|
-
} else {
|
|
294
|
-
print(`
|
|
295
|
-
${GREEN}\u2714 ${countTestsOverall} completed${RESET}`);
|
|
296
|
-
}
|
|
297
|
-
};
|
|
298
|
-
const getRuntime = async () => {
|
|
299
|
-
if (runtime && runtime !== "Unknown") {
|
|
300
|
-
return runtime;
|
|
301
|
-
}
|
|
302
|
-
if (globalThis.Deno?.version?.deno) {
|
|
303
|
-
return "Deno " + globalThis.Deno?.version?.deno;
|
|
304
|
-
} else {
|
|
305
|
-
let process = globalThis.process;
|
|
306
|
-
if (!process) {
|
|
307
|
-
try {
|
|
308
|
-
process = await import("process");
|
|
309
|
-
} catch (error) {
|
|
310
|
-
console.error(error);
|
|
311
|
-
console.warn(error.message);
|
|
312
|
-
runtime = "Unknown";
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
if (process?.versions?.gjs) {
|
|
316
|
-
runtime = "Gjs " + process.versions.gjs;
|
|
317
|
-
} else if (process?.versions?.node) {
|
|
318
|
-
runtime = "Node.js " + process.versions.node;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
return runtime || "Unknown";
|
|
322
|
-
};
|
|
323
|
-
const printRuntime = async () => {
|
|
324
|
-
const runtime2 = await getRuntime();
|
|
325
|
-
print(`
|
|
326
|
-
Running on ${runtime2}`);
|
|
327
|
-
};
|
|
328
|
-
const run = async (namespaces) => {
|
|
329
|
-
printRuntime().then(async () => {
|
|
330
|
-
return runTests(namespaces).then(() => {
|
|
331
|
-
printResult();
|
|
332
|
-
print();
|
|
333
|
-
mainloop?.quit();
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
mainloop?.run();
|
|
337
|
-
};
|
|
338
|
-
var src_default = {
|
|
339
|
-
run,
|
|
340
|
-
assert,
|
|
341
|
-
expect,
|
|
342
|
-
it,
|
|
343
|
-
afterEach,
|
|
344
|
-
beforeEach,
|
|
345
|
-
on,
|
|
346
|
-
describe,
|
|
347
|
-
print
|
|
348
|
-
};
|
|
349
|
-
export {
|
|
350
|
-
afterEach,
|
|
351
|
-
assert,
|
|
352
|
-
beforeEach,
|
|
353
|
-
src_default as default,
|
|
354
|
-
describe,
|
|
355
|
-
expect,
|
|
356
|
-
it,
|
|
357
|
-
on,
|
|
358
|
-
print,
|
|
359
|
-
run
|
|
360
|
-
};
|
package/lib/cjs/spy.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
function spy(f) {
|
|
2
|
-
const calls = [];
|
|
3
|
-
function spy2(...args) {
|
|
4
|
-
let retv;
|
|
5
|
-
try {
|
|
6
|
-
retv = f ? f.apply(this, args) : void 0;
|
|
7
|
-
} catch (error) {
|
|
8
|
-
calls.push({
|
|
9
|
-
type: "throw",
|
|
10
|
-
this: this,
|
|
11
|
-
arguments: args,
|
|
12
|
-
throw: error
|
|
13
|
-
});
|
|
14
|
-
throw error;
|
|
15
|
-
}
|
|
16
|
-
calls.push({
|
|
17
|
-
type: "return",
|
|
18
|
-
this: this,
|
|
19
|
-
arguments: args,
|
|
20
|
-
return: retv
|
|
21
|
-
});
|
|
22
|
-
return retv;
|
|
23
|
-
}
|
|
24
|
-
Object.defineProperties(spy2, {
|
|
25
|
-
calls: descriptors.calls(calls),
|
|
26
|
-
returnedCalls: descriptors.returnedCalls,
|
|
27
|
-
thrownCalls: descriptors.thrownCalls,
|
|
28
|
-
firstCall: descriptors.firstCall,
|
|
29
|
-
lastCall: descriptors.lastCall,
|
|
30
|
-
firstReturnedCall: descriptors.firstReturnedCall,
|
|
31
|
-
lastReturnedCall: descriptors.lastReturnedCall,
|
|
32
|
-
firstThrownCall: descriptors.firstThrownCall,
|
|
33
|
-
lastThrownCall: descriptors.lastThrownCall,
|
|
34
|
-
reset: descriptors.reset,
|
|
35
|
-
toString: descriptors.toString(f)
|
|
36
|
-
});
|
|
37
|
-
return spy2;
|
|
38
|
-
}
|
|
39
|
-
const descriptors = {
|
|
40
|
-
calls(value) {
|
|
41
|
-
return { value, configurable: true };
|
|
42
|
-
},
|
|
43
|
-
returnedCalls: {
|
|
44
|
-
get: function returnedCalls() {
|
|
45
|
-
return this.calls.filter(isReturned);
|
|
46
|
-
},
|
|
47
|
-
configurable: true
|
|
48
|
-
},
|
|
49
|
-
thrownCalls: {
|
|
50
|
-
get: function thrownCalls() {
|
|
51
|
-
return this.calls.filter(isThrown);
|
|
52
|
-
},
|
|
53
|
-
configurable: true
|
|
54
|
-
},
|
|
55
|
-
firstCall: {
|
|
56
|
-
get: function firstCall() {
|
|
57
|
-
return this.calls[0] || null;
|
|
58
|
-
},
|
|
59
|
-
configurable: true
|
|
60
|
-
},
|
|
61
|
-
lastCall: {
|
|
62
|
-
get: function lastCall() {
|
|
63
|
-
return this.calls[this.calls.length - 1] || null;
|
|
64
|
-
},
|
|
65
|
-
configurable: true
|
|
66
|
-
},
|
|
67
|
-
firstReturnedCall: {
|
|
68
|
-
get: function firstReturnedCall() {
|
|
69
|
-
for (let i = 0; i < this.calls.length; ++i) {
|
|
70
|
-
const call = this.calls[i];
|
|
71
|
-
if (isReturned(call)) {
|
|
72
|
-
return call;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return null;
|
|
76
|
-
},
|
|
77
|
-
configurable: true
|
|
78
|
-
},
|
|
79
|
-
lastReturnedCall: {
|
|
80
|
-
get: function lastReturnedCall() {
|
|
81
|
-
for (let i = this.calls.length - 1; i >= 0; --i) {
|
|
82
|
-
const call = this.calls[i];
|
|
83
|
-
if (isReturned(call)) {
|
|
84
|
-
return call;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return null;
|
|
88
|
-
},
|
|
89
|
-
configurable: true
|
|
90
|
-
},
|
|
91
|
-
firstThrownCall: {
|
|
92
|
-
get: function firstThrownCall() {
|
|
93
|
-
for (let i = 0; i < this.calls.length; ++i) {
|
|
94
|
-
const call = this.calls[i];
|
|
95
|
-
if (isThrown(call)) {
|
|
96
|
-
return call;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return null;
|
|
100
|
-
},
|
|
101
|
-
configurable: true
|
|
102
|
-
},
|
|
103
|
-
lastThrownCall: {
|
|
104
|
-
get: function lastThrownCall() {
|
|
105
|
-
for (let i = this.calls.length - 1; i >= 0; --i) {
|
|
106
|
-
const call = this.calls[i];
|
|
107
|
-
if (isThrown(call)) {
|
|
108
|
-
return call;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return null;
|
|
112
|
-
},
|
|
113
|
-
configurable: true
|
|
114
|
-
},
|
|
115
|
-
reset: {
|
|
116
|
-
value: function reset() {
|
|
117
|
-
;
|
|
118
|
-
this.calls.length = 0;
|
|
119
|
-
},
|
|
120
|
-
configurable: true
|
|
121
|
-
},
|
|
122
|
-
toString(f) {
|
|
123
|
-
return {
|
|
124
|
-
value: function toString() {
|
|
125
|
-
return `/* The spy of */ ${f ? f.toString() : "function(){}"}`;
|
|
126
|
-
},
|
|
127
|
-
configurable: true
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
function isReturned(call) {
|
|
132
|
-
return call.type === "return";
|
|
133
|
-
}
|
|
134
|
-
function isThrown(call) {
|
|
135
|
-
return call.type === "throw";
|
|
136
|
-
}
|
|
137
|
-
export {
|
|
138
|
-
spy
|
|
139
|
-
};
|