Skip to content

Commit 71d264c

Browse files
huoyaoyuanAaronRobinsonMSFT
authored andcommitted
Add tests for OAVariantLib (dotnet#101841)
* Add native return test for basic supported types --------- Co-authored-by: Aaron Robinson <[email protected]>
1 parent 1ed4ba9 commit 71d264c

File tree

12 files changed

+550
-0
lines changed

12 files changed

+550
-0
lines changed

src/tests/Interop/COM/NETClients/IDispatch/Program.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,67 @@ System.Collections.Generic.IEnumerable<int> GetEnumerable(System.Collections.IEn
215215
}
216216
}
217217

218+
static void Validate_ValueCoerce_ReturnToManaged()
219+
{
220+
var dispatchCoerceTesting = (DispatchCoerceTesting)new DispatchCoerceTestingClass();
221+
222+
Console.WriteLine($"Calling {nameof(DispatchCoerceTesting.ReturnToManaged)} ...");
223+
224+
// Supported types
225+
// See returned values in DispatchCoerceTesting.h
226+
(VarEnum type, int expectedValue)[] supportedTypes =
227+
{
228+
(VarEnum.VT_EMPTY, 0),
229+
(VarEnum.VT_I2, 123),
230+
(VarEnum.VT_I4, 123),
231+
(VarEnum.VT_R4, 1),
232+
(VarEnum.VT_R8, 1),
233+
(VarEnum.VT_CY, 123),
234+
(VarEnum.VT_DATE, 1),
235+
(VarEnum.VT_BSTR, 123),
236+
(VarEnum.VT_ERROR, 123),
237+
(VarEnum.VT_BOOL, -1),
238+
(VarEnum.VT_DECIMAL, 123),
239+
};
240+
241+
foreach (var (vt, expected) in supportedTypes)
242+
{
243+
Console.WriteLine($"Converting {vt} to int should be supported.");
244+
int result = dispatchCoerceTesting.ReturnToManaged((short)vt);
245+
Assert.Equal(expected, result);
246+
}
247+
248+
// Invalid: Rejected before reaching coerce
249+
Console.WriteLine("Invalid variant type should throw InvalidOleVariantTypeException.");
250+
var variantException = Assert.Throws<InvalidOleVariantTypeException>(() => dispatchCoerceTesting.ReturnToManaged(0x7FFF));
251+
Assert.Equal(unchecked((int)0x80131531), variantException.HResult);
252+
253+
// Not supported source or destination type: COMException { HResult: 0x80020005 }
254+
255+
// DISP_E_PARAMNOTFOUND: Converts to Missing
256+
Console.WriteLine("Converting from VT_ERROR with DISP_E_PARAMNOTFOUND should be rejected.");
257+
var comException = Assert.Throws<COMException>(() => dispatchCoerceTesting.ReturnToManaged(unchecked((short)((short)VarEnum.VT_ERROR | 0x8000))));
258+
Assert.Equal(unchecked((int)0x80020005), comException.HResult);
259+
260+
Console.WriteLine("Converting int to VT_MISSING should be rejected.");
261+
comException = Assert.Throws<COMException>(() => dispatchCoerceTesting.ReturnToManaged_Missing());
262+
Assert.Equal(unchecked((int)0x80020005), comException.HResult);
263+
264+
Console.WriteLine("Converting int to VT_NULL should be rejected.");
265+
comException = Assert.Throws<COMException>(() => dispatchCoerceTesting.ReturnToManaged_DBNull());
266+
Assert.Equal(unchecked((int)0x80020005), comException.HResult);
267+
268+
// Rejected by VariantChangeTypeEx
269+
Console.WriteLine("Converting VT_UNKNOWN to int should fail from VariantChangeTypeEx.");
270+
Assert.Throws<InvalidCastException>(() => dispatchCoerceTesting.ReturnToManaged((short)VarEnum.VT_UNKNOWN));
271+
Console.WriteLine("Converting VT_NULL to int should fail from VariantChangeTypeEx.");
272+
Assert.Throws<InvalidCastException>(() => dispatchCoerceTesting.ReturnToManaged((short)VarEnum.VT_NULL));
273+
274+
// LOCAL_BOOL
275+
Console.WriteLine("VARIANT_BOOL should convert to non-numeric string.");
276+
Assert.Equal("True", dispatchCoerceTesting.BoolToString());
277+
}
278+
218279
[Fact]
219280
public static int TestEntryPoint()
220281
{
@@ -233,6 +294,7 @@ public static int TestEntryPoint()
233294
Validate_StructNotSupported();
234295
Validate_LCID_Marshaled();
235296
Validate_Enumerator();
297+
Validate_ValueCoerce_ReturnToManaged();
236298
}
237299
catch (Exception e)
238300
{
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Globalization;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Runtime.InteropServices;
9+
using Server.Contract;
10+
11+
[ComVisible(true)]
12+
[Guid(Server.Contract.Guids.DispatchCoerceTesting)]
13+
public class DispatchCoerceTesting : Server.Contract.IDispatchCoerceTesting
14+
{
15+
public int ReturnToManaged(short vt)
16+
{
17+
throw new NotImplementedException();
18+
}
19+
20+
public int ManagedArgument(int arg)
21+
{
22+
return arg;
23+
}
24+
25+
public System.Reflection.Missing ReturnToManaged_Missing()
26+
{
27+
return System.Reflection.Missing.Value;
28+
}
29+
30+
public DBNull ReturnToManaged_DBNull()
31+
{
32+
return DBNull.Value;
33+
}
34+
35+
public string BoolToString()
36+
{
37+
throw new NotImplementedException();
38+
}
39+
}

src/tests/Interop/COM/NativeClients/Dispatch/Client.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ void Validate_Float_In_ReturnAndUpdateByRef();
1111
void Validate_Double_In_ReturnAndUpdateByRef();
1212
void Validate_LCID_Marshaled();
1313
void Validate_Enumerator();
14+
void Validate_ParamCoerce();
1415

1516
template<COINIT TM>
1617
struct ComInit
@@ -48,6 +49,7 @@ int __cdecl main()
4849
Validate_Double_In_ReturnAndUpdateByRef();
4950
Validate_LCID_Marshaled();
5051
Validate_Enumerator();
52+
Validate_ParamCoerce();
5153
}
5254
catch (HRESULT hr)
5355
{
@@ -459,3 +461,111 @@ void Validate_Enumerator()
459461
::printf(" -- Validate returned IEnumVARIANT\n");
460462
ValidateReturnedEnumerator(&result);
461463
}
464+
465+
void Validate_ParamCoerce_Type(ComSmartPtr<IDispatchCoerceTesting>& dispatchCoerceTesting, VARENUM type, int lcid, DISPID methodId)
466+
{
467+
HRESULT hr;
468+
469+
DISPPARAMS params;
470+
VARIANTARG arg;
471+
params.cArgs = 1;
472+
params.rgvarg = &arg;
473+
params.cNamedArgs = 0;
474+
params.rgdispidNamedArgs = nullptr;
475+
476+
VARIANT result;
477+
478+
V_VT(&arg) = type;
479+
480+
switch (type)
481+
{
482+
case VT_BSTR:
483+
{
484+
BSTR str = ::SysAllocString(L"123");
485+
V_BSTR(&arg) = str;
486+
break;
487+
}
488+
case VT_R4:
489+
{
490+
V_R4(&arg) = 1.23f;
491+
break;
492+
}
493+
case VT_DATE:
494+
case VT_R8:
495+
{
496+
V_R8(&arg) = 1.23;
497+
break;
498+
}
499+
case VT_CY:
500+
{
501+
VarCyFromI4(123, &V_CY(&arg));
502+
break;
503+
}
504+
case VT_DECIMAL:
505+
{
506+
VarDecFromI4(123, &V_DECIMAL(&arg));
507+
break;
508+
}
509+
default:
510+
{
511+
V_I1(&arg) = 123;
512+
break;
513+
}
514+
}
515+
516+
THROW_IF_FAILED(dispatchCoerceTesting->Invoke(
517+
methodId,
518+
IID_NULL,
519+
lcid,
520+
DISPATCH_METHOD,
521+
&params,
522+
&result,
523+
nullptr,
524+
nullptr
525+
));
526+
527+
THROW_FAIL_IF_FALSE(V_I4(&result) != 0);
528+
}
529+
530+
void Validate_ParamCoerce()
531+
{
532+
HRESULT hr;
533+
534+
CoreShimComActivation csact{ W("NETServer"), W("DispatchCoerceTesting") };
535+
536+
ComSmartPtr<IDispatchCoerceTesting> dispatchCoerceTesting;
537+
THROW_IF_FAILED(::CoCreateInstance(CLSID_DispatchCoerceTesting, nullptr, CLSCTX_INPROC, IID_IDispatchCoerceTesting, (void**)&dispatchCoerceTesting));
538+
539+
LPOLESTR numericMethodName = (LPOLESTR)W("ManagedArgument");
540+
LCID lcid = MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT);
541+
DISPID methodId;
542+
543+
::wprintf(W("Invoke %s\n"), numericMethodName);
544+
THROW_IF_FAILED(dispatchCoerceTesting->GetIDsOfNames(
545+
IID_NULL,
546+
&numericMethodName,
547+
1,
548+
lcid,
549+
&methodId));
550+
551+
::wprintf(W("Validating VT_I2\n"));
552+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_I2, lcid, methodId);
553+
::wprintf(W("Validating VT_I4\n"));
554+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_I4, lcid, methodId);
555+
::wprintf(W("Validating VT_R4\n"));
556+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_R4, lcid, methodId);
557+
::wprintf(W("Validating VT_R8\n"));
558+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_R8, lcid, methodId);
559+
::wprintf(W("Validating VT_CY\n"));
560+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_CY, lcid, methodId);
561+
::wprintf(W("Validating VT_DATE\n"));
562+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_DATE, lcid, methodId);
563+
::wprintf(W("Validating VT_BSTR\n"));
564+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_BSTR, lcid, methodId);
565+
::wprintf(W("Validating VT_ERROR\n"));
566+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_ERROR, lcid, methodId);
567+
::wprintf(W("Validating VT_BOOL\n"));
568+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_BOOL, lcid, methodId);
569+
::wprintf(W("Validating VT_DECIMAL\n"));
570+
Validate_ParamCoerce_Type(dispatchCoerceTesting, VT_DECIMAL, lcid, methodId);
571+
}

src/tests/Interop/COM/NativeClients/Dispatch/CoreShim.X.manifest

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
<comClass
1212
clsid="{0F8ACD0C-ECE0-4F2A-BD1B-6BFCA93A0726}"
1313
threadingModel="Both" />
14+
15+
<!-- DispatchCoerceTesting -->
16+
<comClass
17+
clsid="{661F9962-3477-416B-BE40-4CBA3190A562}"
18+
threadingModel="Both" />
1419
</file>
1520

1621
</assembly>

src/tests/Interop/COM/NativeServer/COMNativeServer.X.manifest

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@
4242
clsid="{4DBD9B61-E372-499F-84DE-EFC70AA8A009}"
4343
threadingModel="Both" />
4444

45+
<!-- DispatchCoerceTesting -->
46+
<comClass
47+
clsid="{661F9962-3477-416B-BE40-4CBA3190A562}"
48+
threadingModel="Both" />
49+
4550
<!-- AggregationTesting -->
4651
<comClass
4752
clsid="{4CEFE36D-F377-4B6E-8C34-819A8BB9CB04}"

0 commit comments

Comments
 (0)