WwiseUnitTests.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*******************************************************************************
  2. The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
  3. Technology released in source code form as part of the game integration package.
  4. The content of this file may not be used without valid licenses to the
  5. AUDIOKINETIC Wwise Technology.
  6. Note that the use of the game engine is subject to the Unreal(R) Engine End User
  7. License Agreement at https://www.unrealengine.com/en-US/eula/unreal
  8. License Usage
  9. Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
  10. this file in accordance with the end user license agreement provided with the
  11. software or, alternatively, in accordance with the terms contained
  12. in a written agreement between you and Audiokinetic Inc.
  13. Copyright (c) 2023 Audiokinetic Inc.
  14. *******************************************************************************/
  15. #pragma once
  16. #include "WwiseUnrealDefines.h"
  17. // We use Catch2 Test Harness, available starting UE5.1
  18. #if UE_5_2_OR_LATER
  19. #include "Tests/TestHarnessAdapter.h"
  20. #elif UE_5_1_OR_LATER
  21. #include "Tests/TestHarness.h"
  22. #else
  23. #include "Misc/AutomationTest.h"
  24. #endif // UE_5_2_OR_LATER
  25. // Determine if we have unit tests. These Unreal macros are defined in the previously included header files.
  26. #if !defined(WWISE_LOW_LEVEL_TESTS)
  27. #if defined(WITH_LOW_LEVEL_TESTS) && WITH_LOW_LEVEL_TESTS
  28. #define WWISE_LOW_LEVEL_TESTS 1
  29. #else
  30. #define WWISE_LOW_LEVEL_TESTS 0
  31. #endif
  32. #endif
  33. #if !defined(WWISE_AUTOMATION_TESTS)
  34. #if defined(WITH_AUTOMATION_TESTS) && WITH_AUTOMATION_TESTS
  35. #define WWISE_AUTOMATION_TESTS 1
  36. #else
  37. #define WWISE_AUTOMATION_TESTS 0
  38. #endif
  39. #endif
  40. #if !defined(WWISE_UNIT_TESTS)
  41. #if WWISE_LOW_LEVEL_TESTS || WWISE_AUTOMATION_TESTS
  42. #define WWISE_UNIT_TESTS 1
  43. #else
  44. #define WWISE_UNIT_TESTS 0
  45. #endif
  46. #endif
  47. //
  48. // Definition of Wwise Unit Tests API. Unreal's Test API improved throughout the earlier UE5 versions. This
  49. // allows for a normalized interface starting from UE4.27.
  50. //
  51. #if WWISE_UNIT_TESTS
  52. #include <type_traits>
  53. // This is an adapted copy of UE5.1's Misc/LowLevelTestAdapter.h for UE4.27 & UE5.0 usage.
  54. #if !UE_5_1_OR_LATER
  55. #include "Misc/AssertionMacros.h"
  56. #include "Misc/ScopeExit.h"
  57. #include "CoreTypes.h"
  58. class FWwiseAutomationTestBase : public FAutomationTestBase
  59. {
  60. public:
  61. FWwiseAutomationTestBase( const FString& InName )
  62. : FAutomationTestBase( InName, false )
  63. {
  64. }
  65. // Adapted from UE5.1's Misc/AutomationTest.h and .cpp
  66. uint32 ExtractAutomationTestFlags(FString InTagNotation)
  67. {
  68. static const TMap<FString, EAutomationTestFlags::Type> FlagsMap = {
  69. { TEXT("EditorContext"), EAutomationTestFlags::Type::EditorContext},
  70. { TEXT("ClientContext"), EAutomationTestFlags::Type::ClientContext},
  71. { TEXT("ServerContext"), EAutomationTestFlags::Type::ServerContext},
  72. { TEXT("CommandletContext"), EAutomationTestFlags::Type::CommandletContext},
  73. { TEXT("ApplicationContextMask"), EAutomationTestFlags::Type::ApplicationContextMask},
  74. { TEXT("NonNullRHI"), EAutomationTestFlags::Type::NonNullRHI},
  75. { TEXT("RequiresUser"), EAutomationTestFlags::Type::RequiresUser},
  76. { TEXT("FeatureMask"), EAutomationTestFlags::Type::FeatureMask},
  77. { TEXT("Disabled"), EAutomationTestFlags::Type::Disabled},
  78. { TEXT("CriticalPriority"), EAutomationTestFlags::Type::CriticalPriority},
  79. { TEXT("HighPriority"), EAutomationTestFlags::Type::HighPriority},
  80. { TEXT("HighPriorityAndAbove"), EAutomationTestFlags::Type::HighPriorityAndAbove},
  81. { TEXT("MediumPriority"), EAutomationTestFlags::Type::MediumPriority},
  82. { TEXT("MediumPriorityAndAbove"), EAutomationTestFlags::Type::MediumPriorityAndAbove},
  83. { TEXT("LowPriority"), EAutomationTestFlags::Type::LowPriority},
  84. { TEXT("PriorityMask"), EAutomationTestFlags::Type::PriorityMask},
  85. { TEXT("SmokeFilter"), EAutomationTestFlags::Type::SmokeFilter},
  86. { TEXT("EngineFilter"), EAutomationTestFlags::Type::EngineFilter},
  87. { TEXT("ProductFilter"), EAutomationTestFlags::Type::ProductFilter},
  88. { TEXT("PerfFilter"), EAutomationTestFlags::Type::PerfFilter},
  89. { TEXT("StressFilter"), EAutomationTestFlags::Type::StressFilter},
  90. { TEXT("NegativeFilter"), EAutomationTestFlags::Type::NegativeFilter},
  91. { TEXT("FilterMask"), EAutomationTestFlags::Type::FilterMask}
  92. };
  93. uint32 Result = 0;
  94. TArray<FString> OutputParts;
  95. InTagNotation
  96. .Replace(TEXT("["), TEXT(""))
  97. .Replace(TEXT("]"), TEXT(";"))
  98. .ParseIntoArray(OutputParts, TEXT(";"), true);
  99. for (auto it = OutputParts.begin(); it != OutputParts.end(); ++it)
  100. {
  101. if (FlagsMap.Contains(*it))
  102. {
  103. Result |= FlagsMap[*it];
  104. }
  105. }
  106. return Result;
  107. }
  108. };
  109. #define IMPLEMENT_SIMPLE_AUTOMATION_TEST_PRIVATE_LLT( TClass, PrettyName, TFlags, FileName, LineNumber ) \
  110. class TClass : public FWwiseAutomationTestBase \
  111. { \
  112. public:\
  113. TClass( const FString& InName) \
  114. : FWwiseAutomationTestBase( InName ) \
  115. { \
  116. TestFlags = ExtractAutomationTestFlags(TFlags); \
  117. PrettyNameDotNotation = FString(PrettyName).Replace(TEXT("::"), TEXT(".")); \
  118. if (!(TestFlags & EAutomationTestFlags::ApplicationContextMask)) \
  119. { \
  120. TestFlags |= EAutomationTestFlags::ApplicationContextMask; \
  121. } \
  122. if (!(TestFlags & EAutomationTestFlags::FilterMask)) \
  123. { \
  124. TestFlags |= EAutomationTestFlags::EngineFilter; \
  125. } \
  126. } \
  127. virtual uint32 GetTestFlags() const override { return TestFlags; } \
  128. virtual bool IsStressTest() const { return false; } \
  129. virtual uint32 GetRequiredDeviceNum() const override { return 1; } \
  130. virtual FString GetTestSourceFileName() const override { return FileName; } \
  131. virtual int32 GetTestSourceFileLine() const override { return LineNumber; } \
  132. protected: \
  133. virtual void GetTests(TArray<FString>& OutBeautifiedNames, TArray <FString>& OutTestCommands) const override \
  134. { \
  135. OutBeautifiedNames.Add(PrettyNameDotNotation); \
  136. OutTestCommands.Add(FString());\
  137. } \
  138. void TestBody(const FString& Parameters); \
  139. virtual bool RunTest(const FString& Parameters) { \
  140. TestBody(Parameters); \
  141. return true; \
  142. } \
  143. virtual FString GetBeautifiedTestName() const override { return PrettyNameDotNotation; } \
  144. private:\
  145. uint32 TestFlags; \
  146. FString PrettyNameDotNotation; \
  147. };
  148. #define LLT_JOIN(Prefix, Counter) LLT_JOIN_INNER(Prefix, Counter)
  149. #define LLT_JOIN_INNER(Prefix, Counter) Prefix##Counter
  150. #define TEST_CASE_NAMED(TClass, StrName, PrettyName, TFlags) \
  151. IMPLEMENT_SIMPLE_AUTOMATION_TEST_PRIVATE_LLT(TClass, PrettyName, TFlags, __FILE__, __LINE__) \
  152. namespace \
  153. { \
  154. TClass LLT_JOIN(TClass, Instance)(TEXT(StrName)); \
  155. } \
  156. void TClass::TestBody(const FString& Parameters)
  157. //#define TEST_CASE_GENERATED_NAME_UNIQUE LLT_JOIN(FLLTAdaptedTest, __COUNTER__)
  158. #define LLT_STR(Macro) #Macro
  159. #define LLT_STR_EXPAND(Macro) LLT_STR(Macro)
  160. //#define TEST_CASE_GENERATED_NAME_UNIQUE_STR LLT_STR_EXPAND(TEST_CASE_GENERATED_NAME_UNIQUE)
  161. //#define TEST_CASE(PrettyName, TFlags) TEST_CASE_NAMED(TEST_CASE_GENERATED_NAME_UNIQUE, TEST_CASE_GENERATED_NAME_UNIQUE_STR, PrettyName, TFlags)
  162. #define CHECK(Expr) if (!(Expr)) { FAutomationTestFramework::Get().GetCurrentTest()->AddError(TEXT("Condition failed")); }
  163. #define CHECK_FALSE(Expr) if (Expr) { FAutomationTestFramework::Get().GetCurrentTest()->AddError(TEXT("Condition expected to return false but returned true")); }
  164. #define REQUIRE(Expr) if (!(Expr)) { FAutomationTestFramework::Get().GetCurrentTest()->AddError(TEXT("Required condition failed, interrupting test")); return; }
  165. #define SECTION(Text) AddInfo(TEXT(Text));
  166. #endif
  167. // Some of our testing actually prefer to use the fast version of HashCombine. This is only accessible in UE5.
  168. inline uint32 WwiseHashCombineFast(uint32 A, uint32 B)
  169. {
  170. #if UE_5_0_OR_LATER
  171. return HashCombineFast(A, B);
  172. #else
  173. return HashCombine(A, B);
  174. #endif
  175. }
  176. // Add logging facilities when running in Automation
  177. #if WWISE_AUTOMATION_TESTS
  178. #define WWISE_TEST_LOG(Format, ...) FAutomationTestFramework::Get().GetCurrentTest()->AddInfo(FString::Printf(TEXT(Format), __VA_ARGS__));
  179. #else
  180. #define WWISE_TEST_LOG(Format, ...) (void)0
  181. #endif
  182. // Use a normalized test case that works correctly with multiple compilation units (Unreal's TEST_CASE doesn't like being used in more than one module)
  183. #if WWISE_LOW_LEVEL_TESTS
  184. #define WWISE_TEST_CASE(ClassName, PrettyName, Flags) TEST_CASE(PrettyName, Flags)
  185. #elif UE_5_3_OR_LATER
  186. #define WWISE_TEST_CASE(ClassName, PrettyName, Flags) TEST_CASE_NAMED(FWwiseTest ## ClassName, PrettyName, Flags)
  187. #else
  188. #define WWISE_TEST_CASE(ClassName, PrettyName, Flags) TEST_CASE_NAMED(FWwiseTest ## ClassName, LLT_STR_EXPAND(FWwiseTest ## ClassName), PrettyName, Flags)
  189. #endif
  190. #define WWISE_TEST_ASYNC_NAME TEXT("WwiseUnitTests Async")
  191. #endif // WWISE_UNIT_TESTS