@@ -17,6 +17,7 @@ public async Task SupportsAllXmlTagsOnSchemas()
17
17
{
18
18
var source = """
19
19
using System;
20
+ using System.Collections.Generic;
20
21
using System.Threading.Tasks;
21
22
using Microsoft.AspNetCore.Builder;
22
23
using Microsoft.Extensions.DependencyInjection;
@@ -36,6 +37,7 @@ public async Task SupportsAllXmlTagsOnSchemas()
36
37
app.MapPost("/inherit-only-returns", (InheritOnlyReturns returns) => { });
37
38
app.MapPost("/inherit-all-but-remarks", (InheritAllButRemarks remarks) => { });
38
39
app.MapPost("/generic-class", (GenericClass<string> generic) => { });
40
+ app.MapPost("/generic-parent", (GenericParent parent) => { });
39
41
app.MapPost("/params-and-param-refs", (ParamsAndParamRefs refs) => { });
40
42
41
43
@@ -335,6 +337,89 @@ public class GenericClass<T>
335
337
// Fields and members.
336
338
}
337
339
340
+ /// <summary>
341
+ /// This class validates the behavior for mapping
342
+ /// generic types to open generics for use in
343
+ /// typeof expressions.
344
+ /// </summary>
345
+ public class GenericParent
346
+ {
347
+ /// <summary>
348
+ /// This property is a nullable value type.
349
+ /// </summary>
350
+ public int? Id { get; set; }
351
+
352
+ /// <summary>
353
+ /// This property is a nullable reference type.
354
+ /// </summary>
355
+ public string? Name { get; set; }
356
+
357
+ /// <summary>
358
+ /// This property is a generic type containing a tuple.
359
+ /// </summary>
360
+ public Task<(int, string)> TaskOfTupleProp { get; set; }
361
+
362
+ /// <summary>
363
+ /// This property is a tuple with a generic type inside.
364
+ /// </summary>
365
+ public (int, Dictionary<int, string>) TupleWithGenericProp { get; set; }
366
+
367
+ /// <summary>
368
+ /// This property is a tuple with a nested generic type inside.
369
+ /// </summary>
370
+ public (int, Dictionary<int, Dictionary<string, int>>) TupleWithNestedGenericProp { get; set; }
371
+
372
+ /// <summary>
373
+ /// This method returns a generic type containing a tuple.
374
+ /// </summary>
375
+ public static Task<(int, string)> GetTaskOfTuple()
376
+ {
377
+ return Task.FromResult((1, "test"));
378
+ }
379
+
380
+ /// <summary>
381
+ /// This method returns a tuple with a generic type inside.
382
+ /// </summary>
383
+ public static (int, Dictionary<int, string>) GetTupleOfTask()
384
+ {
385
+ return (1, new Dictionary<int, string>());
386
+ }
387
+
388
+ /// <summary>
389
+ /// This method return a tuple with a generic type containing a
390
+ /// type parameter inside.
391
+ /// </summary>
392
+ public static (int, Dictionary<int, T>) GetTupleOfTask1<T>()
393
+ {
394
+ return (1, new Dictionary<int, T>());
395
+ }
396
+
397
+ /// <summary>
398
+ /// This method return a tuple with a generic type containing a
399
+ /// type parameter inside.
400
+ /// </summary>
401
+ public static (T, Dictionary<int, string>) GetTupleOfTask2<T>()
402
+ {
403
+ return (default, new Dictionary<int, string>());
404
+ }
405
+
406
+ /// <summary>
407
+ /// This method returns a nested generic with all types resolved.
408
+ /// </summary>
409
+ public static Dictionary<int, Dictionary<int, string>> GetNestedGeneric()
410
+ {
411
+ return new Dictionary<int, Dictionary<int, string>>();
412
+ }
413
+
414
+ /// <summary>
415
+ /// This method returns a nested generic with a type parameter.
416
+ /// </summary>
417
+ public static Dictionary<int, Dictionary<int, T>> GetNestedGeneric1<T>()
418
+ {
419
+ return new Dictionary<int, Dictionary<int, T>>();
420
+ }
421
+ }
422
+
338
423
/// <summary>
339
424
/// This shows examples of typeparamref and typeparam tags
340
425
/// </summary>
@@ -394,6 +479,15 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, document =>
394
479
var genericClass = path . RequestBody . Content [ "application/json" ] . Schema ;
395
480
Assert . Equal ( "This is a generic class." , genericClass . Description ) ;
396
481
482
+ path = document . Paths [ "/generic-parent" ] . Operations [ OperationType . Post ] ;
483
+ var genericParent = path . RequestBody . Content [ "application/json" ] . Schema ;
484
+ Assert . Equal ( "This class validates the behavior for mapping\n generic types to open generics for use in\n typeof expressions." , genericParent . Description , ignoreLineEndingDifferences : true ) ;
485
+ Assert . Equal ( "This property is a nullable value type." , genericParent . Properties [ "id" ] . Description ) ;
486
+ Assert . Equal ( "This property is a nullable reference type." , genericParent . Properties [ "name" ] . Description ) ;
487
+ Assert . Equal ( "This property is a generic type containing a tuple." , genericParent . Properties [ "taskOfTupleProp" ] . Description ) ;
488
+ Assert . Equal ( "This property is a tuple with a generic type inside." , genericParent . Properties [ "tupleWithGenericProp" ] . Description ) ;
489
+ Assert . Equal ( "This property is a tuple with a nested generic type inside." , genericParent . Properties [ "tupleWithNestedGenericProp" ] . Description ) ;
490
+
397
491
path = document . Paths [ "/params-and-param-refs" ] . Operations [ OperationType . Post ] ;
398
492
var paramsAndParamRefs = path . RequestBody . Content [ "application/json" ] . Schema ;
399
493
Assert . Equal ( "This shows examples of typeparamref and typeparam tags" , paramsAndParamRefs . Description ) ;
0 commit comments