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