StringPool_test.cpp revision 769de98f2dd41bfe39a1c9f76aefd1ad58942733
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 165TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) { 166 StringPool pool; 167 BigBuffer buffer(1024); 168 StringPool::flattenUtf8(&buffer, pool); 169 170 std::unique_ptr<uint8_t[]> data = util::copy(buffer); 171 android::ResStringPool test; 172 ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR); 173} 174 175constexpr const char16_t* sLongString = u"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使 用するその他のアプリは、起動しても更新されないことがあります。バッテリーセーバーは端末の充電中は自動的にOFFになります。"; 176 177TEST(StringPoolTest, FlattenUtf8) { 178 StringPool pool; 179 180 StringPool::Ref ref1 = pool.makeRef(u"hello"); 181 StringPool::Ref ref2 = pool.makeRef(u"goodbye"); 182 StringPool::Ref ref3 = pool.makeRef(sLongString); 183 StringPool::StyleRef ref4 = pool.makeRef(StyleString{ 184 { u"style" }, 185 { Span{ { u"b" }, 0, 1 }, Span{ { u"i" }, 2, 3 } } 186 }); 187 188 EXPECT_EQ(0u, ref1.getIndex()); 189 EXPECT_EQ(1u, ref2.getIndex()); 190 EXPECT_EQ(2u, ref3.getIndex()); 191 EXPECT_EQ(3u, ref4.getIndex()); 192 193 BigBuffer buffer(1024); 194 StringPool::flattenUtf8(&buffer, pool); 195 196 std::unique_ptr<uint8_t[]> data = util::copy(buffer); 197 { 198 android::ResStringPool test; 199 ASSERT_EQ(test.setTo(data.get(), buffer.size()), android::NO_ERROR); 200 201 EXPECT_EQ(util::getString(test, 0), u"hello"); 202 EXPECT_EQ(util::getString(test, 1), u"goodbye"); 203 EXPECT_EQ(util::getString(test, 2), sLongString); 204 EXPECT_EQ(util::getString(test, 3), u"style"); 205 206 const ResStringPool_span* span = test.styleAt(3); 207 ASSERT_NE(nullptr, span); 208 EXPECT_EQ(util::getString(test, span->name.index), u"b"); 209 EXPECT_EQ(0u, span->firstChar); 210 EXPECT_EQ(1u, span->lastChar); 211 span++; 212 213 ASSERT_NE(ResStringPool_span::END, span->name.index); 214 EXPECT_EQ(util::getString(test, span->name.index), u"i"); 215 EXPECT_EQ(2u, span->firstChar); 216 EXPECT_EQ(3u, span->lastChar); 217 span++; 218 219 EXPECT_EQ(ResStringPool_span::END, span->name.index); 220 } 221} 222 223} // namespace aapt 224