1 /* 2 * Copyright (C) 2017 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.util; 18 19 import com.android.ide.common.rendering.api.LayoutlibCallback; 20 import com.android.ide.common.rendering.api.RenderResources; 21 import com.android.ide.common.rendering.api.ResourceNamespace; 22 import com.android.ide.common.rendering.api.ResourceNamespace.Resolver; 23 import com.android.ide.common.rendering.api.ResourceValue; 24 import com.android.layoutlib.bridge.BridgeConstants; 25 import com.android.layoutlib.bridge.android.BridgeContext; 26 import com.android.tools.layoutlib.annotations.NotNull; 27 28 import org.junit.Test; 29 import org.xmlpull.v1.XmlPullParser; 30 31 import com.google.common.collect.ImmutableMap; 32 33 import static org.junit.Assert.assertEquals; 34 import static org.junit.Assert.assertTrue; 35 import static org.mockito.Mockito.mock; 36 import static org.mockito.Mockito.when; 37 38 public class BridgeXmlPullAttributesTest { 39 @NotNull prepareParser()40 private static XmlPullParser prepareParser() { 41 XmlPullParser parser = mock(XmlPullParser.class); 42 43 when(parser.getAttributeValue(BridgeConstants.NS_RESOURCES, "layout_width")) 44 .thenReturn("match_parent"); 45 when(parser.getAttributeName(0)).thenReturn("layout_width"); 46 when(parser.getAttributeNamespace(0)).thenReturn(BridgeConstants.NS_RESOURCES); 47 // Return every value twice since there is one test using name and other using index 48 when(parser.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, "my_custom_attr")) 49 .thenReturn("a", "a", "b", "b", "invalid", "invalid"); 50 when(parser.getAttributeName(1)).thenReturn("my_custom_attr"); 51 when(parser.getAttributeNamespace(1)).thenReturn(BridgeConstants.NS_APP_RES_AUTO); 52 53 return parser; 54 } 55 56 @NotNull prepareContext()57 private static BridgeContext prepareContext() { 58 BridgeContext context = mock(BridgeContext.class); 59 RenderResources renderResources = new RenderResources() { 60 @Override 61 public ResourceValue resolveResValue(ResourceValue value) { 62 // Simulate behaviour from the actual resolver where a failed resolution will 63 // return the passed value. 64 return value; 65 } 66 }; 67 when(context.getRenderResources()).thenReturn(renderResources); 68 LayoutlibCallback callback = mock(LayoutlibCallback.class); 69 when(callback.getImplicitNamespaces()).thenReturn(Resolver.EMPTY_RESOLVER); 70 when(context.getLayoutlibCallback()).thenReturn(callback); 71 72 return context; 73 } 74 75 private final XmlPullParser parser = prepareParser(); 76 private final BridgeContext context = prepareContext(); 77 private final BridgeXmlPullAttributes attributes = new BridgeXmlPullAttributes( 78 parser, 79 context, 80 ResourceNamespace.RES_AUTO, 81 attrName -> { 82 if ("layout_width".equals(attrName)) { 83 return ImmutableMap.of( 84 "match_parent", 123); 85 } 86 return ImmutableMap.of(); 87 }, 88 (ns, attrName) -> { 89 if ("my_custom_attr".equals(attrName)) { 90 return ImmutableMap.of( 91 "a", 1, 92 "b", 2 93 ); 94 } 95 return ImmutableMap.of(); 96 }); 97 98 @Test testGetAttributeIntValueForEnums()99 public void testGetAttributeIntValueForEnums() { 100 // Test a framework defined enum attribute 101 assertEquals(123, attributes.getAttributeIntValue(BridgeConstants.NS_RESOURCES, 102 "layout_width", 500)); 103 assertEquals(123, attributes.getAttributeIntValue(0, 500)); 104 // Test non existing attribute (it should return the default value) 105 assertEquals(500, attributes.getAttributeIntValue(BridgeConstants.NS_RESOURCES, 106 "layout_height", 500)); 107 assertEquals(500, attributes.getAttributeIntValue(2, 500)); 108 109 // Test project defined enum attribute 110 assertEquals(1, attributes.getAttributeIntValue(BridgeConstants.NS_APP_RES_AUTO, 111 "my_custom_attr", 500)); 112 assertEquals(1, attributes.getAttributeIntValue(1, 500)); 113 assertEquals(2, attributes.getAttributeIntValue(BridgeConstants.NS_APP_RES_AUTO, 114 "my_custom_attr", 500)); 115 assertEquals(2, attributes.getAttributeIntValue(1, 500)); 116 // Test an invalid enum 117 boolean exception = false; 118 try { 119 attributes.getAttributeIntValue(BridgeConstants.NS_APP_RES_AUTO, "my_custom_attr", 500); 120 } catch(NumberFormatException e) { 121 exception = true; 122 } 123 assertTrue(exception); 124 exception = false; 125 try { 126 attributes.getAttributeIntValue(1, 500); 127 } catch(NumberFormatException e) { 128 exception = true; 129 } 130 assertTrue(exception); 131 132 // Test non existing project attribute 133 assertEquals(500, attributes.getAttributeIntValue(BridgeConstants.NS_APP_RES_AUTO, 134 "my_other_attr", 500)); 135 } 136 137 @Test testNotExistingAttributes()138 public void testNotExistingAttributes() { 139 assertEquals(501, attributes.getAttributeUnsignedIntValue(BridgeConstants.NS_APP_RES_AUTO, 140 "my_other_attr", 501)); 141 assertEquals(502, attributes.getAttributeResourceValue(BridgeConstants.NS_APP_RES_AUTO, 142 "my_other_attr", 502)); 143 } 144 } 145