server-app: make _sortLayersByPhase stable

Fix the phase-sorting algorithm to use a stable sorting algorithm,
since the built-in `Array.prototype.sort` is not stable.
This commit is contained in:
Miroslav Bajtoš 2014-12-15 08:14:26 +01:00
parent 5150a58364
commit 4744aa6920
3 changed files with 23 additions and 1 deletions

View File

@ -3,6 +3,7 @@ var express = require('express');
var merge = require('util')._extend; var merge = require('util')._extend;
var mergePhaseNameLists = require('loopback-phase').mergePhaseNameLists; var mergePhaseNameLists = require('loopback-phase').mergePhaseNameLists;
var debug = require('debug')('loopback:app'); var debug = require('debug')('loopback:app');
var stableSortInPlace = require('stable').inplace;
var BUILTIN_MIDDLEWARE = { builtin: true }; var BUILTIN_MIDDLEWARE = { builtin: true };
@ -214,7 +215,7 @@ proto._sortLayersByPhase = function() {
}); });
var router = this._router; var router = this._router;
router.stack.sort(compareLayers); stableSortInPlace(router.stack, compareLayers);
function compareLayers(left, right) { function compareLayers(left, right) {
var leftPhase = left.phase; var leftPhase = left.phase;

View File

@ -46,6 +46,7 @@
"nodemailer": "~1.3.0", "nodemailer": "~1.3.0",
"nodemailer-stub-transport": "~0.1.4", "nodemailer-stub-transport": "~0.1.4",
"serve-favicon": "^2.1.6", "serve-favicon": "^2.1.6",
"stable": "^0.1.5",
"strong-remoting": "^2.4.0", "strong-remoting": "^2.4.0",
"uid2": "0.0.3", "uid2": "0.0.3",
"underscore.string": "~2.3.3" "underscore.string": "~2.3.3"

View File

@ -239,6 +239,26 @@ describe('app', function() {
}); });
}); });
it('preserves order of middleware in the same phase', function(done) {
// while we are discouraging developers from depending on
// the registration order of middleware in the same phase,
// we must preserve the order for compatibility with `app.use`
// and `app.route`.
// we need at least 9 elements to expose non-stability
// of the built-in sort function
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
numbers.forEach(function(n) {
app.middleware('routes', namedHandler(n));
});
executeMiddlewareHandlers(app, function(err) {
if (err) return done;
expect(steps).to.eql(numbers);
done();
});
});
it('correctly mounts express apps', function(done) { it('correctly mounts express apps', function(done) {
var data; var data;
var mountWasEmitted; var mountWasEmitted;