//---------------------------------------------------------------------------------------------------------------------- /// \file /// API and data types for using data in data driven native tests // Copyright (c) Microsoft Corporation. All Rights Reserved. //---------------------------------------------------------------------------------------------------------------------- #pragma once // The test data retrieval APIs are not yet implemented on Linux. #if defined(_WIN32) #include "TE.Common.h" #if defined(_WIN32) #include "WexDebug.h" #endif #if !defined(_WIN32) #pragma push_macro("_In_z_") #pragma push_macro("_Outptr_") #if !defined(_In_z_) #define _In_z_ #endif #if !defined(_Outptr_) #define _Outptr_ #endif #endif // #if !defined(_WIN32) #if defined(_WIN32) // Forward define 'IStream' typedef interface IStream IStream; namespace WEX { namespace Common { class NoThrowString; class String; }/* namespace Common */}/* namespace WEX */ #endif // #if defined(_WIN32) namespace WEX { namespace TestExecution { class TestDataArrayPrivate; /// /// A helper class to work with arrays in data driven testing /// /// \code /// Example: /// /// TestDataArray sizes; /// if (SUCCEEDED(TestData::TryGetValue(L"size", sizes))) /// { /// size_t count = sizes.GetSize(); /// for (size_t i = 0; i < count; ++i) /// { /// Log::Comment(String().Format(L"Size[%d] retrieved was %d", i, sizes[i])); /// } /// } /// \endcode template class TECOMMON_API TestDataArray final { friend class TestDataArrayPrivate; public: TestDataArray(); ~TestDataArray(); T& operator[](size_t index); #if defined(__GNUC__) /*clang and gcc on linux*/ # pragma GCC diagnostic push // We have to return a const size_t in order to preserve the decorated name of the export. // This will be fixed once we refactor this code to avoid decorated C++ exports. # pragma GCC diagnostic ignored "-Wignored-qualifiers" #elif defined(__clang__) /*clang on Windows*/ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wignored-qualifiers" #endif const size_t GetSize() const; #if defined(__GNUC__) # pragma GCC diagnostic pop #elif defined(__clang__) /*clang on Windows*/ # pragma clang diagnostic pop #endif const T& operator[](size_t index) const; private: void Allocate(size_t elements); TestDataArray(const TestDataArray& other); TestDataArray& operator=(TestDataArray& other); void Free(); T* Detach(); /// \internal /// we need a way to get an address because operator& is overloaded TestDataArray* This() {return this;} size_t m_size; T* m_p; }; namespace Private { /// \internal /// WEX::TestExecution::Private::TestData must be a templatized *class* so that we can dll export explicit /// instantiations. template class TECOMMON_API TestData final { public: /// Tries to get the requested value in the requested format static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const wchar_t* pszString, T& result); /// TestDataArray specific TestData implementation static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const wchar_t* pszString, TestDataArray& results); #if defined(TECOMMON_EXPORTS) static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const unsigned short* pszString, T& result); static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const unsigned short* pszString, TestDataArray& results); #endif }; #if defined(_WIN32) class TECOMMON_API XmlTestData final { public: static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const wchar_t* pszString, _Outptr_ IStream** result); #if defined(TECOMMON_EXPORTS) static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const unsigned short* pszString, _Outptr_ IStream** result); #endif }; #endif // #if defined(_WIN32) template class AreSameType { public: static const bool value = false; }; template class AreSameType { public: static const bool value = true; }; } /// /// Data driven test data retrival class /// /// \internal /// WEX::TestExecution::TestData provides templatized *methods* to allow compiler type inference, and simply routes /// the call to the matching WEX::TestExecution::Private::TestData instantiation. class TestData { public: /// /// Data driven test data retrival API for basic types /// template static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const wchar_t* pszString, T& result) { static_assert(Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value #if defined(_WIN32) || Private::AreSameType<__int64, T>::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value #endif // #if defined(_WIN32) , "Attempt to use TestData::TryGetValue with an unsupported type"); return Private::TestData::TryGetValue(pszString, result); } #if defined(_WIN32) static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const wchar_t* pszString, _Outptr_ IStream** result) { return Private::XmlTestData::TryGetValue(pszString, result); } #endif // #if defined(_WIN32) /// /// Data driven test data retrival API for array types /// template static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const wchar_t* pszString, TestDataArray& results) { static_assert(Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value #if defined(_WIN32) || Private::AreSameType<__int64, T>::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value #endif // #if defined(_WIN32) , "Attempt to use TestData::TryGetValue with an unsupported type for TestDataArray"); return Private::TestData::TryGetValue(pszString, results); } #if defined(TECOMMON_EXPORTS) template static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const unsigned short* pszString, T& result) { static_assert(Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value #if defined(_WIN32) || Private::AreSameType<__int64, T>::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value #endif // #if defined(_WIN32) , "Attempt to use TestData::TryGetValue with an unsupported type"); return Private::TestData::TryGetValue(pszString, result); } #if defined(_WIN32) static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const unsigned short* pszString, _Outptr_ IStream** result) { return Private::XmlTestData::TryGetValue(pszString, result); } #endif // #if defined(_WIN32) /// /// Data driven test data retrival API for array types /// template static HRESULT TAEF_STDCALL TryGetValue(_In_z_ const unsigned short* pszString, TestDataArray& results) { static_assert(Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value #if defined(_WIN32) || Private::AreSameType<__int64, T>::value || Private::AreSameType::value || Private::AreSameType::value || Private::AreSameType::value #endif // #if defined(_WIN32) , "Attempt to use TestData::TryGetValue with an unsupported type for TestDataArray"); return Private::TestData::TryGetValue(pszString, results); } #endif }; }/* namespace TestExecution */}/* namespace WEX */ #if !defined(_WIN32) #pragma pop_macro("_In_z_") #pragma pop_macro("_Outptr_") #endif // #if !defined(_WIN32) #endif // #if defined(_WIN32)