9#include "system/object.h"
10#include "system/object_ext.h"
11#include "system/string.h"
12#include "system/constraints.h"
13#include "system/text/string_builder.h"
14#include "system/collections/icollection.h"
15#include "system/collections/ienumerable.h"
16#include "system/collections/dictionary.h"
17#include "system/collections/keyvalue_pair.h"
27template <
typename TT,
typename T>
28class IEnumeratorIterator :
public Details::BaseIterator<std::input_iterator_tag, TT> {
35 IEnumeratorIterator(
const IEnumeratorIterator& o) : m_data(o.m_data) {};
39 IEnumeratorIterator& operator++() {
if (!m_data->MoveNext()) m_data =
nullptr;
return *
this; }
42 TT
operator*() {
return TT(m_data->get_Current()); };
47 bool operator==(
const IEnumeratorIterator& o)
const {
return m_data == o.m_data; }
51 bool operator!=(
const IEnumeratorIterator& o)
const {
return m_data != o.m_data; }
62template <
typename TT,
typename T>
63class IEnumerableAdapter
67 using value_type = TT;
69 using const_iterator = IEnumeratorIterator<TT, T>;
72 IEnumerableAdapter() : m_data(nullptr) {}
79 IEnumeratorIterator<TT, T> begin()
const
81 return m_data->MoveNext() ? IEnumeratorIterator<TT, T>(m_data) : IEnumeratorIterator<TT,
T>(nullptr);
85 IEnumeratorIterator<TT, T> end()
const {
return IEnumeratorIterator<TT, T>(
nullptr); }
97template <typename TT, class Guard = typename std::enable_if<System::Constraints::IsStdTuple<TT>::value>::type,
98 typename T =
typename std::tuple_element<0, TT>::type>
99class IEnumerableTupleAdapter :
public IEnumerableAdapter<TT, T>
105 IEnumerableAdapter<TT,
T>(data)
114class IEnumerableDefaultAdapter :
public IEnumerableAdapter<T, T>
120 IEnumerableAdapter<
T,
T>(data)
137static typename std::enable_if<std::is_arithmetic<T>::value || std::is_enum<T>::value,
bool>::type
IsNull(T obj)
147static typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_enum<T>::value,
bool>::type
IsNull(
const T &obj)
149 return obj ==
nullptr;
159 return obj ==
nullptr;
167template<
typename K,
typename V>
170 return kvp ==
nullptr;
187 return collection->get_Count() == 0;
197 return collection ==
nullptr || collection->get_Count() == 0;
243 template <
typename T1,
typename T2>
246 auto diff = System::MakeObject<System::Collections::Generic::Dictionary<T1, int32_t>>();
248 auto e_enumerator = (expected)->GetEnumerator();
249 while (e_enumerator->MoveNext())
251 auto&& e = e_enumerator->get_Current();
253 if (diff->TryGetValue(e, v))
255 diff->idx_set(e, v + 1);
263 auto a_enumerator = (actual)->GetEnumerator();
264 while (a_enumerator->MoveNext())
266 auto&& a = a_enumerator->get_Current();
268 const auto aa =
static_cast<T1
>(a);
269 if (diff->TryGetValue(aa, v))
271 diff->idx_set(aa, v - 1);
287 auto v_enumerator = (values)->GetEnumerator();
288 while (v_enumerator->MoveNext())
290 auto&& v = v_enumerator->get_Current();
304 auto v_enumerator = (values)->GetEnumerator();
305 while (v_enumerator->MoveNext())
307 auto&& v = v_enumerator->get_Current();
320 template <
typename T>
323 if (ie ==
nullptr || !ie->GetEnumerator()->MoveNext())
330 auto e_enumerator = (ie)->GetEnumerator();
331 while (e_enumerator->MoveNext())
333 auto&& e = e_enumerator->get_Current();
337 sb->Remove(sb->get_Length() - 2, 2);
339 return sb->ToString();
350 template <
typename T1,
typename T2>
355 return u
"\r\nExpected: " + extra_msg + u
"< " +
IEnumerableToStr(expected) + u
" >" +
364 return System::String(u
"Message: ") + (message.IsEmpty() ? u
"<empty>" : message);
373#define COLLECTION_ASSERT_MAKE_DIFF(expected, actual) ((System::CollectionAssertHelper::MakeDiff<std::remove_const<std::remove_reference<decltype((expected)->GetEnumerator()->get_Current())>::type>::type, std::remove_const<std::remove_reference<decltype((actual)->GetEnumerator()->get_Current())>::type>::type>((expected), (actual)))->get_Values())
378#define COLLECTION_ASSERT_COLLECTIONS_TO_MSG(str, expected, actual) (System::CollectionAssertHelper::CollectionsToMsg<std::remove_const<std::remove_reference<decltype((expected)->GetEnumerator()->get_Current())>::type>::type, std::remove_const<std::remove_reference<decltype((actual)->GetEnumerator()->get_Current())>::type>::type>((str), (expected), (actual)))
383#define COLLECTION_ASSERT_ARE_EQUIVALENT(expected, actual, ...) {\
384 if (!System::CollectionAssertHelper::CheckDiffForAll([](int32_t v) {return v == 0;}, COLLECTION_ASSERT_MAKE_DIFF(expected, actual)))\
385 FAIL() << (System::CollectionAssertHelper::ToFullMessage(__VA_ARGS__) + COLLECTION_ASSERT_COLLECTIONS_TO_MSG(u"equivalent to ", expected, actual)).ToUtf8String();\
391#define COLLECTION_ASSERT_ARE_NOT_EQUIVALENT(expected, actual, ...) {\
392 if (!System::CollectionAssertHelper::CheckDiffForAny([](int32_t v) {return v != 0;}, COLLECTION_ASSERT_MAKE_DIFF(expected, actual)))\
393 FAIL() << (System::CollectionAssertHelper::ToFullMessage(__VA_ARGS__) + COLLECTION_ASSERT_COLLECTIONS_TO_MSG(u"not equivalent to ", expected, actual)).ToUtf8String();\
399#define COLLECTION_ASSERT_IS_SUBSET_OF(subset, superset, ...) {\
400 if (!System::CollectionAssertHelper::CheckDiffForAll([](int32_t v) {return v >= 0;}, COLLECTION_ASSERT_MAKE_DIFF(superset, subset)))\
401 FAIL() << (System::CollectionAssertHelper::ToFullMessage(__VA_ARGS__) + COLLECTION_ASSERT_COLLECTIONS_TO_MSG(u"subset of ", superset, subset)).ToUtf8String();\
407#define COLLECTION_ASSERT_IS_NOT_SUBSET_OF(subset, superset, ...) {\
408 if (!System::CollectionAssertHelper::CheckDiffForAny([](int32_t v) {return v < 0;}, COLLECTION_ASSERT_MAKE_DIFF(superset, subset)))\
409 FAIL() << (System::CollectionAssertHelper::ToFullMessage(__VA_ARGS__) + COLLECTION_ASSERT_COLLECTIONS_TO_MSG(u"not subset of ", superset, subset)).ToUtf8String();\
415#define TEST_IF_CASE_HAS(member, name) \
416 template<typename T> struct has_##member \
419 static int detect(...); \
420 template<typename U> static decltype(void(std::declval<U>().name)) detect(const U&); \
422 static constexpr bool value = std::is_same<void, decltype(detect(std::declval<T>()))>::value; \
428#define TEST_IF_STATIC_METHOD(name) \
429 template<typename T> struct is_static_method \
432 static int detect(...); \
433 template<typename U> static typename std::enable_if<std::is_function<decltype(U::name)>::value, bool>::type detect(const U&); \
435 static constexpr bool value = std::is_same<bool, decltype(detect(std::declval<T>()))>::value; \
440#define TEST_IF_STATIC_METHOD_NAMED(name) \
441 template<typename T> struct is_static_method_##name \
444 static int detect(...); \
445 template<typename U> static typename std::enable_if<std::is_function<decltype(U::name)>::value, bool>::type detect(const U&); \
447 static constexpr bool value = std::is_same<bool, decltype(detect(std::declval<T>()))>::value; \
Interface of collection of elements. Objects of this class should only be allocated using System::Mak...
Definition: icollection.h:20
Interface of object providing enumerator on contained elements.
Definition: ienumerable.h:25
Interface of enumerator which can be used to iterate through some elements. Objects of this class sho...
Definition: ienumerator.h:63
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
static String ToString(const char_t *obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:96
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:122
bool IsNullOrEmpty() const
Checks if string is empty or is considered null.
bool IsEmpty() const
Checks if string is both non-null and empty.
bool IsNull() const
Checks if string is considered null. String is null and only if it is constructed via String() constr...
Definition: string.h:280
Definition: db_command.h:9
bool operator!=(ArraySegment< T > a, ArraySegment< T > b)
Definition: array_segment.h:157
Decimal operator*(const T &x, const Decimal &d)
Returns a new instance of Decimal class that represents a value that is a result of multiplication of...
Definition: decimal.h:556
bool operator==(ArraySegment< T > a, ArraySegment< T > b)
Definition: array_segment.h:151
Heler API for collection-related operations.
Definition: test_tools.h:234
static bool CheckDiffForAny(const std::function< bool(int)> &pred, const System::SharedPtr< System::Collections::Generic::ICollection< int32_t > > &values)
Checks that any collection element adheres the predicate.
Definition: test_tools.h:302
static System::SharedPtr< System::Collections::Generic::Dictionary< T1, int32_t > > MakeDiff(const System::SharedPtr< System::Collections::Generic::IEnumerable< T1 > > &expected, const System::SharedPtr< System::Collections::Generic::IEnumerable< T2 > > &actual)
Calculates 'diff' between two collections. For every element of each collection as key resulting valu...
Definition: test_tools.h:244
static System::String ToFullMessage(const System::String &message=u"")
Formats string to be used as message text.
Definition: test_tools.h:362
static bool CheckDiffForAll(const std::function< bool(int)> &pred, const System::SharedPtr< System::Collections::Generic::ICollection< int32_t > > &values)
Checks that all collection elements adhere the predicate.
Definition: test_tools.h:285
static System::String IEnumerableToStr(const System::SharedPtr< System::Collections::Generic::IEnumerable< T > > &ie)
Converts collection to string by joining string representations of elements.
Definition: test_tools.h:321
static System::String CollectionsToMsg(const System::String &extra_msg, const System::SharedPtr< System::Collections::Generic::IEnumerable< T1 > > &expected, const System::SharedPtr< System::Collections::Generic::IEnumerable< T2 > > &actual)
Serializes two collections for message representation.
Definition: test_tools.h:351