@@ -1034,4 +1034,81 @@ const test = require("./test");`,
10341034 assert . isTrue ( helpers . isInteractive ( ) ) ;
10351035 } ) ;
10361036 } ) ;
1037+
1038+ describe ( "decorateMethod" , ( ) => {
1039+ const decorate = ( middlewares : Function [ ] , sink : Function ) : Function => {
1040+ const descriptor : TypedPropertyDescriptor < Function > = { value : sink } ;
1041+ helpers . decorateMethod (
1042+ async ( ) => middlewares ,
1043+ async ( method , self , result ) => result ,
1044+ ) ( null , "method" , descriptor ) ;
1045+ return descriptor . value ;
1046+ } ;
1047+
1048+ it ( "passes the original args and the sink to a single middleware" , async ( ) => {
1049+ let received : any [ ] ;
1050+ const middleware = async ( args : any [ ] , next : Function ) => {
1051+ received = args ;
1052+ return next . apply ( null , [ "replaced" ] ) ;
1053+ } ;
1054+ const decorated = decorate ( [ middleware ] , async function ( ...args : any [ ] ) {
1055+ return args ;
1056+ } ) ;
1057+
1058+ const result = await decorated . call ( { } , "original" ) ;
1059+
1060+ assert . deepStrictEqual ( received , [ "original" ] ) ;
1061+ assert . deepStrictEqual ( result , [ "replaced" ] ) ;
1062+ } ) ;
1063+
1064+ it ( "forwards args changed by every middleware, not only the innermost" , async ( ) => {
1065+ const seen : { [ key : string ] : any [ ] } = { } ;
1066+ // The last middleware in the array is the outermost link, so it runs
1067+ // first.
1068+ const runsSecond = async ( args : any [ ] , next : Function ) => {
1069+ seen . second = args . slice ( ) ;
1070+ return next . apply ( null , args . concat ( "second" ) ) ;
1071+ } ;
1072+ const runsFirst = async ( args : any [ ] , next : Function ) => {
1073+ seen . first = args . slice ( ) ;
1074+ return next . apply ( null , args . concat ( "first" ) ) ;
1075+ } ;
1076+ const decorated = decorate (
1077+ [ runsSecond , runsFirst ] ,
1078+ async function ( ...args : any [ ] ) {
1079+ seen . sink = args ;
1080+ return "done" ;
1081+ } ,
1082+ ) ;
1083+
1084+ const result = await decorated . call ( { } , "start" ) ;
1085+
1086+ assert . deepStrictEqual ( seen . first , [ "start" ] ) ;
1087+ assert . deepStrictEqual ( seen . second , [ "start" , "first" ] ) ;
1088+ assert . deepStrictEqual ( seen . sink , [ "start" , "first" , "second" ] ) ;
1089+ assert . strictEqual ( result , "done" ) ;
1090+ } ) ;
1091+
1092+ it ( "keeps the current args when a middleware calls next() without arguments" , async ( ) => {
1093+ const seen : { [ key : string ] : any [ ] } = { } ;
1094+ const inner = async ( args : any [ ] , next : Function ) => {
1095+ seen . inner = args . slice ( ) ;
1096+ return next . apply ( null , args ) ;
1097+ } ;
1098+ const outer = async ( args : any [ ] , next : Function ) => {
1099+ return next ( ) ;
1100+ } ;
1101+ const decorated = decorate (
1102+ [ inner , outer ] ,
1103+ async function ( ...args : any [ ] ) {
1104+ seen . sink = args ;
1105+ } ,
1106+ ) ;
1107+
1108+ await decorated . call ( { } , "kept" ) ;
1109+
1110+ assert . deepStrictEqual ( seen . inner , [ "kept" ] ) ;
1111+ assert . deepStrictEqual ( seen . sink , [ "kept" ] ) ;
1112+ } ) ;
1113+ } ) ;
10371114} ) ;
0 commit comments