1 #[allow(unused_imports)] // test for #919
2 use std::borrow::BorrowMut;
3 
4 use wasm_bindgen::prelude::*;
5 use wasm_bindgen_test::*;
6 
7 #[wasm_bindgen(module = "tests/wasm/classes.js")]
8 extern "C" {
9     fn js_simple();
10     fn js_strings();
11     fn js_exceptions();
12     fn js_pass_one_to_another();
13     fn take_class(foo: ClassesIntoJs);
14     #[wasm_bindgen(js_name = take_class)]
15     fn take_class_as_jsvalue(foo: JsValue);
16     fn js_constructors();
17     fn js_empty_structs();
18     fn js_public_fields();
19     fn js_getter_with_clone();
20     fn js_using_self();
21     fn js_readonly_fields();
22     fn js_double_consume();
23     fn js_js_rename();
24     fn js_access_fields();
25     fn js_renamed_export();
26     fn js_renamed_field();
27     fn js_conditional_bindings();
28 
29     fn js_assert_none(a: Option<OptionClass>);
30     fn js_assert_some(a: Option<OptionClass>);
31     fn js_return_none1() -> Option<OptionClass>;
32     fn js_return_none2() -> Option<OptionClass>;
33     fn js_return_some(a: OptionClass) -> Option<OptionClass>;
34     fn js_test_option_classes();
35     fn js_test_inspectable_classes();
36     fn js_test_inspectable_classes_can_override_generated_methods();
37 }
38 
39 #[wasm_bindgen_test]
40 fn simple() {
41     js_simple();
42 }
43 
44 #[wasm_bindgen]
45 pub struct ClassesSimple {
46     contents: u32,
47 }
48 
49 #[wasm_bindgen]
50 impl ClassesSimple {
51     #[wasm_bindgen(constructor)]
52     pub fn new() -> ClassesSimple {
53         ClassesSimple::with_contents(0)
54     }
55 
56     pub fn with_contents(a: u32) -> ClassesSimple {
57         ClassesSimple { contents: a }
58     }
59 
60     pub fn add(&mut self, amt: u32) -> u32 {
61         self.contents += amt;
62         self.contents
63     }
64 
65     pub fn consume(self) -> u32 {
66         self.contents
67     }
68 }
69 
70 #[wasm_bindgen_test]
71 fn strings() {
72     js_strings()
73 }
74 
75 #[wasm_bindgen]
76 pub struct ClassesStrings1 {
77     name: u32,
78 }
79 
80 #[wasm_bindgen]
81 pub struct ClassesStrings2 {
82     contents: String,
83 }
84 
85 #[wasm_bindgen]
86 impl ClassesStrings1 {
87     pub fn new() -> ClassesStrings1 {
88         ClassesStrings1 { name: 0 }
89     }
90 
91     pub fn set(&mut self, amt: u32) {
92         self.name = amt;
93     }
94 
95     pub fn bar(&self, mix: &str) -> ClassesStrings2 {
96         ClassesStrings2 {
97             contents: format!("foo-{}-{}", mix, self.name),
98         }
99     }
100 }
101 
102 #[wasm_bindgen]
103 impl ClassesStrings2 {
104     pub fn name(&self) -> String {
105         self.contents.clone()
106     }
107 }
108 
109 #[wasm_bindgen_test]
110 fn exceptions() {
111     js_exceptions();
112 }
113 
114 #[wasm_bindgen]
115 pub struct ClassesExceptions1 {}
116 
117 #[wasm_bindgen]
118 impl ClassesExceptions1 {
119     pub fn new() -> ClassesExceptions1 {
120         ClassesExceptions1 {}
121     }
122 
123     pub fn foo(&self, _: &ClassesExceptions1) {}
124 
125     pub fn bar(&mut self, _: &mut ClassesExceptions1) {}
126 }
127 
128 #[wasm_bindgen]
129 pub struct ClassesExceptions2 {}
130 
131 #[wasm_bindgen]
132 impl ClassesExceptions2 {
133     pub fn new() -> ClassesExceptions2 {
134         ClassesExceptions2 {}
135     }
136 }
137 
138 #[wasm_bindgen_test]
139 fn pass_one_to_another() {
140     js_pass_one_to_another();
141 }
142 
143 #[wasm_bindgen]
144 pub struct ClassesPassA {}
145 
146 #[wasm_bindgen]
147 impl ClassesPassA {
148     pub fn new() -> ClassesPassA {
149         ClassesPassA {}
150     }
151 
152     pub fn foo(&self, _other: &ClassesPassB) {}
153 
154     pub fn bar(&self, _other: ClassesPassB) {}
155 }
156 
157 #[wasm_bindgen]
158 pub struct ClassesPassB {}
159 
160 #[wasm_bindgen]
161 impl ClassesPassB {
162     pub fn new() -> ClassesPassB {
163         ClassesPassB {}
164     }
165 }
166 
167 #[wasm_bindgen_test]
168 fn pass_into_js() {
169     take_class(ClassesIntoJs(13));
170 }
171 
172 #[wasm_bindgen]
173 pub struct ClassesIntoJs(i32);
174 
175 #[wasm_bindgen]
176 impl ClassesIntoJs {
177     pub fn inner(&self) -> i32 {
178         self.0
179     }
180 }
181 
182 #[wasm_bindgen]
183 pub struct Issue27Context {}
184 
185 #[wasm_bindgen]
186 impl Issue27Context {
187     pub fn parse(&self, _expr: &str) -> Issue27Expr {
188         panic!()
189     }
190     pub fn eval(&self, _expr: &Issue27Expr) -> f64 {
191         panic!()
192     }
193     pub fn set(&mut self, _var: &str, _val: f64) {
194         panic!()
195     }
196 }
197 
198 #[wasm_bindgen]
199 pub struct Issue27Expr {}
200 
201 #[wasm_bindgen_test]
202 fn pass_into_js_as_js_class() {
203     take_class_as_jsvalue(ClassesIntoJs(13).into());
204 }
205 
206 #[wasm_bindgen_test]
207 fn constructors() {
208     js_constructors();
209 }
210 
211 #[wasm_bindgen]
212 pub fn cross_item_construction() -> ConstructorsBar {
213     ConstructorsBar::other_name(7, 8)
214 }
215 
216 #[wasm_bindgen]
217 pub struct ConstructorsFoo {
218     number: u32,
219 }
220 
221 #[wasm_bindgen]
222 impl ConstructorsFoo {
223     #[wasm_bindgen(constructor)]
224     pub fn new(number: u32) -> ConstructorsFoo {
225         ConstructorsFoo { number }
226     }
227 
228     pub fn get_number(&self) -> u32 {
229         self.number
230     }
231 }
232 
233 #[wasm_bindgen]
234 pub struct ConstructorsBar {
235     number: u32,
236     number2: u32,
237 }
238 
239 #[wasm_bindgen]
240 impl ConstructorsBar {
241     #[wasm_bindgen(constructor)]
242     pub fn other_name(number: u32, number2: u32) -> ConstructorsBar {
243         ConstructorsBar { number, number2 }
244     }
245 
246     pub fn get_sum(&self) -> u32 {
247         self.number + self.number2
248     }
249 }
250 
251 #[wasm_bindgen_test]
252 fn empty_structs() {
253     js_empty_structs();
254 }
255 
256 #[wasm_bindgen]
257 pub struct MissingClass {}
258 
259 #[wasm_bindgen]
260 pub struct OtherEmpty {}
261 
262 #[wasm_bindgen]
263 impl OtherEmpty {
264     pub fn return_a_value() -> MissingClass {
265         MissingClass {}
266     }
267 }
268 
269 #[wasm_bindgen_test]
270 fn public_fields() {
271     js_public_fields();
272 }
273 
274 #[wasm_bindgen]
275 #[derive(Default)]
276 pub struct PublicFields {
277     pub a: u32,
278     pub b: f32,
279     pub c: f64,
280     pub d: i32,
281     #[wasm_bindgen(skip)]
282     pub skipped: u32,
283 }
284 
285 #[wasm_bindgen]
286 impl PublicFields {
287     pub fn new() -> PublicFields {
288         PublicFields::default()
289     }
290 }
291 
292 #[wasm_bindgen_test]
293 fn getter_with_clone() {
294     js_getter_with_clone();
295 }
296 
297 #[wasm_bindgen(getter_with_clone)]
298 #[derive(Default)]
299 pub struct GetterWithCloneStruct {
300     pub a: String,
301 }
302 
303 #[wasm_bindgen]
304 impl GetterWithCloneStruct {
305     pub fn new() -> GetterWithCloneStruct {
306         GetterWithCloneStruct::default()
307     }
308 }
309 
310 #[wasm_bindgen]
311 #[derive(Default)]
312 pub struct GetterWithCloneStructField {
313     #[wasm_bindgen(getter_with_clone)]
314     pub a: String,
315 }
316 
317 #[wasm_bindgen]
318 impl GetterWithCloneStructField {
319     pub fn new() -> GetterWithCloneStructField {
320         GetterWithCloneStructField::default()
321     }
322 }
323 
324 #[wasm_bindgen_test]
325 fn using_self() {
326     js_using_self();
327 }
328 
329 #[wasm_bindgen]
330 pub struct UseSelf {}
331 
332 #[wasm_bindgen]
333 impl UseSelf {
334     pub fn new() -> Self {
335         UseSelf {}
336     }
337 }
338 
339 #[wasm_bindgen_test]
340 fn readonly_fields() {
341     js_readonly_fields();
342 }
343 
344 #[wasm_bindgen]
345 #[derive(Default)]
346 pub struct Readonly {
347     #[wasm_bindgen(readonly)]
348     pub a: u32,
349 }
350 
351 #[wasm_bindgen]
352 impl Readonly {
353     pub fn new() -> Readonly {
354         Readonly::default()
355     }
356 }
357 
358 #[wasm_bindgen_test]
359 fn double_consume() {
360     js_double_consume();
361 }
362 
363 #[wasm_bindgen]
364 pub struct DoubleConsume {}
365 
366 #[wasm_bindgen]
367 impl DoubleConsume {
368     #[wasm_bindgen(constructor)]
369     pub fn new() -> DoubleConsume {
370         DoubleConsume {}
371     }
372 
373     pub fn consume(self, other: DoubleConsume) {
374         drop(other);
375     }
376 }
377 
378 #[wasm_bindgen_test]
379 fn rename_function_for_js() {
380     js_js_rename();
381     foo();
382 }
383 
384 #[wasm_bindgen]
385 pub struct JsRename {}
386 
387 #[wasm_bindgen]
388 impl JsRename {
389     #[wasm_bindgen(constructor)]
390     pub fn new() -> JsRename {
391         let f = JsRename {};
392         f.foo();
393         f
394     }
395 
396     #[wasm_bindgen(js_name = bar)]
397     pub fn foo(&self) {}
398 }
399 
400 #[wasm_bindgen(js_name = classes_foo)]
401 pub fn foo() {}
402 
403 #[wasm_bindgen]
404 pub struct AccessFieldFoo {
405     pub bar: AccessFieldBar,
406 }
407 
408 #[wasm_bindgen]
409 pub struct AccessField0(pub AccessFieldBar);
410 
411 #[wasm_bindgen]
412 #[derive(Copy, Clone)]
413 pub struct AccessFieldBar {
414     _value: u32,
415 }
416 
417 #[wasm_bindgen]
418 impl AccessFieldFoo {
419     #[wasm_bindgen(constructor)]
420     pub fn new() -> AccessFieldFoo {
421         AccessFieldFoo {
422             bar: AccessFieldBar { _value: 2 },
423         }
424     }
425 }
426 
427 #[wasm_bindgen]
428 impl AccessField0 {
429     #[wasm_bindgen(constructor)]
430     pub fn new() -> AccessField0 {
431         AccessField0(AccessFieldBar { _value: 2 })
432     }
433 }
434 
435 #[wasm_bindgen_test]
436 fn access_fields() {
437     js_access_fields();
438 }
439 
440 #[wasm_bindgen(js_name = JsRenamedExport)]
441 pub struct RenamedExport {
442     pub x: u32,
443 }
444 
445 #[wasm_bindgen(js_class = JsRenamedExport)]
446 impl RenamedExport {
447     #[wasm_bindgen(constructor)]
448     pub fn new() -> RenamedExport {
449         RenamedExport { x: 3 }
450     }
451     pub fn foo(&self) {}
452 
453     pub fn bar(&self, other: &RenamedExport) {
454         drop(other);
455     }
456 }
457 
458 #[wasm_bindgen_test]
459 fn renamed_export() {
460     js_renamed_export();
461 }
462 
463 #[wasm_bindgen]
464 pub struct RenamedField {
465     #[wasm_bindgen(js_name = bar)]
466     pub foo: u32,
467 }
468 
469 #[wasm_bindgen(js_class = RenamedField)]
470 impl RenamedField {
471     #[wasm_bindgen(constructor)]
472     pub fn new() -> RenamedField {
473         RenamedField { foo: 3 }
474     }
475 
476     pub fn foo(&self) {}
477 }
478 
479 #[wasm_bindgen_test]
480 fn renamed_field() {
481     js_renamed_field();
482 }
483 
484 #[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
485 pub struct ConditionalBindings {}
486 
487 #[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
488 impl ConditionalBindings {
489     #[cfg_attr(target_arch = "wasm32", wasm_bindgen(constructor))]
490     pub fn new() -> ConditionalBindings {
491         ConditionalBindings {}
492     }
493 }
494 
495 #[wasm_bindgen_test]
496 fn conditional_bindings() {
497     js_conditional_bindings();
498 }
499 
500 #[wasm_bindgen]
501 pub struct OptionClass(u32);
502 
503 #[wasm_bindgen_test]
504 fn option_class() {
505     js_assert_none(None);
506     js_assert_some(Some(OptionClass(1)));
507     assert!(js_return_none1().is_none());
508     assert!(js_return_none2().is_none());
509     assert_eq!(js_return_some(OptionClass(2)).unwrap().0, 2);
510     js_test_option_classes();
511 }
512 
513 #[wasm_bindgen]
514 pub fn option_class_none() -> Option<OptionClass> {
515     None
516 }
517 
518 #[wasm_bindgen]
519 pub fn option_class_some() -> Option<OptionClass> {
520     Some(OptionClass(3))
521 }
522 
523 #[wasm_bindgen]
524 pub fn option_class_assert_none(x: Option<OptionClass>) {
525     assert!(x.is_none());
526 }
527 
528 #[wasm_bindgen]
529 pub fn option_class_assert_some(x: Option<OptionClass>) {
530     assert_eq!(x.unwrap().0, 3);
531 }
532 
533 mod works_in_module {
534     use wasm_bindgen::prelude::wasm_bindgen;
535 
536     #[wasm_bindgen]
537     pub struct WorksInModule(u32);
538 
539     #[wasm_bindgen]
540     impl WorksInModule {
541         #[wasm_bindgen(constructor)]
542         pub fn new() -> WorksInModule {
543             WorksInModule(1)
544         }
545 
546         pub fn foo(&self) {}
547     }
548 }
549 
550 #[wasm_bindgen_test]
551 fn inspectable_classes() {
552     js_test_inspectable_classes();
553 }
554 
555 #[wasm_bindgen(inspectable)]
556 #[derive(Default)]
557 pub struct Inspectable {
558     pub a: u32,
559     // This private field will not be exposed unless a getter is provided for it
560     #[allow(dead_code)]
561     private: u32,
562 }
563 
564 #[wasm_bindgen]
565 impl Inspectable {
566     pub fn new() -> Self {
567         Self::default()
568     }
569 }
570 
571 #[wasm_bindgen]
572 #[derive(Default)]
573 pub struct NotInspectable {
574     pub a: u32,
575 }
576 
577 #[wasm_bindgen]
578 impl NotInspectable {
579     pub fn new() -> Self {
580         Self::default()
581     }
582 }
583 
584 #[wasm_bindgen_test]
585 fn inspectable_classes_can_override_generated_methods() {
586     js_test_inspectable_classes_can_override_generated_methods();
587 }
588 
589 #[wasm_bindgen(inspectable)]
590 #[derive(Default)]
591 pub struct OverriddenInspectable {
592     pub a: u32,
593 }
594 
595 #[wasm_bindgen]
596 impl OverriddenInspectable {
597     pub fn new() -> Self {
598         Self::default()
599     }
600 
601     #[wasm_bindgen(js_name = toJSON)]
602     pub fn to_json(&self) -> String {
603         String::from("JSON was overwritten")
604     }
605 
606     #[wasm_bindgen(js_name = toString)]
607     pub fn to_string(&self) -> String {
608         String::from("string was overwritten")
609     }
610 }
611