Commit d0d0d62a authored by Robert Liao's avatar Robert Liao Committed by Commit Bot

Break Up ScopedVariant Unit Tests

BUG=1034666

Change-Id: I18336ab0f3d36adbe2b47f0784baed6e4ac9f2f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2072577
Commit-Queue: Robert Liao <robliao@chromium.org>
Commit-Queue: Will Harris <wfh@chromium.org>
Auto-Submit: Robert Liao <robliao@chromium.org>
Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#744316}
parent 4cd5f3ab
...@@ -16,13 +16,16 @@ namespace win { ...@@ -16,13 +16,16 @@ namespace win {
namespace { namespace {
static const wchar_t kTestString1[] = L"Used to create BSTRs"; constexpr wchar_t kTestString[] = L"Test string for BSTRs.";
static const wchar_t kTestString2[] = L"Also used to create BSTRs";
void GiveMeAVariant(VARIANT* ret) { void InitializeVariantWithBstr(VARIANT* var) {
EXPECT_TRUE(ret != nullptr); if (!var) {
ret->vt = VT_BSTR; ADD_FAILURE() << "|var| cannot be null.";
V_BSTR(ret) = ::SysAllocString(kTestString1); return;
}
var->vt = VT_BSTR;
V_BSTR(var) = ::SysAllocString(kTestString);
} }
// An unimplemented IDispatch subclass. // An unimplemented IDispatch subclass.
...@@ -68,184 +71,287 @@ void ExpectRefCount(ULONG expected_refcount, IUnknown* object) { ...@@ -68,184 +71,287 @@ void ExpectRefCount(ULONG expected_refcount, IUnknown* object) {
EXPECT_EQ(expected_refcount, object->Release()); EXPECT_EQ(expected_refcount, object->Release());
} }
void ExpectVariantType(VARENUM var_type, const ScopedVariant& var) {
EXPECT_EQ(var_type, var.type());
EXPECT_EQ(var_type, V_VT(var.ptr()));
}
} // namespace } // namespace
TEST(ScopedVariantTest, ScopedVariant) { TEST(ScopedVariantTest, Empty) {
ScopedVariant var; ScopedVariant var;
EXPECT_TRUE(var.type() == VT_EMPTY); ExpectVariantType(VT_EMPTY, var);
// V_BSTR(var.ptr()) = NULL; <- NOTE: Assignment like that is not supported. }
ScopedVariant var_bstr(L"VT_BSTR"); TEST(ScopedVariantTest, ConstructBstr) {
EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr())); ScopedVariant var(kTestString);
EXPECT_TRUE(V_BSTR(var_bstr.ptr()) != ExpectVariantType(VT_BSTR, var);
nullptr); // can't use EXPECT_NE for BSTR EXPECT_STREQ(kTestString, V_BSTR(var.ptr()));
var_bstr.Reset(); }
EXPECT_NE(VT_BSTR, V_VT(var_bstr.ptr()));
var_bstr.Set(kTestString2); TEST(ScopedVariantTest, SetBstr) {
EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr())); ScopedVariant var;
var.Set(kTestString);
VARIANT tmp = var_bstr.Release(); ExpectVariantType(VT_BSTR, var);
EXPECT_EQ(VT_EMPTY, V_VT(var_bstr.ptr())); EXPECT_STREQ(kTestString, V_BSTR(var.ptr()));
EXPECT_EQ(VT_BSTR, V_VT(&tmp)); }
EXPECT_EQ(0, lstrcmp(V_BSTR(&tmp), kTestString2));
TEST(ScopedVariantTest, ReleaseBstr) {
var.Reset(tmp); ScopedVariant var;
EXPECT_EQ(VT_BSTR, V_VT(var.ptr())); var.Set(kTestString);
EXPECT_EQ(0, lstrcmpW(V_BSTR(var.ptr()), kTestString2)); VARIANT released_variant = var.Release();
ExpectVariantType(VT_EMPTY, var);
var_bstr.Swap(var); EXPECT_EQ(VT_BSTR, V_VT(&released_variant));
EXPECT_EQ(VT_EMPTY, V_VT(var.ptr())); EXPECT_STREQ(kTestString, V_BSTR(&released_variant));
EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr())); ::VariantClear(&released_variant);
EXPECT_EQ(0, lstrcmpW(V_BSTR(var_bstr.ptr()), kTestString2)); }
var_bstr.Reset();
TEST(ScopedVariantTest, ResetToEmptyBstr) {
// Test the Compare and Copy routines. ScopedVariant var(kTestString);
GiveMeAVariant(var_bstr.Receive()); ExpectVariantType(VT_BSTR, var);
ScopedVariant var_bstr2(V_BSTR(var_bstr.ptr())); var.Reset();
EXPECT_EQ(0, var_bstr.Compare(var_bstr2)); ExpectVariantType(VT_EMPTY, var);
var_bstr2.Reset(); }
EXPECT_NE(0, var_bstr.Compare(var_bstr2));
var_bstr2.Reset(var_bstr.Copy()); TEST(ScopedVariantTest, TakeOwnershipBstr) {
EXPECT_EQ(0, var_bstr.Compare(var_bstr2)); VARIANT bstr_variant;
var_bstr2.Reset(); bstr_variant.vt = VT_BSTR;
var_bstr2.Set(V_BSTR(var_bstr.ptr())); bstr_variant.bstrVal = ::SysAllocString(kTestString);
EXPECT_EQ(0, var_bstr.Compare(var_bstr2));
ScopedVariant var;
var.Reset(bstr_variant);
ExpectVariantType(VT_BSTR, var);
EXPECT_EQ(bstr_variant.bstrVal, V_BSTR(var.ptr()));
}
TEST(ScopedVariantTest, SwapBstr) {
ScopedVariant from(kTestString);
ScopedVariant to;
to.Swap(from);
ExpectVariantType(VT_EMPTY, from);
ExpectVariantType(VT_BSTR, to);
EXPECT_STREQ(kTestString, V_BSTR(to.ptr()));
}
TEST(ScopedVariantTest, CompareBstr) {
ScopedVariant var_bstr1;
InitializeVariantWithBstr(var_bstr1.Receive());
ScopedVariant var_bstr2(V_BSTR(var_bstr1.ptr()));
EXPECT_EQ(0, var_bstr1.Compare(var_bstr2));
var_bstr2.Reset(); var_bstr2.Reset();
var_bstr.Reset(); EXPECT_NE(0, var_bstr1.Compare(var_bstr2));
}
// Test for the SetDate setter. TEST(ScopedVariantTest, ReceiveAndCopyBstr) {
ScopedVariant var_bstr1;
InitializeVariantWithBstr(var_bstr1.Receive());
ScopedVariant var_bstr2;
var_bstr2.Reset(var_bstr1.Copy());
EXPECT_EQ(0, var_bstr1.Compare(var_bstr2));
}
TEST(ScopedVariantTest, SetBstrFromBstrVariant) {
ScopedVariant var_bstr1;
InitializeVariantWithBstr(var_bstr1.Receive());
ScopedVariant var_bstr2;
var_bstr2.Set(V_BSTR(var_bstr1.ptr()));
EXPECT_EQ(0, var_bstr1.Compare(var_bstr2));
}
TEST(ScopedVariantTest, SetDate) {
ScopedVariant var;
SYSTEMTIME sys_time; SYSTEMTIME sys_time;
::GetSystemTime(&sys_time); ::GetSystemTime(&sys_time);
DATE date; DATE date;
::SystemTimeToVariantTime(&sys_time, &date); ::SystemTimeToVariantTime(&sys_time, &date);
var.Reset();
var.SetDate(date); var.SetDate(date);
EXPECT_EQ(VT_DATE, var.type()); ExpectVariantType(VT_DATE, var);
EXPECT_EQ(date, V_DATE(var.ptr())); EXPECT_EQ(date, V_DATE(var.ptr()));
}
// Simple setter tests. These do not require resetting the variant TEST(ScopedVariantTest, SetSigned1Byte) {
// after each test since the variant type is not "leakable" (i.e. doesn't ScopedVariant var;
// need to be freed explicitly).
// We need static cast here since char defaults to int (!?).
var.Set(static_cast<int8_t>('v')); var.Set(static_cast<int8_t>('v'));
EXPECT_EQ(VT_I1, var.type()); ExpectVariantType(VT_I1, var);
EXPECT_EQ('v', V_I1(var.ptr())); EXPECT_EQ('v', V_I1(var.ptr()));
}
TEST(ScopedVariantTest, SetSigned2Byte) {
ScopedVariant var;
var.Set(static_cast<short>(123)); var.Set(static_cast<short>(123));
EXPECT_EQ(VT_I2, var.type()); ExpectVariantType(VT_I2, var);
EXPECT_EQ(123, V_I2(var.ptr())); EXPECT_EQ(123, V_I2(var.ptr()));
}
var.Set(static_cast<int32_t>(123)); TEST(ScopedVariantTest, SetSigned4Byte) {
EXPECT_EQ(VT_I4, var.type()); ScopedVariant var;
var.Set(123);
ExpectVariantType(VT_I4, var);
EXPECT_EQ(123, V_I4(var.ptr())); EXPECT_EQ(123, V_I4(var.ptr()));
}
TEST(ScopedVariantTest, SetSigned8Byte) {
ScopedVariant var;
var.Set(static_cast<int64_t>(123)); var.Set(static_cast<int64_t>(123));
EXPECT_EQ(VT_I8, var.type()); ExpectVariantType(VT_I8, var);
EXPECT_EQ(123, V_I8(var.ptr())); EXPECT_EQ(123, V_I8(var.ptr()));
}
TEST(ScopedVariantTest, SetUnsigned1Byte) {
ScopedVariant var;
var.Set(static_cast<uint8_t>(123)); var.Set(static_cast<uint8_t>(123));
EXPECT_EQ(VT_UI1, var.type()); ExpectVariantType(VT_UI1, var);
EXPECT_EQ(123u, V_UI1(var.ptr())); EXPECT_EQ(123u, V_UI1(var.ptr()));
}
TEST(ScopedVariantTest, SetUnsigned2Byte) {
ScopedVariant var;
var.Set(static_cast<unsigned short>(123)); var.Set(static_cast<unsigned short>(123));
EXPECT_EQ(VT_UI2, var.type()); ExpectVariantType(VT_UI2, var);
EXPECT_EQ(123u, V_UI2(var.ptr())); EXPECT_EQ(123u, V_UI2(var.ptr()));
}
TEST(ScopedVariantTest, SetUnsigned4Byte) {
ScopedVariant var;
var.Set(static_cast<uint32_t>(123)); var.Set(static_cast<uint32_t>(123));
EXPECT_EQ(VT_UI4, var.type()); ExpectVariantType(VT_UI4, var);
EXPECT_EQ(123u, V_UI4(var.ptr())); EXPECT_EQ(123u, V_UI4(var.ptr()));
}
TEST(ScopedVariantTest, SetUnsigned8Byte) {
ScopedVariant var;
var.Set(static_cast<uint64_t>(123)); var.Set(static_cast<uint64_t>(123));
EXPECT_EQ(VT_UI8, var.type()); ExpectVariantType(VT_UI8, var);
EXPECT_EQ(123u, V_UI8(var.ptr())); EXPECT_EQ(123u, V_UI8(var.ptr()));
}
TEST(ScopedVariantTest, SetReal4Byte) {
ScopedVariant var;
var.Set(123.123f); var.Set(123.123f);
EXPECT_EQ(VT_R4, var.type()); ExpectVariantType(VT_R4, var);
EXPECT_EQ(123.123f, V_R4(var.ptr())); EXPECT_EQ(123.123f, V_R4(var.ptr()));
}
TEST(ScopedVariantTest, SetReal8Byte) {
ScopedVariant var;
var.Set(static_cast<double>(123.123)); var.Set(static_cast<double>(123.123));
EXPECT_EQ(VT_R8, var.type()); ExpectVariantType(VT_R8, var);
EXPECT_EQ(123.123, V_R8(var.ptr())); EXPECT_EQ(123.123, V_R8(var.ptr()));
}
TEST(ScopedVariantTest, SetBooleanTrue) {
ScopedVariant var;
var.Set(true); var.Set(true);
EXPECT_EQ(VT_BOOL, var.type()); ExpectVariantType(VT_BOOL, var);
EXPECT_EQ(VARIANT_TRUE, V_BOOL(var.ptr())); EXPECT_EQ(VARIANT_TRUE, V_BOOL(var.ptr()));
}
TEST(ScopedVariantTest, SetBooleanFalse) {
ScopedVariant var;
var.Set(false); var.Set(false);
EXPECT_EQ(VT_BOOL, var.type()); ExpectVariantType(VT_BOOL, var);
EXPECT_EQ(VARIANT_FALSE, V_BOOL(var.ptr())); EXPECT_EQ(VARIANT_FALSE, V_BOOL(var.ptr()));
}
// Com interface tests TEST(ScopedVariantTest, SetComIDispatch) {
ScopedVariant var;
var.Set(static_cast<IDispatch*>(nullptr));
EXPECT_EQ(VT_DISPATCH, var.type());
EXPECT_EQ(nullptr, V_DISPATCH(var.ptr()));
var.Reset();
var.Set(static_cast<IUnknown*>(nullptr));
EXPECT_EQ(VT_UNKNOWN, var.type());
EXPECT_EQ(nullptr, V_UNKNOWN(var.ptr()));
var.Reset();
Microsoft::WRL::ComPtr<IDispatch> dispatch_stub = Microsoft::WRL::ComPtr<IDispatch> dispatch_stub =
Microsoft::WRL::Make<DispatchStub>(); Microsoft::WRL::Make<DispatchStub>();
ExpectRefCount(1U, dispatch_stub.Get()); ExpectRefCount(1U, dispatch_stub.Get());
var.Set(dispatch_stub.Get()); var.Set(dispatch_stub.Get());
EXPECT_EQ(VT_DISPATCH, var.type()); ExpectVariantType(VT_DISPATCH, var);
EXPECT_EQ(dispatch_stub.Get(), V_DISPATCH(var.ptr())); EXPECT_EQ(dispatch_stub.Get(), V_DISPATCH(var.ptr()));
ExpectRefCount(2U, dispatch_stub.Get()); ExpectRefCount(2U, dispatch_stub.Get());
var.Reset(); var.Reset();
ExpectRefCount(1U, dispatch_stub.Get()); ExpectRefCount(1U, dispatch_stub.Get());
}
TEST(ScopedVariantTest, SetComNullIDispatch) {
ScopedVariant var;
var.Set(static_cast<IDispatch*>(nullptr));
ExpectVariantType(VT_DISPATCH, var);
EXPECT_EQ(nullptr, V_DISPATCH(var.ptr()));
}
// A separate instance to handle IUnknown makes refcount checking easier. TEST(ScopedVariantTest, SetComIUnknown) {
ScopedVariant var;
Microsoft::WRL::ComPtr<IUnknown> unknown_stub = Microsoft::WRL::ComPtr<IUnknown> unknown_stub =
Microsoft::WRL::Make<DispatchStub>(); Microsoft::WRL::Make<DispatchStub>();
ExpectRefCount(1U, unknown_stub.Get()); ExpectRefCount(1U, unknown_stub.Get());
var.Set(unknown_stub.Get()); var.Set(unknown_stub.Get());
EXPECT_EQ(VT_UNKNOWN, var.type()); ExpectVariantType(VT_UNKNOWN, var);
EXPECT_EQ(unknown_stub.Get(), V_UNKNOWN(var.ptr())); EXPECT_EQ(unknown_stub.Get(), V_UNKNOWN(var.ptr()));
ExpectRefCount(2U, unknown_stub.Get()); ExpectRefCount(2U, unknown_stub.Get());
var.Reset(); var.Reset();
ExpectRefCount(1U, unknown_stub.Get()); ExpectRefCount(1U, unknown_stub.Get());
}
TEST(ScopedVariantTest, SetComNullIUnknown) {
ScopedVariant var;
var.Set(static_cast<IUnknown*>(nullptr));
ExpectVariantType(VT_UNKNOWN, var);
EXPECT_EQ(nullptr, V_UNKNOWN(var.ptr()));
}
TEST(ScopedVariant, ScopedComIDispatchConstructor) {
Microsoft::WRL::ComPtr<IDispatch> dispatch_stub =
Microsoft::WRL::Make<DispatchStub>();
{ {
ScopedVariant disp_var(dispatch_stub.Get()); ScopedVariant var(dispatch_stub.Get());
EXPECT_EQ(VT_DISPATCH, disp_var.type()); ExpectVariantType(VT_DISPATCH, var);
EXPECT_EQ(dispatch_stub.Get(), V_DISPATCH(disp_var.ptr())); EXPECT_EQ(dispatch_stub.Get(), V_DISPATCH(var.ptr()));
ExpectRefCount(2U, dispatch_stub.Get()); ExpectRefCount(2U, dispatch_stub.Get());
} }
ExpectRefCount(1U, dispatch_stub.Get()); ExpectRefCount(1U, dispatch_stub.Get());
}
TEST(ScopedVariant, ScopedComIDispatchMove) {
Microsoft::WRL::ComPtr<IDispatch> dispatch_stub =
Microsoft::WRL::Make<DispatchStub>();
{ {
ScopedVariant ref1(dispatch_stub.Get()); ScopedVariant var1(dispatch_stub.Get());
ExpectRefCount(2U, dispatch_stub.Get()); ExpectRefCount(2U, dispatch_stub.Get());
ScopedVariant ref2(std::move(ref1)); ScopedVariant var2(std::move(var1));
ExpectRefCount(2U, dispatch_stub.Get()); ExpectRefCount(2U, dispatch_stub.Get());
ScopedVariant ref3; ScopedVariant var3;
ref3 = std::move(ref2); var3 = std::move(var2);
ExpectRefCount(2U, dispatch_stub.Get()); ExpectRefCount(2U, dispatch_stub.Get());
} }
ExpectRefCount(1U, dispatch_stub.Get()); ExpectRefCount(1U, dispatch_stub.Get());
}
TEST(ScopedVariant, ScopedComIDispatchCopy) {
Microsoft::WRL::ComPtr<IDispatch> dispatch_stub =
Microsoft::WRL::Make<DispatchStub>();
{ {
ScopedVariant ref1(dispatch_stub.Get()); ScopedVariant var1(dispatch_stub.Get());
ExpectRefCount(2U, dispatch_stub.Get()); ExpectRefCount(2U, dispatch_stub.Get());
ScopedVariant ref2(static_cast<const VARIANT&>(ref1)); ScopedVariant var2(static_cast<const VARIANT&>(var1));
ExpectRefCount(3U, dispatch_stub.Get()); ExpectRefCount(3U, dispatch_stub.Get());
ScopedVariant ref3; ScopedVariant var3;
ref3 = static_cast<const VARIANT&>(ref2); var3 = static_cast<const VARIANT&>(var2);
ExpectRefCount(4U, dispatch_stub.Get()); ExpectRefCount(4U, dispatch_stub.Get());
} }
ExpectRefCount(1U, dispatch_stub.Get()); ExpectRefCount(1U, dispatch_stub.Get());
}
TEST(ScopedVariant, ScopedComIUnknownConstructor) {
Microsoft::WRL::ComPtr<IUnknown> unknown_stub =
Microsoft::WRL::Make<DispatchStub>();
{ {
ScopedVariant unk_var(unknown_stub.Get()); ScopedVariant unk_var(unknown_stub.Get());
EXPECT_EQ(VT_UNKNOWN, unk_var.type()); ExpectVariantType(VT_UNKNOWN, unk_var);
EXPECT_EQ(unknown_stub.Get(), V_UNKNOWN(unk_var.ptr())); EXPECT_EQ(unknown_stub.Get(), V_UNKNOWN(unk_var.ptr()));
ExpectRefCount(2U, unknown_stub.Get()); ExpectRefCount(2U, unknown_stub.Get());
} }
ExpectRefCount(1U, unknown_stub.Get()); ExpectRefCount(1U, unknown_stub.Get());
}
TEST(ScopedVariant, ScopedComIUnknownWithRawVariant) {
ScopedVariant var;
Microsoft::WRL::ComPtr<IUnknown> unknown_stub =
Microsoft::WRL::Make<DispatchStub>();
VARIANT raw; VARIANT raw;
raw.vt = VT_UNKNOWN; raw.vt = VT_UNKNOWN;
raw.punkVal = unknown_stub.Get(); raw.punkVal = unknown_stub.Get();
...@@ -254,25 +360,25 @@ TEST(ScopedVariantTest, ScopedVariant) { ...@@ -254,25 +360,25 @@ TEST(ScopedVariantTest, ScopedVariant) {
ExpectRefCount(2U, unknown_stub.Get()); ExpectRefCount(2U, unknown_stub.Get());
var.Reset(); var.Reset();
ExpectRefCount(1U, unknown_stub.Get()); ExpectRefCount(1U, unknown_stub.Get());
}
{ TEST(ScopedVariant, SetSafeArray) {
ScopedVariant number(123);
EXPECT_EQ(VT_I4, number.type());
EXPECT_EQ(123, V_I4(number.ptr()));
}
// SAFEARRAY tests
var.Set(static_cast<SAFEARRAY*>(nullptr));
EXPECT_EQ(VT_EMPTY, var.type());
SAFEARRAY* sa = ::SafeArrayCreateVector(VT_UI1, 0, 100); SAFEARRAY* sa = ::SafeArrayCreateVector(VT_UI1, 0, 100);
ASSERT_TRUE(sa != nullptr); ASSERT_TRUE(sa);
ScopedVariant var;
var.Set(sa); var.Set(sa);
EXPECT_TRUE(ScopedVariant::IsLeakableVarType(var.type())); EXPECT_TRUE(ScopedVariant::IsLeakableVarType(var.type()));
EXPECT_EQ(VT_ARRAY | VT_UI1, var.type()); ExpectVariantType(static_cast<VARENUM>(VT_ARRAY | VT_UI1), var);
EXPECT_EQ(sa, V_ARRAY(var.ptr())); EXPECT_EQ(sa, V_ARRAY(var.ptr()));
// The array is destroyed in the destructor of var. // The array is destroyed in the destructor of var.
sa = nullptr;
}
TEST(ScopedVariant, SetNullSafeArray) {
ScopedVariant var;
var.Set(static_cast<SAFEARRAY*>(nullptr));
ExpectVariantType(VT_EMPTY, var);
} }
} // namespace win } // namespace win
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment