CommonTests.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #include <wil/common.h>
  2. #include <wil/resource.h>
  3. #include <wrl/client.h>
  4. #include "common.h"
  5. TEST_CASE("CommonTests::OutParamHelpers", "[common]")
  6. {
  7. int i = 2;
  8. int *pOutTest = &i;
  9. int *pNullTest = nullptr;
  10. SECTION("Value type")
  11. {
  12. wil::assign_to_opt_param(pNullTest, 3);
  13. wil::assign_to_opt_param(pOutTest, 3);
  14. REQUIRE(*pOutTest == 3);
  15. }
  16. SECTION("Pointer to value type")
  17. {
  18. int **ppOutTest = &pOutTest;
  19. int **ppNullTest = nullptr;
  20. wil::assign_null_to_opt_param(ppNullTest);
  21. wil::assign_null_to_opt_param(ppOutTest);
  22. REQUIRE(*ppOutTest == nullptr);
  23. }
  24. SECTION("COM out pointer")
  25. {
  26. Microsoft::WRL::ComPtr<IUnknown> spUnk;
  27. IUnknown **ppunkNull = nullptr;
  28. IUnknown *pUnk = reinterpret_cast<IUnknown *>(1);
  29. IUnknown **ppUnkValid = &pUnk;
  30. wil::detach_to_opt_param(ppunkNull, spUnk);
  31. wil::detach_to_opt_param(ppUnkValid, spUnk);
  32. REQUIRE(*ppUnkValid == nullptr);
  33. }
  34. }
  35. TEST_CASE("CommonTests::TypeValidation", "[common]")
  36. {
  37. std::unique_ptr<BYTE> boolCastClass;
  38. std::vector<int> noBoolCastClass;
  39. HRESULT hr = S_OK;
  40. BOOL bigBool = true;
  41. bool smallBool = true;
  42. DWORD dword = 1;
  43. Microsoft::WRL::ComPtr<IUnknown> comPtr;
  44. (void)dword;
  45. // NOTE: The commented out verify* calls should give compilation errors
  46. SECTION("verify_bool")
  47. {
  48. REQUIRE(wil::verify_bool(smallBool));
  49. REQUIRE(wil::verify_bool(bigBool));
  50. REQUIRE_FALSE(wil::verify_bool(boolCastClass));
  51. REQUIRE_FALSE(wil::verify_bool(comPtr));
  52. //wil::verify_bool(noBoolCastClass);
  53. //wil::verify_bool(dword);
  54. //wil::verify_bool(hr);
  55. }
  56. SECTION("verify_hresult")
  57. {
  58. //wil::verify_hresult(smallBool);
  59. //wil::verify_hresult(bigBool);
  60. //wil::verify_hresult(boolCastClass);
  61. //wil::verify_hresult(noBoolCastClass);
  62. //wil::verify_hresult(dword);
  63. //wil::verify_hresult(comPtr);
  64. REQUIRE(wil::verify_hresult(hr) == S_OK);
  65. }
  66. SECTION("verify_BOOL")
  67. {
  68. //wil::verify_BOOL(smallBool);
  69. REQUIRE(wil::verify_BOOL(bigBool));
  70. //wil::verify_BOOL(boolCastClass);
  71. //wil::verify_BOOL(noBoolCastClass);
  72. //wil::verify_BOOL(dword);
  73. //wil::verify_BOOL(comPtr);
  74. //wil::verify_BOOL(hr);
  75. }
  76. }
  77. template <typename T>
  78. static void FlagsMacrosNonStatic(T none, T one, T two, T three, T four)
  79. {
  80. T eval = one | four;
  81. REQUIRE(WI_AreAllFlagsSet(MDEC(eval), MDEC(one | four)));
  82. REQUIRE_FALSE(WI_AreAllFlagsSet(eval, one | three));
  83. REQUIRE_FALSE(WI_AreAllFlagsSet(eval, three | two));
  84. REQUIRE(WI_AreAllFlagsSet(eval, none));
  85. REQUIRE(WI_IsAnyFlagSet(MDEC(eval), MDEC(one)));
  86. REQUIRE(WI_IsAnyFlagSet(eval, one | four | three));
  87. REQUIRE_FALSE(WI_IsAnyFlagSet(eval, two));
  88. REQUIRE(WI_AreAllFlagsClear(MDEC(eval), MDEC(three)));
  89. REQUIRE(WI_AreAllFlagsClear(eval, three | two));
  90. REQUIRE_FALSE(WI_AreAllFlagsClear(eval, one | four));
  91. REQUIRE_FALSE(WI_AreAllFlagsClear(eval, one | three));
  92. REQUIRE(WI_IsAnyFlagClear(MDEC(eval), MDEC(three)));
  93. REQUIRE(WI_IsAnyFlagClear(eval, three | two));
  94. REQUIRE(WI_IsAnyFlagClear(eval, four | three));
  95. REQUIRE_FALSE(WI_IsAnyFlagClear(eval, one));
  96. REQUIRE_FALSE(WI_IsAnyFlagClear(eval, one | four));
  97. REQUIRE_FALSE(WI_IsSingleFlagSet(MDEC(eval)));
  98. REQUIRE(WI_IsSingleFlagSet(eval & one));
  99. REQUIRE(WI_IsSingleFlagSetInMask(MDEC(eval), MDEC(one)));
  100. REQUIRE(WI_IsSingleFlagSetInMask(eval, one | three));
  101. REQUIRE_FALSE(WI_IsSingleFlagSetInMask(eval, three));
  102. REQUIRE_FALSE(WI_IsSingleFlagSetInMask(eval, one | four));
  103. REQUIRE_FALSE(WI_IsClearOrSingleFlagSet(MDEC(eval)));
  104. REQUIRE(WI_IsClearOrSingleFlagSet(eval & one));
  105. REQUIRE(WI_IsClearOrSingleFlagSet(none));
  106. REQUIRE(WI_IsClearOrSingleFlagSetInMask(MDEC(eval), MDEC(one)));
  107. REQUIRE(WI_IsClearOrSingleFlagSetInMask(eval, one | three));
  108. REQUIRE(WI_IsClearOrSingleFlagSetInMask(eval, three));
  109. REQUIRE_FALSE(WI_IsClearOrSingleFlagSetInMask(eval, one | four));
  110. eval = none;
  111. WI_SetAllFlags(MDEC(eval), MDEC(one));
  112. REQUIRE(eval == one);
  113. WI_SetAllFlags(eval, one | two);
  114. REQUIRE(eval == (one | two));
  115. eval = one | two;
  116. WI_ClearAllFlags(MDEC(eval), one);
  117. REQUIRE(eval == two);
  118. WI_ClearAllFlags(eval, two);
  119. REQUIRE(eval == none);
  120. eval = one | two;
  121. WI_UpdateFlagsInMask(MDEC(eval), MDEC(two | three), MDEC(three | four));
  122. REQUIRE(eval == (one | three));
  123. eval = one;
  124. WI_ToggleAllFlags(MDEC(eval), MDEC(one | two));
  125. REQUIRE(eval == two);
  126. }
  127. enum class EClassTest
  128. {
  129. None = 0x0,
  130. One = 0x1,
  131. Two = 0x2,
  132. Three = 0x4,
  133. Four = 0x8,
  134. };
  135. DEFINE_ENUM_FLAG_OPERATORS(EClassTest);
  136. enum ERawTest : unsigned int
  137. {
  138. ER_None = 0x0,
  139. ER_One = 0x1,
  140. ER_Two = 0x2,
  141. ER_Three = 0x4,
  142. ER_Four = 0x8,
  143. };
  144. DEFINE_ENUM_FLAG_OPERATORS(ERawTest);
  145. TEST_CASE("CommonTests::FlagsMacros", "[common]")
  146. {
  147. SECTION("Integral types")
  148. {
  149. FlagsMacrosNonStatic<char>(static_cast<char>(0), static_cast<char>(0x1), static_cast<char>(0x2), static_cast<char>(0x4), static_cast<char>(0x40));
  150. FlagsMacrosNonStatic<unsigned char>(0, 0x1, 0x2, 0x4, 0x80u);
  151. FlagsMacrosNonStatic<short>(0, 0x1, 0x2, 0x4, 0x4000);
  152. FlagsMacrosNonStatic<unsigned short>(0, 0x1, 0x2, 0x4, 0x8000u);
  153. FlagsMacrosNonStatic<long>(0, 0x1, 0x2, 0x4, 0x80000000ul);
  154. FlagsMacrosNonStatic<unsigned long>(0, 0x1, 0x2, 0x4, 0x80000000ul);
  155. FlagsMacrosNonStatic<long long>(0, 0x1, 0x2, 0x4, 0x8000000000000000ull);
  156. FlagsMacrosNonStatic<unsigned long long>(0, 0x1, 0x2, 0x4, 0x8000000000000000ull);
  157. }
  158. SECTION("Raw enum")
  159. {
  160. FlagsMacrosNonStatic<ERawTest>(ER_None, ER_One, ER_Two, ER_Three, ER_Four);
  161. }
  162. SECTION("Enum class")
  163. {
  164. FlagsMacrosNonStatic<EClassTest>(EClassTest::None, EClassTest::One, EClassTest::Two, EClassTest::Three, EClassTest::Four);
  165. EClassTest eclass = EClassTest::One | EClassTest::Two;
  166. REQUIRE(WI_IsFlagSet(MDEC(eclass), EClassTest::One));
  167. REQUIRE(WI_IsFlagSet(eclass, EClassTest::Two));
  168. REQUIRE_FALSE(WI_IsFlagSet(eclass, EClassTest::Three));
  169. REQUIRE(WI_IsFlagClear(MDEC(eclass), EClassTest::Three));
  170. REQUIRE_FALSE(WI_IsFlagClear(eclass, EClassTest::One));
  171. REQUIRE_FALSE(WI_IsSingleFlagSet(MDEC(eclass)));
  172. REQUIRE(WI_IsSingleFlagSet(eclass & EClassTest::One));
  173. eclass = EClassTest::None;
  174. WI_SetFlag(MDEC(eclass), EClassTest::One);
  175. REQUIRE(eclass == EClassTest::One);
  176. eclass = EClassTest::None;
  177. WI_SetFlagIf(eclass, EClassTest::One, false);
  178. REQUIRE(eclass == EClassTest::None);
  179. WI_SetFlagIf(eclass, EClassTest::One, true);
  180. REQUIRE(eclass == EClassTest::One);
  181. eclass = EClassTest::None;
  182. WI_SetFlagIf(eclass, EClassTest::One, false);
  183. REQUIRE(eclass == EClassTest::None);
  184. WI_SetFlagIf(eclass, EClassTest::One, true);
  185. REQUIRE(eclass == EClassTest::One);
  186. eclass = EClassTest::One | EClassTest::Two;
  187. WI_ClearFlag(eclass, EClassTest::Two);
  188. REQUIRE(eclass == EClassTest::One);
  189. eclass = EClassTest::One | EClassTest::Two;
  190. WI_ClearFlagIf(eclass, EClassTest::One, false);
  191. REQUIRE(eclass == (EClassTest::One | EClassTest::Two));
  192. WI_ClearFlagIf(eclass, EClassTest::One, true);
  193. REQUIRE(eclass == EClassTest::Two);
  194. eclass = EClassTest::None;
  195. WI_UpdateFlag(eclass, EClassTest::One, true);
  196. REQUIRE(eclass == EClassTest::One);
  197. WI_UpdateFlag(eclass, EClassTest::One, false);
  198. REQUIRE(eclass == EClassTest::None);
  199. eclass = EClassTest::One;
  200. WI_ToggleFlag(eclass, EClassTest::One);
  201. WI_ToggleFlag(eclass, EClassTest::Two);
  202. REQUIRE(eclass == EClassTest::Two);
  203. }
  204. }