[oleaut32 2/2] VarSub: Conformance test

Benjamin Arai me at benjaminarai.com
Thu Jul 27 19:19:59 CDT 2006


Skipped content of type multipart/alternative-------------- next part --------------
---
 dlls/oleaut32/tests/vartest.c |  242 +++++++++++++++++++++++++++++++++++++++--
 1 files changed, 231 insertions(+), 11 deletions(-)

diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c
index 3a14482..3bbcd66 100644
--- a/dlls/oleaut32/tests/vartest.c
+++ b/dlls/oleaut32/tests/vartest.c
@@ -2158,25 +2158,245 @@ static void test_VarNot(void)
     pcy->int64 = -1;
     VARNOT(CY,*pcy,I4,-1);
 }
+
 static HRESULT (WINAPI *pVarSub)(LPVARIANT,LPVARIANT,LPVARIANT);
 
+static const char *szVarSubI4 = "VarSub(%d,%d): expected 0x0,%d,%d, got 0x%lX,%d,%d\n";
+static const char *szVarSubR8 = "VarSub(%d,%d): expected 0x0,%d,%f, got 0x%lX,%d,%f\n";
+
+#define VARSUB(vt1,val1,vt2,val2,rvt,rval) \
+        V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
+        V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
+        memset(&result,0,sizeof(result)); hres = pVarSub(&left,&right,&result); \
+        if (VT_##rvt == VT_R4 || VT_##rvt == VT_R8 || VT_##rvt == VT_DATE) { \
+        ok(hres == S_OK && V_VT(&result) == VT_##rvt && \
+        EQ_FLOAT(V_##rvt(&result), rval), \
+        szVarSubR8, VT_##vt1, VT_##vt2, \
+        VT_##rvt, (double)(rval), hres, V_VT(&result), (double)V_##rvt(&result)); \
+        } else { \
+        ok(hres == S_OK && V_VT(&result) == VT_##rvt && V_##rvt(&result) == (rval), \
+        szVarSubI4, VT_##vt1, VT_##vt2, \
+        VT_##rvt, (int)(rval), hres, V_VT(&result), (int)V_##rvt(&result)); }
+
 static void test_VarSub(void)
 {
-    VARIANT va, vb, vc;
-    HRESULT hr;
+    static const WCHAR sz12[] = {'1','2','\0'};
+    VARIANT left, right, result, cy, dec;
+    VARTYPE i;
+    BSTR lbstr, rbstr;
+    HRESULT hres, expectedhres;
+    double r;
 
     CHECKPTR(VarSub);
 
-    V_VT(&va) = VT_DATE;
-    V_DATE(&va) = 200000.0;
-    V_VT(&vb) = VT_DATE;
-    V_DATE(&vb) = 100000.0;
+    lbstr = SysAllocString(sz12);
+    rbstr = SysAllocString(sz12);
+
+    VariantInit(&left);
+    VariantInit(&right);
+    VariantInit(&result);
+
+    /* Test all possible flag/vt combinations & the resulting vt type */
+    for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+    {
+
+        VARTYPE leftvt, rightvt, resvt;
+
+        for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
+        {
+
+            SKIPTESTS(leftvt);
+
+            for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
+            {
+
+                SKIPTESTS(rightvt);
+                expectedhres = S_OK;
+
+                memset(&left, 0, sizeof(left));
+                memset(&right, 0, sizeof(right));
+                V_VT(&left) = leftvt | ExtraFlags[i];
+                if (leftvt == VT_BSTR)
+                    V_BSTR(&left) = lbstr;
+                V_VT(&right) = rightvt | ExtraFlags[i];
+                if (rightvt == VT_BSTR)
+                    V_BSTR(&right) = rbstr;
+                V_VT(&result) = VT_EMPTY;
+                resvt = VT_ERROR;
+
+                /* All extra flags produce errors */
+                if (ExtraFlags[i] == (VT_VECTOR|VT_BYREF|VT_RESERVED) ||
+                    ExtraFlags[i] == (VT_VECTOR|VT_RESERVED) ||
+                    ExtraFlags[i] == (VT_VECTOR|VT_BYREF) ||
+                    ExtraFlags[i] == (VT_BYREF|VT_RESERVED) ||
+                    ExtraFlags[i] == VT_VECTOR ||
+                    ExtraFlags[i] == VT_BYREF ||
+                    ExtraFlags[i] == VT_RESERVED)
+                {
+                    expectedhres = DISP_E_BADVARTYPE;
+                    resvt = VT_EMPTY;
+                }
+                else if (ExtraFlags[i] >= VT_ARRAY)
+                {
+                    expectedhres = DISP_E_TYPEMISMATCH;
+                    resvt = VT_EMPTY;
+                }
+                /* Native VarSub cannot handle: VT_I1, VT_UI2, VT_UI4,
+                   VT_INT, VT_UINT and VT_UI8. Tested with WinXP */
+                else if (!IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
+                    !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
+                    leftvt == VT_CLSID || rightvt == VT_CLSID ||
+                    leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
+                    leftvt == VT_I1 || rightvt == VT_I1 ||
+                    leftvt == VT_UI2 || rightvt == VT_UI2 ||
+                    leftvt == VT_UI4 || rightvt == VT_UI4 ||
+                    leftvt == VT_UI8 || rightvt == VT_UI8 ||
+                    leftvt == VT_INT || rightvt == VT_INT ||
+                    leftvt == VT_UINT || rightvt == VT_UINT ||
+                    leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
+                    leftvt == VT_RECORD || rightvt == VT_RECORD)
+                {
+                    if (leftvt == VT_RECORD && rightvt == VT_I8)
+                        expectedhres = DISP_E_TYPEMISMATCH;
+                    else if (leftvt < VT_UI1 && rightvt == VT_RECORD)
+                        expectedhres = DISP_E_TYPEMISMATCH;
+                    else if (leftvt >= VT_UI1 && rightvt == VT_RECORD)
+                        expectedhres = DISP_E_TYPEMISMATCH;
+                    else if (leftvt == VT_RECORD && rightvt <= VT_UI1)
+                        expectedhres = DISP_E_TYPEMISMATCH;
+                    else if (leftvt == VT_RECORD && rightvt > VT_UI1)
+                        expectedhres = DISP_E_BADVARTYPE;
+                    else
+                        expectedhres = DISP_E_BADVARTYPE;
+                    resvt = VT_EMPTY;
+                }
+                else if ((leftvt == VT_NULL && rightvt == VT_DISPATCH) ||
+                    (leftvt == VT_DISPATCH && rightvt == VT_NULL))
+                    resvt = VT_NULL;
+                else if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
+                    leftvt == VT_ERROR || rightvt == VT_ERROR)
+                {
+                    resvt = VT_EMPTY;
+                    expectedhres = DISP_E_TYPEMISMATCH;
+                }
+                else if (leftvt == VT_NULL || rightvt == VT_NULL)
+                    resvt = VT_NULL;
+                else if ((leftvt == VT_EMPTY && rightvt == VT_BSTR) ||
+                    (leftvt == VT_DATE && rightvt == VT_DATE) ||
+                    (leftvt == VT_BSTR && rightvt == VT_EMPTY) ||
+                    (leftvt == VT_BSTR && rightvt == VT_BSTR))
+                    resvt = VT_R8;
+                else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
+                    resvt = VT_DECIMAL;
+                else if (leftvt == VT_DATE || rightvt == VT_DATE)
+                    resvt = VT_DATE;
+                else if (leftvt == VT_CY || rightvt == VT_CY)
+                    resvt = VT_CY;
+                else if (leftvt == VT_R8 || rightvt == VT_R8)
+                    resvt = VT_R8;
+                else if (leftvt == VT_BSTR || rightvt == VT_BSTR) {
+                    resvt = VT_R8;
+                } else if (leftvt == VT_R4 || rightvt == VT_R4) {
+                    if (leftvt == VT_I4 || rightvt == VT_I4 ||
+                        leftvt == VT_I8 || rightvt == VT_I8)
+                        resvt = VT_R8;
+                    else
+                        resvt = VT_R4;
+                }
+                else if (leftvt == VT_I8 || rightvt == VT_I8)
+                    resvt = VT_I8;
+                else if (leftvt == VT_I4 || rightvt == VT_I4)
+                    resvt = VT_I4;
+                else if (leftvt == VT_I2 || rightvt == VT_I2 ||
+                    leftvt == VT_BOOL || rightvt == VT_BOOL ||
+                    (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
+                    resvt = VT_I2;
+                else if (leftvt == VT_UI1 || rightvt == VT_UI1)
+                    resvt = VT_UI1;
+                else
+                {
+                    resvt = VT_EMPTY;
+                    expectedhres = DISP_E_TYPEMISMATCH;
+                }
+
+                hres = pVarSub(&left, &right, &result);
 
-    hr = pVarSub(&va, &vb, &vc);
-    ok(hr == S_OK,"VarSub of VT_DATE - VT_DATE failed with %lx\n", hr);
-    ok(V_VT(&vc) == VT_R8,"VarSub of VT_DATE - VT_DATE returned vt 0x%x\n", V_VT(&vc));
-    ok(((V_R8(&vc) >  99999.9) && (V_R8(&vc) < 100000.1)),"VarSub of VT_DATE - VT_DATE  should return 100000.0, but returned %g\n", V_R8(&vc));
-    /* fprintf(stderr,"VarSub of 10000-20000 returned: %g\n", V_R8(&vc)); */
+                ok(hres == expectedhres && V_VT(&result) == resvt,
+                    "VarSub: %d|0x%X, %d|0x%X: Expected failure 0x%lX, "
+                    "got 0x%lX, expected vt %d got vt %d\n",
+                    leftvt, ExtraFlags[i], rightvt, ExtraFlags[i],
+                    expectedhres, hres, resvt, V_VT(&result));
+            }
+        }
+    }
+
+    /* Test returned values */
+    VARSUB(I4,4,I4,2,I4,2);
+    VARSUB(I2,4,I2,2,I2,2);
+    VARSUB(I2,-13,I4,5,I4,-18);
+    VARSUB(I4,-13,I4,5,I4,-18);
+    VARSUB(I2,7,R4,0.5,R4,6.5);
+    VARSUB(R4,0.5,I4,5,R8,-4.5);
+    VARSUB(R8,7.1,BOOL,0,R8,7.1);
+    VARSUB(BSTR,lbstr,I2,4,R8,8);
+    VARSUB(BSTR,lbstr,BOOL,1,R8,11);
+    VARSUB(BSTR,lbstr,R4,0.1,R8,11.9);
+    VARSUB(R4,0.2,BSTR,rbstr,R8,-11.8);
+    VARSUB(DATE,2.25,I4,7,DATE,-4.75);
+    VARSUB(DATE,1.25,R4,-1.7,DATE,2.95);
+
+    VARSUB(UI1, UI1_MAX, UI1, UI1_MAX, UI1, 0);
+    VARSUB(I2, I2_MAX, I2, I2_MAX, I2, 0);
+    VARSUB(I2, I2_MIN, I2, I2_MIN, I2, 0);
+    VARSUB(I4, I4_MAX, I4, I4_MAX, I4, 0.0);
+    VARSUB(I4, I4_MIN, I4, I4_MIN, I4, 0.0);
+    VARSUB(R4, R4_MAX, R4, R4_MAX, R4, 0.0);
+    VARSUB(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX - R4_MIN);
+    VARSUB(R4, R4_MIN, R4, R4_MIN, R4, 0.0);
+    VARSUB(R8, R8_MAX, R8, R8_MIN, R8, R8_MAX - R8_MIN);
+    VARSUB(R8, R8_MIN, R8, R8_MIN, R8, 0.0);
+
+    /* Manually test BSTR + BSTR */
+    V_VT(&left) = VT_BSTR;
+    V_BSTR(&left) = lbstr;
+    V_VT(&right) = VT_BSTR;
+    V_BSTR(&right) = rbstr;
+    hres = VarSub(&left, &right, &result);
+    ok(hres == S_OK && V_VT(&result) == VT_R8,
+        "VarSub: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
+    ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 0),
+        "VarSub: BSTR + BSTR, expected %f got %f\n", 0.0, V_R8(&result));
+
+    /* Manually test some VT_CY and VT_DECIMAL variants */
+    V_VT(&cy) = VT_CY;
+    hres = VarCyFromI4(4711, &V_CY(&cy));
+    ok(hres == S_OK, "VarCyFromI4 failed!\n");
+    V_VT(&dec) = VT_DECIMAL;
+    hres = VarDecFromR8(-4.2, &V_DECIMAL(&dec));
+    ok(hres == S_OK, "VarDecFromR4 failed!\n");
+    memset(&left, 0, sizeof(left));
+    memset(&right, 0, sizeof(right));
+    V_VT(&left) = VT_I4;
+    V_I4(&left) = -11;
+    V_VT(&right) = VT_UI1;
+    V_UI1(&right) = 9;
+
+    hres = VarSub(&cy, &right, &result);
+    ok(hres == S_OK && V_VT(&result) == VT_CY,
+        "VarSub: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
+    hres = VarR8FromCy(V_CY(&result), &r);
+    ok(hres == S_OK && EQ_DOUBLE(r, 4702),
+        "VarSub: CY value %f, expected %f\n", r, (double)4720);
+
+    hres = VarSub(&left, &dec, &result);
+    ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
+        "VarSub: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
+    hres = VarR8FromDec(&V_DECIMAL(&result), &r);
+    ok(hres == S_OK && EQ_DOUBLE(r, -6.8),
+        "VarSub: DECIMAL value %f, expected %f\n", r, (double)-15.2);
+
+    SysFreeString(lbstr);
+    SysFreeString(rbstr);
 }
 
 static const char *szVarModFail = "VarMod: expected 0x%lx,%d(%s),%d, got 0x%lX,%d(%s),%d\n";
-- 
1.4.0


More information about the wine-patches mailing list