@@ -31,8 +31,9 @@ public void When_an_option_accepts_only_specific_arguments_but_a_wrong_one_is_su
31
31
32
32
result . Errors
33
33
. Select ( e => e . Message )
34
- . Single ( )
35
34
. Should ( )
35
+ . HaveCount ( 1 )
36
+ . And
36
37
. Contain ( "Argument 'none-of-those' not recognized. Must be one of:\n \t 'this'\n \t 'that'\n \t 'the-other-thing'" ) ;
37
38
}
38
39
@@ -109,7 +110,9 @@ public void When_FromAmong_is_used_for_multiple_arguments_and_invalid_input_is_p
109
110
110
111
var result = command . Parse ( "set not-key1 value1" ) ;
111
112
112
- result . Errors . Should ( ) . ContainSingle ( )
113
+ result . Errors
114
+ . Should ( )
115
+ . ContainSingle ( )
113
116
. Which
114
117
. Message
115
118
. Should ( )
@@ -127,7 +130,9 @@ public void When_FromAmong_is_used_for_multiple_arguments_and_invalid_input_is_p
127
130
128
131
var result = command . Parse ( "set key1 not-value1" ) ;
129
132
130
- result . Errors . Should ( ) . ContainSingle ( )
133
+ result . Errors
134
+ . Should ( )
135
+ . ContainSingle ( )
131
136
. Which
132
137
. Message
133
138
. Should ( )
@@ -143,6 +148,8 @@ public void When_a_required_argument_is_not_supplied_then_an_error_is_returned()
143
148
144
149
result . Errors
145
150
. Should ( )
151
+ . HaveCount ( 1 )
152
+ . And
146
153
. Contain ( e => e . Message == "Required argument missing for option: '-x'." ) ;
147
154
}
148
155
@@ -161,7 +168,9 @@ public void When_a_required_option_is_not_supplied_then_an_error_is_returned()
161
168
162
169
result . Errors
163
170
. Should ( )
164
- . ContainSingle ( e => e . SymbolResult . Symbol == command )
171
+ . HaveCount ( 1 )
172
+ . And
173
+ . Contain ( e => e . SymbolResult . Symbol == command )
165
174
. Which
166
175
. Message
167
176
. Should ( )
@@ -225,7 +234,9 @@ public void When_no_option_accepts_arguments_but_one_is_supplied_then_an_error_i
225
234
result . Errors
226
235
. Select ( e => e . Message )
227
236
. Should ( )
228
- . ContainSingle ( e => e == "Unrecognized command or argument 'some-arg'." ) ;
237
+ . HaveCount ( 1 )
238
+ . And
239
+ . Contain ( e => e == "Unrecognized command or argument 'some-arg'." ) ;
229
240
}
230
241
231
242
[ Fact ]
@@ -252,7 +263,9 @@ public void A_custom_validator_can_be_added_to_a_command()
252
263
. Errors
253
264
. Select ( e => e . Message )
254
265
. Should ( )
255
- . ContainSingle ( "Options '--one' and '--two' cannot be used together." ) ;
266
+ . HaveCount ( 1 )
267
+ . And
268
+ . Contain ( "Options '--one' and '--two' cannot be used together." ) ;
256
269
}
257
270
258
271
[ Fact ]
@@ -273,7 +286,9 @@ public void A_custom_validator_can_be_added_to_an_option()
273
286
274
287
result . Errors
275
288
. Should ( )
276
- . ContainSingle ( e => e . SymbolResult . Symbol == option )
289
+ . HaveCount ( 1 )
290
+ . And
291
+ . Contain ( e => e . SymbolResult . Symbol == option )
277
292
. Which
278
293
. Message
279
294
. Should ( )
@@ -298,7 +313,9 @@ public void A_custom_validator_can_be_added_to_an_argument()
298
313
299
314
result . Errors
300
315
. Should ( )
301
- . ContainSingle ( e => e . SymbolResult . Symbol == argument )
316
+ . HaveCount ( 1 )
317
+ . And
318
+ . Contain ( e => e . SymbolResult . Symbol == argument )
302
319
. Which
303
320
. Message
304
321
. Should ( )
@@ -365,7 +382,9 @@ public void Validators_on_global_options_are_executed_when_invoking_a_subcommand
365
382
366
383
result . Errors
367
384
. Should ( )
368
- . ContainSingle ( e => e . SymbolResult . Symbol == option )
385
+ . HaveCount ( 1 )
386
+ . And
387
+ . Contain ( e => e . SymbolResult . Symbol == option )
369
388
. Which
370
389
. Message
371
390
. Should ( )
@@ -421,11 +440,13 @@ public void Custom_validator_error_messages_are_not_repeated()
421
440
argument
422
441
} ;
423
442
424
- var result = cmd . Parse ( "get something" ) ;
443
+ var result = cmd . Parse ( "get something" ) ;
425
444
426
445
result . Errors
427
446
. Should ( )
428
- . ContainSingle ( errorMessage ) ;
447
+ . HaveCount ( 1 )
448
+ . And
449
+ . Contain ( e => e . Message == errorMessage ) ;
429
450
}
430
451
431
452
public class PathValidity
@@ -444,6 +465,8 @@ public void LegalFilePathsOnly_rejects_command_arguments_containing_invalid_path
444
465
445
466
result . Errors
446
467
. Should ( )
468
+ . HaveCount ( 1 )
469
+ . And
447
470
. Contain ( e => e . SymbolResult . Symbol == command . Arguments . First ( ) &&
448
471
e . Message == $ "Character not allowed in a path: '{ invalidCharacter } '.") ;
449
472
}
@@ -462,6 +485,8 @@ public void LegalFilePathsOnly_rejects_option_arguments_containing_invalid_path_
462
485
463
486
result . Errors
464
487
. Should ( )
488
+ . HaveCount ( 1 )
489
+ . And
465
490
. Contain ( e => e . SymbolResult . Symbol . Name == "x" &&
466
491
e . Message == $ "Character not allowed in a path: '{ invalidCharacter } '.") ;
467
492
}
@@ -515,6 +540,8 @@ public void LegalFileNamesOnly_rejects_command_arguments_containing_invalid_file
515
540
516
541
result . Errors
517
542
. Should ( )
543
+ . HaveCount ( 1 )
544
+ . And
518
545
. Contain ( e => e . SymbolResult . Symbol == command . Arguments . First ( ) &&
519
546
e . Message == $ "Character not allowed in a file name: '{ invalidCharacter } '.") ;
520
547
}
@@ -533,6 +560,8 @@ public void LegalFileNamesOnly_rejects_option_arguments_containing_invalid_file_
533
560
534
561
result . Errors
535
562
. Should ( )
563
+ . HaveCount ( 1 )
564
+ . And
536
565
. Contain ( e => e . SymbolResult . Symbol . Name == "x" &&
537
566
e . Message == $ "Character not allowed in a file name: '{ invalidCharacter } '.") ;
538
567
}
@@ -739,8 +768,8 @@ public void A_command_argument_with_multiple_directories_can_be_invalid_based_on
739
768
.Should()
740
769
.HaveCount(1)
741
770
.And
742
- .Contain (e => e.SymbolResult.Symbol.Name == " to" &&
743
- e . Message == $ "Directory does not exist: '{ path } '.") ;
771
+ .ContainSingle (e => e.SymbolResult.Symbol.Name == " to" &&
772
+ e . Message == $ "Directory does not exist: '{ path } '.") ;
744
773
}
745
774
746
775
[ Fact ]
@@ -758,8 +787,8 @@ public void An_option_argument_with_multiple_directories_can_be_invalid_based_on
758
787
.Should()
759
788
.HaveCount(1)
760
789
.And
761
- .Contain (e => e.SymbolResult.Symbol.Name == " to" &&
762
- e . Message == $ "Directory does not exist: '{ path } '.") ;
790
+ .ContainSingle (e => e.SymbolResult.Symbol.Name == " to" &&
791
+ e . Message == $ "Directory does not exist: '{ path } '.") ;
763
792
}
764
793
765
794
[ Fact ]
@@ -779,8 +808,8 @@ public void A_command_argument_with_multiple_FileSystemInfos_can_be_invalid_base
779
808
780
809
result.Errors
781
810
.Should()
782
- .Contain (e => e.SymbolResult.Symbol.Name == " to" &&
783
- e . Message == $ "File or directory does not exist: '{ path } '.") ;
811
+ .ContainSingle (e => e.SymbolResult.Symbol.Name == " to" &&
812
+ e . Message == $ "File or directory does not exist: '{ path } '.") ;
784
813
}
785
814
786
815
[ Fact ]
@@ -798,8 +827,8 @@ public void An_option_argument_with_multiple_FileSystemInfos_can_be_invalid_base
798
827
799
828
result.Errors
800
829
.Should()
801
- .Contain (e => e.SymbolResult.Symbol.Name == " to" &&
802
- e . Message == $ "File or directory does not exist: '{ path } '.") ;
830
+ .ContainSingle (e => e.SymbolResult.Symbol.Name == " to" &&
831
+ e . Message == $ "File or directory does not exist: '{ path } '.") ;
803
832
}
804
833
805
834
[ Fact ]
@@ -817,8 +846,8 @@ public void A_command_argument_with_multiple_FileSystemInfos_can_be_invalid_base
817
846
.Should()
818
847
.HaveCount(1)
819
848
.And
820
- .Contain (e => e.SymbolResult.Symbol.Name == " to" &&
821
- e . Message == $ "File or directory does not exist: '{ path } '.") ;
849
+ .ContainSingle (e => e.SymbolResult.Symbol.Name == " to" &&
850
+ e . Message == $ "File or directory does not exist: '{ path } '.") ;
822
851
}
823
852
824
853
[ Fact ]
@@ -836,8 +865,8 @@ public void An_option_argument_with_multiple_FileSystemInfos_can_be_invalid_base
836
865
.Should()
837
866
.HaveCount(1)
838
867
.And
839
- .Contain (e => e.SymbolResult.Symbol.Name == " to" &&
840
- e . Message == $ "File or directory does not exist: '{ path } '.") ;
868
+ .ContainSingle (e => e.SymbolResult.Symbol.Name == " to" &&
869
+ e . Message == $ "File or directory does not exist: '{ path } '.") ;
841
870
}
842
871
843
872
[ Fact ]
@@ -999,7 +1028,7 @@ public void Arity_failures_are_not_reported_for_both_an_argument_and_its_parent_
999
1028
{
1000
1029
var newCommand = new Command ( "test" )
1001
1030
{
1002
- new Option < string > ( "--opt" , ParseMe )
1031
+ new Option < string > ( "--opt" )
1003
1032
} ;
1004
1033
1005
1034
var parseResult = newCommand . Parse ( "test --opt" ) ;
@@ -1010,36 +1039,71 @@ public void Arity_failures_are_not_reported_for_both_an_argument_and_its_parent_
1010
1039
. Which
1011
1040
. Message
1012
1041
. Should ( )
1013
- . Be (
1014
- "Required argument missing for option: '--opt'." ) ;
1042
+ . Be ( "Required argument missing for option: '--opt'." ) ;
1015
1043
}
1016
1044
1017
- private static string ParseMe ( ArgumentResult argumentResult )
1045
+ [ Fact ] // https://github.com/dotnet/command-line-api/issues/1573
1046
+ public void Multiple_validators_on_the_same_command_do_not_report_duplicate_errors ( )
1018
1047
{
1019
- if ( argumentResult . Parent is not OptionResult or)
1020
- {
1021
- throw new NotSupportedException ( "The method should be only used with option." ) ;
1022
- }
1048
+ var command = new RootCommand ( ) ;
1049
+ command . AddValidator ( result => result . ErrorMessage = "Wrong" ) ;
1050
+ command . AddValidator ( _ => { } ) ;
1023
1051
1024
- if ( argumentResult . Tokens . Count == 0 )
1025
- {
1026
- if ( or . IsImplicit )
1027
- {
1028
- return "default" ;
1029
- }
1030
- //no arg is not allowed
1031
- argumentResult . ErrorMessage = $ "(CUSTOM) Required argument missing for option: { or . Token . Value } .";
1032
- return default ! ;
1033
- }
1034
- else if ( argumentResult . Tokens . Count == 1 )
1052
+ var parseResult = command . Parse ( "" ) ;
1053
+
1054
+ parseResult . Errors
1055
+ . Should ( )
1056
+ . ContainSingle ( )
1057
+ . Which
1058
+ . Message
1059
+ . Should ( )
1060
+ . Be ( "Wrong" ) ;
1061
+ }
1062
+
1063
+ [ Fact ] // https://github.com/dotnet/command-line-api/issues/1573
1064
+ public void Multiple_validators_on_the_same_option_do_not_report_duplicate_errors ( )
1065
+ {
1066
+ var option = new Option < string > ( "-x" ) ;
1067
+ option . AddValidator ( result => result . ErrorMessage = "Wrong" ) ;
1068
+ option . AddValidator ( _ => { } ) ;
1069
+
1070
+ var command = new RootCommand
1035
1071
{
1036
- return "value" ;
1037
- }
1038
- else
1072
+ option
1073
+ } ;
1074
+
1075
+ var parseResult = command . Parse ( "-x b" ) ;
1076
+
1077
+ parseResult . Errors
1078
+ . Should ( )
1079
+ . ContainSingle ( )
1080
+ . Which
1081
+ . Message
1082
+ . Should ( )
1083
+ . Be ( "Wrong" ) ;
1084
+ }
1085
+
1086
+ [ Fact ] // https://github.com/dotnet/command-line-api/issues/1573
1087
+ public void Multiple_validators_on_the_same_argument_do_not_report_duplicate_errors ( )
1088
+ {
1089
+ var argument = new Argument < string > ( ) ;
1090
+ argument . AddValidator ( result => result . ErrorMessage = "Wrong" ) ;
1091
+ argument . AddValidator ( _ => { } ) ;
1092
+
1093
+ var command = new RootCommand
1039
1094
{
1040
- argumentResult . ErrorMessage = $ "Using more than 1 argument is not allowed for '{ or . Token . Value } ', used: { argumentResult . Tokens . Count } .";
1041
- return default ! ;
1042
- }
1095
+ argument
1096
+ } ;
1097
+
1098
+ var parseResult = command . Parse ( "b" ) ;
1099
+
1100
+ parseResult . Errors
1101
+ . Should ( )
1102
+ . ContainSingle ( )
1103
+ . Which
1104
+ . Message
1105
+ . Should ( )
1106
+ . Be ( "Wrong" ) ;
1043
1107
}
1044
1108
}
1045
1109
}
0 commit comments