Make sure middleware layer sorting is stable
See https://github.com/strongloop/strong-arc/issues/767
This commit is contained in:
parent
5150a58364
commit
cd89299163
|
@ -214,13 +214,22 @@ proto._sortLayersByPhase = function() {
|
|||
});
|
||||
|
||||
var router = this._router;
|
||||
|
||||
// See https://code.google.com/p/v8/issues/detail?id=90
|
||||
router.stack.forEach(function(layer, ix) {
|
||||
layer.order = ix;
|
||||
});
|
||||
router.stack.sort(compareLayers);
|
||||
|
||||
function compareLayers(left, right) {
|
||||
var leftPhase = left.phase;
|
||||
var rightPhase = right.phase;
|
||||
|
||||
if (leftPhase === rightPhase) return 0;
|
||||
var result;
|
||||
if (leftPhase === rightPhase) {
|
||||
// Keep the order (stable sorting)
|
||||
return left.order - right.order;
|
||||
}
|
||||
|
||||
// Builtin middleware is always first
|
||||
if (leftPhase === BUILTIN_MIDDLEWARE) return -1;
|
||||
|
@ -232,13 +241,23 @@ proto._sortLayersByPhase = function() {
|
|||
if (rightPhase === 'routes')
|
||||
return -1;
|
||||
|
||||
return phaseOrder['routes'] - phaseOrder[rightPhase];
|
||||
result = phaseOrder['routes'] - phaseOrder[rightPhase];
|
||||
if (result === 0) {
|
||||
return left.order - right.order;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (rightPhase === undefined)
|
||||
return -compareLayers(right, left);
|
||||
|
||||
// Layers registered via `app.middleware` are compared via phase & hook
|
||||
return phaseOrder[leftPhase] - phaseOrder[rightPhase];
|
||||
result = phaseOrder[leftPhase] - phaseOrder[rightPhase];
|
||||
if (result === 0) {
|
||||
return left.order - right.order;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -297,6 +297,19 @@ describe('app', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('keep orders of middleware added by app.use()', function(done) {
|
||||
var expectedSteps = [];
|
||||
for (var i = 0; i < 10; i++) {
|
||||
app.use(namedHandler('m' + i));
|
||||
expectedSteps.push('m' + i);
|
||||
}
|
||||
executeMiddlewareHandlers(app, function(err) {
|
||||
if (err) return done(err);
|
||||
expect(steps).to.eql(expectedSteps);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
function namedHandler(name) {
|
||||
return function(req, res, next) {
|
||||
steps.push(name);
|
||||
|
|
Loading…
Reference in New Issue