OLD | NEW |
| (Empty) |
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 | |
5 #include "base/win/scoped_variant.h" | |
6 #include "testing/gtest/include/gtest/gtest.h" | |
7 | |
8 namespace base { | |
9 namespace win { | |
10 | |
11 namespace { | |
12 | |
13 static const wchar_t kTestString1[] = L"Used to create BSTRs"; | |
14 static const wchar_t kTestString2[] = L"Also used to create BSTRs"; | |
15 | |
16 void GiveMeAVariant(VARIANT* ret) { | |
17 EXPECT_TRUE(ret != NULL); | |
18 ret->vt = VT_BSTR; | |
19 V_BSTR(ret) = ::SysAllocString(kTestString1); | |
20 } | |
21 | |
22 // A dummy IDispatch implementation (if you can call it that). | |
23 // The class does nothing intelligent really. Only increments a counter | |
24 // when AddRef is called and decrements it when Release is called. | |
25 class FakeComObject : public IDispatch { | |
26 public: | |
27 FakeComObject() : ref_(0) { | |
28 } | |
29 | |
30 STDMETHOD_(DWORD, AddRef)() override { | |
31 ref_++; | |
32 return ref_; | |
33 } | |
34 | |
35 STDMETHOD_(DWORD, Release)() override { | |
36 ref_--; | |
37 return ref_; | |
38 } | |
39 | |
40 STDMETHOD(QueryInterface)(REFIID, void**) override { return E_NOTIMPL; } | |
41 | |
42 STDMETHOD(GetTypeInfoCount)(UINT*) override { return E_NOTIMPL; } | |
43 | |
44 STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**) override { return E_NOTIMPL; } | |
45 | |
46 STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, UINT, LCID, DISPID*) override { | |
47 return E_NOTIMPL; | |
48 } | |
49 | |
50 STDMETHOD(Invoke)(DISPID, | |
51 REFIID, | |
52 LCID, | |
53 WORD, | |
54 DISPPARAMS*, | |
55 VARIANT*, | |
56 EXCEPINFO*, | |
57 UINT*) override { | |
58 return E_NOTIMPL; | |
59 } | |
60 | |
61 // A way to check the internal reference count of the class. | |
62 int ref_count() const { | |
63 return ref_; | |
64 } | |
65 | |
66 protected: | |
67 int ref_; | |
68 }; | |
69 | |
70 } // namespace | |
71 | |
72 TEST(ScopedVariantTest, ScopedVariant) { | |
73 ScopedVariant var; | |
74 EXPECT_TRUE(var.type() == VT_EMPTY); | |
75 // V_BSTR(var.ptr()) = NULL; <- NOTE: Assignment like that is not supported. | |
76 | |
77 ScopedVariant var_bstr(L"VT_BSTR"); | |
78 EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr())); | |
79 EXPECT_TRUE(V_BSTR(var_bstr.ptr()) != NULL); // can't use EXPECT_NE for BSTR | |
80 var_bstr.Reset(); | |
81 EXPECT_NE(VT_BSTR, V_VT(var_bstr.ptr())); | |
82 var_bstr.Set(kTestString2); | |
83 EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr())); | |
84 | |
85 VARIANT tmp = var_bstr.Release(); | |
86 EXPECT_EQ(VT_EMPTY, V_VT(var_bstr.ptr())); | |
87 EXPECT_EQ(VT_BSTR, V_VT(&tmp)); | |
88 EXPECT_EQ(0, lstrcmp(V_BSTR(&tmp), kTestString2)); | |
89 | |
90 var.Reset(tmp); | |
91 EXPECT_EQ(VT_BSTR, V_VT(var.ptr())); | |
92 EXPECT_EQ(0, lstrcmpW(V_BSTR(var.ptr()), kTestString2)); | |
93 | |
94 var_bstr.Swap(var); | |
95 EXPECT_EQ(VT_EMPTY, V_VT(var.ptr())); | |
96 EXPECT_EQ(VT_BSTR, V_VT(var_bstr.ptr())); | |
97 EXPECT_EQ(0, lstrcmpW(V_BSTR(var_bstr.ptr()), kTestString2)); | |
98 var_bstr.Reset(); | |
99 | |
100 // Test the Compare and Copy routines. | |
101 GiveMeAVariant(var_bstr.Receive()); | |
102 ScopedVariant var_bstr2(V_BSTR(var_bstr.ptr())); | |
103 EXPECT_EQ(0, var_bstr.Compare(var_bstr2)); | |
104 var_bstr2.Reset(); | |
105 EXPECT_NE(0, var_bstr.Compare(var_bstr2)); | |
106 var_bstr2.Reset(var_bstr.Copy()); | |
107 EXPECT_EQ(0, var_bstr.Compare(var_bstr2)); | |
108 var_bstr2.Reset(); | |
109 var_bstr2.Set(V_BSTR(var_bstr.ptr())); | |
110 EXPECT_EQ(0, var_bstr.Compare(var_bstr2)); | |
111 var_bstr2.Reset(); | |
112 var_bstr.Reset(); | |
113 | |
114 // Test for the SetDate setter. | |
115 SYSTEMTIME sys_time; | |
116 ::GetSystemTime(&sys_time); | |
117 DATE date; | |
118 ::SystemTimeToVariantTime(&sys_time, &date); | |
119 var.Reset(); | |
120 var.SetDate(date); | |
121 EXPECT_EQ(VT_DATE, var.type()); | |
122 EXPECT_EQ(date, V_DATE(var.ptr())); | |
123 | |
124 // Simple setter tests. These do not require resetting the variant | |
125 // after each test since the variant type is not "leakable" (i.e. doesn't | |
126 // need to be freed explicitly). | |
127 | |
128 // We need static cast here since char defaults to int (!?). | |
129 var.Set(static_cast<int8>('v')); | |
130 EXPECT_EQ(VT_I1, var.type()); | |
131 EXPECT_EQ('v', V_I1(var.ptr())); | |
132 | |
133 var.Set(static_cast<short>(123)); | |
134 EXPECT_EQ(VT_I2, var.type()); | |
135 EXPECT_EQ(123, V_I2(var.ptr())); | |
136 | |
137 var.Set(static_cast<int32>(123)); | |
138 EXPECT_EQ(VT_I4, var.type()); | |
139 EXPECT_EQ(123, V_I4(var.ptr())); | |
140 | |
141 var.Set(static_cast<int64>(123)); | |
142 EXPECT_EQ(VT_I8, var.type()); | |
143 EXPECT_EQ(123, V_I8(var.ptr())); | |
144 | |
145 var.Set(static_cast<uint8>(123)); | |
146 EXPECT_EQ(VT_UI1, var.type()); | |
147 EXPECT_EQ(123, V_UI1(var.ptr())); | |
148 | |
149 var.Set(static_cast<unsigned short>(123)); | |
150 EXPECT_EQ(VT_UI2, var.type()); | |
151 EXPECT_EQ(123, V_UI2(var.ptr())); | |
152 | |
153 var.Set(static_cast<uint32>(123)); | |
154 EXPECT_EQ(VT_UI4, var.type()); | |
155 EXPECT_EQ(123, V_UI4(var.ptr())); | |
156 | |
157 var.Set(static_cast<uint64>(123)); | |
158 EXPECT_EQ(VT_UI8, var.type()); | |
159 EXPECT_EQ(123, V_UI8(var.ptr())); | |
160 | |
161 var.Set(123.123f); | |
162 EXPECT_EQ(VT_R4, var.type()); | |
163 EXPECT_EQ(123.123f, V_R4(var.ptr())); | |
164 | |
165 var.Set(static_cast<double>(123.123)); | |
166 EXPECT_EQ(VT_R8, var.type()); | |
167 EXPECT_EQ(123.123, V_R8(var.ptr())); | |
168 | |
169 var.Set(true); | |
170 EXPECT_EQ(VT_BOOL, var.type()); | |
171 EXPECT_EQ(VARIANT_TRUE, V_BOOL(var.ptr())); | |
172 var.Set(false); | |
173 EXPECT_EQ(VT_BOOL, var.type()); | |
174 EXPECT_EQ(VARIANT_FALSE, V_BOOL(var.ptr())); | |
175 | |
176 // Com interface tests | |
177 | |
178 var.Set(static_cast<IDispatch*>(NULL)); | |
179 EXPECT_EQ(VT_DISPATCH, var.type()); | |
180 EXPECT_EQ(NULL, V_DISPATCH(var.ptr())); | |
181 var.Reset(); | |
182 | |
183 var.Set(static_cast<IUnknown*>(NULL)); | |
184 EXPECT_EQ(VT_UNKNOWN, var.type()); | |
185 EXPECT_EQ(NULL, V_UNKNOWN(var.ptr())); | |
186 var.Reset(); | |
187 | |
188 FakeComObject faker; | |
189 EXPECT_EQ(0, faker.ref_count()); | |
190 var.Set(static_cast<IDispatch*>(&faker)); | |
191 EXPECT_EQ(VT_DISPATCH, var.type()); | |
192 EXPECT_EQ(&faker, V_DISPATCH(var.ptr())); | |
193 EXPECT_EQ(1, faker.ref_count()); | |
194 var.Reset(); | |
195 EXPECT_EQ(0, faker.ref_count()); | |
196 | |
197 var.Set(static_cast<IUnknown*>(&faker)); | |
198 EXPECT_EQ(VT_UNKNOWN, var.type()); | |
199 EXPECT_EQ(&faker, V_UNKNOWN(var.ptr())); | |
200 EXPECT_EQ(1, faker.ref_count()); | |
201 var.Reset(); | |
202 EXPECT_EQ(0, faker.ref_count()); | |
203 | |
204 { | |
205 ScopedVariant disp_var(&faker); | |
206 EXPECT_EQ(VT_DISPATCH, disp_var.type()); | |
207 EXPECT_EQ(&faker, V_DISPATCH(disp_var.ptr())); | |
208 EXPECT_EQ(1, faker.ref_count()); | |
209 } | |
210 EXPECT_EQ(0, faker.ref_count()); | |
211 | |
212 { | |
213 ScopedVariant ref1(&faker); | |
214 EXPECT_EQ(1, faker.ref_count()); | |
215 ScopedVariant ref2(static_cast<const VARIANT&>(ref1)); | |
216 EXPECT_EQ(2, faker.ref_count()); | |
217 ScopedVariant ref3; | |
218 ref3 = static_cast<const VARIANT&>(ref2); | |
219 EXPECT_EQ(3, faker.ref_count()); | |
220 } | |
221 EXPECT_EQ(0, faker.ref_count()); | |
222 | |
223 { | |
224 ScopedVariant unk_var(static_cast<IUnknown*>(&faker)); | |
225 EXPECT_EQ(VT_UNKNOWN, unk_var.type()); | |
226 EXPECT_EQ(&faker, V_UNKNOWN(unk_var.ptr())); | |
227 EXPECT_EQ(1, faker.ref_count()); | |
228 } | |
229 EXPECT_EQ(0, faker.ref_count()); | |
230 | |
231 VARIANT raw; | |
232 raw.vt = VT_UNKNOWN; | |
233 raw.punkVal = &faker; | |
234 EXPECT_EQ(0, faker.ref_count()); | |
235 var.Set(raw); | |
236 EXPECT_EQ(1, faker.ref_count()); | |
237 var.Reset(); | |
238 EXPECT_EQ(0, faker.ref_count()); | |
239 | |
240 { | |
241 ScopedVariant number(123); | |
242 EXPECT_EQ(VT_I4, number.type()); | |
243 EXPECT_EQ(123, V_I4(number.ptr())); | |
244 } | |
245 | |
246 // SAFEARRAY tests | |
247 var.Set(static_cast<SAFEARRAY*>(NULL)); | |
248 EXPECT_EQ(VT_EMPTY, var.type()); | |
249 | |
250 SAFEARRAY* sa = ::SafeArrayCreateVector(VT_UI1, 0, 100); | |
251 ASSERT_TRUE(sa != NULL); | |
252 | |
253 var.Set(sa); | |
254 EXPECT_TRUE(ScopedVariant::IsLeakableVarType(var.type())); | |
255 EXPECT_EQ(VT_ARRAY | VT_UI1, var.type()); | |
256 EXPECT_EQ(sa, V_ARRAY(var.ptr())); | |
257 // The array is destroyed in the destructor of var. | |
258 } | |
259 | |
260 } // namespace win | |
261 } // namespace base | |
OLD | NEW |