Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae3c2449 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "AAPT2: Fix Plural::Equals() method"

parents 64979aac 8f7c550e
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -582,6 +582,16 @@ TEST_F(ResourceParserTest, ParsePlural) {
      "  <item quantity=\"one\">apple</item>\n"
      "</plurals>";
  ASSERT_TRUE(TestParse(input));

  Plural* plural = test::GetValue<Plural>(&table_, "plurals/foo");
  ASSERT_NE(nullptr, plural);
  EXPECT_EQ(nullptr, plural->values[Plural::Zero]);
  EXPECT_EQ(nullptr, plural->values[Plural::Two]);
  EXPECT_EQ(nullptr, plural->values[Plural::Few]);
  EXPECT_EQ(nullptr, plural->values[Plural::Many]);

  EXPECT_NE(nullptr, plural->values[Plural::One]);
  EXPECT_NE(nullptr, plural->values[Plural::Other]);
}

TEST_F(ResourceParserTest, ParseCommentsWithResource) {
+23 −16
Original line number Diff line number Diff line
@@ -341,7 +341,7 @@ Attribute::Attribute(bool w, uint32_t t)
}

template <typename T>
T* addPointer(T& val) {
constexpr T* add_pointer(T& val) {
  return &val;
}

@@ -362,7 +362,7 @@ bool Attribute::Equals(const Value* value) const {

  std::vector<const Symbol*> sorted_a;
  std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a),
                 addPointer<const Symbol>);
                 add_pointer<const Symbol>);
  std::sort(sorted_a.begin(), sorted_a.end(),
            [](const Symbol* a, const Symbol* b) -> bool {
              return a->symbol.name < b->symbol.name;
@@ -370,7 +370,7 @@ bool Attribute::Equals(const Value* value) const {

  std::vector<const Symbol*> sorted_b;
  std::transform(other->symbols.begin(), other->symbols.end(),
                 std::back_inserter(sorted_b), addPointer<const Symbol>);
                 std::back_inserter(sorted_b), add_pointer<const Symbol>);
  std::sort(sorted_b.begin(), sorted_b.end(),
            [](const Symbol* a, const Symbol* b) -> bool {
              return a->symbol.name < b->symbol.name;
@@ -599,7 +599,7 @@ bool Style::Equals(const Value* value) const {

  std::vector<const Entry*> sorted_a;
  std::transform(entries.begin(), entries.end(), std::back_inserter(sorted_a),
                 addPointer<const Entry>);
                 add_pointer<const Entry>);
  std::sort(sorted_a.begin(), sorted_a.end(),
            [](const Entry* a, const Entry* b) -> bool {
              return a->key.name < b->key.name;
@@ -607,7 +607,7 @@ bool Style::Equals(const Value* value) const {

  std::vector<const Entry*> sorted_b;
  std::transform(other->entries.begin(), other->entries.end(),
                 std::back_inserter(sorted_b), addPointer<const Entry>);
                 std::back_inserter(sorted_b), add_pointer<const Entry>);
  std::sort(sorted_b.begin(), sorted_b.end(),
            [](const Entry* a, const Entry* b) -> bool {
              return a->key.name < b->key.name;
@@ -695,18 +695,21 @@ bool Plural::Equals(const Value* value) const {
    return false;
  }

  if (values.size() != other->values.size()) {
  auto one_iter = values.begin();
  auto one_end_iter = values.end();
  auto two_iter = other->values.begin();
  for (; one_iter != one_end_iter; ++one_iter, ++two_iter) {
    const std::unique_ptr<Item>& a = *one_iter;
    const std::unique_ptr<Item>& b = *two_iter;
    if (a != nullptr && b != nullptr) {
      if (!a->Equals(b.get())) {
        return false;
      }

  return std::equal(values.begin(), values.end(), other->values.begin(),
                    [](const std::unique_ptr<Item>& a,
                       const std::unique_ptr<Item>& b) -> bool {
                      if (bool(a) != bool(b)) {
    } else if (a != b) {
      return false;
    }
                      return bool(a) == bool(b) || a->Equals(b.get());
                    });
  }
  return true;
}

Plural* Plural::Clone(StringPool* new_pool) const {
@@ -743,6 +746,10 @@ void Plural::Print(std::ostream* out) const {
  if (values[Many]) {
    *out << " many=" << *values[Many];
  }

  if (values[Other]) {
    *out << " other=" << *values[Other];
  }
}

static ::std::ostream& operator<<(::std::ostream& out,
+151 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ResourceValues.h"

#include "test/Test.h"

namespace aapt {

TEST(ResourceValuesTest, PluralEquals) {
  StringPool pool;

  Plural a;
  a.values[Plural::One] = util::make_unique<String>(pool.MakeRef("one"));
  a.values[Plural::Other] = util::make_unique<String>(pool.MakeRef("other"));

  Plural b;
  b.values[Plural::One] = util::make_unique<String>(pool.MakeRef("une"));
  b.values[Plural::Other] = util::make_unique<String>(pool.MakeRef("autre"));

  Plural c;
  c.values[Plural::One] = util::make_unique<String>(pool.MakeRef("one"));
  c.values[Plural::Other] = util::make_unique<String>(pool.MakeRef("other"));

  EXPECT_FALSE(a.Equals(&b));
  EXPECT_TRUE(a.Equals(&c));
}

TEST(ResourceValuesTest, PluralClone) {
  StringPool pool;

  Plural a;
  a.values[Plural::One] = util::make_unique<String>(pool.MakeRef("one"));
  a.values[Plural::Other] = util::make_unique<String>(pool.MakeRef("other"));

  std::unique_ptr<Plural> b(a.Clone(&pool));
  EXPECT_TRUE(a.Equals(b.get()));
}

TEST(ResourceValuesTest, ArrayEquals) {
  StringPool pool;

  Array a;
  a.items.push_back(util::make_unique<String>(pool.MakeRef("one")));
  a.items.push_back(util::make_unique<String>(pool.MakeRef("two")));

  Array b;
  b.items.push_back(util::make_unique<String>(pool.MakeRef("une")));
  b.items.push_back(util::make_unique<String>(pool.MakeRef("deux")));

  Array c;
  c.items.push_back(util::make_unique<String>(pool.MakeRef("uno")));

  Array d;
  d.items.push_back(util::make_unique<String>(pool.MakeRef("one")));
  d.items.push_back(util::make_unique<String>(pool.MakeRef("two")));

  EXPECT_FALSE(a.Equals(&b));
  EXPECT_FALSE(a.Equals(&c));
  EXPECT_FALSE(b.Equals(&c));
  EXPECT_TRUE(a.Equals(&d));
}

TEST(ResourceValuesTest, ArrayClone) {
  StringPool pool;

  Array a;
  a.items.push_back(util::make_unique<String>(pool.MakeRef("one")));
  a.items.push_back(util::make_unique<String>(pool.MakeRef("two")));

  std::unique_ptr<Array> b(a.Clone(&pool));
  EXPECT_TRUE(a.Equals(b.get()));
}

TEST(ResourceValuesTest, StyleEquals) {
  StringPool pool;

  std::unique_ptr<Style> a = test::StyleBuilder()
      .SetParent("android:style/Parent")
      .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
      .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
      .Build();

  std::unique_ptr<Style> b = test::StyleBuilder()
      .SetParent("android:style/Parent")
      .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
      .AddItem("android:attr/bar", ResourceUtils::TryParseInt("3"))
      .Build();

  std::unique_ptr<Style> c = test::StyleBuilder()
      .SetParent("android:style/NoParent")
      .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
      .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
      .Build();

  std::unique_ptr<Style> d = test::StyleBuilder()
      .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
      .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
      .Build();

  std::unique_ptr<Style> e = test::StyleBuilder()
      .SetParent("android:style/Parent")
      .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
      .AddItem("android:attr/bat", ResourceUtils::TryParseInt("2"))
      .Build();

  std::unique_ptr<Style> f = test::StyleBuilder()
      .SetParent("android:style/Parent")
      .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
      .Build();

  std::unique_ptr<Style> g = test::StyleBuilder()
      .SetParent("android:style/Parent")
      .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
      .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
      .Build();

  EXPECT_FALSE(a->Equals(b.get()));
  EXPECT_FALSE(a->Equals(c.get()));
  EXPECT_FALSE(a->Equals(d.get()));
  EXPECT_FALSE(a->Equals(e.get()));
  EXPECT_FALSE(a->Equals(f.get()));

  EXPECT_TRUE(a->Equals(g.get()));
}

TEST(ResourceValuesTest, StyleClone) {
  std::unique_ptr<Style> a = test::StyleBuilder()
      .SetParent("android:style/Parent")
      .AddItem("android:attr/foo", ResourceUtils::TryParseInt("1"))
      .AddItem("android:attr/bar", ResourceUtils::TryParseInt("2"))
      .Build();

  std::unique_ptr<Style> b(a->Clone(nullptr));
  EXPECT_TRUE(a->Equals(b.get()));
}

} // namespace aapt
+2 −0
Original line number Diff line number Diff line
@@ -77,6 +77,8 @@ class DominatedKeyValueRemover : public DominatorTree::BottomUpVisitor {
          DiagMessage(node_value->value->GetSource())
          << "removing dominated duplicate resource with name \""
          << entry_->name << "\"");
      context_->GetDiagnostics()->Note(
          DiagMessage(parent_value->value->GetSource()) << "dominated here");
    }
    node_value->value = {};
  }