@@ -15,10 +15,12 @@ interface LambdaInterface {
1515}
1616
1717type CaptureAsyncFuncMock = jest . SpyInstance < unknown , [ name : string , fcn : ( subsegment ?: Subsegment ) => unknown , parent ?: Segment | Subsegment ] > ;
18- const createCaptureAsyncFuncMock = function ( provider : ProviderServiceInterface ) : CaptureAsyncFuncMock {
18+ const createCaptureAsyncFuncMock = function ( provider : ProviderServiceInterface , subsegment ?: Subsegment ) : CaptureAsyncFuncMock {
1919 return jest . spyOn ( provider , 'captureAsyncFunc' )
2020 . mockImplementation ( async ( methodName , callBackFn ) => {
21- const subsegment = new Subsegment ( `### ${ methodName } ` ) ;
21+ if ( ! subsegment ) {
22+ subsegment = new Subsegment ( `### ${ methodName } ` ) ;
23+ }
2224 jest . spyOn ( subsegment , 'flush' ) . mockImplementation ( ( ) => null ) ;
2325 await callBackFn ( subsegment ) ;
2426 } ) ;
@@ -1239,6 +1241,67 @@ describe('Class: Tracer', () => {
12391241
12401242 } ) ;
12411243
1244+ test ( 'when used as decorator together with another external decorator, the method name is detected properly' , async ( ) => {
1245+
1246+ // Prepare
1247+ const tracer : Tracer = new Tracer ( ) ;
1248+ const newSubsegment : Segment | Subsegment | undefined = new Subsegment ( '### dummyMethod' ) ;
1249+ jest . spyOn ( tracer . provider , 'getSegment' )
1250+ . mockImplementation ( ( ) => newSubsegment ) ;
1251+ setContextMissingStrategy ( ( ) => null ) ;
1252+ createCaptureAsyncFuncMock ( tracer . provider , newSubsegment ) ;
1253+
1254+ // Creating custom external decorator
1255+ // eslint-disable-next-line func-style
1256+ function passThrough ( ) {
1257+ // A decorator that calls the original method.
1258+ return (
1259+ _target : unknown ,
1260+ _propertyKey : string ,
1261+ descriptor : PropertyDescriptor
1262+ ) => {
1263+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1264+ const originalMethod = descriptor . value ! ;
1265+ descriptor . value = function ( ...args : unknown [ ] ) {
1266+ return originalMethod . apply ( this , [ ...args ] ) ;
1267+ } ;
1268+ } ;
1269+ }
1270+
1271+ class Lambda implements LambdaInterface {
1272+ @tracer . captureMethod ( )
1273+ @passThrough ( )
1274+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1275+ // @ts -ignore
1276+ public async dummyMethod ( ) : Promise < string > {
1277+ return `foo` ;
1278+ }
1279+
1280+ public async handler < TEvent , TResult > ( _event : TEvent , _context : Context , _callback : Callback < TResult > ) : Promise < void > {
1281+ await this . dummyMethod ( ) ;
1282+
1283+ return ;
1284+ }
1285+
1286+ }
1287+
1288+ // Act / Assess
1289+ const lambda = new Lambda ( ) ;
1290+ const handler = lambda . handler . bind ( lambda ) ;
1291+ await handler ( { } , context , ( ) => console . log ( 'Lambda invoked!' ) ) ;
1292+
1293+ // Assess
1294+ expect ( newSubsegment ) . toEqual ( expect . objectContaining ( {
1295+ metadata : {
1296+ 'hello-world' : {
1297+ // Assess that the method name is added correctly
1298+ 'dummyMethod response' : 'foo' ,
1299+ } ,
1300+ }
1301+ } ) ) ;
1302+
1303+ } ) ;
1304+
12421305 } ) ;
12431306
12441307 describe ( 'Method: captureAWS' , ( ) => {
0 commit comments