/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.ide.common.resources; import com.android.annotations.Nullable; import com.android.ide.common.rendering.api.ArrayResourceValue; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.res2.ResourceRepository; import com.android.ide.common.resources.configuration.FolderConfiguration; import com.android.resources.ResourceType; import com.google.common.collect.Lists; import junit.framework.TestCase; import java.util.List; import java.util.Map; public class ResourceItemResolverTest extends TestCase { @SuppressWarnings("ConstantConditions") public void test() throws Exception { final TestResourceRepository frameworkResources = TestResourceRepository.create(true, new Object[]{ "values/strings.xml", "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<resources>\n" + " <string name=\"ok\">Ok</string>\n" + " <array name=\"my_fw_array\">\"\n" + " <item> fw_value1</item>\n" // also test trimming. + " <item>fw_value2\n</item>\n" + " <item>fw_value3</item>\n" + " </array>\n" + "</resources>\n", "values/themes.xml", "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<resources>\n" + " <style name=\"Theme\">\n" + " <item name=\"colorForeground\">@android:color/bright_foreground_dark</item>\n" + " <item name=\"colorBackground\">@android:color/background_dark</item>\n" + " </style>\n" + " <style name=\"Theme.Light\">\n" + " <item name=\"colorBackground\">@android:color/background_light</item>\n" + " <item name=\"colorForeground\">@color/bright_foreground_light</item>\n" + " </style>\n" + "</resources>\n", "values/colors.xml", "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<resources>\n" + " <color name=\"background_dark\">#ff000000</color>\n" + " <color name=\"background_light\">#ffffffff</color>\n" + " <color name=\"bright_foreground_dark\">@android:color/background_light</color>\n" + " <color name=\"bright_foreground_light\">@android:color/background_dark</color>\n" + "</resources>\n", }); final ResourceRepository appResources = TestResourceRepository.createRes2(false, new Object[]{ "layout/layout1.xml", "<!--contents doesn't matter-->", "layout/layout2.xml", "<!--contents doesn't matter-->", "layout-land/layout1.xml", "<!--contents doesn't matter-->", "layout-land/only_land.xml", "<!--contents doesn't matter-->", "drawable/graphic.9.png", new byte[0], "values/styles.xml", "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<resources>\n" + " <style name=\"MyTheme\" parent=\"android:Theme.Light\">\n" + " <item name=\"android:textColor\">#999999</item>\n" + " <item name=\"foo\">?android:colorForeground</item>\n" + " </style>\n" + " <style name=\"MyTheme.Dotted1\" parent=\"\">\n" + " </style>" + " <style name=\"MyTheme.Dotted2\">\n" + " </style>" + " <style name=\"RandomStyle\">\n" + " </style>" + " <style name=\"RandomStyle2\" parent=\"RandomStyle\">\n" + " </style>" + "</resources>\n", "values/strings.xml", "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n" + " <item type=\"id\" name=\"action_bar_refresh\" />\n" + " <item type=\"dimen\" name=\"dialog_min_width_major\">45%</item>\n" + " <string name=\"home_title\">Home Sample</string>\n" + " <string name=\"show_all_apps\">All</string>\n" + " <string name=\"menu_wallpaper\">Wallpaper</string>\n" + " <string name=\"menu_search\">Search</string>\n" + " <string name=\"menu_settings\">Settings</string>\n" + " <string name=\"dummy\" translatable=\"false\">Ignore Me</string>\n" + " <string name=\"wallpaper_instructions\">Tap picture to set portrait wallpaper</string>\n" + " <string name=\"xliff_string\">First: <xliff:g id=\"firstName\">%1$s</xliff:g> Last: <xliff:g id=\"lastName\">%2$s</xliff:g></string>\n" + " <array name=\"my_array\">\"\n" + " <item> value1</item>\n" // also test trimming. + " <item>value2\n</item>\n" + " <item>value3</item>\n" + " </array>\n" + "</resources>\n", "values-es/strings.xml", "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<resources>\n" + " <string name=\"show_all_apps\">Todo</string>\n" + "</resources>\n", }); final FolderConfiguration config = FolderConfiguration.getConfigForFolder("values-es-land"); assertFalse(appResources.isFramework()); assertNotNull(config); final LayoutLog logger = new LayoutLog() { @Override public void warning(String tag, String message, Object data) { fail(message); } @Override public void fidelityWarning(String tag, String message, Throwable throwable, Object data) { fail(message); } @Override public void error(String tag, String message, Object data) { fail(message); } @Override public void error(String tag, String message, Throwable throwable, Object data) { fail(message); } }; ResourceItemResolver.ResourceProvider provider = new ResourceItemResolver.ResourceProvider() { private ResourceResolver mResolver; @Nullable @Override public ResourceResolver getResolver(boolean createIfNecessary) { if (mResolver == null && createIfNecessary) { Map<ResourceType, Map<String, ResourceValue>> appResourceMap; appResourceMap = appResources.getConfiguredResources(config); Map<ResourceType, Map<String, ResourceValue>> frameworkResourcesMap = frameworkResources.getConfiguredResources(config); assertNotNull(appResourceMap); mResolver = ResourceResolver.create(appResourceMap, frameworkResourcesMap, "MyTheme", true); assertNotNull(mResolver); mResolver.setLogger(logger); } return mResolver; } @Nullable @Override public com.android.ide.common.resources.ResourceRepository getFrameworkResources() { return frameworkResources; } @Nullable @Override public ResourceRepository getAppResources() { return appResources; } }; ResourceItemResolver resolver = new ResourceItemResolver(config, provider, logger); // findResValue assertNotNull(resolver.findResValue("@string/show_all_apps", false)); assertNotNull(resolver.findResValue("@android:string/ok", false)); assertNotNull(resolver.findResValue("@android:string/ok", true)); assertEquals("Todo", resolver.findResValue("@string/show_all_apps", false).getValue()); assertEquals("Home Sample", resolver.findResValue("@string/home_title", false).getValue()); assertEquals("45%", resolver.findResValue("@dimen/dialog_min_width_major", false).getValue()); assertNotNull(resolver.findResValue("@android:color/bright_foreground_dark", true)); assertEquals("@android:color/background_light", resolver.findResValue("@android:color/bright_foreground_dark", true).getValue()); assertEquals("#ffffffff", resolver.findResValue("@android:color/background_light", true).getValue()); // resolveResValue // android:color/bright_foreground_dark => @android:color/background_light => white assertEquals("Todo", resolver.resolveResValue( resolver.findResValue("@string/show_all_apps", false)).getValue()); assertEquals("#ffffffff", resolver.resolveResValue( resolver.findResValue("@android:color/bright_foreground_dark", false)).getValue()); // Test array values. ResourceValue resValue = resolver.findResValue("@array/my_array", false); assertTrue(resValue instanceof ArrayResourceValue); assertEquals(3, ((ArrayResourceValue) resValue).getElementCount()); assertEquals("value1", ((ArrayResourceValue) resValue).getElement(0)); assertEquals("value2", ((ArrayResourceValue) resValue).getElement(1)); assertEquals("value3", ((ArrayResourceValue) resValue).getElement(2)); resValue = resolver.findResValue("@android:array/my_fw_array", false); assertTrue(resValue instanceof ArrayResourceValue); assertEquals(3, ((ArrayResourceValue) resValue).getElementCount()); assertEquals("fw_value1", ((ArrayResourceValue) resValue).getElement(0)); assertEquals("fw_value2", ((ArrayResourceValue) resValue).getElement(1)); assertEquals("fw_value3", ((ArrayResourceValue) resValue).getElement(2)); // Now do everything over again, but this time without a resource resolver. // Also set a lookup chain. resolver = new ResourceItemResolver(config, frameworkResources, appResources, logger); List<ResourceValue> chain = Lists.newArrayList(); resolver.setLookupChainList(chain); // findResValue assertNotNull(resolver.findResValue("@string/show_all_apps", false)); assertNotNull(resolver.findResValue("@android:string/ok", false)); assertNotNull(resolver.findResValue("@android:string/ok", true)); assertEquals("Todo", resolver.findResValue("@string/show_all_apps", false).getValue()); assertEquals("Home Sample", resolver.findResValue("@string/home_title", false).getValue()); assertEquals("45%", resolver.findResValue("@dimen/dialog_min_width_major", false).getValue()); assertNotNull(resolver.findResValue("@android:color/bright_foreground_dark", true)); assertEquals("@android:color/background_light", resolver.findResValue("@android:color/bright_foreground_dark", true).getValue()); assertEquals("#ffffffff", resolver.findResValue("@android:color/background_light", true).getValue()); assertEquals("Todo", resolver.resolveResValue( resolver.findResValue("@string/show_all_apps", false)).getValue()); chain.clear(); ResourceValue v = resolver.findResValue("@android:color/bright_foreground_dark", false); assertEquals("@android:color/bright_foreground_dark => @android:color/background_light", ResourceItemResolver.getDisplayString(ResourceType.COLOR, "bright_foreground_dark", true, chain)); assertEquals("First: ${firstName} Last: ${lastName}", resolver.findResValue("@string/xliff_string", false).getValue()); assertEquals("First: <xliff:g id=\"firstName\">%1$s</xliff:g> Last: <xliff:g id=\"lastName\">%2$s</xliff:g>", resolver.findResValue("@string/xliff_string", false).getRawXmlValue()); chain.clear(); assertEquals("#ffffffff", resolver.resolveResValue(v).getValue()); assertEquals("@android:color/bright_foreground_dark => @android:color/background_light " + "=> #ffffffff", ResourceItemResolver.getDisplayString("@android:color/bright_foreground_dark", chain)); // Try to resolve style attributes resolver = new ResourceItemResolver(config, provider, logger); resolver.setLookupChainList(chain); chain.clear(); ResourceValue target = new ResourceValue(ResourceType.STRING, "dummy", false); target.setValue("?foo"); assertEquals("#ff000000", resolver.resolveResValue(target).getValue()); assertEquals("?foo => ?android:colorForeground => @color/bright_foreground_light => " + "@android:color/background_dark => #ff000000", ResourceItemResolver.getDisplayString("?foo", chain)); // Test array values. resValue = resolver.findResValue("@array/my_array", false); assertTrue(resValue instanceof ArrayResourceValue); assertEquals(3, ((ArrayResourceValue) resValue).getElementCount()); assertEquals("value1", ((ArrayResourceValue) resValue).getElement(0)); assertEquals("value2", ((ArrayResourceValue) resValue).getElement(1)); assertEquals("value3", ((ArrayResourceValue) resValue).getElement(2)); resValue = resolver.findResValue("@android:array/my_fw_array", false); assertTrue(resValue instanceof ArrayResourceValue); assertEquals(3, ((ArrayResourceValue) resValue).getElementCount()); assertEquals("fw_value1", ((ArrayResourceValue) resValue).getElement(0)); assertEquals("fw_value2", ((ArrayResourceValue) resValue).getElement(1)); assertEquals("fw_value3", ((ArrayResourceValue) resValue).getElement(2)); } }