//----------------------------------------------------------------------------------------------------------------------
/// \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)