StringPool_test.cpp revision 6f6ceb7e1456698b1f33e04536bfb3227f9fcfcb
1/* 2 * Copyright (C) 2015 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 "StringPool.h" 18#include "Util.h" 19 20#include <gtest/gtest.h> 21#include <string> 22 23namespace aapt { 24 25TEST(StringPoolTest, InsertOneString) { 26 StringPool pool; 27 28 StringPool::Ref ref = pool.makeRef(u"wut"); 29 EXPECT_EQ(*ref, u"wut"); 30} 31 32TEST(StringPoolTest, InsertTwoUniqueStrings) { 33 StringPool pool; 34 35 StringPool::Ref ref = pool.makeRef(u"wut"); 36 StringPool::Ref ref2 = pool.makeRef(u"hey"); 37 38 EXPECT_EQ(*ref, u"wut"); 39 EXPECT_EQ(*ref2, u"hey"); 40} 41 42TEST(StringPoolTest, DoNotInsertNewDuplicateString) { 43 StringPool pool; 44 45 StringPool::Ref ref = pool.makeRef(u"wut"); 46 StringPool::Ref ref2 = pool.makeRef(u"wut"); 47 48 EXPECT_EQ(*ref, u"wut"); 49 EXPECT_EQ(*ref2, u"wut"); 50 EXPECT_EQ(1u, pool.size()); 51} 52 53TEST(StringPoolTest, MaintainInsertionOrderIndex) { 54 StringPool pool; 55 56 StringPool::Ref ref = pool.makeRef(u"z"); 57 StringPool::Ref ref2 = pool.makeRef(u"a"); 58 StringPool::Ref ref3 = pool.makeRef(u"m"); 59 60 EXPECT_EQ(0u, ref.getIndex()); 61 EXPECT_EQ(1u, ref2.getIndex()); 62 EXPECT_EQ(2u, ref3.getIndex()); 63} 64 65TEST(StringPoolTest, PruneStringsWithNoReferences) { 66 StringPool pool; 67 68 { 69 StringPool::Ref ref = pool.makeRef(u"wut"); 70 EXPECT_EQ(*ref, u"wut"); 71 EXPECT_EQ(1u, pool.size()); 72 } 73 74 EXPECT_EQ(1u, pool.size()); 75 pool.prune(); 76 EXPECT_EQ(0u, pool.size()); 77} 78 79TEST(StringPoolTest, SortAndMaintainIndexesInReferences) { 80 StringPool pool; 81 82 StringPool::Ref ref = pool.makeRef(u"z"); 83 StringPool::StyleRef ref2 = pool.makeRef(StyleString{ {u"a"} }); 84 StringPool::Ref ref3 = pool.makeRef(u"m"); 85 86 EXPECT_EQ(*ref, u"z"); 87 EXPECT_EQ(0u, ref.getIndex()); 88 89 EXPECT_EQ(*(ref2->str), u"a"); 90 EXPECT_EQ(1u, ref2.getIndex()); 91 92 EXPECT_EQ(*ref3, u"m"); 93 EXPECT_EQ(2u, ref3.getIndex()); 94 95 pool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { 96 return a.value < b.value; 97 }); 98 99 100 EXPECT_EQ(*ref, u"z"); 101 EXPECT_EQ(2u, ref.getIndex()); 102 103 EXPECT_EQ(*(ref2->str), u"a"); 104 EXPECT_EQ(0u, ref2.getIndex()); 105 106 EXPECT_EQ(*ref3, u"m"); 107 EXPECT_EQ(1u, ref3.getIndex()); 108} 109 110TEST(StringPoolTest, SortAndStillDedupe) { 111 StringPool pool; 112 113 StringPool::Ref ref = pool.makeRef(u"z"); 114 StringPool::Ref ref2 = pool.makeRef(u"a"); 115 StringPool::Ref ref3 = pool.makeRef(u"m"); 116 117 pool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool { 118 return a.value < b.value; 119 }); 120 121 StringPool::Ref ref4 = pool.makeRef(u"z"); 122 StringPool::Ref ref5 = pool.makeRef(u"a"); 123 StringPool::Ref ref6 = pool.makeRef(u"m"); 124 125 EXPECT_EQ(ref4.getIndex(), ref.getIndex()); 126 EXPECT_EQ(ref5.getIndex(), ref2.getIndex()); 127 EXPECT_EQ(ref6.getIndex(), ref3.getIndex()); 128} 129 130TEST(StringPoolTest, AddStyles) { 131 StringPool pool; 132 133 StyleString str { 134 { u"android" }, 135 { 136 Span{ { u"b" }, 2, 6 } 137 } 138 }; 139 140 StringPool::StyleRef ref = pool.makeRef(str); 141 142 EXPECT_EQ(0u, ref.getIndex()); 143 EXPECT_EQ(std::u16string(u"android"), *(ref->str)); 144 ASSERT_EQ(1u, ref->spans.size()); 145 146 const StringPool::Span& span = ref->spans.front(); 147 EXPECT_EQ(*(span.name), u"b"); 148 EXPECT_EQ(2u, span.firstChar); 149 EXPECT_EQ(6u, span.lastChar); 150} 151 152TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) { 153 StringPool pool; 154 155 StringPool::Ref ref = pool.makeRef(u"android"); 156 157 StyleString str { { u"android" } }; 158 StringPool::StyleRef styleRef = pool.makeRef(str); 159 160 EXPECT_NE(ref.getIndex(), styleRef.getIndex()); 161} 162 163constexpr const char16_t* sLongString = u"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使 用するその他のアプリは、起動しても更新されないことがあります。バッテリーセーバーは端末の充電中は自動的にOFFになります。"; 164 165TEST(StringPoolTest, FlattenUtf8) { 166 StringPool pool; 167 168 StringPool::Ref ref1 = pool.makeRef(u"hello"); 169 StringPool::Ref ref2 = pool.makeRef(u"goodbye"); 170 StringPool::Ref ref3 = pool.makeRef(sLongString); 171 StringPool::StyleRef ref4 = pool.makeRef(StyleString{ 172 { u"style" }, 173 { Span{ { u"b" }, 0, 1 }, Span{ { u"i" }, 2, 3 } } 174 }); 175 176 EXPECT_EQ(0u, ref1.getIndex()); 177 EXPECT_EQ(1u, ref2.getIndex()); 178 EXPECT_EQ(2u, ref3.getIndex()); 179 EXPECT_EQ(3u, ref4.getIndex()); 180 181 BigBuffer buffer(1024); 182 StringPool::flattenUtf8(&buffer, pool); 183 184 uint8_t* data = new uint8_t[buffer.size()]; 185 uint8_t* p = data; 186 for (const auto& b : buffer) { 187 memcpy(p, b.buffer.get(), b.size); 188 p += b.size; 189 } 190 191 { 192 android::ResStringPool test; 193 ASSERT_EQ(android::NO_ERROR, test.setTo(data, buffer.size())); 194 195 EXPECT_EQ(util::getString(test, 0), u"hello"); 196 EXPECT_EQ(util::getString(test, 1), u"goodbye"); 197 EXPECT_EQ(util::getString(test, 2), sLongString); 198 EXPECT_EQ(util::getString(test, 3), u"style"); 199 200 const android::ResStringPool_span* span = test.styleAt(3); 201 ASSERT_NE(nullptr, span); 202 EXPECT_EQ(util::getString(test, span->name.index), u"b"); 203 EXPECT_EQ(0u, span->firstChar); 204 EXPECT_EQ(1u, span->lastChar); 205 span++; 206 207 ASSERT_NE(android::ResStringPool_span::END, span->name.index); 208 EXPECT_EQ(util::getString(test, span->name.index), u"i"); 209 EXPECT_EQ(2u, span->firstChar); 210 EXPECT_EQ(3u, span->lastChar); 211 span++; 212 213 EXPECT_EQ(android::ResStringPool_span::END, span->name.index); 214 } 215 delete[] data; 216} 217 218} // namespace aapt 219