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 25using namespace android; 26 27namespace split { 28 29class GrouperTest : public ::testing::Test { 30protected: 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 68TEST_F(GrouperTest, shouldHaveCorrectNumberOfGroups) { 69 EXPECT_EQ(15u, mGroups.size()); 70} 71 72TEST_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 79TEST_F(GrouperTest, shouldGroupAbi) { 80 expectHasGroupWithSplits(":armeabi", ":x86"); 81} 82 83TEST_F(GrouperTest, shouldGroupLocale) { 84 expectHasGroupWithSplits("pl-rPL"); 85 expectHasGroupWithSplits("de-rDE"); 86 expectHasGroupWithSplits("fr"); 87 expectHasGroupWithSplits("fr-rCA"); 88} 89 90TEST_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 103void GrouperTest::expectHasGroupWithSplits(const char* a) { 104 Vector<const char*> expected; 105 expected.add(a); 106 expectHasGroupWithSplits(expected); 107} 108 109void 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 116void 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 124void 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 133void 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 185void 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