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