@@ -1294,7 +1294,7 @@ describe('Class: Tracer', () => {
1294
1294
// Prepare
1295
1295
const tracer : Tracer = new Tracer ( ) ;
1296
1296
const newSubsegment : Segment | Subsegment | undefined = new Subsegment ( '### dummyMethod' ) ;
1297
-
1297
+
1298
1298
jest . spyOn ( tracer . provider , 'getSegment' )
1299
1299
. mockImplementation ( ( ) => newSubsegment ) ;
1300
1300
setContextMissingStrategy ( ( ) => null ) ;
@@ -1319,23 +1319,82 @@ describe('Class: Tracer', () => {
1319
1319
public otherDummyMethod ( ) : void {
1320
1320
return ;
1321
1321
}
1322
-
1323
1322
}
1324
-
1323
+
1325
1324
// Act
1326
1325
const lambda = new Lambda ( ) ;
1327
1326
const otherDummyMethodSpy = jest . spyOn ( lambda , 'otherDummyMethod' ) . mockImplementation ( ) ;
1328
1327
const handler = lambda . handler . bind ( lambda ) ;
1329
1328
await handler ( { } , context , ( ) => console . log ( 'Lambda invoked!' ) ) ;
1330
-
1331
- // Assess
1329
+
1332
1330
// Here we assert that the subsegment.close() (inside the finally of decorator) is called before the other otherDummyMethodSpy method
1333
1331
// that should always be called after the handler has returned. If subsegment.close() is called after it means the
1334
1332
// decorator is NOT awaiting the method which would cause the test to fail.
1335
1333
expect ( subsegmentCloseSpy . mock . invocationCallOrder [ 0 ] ) . toBeLessThan ( otherDummyMethodSpy . mock . invocationCallOrder [ 0 ] ) ;
1336
1334
1337
1335
} ) ;
1338
1336
1337
+ test ( 'when used as decorator together with another external decorator, the method name is detected properly' , async ( ) => {
1338
+
1339
+ // Prepare
1340
+ const tracer : Tracer = new Tracer ( ) ;
1341
+ const newSubsegment : Segment | Subsegment | undefined = new Subsegment ( '### dummyMethod' ) ;
1342
+ jest . spyOn ( tracer . provider , 'getSegment' )
1343
+ . mockImplementation ( ( ) => newSubsegment ) ;
1344
+ setContextMissingStrategy ( ( ) => null ) ;
1345
+ createCaptureAsyncFuncMock ( tracer . provider , newSubsegment ) ;
1346
+
1347
+ // Creating custom external decorator
1348
+ // eslint-disable-next-line func-style
1349
+ function passThrough ( ) {
1350
+ // A decorator that calls the original method.
1351
+ return (
1352
+ _target : unknown ,
1353
+ _propertyKey : string ,
1354
+ descriptor : PropertyDescriptor
1355
+ ) => {
1356
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1357
+ const originalMethod = descriptor . value ! ;
1358
+ descriptor . value = function ( ...args : unknown [ ] ) {
1359
+ return originalMethod . apply ( this , [ ...args ] ) ;
1360
+ } ;
1361
+ } ;
1362
+ }
1363
+
1364
+ class Lambda implements LambdaInterface {
1365
+ @tracer . captureMethod ( )
1366
+ @passThrough ( )
1367
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1368
+ // @ts -ignore
1369
+ public async dummyMethod ( ) : Promise < string > {
1370
+ return `foo` ;
1371
+ }
1372
+
1373
+ public async handler < TEvent , TResult > ( _event : TEvent , _context : Context , _callback : Callback < TResult > ) : Promise < void > {
1374
+ await this . dummyMethod ( ) ;
1375
+
1376
+ return ;
1377
+ }
1378
+
1379
+ }
1380
+
1381
+ // Act / Assess
1382
+ const lambda = new Lambda ( ) ;
1383
+ const handler = lambda . handler . bind ( lambda ) ;
1384
+ await handler ( { } , context , ( ) => console . log ( 'Lambda invoked!' ) ) ;
1385
+
1386
+ // Assess
1387
+ expect ( newSubsegment ) . toEqual ( expect . objectContaining ( {
1388
+ metadata : {
1389
+ 'hello-world' : {
1390
+ // Assess that the method name is added correctly
1391
+ 'dummyMethod response' : 'foo' ,
1392
+ } ,
1393
+ }
1394
+ } ) ) ;
1395
+
1396
+ } ) ;
1397
+
1339
1398
} ) ;
1340
1399
1341
1400
describe ( 'Method: captureAWS' , ( ) => {
0 commit comments