1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tools.metalava.model.testsuite.annotationitem 18 19 import com.android.tools.metalava.model.AnnotationItem 20 import com.android.tools.metalava.model.ClassItem 21 import com.android.tools.metalava.model.getAttributeValue 22 import com.android.tools.metalava.model.getAttributeValues 23 import com.android.tools.metalava.model.testsuite.BaseModelTest 24 import com.android.tools.metalava.testing.java 25 import kotlin.test.assertEquals 26 import org.junit.Test 27 28 /** Common tests for implementations of [ClassItem]. */ 29 class CommonAnnotationItemTest : BaseModelTest() { 30 31 @Test annotation with annotation valuesnull32 fun `annotation with annotation values`() { 33 runCodebaseTest( 34 signature( 35 """ 36 // Signature format: 2.0 37 package test.pkg { 38 @test.pkg.Test.Anno( 39 annotationValue = @test.pkg.Other("other"), 40 annotationArrayValue = {@test.pkg.Other("other1"), @test.pkg.Other("other2")} 41 ) 42 public class Test { 43 ctor public Test(); 44 } 45 46 public @interface Test.Anno { 47 method public Other annotationValue(); 48 method public Other[] annotationArrayValue(); 49 } 50 } 51 """ 52 ), 53 java( 54 """ 55 package test.pkg; 56 57 @Test.Anno( 58 annotationValue = @test.pkg.Other("other"), 59 annotationArrayValue = {@test.pkg.Other("other1"), @test.pkg.Other("other2")} 60 ) 61 public class Test { 62 public Test() {} 63 64 public @interface Anno { 65 Other annotationValue(); 66 Other[] annotationArrayValue(); 67 } 68 } 69 70 @interface Other { 71 String value(); 72 } 73 """ 74 ), 75 ) { 76 val testClass = codebase.assertClass("test.pkg.Test") 77 val anno = testClass.modifiers.annotations().single() 78 79 val other = anno.getAttributeValue<AnnotationItem>("annotationValue")!! 80 assertEquals("test.pkg.Other", other.qualifiedName) 81 other.assertAttributeValue("value", "other") 82 83 val otherAsList = anno.getAttributeValues<AnnotationItem>("annotationValue") 84 assertEquals(listOf(other), otherAsList) 85 86 val others = anno.getAttributeValues<AnnotationItem>("annotationArrayValue")!! 87 assertEquals( 88 "other1, other2", 89 others.mapNotNull { it.getAttributeValue("value") }.joinToString() 90 ) 91 } 92 } 93 94 @Test annotation with boolean valuesnull95 fun `annotation with boolean values`() { 96 runCodebaseTest( 97 signature( 98 """ 99 // Signature format: 2.0 100 package test.pkg { 101 @test.pkg.Test.Anno( 102 booleanValue = true, 103 booleanArrayValue = {true, false}, 104 ) 105 public class Test { 106 ctor public Test(); 107 } 108 109 public @interface Test.Anno { 110 method public boolean booleanValue(); 111 method public boolean[] booleanArrayValue(); 112 } 113 } 114 """ 115 ), 116 java( 117 """ 118 package test.pkg; 119 120 @Test.Anno( 121 booleanValue = true, 122 booleanArrayValue = {true, false} 123 ) 124 public class Test { 125 public Test() {} 126 127 public @interface Anno { 128 boolean booleanValue(); 129 boolean[] booleanArrayValue(); 130 } 131 } 132 """ 133 ), 134 ) { 135 val testClass = codebase.assertClass("test.pkg.Test") 136 val anno = testClass.modifiers.annotations().single() 137 138 anno.assertAttributeValue("booleanValue", true) 139 anno.assertAttributeValues("booleanValue", listOf(true)) 140 anno.assertAttributeValues("booleanArrayValue", listOf(true, false)) 141 } 142 } 143 144 @Test annotation with char valuesnull145 fun `annotation with char values`() { 146 runCodebaseTest( 147 signature( 148 """ 149 // Signature format: 2.0 150 package test.pkg { 151 @test.pkg.Test.Anno( 152 charValue = 'a', 153 charArrayValue = {'a', 'b'}, 154 ) 155 public class Test { 156 ctor public Test(); 157 } 158 159 public @interface Test.Anno { 160 method public char charValue(); 161 method public char[] charArrayValue(); 162 } 163 } 164 """ 165 ), 166 java( 167 """ 168 package test.pkg; 169 170 @Test.Anno( 171 charValue = 'a', 172 charArrayValue = {'a', 'b'} 173 ) 174 public class Test { 175 public Test() {} 176 177 public @interface Anno { 178 char charValue(); 179 char[] charArrayValue(); 180 } 181 } 182 """ 183 ), 184 ) { 185 val testClass = codebase.assertClass("test.pkg.Test") 186 val anno = testClass.modifiers.annotations().single() 187 188 anno.assertAttributeValue("charValue", 'a') 189 anno.assertAttributeValues("charValue", listOf('a')) 190 anno.assertAttributeValues("charArrayValue", listOf('a', 'b')) 191 } 192 } 193 194 @Test annotation with class valuesnull195 fun `annotation with class values`() { 196 runCodebaseTest( 197 signature( 198 """ 199 // Signature format: 2.0 200 package test.pkg { 201 @test.pkg.Test.Anno( 202 classValue = test.pkg.Test, 203 classArrayValue = {test.pkg.Test, Anno} 204 ) 205 public class Test { 206 ctor public Test(); 207 } 208 209 public @interface Test.Anno { 210 method public Class<?> classValue(); 211 method public Class<?>[] classArrayValue(); 212 } 213 } 214 """ 215 ), 216 java( 217 """ 218 package test.pkg; 219 220 @Test.Anno( 221 classValue = Test.class, 222 classArrayValue = {Test.class, Anno.class} 223 ) 224 public class Test { 225 public Test() {} 226 227 public @interface Anno { 228 Class<?> classValue(); 229 Class<?>[] classArrayValue(); 230 } 231 } 232 """ 233 ), 234 ) { 235 val testClass = codebase.assertClass("test.pkg.Test") 236 val anno = testClass.modifiers.annotations().single() 237 238 // A class value can be retrieved as a string. 239 anno.assertAttributeValue("classValue", "test.pkg.Test") 240 anno.assertAttributeValues("classValue", listOf("test.pkg.Test")) 241 anno.assertAttributeValues("classArrayValue", listOf("test.pkg.Test", "Anno")) 242 } 243 } 244 245 @Test annotation with number valuesnull246 fun `annotation with number values`() { 247 runCodebaseTest( 248 signature( 249 """ 250 // Signature format: 2.0 251 package test.pkg { 252 @test.pkg.Test.Anno( 253 byteValue = 1, 254 byteArrayValue = {1, 2}, 255 256 doubleValue = 1.5, 257 doubleArrayValue = {1.5, 2.5}, 258 259 floatValue = 0.5F, 260 floatArrayValue = {0.5F, 1.5F}, 261 262 intValue = 1, 263 intArrayValue = {1, 2, 3}, 264 265 longValue = 2, 266 longArrayValue = {2, 4}, 267 268 shortValue = 3, 269 shortArrayValue = {3, 5}, 270 ) 271 public class Test { 272 ctor public Test(); 273 } 274 275 public @interface Test.Anno { 276 method public byte byteValue(); 277 method public byte[] byteArrayValue(); 278 279 method public double doubleValue(); 280 method public double[] doubleArrayValue(); 281 282 method public float floatValue(); 283 method public float[] floatArrayValue(); 284 285 method public int intValue(); 286 method public int[] intArrayValue(); 287 288 method public long longValue(); 289 method public long[] longArrayValue(); 290 291 method public short shortValue(); 292 method public short[] shortArrayValue(); 293 } 294 } 295 """ 296 ), 297 java( 298 """ 299 package test.pkg; 300 301 @Test.Anno( 302 byteValue = 1, 303 byteArrayValue = {1, 2}, 304 305 doubleValue = 1.5, 306 doubleArrayValue = {1.5, 2.5}, 307 308 floatValue = 0.5F, 309 floatArrayValue = {0.5F, 1.5F}, 310 311 intValue = 1, 312 intArrayValue = {1, 2, 3}, 313 314 longValue = 2L, 315 longArrayValue = {2L, 4L}, 316 317 shortValue = 3, 318 shortArrayValue = {3, 5} 319 ) 320 public class Test { 321 public Test() {} 322 323 public @interface Anno { 324 byte byteValue(); 325 byte[] byteArrayValue(); 326 327 double doubleValue(); 328 double[] doubleArrayValue(); 329 330 float floatValue(); 331 float[] floatArrayValue(); 332 333 int intValue(); 334 int[] intArrayValue(); 335 336 long longValue(); 337 long[] longArrayValue(); 338 339 short shortValue(); 340 short[] shortArrayValue(); 341 } 342 } 343 """ 344 ), 345 ) { 346 val testClass = codebase.assertClass("test.pkg.Test") 347 val anno = testClass.modifiers.annotations().single() 348 349 anno.assertAttributeValue("byteValue", 1.toByte()) 350 anno.assertAttributeValues("byteValue", byteArrayOf(1).toList()) 351 anno.assertAttributeValues("byteArrayValue", byteArrayOf(1, 2).toList()) 352 353 anno.assertAttributeValue("doubleValue", 1.5) 354 anno.assertAttributeValues("doubleValue", listOf(1.5)) 355 anno.assertAttributeValues("doubleArrayValue", listOf(1.5, 2.5)) 356 357 anno.assertAttributeValue("floatValue", 0.5F) 358 anno.assertAttributeValues("floatValue", listOf(0.5F)) 359 anno.assertAttributeValues("floatArrayValue", listOf(0.5F, 1.5F)) 360 361 anno.assertAttributeValue("intValue", 1) 362 anno.assertAttributeValues("intValue", listOf(1)) 363 anno.assertAttributeValues("intArrayValue", listOf(1, 2, 3)) 364 365 anno.assertAttributeValue("longValue", 2L) 366 anno.assertAttributeValues("longValue", listOf(2L)) 367 anno.assertAttributeValues("longArrayValue", listOf(2L, 4L)) 368 369 anno.assertAttributeValue("shortValue", 3.toShort()) 370 anno.assertAttributeValues("shortValue", listOf(3.toShort())) 371 anno.assertAttributeValues("shortArrayValue", shortArrayOf(3, 5).toList()) 372 } 373 } 374 375 @Test annotation with string valuesnull376 fun `annotation with string values`() { 377 runCodebaseTest( 378 signature( 379 """ 380 // Signature format: 2.0 381 package test.pkg { 382 @test.pkg.Test.Anno( 383 stringValue = "string", 384 stringArrayValue = {"string1", "string2"}, 385 ) 386 public class Test { 387 ctor public Test(); 388 } 389 390 public @interface Test.Anno { 391 method public String stringValue(); 392 method public String[] stringArrayValue(); 393 } 394 } 395 """ 396 ), 397 java( 398 """ 399 package test.pkg; 400 401 @Test.Anno( 402 stringValue = "string", 403 stringArrayValue = {"string1", "string2"} 404 ) 405 public class Test { 406 public Test() {} 407 408 public @interface Anno { 409 String stringValue(); 410 String[] stringArrayValue(); 411 } 412 } 413 """ 414 ), 415 ) { 416 val testClass = codebase.assertClass("test.pkg.Test") 417 val anno = testClass.modifiers.annotations().single() 418 419 anno.assertAttributeValue("stringValue", "string") 420 anno.assertAttributeValues("stringValue", listOf("string")) 421 anno.assertAttributeValues("stringArrayValue", listOf("string1", "string2")) 422 } 423 } 424 425 @Test annotation array values with single elementnull426 fun `annotation array values with single element`() { 427 runCodebaseTest( 428 signature( 429 """ 430 // Signature format: 2.0 431 package test.pkg { 432 @test.pkg.Test.Anno("string") 433 public class Test { 434 ctor public Test(); 435 } 436 437 public @interface Test.Anno { 438 method public String[] value(); 439 } 440 } 441 """ 442 ), 443 java( 444 """ 445 package test.pkg; 446 447 @Test.Anno("string") 448 public class Test { 449 public Test() {} 450 451 public @interface Anno { 452 String[] value(); 453 } 454 } 455 """ 456 ), 457 ) { 458 val testClass = codebase.assertClass("test.pkg.Test") 459 val anno = testClass.modifiers.annotations().single() 460 461 // It is expected to be not of array type 462 anno.assertAttributeValue("value", "string") 463 } 464 } 465 466 @Test annotation array values with single array elementnull467 fun `annotation array values with single array element`() { 468 runCodebaseTest( 469 signature( 470 """ 471 // Signature format: 2.0 472 package test.pkg { 473 @test.pkg.Test.Anno({"string"}) 474 public class Test { 475 ctor public Test(); 476 } 477 478 public @interface Test.Anno { 479 method public String[] value(); 480 } 481 } 482 """ 483 ), 484 java( 485 """ 486 package test.pkg; 487 488 @Test.Anno({"string"}) 489 public class Test { 490 public Test() {} 491 492 public @interface Anno { 493 String[] value(); 494 } 495 } 496 """ 497 ), 498 ) { 499 val testClass = codebase.assertClass("test.pkg.Test") 500 val anno = testClass.modifiers.annotations().single() 501 502 // It is expected to be of array type 503 anno.assertAttributeValues("value", listOf("string")) 504 } 505 } 506 507 @Test annotation with enum valuesnull508 fun `annotation with enum values`() { 509 runCodebaseTest( 510 signature( 511 """ 512 // Signature format: 2.0 513 package test.pkg { 514 @test.pkg.Test.Anno( 515 enumValue = test.pkg.Enum.ENUM1, 516 enumArrayValue = {test.pkg.Enum.ENUM1, test.pkg.Enum.ENUM2}, 517 ) 518 public class Test { 519 ctor public Test(); 520 } 521 522 public @interface Test.Anno { 523 method public Enum stringValue(); 524 method public Enum[] stringArrayValue(); 525 } 526 527 public enum Enum { 528 enum_constant public test.pkg.Enum ENUM1; 529 enum_constant public test.pkg.Enum ENUM2; 530 } 531 } 532 """ 533 ), 534 java( 535 """ 536 package test.pkg; 537 538 @Test.Anno( 539 enumValue = Enum.ENUM1, 540 enumArrayValue = {Enum.ENUM1,Enum.ENUM2} 541 ) 542 public class Test { 543 public Test() {} 544 545 public @interface Anno { 546 Enum enumValue(); 547 Enum[] enumArrayValue(); 548 } 549 } 550 551 public enum Enum { 552 ENUM1, 553 ENUM2, 554 } 555 """ 556 ), 557 ) { 558 val testClass = codebase.assertClass("test.pkg.Test") 559 val anno = testClass.modifiers.annotations().single() 560 561 anno.assertAttributeValue("enumValue", "test.pkg.Enum.ENUM1") 562 anno.assertAttributeValues("enumValue", listOf("test.pkg.Enum.ENUM1")) 563 anno.assertAttributeValues( 564 "enumArrayValue", 565 listOf("test.pkg.Enum.ENUM1", "test.pkg.Enum.ENUM2") 566 ) 567 } 568 } 569 570 @Test annotation with constant literal valuesnull571 fun `annotation with constant literal values`() { 572 runCodebaseTest( 573 signature( 574 """ 575 // Signature format: 2.0 576 package test.pkg { 577 @test.pkg.Test.Anno(test.pkg.Test.FIELD) 578 public class Test { 579 ctor public Test(); 580 field public static final int FIELD = 5; 581 } 582 583 public @interface Test.Anno { 584 method public Int value(); 585 } 586 } 587 """ 588 ), 589 java( 590 """ 591 package test.pkg; 592 593 @Test.Anno(Test.FIELD) 594 public class Test { 595 public Test() {} 596 597 public static final int FIELD = 5; 598 599 public @interface Anno { 600 int value(); 601 } 602 } 603 """ 604 ), 605 ) { 606 val testClass = codebase.assertClass("test.pkg.Test") 607 val anno = testClass.modifiers.annotations().single() 608 609 anno.assertAttributeValue("value", 5) 610 } 611 } 612 613 @Test annotation toSource() with annotation valuesnull614 fun `annotation toSource() with annotation values`() { 615 runCodebaseTest( 616 signature( 617 """ 618 // Signature format: 2.0 619 package test.pkg { 620 @test.pkg.Test.Anno( 621 annotationValue = @test.pkg.Other("other"), 622 annotationArrayValue = {@test.pkg.Other("other1"), @test.pkg.Other("other2")} 623 ) 624 public class Test { 625 ctor public Test(); 626 } 627 628 public @interface Test.Anno { 629 method public Other annotationValue(); 630 method public Other[] annotationArrayValue(); 631 } 632 } 633 """ 634 ), 635 java( 636 """ 637 package test.pkg; 638 639 @Test.Anno( 640 annotationValue = @test.pkg.Other("other"), 641 annotationArrayValue = {@test.pkg.Other("other1"), @test.pkg.Other("other2")} 642 ) 643 public class Test { 644 public Test() {} 645 646 public @interface Anno { 647 Other annotationValue(); 648 Other[] annotationArrayValue(); 649 } 650 } 651 652 @interface Other { 653 String value(); 654 } 655 """ 656 ), 657 ) { 658 val testClass = codebase.assertClass("test.pkg.Test") 659 val anno = testClass.modifiers.annotations().single() 660 661 val toSource = 662 "@test.pkg.Test.Anno(annotationValue=@test.pkg.Other(\"other\"), annotationArrayValue={@test.pkg.Other(\"other1\"), @test.pkg.Other(\"other2\")})" 663 assertEquals(toSource, anno.toSource()) 664 } 665 } 666 667 @Test annotation toSource() with boolean valuesnull668 fun `annotation toSource() with boolean values`() { 669 runCodebaseTest( 670 signature( 671 """ 672 // Signature format: 2.0 673 package test.pkg { 674 @test.pkg.Test.Anno( 675 booleanValue = true, 676 booleanArrayValue = {true, false}, 677 ) 678 public class Test { 679 ctor public Test(); 680 } 681 682 public @interface Test.Anno { 683 method public boolean booleanValue(); 684 method public boolean[] booleanArrayValue(); 685 } 686 } 687 """ 688 ), 689 java( 690 """ 691 package test.pkg; 692 693 @Test.Anno( 694 booleanValue = true, 695 booleanArrayValue = {true, false} 696 ) 697 public class Test { 698 public Test() {} 699 700 public @interface Anno { 701 boolean booleanValue(); 702 boolean[] booleanArrayValue(); 703 } 704 } 705 """ 706 ), 707 ) { 708 val testClass = codebase.assertClass("test.pkg.Test") 709 val anno = testClass.modifiers.annotations().single() 710 711 val toSource = "@test.pkg.Test.Anno(booleanValue=true, booleanArrayValue={true, false})" 712 assertEquals(toSource, anno.toSource()) 713 } 714 } 715 716 @Test annotation toSource() with char valuesnull717 fun `annotation toSource() with char values`() { 718 runCodebaseTest( 719 signature( 720 """ 721 // Signature format: 2.0 722 package test.pkg { 723 @test.pkg.Test.Anno( 724 charValue = 'a', 725 charArrayValue = {'a', '\uFF00'}, 726 ) 727 public class Test { 728 ctor public Test(); 729 } 730 731 public @interface Test.Anno { 732 method public char charValue(); 733 method public char[] charArrayValue(); 734 } 735 } 736 """ 737 ), 738 java( 739 """ 740 package test.pkg; 741 742 @Test.Anno( 743 charValue = 'a', 744 charArrayValue = {'a', '\uFF00'} 745 ) 746 public class Test { 747 public Test() {} 748 749 public @interface Anno { 750 char charValue(); 751 char[] charArrayValue(); 752 } 753 } 754 """ 755 ), 756 ) { 757 val testClass = codebase.assertClass("test.pkg.Test") 758 val anno = testClass.modifiers.annotations().single() 759 760 val toSource = "@test.pkg.Test.Anno(charValue='a', charArrayValue={'a', '\\uff00'})" 761 assertEquals(toSource, anno.toSource()) 762 } 763 } 764 765 @Test annotation toSource() with class valuesnull766 fun `annotation toSource() with class values`() { 767 runCodebaseTest( 768 signature( 769 """ 770 // Signature format: 2.0 771 package test.pkg { 772 @test.pkg.Test.Anno( 773 classValue = test.pkg.Test, 774 classArrayValue = {test.pkg.Test, Anno} 775 ) 776 public class Test { 777 ctor public Test(); 778 } 779 780 public @interface Test.Anno { 781 method public Class<?> classValue(); 782 method public Class<?>[] classArrayValue(); 783 } 784 } 785 """ 786 ), 787 java( 788 """ 789 package test.pkg; 790 791 @Test.Anno( 792 classValue = Test.class, 793 classArrayValue = {Test.class, Anno.class} 794 ) 795 public class Test { 796 public Test() {} 797 798 public @interface Anno { 799 Class<?> classValue(); 800 Class<?>[] classArrayValue(); 801 } 802 } 803 """ 804 ), 805 ) { 806 val testClass = codebase.assertClass("test.pkg.Test") 807 val anno = testClass.modifiers.annotations().single() 808 809 val toSource = 810 "@test.pkg.Test.Anno(classValue=Test.class, classArrayValue={Test.class, Anno.class})" 811 assertEquals(toSource, anno.toSource()) 812 } 813 } 814 815 @Test annotation toSource() with number valuesnull816 fun `annotation toSource() with number values`() { 817 runCodebaseTest( 818 signature( 819 """ 820 // Signature format: 2.0 821 package test.pkg { 822 @test.pkg.Test.Anno( 823 byteValue = 1, 824 byteArrayValue = {1, 2}, 825 826 doubleValue = 1.5, 827 doubleArrayValue = {1.5, 2.5}, 828 829 floatValue = 0.5F, 830 floatArrayValue = {0.5F, 1.5F}, 831 832 intValue = 1, 833 intArrayValue = {1, 2, 3}, 834 835 longValue = 2, 836 longArrayValue = {2, 4}, 837 838 shortValue = 3, 839 shortArrayValue = {3, 5}, 840 ) 841 public class Test { 842 ctor public Test(); 843 } 844 845 public @interface Test.Anno { 846 method public byte byteValue(); 847 method public byte[] byteArrayValue(); 848 849 method public double doubleValue(); 850 method public double[] doubleArrayValue(); 851 852 method public float floatValue(); 853 method public float[] floatArrayValue(); 854 855 method public int intValue(); 856 method public int[] intArrayValue(); 857 858 method public long longValue(); 859 method public long[] longArrayValue(); 860 861 method public short shortValue(); 862 method public short[] shortArrayValue(); 863 } 864 } 865 """ 866 ), 867 java( 868 """ 869 package test.pkg; 870 871 @Test.Anno( 872 byteValue = 1, 873 byteArrayValue = {1, 2}, 874 875 doubleValue = 1.5, 876 doubleArrayValue = {1.5, 2.5}, 877 878 floatValue = 0.5F, 879 floatArrayValue = {0.5F, 1.5F}, 880 881 intValue = 1, 882 intArrayValue = {1, 2, 3}, 883 884 longValue = 2L, 885 longArrayValue = {2L, 4L}, 886 887 shortValue = 3, 888 shortArrayValue = {3, 5} 889 ) 890 public class Test { 891 public Test() {} 892 893 public @interface Anno { 894 byte byteValue(); 895 byte[] byteArrayValue(); 896 897 double doubleValue(); 898 double[] doubleArrayValue(); 899 900 float floatValue(); 901 float[] floatArrayValue(); 902 903 int intValue(); 904 int[] intArrayValue(); 905 906 long longValue(); 907 long[] longArrayValue(); 908 909 short shortValue(); 910 short[] shortArrayValue(); 911 } 912 } 913 """ 914 ), 915 ) { 916 val testClass = codebase.assertClass("test.pkg.Test") 917 val anno = testClass.modifiers.annotations().single() 918 919 val toSource = 920 "@test.pkg.Test.Anno(byteValue=1, byteArrayValue={1, 2}, doubleValue=1.5, doubleArrayValue={1.5, 2.5}, floatValue=0.5f, floatArrayValue={0.5f, 1.5f}, intValue=1, intArrayValue={1, 2, 3}, longValue=2L, longArrayValue={2L, 4L}, shortValue=3, shortArrayValue={3, 5})" 921 assertEquals(toSource, anno.toSource()) 922 } 923 } 924 925 @Test annotation toSource() with string valuesnull926 fun `annotation toSource() with string values`() { 927 runCodebaseTest( 928 signature( 929 """ 930 // Signature format: 2.0 931 package test.pkg { 932 @test.pkg.Test.Anno( 933 stringValue = "string", 934 stringArrayValue = {"string1", "string2"}, 935 ) 936 public class Test { 937 ctor public Test(); 938 } 939 940 public @interface Test.Anno { 941 method public String stringValue(); 942 method public String[] stringArrayValue(); 943 } 944 } 945 """ 946 ), 947 java( 948 """ 949 package test.pkg; 950 951 @Test.Anno( 952 stringValue = "string", 953 stringArrayValue = {"string1", "string2"} 954 ) 955 public class Test { 956 public Test() {} 957 958 public @interface Anno { 959 String stringValue(); 960 String[] stringArrayValue(); 961 } 962 } 963 """ 964 ), 965 ) { 966 val testClass = codebase.assertClass("test.pkg.Test") 967 val anno = testClass.modifiers.annotations().single() 968 969 val toSource = 970 "@test.pkg.Test.Anno(stringValue=\"string\", stringArrayValue={\"string1\", \"string2\"})" 971 assertEquals(toSource, anno.toSource()) 972 } 973 } 974 975 @Test annotation toSource() for array values with single elementnull976 fun `annotation toSource() for array values with single element`() { 977 runCodebaseTest( 978 signature( 979 """ 980 // Signature format: 2.0 981 package test.pkg { 982 @test.pkg.Test.Anno("string") 983 public class Test { 984 ctor public Test(); 985 } 986 987 public @interface Test.Anno { 988 method public String[] value(); 989 } 990 } 991 """ 992 ), 993 java( 994 """ 995 package test.pkg; 996 997 @Test.Anno("string") 998 public class Test { 999 public Test() {} 1000 1001 public @interface Anno { 1002 String[] value(); 1003 } 1004 } 1005 """ 1006 ), 1007 ) { 1008 val testClass = codebase.assertClass("test.pkg.Test") 1009 val anno = testClass.modifiers.annotations().single() 1010 1011 val toSource = "@test.pkg.Test.Anno(\"string\")" 1012 assertEquals(toSource, anno.toSource()) 1013 } 1014 } 1015 1016 @Test annotation toSource() for array values with single array elementnull1017 fun `annotation toSource() for array values with single array element`() { 1018 runCodebaseTest( 1019 signature( 1020 """ 1021 // Signature format: 2.0 1022 package test.pkg { 1023 @test.pkg.Test.Anno({"string"}) 1024 public class Test { 1025 ctor public Test(); 1026 } 1027 1028 public @interface Test.Anno { 1029 method public String[] value(); 1030 } 1031 } 1032 """ 1033 ), 1034 java( 1035 """ 1036 package test.pkg; 1037 1038 @Test.Anno({"string"}) 1039 public class Test { 1040 public Test() {} 1041 1042 public @interface Anno { 1043 String[] value(); 1044 } 1045 } 1046 """ 1047 ), 1048 ) { 1049 val testClass = codebase.assertClass("test.pkg.Test") 1050 val anno = testClass.modifiers.annotations().single() 1051 1052 val toSource = "@test.pkg.Test.Anno({\"string\"})" 1053 assertEquals(toSource, anno.toSource()) 1054 } 1055 } 1056 1057 @Test annotation toSource() with enum valuesnull1058 fun `annotation toSource() with enum values`() { 1059 runCodebaseTest( 1060 signature( 1061 """ 1062 // Signature format: 2.0 1063 package test.pkg { 1064 @test.pkg.Test.Anno( 1065 enumValue = test.pkg.Enum.ENUM1, 1066 enumArrayValue = {test.pkg.Enum.ENUM1, test.pkg.Enum.ENUM2}, 1067 ) 1068 public class Test { 1069 ctor public Test(); 1070 } 1071 1072 public @interface Test.Anno { 1073 method public Enum stringValue(); 1074 method public Enum[] stringArrayValue(); 1075 } 1076 1077 public enum Enum { 1078 enum_constant public test.pkg.Enum ENUM1; 1079 enum_constant public test.pkg.Enum ENUM2; 1080 } 1081 } 1082 """ 1083 ), 1084 java( 1085 """ 1086 package test.pkg; 1087 1088 @Test.Anno( 1089 enumValue = Enum.ENUM1, 1090 enumArrayValue = {Enum.ENUM1,Enum.ENUM2} 1091 ) 1092 public class Test { 1093 public Test() {} 1094 1095 public @interface Anno { 1096 Enum enumValue(); 1097 Enum[] enumArrayValue(); 1098 } 1099 } 1100 1101 public enum Enum { 1102 ENUM1, 1103 ENUM2, 1104 } 1105 """ 1106 ), 1107 ) { 1108 val testClass = codebase.assertClass("test.pkg.Test") 1109 val anno = testClass.modifiers.annotations().single() 1110 1111 val toSource = 1112 "@test.pkg.Test.Anno(enumValue=test.pkg.Enum.ENUM1, enumArrayValue={test.pkg.Enum.ENUM1, test.pkg.Enum.ENUM2})" 1113 assertEquals(toSource, anno.toSource()) 1114 } 1115 } 1116 1117 @Test annotation toSource() with constant literal valuesnull1118 fun `annotation toSource() with constant literal values`() { 1119 runCodebaseTest( 1120 signature( 1121 """ 1122 // Signature format: 2.0 1123 package test.pkg { 1124 @test.pkg.Test.Anno(test.pkg.Test.FIELD) 1125 public class Test { 1126 ctor public Test(); 1127 field public static final int FIELD = 5; 1128 } 1129 1130 public @interface Test.Anno { 1131 method public Int value(); 1132 } 1133 } 1134 """ 1135 ), 1136 java( 1137 """ 1138 package test.pkg; 1139 1140 @Test.Anno(Test.FIELD) 1141 public class Test { 1142 public Test() {} 1143 1144 public static final int FIELD = 5; 1145 1146 public @interface Anno { 1147 int value(); 1148 } 1149 } 1150 """ 1151 ), 1152 ) { 1153 val testClass = codebase.assertClass("test.pkg.Test") 1154 val anno = testClass.modifiers.annotations().single() 1155 1156 val toSource = "@test.pkg.Test.Anno(test.pkg.Test.FIELD)" 1157 assertEquals(toSource, anno.toSource()) 1158 } 1159 } 1160 1161 @Test annotation toSource() with compound expression valuesnull1162 fun `annotation toSource() with compound expression values`() { 1163 runCodebaseTest( 1164 signature( 1165 """ 1166 // Signature format: 2.0 1167 package test.pkg { 1168 @test.pkg.Test.Anno(value=test.pkg.Test.FIELD1+test.pkg.Test.FIELD2, name="FirstName"+"LastName", id=1+test.pkg.FIELD1) 1169 public class Test { 1170 ctor public Test(); 1171 field public static final int FIELD1 = 5; 1172 field public static final int FIELD2 = 7; 1173 } 1174 1175 public @interface Test.Anno { 1176 method public int value(); 1177 method public String name(); 1178 method public int id(); 1179 } 1180 } 1181 """ 1182 ), 1183 java( 1184 """ 1185 package test.pkg; 1186 1187 @Test.Anno(value = Test.FIELD1+Test.FIELD2, name = "FirstName"+"LastName", id = 1+Test.FIELD1) 1188 public class Test { 1189 public Test() {} 1190 1191 public static final int FIELD1 = 5; 1192 public static final int FIELD2 = 7; 1193 1194 public @interface Anno { 1195 int value(); 1196 String name(); 1197 int id(); 1198 } 1199 } 1200 """ 1201 ), 1202 ) { 1203 val testClass = codebase.assertClass("test.pkg.Test") 1204 val anno = testClass.modifiers.annotations().single() 1205 1206 anno.assertAttributeValue("value", 12) 1207 anno.assertAttributeValue("name", "FirstNameLastName") 1208 anno.assertAttributeValue("id", 6) 1209 val toSource = 1210 "@test.pkg.Test.Anno(value=test.pkg.Test.FIELD1 + test.pkg.Test.FIELD2, name=\"FirstName\" + \"LastName\", id=1 + test.pkg.Test.FIELD1)" 1211 assertEquals(toSource, anno.toSource()) 1212 } 1213 } 1214 1215 @Test annotation with negative number valuesnull1216 fun `annotation with negative number values`() { 1217 runCodebaseTest( 1218 signature( 1219 """ 1220 // Signature format: 2.0 1221 package test.pkg { 1222 @test.pkg.Test.Anno( 1223 doubleValue = -1.5, 1224 floatValue = -0.5F, 1225 intValue = -1, 1226 longValue = -2, 1227 shortValue = -3, 1228 ) 1229 public class Test { 1230 ctor public Test(); 1231 } 1232 1233 public @interface Test.Anno { 1234 method public double doubleValue(); 1235 method public float floatValue(); 1236 method public int intValue(); 1237 method public long longValue(); 1238 method public short shortValue(); 1239 } 1240 } 1241 """ 1242 ), 1243 java( 1244 """ 1245 package test.pkg; 1246 1247 @Test.Anno( 1248 doubleValue = -1.5, 1249 floatValue = -0.5F, 1250 intValue = -1, 1251 longValue = -2L, 1252 shortValue = -3, 1253 ) 1254 public class Test { 1255 public Test() {} 1256 1257 public @interface Anno { 1258 double doubleValue(); 1259 float floatValue(); 1260 int intValue(); 1261 long longValue(); 1262 short shortValue(); 1263 } 1264 } 1265 """ 1266 ), 1267 ) { 1268 val testClass = codebase.assertClass("test.pkg.Test") 1269 val anno = testClass.modifiers.annotations().single() 1270 1271 anno.assertAttributeValue("doubleValue", -1.5) 1272 anno.assertAttributeValue("floatValue", -0.5F) 1273 anno.assertAttributeValue("intValue", -1) 1274 anno.assertAttributeValue("longValue", -2L) 1275 anno.assertAttributeValue("shortValue", -3.toShort()) 1276 1277 val toSource = 1278 "@test.pkg.Test.Anno(doubleValue=-1.5, floatValue=-0.5F, intValue=0xffffffff, longValue=-2L, shortValue=0xfffffffd)" 1279 assertEquals(toSource, anno.toSource()) 1280 } 1281 } 1282 1283 @Test annotation with type cast valuesnull1284 fun `annotation with type cast values`() { 1285 runCodebaseTest( 1286 signature( 1287 """ 1288 // Signature format: 2.0 1289 package test.pkg { 1290 @test.pkg.Test.Anno((int)5.6) 1291 public class Test { 1292 ctor public Test(); 1293 } 1294 1295 public @interface Test.Anno { 1296 method public int value(); 1297 } 1298 } 1299 """ 1300 ), 1301 java( 1302 """ 1303 package test.pkg; 1304 1305 @Test.Anno((int)5.6f) 1306 public class Test { 1307 public Test() {} 1308 1309 public @interface Anno { 1310 int value(); 1311 } 1312 } 1313 """ 1314 ), 1315 ) { 1316 val testClass = codebase.assertClass("test.pkg.Test") 1317 val anno = testClass.modifiers.annotations().single() 1318 1319 anno.assertAttributeValue("value", 5) 1320 assertEquals("@test.pkg.Test.Anno(0x5)", anno.toSource()) 1321 } 1322 } 1323 1324 @Test annotation with infinity valuesnull1325 fun `annotation with infinity values`() { 1326 runCodebaseTest( 1327 signature( 1328 """ 1329 // Signature format: 2.0 1330 package test.pkg { 1331 @test.pkg.Test.Anno({java.lang.Double.POSITIVE_INFINITY,java.lang.Double.POSITIVE_INFINITY}) 1332 public class Test { 1333 ctor public Test(); 1334 } 1335 1336 public @interface Test.Anno { 1337 method public double [] value(); 1338 } 1339 } 1340 """ 1341 ), 1342 java( 1343 """ 1344 package test.pkg; 1345 1346 @Test.Anno({Double.POSITIVE_INFINITY,Double.NEGATIVE_INFINITY}) 1347 public class Test { 1348 public Test() {} 1349 1350 public @interface Anno { 1351 double [] value(); 1352 } 1353 } 1354 """ 1355 ), 1356 ) { 1357 val testClass = codebase.assertClass("test.pkg.Test") 1358 val anno = testClass.modifiers.annotations().single() 1359 1360 anno.assertAttributeValues("value", listOf(2147483647, -2147483648)) 1361 assertEquals( 1362 "@test.pkg.Test.Anno({java.lang.Double.POSITIVE_INFINITY, java.lang.Double.NEGATIVE_INFINITY})", 1363 anno.toSource() 1364 ) 1365 } 1366 } 1367 assertAttributeValuenull1368 inline fun <reified T : Any> AnnotationItem.assertAttributeValue( 1369 attributeName: String, 1370 expected: T 1371 ) { 1372 assertEquals( 1373 expected, 1374 getAttributeValue(attributeName), 1375 message = "getAttributeValue($attributeName)" 1376 ) 1377 } 1378 assertAttributeValuesnull1379 inline fun <reified T : Any> AnnotationItem.assertAttributeValues( 1380 attributeName: String, 1381 expected: List<T> 1382 ) { 1383 assertEquals( 1384 expected, 1385 getAttributeValues(attributeName), 1386 message = "getAttributeValues($attributeName)" 1387 ) 1388 } 1389 } 1390