/* * Copyright (C) 2011 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.configuration; import com.android.ide.common.res2.ResourceFile; import com.android.ide.common.res2.ResourceItem; import com.android.resources.Density; import com.android.resources.ResourceFolderType; import com.android.resources.ResourceType; import com.android.resources.ScreenOrientation; import com.android.resources.ScreenRound; import com.android.resources.UiMode; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import junit.framework.TestCase; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class FolderConfigurationTest extends TestCase { /* * Test createDefault creates all the qualifiers. */ public void testCreateDefault() { FolderConfiguration defaultConfig = new FolderConfiguration(); defaultConfig.createDefault(); // this is always valid and up to date. final int count = FolderConfiguration.getQualifierCount(); // make sure all the qualifiers were created. for (int i = 0 ; i < count ; i++) { assertNotNull(defaultConfig.getQualifier(i)); } } public void testSimpleResMatch() { runConfigMatchTest( "en-rGB-port-hdpi-notouch-12key", 3, "", "en", "fr-rCA", "en-port", "en-notouch-12key", "port-ldpi", "port-notouch-12key"); } public void testIsMatchFor() { FolderConfiguration en = FolderConfiguration.getConfigForFolder("values-en"); FolderConfiguration enUs = FolderConfiguration.getConfigForFolder("values-en-rUS"); assertNotNull(en); assertNotNull(enUs); assertTrue(enUs.isMatchFor(enUs)); assertTrue(en.isMatchFor(en)); assertTrue(enUs.isMatchFor(en)); assertTrue(en.isMatchFor(enUs)); } public void testVersionResMatch() { runConfigMatchTest( "en-rUS-w600dp-h1024dp-large-port-mdpi-finger-nokeys-v12", 2, "", "large", "w540dp"); } public void testVersionResMatchWithBcp47() { runConfigMatchTest( "b+kok+Knda+419+VARIANT-w600dp", 2, "", "large", "w540dp"); } @SuppressWarnings("ConstantConditions") public void testAddQualifier() { FolderConfiguration defaultConfig = new FolderConfiguration(); defaultConfig.createDefault(); final int count = FolderConfiguration.getQualifierCount(); for (int i = 0 ; i < count ; i++) { FolderConfiguration empty = new FolderConfiguration(); ResourceQualifier q = defaultConfig.getQualifier(i); empty.addQualifier(q); // check it was added assertNotNull( "addQualifier failed for " + q.getClass().getName(), empty.getQualifier(i)); } } @SuppressWarnings("ConstantConditions") public void testGetConfig1() { FolderConfiguration configForFolder = FolderConfiguration.getConfig(new String[] { "values", "en", "rUS" }); assertNotNull(configForFolder); assertEquals("en", configForFolder.getLocaleQualifier().getLanguage()); assertEquals("US", configForFolder.getLocaleQualifier().getRegion()); assertNull(configForFolder.getScreenDimensionQualifier()); assertNull(configForFolder.getLayoutDirectionQualifier()); } @SuppressWarnings("ConstantConditions") public void testInvalidRepeats() { assertNull(FolderConfiguration.getConfigForFolder("values-en-rUS-rES")); } @SuppressWarnings("ConstantConditions") public void testGetConfig2() { FolderConfiguration configForFolder = FolderConfiguration.getConfigForFolder("values-en-rUS"); assertNotNull(configForFolder); assertEquals("en", configForFolder.getLocaleQualifier().getLanguage()); assertEquals("US", configForFolder.getLocaleQualifier().getRegion()); assertNull(configForFolder.getScreenDimensionQualifier()); assertNull(configForFolder.getLayoutDirectionQualifier()); } @SuppressWarnings("ConstantConditions") public void testGetConfigCaseInsensitive() { FolderConfiguration configForFolder = FolderConfiguration.getConfigForFolder("values-EN-rus"); assertNotNull(configForFolder); assertEquals("en", configForFolder.getLocaleQualifier().getLanguage()); assertEquals("US", configForFolder.getLocaleQualifier().getRegion()); assertNull(configForFolder.getScreenDimensionQualifier()); assertNull(configForFolder.getLayoutDirectionQualifier()); assertEquals("layout-en-rUS", configForFolder.getFolderName(ResourceFolderType.LAYOUT)); runConfigMatchTest( "en-rgb-Port-HDPI-notouch-12key", 3, "", "en", "fr-rCA", "en-port", "en-notouch-12key", "port-ldpi", "port-notouch-12key"); } public void testToStrings() { FolderConfiguration configForFolder = FolderConfiguration.getConfigForFolder("values-en-rUS"); assertNotNull(configForFolder); assertEquals("Locale en_US", configForFolder.toDisplayString()); assertEquals("en,US", configForFolder.toShortDisplayString()); assertEquals("layout-en-rUS", configForFolder.getFolderName(ResourceFolderType.LAYOUT)); assertEquals("-en-rUS", configForFolder.getUniqueKey()); } public void testNormalize() { // test normal qualifiers that all have the same min SDK doTestNormalize(4, "large"); doTestNormalize(8, "notnight"); doTestNormalize(13, "sw42dp"); doTestNormalize(17, "ldrtl"); // test we take the highest qualifier doTestNormalize(13, "sw42dp", "large"); // test where different values have different minSdk /* Ambiguous now that aapt accepts 3 letter language codes; get clarification. doTestNormalize(8, "car"); */ doTestNormalize(13, "television"); doTestNormalize(16, "appliance"); // test case where there's already a higher -v# qualifier doTestNormalize(18, "sw42dp", "v18"); // finally test that in some cases it won't add a -v# value. FolderConfiguration configForFolder = FolderConfiguration.getConfigFromQualifiers( Collections.singletonList("port")); assertNotNull(configForFolder); configForFolder.normalize(); VersionQualifier versionQualifier = configForFolder.getVersionQualifier(); assertNull(versionQualifier); } @SuppressWarnings("ConstantConditions") public void testConfigMatch() { FolderConfiguration ref = new FolderConfiguration(); ref.createDefault(); ref.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT)); List<Configurable> configurables = getConfigurable( "", // No qualifier "xhdpi", // A matching qualifier "land", // A non matching qualifier "xhdpi-v14", // Matching qualifier with ignored qualifier "v14" // Ignored qualifier ); // First check that when all qualifiers are present, we match only one resource. List<Configurable> matchingConfigurables = ref.findMatchingConfigurables(configurables); assertEquals(ImmutableList.of(configurables.get(3)), matchingConfigurables); // Now remove the version qualifier and check that we "xhdpi" and "xhdpi-v14" ref.setVersionQualifier(null); matchingConfigurables = ref.findMatchingConfigurables(configurables); assertEquals(ImmutableSet.of(configurables.get(1), configurables.get(3)), ImmutableSet.copyOf(matchingConfigurables)); } public void testIsRoundMatch() { FolderConfiguration configForFolder = FolderConfiguration .getConfigForFolder("values-en-round"); assertNotNull(configForFolder); assertNotNull(configForFolder.getScreenRoundQualifier()); assertEquals(ScreenRound.ROUND, configForFolder.getScreenRoundQualifier().getValue()); runConfigMatchTest("en-rgb-Round-Port-HDPI-notouch-12key", 4, "", "en", "fr-rCa", "en-notround-hdpi", "en-notouch"); runConfigMatchTest("en-rgb-Round-Port-HDPI-notouch-12key", 2, "", "en", "en-round-hdpi", "port-12key"); } // --- helper methods private static final class MockConfigurable implements Configurable { private final FolderConfiguration mConfig; MockConfigurable(String config) { mConfig = FolderConfiguration.getConfig(getFolderSegments(config)); } @Override public FolderConfiguration getConfiguration() { return mConfig; } @Override public String toString() { return mConfig.toString(); } } private static void runConfigMatchTest(String refConfig, int resultIndex, String... configs) { FolderConfiguration reference = FolderConfiguration.getConfig(getFolderSegments(refConfig)); assertNotNull(reference); List<Configurable> list = getConfigurable(configs); Configurable match = reference.findMatchingConfigurable(list); assertEquals(resultIndex, list.indexOf(match)); } private static List<Configurable> getConfigurable(String... configs) { ArrayList<Configurable> list = new ArrayList<Configurable>(); for (String config : configs) { list.add(new MockConfigurable(config)); } return list; } private static String[] getFolderSegments(String config) { return (!config.isEmpty() ? "foo-" + config : "foo").split("-"); } public void testSort1() { List<FolderConfiguration> configs = Lists.newArrayList(); FolderConfiguration f1 = FolderConfiguration.getConfigForFolder("values-hdpi"); FolderConfiguration f2 = FolderConfiguration.getConfigForFolder("values-v11"); FolderConfiguration f3 = FolderConfiguration.getConfigForFolder("values-sp"); FolderConfiguration f4 = FolderConfiguration.getConfigForFolder("values-v4"); configs.add(f1); configs.add(f2); configs.add(f3); configs.add(f4); assertEquals(Arrays.asList(f1, f2, f3, f4), configs); Collections.sort(configs); assertEquals(Arrays.asList(f2, f4, f1, f3), configs); } public void testSort2() { // Test case from // http://developer.android.com/guide/topics/resources/providing-resources.html#BestMatch List<FolderConfiguration> configs = Lists.newArrayList(); for (String name : new String[] { "drawable", "drawable-en", "drawable-fr-rCA", "drawable-en-port", "drawable-en-notouch-12key", "drawable-port-ldpi", "drawable-port-notouch-12key" }) { FolderConfiguration config = FolderConfiguration.getConfigForFolder(name); assertNotNull(name, config); configs.add(config); } Collections.sort(configs); Collections.reverse(configs); //assertEquals("", configs.get(0).toDisplayString()); List<String> strings = Lists.newArrayList(); for (FolderConfiguration config : configs) { strings.add(config.getUniqueKey()); } assertEquals("-fr-rCA,-en-port,-en-notouch-12key,-en,-port-ldpi,-port-notouch-12key,", Joiner.on(",").skipNulls().join(strings)); } private void doTestNormalize(int expectedVersion, String... segments) { FolderConfiguration configForFolder = FolderConfiguration.getConfigFromQualifiers( Arrays.asList(segments)); assertNotNull(configForFolder); configForFolder.normalize(); VersionQualifier versionQualifier = configForFolder.getVersionQualifier(); assertNotNull(versionQualifier); assertEquals(expectedVersion, versionQualifier.getVersion()); } public void testCarModeAndLanguage() { FolderConfiguration config = FolderConfiguration.getConfigForFolder("values-car"); assertNotNull(config); assertNull(config.getLocaleQualifier()); assertNotNull(config.getUiModeQualifier()); assertEquals(UiMode.CAR, config.getUiModeQualifier().getValue()); config = FolderConfiguration.getConfigForFolder("values-b+car"); assertNotNull(config); assertNotNull(config.getLocaleQualifier()); assertNull(config.getUiModeQualifier()); assertEquals("car", config.getLocaleQualifier().getLanguage()); } public void testIsMatchForBcp47() { FolderConfiguration blankFolder = FolderConfiguration.getConfigForFolder("values"); FolderConfiguration enFolder = FolderConfiguration.getConfigForFolder("values-en"); FolderConfiguration deFolder = FolderConfiguration.getConfigForFolder("values-de"); FolderConfiguration deBcp47Folder = FolderConfiguration.getConfigForFolder("values-b+de"); assertNotNull(enFolder); assertNotNull(deFolder); assertNotNull(deBcp47Folder); assertFalse(enFolder.isMatchFor(deFolder)); assertFalse(deFolder.isMatchFor(enFolder)); assertFalse(enFolder.isMatchFor(deBcp47Folder)); assertFalse(deBcp47Folder.isMatchFor(enFolder)); assertTrue(enFolder.isMatchFor(blankFolder)); assertTrue(deFolder.isMatchFor(blankFolder)); assertTrue(deBcp47Folder.isMatchFor(blankFolder)); } public void testFindMatchingConfigurables() { ResourceItem itemBlank = new ResourceItem("foo", ResourceType.STRING, null) { @Override public String toString() { return "itemBlank"; } }; ResourceFile sourceBlank = new ResourceFile(new File("sourceBlank"), itemBlank, ""); itemBlank.setSource(sourceBlank); FolderConfiguration configBlank = itemBlank.getConfiguration(); ResourceItem itemEn = new ResourceItem("foo", ResourceType.STRING, null) { @Override public String toString() { return "itemEn"; } }; ResourceFile sourceEn = new ResourceFile(new File("sourceEn"), itemBlank, "en"); itemEn.setSource(sourceEn); FolderConfiguration configEn = itemEn.getConfiguration(); ResourceItem itemBcpEn = new ResourceItem("foo", ResourceType.STRING, null) { @Override public String toString() { return "itemBcpEn"; } }; ResourceFile sourceBcpEn = new ResourceFile(new File("sourceBcpEn"), itemBlank, "b+en"); itemBcpEn.setSource(sourceBcpEn); FolderConfiguration configBcpEn = itemBcpEn.getConfiguration(); ResourceItem itemDe = new ResourceItem("foo", ResourceType.STRING, null) { @Override public String toString() { return "itemDe"; } }; ResourceFile sourceDe = new ResourceFile(new File("sourceDe"), itemBlank, "de"); itemDe.setSource(sourceDe); FolderConfiguration configDe = itemDe.getConfiguration(); // "" matches everything assertEquals(Arrays.<Configurable>asList(itemBlank, itemBcpEn, itemEn, itemDe), configBlank.findMatchingConfigurables( Arrays.asList(itemBlank, itemBcpEn, itemEn, itemDe))); // "de" matches only "" and "de" assertEquals(Arrays.<Configurable>asList(itemBlank, itemDe), configDe.findMatchingConfigurables( Arrays.asList(itemBlank, itemBcpEn, itemEn, itemDe))); // "en" matches "en" and "b+en" assertTrue(configEn.isMatchFor(configBcpEn)); assertTrue(configBcpEn.isMatchFor(configEn)); assertEquals(Arrays.<Configurable>asList(itemBcpEn, itemEn), configEn.findMatchingConfigurables( Arrays.asList(itemBlank, itemBcpEn, itemEn, itemDe))); // "b+en" matches "en and "b+en" assertEquals(Arrays.<Configurable>asList(itemBcpEn, itemEn), configBcpEn.findMatchingConfigurables( Arrays.asList(itemBlank, itemBcpEn, itemEn, itemDe))); } public void testFromQualifierString() throws Exception { FolderConfiguration blankFolder = FolderConfiguration.getConfigForQualifierString(""); FolderConfiguration enFolder = FolderConfiguration.getConfigForQualifierString("en"); FolderConfiguration deFolder = FolderConfiguration.getConfigForQualifierString("de"); FolderConfiguration deBcp47Folder = FolderConfiguration.getConfigForQualifierString("b+de"); FolderConfiguration twoQualifiersFolder = FolderConfiguration.getConfigForQualifierString("de-hdpi"); assertNotNull(enFolder); assertNotNull(deFolder); assertNotNull(deBcp47Folder); assertFalse(enFolder.isMatchFor(deFolder)); assertFalse(deFolder.isMatchFor(enFolder)); assertFalse(enFolder.isMatchFor(deBcp47Folder)); assertFalse(deBcp47Folder.isMatchFor(enFolder)); assertTrue(enFolder.isMatchFor(blankFolder)); assertTrue(deFolder.isMatchFor(blankFolder)); assertTrue(deBcp47Folder.isMatchFor(blankFolder)); assertEquals("de", twoQualifiersFolder.getLocaleQualifier().getLanguage()); assertEquals(Density.HIGH, twoQualifiersFolder.getDensityQualifier().getValue()); } public void testCopyOf() throws Exception { FolderConfiguration deBcp47Folder = FolderConfiguration.getConfigForFolder("values-b+de"); FolderConfiguration copy = FolderConfiguration.copyOf(deBcp47Folder); assertTrue(copy.isMatchFor(deBcp47Folder)); copy.setLocaleQualifier(new LocaleQualifier("en")); assertEquals("en", copy.getLocaleQualifier().getLanguage()); assertEquals("de", deBcp47Folder.getLocaleQualifier().getLanguage()); copy.setDensityQualifier(new DensityQualifier(Density.HIGH)); assertEquals(Density.HIGH, copy.getDensityQualifier().getValue()); assertNull(deBcp47Folder.getDensityQualifier()); FolderConfiguration blankFolder = FolderConfiguration.getConfigForFolder("values"); copy = FolderConfiguration.copyOf(blankFolder); assertTrue(copy.isMatchFor(blankFolder)); copy.setVersionQualifier(new VersionQualifier(21)); assertEquals(21, copy.getVersionQualifier().getVersion()); assertNull(blankFolder.getVersionQualifier()); } }