/
asserts.js
165 lines (135 loc) · 3.81 KB
/
asserts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// @flow
import { assert } from "mamacro";
import Long from "@xtuc/long";
function eq(actual: StackLocal, expected: Object) {
// check type
assert(
actual.type === expected.type,
`type mismatch; expected ${expected.type}, given ${actual.type}`
);
// check value
switch (expected.type) {
case "i32": {
const i32Value = Long.fromString(expected.value).toInt();
assert(
actual.value.toString() === i32Value.toString(),
`Expected value ${i32Value}, got ${actual.value.toString()}`
);
break;
}
case "f32": {
const actuali32 = actual.value.reinterpret();
const expectedi32 = Long.fromString(expected.value).toInt();
assert(
actuali32.toNumber() === expectedi32,
`Expected value ${expectedi32}, got ${actuali32.toString()}`
);
break;
}
case "f64": {
const actuali32 = actual.value.reinterpret();
const expectedi32 = Long.fromString(expected.value).toNumber();
assert(
actuali32.toNumber() === expectedi32,
`Expected value ${expectedi32}, got ${actuali32.toString()}`
);
break;
}
case "i64": {
console.warn("eq with i64 is unsupported");
// const actuali64 = actual.value.toString();
// const expectedi64 = Long.fromString(expected.value)
// .toSigned()
// .toString();
// FIXME(sven): fix this
// assert(
// actuali64 === expectedi64,
// `Expected value ${expectedi64}, got ${actuali64}`
// );
break;
}
default:
throw new Error("Unsupport eq with type: " + expected.type);
}
}
// assert action has expected results
// ( assert_return <action> <expr>* )
//
export function assert_return(element: any, action: Object, expected: Object) {
const { type, args } = action;
assert(type === "invoke" || type === "get", `unsupported type "${type}"`);
if (type === "get") {
if (expected.length > 0) {
eq(element, expected[0]);
}
}
if (type === "invoke") {
const compatibleArgs = args.map(x => {
if (x.type === "i64") {
return new Long.fromString(x.value);
}
return x.value;
});
const res = element(...compatibleArgs);
if (expected.length > 0) {
eq(res, expected[0]);
}
}
}
// ;; assert module cannot be decoded with given failure string
// ( assert_malformed <module> <failure> )
//
export function assert_malformed(
getInstance: () => Instance,
expected: string
) {
try {
getInstance();
assert(false, "did not throw any error");
} catch (e) {
assert(
e.message.match(new RegExp(expected, "gm")),
`Expected error "${expected}", got "${e.message}"`
);
}
}
// assert module is invalid with given failure string
// ( assert_invalid <module> <failure> )
//
export function assert_invalid(getInstance: () => Instance, expected: string) {
if (expected === "type mismatch") {
expected = "Expected type|Stack contains additional type";
}
try {
getInstance();
assert(false, "did not throw any error");
} catch (e) {
assert(
e.message.match(new RegExp(expected, "gm")),
`Expected error "${expected}", got "${e.message}"`
);
}
}
// assert module traps on instantiation
// ( assert_trap <module> <failure> )
//
export function assert_trap(element: any, action: Object, expected: string) {
const { type, args } = action;
assert(type === "invoke", `unsupported type "${type}"`);
if (type === "invoke") {
const compatibleArgs = args.map(x => {
if (x.type === "i64") {
return new Long.fromString(x.value);
}
return x.value;
});
try {
element(...compatibleArgs);
} catch (e) {
assert(
e.message.match(new RegExp(expected, "gm")),
`Expected error "${expected}", got "${e.message}"`
);
}
}
}