Restructured the controls tests to allow for more flexibility and implemented that on Windows. Now I can start building ad-hoc controls in tests.

This commit is contained in:
Pietro Gagliardi 2022-07-30 18:40:10 -04:00
parent 79d8eb534e
commit c241e8676a
4 changed files with 157 additions and 116 deletions

View File

@ -1,34 +1,72 @@
// 8 june 2019
#include "test.h"
static bool vtableNopInit(uiControl *c, void *implData, void *initData)
static bool testControlInit(uiControl *c, void *implData, void *initData)
{
struct testControlImplData *ti = (struct testControlImplData *) implData;
struct testControlImplData *tinit = (struct testControlImplData *) initData;
if (tinit == NULL)
return true;
*ti = *tinit;
if (ti->realVtable != NULL && ti->realVtable->Init != NULL)
return (*(ti->realVtable->Init))(c, ti->realImplData, initData);
return true;
}
static void testControlFree(uiControl *c, void *implData)
{
struct testControlImplData *ti = (struct testControlImplData *) implData;
if (ti->realVtable != NULL && ti->realVtable->Free != NULL)
(*(ti->realVtable->Free))(c, ti->realImplData);
}
static void testControlParentChanging(uiControl *c, void *implData, uiControl *oldParent)
{
struct testControlImplData *ti = (struct testControlImplData *) implData;
if (ti->realVtable != NULL && ti->realVtable->ParentChanging != NULL)
(*(ti->realVtable->ParentChanging))(c, ti->realImplData, oldParent);
}
static void testControlParentChanged(uiControl *c, void *implData, uiControl *newParent)
{
struct testControlImplData *ti = (struct testControlImplData *) implData;
if (ti->realVtable != NULL && ti->realVtable->ParentChanged != NULL)
(*(ti->realVtable->ParentChanged))(c, ti->realImplData, newParent);
}
static const uiControlVtable vtable = {
.Size = sizeof (uiControlVtable),
.Init = testControlInit,
.Free = testControlFree,
.ParentChanging = testControlParentChanging,
.ParentChanged = testControlParentChanged,
};
const uiControlVtable *testControlVtable(void)
{
return &vtable;
}
// the following are kludges for just these first two tests
static bool nopInit(uiControl *c, void *implData, void *initData)
{
return true;
}
static void vtableNopFree(uiControl *c, void *implData)
static void nopFree(uiControl *c, void *implData)
{
// do nothing
}
static void vtableNopParentChanging(uiControl *c, void *implData, uiControl *oldParent)
static void testControlVtableWithNopInitFree(uiControlVtable *vt)
{
// do nothing
}
static void vtableNopParentChanged(uiControl *c, void *implData, uiControl *newParent)
{
// do nothing
}
void testControlLoadNopVtable(uiControlVtable *vtable)
{
memset(vtable, 0, sizeof (uiControlVtable));
vtable->Size = sizeof (uiControlVtable);
vtable->Init = vtableNopInit;
vtable->Free = vtableNopFree;
vtable->ParentChanging = vtableNopParentChanging;
vtable->ParentChanged = vtableNopParentChanged;
*vt = vtable;
vt->Init = nopInit;
vt->Free = nopFree;
}
// TODO we'll have to eventually find out for real if memset(0) is sufficient to set pointers to NULL or not; C99 doesn't seem to say
@ -40,8 +78,8 @@ Test(ControlImplDataIsClearedOnNewControl)
uiControl *c;
char *implData;
testControlLoadNopVtable(&vt);
type = uiRegisterControlType("TestControl", &vt, testOSVtable(), sizeof (memory));
testControlVtableWithNopInitFree(&vt);
type = uiRegisterControlType("TestControl", &vt, testControlOSVtable(), sizeof (memory));
c = uiNewControl(type, NULL);
implData = (char *) uiControlImplData(c);
memset(memory, 0, sizeof (memory));
@ -56,14 +94,32 @@ Test(ZeroSizeImplDataIsNULL)
uint32_t type;
uiControl *c;
testControlLoadNopVtable(&vt);
type = uiRegisterControlType("TestControl", &vt, testOSVtable(), 0);
testControlVtableWithNopInitFree(&vt);
type = uiRegisterControlType("TestControl", &vt, testControlOSVtable(), 0);
c = uiNewControl(type, NULL);
if (uiControlImplData(c) != NULL)
TestErrorf("control impl data is non-NULL despite being of size 0");
uiControlFree(c);
}
uint32_t testControlType(void)
{
static uint32_t type = 0;
if (type == 0)
type = uiRegisterControlType("TestControl", testControlVtable(), testControlOSVtable(), sizeof (struct testControlImplData));
return type;
}
static uint32_t testControlType2(void)
{
static uint32_t type = 0;
if (type == 0)
type = uiRegisterControlType("TestControl2", testControlVtable(), testControlOSVtable(), sizeof (struct testControlImplData));
return type;
}
struct counts {
unsigned int countInit;
unsigned int countFree;
@ -73,101 +129,65 @@ struct counts {
uiControl *newParent;
};
struct testImplData {
struct counts *counts;
};
static struct counts failInit;
static void *testControlFailInit = &failInit;
static bool testVtableInit(uiControl *c, void *implData, void *initData)
static bool countsInit(uiControl *c, void *implData, void *initData)
{
struct testImplData *d = (struct testImplData *) implData;
struct counts *counts = (struct counts *) initData;
struct counts *counts = (struct counts *) implData;
if (initData == testControlFailInit)
return false;
if (initData == NULL)
return true;
if (d->counts == NULL)
d->counts = counts;
d->counts->countInit++;
if (d->counts->countInit > 2)
d->counts->countInit = 2;
counts->countInit++;
if (counts->countInit > 2)
counts->countInit = 2;
return true;
}
static void testVtableFree(uiControl *c, void *implData)
static void countsFree(uiControl *c, void *implData)
{
struct testImplData *d = (struct testImplData *) implData;
struct counts *counts = (struct counts *) implData;
if (d->counts != NULL) {
d->counts->countFree++;
if (d->counts->countFree > 2)
d->counts->countFree = 2;
}
counts->countFree++;
if (counts->countFree > 2)
counts->countFree = 2;
}
static void testVtableParentChanging(uiControl *c, void *implData, uiControl *oldParent)
static void countsParentChanging(uiControl *c, void *implData, uiControl *oldParent)
{
struct testImplData *d = (struct testImplData *) implData;
struct counts *counts = (struct counts *) implData;
if (d->counts != NULL) {
d->counts->oldParent = oldParent;
d->counts->countParentChanging++;
if (d->counts->countParentChanging > 3)
d->counts->countParentChanging = 3;
}
counts->oldParent = oldParent;
counts->countParentChanging++;
if (counts->countParentChanging > 3)
counts->countParentChanging = 3;
}
static void testVtableParentChanged(uiControl *c, void *implData, uiControl *newParent)
static void countsParentChanged(uiControl *c, void *implData, uiControl *newParent)
{
struct testImplData *d = (struct testImplData *) implData;
struct counts *counts = (struct counts *) implData;
if (d->counts != NULL) {
d->counts->newParent = newParent;
d->counts->countParentChanged++;
if (d->counts->countParentChanged > 3)
d->counts->countParentChanged = 3;
}
counts->newParent = newParent;
counts->countParentChanged++;
if (counts->countParentChanged > 3)
counts->countParentChanged = 3;
}
static const uiControlVtable vtable = {
.Size = sizeof (uiControlVtable),
.Init = testVtableInit,
.Free = testVtableFree,
.ParentChanging = testVtableParentChanging,
.ParentChanged = testVtableParentChanged,
static const uiControlVtable countsVtable = {
.Init = countsInit,
.Free = countsFree,
.ParentChanging = countsParentChanging,
.ParentChanged = countsParentChanged,
};
static uint32_t testControlType(void)
{
static uint32_t type = 0;
if (type == 0)
type = uiRegisterControlType("TestControl", &vtable, testOSVtable(), sizeof (struct testImplData));
return type;
}
static uint32_t testControlType2(void)
{
static uint32_t type = 0;
if (type == 0)
type = uiRegisterControlType("TestControl2", &vtable, testOSVtable(), sizeof (struct testImplData));
return type;
}
// TODO do this but for the OS-specific methods
Test(ControlMethodsCalled)
{
uiControl *c, *d;
struct testControlImplData initData;
struct counts counts;
memset(&counts, 0, sizeof (struct counts));
c = uiNewControl(testControlType(), &counts);
initData.realVtable = &countsVtable;
initData.realOSVtable = NULL;
initData.realImplData = &counts;
c = uiNewControl(testControlType(), &initData);
switch (counts.countInit) {
case 0:
TestErrorf("Init() was not called");
@ -458,14 +478,24 @@ Test(NewControlOfUnknownTypeIsProgrammerError)
endCheckProgrammerError(ctx);
}
static bool alwaysFailInit(uiControl *c, void *implData, void *initData)
{
return false;
}
Test(NewControlWithInvalidInitDataIsProgrammerError)
{
uint32_t ctrlType;
struct testControlImplData initData;
uiControlVtable vtable;
void *ctx;
ctrlType = testControlType();
ctx = beginCheckProgrammerError("uiNewControl(): invalid init data for TestControl");
uiNewControl(ctrlType, testControlFailInit);
memset(&vtable, 0, sizeof (uiControlVtable));
vtable.Init = alwaysFailInit;
initData.realVtable = &vtable;
uiNewControl(ctrlType, &initData);
endCheckProgrammerError(ctx);
}

View File

@ -1,86 +1,90 @@
// 10 june 2019
#include "test_windows.h"
static HWND osVtableNopHandle(uiControl *c, void *implData)
static HWND testControlHandle(uiControl *c, void *implData)
{
struct testControlImplData *ti = (struct testControlImplData *) implData;
if (ti->realOSVtable != NULL && ti->realOSVtable->Handle != NULL)
return (*(ti->realOSVtable->Handle))(c, ti->realImplData);
return NULL;
}
static HWND osVtableNopParentHandleForChild(uiControl *c, void *implData, uiControl *child)
static HWND testControlParentHandleForChild(uiControl *c, void *implData, uiControl *child)
{
struct testControlImplData *ti = (struct testControlImplData *) implData;
if (ti->realOSVtable != NULL && ti->realOSVtable->ParentHandleForChild != NULL)
return (*(ti->realOSVtable->ParentHandleForChild))(c, ti->realImplData, child);
return NULL;
}
HRESULT osVtableNopSetControlPos(uiControl *c, void *implData, const RECT *r)
static HRESULT testControlSetControlPos(uiControl *c, void *implData, const RECT *r)
{
struct testControlImplData *ti = (struct testControlImplData *) implData;
if (ti->realOSVtable != NULL && ti->realOSVtable->SetControlPos != NULL)
return (*(ti->realOSVtable->SetControlPos))(c, ti->realImplData, r);
return S_OK;
}
static const uiControlOSVtable osVtable = {
.Size = sizeof (uiControlOSVtable),
.Handle = osVtableNopHandle,
.ParentHandleForChild = osVtableNopParentHandleForChild,
.SetControlPos = osVtableNopSetControlPos,
.Handle = testControlHandle,
.ParentHandleForChild = testControlParentHandleForChild,
.SetControlPos = testControlSetControlPos,
};
const uiControlOSVtable *testOSVtable(void)
const uiControlOSVtable *testControlOSVtable(void)
{
return &osVtable;
}
Test(WrongControlOSVtableSizeIsProgrammerError)
{
uiControlVtable vtable;
uiControlOSVtable osvt;
void *ctx;
testControlLoadNopVtable(&vtable);
ctx = beginCheckProgrammerError("uiRegisterControlType(): wrong size 1 for uiControlOSVtable");
memset(&osvt, 0, sizeof (uiControlOSVtable));
osvt.Size = 1;
uiRegisterControlType("name", &vtable, &osvt, 0);
uiRegisterControlType("name", testControlVtable(), &osvt, 0);
endCheckProgrammerError(ctx);
}
Test(ControlOSVtableWithMissingHandleMethodIsProgrammerError)
{
uiControlVtable vtable;
uiControlOSVtable osvt;
void *ctx;
testControlLoadNopVtable(&vtable);
ctx = beginCheckProgrammerError("uiRegisterControlType(): required uiControlOSVtable method Handle() missing for uiControl type name");
osvt = osVtable;
osvt.Handle = NULL;
uiRegisterControlType("name", &vtable, &osvt, 0);
uiRegisterControlType("name", testControlVtable(), &osvt, 0);
endCheckProgrammerError(ctx);
}
Test(ControlOSVtableWithMissingParentHandleForChildMethodIsProgrammerError)
{
uiControlVtable vtable;
uiControlOSVtable osvt;
void *ctx;
testControlLoadNopVtable(&vtable);
ctx = beginCheckProgrammerError("uiRegisterControlType(): required uiControlOSVtable method ParentHandleForChild() missing for uiControl type name");
osvt = osVtable;
osvt.ParentHandleForChild = NULL;
uiRegisterControlType("name", &vtable, &osvt, 0);
uiRegisterControlType("name", testControlVtable(), &osvt, 0);
endCheckProgrammerError(ctx);
}
Test(ControlOSVtableWithMissingSetControlPosMethodIsProgrammerError)
{
uiControlVtable vtable;
uiControlOSVtable osvt;
void *ctx;
testControlLoadNopVtable(&vtable);
ctx = beginCheckProgrammerError("uiRegisterControlType(): required uiControlOSVtable method SetControlPos() missing for uiControl type name");
osvt = osVtable;
osvt.SetControlPos = NULL;
uiRegisterControlType("name", &vtable, &osvt, 0);
uiRegisterControlType("name", testControlVtable(), &osvt, 0);
endCheckProgrammerError(ctx);
}
@ -113,15 +117,14 @@ Test(SettingWindowsControlPosOfNullControlIsProgrammerError)
Test(SettingWindowsControlPosToNullRectIsProgrammerError)
{
#if 0
// TODO
uiControl *c;
void *ctx;
c = uiNewControl(testControlType(), NULL);
ctx = beginCheckProgrammerError("uiWindowsControlSetControlPos(): invalid null pointer for RECT");
uiWindowsControlSetControlPos(c, NULL);
endCheckProgrammerError(ctx);
#endif
uiControlFree(c);
}
// TODO uiWindowsSetControlHandlePos errors

View File

@ -84,8 +84,14 @@ extern void endCheckProgrammerErrorFull(const char *file, long line, void *conte
#define endCheckProgrammerError(context) endCheckProgrammerErrorFull(__FILE__, __LINE__, context)
// controls.c
extern void testControlLoadNopVtable(uiControlVtable *vtable);
extern const uiControlOSVtable *testOSVtable(void);
struct testControlImplData {
const uiControlVtable *realVtable;
const uiControlOSVtable *realOSVtable;
void *realImplData;
};
extern const uiControlVtable *testControlVtable(void);
extern const uiControlOSVtable *testControlOSVtable(void);
extern uint32_t testControlType(void);
// utf8.c
extern const char testUTF8Empty[];

View File

@ -81,6 +81,8 @@ HRESULT uiWindowsControlSetControlPos(uiControl *c, const RECT *r)
HRESULT uiWindowsSetControlHandlePos(HWND hwnd, const RECT *r)
{
if (!uiprivCheckInitializedAndThread())
return E_FAIL;
// TODO
return S_OK;
}