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