Home | History | Annotate | Download | only in win
      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