1393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski/*
2393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski * Copyright (C) 2016 The Android Open Source Project
3393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski *
4393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski * you may not use this file except in compliance with the License.
6393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski * You may obtain a copy of the License at
7393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski *
8393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski *
10393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski * See the License for the specific language governing permissions and
14393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski * limitations under the License.
15393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski */
16393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
17393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski#include "compile/PseudolocaleGenerator.h"
18ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
19d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski#include "test/Test.h"
20393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski#include "util/Util.h"
21393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
22393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinskinamespace aapt {
23393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
24393b5f0d6130d3848dd82075986a5cf40c09ce44Adam LesinskiTEST(PseudolocaleGeneratorTest, PseudolocalizeStyledString) {
25cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  StringPool pool;
26ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  StyleString original_style;
27ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  original_style.str = "Hello world!";
288049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.spans = {Span{"i", 1, 10}, Span{"b", 2, 3}, Span{"b", 6, 7}};
29393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
30ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
31ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
32cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      Pseudolocalizer::Method::kNone, &pool);
33393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
34ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_EQ(original_style.str, *new_string->value->str);
35ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size());
36393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
378049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("i"), *new_string->value->spans[0].name);
388049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"H").size(), new_string->value->spans[0].first_char);
398049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"Hello worl").size(), new_string->value->spans[0].last_char);
40393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_EQ(std::string("b"), *new_string->value->spans[1].name);
428049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"He").size(), new_string->value->spans[1].first_char);
438049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"Hel").size(), new_string->value->spans[1].last_char);
44393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
458049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("b"), *new_string->value->spans[2].name);
468049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"Hello ").size(), new_string->value->spans[2].first_char);
478049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"Hello w").size(), new_string->value->spans[2].last_char);
48393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
498049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.spans.insert(original_style.spans.begin(), Span{"em", 0, 11u});
50393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
51ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  new_string = PseudolocalizeStyledString(
52ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      Pseudolocalizer::Method::kAccent, &pool);
54393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
55ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð¡ one two]"), *new_string->value->str);
56ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size());
57393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
588049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[0].first_char);
598049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ĥéļļö ŵöŕļð").size(), new_string->value->spans[0].last_char);
608049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
618049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ĥ").size(), new_string->value->spans[1].first_char);
628049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ĥéļļö ŵöŕļ").size(), new_string->value->spans[1].last_char);
638049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
648049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ĥé").size(), new_string->value->spans[2].first_char);
658049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ĥéļ").size(), new_string->value->spans[2].last_char);
668049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
678049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ĥéļļö ").size(), new_string->value->spans[3].first_char);
688049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ĥéļļö ŵ").size(), new_string->value->spans[3].last_char);
698049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski}
708049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
718049f3da712ea9c3154b57ce2276c97e749d1f2cAdam LesinskiTEST(PseudolocaleGeneratorTest, PseudolocalizeAdjacentNestedTags) {
728049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  StringPool pool;
738049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  StyleString original_style;
748049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.str = "bold";
758049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.spans = {Span{"b", 0, 3}, Span{"i", 0, 3}};
768049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
778049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
788049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
798049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski      Pseudolocalizer::Method::kAccent, &pool);
808049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  ASSERT_NE(nullptr, new_string);
818049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  ASSERT_EQ(2u, new_string->value->spans.size());
828049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("[ɓöļð one]"), *new_string->value->str);
838049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
848049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
858049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[0].first_char);
868049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[ɓöļ").size(), new_string->value->spans[0].last_char);
878049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
888049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("i"), *new_string->value->spans[1].name);
898049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[1].first_char);
908049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[ɓöļ").size(), new_string->value->spans[1].last_char);
918049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski}
928049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
938049f3da712ea9c3154b57ce2276c97e749d1f2cAdam LesinskiTEST(PseudolocaleGeneratorTest, PseudolocalizeAdjacentTagsUnsorted) {
948049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  StringPool pool;
958049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  StyleString original_style;
968049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.str = "bold";
978049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.spans = {Span{"i", 2, 3}, Span{"b", 0, 1}};
988049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
998049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
1008049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
1018049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski      Pseudolocalizer::Method::kAccent, &pool);
1028049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  ASSERT_NE(nullptr, new_string);
1038049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  ASSERT_EQ(2u, new_string->value->spans.size());
1048049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("[ɓöļð one]"), *new_string->value->str);
1058049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
1068049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
1078049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[0].first_char);
1088049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[ɓ").size(), new_string->value->spans[0].last_char);
1098049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
1108049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("i"), *new_string->value->spans[1].name);
1118049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[ɓö").size(), new_string->value->spans[1].first_char);
1128049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[ɓöļ").size(), new_string->value->spans[1].last_char);
1138049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski}
1148049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
1158049f3da712ea9c3154b57ce2276c97e749d1f2cAdam LesinskiTEST(PseudolocaleGeneratorTest, PseudolocalizeNestedAndAdjacentTags) {
1168049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  StringPool pool;
1178049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  StyleString original_style;
1188049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.str = "This sentence is not what you think it is at all.";
1198049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.spans = {Span{"b", 16u, 19u}, Span{"em", 29u, 47u}, Span{"i", 38u, 40u},
1208049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski                          Span{"b", 44u, 47u}};
121393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
1228049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
1238049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
1248049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski      Pseudolocalizer::Method::kAccent, &pool);
1258049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  ASSERT_NE(nullptr, new_string);
1268049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  ASSERT_EQ(4u, new_string->value->spans.size());
1278049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string(
1288049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski                "[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ îš åţ åļļ. one two three four five six]"),
1298049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski            *new_string->value->str);
1308049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
1318049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
1328049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš").size(), new_string->value->spans[0].first_char);
1338049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñö").size(), new_string->value->spans[0].last_char);
1348049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
1358049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("em"), *new_string->value->spans[1].name);
1368049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû").size(),
137ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            new_string->value->spans[1].first_char);
1388049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ îš åţ åļ").size(),
139ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            new_string->value->spans[1].last_char);
140393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
1418049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("i"), *new_string->value->spans[2].name);
1428049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ").size(),
1438049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski            new_string->value->spans[2].first_char);
1448049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ î").size(),
145ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            new_string->value->spans[2].last_char);
146393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
1478049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("b"), *new_string->value->spans[3].name);
1488049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ îš åţ").size(),
1498049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski            new_string->value->spans[3].first_char);
1508049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ îš åţ åļ").size(),
151ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            new_string->value->spans[3].last_char);
152393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski}
153393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
1548049f3da712ea9c3154b57ce2276c97e749d1f2cAdam LesinskiTEST(PseudolocaleGeneratorTest, PseudolocalizePartsOfString) {
1558049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  StringPool pool;
1568049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  StyleString original_style;
1578049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.str = "This should NOT be pseudolocalized.";
1588049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_style.spans = {Span{"em", 4u, 14u}, Span{"i", 18u, 33u}};
1598049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  std::unique_ptr<StyledString> original_string =
1608049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski      util::make_unique<StyledString>(pool.MakeRef(original_style));
1618049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  original_string->untranslatable_sections = {UntranslatableSection{11u, 15u}};
1628049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
1638049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  std::unique_ptr<StyledString> new_string =
1648049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski      PseudolocalizeStyledString(original_string.get(), Pseudolocalizer::Method::kAccent, &pool);
1658049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  ASSERT_NE(nullptr, new_string);
1668049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  ASSERT_EQ(2u, new_string->value->spans.size());
1678049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("[Ţĥîš šĥöûļð NOT ɓé þšéûðöļöçåļîžéð. one two three four]"),
1688049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski            *new_string->value->str);
1698049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
1708049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("em"), *new_string->value->spans[0].name);
1718049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš").size(), new_string->value->spans[0].first_char);
1728049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šĥöûļð NO").size(), new_string->value->spans[0].last_char);
1738049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
1748049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::string("i"), *new_string->value->spans[1].name);
1758049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šĥöûļð NOT ɓé").size(), new_string->value->spans[1].first_char);
1768049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski  EXPECT_EQ(std::u16string(u"[Ţĥîš šĥöûļð NOT ɓé þšéûðöļöçåļîžé").size(),
1778049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski            new_string->value->spans[1].last_char);
1788049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski}
1798049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski
180393b5f0d6130d3848dd82075986a5cf40c09ce44Adam LesinskiTEST(PseudolocaleGeneratorTest, PseudolocalizeOnlyDefaultConfigs) {
181cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  std::unique_ptr<ResourceTable> table =
182cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      test::ResourceTableBuilder()
183ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .AddString("android:string/one", "one")
184ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .AddString("android:string/two", ResourceId{},
185ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                     test::ParseConfigOrDie("en"), "two")
186ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .AddString("android:string/three", "three")
187ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .AddString("android:string/three", ResourceId{},
188ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                     test::ParseConfigOrDie("en-rXA"), "three")
189ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .AddString("android:string/four", "four")
190ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski          .Build();
191ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
192ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  String* val = test::GetValue<String>(table.get(), "android:string/four");
193cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_NE(nullptr, val);
1947542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  val->SetTranslatable(false);
195cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
196ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
197cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  PseudolocaleGenerator generator;
198ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ASSERT_TRUE(generator.Consume(context.get(), table.get()));
199cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
200cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Normal pseudolocalization should take place.
201cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_NE(nullptr,
202ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            test::GetValueForConfig<String>(table.get(), "android:string/one",
203ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                            test::ParseConfigOrDie("en-rXA")));
204cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_NE(nullptr,
205ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            test::GetValueForConfig<String>(table.get(), "android:string/one",
206ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                            test::ParseConfigOrDie("ar-rXB")));
207cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
208cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // No default config for android:string/two, so no pseudlocales should exist.
209cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_EQ(nullptr,
210ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            test::GetValueForConfig<String>(table.get(), "android:string/two",
211ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                            test::ParseConfigOrDie("en-rXA")));
212cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_EQ(nullptr,
213ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            test::GetValueForConfig<String>(table.get(), "android:string/two",
214ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                            test::ParseConfigOrDie("ar-rXB")));
215cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
216cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Check that we didn't override manual pseudolocalization.
217ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  val = test::GetValueForConfig<String>(table.get(), "android:string/three",
218ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                        test::ParseConfigOrDie("en-rXA"));
219cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_NE(nullptr, val);
220cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  EXPECT_EQ(std::string("three"), *val->value);
221cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
222cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_NE(nullptr,
223ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            test::GetValueForConfig<String>(table.get(), "android:string/three",
224ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                            test::ParseConfigOrDie("ar-rXB")));
225cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
226cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  // Check that four's translateable marker was honored.
227cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_EQ(nullptr,
228ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            test::GetValueForConfig<String>(table.get(), "android:string/four",
229ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                            test::ParseConfigOrDie("en-rXA")));
230cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  ASSERT_EQ(nullptr,
231ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski            test::GetValueForConfig<String>(table.get(), "android:string/four",
232ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski                                            test::ParseConfigOrDie("ar-rXB")));
233393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski}
234393b5f0d6130d3848dd82075986a5cf40c09ce44Adam Lesinski
2357542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam LesinskiTEST(PseudolocaleGeneratorTest, RespectUntranslateableSections) {
2367542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  std::unique_ptr<IAaptContext> context =
2377542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski      test::ContextBuilder().SetCompilationPackage("android").Build();
2387542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
2397542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2407542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  {
2417542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski    StyleString original_style;
2427542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski    original_style.str = "Hello world!";
2438049f3da712ea9c3154b57ce2276c97e749d1f2cAdam Lesinski    original_style.spans = {Span{"i", 1, 10}, Span{"b", 2, 3}, Span{"b", 6, 7}};
2447542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2457542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski    auto styled_string =
2467542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski        util::make_unique<StyledString>(table->string_pool.MakeRef(original_style));
2477542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski    styled_string->untranslatable_sections.push_back(UntranslatableSection{6u, 8u});
2487542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski    styled_string->untranslatable_sections.push_back(UntranslatableSection{8u, 11u});
2497542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2507542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski    auto string = util::make_unique<String>(table->string_pool.MakeRef(original_style.str));
2517542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski    string->untranslatable_sections.push_back(UntranslatableSection{6u, 11u});
2527542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2537542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski    ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("android:string/foo"), ConfigDescription{},
2547542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski                                   {} /* product */, std::move(styled_string),
2557542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski                                   context->GetDiagnostics()));
2567542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski    ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("android:string/bar"), ConfigDescription{},
2577542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski                                   {} /* product */, std::move(string), context->GetDiagnostics()));
2587542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  }
2597542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2607542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  PseudolocaleGenerator generator;
2617542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  ASSERT_TRUE(generator.Consume(context.get(), table.get()));
2627542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2637542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  StyledString* new_styled_string = test::GetValueForConfig<StyledString>(
2647542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski      table.get(), "android:string/foo", test::ParseConfigOrDie("en-rXA"));
2657542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  ASSERT_NE(nullptr, new_styled_string);
2667542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2677542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // "world" should be untranslated.
2687542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  EXPECT_NE(std::string::npos, new_styled_string->value->str->find("world"));
2697542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2707542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  String* new_string = test::GetValueForConfig<String>(table.get(), "android:string/bar",
2717542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski                                                       test::ParseConfigOrDie("en-rXA"));
2727542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  ASSERT_NE(nullptr, new_string);
2737542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
2747542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  // "world" should be untranslated.
2757542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski  EXPECT_NE(std::string::npos, new_string->value->find("world"));
2767542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski}
2777542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski
278cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
279