1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef META_TEST_TEST_UTILS_H
17 #define META_TEST_TEST_UTILS_H
18
19 #include <algorithm>
20 #include <limits>
21 #include <ostream>
22
23 #include <base/math/mathf.h>
24 #include <base/math/vector.h>
25 #include <base/util/uid.h>
26
27 #include <meta/base/time_span.h>
28 #include <meta/interface/intf_attach.h>
29 #include <meta/interface/intf_metadata.h>
30
31 #include "testing_objects.h"
32
33 namespace BASE_NS {
34 std::ostream& operator<<(std::ostream& os, const BASE_NS::Uid& uid);
35 std::ostream& operator<<(std::ostream& os, const BASE_NS::string& s);
36 std::ostream& operator<<(std::ostream& os, const BASE_NS::string_view& s);
37
38 namespace Math {
39 // Operators for EXPECT_LT/GT/LE/GE macros to work
40 // Note: These are not proper comparison operators, they only verify if
41 // both x and y of lhs is > or < than rhs.
42 bool operator>(const BASE_NS::Math::Vec3& lhs, const BASE_NS::Math::Vec3& rhs);
43 bool operator<(const BASE_NS::Math::Vec3& lhs, const BASE_NS::Math::Vec3& rhs);
44 bool operator>(const BASE_NS::Math::Vec2& lhs, const BASE_NS::Math::Vec2& rhs);
45 bool operator<(const BASE_NS::Math::Vec2& lhs, const BASE_NS::Math::Vec2& rhs);
46
47 bool operator>=(const BASE_NS::Math::Vec3& lhs, const BASE_NS::Math::Vec3& rhs);
48 bool operator<=(const BASE_NS::Math::Vec3& lhs, const BASE_NS::Math::Vec3& rhs);
49 bool operator>=(const BASE_NS::Math::Vec2& lhs, const BASE_NS::Math::Vec2& rhs);
50 bool operator<=(const BASE_NS::Math::Vec2& lhs, const BASE_NS::Math::Vec2& rhs);
51
52 // Tests if all components of a vector are within epsilon of each other
53 bool AreEqual(const BASE_NS::Math::Vec3& lhs, const BASE_NS::Math::Vec3& rhs, float epsilon = BASE_NS::Math::EPSILON);
54 bool AreNear(const BASE_NS::Math::Vec3& lhs, const BASE_NS::Math::Vec3& rhs);
55 bool AreEqual(const BASE_NS::Math::Vec2& lhs, const BASE_NS::Math::Vec2& rhs, float epsilon = BASE_NS::Math::EPSILON);
56 bool AreNear(const BASE_NS::Math::Vec2& lhs, const BASE_NS::Math::Vec2& rhs);
57 std::ostream& operator<<(std::ostream& os, const BASE_NS::Math::Vec2& vec);
58 std::ostream& operator<<(std::ostream& os, const BASE_NS::Math::Vec3& vec);
59 } // namespace Math
60 } // namespace BASE_NS
61
62 namespace META_NS {
63 std::ostream& operator<<(std::ostream& os, const META_NS::TimeSpan& vec);
64
65 template<typename Type>
ContainsObjectWithName(const BASE_NS::vector<Type> & vec,const BASE_NS::string & name)66 bool ContainsObjectWithName(const BASE_NS::vector<Type>& vec, const BASE_NS::string& name)
67 {
68 for (auto c : vec) {
69 if (auto i = interface_cast<IObject>(c)) {
70 if (i->GetName() == name) {
71 return true;
72 }
73 }
74 }
75 return false;
76 }
77
78 template<typename T>
79 bool IsEqual(const BASE_NS::vector<T>& a, const BASE_NS::vector<T>& b);
80
81 template<class A>
IsEqual(const A & a,const A & b)82 inline bool IsEqual(const A& a, const A& b)
83 {
84 if constexpr (BASE_NS::is_floating_point_v<A>) {
85 double mul = std::max({ A(1.0), std::fabs(a), std::fabs(b) });
86 return std::fabs(a - b) <= std::numeric_limits<A>::epsilon() * mul;
87 } else {
88 return a == b;
89 }
90 }
91
IsEqual(const ITestType::ConstPtr & a,const ITestType::ConstPtr & b)92 inline bool IsEqual(const ITestType::ConstPtr& a, const ITestType::ConstPtr& b)
93 {
94 auto lobj = interface_cast<IObject>(a);
95 auto robj = interface_cast<IObject>(b);
96 return lobj && robj && lobj->GetName() == robj->GetName();
97 }
98
IsEqual(const ITestType::Ptr & a,const ITestType::Ptr & b)99 inline bool IsEqual(const ITestType::Ptr& a, const ITestType::Ptr& b)
100 {
101 return IsEqual(ITestType::ConstPtr(a), ITestType::ConstPtr(b));
102 }
103
IsEqual(const IAny & a,const IAny & b)104 inline bool IsEqual(const IAny& a, const IAny& b)
105 {
106 SharedPtrConstIInterface pa;
107 SharedPtrConstIInterface pb;
108 if (a.GetValue(pa) && b.GetValue(pb)) {
109 return (pa != nullptr) == (pb != nullptr);
110 }
111 auto copy = a.Clone(true);
112 return copy->CopyFrom(b) == AnyReturn::NOTHING_TO_DO;
113 }
114
IsEqual(const IAny::Ptr & a,const IAny::Ptr & b)115 inline bool IsEqual(const IAny::Ptr& a, const IAny::Ptr& b)
116 {
117 return (!a && !b) || (a && b && IsEqual(*a, *b));
118 }
119
IsEqual(const IValue::Ptr & a,const IValue::Ptr & b)120 inline bool IsEqual(const IValue::Ptr& a, const IValue::Ptr& b)
121 {
122 return IsEqual(a->GetValue(), b->GetValue());
123 }
124
IsEqual(const IArrayAny::Ptr & a,const IArrayAny::Ptr & b)125 inline bool IsEqual(const IArrayAny::Ptr& a, const IArrayAny::Ptr& b)
126 {
127 if (a->GetSize() != b->GetSize()) {
128 return false;
129 }
130 for (size_t i = 0; i != a->GetSize(); ++i) {
131 auto anya = a->Clone(AnyCloneOptions { CloneValueType::DEFAULT_VALUE, TypeIdRole::ITEM });
132 auto anyb = b->Clone(AnyCloneOptions { CloneValueType::DEFAULT_VALUE, TypeIdRole::ITEM });
133 if (!a->GetAnyAt(i, *anya) || !b->GetAnyAt(i, *anyb)) {
134 return false;
135 }
136 if (!IsEqual(anya, anyb)) {
137 return false;
138 }
139 }
140 return true;
141 }
142
IsEqual(IObject::Ptr a,IObject::Ptr b)143 inline bool IsEqual(IObject::Ptr a, IObject::Ptr b)
144 {
145 if ((a != nullptr) != (b != nullptr)) {
146 return false;
147 }
148 if (a && b && a->GetClassId() != b->GetClassId()) {
149 return false;
150 }
151 auto ta = interface_pointer_cast<ITestType>(a);
152 auto tb = interface_pointer_cast<ITestType>(b);
153 return (!ta && !tb) || IsEqual(ta, tb);
154 }
155
IsEqual(IContainer::Ptr a,IContainer::Ptr b)156 inline bool IsEqual(IContainer::Ptr a, IContainer::Ptr b)
157 {
158 if (a->GetSize() != b->GetSize()) {
159 return false;
160 }
161 for (size_t i = 0; i != a->GetSize(); ++i) {
162 if (!IsEqual(a->GetAt(i), b->GetAt(i))) {
163 return false;
164 }
165 }
166 return true;
167 }
168
IsEqual(IAttach::Ptr a,IAttach::Ptr b)169 inline bool IsEqual(IAttach::Ptr a, IAttach::Ptr b)
170 {
171 return IsEqual(a->GetAttachments(), b->GetAttachments());
172 }
173
IsEqual(IAttachment::Ptr a,IAttachment::Ptr b)174 inline bool IsEqual(IAttachment::Ptr a, IAttachment::Ptr b)
175 {
176 auto ao = interface_cast<IObject>(a);
177 auto bo = interface_cast<IObject>(b);
178 return (!ao && !bo) || (ao && bo && ao->GetName() == bo->GetName());
179 }
180
IsEqual(IProperty::Ptr a,IProperty::Ptr b)181 inline bool IsEqual(IProperty::Ptr a, IProperty::Ptr b)
182 {
183 if (a->GetName() != b->GetName()) {
184 return false;
185 }
186 if ((a->GetOwner().lock() != nullptr) != (b->GetOwner().lock() != nullptr)) {
187 return false;
188 }
189 if (a->IsDefaultValue() != b->IsDefaultValue()) {
190 return false;
191 }
192 auto as = interface_cast<IStackProperty>(a);
193 auto bs = interface_cast<IStackProperty>(b);
194 if (!as || !bs) {
195 return false;
196 }
197 return IsEqual(as->GetDefaultValue(), bs->GetDefaultValue()) &&
198 IsEqual(as->GetValues({}, false), bs->GetValues({}, false)) &&
199 as->GetModifiers({}, false).size() == bs->GetModifiers({}, false).size();
200 }
201
202 template<typename T>
IsEqual(const BASE_NS::vector<T> & a,const BASE_NS::vector<T> & b)203 inline bool IsEqual(const BASE_NS::vector<T>& a, const BASE_NS::vector<T>& b)
204 {
205 if (a.size() != b.size()) {
206 return false;
207 }
208 for (size_t i = 0; i != a.size(); ++i) {
209 if (!IsEqual(a[i], b[i])) {
210 return false;
211 }
212 }
213 return true;
214 }
215
SortByName(BASE_NS::vector<META_NS::IProperty::Ptr> vec)216 inline BASE_NS::vector<META_NS::IProperty::Ptr> SortByName(BASE_NS::vector<META_NS::IProperty::Ptr> vec)
217 {
218 std::stable_sort(vec.begin(), vec.end(), [](auto a, auto b) { return a->GetName() < b->GetName(); });
219 return vec;
220 }
221
IsEqual(IMetadata::Ptr a,IMetadata::Ptr b)222 inline bool IsEqual(IMetadata::Ptr a, IMetadata::Ptr b)
223 {
224 return IsEqual(SortByName(a->GetProperties()), SortByName(b->GetProperties()));
225 }
226
227 } // namespace META_NS
228
229 #endif // UI_TEST_MACROS_H
230