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