[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