1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 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 #include "Grouper.h" 18 19 #include "SplitDescription.h" 20 21 #include <gtest/gtest.h> 22 #include <utils/String8.h> 23 #include <utils/Vector.h> 24 25 using namespace android; 26 27 namespace split { 28 29 class GrouperTest : public ::testing::Test { 30 protected: 31 virtual void SetUp() { 32 Vector<SplitDescription> splits; 33 addSplit(splits, "en-rUS-sw600dp-hdpi"); 34 addSplit(splits, "fr-rFR-sw600dp-hdpi"); 35 addSplit(splits, "fr-rFR-sw600dp-xhdpi"); 36 addSplit(splits, ":armeabi"); 37 addSplit(splits, "en-rUS-sw300dp-xhdpi"); 38 addSplit(splits, "large"); 39 addSplit(splits, "pl-rPL"); 40 addSplit(splits, "xlarge"); 41 addSplit(splits, "en-rUS-sw600dp-xhdpi"); 42 addSplit(splits, "en-rUS-sw300dp-hdpi"); 43 addSplit(splits, "xxhdpi"); 44 addSplit(splits, "hdpi"); 45 addSplit(splits, "de-rDE"); 46 addSplit(splits, "xhdpi"); 47 addSplit(splits, ":x86"); 48 addSplit(splits, "anydpi"); 49 addSplit(splits, "v7"); 50 addSplit(splits, "v8"); 51 addSplit(splits, "sw600dp"); 52 addSplit(splits, "sw300dp"); 53 mGroups = groupByMutualExclusivity(splits); 54 } 55 56 void addSplit(Vector<SplitDescription>& splits, const char* str); 57 void expectHasGroupWithSplits(const char* a); 58 void expectHasGroupWithSplits(const char* a, const char* b); 59 void expectHasGroupWithSplits(const char* a, const char* b, const char* c); 60 void expectHasGroupWithSplits(const char* a, const char* b, const char* c, const char* d); 61 void expectHasGroupWithSplits(const Vector<const char*>& expectedStrs); 62 63 Vector<SortedVector<SplitDescription> > mGroups; 64 }; 65 66 TEST_F(GrouperTest, shouldHaveCorrectNumberOfGroups) { 67 EXPECT_EQ(12u, mGroups.size()); 68 } 69 70 TEST_F(GrouperTest, shouldGroupDensities) { 71 expectHasGroupWithSplits("en-rUS-sw300dp-hdpi", "en-rUS-sw300dp-xhdpi"); 72 expectHasGroupWithSplits("en-rUS-sw600dp-hdpi", "en-rUS-sw600dp-xhdpi"); 73 expectHasGroupWithSplits("fr-rFR-sw600dp-hdpi", "fr-rFR-sw600dp-xhdpi"); 74 expectHasGroupWithSplits("hdpi", "xhdpi", "xxhdpi", "anydpi"); 75 } 76 77 TEST_F(GrouperTest, shouldGroupAbi) { 78 expectHasGroupWithSplits(":armeabi", ":x86"); 79 } 80 81 TEST_F(GrouperTest, shouldGroupLocale) { 82 expectHasGroupWithSplits("pl-rPL", "de-rDE"); 83 } 84 85 TEST_F(GrouperTest, shouldGroupEachSplitIntoItsOwnGroup) { 86 expectHasGroupWithSplits("large"); 87 expectHasGroupWithSplits("xlarge"); 88 expectHasGroupWithSplits("v7"); 89 expectHasGroupWithSplits("v8"); 90 expectHasGroupWithSplits("sw600dp"); 91 expectHasGroupWithSplits("sw300dp"); 92 } 93 94 // 95 // Helper methods 96 // 97 98 void GrouperTest::expectHasGroupWithSplits(const char* a) { 99 Vector<const char*> expected; 100 expected.add(a); 101 expectHasGroupWithSplits(expected); 102 } 103 104 void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b) { 105 Vector<const char*> expected; 106 expected.add(a); 107 expected.add(b); 108 expectHasGroupWithSplits(expected); 109 } 110 111 void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b, const char* c) { 112 Vector<const char*> expected; 113 expected.add(a); 114 expected.add(b); 115 expected.add(c); 116 expectHasGroupWithSplits(expected); 117 } 118 119 void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b, const char* c, const char* d) { 120 Vector<const char*> expected; 121 expected.add(a); 122 expected.add(b); 123 expected.add(c); 124 expected.add(d); 125 expectHasGroupWithSplits(expected); 126 } 127 128 void GrouperTest::expectHasGroupWithSplits(const Vector<const char*>& expectedStrs) { 129 Vector<SplitDescription> splits; 130 const size_t expectedStrCount = expectedStrs.size(); 131 for (size_t i = 0; i < expectedStrCount; i++) { 132 splits.add(); 133 if (!SplitDescription::parse(String8(expectedStrs[i]), &splits.editTop())) { 134 ADD_FAILURE() << "Failed to parse SplitDescription " << expectedStrs[i]; 135 return; 136 } 137 } 138 const size_t splitCount = splits.size(); 139 140 const size_t groupCount = mGroups.size(); 141 for (size_t i = 0; i < groupCount; i++) { 142 const SortedVector<SplitDescription>& group = mGroups[i]; 143 if (group.size() != splitCount) { 144 continue; 145 } 146 147 size_t found = 0; 148 for (size_t j = 0; j < splitCount; j++) { 149 if (group.indexOf(splits[j]) >= 0) { 150 found++; 151 } 152 } 153 154 if (found == splitCount) { 155 return; 156 } 157 } 158 159 String8 errorMessage("Failed to find expected group ["); 160 for (size_t i = 0; i < splitCount; i++) { 161 if (i != 0) { 162 errorMessage.append(", "); 163 } 164 errorMessage.append(splits[i].toString()); 165 } 166 errorMessage.append("].\nActual:\n"); 167 168 for (size_t i = 0; i < groupCount; i++) { 169 errorMessage.appendFormat("Group %d:\n", int(i + 1)); 170 const SortedVector<SplitDescription>& group = mGroups[i]; 171 for (size_t j = 0; j < group.size(); j++) { 172 errorMessage.append(" "); 173 errorMessage.append(group[j].toString()); 174 errorMessage.append("\n"); 175 } 176 } 177 ADD_FAILURE() << errorMessage.string(); 178 } 179 180 void GrouperTest::addSplit(Vector<SplitDescription>& splits, const char* str) { 181 splits.add(); 182 EXPECT_TRUE(SplitDescription::parse(String8(str), &splits.editTop())); 183 } 184 185 } // namespace split 186