1+ // Copyright (c) .NET Foundation and contributors. All rights reserved.
2+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+ using System . Collections . Generic ;
5+ using System . CommandLine . Invocation ;
6+ using System . Linq ;
7+ using FluentAssertions ;
8+ using System . Threading . Tasks ;
9+ using Xunit ;
10+
11+ namespace System . CommandLine . Tests . Binding
12+ {
13+ public partial class ModelBindingCommandHandlerTests
14+ {
15+ public class BindingBySymbol
16+ {
17+ [ Theory ]
18+ [ InlineData ( 1 ) ]
19+ [ InlineData ( 2 ) ]
20+ [ InlineData ( 3 ) ]
21+ [ InlineData ( 4 ) ]
22+ [ InlineData ( 5 ) ]
23+ [ InlineData ( 6 ) ]
24+ [ InlineData ( 7 ) ]
25+ [ InlineData ( 8 ) ]
26+ [ InlineData ( 9 ) ]
27+ [ InlineData ( 10 ) ]
28+ [ InlineData ( 11 ) ]
29+ [ InlineData ( 12 ) ]
30+ [ InlineData ( 13 ) ]
31+ [ InlineData ( 14 ) ]
32+ [ InlineData ( 15 ) ]
33+ [ InlineData ( 16 ) ]
34+ public void Binding_is_correct_for_overload_having_arity_ ( int arity )
35+ {
36+ var command = new RootCommand ( ) ;
37+ var commandLine = "" ;
38+
39+ for ( var i = 1 ; i <= arity ; i ++ )
40+ {
41+ command . AddArgument ( new Argument < int > ( $ "i{ i } ") ) ;
42+
43+ commandLine += $ " { i } ";
44+ }
45+
46+ var receivedValues = new List < int > ( ) ;
47+ Delegate handlerFunc = arity switch
48+ {
49+ 1 => new Func < int , Task > (
50+ i1 =>
51+ Received ( i1 ) ) ,
52+ 2 => new Func < int , int , Task > (
53+ ( i1 , i2 ) =>
54+ Received ( i1 , i2 ) ) ,
55+ 3 => new Func < int , int , int , Task > (
56+ ( i1 , i2 , i3 ) =>
57+ Received ( i1 , i2 , i3 ) ) ,
58+ 4 => new Func < int , int , int , int , Task > (
59+ ( i1 , i2 , i3 , i4 ) =>
60+ Received ( i1 , i2 , i3 , i4 ) ) ,
61+ 5 => new Func < int , int , int , int , int , Task > (
62+ ( i1 , i2 , i3 , i4 , i5 ) =>
63+ Received ( i1 , i2 , i3 , i4 , i5 ) ) ,
64+ 6 => new Func < int , int , int , int , int , int , Task > (
65+ ( i1 , i2 , i3 , i4 , i5 , i6 ) =>
66+ Received ( i1 , i2 , i3 , i4 , i5 , i6 ) ) ,
67+ 7 => new Func < int , int , int , int , int , int , int , Task > (
68+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 ) =>
69+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 ) ) ,
70+ 8 => new Func < int , int , int , int , int , int , int , int , Task > (
71+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 ) =>
72+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 ) ) ,
73+ 9 => new Func < int , int , int , int , int , int , int , int , int , Task > (
74+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 ) =>
75+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 ) ) ,
76+ 10 => new Func < int , int , int , int , int , int , int , int , int , int , Task > (
77+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 ) =>
78+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 ) ) ,
79+ 11 => new Func < int , int , int , int , int , int , int , int , int , int , int , Task > (
80+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 ) =>
81+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 ) ) ,
82+ 12 => new Func < int , int , int , int , int , int , int , int , int , int , int , int , Task > (
83+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 ) =>
84+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 ) ) ,
85+ 13 => new Func < int , int , int , int , int , int , int , int , int , int , int , int , int , Task > (
86+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 , i13 ) =>
87+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 , i13 ) ) ,
88+ 14 => new Func < int , int , int , int , int , int , int , int , int , int , int , int , int , int , Task > (
89+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 , i13 , i14 ) =>
90+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 , i13 , i14 ) ) ,
91+ 15 => new Func < int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , Task > (
92+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 , i13 , i14 , i15 ) =>
93+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 , i13 , i14 , i15 ) ) ,
94+ 16 => new Func < int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , Task > (
95+
96+ ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 , i13 , i14 , i15 , i16 ) =>
97+ Received ( i1 , i2 , i3 , i4 , i5 , i6 , i7 , i8 , i9 , i10 , i11 , i12 , i13 , i14 , i15 , i16 ) ) ,
98+
99+ _ => throw new ArgumentOutOfRangeException ( )
100+ } ;
101+
102+ // build up the method invocation
103+ var genericMethodDef = typeof ( CommandHandler )
104+ . GetMethods ( )
105+ . Where ( m => m . Name == nameof ( CommandHandler . Create ) )
106+ . Where ( m => m . IsGenericMethod /* symbols + handler Func */ )
107+ . Single ( m => m . GetParameters ( ) . Length == arity + 1 ) ;
108+
109+ var genericParameterTypes = Enumerable . Range ( 1 , arity )
110+ . Select ( _ => typeof ( int ) )
111+ . ToArray ( ) ;
112+
113+ var createMethod = genericMethodDef . MakeGenericMethod ( genericParameterTypes ) ;
114+
115+ var parameters = new List < object > ( ) ;
116+
117+ parameters . AddRange ( command . Arguments ) ;
118+ parameters . Add ( handlerFunc ) ;
119+
120+ var handler = ( ICommandHandler ) createMethod . Invoke ( null , parameters . ToArray ( ) ) ;
121+
122+ command . Handler = handler ;
123+
124+ command . Invoke ( commandLine ) ;
125+
126+ receivedValues . Should ( ) . BeEquivalentTo (
127+ Enumerable . Range ( 1 , arity ) ,
128+ config => config . WithStrictOrdering ( ) ) ;
129+
130+ Task Received ( params int [ ] values )
131+ {
132+ receivedValues . AddRange ( values ) ;
133+ return Task . CompletedTask ;
134+ }
135+ }
136+ }
137+ }
138+ }
0 commit comments