1f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye/* 2f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * Copyright (C) 2012 The Android Open Source Project 3f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * 4f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * you may not use this file except in compliance with the License. 6f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * You may obtain a copy of the License at 7f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * 8f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * http://www.eclipse.org/org/documents/epl-v10.php 9f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * 10f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * Unless required by applicable law or agreed to in writing, software 11f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * distributed under the License is distributed on an "AS IS" BASIS, 12f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * See the License for the specific language governing permissions and 14f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye * limitations under the License. 15f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye */ 16f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyepackage com.android.ide.common.resources.platform; 17f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 18f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport static com.android.SdkConstants.ANDROID_URI; 19f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport static com.android.SdkConstants.DOT_XML; 20f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 210072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohetimport com.android.SdkConstants; 22f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.android.annotations.NonNull; 23f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.android.ide.common.api.IAttributeInfo.Format; 24f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.android.ide.common.resources.ResourceItem; 25f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.android.ide.common.resources.ResourceRepository; 26f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities; 270072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohetimport com.android.ide.eclipse.mock.Mocks; 280072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohetimport com.android.io.IAbstractFolder; 290072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohetimport com.android.io.IAbstractResource; 30f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.android.resources.ResourceType; 31f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.android.utils.StdLogger; 32f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.google.common.base.Charsets; 33f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.google.common.collect.ArrayListMultimap; 34f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.google.common.collect.Multimap; 35f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.google.common.collect.Sets; 36f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport com.google.common.io.Files; 37f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 385a56f60c78b0cff7867d9708fb0033f9f4f53211Tor Norbyeimport junit.framework.TestCase; 395a56f60c78b0cff7867d9708fb0033f9f4f53211Tor Norbye 40f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport org.w3c.dom.Attr; 41f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport org.w3c.dom.Document; 42f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport org.w3c.dom.Element; 43f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport org.w3c.dom.NamedNodeMap; 44f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 45f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport java.io.File; 46f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport java.io.IOException; 47f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport java.util.Collection; 48f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport java.util.EnumSet; 49f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport java.util.Map; 50f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyeimport java.util.Set; 51f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 52f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye@SuppressWarnings("javadoc") 53f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbyepublic class AttributeInfoTest extends TestCase { 54f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testSimple() throws Exception { 55f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", EnumSet.noneOf(Format.class)); 56f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("", null, null)); 57f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("a b c", null, null)); 58f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@android foo bar", null, null)); 59f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 60f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 61f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidString() throws Exception { 62f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.STRING_SET); 63f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("", null, null)); 64f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("a b c", null, null)); 65f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@android foo bar", null, null)); 66f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 67f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 68f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidBoolean() throws Exception { 69f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.BOOLEAN_SET); 70f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("true", null, null)); 71f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("false", null, null)); 72f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("", null, null)); 735a56f60c78b0cff7867d9708fb0033f9f4f53211Tor Norbye assertTrue(info.isValid("TRUE", null, null)); 745a56f60c78b0cff7867d9708fb0033f9f4f53211Tor Norbye assertTrue(info.isValid("True", null, null)); 755a56f60c78b0cff7867d9708fb0033f9f4f53211Tor Norbye assertTrue(info.isValid("FALSE", null, null)); 765a56f60c78b0cff7867d9708fb0033f9f4f53211Tor Norbye assertTrue(info.isValid("False", null, null)); 77f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 78f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 79f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidInteger() throws Exception { 80f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.INTEGER_SET); 81f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("0", null, null)); 82f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("1", null, null)); 83f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("10", null, null)); 84f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("-10", null, null)); 85f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid(Integer.toString(Integer.MAX_VALUE), null, null)); 86f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 87f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("", null, null)); 88f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("a", null, null)); 89f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("a1", null, null)); 90f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("1a", null, null)); 91f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("1.0", null, null)); 92f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 93f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 94f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidFloat() throws Exception { 95f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.FLOAT_SET); 96f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("0", null, null)); 97f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("1", null, null)); 98f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("10", null, null)); 99f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("-10", null, null)); 100f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("-10.1234", null, null)); 101f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid(".1", null, null)); 102f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("-.1", null, null)); 103f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("1.5e22", null, null)); 104f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid(Integer.toString(Integer.MAX_VALUE), null, null)); 105f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 106f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("", null, null)); 107f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid(".", null, null)); 108f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("-.", null, null)); 109f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("a", null, null)); 110f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("a1", null, null)); 111f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("1a", null, null)); 112f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 113f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 114f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidDimension() throws Exception { 115f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.DIMENSION_SET); 116f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("0dp", null, null)); 117f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("1dp", null, null)); 118f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("10dip", null, null)); 119f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("-10px", null, null)); 120f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("-10.1234mm", null, null)); 121f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("14sp", null, null)); 122f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("72pt", null, null)); 123f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 124f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("", null, null)); 125f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("5", null, null)); 126f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("50ps", null, null)); 127f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye // Since we allow resources even when not specified in format, don't assert 128f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye // this: 129f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye //assertFalse(info.isValid("@dimen/foo")); 130f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 131f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 132f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidColor() throws Exception { 133f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.COLOR_SET); 134f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("#fff", null, null)); 135f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("#ffffff", null, null)); 136f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("#12345678", null, null)); 137f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("#abcdef00", null, null)); 138f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 139f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("", null, null)); 140f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("#fffffffff", null, null)); 141f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("red", null, null)); 142f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("rgb(1,2,3)", null, null)); 143f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 144f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 145f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidFraction() throws Exception { 146f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", EnumSet.<Format>of(Format.FRACTION)); 147f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("5%", null, null)); 148f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("25%p", null, null)); 149f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 150f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye // We don't validate fractions accurately yet 151f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye //assertFalse(info.isValid("")); 152f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye //assertFalse(info.isValid("50%%")); 153f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye //assertFalse(info.isValid("50")); 154f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye //assertFalse(info.isValid("-2%")); 155f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 156f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 157f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidReference() throws Exception { 158f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.REFERENCE_SET); 159f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@android:string/foo", null, null)); 160f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@string/foo", null, null)); 161f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@dimen/foo", null, null)); 162f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@color/foo", null, null)); 163f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@animator/foo", null, null)); 164f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@anim/foo", null, null)); 165f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("?android:attr/textAppearanceMedium", null, null)); 1665a56f60c78b0cff7867d9708fb0033f9f4f53211Tor Norbye assertTrue(info.isValid("?textAppearanceMedium", null, null)); 167f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 168f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("", null, null)); 169f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("foo", null, null)); 170f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("3.4", null, null)); 171f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 172f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 173f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidEnum() throws Exception { 174f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.ENUM_SET); 175f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye info.setEnumValues(new String[] { "wrap_content", "match_parent" }); 176f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("wrap_content", null, null)); 177f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("match_parent", null, null)); 178f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("", null, null)); 179f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("other", null, null)); 180f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("50", null, null)); 181f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 182f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 183f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValidFlag() throws Exception { 184f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.FLAG_SET); 185f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye info.setFlagValues(new String[] { "left", "top", "right", "bottom" }); 186f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("left", null, null)); 187f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("top", null, null)); 188f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("left|top", null, null)); 1895a56f60c78b0cff7867d9708fb0033f9f4f53211Tor Norbye assertTrue(info.isValid("", null, null)); 190f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 191f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("other", null, null)); 192f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("50", null, null)); 193f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 194f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 195f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testCombined1() throws Exception { 196f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", EnumSet.<Format>of(Format.INTEGER, 197f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Format.REFERENCE)); 198f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("1", null, null)); 199f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@dimen/foo", null, null)); 200f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("foo", null, null)); 201f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 202f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 203f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testCombined2() throws Exception { 204f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", EnumSet.<Format>of(Format.COLOR, 205f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Format.REFERENCE)); 206f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("#ff00ff00", null, null)); 207f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@color/foo", null, null)); 208f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("foo", null, null)); 209f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 210f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 211f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testCombined3() throws Exception { 212f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", EnumSet.<Format>of(Format.STRING, 213f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Format.REFERENCE)); 214f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("test", null, null)); 215f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@color/foo", null, null)); 216f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 217f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 218f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testCombined4() throws Exception { 219f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", EnumSet.<Format>of(Format.ENUM, 220f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Format.DIMENSION)); 221f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye info.setEnumValues(new String[] { "wrap_content", "match_parent" }); 222f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("wrap_content", null, null)); 223f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("match_parent", null, null)); 224f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("50dp", null, null)); 225f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("50", null, null)); 226f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("test", null, null)); 227f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 228f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 229f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testResourcesExist() throws Exception { 2300072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohet IAbstractFolder folder = Mocks.createAbstractFolder( 2310072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohet SdkConstants.FD_RESOURCES, new IAbstractResource[0]); 2320072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohet 233f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = new AttributeInfo("test", Format.REFERENCE_SET); 2340072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohet TestResourceRepository projectResources = new TestResourceRepository(folder,false); 235f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye projectResources.addResource(ResourceType.STRING, "mystring"); 236f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye projectResources.addResource(ResourceType.DIMEN, "mydimen"); 2370072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohet TestResourceRepository frameworkResources = new TestResourceRepository(folder, true); 238f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye frameworkResources.addResource(ResourceType.LAYOUT, "mylayout"); 239f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 240f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@string/mystring", null, null)); 241f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@dimen/mydimen", null, null)); 242f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@android:layout/mylayout", null, null)); 243f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("?android:attr/listPreferredItemHeigh", null, null)); 244f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 245f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@string/mystring", projectResources, frameworkResources)); 246f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@dimen/mydimen", projectResources, frameworkResources)); 247f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(info.isValid("@android:layout/mylayout", projectResources, frameworkResources)); 248f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 249f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("@android:string/mystring", projectResources, 250f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye frameworkResources)); 251f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("@android:dimen/mydimen", projectResources, frameworkResources)); 252f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("@layout/mylayout", projectResources, frameworkResources)); 253f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("@layout/foo", projectResources, frameworkResources)); 254f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("@anim/foo", projectResources, frameworkResources)); 255f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertFalse(info.isValid("@android:anim/foo", projectResources, frameworkResources)); 256f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 257f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 258f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye private class TestResourceRepository extends ResourceRepository { 259f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye private Multimap<ResourceType, String> mResources = ArrayListMultimap.create(); 260f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 2610072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohet protected TestResourceRepository(IAbstractFolder resFolder, boolean isFrameworkRepository) { 2620072bac9da2f60fec9c7f48b17aafd1705094505Xavier Ducrohet super(resFolder, isFrameworkRepository); 263f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 264f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 265f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye void addResource(ResourceType type, String name) { 266f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye mResources.put(type, name); 267f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 268f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 269f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye @Override 270f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye @NonNull 271f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye protected ResourceItem createResourceItem(@NonNull String name) { 272f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye fail("Not used in test"); 273f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye return null; 274f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 275f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 276f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye @Override 277f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public boolean hasResourceItem(@NonNull ResourceType type, @NonNull String name) { 278f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Collection<String> names = mResources.get(type); 279f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (names != null) { 280f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye return names.contains(name); 281f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 282f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 283f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye return false; 284f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 285f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye }; 286f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 287f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 288f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye public void testIsValid() throws Exception { 289f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye // This test loads the full attrs.xml file and then processes a bunch of platform 290f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye // resource file and makes sure that they're all considered valid. This helps 291f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye // make sure that isValid() closely matches what aapt accepts. 292f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye String sdkPath = System.getenv("ADT_SDK_SOURCE_PATH"); 293f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertNotNull("This test requires ADT_SDK_SOURCE_PATH to be set to point to the" + 294f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye "SDK git repository", sdkPath); 295f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye File sdk = new File(sdkPath); 296f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertNotNull("$ADT_SDK_SOURCE_PATH (" + sdk.getPath() + ") is not a directory", 297f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye sdk.isDirectory()); 298f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye File git = sdk.getParentFile(); 299f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye File attrsPath = new File(git, "frameworks" + File.separator + "base" 300f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye + File.separator + "core" + File.separator + "res" + File.separator + "res" 301f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye + File.separator + "values" + File.separator + "attrs.xml"); 302f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(attrsPath.getPath(), attrsPath.exists()); 303f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttrsXmlParser parser = new AttrsXmlParser(attrsPath.getPath(), 304f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye new StdLogger(StdLogger.Level.VERBOSE), 1100); 305f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye parser.preload(); 306f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Map<String, AttributeInfo> attributeMap = parser.getAttributeMap(); 307f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertNotNull(attributeMap); 308f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertNotNull(attributeMap.get("layout_width")); 309f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Set<String> seen = Sets.newHashSet(); 310f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 311f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye checkDir(new File(git, "packages" + File.separator + "apps"), false, attributeMap, seen); 312f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 313f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 314f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye private void checkDir(File dir, boolean isResourceDir, 315f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Map<String, AttributeInfo> map, Set<String> seen) throws IOException { 316f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye assertTrue(dir.isDirectory()); 317f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye File[] list = dir.listFiles(); 318f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (list != null) { 319f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye for (File file : list) { 320f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (isResourceDir && file.isFile() && file.getPath().endsWith(DOT_XML)) { 321f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye checkXmlFile(file, map, seen); 322f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } else if (file.isDirectory()) { 323f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye checkDir(file, isResourceDir || file.getName().equals("res"), map, seen); 324f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 325f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 326f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 327f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 328f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 329f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye private void checkXmlFile(File file, Map<String, AttributeInfo> map, 330f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Set<String> seen) throws IOException { 331f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye String xml = Files.toString(file, Charsets.UTF_8); 332f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (xml != null) { 333f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye //Document doc = DomUtilities.parseStructuredDocument(xml); 334f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Document doc = DomUtilities.parseDocument(xml, false); 335f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (doc != null && doc.getDocumentElement() != null) { 336f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye checkElement(file, doc.getDocumentElement(), map, seen); 337f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 338f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 339f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 340f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 341f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye private void checkElement(File file, Element element, Map<String, AttributeInfo> map, 342f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Set<String> seen) { 343f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye NamedNodeMap attributes = element.getAttributes(); 344f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye for (int i = 0, n = attributes.getLength(); i < n; i++) { 345f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye Attr attribute = (Attr) attributes.item(i); 346f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 347f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye String uri = attribute.getNamespaceURI(); 348f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye String name = attribute.getLocalName(); 349f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye String value = attribute.getValue(); 350f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (ANDROID_URI.equals(uri)) { 351f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye AttributeInfo info = map.get(name); 352f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (info == null) { 353f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye System.out.println("Warning: Unknown attribute '" + name + "' in " + file); 354f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye return; 355f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 356f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (!info.isValid(value, null, null)) { 357f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (name.equals("duration") || name.equals("exitFadeDuration")) { 358f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye // Already known 359f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye return; 360f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 361f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye String message = "In file " + 362f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye file.getPath() + ":\nCould not validate value \"" + value 363f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye + "\" for attribute '" 364f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye + name + "' where the attribute info has formats " + info.getFormats() 365f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye + "\n"; 366f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye System.out.println("\n" + message); 367f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye fail(message); 368f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 369f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if ((value.startsWith("@") || value.startsWith("?")) && 370f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye !info.getFormats().contains(Format.REFERENCE)) { 371f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye // Print out errors in attrs.xml 372f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye 373f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye if (!seen.contains(name)) { 374f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye seen.add(name); 375f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye System.out.println("\"" + name + "\" with formats " + info.getFormats() 376f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye + " was passed a reference (" + value + ") in file " + file); 377f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 378f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 379f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 380f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 381f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye } 382f48bde52e60fefec0763cad1b45bc1dcd1bf0841Tor Norbye} 383