Pseudolocalizer_test.cpp revision b2106687e1fa781d6470ae6374122cf34468846f
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 "compile/Pseudolocalizer.h" 18#include "util/Util.h" 19 20#include <androidfw/ResourceTypes.h> 21#include <gtest/gtest.h> 22 23namespace aapt { 24 25// In this context, 'Axis' represents a particular field in the configuration, 26// such as language or density. 27 28static ::testing::AssertionResult simpleHelper(const char* input, const char* expected, 29 Pseudolocalizer::Method method) { 30 Pseudolocalizer pseudo(method); 31 std::string result = util::utf16ToUtf8( 32 pseudo.start() + pseudo.text(util::utf8ToUtf16(input)) + pseudo.end()); 33 if (StringPiece(expected) != result) { 34 return ::testing::AssertionFailure() << expected << " != " << result; 35 } 36 return ::testing::AssertionSuccess(); 37} 38 39static ::testing::AssertionResult compoundHelper(const char* in1, const char* in2, const char *in3, 40 const char* expected, 41 Pseudolocalizer::Method method) { 42 Pseudolocalizer pseudo(method); 43 std::string result = util::utf16ToUtf8(pseudo.start() + 44 pseudo.text(util::utf8ToUtf16(in1)) + 45 pseudo.text(util::utf8ToUtf16(in2)) + 46 pseudo.text(util::utf8ToUtf16(in3)) + 47 pseudo.end()); 48 if (StringPiece(expected) != result) { 49 return ::testing::AssertionFailure() << expected << " != " << result; 50 } 51 return ::testing::AssertionSuccess(); 52} 53 54TEST(PseudolocalizerTest, NoPseudolocalization) { 55 EXPECT_TRUE(simpleHelper("", "", Pseudolocalizer::Method::kNone)); 56 EXPECT_TRUE(simpleHelper("Hello, world", "Hello, world", Pseudolocalizer::Method::kNone)); 57 58 EXPECT_TRUE(compoundHelper("Hello,", " world", "", 59 "Hello, world", Pseudolocalizer::Method::kNone)); 60} 61 62TEST(PseudolocalizerTest, PlaintextAccent) { 63 EXPECT_TRUE(simpleHelper("", "[]", Pseudolocalizer::Method::kAccent)); 64 EXPECT_TRUE(simpleHelper("Hello, world", 65 "[Ĥéļļö, ŵöŕļð one two]", Pseudolocalizer::Method::kAccent)); 66 67 EXPECT_TRUE(simpleHelper("Hello, %1d", 68 "[Ĥéļļö, »%1d« one two]", Pseudolocalizer::Method::kAccent)); 69 70 EXPECT_TRUE(simpleHelper("Battery %1d%%", 71 "[βåţţéŕý »%1d«%% one two]", Pseudolocalizer::Method::kAccent)); 72 EXPECT_TRUE(simpleHelper("^1 %", "[^1 % one]", Pseudolocalizer::Method::kAccent)); 73 EXPECT_TRUE(compoundHelper("", "", "", "[]", Pseudolocalizer::Method::kAccent)); 74 EXPECT_TRUE(compoundHelper("Hello,", " world", "", 75 "[Ĥéļļö, ŵöŕļð one two]", Pseudolocalizer::Method::kAccent)); 76} 77 78TEST(PseudolocalizerTest, PlaintextBidi) { 79 EXPECT_TRUE(simpleHelper("", "", Pseudolocalizer::Method::kBidi)); 80 EXPECT_TRUE(simpleHelper("word", 81 "\xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f", 82 Pseudolocalizer::Method::kBidi)); 83 EXPECT_TRUE(simpleHelper(" word ", 84 " \xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f ", 85 Pseudolocalizer::Method::kBidi)); 86 EXPECT_TRUE(simpleHelper(" word ", 87 " \xe2\x80\x8f\xE2\x80\xaeword\xE2\x80\xac\xe2\x80\x8f ", 88 Pseudolocalizer::Method::kBidi)); 89 EXPECT_TRUE(simpleHelper("hello\n world\n", 90 "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n" \ 91 " \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n", 92 Pseudolocalizer::Method::kBidi)); 93 EXPECT_TRUE(compoundHelper("hello", "\n ", " world\n", 94 "\xe2\x80\x8f\xE2\x80\xaehello\xE2\x80\xac\xe2\x80\x8f\n" \ 95 " \xe2\x80\x8f\xE2\x80\xaeworld\xE2\x80\xac\xe2\x80\x8f\n", 96 Pseudolocalizer::Method::kBidi)); 97} 98 99TEST(PseudolocalizerTest, SimpleICU) { 100 // Single-fragment messages 101 EXPECT_TRUE(simpleHelper("{placeholder}", "[»{placeholder}«]", 102 Pseudolocalizer::Method::kAccent)); 103 EXPECT_TRUE(simpleHelper("{USER} is offline", 104 "[»{USER}« îš öƒƒļîñé one two]", Pseudolocalizer::Method::kAccent)); 105 EXPECT_TRUE(simpleHelper("Copy from {path1} to {path2}", 106 "[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]", 107 Pseudolocalizer::Method::kAccent)); 108 EXPECT_TRUE(simpleHelper("Today is {1,date} {1,time}", 109 "[Ţöðåý îš »{1,date}« »{1,time}« one two]", 110 Pseudolocalizer::Method::kAccent)); 111 112 // Multi-fragment messages 113 EXPECT_TRUE(compoundHelper("{USER}", " ", "is offline", 114 "[»{USER}« îš öƒƒļîñé one two]", 115 Pseudolocalizer::Method::kAccent)); 116 EXPECT_TRUE(compoundHelper("Copy from ", "{path1}", " to {path2}", 117 "[Çöþý ƒŕöḿ »{path1}« ţö »{path2}« one two three]", 118 Pseudolocalizer::Method::kAccent)); 119} 120 121TEST(PseudolocalizerTest, ICUBidi) { 122 // Single-fragment messages 123 EXPECT_TRUE(simpleHelper("{placeholder}", 124 "\xe2\x80\x8f\xE2\x80\xae{placeholder}\xE2\x80\xac\xe2\x80\x8f", 125 Pseudolocalizer::Method::kBidi)); 126 EXPECT_TRUE(simpleHelper( 127 "{COUNT, plural, one {one} other {other}}", 128 "{COUNT, plural, " \ 129 "one {\xe2\x80\x8f\xE2\x80\xaeone\xE2\x80\xac\xe2\x80\x8f} " \ 130 "other {\xe2\x80\x8f\xE2\x80\xaeother\xE2\x80\xac\xe2\x80\x8f}}", 131 Pseudolocalizer::Method::kBidi)); 132} 133 134TEST(PseudolocalizerTest, Escaping) { 135 // Single-fragment messages 136 EXPECT_TRUE(simpleHelper("'{USER'} is offline", 137 "['{ÛŠÉŔ'} îš öƒƒļîñé one two three]", 138 Pseudolocalizer::Method::kAccent)); 139 140 // Multi-fragment messages 141 EXPECT_TRUE(compoundHelper("'{USER}", " ", "''is offline", 142 "['{ÛŠÉŔ} ''îš öƒƒļîñé one two three]", 143 Pseudolocalizer::Method::kAccent)); 144} 145 146TEST(PseudolocalizerTest, PluralsAndSelects) { 147 EXPECT_TRUE(simpleHelper( 148 "{COUNT, plural, one {Delete a file} other {Delete {COUNT} files}}", 149 "[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} " \ 150 "other {Ðéļéţé »{COUNT}« ƒîļéš one two}}]", 151 Pseudolocalizer::Method::kAccent)); 152 153 EXPECT_TRUE(simpleHelper( 154 "Distance is {COUNT, plural, one {# mile} other {# miles}}", 155 "[Ðîšţåñçé îš {COUNT, plural, one {# ḿîļé one two} " \ 156 "other {# ḿîļéš one two}}]", 157 Pseudolocalizer::Method::kAccent)); 158 159 EXPECT_TRUE(simpleHelper( 160 "{1, select, female {{1} added you} " \ 161 "male {{1} added you} other {{1} added you}}", 162 "[{1, select, female {»{1}« åððéð ýöû one two} " \ 163 "male {»{1}« åððéð ýöû one two} other {»{1}« åððéð ýöû one two}}]", 164 Pseudolocalizer::Method::kAccent)); 165 166 EXPECT_TRUE(compoundHelper( 167 "{COUNT, plural, one {Delete a file} " \ 168 "other {Delete ", "{COUNT}", " files}}", 169 "[{COUNT, plural, one {Ðéļéţé å ƒîļé one two} " \ 170 "other {Ðéļéţé »{COUNT}« ƒîļéš one two}}]", 171 Pseudolocalizer::Method::kAccent)); 172} 173 174TEST(PseudolocalizerTest, NestedICU) { 175 EXPECT_TRUE(simpleHelper( 176 "{person, select, " \ 177 "female {" \ 178 "{num_circles, plural," \ 179 "=0{{person} didn't add you to any of her circles.}" \ 180 "=1{{person} added you to one of her circles.}" \ 181 "other{{person} added you to her # circles.}}}" \ 182 "male {" \ 183 "{num_circles, plural," \ 184 "=0{{person} didn't add you to any of his circles.}" \ 185 "=1{{person} added you to one of his circles.}" \ 186 "other{{person} added you to his # circles.}}}" \ 187 "other {" \ 188 "{num_circles, plural," \ 189 "=0{{person} didn't add you to any of their circles.}" \ 190 "=1{{person} added you to one of their circles.}" \ 191 "other{{person} added you to their # circles.}}}}", 192 "[{person, select, " \ 193 "female {" \ 194 "{num_circles, plural," \ 195 "=0{»{person}« ðîðñ'ţ åðð ýöû ţö åñý öƒ ĥéŕ çîŕçļéš." \ 196 " one two three four five}" \ 197 "=1{»{person}« åððéð ýöû ţö öñé öƒ ĥéŕ çîŕçļéš." \ 198 " one two three four}" \ 199 "other{»{person}« åððéð ýöû ţö ĥéŕ # çîŕçļéš." \ 200 " one two three four}}}" \ 201 "male {" \ 202 "{num_circles, plural," \ 203 "=0{»{person}« ðîðñ'ţ åðð ýöû ţö åñý öƒ ĥîš çîŕçļéš." \ 204 " one two three four five}" \ 205 "=1{»{person}« åððéð ýöû ţö öñé öƒ ĥîš çîŕçļéš." \ 206 " one two three four}" \ 207 "other{»{person}« åððéð ýöû ţö ĥîš # çîŕçļéš." \ 208 " one two three four}}}" \ 209 "other {{num_circles, plural," \ 210 "=0{»{person}« ðîðñ'ţ åðð ýöû ţö åñý öƒ ţĥéîŕ çîŕçļéš." \ 211 " one two three four five}" \ 212 "=1{»{person}« åððéð ýöû ţö öñé öƒ ţĥéîŕ çîŕçļéš." \ 213 " one two three four}" \ 214 "other{»{person}« åððéð ýöû ţö ţĥéîŕ # çîŕçļéš." \ 215 " one two three four}}}}]", 216 Pseudolocalizer::Method::kAccent)); 217} 218 219TEST(PseudolocalizerTest, RedefineMethod) { 220 Pseudolocalizer pseudo(Pseudolocalizer::Method::kAccent); 221 std::u16string result = pseudo.text(u"Hello, "); 222 pseudo.setMethod(Pseudolocalizer::Method::kNone); 223 result += pseudo.text(u"world!"); 224 ASSERT_EQ(StringPiece("Ĥéļļö, world!"), util::utf16ToUtf8(result)); 225} 226 227} // namespace aapt 228