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