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 <iostream> 21 22#include "android-base/logging.h" 23#include "android-base/macros.h" 24#include "androidfw/StringPiece.h" 25#include "gmock/gmock.h" 26#include "gtest/gtest.h" 27 28#include "ConfigDescription.h" 29#include "Debug.h" 30#include "ResourceTable.h" 31#include "ResourceUtils.h" 32#include "ResourceValues.h" 33#include "ValueVisitor.h" 34#include "io/File.h" 35#include "process/IResourceTableConsumer.h" 36 37// 38// GTEST 1.7 doesn't explicitly cast to bool, which causes explicit operators to 39// fail to compile. 40// 41#define AAPT_ASSERT_TRUE(v) ASSERT_TRUE(bool(v)) 42#define AAPT_ASSERT_FALSE(v) ASSERT_FALSE(bool(v)) 43#define AAPT_EXPECT_TRUE(v) EXPECT_TRUE(bool(v)) 44#define AAPT_EXPECT_FALSE(v) EXPECT_FALSE(bool(v)) 45 46namespace aapt { 47namespace test { 48 49IDiagnostics* GetDiagnostics(); 50 51inline ResourceName ParseNameOrDie(const android::StringPiece& str) { 52 ResourceNameRef ref; 53 CHECK(ResourceUtils::ParseResourceName(str, &ref)) << "invalid resource name"; 54 return ref.ToResourceName(); 55} 56 57inline ConfigDescription ParseConfigOrDie(const android::StringPiece& str) { 58 ConfigDescription config; 59 CHECK(ConfigDescription::Parse(str, &config)) << "invalid configuration"; 60 return config; 61} 62 63template <typename T = Value> 64T* GetValueForConfigAndProduct(ResourceTable* table, const android::StringPiece& res_name, 65 const ConfigDescription& config, 66 const android::StringPiece& product) { 67 Maybe<ResourceTable::SearchResult> result = table->FindResource(ParseNameOrDie(res_name)); 68 if (result) { 69 ResourceConfigValue* config_value = result.value().entry->FindValue(config, product); 70 if (config_value) { 71 return ValueCast<T>(config_value->value.get()); 72 } 73 } 74 return nullptr; 75} 76 77template <> 78Value* GetValueForConfigAndProduct<Value>(ResourceTable* table, 79 const android::StringPiece& res_name, 80 const ConfigDescription& config, 81 const android::StringPiece& product); 82 83template <typename T = Value> 84T* GetValueForConfig(ResourceTable* table, const android::StringPiece& res_name, 85 const ConfigDescription& config) { 86 return GetValueForConfigAndProduct<T>(table, res_name, config, {}); 87} 88 89template <typename T = Value> 90T* GetValue(ResourceTable* table, const android::StringPiece& res_name) { 91 return GetValueForConfig<T>(table, res_name, {}); 92} 93 94class TestFile : public io::IFile { 95 public: 96 explicit TestFile(const android::StringPiece& path) : source_(path) {} 97 98 std::unique_ptr<io::IData> OpenAsData() override { 99 return {}; 100 } 101 102 const Source& GetSource() const override { 103 return source_; 104 } 105 106 private: 107 DISALLOW_COPY_AND_ASSIGN(TestFile); 108 109 Source source_; 110}; 111 112} // namespace test 113 114// Workaround gtest bug (https://github.com/google/googletest/issues/443) 115// that does not select base class operator<< for derived class T. 116template <typename T> 117typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<( 118 std::ostream& out, const T& value) { 119 value.Print(&out); 120 return out; 121} 122 123template std::ostream& operator<<<Item>(std::ostream&, const Item&); 124template std::ostream& operator<<<Reference>(std::ostream&, const Reference&); 125template std::ostream& operator<<<Id>(std::ostream&, const Id&); 126template std::ostream& operator<<<RawString>(std::ostream&, const RawString&); 127template std::ostream& operator<<<String>(std::ostream&, const String&); 128template std::ostream& operator<<<StyledString>(std::ostream&, const StyledString&); 129template std::ostream& operator<<<FileReference>(std::ostream&, const FileReference&); 130template std::ostream& operator<<<BinaryPrimitive>(std::ostream&, const BinaryPrimitive&); 131template std::ostream& operator<<<Attribute>(std::ostream&, const Attribute&); 132template std::ostream& operator<<<Style>(std::ostream&, const Style&); 133template std::ostream& operator<<<Array>(std::ostream&, const Array&); 134template std::ostream& operator<<<Plural>(std::ostream&, const Plural&); 135 136// Add a print method to Maybe. 137template <typename T> 138void PrintTo(const Maybe<T>& value, std::ostream* out) { 139 if (value) { 140 *out << ::testing::PrintToString(value.value()); 141 } else { 142 *out << "Nothing"; 143 } 144} 145 146namespace test { 147 148MATCHER_P(ValueEq, a, 149 std::string(negation ? "isn't" : "is") + " equal to " + ::testing::PrintToString(a)) { 150 return arg.Equals(&a); 151} 152 153} // namespace test 154} // namespace aapt 155 156#endif /* AAPT_TEST_COMMON_H */ 157