1 package org.robolectric.res; 2 3 import static com.google.common.truth.Truth.assertThat; 4 import static org.junit.Assert.assertThrows; 5 6 import java.util.HashSet; 7 import java.util.Set; 8 import org.junit.Test; 9 import org.junit.runner.RunWith; 10 import org.junit.runners.JUnit4; 11 12 @RunWith(JUnit4.class) 13 public class ResourceRemapperTest { 14 15 @Test forbidFinalRClasses()16 public void forbidFinalRClasses() { 17 ResourceRemapper remapper = new ResourceRemapper(null); 18 assertThrows(IllegalArgumentException.class, () -> remapper.remapRClass(FinalRClass.class)); 19 } 20 21 @SuppressWarnings("TruthConstantAsserts") 22 @Test testRemap()23 public void testRemap() { 24 ResourceRemapper remapper = new ResourceRemapper(ApplicationRClass.class); 25 remapper.remapRClass(SecondClass.class); 26 remapper.remapRClass(ThirdClass.class); 27 28 // Resource identifiers that are common across libraries should be remapped to the same value. 29 assertThat(ApplicationRClass.string.string_one).isEqualTo(SecondClass.string.string_one); 30 assertThat(ApplicationRClass.string.string_one).isEqualTo(ThirdClass.string.string_one); 31 32 // Resource identifiers that clash across two libraries should be remapped to different values. 33 assertThat(SecondClass.id.id_clash).isNotEqualTo(ThirdClass.id.another_id_clash); 34 35 // Styleable arrays of values should be updated to match the remapped values. 36 assertThat(ThirdClass.styleable.SomeStyleable) 37 .isEqualTo(ApplicationRClass.styleable.SomeStyleable); 38 assertThat(SecondClass.styleable.SomeStyleable) 39 .isEqualTo(ApplicationRClass.styleable.SomeStyleable); 40 assertThat(ApplicationRClass.styleable.SomeStyleable) 41 .asList() 42 .containsExactly(ApplicationRClass.attr.attr_one, ApplicationRClass.attr.attr_two); 43 } 44 45 @Test resourcesOfDifferentTypes_shouldHaveDifferentTypeSpaces()46 public void resourcesOfDifferentTypes_shouldHaveDifferentTypeSpaces() { 47 ResourceRemapper remapper = new ResourceRemapper(ApplicationRClass.class); 48 remapper.remapRClass(SecondClass.class); 49 remapper.remapRClass(ThirdClass.class); 50 51 Set<Integer> allIds = new HashSet<>(); 52 assertThat(allIds.add(ApplicationRClass.string.string_one)).isTrue(); 53 assertThat(allIds.add(ApplicationRClass.string.string_two)).isTrue(); 54 assertThat(allIds.add(SecondClass.integer.integer_one)).isTrue(); 55 assertThat(allIds.add(SecondClass.integer.integer_two)).isTrue(); 56 assertThat(allIds.add(SecondClass.string.string_one)).isFalse(); 57 assertThat(allIds.add(SecondClass.string.string_three)).isTrue(); 58 assertThat(allIds.add(ThirdClass.raw.raw_one)).isTrue(); 59 assertThat(allIds.add(ThirdClass.raw.raw_two)).isTrue(); 60 61 assertThat(ResourceIds.getTypeIdentifier(ApplicationRClass.string.string_one)) 62 .isEqualTo(ResourceIds.getTypeIdentifier(ApplicationRClass.string.string_two)); 63 assertThat(ResourceIds.getTypeIdentifier(ApplicationRClass.string.string_one)) 64 .isEqualTo(ResourceIds.getTypeIdentifier(SecondClass.string.string_three)); 65 66 assertThat(ResourceIds.getTypeIdentifier(ApplicationRClass.string.string_two)) 67 .isNotEqualTo(ResourceIds.getTypeIdentifier(SecondClass.integer.integer_two)); 68 assertThat(ResourceIds.getTypeIdentifier(ThirdClass.raw.raw_two)) 69 .isNotEqualTo(ResourceIds.getTypeIdentifier(SecondClass.integer.integer_two)); 70 } 71 72 public static final class FinalRClass { 73 public static final class string { 74 public static final int a_final_value = 0x7f020001; 75 public static final int another_final_value = 0x7f020002; 76 } 77 } 78 79 public static final class ApplicationRClass { 80 public static final class string { 81 public static final int string_one = 0x7f010001; 82 public static final int string_two = 0x7f010002; 83 } 84 85 public static final class attr { 86 public static int attr_one = 0x7f010008; 87 public static int attr_two = 0x7f010009; 88 } 89 90 public static final class styleable { 91 public static final int[] SomeStyleable = 92 new int[] {ApplicationRClass.attr.attr_one, ApplicationRClass.attr.attr_two}; 93 public static final int SomeStyleable_offsetX = 0; 94 public static final int SomeStyleable_offsetY = 1; 95 } 96 } 97 98 public static final class SecondClass { 99 public static final class id { 100 public static int id_clash = 0x7f010001; 101 } 102 103 public static final class integer { 104 public static int integer_one = 0x7f010001; 105 public static int integer_two = 0x7f010002; 106 } 107 108 public static final class string { 109 public static int string_one = 0x7f020001; 110 public static int string_three = 0x7f020002; 111 } 112 113 public static final class attr { 114 public static int attr_one = 0x7f010001; 115 public static int attr_two = 0x7f010002; 116 } 117 118 public static final class styleable { 119 public static final int[] SomeStyleable = 120 new int[] {SecondClass.attr.attr_one, SecondClass.attr.attr_two}; 121 public static final int SomeStyleable_offsetX = 0; 122 public static final int SomeStyleable_offsetY = 1; 123 } 124 } 125 126 public static final class ThirdClass { 127 public static final class id { 128 public static int another_id_clash = 0x7f010001; 129 } 130 131 public static final class raw { 132 public static int raw_one = 0x7f010001; 133 public static int raw_two = 0x7f010002; 134 } 135 136 public static final class string { 137 public static int string_one = 0x7f020009; 138 } 139 140 public static final class attr { 141 public static int attr_one = 0x7f010003; 142 public static int attr_two = 0x7f010004; 143 } 144 145 public static final class styleable { 146 public static final int[] SomeStyleable = 147 new int[] {ThirdClass.attr.attr_one, ThirdClass.attr.attr_two}; 148 public static final int SomeStyleable_offsetX = 0; 149 public static final int SomeStyleable_offsetY = 1; 150 } 151 } 152 } 153