mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 20:59:54 +00:00
oleaut32: VarSub: Conformance test.
This commit is contained in:
parent
9634ffa7dc
commit
f10ed1f16e
@ -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);
|
||||
|
||||
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)); */
|
||||
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);
|
||||
|
||||
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";
|
||||
|
Loading…
Reference in New Issue
Block a user