scoped_variant_unittest.cc 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stdint.h>
  5. #include <wrl/client.h>
  6. #include <wrl/implements.h>
  7. #include <utility>
  8. #include "base/win/dispatch_stub.h"
  9. #include "base/win/scoped_variant.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. using base::win::test::DispatchStub;
  12. namespace base {
  13. namespace win {
  14. namespace {
  15. constexpr wchar_t kTestString[] = L"Test string for BSTRs.";
  16. void InitializeVariantWithBstr(VARIANT* var) {
  17. if (!var) {
  18. ADD_FAILURE() << "|var| cannot be null.";
  19. return;
  20. }
  21. var->vt = VT_BSTR;
  22. V_BSTR(var) = ::SysAllocString(kTestString);
  23. }
  24. void ExpectRefCount(ULONG expected_refcount, IUnknown* object) {
  25. // In general, code should not check the values of AddRef() and Release().
  26. // However, tests need to validate that ScopedVariant safely owns a COM object
  27. // so they are checked for this unit test.
  28. EXPECT_EQ(expected_refcount + 1, object->AddRef());
  29. EXPECT_EQ(expected_refcount, object->Release());
  30. }
  31. void ExpectVariantType(VARENUM var_type, const ScopedVariant& var) {
  32. EXPECT_EQ(var_type, var.type());
  33. EXPECT_EQ(var_type, V_VT(var.ptr()));
  34. }
  35. } // namespace
  36. TEST(ScopedVariantTest, Empty) {
  37. ScopedVariant var;
  38. ExpectVariantType(VT_EMPTY, var);
  39. }
  40. TEST(ScopedVariantTest, ConstructBstr) {
  41. ScopedVariant var(kTestString);
  42. ExpectVariantType(VT_BSTR, var);
  43. EXPECT_STREQ(kTestString, V_BSTR(var.ptr()));
  44. }
  45. TEST(ScopedVariantTest, SetBstr) {
  46. ScopedVariant var;
  47. var.Set(kTestString);
  48. ExpectVariantType(VT_BSTR, var);
  49. EXPECT_STREQ(kTestString, V_BSTR(var.ptr()));
  50. }
  51. TEST(ScopedVariantTest, ReleaseBstr) {
  52. ScopedVariant var;
  53. var.Set(kTestString);
  54. VARIANT released_variant = var.Release();
  55. ExpectVariantType(VT_EMPTY, var);
  56. EXPECT_EQ(VT_BSTR, V_VT(&released_variant));
  57. EXPECT_STREQ(kTestString, V_BSTR(&released_variant));
  58. ::VariantClear(&released_variant);
  59. }
  60. TEST(ScopedVariantTest, ResetToEmptyBstr) {
  61. ScopedVariant var(kTestString);
  62. ExpectVariantType(VT_BSTR, var);
  63. var.Reset();
  64. ExpectVariantType(VT_EMPTY, var);
  65. }
  66. TEST(ScopedVariantTest, TakeOwnershipBstr) {
  67. VARIANT bstr_variant;
  68. bstr_variant.vt = VT_BSTR;
  69. bstr_variant.bstrVal = ::SysAllocString(kTestString);
  70. ScopedVariant var;
  71. var.Reset(bstr_variant);
  72. ExpectVariantType(VT_BSTR, var);
  73. EXPECT_EQ(bstr_variant.bstrVal, V_BSTR(var.ptr()));
  74. }
  75. TEST(ScopedVariantTest, SwapBstr) {
  76. ScopedVariant from(kTestString);
  77. ScopedVariant to;
  78. to.Swap(from);
  79. ExpectVariantType(VT_EMPTY, from);
  80. ExpectVariantType(VT_BSTR, to);
  81. EXPECT_STREQ(kTestString, V_BSTR(to.ptr()));
  82. }
  83. TEST(ScopedVariantTest, CompareBstr) {
  84. ScopedVariant var_bstr1;
  85. InitializeVariantWithBstr(var_bstr1.Receive());
  86. ScopedVariant var_bstr2(V_BSTR(var_bstr1.ptr()));
  87. EXPECT_EQ(0, var_bstr1.Compare(var_bstr2));
  88. var_bstr2.Reset();
  89. EXPECT_NE(0, var_bstr1.Compare(var_bstr2));
  90. }
  91. TEST(ScopedVariantTest, ReceiveAndCopyBstr) {
  92. ScopedVariant var_bstr1;
  93. InitializeVariantWithBstr(var_bstr1.Receive());
  94. ScopedVariant var_bstr2;
  95. var_bstr2.Reset(var_bstr1.Copy());
  96. EXPECT_EQ(0, var_bstr1.Compare(var_bstr2));
  97. }
  98. TEST(ScopedVariantTest, SetBstrFromBstrVariant) {
  99. ScopedVariant var_bstr1;
  100. InitializeVariantWithBstr(var_bstr1.Receive());
  101. ScopedVariant var_bstr2;
  102. var_bstr2.Set(V_BSTR(var_bstr1.ptr()));
  103. EXPECT_EQ(0, var_bstr1.Compare(var_bstr2));
  104. }
  105. TEST(ScopedVariantTest, SetDate) {
  106. ScopedVariant var;
  107. SYSTEMTIME sys_time;
  108. ::GetSystemTime(&sys_time);
  109. DATE date;
  110. ::SystemTimeToVariantTime(&sys_time, &date);
  111. var.SetDate(date);
  112. ExpectVariantType(VT_DATE, var);
  113. EXPECT_EQ(date, V_DATE(var.ptr()));
  114. }
  115. TEST(ScopedVariantTest, SetSigned1Byte) {
  116. ScopedVariant var;
  117. var.Set(static_cast<int8_t>('v'));
  118. ExpectVariantType(VT_I1, var);
  119. EXPECT_EQ('v', V_I1(var.ptr()));
  120. }
  121. TEST(ScopedVariantTest, SetSigned2Byte) {
  122. ScopedVariant var;
  123. var.Set(static_cast<int16_t>(123));
  124. ExpectVariantType(VT_I2, var);
  125. EXPECT_EQ(123, V_I2(var.ptr()));
  126. }
  127. TEST(ScopedVariantTest, SetSigned4Byte) {
  128. ScopedVariant var;
  129. var.Set(123);
  130. ExpectVariantType(VT_I4, var);
  131. EXPECT_EQ(123, V_I4(var.ptr()));
  132. }
  133. TEST(ScopedVariantTest, SetSigned8Byte) {
  134. ScopedVariant var;
  135. var.Set(static_cast<int64_t>(123));
  136. ExpectVariantType(VT_I8, var);
  137. EXPECT_EQ(123, V_I8(var.ptr()));
  138. }
  139. TEST(ScopedVariantTest, SetUnsigned1Byte) {
  140. ScopedVariant var;
  141. var.Set(static_cast<uint8_t>(123));
  142. ExpectVariantType(VT_UI1, var);
  143. EXPECT_EQ(123u, V_UI1(var.ptr()));
  144. }
  145. TEST(ScopedVariantTest, SetUnsigned2Byte) {
  146. ScopedVariant var;
  147. var.Set(static_cast<uint16_t>(123));
  148. ExpectVariantType(VT_UI2, var);
  149. EXPECT_EQ(123u, V_UI2(var.ptr()));
  150. }
  151. TEST(ScopedVariantTest, SetUnsigned4Byte) {
  152. ScopedVariant var;
  153. var.Set(static_cast<uint32_t>(123));
  154. ExpectVariantType(VT_UI4, var);
  155. EXPECT_EQ(123u, V_UI4(var.ptr()));
  156. }
  157. TEST(ScopedVariantTest, SetUnsigned8Byte) {
  158. ScopedVariant var;
  159. var.Set(static_cast<uint64_t>(123));
  160. ExpectVariantType(VT_UI8, var);
  161. EXPECT_EQ(123u, V_UI8(var.ptr()));
  162. }
  163. TEST(ScopedVariantTest, SetReal4Byte) {
  164. ScopedVariant var;
  165. var.Set(123.123f);
  166. ExpectVariantType(VT_R4, var);
  167. EXPECT_EQ(123.123f, V_R4(var.ptr()));
  168. }
  169. TEST(ScopedVariantTest, SetReal8Byte) {
  170. ScopedVariant var;
  171. var.Set(static_cast<double>(123.123));
  172. ExpectVariantType(VT_R8, var);
  173. EXPECT_EQ(123.123, V_R8(var.ptr()));
  174. }
  175. TEST(ScopedVariantTest, SetBooleanTrue) {
  176. ScopedVariant var;
  177. var.Set(true);
  178. ExpectVariantType(VT_BOOL, var);
  179. EXPECT_EQ(VARIANT_TRUE, V_BOOL(var.ptr()));
  180. }
  181. TEST(ScopedVariantTest, SetBooleanFalse) {
  182. ScopedVariant var;
  183. var.Set(false);
  184. ExpectVariantType(VT_BOOL, var);
  185. EXPECT_EQ(VARIANT_FALSE, V_BOOL(var.ptr()));
  186. }
  187. TEST(ScopedVariantTest, SetComIDispatch) {
  188. ScopedVariant var;
  189. Microsoft::WRL::ComPtr<IDispatch> dispatch_stub =
  190. Microsoft::WRL::Make<DispatchStub>();
  191. ExpectRefCount(1U, dispatch_stub.Get());
  192. var.Set(dispatch_stub.Get());
  193. ExpectVariantType(VT_DISPATCH, var);
  194. EXPECT_EQ(dispatch_stub.Get(), V_DISPATCH(var.ptr()));
  195. ExpectRefCount(2U, dispatch_stub.Get());
  196. var.Reset();
  197. ExpectRefCount(1U, dispatch_stub.Get());
  198. }
  199. TEST(ScopedVariantTest, SetComNullIDispatch) {
  200. ScopedVariant var;
  201. var.Set(static_cast<IDispatch*>(nullptr));
  202. ExpectVariantType(VT_DISPATCH, var);
  203. EXPECT_EQ(nullptr, V_DISPATCH(var.ptr()));
  204. }
  205. TEST(ScopedVariantTest, SetComIUnknown) {
  206. ScopedVariant var;
  207. Microsoft::WRL::ComPtr<IUnknown> unknown_stub =
  208. Microsoft::WRL::Make<DispatchStub>();
  209. ExpectRefCount(1U, unknown_stub.Get());
  210. var.Set(unknown_stub.Get());
  211. ExpectVariantType(VT_UNKNOWN, var);
  212. EXPECT_EQ(unknown_stub.Get(), V_UNKNOWN(var.ptr()));
  213. ExpectRefCount(2U, unknown_stub.Get());
  214. var.Reset();
  215. ExpectRefCount(1U, unknown_stub.Get());
  216. }
  217. TEST(ScopedVariantTest, SetComNullIUnknown) {
  218. ScopedVariant var;
  219. var.Set(static_cast<IUnknown*>(nullptr));
  220. ExpectVariantType(VT_UNKNOWN, var);
  221. EXPECT_EQ(nullptr, V_UNKNOWN(var.ptr()));
  222. }
  223. TEST(ScopedVariant, ScopedComIDispatchConstructor) {
  224. Microsoft::WRL::ComPtr<IDispatch> dispatch_stub =
  225. Microsoft::WRL::Make<DispatchStub>();
  226. {
  227. ScopedVariant var(dispatch_stub.Get());
  228. ExpectVariantType(VT_DISPATCH, var);
  229. EXPECT_EQ(dispatch_stub.Get(), V_DISPATCH(var.ptr()));
  230. ExpectRefCount(2U, dispatch_stub.Get());
  231. }
  232. ExpectRefCount(1U, dispatch_stub.Get());
  233. }
  234. TEST(ScopedVariant, ScopedComIDispatchMove) {
  235. Microsoft::WRL::ComPtr<IDispatch> dispatch_stub =
  236. Microsoft::WRL::Make<DispatchStub>();
  237. {
  238. ScopedVariant var1(dispatch_stub.Get());
  239. ExpectRefCount(2U, dispatch_stub.Get());
  240. ScopedVariant var2(std::move(var1));
  241. ExpectRefCount(2U, dispatch_stub.Get());
  242. ScopedVariant var3;
  243. var3 = std::move(var2);
  244. ExpectRefCount(2U, dispatch_stub.Get());
  245. }
  246. ExpectRefCount(1U, dispatch_stub.Get());
  247. }
  248. TEST(ScopedVariant, ScopedComIDispatchCopy) {
  249. Microsoft::WRL::ComPtr<IDispatch> dispatch_stub =
  250. Microsoft::WRL::Make<DispatchStub>();
  251. {
  252. ScopedVariant var1(dispatch_stub.Get());
  253. ExpectRefCount(2U, dispatch_stub.Get());
  254. ScopedVariant var2(static_cast<const VARIANT&>(var1));
  255. ExpectRefCount(3U, dispatch_stub.Get());
  256. ScopedVariant var3;
  257. var3 = static_cast<const VARIANT&>(var2);
  258. ExpectRefCount(4U, dispatch_stub.Get());
  259. }
  260. ExpectRefCount(1U, dispatch_stub.Get());
  261. }
  262. TEST(ScopedVariant, ScopedComIUnknownConstructor) {
  263. Microsoft::WRL::ComPtr<IUnknown> unknown_stub =
  264. Microsoft::WRL::Make<DispatchStub>();
  265. {
  266. ScopedVariant unk_var(unknown_stub.Get());
  267. ExpectVariantType(VT_UNKNOWN, unk_var);
  268. EXPECT_EQ(unknown_stub.Get(), V_UNKNOWN(unk_var.ptr()));
  269. ExpectRefCount(2U, unknown_stub.Get());
  270. }
  271. ExpectRefCount(1U, unknown_stub.Get());
  272. }
  273. TEST(ScopedVariant, ScopedComIUnknownWithRawVariant) {
  274. ScopedVariant var;
  275. Microsoft::WRL::ComPtr<IUnknown> unknown_stub =
  276. Microsoft::WRL::Make<DispatchStub>();
  277. VARIANT raw;
  278. raw.vt = VT_UNKNOWN;
  279. raw.punkVal = unknown_stub.Get();
  280. ExpectRefCount(1U, unknown_stub.Get());
  281. var.Set(raw);
  282. ExpectRefCount(2U, unknown_stub.Get());
  283. var.Reset();
  284. ExpectRefCount(1U, unknown_stub.Get());
  285. }
  286. TEST(ScopedVariant, SetSafeArray) {
  287. SAFEARRAY* sa = ::SafeArrayCreateVector(VT_UI1, 0, 100);
  288. ASSERT_TRUE(sa);
  289. ScopedVariant var;
  290. var.Set(sa);
  291. EXPECT_TRUE(ScopedVariant::IsLeakableVarType(var.type()));
  292. ExpectVariantType(static_cast<VARENUM>(VT_ARRAY | VT_UI1), var);
  293. EXPECT_EQ(sa, V_ARRAY(var.ptr()));
  294. // The array is destroyed in the destructor of var.
  295. sa = nullptr;
  296. }
  297. TEST(ScopedVariant, SetNullSafeArray) {
  298. ScopedVariant var;
  299. var.Set(static_cast<SAFEARRAY*>(nullptr));
  300. ExpectVariantType(VT_EMPTY, var);
  301. }
  302. } // namespace win
  303. } // namespace base