CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
test_predicates.h
1
2#pragma once
3
4#include <gtest/gtest.h>
5
6#include "system/shared_ptr.h"
7#include "system/decimal.h"
8#include "system/array.h"
9#include "system/collections/list.h"
10#include "system/collections/dictionary.h"
11#include "system/collections/sorted_dictionary.h"
12#include "system/collections/sorted_list.h"
13#include "system/collections/stack.h"
14#include "system/collections/queue.h"
15#include "system/collections/bitarray.h"
16#include "system/collections/specialized/string_collection.h"
17#include "system/collections/hashset.h"
18#include "system/object_ext.h"
19
20#include "system/test_tools/test_tools.h"
21#include "system/test_tools/compare.h"
22
23#include <algorithm>
24#include <cmath>
25
26namespace System
27{
28namespace TestPredicates
29{
30namespace TypeTraits
31{
32
37template<typename T1, typename T2>
38using AreFPandArithmetic = std::integral_constant<bool, (std::is_floating_point<T1>::value && std::is_arithmetic<T2>::value) || (std::is_arithmetic<T1>::value && std::is_floating_point<T2>::value) >;
39
44template<typename T1, typename T2>
45using AnyOfDecimal = std::integral_constant<bool, std::is_same<T1, System::Decimal>::value || std::is_same<T2, System::Decimal>::value>;
46
51template<typename T1, typename T2, typename Enable = void>
52struct LargestFPType {};
54template<typename T1, typename T2>
55struct LargestFPType<T1, T2, typename std::enable_if<std::is_floating_point<T1>::value && !std::is_floating_point<T2>::value>::type>
56{
58 using type = T1;
59};
61template<typename T1, typename T2>
62struct LargestFPType<T1, T2, typename std::enable_if<std::is_floating_point<T2>::value && !std::is_floating_point<T1>::value>::type>
63{
65 using type = T2;
66};
68template<typename T1, typename T2>
69struct LargestFPType<T1, T2, typename std::enable_if<std::is_floating_point<T1>::value && std::is_floating_point<T2>::value>::type>
70{
72 using type = typename std::conditional<sizeof(T1) >= sizeof(T2), T1, T2>::type;
73};
74
79template<typename T, typename Enable = void>
80struct has_print_to_method : std::false_type {};
82template<typename T>
84 T
85 , decltype((void)(PrintTo(std::declval<T&>(), std::declval<std::ostream*>())))
86> : std::true_type {};
87
91template<typename T, typename Enable = void>
92struct has_data_method : std::false_type {};
94template<typename T>
95struct has_data_method<
96 T
97 , decltype((void)(std::declval<T>().data()))
98> : std::true_type {};
100template<>
103 , void
104> : std::false_type {}; // Forcing to false as boost types ain't accessible there
105
108template<typename T>
109using IsArray = std::is_same<T, System::Array<typename T::ValueType>>;
110
113template<typename T>
114using IsList = std::is_same<T, System::Collections::Generic::List<typename T::ValueType>>;
115
120template<typename T1, typename T2>
122
126template<typename T, typename Enable = void>
127struct IsEnumerable : std::false_type {};
129template<typename T>
130struct IsEnumerable<
131 T
132 , decltype((void)(std::declval<typename T::ValueType>()))
133> : std::is_base_of<System::Collections::Generic::IEnumerable<typename T::ValueType>, T> {};
134
139template <typename T1, typename T2>
140using BothEnumerable = std::integral_constant<bool, IsEnumerable<T1>::value && IsEnumerable<T2>::value>;
141
142
147template<typename T, typename Enable = void>
148struct IsCppContainer : std::false_type {};
150template<typename T>
151struct IsCppContainer<
152 T
153 , decltype(std::declval<typename T::iterator>(), std::declval<typename T::const_iterator>(), void(0))
154> : std::true_type {};
155
156} // namespace TypeTraits
157
158namespace Details
159{
160
161template<typename T>
162std::enable_if_t<!TypeTraits::IsEnumerable<T>::value, std::string>
163PrintToString(const T&);
164
165template<typename T>
166std::enable_if_t<TypeTraits::IsEnumerable<T>::value, std::string>
167PrintToString(const T& value);
168
169std::string PrintToString(std::nullptr_t);
171
178template<typename T>
179typename std::enable_if<System::Details::HasToString<T>::value, std::string>::type
180PrintToStringImpl(const SharedPtr<T>& value, long long s)
181{
182 if (value)
183 {
184 return value->ToString().ToUtf8String();
185 }
186
187 return "nullptr";
188}
195template<typename T>
196typename std::enable_if<System::Details::HasToString<T>::value, std::string>::type
197PrintToStringImpl(const WeakPtr<T>& value, long long s)
198{
199 if (auto ptr = value.lock())
200 {
201 return ptr->ToString().ToUtf8String();
202 }
203
204 return "nullptr";
205}
212template<typename T>
213typename std::enable_if<!TypeTraits::has_print_to_method<T>::value && System::Details::HasToString<T>::value, std::string>::type
214PrintToStringImpl(const T& value, long long s)
215{
216 ASPOSE_UNUSED(s);
217 return const_cast<T&>(value).ToString().ToUtf8String();
218}
225template<typename T>
226typename std::enable_if<TypeTraits::has_print_to_method<T>::value && !TypeTraits::IsEnumerable<T>::value, std::string>::type
227PrintToStringImpl(const T& value, long long s)
228{
229 ASPOSE_UNUSED(s);
230 ::std::stringstream ss;
231 PrintTo(value, &ss);
232 return ss.str();
233}
240template<typename T>
241typename std::enable_if<TypeTraits::has_print_to_method<T>::value && TypeTraits::IsEnumerable<T>::value, std::string>::type
242PrintToStringImpl(const T& value, long long s)
243{
244 ASPOSE_UNUSED(s);
246}
254template<typename T1, typename T2>
255std::string PrintToStringImpl(const std::pair<T1, T2>& value, long long s)
256{
257 ASPOSE_UNUSED(s);
258 std::ostringstream os;
259 os << '(' << PrintToString(value.first) << ", " << PrintToString(value.second) << ')';
260 return os.str();
261}
269template<typename T1, typename T2>
271{
272 ASPOSE_UNUSED(s);
273 std::ostringstream os;
274 os << '(' << PrintToString(value.get_Key()) << ", " << PrintToString(value.get_Value()) << ')';
275 return os.str();
276}
283template<typename T>
284typename std::enable_if<TypeTraits::IsCppContainer<T>::value && !std::is_base_of<Object, T>::value, std::string>::type
285PrintToStringImpl(const T& container, long long s)
286{
287 ASPOSE_UNUSED(s);
288 std::ostringstream ostr;
289 const size_t kMaxCount = 32; // The maximum number of elements to print
290 ostr << '{';
291
292 size_t count = 0;
293 for (auto it = container.begin();
294 it != container.end(); ++it, ++count) {
295 if (count > 0) {
296 ostr << ',';
297 if (count == kMaxCount) { // Enough has been printed.
298 ostr << " ...";
299 break;
300 }
301 }
302 ostr << ' ';
303 ostr << PrintToString(*it);
304 }
305
306 if (count > 0) {
307 ostr << ' ';
308 }
309 ostr << '}';
310
311 return ostr.str();
312}
319template<typename T>
320std::string PrintToStringImpl(const T& value, int s)
321{
322 ASPOSE_UNUSED(s);
323 return ::testing::PrintToString(value);
324}
329template<typename T>
330std::enable_if_t<!TypeTraits::IsEnumerable<T>::value, std::string>
331PrintToString(const T& value)
332{
333 return PrintToStringImpl(value, 1LL);
334}
337inline std::string PrintToString(std::nullptr_t)
338{
339 return "nullptr";
340}
346{
347 std::ostringstream ostr;
348 const size_t kMaxCount = 32; // The maximum number of elements to print
349 size_t count = 0;
350
351 auto enumerator = const_cast<Collections::Generic::IEnumerable<bool>&>(value).GetEnumerator();
352 while (enumerator->MoveNext())
353 {
354 if (count > 0)
355 {
356 if (count == kMaxCount)
357 {
358 // Enough has been printed.
359 ostr << " ...";
360 break;
361 }
362 }
363 ++count;
364 ostr << enumerator->get_Current();
365 }
366 return ostr.str();
367}
372template<typename T>
373std::enable_if_t<TypeTraits::IsEnumerable<T>::value, std::string>
374PrintToString(const T& value)
375{
376 std::ostringstream ostr;
377 const size_t kMaxCount = 32; // The maximum number of elements to print
378
379 ostr << '{';
380 size_t count = 0;
381
382 auto enumerator = const_cast<T&>(value).GetEnumerator();
383 while (enumerator->MoveNext())
384 {
385 if (count > 0)
386 {
387 ostr << ',';
388 if (count == kMaxCount) { // Enough has been printed.
389 ostr << " ...";
390 break;
391 }
392 }
393 ++count;
394 ostr << ' ' << PrintToString(enumerator->get_Current());
395 }
396
397 if (count > 0)
398 ostr << ' ';
399
400 ostr << '}';
401 return ostr.str();
402}
403
412template<typename T1, typename T2>
413testing::AssertionResult EqFailure(const char* lhs_expr, const char* rhs_expr
414 , T1& lhs
415 , T2& rhs)
416{
417 return testing::internal::EqFailure(lhs_expr,
418 rhs_expr,
421 false);
422}
431template<typename T1, typename T2>
432testing::AssertionResult NotEqFailure(const char* lhs_expr, const char* rhs_expr
433 , T1& lhs
434 , T2& rhs)
435{
436 return testing::AssertionFailure()
437 << "Expected: (" << lhs_expr << ") != (" << rhs_expr
438 << "), actual: " << Details::PrintToString(lhs)
439 << " vs " << Details::PrintToString(rhs);
440}
449template<typename T1, typename T2>
450testing::AssertionResult SameFailure(const char* lhs_expr, const char* rhs_expr
451 , T1& lhs
452 , T2& rhs)
453{
454 return testing::AssertionFailure()
455 << "Expected: (" << lhs_expr << ") same (" << rhs_expr
456 << "), actual: " << Details::PrintToString(lhs)
457 << " vs " << Details::PrintToString(rhs);
458}
467template<typename T1, typename T2>
468testing::AssertionResult NotSameFailure(const char* lhs_expr, const char* rhs_expr
469 , T1& lhs
470 , T2& rhs)
471{
472 return testing::AssertionFailure()
473 << "Expected: (" << lhs_expr << ") isn't same (" << rhs_expr
474 << "), actual: " << Details::PrintToString(lhs)
475 << " vs " << Details::PrintToString(rhs);
476}
477
478namespace SharedPtrAsserts
479{
480
487template<typename T1, typename T2>
488typename std::enable_if<!System::IsSmartPtr<typename T1::value_type>::value && !System::IsSmartPtr<typename T2::value_type>::value
489 ,bool>::type
490AreEqualContainer(const T1& lhs, const T2& rhs)
491{
492 return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
493}
500template<typename T1, typename T2>
501typename std::enable_if<System::IsSmartPtr<typename T1::value_type>::value && System::IsSmartPtr<typename T2::value_type>::value
502 ,bool>::type
503AreEqualContainer(const T1& lhs, const T2& rhs)
504{
505 return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(),
506 [](const typename T1::value_type &l, const typename T2::value_type &r)
507 {
508 return System::Object::Equals(l, r);
509 }
510 );
511}
512
519template<typename T1, typename T2>
520typename std::enable_if<System::IsSmartPtr<typename T1::value_type>::value && System::IsSmartPtr<typename T2::value_type>::value
521 ,bool>::type
522AreEqualData(const T1& lhs, const T2& rhs)
523{
524 return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(),
525 [](const typename T1::value_type &l, const typename T2::value_type &r)
526 {
527 return System::Object::Equals(l, r);
528 }
529 );
530}
537template<typename T1, typename T2>
538typename std::enable_if<!System::IsSmartPtr<typename T1::value_type>::value && !System::IsSmartPtr<typename T2::value_type>::value
539 ,bool>::type
540AreEqualData(const T1& lhs, const T2& rhs)
541{
542 return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
543}
550template<typename T>
551typename std::enable_if<!System::IsSmartPtr<typename T::value_type>::value
552 ,bool>::type
553AreEqualData(const T& lhs, const T& rhs)
554{
555 return lhs == rhs;
556}
557
563template<typename T>
564bool AreEqualMapOfObjects(const T& lhs, const T& rhs)
565{
566 return lhs.size() == rhs.size() && std::all_of(lhs.begin(), lhs.end(),
567 [&rhs](const typename T::value_type value)
568 {
569 auto it = rhs.find(value.first);
570 return it != rhs.end() && System::Object::Equals(value.second, it->second);
571 });
572}
573
584template<typename T1, typename T2>
585typename std::enable_if<TypeTraits::BothArrayOrList<typename T1::Pointee_, typename T2::Pointee_>::value
586, testing::AssertionResult>::type
587NotNullAreEqualImpl(const char* lhs_expr, const char* rhs_expr
588 , const T1& lhs, const T2& rhs, long long s)
589{
590 if (AreEqualData(lhs->data(), rhs->data()))
591 {
592 return testing::AssertionSuccess();
593 }
594 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
595}
596
607template<typename T1, typename T2>
608typename std::enable_if<
613 testing::AssertionResult
614>::type NotNullAreEqualImpl(const char* lhs_expr, const char* rhs_expr
615 , const T1& lhs, const T2& rhs, long long s)
616{
620 {
621 return testing::AssertionSuccess();
622 }
623 return EqFailure(lhs_expr, rhs_expr, lhs, rhs);
624}
625
626
635template<typename K, typename V>
636testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
639{
640 if (AreEqualData(lhs->data(), rhs->data()))
641 {
642 return testing::AssertionSuccess();
643 }
644 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
645}
654template<typename K, typename V>
655testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
658{
659 if (AreEqualMapOfObjects(lhs->data(), rhs->data()))
660 {
661 return testing::AssertionSuccess();
662 }
663 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
664}
673template<typename T1, typename T2>
674testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
677{
678 if (AreEqualContainer(lhs->data(), rhs->data()))
679 {
680 return testing::AssertionSuccess();
681 }
682 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
683}
692template<typename T1, typename T2>
693testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
696{
697 if (AreEqualData(lhs->data(), rhs->data()))
698 {
699 return testing::AssertionSuccess();
700 }
701 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
702}
711template<typename T1, typename T2>
712testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
715{
716 if (AreEqualData(lhs->data(), rhs->data()))
717 {
718 return testing::AssertionSuccess();
719 }
720 return EqFailure(lhs_expr, rhs_expr, *lhs, *rhs);
721}
730template<typename K, typename V>
731testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
734{
735 if (AreEqualData(lhs->data(), rhs->data()))
736 {
737 return testing::AssertionSuccess();
738 }
739 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
740}
749template<typename K, typename V>
750testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
753{
754 if (AreEqualMapOfObjects(lhs->data(), rhs->data()))
755 {
756 return testing::AssertionSuccess();
757 }
758 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
759}
768template<typename K, typename V>
769testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
772{
773 if (AreEqualData(lhs->data(), rhs->data()))
774 {
775 return testing::AssertionSuccess();
776 }
777 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
778}
787template<typename K, typename V>
788testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
791{
792 if (AreEqualMapOfObjects(lhs->data(), rhs->data()))
793 {
794 return testing::AssertionSuccess();
795 }
796 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
797}
804inline testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
807{
808 if (*lhs == *rhs)
809 {
810 return testing::AssertionSuccess();
811 }
812
813 return EqFailure(lhs_expr,
814 rhs_expr,
817 );
818}
825inline testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
828{
829 if (AreEqualData(lhs->data(), rhs->data()))
830 {
831 return testing::AssertionSuccess();
832 }
833 return EqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
834}
840template<typename T>
843{
844 static_assert(System::IsBoxable<T>::value, "Unsupported type for ICollection<T,_> compare");
845
846 if (lhs->get_Count() != rhs->get_Count())
847 {
848 return false;
849 }
850
851 if (lhs->get_Count() == 0)
852 {
853 return true;
854 }
855
856 auto lhs_en = lhs->GetEnumerator();
857 auto rhs_en = rhs->GetEnumerator();
858
859 while (lhs_en->MoveNext() && rhs_en->MoveNext())
860 {
861 auto lhs_it = lhs_en->get_Current();
862 auto rhs_it = rhs_en->get_Current();
863 if (lhs_it != rhs_it)
864 {
865 return false;
866 }
867 }
868
869 return true;
870}
878template<typename T>
879testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
882{
883 if (NotNullAreEqualHelper(lhs, rhs))
884 {
885 return testing::AssertionSuccess();
886 }
887
888 return EqFailure(lhs_expr, rhs_expr, *lhs, *rhs);
889}
898template<typename T1, typename T2>
899testing::AssertionResult NotNullAreEqualImpl(const char* lhs_expr, const char* rhs_expr
900 , const T1& lhs, const T2& rhs, int32_t)
901{
902 if (lhs->Equals(rhs))
903 {
904 return ::testing::AssertionSuccess();
905 }
906
907 return EqFailure(lhs_expr, rhs_expr, *lhs, *rhs);
908}
909
916inline testing::AssertionResult AreBoxedValuesEqual(const char* lhs_expr, const char* rhs_expr
917 , const SharedPtr<BoxedValueBase>& lhs
918 , const SharedPtr<BoxedValueBase>& rhs)
919{
920 if (lhs->Equals(rhs))
921 {
922 return ::testing::AssertionSuccess();
923 }
924
925 const auto lt = lhs->GetTypeCode();
926 const auto rt = rhs->GetTypeCode();
927
928 if (lt == TypeCode::Double || rt == TypeCode::Double)
929 {
930 if (Convert::ToDouble(lhs) == Convert::ToDouble(rhs))
931 return ::testing::AssertionSuccess();
932 }
933 else if (lt == TypeCode::Single || rt == TypeCode::Single)
934 {
935 if (Convert::ToSingle(lhs) == Convert::ToSingle(rhs))
936 return ::testing::AssertionSuccess();
937 }
938 else if (lt == TypeCode::Decimal || rt == TypeCode::Decimal)
939 {
940 if (Convert::ToDecimal(lhs) == Convert::ToDecimal(rhs))
941 return ::testing::AssertionSuccess();
942 }
943 return EqFailure(lhs_expr, rhs_expr, *lhs, *rhs);
944}
945
952inline testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
953 , const SharedPtr<Object>& lhs
954 , const SharedPtr<Object>& rhs)
955{
957 {
958 return AreBoxedValuesEqual(lhs_expr, rhs_expr, AsCast<BoxedValueBase>(lhs), AsCast<BoxedValueBase>(rhs));
959 }
960
961 return NotNullAreEqualImpl(lhs_expr, rhs_expr, lhs, rhs, 1LL);
962}
971template<typename T1, typename T2>
972testing::AssertionResult NotNullAreEqual(const char* lhs_expr, const char* rhs_expr
973 , const SharedPtr<T1>& lhs
974 , const SharedPtr<T2>& rhs)
975{
976 return NotNullAreEqualImpl(lhs_expr, rhs_expr, lhs, rhs, 1LL);
977}
978
987template<typename T1, typename T2>
988testing::AssertionResult AreEqual(const char* lhs_expr, const char* rhs_expr
989 , const T1& lhs, const T2& rhs)
990{
991 if (static_cast<System::Object*>(lhs.GetObjectOrNull()) == static_cast<System::Object*>(rhs.GetObjectOrNull()))
992 {
993 return testing::AssertionSuccess();
994 }
995
996 if (!lhs || !rhs)
997 {
998 if (!lhs)
999 {
1000 return testing::internal::EqFailure(lhs_expr, rhs_expr,
1001 "nullptr",
1003 false);
1004 }
1005 return testing::internal::EqFailure(lhs_expr, rhs_expr,
1007 "nullptr",
1008 false);
1009 }
1010
1011 return NotNullAreEqual(lhs_expr, rhs_expr, lhs, rhs);
1012}
1013
1014// AreNotEqual for SharedPtr ==================================
1015
1026template<typename T1, typename T2>
1027typename std::enable_if<TypeTraits::BothArrayOrList<typename T1::Pointee_, typename T2::Pointee_>::value
1028, testing::AssertionResult>::type
1029NotNullAreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
1030 , const T1& lhs, const T2& rhs, long long s)
1031{
1032 if (!AreEqualData(lhs->data(), rhs->data()))
1033 {
1034 return testing::AssertionSuccess();
1035 }
1036 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1037}
1038
1049template<typename T1, typename T2>
1050typename std::enable_if<
1055 testing::AssertionResult
1056>::type NotNullAreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
1057 , const T1& lhs, const T2& rhs, long long s)
1058{
1062 ))
1063 {
1064 return testing::AssertionSuccess();
1065 }
1066 return NotEqFailure(lhs_expr, rhs_expr, lhs, rhs);
1067}
1068
1077template<typename K, typename V>
1078testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1081{
1082 if (!AreEqualData(lhs->data(), rhs->data()))
1083 {
1084 return testing::AssertionSuccess();
1085 }
1086 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1087}
1096template<typename K, typename V>
1097testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1100{
1101 if (!AreEqualMapOfObjects(lhs->data(), rhs->data()))
1102 {
1103 return testing::AssertionSuccess();
1104 }
1105 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1106}
1115template<typename T1, typename T2>
1116testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1119{
1120 if (!AreEqualContainer(lhs->data(), rhs->data()))
1121 {
1122 return testing::AssertionSuccess();
1123 }
1124 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1125}
1134template<typename T1, typename T2>
1135testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1138{
1139 if (!AreEqualData(lhs->data(), rhs->data()))
1140 {
1141 return testing::AssertionSuccess();
1142 }
1143 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1144}
1153template<typename T1, typename T2>
1154testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1157{
1158 if (!AreEqualData(lhs->data(), rhs->data()))
1159 {
1160 return testing::AssertionSuccess();
1161 }
1162 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1163}
1172template<typename K, typename V>
1173testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1176{
1177 if (!AreEqualData(lhs->data(), rhs->data()))
1178 {
1179 return testing::AssertionSuccess();
1180 }
1181 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1182}
1191template<typename K, typename V>
1192testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1195{
1196 if (!AreEqualMapOfObjects(lhs->data(), rhs->data()))
1197 {
1198 return testing::AssertionSuccess();
1199 }
1200 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1201}
1210template<typename K, typename V>
1211testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1214{
1215 if (!AreEqualData(lhs->data(), rhs->data()))
1216 {
1217 return testing::AssertionSuccess();
1218 }
1219 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1220}
1229template<typename K, typename V>
1230testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1233{
1234 if (!AreEqualMapOfObjects(lhs->data(), rhs->data()))
1235 {
1236 return testing::AssertionSuccess();
1237 }
1238 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1239}
1246inline testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1249{
1250 if (*lhs != *rhs)
1251 {
1252 return testing::AssertionSuccess();
1253 }
1254
1255 return NotEqFailure(lhs_expr,
1256 rhs_expr,
1259 );
1260}
1267inline testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1270{
1271 if (!AreEqualData(lhs->data(), rhs->data()))
1272 {
1273 return testing::AssertionSuccess();
1274 }
1275 return NotEqFailure(lhs_expr, rhs_expr, lhs->data(), rhs->data());
1276}
1284template<typename T>
1285testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1288{
1289 if (!NotNullAreEqualHelper(lhs, rhs))
1290 {
1291 return testing::AssertionSuccess();
1292 }
1293
1294 return NotEqFailure(lhs_expr, rhs_expr, *lhs, *rhs);
1295}
1304template<typename T1, typename T2>
1305testing::AssertionResult NotNullAreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
1306 , const T1& lhs, const T2& rhs, int32_t)
1307{
1308 if (!lhs->Equals(rhs))
1309 {
1310 return ::testing::AssertionSuccess();
1311 }
1312
1313 return NotEqFailure(lhs_expr, rhs_expr, *lhs, *rhs);
1314}
1323template<typename T1, typename T2>
1324testing::AssertionResult NotNullAreNotEqual(const char* lhs_expr, const char* rhs_expr
1325 , const SharedPtr<T1>& lhs
1326 , const SharedPtr<T2>& rhs)
1327{
1328 return NotNullAreNotEqualImpl(lhs_expr, rhs_expr, lhs, rhs, 1LL);
1329}
1330
1339template<typename T1, typename T2>
1340testing::AssertionResult AreNotEqual(const char* lhs_expr, const char* rhs_expr
1341 , const T1& lhs, const T2& rhs)
1342{
1343 // xor
1344 if (!lhs != !rhs)
1345 {
1346 // One of operands is nullptr
1347 return testing::AssertionSuccess();
1348 }
1349
1350 // both are nullptr
1351 if (!lhs && !rhs)
1352 {
1353 return NotEqFailure(lhs_expr, rhs_expr, "nullptr", "nullptr");
1354 }
1355
1356 if (static_cast<System::Object*>(lhs.GetObjectOrNull()) == static_cast<System::Object*>(rhs.GetObjectOrNull()))
1357 {
1358 return NotEqFailure(lhs_expr, rhs_expr, *lhs, *rhs);
1359 }
1360
1361 return NotNullAreNotEqual(lhs_expr, rhs_expr, lhs, rhs);
1362}
1363
1364}
1365}
1366
1374template<typename T1, typename T2>
1375typename std::enable_if<std::numeric_limits<T1>::has_quiet_NaN && std::numeric_limits<T2>::has_quiet_NaN, bool>::type
1376 AreFPNaN(T1 lhs, T2 rhs) { return (std::isnan(lhs) && std::isnan(rhs)); }
1384template<typename T1, typename T2>
1385typename std::enable_if<!std::numeric_limits<T1>::has_quiet_NaN || !std::numeric_limits<T2>::has_quiet_NaN, bool>::type
1386 AreFPNaN(T1 lhs, T2 rhs) { return false; }
1387
1388
1389// AreEqual ===========================================================
1398template<typename T1, typename T2>
1399testing::AssertionResult AreEqual(const char* lhs_expr, const char* rhs_expr, T1&& lhs, T2&& rhs);
1400
1401// FP and arithmetic types
1412template <typename T1, typename T2>
1413typename std::enable_if<TypeTraits::AreFPandArithmetic<T1, T2>::value
1414 , testing::AssertionResult>::type
1415 AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1416 , const T1 lhs
1417 , const T2 rhs
1418 , long long s)
1419{
1420 return AreFPNaN(lhs, rhs) ? testing::AssertionSuccess() :
1421 testing::internal::CmpHelperFloatingPointEQ<typename TypeTraits::LargestFPType<T1, T2>::type>(lhs_expr, rhs_expr,
1422 static_cast<typename TypeTraits::LargestFPType<T1, T2>::type>(lhs), static_cast<typename TypeTraits::LargestFPType<T1, T2>::type>(rhs));
1423}
1434template <typename T1, typename T2>
1435typename std::enable_if<TypeTraits::AnyOfDecimal<T1, T2>::value
1436 , testing::AssertionResult>::type
1437 AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1438 , const T1& lhs
1439 , const T2& rhs
1440 , long long s)
1441{
1442 return testing::internal::
1443 EqHelper::Compare<System::Decimal, System::Decimal>
1444 (lhs_expr, rhs_expr, lhs, rhs);
1445}
1455template <typename T>
1456typename std::enable_if<!IsSmartPtr<T>::value && !std::is_same<T, System::String>::value && detail::has_method_equals<T>::value
1457 , testing::AssertionResult>::type
1458 AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1459 , const T& lhs
1460 , const T& rhs
1461 , long long s)
1462{
1463 if (lhs.Equals(rhs)) {
1464 return testing::AssertionSuccess();
1465 }
1466
1467 return Details::EqFailure(lhs_expr, rhs_expr, lhs, rhs);
1468}
1478template <typename T>
1479typename std::enable_if<!IsSmartPtr<T>::value && !std::is_same<T, System::String>::value && detail::has_method_equals<T>::value
1480 , testing::AssertionResult>::type
1481 AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1482 , T& lhs
1483 , const T& rhs
1484 , long long s)
1485{
1486 ASPOSE_UNUSED(s);
1487 if (lhs.Equals(rhs)) {
1488 return testing::AssertionSuccess();
1489 }
1490
1491 return Details::EqFailure(lhs_expr, rhs_expr, lhs, rhs);
1492}
1502template <typename T>
1503typename std::enable_if<!IsSmartPtr<T>::value && std::is_class<T>::value && !detail::has_method_equals<T>::value && detail::has_operator_equal<T>::value
1504 , testing::AssertionResult>::type
1505 AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1506 , const T& lhs
1507 , const T& rhs
1508 , long long s)
1509{
1510 if (lhs == rhs) {
1511 return testing::AssertionSuccess();
1512 }
1513
1514 return Details::EqFailure(lhs_expr, rhs_expr, lhs, rhs);
1515}
1525template <typename T>
1526typename std::enable_if<IsBoxable<T>::value && ! IsStringByteSequence<T, char16_t>::value
1527 , testing::AssertionResult>::type
1528 AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1529 , T lhs
1530 , const System::SharedPtr<Object>& rhs
1531 , long long s)
1532{
1533 return AreEqual(lhs_expr, rhs_expr, ObjectExt::Box<T>(lhs), rhs);
1534}
1544template <typename T>
1545typename std::enable_if<IsBoxable<T>::value && ! IsStringByteSequence<T, char16_t>::value
1546 , testing::AssertionResult>::type
1547 AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1548 , const System::SharedPtr<Object>& lhs
1549 , T rhs
1550 , long long s)
1551{
1552 return AreEqual(lhs_expr, rhs_expr, lhs, ObjectExt::Box<T>(rhs));
1553}
1562inline testing::AssertionResult AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1563 , const char16_t* lhs
1564 , const System::SharedPtr<Object>& rhs
1565 , long long s)
1566{
1567 ASPOSE_UNUSED(s);
1568 return AreEqual(lhs_expr, rhs_expr, System::String(lhs), System::ObjectExt::Unbox<System::String>(rhs));
1569}
1578inline testing::AssertionResult AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1579 , const System::SharedPtr<Object>& lhs
1580 , const char16_t* rhs
1581 , long long s)
1582{
1583 ASPOSE_UNUSED(s);
1584 return AreEqual(lhs_expr, rhs_expr, System::ObjectExt::Unbox<System::String>(lhs), System::String(rhs));
1585}
1594template <typename T>
1595testing::AssertionResult AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1596 , T lhs
1597 , std::nullptr_t
1598 , long long s)
1599{
1601 {
1602 return testing::AssertionSuccess();
1603 }
1604
1605 return testing::internal::EqFailure(lhs_expr, rhs_expr,
1607 "nullptr",
1608 false);
1609}
1618template <typename T>
1619testing::AssertionResult AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1620 , std::nullptr_t
1621 , T rhs
1622 , long long s)
1623{
1625 {
1626 return testing::AssertionSuccess();
1627 }
1628
1629 return testing::internal::EqFailure(lhs_expr, rhs_expr,
1630 "nullptr",
1632 false);
1633}
1644template<typename T1, typename T2>
1645typename
1646 std::enable_if<
1648 (
1649 !std::is_base_of<System::IO::Stream, typename T1::Pointee_>::value ||
1650 !std::is_base_of<System::IO::Stream, typename T2::Pointee_>::value
1651 ),
1652 testing::AssertionResult
1653 >::type
1654AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1655 , const T1& lhs
1656 , const T2& rhs
1657 , long long s)
1658{
1659 return Details::SharedPtrAsserts::AreEqual(lhs_expr, rhs_expr, lhs, rhs);
1660}
1661
1672template<typename T1, typename T2>
1673typename
1674 std::enable_if<
1676 std::is_base_of<System::IO::Stream, typename T1::Pointee_>::value &&
1677 std::is_base_of<System::IO::Stream, typename T2::Pointee_>::value,
1678 testing::AssertionResult
1679 >::type
1680AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1681 , const T1& lhs
1682 , const T2& rhs
1683 , long long s)
1684{
1685 if (static_cast<System::Object*>(lhs.GetObjectOrNull()) == static_cast<System::Object*>(rhs.GetObjectOrNull()))
1686 {
1687 return testing::AssertionSuccess();
1688 }
1689
1690 if (!lhs || !rhs)
1691 {
1692 if (!lhs)
1693 {
1694 return testing::internal::EqFailure(lhs_expr, rhs_expr,
1695 "nullptr",
1697 false);
1698 }
1699 return testing::internal::EqFailure(lhs_expr, rhs_expr,
1701 "nullptr",
1702 false);
1703 }
1704
1705 int32_t b1, b2;
1706
1707 lhs->set_Position(0);
1708 rhs->set_Position(0);
1709
1710 do
1711 {
1712 b1 = lhs->ReadByte();
1713 b2 = rhs->ReadByte();
1714
1715 if (b1 != b2)
1716 {
1717 return testing::internal::EqFailure(lhs_expr, rhs_expr,
1720 false);
1721 }
1722
1723 } while (b1 != -1 && b2 != -1);
1724
1725 return testing::AssertionSuccess();
1726}
1727
1738template <typename T1, typename T2>
1739typename std::enable_if<!std::is_null_pointer<T1>::value && !IsNullable<T1>::value, testing::AssertionResult>::type
1740AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1741 , T1 lhs
1742 , const Nullable<T2>& rhs
1743 , long long s)
1744{
1745 return rhs.IsNull() ? AreEqual(lhs_expr, rhs_expr, lhs, nullptr)
1746 : AreEqual(lhs_expr, rhs_expr, lhs, rhs.get_Value());
1747}
1758template <typename T1, typename T2>
1759typename std::enable_if<!std::is_null_pointer<T2>::value && !IsNullable<T2>::value, testing::AssertionResult>::type
1760AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1761 , const Nullable<T1>& lhs
1762 , T2 rhs
1763 , long long s)
1764{
1765 return lhs.IsNull() ? AreEqual(lhs_expr, rhs_expr, nullptr, rhs)
1766 : AreEqual(lhs_expr, rhs_expr, lhs.get_Value(), rhs);
1767}
1768
1777template<typename T1, typename T2>
1778testing::AssertionResult AreEqualImpl(const char* lhs_expr, const char* rhs_expr, T1 lhs, T2 rhs, int)
1779{
1780 return ::testing::internal::EqHelper::Compare(lhs_expr, rhs_expr, lhs, rhs);
1781}
1790template<typename T1, typename T2>
1791testing::AssertionResult AreEqual(const char* lhs_expr, const char* rhs_expr, T1&& lhs, T2&& rhs)
1792{
1793 return AreEqualImpl(lhs_expr, rhs_expr, lhs, rhs, 1LL);
1794}
1795
1796// AreNotEqual ========================================================
1805template<typename T1, typename T2>
1806testing::AssertionResult AreNotEqual(const char* lhs_expr, const char* rhs_expr, T1&& lhs, T2&& rhs);
1807
1818template <typename T1, typename T2>
1819typename std::enable_if<TypeTraits::AnyOfDecimal<T1, T2>::value
1820 , testing::AssertionResult>::type
1821 AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
1822 , const T1& lhs
1823 , const T2& rhs
1824 , long long s)
1825{
1826 if (System::Decimal(lhs) != System::Decimal(rhs))
1827 {
1828 return testing::AssertionSuccess();
1829 }
1830
1831 return Details::NotEqFailure(lhs_expr, rhs_expr, lhs, rhs);
1832}
1833
1849template <typename T>
1850typename std::enable_if<std::is_same<T, System::String>::value
1851 , testing::AssertionResult>::type
1852 AreEqualImpl(const char* lhs_expr, const char* rhs_expr
1853 , const T& lhs
1854 , const T& rhs
1855 , long long s)
1856{
1857 ASPOSE_UNUSED(s);
1858
1859 if (lhs.IsNull() || rhs.IsNull())
1860 {
1861 if (lhs.IsNull() && rhs.IsNull())
1862 {
1863 return testing::AssertionSuccess();
1864 }
1865 return testing::internal::EqFailure(lhs_expr, rhs_expr,
1866 lhs.IsNull() ? std::string("nullptr") : Details::PrintToString(lhs),
1867 rhs.IsNull() ? std::string("nullptr") : Details::PrintToString(rhs),
1868 false);
1869 }
1870
1871 if (lhs.Equals(rhs))
1872 {
1873 return testing::AssertionSuccess();
1874 }
1875
1876 return Details::EqFailure(lhs_expr, rhs_expr, lhs, rhs);
1877}
1878
1890template <typename T>
1891typename std::enable_if<std::is_same<T, System::String>::value
1892 , testing::AssertionResult>::type
1893 AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
1894 , const T& lhs
1895 , const T& rhs
1896 , long long s)
1897{
1898 ASPOSE_UNUSED(s);
1899
1900 if (lhs.IsNull() || rhs.IsNull())
1901 {
1902 if (lhs.IsNull() && rhs.IsNull())
1903 {
1904 return Details::NotEqFailure(lhs_expr, rhs_expr, "nullptr", "nullptr");
1905 }
1906 return testing::AssertionSuccess();
1907 }
1908
1909 if (!lhs.Equals(rhs))
1910 {
1911 return testing::AssertionSuccess();
1912 }
1913
1914 return Details::NotEqFailure(lhs_expr, rhs_expr, lhs, rhs);
1915}
1916
1926template <typename T>
1927typename std::enable_if<!IsSmartPtr<T>::value && !std::is_same<T, System::String>::value && detail::has_method_equals<T>::value
1928 , testing::AssertionResult>::type
1929 AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
1930 , const T& lhs
1931 , const T& rhs
1932 , long long s)
1933{
1934 if (! lhs.Equals(rhs)) {
1935 return testing::AssertionSuccess();
1936 }
1937
1938 return Details::NotEqFailure(lhs_expr, rhs_expr, lhs, rhs);
1939}
1949template <typename T>
1950typename std::enable_if<!IsSmartPtr<T>::value && !std::is_same<T, System::String>::value && detail::has_method_equals<T>::value
1951 , testing::AssertionResult>::type
1952 AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
1953 , T& lhs
1954 , const T& rhs
1955 , long long s)
1956{
1957 if (!lhs.Equals(rhs)) {
1958 return testing::AssertionSuccess();
1959 }
1960
1961 return Details::NotEqFailure(lhs_expr, rhs_expr, lhs, rhs);
1962}
1972template <typename T>
1973typename std::enable_if<!IsSmartPtr<T>::value && std::is_class<T>::value && !detail::has_method_equals<T>::value && detail::has_operator_equal<T>::value
1974 , testing::AssertionResult>::type
1975 AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
1976 , const T& lhs
1977 , const T& rhs
1978 , long long s)
1979{
1980 if (lhs != rhs) {
1981 return testing::AssertionSuccess();
1982 }
1983
1984 return Details::EqFailure(lhs_expr, rhs_expr, lhs, rhs);
1985}
1995template <typename T>
1996typename std::enable_if<IsBoxable<T>::value
1997 , testing::AssertionResult>::type
1998 AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
1999 , T lhs
2000 , const System::SharedPtr<Object>& rhs
2001 , long long s)
2002{
2003 return AreNotEqual(lhs_expr, rhs_expr, lhs, System::ObjectExt::Unbox<T>(rhs));
2004}
2014template <typename T>
2015typename std::enable_if<IsBoxable<T>::value
2016 , testing::AssertionResult>::type
2017 AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
2018 , const System::SharedPtr<Object>& lhs
2019 , T rhs
2020 , long long s)
2021{
2022 return AreNotEqual(lhs_expr, rhs_expr, System::ObjectExt::Unbox<T>(lhs), rhs);
2023}
2032template <typename T>
2033testing::AssertionResult AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
2034 , T lhs
2035 , std::nullptr_t
2036 , long long s)
2037{
2038 if (!System::TestTools::IsNull(lhs))
2039 {
2040 return testing::AssertionSuccess();
2041 }
2042
2043 return Details::NotEqFailure(lhs_expr, rhs_expr, lhs, "nullptr");
2044}
2053template <typename T>
2054testing::AssertionResult AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
2055 , std::nullptr_t
2056 , T rhs
2057 , long long s)
2058{
2059 if (!System::TestTools::IsNull(rhs))
2060 {
2061 return testing::AssertionSuccess();
2062 }
2063
2064 return Details::NotEqFailure(lhs_expr, rhs_expr, "nullptr", rhs);
2065}
2076template<typename T1, typename T2>
2077typename std::enable_if<IsSmartPtr<T1>::value && IsSmartPtr<T2>::value
2078 , testing::AssertionResult>::type
2079 AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr
2080 , const T1& lhs
2081 , const T2& rhs
2082 , long long s)
2083{
2084 return Details::SharedPtrAsserts::AreNotEqual(lhs_expr, rhs_expr, lhs, rhs);
2085}
2094template<typename T1, typename T2>
2095testing::AssertionResult AreNotEqualImpl(const char* lhs_expr, const char* rhs_expr, T1 lhs, T2 rhs, int)
2096{
2097 return ::testing::internal::CmpHelperNE(lhs_expr, rhs_expr, lhs , rhs);
2098}
2107template<typename T1, typename T2>
2108testing::AssertionResult AreNotEqual(const char* lhs_expr, const char* rhs_expr, T1&& lhs, T2&& rhs)
2109{
2110 return AreNotEqualImpl(lhs_expr, rhs_expr, lhs, rhs, 1LL);
2111}
2112
2113// AreSame ============================================================
2122template<typename T1, typename T2>
2123testing::AssertionResult AreSame(const char* lhs_expr, const char* rhs_expr, const T1& lhs, const T2& rhs);
2124
2135template<typename T1, typename T2>
2136typename std::enable_if<IsSmartPtr<T1>::value && IsSmartPtr<T2>::value
2137 , testing::AssertionResult>::type
2138 AreSameImpl(const char* lhs_expr, const char* rhs_expr
2139 , const T1& lhs
2140 , const T2& rhs
2141 , long long s)
2142{
2143 // xor
2144 if (!lhs != !rhs)
2145 {
2146 if (!lhs)
2147 {
2148 auto rhs_addr = reinterpret_cast<std::ptrdiff_t>(rhs.GetObjectOrNull());
2149 return Details::SameFailure(lhs_expr, rhs_expr, "nullptr", rhs_addr);
2150 }
2151 auto lhs_addr = reinterpret_cast<std::ptrdiff_t>(lhs.GetObjectOrNull());
2152 return Details::SameFailure(lhs_expr, rhs_expr, lhs_addr, "nullptr");
2153 }
2154
2155 // both are nullptr
2156 if (!lhs && !rhs)
2157 {
2158 return testing::AssertionSuccess();
2159 }
2160
2161 if (static_cast<System::Object*>(lhs.GetObjectOrNull()) == static_cast<System::Object*>(rhs.GetObjectOrNull()))
2162 {
2163 return testing::AssertionSuccess();
2164 }
2165
2166 auto rhs_addr = reinterpret_cast<std::ptrdiff_t>(rhs.GetObjectOrNull());
2167 auto lhs_addr = reinterpret_cast<std::ptrdiff_t>(lhs.GetObjectOrNull());
2168 return Details::SameFailure(lhs_expr, rhs_expr, lhs_addr, rhs_addr);
2169}
2180template<typename T1, typename T2>
2181typename std::enable_if<IsExceptionWrapper<T1>::value && IsExceptionWrapper<T2>::value
2182 , testing::AssertionResult>::type
2183 AreSameImpl(const char* lhs_expr, const char* rhs_expr
2184 , const T1& lhs
2185 , const T2& rhs
2186 , long long s)
2187{
2188 if (lhs == rhs)
2189 return testing::AssertionSuccess();
2190
2191 auto rhs_addr = reinterpret_cast<std::ptrdiff_t>(&rhs);
2192 auto lhs_addr = reinterpret_cast<std::ptrdiff_t>(&lhs);
2193 return Details::SameFailure(lhs_expr, rhs_expr, lhs_addr, rhs_addr);
2194}
2203template<typename T1, typename T2>
2204testing::AssertionResult AreSameImpl(const char* lhs_expr, const char* rhs_expr, const T1& lhs, const T2& rhs, int)
2205{
2206 if (&lhs == &rhs)
2207 {
2208 return testing::AssertionSuccess();
2209 }
2210
2211 std::ptrdiff_t lhs_addr = reinterpret_cast<std::ptrdiff_t>(&lhs);
2212 std::ptrdiff_t rhs_addr = reinterpret_cast<std::ptrdiff_t>(&rhs);
2213 return Details::SameFailure(lhs_expr, rhs_expr, lhs_addr, rhs_addr);
2214}
2215
2224template<typename T1, typename T2>
2225testing::AssertionResult AreSame(const char* lhs_expr, const char* rhs_expr, const T1& lhs, const T2& rhs)
2226{
2227 return AreSameImpl(lhs_expr, rhs_expr, lhs, rhs, 1LL);
2228}
2229
2230// AreNotSame =========================================================
2239template<typename T1, typename T2>
2240testing::AssertionResult AreNotSame(const char* lhs_expr, const char* rhs_expr, const T1& lhs, const T2& rhs);
2241
2252template<typename T1, typename T2>
2253typename std::enable_if<IsSmartPtr<T1>::value && IsSmartPtr<T2>::value
2254 , testing::AssertionResult>::type
2255 AreNotSameImpl(const char* lhs_expr, const char* rhs_expr
2256 , const T1& lhs
2257 , const T2& rhs
2258 , long long s)
2259{
2260 // xor
2261 if (!lhs != !rhs)
2262 {
2263 return testing::AssertionSuccess();
2264 }
2265
2266 // both are nullptr
2267 if (!lhs && !rhs)
2268 {
2269 return Details::NotSameFailure(lhs_expr, rhs_expr, "nullptr", "nullptr");
2270 }
2271
2272 if (static_cast<System::Object*>(lhs.GetObjectOrNull()) != static_cast<System::Object*>(rhs.GetObjectOrNull()))
2273 {
2274 return testing::AssertionSuccess();
2275 }
2276
2277 auto rhs_addr = reinterpret_cast<std::ptrdiff_t>(rhs.GetObjectOrNull());
2278 auto lhs_addr = reinterpret_cast<std::ptrdiff_t>(lhs.GetObjectOrNull());
2279 return Details::NotSameFailure(lhs_expr, rhs_expr, lhs_addr, rhs_addr);
2280}
2289template<typename T1, typename T2>
2290testing::AssertionResult AreNotSameImpl(const char* lhs_expr, const char* rhs_expr, const T1& lhs, const T2& rhs, int)
2291{
2292 if (&lhs != &rhs)
2293 {
2294 return testing::AssertionSuccess();
2295 }
2296
2297 std::ptrdiff_t lhs_addr = reinterpret_cast<std::ptrdiff_t>(&lhs);
2298 std::ptrdiff_t rhs_addr = reinterpret_cast<std::ptrdiff_t>(&rhs);
2299 return Details::NotSameFailure(lhs_expr, rhs_expr, lhs_addr, rhs_addr);
2300}
2301
2310template<typename T1, typename T2>
2311testing::AssertionResult AreNotSame(const char* lhs_expr, const char* rhs_expr, const T1& lhs, const T2& rhs)
2312{
2313 return AreNotSameImpl(lhs_expr, rhs_expr, lhs, rhs, 1LL);
2314}
2315
2323template<typename T>
2324testing::AssertionResult IsInstanceOf(const char* lhs_expr, const char* rhs_expr, const TypeInfo& typeInfo, const T& obj)
2325{
2326 if (obj->Is(typeInfo))
2327 {
2328 return ::testing::AssertionSuccess();
2329 }
2330
2331 return testing::AssertionFailure()
2332 << "Expected: " << rhs_expr << " is " << lhs_expr
2333 << ", actual: " << obj->GetType().ToString().ToUtf8String()
2334 << " vs " << typeInfo.ToString().ToUtf8String();
2335}
2336
2337} // namespace TestPredicates
2338} // namespace System
2339
2343#define ASPOSE_ASSERT_EQ(val1, val2) \
2344 ASSERT_PRED_FORMAT2(System::TestPredicates::AreEqual, val1, val2)
2345
2349#define ASPOSE_EXPECT_EQ(val1, val2) \
2350 EXPECT_PRED_FORMAT2(System::TestPredicates::AreEqual, val1, val2)
2351
2355#define ASPOSE_ASSERT_NE(val1, val2) \
2356 ASSERT_PRED_FORMAT2(System::TestPredicates::AreNotEqual, val1, val2)
2357
2361#define ASPOSE_EXPECT_NE(val1, val2) \
2362 EXPECT_PRED_FORMAT2(System::TestPredicates::AreNotEqual, val1, val2)
2363
2367#define ASPOSE_ASSERT_SAME(val1, val2) \
2368 ASSERT_PRED_FORMAT2(System::TestPredicates::AreSame, val1, val2)
2369
2373#define ASPOSE_EXPECT_SAME(val1, val2) \
2374 EXPECT_PRED_FORMAT2(System::TestPredicates::AreSame, val1, val2)
2375
2379#define ASPOSE_ASSERT_NS(val1, val2) \
2380 ASSERT_PRED_FORMAT2(System::TestPredicates::AreNotSame, val1, val2)
2381
2385#define ASPOSE_EXPECT_NS(val1, val2) \
2386 EXPECT_PRED_FORMAT2(System::TestPredicates::AreNotSame, val1, val2)
2387
2391#define ASPOSE_ASSERT_ISINSTANCEOF(val1, val2) \
2392 ASSERT_PRED_FORMAT2(System::TestPredicates::IsInstanceOf, val1, val2)
2393
2397#define ASPOSE_EXPECT_ISINSTANCEOF(val1, val2) \
2398 EXPECT_PRED_FORMAT2(System::TestPredicates::IsInstanceOf, val1, val2)
2399
2402#define ASPOSE_GTEST_TEST_THROW_(statement, expected_exception, exception_ref, fail) \
2403 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
2404 if (::testing::internal::ConstCharPtr gtest_msg = "") { \
2405 bool gtest_caught_expected = false; \
2406 try { \
2407 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
2408 } \
2409 catch (expected_exception const& e) { \
2410 gtest_caught_expected = true; \
2411 static_assert(std::is_base_of<std::remove_pointer<decltype(exception_ref)>::type, expected_exception>::value, "Should be base class of expected exception"); \
2412 *exception_ref = e; \
2413 } \
2414 catch (...) { \
2415 gtest_msg.value = \
2416 "Expected: " #statement " throws an exception of type " \
2417 #expected_exception ".\n Actual: it throws a different type."; \
2418 goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
2419 } \
2420 if (!gtest_caught_expected) { \
2421 gtest_msg.value = \
2422 "Expected: " #statement " throws an exception of type " \
2423 #expected_exception ".\n Actual: it throws nothing."; \
2424 goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
2425 } \
2426 } else \
2427 GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
2428 fail(gtest_msg.value)
2429
2434#define ASPOSE_ASSERT_THROW(statement, expected_exception, exception_ref) \
2435 ASPOSE_GTEST_TEST_THROW_(statement, expected_exception, exception_ref, GTEST_FATAL_FAILURE_);
2436
2438#define ASPOSE_ASSERT_THROW_EXCEPTION_TYPE_(statement, expected_exception_type, fail) \
2439 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
2440 if (::testing::internal::ConstCharPtr gtest_msg = "") { \
2441 bool gtest_caught_expected = false; \
2442 try { \
2443 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
2444 } \
2445 catch (const System::Exception& e) { \
2446 gtest_caught_expected = true; \
2447 if(e.Get()->GetType() != expected_exception_type)\
2448 { \
2449 gtest_msg.value = \
2450 "Actual: " #statement " throws a different type."; \
2451 goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
2452 } \
2453 } \
2454 catch (...) { \
2455 gtest_msg.value = \
2456 "Actual: " #statement " throws a unexpected exception type."; \
2457 goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
2458 } \
2459 if (!gtest_caught_expected) { \
2460 gtest_msg.value = \
2461 "Actual: " #statement " throws nothing."; \
2462 goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
2463 } \
2464 } else \
2465 GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
2466 fail(gtest_msg.value)
2467
2476#define ASPOSE_ASSERT_THROW_EXCEPTION_TYPE(statement, exceptionType) \
2477 ASPOSE_ASSERT_THROW_EXCEPTION_TYPE_(statement, exceptionType, GTEST_FATAL_FAILURE_)
Array of bits which can be addressed by index. Objects of this class should only be allocated using S...
Definition: bitarray.h:97
Forward declaration of Dictionary class.
Definition: dictionary.h:96
Forward declaration of HashSet class.
Definition: hashset.h:82
Interface of collection of elements. Objects of this class should only be allocated using System::Mak...
Definition: icollection.h:20
Pair of key and value. This type should be allocated on stack and passed to functions by value or by ...
Definition: keyvalue_pair.h:20
const TKey & get_Key() const
Gets key.
Definition: keyvalue_pair.h:40
const TValue & get_Value() const
Gets value.
Definition: keyvalue_pair.h:43
Queue class forward declaration.
Definition: queue.h:88
Sorted dictionary type forward declaration.
Definition: sorted_dictionary.h:52
Sorted list wrapping FlatMap structure. Objects of this class should only be allocated using System::...
Definition: sorted_list.h:334
Stack class forward declaration.
Definition: stack.h:87
Represents a decimal number. This type should be allocated on stack and passed to functions by value ...
Definition: decimal.h:107
Forward declaration.
Definition: nullable.h:75
T get_Value() const
Returns a copy of the value represented by the current object.
Definition: nullable.h:144
bool IsNull() const
Determines if the current object represents a null-value.
Definition: nullable.h:180
static bool IsBoxedValue(const SmartPtr< Object > &obj)
Checks if object is a boxed value.
Base class that enables using methods available for System.Object class in C#. All non-trivial classe...
Definition: object.h:51
Pointer class to wrap types being allocated on heap. Use it to manage memory for classes inheriting O...
Definition: smart_ptr.h:180
String class used across the library. Is a substitute for C# System.String when translating code....
Definition: string.h:125
std::string ToUtf8String() const
Converts string to std::string. Uses UTF-8 encoding.
Represents a particular type and provides information about it.
Definition: type_info.h:109
String ToString() const
Returns a string containing the name of the type represented by the current object.
Subclass of System::SmartPtr which sets itself to weak mode at construction. Please note that this cl...
Definition: weak_ptr.h:18
std::enable_if< TypeTraits::BothArrayOrList< typenameT1::Pointee_, typenameT2::Pointee_ >::value, testing::AssertionResult >::type NotNullAreEqualImpl(const char *lhs_expr, const char *rhs_expr, const T1 &lhs, const T2 &rhs, long long s)
Equal-compares arrays or lists.
Definition: test_predicates.h:587
testing::AssertionResult NotNullAreEqual(const char *lhs_expr, const char *rhs_expr, const SharedPtr< System::Collections::Generic::Dictionary< K, V > > &lhs, const SharedPtr< System::Collections::Generic::Dictionary< K, V > > &rhs)
Equal-compares dictionaries of value types.
Definition: test_predicates.h:636
testing::AssertionResult AreBoxedValuesEqual(const char *lhs_expr, const char *rhs_expr, const SharedPtr< BoxedValueBase > &lhs, const SharedPtr< BoxedValueBase > &rhs)
Equal-compares two Boxed types.
Definition: test_predicates.h:916
testing::AssertionResult NotNullAreNotEqual(const char *lhs_expr, const char *rhs_expr, const SharedPtr< System::Collections::Generic::Dictionary< K, V > > &lhs, const SharedPtr< System::Collections::Generic::Dictionary< K, V > > &rhs)
Not-equal-compares dictionaries of value types.
Definition: test_predicates.h:1078
std::enable_if< System::IsSmartPtr< typenameT1::value_type >::value &&System::IsSmartPtr< typenameT2::value_type >::value, bool >::type AreEqualData(const T1 &lhs, const T2 &rhs)
Equal-compares two containers using System::Object::Equals on elements. Works for SmartPtr elements.
Definition: test_predicates.h:522
testing::AssertionResult AreNotEqual(const char *lhs_expr, const char *rhs_expr, const T1 &lhs, const T2 &rhs)
Not-equal-compares arguments for AreNotEqual assertion translation.
Definition: test_predicates.h:1340
std::enable_if<!System::IsSmartPtr< typenameT1::value_type >::value &&!System::IsSmartPtr< typenameT2::value_type >::value, bool >::type AreEqualContainer(const T1 &lhs, const T2 &rhs)
Equal-compares two containers using operator == on elements. Works for non-SmartPtr elements.
Definition: test_predicates.h:490
bool NotNullAreEqualHelper(const SharedPtr< System::Collections::Generic::ICollection< T > > &lhs, const SharedPtr< System::Collections::Generic::ICollection< T > > &rhs)
Equal-compares abstract collections.
Definition: test_predicates.h:841
std::enable_if< TypeTraits::BothArrayOrList< typenameT1::Pointee_, typenameT2::Pointee_ >::value, testing::AssertionResult >::type NotNullAreNotEqualImpl(const char *lhs_expr, const char *rhs_expr, const T1 &lhs, const T2 &rhs, long long s)
Not-equal-compares arrays or lists.
Definition: test_predicates.h:1029
bool AreEqualMapOfObjects(const T &lhs, const T &rhs)
Equal-compares two maps using System::Object::Equals on elements.
Definition: test_predicates.h:564
testing::AssertionResult AreEqual(const char *lhs_expr, const char *rhs_expr, const T1 &lhs, const T2 &rhs)
Equal-compares arguments for AreEqual assertion translation.
Definition: test_predicates.h:988
std::enable_if< System::Details::HasToString< T >::value, std::string >::type PrintToStringImpl(const SharedPtr< T > &value, long long s)
Prints System::Object subclass to string using ToString() method.
Definition: test_predicates.h:180
std::enable_if_t<!TypeTraits::IsEnumerable< T >::value, std::string > PrintToString(const T &)
Prints object to string by selecting proper serializer function.
Definition: test_predicates.h:331
testing::AssertionResult NotSameFailure(const char *lhs_expr, const char *rhs_expr, T1 &lhs, T2 &rhs)
Formats 'not same' assertion failure for output.
Definition: test_predicates.h:468
testing::AssertionResult EqFailure(const char *lhs_expr, const char *rhs_expr, T1 &lhs, T2 &rhs)
Formats == assertion failure for output.
Definition: test_predicates.h:413
testing::AssertionResult SameFailure(const char *lhs_expr, const char *rhs_expr, T1 &lhs, T2 &rhs)
Formats 'same' assertion failure for output.
Definition: test_predicates.h:450
testing::AssertionResult NotEqFailure(const char *lhs_expr, const char *rhs_expr, T1 &lhs, T2 &rhs)
Formats != assertion failure for output.
Definition: test_predicates.h:432
std::is_same< T, System::Array< typename T::ValueType > > IsArray
Checks if type is a System::Array specialization. If so, value member is set to true,...
Definition: test_predicates.h:109
std::integral_constant< bool,(IsArray< T1 >::value||IsList< T1 >::value) &&(IsArray< T2 >::value||IsList< T2 >::value)> BothArrayOrList
Checks if both type arguments are arrays or lists. If so, value member is set to true,...
Definition: test_predicates.h:121
std::integral_constant< bool, std::is_same< T1, System::Decimal >::value||std::is_same< T2, System::Decimal >::value > AnyOfDecimal
Checks that at least one of type arguments is System::Decimal. If so, sets value member to true,...
Definition: test_predicates.h:45
std::is_same< T, System::Collections::Generic::List< typename T::ValueType > > IsList
Checks if type is a System::Collections::Generic::List specialization. If so, value member is set to ...
Definition: test_predicates.h:114
std::integral_constant< bool, IsEnumerable< T1 >::value &&IsEnumerable< T2 >::value > BothEnumerable
Checks if both type arguments are IEnumerable. If so, value member is set to true,...
Definition: test_predicates.h:140
std::integral_constant< bool,(std::is_floating_point< T1 >::value &&std::is_arithmetic< T2 >::value)||(std::is_arithmetic< T1 >::value &&std::is_floating_point< T2 >::value) > AreFPandArithmetic
Checks that T1 is arithmetic and T2 is floating point, or vice versa. If so, sets value member to tru...
Definition: test_predicates.h:38
std::enable_if< TypeTraits::AnyOfDecimal< T1, T2 >::value, testing::AssertionResult >::type AreNotEqualImpl(const char *lhs_expr, const char *rhs_expr, const T1 &lhs, const T2 &rhs, long long s)
Not-equal-compares values one or both of them being Decimal.
Definition: test_predicates.h:1821
std::enable_if< TypeTraits::AreFPandArithmetic< T1, T2 >::value, testing::AssertionResult >::type AreEqualImpl(const char *lhs_expr, const char *rhs_expr, const T1 lhs, const T2 rhs, long long s)
Equal-compares floating point with arithmetic types.
Definition: test_predicates.h:1415
testing::AssertionResult AreNotSame(const char *lhs_expr, const char *rhs_expr, const T1 &lhs, const T2 &rhs)
Are-not-same-compares arguments for AreSame assertion translation.
Definition: test_predicates.h:2311
testing::AssertionResult AreEqual(const char *lhs_expr, const char *rhs_expr, T1 &&lhs, T2 &&rhs)
Equal-compares arguments for AreEqual assertion translation.
Definition: test_predicates.h:1791
std::enable_if< IsSmartPtr< T1 >::value &&IsSmartPtr< T2 >::value, testing::AssertionResult >::type AreNotSameImpl(const char *lhs_expr, const char *rhs_expr, const T1 &lhs, const T2 &rhs, long long s)
Are-not-same-compares smart pointers.
Definition: test_predicates.h:2255
testing::AssertionResult IsInstanceOf(const char *lhs_expr, const char *rhs_expr, const TypeInfo &typeInfo, const T &obj)
Is-instance-of-compares arguments for IsInstanceOf assertion translation.
Definition: test_predicates.h:2324
testing::AssertionResult AreSame(const char *lhs_expr, const char *rhs_expr, const T1 &lhs, const T2 &rhs)
Are-same-compares arguments for AreSame assertion translation.
Definition: test_predicates.h:2225
std::enable_if< IsSmartPtr< T1 >::value &&IsSmartPtr< T2 >::value, testing::AssertionResult >::type AreSameImpl(const char *lhs_expr, const char *rhs_expr, const T1 &lhs, const T2 &rhs, long long s)
Are-same-compares smart pointers.
Definition: test_predicates.h:2138
testing::AssertionResult AreNotEqual(const char *lhs_expr, const char *rhs_expr, T1 &&lhs, T2 &&rhs)
Not-equal-compares arguments for AreEqual assertion translation.
Definition: test_predicates.h:2108
std::enable_if< std::numeric_limits< T1 >::has_quiet_NaN &&std::numeric_limits< T2 >::has_quiet_NaN, bool >::type AreFPNaN(T1 lhs, T2 rhs)
namespace Details
Definition: test_predicates.h:1376
Definition: db_command.h:9
void PrintTo(DateTime value, std::ostream *stream)
Prints value to ostream. Mostly used for debug.
@ Single
A floating point type representing values ranging from approximately 1.5 x 10 -45 to 3....
@ Decimal
A simple type representing values ranging from 1.0 x 10 -28 to approximately 7.9 x 10 28 with 28-29 s...
@ Double
A floating point type representing values ranging from approximately 5.0 x 10 -324 to 1....
std::enable_if_t< Details::CastType< Source, Result >::Static, Result > AsCast(const Source &value)
Casts the source type to the result type using 'as' operator cast. Used when simple constructor-like ...
Definition: object_ext.h:1203
static Decimal ToDecimal(bool value)
Converts the specified boolean value to an equivalent decimal number.
Definition: convert.h:1022
static constexpr double ToDouble(bool value)
Converts the specified boolean value to an equivalent double-precision floating-point number.
Definition: convert.h:956
static constexpr float ToSingle(bool value)
Converts the specified boolean value to an equivalent single-precision floating-point number.
Definition: convert.h:890
Template predicate that checks if boxing of the specified type is supported.
Definition: boxable_traits.h:16
A template predicate that determines if the specified type is a Exception class or its descendant.
Definition: object.h:394
A template predicate that determines if its template argument T in Nullable or its subclass.
Definition: nullable.h:23
Trait class to check if a type is a specialization of SmartPtr class.
Definition: smart_ptr.h:1499
Template magic to check if a type is a sequence of string characters.
Definition: string.h:71
static bool AreEqual(const SharedPtr< Array< T > > &arrA, const SharedPtr< Array< U > > &arrB)
Compares arrays of non-pointers.
Definition: compare.h:41
Checks if specific type is STL-style container. To do so, checks for iterator and const_iterator memb...
Definition: test_predicates.h:148
Checks if type has System::Collections::Generic::IEnumerable specialization as basetype....
Definition: test_predicates.h:127
Provides alias for longest floating point type provided. Ignores non-floating point types.
Definition: test_predicates.h:52
Checks if a type has data() method. If it does, inherits std::true_type, otherwise inherits std::fals...
Definition: test_predicates.h:92
Checks for overload of PrintTo function that accepts given type as first argument....
Definition: test_predicates.h:80
static std::enable_if< std::is_arithmetic< T >::value||std::is_enum< T >::value, bool >::type IsNull(T obj)
Checks if specific value is null. Version for arithmetic and enum types.
Definition: test_tools.h:137
Checks whether Equals method exists in specified type. If so, inherits std::true_type,...
Definition: detail.h:137
Checks whether operator == exists in specified type. If so, inherits std::true_type,...
Definition: detail.h:122