From 4744aa6920c73a9a244e5b5b12dbc630b0a35282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Mon, 15 Dec 2014 08:14:26 +0100 Subject: [PATCH] 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. --- lib/server-app.js | 3 ++- package.json | 1 + test/app.test.js | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/server-app.js b/lib/server-app.js index 7788dd9e..13f993a8 100644 --- a/lib/server-app.js +++ b/lib/server-app.js @@ -3,6 +3,7 @@ var express = require('express'); var merge = require('util')._extend; var mergePhaseNameLists = require('loopback-phase').mergePhaseNameLists; var debug = require('debug')('loopback:app'); +var stableSortInPlace = require('stable').inplace; var BUILTIN_MIDDLEWARE = { builtin: true }; @@ -214,7 +215,7 @@ proto._sortLayersByPhase = function() { }); var router = this._router; - router.stack.sort(compareLayers); + stableSortInPlace(router.stack, compareLayers); function compareLayers(left, right) { var leftPhase = left.phase; diff --git a/package.json b/package.json index bae83f44..ad3ef774 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "nodemailer": "~1.3.0", "nodemailer-stub-transport": "~0.1.4", "serve-favicon": "^2.1.6", + "stable": "^0.1.5", "strong-remoting": "^2.4.0", "uid2": "0.0.3", "underscore.string": "~2.3.3" diff --git a/test/app.test.js b/test/app.test.js index 978773ac..18f326c4 100644 --- a/test/app.test.js +++ b/test/app.test.js @@ -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) { var data; var mountWasEmitted;