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, "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 66TEST_F(GrouperTest, shouldHaveCorrectNumberOfGroups) { 67 EXPECT_EQ(12u, mGroups.size()); 68} 69 70TEST_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 77TEST_F(GrouperTest, shouldGroupAbi) { 78 expectHasGroupWithSplits(":armeabi", ":x86"); 79} 80 81TEST_F(GrouperTest, shouldGroupLocale) { 82 expectHasGroupWithSplits("pl-rPL", "de-rDE"); 83} 84 85TEST_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 98void GrouperTest::expectHasGroupWithSplits(const char* a) { 99 Vector<const char*> expected; 100 expected.add(a); 101 expectHasGroupWithSplits(expected); 102} 103 104void 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 111void 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 119void 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 128void 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 180void 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