[ATL][ATL_APITEST] Implement some basic functionality for CComVariant + tests. CORE...
authorMark Jansen <mark.jansen@reactos.org>
Mon, 26 Sep 2016 20:50:36 +0000 (20:50 +0000)
committerMark Jansen <mark.jansen@reactos.org>
Mon, 26 Sep 2016 20:50:36 +0000 (20:50 +0000)
Also adds Detach() to CComBSTR.

svn path=/trunk/; revision=72820

reactos/sdk/lib/atl/atlcomcli.h
rostests/apitests/atl/CComVariant.cpp [new file with mode: 0644]
rostests/apitests/atl/CMakeLists.txt
rostests/apitests/atl/testlist.c

index 12098d3..b7b8d0b 100644 (file)
@@ -241,6 +241,13 @@ public:
         return *this;
     }
 
+    BSTR Detach()
+    {
+        BSTR str = m_str;
+        m_str = NULL;
+        return str;
+    }
+
     BSTR Copy() const
     {
         if (!m_str)
@@ -287,15 +294,162 @@ public:
         ::VariantInit(this);
     }
 
+    CComVariant(const CComVariant& other)
+    {
+        V_VT(this) = VT_EMPTY;
+        Copy(&other);
+    }
+
     ~CComVariant()
     {
         Clear();
     }
 
+    CComVariant(LPCOLESTR lpStr)
+    {
+        V_VT(this) = VT_BSTR;
+        V_BSTR(this) = ::SysAllocString(lpStr);
+    }
+
+    CComVariant(LPCSTR lpStr)
+    {
+        V_VT(this) = VT_BSTR;
+        CComBSTR str(lpStr);
+        V_BSTR(this) = str.Detach();
+    }
+
+    CComVariant(bool value)
+    {
+        V_VT(this) = VT_BOOL;
+        V_BOOL(this) = value ? VARIANT_TRUE : VARIANT_FALSE;
+    }
+
+    CComVariant(char value)
+    {
+        V_VT(this) = VT_I1;
+        V_I1(this) = value;
+    }
+
+    CComVariant(BYTE value)
+    {
+        V_VT(this) = VT_UI1;
+        V_UI1(this) = value;
+    }
+
+    CComVariant(short value)
+    {
+        V_VT(this) = VT_I2;
+        V_I2(this) = value;
+    }
+
+    CComVariant(unsigned short value)
+    {
+        V_VT(this) = VT_UI2;
+        V_UI2(this) = value;
+    }
+
+    CComVariant(int value, VARENUM type = VT_I4)
+    {
+        if (type == VT_I4 || type == VT_INT)
+        {
+            V_VT(this) = type;
+            V_I4(this) = value;
+        }
+        else
+        {
+            V_VT(this) = VT_ERROR;
+            V_ERROR(this) = E_INVALIDARG;
+        }
+    }
+
+    CComVariant(unsigned int value, VARENUM type = VT_UI4)
+    {
+        if (type == VT_UI4 || type == VT_UINT)
+        {
+            V_VT(this) = type;
+            V_UI4(this) = value;
+        }
+        else
+        {
+            V_VT(this) = VT_ERROR;
+            V_ERROR(this) = E_INVALIDARG;
+        }
+    }
+
+    CComVariant(long value, VARENUM type = VT_I4)
+    {
+        if (type == VT_I4 || type == VT_ERROR)
+        {
+            V_VT(this) = type;
+            V_I4(this) = value;
+        }
+        else
+        {
+            V_VT(this) = VT_ERROR;
+            V_ERROR(this) = E_INVALIDARG;
+        }
+    }
+
+    CComVariant(unsigned long value)
+    {
+        V_VT(this) = VT_UI4;
+        V_UI4(this) = value;
+    }
+
+    CComVariant(float value)
+    {
+        V_VT(this) = VT_R4;
+        V_R4(this) = value;
+    }
+
+    CComVariant(double value, VARENUM type = VT_R8)
+    {
+        if (type == VT_R8 || type == VT_DATE)
+        {
+            V_VT(this) = type;
+            V_R8(this) = value;
+        }
+        else
+        {
+            V_VT(this) = VT_ERROR;
+            V_ERROR(this) = E_INVALIDARG;
+        }
+    }
+
+    CComVariant(const LONGLONG& value)
+    {
+        V_VT(this) = VT_I8;
+        V_I8(this) = value;
+    }
+
+    CComVariant(const ULONGLONG& value)
+    {
+        V_VT(this) = VT_UI8;
+        V_UI8(this) = value;
+    }
+
+    CComVariant(const CY& value)
+    {
+        V_VT(this) = VT_CY;
+        V_I8(this) = value.int64;
+    }
+
+
     HRESULT Clear()
     {
         return ::VariantClear(this);
     }
+
+    HRESULT Copy(_In_ const VARIANT* src)
+    {
+        return ::VariantCopy(this, const_cast<VARIANT*>(src));
+    }
+
+    HRESULT ChangeType(_In_ VARTYPE newType, _In_opt_ const LPVARIANT src = NULL)
+    {
+        const LPVARIANT lpSrc = src ? src : this;
+        return ::VariantChangeType(this, lpSrc, 0, newType);
+    }
 };
 
 
diff --git a/rostests/apitests/atl/CComVariant.cpp b/rostests/apitests/atl/CComVariant.cpp
new file mode 100644 (file)
index 0000000..d41d128
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+ * PROJECT:         ReactOS api tests
+ * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE:         Test for CComVariant
+ * PROGRAMMER:      Mark Jansen
+ */
+
+/* In case we are building against the MS headers, we need to disable assertions. */
+#define ATLASSERT(x)
+#define _ATL_NO_VARIANT_THROW
+
+#include <apitest.h>
+#include <atlbase.h>
+#include <atlcom.h>
+
+void expect_bool_imp(const CComVariant& ccv, bool value)
+{
+    winetest_ok(V_VT(&ccv) == VT_BOOL, "Expected .vt to be BOOL, was %u\n", V_VT(&ccv));
+    VARIANT_BOOL expected = (value ? VARIANT_TRUE : VARIANT_FALSE);
+    winetest_ok(V_BOOL(&ccv) == expected, "Expected value to be %u, was: %u\n", expected, V_BOOL(&ccv));
+}
+
+void expect_int_imp(const CComVariant& ccv, int value, unsigned short type)
+{
+    winetest_ok(V_VT(&ccv) == type, "Expected .vt to be %u, was %u\n", type, V_VT(&ccv));
+    winetest_ok(V_I4(&ccv) == value, "Expected value to be %d, was: %ld\n", value, V_I4(&ccv));
+}
+
+void expect_uint_imp(const CComVariant& ccv, unsigned int value, unsigned short type)
+{
+    winetest_ok(V_VT(&ccv) == type, "Expected .vt to be %u, was %u\n", type, V_VT(&ccv));
+    winetest_ok(V_UI4(&ccv) == value, "Expected value to be %u, was: %lu\n", value, V_UI4(&ccv));
+}
+
+void expect_double_imp(const CComVariant& ccv, double value, unsigned short type)
+{
+    winetest_ok(V_VT(&ccv) == type, "Expected .vt to be %u, was %u\n", type, V_VT(&ccv));
+    winetest_ok(V_R8(&ccv) == value, "Expected value to be %f, was: %f\n", value, V_R8(&ccv));
+}
+
+void expect_error_imp(const CComVariant& ccv, SCODE value)
+{
+    winetest_ok(V_VT(&ccv) == VT_ERROR, "Expected .vt to be VT_ERROR, was %u\n", V_VT(&ccv));
+    winetest_ok(V_ERROR(&ccv) == value, "Expected value to be %lx, was: %lx\n", value, V_ERROR(&ccv));
+}
+
+void expect_empty_imp(const CComVariant& ccv)
+{
+    winetest_ok(V_VT(&ccv) == VT_EMPTY, "Expected .vt to be VT_EMPTY, was %u\n", V_VT(&ccv));
+    winetest_ok(V_I8(&ccv) == 0ll, "Expected value to be 0, was: %I64d\n", V_I8(&ccv));
+}
+
+#define expect_bool         (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_bool_imp
+#define expect_int          (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_int_imp
+#define expect_uint         (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_uint_imp
+#define expect_double       (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_double_imp
+#define expect_error        (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_error_imp
+#define expect_empty        (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_empty_imp
+
+
+static void test_construction()
+{
+    {
+        CComVariant empty;
+        expect_empty(empty);
+    }
+    {
+        CComBSTR bstr(L"TESTW");
+        CComVariant olestr((LPCOLESTR)bstr), comstr(bstr);
+        ok(V_VT(&olestr) == VT_BSTR, "Expected .vt to be VT_LPWSTR, was %u\n", V_VT(&olestr));
+        ok(!wcscmp(V_BSTR(&olestr), L"TESTW"), "Expected value to be L\"TESTW\", was: %s\n", wine_dbgstr_w(V_BSTR(&olestr)));
+        ok(V_VT(&comstr) == VT_BSTR, "Expected .vt to be VT_LPWSTR, was %u\n", V_VT(&comstr));
+        ok(!wcscmp(V_BSTR(&comstr), L"TESTW"), "Expected value to be L\"TESTW\", was: %s\n", wine_dbgstr_w(V_BSTR(&comstr)));
+    }
+    {
+        CComVariant cstr((LPCSTR)"TESTA");
+        ok(V_VT(&cstr) == VT_BSTR, "Expected .vt to be VT_LPWSTR, was %u\n", V_VT(&cstr));
+        ok(!wcscmp(V_BSTR(&cstr), L"TESTA"), "Expected value to be L\"TESTW\", was: %s\n", wine_dbgstr_w(V_BSTR(&cstr)));
+    }
+    {
+        CComVariant trueVal(true), falseVal(false);
+        ok(V_VT(&trueVal) == VT_BOOL, "Expected .vt to be BOOL, was %u\n", V_VT(&trueVal));
+        ok(V_BOOL(&trueVal) == VARIANT_TRUE, "Expected value to be VARIANT_TRUE, was: %u\n", V_BOOL(&trueVal));
+        ok(V_VT(&falseVal) == VT_BOOL, "Expected .vt to be BOOL, was %u\n", V_VT(&falseVal));
+        ok(V_BOOL(&falseVal) == VARIANT_FALSE, "Expected value to be VARIANT_TRUE, was: %u\n", V_BOOL(&falseVal));
+    }
+    {
+        CComVariant b1((BYTE)33);
+        ok(V_VT(&b1) == VT_UI1, "Expected .vt to be VT_UI1, was %u\n", V_VT(&b1));
+        ok(V_UI1(&b1) == (BYTE)33, "Expected value to be 33, was: %u\n", V_UI1(&b1));
+    }
+    {
+        CComVariant c1((char)33);
+        ok(V_VT(&c1) == VT_I1, "Expected .vt to be VT_I1, was %u\n", V_VT(&c1));
+        ok(V_I1(&c1) == (char)33, "Expected value to be 33, was: %d\n", V_I1(&c1));
+    }
+    {
+        CComVariant s1((short)12345);
+        ok(V_VT(&s1) == VT_I2, "Expected .vt to be VT_I2, was %u\n", V_VT(&s1));
+        ok(V_I2(&s1) == (short)12345, "Expected value to be 12345, was: %d\n", V_I1(&s1));
+    }
+    {
+        CComVariant us1((unsigned short)12345);
+        ok(V_VT(&us1) == VT_UI2, "Expected .vt to be VT_UI2, was %u\n", V_VT(&us1));
+        ok(V_UI2(&us1) == (unsigned short)12345, "Expected value to be 12345, was: %u\n", V_UI2(&us1));
+    }
+    {
+        CComVariant i1((int)4, VT_I4), i2((int)3, VT_INT), i3((int)2, VT_I2), i4((int)1);
+        expect_int(i1, 4, VT_I4);
+        expect_int(i2, 3, VT_INT);
+        expect_error(i3, E_INVALIDARG);
+        expect_int(i4, 1, VT_I4);
+    }
+    {
+        CComVariant ui1((unsigned int)4, VT_UI4), ui2((unsigned int)3, VT_UINT), ui3((unsigned int)2, VT_UI2), ui4((unsigned int)1);
+        expect_uint(ui1, 4, VT_UI4);
+        expect_uint(ui2, 3, VT_UINT);
+        expect_error(ui3, E_INVALIDARG);
+        expect_uint(ui4, 1, VT_UI4);
+    }
+    {
+        CComVariant l1((long)4, VT_I4), l2((long)3, VT_INT), l3((long)2, VT_ERROR), l4((long)1);
+        expect_int(l1, 4, VT_I4);
+        expect_error(l2, E_INVALIDARG);
+        expect_error(l3, 2);
+        expect_int(l4, 1, VT_I4);
+    }
+    {
+        CComVariant ul1((unsigned long)33);
+        expect_uint(ul1, 33, VT_UI4);
+    }
+    {
+        CComVariant f1(3.4f);
+        ok(V_VT(&f1) == VT_R4, "Expected .vt to be VT_R4, was %u\n", V_VT(&f1));
+        ok(V_R4(&f1) == 3.4f, "Expected value to be 3.4f, was: %f\n", V_R4(&f1));
+    }
+    {
+        CComVariant d1(3.4, VT_R8), d2(3.4, VT_DATE), d3(8.8, VT_I1), d4(1.9);
+        expect_double(d1, 3.4, VT_R8);
+        expect_double(d2, 3.4, VT_DATE);
+        expect_error(d3, E_INVALIDARG);
+        expect_double(d4, 1.9, VT_R8);
+    }
+    {
+        LONGLONG lv = 12030912309123ll;
+        CComVariant l1(lv);
+        ok(V_VT(&l1) == VT_I8, "Expected .vt to be VT_I8, was %u\n", V_VT(&l1));
+        ok(V_I8(&l1) == lv, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(lv), wine_dbgstr_longlong(V_I8(&l1)));
+    }
+    {
+        ULONGLONG lv = 12030912309123llu;
+        CComVariant l1(lv);
+        ok(V_VT(&l1) == VT_UI8, "Expected .vt to be VT_UI8, was %u\n", V_VT(&l1));
+        ok(V_UI8(&l1) == lv, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(lv), wine_dbgstr_longlong(V_UI8(&l1)));
+    }
+    {
+        CY cy;
+        cy.int64 = 12030912309123ll;
+        CComVariant c1(cy);
+        ok(V_VT(&c1) == VT_CY, "Expected .vt to be VT_CY, was %u\n", V_VT(&c1));
+        ok(V_CY(&c1).int64 == cy.int64, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(cy.int64), wine_dbgstr_longlong(V_CY(&c1).int64));
+    }
+    // IDispatch
+    // IUnknown
+}
+
+
+static void test_copyconstructor()
+{
+    {
+        CComVariant empty;
+        CComVariant empty2(empty);
+        expect_empty(empty2);
+    }
+    {
+        CComBSTR bstr(L"TESTW");
+        CComVariant olestr((LPCOLESTR)bstr);
+        CComVariant olestr2(olestr);
+        ok(V_VT(&olestr2) == VT_BSTR, "Expected .vt to be VT_LPWSTR, was %u\n", V_VT(&olestr2));
+        ok(!wcscmp(V_BSTR(&olestr2), L"TESTW"), "Expected value to be L\"TESTW\", was: %s\n", wine_dbgstr_w(V_BSTR(&olestr2)));
+    }
+    {
+        CComVariant trueVal(true);
+        CComVariant trueVal2(trueVal);
+        ok(V_VT(&trueVal2) == VT_BOOL, "Expected .vt to be BOOL, was %u\n", V_VT(&trueVal2));
+        ok(V_BOOL(&trueVal2) == VARIANT_TRUE, "Expected value to be VARIANT_TRUE, was: %u\n", V_BOOL(&trueVal2));
+    }
+    {
+        CComVariant b1((BYTE)33);
+        CComVariant b2(b1);
+        ok(V_VT(&b2) == VT_UI1, "Expected .vt to be VT_UI1, was %u\n", V_VT(&b2));
+        ok(V_UI1(&b2) == (BYTE)33, "Expected value to be 33, was: %u\n", V_UI1(&b2));
+    }
+    {
+        CComVariant c1((char)33);
+        CComVariant c2(c1);
+        ok(V_VT(&c2) == VT_I1, "Expected .vt to be VT_I1, was %u\n", V_VT(&c2));
+        ok(V_I1(&c2) == (char)33, "Expected value to be 33, was: %d\n", V_I1(&c2));
+    }
+    {
+        CComVariant s1((short)12345);
+        CComVariant s2(s1);
+        ok(V_VT(&s2) == VT_I2, "Expected .vt to be VT_I2, was %u\n", V_VT(&s2));
+        ok(V_I2(&s2) == (short)12345, "Expected value to be 12345, was: %d\n", V_I1(&s2));
+    }
+    {
+        CComVariant us1((unsigned short)12345);
+        CComVariant us2(us1);
+        ok(V_VT(&us2) == VT_UI2, "Expected .vt to be VT_UI2, was %u\n", V_VT(&us2));
+        ok(V_UI2(&us2) == (unsigned short)12345, "Expected value to be 12345, was: %u\n", V_UI2(&us2));
+    }
+    {
+        CComVariant i1((int)4, VT_I4);
+        CComVariant i2(i1);
+        expect_int(i2, 4, VT_I4);
+    }
+    {
+        CComVariant ui1((unsigned int)4, VT_UI4);
+        CComVariant ui2(ui1);
+        expect_uint(ui2, 4, VT_UI4);
+    }
+    {
+        CComVariant l1((long)4, VT_I4);
+        CComVariant l2(l1);
+        expect_uint(l2, 4, VT_I4);
+    }
+    {
+        CComVariant ul1((unsigned long)33);
+        CComVariant ul2(ul1);
+        expect_uint(ul2, 33, VT_UI4);
+    }
+    {
+        CComVariant f1(3.4f);
+        CComVariant f2(f1);
+        ok(V_VT(&f2) == VT_R4, "Expected .vt to be VT_R4, was %u\n", V_VT(&f2));
+        ok(V_R4(&f2) == 3.4f, "Expected value to be 3.4f, was: %f\n", V_R4(&f2));
+    }
+    {
+        CComVariant d1(3.4, VT_R8);
+        CComVariant d2(d1);
+        expect_double(d2, 3.4, VT_R8);
+    }
+    {
+        LONGLONG lv = 12030912309123ll;
+        CComVariant l1(lv);
+        CComVariant l2(l1);
+        ok(V_VT(&l2) == VT_I8, "Expected .vt to be VT_I8, was %u\n", V_VT(&l2));
+        ok(V_I8(&l2) == lv, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(lv), wine_dbgstr_longlong(V_I8(&l2)));
+    }
+    {
+        ULONGLONG lv = 12030912309123llu;
+        CComVariant l1(lv);
+        CComVariant l2(l1);
+        ok(V_VT(&l2) == VT_UI8, "Expected .vt to be VT_UI8, was %u\n", V_VT(&l2));
+        ok(V_UI8(&l2) == lv, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(lv), wine_dbgstr_longlong(V_UI8(&l2)));
+    }
+    {
+        CY cy;
+        cy.int64 = 12030912309123ll;
+        CComVariant c1(cy);
+        CComVariant c2(c1);
+        ok(V_VT(&c2) == VT_CY, "Expected .vt to be VT_I8, was %u\n", V_VT(&c2));
+        ok(V_CY(&c2).int64 == cy.int64, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(cy.int64), wine_dbgstr_longlong(V_CY(&c2).int64));
+    }
+    // IDispatch
+    // IUnknown
+}
+
+static void test_assign()
+{
+    {
+        CComVariant empty;
+        CComVariant empty2 = empty;
+        expect_empty(empty2);
+    }
+    {
+        CComBSTR bstr(L"TESTW");
+        CComVariant olestr = (LPCOLESTR)bstr;
+        ok(V_VT(&olestr) == VT_BSTR, "Expected .vt to be VT_LPWSTR, was %u\n", V_VT(&olestr));
+        ok(!wcscmp(V_BSTR(&olestr), L"TESTW"), "Expected value to be L\"TESTW\", was: %s\n", wine_dbgstr_w(V_BSTR(&olestr)));
+        CComVariant olestr2 = olestr;
+        ok(V_VT(&olestr2) == VT_BSTR, "Expected .vt to be VT_LPWSTR, was %u\n", V_VT(&olestr2));
+        ok(!wcscmp(V_BSTR(&olestr2), L"TESTW"), "Expected value to be L\"TESTW\", was: %s\n", wine_dbgstr_w(V_BSTR(&olestr2)));
+    }
+    {
+        CComVariant trueVal = true;
+        ok(V_VT(&trueVal) == VT_BOOL, "Expected .vt to be BOOL, was %u\n", V_VT(&trueVal));
+        ok(V_BOOL(&trueVal) == VARIANT_TRUE, "Expected value to be VARIANT_TRUE, was: %u\n", V_BOOL(&trueVal));
+        CComVariant trueVal2 = trueVal;
+        ok(V_VT(&trueVal2) == VT_BOOL, "Expected .vt to be BOOL, was %u\n", V_VT(&trueVal2));
+        ok(V_BOOL(&trueVal2) == VARIANT_TRUE, "Expected value to be VARIANT_TRUE, was: %u\n", V_BOOL(&trueVal2));
+    }
+    {
+        CComVariant b1 = (BYTE)33;
+        ok(V_VT(&b1) == VT_UI1, "Expected .vt to be VT_UI1, was %u\n", V_VT(&b1));
+        ok(V_UI1(&b1) == (BYTE)33, "Expected value to be 33, was: %u\n", V_UI1(&b1));
+        CComVariant b2 = b1;
+        ok(V_VT(&b2) == VT_UI1, "Expected .vt to be VT_UI1, was %u\n", V_VT(&b2));
+        ok(V_UI1(&b2) == (BYTE)33, "Expected value to be 33, was: %u\n", V_UI1(&b2));
+    }
+    {
+        CComVariant c1 = (char)33;
+        ok(V_VT(&c1) == VT_I1, "Expected .vt to be VT_I1, was %u\n", V_VT(&c1));
+        ok(V_I1(&c1) == (char)33, "Expected value to be 33, was: %d\n", V_I1(&c1));
+        CComVariant c2 = c1;
+        ok(V_VT(&c2) == VT_I1, "Expected .vt to be VT_I1, was %u\n", V_VT(&c2));
+        ok(V_I1(&c2) == (char)33, "Expected value to be 33, was: %d\n", V_I1(&c2));
+    }
+    {
+        CComVariant s1 = (short)12345;
+        ok(V_VT(&s1) == VT_I2, "Expected .vt to be VT_I2, was %u\n", V_VT(&s1));
+        ok(V_I2(&s1) == (short)12345, "Expected value to be 12345, was: %d\n", V_I1(&s1));
+        CComVariant s2 = s1;
+        ok(V_VT(&s2) == VT_I2, "Expected .vt to be VT_I2, was %u\n", V_VT(&s2));
+        ok(V_I2(&s2) == (short)12345, "Expected value to be 12345, was: %d\n", V_I1(&s2));
+    }
+    {
+        CComVariant us1 = (unsigned short)12345;
+        ok(V_VT(&us1) == VT_UI2, "Expected .vt to be VT_UI2, was %u\n", V_VT(&us1));
+        ok(V_UI2(&us1) == (unsigned short)12345, "Expected value to be 12345, was: %u\n", V_UI2(&us1));
+        CComVariant us2 = us1;
+        ok(V_VT(&us2) == VT_UI2, "Expected .vt to be VT_UI2, was %u\n", V_VT(&us2));
+        ok(V_UI2(&us2) == (unsigned short)12345, "Expected value to be 12345, was: %u\n", V_UI2(&us2));
+    }
+    {
+        CComVariant i1 = (int)4;
+        expect_int(i1, 4, VT_I4);
+        CComVariant i2 = i1;
+        expect_int(i2, 4, VT_I4);
+    }
+    {
+        CComVariant ui1 = (unsigned int)4;
+        expect_uint(ui1, 4, VT_UI4);
+        CComVariant ui2 = ui1;
+        expect_uint(ui2, 4, VT_UI4);
+    }
+    {
+        CComVariant l1 = (long)4;
+        expect_uint(l1, 4, VT_I4);
+        CComVariant l2 = l1;
+        expect_uint(l2, 4, VT_I4);
+    }
+    {
+        CComVariant ul1 = (unsigned long)33;
+        expect_uint(ul1, 33, VT_UI4);
+        CComVariant ul2 = ul1;
+        expect_uint(ul2, 33, VT_UI4);
+    }
+    {
+        CComVariant f1 = 3.4f;
+        ok(V_VT(&f1) == VT_R4, "Expected .vt to be VT_R4, was %u\n", V_VT(&f1));
+        ok(V_R4(&f1) == 3.4f, "Expected value to be 3.4f, was: %f\n", V_R4(&f1));
+        CComVariant f2 = f1;
+        ok(V_VT(&f2) == VT_R4, "Expected .vt to be VT_R4, was %u\n", V_VT(&f2));
+        ok(V_R4(&f2) == 3.4f, "Expected value to be 3.4f, was: %f\n", V_R4(&f2));
+    }
+    {
+        CComVariant d1 = 3.4;
+        expect_double(d1, 3.4, VT_R8);
+        CComVariant d2 = d1;
+        expect_double(d2, 3.4, VT_R8);
+    }
+    {
+        LONGLONG lv = 12030912309123ll;
+        CComVariant l1 = lv;
+        ok(V_VT(&l1) == VT_I8, "Expected .vt to be VT_I8, was %u\n", V_VT(&l1));
+        ok(V_I8(&l1) == lv, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(lv), wine_dbgstr_longlong(V_I8(&l1)));
+        CComVariant l2 = l1;
+        ok(V_VT(&l2) == VT_I8, "Expected .vt to be VT_I8, was %u\n", V_VT(&l2));
+        ok(V_I8(&l2) == lv, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(lv), wine_dbgstr_longlong(V_I8(&l2)));
+    }
+    {
+        ULONGLONG lv = 12030912309123llu;
+        CComVariant l1 = lv;
+        ok(V_VT(&l1) == VT_UI8, "Expected .vt to be VT_UI8, was %u\n", V_VT(&l1));
+        ok(V_UI8(&l1) == lv, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(lv), wine_dbgstr_longlong(V_UI8(&l1)));
+        CComVariant l2 = l1;
+        ok(V_VT(&l2) == VT_UI8, "Expected .vt to be VT_UI8, was %u\n", V_VT(&l2));
+        ok(V_UI8(&l2) == lv, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(lv), wine_dbgstr_longlong(V_UI8(&l2)));
+    }
+    {
+        CY cy;
+        cy.int64 = 12030912309123ll;
+        CComVariant c1 = cy;
+        ok(V_VT(&c1) == VT_CY, "Expected .vt to be VT_I8, was %u\n", V_VT(&c1));
+        ok(V_CY(&c1).int64 == cy.int64, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(cy.int64), wine_dbgstr_longlong(V_CY(&c1).int64));
+        CComVariant c2 = c1;
+        ok(V_VT(&c2) == VT_CY, "Expected .vt to be VT_I8, was %u\n", V_VT(&c2));
+        ok(V_CY(&c2).int64 == cy.int64, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(cy.int64), wine_dbgstr_longlong(V_CY(&c2).int64));
+    }
+    // IDispatch
+    // IUnknown
+}
+
+static void test_misc()
+{
+    HRESULT hr;
+    {
+        CComVariant empty;
+        hr = empty.Clear();
+        ok(SUCCEEDED(hr), "Expected .Clear() to succeed, but it failed: 0x%lx\n", hr);
+        expect_empty(empty);
+    }
+
+    {
+        CComBSTR bstr(L"TESTW");
+        CComVariant olestr((LPCOLESTR)bstr), empty;
+
+        hr = empty.Copy(&olestr);   // VARIANT*
+        ok(SUCCEEDED(hr), "Expected .Copy() to succeed, but it failed: 0x%lx\n", hr);
+        ok(V_VT(&empty) == VT_BSTR, "Expected .vt to be VT_LPWSTR, was %u\n", V_VT(&empty));
+        ok(!wcscmp(V_BSTR(&empty), L"TESTW"), "Expected value to be L\"TESTW\", was: %s\n", wine_dbgstr_w(V_BSTR(&empty)));
+
+        /* Clear does not null out the rest, it just sets .vt! */
+        hr = olestr.Clear();
+        ok(SUCCEEDED(hr), "Expected .Clear() to succeed, but it failed: 0x%lx\n", hr);
+        ok(V_VT(&olestr) == VT_EMPTY, "Expected .vt to be VT_EMPTY, was %u\n", V_VT(&olestr));
+    }
+
+    {
+        CComVariant d1(3.4, VT_R8), empty;
+        hr = empty.Copy(&d1);
+        ok(SUCCEEDED(hr), "Expected .Copy() to succeed, but it failed: 0x%lx\n", hr);
+        expect_double(empty, 3.4, VT_R8);
+    }
+
+    {
+        LONGLONG lv = 12030912309123ll;
+        CComVariant l1(lv);
+        CComVariant empty;
+        hr = empty.Copy(&l1);
+        ok(SUCCEEDED(hr), "Expected .Copy() to succeed, but it failed: 0x%lx\n", hr);
+        ok(V_VT(&empty) == VT_I8, "Expected .vt to be VT_I8, was %u\n", V_VT(&empty));
+        ok(V_I8(&empty) == lv, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(lv), wine_dbgstr_longlong(V_I8(&empty)));
+    }
+
+    {
+        CY cy;
+        cy.int64 = 12030912309123ll;
+        CComVariant c1(cy);
+        CComVariant empty;
+        hr = empty.Copy(&c1);
+        ok(SUCCEEDED(hr), "Expected .Copy() to succeed, but it failed: 0x%lx\n", hr);
+        ok(V_VT(&empty) == VT_CY, "Expected .vt to be VT_I8, was %u\n", V_VT(&empty));
+        ok(V_CY(&empty).int64 == cy.int64, "Expected value to be %s, was: %s\n", wine_dbgstr_longlong(cy.int64), wine_dbgstr_longlong(V_CY(&empty).int64));
+    }
+    {
+        CComVariant var = (int)333;
+        CComVariant var2;
+        // var2 = var changed to bstr
+        HRESULT hr = var2.ChangeType(VT_BSTR, &var);
+        ok(SUCCEEDED(hr), "Expected .ChangeType() to succeed, but it failed: 0x%lx\n", hr);
+        expect_int(var, 333, VT_I4);
+        ok(V_VT(&var2) == VT_BSTR, "Expected .vt to be VT_LPWSTR, was %u\n", V_VT(&var2));
+        ok(!wcscmp(V_BSTR(&var2), L"333"), "Expected value to be L\"TESTW\", was: %s\n", wine_dbgstr_w(V_BSTR(&var2)));
+
+        // change in place
+        hr = var.ChangeType(VT_BSTR);
+        ok(SUCCEEDED(hr), "Expected .ChangeType() to succeed, but it failed: 0x%lx\n", hr);
+        ok(V_VT(&var) == VT_BSTR, "Expected .vt to be VT_LPWSTR, was %u\n", V_VT(&var));
+        ok(!wcscmp(V_BSTR(&var), L"333"), "Expected value to be L\"TESTW\", was: %s\n", wine_dbgstr_w(V_BSTR(&var)));
+    }
+}
+
+
+START_TEST(CComVariant)
+{
+    test_construction();
+    test_copyconstructor();
+    test_assign();
+    test_misc();
+}
index 802911c..6ca38ea 100644 (file)
@@ -1,5 +1,5 @@
 
-add_definitions(-DINITGUID)
+add_definitions(-DINITGUID -DWINETEST_USE_DBGSTR_LONGLONG)
 set_cpp(WITH_RUNTIME WITH_EXCEPTIONS)
 
 include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl)
@@ -8,6 +8,7 @@ add_executable(atl_apitest
     atltypes.cpp
     CComBSTR.cpp
     CComHeapPtr.cpp
+    CComVariant.cpp
     CImage.cpp
     CRegKey.cpp
     CSimpleArray.cpp
@@ -18,5 +19,5 @@ add_executable(atl_apitest
 
 target_link_libraries(atl_apitest wine uuid)
 set_module_type(atl_apitest win32cui)
-add_importlibs(atl_apitest rpcrt4 ole32 oleaut32 msimg32 gdi32 advapi32 user32 msvcrt kernel32)
+add_importlibs(atl_apitest rpcrt4 ole32 oleaut32 msimg32 gdi32 advapi32 user32 msvcrt kernel32 ntdll)
 add_cd_file(TARGET atl_apitest DESTINATION reactos/bin FOR all)
index bfeb9d0..f154b0d 100644 (file)
@@ -4,6 +4,7 @@
 extern void func_atltypes(void);
 extern void func_CComBSTR(void);
 extern void func_CComHeapPtr(void);
+extern void func_CComVariant(void);
 extern void func_CImage(void);
 extern void func_CRegKey(void);
 extern void func_CSimpleArray(void);
@@ -15,6 +16,7 @@ const struct test winetest_testlist[] =
     { "atltypes", func_atltypes },
     { "CComBSTR", func_CComBSTR },
     { "CComHeapPtr", func_CComHeapPtr },
+    { "CComVariant", func_CComVariant },
     { "CImage", func_CImage },
     { "CRegKey", func_CRegKey },
     { "CSimpleArray", func_CSimpleArray },