1+ using AspectInjector . Broker ;
2+ using System ;
3+ using System . Collections . Generic ;
4+ using System . Linq ;
5+ using Allure . Net . Commons ;
6+ using Xunit . Sdk ;
7+ using System . Reflection ;
8+ using System . Threading . Tasks ;
9+ using Allure . Xunit ;
10+ using Allure . XUnit . Attributes . Steps ;
11+
12+ namespace Allure . XUnit
13+ {
14+ [ Aspect ( Scope . Global ) ]
15+ public class AllureStepAspect
16+ {
17+ private static readonly MethodInfo AsyncHandler =
18+ typeof ( AllureStepAspect ) . GetMethod ( nameof ( WrapAsync ) , BindingFlags . NonPublic | BindingFlags . Static ) ;
19+
20+ private static readonly MethodInfo SyncHandler =
21+ typeof ( AllureStepAspect ) . GetMethod ( nameof ( WrapSync ) , BindingFlags . NonPublic | BindingFlags . Static ) ;
22+
23+ [ Advice ( Kind . Around ) ]
24+ public object Around ( [ Argument ( Source . Name ) ] string name ,
25+ [ Argument ( Source . Arguments ) ] object [ ] args ,
26+ [ Argument ( Source . Target ) ] Func < object [ ] , object > target ,
27+ [ Argument ( Source . Metadata ) ] MethodBase metadata ,
28+ [ Argument ( Source . ReturnType ) ] Type returnType )
29+ {
30+ object executionResult ;
31+
32+ var allureBeforeAttribute = metadata . GetCustomAttribute < AllureBeforeAttribute > ( ) ;
33+ var allureAfterAttribute = metadata . GetCustomAttribute < AllureAfterAttribute > ( ) ;
34+ var stepName = metadata . GetCustomAttribute < AllureStepBaseAttribute > ( ) . Name ?? name ;
35+
36+ if ( allureBeforeAttribute != null )
37+ {
38+ Steps . StartBeforeFixture ( allureBeforeAttribute . Name ?? name ) ;
39+ }
40+
41+ if ( allureAfterAttribute != null )
42+ {
43+ Steps . StartAfterFixture ( allureAfterAttribute . Name ?? name ) ;
44+ }
45+
46+
47+ foreach ( var parameterInfo in metadata . GetParameters ( ) )
48+ {
49+ stepName = stepName ? . Replace ( "{" + parameterInfo . Name + "}" ,
50+ args [ parameterInfo . Position ] ? . ToString ( ) ?? "null" ) ;
51+ }
52+
53+ List < Parameter > stepParameters = metadata . GetParameters ( )
54+ . Select ( x => (
55+ name : x . GetCustomAttribute < NameAttribute > ( ) ? . Name ?? x . Name ,
56+ skip : x . GetCustomAttribute < SkipAttribute > ( ) != null ) )
57+ . Zip ( args , ( parameter , value ) => parameter . skip
58+ ? null
59+ : new Parameter
60+ {
61+ name = parameter . name ,
62+ value = value ? . ToString ( )
63+ } )
64+ . Where ( x => x != null )
65+ . ToList ( ) ;
66+
67+ try
68+ {
69+ if ( allureBeforeAttribute == null && allureAfterAttribute == null )
70+ {
71+ Steps . StartStep ( stepName ) ;
72+ Steps . Current . parameters = stepParameters ;
73+ }
74+
75+ if ( typeof ( Task ) . IsAssignableFrom ( returnType ) )
76+ {
77+ var syncResultType = returnType . IsConstructedGenericType
78+ ? returnType . GenericTypeArguments [ 0 ]
79+ : typeof ( object ) ;
80+ executionResult = AsyncHandler . MakeGenericMethod ( syncResultType )
81+ . Invoke ( this , new object [ ] { target , args } ) ;
82+ }
83+ else if ( typeof ( void ) . IsAssignableFrom ( returnType ) )
84+ {
85+ executionResult = target ( args ) ;
86+ }
87+ else
88+ {
89+ executionResult = SyncHandler . MakeGenericMethod ( returnType )
90+ . Invoke ( this , new object [ ] { target , args } ) ;
91+ }
92+
93+ Steps . PassStep ( ) ;
94+ }
95+ catch ( Exception e )
96+ {
97+ Steps . Current . statusDetails = new StatusDetails
98+ {
99+ message = e . Message ,
100+ trace = e . StackTrace
101+ } ;
102+
103+ if ( e is XunitException )
104+ {
105+ Steps . FailStep ( ) ;
106+ }
107+ else
108+ {
109+ Steps . BrokeStep ( ) ;
110+ }
111+
112+ throw ;
113+ }
114+
115+ return executionResult ;
116+ }
117+
118+ private static T WrapSync < T > ( Func < object [ ] , object > target , object [ ] args )
119+ {
120+ try
121+ {
122+ return ( T ) target ( args ) ;
123+ }
124+ catch ( Exception e )
125+ {
126+ return default ( T ) ;
127+ }
128+ }
129+
130+ private static async Task < T > WrapAsync < T > ( Func < object [ ] , object > target , object [ ] args )
131+ {
132+ try
133+ {
134+ return await ( Task < T > ) target ( args ) ;
135+ }
136+ catch ( Exception e )
137+ {
138+ return default ( T ) ;
139+ }
140+ }
141+ }
142+ }
0 commit comments