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