summaryrefslogtreecommitdiffstats
path: root/vendor/wasm-bindgen/tests/wasm/classes.js
blob: bcb61e054020ab4eebe3ce05dca94eb3d97c4e98 (plain)
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
const wasm = require('wasm-bindgen-test.js');
const assert = require('assert');

exports.js_simple = () => {
    const r = new wasm.ClassesSimple();
    assert.strictEqual(r.add(0), 0);
    assert.strictEqual(r.add(1), 1);
    assert.strictEqual(r.add(1), 2);
    r.add(2);
    assert.strictEqual(r.consume(), 4);
    assert.throws(() => r.free(), /null pointer passed to rust/);

    const r2 = wasm.ClassesSimple.with_contents(10);
    assert.strictEqual(r2.add(1), 11);
    assert.strictEqual(r2.add(2), 13);
    assert.strictEqual(r2.add(3), 16);
    r2.free();

    const r3 = new wasm.ClassesSimple();
    assert.strictEqual(r3.add(42), 42);
    r3.free();
};

exports.js_strings = () => {
    const r = wasm.ClassesStrings1.new();
    r.set(3);
    let bar = r.bar('baz');
    r.free();
    assert.strictEqual(bar.name(), 'foo-baz-3');
    bar.free();
};

exports.js_exceptions = () => {
    // this test only works when `--debug` is passed to `wasm-bindgen` (or the
    // equivalent thereof)
    if (require('process').env.WASM_BINDGEN_NO_DEBUG)
        return;
    assert.throws(() => new wasm.ClassesExceptions1(), /cannot invoke `new` directly/);
    let a = wasm.ClassesExceptions1.new();
    a.free();
    assert.throws(() => a.free(), /null pointer passed to rust/);

    let b = wasm.ClassesExceptions1.new();
    b.foo(b);
    assert.throws(() => b.bar(b), /recursive use of an object/);
    // TODO: throws because it tries to borrow_mut, but the throw_str from the previous line doesn't clean up the
    // RefMut so the object is left in a broken state.
    // We still try to call free here so the object is removed from the FinalizationRegistry when weak refs are enabled.
    assert.throws(() => b.free(), /recursive use of an object/);

    let c = wasm.ClassesExceptions1.new();
    let d = wasm.ClassesExceptions2.new();
    assert.throws(() => c.foo(d), /expected instance of ClassesExceptions1/);
    d.free();
    c.free();
};

exports.js_pass_one_to_another = () => {
    let a = wasm.ClassesPassA.new();
    let b = wasm.ClassesPassB.new();
    a.foo(b);
    a.bar(b);
    a.free();
};

exports.take_class = foo => {
    assert.strictEqual(foo.inner(), 13);
    foo.free();
    assert.throws(() => foo.free(), /null pointer passed to rust/);
};

exports.js_constructors = () => {
    const foo = new wasm.ConstructorsFoo(1);
    assert.strictEqual(foo.get_number(), 1);
    foo.free();

    assert.strictEqual(wasm.ConstructorsBar.new, undefined);
    const foo2 = new wasm.ConstructorsFoo(2);
    assert.strictEqual(foo2.get_number(), 2);
    foo2.free();

    const bar = new wasm.ConstructorsBar(3, 4);
    assert.strictEqual(bar.get_sum(), 7);
    bar.free();

    assert.strictEqual(wasm.ConstructorsBar.other_name, undefined);
    const bar2 = new wasm.ConstructorsBar(5, 6);
    assert.strictEqual(bar2.get_sum(), 11);
    bar2.free();

    assert.strictEqual(wasm.cross_item_construction().get_sum(), 15);
};

exports.js_empty_structs = () => {
    wasm.OtherEmpty.return_a_value();
};

exports.js_public_fields = () => {
    const a = wasm.PublicFields.new();
    assert.strictEqual(a.a, 0);
    a.a = 3;
    assert.strictEqual(a.a, 3);

    assert.strictEqual(a.b, 0);
    a.b = 7;
    assert.strictEqual(a.b, 7);

    assert.strictEqual(a.c, 0);
    a.c = 8;
    assert.strictEqual(a.c, 8);

    assert.strictEqual(a.d, 0);
    a.d = 3.3;
    assert.strictEqual(a.d, 3);

    assert.strictEqual(a.skipped, undefined);
};

exports.js_getter_with_clone = () => {
    const a = wasm.GetterWithCloneStruct.new();
    assert.strictEqual(a.a, '');
    a.a = 'foo';
    assert.strictEqual(a.a, 'foo');

    const b = wasm.GetterWithCloneStructField.new();
    assert.strictEqual(b.a, '');
    b.a = 'foo';
    assert.strictEqual(b.a, 'foo');
};

exports.js_using_self = () => {
    wasm.UseSelf.new().free();
};

exports.js_readonly_fields = () => {
    const a = wasm.Readonly.new();
    assert.strictEqual(a.a, 0);
    a.a = 3;
    assert.strictEqual(a.a, 0);
    a.free();
};

exports.js_double_consume = () => {
    const r = new wasm.DoubleConsume();
    assert.throws(() => r.consume(r));
};


exports.js_js_rename = () => {
    (new wasm.JsRename()).bar();
    wasm.classes_foo();
};

exports.js_access_fields = () => {
    assert.ok((new wasm.AccessFieldFoo()).bar instanceof wasm.AccessFieldBar);
    assert.ok((new wasm.AccessField0())[0] instanceof wasm.AccessFieldBar);
};

exports.js_renamed_export = () => {
    const x = new wasm.JsRenamedExport();
    assert.ok(x.x === 3);
    x.foo();
    x.bar(x);
};

exports.js_renamed_field = () => {
    const x = new wasm.RenamedField();
    assert.ok(x.bar === 3);

    x.foo();
}

exports.js_conditional_bindings = () => {
    const x = new wasm.ConditionalBindings();
    x.free();
};

exports.js_assert_none = x => {
  assert.strictEqual(x, undefined);
};
exports.js_assert_some = x => {
  assert.ok(x instanceof wasm.OptionClass);
};
exports.js_return_none1 = () => null;
exports.js_return_none2 = () => undefined;
exports.js_return_some = x => x;

exports.js_test_option_classes = () => {
  assert.strictEqual(wasm.option_class_none(), undefined);
  wasm.option_class_assert_none(undefined);
  wasm.option_class_assert_none(null);
  const c = wasm.option_class_some();
  assert.ok(c instanceof wasm.OptionClass);
  wasm.option_class_assert_some(c);
};

/**
 * Invokes `console.log`, but logs to a string rather than stdout
 * @param {any} data Data to pass to `console.log`
 * @returns {string} Output from `console.log`, without color or trailing newlines
 */
const console_log_to_string = data => {
    // Store the original stdout.write and create a console that logs without color
    const original_write = process.stdout.write;
    const colorless_console = new console.Console({
      stdout: process.stdout,
      colorMode: false
    });
    let output = '';

    // Change stdout.write to append to our string, then restore the original function
    process.stdout.write = chunk => output += chunk.trim();
    colorless_console.log(data);
    process.stdout.write = original_write;

    return output;
};

exports.js_test_inspectable_classes = () => {
    const inspectable = wasm.Inspectable.new();
    const not_inspectable = wasm.NotInspectable.new();
    // Inspectable classes have a toJSON and toString implementation generated
    assert.deepStrictEqual(inspectable.toJSON(), { a: inspectable.a });
    assert.strictEqual(inspectable.toString(), `{"a":${inspectable.a}}`);
    // Inspectable classes in Node.js have improved console.log formatting as well
    assert(console_log_to_string(inspectable).endsWith(`{ a: ${inspectable.a} }`));
    // Non-inspectable classes do not have a toJSON or toString generated
    assert.strictEqual(not_inspectable.toJSON, undefined);
    assert.strictEqual(not_inspectable.toString(), '[object Object]');
    // Non-inspectable classes in Node.js have no special console.log formatting
    assert.strictEqual(console_log_to_string(not_inspectable), `NotInspectable { ptr: ${not_inspectable.ptr} }`);
    inspectable.free();
    not_inspectable.free();
};

exports.js_test_inspectable_classes_can_override_generated_methods = () => {
    const overridden_inspectable = wasm.OverriddenInspectable.new();
    // Inspectable classes can have the generated toJSON and toString overwritten
    assert.strictEqual(overridden_inspectable.a, 0);
    assert.deepStrictEqual(overridden_inspectable.toJSON(), 'JSON was overwritten');
    assert.strictEqual(overridden_inspectable.toString(), 'string was overwritten');
    overridden_inspectable.free();
};