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 22 using android::StringPiece; 23 24 namespace aapt { 25 26 // In this context, 'Axis' represents a particular field in the configuration, 27 // such as language or density. 28 29 static ::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 40 static ::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 52 TEST(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 61 TEST(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 79 TEST(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 107 TEST(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 129 TEST(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 143 TEST(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 155 TEST(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 184 TEST(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 229 TEST(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