[PATCH v2 3/7] windows.media.speech: Add tests for IAsyncOperation.

Bernhard Kölbl besentv at gmail.com
Tue Apr 5 16:29:48 CDT 2022


Signed-off-by: Bernhard Kölbl <besentv at gmail.com>
---
v2: Test for status before adding a handler.
---
 dlls/windows.media.speech/tests/speech.c | 240 ++++++++++++++++++++++-
 1 file changed, 238 insertions(+), 2 deletions(-)

diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c
index 8093c4b95b8..a3866683016 100644
--- a/dlls/windows.media.speech/tests/speech.c
+++ b/dlls/windows.media.speech/tests/speech.c
@@ -38,6 +38,8 @@
 
 #include "wine/test.h"
 
+#define AsyncStatus_Closed 4
+
 #define SPERR_WINRT_INTERNAL_ERROR 0x800455a0
 
 #define IHandler_RecognitionResult ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionResultGeneratedEventArgs
@@ -52,6 +54,12 @@
 #define impl_from_IHandler_RecognitionCompleted impl_from_ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionCompletedEventArgs
 #define IHandler_RecognitionCompleted_iface ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionCompletedEventArgs_iface
 
+#define IAsyncHandler_Compilation IAsyncOperationCompletedHandler_SpeechRecognitionCompilationResult
+#define IAsyncHandler_CompilationVtbl IAsyncOperationCompletedHandler_SpeechRecognitionCompilationResultVtbl
+#define IID_IAsyncHandler_Compilation IID_IAsyncOperationCompletedHandler_SpeechRecognitionCompilationResult
+#define impl_from_IAsyncHandler_Compilation impl_from_IAsyncOperationCompletedHandler_SpeechRecognitionCompilationResult
+#define IAsyncHandler_Compilation_iface IAsyncOperationCompletedHandler_SpeechRecognitionCompilationResult_iface
+
 HRESULT WINAPI (*pDllGetActivationFactory)(HSTRING, IActivationFactory **);
 static BOOL is_win10_1507 = FALSE;
 
@@ -226,6 +234,87 @@ static HRESULT WINAPI recognition_result_handler_create_static( struct recogniti
     return S_OK;
 }
 
+struct compilation_handler
+{
+    IAsyncHandler_Compilation IAsyncHandler_Compilation_iface;
+    LONG ref;
+
+    HANDLE event_finished;
+    BOOLEAN sleeping;
+    DWORD thread_id;
+};
+
+static inline struct compilation_handler *impl_from_IAsyncHandler_Compilation( IAsyncHandler_Compilation *iface )
+{
+    return CONTAINING_RECORD(iface, struct compilation_handler, IAsyncHandler_Compilation_iface);
+}
+
+HRESULT WINAPI compilation_handler_QueryInterface( IAsyncHandler_Compilation *iface,
+                                                   REFIID iid,
+                                                   void **out )
+{
+    if (IsEqualGUID(iid, &IID_IUnknown) ||
+        IsEqualGUID(iid, &IID_IAgileObject) ||
+        IsEqualGUID(iid, &IID_IAsyncHandler_Compilation))
+    {
+        IUnknown_AddRef(iface);
+        *out = iface;
+        return S_OK;
+    }
+
+    trace("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+    *out = NULL;
+    return E_NOINTERFACE;
+}
+
+ULONG WINAPI compilation_handler_AddRef( IAsyncHandler_Compilation *iface )
+{
+    struct compilation_handler *impl = impl_from_IAsyncHandler_Compilation(iface);
+    ULONG ref = InterlockedIncrement(&impl->ref);
+    return ref;
+}
+
+ULONG WINAPI compilation_handler_Release( IAsyncHandler_Compilation *iface )
+{
+    struct compilation_handler *impl = impl_from_IAsyncHandler_Compilation(iface);
+    ULONG ref = InterlockedDecrement(&impl->ref);
+    return ref;
+}
+
+HRESULT WINAPI compilation_handler_Invoke( IAsyncHandler_Compilation *iface,
+                                           IAsyncOperation_SpeechRecognitionCompilationResult *info,
+                                           AsyncStatus status )
+{
+    struct compilation_handler *impl = impl_from_IAsyncHandler_Compilation(iface);
+    DWORD id = GetCurrentThreadId();
+    trace("Iface %p, info %p, status %d.\n", iface, info, status);
+    trace("Caller thread id %lu callback thread id %lu.\n", impl->thread_id, id);
+
+    ok(status != Started, "Got unexpected status %x.\n", status);
+    if (impl->event_finished) SetEvent(impl->event_finished);
+
+    return S_OK;
+}
+
+static const struct IAsyncHandler_CompilationVtbl compilation_handler_vtbl =
+{
+    /* IUnknown methods */
+    compilation_handler_QueryInterface,
+    compilation_handler_AddRef,
+    compilation_handler_Release,
+    /* IAsyncOperationCompletedHandler<SpeechRecognitionCompilationResult* > methods */
+    compilation_handler_Invoke
+};
+
+
+static HRESULT WINAPI compilation_handler_create_static( struct compilation_handler *impl )
+{
+    impl->IAsyncHandler_Compilation_iface.lpVtbl = &compilation_handler_vtbl;
+    impl->ref = 1;
+
+    return S_OK;
+}
+
 struct iterator_hstring
 {
     IIterator_HSTRING IIterator_HSTRING_iface;
@@ -421,8 +510,6 @@ static HRESULT WINAPI iterable_hstring_First( IIterable_HSTRING *iface, IIterato
     struct iterable_hstring *impl = impl_from_Iterable_HSTRING(iface);
     struct iterator_hstring *impl_iter = impl_from_IIterator_HSTRING(impl->iterator);
 
-    trace("iface %p, value %p.\n", iface, value);
-
     impl_iter->index = 0;
     IIterator_HSTRING_AddRef((*value = impl->iterator));
     return S_OK;
@@ -729,6 +816,9 @@ static void test_VoiceInformation(void)
 static void test_SpeechRecognizer(void)
 {
     static const WCHAR *speech_recognition_name = L"Windows.Media.SpeechRecognition.SpeechRecognizer";
+    IAsyncOperationCompletedHandler_SpeechRecognitionCompilationResult *handler = NULL;
+    IAsyncOperation_SpeechRecognitionCompilationResult *operation = NULL;
+    ISpeechRecognitionCompilationResult *compilation_result = NULL;
     IVector_ISpeechRecognitionConstraint *constraints = NULL;
     ISpeechContinuousRecognitionSession *session = NULL;
     ISpeechRecognizerFactory *sr_factory = NULL;
@@ -740,11 +830,17 @@ static void test_SpeechRecognizer(void)
     IInspectable *inspectable = NULL;
     IClosable *closable = NULL;
     ILanguage *language = NULL;
+    IAsyncInfo *info = NULL;
     struct completed_event_handler completed_handler;
     struct recognition_result_handler result_handler;
+    struct compilation_handler compilation_handler;
+    struct compilation_handler compilation_handler2;
+    SpeechRecognitionResultStatus result_status;
     EventRegistrationToken token = { .value = 0 };
+    AsyncStatus async_status;
     HSTRING hstr, hstr_lang;
     HRESULT hr;
+    UINT32 id;
     LONG ref;
 
     hr = RoInitialize(RO_INIT_MULTITHREADED);
@@ -848,6 +944,146 @@ static void test_SpeechRecognizer(void)
         ref = IVector_ISpeechRecognitionConstraint_Release(constraints);
         ok(ref == 1, "Got unexpected ref %lu.\n", ref);
 
+        compilation_handler_create_static(&compilation_handler);
+        compilation_handler.event_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
+        compilation_handler.thread_id = GetCurrentThreadId();
+
+        hr = ISpeechRecognizer_CompileConstraintsAsync(recognizer, &operation);
+        ok(hr == S_OK, "ISpeechRecognizer_CompileConstraintsAsync failed, hr %#lx.\n", hr);
+
+        handler = (void*)0xdeadbeef;
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_get_Completed(operation, &handler);
+        todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+        todo_wine ok(handler == NULL, "Handler had value %p.\n", handler);
+
+        if (FAILED(hr)) goto skip_operation;
+
+        compilation_result = (void*)0xdeadbeef;
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result);
+        todo_wine ok(hr == E_ILLEGAL_METHOD_CALL, "Got unexpected hr %#lx.\n", hr);
+        todo_wine ok(compilation_result == (void*)0xdeadbeef, "Compilation result had value %p.\n", compilation_result);
+
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler.IAsyncHandler_Compilation_iface);
+        todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+        todo_wine check_refcount(&compilation_handler.IAsyncHandler_Compilation_iface, 1);
+
+        WaitForSingleObject(compilation_handler.event_finished, INFINITE);
+        CloseHandle(compilation_handler.event_finished);
+
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, NULL);
+        todo_wine ok(hr == E_ILLEGAL_DELEGATE_ASSIGNMENT, "Got unexpected hr %#lx.\n", hr);
+
+        handler = (void*)0xdeadbeef;
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_get_Completed(operation, &handler);
+        todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+        todo_wine ok(handler == NULL, "Handler had value %p.\n", handler);
+
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result);
+        todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+        todo_wine check_interface(compilation_result, &IID_IAgileObject, TRUE);
+
+        hr = ISpeechRecognitionCompilationResult_get_Status(compilation_result, &result_status);
+        todo_wine ok(hr == S_OK, "ISpeechRecognitionCompilationResult_get_Status failed, hr %#lx.\n", hr);
+        todo_wine ok(result_status == SpeechRecognitionResultStatus_Success, "Got unexpected status %x.\n", result_status);
+
+        ref = ISpeechRecognitionCompilationResult_Release(compilation_result);
+        todo_wine ok(!ref , "Got unexpected ref %lu.\n", ref);
+
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result);
+        todo_wine ok(hr == E_UNEXPECTED, "Got unexpected hr %#lx.\n", hr);
+
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info);
+        todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+        /* Check if AsyncInfo and AsyncOperation share the same refcount. */
+        IAsyncOperation_SpeechRecognitionCompilationResult_AddRef(operation);
+        todo_wine check_refcount(operation, 3);
+        todo_wine check_refcount(info, 3);
+
+        IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
+        todo_wine check_refcount(info, 2);
+
+        id = 0xdeadbeef;
+        hr = IAsyncInfo_get_Id(info, &id);
+        todo_wine ok(hr == S_OK, "IAsyncInfo_get_Id failed, hr %#lx.\n", hr);
+        todo_wine ok(id != 0xdeadbeef, "Id was %x.\n", id);
+
+        async_status = 0xdeadbeef;
+        hr = IAsyncInfo_get_Status(info, &async_status);
+        todo_wine ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr);
+        todo_wine ok(async_status == Completed, "Status was %x.\n", async_status);
+
+        hr = IAsyncInfo_Cancel(info);
+        todo_wine ok(hr == S_OK, "IAsyncInfo_Cancel failed, hr %#lx.\n", hr);
+
+        async_status = 0xdeadbeef;
+        hr = IAsyncInfo_get_Status(info, &async_status);
+        todo_wine ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr);
+        todo_wine ok(async_status == Completed, "Status was %x.\n", async_status);
+
+        hr = IAsyncInfo_Close(info);
+        todo_wine ok(hr == S_OK, "IAsyncInfo_Close failed, hr %#lx.\n", hr);
+        hr = IAsyncInfo_Close(info);
+        todo_wine ok(hr == S_OK, "IAsyncInfo_Close failed, hr %#lx.\n", hr);
+
+        async_status = 0xdeadbeef;
+        hr = IAsyncInfo_get_Status(info, &async_status);
+        todo_wine ok(hr == E_ILLEGAL_METHOD_CALL, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr);
+        todo_wine ok(async_status == AsyncStatus_Closed, "Status was %x.\n", async_status);
+
+        ref = IAsyncInfo_Release(info);
+        todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref);
+
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, NULL);
+        todo_wine ok(hr == E_ILLEGAL_METHOD_CALL, "Got unexpected hr %#lx.\n", hr);
+
+        handler = (void*)0xdeadbeef;
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_get_Completed(operation, &handler);
+        todo_wine ok(hr == E_ILLEGAL_METHOD_CALL, "Got unexpected hr %#lx.\n", hr);
+
+        IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
+
+        /* Test if AsyncOperation is started immediately. */
+        compilation_handler_create_static(&compilation_handler2);
+        compilation_handler2.event_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
+        compilation_handler2.thread_id = GetCurrentThreadId();
+
+        ok(compilation_handler2.event_finished != NULL, "Finished event wasn't created.\n");
+
+        hr = ISpeechRecognizer_CompileConstraintsAsync(recognizer, &operation);
+        todo_wine ok(hr == S_OK, "ISpeechRecognizer_CompileConstraintsAsync failed, hr %#lx.\n", hr);
+        todo_wine check_interface(operation, &IID_IAgileObject, TRUE);
+
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_QueryInterface(operation, &IID_IAsyncInfo, (void **)&info);
+        todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+        compilation_result = (void*)0xdeadbeef;
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_GetResults(operation, &compilation_result);
+        todo_wine ok(hr == E_ILLEGAL_METHOD_CALL, "Got unexpected hr %#lx.\n", hr);
+        todo_wine ok(compilation_result == (void*)0xdeadbeef, "Compilation result had value %p.\n", compilation_result);
+
+        async_status = 0xdeadbeef;
+        hr = IAsyncInfo_get_Status(info, &async_status);
+        todo_wine ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr);
+        todo_wine ok(async_status == Started || async_status == Completed, "Status was %x.\n", async_status);
+
+        IAsyncInfo_Release(info);
+
+        hr = IAsyncOperation_SpeechRecognitionCompilationResult_put_Completed(operation, &compilation_handler2.IAsyncHandler_Compilation_iface);
+        todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+        WaitForSingleObject(compilation_handler2.event_finished, INFINITE);
+        CloseHandle(compilation_handler2.event_finished);
+
+        async_status = 0xdeadbeef;
+        hr = IAsyncInfo_get_Status(info, &async_status);
+        todo_wine ok(hr == S_OK, "IAsyncInfo_get_Status failed, hr %#lx.\n", hr);
+        todo_wine ok(async_status == Completed, "Status was %x.\n", async_status);
+
+skip_operation:
+        ref = IAsyncOperation_SpeechRecognitionCompilationResult_Release(operation);
+        ok(!ref, "Got unexpected ref %lu.\n", ref);
+
         ref = ISpeechContinuousRecognitionSession_Release(session);
         ok(ref == 1, "Got unexpected ref %lu.\n", ref);
 
-- 
2.35.1




More information about the wine-devel mailing list