Home | History | Annotate | Download | only in compile
      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 
     23 namespace aapt {
     24 
     25 // In this context, 'Axis' represents a particular field in the configuration,
     26 // such as language or density.
     27 
     28 static ::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 
     39 static ::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 
     54 TEST(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 
     62 TEST(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 
     73     EXPECT_TRUE(compoundHelper("", "", "", "[]", Pseudolocalizer::Method::kAccent));
     74     EXPECT_TRUE(compoundHelper("Hello,", " world", "",
     75                                "[,  one two]", Pseudolocalizer::Method::kAccent));
     76 }
     77 
     78 TEST(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 
     99 TEST(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 
    121 TEST(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 
    134 TEST(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 
    146 TEST(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 
    174 TEST(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 
    219 TEST(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