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