Skip to content

Commit 5afc0d6

Browse files
AllanZhengYPtrivikr
authored andcommitted
fix: fix bugs when recursively appending middleware (#476)
1 parent fe5a061 commit 5afc0d6

File tree

2 files changed

+69
-43
lines changed

2 files changed

+69
-43
lines changed

packages/middleware-stack/src/MiddlewareStack.spec.ts

+54-30
Original file line numberDiff line numberDiff line change
@@ -97,59 +97,83 @@ describe("MiddlewareStack", () => {
9797
it("should allow adding middleware relatively", async () => {
9898
const stack = new MiddlewareStack<input, output>();
9999
type MW = InitializeMiddleware<input, output>;
100-
stack.addRelativeTo(getConcatMiddleware("G") as MW, {
101-
name: "G",
100+
stack.addRelativeTo(getConcatMiddleware("H") as MW, {
101+
name: "H",
102102
relation: "after",
103-
toMiddleware: "F"
103+
toMiddleware: "G"
104104
});
105105
stack.addRelativeTo(getConcatMiddleware("A") as MW, {
106106
name: "A",
107107
relation: "after",
108108
toMiddleware: "nonExist"
109109
});
110-
stack.addRelativeTo(getConcatMiddleware("B") as MW, {
111-
name: "B",
112-
relation: "after",
113-
toMiddleware: "A"
114-
});
115110
stack.addRelativeTo(getConcatMiddleware("C") as MW, {
116111
name: "C",
117112
relation: "after",
118113
toMiddleware: "A"
119114
});
120-
stack.add(getConcatMiddleware("F") as MW, {
121-
name: "F",
122-
priority: "low"
115+
stack.addRelativeTo(getConcatMiddleware("B") as MW, {
116+
name: "B",
117+
relation: "after",
118+
toMiddleware: "A"
123119
});
124120
stack.addRelativeTo(getConcatMiddleware("D") as MW, {
125121
name: "D",
126-
relation: "before",
127-
toMiddleware: "F"
122+
relation: "after",
123+
toMiddleware: "C"
124+
});
125+
stack.add(getConcatMiddleware("G") as MW, {
126+
name: "G",
127+
priority: "low"
128128
});
129129
stack.addRelativeTo(getConcatMiddleware("E") as MW, {
130130
name: "E",
131131
relation: "before",
132132
toMiddleware: "F"
133133
});
134-
stack.addRelativeTo(getConcatMiddleware("H") as MW, {
135-
name: "H",
134+
stack.addRelativeTo(getConcatMiddleware("F") as MW, {
135+
name: "F",
136136
relation: "before",
137-
toMiddleware: "I"
137+
toMiddleware: "G"
138138
});
139139
stack.addRelativeTo(getConcatMiddleware("I") as MW, {
140140
name: "I",
141+
relation: "before",
142+
toMiddleware: "J"
143+
});
144+
stack.addRelativeTo(getConcatMiddleware("J") as MW, {
145+
name: "J",
141146
relation: "after",
142-
toMiddleware: "H"
147+
toMiddleware: "I"
143148
});
144149
const inner = jest.fn();
145150

146151
const composed = stack.resolve(inner, {} as any);
147152
await composed({ input: [] });
148153

149154
expect(inner.mock.calls.length).toBe(1);
150-
expect(inner).toBeCalledWith({
151-
input: ["A", "B", "C", "H", "I", "D", "E", "F", "G"]
152-
});
155+
const concatenated = inner.mock.calls[0][0].input;
156+
expect(concatenated.indexOf("H")).toBeGreaterThan(
157+
concatenated.indexOf("G")
158+
);
159+
expect(concatenated.indexOf("C")).toBeGreaterThan(
160+
concatenated.indexOf("A")
161+
);
162+
expect(concatenated.indexOf("B")).toBeGreaterThan(
163+
concatenated.indexOf("A")
164+
);
165+
expect(concatenated.indexOf("D")).toBeGreaterThan(
166+
concatenated.indexOf("C")
167+
);
168+
expect(concatenated.indexOf("E")).toBeLessThan(concatenated.indexOf("F"));
169+
expect(concatenated.indexOf("F")).toBeLessThan(concatenated.indexOf("G"));
170+
expect(concatenated.indexOf("I")).toBeLessThan(concatenated.indexOf("J"));
171+
expect(concatenated.indexOf("J")).toBeGreaterThan(
172+
concatenated.indexOf("I")
173+
);
174+
expect(concatenated.indexOf("H")).toBeGreaterThan(
175+
concatenated.indexOf("G")
176+
);
153177
});
154178

155179
it("should allow cloning", async () => {
@@ -187,26 +211,26 @@ describe("MiddlewareStack", () => {
187211

188212
it("should allow combining stacks", async () => {
189213
const stack = new MiddlewareStack<input, output>();
190-
stack.add(getConcatMiddleware("second") as InitializeMiddleware<
214+
stack.add(getConcatMiddleware("first") as InitializeMiddleware<
191215
input,
192216
output
193217
>);
194218
stack.add(
195-
getConcatMiddleware("first") as InitializeMiddleware<input, output>,
219+
getConcatMiddleware("second") as InitializeMiddleware<input, output>,
196220
{
197-
name: "first",
198-
priority: "high"
221+
name: "second",
222+
priority: "low"
199223
}
200224
);
201225

202226
const secondStack = new MiddlewareStack<input, output>();
203227
secondStack.add(
204228
getConcatMiddleware("fourth") as FinalizeRequestMiddleware<input, output>,
205-
{ step: "build" }
229+
{ step: "build", priority: "low" }
206230
);
207-
secondStack.add(
231+
secondStack.addRelativeTo(
208232
getConcatMiddleware("third") as FinalizeRequestMiddleware<input, output>,
209-
{ step: "build", priority: "high" }
233+
{ step: "build", relation: "after", toMiddleware: "second" }
210234
);
211235

212236
let inner = jest.fn(({ input }: DeserializeHandlerArguments<input>) => {
@@ -218,11 +242,11 @@ describe("MiddlewareStack", () => {
218242
expect(inner.mock.calls.length).toBe(1);
219243

220244
secondStack.add(
221-
getConcatMiddleware("first") as FinalizeRequestMiddleware<input, output>,
222-
{ step: "build", priority: "high", name: "first" }
245+
getConcatMiddleware("second") as FinalizeRequestMiddleware<input, output>,
246+
{ step: "build", priority: "high", name: "second" }
223247
);
224248
expect(() => stack.concat(secondStack)).toThrow(
225-
"Duplicated middleware name 'first'"
249+
"Duplicated middleware name 'second'"
226250
);
227251
});
228252

packages/middleware-stack/src/MiddlewareStack.ts

+15-13
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,12 @@ export class MiddlewareStack<Input extends object, Output extends object> {
147147
> {
148148
//reverse before sorting so that middleware of same step will execute in
149149
//the order of being added
150-
return entries
151-
.reverse()
152-
.sort(
153-
(a, b) =>
154-
stepWeights[a.step] - stepWeights[b.step] ||
155-
priorityWeights[a.priority || "normal"] -
156-
priorityWeights[b.priority || "normal"]
157-
);
150+
return entries.sort(
151+
(a, b) =>
152+
stepWeights[b.step] - stepWeights[a.step] ||
153+
priorityWeights[b.priority || "normal"] -
154+
priorityWeights[a.priority || "normal"]
155+
);
158156
}
159157

160158
clone(): IMiddlewareStack<Input, Output> {
@@ -405,24 +403,28 @@ export class MiddlewareStack<Input extends object, Output extends object> {
405403
const { prev, next } = entry.name
406404
? anchors[entry.name] || defaultAnchorValue
407405
: defaultAnchorValue;
408-
let relativeEntry = next;
406+
let relativeEntry = prev;
407+
//reverse relative entry linked list and add to ordered handler list
408+
while (relativeEntry && relativeEntry.prev) {
409+
relativeEntry = relativeEntry.prev;
410+
}
409411
while (relativeEntry) {
410412
middlewareList.push(relativeEntry.middleware);
411413
relativeEntry = relativeEntry.next;
412414
}
415+
middlewareList.push(entry.middleware);
413416
let orphanedEntry = entry as any;
414417
while ((orphanedEntry as any).next) {
415418
middlewareList.push((orphanedEntry as any).next.middleware);
416419
orphanedEntry = (orphanedEntry as any).next;
417420
}
418-
middlewareList.push(entry.middleware);
419-
relativeEntry = prev;
421+
relativeEntry = next;
420422
while (relativeEntry) {
421423
middlewareList.push(relativeEntry.middleware);
422-
relativeEntry = relativeEntry.prev;
424+
relativeEntry = relativeEntry.next;
423425
}
424426
}
425-
return middlewareList;
427+
return middlewareList.reverse();
426428
}
427429

428430
resolve<InputType extends Input, OutputType extends Output>(

0 commit comments

Comments
 (0)