Skip to content

Commit 252f3b2

Browse files
authored
feat: Added support for express@5 (#2555)
1 parent 44edd0c commit 252f3b2

File tree

11 files changed

+57
-72
lines changed

11 files changed

+57
-72
lines changed

lib/shim/shim.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,7 @@ function getName(obj) {
13001300
* @returns {boolean} True if the object is an Object, else false.
13011301
*/
13021302
function isObject(obj) {
1303-
return obj instanceof Object
1303+
return obj != null && (obj instanceof Object || (!obj.constructor && typeof obj === 'object'))
13041304
}
13051305

13061306
/**

test/unit/shim/shim.test.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,16 +2545,20 @@ tap.test('Shim', function (t) {
25452545
t.beforeEach(beforeEach)
25462546
t.afterEach(afterEach)
25472547
t.test('should detect if an item is an object', function (t) {
2548-
t.ok(shim.isObject({}))
2549-
t.ok(shim.isObject([]))
2550-
t.ok(shim.isObject(arguments))
2551-
t.ok(shim.isObject(function () {}))
2552-
t.notOk(shim.isObject(true))
2553-
t.notOk(shim.isObject(false))
2554-
t.notOk(shim.isObject('foobar'))
2555-
t.notOk(shim.isObject(1234))
2556-
t.notOk(shim.isObject(null))
2557-
t.notOk(shim.isObject(undefined))
2548+
t.equal(shim.isObject({}), true)
2549+
t.equal(shim.isObject([]), true)
2550+
t.equal(shim.isObject(arguments), true)
2551+
t.equal(
2552+
shim.isObject(function () {}),
2553+
true
2554+
)
2555+
t.equal(shim.isObject(Object.create(null)), true)
2556+
t.equal(shim.isObject(true), false)
2557+
t.equal(shim.isObject(false), false)
2558+
t.equal(shim.isObject('foobar'), false)
2559+
t.equal(shim.isObject(1234), false)
2560+
t.equal(shim.isObject(null), false)
2561+
t.equal(shim.isObject(undefined), false)
25582562
t.end()
25592563
})
25602564
})

test/versioned/express-esm/package.json

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,14 @@
1111
},
1212
"dependencies": {
1313
"express": {
14-
"versions": ">=4.6.0 && <5.0.0",
14+
"versions": ">=4.6.0",
1515
"samples": 5
1616
}
1717
},
1818
"files": [
1919
"segments.tap.mjs",
2020
"transaction-naming.tap.mjs"
2121
]
22-
},
23-
{
24-
"engines": {
25-
"node": ">=18"
26-
},
27-
"dependencies": {
28-
"express": "5.0.0-beta.3"
29-
},
30-
"files": [
31-
"segments.tap.mjs",
32-
"transaction-naming.tap.mjs"
33-
]
3422
}
3523
],
3624
"dependencies": {}

test/versioned/express-esm/segments.tap.mjs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ const assertSegmentsOptions = {
2020
// const pkgVersion = expressPkg.version
2121
import { readFileSync } from 'node:fs'
2222
const { version: pkgVersion } = JSON.parse(readFileSync('./node_modules/express/package.json'))
23-
// TODO: change to 5.0.0 when officially released
24-
const isExpress5 = semver.gte(pkgVersion, '5.0.0-beta.3')
23+
const isExpress5 = semver.gte(pkgVersion, '5.0.0')
2524

2625
test('transaction segments tests', (t) => {
2726
t.autoend()
@@ -215,14 +214,25 @@ test('transaction segments tests', (t) => {
215214
res.send('test')
216215
})
217216

218-
const path = isExpress5 ? '(.*)' : '*'
217+
let path = '*'
218+
let segmentPath = '/*'
219+
let metricsPath = segmentPath
220+
221+
// express 5 router must be regular expressions
222+
// need to handle the nuance of the segment vs metric name in express 5
223+
if (isExpress5) {
224+
path = /(.*)/
225+
segmentPath = '/(.*)/'
226+
metricsPath = '/(.*)'
227+
}
228+
219229
app.get(path, router1)
220230

221231
const { rootSegment, transaction } = await runTest({ app, t })
222232
t.assertSegments(
223233
rootSegment,
224234
[
225-
`Expressjs/Route Path: /${path}`,
235+
`Expressjs/Route Path: ${segmentPath}`,
226236
[
227237
'Expressjs/Router: /',
228238
['Expressjs/Route Path: /test', [NAMES.EXPRESS.MIDDLEWARE + 'testHandler']]
@@ -234,8 +244,8 @@ test('transaction segments tests', (t) => {
234244
checkMetrics(
235245
t,
236246
transaction.metrics,
237-
[`${NAMES.EXPRESS.MIDDLEWARE}testHandler//${path}/test`],
238-
`/${path}/test`
247+
[`${NAMES.EXPRESS.MIDDLEWARE}testHandler/${metricsPath}/test`],
248+
`${metricsPath}/test`
239249
)
240250
})
241251

test/versioned/express-esm/transaction-naming.tap.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ const { setup, makeRequest, makeRequestAndFinishTransaction } = expressHelpers
2020
// const pkgVersion = expressPkg.version
2121
import { readFileSync } from 'node:fs'
2222
const { version: pkgVersion } = JSON.parse(readFileSync('./node_modules/express/package.json'))
23-
// TODO: change to 5.0.0 when officially released
24-
const isExpress5 = semver.gte(pkgVersion, '5.0.0-beta.3')
23+
const isExpress5 = semver.gte(pkgVersion, '5.0.0')
2524

2625
test('transaction naming tests', (t) => {
2726
t.autoend()

test/versioned/express/async-error.tap.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
const path = require('path')
99
const test = require('tap').test
1010
const fork = require('child_process').fork
11+
const { isExpress5 } = require('./utils')
1112

1213
/*
1314
*
@@ -16,7 +17,7 @@ const fork = require('child_process').fork
1617
*/
1718
const COMPLETION = 27
1819

19-
test('Express async throw', function (t) {
20+
test('Express async throw', { skip: isExpress5() }, function (t) {
2021
const erk = fork(path.join(__dirname, 'erk.js'))
2122
let timer
2223

test/versioned/express/async-handlers.tap.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
'use strict'
77

8-
const { makeRequest, setup } = require('./utils')
8+
const { makeRequest, setup, isExpress5 } = require('./utils')
99
const { test } = require('tap')
1010

11-
test('should properly track async handlers', (t) => {
11+
test('should properly track async handlers', { skip: !isExpress5() }, (t) => {
1212
setup(t)
1313
const { app } = t.context
1414
const mwTimeout = 20
@@ -44,7 +44,7 @@ test('should properly track async handlers', (t) => {
4444
})
4545
})
4646

47-
test('should properly handle errors in async handlers', (t) => {
47+
test('should properly handle errors in async handlers', { skip: !isExpress5() }, (t) => {
4848
setup(t)
4949
const { app } = t.context
5050

test/versioned/express/express-enrouten.tap.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010

1111
const test = require('tap').test
1212
const helper = require('../../lib/agent_helper')
13+
const { isExpress5 } = require('./utils')
1314

14-
test('Express + express-enrouten compatibility test', function (t) {
15+
test('Express + express-enrouten compatibility test', { skip: isExpress5() }, function (t) {
1516
t.plan(2)
1617

1718
const agent = helper.instrumentMockedAgent()

test/versioned/express/package.json

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
},
1616
"dependencies": {
1717
"express": {
18-
"versions": ">=4.6.0 && <5.0.0",
18+
"versions": ">=4.6.0",
1919
"samples": 5
2020
},
2121
"express-enrouten": "1.1",
@@ -24,39 +24,12 @@
2424
"files": [
2525
"app-use.tap.js",
2626
"async-error.tap.js",
27-
"bare-router.tap.js",
28-
"captures-params.tap.js",
29-
"client-disconnect.tap.js",
30-
"errors.tap.js",
31-
"express-enrouten.tap.js",
32-
"ignoring.tap.js",
33-
"issue171.tap.js",
34-
"middleware-name.tap.js",
35-
"render.tap.js",
36-
"require.tap.js",
37-
"route-iteration.tap.js",
38-
"route-param.tap.js",
39-
"router-params.tap.js",
40-
"segments.tap.js",
41-
"transaction-naming.tap.js"
42-
]
43-
},
44-
{
45-
"engines": {
46-
"node": ">=18"
47-
},
48-
"dependencies": {
49-
"express": "5.0.0-beta.3",
50-
"ejs": "2.5.9"
51-
},
52-
"files": [
53-
"app-use.tap.js",
5427
"async-handlers.tap.js",
55-
"async-error.tap.js",
5628
"bare-router.tap.js",
5729
"captures-params.tap.js",
5830
"client-disconnect.tap.js",
5931
"errors.tap.js",
32+
"express-enrouten.tap.js",
6033
"ignoring.tap.js",
6134
"issue171.tap.js",
6235
"middleware-name.tap.js",

test/versioned/express/segments.tap.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,15 +243,25 @@ test('router mounted as a route handler', function (t) {
243243
res.send('test')
244244
})
245245

246-
const path = isExpress5 ? '(.*)' : '*'
246+
let path = '*'
247+
let segmentPath = '/*'
248+
let metricsPath = segmentPath
249+
250+
// express 5 router must be regular expressions
251+
// need to handle the nuance of the segment vs metric name in express 5
252+
if (isExpress5) {
253+
path = /(.*)/
254+
segmentPath = '/(.*)/'
255+
metricsPath = '/(.*)'
256+
}
247257
app.get(path, router1)
248258

249259
runTest(t, '/test', function (segments, transaction) {
250260
checkSegments(
251261
t,
252262
transaction.trace.root.children[0],
253263
[
254-
`Expressjs/Route Path: /${path}`,
264+
`Expressjs/Route Path: ${segmentPath}`,
255265
[
256266
'Expressjs/Router: /',
257267
['Expressjs/Route Path: /test', [NAMES.EXPRESS.MIDDLEWARE + 'testHandler']]
@@ -263,8 +273,8 @@ test('router mounted as a route handler', function (t) {
263273
checkMetrics(
264274
t,
265275
transaction.metrics,
266-
[`${NAMES.EXPRESS.MIDDLEWARE}testHandler//${path}/test`],
267-
`/${path}/test`
276+
[`${NAMES.EXPRESS.MIDDLEWARE}testHandler/${metricsPath}/test`],
277+
`${metricsPath}/test`
268278
)
269279

270280
t.end()

0 commit comments

Comments
 (0)