From 2b8f479d2f589b7c6d6698f392664b2bfd704fab Mon Sep 17 00:00:00 2001 From: Austin Lund Date: Fri, 27 Jun 2008 22:40:51 +1000 Subject: [PATCH] richedit: Added conformance tests for txtsrv.c --- dlls/riched20/tests/Makefile.in | 5 +- dlls/riched20/tests/txtsrv.c | 521 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 524 insertions(+), 2 deletions(-) create mode 100644 dlls/riched20/tests/txtsrv.c diff --git a/dlls/riched20/tests/Makefile.in b/dlls/riched20/tests/Makefile.in index a3c4251..a4db8f1 100644 --- a/dlls/riched20/tests/Makefile.in +++ b/dlls/riched20/tests/Makefile.in @@ -3,11 +3,12 @@ TOPOBJDIR = ../../.. SRCDIR = @srcdir@ VPATH = @srcdir@ TESTDLL = riched20.dll -IMPORTS = uuid ole32 user32 gdi32 kernel32 +IMPORTS = ole32 user32 gdi32 kernel32 uuid riched20 CTESTS = \ editor.c \ - richole.c + richole.c \ + txtsrv.c @MAKE_TEST_RULES@ diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c new file mode 100644 index 0000000..3b686c4 --- /dev/null +++ b/dlls/riched20/tests/txtsrv.c @@ -0,0 +1,521 @@ +/* + * Unit test suite for windowless rich edit controls + * + * Copyright 2008 Austin Lund + * Copyright 2008 Maarten Lankhorst + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "config.h" +#include "wine/port.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/************************************************************************/ +/* ITextHost implementation for conformance testing. */ + +typedef struct ITextHostTestImpl { + ITextHostVtbl *lpVtbl; + LONG refCount; +} ITextHostTestImpl; + +static ITextHostVtbl itestvtbl; + +static HRESULT WINAPI ITextHostImpl_QueryInterface(ITextHost *iface, + REFIID riid, + LPVOID *ppvObject) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + *ppvObject = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ITextHost)) + *ppvObject = (LPVOID)This; + else + return E_NOINTERFACE; + + if (*ppvObject) + { + ITextHost_AddRef((ITextHost *)(*ppvObject)); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI ITextHostImpl_AddRef(ITextHost *iface) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->refCount); + return refCount; +} + +static ULONG WINAPI ITextHostImpl_Release(ITextHost *iface) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->refCount); + + if (!refCount) + { + CoTaskMemFree(This); + return 0; + } + else + return refCount; +} + +HDC WINAPI ITextHostImpl_TxGetDC(ITextHost *iface) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetDC\n", This); + return NULL; +} + +INT WINAPI ITextHostImpl_TxReleaseDC(ITextHost *iface, + HDC hdc) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxReleaseDC\n", This); + return 0; +} + +BOOL WINAPI ITextHostImpl_TxShowScrollBar(ITextHost *iface, + INT fnBar, + BOOL fShow) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxShowScrollBar\n", This); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxEnableScrollBar(ITextHost *iface, + INT fuSBFlags, + INT fuArrowflags) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxEnableScrollBar\n", This); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxSetScrollRange(ITextHost *iface, + INT fnBar, + LONG nMinPos, + INT nMaxPos, + BOOL fRedraw) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxSetScrollRange\n", This); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxSetScrollPos(ITextHost *iface, + INT fnBar, + INT nPos, + BOOL fRedraw) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxSetScrollPos\n", This); + return E_NOTIMPL; +} + +void WINAPI ITextHostImpl_TxInvalidateRect(ITextHost *iface, + LPCRECT prc, + BOOL fMode) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxInvalidateRect (prc %p, fMode %d)\n", + This, prc, fMode); +} + +void WINAPI ITextHostImpl_TxViewChange(ITextHost *iface, BOOL fUpdate) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxViewChange(fUpdate: %d)\n", + This, fUpdate); +} + +BOOL WINAPI ITextHostImpl_TxCreateCaret(ITextHost *iface, + HBITMAP hbmp, + INT xWidth, INT yHeight) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxCreateCaret\n", This); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxShowCaret(ITextHost *iface, BOOL fShow) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxShowCaret\n", This); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxSetCaretPos(ITextHost *iface, + INT x, INT y) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxSetCaretPos\n", This); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxSetTimer(ITextHost *iface, + UINT idTimer, UINT uTimeout) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxSetTimer\n", This); + return E_NOTIMPL; +} + +void WINAPI ITextHostImpl_TxKillTimer(ITextHost *iface, UINT idTimer) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxKillTimer\n", This); +} + +void WINAPI ITextHostImpl_TxScrollWindowEx(ITextHost *iface, + INT dx, INT dy, + LPCRECT lprcScroll, + LPCRECT lprcClip, + HRGN hRgnUpdate, + LPRECT lprcUpdate, + UINT fuScroll) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxScrollWindowEx\n", This); +} + +void WINAPI ITextHostImpl_TxSetCapture(ITextHost *iface, BOOL fCapture) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxSetCapture\n", This); +} + +void WINAPI ITextHostImpl_TxSetFocus(ITextHost *iface) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxSetFocus\n", This); +} + +void WINAPI ITextHostImpl_TxSetCursor(ITextHost *iface, + HCURSOR hcur, + BOOL fText) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxSetCursor\n", This); +} + +BOOL WINAPI ITextHostImpl_TxScreenToClient(ITextHost *iface, + LPPOINT lppt) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxScreenToClient\n", This); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxClientToScreen(ITextHost *iface, + LPPOINT lppt) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxClientToScreen\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxActivate(ITextHost *iface, + LONG *plOldState) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxActivate\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxDeactivate(ITextHost *iface, + LONG lNewState) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxDeactivate\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetClientRect(ITextHost *iface, + LPRECT prc) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetClientRect\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetViewInset(ITextHost *iface, + LPRECT prc) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetViewInset (prc %p)\n", This, prc); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetCharFormat(ITextHost *iface, + const CHARFORMATW **ppCF) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetCharFormat\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetParaFormat(ITextHost *iface, + const PARAFORMAT **ppPF) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetParaFormat\n", This); + return E_NOTIMPL; +} + +COLORREF WINAPI ITextHostImpl_TxGetSysColor(ITextHost *iface, + int nIndex) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetSysColor (nIndex %d)\n", This, nIndex); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetBackStyle(ITextHost *iface, + TXTBACKSTYLE *pStyle) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetBackStyle\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetMaxLength(ITextHost *iface, + DWORD *plength) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetMaxLength\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetScrollbars(ITextHost *iface, + DWORD *pdwScrollBar) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetScrollbars\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetPasswordChar(ITextHost *iface, + WCHAR *pch) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetPasswordChar\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetAcceleratorPos(ITextHost *iface, + LONG *pch) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetAcceleratorPos\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetExtent(ITextHost *iface, + LPSIZEL lpExtent) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetExtent (lpExtent %p)\n", + This, lpExtent); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_OnTxCharFormatChange(ITextHost *iface, + const CHARFORMATW *pcf) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to OnTxCharFormatChange\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_OnTxParaFormatChange(ITextHost *iface, + const PARAFORMAT *ppf) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to OnTxParaFormatChange\n", This); + return E_NOTIMPL; +} + +/* This must return S_OK for the native ITextServices object to + initialize. */ +HRESULT WINAPI ITextHostImpl_TxGetPropertyBits(ITextHost *iface, + DWORD dwMask, + DWORD *pdwBits) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetPropertyBits (dwMask 0x%08x)\n", + This, dwMask); + *pdwBits = 0; + return S_OK; +} + +HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, + void *pv) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxNotify (iNotify %d, pv %p)\n", This, iNotify, pv); + return E_NOTIMPL; +} + +HIMC WINAPI ITextHostImpl_TxImmGetContext(ITextHost *iface) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxImmGetContext\n", This); + return 0; +} + +void WINAPI ITextHostImpl_TxImmReleaseContext(ITextHost *iface, HIMC himc) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxImmReleaseContext\n", This); +} + +HRESULT WINAPI ITextHostImpl_TxGetSelectionBarWidth(ITextHost *iface, + LONG *lSelBarWidth) { + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + trace("(%p) Call to TxGetSelectionBarWidth (lSelBarWidth %p)\n", + This, lSelBarWidth); + return E_NOTIMPL; +} + +/* Each function must now be converted into a thiscall style function. + * These wrappers do this. */ + +/* In order to call thiscall functions using stdcall, the values + * passed via the registers are pushed onto the stack. The return + * pointer needs to be bypassed to maintain the intergrity of the + * stack. + */ + +#ifdef __i386__ /* thiscall functions are i386-specific */ + +#define THISCALL(func) __thiscall_ ## func +#define DEFINE_THISCALL_WRAPPER(func) \ + extern typeof(func) THISCALL(func); \ + __ASM_GLOBAL_FUNC(__thiscall_ ## func, \ + "popl %eax\n\t" \ + "pushl %ecx\n\t" \ + "pushl %eax\n\t" \ + "jmp " __ASM_NAME(#func) ) +#else /* __i386__ */ + +#define THISCALL(func) func +#define DEFINE_THISCALL_WRAPPER(func) /* nothing */ + +#endif /* __i386__ */ + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollbars) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth) + +static ITextHostVtbl itestvtbl = { + ITextHostImpl_QueryInterface, + ITextHostImpl_AddRef, + ITextHostImpl_Release, + THISCALL(ITextHostImpl_TxGetDC), + THISCALL(ITextHostImpl_TxReleaseDC), + THISCALL(ITextHostImpl_TxShowScrollBar), + THISCALL(ITextHostImpl_TxEnableScrollBar), + THISCALL(ITextHostImpl_TxSetScrollRange), + THISCALL(ITextHostImpl_TxSetScrollPos), + THISCALL(ITextHostImpl_TxInvalidateRect), + THISCALL(ITextHostImpl_TxViewChange), + THISCALL(ITextHostImpl_TxCreateCaret), + THISCALL(ITextHostImpl_TxShowCaret), + THISCALL(ITextHostImpl_TxSetCaretPos), + THISCALL(ITextHostImpl_TxSetTimer), + THISCALL(ITextHostImpl_TxKillTimer), + THISCALL(ITextHostImpl_TxScrollWindowEx), + THISCALL(ITextHostImpl_TxSetCapture), + THISCALL(ITextHostImpl_TxSetFocus), + THISCALL(ITextHostImpl_TxSetCursor), + THISCALL(ITextHostImpl_TxScreenToClient), + THISCALL(ITextHostImpl_TxClientToScreen), + THISCALL(ITextHostImpl_TxActivate), + THISCALL(ITextHostImpl_TxDeactivate), + THISCALL(ITextHostImpl_TxGetClientRect), + THISCALL(ITextHostImpl_TxGetViewInset), + THISCALL(ITextHostImpl_TxGetCharFormat), + THISCALL(ITextHostImpl_TxGetParaFormat), + THISCALL(ITextHostImpl_TxGetSysColor), + THISCALL(ITextHostImpl_TxGetBackStyle), + THISCALL(ITextHostImpl_TxGetMaxLength), + THISCALL(ITextHostImpl_TxGetScrollbars), + THISCALL(ITextHostImpl_TxGetPasswordChar), + THISCALL(ITextHostImpl_TxGetAcceleratorPos), + THISCALL(ITextHostImpl_TxGetExtent), + THISCALL(ITextHostImpl_OnTxCharFormatChange), + THISCALL(ITextHostImpl_OnTxParaFormatChange), + THISCALL(ITextHostImpl_TxGetPropertyBits), + THISCALL(ITextHostImpl_TxNotify), + THISCALL(ITextHostImpl_TxImmGetContext), + THISCALL(ITextHostImpl_TxImmReleaseContext), + THISCALL(ITextHostImpl_TxGetSelectionBarWidth) +}; + +ITextServices *txtserv = NULL; +ITextHostTestImpl *dummyTextHost; + +/*************************************************************************/ +/* Conformance test functions. */ + +/* Initialize the test texthost structure */ +BOOL init_texthost() { + IUnknown *init; + HRESULT result; + + dummyTextHost = CoTaskMemAlloc(sizeof(*dummyTextHost)); + if (dummyTextHost == NULL) { + skip("Insufficient memory to create ITextHost interface\n"); + return FALSE; + } + dummyTextHost->lpVtbl = &itestvtbl; + dummyTextHost->refCount = 1; + + /* MSDN states that an IUnknown object is returned by + CreateTextServices which is then queried to obtain a + ITextServices object. */ + result = CreateTextServices(NULL,(ITextHost*)dummyTextHost, &init); + ok(result == S_OK, "Did not return OK when created. Returned %x\n", result); + if (result != S_OK) { + skip("CreateTextServices failed.\n"); + return FALSE; + } + + result = IUnknown_QueryInterface(init, &IID_ITextServices, + (void **) &(txtserv)); + ok((result == S_OK) && (txtserv != NULL), "Querying interface failed\n"); + if (!((result == S_OK) && (txtserv != NULL))) { + skip("Could not retrieve ITextServices interface\n"); + return FALSE; + } + + return TRUE; +} + +START_TEST( txtsrv ) +{ + if (!init_texthost()) + return; +} -- 1.5.4.3