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, "fr-rCA"); 41 addSplit(splits, "fr"); 42 addSplit(splits, "xlarge"); 43 addSplit(splits, "en-rUS-sw600dp-xhdpi"); 44 addSplit(splits, "en-rUS-sw300dp-hdpi"); 45 addSplit(splits, "xxhdpi"); 46 addSplit(splits, "hdpi"); 47 addSplit(splits, "de-rDE"); 48 addSplit(splits, "xhdpi"); 49 addSplit(splits, ":x86"); 50 addSplit(splits, "anydpi"); 51 addSplit(splits, "v7"); 52 addSplit(splits, "v8"); 53 addSplit(splits, "sw600dp"); 54 addSplit(splits, "sw300dp"); 55 mGroups = groupByMutualExclusivity(splits); 56 } 57 58 void addSplit(Vector<SplitDescription>& splits, const char* str); 59 void expectHasGroupWithSplits(const char* a); 60 void expectHasGroupWithSplits(const char* a, const char* b); 61 void expectHasGroupWithSplits(const char* a, const char* b, const char* c); 62 void expectHasGroupWithSplits(const char* a, const char* b, const char* c, const char* d); 63 void expectHasGroupWithSplits(const Vector<const char*>& expectedStrs); 64 65 Vector<SortedVector<SplitDescription> > mGroups; 66 }; 67 68 TEST_F(GrouperTest, shouldHaveCorrectNumberOfGroups) { 69 EXPECT_EQ(15u, mGroups.size()); 70 } 71 72 TEST_F(GrouperTest, shouldGroupDensities) { 73 expectHasGroupWithSplits("en-rUS-sw300dp-hdpi", "en-rUS-sw300dp-xhdpi"); 74 expectHasGroupWithSplits("en-rUS-sw600dp-hdpi", "en-rUS-sw600dp-xhdpi"); 75 expectHasGroupWithSplits("fr-rFR-sw600dp-hdpi", "fr-rFR-sw600dp-xhdpi"); 76 expectHasGroupWithSplits("hdpi", "xhdpi", "xxhdpi", "anydpi"); 77 } 78 79 TEST_F(GrouperTest, shouldGroupAbi) { 80 expectHasGroupWithSplits(":armeabi", ":x86"); 81 } 82 83 TEST_F(GrouperTest, shouldGroupLocale) { 84 expectHasGroupWithSplits("pl-rPL"); 85 expectHasGroupWithSplits("de-rDE"); 86 expectHasGroupWithSplits("fr"); 87 expectHasGroupWithSplits("fr-rCA"); 88 } 89 90 TEST_F(GrouperTest, shouldGroupEachSplitIntoItsOwnGroup) { 91 expectHasGroupWithSplits("large"); 92 expectHasGroupWithSplits("xlarge"); 93 expectHasGroupWithSplits("v7"); 94 expectHasGroupWithSplits("v8"); 95 expectHasGroupWithSplits("sw600dp"); 96 expectHasGroupWithSplits("sw300dp"); 97 } 98 99 // 100 // Helper methods 101 // 102 103 void GrouperTest::expectHasGroupWithSplits(const char* a) { 104 Vector<const char*> expected; 105 expected.add(a); 106 expectHasGroupWithSplits(expected); 107 } 108 109 void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b) { 110 Vector<const char*> expected; 111 expected.add(a); 112 expected.add(b); 113 expectHasGroupWithSplits(expected); 114 } 115 116 void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b, const char* c) { 117 Vector<const char*> expected; 118 expected.add(a); 119 expected.add(b); 120 expected.add(c); 121 expectHasGroupWithSplits(expected); 122 } 123 124 void GrouperTest::expectHasGroupWithSplits(const char* a, const char* b, const char* c, const char* d) { 125 Vector<const char*> expected; 126 expected.add(a); 127 expected.add(b); 128 expected.add(c); 129 expected.add(d); 130 expectHasGroupWithSplits(expected); 131 } 132 133 void GrouperTest::expectHasGroupWithSplits(const Vector<const char*>& expectedStrs) { 134 Vector<SplitDescription> splits; 135 const size_t expectedStrCount = expectedStrs.size(); 136 for (size_t i = 0; i < expectedStrCount; i++) { 137 splits.add(); 138 if (!SplitDescription::parse(String8(expectedStrs[i]), &splits.editTop())) { 139 ADD_FAILURE() << "Failed to parse SplitDescription " << expectedStrs[i]; 140 return; 141 } 142 } 143 const size_t splitCount = splits.size(); 144 145 const size_t groupCount = mGroups.size(); 146 for (size_t i = 0; i < groupCount; i++) { 147 const SortedVector<SplitDescription>& group = mGroups[i]; 148 if (group.size() != splitCount) { 149 continue; 150 } 151 152 size_t found = 0; 153 for (size_t j = 0; j < splitCount; j++) { 154 if (group.indexOf(splits[j]) >= 0) { 155 found++; 156 } 157 } 158 159 if (found == splitCount) { 160 return; 161 } 162 } 163 164 String8 errorMessage("Failed to find expected group ["); 165 for (size_t i = 0; i < splitCount; i++) { 166 if (i != 0) { 167 errorMessage.append(", "); 168 } 169 errorMessage.append(splits[i].toString()); 170 } 171 errorMessage.append("].\nActual:\n"); 172 173 for (size_t i = 0; i < groupCount; i++) { 174 errorMessage.appendFormat("Group %d:\n", int(i + 1)); 175 const SortedVector<SplitDescription>& group = mGroups[i]; 176 for (size_t j = 0; j < group.size(); j++) { 177 errorMessage.append(" "); 178 errorMessage.append(group[j].toString()); 179 errorMessage.append("\n"); 180 } 181 } 182 ADD_FAILURE() << errorMessage.string(); 183 } 184 185 void GrouperTest::addSplit(Vector<SplitDescription>& splits, const char* str) { 186 splits.add(); 187 EXPECT_TRUE(SplitDescription::parse(String8(str), &splits.editTop())); 188 } 189 190 } // namespace split 191