Use let or const to avoid scope issues and hoisting
var after = require('after');
1'use strict'23var after = require('after');4var assert = require('node:assert')5var express = require('../')6 , Route = express.Route7 , methods = require('../lib/utils').methods89describe('Route', function(){10 it('should work without handlers', function(done) {11 var req = { method: 'GET', url: '/' }12 var route = new Route('/foo')13 route.dispatch(req, {}, done)14 })1516 it('should not stack overflow with a large sync stack', function (done) {17 this.timeout(5000) // long-running test1819 var req = { method: 'GET', url: '/' }20 var route = new Route('/foo')2122 route.get(function (req, res, next) {23 req.counter = 024 next()25 })2627 for (var i = 0; i < 6000; i++) {28 route.all(function (req, res, next) {29 req.counter++30 next()31 })32 }3334 route.get(function (req, res, next) {35 req.called = true36 next()37 })3839 route.dispatch(req, {}, function (err) {40 if (err) return done(err)41 assert.ok(req.called)42 assert.strictEqual(req.counter, 6000)43 done()44 })45 })4647 describe('.all', function(){48 it('should add handler', function(done){49 var req = { method: 'GET', url: '/' };50 var route = new Route('/foo');5152 route.all(function(req, res, next) {53 req.called = true;54 next();55 });5657 route.dispatch(req, {}, function (err) {58 if (err) return done(err);59 assert.ok(req.called)60 done();61 });62 })6364 it('should handle VERBS', function(done) {65 var count = 0;66 var route = new Route('/foo');67 var cb = after(methods.length, function (err) {68 if (err) return done(err);69 assert.strictEqual(count, methods.length)70 done();71 });7273 route.all(function(req, res, next) {74 count++;75 next();76 });7778 methods.forEach(function testMethod(method) {79 var req = { method: method, url: '/' };80 route.dispatch(req, {}, cb);81 });82 })8384 it('should stack', function(done) {85 var req = { count: 0, method: 'GET', url: '/' };86 var route = new Route('/foo');8788 route.all(function(req, res, next) {89 req.count++;90 next();91 });9293 route.all(function(req, res, next) {94 req.count++;95 next();96 });9798 route.dispatch(req, {}, function (err) {99 if (err) return done(err);100 assert.strictEqual(req.count, 2)101 done();102 });103 })104 })105106 describe('.VERB', function(){107 it('should support .get', function(done){108 var req = { method: 'GET', url: '/' };109 var route = new Route('');110111 route.get(function(req, res, next) {112 req.called = true;113 next();114 })115116 route.dispatch(req, {}, function (err) {117 if (err) return done(err);118 assert.ok(req.called)119 done();120 });121 })122123 it('should limit to just .VERB', function(done){124 var req = { method: 'POST', url: '/' };125 var route = new Route('');126127 route.get(function () {128 throw new Error('not me!');129 })130131 route.post(function(req, res, next) {132 req.called = true;133 next();134 })135136 route.dispatch(req, {}, function (err) {137 if (err) return done(err);138 assert.ok(req.called)139 done();140 });141 })142143 it('should allow fallthrough', function(done){144 var req = { order: '', method: 'GET', url: '/' };145 var route = new Route('');146147 route.get(function(req, res, next) {148 req.order += 'a';149 next();150 })151152 route.all(function(req, res, next) {153 req.order += 'b';154 next();155 });156157 route.get(function(req, res, next) {158 req.order += 'c';159 next();160 })161162 route.dispatch(req, {}, function (err) {163 if (err) return done(err);164 assert.strictEqual(req.order, 'abc')165 done();166 });167 })168 })169170 describe('errors', function(){171 it('should handle errors via arity 4 functions', function(done){172 var req = { order: '', method: 'GET', url: '/' };173 var route = new Route('');174175 route.all(function(req, res, next){176 next(new Error('foobar'));177 });178179 route.all(function(req, res, next){180 req.order += '0';181 next();182 });183184 route.all(function(err, req, res, next){185 req.order += 'a';186 next(err);187 });188189 route.dispatch(req, {}, function (err) {190 assert.ok(err)191 assert.strictEqual(err.message, 'foobar')192 assert.strictEqual(req.order, 'a')193 done();194 });195 })196197 it('should handle throw', function(done) {198 var req = { order: '', method: 'GET', url: '/' };199 var route = new Route('');200201 route.all(function () {202 throw new Error('foobar');203 });204205 route.all(function(req, res, next){206 req.order += '0';207 next();208 });209210 route.all(function(err, req, res, next){211 req.order += 'a';212 next(err);213 });214215 route.dispatch(req, {}, function (err) {216 assert.ok(err)217 assert.strictEqual(err.message, 'foobar')218 assert.strictEqual(req.order, 'a')219 done();220 });221 });222223 it('should handle throwing inside error handlers', function(done) {224 var req = { method: 'GET', url: '/' };225 var route = new Route('');226227 route.get(function () {228 throw new Error('boom!');229 });230231 route.get(function(err, req, res, next){232 throw new Error('oops');233 });234235 route.get(function(err, req, res, next){236 req.message = err.message;237 next();238 });239240 route.dispatch(req, {}, function (err) {241 if (err) return done(err);242 assert.strictEqual(req.message, 'oops')243 done();244 });245 });246247 it('should handle throw in .all', function(done) {248 var req = { method: 'GET', url: '/' };249 var route = new Route('');250251 route.all(function(req, res, next){252 throw new Error('boom!');253 });254255 route.dispatch(req, {}, function(err){256 assert.ok(err)257 assert.strictEqual(err.message, 'boom!')258 done();259 });260 });261262 it('should handle single error handler', function(done) {263 var req = { method: 'GET', url: '/' };264 var route = new Route('');265266 route.all(function(err, req, res, next){267 // this should not execute268 throw new Error('should not be called')269 });270271 route.dispatch(req, {}, done);272 });273 })274})
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.