1 // Copyright (c) 2009 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)() { 31 ref_++; 32 return ref_; 33 } 34 35 STDMETHOD_(DWORD, Release)() { 36 ref_--; 37 return ref_; 38 } 39 40 STDMETHOD(QueryInterface)(REFIID, void**) { 41 return E_NOTIMPL; 42 } 43 44 STDMETHOD(GetTypeInfoCount)(UINT*) { 45 return E_NOTIMPL; 46 } 47 48 STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**) { 49 return E_NOTIMPL; 50 } 51 52 STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, UINT, LCID, DISPID*) { 53 return E_NOTIMPL; 54 } 55 56 STDMETHOD(Invoke)(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, 57 EXCEPINFO*, UINT*) { 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) = 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)); 79 EXPECT_TRUE(V_BSTR(&var_bstr) != NULL); // can't use EXPECT_NE for BSTR 80 var_bstr.Reset(); 81 EXPECT_NE(VT_BSTR, V_VT(&var_bstr)); 82 var_bstr.Set(kTestString2); 83 EXPECT_EQ(VT_BSTR, V_VT(&var_bstr)); 84 85 VARIANT tmp = var_bstr.Release(); 86 EXPECT_EQ(VT_EMPTY, V_VT(&var_bstr)); 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)); 92 EXPECT_EQ(0, lstrcmpW(V_BSTR(&var), kTestString2)); 93 94 var_bstr.Swap(var); 95 EXPECT_EQ(VT_EMPTY, V_VT(&var)); 96 EXPECT_EQ(VT_BSTR, V_VT(&var_bstr)); 97 EXPECT_EQ(0, lstrcmpW(V_BSTR(&var_bstr), 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)); 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)); 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)); 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)); 132 133 var.Set(static_cast<short>(123)); 134 EXPECT_EQ(VT_I2, var.type()); 135 EXPECT_EQ(123, V_I2(&var)); 136 137 var.Set(static_cast<int32>(123)); 138 EXPECT_EQ(VT_I4, var.type()); 139 EXPECT_EQ(123, V_I4(&var)); 140 141 var.Set(static_cast<int64>(123)); 142 EXPECT_EQ(VT_I8, var.type()); 143 EXPECT_EQ(123, V_I8(&var)); 144 145 var.Set(static_cast<uint8>(123)); 146 EXPECT_EQ(VT_UI1, var.type()); 147 EXPECT_EQ(123, V_UI1(&var)); 148 149 var.Set(static_cast<unsigned short>(123)); 150 EXPECT_EQ(VT_UI2, var.type()); 151 EXPECT_EQ(123, V_UI2(&var)); 152 153 var.Set(static_cast<uint32>(123)); 154 EXPECT_EQ(VT_UI4, var.type()); 155 EXPECT_EQ(123, V_UI4(&var)); 156 157 var.Set(static_cast<uint64>(123)); 158 EXPECT_EQ(VT_UI8, var.type()); 159 EXPECT_EQ(123, V_UI8(&var)); 160 161 var.Set(123.123f); 162 EXPECT_EQ(VT_R4, var.type()); 163 EXPECT_EQ(123.123f, V_R4(&var)); 164 165 var.Set(static_cast<double>(123.123)); 166 EXPECT_EQ(VT_R8, var.type()); 167 EXPECT_EQ(123.123, V_R8(&var)); 168 169 var.Set(true); 170 EXPECT_EQ(VT_BOOL, var.type()); 171 EXPECT_EQ(VARIANT_TRUE, V_BOOL(&var)); 172 var.Set(false); 173 EXPECT_EQ(VT_BOOL, var.type()); 174 EXPECT_EQ(VARIANT_FALSE, V_BOOL(&var)); 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)); 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)); 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)); 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)); 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)); 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)); 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)); 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 #ifndef OFFICIAL_BUILD 255 EXPECT_TRUE(ScopedVariant::IsLeakableVarType(var.type())); 256 #endif 257 EXPECT_EQ(VT_ARRAY | VT_UI1, var.type()); 258 EXPECT_EQ(sa, V_ARRAY(&var)); 259 // The array is destroyed in the destructor of var. 260 } 261 262 } // namespace win 263 } // namespace base 264