@@ -416,14 +416,16 @@ private TestAssemblyInfo GetAssemblyInfo(Type type)
416
416
// Enumerate through all methods and identify the Assembly Init and cleanup methods.
417
417
foreach ( MethodInfo methodInfo in PlatformServiceProvider . Instance . ReflectionOperations . GetDeclaredMethods ( t ) )
418
418
{
419
- if ( IsAssemblyOrClassInitializeMethod < AssemblyInitializeAttribute > ( methodInfo ) )
419
+ if ( GetAssemblyOrClassInitializeMethod < AssemblyInitializeAttribute > ( methodInfo ) is { } assemblyInitializeAttribute )
420
420
{
421
421
assemblyInfo . AssemblyInitializeMethod = methodInfo ;
422
+ assemblyInfo . AssemblyInitializeAttribute = assemblyInitializeAttribute ;
422
423
assemblyInfo . AssemblyInitializeMethodTimeoutMilliseconds = TryGetTimeoutInfo ( methodInfo , FixtureKind . AssemblyInitialize ) ;
423
424
}
424
- else if ( IsAssemblyOrClassCleanupMethod < AssemblyCleanupAttribute > ( methodInfo ) )
425
+ else if ( GetAssemblyOrClassCleanupMethod < AssemblyCleanupAttribute > ( methodInfo ) is { } assemblyCleanupAttribute )
425
426
{
426
427
assemblyInfo . AssemblyCleanupMethod = methodInfo ;
428
+ assemblyInfo . AssemblyCleanupAttribute = assemblyCleanupAttribute ;
427
429
assemblyInfo . AssemblyCleanupMethodTimeoutMilliseconds = TryGetTimeoutInfo ( methodInfo , FixtureKind . AssemblyCleanup ) ;
428
430
}
429
431
}
@@ -440,17 +442,28 @@ private TestAssemblyInfo GetAssemblyInfo(Type type)
440
442
/// <typeparam name="TInitializeAttribute">The initialization attribute type. </typeparam>
441
443
/// <param name="methodInfo"> The method info. </param>
442
444
/// <returns> True if its an initialization method. </returns>
443
- private bool IsAssemblyOrClassInitializeMethod < TInitializeAttribute > ( MethodInfo methodInfo )
445
+ private TInitializeAttribute ? GetAssemblyOrClassInitializeMethod < TInitializeAttribute > ( MethodInfo methodInfo )
444
446
where TInitializeAttribute : Attribute
445
447
{
446
448
// TODO: this would be inconsistent with the codebase, but potential perf gain, issue: https://github.com/microsoft/testfx/issues/2999
447
449
// if (!methodInfo.IsStatic)
448
450
// {
449
451
// return false;
450
452
// }
451
- if ( ! _reflectionHelper . IsNonDerivedAttributeDefined < TInitializeAttribute > ( methodInfo , false ) )
453
+ IEnumerable < TInitializeAttribute > attributes = _reflectionHelper . GetDerivedAttributes < TInitializeAttribute > ( methodInfo , inherit : false ) ;
454
+ using IEnumerator < TInitializeAttribute > enumerator = attributes . GetEnumerator ( ) ;
455
+ if ( ! enumerator . MoveNext ( ) )
452
456
{
453
- return false ;
457
+ // No attribute found.
458
+ return null ;
459
+ }
460
+
461
+ TInitializeAttribute attribute = enumerator . Current ;
462
+ if ( enumerator . MoveNext ( ) )
463
+ {
464
+ // More than one attribute found.
465
+ string message = string . Format ( CultureInfo . CurrentCulture , Resource . UTA_MultipleAttributesOnTestMethod , methodInfo . DeclaringType ! . FullName , methodInfo . Name ) ;
466
+ throw new TypeInspectionException ( message ) ;
454
467
}
455
468
456
469
if ( ! methodInfo . HasCorrectClassOrAssemblyInitializeSignature ( ) )
@@ -459,7 +472,7 @@ private bool IsAssemblyOrClassInitializeMethod<TInitializeAttribute>(MethodInfo
459
472
throw new TypeInspectionException ( message ) ;
460
473
}
461
474
462
- return true ;
475
+ return attribute ;
463
476
}
464
477
465
478
/// <summary>
@@ -468,17 +481,28 @@ private bool IsAssemblyOrClassInitializeMethod<TInitializeAttribute>(MethodInfo
468
481
/// <typeparam name="TCleanupAttribute">The cleanup attribute type.</typeparam>
469
482
/// <param name="methodInfo"> The method info. </param>
470
483
/// <returns> True if its a cleanup method. </returns>
471
- private bool IsAssemblyOrClassCleanupMethod < TCleanupAttribute > ( MethodInfo methodInfo )
484
+ private TCleanupAttribute ? GetAssemblyOrClassCleanupMethod < TCleanupAttribute > ( MethodInfo methodInfo )
472
485
where TCleanupAttribute : Attribute
473
486
{
474
487
// TODO: this would be inconsistent with the codebase, but potential perf gain, issue: https://github.com/microsoft/testfx/issues/2999
475
488
// if (!methodInfo.IsStatic)
476
489
// {
477
490
// return false;
478
491
// }
479
- if ( ! _reflectionHelper . IsNonDerivedAttributeDefined < TCleanupAttribute > ( methodInfo , false ) )
492
+ IEnumerable < TCleanupAttribute > attributes = _reflectionHelper . GetDerivedAttributes < TCleanupAttribute > ( methodInfo , inherit : false ) ;
493
+ using IEnumerator < TCleanupAttribute > enumerator = attributes . GetEnumerator ( ) ;
494
+ if ( ! enumerator . MoveNext ( ) )
480
495
{
481
- return false ;
496
+ // No attribute found.
497
+ return null ;
498
+ }
499
+
500
+ TCleanupAttribute attribute = enumerator . Current ;
501
+ if ( enumerator . MoveNext ( ) )
502
+ {
503
+ // More than one attribute found.
504
+ string message = string . Format ( CultureInfo . CurrentCulture , Resource . UTA_MultipleAttributesOnTestMethod , methodInfo . DeclaringType ! . FullName , methodInfo . Name ) ;
505
+ throw new TypeInspectionException ( message ) ;
482
506
}
483
507
484
508
if ( ! methodInfo . HasCorrectClassOrAssemblyCleanupSignature ( ) )
@@ -487,7 +511,7 @@ private bool IsAssemblyOrClassCleanupMethod<TCleanupAttribute>(MethodInfo method
487
511
throw new TypeInspectionException ( message ) ;
488
512
}
489
513
490
- return true ;
514
+ return attribute ;
491
515
}
492
516
493
517
#endregion
@@ -546,10 +570,10 @@ private void UpdateInfoIfClassInitializeOrCleanupMethod(
546
570
bool isBase ,
547
571
ref MethodInfo ? [ ] initAndCleanupMethods )
548
572
{
549
- bool isInitializeMethod = IsAssemblyOrClassInitializeMethod < ClassInitializeAttribute > ( methodInfo ) ;
550
- bool isCleanupMethod = IsAssemblyOrClassCleanupMethod < ClassCleanupAttribute > ( methodInfo ) ;
573
+ ClassInitializeAttribute ? classInitializeAttribute = GetAssemblyOrClassInitializeMethod < ClassInitializeAttribute > ( methodInfo ) ;
574
+ ClassCleanupAttribute ? classCleanupAttribute = GetAssemblyOrClassCleanupMethod < ClassCleanupAttribute > ( methodInfo ) ;
551
575
552
- if ( isInitializeMethod )
576
+ if ( classInitializeAttribute is not null )
553
577
{
554
578
if ( TryGetTimeoutInfo ( methodInfo , FixtureKind . ClassInitialize ) is { } timeoutInfo )
555
579
{
@@ -571,7 +595,7 @@ private void UpdateInfoIfClassInitializeOrCleanupMethod(
571
595
}
572
596
}
573
597
574
- if ( isCleanupMethod )
598
+ if ( classCleanupAttribute is not null )
575
599
{
576
600
if ( TryGetTimeoutInfo ( methodInfo , FixtureKind . ClassCleanup ) is { } timeoutInfo )
577
601
{
0 commit comments