Home | History | Annotate | Download | only in test
      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 #ifndef AAPT_TEST_BUILDERS_H
     18 #define AAPT_TEST_BUILDERS_H
     19 
     20 #include <memory>
     21 
     22 #include "android-base/logging.h"
     23 #include "android-base/macros.h"
     24 
     25 #include "ResourceTable.h"
     26 #include "ResourceValues.h"
     27 #include "test/Common.h"
     28 #include "util/Util.h"
     29 #include "xml/XmlDom.h"
     30 
     31 namespace aapt {
     32 namespace test {
     33 
     34 class ResourceTableBuilder {
     35  public:
     36   ResourceTableBuilder() = default;
     37 
     38   StringPool* string_pool() { return &table_->string_pool; }
     39 
     40   ResourceTableBuilder& SetPackageId(const android::StringPiece& package_name, uint8_t id) {
     41     ResourceTablePackage* package = table_->CreatePackage(package_name, id);
     42     CHECK(package != nullptr);
     43     return *this;
     44   }
     45 
     46   ResourceTableBuilder& AddSimple(const android::StringPiece& name, const ResourceId& id = {}) {
     47     return AddValue(name, id, util::make_unique<Id>());
     48   }
     49 
     50   ResourceTableBuilder& AddSimple(const android::StringPiece& name, const ConfigDescription& config,
     51                                   const ResourceId& id = {}) {
     52     return AddValue(name, config, id, util::make_unique<Id>());
     53   }
     54 
     55   ResourceTableBuilder& AddReference(const android::StringPiece& name,
     56                                      const android::StringPiece& ref) {
     57     return AddReference(name, {}, ref);
     58   }
     59 
     60   ResourceTableBuilder& AddReference(const android::StringPiece& name, const ResourceId& id,
     61                                      const android::StringPiece& ref) {
     62     return AddValue(name, id, util::make_unique<Reference>(ParseNameOrDie(ref)));
     63   }
     64 
     65   ResourceTableBuilder& AddString(const android::StringPiece& name,
     66                                   const android::StringPiece& str) {
     67     return AddString(name, {}, str);
     68   }
     69 
     70   ResourceTableBuilder& AddString(const android::StringPiece& name, const ResourceId& id,
     71                                   const android::StringPiece& str) {
     72     return AddValue(
     73         name, id, util::make_unique<String>(table_->string_pool.MakeRef(str)));
     74   }
     75 
     76   ResourceTableBuilder& AddString(const android::StringPiece& name, const ResourceId& id,
     77                                   const ConfigDescription& config,
     78                                   const android::StringPiece& str) {
     79     return AddValue(name, config, id, util::make_unique<String>(
     80                                           table_->string_pool.MakeRef(str)));
     81   }
     82 
     83   ResourceTableBuilder& AddFileReference(const android::StringPiece& name,
     84                                          const android::StringPiece& path) {
     85     return AddFileReference(name, {}, path);
     86   }
     87 
     88   ResourceTableBuilder& AddFileReference(const android::StringPiece& name, const ResourceId& id,
     89                                          const android::StringPiece& path) {
     90     return AddValue(name, id, util::make_unique<FileReference>(
     91                                   table_->string_pool.MakeRef(path)));
     92   }
     93 
     94   ResourceTableBuilder& AddFileReference(const android::StringPiece& name,
     95                                          const android::StringPiece& path,
     96                                          const ConfigDescription& config) {
     97     return AddValue(name, config, {}, util::make_unique<FileReference>(
     98                                           table_->string_pool.MakeRef(path)));
     99   }
    100 
    101   ResourceTableBuilder& AddValue(const android::StringPiece& name, std::unique_ptr<Value> value) {
    102     return AddValue(name, {}, std::move(value));
    103   }
    104 
    105   ResourceTableBuilder& AddValue(const android::StringPiece& name, const ResourceId& id,
    106                                  std::unique_ptr<Value> value) {
    107     return AddValue(name, {}, id, std::move(value));
    108   }
    109 
    110   ResourceTableBuilder& AddValue(const android::StringPiece& name, const ConfigDescription& config,
    111                                  const ResourceId& id, std::unique_ptr<Value> value) {
    112     ResourceName res_name = ParseNameOrDie(name);
    113     CHECK(table_->AddResourceAllowMangled(res_name, id, config, {}, std::move(value),
    114                                           GetDiagnostics()));
    115     return *this;
    116   }
    117 
    118   ResourceTableBuilder& SetSymbolState(const android::StringPiece& name, const ResourceId& id,
    119                                        SymbolState state, bool allow_new = false) {
    120     ResourceName res_name = ParseNameOrDie(name);
    121     Symbol symbol;
    122     symbol.state = state;
    123     symbol.allow_new = allow_new;
    124     CHECK(table_->SetSymbolStateAllowMangled(res_name, id, symbol, GetDiagnostics()));
    125     return *this;
    126   }
    127 
    128   std::unique_ptr<ResourceTable> Build() { return std::move(table_); }
    129 
    130  private:
    131   DISALLOW_COPY_AND_ASSIGN(ResourceTableBuilder);
    132 
    133   std::unique_ptr<ResourceTable> table_ = util::make_unique<ResourceTable>();
    134 };
    135 
    136 inline std::unique_ptr<Reference> BuildReference(const android::StringPiece& ref,
    137                                                  const Maybe<ResourceId>& id = {}) {
    138   std::unique_ptr<Reference> reference =
    139       util::make_unique<Reference>(ParseNameOrDie(ref));
    140   reference->id = id;
    141   return reference;
    142 }
    143 
    144 inline std::unique_ptr<BinaryPrimitive> BuildPrimitive(uint8_t type,
    145                                                        uint32_t data) {
    146   android::Res_value value = {};
    147   value.size = sizeof(value);
    148   value.dataType = type;
    149   value.data = data;
    150   return util::make_unique<BinaryPrimitive>(value);
    151 }
    152 
    153 template <typename T>
    154 class ValueBuilder {
    155  public:
    156   template <typename... Args>
    157   explicit ValueBuilder(Args&&... args)
    158       : value_(new T{std::forward<Args>(args)...}) {}
    159 
    160   template <typename... Args>
    161   ValueBuilder& SetSource(Args&&... args) {
    162     value_->SetSource(Source{std::forward<Args>(args)...});
    163     return *this;
    164   }
    165 
    166   ValueBuilder& SetComment(const android::StringPiece& str) {
    167     value_->SetComment(str);
    168     return *this;
    169   }
    170 
    171   std::unique_ptr<Value> Build() { return std::move(value_); }
    172 
    173  private:
    174   DISALLOW_COPY_AND_ASSIGN(ValueBuilder);
    175 
    176   std::unique_ptr<Value> value_;
    177 };
    178 
    179 class AttributeBuilder {
    180  public:
    181   explicit AttributeBuilder(bool weak = false)
    182       : attr_(util::make_unique<Attribute>(weak)) {
    183     attr_->type_mask = android::ResTable_map::TYPE_ANY;
    184   }
    185 
    186   AttributeBuilder& SetTypeMask(uint32_t typeMask) {
    187     attr_->type_mask = typeMask;
    188     return *this;
    189   }
    190 
    191   AttributeBuilder& AddItem(const android::StringPiece& name, uint32_t value) {
    192     attr_->symbols.push_back(Attribute::Symbol{
    193         Reference(ResourceName({}, ResourceType::kId, name)), value});
    194     return *this;
    195   }
    196 
    197   std::unique_ptr<Attribute> Build() { return std::move(attr_); }
    198 
    199  private:
    200   DISALLOW_COPY_AND_ASSIGN(AttributeBuilder);
    201 
    202   std::unique_ptr<Attribute> attr_;
    203 };
    204 
    205 class StyleBuilder {
    206  public:
    207   StyleBuilder() = default;
    208 
    209   StyleBuilder& SetParent(const android::StringPiece& str) {
    210     style_->parent = Reference(ParseNameOrDie(str));
    211     return *this;
    212   }
    213 
    214   StyleBuilder& AddItem(const android::StringPiece& str, std::unique_ptr<Item> value) {
    215     style_->entries.push_back(
    216         Style::Entry{Reference(ParseNameOrDie(str)), std::move(value)});
    217     return *this;
    218   }
    219 
    220   StyleBuilder& AddItem(const android::StringPiece& str, const ResourceId& id,
    221                         std::unique_ptr<Item> value) {
    222     AddItem(str, std::move(value));
    223     style_->entries.back().key.id = id;
    224     return *this;
    225   }
    226 
    227   std::unique_ptr<Style> Build() { return std::move(style_); }
    228 
    229  private:
    230   DISALLOW_COPY_AND_ASSIGN(StyleBuilder);
    231 
    232   std::unique_ptr<Style> style_ = util::make_unique<Style>();
    233 };
    234 
    235 class StyleableBuilder {
    236  public:
    237   StyleableBuilder() = default;
    238 
    239   StyleableBuilder& AddItem(const android::StringPiece& str, const Maybe<ResourceId>& id = {}) {
    240     styleable_->entries.push_back(Reference(ParseNameOrDie(str)));
    241     styleable_->entries.back().id = id;
    242     return *this;
    243   }
    244 
    245   std::unique_ptr<Styleable> Build() { return std::move(styleable_); }
    246 
    247  private:
    248   DISALLOW_COPY_AND_ASSIGN(StyleableBuilder);
    249 
    250   std::unique_ptr<Styleable> styleable_ = util::make_unique<Styleable>();
    251 };
    252 
    253 inline std::unique_ptr<xml::XmlResource> BuildXmlDom(const android::StringPiece& str) {
    254   std::stringstream in;
    255   in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str;
    256   StdErrDiagnostics diag;
    257   std::unique_ptr<xml::XmlResource> doc =
    258       xml::Inflate(&in, &diag, Source("test.xml"));
    259   CHECK(doc != nullptr) << "failed to parse inline XML string";
    260   return doc;
    261 }
    262 
    263 inline std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(
    264     IAaptContext* context, const android::StringPiece& str) {
    265   std::unique_ptr<xml::XmlResource> doc = BuildXmlDom(str);
    266   doc->file.name.package = context->GetCompilationPackage();
    267   return doc;
    268 }
    269 
    270 }  // namespace test
    271 }  // namespace aapt
    272 
    273 #endif /* AAPT_TEST_BUILDERS_H */
    274