#include #include #include #include "common.h" TEST_CASE("CommonTests::OutParamHelpers", "[common]") { int i = 2; int *pOutTest = &i; int *pNullTest = nullptr; SECTION("Value type") { wil::assign_to_opt_param(pNullTest, 3); wil::assign_to_opt_param(pOutTest, 3); REQUIRE(*pOutTest == 3); } SECTION("Pointer to value type") { int **ppOutTest = &pOutTest; int **ppNullTest = nullptr; wil::assign_null_to_opt_param(ppNullTest); wil::assign_null_to_opt_param(ppOutTest); REQUIRE(*ppOutTest == nullptr); } SECTION("COM out pointer") { Microsoft::WRL::ComPtr spUnk; IUnknown **ppunkNull = nullptr; IUnknown *pUnk = reinterpret_cast(1); IUnknown **ppUnkValid = &pUnk; wil::detach_to_opt_param(ppunkNull, spUnk); wil::detach_to_opt_param(ppUnkValid, spUnk); REQUIRE(*ppUnkValid == nullptr); } } TEST_CASE("CommonTests::TypeValidation", "[common]") { std::unique_ptr boolCastClass; std::vector noBoolCastClass; HRESULT hr = S_OK; BOOL bigBool = true; bool smallBool = true; DWORD dword = 1; Microsoft::WRL::ComPtr comPtr; (void)dword; // NOTE: The commented out verify* calls should give compilation errors SECTION("verify_bool") { REQUIRE(wil::verify_bool(smallBool)); REQUIRE(wil::verify_bool(bigBool)); REQUIRE_FALSE(wil::verify_bool(boolCastClass)); REQUIRE_FALSE(wil::verify_bool(comPtr)); //wil::verify_bool(noBoolCastClass); //wil::verify_bool(dword); //wil::verify_bool(hr); } SECTION("verify_hresult") { //wil::verify_hresult(smallBool); //wil::verify_hresult(bigBool); //wil::verify_hresult(boolCastClass); //wil::verify_hresult(noBoolCastClass); //wil::verify_hresult(dword); //wil::verify_hresult(comPtr); REQUIRE(wil::verify_hresult(hr) == S_OK); } SECTION("verify_BOOL") { //wil::verify_BOOL(smallBool); REQUIRE(wil::verify_BOOL(bigBool)); //wil::verify_BOOL(boolCastClass); //wil::verify_BOOL(noBoolCastClass); //wil::verify_BOOL(dword); //wil::verify_BOOL(comPtr); //wil::verify_BOOL(hr); } } template static void FlagsMacrosNonStatic(T none, T one, T two, T three, T four) { T eval = one | four; REQUIRE(WI_AreAllFlagsSet(MDEC(eval), MDEC(one | four))); REQUIRE_FALSE(WI_AreAllFlagsSet(eval, one | three)); REQUIRE_FALSE(WI_AreAllFlagsSet(eval, three | two)); REQUIRE(WI_AreAllFlagsSet(eval, none)); REQUIRE(WI_IsAnyFlagSet(MDEC(eval), MDEC(one))); REQUIRE(WI_IsAnyFlagSet(eval, one | four | three)); REQUIRE_FALSE(WI_IsAnyFlagSet(eval, two)); REQUIRE(WI_AreAllFlagsClear(MDEC(eval), MDEC(three))); REQUIRE(WI_AreAllFlagsClear(eval, three | two)); REQUIRE_FALSE(WI_AreAllFlagsClear(eval, one | four)); REQUIRE_FALSE(WI_AreAllFlagsClear(eval, one | three)); REQUIRE(WI_IsAnyFlagClear(MDEC(eval), MDEC(three))); REQUIRE(WI_IsAnyFlagClear(eval, three | two)); REQUIRE(WI_IsAnyFlagClear(eval, four | three)); REQUIRE_FALSE(WI_IsAnyFlagClear(eval, one)); REQUIRE_FALSE(WI_IsAnyFlagClear(eval, one | four)); REQUIRE_FALSE(WI_IsSingleFlagSet(MDEC(eval))); REQUIRE(WI_IsSingleFlagSet(eval & one)); REQUIRE(WI_IsSingleFlagSetInMask(MDEC(eval), MDEC(one))); REQUIRE(WI_IsSingleFlagSetInMask(eval, one | three)); REQUIRE_FALSE(WI_IsSingleFlagSetInMask(eval, three)); REQUIRE_FALSE(WI_IsSingleFlagSetInMask(eval, one | four)); REQUIRE_FALSE(WI_IsClearOrSingleFlagSet(MDEC(eval))); REQUIRE(WI_IsClearOrSingleFlagSet(eval & one)); REQUIRE(WI_IsClearOrSingleFlagSet(none)); REQUIRE(WI_IsClearOrSingleFlagSetInMask(MDEC(eval), MDEC(one))); REQUIRE(WI_IsClearOrSingleFlagSetInMask(eval, one | three)); REQUIRE(WI_IsClearOrSingleFlagSetInMask(eval, three)); REQUIRE_FALSE(WI_IsClearOrSingleFlagSetInMask(eval, one | four)); eval = none; WI_SetAllFlags(MDEC(eval), MDEC(one)); REQUIRE(eval == one); WI_SetAllFlags(eval, one | two); REQUIRE(eval == (one | two)); eval = one | two; WI_ClearAllFlags(MDEC(eval), one); REQUIRE(eval == two); WI_ClearAllFlags(eval, two); REQUIRE(eval == none); eval = one | two; WI_UpdateFlagsInMask(MDEC(eval), MDEC(two | three), MDEC(three | four)); REQUIRE(eval == (one | three)); eval = one; WI_ToggleAllFlags(MDEC(eval), MDEC(one | two)); REQUIRE(eval == two); } enum class EClassTest { None = 0x0, One = 0x1, Two = 0x2, Three = 0x4, Four = 0x8, }; DEFINE_ENUM_FLAG_OPERATORS(EClassTest); enum ERawTest { ER_None = 0x0, ER_One = 0x1, ER_Two = 0x2, ER_Three = 0x4, ER_Four = 0x8, }; DEFINE_ENUM_FLAG_OPERATORS(ERawTest); TEST_CASE("CommonTests::FlagsMacros", "[common]") { SECTION("Integral types") { FlagsMacrosNonStatic(static_cast(0), static_cast(0x1), static_cast(0x2), static_cast(0x4), static_cast(0x40)); FlagsMacrosNonStatic(0, 0x1, 0x2, 0x4, 0x80u); FlagsMacrosNonStatic(0, 0x1, 0x2, 0x4, 0x4000); FlagsMacrosNonStatic(0, 0x1, 0x2, 0x4, 0x8000u); FlagsMacrosNonStatic(0, 0x1, 0x2, 0x4, 0x80000000ul); FlagsMacrosNonStatic(0, 0x1, 0x2, 0x4, 0x80000000ul); FlagsMacrosNonStatic(0, 0x1, 0x2, 0x4, 0x8000000000000000ull); FlagsMacrosNonStatic(0, 0x1, 0x2, 0x4, 0x8000000000000000ull); } SECTION("Raw enum") { FlagsMacrosNonStatic(ER_None, ER_One, ER_Two, ER_Three, ER_Four); } SECTION("Enum class") { FlagsMacrosNonStatic(EClassTest::None, EClassTest::One, EClassTest::Two, EClassTest::Three, EClassTest::Four); EClassTest eclass = EClassTest::One | EClassTest::Two; REQUIRE(WI_IsFlagSet(MDEC(eclass), EClassTest::One)); REQUIRE(WI_IsFlagSet(eclass, EClassTest::Two)); REQUIRE_FALSE(WI_IsFlagSet(eclass, EClassTest::Three)); REQUIRE(WI_IsFlagClear(MDEC(eclass), EClassTest::Three)); REQUIRE_FALSE(WI_IsFlagClear(eclass, EClassTest::One)); REQUIRE_FALSE(WI_IsSingleFlagSet(MDEC(eclass))); REQUIRE(WI_IsSingleFlagSet(eclass & EClassTest::One)); eclass = EClassTest::None; WI_SetFlag(MDEC(eclass), EClassTest::One); REQUIRE(eclass == EClassTest::One); eclass = EClassTest::None; WI_SetFlagIf(eclass, EClassTest::One, false); REQUIRE(eclass == EClassTest::None); WI_SetFlagIf(eclass, EClassTest::One, true); REQUIRE(eclass == EClassTest::One); eclass = EClassTest::None; WI_SetFlagIf(eclass, EClassTest::One, false); REQUIRE(eclass == EClassTest::None); WI_SetFlagIf(eclass, EClassTest::One, true); REQUIRE(eclass == EClassTest::One); eclass = EClassTest::One | EClassTest::Two; WI_ClearFlag(eclass, EClassTest::Two); REQUIRE(eclass == EClassTest::One); eclass = EClassTest::One | EClassTest::Two; WI_ClearFlagIf(eclass, EClassTest::One, false); REQUIRE(eclass == (EClassTest::One | EClassTest::Two)); WI_ClearFlagIf(eclass, EClassTest::One, true); REQUIRE(eclass == EClassTest::Two); eclass = EClassTest::None; WI_UpdateFlag(eclass, EClassTest::One, true); REQUIRE(eclass == EClassTest::One); WI_UpdateFlag(eclass, EClassTest::One, false); REQUIRE(eclass == EClassTest::None); eclass = EClassTest::One; WI_ToggleFlag(eclass, EClassTest::One); WI_ToggleFlag(eclass, EClassTest::Two); REQUIRE(eclass == EClassTest::Two); } }