1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php 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.ide.eclipse.adt.internal.editors.layout; 18 19 import com.android.ide.eclipse.adt.editors.layout.gscripts.IAttributeInfo.Format; 20 import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; 21 import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; 22 import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; 23 import com.android.ide.eclipse.adt.internal.editors.mock.MockXmlNode; 24 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; 25 import com.android.ide.eclipse.adt.internal.resources.AttributeInfo; 26 import com.android.sdklib.SdkConstants; 27 import com.android.sdklib.resources.Density; 28 29 import org.w3c.dom.Node; 30 import org.xmlpull.v1.XmlPullParser; 31 import org.xmlpull.v1.XmlPullParserException; 32 33 import java.util.HashMap; 34 35 import junit.framework.TestCase; 36 37 public class UiElementPullParserTest extends TestCase { 38 39 private UiElementNode ui; 40 private HashMap<String, String> button1Map; 41 private HashMap<String, String> button2Map; 42 private HashMap<String, String> textMap; 43 createTextAttrDesc(String xmlName)44 private TextAttributeDescriptor createTextAttrDesc(String xmlName) { 45 return new TextAttributeDescriptor( 46 xmlName, // xmlLocalName 47 xmlName, // uiName 48 SdkConstants.NS_RESOURCES, // ns uri 49 "", // tooltip 50 new AttributeInfo(xmlName, new Format[] { Format.STRING }) 51 ); 52 } 53 54 @Override setUp()55 protected void setUp() throws Exception { 56 // set up some basic descriptors. 57 // We have button, textview, linear layout, relative layout. 58 // only the layouts have children (all 4 descriptors possible) 59 // Also add some dummy attributes. 60 ElementDescriptor buttonDescriptor = new ElementDescriptor("Button", "Button", "", "", 61 new AttributeDescriptor[] { 62 createTextAttrDesc("name"), 63 createTextAttrDesc("text"), 64 }, 65 new ElementDescriptor[] {}, false); 66 67 ElementDescriptor textDescriptor = new ElementDescriptor("TextView", "TextView", "", "", 68 new AttributeDescriptor[] { 69 createTextAttrDesc("name"), 70 createTextAttrDesc("text"), 71 }, 72 new ElementDescriptor[] {}, false); 73 74 ElementDescriptor linearDescriptor = new ElementDescriptor("LinearLayout", "Linear Layout", 75 "", "", 76 new AttributeDescriptor[] { 77 createTextAttrDesc("orientation"), 78 }, 79 new ElementDescriptor[] { }, false); 80 81 ElementDescriptor relativeDescriptor = new ElementDescriptor("RelativeLayout", 82 "Relative Layout", "", "", 83 new AttributeDescriptor[] { 84 createTextAttrDesc("orientation"), 85 }, 86 new ElementDescriptor[] { }, false); 87 88 ElementDescriptor[] a = new ElementDescriptor[] { 89 buttonDescriptor, textDescriptor, linearDescriptor, relativeDescriptor 90 }; 91 92 linearDescriptor.setChildren(a); 93 relativeDescriptor.setChildren(a); 94 95 // document descriptor 96 ElementDescriptor rootDescriptor = new ElementDescriptor("root", "", "", "", 97 new AttributeDescriptor[] { }, a, false); 98 99 100 ui = new UiElementNode(rootDescriptor); 101 102 /* create a dummy XML file. 103 * <LinearLayout android:orientation="vertical"> 104 * <Button android:name="button1" android:text="button1text"/> 105 * <RelativeLayout android:orientation="toto"> 106 * <Button android:name="button2" android:text="button2text"/> 107 * <TextView android:name="text1" android:text="text1text"/> 108 * </RelativeLayout> 109 * </LinearLayout> 110 */ 111 MockXmlNode button1 = new MockXmlNode(null /* namespace */, "Button", Node.ELEMENT_NODE, 112 null); 113 button1.addAttributes(SdkConstants.NS_RESOURCES, "name", "button1"); 114 button1.addAttributes(SdkConstants.NS_RESOURCES, "text", "button1text"); 115 116 // create a map of the attributes we add to the multi-attribute nodes so that 117 // we can more easily test the values when we parse the XML. 118 // This is due to some attributes showing in a certain order for a node and in a different 119 // order in another node. Since the order doesn't matter, we just simplify the test. 120 button1Map = new HashMap<String, String>(); 121 button1Map.put("name", "button1"); 122 button1Map.put("text", "button1text"); 123 124 MockXmlNode button2 = new MockXmlNode(null /* namespace */, "Button", Node.ELEMENT_NODE, 125 null); 126 button2.addAttributes(SdkConstants.NS_RESOURCES, "name", "button2"); 127 button2.addAttributes(SdkConstants.NS_RESOURCES, "text", "button2text"); 128 129 button2Map = new HashMap<String, String>(); 130 button2Map.put("name", "button2"); 131 button2Map.put("text", "button2text"); 132 133 MockXmlNode text = new MockXmlNode(null /* namespace */, "TextView", Node.ELEMENT_NODE, 134 null); 135 text.addAttributes(SdkConstants.NS_RESOURCES, "name", "text1"); 136 text.addAttributes(SdkConstants.NS_RESOURCES, "text", "text1text"); 137 138 textMap = new HashMap<String, String>(); 139 textMap.put("name", "text1"); 140 textMap.put("text", "text1text"); 141 142 MockXmlNode relative = new MockXmlNode(null /* namespace */, "RelativeLayout", 143 Node.ELEMENT_NODE, new MockXmlNode[] { button2, text }); 144 relative.addAttributes(SdkConstants.NS_RESOURCES, "orientation", "toto"); 145 146 MockXmlNode linear = new MockXmlNode(null /* namespace */, "LinearLayout", 147 Node.ELEMENT_NODE, new MockXmlNode[] { button1, relative }); 148 linear.addAttributes(SdkConstants.NS_RESOURCES, "orientation", "vertical"); 149 150 MockXmlNode root = new MockXmlNode(null /* namespace */, "root", Node.ELEMENT_NODE, 151 new MockXmlNode[] { linear }); 152 153 // put the namespace/prefix in place 154 root.setPrefix(SdkConstants.NS_RESOURCES, "android"); 155 156 // load the xml into the UiElementNode 157 ui.loadFromXmlNode(root); 158 159 super.setUp(); 160 } 161 162 @Override tearDown()163 protected void tearDown() throws Exception { 164 super.tearDown(); 165 } 166 testParser()167 public void testParser() { 168 try { 169 // wrap the parser around the ui element node, and start parsing 170 UiElementPullParser parser = new UiElementPullParser( 171 ui, // model 172 false, // explodedView 173 Density.MEDIUM.getDpiValue(), // density (default from ConfigurationComposite) 174 Density.MEDIUM.getDpiValue(), // xdpi (default from ConfigurationComposite) 175 null // iProject 176 ); 177 178 assertEquals(XmlPullParser.START_DOCUMENT, parser.getEventType()); 179 180 // top level Linear layout 181 assertEquals(XmlPullParser.START_TAG, parser.next()); 182 assertEquals("LinearLayout", parser.getName()); 183 assertEquals(1, parser.getAttributeCount()); 184 assertEquals("orientation", parser.getAttributeName(0)); 185 assertEquals(SdkConstants.NS_RESOURCES, parser.getAttributeNamespace(0)); 186 assertEquals("android", parser.getAttributePrefix(0)); 187 assertEquals("vertical", parser.getAttributeValue(0)); 188 189 // Button 190 assertEquals(XmlPullParser.START_TAG, parser.next()); 191 assertEquals("Button", parser.getName()); 192 assertEquals(2, parser.getAttributeCount()); 193 check(parser, 0, button1Map); 194 check(parser, 1, button1Map); 195 // end of button 196 assertEquals(XmlPullParser.END_TAG, parser.next()); 197 198 // Relative Layout 199 assertEquals(XmlPullParser.START_TAG, parser.next()); 200 assertEquals("RelativeLayout", parser.getName()); 201 assertEquals(1, parser.getAttributeCount()); 202 assertEquals("orientation", parser.getAttributeName(0)); 203 assertEquals(SdkConstants.NS_RESOURCES, parser.getAttributeNamespace(0)); 204 assertEquals("android", parser.getAttributePrefix(0)); 205 assertEquals("toto", parser.getAttributeValue(0)); 206 207 // Button 208 assertEquals(XmlPullParser.START_TAG, parser.next()); 209 assertEquals("Button", parser.getName()); 210 assertEquals(2, parser.getAttributeCount()); 211 check(parser, 0, button2Map); 212 check(parser, 1, button2Map); 213 // end of button 214 assertEquals(XmlPullParser.END_TAG, parser.next()); 215 216 // TextView 217 assertEquals(XmlPullParser.START_TAG, parser.next()); 218 assertEquals("TextView", parser.getName()); 219 assertEquals(2, parser.getAttributeCount()); 220 check(parser, 0, textMap); 221 check(parser, 1, textMap); 222 // end of TextView 223 assertEquals(XmlPullParser.END_TAG, parser.next()); 224 225 // end of RelativeLayout 226 assertEquals(XmlPullParser.END_TAG, parser.next()); 227 228 229 // end of top level linear layout 230 assertEquals(XmlPullParser.END_TAG, parser.next()); 231 232 assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); 233 } catch (XmlPullParserException e) { 234 e.printStackTrace(); 235 assertTrue(false); 236 } 237 } 238 239 /** 240 * Receives a {@link XmlPullParser} at the START_TAG level, and checks the i-th attribute 241 * to be present in the {@link HashMap} with the proper (name, value) 242 * @param parser 243 * @param i 244 * @param map 245 */ check(UiElementPullParser parser, int i, HashMap<String, String> map)246 private void check(UiElementPullParser parser, int i, HashMap<String, String> map) { 247 String name = parser.getAttributeName(i); 248 String value = parser.getAttributeValue(i); 249 250 String referenceValue = map.get(name); 251 assertNotNull(referenceValue); 252 assertEquals(referenceValue, value); 253 254 assertEquals(SdkConstants.NS_RESOURCES, parser.getAttributeNamespace(i)); 255 assertEquals("android", parser.getAttributePrefix(i)); 256 } 257 258 } 259