@@ -318,6 +318,284 @@ static void Main(string[] args)
318
318
await VerifyCS . VerifyAnalyzerAsync ( source ) ;
319
319
}
320
320
321
+ [ Fact ]
322
+ public async Task ActionRouteToken_DifferentActionNames_NoDiagnostics ( )
323
+ {
324
+ // Arrange
325
+ var source = @"
326
+ using Microsoft.AspNetCore.Builder;
327
+ using Microsoft.AspNetCore.Mvc;
328
+ public class WeatherForecastController : ControllerBase
329
+ {
330
+ [Route(""{action}"")]
331
+ public object Get() => new object();
332
+
333
+ [Route(""{action}"")]
334
+ public object Get1() => new object();
335
+ }
336
+ internal class Program
337
+ {
338
+ static void Main(string[] args)
339
+ {
340
+ }
341
+ }
342
+ " ;
343
+
344
+ // Act & Assert
345
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
346
+ }
347
+
348
+ [ Fact ]
349
+ public async Task ActionRouteToken_SameActionName_HasDiagnostics ( )
350
+ {
351
+ // Arrange
352
+ var source = @"
353
+ using Microsoft.AspNetCore.Builder;
354
+ using Microsoft.AspNetCore.Mvc;
355
+ public class WeatherForecastController : ControllerBase
356
+ {
357
+ [Route({|#0:""{action}""|})]
358
+ public object Get() => new object();
359
+
360
+ [Route({|#1:""{action}""|})]
361
+ public object Get(int i) => new object();
362
+ }
363
+ internal class Program
364
+ {
365
+ static void Main(string[] args)
366
+ {
367
+ }
368
+ }
369
+ " ;
370
+
371
+ var expectedDiagnostics = new [ ] {
372
+ new DiagnosticResult ( DiagnosticDescriptors . AmbiguousActionRoute ) . WithArguments ( "{action}" ) . WithLocation ( 0 ) ,
373
+ new DiagnosticResult ( DiagnosticDescriptors . AmbiguousActionRoute ) . WithArguments ( "{action}" ) . WithLocation ( 1 )
374
+ } ;
375
+
376
+ // Act & Assert
377
+ await VerifyCS . VerifyAnalyzerAsync ( source , expectedDiagnostics ) ;
378
+ }
379
+
380
+ [ Fact ]
381
+ public async Task ActionRouteToken_ActionNameAttribute_HasDiagnostics ( )
382
+ {
383
+ // Arrange
384
+ var source = @"
385
+ using Microsoft.AspNetCore.Builder;
386
+ using Microsoft.AspNetCore.Mvc;
387
+ public class WeatherForecastController : ControllerBase
388
+ {
389
+ [Route({|#0:""{action}""|})]
390
+ public object Get() => new object();
391
+
392
+ [Route({|#1:""{action}""|})]
393
+ [ActionName(""get"")]
394
+ public object Get1(int i) => new object();
395
+ }
396
+ internal class Program
397
+ {
398
+ static void Main(string[] args)
399
+ {
400
+ }
401
+ }
402
+ " ;
403
+
404
+ var expectedDiagnostics = new [ ] {
405
+ new DiagnosticResult ( DiagnosticDescriptors . AmbiguousActionRoute ) . WithArguments ( "{action}" ) . WithLocation ( 0 ) ,
406
+ new DiagnosticResult ( DiagnosticDescriptors . AmbiguousActionRoute ) . WithArguments ( "{action}" ) . WithLocation ( 1 )
407
+ } ;
408
+
409
+ // Act & Assert
410
+ await VerifyCS . VerifyAnalyzerAsync ( source , expectedDiagnostics ) ;
411
+ }
412
+
413
+ [ Fact ]
414
+ public async Task ActionRouteToken_ActionNameAttributeNullValue_NoDiagnostics ( )
415
+ {
416
+ // Arrange
417
+ var source = @"
418
+ using Microsoft.AspNetCore.Builder;
419
+ using Microsoft.AspNetCore.Mvc;
420
+ public class WeatherForecastController : ControllerBase
421
+ {
422
+ [Route({|#0:""{action}""|})]
423
+ public object Get() => new object();
424
+
425
+ [Route({|#1:""{action}""|})]
426
+ [ActionName(null)]
427
+ public object Get1(int i) => new object();
428
+ }
429
+ internal class Program
430
+ {
431
+ static void Main(string[] args)
432
+ {
433
+ }
434
+ }
435
+ " ;
436
+
437
+ // Act & Assert
438
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
439
+ }
440
+
441
+ [ Fact ]
442
+ public async Task ActionRouteToken_OnController_NoDiagnostics ( )
443
+ {
444
+ // Arrange
445
+ var source = @"
446
+ using Microsoft.AspNetCore.Builder;
447
+ using Microsoft.AspNetCore.Mvc;
448
+ [Route(""{controller}/{action}"")]
449
+ public class WeatherForecastController : ControllerBase
450
+ {
451
+ [Route(""{i}"")]
452
+ public object Get(int i) => new object();
453
+
454
+ [Route(""{i}"")]
455
+ public object Get1(int i) => new object();
456
+ }
457
+ internal class Program
458
+ {
459
+ static void Main(string[] args)
460
+ {
461
+ }
462
+ }
463
+ " ;
464
+
465
+ // Act & Assert
466
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
467
+ }
468
+
469
+ [ Fact ]
470
+ public async Task ActionRouteToken_OnBaseController_NoDiagnostics ( )
471
+ {
472
+ // Arrange
473
+ var source = @"
474
+ using Microsoft.AspNetCore.Builder;
475
+ using Microsoft.AspNetCore.Mvc;
476
+ [Route(""{controller}/{action}"")]
477
+ public class MyControllerBase : ControllerBase
478
+ {
479
+ }
480
+ public class WeatherForecastController : MyControllerBase
481
+ {
482
+ [Route(""{i}"")]
483
+ public object Get(int i) => new object();
484
+
485
+ [Route(""{i}"")]
486
+ public object Get1(int i) => new object();
487
+ }
488
+ internal class Program
489
+ {
490
+ static void Main(string[] args)
491
+ {
492
+ }
493
+ }
494
+ " ;
495
+
496
+ // Act & Assert
497
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
498
+ }
499
+
500
+ [ Fact ]
501
+ public async Task ActionRouteToken_OnBaseControllerButOverridden_HasDiagnostics ( )
502
+ {
503
+ // Arrange
504
+ var source = @"
505
+ using Microsoft.AspNetCore.Builder;
506
+ using Microsoft.AspNetCore.Mvc;
507
+ [Route(""{controller}/{action}"")]
508
+ public class MyControllerBase : ControllerBase
509
+ {
510
+ }
511
+ [Route(""api"")]
512
+ public class WeatherForecastController : MyControllerBase
513
+ {
514
+ [Route({|#0:""{i}""|})]
515
+ public object Get(int i) => new object();
516
+
517
+ [Route({|#1:""{i}""|})]
518
+ public object Get1(int i) => new object();
519
+ }
520
+ internal class Program
521
+ {
522
+ static void Main(string[] args)
523
+ {
524
+ }
525
+ }
526
+ " ;
527
+
528
+ var expectedDiagnostics = new [ ] {
529
+ new DiagnosticResult ( DiagnosticDescriptors . AmbiguousActionRoute ) . WithArguments ( "{i}" ) . WithLocation ( 0 ) ,
530
+ new DiagnosticResult ( DiagnosticDescriptors . AmbiguousActionRoute ) . WithArguments ( "{i}" ) . WithLocation ( 1 )
531
+ } ;
532
+
533
+ // Act & Assert
534
+ await VerifyCS . VerifyAnalyzerAsync ( source , expectedDiagnostics ) ;
535
+ }
536
+
537
+ [ Fact ]
538
+ public async Task ActionRouteToken_OnController_ActionName_NoDiagnostics ( )
539
+ {
540
+ // Arrange
541
+ var source = @"
542
+ using Microsoft.AspNetCore.Builder;
543
+ using Microsoft.AspNetCore.Mvc;
544
+ [Route(""{controller}/{action}"")]
545
+ public class WeatherForecastController : ControllerBase
546
+ {
547
+ [Route(""{i}"")]
548
+ public object Get(int i) => new object();
549
+
550
+ [Route(""{s}"")]
551
+ [ActionName(name: ""getWithString"")]
552
+ public object Get(string s) => new object();
553
+ }
554
+ internal class Program
555
+ {
556
+ static void Main(string[] args)
557
+ {
558
+ }
559
+ }
560
+ " ;
561
+
562
+ // Act & Assert
563
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
564
+ }
565
+
566
+ [ Fact ]
567
+ public async Task ActionRouteToken_OnController_ActionNameOnBase_NoDiagnostics ( )
568
+ {
569
+ // Arrange
570
+ var source = @"
571
+ using Microsoft.AspNetCore.Builder;
572
+ using Microsoft.AspNetCore.Mvc;
573
+ public abstract class MyControllerBase : ControllerBase
574
+ {
575
+ [ActionName(name: ""getWithString"")]
576
+ public abstract object Get(string s);
577
+ }
578
+ [Route(""{controller}/{action}"")]
579
+ public class WeatherForecastController : MyControllerBase
580
+ {
581
+ [Route(""{i}"")]
582
+ public object Get(int i) => new object();
583
+
584
+ [Route(""{s}"")]
585
+ public override object Get(string s) => new object();
586
+ }
587
+ internal class Program
588
+ {
589
+ static void Main(string[] args)
590
+ {
591
+ }
592
+ }
593
+ " ;
594
+
595
+ // Act & Assert
596
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
597
+ }
598
+
321
599
[ Fact ]
322
600
public async Task MixedRoutes_DifferentAction_HasDiagnostics ( )
323
601
{
0 commit comments