vitest-pool-assemblyscript 0.11.0 → 0.12.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/assembly/compare.ts +44 -38
- package/assembly/expect.ts +13 -3
- package/assembly/utils.ts +4 -1
- package/package.json +1 -1
package/assembly/compare.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { stringifyValue } from './utils';
|
|
1
|
+
import { isNull, stringifyValue } from './utils';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Byte offset from an object pointer to the rtId field in the AS managed object header.
|
|
@@ -325,19 +325,15 @@ function arrayBufferEquals<T, U>(actual: T, expected: U): __vitest_assemblyscrip
|
|
|
325
325
|
* (or same reference type) for provided values.
|
|
326
326
|
*/
|
|
327
327
|
export function identical<T, U>(actual: T, expected: U): bool {
|
|
328
|
+
const actualIsNull = isNull(actual);
|
|
329
|
+
const expectedIsNull = isNull(expected);
|
|
330
|
+
|
|
328
331
|
// both refs
|
|
329
332
|
if (isReference<T>() && isReference<U>()) {
|
|
330
|
-
const actualIsNullable = isNullable<T>();
|
|
331
|
-
// Use changetype pointer check instead of `== null` to avoid invoking
|
|
332
|
-
// user-defined @operator("==") overloads, which reject null arguments
|
|
333
|
-
const actualIsNull = actualIsNullable && changetype<usize>(actual) == 0;
|
|
334
|
-
const expectedIsNullable = isNullable<U>();
|
|
335
|
-
const expectedIsNull = expectedIsNullable && changetype<usize>(expected) == 0;
|
|
336
|
-
|
|
337
333
|
// null refs
|
|
338
334
|
if (actualIsNull && expectedIsNull) {
|
|
339
335
|
return true;
|
|
340
|
-
} else if (
|
|
336
|
+
} else if ( actualIsNull != expectedIsNull ) {
|
|
341
337
|
return false;
|
|
342
338
|
}
|
|
343
339
|
|
|
@@ -348,27 +344,26 @@ export function identical<T, U>(actual: T, expected: U): bool {
|
|
|
348
344
|
// object refs
|
|
349
345
|
return changetype<usize>(actual) == changetype<usize>(expected);
|
|
350
346
|
}
|
|
351
|
-
} else if (
|
|
352
|
-
|
|
353
|
-
|
|
347
|
+
} else if (
|
|
348
|
+
(isReference<T>() && !isReference<U>())
|
|
349
|
+
|| (!isReference<T>() && isReference<U>())
|
|
350
|
+
) {
|
|
351
|
+
if (actualIsNull && expectedIsNull) {
|
|
354
352
|
return true;
|
|
353
|
+
} else if ( actualIsNull != expectedIsNull ) {
|
|
354
|
+
return false;
|
|
355
355
|
}
|
|
356
|
+
|
|
356
357
|
// Non-null reference vs value type: fundamentally incomparable
|
|
357
358
|
throw new Error(
|
|
358
359
|
"Cannot compare " + nameof<T>() + " with " + nameof<U>()
|
|
359
360
|
+ equalsPathAtSuffix() + ": reference and value types are not comparable."
|
|
360
361
|
);
|
|
361
|
-
} else if (!isReference<T>() && isReference<U>()) {
|
|
362
|
-
// Both null/zero: bare null (usize(0)) matches null reference
|
|
363
|
-
if (actual == usize(0) && changetype<usize>(expected) == 0) {
|
|
364
|
-
return true;
|
|
365
|
-
}
|
|
366
|
-
// Value type vs non-null reference: fundamentally incomparable
|
|
367
|
-
throw new Error(
|
|
368
|
-
"Cannot compare " + nameof<T>() + " with " + nameof<U>()
|
|
369
|
-
+ equalsPathAtSuffix() + ": reference and value types are not comparable."
|
|
370
|
-
);
|
|
371
362
|
} else { // both primitives
|
|
363
|
+
if ( actualIsNull != expectedIsNull ) {
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
|
|
372
367
|
if ( (isBoolean<T>() && !isBoolean<U>()) || (!isBoolean<T>() && isBoolean<U>())
|
|
373
368
|
) {
|
|
374
369
|
// when one is boolean and the other is not, they are not identical
|
|
@@ -484,27 +479,39 @@ export function equals<T, U>(actual: T, expected: U): __vitest_assemblyscript_Eq
|
|
|
484
479
|
exactMatch = identical(actual, expected);
|
|
485
480
|
}
|
|
486
481
|
|
|
487
|
-
|
|
488
|
-
|
|
482
|
+
const actualIsNull = isNull(actual);
|
|
483
|
+
const expectedIsNull = isNull(expected);
|
|
484
|
+
|
|
485
|
+
if (
|
|
486
|
+
(!isReference<T>() && !isReference<U>())
|
|
487
|
+
|| (isString<T>() && isString<U>())
|
|
488
|
+
|| (isVector<T>() && isVector<U>())
|
|
489
|
+
) {
|
|
490
|
+
// non-bool primitives or strings or vectors: return result of identity compare
|
|
489
491
|
return exactMatch ? __vitest_assemblyscript_EqualityResult.Equal : __vitest_assemblyscript_EqualityResult.NotEqual;
|
|
490
492
|
} else if (exactMatch) {
|
|
491
493
|
// primitive / reference comparison passed already
|
|
492
494
|
return __vitest_assemblyscript_EqualityResult.Equal;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
const expectedIsNull = changetype<usize>(expected) == 0;
|
|
500
|
-
|
|
501
|
-
if (actualIsNull && expectedIsNull) {
|
|
502
|
-
return __vitest_assemblyscript_EqualityResult.Equal;
|
|
495
|
+
} else if (
|
|
496
|
+
(isReference<T>() && !isReference<U>())
|
|
497
|
+
|| (!isReference<T>() && isReference<U>())
|
|
498
|
+
) {
|
|
499
|
+
if (actualIsNull || expectedIsNull) {
|
|
500
|
+
return exactMatch ? __vitest_assemblyscript_EqualityResult.Equal : __vitest_assemblyscript_EqualityResult.NotEqual;
|
|
503
501
|
}
|
|
504
502
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
503
|
+
// Non-null reference vs value type: fundamentally incomparable
|
|
504
|
+
throw new Error(
|
|
505
|
+
"Cannot compare " + nameof<T>() + " with " + nameof<U>()
|
|
506
|
+
+ equalsPathAtSuffix() + ": reference and value types are not comparable."
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (actualIsNull && expectedIsNull) {
|
|
511
|
+
return __vitest_assemblyscript_EqualityResult.Equal;
|
|
512
|
+
}
|
|
513
|
+
if (actualIsNull != expectedIsNull) {
|
|
514
|
+
return __vitest_assemblyscript_EqualityResult.NotEqual;
|
|
508
515
|
}
|
|
509
516
|
|
|
510
517
|
// Cycle detection: if this reference pair is already being compared further up
|
|
@@ -784,4 +791,3 @@ export function compareInequality<T, U>(actual: T, compareTo: U, expectedOperati
|
|
|
784
791
|
export function truthyOrFalsey<T>(actual: T, expected: bool): bool {
|
|
785
792
|
return actual ? expected == true : expected == false;
|
|
786
793
|
}
|
|
787
|
-
|
package/assembly/expect.ts
CHANGED
|
@@ -77,10 +77,15 @@ abstract class BaseExpectMatcher<T> {
|
|
|
77
77
|
* involving a float and allows all numeric types because it can still produce accurate
|
|
78
78
|
* results in precision-loss casting edge cases.
|
|
79
79
|
*
|
|
80
|
+
* Null comparison: a null reference, the bare `null` literal, and `usize(0)` are all treated
|
|
81
|
+
* as null and compare as identical to one another. Zero-valued primitives (`0`, `false`, `0.0`) are
|
|
82
|
+
* **not** identical to null. Because the bare `null` literal is `usize(0)` in AssemblyScript,
|
|
83
|
+
* `usize(0)` will not compare as identical to a `0` of another numeric type.
|
|
84
|
+
*
|
|
80
85
|
* @throws When comparing float/integer types where the float's mantissa cannot losslessly
|
|
81
86
|
* represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
|
|
82
87
|
* @throws When comparing fundamentally incompatible types: reference vs value type
|
|
83
|
-
* (e.g. `string` vs `i32`, unless one is null
|
|
88
|
+
* (e.g. `string` vs `i32`, unless one side is null, or `v128` vs non-vector type).
|
|
84
89
|
*
|
|
85
90
|
* @example
|
|
86
91
|
* expect(1 + 1).toBe(2);
|
|
@@ -278,12 +283,17 @@ abstract class BaseExpectMatcher<T> {
|
|
|
278
283
|
* are not included, as deep equality injection is scoped to user source files only
|
|
279
284
|
*
|
|
280
285
|
* SIMD vectors use WASM's native `==` comparison, which compares at the bit level,
|
|
281
|
-
* ignoring lane type.
|
|
286
|
+
* ignoring lane type.
|
|
287
|
+
*
|
|
288
|
+
* Null comparison: a null reference, the bare `null` literal, and `usize(0)` are all treated
|
|
289
|
+
* as null and compare equal to one another. Zero-valued primitives (`0`, `false`, `0.0`) are
|
|
290
|
+
* **not** equal to null. Because the bare `null` literal is `usize(0)` in AssemblyScript,
|
|
291
|
+
* `usize(0)` will not compare as identical to a `0` of another numeric type.
|
|
282
292
|
*
|
|
283
293
|
* @throws When comparing float/integer types where the float's mantissa cannot losslessly
|
|
284
294
|
* represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
|
|
285
295
|
* @throws When comparing fundamentally incompatible types: reference vs value type
|
|
286
|
-
* (e.g. `string` vs `i32`, unless one is null
|
|
296
|
+
* (e.g. `string` vs `i32`, unless one side is null, or `v128` vs non-vector type).
|
|
287
297
|
* @throws When comparing containers with incompatible element types (e.g. `Array<string>`
|
|
288
298
|
* vs `Array<i32>`), or precision-loss numeric combinations (e.g. `Array<f32>` vs `Array<i32>`).
|
|
289
299
|
*
|
package/assembly/utils.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export function isNull<T>(value: T): bool {
|
|
2
2
|
if (isReference<T>()) {
|
|
3
3
|
if (isNullable<T>()) {
|
|
4
|
-
|
|
4
|
+
// Use changetype pointer checks instead of `== null` / `!= null` to avoid
|
|
5
|
+
// invoking user-defined @operator("==") overloads, which reject null arguments
|
|
6
|
+
return changetype<usize>(value) == 0;
|
|
5
7
|
} else {
|
|
6
8
|
return false;
|
|
7
9
|
}
|
|
@@ -11,6 +13,7 @@ export function isNull<T>(value: T): bool {
|
|
|
11
13
|
} else if (isVector<T>()) {
|
|
12
14
|
return false;
|
|
13
15
|
} else {
|
|
16
|
+
// handles bare nulls
|
|
14
17
|
return nameof<T>(value) == 'usize' && value == 0;
|
|
15
18
|
}
|
|
16
19
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitest-pool-assemblyscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "AssemblyScript testing with Vitest - Simple, fast, familiar, AS-native, with full coverage output",
|
|
5
5
|
"author": "Matt Ritter <matthew.d.ritter@gmail.com>",
|
|
6
6
|
"license": "MIT",
|