Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / compiler-core / src / metadata / tests.rs
65 kB 1996 lines
1use hexpm::version::Version; 2use rand::Rng; 3use type_::{AccessorsMap, FieldMap, RecordAccessor}; 4 5use super::*; 6use crate::{ 7 ast::{ 8 BitArrayOption, BitArraySegment, CallArg, Constant, Publicity, SrcSpan, TypedConstant, 9 TypedConstantBitArraySegmentOption, 10 }, 11 build::Origin, 12 line_numbers::LineNumbers, 13 parse::LiteralFloatValue, 14 reference::{Reference, ReferenceKind}, 15 type_::{ 16 self, Deprecation, ModuleInterface, Opaque, References, Type, TypeAliasConstructor, 17 TypeConstructor, TypeValueConstructor, TypeValueConstructorField, TypeVariantConstructors, 18 ValueConstructor, ValueConstructorVariant, 19 expression::{Implementations, Purity}, 20 prelude, 21 }, 22 uid::UniqueIdGenerator, 23}; 24use std::{collections::HashMap, io::BufReader, sync::Arc}; 25 26use pretty_assertions::assert_eq; 27 28fn roundtrip(input: &ModuleInterface) -> ModuleInterface { 29 let buffer = ModuleEncoder::new(input).encode().unwrap(); 30 let ids = UniqueIdGenerator::new(); 31 ModuleDecoder::new(ids) 32 .read(BufReader::new(buffer.as_slice())) 33 .unwrap() 34} 35 36fn constant_module(constant: TypedConstant) -> ModuleInterface { 37 ModuleInterface { 38 warnings: vec![], 39 is_internal: true, 40 package: "some_package".into(), 41 origin: Origin::Src, 42 name: "a".into(), 43 types: HashMap::new(), 44 types_value_constructors: HashMap::new(), 45 accessors: HashMap::new(), 46 values: [( 47 "one".into(), 48 ValueConstructor { 49 publicity: Publicity::Public, 50 deprecation: Deprecation::NotDeprecated, 51 type_: type_::int(), 52 variant: ValueConstructorVariant::ModuleConstant { 53 documentation: Some("Some documentation".into()), 54 literal: constant, 55 location: SrcSpan::default(), 56 module: "one/two".into(), 57 implementations: Implementations { 58 gleam: true, 59 uses_erlang_externals: false, 60 uses_javascript_externals: false, 61 can_run_on_erlang: true, 62 can_run_on_javascript: true, 63 }, 64 name: "one".into(), 65 }, 66 }, 67 )] 68 .into(), 69 line_numbers: LineNumbers::new(""), 70 src_path: "some_path".into(), 71 minimum_required_version: Version::new(0, 1, 0), 72 type_aliases: HashMap::new(), 73 documentation: Vec::new(), 74 contains_echo: false, 75 76 references: References::default(), 77 inline_functions: HashMap::new(), 78 } 79} 80 81fn bit_array_segment_option_module(option: TypedConstantBitArraySegmentOption) -> ModuleInterface { 82 constant_module(Constant::BitArray { 83 location: Default::default(), 84 segments: vec![BitArraySegment { 85 location: Default::default(), 86 value: Box::new(Constant::Int { 87 location: Default::default(), 88 value: "1".into(), 89 int_value: 1.into(), 90 }), 91 options: vec![option], 92 type_: type_::int(), 93 }], 94 }) 95} 96 97#[test] 98fn empty_module() { 99 let module = ModuleInterface { 100 warnings: vec![], 101 is_internal: true, 102 package: "some_package".into(), 103 origin: Origin::Src, 104 name: "one/two".into(), 105 types: HashMap::new(), 106 types_value_constructors: HashMap::new(), 107 values: HashMap::new(), 108 accessors: HashMap::new(), 109 line_numbers: LineNumbers::new(""), 110 src_path: "some_path".into(), 111 minimum_required_version: Version::new(0, 1, 0), 112 type_aliases: HashMap::new(), 113 documentation: Vec::new(), 114 contains_echo: false, 115 116 references: References::default(), 117 inline_functions: HashMap::new(), 118 }; 119 assert_eq!(roundtrip(&module), module); 120} 121 122#[test] 123fn with_line_numbers() { 124 let module = ModuleInterface { 125 warnings: vec![], 126 is_internal: false, 127 package: "some_package".into(), 128 origin: Origin::Src, 129 name: "one/two".into(), 130 types: HashMap::new(), 131 types_value_constructors: HashMap::new(), 132 values: HashMap::new(), 133 accessors: HashMap::new(), 134 line_numbers: LineNumbers::new( 135 "const a = 1 136 const b = 2 137 const c = 3", 138 ), 139 src_path: "some_path".into(), 140 minimum_required_version: Version::new(0, 1, 0), 141 type_aliases: HashMap::new(), 142 documentation: Vec::new(), 143 contains_echo: false, 144 145 references: References::default(), 146 inline_functions: HashMap::new(), 147 }; 148 assert_eq!(roundtrip(&module), module); 149} 150 151#[test] 152fn module_with_private_type() { 153 let module = ModuleInterface { 154 warnings: vec![], 155 is_internal: false, 156 package: "some_package".into(), 157 origin: Origin::Src, 158 name: "a/b".into(), 159 types: [( 160 "ListIntType".into(), 161 TypeConstructor { 162 type_: type_::list(type_::int()), 163 publicity: Publicity::Private, 164 origin: Default::default(), 165 module: "the/module".into(), 166 parameters: vec![], 167 deprecation: Deprecation::NotDeprecated, 168 documentation: None, 169 }, 170 )] 171 .into(), 172 types_value_constructors: HashMap::new(), 173 values: HashMap::new(), 174 accessors: HashMap::new(), 175 line_numbers: LineNumbers::new(""), 176 src_path: "some_path".into(), 177 minimum_required_version: Version::new(0, 1, 0), 178 type_aliases: HashMap::new(), 179 documentation: Vec::new(), 180 contains_echo: false, 181 182 references: References::default(), 183 inline_functions: HashMap::new(), 184 }; 185 assert_eq!(roundtrip(&module), module); 186} 187 188#[test] 189fn module_with_app_type() { 190 let module = ModuleInterface { 191 warnings: vec![], 192 is_internal: false, 193 package: "some_package".into(), 194 origin: Origin::Src, 195 name: "a/b".into(), 196 types: [( 197 "ListIntType".into(), 198 TypeConstructor { 199 type_: type_::list(type_::int()), 200 publicity: Publicity::Public, 201 origin: Default::default(), 202 module: "the/module".into(), 203 parameters: vec![], 204 deprecation: Deprecation::NotDeprecated, 205 documentation: None, 206 }, 207 )] 208 .into(), 209 types_value_constructors: HashMap::new(), 210 values: HashMap::new(), 211 accessors: HashMap::new(), 212 line_numbers: LineNumbers::new(""), 213 src_path: "some_path".into(), 214 minimum_required_version: Version::new(0, 1, 0), 215 type_aliases: HashMap::new(), 216 documentation: Vec::new(), 217 contains_echo: false, 218 219 references: References::default(), 220 inline_functions: HashMap::new(), 221 }; 222 assert_eq!(roundtrip(&module), module); 223} 224 225#[test] 226fn module_with_fn_type() { 227 let module = ModuleInterface { 228 warnings: vec![], 229 is_internal: false, 230 package: "some_package".into(), 231 origin: Origin::Src, 232 name: "a/b".into(), 233 types: [( 234 "FnType".into(), 235 TypeConstructor { 236 type_: type_::fn_(vec![type_::nil(), type_::float()], type_::int()), 237 publicity: Publicity::Public, 238 origin: Default::default(), 239 module: "the/module".into(), 240 parameters: vec![], 241 deprecation: Deprecation::NotDeprecated, 242 documentation: None, 243 }, 244 )] 245 .into(), 246 types_value_constructors: HashMap::new(), 247 values: HashMap::new(), 248 accessors: HashMap::new(), 249 line_numbers: LineNumbers::new(""), 250 src_path: "some_path".into(), 251 minimum_required_version: Version::new(0, 1, 0), 252 type_aliases: HashMap::new(), 253 documentation: Vec::new(), 254 contains_echo: false, 255 256 references: References::default(), 257 inline_functions: HashMap::new(), 258 }; 259 assert_eq!(roundtrip(&module), module); 260} 261 262#[test] 263fn module_with_tuple_type() { 264 let module = ModuleInterface { 265 warnings: vec![], 266 is_internal: false, 267 package: "some_package".into(), 268 origin: Origin::Src, 269 name: "a/b".into(), 270 types: [( 271 "TupleType".into(), 272 TypeConstructor { 273 type_: type_::tuple(vec![type_::nil(), type_::float(), type_::int()]), 274 publicity: Publicity::Public, 275 origin: Default::default(), 276 module: "the/module".into(), 277 parameters: vec![], 278 deprecation: Deprecation::NotDeprecated, 279 documentation: None, 280 }, 281 )] 282 .into(), 283 types_value_constructors: HashMap::new(), 284 values: HashMap::new(), 285 accessors: HashMap::new(), 286 line_numbers: LineNumbers::new(""), 287 src_path: "some_path".into(), 288 minimum_required_version: Version::new(0, 1, 0), 289 type_aliases: HashMap::new(), 290 documentation: Vec::new(), 291 contains_echo: false, 292 293 references: References::default(), 294 inline_functions: HashMap::new(), 295 }; 296 assert_eq!(roundtrip(&module), module); 297} 298 299#[test] 300fn module_with_generic_type() { 301 let t0 = type_::generic_var(0); 302 let t1 = type_::generic_var(1); 303 let t7 = type_::generic_var(7); 304 let t8 = type_::generic_var(8); 305 306 fn make(t1: Arc<Type>, t2: Arc<Type>) -> ModuleInterface { 307 ModuleInterface { 308 warnings: vec![], 309 is_internal: false, 310 package: "some_package".into(), 311 origin: Origin::Src, 312 name: "a/b".into(), 313 types: [( 314 "TupleType".into(), 315 TypeConstructor { 316 type_: type_::tuple(vec![t1.clone(), t1.clone(), t2.clone()]), 317 publicity: Publicity::Public, 318 origin: Default::default(), 319 module: "the/module".into(), 320 parameters: vec![t1, t2], 321 deprecation: Deprecation::NotDeprecated, 322 documentation: None, 323 }, 324 )] 325 .into(), 326 types_value_constructors: HashMap::new(), 327 values: HashMap::new(), 328 accessors: HashMap::new(), 329 line_numbers: LineNumbers::new(""), 330 src_path: "some_path".into(), 331 minimum_required_version: Version::new(0, 1, 0), 332 type_aliases: HashMap::new(), 333 documentation: Vec::new(), 334 contains_echo: false, 335 references: References::default(), 336 inline_functions: HashMap::new(), 337 } 338 } 339 340 assert_eq!(roundtrip(&make(t7, t8)), make(t0, t1)); 341} 342 343#[test] 344fn module_with_type_links() { 345 let linked_type = type_::link(type_::int()); 346 let type_ = type_::int(); 347 348 fn make(type_: Arc<Type>) -> ModuleInterface { 349 ModuleInterface { 350 warnings: vec![], 351 is_internal: false, 352 package: "some_package".into(), 353 origin: Origin::Src, 354 name: "a".into(), 355 types: [( 356 "SomeType".into(), 357 TypeConstructor { 358 type_, 359 publicity: Publicity::Public, 360 origin: Default::default(), 361 module: "a".into(), 362 parameters: vec![], 363 deprecation: Deprecation::NotDeprecated, 364 documentation: None, 365 }, 366 )] 367 .into(), 368 types_value_constructors: HashMap::new(), 369 values: HashMap::new(), 370 accessors: HashMap::new(), 371 line_numbers: LineNumbers::new(""), 372 src_path: "some_path".into(), 373 minimum_required_version: Version::new(0, 1, 0), 374 type_aliases: HashMap::new(), 375 documentation: Vec::new(), 376 contains_echo: false, 377 references: References::default(), 378 inline_functions: HashMap::new(), 379 } 380 } 381 382 assert_eq!(roundtrip(&make(linked_type)), make(type_)); 383} 384 385#[test] 386fn module_with_type_constructor_documentation() { 387 let linked_type = type_::link(type_::int()); 388 let type_ = type_::int(); 389 390 fn make(type_: Arc<Type>) -> ModuleInterface { 391 ModuleInterface { 392 warnings: vec![], 393 is_internal: false, 394 package: "some_package".into(), 395 origin: Origin::Src, 396 name: "a".into(), 397 types: [( 398 "SomeType".into(), 399 TypeConstructor { 400 type_, 401 publicity: Publicity::Public, 402 origin: Default::default(), 403 module: "a".into(), 404 parameters: vec![], 405 deprecation: Deprecation::NotDeprecated, 406 documentation: Some("type documentation".into()), 407 }, 408 )] 409 .into(), 410 types_value_constructors: HashMap::new(), 411 values: HashMap::new(), 412 accessors: HashMap::new(), 413 line_numbers: LineNumbers::new(""), 414 src_path: "some_path".into(), 415 minimum_required_version: Version::new(0, 1, 0), 416 type_aliases: HashMap::new(), 417 documentation: Vec::new(), 418 contains_echo: false, 419 references: References::default(), 420 inline_functions: HashMap::new(), 421 } 422 } 423 424 assert_eq!(roundtrip(&make(linked_type)), make(type_)); 425} 426 427#[test] 428fn module_with_type_constructor_origin() { 429 let linked_type = type_::link(type_::int()); 430 let type_ = type_::int(); 431 432 fn make(type_: Arc<Type>) -> ModuleInterface { 433 ModuleInterface { 434 warnings: vec![], 435 is_internal: false, 436 package: "some_package".into(), 437 origin: Origin::Src, 438 name: "a".into(), 439 types: [( 440 "SomeType".into(), 441 TypeConstructor { 442 type_, 443 publicity: Publicity::Public, 444 origin: SrcSpan { 445 start: 535, 446 end: 543, 447 }, 448 module: "a".into(), 449 parameters: vec![], 450 deprecation: Deprecation::NotDeprecated, 451 documentation: None, 452 }, 453 )] 454 .into(), 455 types_value_constructors: HashMap::new(), 456 values: HashMap::new(), 457 accessors: HashMap::new(), 458 line_numbers: LineNumbers::new(""), 459 src_path: "some_path".into(), 460 minimum_required_version: Version::new(0, 1, 0), 461 type_aliases: HashMap::new(), 462 documentation: Vec::new(), 463 contains_echo: false, 464 references: References::default(), 465 inline_functions: HashMap::new(), 466 } 467 } 468 469 assert_eq!(roundtrip(&make(linked_type)), make(type_)); 470} 471 472#[test] 473fn module_type_to_constructors_mapping() { 474 let module = ModuleInterface { 475 warnings: vec![], 476 is_internal: false, 477 package: "some_package".into(), 478 origin: Origin::Src, 479 name: "a".into(), 480 types: HashMap::new(), 481 types_value_constructors: [( 482 "SomeType".into(), 483 TypeVariantConstructors { 484 type_parameters_ids: vec![0, 1, 2], 485 variants: vec![TypeValueConstructor { 486 name: "One".into(), 487 parameters: vec![], 488 documentation: Some("Some documentation".into()), 489 }], 490 opaque: Opaque::NotOpaque, 491 }, 492 )] 493 .into(), 494 accessors: HashMap::new(), 495 values: HashMap::new(), 496 line_numbers: LineNumbers::new(""), 497 src_path: "some_path".into(), 498 minimum_required_version: Version::new(0, 1, 0), 499 type_aliases: HashMap::new(), 500 documentation: Vec::new(), 501 contains_echo: false, 502 503 references: References::default(), 504 inline_functions: HashMap::new(), 505 }; 506 507 assert_eq!(roundtrip(&module), module); 508} 509 510#[test] 511fn module_fn_value() { 512 let module = ModuleInterface { 513 warnings: vec![], 514 is_internal: false, 515 package: "some_package".into(), 516 origin: Origin::Src, 517 name: "a".into(), 518 types: HashMap::new(), 519 types_value_constructors: HashMap::new(), 520 accessors: HashMap::new(), 521 values: [( 522 "one".into(), 523 ValueConstructor { 524 publicity: Publicity::Public, 525 deprecation: Deprecation::NotDeprecated, 526 type_: type_::int(), 527 variant: ValueConstructorVariant::ModuleFn { 528 documentation: Some("wobble!".into()), 529 name: "one".into(), 530 field_map: None, 531 module: "a".into(), 532 arity: 5, 533 location: SrcSpan { 534 start: 535, 535 end: 1100, 536 }, 537 external_erlang: None, 538 external_javascript: None, 539 implementations: Implementations { 540 gleam: true, 541 uses_erlang_externals: false, 542 uses_javascript_externals: false, 543 can_run_on_erlang: true, 544 can_run_on_javascript: true, 545 }, 546 purity: Purity::Pure, 547 }, 548 }, 549 )] 550 .into(), 551 line_numbers: LineNumbers::new(""), 552 src_path: "some_path".into(), 553 minimum_required_version: Version::new(0, 1, 0), 554 type_aliases: HashMap::new(), 555 documentation: Vec::new(), 556 contains_echo: false, 557 558 references: References::default(), 559 inline_functions: HashMap::new(), 560 }; 561 assert_eq!(roundtrip(&module), module); 562} 563 564#[test] 565fn deprecated_module_fn_value() { 566 let module = ModuleInterface { 567 warnings: vec![], 568 is_internal: false, 569 package: "some_package".into(), 570 origin: Origin::Src, 571 name: "a".into(), 572 types: HashMap::new(), 573 types_value_constructors: HashMap::new(), 574 accessors: HashMap::new(), 575 values: [( 576 "one".into(), 577 ValueConstructor { 578 publicity: Publicity::Public, 579 deprecation: Deprecation::Deprecated { 580 message: "wibble wobble".into(), 581 }, 582 type_: type_::int(), 583 variant: ValueConstructorVariant::ModuleFn { 584 documentation: Some("wobble!".into()), 585 name: "one".into(), 586 field_map: None, 587 module: "a".into(), 588 arity: 5, 589 location: SrcSpan { 590 start: 535, 591 end: 1100, 592 }, 593 external_erlang: None, 594 external_javascript: None, 595 implementations: Implementations { 596 gleam: true, 597 uses_erlang_externals: false, 598 uses_javascript_externals: false, 599 can_run_on_erlang: true, 600 can_run_on_javascript: true, 601 }, 602 purity: Purity::Pure, 603 }, 604 }, 605 )] 606 .into(), 607 line_numbers: LineNumbers::new(""), 608 src_path: "some_path".into(), 609 minimum_required_version: Version::new(0, 1, 0), 610 type_aliases: HashMap::new(), 611 documentation: Vec::new(), 612 contains_echo: false, 613 614 references: References::default(), 615 inline_functions: HashMap::new(), 616 }; 617 assert_eq!(roundtrip(&module), module); 618} 619 620#[test] 621fn private_module_fn_value() { 622 let module = ModuleInterface { 623 warnings: vec![], 624 is_internal: false, 625 package: "some_package".into(), 626 origin: Origin::Src, 627 name: "a".into(), 628 types: HashMap::new(), 629 types_value_constructors: HashMap::new(), 630 accessors: HashMap::new(), 631 values: [( 632 "one".into(), 633 ValueConstructor { 634 publicity: Publicity::Private, 635 deprecation: Deprecation::NotDeprecated, 636 type_: type_::int(), 637 variant: ValueConstructorVariant::ModuleFn { 638 documentation: Some("wobble!".into()), 639 name: "one".into(), 640 field_map: None, 641 module: "a".into(), 642 arity: 5, 643 location: SrcSpan { 644 start: 535, 645 end: 1100, 646 }, 647 external_erlang: None, 648 external_javascript: None, 649 implementations: Implementations { 650 gleam: true, 651 uses_erlang_externals: false, 652 uses_javascript_externals: false, 653 can_run_on_erlang: true, 654 can_run_on_javascript: true, 655 }, 656 purity: Purity::Pure, 657 }, 658 }, 659 )] 660 .into(), 661 line_numbers: LineNumbers::new(""), 662 src_path: "some_path".into(), 663 minimum_required_version: Version::new(0, 1, 0), 664 type_aliases: HashMap::new(), 665 documentation: Vec::new(), 666 contains_echo: false, 667 668 references: References::default(), 669 inline_functions: HashMap::new(), 670 }; 671 672 assert_eq!(roundtrip(&module), module); 673} 674 675// https://github.com/gleam-lang/gleam/commit/c8f3bd0ddbf61c27ea35f37297058ecca7515f6c 676#[test] 677fn module_fn_value_regression() { 678 let module = ModuleInterface { 679 warnings: vec![], 680 is_internal: false, 681 package: "some_package".into(), 682 origin: Origin::Src, 683 name: "a/b/c".into(), 684 types: HashMap::new(), 685 types_value_constructors: HashMap::new(), 686 accessors: HashMap::new(), 687 values: [( 688 "one".into(), 689 ValueConstructor { 690 publicity: Publicity::Public, 691 deprecation: Deprecation::NotDeprecated, 692 type_: type_::int(), 693 variant: ValueConstructorVariant::ModuleFn { 694 documentation: Some("wabble!".into()), 695 name: "one".into(), 696 field_map: None, 697 module: "a".into(), 698 arity: 5, 699 location: SrcSpan { 700 start: 52, 701 end: 1100, 702 }, 703 external_erlang: None, 704 external_javascript: None, 705 implementations: Implementations { 706 gleam: true, 707 uses_erlang_externals: false, 708 uses_javascript_externals: false, 709 can_run_on_erlang: true, 710 can_run_on_javascript: true, 711 }, 712 purity: Purity::TrustedPure, 713 }, 714 }, 715 )] 716 .into(), 717 line_numbers: LineNumbers::new(""), 718 src_path: "some_path".into(), 719 minimum_required_version: Version::new(0, 1, 0), 720 type_aliases: HashMap::new(), 721 documentation: Vec::new(), 722 contains_echo: false, 723 724 references: References::default(), 725 inline_functions: HashMap::new(), 726 }; 727 728 assert_eq!(roundtrip(&module), module); 729} 730 731#[test] 732fn module_fn_value_with_field_map() { 733 let module = ModuleInterface { 734 warnings: vec![], 735 is_internal: false, 736 package: "some_package".into(), 737 origin: Origin::Src, 738 name: "a".into(), 739 types: HashMap::new(), 740 types_value_constructors: HashMap::new(), 741 accessors: HashMap::new(), 742 values: [( 743 "one".into(), 744 ValueConstructor { 745 publicity: Publicity::Public, 746 deprecation: Deprecation::NotDeprecated, 747 type_: type_::int(), 748 variant: ValueConstructorVariant::ModuleFn { 749 documentation: Some("wubble!".into()), 750 name: "one".into(), 751 field_map: Some(FieldMap { 752 arity: 20, 753 fields: [("ok".into(), 5), ("ko".into(), 7)].into(), 754 }), 755 external_erlang: None, 756 external_javascript: None, 757 module: "a".into(), 758 arity: 5, 759 location: SrcSpan { start: 2, end: 11 }, 760 implementations: Implementations { 761 gleam: true, 762 uses_erlang_externals: false, 763 uses_javascript_externals: false, 764 can_run_on_erlang: true, 765 can_run_on_javascript: true, 766 }, 767 purity: Purity::Pure, 768 }, 769 }, 770 )] 771 .into(), 772 line_numbers: LineNumbers::new(""), 773 src_path: "some_path".into(), 774 minimum_required_version: Version::new(0, 1, 0), 775 type_aliases: HashMap::new(), 776 documentation: Vec::new(), 777 contains_echo: false, 778 779 references: References::default(), 780 inline_functions: HashMap::new(), 781 }; 782 783 assert_eq!(roundtrip(&module), module); 784} 785 786#[test] 787fn record_value() { 788 let mut random = rand::rng(); 789 790 let module = ModuleInterface { 791 warnings: vec![], 792 is_internal: false, 793 package: "some_package".into(), 794 origin: Origin::Src, 795 name: "a".into(), 796 types: HashMap::new(), 797 types_value_constructors: HashMap::new(), 798 accessors: HashMap::new(), 799 values: [( 800 "one".into(), 801 ValueConstructor { 802 publicity: Publicity::Public, 803 deprecation: Deprecation::NotDeprecated, 804 type_: type_::int(), 805 variant: ValueConstructorVariant::Record { 806 documentation: Some("webble!".into()), 807 name: "one".into(), 808 module: "themodule".into(), 809 field_map: None, 810 arity: random.random(), 811 variants_count: random.random(), 812 location: SrcSpan { 813 start: random.random(), 814 end: random.random(), 815 }, 816 variant_index: random.random(), 817 }, 818 }, 819 )] 820 .into(), 821 line_numbers: LineNumbers::new(""), 822 src_path: "some_path".into(), 823 minimum_required_version: Version::new(0, 1, 0), 824 type_aliases: HashMap::new(), 825 documentation: Vec::new(), 826 contains_echo: false, 827 828 references: References::default(), 829 inline_functions: HashMap::new(), 830 }; 831 832 assert_eq!(roundtrip(&module), module); 833} 834 835#[test] 836fn record_value_with_field_map() { 837 let mut random = rand::rng(); 838 839 let module = ModuleInterface { 840 warnings: vec![], 841 is_internal: false, 842 package: "some_package".into(), 843 origin: Origin::Src, 844 name: "a".into(), 845 types: HashMap::new(), 846 types_value_constructors: HashMap::new(), 847 accessors: HashMap::new(), 848 values: [( 849 "one".into(), 850 ValueConstructor { 851 publicity: Publicity::Public, 852 deprecation: Deprecation::NotDeprecated, 853 type_: type_::int(), 854 variant: ValueConstructorVariant::Record { 855 documentation: Some("wybble!".into()), 856 module: "themodule".into(), 857 name: "one".into(), 858 field_map: Some(FieldMap { 859 arity: random.random(), 860 fields: [ 861 ("ok".into(), random.random()), 862 ("ko".into(), random.random()), 863 ] 864 .into(), 865 }), 866 arity: random.random(), 867 variants_count: random.random(), 868 variant_index: random.random(), 869 location: SrcSpan { 870 start: random.random(), 871 end: random.random(), 872 }, 873 }, 874 }, 875 )] 876 .into(), 877 line_numbers: LineNumbers::new(""), 878 src_path: "some_path".into(), 879 minimum_required_version: Version::new(0, 1, 0), 880 type_aliases: HashMap::new(), 881 documentation: Vec::new(), 882 contains_echo: false, 883 884 references: References::default(), 885 inline_functions: HashMap::new(), 886 }; 887 888 assert_eq!(roundtrip(&module), module); 889} 890 891#[test] 892fn accessors() { 893 let accessors1 = [ 894 ( 895 "a".into(), 896 RecordAccessor { 897 index: 6, 898 label: "siiixxx".into(), 899 type_: type_::nil(), 900 documentation: Some("Here is some documentation".into()), 901 }, 902 ), 903 ( 904 "a".into(), 905 RecordAccessor { 906 index: 5, 907 label: "fiveee".into(), 908 type_: type_::float(), 909 documentation: None, 910 }, 911 ), 912 ]; 913 914 let accessors2 = [( 915 "a".into(), 916 RecordAccessor { 917 index: 1, 918 label: "ok".into(), 919 type_: type_::float(), 920 documentation: Some("Documentation for the ok field".into()), 921 }, 922 )]; 923 924 let module = ModuleInterface { 925 warnings: vec![], 926 is_internal: false, 927 package: "some_package".into(), 928 origin: Origin::Src, 929 name: "a".into(), 930 types: HashMap::new(), 931 types_value_constructors: HashMap::new(), 932 values: HashMap::new(), 933 accessors: [ 934 ( 935 "one".into(), 936 AccessorsMap { 937 publicity: Publicity::Public, 938 type_: type_::int(), 939 shared_accessors: accessors1.clone().into(), 940 variant_specific_accessors: vec![accessors1.into()], 941 }, 942 ), 943 ( 944 "two".into(), 945 AccessorsMap { 946 publicity: Publicity::Public, 947 type_: type_::int(), 948 shared_accessors: accessors2.clone().into(), 949 variant_specific_accessors: vec![accessors2.into()], 950 }, 951 ), 952 ] 953 .into(), 954 line_numbers: LineNumbers::new(""), 955 src_path: "some_path".into(), 956 minimum_required_version: Version::new(0, 1, 0), 957 type_aliases: HashMap::new(), 958 documentation: Vec::new(), 959 contains_echo: false, 960 961 references: References::default(), 962 inline_functions: HashMap::new(), 963 }; 964 965 assert_eq!(roundtrip(&module), module); 966} 967 968#[test] 969fn private_accessors() { 970 let accessors1 = [ 971 ( 972 "a".into(), 973 RecordAccessor { 974 index: 6, 975 label: "siiixxx".into(), 976 type_: type_::nil(), 977 documentation: None, 978 }, 979 ), 980 ( 981 "a".into(), 982 RecordAccessor { 983 index: 5, 984 label: "fiveee".into(), 985 type_: type_::float(), 986 documentation: None, 987 }, 988 ), 989 ]; 990 991 let accessors2 = [( 992 "a".into(), 993 RecordAccessor { 994 index: 1, 995 label: "ok".into(), 996 type_: type_::float(), 997 documentation: None, 998 }, 999 )]; 1000 1001 let module = ModuleInterface { 1002 warnings: vec![], 1003 is_internal: false, 1004 package: "some_package".into(), 1005 origin: Origin::Src, 1006 name: "a".into(), 1007 types: HashMap::new(), 1008 types_value_constructors: HashMap::new(), 1009 contains_echo: false, 1010 values: HashMap::new(), 1011 accessors: [ 1012 ( 1013 "one".into(), 1014 AccessorsMap { 1015 publicity: Publicity::Private, 1016 type_: type_::int(), 1017 shared_accessors: accessors1.clone().into(), 1018 variant_specific_accessors: vec![accessors1.into()], 1019 }, 1020 ), 1021 ( 1022 "two".into(), 1023 AccessorsMap { 1024 publicity: Publicity::Public, 1025 type_: type_::int(), 1026 shared_accessors: accessors2.clone().into(), 1027 variant_specific_accessors: vec![accessors2.into()], 1028 }, 1029 ), 1030 ] 1031 .into(), 1032 line_numbers: LineNumbers::new(""), 1033 src_path: "some_path".into(), 1034 minimum_required_version: Version::new(0, 1, 0), 1035 type_aliases: HashMap::new(), 1036 documentation: Vec::new(), 1037 references: References::default(), 1038 inline_functions: HashMap::new(), 1039 }; 1040 1041 assert_eq!(roundtrip(&module), module); 1042} 1043 1044#[test] 1045fn constant_int() { 1046 let module = constant_module(Constant::Int { 1047 location: Default::default(), 1048 value: "100".into(), 1049 int_value: 100.into(), 1050 }); 1051 1052 assert_eq!(roundtrip(&module), module); 1053} 1054 1055#[test] 1056fn constant_float() { 1057 let module = constant_module(Constant::Float { 1058 location: Default::default(), 1059 value: "1.0".into(), 1060 float_value: LiteralFloatValue::ONE, 1061 }); 1062 1063 assert_eq!(roundtrip(&module), module); 1064} 1065 1066#[test] 1067fn constant_string() { 1068 let module = constant_module(Constant::String { 1069 location: Default::default(), 1070 value: "hello".into(), 1071 }); 1072 1073 assert_eq!(roundtrip(&module), module); 1074} 1075 1076#[test] 1077fn constant_tuple() { 1078 let module = constant_module(Constant::Tuple { 1079 location: Default::default(), 1080 elements: vec![ 1081 Constant::Int { 1082 location: Default::default(), 1083 value: "1".into(), 1084 int_value: 1.into(), 1085 }, 1086 Constant::Float { 1087 location: Default::default(), 1088 value: "1.0".into(), 1089 float_value: LiteralFloatValue::ONE, 1090 }, 1091 Constant::Tuple { 1092 location: Default::default(), 1093 elements: vec![ 1094 Constant::Int { 1095 location: Default::default(), 1096 value: "1".into(), 1097 int_value: 1.into(), 1098 }, 1099 Constant::Float { 1100 location: Default::default(), 1101 value: "1.0".into(), 1102 float_value: LiteralFloatValue::ONE, 1103 }, 1104 ], 1105 }, 1106 ], 1107 }); 1108 1109 assert_eq!(roundtrip(&module), module); 1110} 1111 1112#[test] 1113fn constant_list() { 1114 let module = constant_module(Constant::List { 1115 location: Default::default(), 1116 type_: type_::int(), 1117 elements: vec![ 1118 Constant::Int { 1119 location: Default::default(), 1120 value: "1".into(), 1121 int_value: 1.into(), 1122 }, 1123 Constant::Int { 1124 location: Default::default(), 1125 value: "2".into(), 1126 int_value: 2.into(), 1127 }, 1128 Constant::Int { 1129 location: Default::default(), 1130 value: "3".into(), 1131 int_value: 3.into(), 1132 }, 1133 ], 1134 }); 1135 1136 assert_eq!(roundtrip(&module), module); 1137} 1138 1139#[test] 1140fn constant_record() { 1141 let module = constant_module(Constant::Record { 1142 location: Default::default(), 1143 module: None, 1144 name: "".into(), 1145 arguments: vec![ 1146 CallArg { 1147 implicit: None, 1148 label: None, 1149 location: Default::default(), 1150 value: Constant::Float { 1151 location: Default::default(), 1152 value: "0.0".into(), 1153 float_value: LiteralFloatValue::ZERO, 1154 }, 1155 }, 1156 CallArg { 1157 implicit: None, 1158 label: None, 1159 location: Default::default(), 1160 value: Constant::Int { 1161 location: Default::default(), 1162 value: "1".into(), 1163 int_value: 1.into(), 1164 }, 1165 }, 1166 ], 1167 tag: "thetag".into(), 1168 type_: type_::int(), 1169 field_map: None, 1170 record_constructor: None, 1171 }); 1172 1173 assert_eq!(roundtrip(&module), module); 1174} 1175 1176#[test] 1177fn constant_var() { 1178 let one_original = Constant::Int { 1179 location: Default::default(), 1180 value: "1".into(), 1181 int_value: 1.into(), 1182 }; 1183 1184 let one = Constant::Var { 1185 location: Default::default(), 1186 module: None, 1187 name: "one_original".into(), 1188 type_: type_::int(), 1189 constructor: Some(Box::from(ValueConstructor { 1190 publicity: Publicity::Public, 1191 deprecation: Deprecation::NotDeprecated, 1192 type_: type_::int(), 1193 variant: ValueConstructorVariant::ModuleConstant { 1194 documentation: Some("some doc".into()), 1195 literal: one_original.clone(), 1196 location: SrcSpan::default(), 1197 module: "one/two".into(), 1198 implementations: Implementations { 1199 gleam: true, 1200 uses_erlang_externals: false, 1201 uses_javascript_externals: false, 1202 can_run_on_erlang: true, 1203 can_run_on_javascript: true, 1204 }, 1205 name: "one_original".into(), 1206 }, 1207 })), 1208 }; 1209 1210 let module = ModuleInterface { 1211 warnings: vec![], 1212 is_internal: false, 1213 package: "some_package".into(), 1214 origin: Origin::Src, 1215 name: "a".into(), 1216 types: HashMap::new(), 1217 types_value_constructors: HashMap::new(), 1218 accessors: HashMap::new(), 1219 values: [ 1220 ( 1221 "one".into(), 1222 ValueConstructor { 1223 publicity: Publicity::Public, 1224 deprecation: Deprecation::NotDeprecated, 1225 type_: type_::int(), 1226 variant: ValueConstructorVariant::ModuleConstant { 1227 documentation: Some("some doc!!!!!!!!!".into()), 1228 literal: one, 1229 location: SrcSpan::default(), 1230 module: "one/two".into(), 1231 implementations: Implementations { 1232 gleam: true, 1233 uses_erlang_externals: false, 1234 uses_javascript_externals: false, 1235 can_run_on_erlang: true, 1236 can_run_on_javascript: true, 1237 }, 1238 name: "one".into(), 1239 }, 1240 }, 1241 ), 1242 ( 1243 "one_original".into(), 1244 ValueConstructor { 1245 publicity: Publicity::Public, 1246 deprecation: Deprecation::NotDeprecated, 1247 type_: type_::int(), 1248 variant: ValueConstructorVariant::ModuleConstant { 1249 documentation: Some("some doc yeah".into()), 1250 literal: one_original, 1251 location: SrcSpan::default(), 1252 module: "one/two".into(), 1253 implementations: Implementations { 1254 gleam: true, 1255 uses_erlang_externals: false, 1256 uses_javascript_externals: false, 1257 can_run_on_erlang: true, 1258 can_run_on_javascript: true, 1259 }, 1260 name: "one_original".into(), 1261 }, 1262 }, 1263 ), 1264 ] 1265 .into(), 1266 line_numbers: LineNumbers::new(""), 1267 src_path: "some_path".into(), 1268 minimum_required_version: Version::new(0, 1, 0), 1269 type_aliases: HashMap::new(), 1270 documentation: Vec::new(), 1271 contains_echo: false, 1272 1273 references: References::default(), 1274 inline_functions: HashMap::new(), 1275 }; 1276 1277 assert_eq!(roundtrip(&module), module); 1278} 1279 1280#[test] 1281fn constant_bit_array() { 1282 let module = constant_module(Constant::BitArray { 1283 location: Default::default(), 1284 segments: vec![], 1285 }); 1286 assert_eq!(roundtrip(&module), module); 1287} 1288 1289#[test] 1290fn constant_bit_array_unit() { 1291 let module = bit_array_segment_option_module(BitArrayOption::Unit { 1292 location: Default::default(), 1293 value: 234, 1294 }); 1295 assert_eq!(roundtrip(&module), module); 1296} 1297 1298#[test] 1299fn constant_bit_array_float() { 1300 let module = bit_array_segment_option_module(BitArrayOption::Float { 1301 location: Default::default(), 1302 }); 1303 assert_eq!(roundtrip(&module), module); 1304} 1305 1306#[test] 1307fn constant_bit_array_int() { 1308 let module = bit_array_segment_option_module(BitArrayOption::Int { 1309 location: Default::default(), 1310 }); 1311 assert_eq!(roundtrip(&module), module); 1312} 1313 1314#[test] 1315fn constant_bit_array_size() { 1316 let module = bit_array_segment_option_module(BitArrayOption::Size { 1317 location: Default::default(), 1318 value: Box::new(Constant::Int { 1319 location: Default::default(), 1320 value: "1".into(), 1321 int_value: 1.into(), 1322 }), 1323 short_form: false, 1324 }); 1325 assert_eq!(roundtrip(&module), module); 1326} 1327 1328#[test] 1329fn constant_bit_array_size_short_form() { 1330 let module = bit_array_segment_option_module(BitArrayOption::Size { 1331 location: Default::default(), 1332 value: Box::new(Constant::Int { 1333 location: Default::default(), 1334 value: "1".into(), 1335 int_value: 1.into(), 1336 }), 1337 short_form: true, 1338 }); 1339 assert_eq!(roundtrip(&module), module); 1340} 1341 1342#[test] 1343fn constant_bit_array_bit_arry() { 1344 let module = bit_array_segment_option_module(BitArrayOption::Bits { 1345 location: Default::default(), 1346 }); 1347 assert_eq!(roundtrip(&module), module); 1348} 1349 1350#[test] 1351fn constant_bit_array_utf8() { 1352 let module = bit_array_segment_option_module(BitArrayOption::Utf8 { 1353 location: Default::default(), 1354 }); 1355 assert_eq!(roundtrip(&module), module); 1356} 1357 1358#[test] 1359fn constant_bit_array_utf16() { 1360 let module = bit_array_segment_option_module(BitArrayOption::Utf16 { 1361 location: Default::default(), 1362 }); 1363 assert_eq!(roundtrip(&module), module); 1364} 1365 1366#[test] 1367fn constant_bit_array_utf32() { 1368 let module = bit_array_segment_option_module(BitArrayOption::Utf32 { 1369 location: Default::default(), 1370 }); 1371 assert_eq!(roundtrip(&module), module); 1372} 1373 1374#[test] 1375fn constant_bit_array_utf8codepoint() { 1376 let module = bit_array_segment_option_module(BitArrayOption::Utf8Codepoint { 1377 location: Default::default(), 1378 }); 1379 assert_eq!(roundtrip(&module), module); 1380} 1381 1382#[test] 1383fn constant_bit_array_utf16codepoint() { 1384 let module = bit_array_segment_option_module(BitArrayOption::Utf16Codepoint { 1385 location: Default::default(), 1386 }); 1387 assert_eq!(roundtrip(&module), module); 1388} 1389 1390#[test] 1391fn constant_bit_array_utf32codepoint() { 1392 let module = bit_array_segment_option_module(BitArrayOption::Utf32Codepoint { 1393 location: Default::default(), 1394 }); 1395 assert_eq!(roundtrip(&module), module); 1396} 1397 1398#[test] 1399fn constant_bit_array_signed() { 1400 let module = bit_array_segment_option_module(BitArrayOption::Signed { 1401 location: Default::default(), 1402 }); 1403 assert_eq!(roundtrip(&module), module); 1404} 1405 1406#[test] 1407fn constant_bit_array_unsigned() { 1408 let module = bit_array_segment_option_module(BitArrayOption::Unsigned { 1409 location: Default::default(), 1410 }); 1411 assert_eq!(roundtrip(&module), module); 1412} 1413 1414#[test] 1415fn constant_bit_array_big() { 1416 let module = bit_array_segment_option_module(BitArrayOption::Big { 1417 location: Default::default(), 1418 }); 1419 assert_eq!(roundtrip(&module), module); 1420} 1421 1422#[test] 1423fn constant_bit_array_little() { 1424 let module = bit_array_segment_option_module(BitArrayOption::Little { 1425 location: Default::default(), 1426 }); 1427 assert_eq!(roundtrip(&module), module); 1428} 1429 1430#[test] 1431fn constant_bit_array_native() { 1432 let module = bit_array_segment_option_module(BitArrayOption::Native { 1433 location: Default::default(), 1434 }); 1435 assert_eq!(roundtrip(&module), module); 1436} 1437 1438#[test] 1439fn deprecated_type() { 1440 let module = ModuleInterface { 1441 warnings: vec![], 1442 is_internal: false, 1443 package: "some_package".into(), 1444 origin: Origin::Src, 1445 name: "a/b".into(), 1446 types: [( 1447 "ListIntType".into(), 1448 TypeConstructor { 1449 type_: type_::list(type_::int()), 1450 publicity: Publicity::Public, 1451 origin: Default::default(), 1452 module: "the/module".into(), 1453 parameters: vec![], 1454 deprecation: Deprecation::Deprecated { 1455 message: "oh no".into(), 1456 }, 1457 documentation: None, 1458 }, 1459 )] 1460 .into(), 1461 types_value_constructors: HashMap::new(), 1462 values: HashMap::new(), 1463 accessors: HashMap::new(), 1464 line_numbers: LineNumbers::new(""), 1465 src_path: "some_path".into(), 1466 minimum_required_version: Version::new(0, 1, 0), 1467 type_aliases: HashMap::new(), 1468 documentation: Vec::new(), 1469 contains_echo: false, 1470 1471 references: References::default(), 1472 inline_functions: HashMap::new(), 1473 }; 1474 assert_eq!(roundtrip(&module), module); 1475} 1476 1477#[test] 1478fn module_fn_value_with_external_implementations() { 1479 let module = ModuleInterface { 1480 warnings: vec![], 1481 is_internal: false, 1482 package: "some_package".into(), 1483 origin: Origin::Src, 1484 name: "a/b/c".into(), 1485 types: HashMap::new(), 1486 types_value_constructors: HashMap::new(), 1487 accessors: HashMap::new(), 1488 values: [( 1489 "one".into(), 1490 ValueConstructor { 1491 publicity: Publicity::Public, 1492 deprecation: Deprecation::NotDeprecated, 1493 type_: type_::int(), 1494 variant: ValueConstructorVariant::ModuleFn { 1495 documentation: Some("wabble!".into()), 1496 name: "one".into(), 1497 field_map: None, 1498 module: "a".into(), 1499 arity: 5, 1500 location: SrcSpan { 1501 start: 52, 1502 end: 1100, 1503 }, 1504 external_erlang: Some(("wibble".into(), "wobble".into())), 1505 external_javascript: Some(("wobble".into(), "wibble".into())), 1506 implementations: Implementations { 1507 gleam: false, 1508 uses_erlang_externals: true, 1509 uses_javascript_externals: true, 1510 can_run_on_erlang: false, 1511 can_run_on_javascript: true, 1512 }, 1513 purity: Purity::Impure, 1514 }, 1515 }, 1516 )] 1517 .into(), 1518 line_numbers: LineNumbers::new(""), 1519 src_path: "some_path".into(), 1520 minimum_required_version: Version::new(0, 1, 0), 1521 type_aliases: HashMap::new(), 1522 documentation: Vec::new(), 1523 contains_echo: false, 1524 references: References::default(), 1525 inline_functions: HashMap::new(), 1526 }; 1527 1528 assert_eq!(roundtrip(&module), module); 1529} 1530 1531#[test] 1532fn module_containing_echo() { 1533 let module = ModuleInterface { 1534 warnings: vec![], 1535 is_internal: false, 1536 package: "some_package".into(), 1537 origin: Origin::Src, 1538 name: "a/b/c".into(), 1539 types: HashMap::new(), 1540 types_value_constructors: HashMap::new(), 1541 accessors: HashMap::new(), 1542 values: [].into(), 1543 line_numbers: LineNumbers::new(""), 1544 src_path: "some_path".into(), 1545 minimum_required_version: Version::new(0, 1, 0), 1546 type_aliases: HashMap::new(), 1547 documentation: Vec::new(), 1548 contains_echo: true, 1549 references: References::default(), 1550 inline_functions: HashMap::new(), 1551 }; 1552 1553 assert_eq!(roundtrip(&module), module); 1554} 1555 1556#[test] 1557fn internal_module_fn() { 1558 let module = ModuleInterface { 1559 warnings: vec![], 1560 is_internal: false, 1561 package: "some_package".into(), 1562 origin: Origin::Src, 1563 name: "a/b/c".into(), 1564 types: HashMap::new(), 1565 types_value_constructors: HashMap::new(), 1566 accessors: HashMap::new(), 1567 values: [( 1568 "one".into(), 1569 ValueConstructor { 1570 publicity: Publicity::Internal { 1571 attribute_location: None, 1572 }, 1573 deprecation: Deprecation::NotDeprecated, 1574 type_: type_::int(), 1575 variant: ValueConstructorVariant::ModuleFn { 1576 documentation: Some("wabble!".into()), 1577 name: "one".into(), 1578 field_map: None, 1579 module: "a".into(), 1580 arity: 5, 1581 location: SrcSpan { 1582 start: 52, 1583 end: 1100, 1584 }, 1585 external_erlang: Some(("wibble".into(), "wobble".into())), 1586 external_javascript: Some(("wobble".into(), "wibble".into())), 1587 implementations: Implementations { 1588 gleam: false, 1589 uses_erlang_externals: true, 1590 uses_javascript_externals: true, 1591 can_run_on_erlang: true, 1592 can_run_on_javascript: true, 1593 }, 1594 purity: Purity::Unknown, 1595 }, 1596 }, 1597 )] 1598 .into(), 1599 line_numbers: LineNumbers::new(""), 1600 src_path: "some_path".into(), 1601 minimum_required_version: Version::new(0, 1, 0), 1602 type_aliases: HashMap::new(), 1603 documentation: Vec::new(), 1604 contains_echo: false, 1605 1606 references: References::default(), 1607 inline_functions: HashMap::new(), 1608 }; 1609 1610 assert_eq!(roundtrip(&module), module); 1611} 1612 1613#[test] 1614fn internal_annotated_module_fn() { 1615 let module = ModuleInterface { 1616 warnings: vec![], 1617 is_internal: false, 1618 package: "some_package".into(), 1619 origin: Origin::Src, 1620 name: "a/b/c".into(), 1621 types: HashMap::new(), 1622 types_value_constructors: HashMap::new(), 1623 accessors: HashMap::new(), 1624 values: [( 1625 "one".into(), 1626 ValueConstructor { 1627 publicity: Publicity::Internal { 1628 attribute_location: Some(SrcSpan { 1629 start: 11, 1630 end: 111, 1631 }), 1632 }, 1633 deprecation: Deprecation::NotDeprecated, 1634 type_: type_::int(), 1635 variant: ValueConstructorVariant::ModuleFn { 1636 documentation: Some("wabble!".into()), 1637 name: "one".into(), 1638 field_map: None, 1639 module: "a".into(), 1640 arity: 5, 1641 location: SrcSpan { 1642 start: 52, 1643 end: 1100, 1644 }, 1645 external_erlang: Some(("wibble".into(), "wobble".into())), 1646 external_javascript: Some(("wobble".into(), "wibble".into())), 1647 implementations: Implementations { 1648 gleam: false, 1649 uses_erlang_externals: true, 1650 uses_javascript_externals: true, 1651 can_run_on_erlang: true, 1652 can_run_on_javascript: true, 1653 }, 1654 purity: Purity::Impure, 1655 }, 1656 }, 1657 )] 1658 .into(), 1659 line_numbers: LineNumbers::new(""), 1660 src_path: "some_path".into(), 1661 minimum_required_version: Version::new(0, 1, 0), 1662 type_aliases: HashMap::new(), 1663 documentation: Vec::new(), 1664 contains_echo: false, 1665 1666 references: References::default(), 1667 inline_functions: HashMap::new(), 1668 }; 1669 1670 assert_eq!(roundtrip(&module), module); 1671} 1672 1673// https://github.com/gleam-lang/gleam/issues/2599 1674#[test] 1675fn type_variable_ids_in_constructors_are_shared() { 1676 let module = ModuleInterface { 1677 warnings: vec![], 1678 is_internal: false, 1679 package: "some_package".into(), 1680 origin: Origin::Src, 1681 name: "a/b/c".into(), 1682 types: HashMap::new(), 1683 types_value_constructors: HashMap::from([( 1684 "SomeType".into(), 1685 TypeVariantConstructors { 1686 type_parameters_ids: vec![4, 5, 6], 1687 variants: vec![TypeValueConstructor { 1688 name: "One".into(), 1689 parameters: vec![ 1690 TypeValueConstructorField { 1691 type_: type_::generic_var(6), 1692 label: None, 1693 documentation: Some("Here's some documentation".into()), 1694 }, 1695 TypeValueConstructorField { 1696 type_: type_::int(), 1697 label: None, 1698 documentation: None, 1699 }, 1700 TypeValueConstructorField { 1701 type_: type_::tuple(vec![type_::generic_var(4), type_::generic_var(5)]), 1702 label: None, 1703 documentation: None, 1704 }, 1705 ], 1706 documentation: None, 1707 }], 1708 opaque: Opaque::NotOpaque, 1709 }, 1710 )]), 1711 accessors: HashMap::new(), 1712 values: [].into(), 1713 line_numbers: LineNumbers::new(""), 1714 src_path: "some_path".into(), 1715 minimum_required_version: Version::new(0, 1, 0), 1716 type_aliases: HashMap::new(), 1717 documentation: Vec::new(), 1718 contains_echo: false, 1719 1720 references: References::default(), 1721 inline_functions: HashMap::new(), 1722 }; 1723 1724 let expected = HashMap::from([( 1725 "SomeType".into(), 1726 TypeVariantConstructors { 1727 type_parameters_ids: vec![1, 2, 0], 1728 variants: vec![TypeValueConstructor { 1729 name: "One".into(), 1730 parameters: vec![ 1731 TypeValueConstructorField { 1732 type_: type_::generic_var(0), 1733 label: None, 1734 documentation: Some("Here's some documentation".into()), 1735 }, 1736 TypeValueConstructorField { 1737 type_: type_::int(), 1738 label: None, 1739 documentation: None, 1740 }, 1741 TypeValueConstructorField { 1742 type_: type_::tuple(vec![type_::generic_var(1), type_::generic_var(2)]), 1743 label: None, 1744 documentation: None, 1745 }, 1746 ], 1747 documentation: None, 1748 }], 1749 opaque: Opaque::NotOpaque, 1750 }, 1751 )]); 1752 1753 assert_eq!(roundtrip(&module).types_value_constructors, expected); 1754} 1755 1756#[test] 1757fn type_with_inferred_variant() { 1758 let module = ModuleInterface { 1759 warnings: vec![], 1760 is_internal: false, 1761 package: "some_package".into(), 1762 contains_echo: false, 1763 origin: Origin::Src, 1764 name: "a/b".into(), 1765 types: [( 1766 "Wibble".into(), 1767 TypeConstructor { 1768 type_: Arc::new(Type::Named { 1769 publicity: Publicity::Internal { 1770 attribute_location: None, 1771 }, 1772 package: "some_package".into(), 1773 module: "the/module".into(), 1774 name: "Wibble".into(), 1775 arguments: Vec::new(), 1776 inferred_variant: Some(1), 1777 }), 1778 publicity: Publicity::Internal { 1779 attribute_location: Some(SrcSpan::new(0, 10)), 1780 }, 1781 origin: Default::default(), 1782 module: "the/module".into(), 1783 parameters: vec![], 1784 deprecation: Deprecation::NotDeprecated, 1785 documentation: None, 1786 }, 1787 )] 1788 .into(), 1789 types_value_constructors: HashMap::new(), 1790 values: HashMap::new(), 1791 accessors: HashMap::new(), 1792 line_numbers: LineNumbers::new(""), 1793 src_path: "some_path".into(), 1794 minimum_required_version: Version::new(0, 1, 0), 1795 type_aliases: HashMap::new(), 1796 documentation: Vec::new(), 1797 references: References::default(), 1798 inline_functions: HashMap::new(), 1799 }; 1800 assert_eq!(roundtrip(&module), module); 1801} 1802 1803#[test] 1804fn module_with_type_aliases() { 1805 let module = ModuleInterface { 1806 warnings: vec![], 1807 is_internal: false, 1808 package: "some_package".into(), 1809 origin: Origin::Src, 1810 name: "some_module".into(), 1811 types: HashMap::new(), 1812 types_value_constructors: HashMap::new(), 1813 values: HashMap::new(), 1814 accessors: HashMap::new(), 1815 line_numbers: LineNumbers::new(""), 1816 src_path: "some_path".into(), 1817 minimum_required_version: Version::new(0, 1, 0), 1818 type_aliases: [( 1819 "MyAlias".into(), 1820 TypeAliasConstructor { 1821 publicity: Publicity::Public, 1822 module: "some_module".into(), 1823 type_: prelude::int(), 1824 arity: 1, 1825 deprecation: Deprecation::NotDeprecated, 1826 documentation: Some("Some documentation".into()), 1827 origin: Default::default(), 1828 parameters: vec![type_::generic_var(0)], 1829 }, 1830 )] 1831 .into(), 1832 documentation: Vec::new(), 1833 contains_echo: false, 1834 1835 references: References::default(), 1836 inline_functions: HashMap::new(), 1837 }; 1838 assert_eq!(roundtrip(&module), module); 1839} 1840 1841#[test] 1842fn module_with_documentation() { 1843 let module = ModuleInterface { 1844 warnings: vec![], 1845 is_internal: false, 1846 package: "some_package".into(), 1847 origin: Origin::Src, 1848 name: "some_module".into(), 1849 types: HashMap::new(), 1850 types_value_constructors: HashMap::new(), 1851 values: HashMap::new(), 1852 accessors: HashMap::new(), 1853 line_numbers: LineNumbers::new(""), 1854 src_path: "some_path".into(), 1855 minimum_required_version: Version::new(0, 1, 0), 1856 type_aliases: HashMap::new(), 1857 documentation: vec![ 1858 "This is a line of documentation".into(), 1859 "And here is another".into(), 1860 "And finally, a third".into(), 1861 ], 1862 contains_echo: false, 1863 1864 references: References::default(), 1865 inline_functions: HashMap::new(), 1866 }; 1867 assert_eq!(roundtrip(&module), module); 1868} 1869 1870#[test] 1871fn module_with_opaque_type() { 1872 let module = ModuleInterface { 1873 warnings: vec![], 1874 is_internal: false, 1875 package: "some_package".into(), 1876 origin: Origin::Src, 1877 name: "a".into(), 1878 types: HashMap::new(), 1879 types_value_constructors: [( 1880 "SomeType".into(), 1881 TypeVariantConstructors { 1882 type_parameters_ids: vec![0, 1, 2], 1883 variants: vec![TypeValueConstructor { 1884 name: "One".into(), 1885 parameters: vec![], 1886 documentation: Some("Some documentation".into()), 1887 }], 1888 opaque: Opaque::Opaque, 1889 }, 1890 )] 1891 .into(), 1892 accessors: HashMap::new(), 1893 values: HashMap::new(), 1894 line_numbers: LineNumbers::new(""), 1895 src_path: "some_path".into(), 1896 minimum_required_version: Version::new(0, 1, 0), 1897 type_aliases: HashMap::new(), 1898 documentation: Vec::new(), 1899 contains_echo: false, 1900 references: References::default(), 1901 inline_functions: HashMap::new(), 1902 }; 1903 1904 assert_eq!(roundtrip(&module), module); 1905} 1906 1907#[test] 1908fn module_with_references() { 1909 let module = ModuleInterface { 1910 warnings: vec![], 1911 is_internal: false, 1912 package: "some_package".into(), 1913 origin: Origin::Src, 1914 name: "a".into(), 1915 types: HashMap::new(), 1916 types_value_constructors: HashMap::new(), 1917 accessors: HashMap::new(), 1918 values: HashMap::new(), 1919 line_numbers: LineNumbers::new(""), 1920 src_path: "some_path".into(), 1921 minimum_required_version: Version::new(0, 1, 0), 1922 type_aliases: HashMap::new(), 1923 documentation: Vec::new(), 1924 contains_echo: false, 1925 references: References { 1926 imported_modules: ["some_module".into(), "some_other_module".into()].into(), 1927 value_references: [ 1928 ( 1929 ("some_module".into(), "some_function".into()), 1930 vec![ 1931 Reference { 1932 location: SrcSpan::new(1, 6), 1933 kind: ReferenceKind::Definition, 1934 }, 1935 Reference { 1936 location: SrcSpan::new(7, 11), 1937 kind: ReferenceKind::Unqualified, 1938 }, 1939 ], 1940 ), 1941 ( 1942 ("some_other_module".into(), "some_constant".into()), 1943 vec![ 1944 Reference { 1945 location: SrcSpan::new(6, 9), 1946 kind: ReferenceKind::Import, 1947 }, 1948 Reference { 1949 location: SrcSpan::new(90, 108), 1950 kind: ReferenceKind::Unqualified, 1951 }, 1952 ], 1953 ), 1954 ( 1955 ("some_other_module".into(), "SomeTypeVariant".into()), 1956 vec![ 1957 Reference { 1958 location: SrcSpan::new(26, 35), 1959 kind: ReferenceKind::Qualified, 1960 }, 1961 Reference { 1962 location: SrcSpan::new(152, 204), 1963 kind: ReferenceKind::Qualified, 1964 }, 1965 Reference { 1966 location: SrcSpan::new(0, 8), 1967 kind: ReferenceKind::Qualified, 1968 }, 1969 ], 1970 ), 1971 ] 1972 .into(), 1973 type_references: [( 1974 ("some_other_module".into(), "TypeVariant".into()), 1975 vec![ 1976 Reference { 1977 location: SrcSpan::new(26, 35), 1978 kind: ReferenceKind::Qualified, 1979 }, 1980 Reference { 1981 location: SrcSpan::new(152, 204), 1982 kind: ReferenceKind::Unqualified, 1983 }, 1984 Reference { 1985 location: SrcSpan::new(0, 8), 1986 kind: ReferenceKind::Definition, 1987 }, 1988 ], 1989 )] 1990 .into(), 1991 }, 1992 inline_functions: HashMap::new(), 1993 }; 1994 1995 assert_eq!(roundtrip(&module), module); 1996}