1 /* 2 * Copyright 2019 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 android.processor.view.inspector.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertNotEquals; 21 import static org.junit.Assert.assertNull; 22 import static org.junit.Assert.assertTrue; 23 import static org.junit.Assert.fail; 24 25 import android.R; 26 import android.content.res.Resources; 27 import android.graphics.Color; 28 import android.view.inspector.InspectableProperty; 29 import android.view.inspector.InspectableProperty.EnumEntry; 30 import android.view.inspector.InspectableProperty.ValueType; 31 import android.view.inspector.InspectionCompanion; 32 33 import androidx.annotation.AnimRes; 34 import androidx.annotation.AnimatorRes; 35 import androidx.annotation.AnyRes; 36 import androidx.annotation.ArrayRes; 37 import androidx.annotation.BoolRes; 38 import androidx.annotation.ColorInt; 39 import androidx.annotation.ColorLong; 40 import androidx.annotation.DimenRes; 41 import androidx.annotation.DrawableRes; 42 import androidx.annotation.FontRes; 43 import androidx.annotation.IdRes; 44 import androidx.annotation.IntegerRes; 45 import androidx.annotation.InterpolatorRes; 46 import androidx.annotation.LayoutRes; 47 import androidx.annotation.MenuRes; 48 import androidx.annotation.NavigationRes; 49 import androidx.annotation.PluralsRes; 50 import androidx.annotation.RawRes; 51 import androidx.annotation.StringRes; 52 import androidx.annotation.StyleRes; 53 import androidx.annotation.StyleableRes; 54 import androidx.annotation.TransitionRes; 55 import androidx.annotation.XmlRes; 56 import androidx.test.filters.SmallTest; 57 import androidx.test.runner.AndroidJUnit4; 58 59 import org.junit.Before; 60 import org.junit.Test; 61 import org.junit.runner.RunWith; 62 63 import java.util.HashSet; 64 import java.util.Objects; 65 import java.util.Random; 66 import java.util.Set; 67 68 /** 69 * Behavioral tests for {@link android.processor.view.inspector.PlatformInspectableProcessor}. 70 */ 71 @SmallTest 72 @RunWith(AndroidJUnit4.class) 73 public class PlatformInspectableProcessorTest { 74 private Random mRandom; 75 private TestPropertyMapper mPropertyMapper; 76 private TestPropertyReader mPropertyReader; 77 78 @Before setup()79 public void setup() { 80 mRandom = new Random(); 81 mPropertyMapper = new TestPropertyMapper(); 82 mPropertyReader = new TestPropertyReader(mPropertyMapper); 83 } 84 85 class IntPropertyTest { 86 private final int mValue; 87 IntPropertyTest(Random seed)88 IntPropertyTest(Random seed) { 89 mValue = seed.nextInt(); 90 } 91 92 @InspectableProperty getValue()93 public int getValue() { 94 return mValue; 95 } 96 } 97 98 @Test testMapAndReadInt()99 public void testMapAndReadInt() { 100 IntPropertyTest node = new IntPropertyTest(mRandom); 101 mapAndRead(node); 102 assertEquals(node.getValue(), mPropertyReader.get("value")); 103 } 104 105 @Test testInferredAttributeId()106 public void testInferredAttributeId() { 107 loadCompanion(IntPropertyTest.class).mapProperties(mPropertyMapper); 108 assertEquals(R.attr.value, mPropertyMapper.getAttributeId("value")); 109 } 110 111 @Test(expected = InspectionCompanion.UninitializedPropertyMapException.class) testUninitializedPropertyMap()112 public void testUninitializedPropertyMap() { 113 IntPropertyTest node = new IntPropertyTest(mRandom); 114 loadCompanion(IntPropertyTest.class).readProperties(node, mPropertyReader); 115 } 116 117 class NamedPropertyTest { 118 private final int mValue; 119 NamedPropertyTest(Random seed)120 NamedPropertyTest(Random seed) { 121 mValue = seed.nextInt(); 122 } 123 124 @InspectableProperty(name = "myNamedValue", hasAttributeId = false) getValue()125 public int getValue() { 126 return mValue; 127 } 128 } 129 130 @Test testNamedProperty()131 public void testNamedProperty() { 132 NamedPropertyTest node = new NamedPropertyTest(mRandom); 133 mapAndRead(node); 134 assertEquals(0, mPropertyMapper.getId("value")); 135 assertEquals(node.getValue(), mPropertyReader.get("myNamedValue")); 136 } 137 138 class HasAttributeIdFalseTest { 139 @InspectableProperty(hasAttributeId = false) getValue()140 public int getValue() { 141 return 0; 142 } 143 } 144 145 @Test testHasAttributeIdFalse()146 public void testHasAttributeIdFalse() { 147 loadCompanion(HasAttributeIdFalseTest.class).mapProperties(mPropertyMapper); 148 assertEquals(Resources.ID_NULL, mPropertyMapper.getAttributeId("value")); 149 } 150 151 class AttributeIdEqualsTest { 152 @InspectableProperty(attributeId = 0xdecafbad) getValue()153 public int getValue() { 154 return 0; 155 } 156 } 157 158 @Test testAttributeIdEquals()159 public void testAttributeIdEquals() { 160 loadCompanion(AttributeIdEqualsTest.class).mapProperties(mPropertyMapper); 161 assertEquals(0xdecafbad, mPropertyMapper.getAttributeId("value")); 162 } 163 164 class InferredPropertyNameTest { 165 private final int mValueA; 166 private final int mValueB; 167 private final int mValueC; 168 InferredPropertyNameTest(Random seed)169 InferredPropertyNameTest(Random seed) { 170 mValueA = seed.nextInt(); 171 mValueB = seed.nextInt(); 172 mValueC = seed.nextInt(); 173 } 174 175 @InspectableProperty(hasAttributeId = false) getValueA()176 public int getValueA() { 177 return mValueA; 178 } 179 180 @InspectableProperty(hasAttributeId = false) isValueB()181 public int isValueB() { 182 return mValueB; 183 } 184 185 @InspectableProperty(hasAttributeId = false) obtainValueC()186 public int obtainValueC() { 187 return mValueC; 188 } 189 } 190 191 @Test testInferredPropertyName()192 public void testInferredPropertyName() { 193 InferredPropertyNameTest node = new InferredPropertyNameTest(mRandom); 194 mapAndRead(node); 195 assertEquals(node.getValueA(), mPropertyReader.get("valueA")); 196 assertEquals(node.isValueB(), mPropertyReader.get("isValueB")); 197 assertEquals(node.obtainValueC(), mPropertyReader.get("obtainValueC")); 198 } 199 200 class InferredBooleanNameTest { 201 private final boolean mValueA; 202 private final boolean mValueB; 203 private final boolean mValueC; 204 InferredBooleanNameTest(Random seed)205 InferredBooleanNameTest(Random seed) { 206 mValueA = seed.nextBoolean(); 207 mValueB = seed.nextBoolean(); 208 mValueC = seed.nextBoolean(); 209 } 210 211 @InspectableProperty(hasAttributeId = false) getValueA()212 public boolean getValueA() { 213 return mValueA; 214 } 215 216 @InspectableProperty(hasAttributeId = false) isValueB()217 public boolean isValueB() { 218 return mValueB; 219 } 220 221 @InspectableProperty(hasAttributeId = false) obtainValueC()222 public boolean obtainValueC() { 223 return mValueC; 224 } 225 } 226 227 @Test testInferredBooleanName()228 public void testInferredBooleanName() { 229 InferredBooleanNameTest node = new InferredBooleanNameTest(mRandom); 230 mapAndRead(node); 231 assertEquals(node.getValueA(), mPropertyReader.get("valueA")); 232 assertEquals(node.isValueB(), mPropertyReader.get("valueB")); 233 assertEquals(node.obtainValueC(), mPropertyReader.get("obtainValueC")); 234 } 235 236 class ColorTest { 237 private final int mColorInt; 238 private final long mColorLong; 239 240 private final Color mColorObject; 241 ColorTest(Random seed)242 ColorTest(Random seed) { 243 mColorInt = seed.nextInt(); 244 mColorLong = Color.pack(seed.nextInt()); 245 mColorObject = Color.valueOf(seed.nextInt()); 246 } 247 248 @InspectableProperty(hasAttributeId = false) 249 @ColorInt getColorInt()250 public int getColorInt() { 251 return mColorInt; 252 } 253 254 @InspectableProperty(hasAttributeId = false) 255 @ColorLong getColorLong()256 public long getColorLong() { 257 return mColorLong; 258 } 259 260 @InspectableProperty(hasAttributeId = false) getColorObject()261 public Color getColorObject() { 262 return mColorObject; 263 } 264 } 265 266 @Test testColorTypeInference()267 public void testColorTypeInference() { 268 ColorTest node = new ColorTest(mRandom); 269 mapAndRead(node); 270 assertEquals(node.getColorInt(), mPropertyReader.get("colorInt")); 271 assertEquals(node.getColorLong(), mPropertyReader.get("colorLong")); 272 assertEquals(node.getColorObject(), mPropertyReader.get("colorObject")); 273 assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("colorInt")); 274 assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("colorLong")); 275 assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("colorObject")); 276 } 277 278 class ValueTypeTest { 279 private final int mColor; 280 private final int mGravity; 281 private final int mValue; 282 ValueTypeTest(Random seed)283 ValueTypeTest(Random seed) { 284 mColor = seed.nextInt(); 285 mGravity = seed.nextInt(); 286 mValue = seed.nextInt(); 287 } 288 289 @InspectableProperty(valueType = ValueType.COLOR) getColor()290 public int getColor() { 291 return mColor; 292 } 293 294 @InspectableProperty(valueType = ValueType.GRAVITY) getGravity()295 public int getGravity() { 296 return mGravity; 297 } 298 299 @InspectableProperty(valueType = ValueType.NONE) 300 @ColorInt getValue()301 public int getValue() { 302 return mValue; 303 } 304 } 305 306 @Test testValueTypeEquals()307 public void testValueTypeEquals() { 308 ValueTypeTest node = new ValueTypeTest(mRandom); 309 mapAndRead(node); 310 assertEquals(node.getColor(), mPropertyReader.get("color")); 311 assertEquals(node.getGravity(), mPropertyReader.get("gravity")); 312 assertEquals(node.getValue(), mPropertyReader.get("value")); 313 assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("color")); 314 assertEquals(ValueType.GRAVITY, mPropertyMapper.getValueType("gravity")); 315 assertEquals(ValueType.NONE, mPropertyMapper.getValueType("value")); 316 } 317 318 class PrimitivePropertiesTest { 319 private final boolean mBoolean; 320 private final byte mByte; 321 private final char mChar; 322 private final double mDouble; 323 private final float mFloat; 324 private final int mInt; 325 private final long mLong; 326 private final short mShort; 327 PrimitivePropertiesTest(Random seed)328 PrimitivePropertiesTest(Random seed) { 329 mBoolean = seed.nextBoolean(); 330 mByte = (byte) seed.nextInt(); 331 mChar = randomLetter(seed); 332 mDouble = seed.nextDouble(); 333 mFloat = seed.nextFloat(); 334 mInt = seed.nextInt(); 335 mLong = seed.nextLong(); 336 mShort = (short) seed.nextInt(); 337 } 338 339 @InspectableProperty(hasAttributeId = false) getBoolean()340 public boolean getBoolean() { 341 return mBoolean; 342 } 343 344 @InspectableProperty(hasAttributeId = false) getByte()345 public byte getByte() { 346 return mByte; 347 } 348 349 @InspectableProperty(hasAttributeId = false) getChar()350 public char getChar() { 351 return mChar; 352 } 353 354 @InspectableProperty(hasAttributeId = false) getDouble()355 public double getDouble() { 356 return mDouble; 357 } 358 359 @InspectableProperty(hasAttributeId = false) getFloat()360 public float getFloat() { 361 return mFloat; 362 } 363 364 @InspectableProperty(hasAttributeId = false) getInt()365 public int getInt() { 366 return mInt; 367 } 368 369 @InspectableProperty(hasAttributeId = false) getLong()370 public long getLong() { 371 return mLong; 372 } 373 374 @InspectableProperty(hasAttributeId = false) getShort()375 public short getShort() { 376 return mShort; 377 } 378 } 379 380 @Test testPrimitiveProperties()381 public void testPrimitiveProperties() { 382 PrimitivePropertiesTest node = new PrimitivePropertiesTest(mRandom); 383 mapAndRead(node); 384 assertEquals(node.getBoolean(), mPropertyReader.get("boolean")); 385 assertEquals(node.getByte(), mPropertyReader.get("byte")); 386 assertEquals(node.getChar(), mPropertyReader.get("char")); 387 assertEquals(node.getDouble(), mPropertyReader.get("double")); 388 assertEquals(node.getFloat(), mPropertyReader.get("float")); 389 assertEquals(node.getInt(), mPropertyReader.get("int")); 390 assertEquals(node.getLong(), mPropertyReader.get("long")); 391 assertEquals(node.getShort(), mPropertyReader.get("short")); 392 } 393 394 class ObjectPropertiesTest { 395 private final String mText; 396 ObjectPropertiesTest(Random seed)397 ObjectPropertiesTest(Random seed) { 398 final StringBuilder stringBuilder = new StringBuilder(); 399 final int length = seed.nextInt(8) + 8; 400 401 for (int i = 0; i < length; i++) { 402 stringBuilder.append(randomLetter(seed)); 403 } 404 405 mText = stringBuilder.toString(); 406 } 407 408 @InspectableProperty getText()409 public String getText() { 410 return mText; 411 } 412 413 @InspectableProperty(hasAttributeId = false) getNull()414 public Objects getNull() { 415 return null; 416 } 417 } 418 419 @Test testObjectProperties()420 public void testObjectProperties() { 421 ObjectPropertiesTest node = new ObjectPropertiesTest(mRandom); 422 mapAndRead(node); 423 assertEquals(node.getText(), mPropertyReader.get("text")); 424 assertNull(mPropertyReader.get("null")); 425 assertNotEquals(0, mPropertyMapper.getId("null")); 426 } 427 428 class IntEnumTest { 429 private int mValue; 430 431 @InspectableProperty(enumMapping = { 432 @InspectableProperty.EnumEntry(name = "ONE", value = 1), 433 @EnumEntry(name = "TWO", value = 2)}) getValue()434 public int getValue() { 435 return mValue; 436 } 437 setValue(int value)438 public void setValue(int value) { 439 mValue = value; 440 } 441 } 442 443 @Test testIntEnum()444 public void testIntEnum() { 445 IntEnumTest node = new IntEnumTest(); 446 InspectionCompanion<IntEnumTest> companion = loadCompanion(IntEnumTest.class); 447 companion.mapProperties(mPropertyMapper); 448 449 node.setValue(1); 450 companion.readProperties(node, mPropertyReader); 451 assertEquals("ONE", mPropertyReader.getIntEnum("value")); 452 453 node.setValue(2); 454 companion.readProperties(node, mPropertyReader); 455 assertEquals("TWO", mPropertyReader.getIntEnum("value")); 456 457 node.setValue(3); 458 companion.readProperties(node, mPropertyReader); 459 assertNull(mPropertyReader.getIntEnum("value")); 460 } 461 462 class IntFlagTest { 463 private int mValue; 464 465 @InspectableProperty(flagMapping = { 466 @InspectableProperty.FlagEntry(name = "ONE", target = 0x1, mask = 0x3), 467 @InspectableProperty.FlagEntry(name = "TWO", target = 0x2, mask = 0x3), 468 @InspectableProperty.FlagEntry(name = "THREE", target = 0x3, mask = 0x3), 469 @InspectableProperty.FlagEntry(name = "FOUR", target = 0x4)}) getValue()470 public int getValue() { 471 return mValue; 472 } 473 setValue(int value)474 public void setValue(int value) { 475 mValue = value; 476 } 477 } 478 479 @Test testIntFlag()480 public void testIntFlag() { 481 IntFlagTest node = new IntFlagTest(); 482 InspectionCompanion<IntFlagTest> companion = loadCompanion(IntFlagTest.class); 483 companion.mapProperties(mPropertyMapper); 484 485 node.setValue(0); 486 companion.readProperties(node, mPropertyReader); 487 assertTrue(mPropertyReader.getIntFlag("value").isEmpty()); 488 489 node.setValue(1); 490 companion.readProperties(node, mPropertyReader); 491 assertEquals(setOf("ONE"), mPropertyReader.getIntFlag("value")); 492 493 node.setValue(2); 494 companion.readProperties(node, mPropertyReader); 495 assertEquals(setOf("TWO"), mPropertyReader.getIntFlag("value")); 496 497 node.setValue(3); 498 companion.readProperties(node, mPropertyReader); 499 assertEquals(setOf("THREE"), mPropertyReader.getIntFlag("value")); 500 501 node.setValue(4); 502 companion.readProperties(node, mPropertyReader); 503 assertEquals(setOf("FOUR"), mPropertyReader.getIntFlag("value")); 504 505 node.setValue(5); 506 companion.readProperties(node, mPropertyReader); 507 assertEquals(setOf("FOUR", "ONE"), mPropertyReader.getIntFlag("value")); 508 } 509 510 class PublicFieldTest { 511 @InspectableProperty 512 public final int value; 513 PublicFieldTest(Random seed)514 PublicFieldTest(Random seed) { 515 value = seed.nextInt(); 516 } 517 } 518 519 @Test testPublicField()520 public void testPublicField() { 521 PublicFieldTest node = new PublicFieldTest(mRandom); 522 mapAndRead(node); 523 assertEquals(node.value, mPropertyReader.get("value")); 524 } 525 526 class ResourceIdTest { 527 @AnimatorRes private final int mAnimatorId; 528 @AnimRes private final int mAnimId; 529 @AnyRes private final int mAnyId; 530 @ArrayRes private final int mArrayId; 531 @BoolRes private final int mBoolId; 532 @DimenRes private final int mDimenId; 533 @DrawableRes private final int mDrawableId; 534 @FontRes private final int mFontId; 535 @IdRes private final int mIdId; 536 @IntegerRes private final int mIntegerId; 537 @InterpolatorRes private final int mInterpolatorId; 538 @LayoutRes private final int mLayoutId; 539 @MenuRes private final int mMenuId; 540 @NavigationRes private final int mNavigationId; 541 @PluralsRes private final int mPluralsId; 542 @RawRes private final int mRawId; 543 @StringRes private final int mStringId; 544 @StyleableRes private final int mStyleableId; 545 @StyleRes private final int mStyleId; 546 @TransitionRes private final int mTransitionId; 547 @XmlRes private final int mXmlId; 548 private final int mUnannotatedId; 549 ResourceIdTest(Random seed)550 ResourceIdTest(Random seed) { 551 mAnimatorId = seed.nextInt(); 552 mAnimId = seed.nextInt(); 553 mAnyId = seed.nextInt(); 554 mArrayId = seed.nextInt(); 555 mBoolId = seed.nextInt(); 556 mDimenId = seed.nextInt(); 557 mDrawableId = seed.nextInt(); 558 mFontId = seed.nextInt(); 559 mIdId = seed.nextInt(); 560 mIntegerId = seed.nextInt(); 561 mInterpolatorId = seed.nextInt(); 562 mLayoutId = seed.nextInt(); 563 mMenuId = seed.nextInt(); 564 mNavigationId = seed.nextInt(); 565 mPluralsId = seed.nextInt(); 566 mRawId = seed.nextInt(); 567 mStringId = seed.nextInt(); 568 mStyleableId = seed.nextInt(); 569 mStyleId = seed.nextInt(); 570 mTransitionId = seed.nextInt(); 571 mXmlId = seed.nextInt(); 572 mUnannotatedId = seed.nextInt(); 573 } 574 575 @InspectableProperty(hasAttributeId = false) 576 @AnimatorRes getAnimatorId()577 public int getAnimatorId() { 578 return mAnimatorId; 579 } 580 581 @InspectableProperty(hasAttributeId = false) 582 @AnimRes getAnimId()583 public int getAnimId() { 584 return mAnimId; 585 } 586 587 @InspectableProperty(hasAttributeId = false) 588 @AnyRes getAnyId()589 public int getAnyId() { 590 return mAnimId; 591 } 592 593 @InspectableProperty(hasAttributeId = false) 594 @ArrayRes getArrayId()595 public int getArrayId() { 596 return mArrayId; 597 } 598 599 @InspectableProperty(hasAttributeId = false) 600 @BoolRes getBoolId()601 public int getBoolId() { 602 return mBoolId; 603 } 604 605 @InspectableProperty(hasAttributeId = false) 606 @DimenRes getDimenId()607 public int getDimenId() { 608 return mDimenId; 609 } 610 611 @InspectableProperty(hasAttributeId = false) 612 @DrawableRes getDrawableId()613 public int getDrawableId() { 614 return mDrawableId; 615 } 616 617 @InspectableProperty(hasAttributeId = false) 618 @FontRes getFontId()619 public int getFontId() { 620 return mFontId; 621 } 622 623 @InspectableProperty(hasAttributeId = false) 624 @IdRes getIdId()625 public int getIdId() { 626 return mIdId; 627 } 628 629 @InspectableProperty(hasAttributeId = false) 630 @IntegerRes getIntegerId()631 public int getIntegerId() { 632 return mIntegerId; 633 } 634 635 @InspectableProperty(hasAttributeId = false) 636 @InterpolatorRes getInterpolatorId()637 public int getInterpolatorId() { 638 return mInterpolatorId; 639 } 640 641 @InspectableProperty(hasAttributeId = false) 642 @LayoutRes getLayoutId()643 public int getLayoutId() { 644 return mLayoutId; 645 } 646 647 @InspectableProperty(hasAttributeId = false) 648 @MenuRes getMenuId()649 public int getMenuId() { 650 return mMenuId; 651 } 652 653 @InspectableProperty(hasAttributeId = false) 654 @NavigationRes getNavigationId()655 public int getNavigationId() { 656 return mNavigationId; 657 } 658 659 @InspectableProperty(hasAttributeId = false) 660 @PluralsRes getPluralsId()661 public int getPluralsId() { 662 return mPluralsId; 663 } 664 665 @InspectableProperty(hasAttributeId = false) 666 @RawRes getRawId()667 public int getRawId() { 668 return mRawId; 669 } 670 671 @InspectableProperty(hasAttributeId = false) 672 @StringRes getStringId()673 public int getStringId() { 674 return mStringId; 675 } 676 677 @InspectableProperty(hasAttributeId = false) 678 @StyleableRes getStyleableId()679 public int getStyleableId() { 680 return mStyleableId; 681 } 682 683 @InspectableProperty(hasAttributeId = false) 684 @StyleRes getStyleId()685 public int getStyleId() { 686 return mStyleId; 687 } 688 689 @InspectableProperty(hasAttributeId = false) 690 @TransitionRes getTransitionId()691 public int getTransitionId() { 692 return mTransitionId; 693 } 694 695 @InspectableProperty(hasAttributeId = false) 696 @XmlRes getXmlId()697 public int getXmlId() { 698 return mXmlId; 699 } 700 701 @InspectableProperty(hasAttributeId = false, valueType = ValueType.RESOURCE_ID) getUnannotatedId()702 public int getUnannotatedId() { 703 return mUnannotatedId; 704 } 705 } 706 707 @Test testResourceId()708 public void testResourceId() { 709 ResourceIdTest node = new ResourceIdTest(mRandom); 710 mapAndRead(node); 711 712 assertEquals(node.getAnimatorId(), mPropertyReader.get("animatorId")); 713 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("animatorId")); 714 715 assertEquals(node.getAnimId(), mPropertyReader.get("animId")); 716 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("animId")); 717 718 assertEquals(node.getAnyId(), mPropertyReader.get("anyId")); 719 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("anyId")); 720 721 assertEquals(node.getArrayId(), mPropertyReader.get("arrayId")); 722 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("arrayId")); 723 724 assertEquals(node.getBoolId(), mPropertyReader.get("boolId")); 725 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("boolId")); 726 727 assertEquals(node.getDimenId(), mPropertyReader.get("dimenId")); 728 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("dimenId")); 729 730 assertEquals(node.getDrawableId(), mPropertyReader.get("drawableId")); 731 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("drawableId")); 732 733 assertEquals(node.getFontId(), mPropertyReader.get("fontId")); 734 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("fontId")); 735 736 assertEquals(node.getIdId(), mPropertyReader.get("idId")); 737 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("idId")); 738 739 assertEquals(node.getIntegerId(), mPropertyReader.get("integerId")); 740 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("integerId")); 741 742 assertEquals(node.getInterpolatorId(), mPropertyReader.get("interpolatorId")); 743 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("interpolatorId")); 744 745 assertEquals(node.getLayoutId(), mPropertyReader.get("layoutId")); 746 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("layoutId")); 747 748 assertEquals(node.getMenuId(), mPropertyReader.get("menuId")); 749 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("menuId")); 750 751 assertEquals(node.getNavigationId(), mPropertyReader.get("navigationId")); 752 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("navigationId")); 753 754 assertEquals(node.getPluralsId(), mPropertyReader.get("pluralsId")); 755 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("pluralsId")); 756 757 assertEquals(node.getRawId(), mPropertyReader.get("rawId")); 758 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("rawId")); 759 760 assertEquals(node.getStringId(), mPropertyReader.get("stringId")); 761 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("stringId")); 762 763 assertEquals(node.getStyleableId(), mPropertyReader.get("styleableId")); 764 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("styleableId")); 765 766 assertEquals(node.getStyleId(), mPropertyReader.get("styleId")); 767 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("styleId")); 768 769 assertEquals(node.getTransitionId(), mPropertyReader.get("transitionId")); 770 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("transitionId")); 771 772 assertEquals(node.getXmlId(), mPropertyReader.get("xmlId")); 773 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("xmlId")); 774 775 assertEquals(node.getUnannotatedId(), mPropertyReader.get("unannotatedId")); 776 assertEquals(ValueType.RESOURCE_ID, mPropertyMapper.getValueType("unannotatedId")); 777 } 778 setOf(T... items)779 private static <T> Set<T> setOf(T... items) { 780 Set<T> set = new HashSet<>(items.length); 781 782 for (T item : items) { 783 set.add(item); 784 } 785 786 return set; 787 } 788 789 @SuppressWarnings("unchecked") mapAndRead(T node)790 private <T> void mapAndRead(T node) { 791 InspectionCompanion<T> companion = loadCompanion((Class<T>) node.getClass()); 792 companion.mapProperties(mPropertyMapper); 793 companion.readProperties(node, mPropertyReader); 794 } 795 796 @SuppressWarnings("unchecked") loadCompanion(Class<T> cls)797 private <T> InspectionCompanion<T> loadCompanion(Class<T> cls) { 798 final ClassLoader classLoader = cls.getClassLoader(); 799 final String companionName = String.format("%s$InspectionCompanion", cls.getName()); 800 801 try { 802 final Class<InspectionCompanion<T>> companion = 803 (Class<InspectionCompanion<T>>) classLoader.loadClass(companionName); 804 return companion.newInstance(); 805 } catch (ClassNotFoundException e) { 806 fail(String.format("Unable to load companion for %s", cls.getCanonicalName())); 807 } catch (InstantiationException | IllegalAccessException e) { 808 fail(String.format("Unable to instantiate companion for %s", cls.getCanonicalName())); 809 } 810 811 return null; 812 } 813 randomLetter(Random random)814 private char randomLetter(Random random) { 815 final String alphabet = "abcdefghijklmnopqrstuvwxyz"; 816 return alphabet.charAt(random.nextInt(alphabet.length())); 817 } 818 } 819