1 /*
2  * Copyright (C) 2010 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.common.layout;
18 
19 import static com.android.SdkConstants.ANDROID_URI;
20 import static com.android.SdkConstants.ATTR_ID;
21 
22 import com.android.ide.common.api.IDragElement;
23 import com.android.ide.common.api.INode;
24 import com.android.ide.common.api.Rect;
25 import com.android.ide.common.layout.BaseLayoutRule.AttributeFilter;
26 import com.android.utils.Pair;
27 
28 import java.util.Arrays;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.Map;
32 import java.util.Set;
33 
34 // TODO: Check assertions
35 // TODO: Check equals() but not == strings by using new String("") to prevent interning
36 // TODO: Rename BaseLayout to BaseLayoutRule, and tests too of course
37 
38 public class BaseLayoutRuleTest extends LayoutTestBase {
39 
40     /** Provides test data used by other test cases */
createSampleElements()41     private IDragElement[] createSampleElements() {
42         IDragElement[] elements = TestDragElement.create(TestDragElement.create(
43                 "android.widget.Button", new Rect(0, 0, 100, 80)).id("@+id/Button01"),
44                 TestDragElement.create("android.widget.LinearLayout", new Rect(0, 80, 100, 280))
45                         .id("@+id/LinearLayout01").add(
46                                 TestDragElement.create("android.widget.Button",
47                                         new Rect(0, 80, 100, 80)).id("@+id/Button011"),
48                                 TestDragElement.create("android.widget.Button",
49                                         new Rect(0, 180, 100, 80)).id("@+id/Button012")),
50                 TestDragElement.create("android.widget.Button", new Rect(100, 0, 100, 80)).id(
51                         "@+id/Button02"));
52         return elements;
53     }
54 
55     /** Test {@link BaseLayoutRule#collectIds}: Check that basic lookup of id works */
testCollectIds1()56     public final void testCollectIds1() {
57         IDragElement[] elements = TestDragElement.create(TestDragElement.create(
58                 "android.widget.Button", new Rect(0, 0, 100, 80)).id("@+id/Button01"));
59         Map<String, Pair<String, String>> idMap = new HashMap<String, Pair<String, String>>();
60         Map<String, Pair<String, String>> ids = new BaseLayoutRule().collectIds(idMap, elements);
61         assertEquals(1, ids.size());
62         assertEquals("@+id/Button01", ids.keySet().iterator().next());
63     }
64 
65     /**
66      * Test {@link BaseLayoutRule#collectIds}: Check that with the wrong URI we
67      * don't pick up the ID
68      */
testCollectIds2()69     public final void testCollectIds2() {
70         IDragElement[] elements = TestDragElement.create(TestDragElement.create(
71                 "android.widget.Button", new Rect(0, 0, 100, 80)).set("myuri", ATTR_ID,
72                 "@+id/Button01"));
73 
74         Map<String, Pair<String, String>> idMap = new HashMap<String, Pair<String, String>>();
75         Map<String, Pair<String, String>> ids = new BaseLayoutRule().collectIds(idMap, elements);
76         assertEquals(0, ids.size());
77     }
78 
79     /**
80      * Test {@link BaseLayoutRule#normalizeId(String)}
81      */
testNormalizeId()82     public final void testNormalizeId() {
83         assertEquals("foo", new BaseLayoutRule().normalizeId("foo"));
84         assertEquals("@+id/name", new BaseLayoutRule().normalizeId("@id/name"));
85         assertEquals("@+id/name", new BaseLayoutRule().normalizeId("@+id/name"));
86     }
87 
88     /**
89      * Test {@link BaseLayoutRule#collectExistingIds}
90      */
testCollectExistingIds1()91     public final void testCollectExistingIds1() {
92         Set<String> existing = new HashSet<String>();
93         INode node = TestNode.create("android.widget.Button").id("@+id/Button012").add(
94                 TestNode.create("android.widget.Button").id("@+id/Button2"));
95 
96         new BaseLayoutRule().collectExistingIds(node, existing);
97 
98         assertEquals(2, existing.size());
99         assertContainsSame(Arrays.asList("@+id/Button2", "@+id/Button012"), existing);
100     }
101 
102     /**
103      * Test {@link BaseLayoutRule#collectIds}: Check that with multiple elements and
104      * some children we still pick up all the right id's
105      */
testCollectIds3()106     public final void testCollectIds3() {
107         Map<String, Pair<String, String>> idMap = new HashMap<String, Pair<String, String>>();
108 
109         IDragElement[] elements = createSampleElements();
110         Map<String, Pair<String, String>> ids = new BaseLayoutRule().collectIds(idMap, elements);
111         assertEquals(5, ids.size());
112         assertContainsSame(Arrays.asList("@+id/Button01", "@+id/Button02", "@+id/Button011",
113                 "@+id/Button012", "@+id/LinearLayout01"), ids.keySet());
114 
115         // Make sure the Pair has the right stuff too;
116         // (having the id again in the pair seems redundant; see if I really
117         // need it in the implementation)
118         assertEquals(Pair.of("@+id/LinearLayout01", "android.widget.LinearLayout"), ids
119                 .get("@+id/LinearLayout01"));
120     }
121 
122     /**
123      * Test {@link BaseLayoutRule#remapIds}: Ensure that it identifies a conflict
124      */
testRemapIds1()125     public final void testRemapIds1() {
126         Map<String, Pair<String, String>> idMap = new HashMap<String, Pair<String, String>>();
127         BaseLayoutRule baseLayout = new BaseLayoutRule();
128         IDragElement[] elements = createSampleElements();
129         baseLayout.collectIds(idMap, elements);
130         INode node = TestNode.create("android.widget.Button").id("@+id/Button012").add(
131                 TestNode.create("android.widget.Button").id("@+id/Button2"));
132 
133         assertEquals(5, idMap.size());
134         Map<String, Pair<String, String>> remapped = baseLayout.remapIds(node, idMap);
135         // 4 original from the sample elements, plus overlap with one
136         // (Button012) - one new
137         // button added in
138         assertEquals(6, remapped.size());
139 
140         // TODO: I'm a little confused about what exactly this method should do;
141         // check with Raphael.
142     }
143 
144 
145     /**
146      * Test {@link BaseLayoutRule#getDropIdMap}
147      */
testGetDropIdMap()148     public final void testGetDropIdMap() {
149         BaseLayoutRule baseLayout = new BaseLayoutRule();
150         IDragElement[] elements = createSampleElements();
151         INode node = TestNode.create("android.widget.Button").id("@+id/Button012").add(
152                 TestNode.create("android.widget.Button").id("@+id/Button2"));
153 
154         Map<String, Pair<String, String>> idMap = baseLayout.getDropIdMap(node, elements, true);
155         assertContainsSame(Arrays.asList("@+id/Button01", "@+id/Button012", "@+id/Button011",
156                 "@id/Button012", "@+id/Button02", "@+id/LinearLayout01"), idMap
157                 .keySet());
158 
159         // TODO: I'm a little confused about what exactly this method should do;
160         // check with Raphael.
161     }
162 
testAddAttributes1()163     public final void testAddAttributes1() {
164         BaseLayoutRule layout = new BaseLayoutRule();
165 
166         // First try with no filter
167         IDragElement oldElement = TestDragElement.create("a.w.B").id("@+id/foo");
168         INode newNode = TestNode.create("a.w.B").id("@+id/foo").set("u", "key", "value").set("u",
169                 "nothidden", "nothiddenvalue");
170         ;
171         AttributeFilter filter = null;
172         // No references in this test case
173         Map<String, Pair<String, String>> idMap = null;
174 
175         layout.addAttributes(newNode, oldElement, idMap, filter);
176         assertEquals("value", newNode.getStringAttr("u", "key"));
177         assertEquals("nothiddenvalue", newNode.getStringAttr("u", "nothidden"));
178     }
179 
testAddAttributes2()180     public final void testAddAttributes2() {
181         // Test filtering
182         BaseLayoutRule layout = new BaseLayoutRule();
183 
184         // First try with no filter
185         IDragElement oldElement = TestDragElement.create("a.w.B").id("@+id/foo");
186         INode newNode = TestNode.create("a.w.B").id("@+id/foo").set("u", "key", "value").set("u",
187                 "hidden", "hiddenvalue");
188         AttributeFilter filter = new AttributeFilter() {
189 
190             @Override
191             public String replace(String attributeUri, String attributeName,
192                     String attributeValue) {
193                 if (attributeName.equals("hidden")) {
194                     return null;
195                 }
196 
197                 return attributeValue;
198             }
199         };
200         // No references in this test case
201         Map<String, Pair<String, String>> idMap = null;
202 
203         layout.addAttributes(newNode, oldElement, idMap, filter);
204         assertEquals("value", newNode.getStringAttr("u", "key"));
205     }
206 
testFindNewId()207     public final void testFindNewId() {
208         BaseLayoutRule baseLayout = new BaseLayoutRule();
209         Set<String> existing = new HashSet<String>();
210         assertEquals("@+id/Widget01", baseLayout.findNewId("a.w.Widget", existing));
211 
212         existing.add("@+id/Widget01");
213         assertEquals("@+id/Widget02", baseLayout.findNewId("a.w.Widget", existing));
214 
215         existing.add("@+id/Widget02");
216         assertEquals("@+id/Widget03", baseLayout.findNewId("a.w.Widget", existing));
217 
218         existing.remove("@+id/Widget02");
219         assertEquals("@+id/Widget02", baseLayout.findNewId("a.w.Widget", existing));
220     }
221 
testDefaultAttributeFilter()222     public final void testDefaultAttributeFilter() {
223         assertEquals("true", BaseLayoutRule.DEFAULT_ATTR_FILTER.replace("myuri", "layout_alignRight",
224                 "true"));
225         assertEquals(null, BaseLayoutRule.DEFAULT_ATTR_FILTER.replace(ANDROID_URI,
226                 "layout_alignRight", "true"));
227         assertEquals("true", BaseLayoutRule.DEFAULT_ATTR_FILTER.replace(ANDROID_URI,
228                 "myproperty", "true"));
229     }
230 
testAddInnerElements()231     public final void testAddInnerElements() {
232         IDragElement oldElement = TestDragElement.create("root").add(
233                 TestDragElement.create("a.w.B").id("@+id/child1")
234                         .set("uri", "childprop1", "value1"),
235                 TestDragElement.create("a.w.B").id("@+id/child2").set("uri", "childprop2a",
236                         "value2a").set("uri", "childprop2b", "value2b"));
237         INode newNode = TestNode.create("a.w.B").id("@+id/foo");
238         Map<String, Pair<String, String>> idMap = new HashMap<String, Pair<String, String>>();
239         BaseLayoutRule layout = new BaseLayoutRule();
240         layout.addInnerElements(newNode, oldElement, idMap);
241         assertEquals(2, newNode.getChildren().length);
242 
243         assertEquals("value2b", newNode.getChildren()[1].getStringAttr("uri", "childprop2b"));
244     }
245 }
246