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_COMMON_H
18 #define AAPT_TEST_COMMON_H
19 
20 #include "ConfigDescription.h"
21 #include "Debug.h"
22 #include "ResourceTable.h"
23 #include "ResourceUtils.h"
24 #include "ValueVisitor.h"
25 #include "io/File.h"
26 #include "process/IResourceTableConsumer.h"
27 #include "util/StringPiece.h"
28 
29 #include <gtest/gtest.h>
30 #include <iostream>
31 
32 //
33 // GTEST 1.7 doesn't explicitly cast to bool, which causes explicit operators to fail to compile.
34 //
35 #define AAPT_ASSERT_TRUE(v) ASSERT_TRUE(bool(v))
36 #define AAPT_ASSERT_FALSE(v) ASSERT_FALSE(bool(v))
37 #define AAPT_EXPECT_TRUE(v) EXPECT_TRUE(bool(v))
38 #define AAPT_EXPECT_FALSE(v) EXPECT_FALSE(bool(v))
39 
40 namespace aapt {
41 namespace test {
42 
43 struct DummyDiagnosticsImpl : public IDiagnostics {
logDummyDiagnosticsImpl44     void log(Level level, DiagMessageActual& actualMsg) override {
45         switch (level) {
46         case Level::Note:
47             return;
48 
49         case Level::Warn:
50             std::cerr << actualMsg.source << ": warn: " << actualMsg.message << "." << std::endl;
51             break;
52 
53         case Level::Error:
54             std::cerr << actualMsg.source << ": error: " << actualMsg.message << "." << std::endl;
55             break;
56         }
57     }
58 };
59 
getDiagnostics()60 inline IDiagnostics* getDiagnostics() {
61     static DummyDiagnosticsImpl diag;
62     return &diag;
63 }
64 
parseNameOrDie(const StringPiece16 & str)65 inline ResourceName parseNameOrDie(const StringPiece16& str) {
66     ResourceNameRef ref;
67     bool result = ResourceUtils::tryParseReference(str, &ref);
68     assert(result && "invalid resource name");
69     return ref.toResourceName();
70 }
71 
parseConfigOrDie(const StringPiece & str)72 inline ConfigDescription parseConfigOrDie(const StringPiece& str) {
73     ConfigDescription config;
74     bool result = ConfigDescription::parse(str, &config);
75     assert(result && "invalid configuration");
76     return config;
77 }
78 
getValueForConfigAndProduct(ResourceTable * table,const StringPiece16 & resName,const ConfigDescription & config,const StringPiece & product)79 template <typename T> T* getValueForConfigAndProduct(ResourceTable* table,
80                                                      const StringPiece16& resName,
81                                                      const ConfigDescription& config,
82                                                      const StringPiece& product) {
83     Maybe<ResourceTable::SearchResult> result = table->findResource(parseNameOrDie(resName));
84     if (result) {
85         ResourceConfigValue* configValue = result.value().entry->findValue(config, product);
86         if (configValue) {
87             return valueCast<T>(configValue->value.get());
88         }
89     }
90     return nullptr;
91 }
92 
getValueForConfig(ResourceTable * table,const StringPiece16 & resName,const ConfigDescription & config)93 template <typename T> T* getValueForConfig(ResourceTable* table, const StringPiece16& resName,
94                                            const ConfigDescription& config) {
95     return getValueForConfigAndProduct<T>(table, resName, config, {});
96 }
97 
getValue(ResourceTable * table,const StringPiece16 & resName)98 template <typename T> T* getValue(ResourceTable* table, const StringPiece16& resName) {
99     return getValueForConfig<T>(table, resName, {});
100 }
101 
102 class TestFile : public io::IFile {
103 private:
104     Source mSource;
105 
106 public:
TestFile(const StringPiece & path)107     TestFile(const StringPiece& path) : mSource(path) {}
108 
openAsData()109     std::unique_ptr<io::IData> openAsData() override {
110         return {};
111     }
112 
getSource()113     const Source& getSource() const override {
114         return mSource;
115     }
116 };
117 
118 } // namespace test
119 } // namespace aapt
120 
121 #endif /* AAPT_TEST_COMMON_H */
122