[PATCH 2/5] ole32/tests: Add some ComposeWith() tests with antimoniker at the right side.

Nikolay Sivov nsivov at codeweavers.com
Wed Jan 29 07:57:01 CST 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/ole32/tests/moniker.c | 329 ++++++++++++++++++++++++++++---------
 1 file changed, 248 insertions(+), 81 deletions(-)

diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c
index 0e6f2677c5..f5f69870bf 100644
--- a/dlls/ole32/tests/moniker.c
+++ b/dlls/ole32/tests/moniker.c
@@ -70,6 +70,56 @@ DEFINE_OLEGUID(CLSID_CompositeMoniker, 0x309, 0, 0);
 DEFINE_OLEGUID(CLSID_ClassMoniker,     0x31a, 0, 0);
 DEFINE_OLEGUID(CLSID_PointerMoniker,   0x306, 0, 0);
 
+#define EXPECT_REF(obj,ref) _expect_ref((IUnknown *)obj, ref, __LINE__)
+static void _expect_ref(IUnknown* obj, ULONG ref, int line)
+{
+    ULONG refcount;
+    IUnknown_AddRef(obj);
+    refcount = IUnknown_Release(obj);
+    ok_(__FILE__, line)(refcount == ref, "Unexpected got %u.\n", refcount);
+}
+
+#define TEST_MONIKER_TYPE_TODO(m,t) _test_moniker_type(m, t, TRUE, __LINE__)
+#define TEST_MONIKER_TYPE(m,t) _test_moniker_type(m, t, FALSE, __LINE__)
+static void _test_moniker_type(IMoniker *moniker, DWORD type, BOOL todo, int line)
+{
+    DWORD type2;
+    HRESULT hr;
+
+    hr = IMoniker_IsSystemMoniker(moniker, &type2);
+    ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#x.\n", hr);
+todo_wine_if(todo)
+    ok_(__FILE__, line)(type2 == type, "Unexpected moniker type %d.\n", type2);
+}
+
+static IMoniker *create_antimoniker(DWORD level)
+{
+    LARGE_INTEGER pos;
+    IMoniker *moniker;
+    IStream *stream;
+    HRESULT hr;
+
+    hr = CreateAntiMoniker(&moniker);
+    ok(hr == S_OK, "Failed to create antimoniker, hr %#x.\n", hr);
+
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr);
+
+    hr = IStream_Write(stream, &level, sizeof(level), NULL);
+    ok(hr == S_OK, "Failed to write contents, hr %#x.\n", hr);
+
+    pos.QuadPart = 0;
+    hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
+    ok(hr == S_OK, "Failed to rewind, hr %#x.\n", hr);
+
+    hr = IMoniker_Load(moniker, stream);
+    ok(hr == S_OK, "Failed to load, hr %#x.\n", hr);
+
+    IStream_Release(stream);
+
+    return moniker;
+}
+
 static LONG cLocks;
 
 static void LockModule(void)
@@ -994,7 +1044,6 @@ static void test_MkParseDisplayName(void)
     DWORD pdwReg1=0;
     DWORD grflags=0;
     DWORD pdwReg2=0;
-    DWORD moniker_type;
     IRunningObjectTable * pprot=NULL;
 
     /* CLSID of My Computer */
@@ -1086,8 +1135,7 @@ todo_wine
         "Processed character count should have been 43 instead of %u\n", eaten);
     if (pmk)
     {
-        IMoniker_IsSystemMoniker(pmk, &moniker_type);
-        ok(moniker_type == MKSYS_CLASSMONIKER, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type);
+        TEST_MONIKER_TYPE(pmk, MKSYS_CLASSMONIKER);
         IMoniker_Release(pmk);
     }
     hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
@@ -1108,8 +1156,7 @@ todo_wine
         "Processed character count should have been 15 instead of %u\n", eaten);
     if (pmk)
     {
-        IMoniker_IsSystemMoniker(pmk, &moniker_type);
-        ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
+        TEST_MONIKER_TYPE(pmk, MKSYS_FILEMONIKER);
         IMoniker_Release(pmk);
     }
     hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
@@ -1126,8 +1173,7 @@ todo_wine
         "Processed character count should have been 8 instead of %u\n", eaten);
     if (pmk)
     {
-        IMoniker_IsSystemMoniker(pmk, &moniker_type);
-        ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
+        TEST_MONIKER_TYPE(pmk, MKSYS_ANTIMONIKER);
         IMoniker_Release(pmk);
     }
 
@@ -1138,8 +1184,7 @@ todo_wine
         "Processed character count should have been 8 instead of %u\n", eaten);
     if (pmk)
     {
-        IMoniker_IsSystemMoniker(pmk, &moniker_type);
-        ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
+        TEST_MONIKER_TYPE(pmk, MKSYS_ANTIMONIKER);
         IMoniker_Release(pmk);
     }
 
@@ -1163,8 +1208,7 @@ todo_wine
     ok(eaten == len - 1, "Processed character count should have been %d instead of %u\n", len - 1, eaten);
     if (pmk)
     {
-        IMoniker_IsSystemMoniker(pmk, &moniker_type);
-        ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
+        TEST_MONIKER_TYPE(pmk, MKSYS_FILEMONIKER);
         IMoniker_Release(pmk);
     }
 
@@ -1717,10 +1761,9 @@ todo_wine_if(moniker_type == MKSYS_GENERICCOMPOSITE)
 
 static void test_class_moniker(void)
 {
-    IMoniker *moniker, *inverse, *reduced;
+    IMoniker *moniker, *moniker2, *inverse, *reduced, *anti;
     IEnumMoniker *enummoniker;
     HRESULT hr;
-    DWORD moniker_type;
     DWORD hash;
     IBindCtx *bindctx;
     IUnknown *unknown;
@@ -1754,13 +1797,7 @@ todo_wine
         hash);
 
     /* IsSystemMoniker test */
-
-    hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
-    ok_ole_success(hr, IMoniker_IsSystemMoniker);
-
-    ok(moniker_type == MKSYS_CLASSMONIKER,
-        "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
-        moniker_type);
+    TEST_MONIKER_TYPE(moniker, MKSYS_CLASSMONIKER);
 
     hr = CreateBindCtx(0, &bindctx);
     ok_ole_success(hr, CreateBindCtx);
@@ -1785,9 +1822,7 @@ todo_wine
 
     hr = IMoniker_Inverse(moniker, &inverse);
     ok(hr == S_OK, "Failed to get inverse, hr %#x.\n", hr);
-    hr = IMoniker_IsSystemMoniker(inverse, &moniker_type);
-    ok(hr == S_OK, "Failed to get moniker type, hr %#x.\n", hr);
-    ok(moniker_type == MKSYS_ANTIMONIKER, "Unexpected moniker type %d.\n", moniker_type);
+    TEST_MONIKER_TYPE(inverse, MKSYS_ANTIMONIKER);
     IMoniker_Release(inverse);
 
     /* Reduce() */
@@ -1813,17 +1848,33 @@ todo_wine
 
     IBindCtx_Release(bindctx);
 
+    /* ComposeWith() */
+
+    /* C + A -> () */
+    anti = create_antimoniker(1);
+    hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
+    ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
+    ok(!moniker2, "Unexpected pointer.\n");
+    IMoniker_Release(anti);
+
+    /* C + A2 -> A */
+    anti = create_antimoniker(2);
+    hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
+    ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
+    ok(!moniker2, "Unexpected pointer.\n");
+    IMoniker_Release(anti);
+
     IMoniker_Release(moniker);
 }
 
 static void test_file_moniker(WCHAR* path)
 {
-    IMoniker *moniker1 = NULL, *moniker2 = NULL, *inverse, *reduced;
+    IMoniker *moniker1 = NULL, *moniker2 = NULL, *inverse, *reduced, *anti;
     IEnumMoniker *enummoniker;
-    DWORD moniker_type;
     IBindCtx *bind_ctx;
     IStream *stream;
     IUnknown *unk;
+    DWORD hash;
     HRESULT hr;
 
     hr = CreateFileMoniker(path, &moniker1);
@@ -1840,9 +1891,7 @@ todo_wine
 
     hr = IMoniker_Inverse(moniker1, &inverse);
     ok(hr == S_OK, "Failed to get inverse, hr %#x.\n", hr);
-    hr = IMoniker_IsSystemMoniker(inverse, &moniker_type);
-    ok(hr == S_OK, "Failed to get moniker type, hr %#x.\n", hr);
-    ok(moniker_type == MKSYS_ANTIMONIKER, "Unexpected moniker type %d.\n", moniker_type);
+    TEST_MONIKER_TYPE(inverse, MKSYS_ANTIMONIKER);
     IMoniker_Release(inverse);
 
     hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
@@ -1894,10 +1943,34 @@ todo_wine
     IBindCtx_Release(bind_ctx);
 
     IStream_Release(stream);
-    if (moniker1) 
-        IMoniker_Release(moniker1);
-    if (moniker2) 
-        IMoniker_Release(moniker2);
+    IMoniker_Release(moniker2);
+
+    /* ComposeWith() */
+
+    /* F + A -> () */
+    anti = create_antimoniker(1);
+    hr = IMoniker_ComposeWith(moniker1, anti, TRUE, &moniker2);
+    ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
+    ok(!moniker2, "Unexpected pointer.\n");
+    IMoniker_Release(anti);
+
+    /* I + A2 -> (A) */
+    anti = create_antimoniker(2);
+    hr = IMoniker_ComposeWith(moniker1, anti, TRUE, &moniker2);
+    ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
+todo_wine
+    ok(!!moniker2, "Unexpected pointer.\n");
+if (moniker2)
+{
+    TEST_MONIKER_TYPE(moniker2, MKSYS_ANTIMONIKER);
+    hr = IMoniker_Hash(moniker2, &hash);
+    ok(hr == S_OK, "Failed to get hash, hr %#x.\n", hr);
+    ok(hash == 0x80000001, "Unexpected hash.\n");
+    IMoniker_Release(moniker2);
+}
+    IMoniker_Release(anti);
+
+    IMoniker_Release(moniker1);
 }
 
 static void test_file_monikers(void)
@@ -2005,12 +2078,10 @@ static void test_item_moniker(void)
         "Moniker_IsRunning",
         NULL
     };
-    IMoniker *moniker, *moniker2, *reduced;
+    IMoniker *moniker, *moniker2, *reduced, *anti, *inverse;
+    DWORD i, hash, eaten, cookie;
     HRESULT hr;
-    DWORD moniker_type, i;
-    DWORD hash, eaten;
     IBindCtx *bindctx;
-    IMoniker *inverse;
     IUnknown *unknown;
     static const WCHAR wszDelimiter[] = {'!',0};
     static const WCHAR wszObjectName[] = {'T','e','s','t',0};
@@ -2023,7 +2094,6 @@ static void test_item_moniker(void)
     BIND_OPTS bind_opts;
     LARGE_INTEGER pos;
     IStream *stream;
-    DWORD cookie;
 
     hr = CreateItemMoniker(NULL, wszObjectName, &moniker);
     ok(hr == S_OK, "Failed to create item moniker, hr %#x.\n", hr);
@@ -2139,13 +2209,7 @@ todo_wine
         54, expected_display_name);
 
     /* IsSystemMoniker test */
-
-    hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
-    ok_ole_success(hr, IMoniker_IsSystemMoniker);
-
-    ok(moniker_type == MKSYS_ITEMMONIKER,
-        "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
-        moniker_type);
+    TEST_MONIKER_TYPE(moniker, MKSYS_ITEMMONIKER);
 
     container_moniker = create_test_moniker();
 
@@ -2272,9 +2336,7 @@ todo_wine
 
     hr = IMoniker_Inverse(moniker, &inverse);
     ok(hr == S_OK, "Failed to get inverse, hr %#x.\n", hr);
-    hr = IMoniker_IsSystemMoniker(inverse, &moniker_type);
-    ok(hr == S_OK, "Failed to get moniker type, hr %#x.\n", hr);
-    ok(moniker_type == MKSYS_ANTIMONIKER, "Unexpected moniker type %d.\n", moniker_type);
+    TEST_MONIKER_TYPE(inverse, MKSYS_ANTIMONIKER);
     IMoniker_Release(inverse);
 
     /* Reduce() */
@@ -2336,6 +2398,35 @@ todo_wine
     ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
 
     IMoniker_Release(moniker);
+
+    /* ComposeWith() */
+    hr = CreateItemMoniker(L"!", L"Item", &moniker);
+    ok(hr == S_OK, "Failed to create a moniker, hr %#x.\n", hr);
+
+    /* I + A -> () */
+    anti = create_antimoniker(1);
+    hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
+    ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
+    ok(!moniker2, "Unexpected pointer.\n");
+    IMoniker_Release(anti);
+
+    /* I + A2 -> (A) */
+    anti = create_antimoniker(2);
+    hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
+    ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
+todo_wine
+    ok(!!moniker2, "Unexpected pointer.\n");
+if (moniker2)
+{
+    TEST_MONIKER_TYPE(moniker2, MKSYS_ANTIMONIKER);
+    hr = IMoniker_Hash(moniker2, &hash);
+    ok(hr == S_OK, "Failed to get hash, hr %#x.\n", hr);
+    ok(hash == 0x80000001, "Unexpected hash.\n");
+    IMoniker_Release(moniker2);
+}
+    IMoniker_Release(anti);
+
+    IMoniker_Release(moniker);
 }
 
 static void stream_write_dword(IStream *stream, DWORD value)
@@ -2358,7 +2449,6 @@ static void test_anti_moniker(void)
 {
     IMoniker *moniker, *moniker2, *moniker3, *inverse, *reduced;
     HRESULT hr;
-    DWORD moniker_type;
     DWORD hash;
     IBindCtx *bindctx;
     FILETIME filetime;
@@ -2394,11 +2484,7 @@ todo_wine
         hash);
 
     /* IsSystemMoniker test */
-    hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
-    ok_ole_success(hr, IMoniker_IsSystemMoniker);
-    ok(moniker_type == MKSYS_ANTIMONIKER,
-        "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
-        moniker_type);
+    TEST_MONIKER_TYPE(moniker, MKSYS_ANTIMONIKER);
 
     hr = IMoniker_Inverse(moniker, &inverse);
     ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr);
@@ -2431,9 +2517,7 @@ todo_wine
 
     hr = IMoniker_ComposeWith(moniker, moniker2, FALSE, &moniker3);
     ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
-    hr = IMoniker_IsSystemMoniker(moniker3, &moniker_type);
-    ok(hr == S_OK, "Failed to get moniker type, hr %#x.\n", hr);
-    ok(moniker_type == MKSYS_GENERICCOMPOSITE, "Unexpected moniker type %d.\n", moniker_type);
+    TEST_MONIKER_TYPE(moniker3, MKSYS_GENERICCOMPOSITE);
     IMoniker_Release(moniker3);
 
     IMoniker_Release(moniker2);
@@ -2619,22 +2703,22 @@ todo_wine
 
 static void test_generic_composite_moniker(void)
 {
+    IMoniker *moniker, *inverse, *inverse2, *moniker1, *moniker2, *moniker3, *moniker4;
     IEnumMoniker *enummoniker;
     HRESULT hr;
-    IMoniker *moniker;
-    IMoniker *moniker1;
-    IMoniker *moniker2;
-    DWORD moniker_type;
     DWORD hash;
     IBindCtx *bindctx;
     FILETIME filetime;
-    IMoniker *inverse;
     IUnknown *unknown;
     static const WCHAR wszDelimiter1[] = {'!',0};
     static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
     static const WCHAR wszDelimiter2[] = {'#',0};
     static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
     static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
+    WCHAR *name;
+
+    hr = CreateBindCtx(0, &bindctx);
+    ok(hr == S_OK, "Failed to create bind context, hr %#x.\n", hr);
 
     hr = CreateItemMoniker(wszDelimiter1, wszObjectName1, &moniker1);
     ok_ole_success(hr, CreateItemMoniker);
@@ -2643,6 +2727,81 @@ static void test_generic_composite_moniker(void)
     hr = CreateGenericComposite(moniker1, moniker2, &moniker);
     ok_ole_success(hr, CreateGenericComposite);
 
+    /* Compose with itself. */
+    EXPECT_REF(moniker1, 2);
+    hr = CreateGenericComposite(moniker1, moniker1, &moniker);
+    ok(hr == S_OK, "Failed to create composite, hr %#x.\n", hr);
+    EXPECT_REF(moniker1, 4);
+    TEST_MONIKER_TYPE(moniker, MKSYS_GENERICCOMPOSITE);
+    IMoniker_Release(moniker);
+
+    /* (I) + (A) -> () */
+    hr = IMoniker_Inverse(moniker1, &inverse);
+    ok(hr == S_OK, "Failed to invert, hr %#x.\n", hr);
+    hr = CreateGenericComposite(moniker1, inverse, &moniker);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+todo_wine
+    ok(!moniker, "Unexpected pointer.\n");
+    if (moniker)
+        IMoniker_Release(moniker);
+
+    /* (I1,I2) + (A,A) -> (I1,I2+A,A) -> (I1,A) -> () */
+    hr = CreateGenericComposite(moniker1, moniker2, &moniker);
+    ok(hr == S_OK, "Failed to create composite, hr %#x.\n", hr);
+    hr = CreateGenericComposite(inverse, inverse, &moniker3);
+    ok(hr == S_OK, "Failed to create composite, hr %#x.\n", hr);
+    TEST_MONIKER_TYPE(moniker3, MKSYS_GENERICCOMPOSITE);
+
+    hr = CreateGenericComposite(moniker, moniker3, &moniker4);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+todo_wine
+    ok(!moniker4, "Unexpected pointer.\n");
+    if (moniker4)
+        IMoniker_Release(moniker4);
+
+    IMoniker_Release(moniker);
+    IMoniker_Release(moniker3);
+
+    /* (I1,I2) + (A2,A) -> (I1,I2+A2,A) -> (I1,A,A) -> (I1+A,A) -> (A) */
+    hr = CreateGenericComposite(moniker1, moniker2, &moniker);
+    ok(hr == S_OK, "Failed to create composite, hr %#x.\n", hr);
+    ok(!!moniker, "Unexpected pointer.\n");
+    inverse2 = create_antimoniker(2);
+    hr = CreateGenericComposite(inverse2, inverse, &moniker3);
+    ok(hr == S_OK, "Failed to create composite, hr %#x.\n", hr);
+    ok(!!moniker3, "Unexpected pointer.\n");
+    IMoniker_Release(inverse2);
+
+    hr = CreateGenericComposite(moniker, moniker3, &moniker4);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    TEST_MONIKER_TYPE_TODO(moniker4, MKSYS_ANTIMONIKER);
+    IMoniker_Release(moniker4);
+    IMoniker_Release(moniker);
+    IMoniker_Release(moniker3);
+
+    /* (I1,I2) + (A,I2) -> (I1,I2+A,I2) -> (I1,I2) */
+    hr = CreateGenericComposite(moniker1, moniker2, &moniker);
+    ok(hr == S_OK, "Failed to create composite, hr %#x.\n", hr);
+    ok(!!moniker, "Unexpected pointer.\n");
+
+    hr = CreateGenericComposite(inverse, moniker2, &moniker3);
+    ok(hr == S_OK, "Failed to create composite, hr %#x.\n", hr);
+    ok(!!moniker3, "Unexpected pointer.\n");
+
+    hr = CreateGenericComposite(moniker, moniker3, &moniker4);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    TEST_MONIKER_TYPE(moniker4, MKSYS_GENERICCOMPOSITE);
+
+    hr = IMoniker_GetDisplayName(moniker4, bindctx, NULL, &name);
+    ok(hr == S_OK, "Failed to get display name, hr %#x.\n", hr);
+    ok(!lstrcmpW(name, L"!Test#Wine"), "Unexpected name %s.\n", wine_dbgstr_w(name));
+    CoTaskMemFree(name);
+
+    IMoniker_Release(moniker4);
+    IMoniker_Release(moniker3);
+
+    IMoniker_Release(inverse);
+
     /* Generic composite is special, as it does not addref in this case. */
     hr = IMoniker_QueryInterface(moniker, &CLSID_CompositeMoniker, (void **)&unknown);
 todo_wine
@@ -2666,13 +2825,7 @@ todo_wine
         hash);
 
     /* IsSystemMoniker test */
-
-    hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
-    ok_ole_success(hr, IMoniker_IsSystemMoniker);
-
-    ok(moniker_type == MKSYS_GENERICCOMPOSITE,
-        "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
-        moniker_type);
+    TEST_MONIKER_TYPE(moniker, MKSYS_GENERICCOMPOSITE);
 
     hr = CreateBindCtx(0, &bindctx);
     ok_ole_success(hr, CreateBindCtx);
@@ -2698,9 +2851,7 @@ todo_wine
 
     hr = IMoniker_Inverse(moniker, &inverse);
     ok(hr == S_OK, "Failed to get inverse, hr %#x.\n", hr);
-    hr = IMoniker_IsSystemMoniker(inverse, &moniker_type);
-    ok(hr == S_OK, "Failed to get moniker type, hr %#x.\n", hr);
-    ok(moniker_type == MKSYS_GENERICCOMPOSITE, "Unexpected moniker type %d.\n", moniker_type);
+    TEST_MONIKER_TYPE(inverse, MKSYS_GENERICCOMPOSITE);
     IMoniker_Release(inverse);
 
     /* Enum() */
@@ -2721,9 +2872,9 @@ todo_wine
 
 static void test_pointer_moniker(void)
 {
-    IMoniker *moniker, *moniker2, *prefix, *inverse;
-    DWORD moniker_type, hash, size;
+    IMoniker *moniker, *moniker2, *prefix, *inverse, *anti;
     IEnumMoniker *enummoniker;
+    DWORD hash, size;
     HRESULT hr;
     IBindCtx *bindctx;
     FILETIME filetime;
@@ -2819,17 +2970,11 @@ todo_wine
         PtrToUlong(&Test_ClassFactory), hash);
 
     /* IsSystemMoniker test */
-    hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
-    ok_ole_success(hr, IMoniker_IsSystemMoniker);
-    ok(moniker_type == MKSYS_POINTERMONIKER,
-        "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
-        moniker_type);
+    TEST_MONIKER_TYPE(moniker, MKSYS_POINTERMONIKER);
 
     hr = IMoniker_Inverse(moniker, &inverse);
     ok(hr == S_OK, "Failed to get inverse, hr %#x.\n", hr);
-    hr = IMoniker_IsSystemMoniker(inverse, &moniker_type);
-    ok(hr == S_OK, "Failed to get moniker type, hr %#x.\n", hr);
-    ok(moniker_type == MKSYS_ANTIMONIKER, "Unexpected moniker type %d.\n", moniker_type);
+    TEST_MONIKER_TYPE(inverse, MKSYS_ANTIMONIKER);
     IMoniker_Release(inverse);
 
     hr = CreateBindCtx(0, &bindctx);
@@ -2914,6 +3059,28 @@ todo_wine
 
     IMoniker_Release(moniker2);
 
+    /* ComposeWith() */
+
+    /* P + A -> () */
+    anti = create_antimoniker(1);
+    hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
+    ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
+    ok(!moniker2, "Unexpected pointer.\n");
+    IMoniker_Release(anti);
+
+    /* P + A2 -> A */
+    anti = create_antimoniker(2);
+    hr = IMoniker_ComposeWith(moniker, anti, TRUE, &moniker2);
+    ok(hr == S_OK, "Failed to compose, hr %#x.\n", hr);
+todo_wine
+    ok(!!moniker2, "Unexpected pointer.\n");
+if (moniker2)
+{
+    TEST_MONIKER_TYPE(moniker2, MKSYS_ANTIMONIKER);
+    IMoniker_Release(moniker2);
+}
+    IMoniker_Release(anti);
+
     IMoniker_Release(moniker);
 }
 
-- 
2.24.1




More information about the wine-devel mailing list