diff --git a/test/lib/custom-assertions.js b/test/lib/custom-assertions.js index 522cff3b26..5f594400e2 100644 --- a/test/lib/custom-assertions.js +++ b/test/lib/custom-assertions.js @@ -61,9 +61,13 @@ function isNonWritable({ obj, key, value }) { }, new RegExp("(read only property '" + key + "'|Cannot set property " + key + ')')) if (value) { - assert.equal(obj[key], value) + assert.strictEqual(obj[key], value) } else { - assert.ok(!obj[key], 'testNonWritable test value', 'should not set value when non-writable') + assert.notStrictEqual( + obj[key], + 'testNonWritable test value', + 'should not set value when non-writable' + ) } } @@ -323,12 +327,50 @@ function assertMetricValues(transaction, expected, exact) { } } +/** + * Asserts the wrapped callback is wrapped and the unwrapped version is the original. + * It also verifies it does not throw an error + * + * @param {object} shim shim lib + * @param {Function} original callback + */ +function checkWrappedCb(shim, cb) { + // The wrapped callback is always the last argument + const wrappedCB = arguments[arguments.length - 1] + assert.notStrictEqual(wrappedCB, cb) + assert.ok(shim.isWrapped(wrappedCB)) + assert.equal(shim.unwrap(wrappedCB), cb) + + assert.doesNotThrow(function () { + wrappedCB() + }) +} + +/** + * Helper that verifies the original callback + * and wrapped callback are the same + * + * @param {object} shim shim lib + * @param {Function} original callback + */ +function checkNotWrappedCb(shim, cb) { + // The callback is always the last argument + const wrappedCB = arguments[arguments.length - 1] + assert.equal(wrappedCB, cb) + assert.equal(shim.isWrapped(wrappedCB), false) + assert.doesNotThrow(function () { + wrappedCB() + }) +} + module.exports = { assertCLMAttrs, assertExactClmAttrs, assertMetrics, assertMetricValues, assertSegments, + checkWrappedCb, + checkNotWrappedCb, compareSegments, isNonWritable, match diff --git a/test/unit/shim/conglomerate-shim.test.js b/test/unit/shim/conglomerate-shim.test.js index 9ff5eb4546..b449cbb705 100644 --- a/test/unit/shim/conglomerate-shim.test.js +++ b/test/unit/shim/conglomerate-shim.test.js @@ -4,8 +4,8 @@ */ 'use strict' - -const { test } = require('tap') +const assert = require('node:assert') +const test = require('node:test') const ConglomerateShim = require('../../../lib/shim/conglomerate-shim') const DatastoreShim = require('../../../lib/shim/datastore-shim') const helper = require('../../lib/agent_helper') @@ -15,72 +15,73 @@ const Shim = require('../../../lib/shim/shim') const TransactionShim = require('../../../lib/shim/transaction-shim') const WebFrameworkShim = require('../../../lib/shim/webframework-shim') -test('ConglomerateShim', (t) => { - t.autoend() - let agent = null - let shim = null - - t.beforeEach(() => { - agent = helper.loadMockedAgent() - shim = new ConglomerateShim(agent, 'test-module') +test('ConglomerateShim', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + const agent = helper.loadMockedAgent() + ctx.nr.shim = new ConglomerateShim(agent, 'test-module') + ctx.nr.agent = agent }) - t.afterEach(() => { - helper.unloadAgent(agent) - agent = null - shim = null + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should require an agent parameter', (t) => { - t.throws(() => new ConglomerateShim(), /^Shim must be initialized with .*? agent/) - t.end() + await t.test('should require an agent parameter', () => { + assert.throws( + () => new ConglomerateShim(), + 'Error: Shim must be initialized with an agent and module name.' + ) }) - t.test('should require a module name parameter', (t) => { - t.throws(() => new ConglomerateShim(agent), /^Shim must be initialized with .*? module name/) - t.end() + await t.test('should require a module name parameter', (t) => { + const { agent } = t.nr + assert.throws( + () => new ConglomerateShim(agent), + 'Error: Shim must be initialized with an agent and module name.' + ) }) - t.test('should exist for each shim type', (t) => { - t.ok(shim.GENERIC, 'generic') - t.ok(shim.DATASTORE, 'datastore') - t.ok(shim.MESSAGE, 'message') - t.ok(shim.PROMISE, 'promise') - t.ok(shim.TRANSACTION, 'transaction') - t.ok(shim.WEB_FRAMEWORK, 'web-framework') - t.end() + await t.test('should exist for each shim type', (t) => { + const { shim } = t.nr + assert.equal(shim.GENERIC, 'generic') + assert.equal(shim.DATASTORE, 'datastore') + assert.equal(shim.MESSAGE, 'message') + assert.equal(shim.PROMISE, 'promise') + assert.equal(shim.TRANSACTION, 'transaction') + assert.equal(shim.WEB_FRAMEWORK, 'web-framework') }) - t.test('should construct a new shim', (t) => { + await t.test('should construct a new shim', (t) => { + const { shim } = t.nr const specialShim = shim.makeSpecializedShim(shim.GENERIC, 'foobar') - t.ok(specialShim instanceof Shim) - t.not(specialShim, shim) - t.end() + assert.ok(specialShim instanceof Shim) + assert.notEqual(specialShim, shim) }) - t.test('should be an instance of the correct class', (t) => { - t.ok(shim.makeSpecializedShim(shim.GENERIC, 'foobar') instanceof Shim) - t.ok(shim.makeSpecializedShim(shim.DATASTORE, 'foobar') instanceof DatastoreShim) - t.ok(shim.makeSpecializedShim(shim.MESSAGE, 'foobar') instanceof MessageShim) - t.ok(shim.makeSpecializedShim(shim.PROMISE, 'foobar') instanceof PromiseShim) - t.ok(shim.makeSpecializedShim(shim.TRANSACTION, 'foobar') instanceof TransactionShim) - t.ok(shim.makeSpecializedShim(shim.WEB_FRAMEWORK, 'foobar') instanceof WebFrameworkShim) - t.end() + await t.test('should be an instance of the correct class', (t) => { + const { shim } = t.nr + assert.ok(shim.makeSpecializedShim(shim.GENERIC, 'foobar') instanceof Shim) + assert.ok(shim.makeSpecializedShim(shim.DATASTORE, 'foobar') instanceof DatastoreShim) + assert.ok(shim.makeSpecializedShim(shim.MESSAGE, 'foobar') instanceof MessageShim) + assert.ok(shim.makeSpecializedShim(shim.PROMISE, 'foobar') instanceof PromiseShim) + assert.ok(shim.makeSpecializedShim(shim.TRANSACTION, 'foobar') instanceof TransactionShim) + assert.ok(shim.makeSpecializedShim(shim.WEB_FRAMEWORK, 'foobar') instanceof WebFrameworkShim) }) - t.test('should assign properties from parent', (t) => { + await t.test('should assign properties from parent', (t) => { + const { agent } = t.nr const mod = 'test-mod' const name = mod const version = '1.0.0' const shim = new ConglomerateShim(agent, mod, mod, name, version) - t.equal(shim.moduleName, mod) - t.equal(agent, shim._agent) - t.equal(shim.pkgVersion, version) + assert.equal(shim.moduleName, mod) + assert.equal(agent, shim._agent) + assert.equal(shim.pkgVersion, version) function childFn() {} const childShim = shim.makeSpecializedShim(shim.DATASTORE, childFn) - t.same(shim._agent, childShim._agent) - t.equal(shim.moduleName, childShim.moduleName) - t.equal(shim.pkgVersion, childShim.pkgVersion) - t.equal(shim.id, childShim.id) - t.end() + assert.deepEqual(shim._agent, childShim._agent) + assert.equal(shim.moduleName, childShim.moduleName) + assert.equal(shim.pkgVersion, childShim.pkgVersion) + assert.equal(shim.id, childShim.id) }) }) diff --git a/test/unit/shim/datastore-shim.test.js b/test/unit/shim/datastore-shim.test.js index 84fdce9822..42388805a4 100644 --- a/test/unit/shim/datastore-shim.test.js +++ b/test/unit/shim/datastore-shim.test.js @@ -4,27 +4,23 @@ */ 'use strict' - -const tap = require('tap') -const { test } = tap +const assert = require('node:assert') +const test = require('node:test') const getMetricHostName = require('../../lib/metrics_helper').getMetricHostName const helper = require('../../lib/agent_helper') const Shim = require('../../../lib/shim/shim') const DatastoreShim = require('../../../lib/shim/datastore-shim') const ParsedStatement = require('../../../lib/db/parsed-statement') const { QuerySpec, OperationSpec } = require('../../../lib/shim/specs') +const { checkWrappedCb } = require('../../lib/custom-assertions') -test('DatastoreShim', function (t) { - t.autoend() - let agent = null - let shim = null - let wrappable = null - - function beforeEach() { - agent = helper.loadMockedAgent() - shim = new DatastoreShim(agent, 'test-cassandra') +test('DatastoreShim', async function (t) { + function beforeEach(ctx) { + ctx.nr = {} + const agent = helper.loadMockedAgent() + const shim = new DatastoreShim(agent, 'test-cassandra') shim.setDatastore(DatastoreShim.CASSANDRA) - wrappable = { + ctx.nr.wrappable = { name: 'this is a name', bar: function barsName() { return 'bar' @@ -43,62 +39,65 @@ test('DatastoreShim', function (t) { return segment } } + ctx.nr.agent = agent + ctx.nr.shim = shim } - function afterEach() { - helper.unloadAgent(agent) - agent = null - shim = null + function afterEach(ctx) { + helper.unloadAgent(ctx.nr.agent) } - t.test('constructor', (t) => { - t.autoend() + await t.test('constructor', async (t) => { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should inherit from Shim', function (t) { - t.ok(shim instanceof DatastoreShim) - t.ok(shim instanceof Shim) - t.end() + await t.test('should inherit from Shim', function (t) { + const { shim } = t.nr + assert.ok(shim instanceof DatastoreShim) + assert.ok(shim instanceof Shim) }) - t.test('should require the `agent` parameter', function (t) { - t.throws(() => new DatastoreShim(), /^Shim must be initialized with .*? agent/) - t.end() + await t.test('should require the `agent` parameter', function () { + assert.throws( + () => new DatastoreShim(), + 'Error: Shim must be initialized with an agent and module name.' + ) }) - t.test('should require the `moduleName` parameter', function (t) { - t.throws(() => new DatastoreShim(agent), /^Shim must be initialized with .*? module name/) - t.end() + await t.test('should require the `moduleName` parameter', function (t) { + const { agent } = t.nr + assert.throws( + () => new DatastoreShim(agent), + 'Error: Shim must be initialized with an agent and module name.' + ) }) - t.test('should take an optional `datastore`', function (t) { + await t.test('should take an optional `datastore`', function (t) { + const { agent, shim } = t.nr // Test without datastore let _shim = null - t.doesNotThrow(function () { + assert.doesNotThrow(function () { _shim = new DatastoreShim(agent, 'test-cassandra') }) - t.notOk(_shim._metrics) + assert.ok(!_shim._metrics) // Use one provided for all tests to check constructed with datastore - t.ok(shim._metrics) - t.end() + assert.ok(shim._metrics) }) - t.test('should assign properties from parent', (t) => { + await t.test('should assign properties from parent', (t) => { + const { agent } = t.nr const mod = 'test-mod' const name = mod const version = '1.0.0' const shim = new DatastoreShim(agent, mod, mod, name, version) - t.equal(shim.moduleName, mod) - t.equal(agent, shim._agent) - t.equal(shim.pkgVersion, version) - t.end() + assert.equal(shim.moduleName, mod) + assert.equal(agent, shim._agent) + assert.equal(shim.pkgVersion, version) }) }) - t.test('well-known datastores', (t) => { - t.autoend() + await t.test('well-known datastores', async (t) => { t.beforeEach(beforeEach) t.afterEach(afterEach) @@ -112,216 +111,213 @@ test('DatastoreShim', function (t) { 'REDIS', 'POSTGRES' ] - datastores.forEach((ds) => { - t.test(`should have property ${ds}`, (t) => { - t.ok(DatastoreShim[ds]) - t.ok(shim[ds]) - t.end() + for (const ds of datastores) { + await t.test(`should have property ${ds}`, (t) => { + const { shim } = t.nr + assert.ok(DatastoreShim[ds]) + assert.ok(shim[ds]) }) - }) + } }) - t.test('#logger', (t) => { - t.autoend() + await t.test('#logger', async (t) => { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('logger should be a non-writable property', function (t) { - t.throws(function () { + await t.test('logger should be a non-writable property', function (t) { + const { shim } = t.nr + assert.throws(function () { shim.logger = 'foobar' }) - t.ok(shim.logger) - t.not(shim.logger, 'foobar') - t.end() + assert.ok(shim.logger) + assert.notDeepEqual(shim.logger, 'foobar') }) const logLevels = ['trace', 'debug', 'info', 'warn', 'error'] - logLevels.forEach((level) => { - t.test(`logger should have ${level} as a function`, (t) => { - t.ok(shim.logger[level] instanceof Function, 'should be function') - t.end() + for (const level of logLevels) { + await t.test(`logger should have ${level} as a function`, (t) => { + const { shim } = t.nr + assert.ok(shim.logger[level] instanceof Function, 'should be function') }) - }) + } }) - t.test('#setDatastore', (t) => { - t.autoend() - let dsAgent = null - let dsShim = null - - t.beforeEach(function () { - dsAgent = helper.loadMockedAgent() - dsShim = new DatastoreShim(dsAgent, 'test-cassandra') + await t.test('#setDatastore', async (t) => { + t.beforeEach(function (ctx) { + ctx.nr = {} + const agent = helper.loadMockedAgent() + ctx.nr.shim = new DatastoreShim(agent, 'test-cassandra') + ctx.nr.agent = agent }) - t.afterEach(function () { - dsShim = null - dsAgent = helper.unloadAgent(dsAgent) + t.afterEach(function (ctx) { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should accept the id of a well-known datastore', function (t) { - t.doesNotThrow(function () { - dsShim.setDatastore(dsShim.CASSANDRA) + await t.test('should accept the id of a well-known datastore', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { + shim.setDatastore(shim.CASSANDRA) }) - t.ok(dsShim._metrics.PREFIX, 'Cassandra') - t.end() + assert.equal(shim._metrics.PREFIX, 'Cassandra') }) - t.test('should create custom metric names if the `datastoreId` is a string', function (t) { - t.doesNotThrow(function () { - dsShim.setDatastore('Fake Datastore') - }) + await t.test( + 'should create custom metric names if the `datastoreId` is a string', + function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { + shim.setDatastore('Fake Datastore') + }) - t.ok(dsShim._metrics.PREFIX, 'Fake Datastore') - t.end() - }) + assert.equal(shim._metrics.PREFIX, 'Fake Datastore') + } + ) - t.test("should update the dsShim's logger", function (t) { - const original = dsShim.logger - dsShim.setDatastore(dsShim.CASSANDRA) - t.not(dsShim.logger, original) - t.ok(dsShim.logger.extra.datastore, 'Cassandra') - t.end() + await t.test("should update the shim's logger", function (t) { + const { shim } = t.nr + const original = shim.logger + shim.setDatastore(shim.CASSANDRA) + assert.notEqual(shim.logger, original) + assert.equal(shim.logger.extra.datastore, 'Cassandra') }) }) - t.test('#setParser', (t) => { - t.autoend() - let parserAgent = null - let parserShim = null - - t.beforeEach(function () { - parserAgent = helper.loadMockedAgent() - // Use a parserShim without a parser set for these tests. - parserShim = new DatastoreShim(parserAgent, 'test') - parserShim._metrics = { PREFIX: '' } + await t.test('#setParser', async (t) => { + t.beforeEach(function (ctx) { + ctx.nr = {} + const agent = helper.loadMockedAgent() + // Use a shim without a parser set for these tests. + const shim = new DatastoreShim(agent, 'test') + shim._metrics = { PREFIX: '' } + ctx.nr.shim = shim + ctx.nr.agent = agent }) - t.afterEach(function () { - parserShim = null - parserAgent = helper.unloadAgent(parserAgent) + t.afterEach(function (ctx) { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should default to an SQL parser', function (t) { - parserShim.agent.config.transaction_tracer.record_sql = 'raw' + await t.test('should default to an SQL parser', function (t) { + const { shim } = t.nr + shim.agent.config.transaction_tracer.record_sql = 'raw' const query = 'SELECT 1 FROM test' - const parsed = parserShim.parseQuery(query) - t.equal(parsed.operation, 'select') - t.equal(parsed.collection, 'test') - t.equal(parsed.raw, query) - t.end() + const parsed = shim.parseQuery(query) + assert.equal(parsed.operation, 'select') + assert.equal(parsed.collection, 'test') + assert.equal(parsed.raw, query) }) - t.test('should allow for the parser to be set', function (t) { + await t.test('should allow for the parser to be set', function (t) { + const { shim } = t.nr let testValue = false - parserShim.setParser(function fakeParser(query) { - t.equal(query, 'foobar') + shim.setParser(function fakeParser(query) { + assert.equal(query, 'foobar') testValue = true return { operation: 'test' } }) - parserShim.parseQuery('foobar') - t.ok(testValue) - t.end() + shim.parseQuery('foobar') + assert.ok(testValue) }) - t.test('should have constants to set the query parser with', function (t) { - parserShim.agent.config.transaction_tracer.record_sql = 'raw' - parserShim.setParser(parserShim.SQL_PARSER) + await t.test('should have constants to set the query parser with', function (t) { + const { shim } = t.nr + shim.agent.config.transaction_tracer.record_sql = 'raw' + shim.setParser(shim.SQL_PARSER) const query = 'SELECT 1 FROM test' - const parsed = parserShim.parseQuery(query) - t.equal(parsed.operation, 'select') - t.equal(parsed.collection, 'test') - t.equal(parsed.raw, query) - t.end() + const parsed = shim.parseQuery(query) + assert.equal(parsed.operation, 'select') + assert.equal(parsed.collection, 'test') + assert.equal(parsed.raw, query) }) - t.test('should not set parser to a new parser with invalid string', function (t) { + await t.test('should not set parser to a new parser with invalid string', function (t) { + const { shim } = t.nr let testValue = false - parserShim.setParser(function fakeParser(query) { - t.equal(query, 'SELECT 1 FROM test') + shim.setParser(function fakeParser(query) { + assert.equal(query, 'SELECT 1 FROM test') testValue = true return { operation: 'test' } }) - parserShim.setParser('bad string') + shim.setParser('bad string') const query = 'SELECT 1 FROM test' - parserShim.parseQuery(query) - t.ok(testValue) - t.end() + shim.parseQuery(query) + assert.ok(testValue) }) - t.test('should not set parser to a new parser with an object', function (t) { + await t.test('should not set parser to a new parser with an object', function (t) { + const { shim } = t.nr let testValue = false - parserShim.setParser(function fakeParser(query) { - t.equal(query, 'SELECT 1 FROM test') + shim.setParser(function fakeParser(query) { + assert.equal(query, 'SELECT 1 FROM test') testValue = true return { operation: 'test' } }) - parserShim.setParser({ + shim.setParser({ parser: function shouldNotBeCalled() { throw new Error('get me outta here') } }) const query = 'SELECT 1 FROM test' - parserShim.parseQuery(query) - t.ok(testValue) - t.end() + shim.parseQuery(query) + assert.ok(testValue) }) }) - t.test('#recordOperation', (t) => { - t.autoend() + + await t.test('#recordOperation', async (t) => { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordOperation(wrappable) - t.equal(wrapped, wrappable) - t.not(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.equal(shim.isWrapped(wrapped), false) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordOperation(wrappable.bar, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordOperation(wrappable.bar, null, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordOperation(wrappable, 'bar', {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordOperation(wrappable, 'name', {}) - t.not(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test( + await t.test( 'should create a datastore operation segment but no metric when `record` is false', - function (t) { + function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordOperation(wrappable, 'getActiveSegment', { record: false, name: 'getActiveSegment' @@ -330,79 +326,90 @@ test('DatastoreShim', function (t) { helper.runInTransaction(agent, function (tx) { const startingSegment = agent.tracer.getSegment() const segment = wrappable.getActiveSegment() - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'getActiveSegment') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'getActiveSegment') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() }) } ) - t.test('should create a datastore operation metric when `record` is true', function (t) { - shim.recordOperation(wrappable, 'getActiveSegment', { - record: true, - name: 'getActiveSegment' - }) + await t.test( + 'should create a datastore operation metric when `record` is true', + function (t, end) { + const { agent, shim, wrappable } = t.nr + shim.recordOperation(wrappable, 'getActiveSegment', { + record: true, + name: 'getActiveSegment' + }) - helper.runInTransaction(agent, function (tx) { - const startingSegment = agent.tracer.getSegment() - const segment = wrappable.getActiveSegment() - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'Datastore/operation/Cassandra/getActiveSegment') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() - }) - }) + helper.runInTransaction(agent, function (tx) { + const startingSegment = agent.tracer.getSegment() + const segment = wrappable.getActiveSegment() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'Datastore/operation/Cassandra/getActiveSegment') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() + }) + } + ) - t.test('should create a datastore operation metric when `record` is defaulted', function (t) { - shim.recordOperation(wrappable, 'getActiveSegment', { name: 'getActiveSegment' }) + await t.test( + 'should create a datastore operation metric when `record` is defaulted', + function (t, end) { + const { agent, shim, wrappable } = t.nr + shim.recordOperation(wrappable, 'getActiveSegment', { name: 'getActiveSegment' }) - helper.runInTransaction(agent, function (tx) { - const startingSegment = agent.tracer.getSegment() - const segment = wrappable.getActiveSegment() - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'Datastore/operation/Cassandra/getActiveSegment') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() - }) - }) + helper.runInTransaction(agent, function (tx) { + const startingSegment = agent.tracer.getSegment() + const segment = wrappable.getActiveSegment() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'Datastore/operation/Cassandra/getActiveSegment') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() + }) + } + ) - t.test('should create a child segment when opaque is false', (t) => { + await t.test('should create a child segment when opaque is false', (t, end) => { + const { agent, shim, wrappable } = t.nr shim.recordOperation(wrappable, 'withNested', () => { return new OperationSpec({ name: 'test', opaque: false }) }) helper.runInTransaction(agent, (tx) => { const startingSegment = agent.tracer.getSegment() const segment = wrappable.withNested() - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'Datastore/operation/Cassandra/test') - t.equal(segment.children.length, 1) + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'Datastore/operation/Cassandra/test') + assert.equal(segment.children.length, 1) const [childSegment] = segment.children - t.equal(childSegment.name, 'ChildSegment') - t.end() + assert.equal(childSegment.name, 'ChildSegment') + end() }) }) - t.test('should not create a child segment when opaque is true', (t) => { + await t.test('should not create a child segment when opaque is true', (t, end) => { + const { agent, shim, wrappable } = t.nr shim.recordOperation(wrappable, 'withNested', () => { return new OperationSpec({ name: 'test', opaque: true }) }) helper.runInTransaction(agent, (tx) => { const startingSegment = agent.tracer.getSegment() const segment = wrappable.withNested() - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'Datastore/operation/Cassandra/test') - t.equal(segment.children.length, 0) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'Datastore/operation/Cassandra/test') + assert.equal(segment.children.length, 0) + end() }) }) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t, end) { + const { agent, shim } = t.nr let executed = false const toWrap = function () { executed = true @@ -410,224 +417,225 @@ test('DatastoreShim', function (t) { const wrapped = shim.recordOperation(toWrap, {}) helper.runInTransaction(agent, function () { - t.not(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) + end() }) }) - t.test('should invoke the spec in the context of the wrapped function', function (t) { - const original = wrappable.bar - let executed = false - shim.recordOperation(wrappable, 'bar', function (_, fn, name, args) { - executed = true - t.equal(fn, original) - t.equal(name, 'bar') - t.equal(this, wrappable) - t.same(args, ['a', 'b', 'c']) - return {} - }) - - helper.runInTransaction(agent, function () { - wrappable.bar('a', 'b', 'c') - t.ok(executed) - t.end() - }) - }) + await t.test( + 'should invoke the spec in the context of the wrapped function', + function (t, end) { + const { agent, shim, wrappable } = t.nr + const original = wrappable.bar + let executed = false + shim.recordOperation(wrappable, 'bar', function (_, fn, name, args) { + executed = true + assert.equal(fn, original) + assert.equal(name, 'bar') + assert.equal(this, wrappable) + assert.deepEqual(args, ['a', 'b', 'c']) + return {} + }) - t.test('should bind the callback if there is one', function (t) { - const cb = function () {} + helper.runInTransaction(agent, function () { + wrappable.bar('a', 'b', 'c') + assert.equal(executed, true) + end() + }) + } + ) - const wrapped = shim.recordOperation(helper.checkWrappedCb.bind(t, shim, cb), { + await t.test('should bind the callback if there is one', function (t, end) { + const { agent, shim } = t.nr + const wrapped = shim.recordOperation(checkWrappedCb.bind(null, shim, end), { callback: shim.LAST }) helper.runInTransaction(agent, function () { - wrapped(cb) + wrapped(end) }) }) }) - t.test('with `parameters`', function (t) { - t.autoend() - let localhost = null - t.beforeEach(function () { - beforeEach() - localhost = getMetricHostName(agent, 'localhost') + await t.test('with `parameters`', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { agent, shim, wrappable } = ctx.nr + ctx.nr.localhost = getMetricHostName(agent, 'localhost') shim.recordOperation(wrappable, 'getActiveSegment', function (s, fn, n, args) { return new OperationSpec({ parameters: args[0] }) }) }) t.afterEach(afterEach) - function run(parameters, cb) { + function run(ctx, parameters, cb) { + const { agent, wrappable } = ctx.nr helper.runInTransaction(agent, function () { const segment = wrappable.getActiveSegment(parameters) cb(segment) }) } - t.test('should set datatastore attributes accordingly', function (t) { + await t.test('should set datastore attributes accordingly', function (t, end) { + const { localhost } = t.nr run( + t, { host: 'localhost', port_path_or_id: 1234, database_name: 'foobar' }, function (segment) { - t.ok(segment.attributes) + assert.ok(segment.attributes) const attributes = segment.getAttributes() - t.equal(attributes.host, localhost) - t.equal(attributes.port_path_or_id, '1234') - t.equal(attributes.database_name, 'foobar') - t.end() + assert.equal(attributes.host, localhost) + assert.equal(attributes.port_path_or_id, '1234') + assert.equal(attributes.database_name, 'foobar') + end() } ) }) - t.test('should default undefined attributes to `unknown`', function (t) { + await t.test('should default undefined attributes to `unknown`', function (t, end) { run( + t, { host: 'some_other_host', port_path_or_id: null, database_name: null }, function (segment) { - t.ok(segment.attributes) + assert.ok(segment.attributes) const attributes = segment.getAttributes() - t.equal(attributes.host, 'some_other_host') - t.equal(attributes.port_path_or_id, 'unknown') - t.equal(attributes.database_name, 'unknown') - t.end() + assert.equal(attributes.host, 'some_other_host') + assert.equal(attributes.port_path_or_id, 'unknown') + assert.equal(attributes.database_name, 'unknown') + end() } ) }) - t.test('should remove `database_name` if disabled', function (t) { - agent.config.datastore_tracer.database_name_reporting.enabled = false + await t.test('should remove `database_name` if disabled', function (t, end) { + const { localhost } = t.nr + t.nr.agent.config.datastore_tracer.database_name_reporting.enabled = false run( + t, { host: 'localhost', port_path_or_id: 1234, database_name: 'foobar' }, function (segment) { - t.ok(segment.attributes) + assert.ok(segment.attributes) const attributes = segment.getAttributes() - t.equal(attributes.host, localhost) - t.equal(attributes.port_path_or_id, '1234') - t.notOk(attributes.database_name) - t.end() + assert.equal(attributes.host, localhost) + assert.equal(attributes.port_path_or_id, '1234') + assert.ok(!attributes.database_name) + end() } ) }) - t.test('should remove `host` and `port_path_or_id` if disabled', function (t) { - agent.config.datastore_tracer.instance_reporting.enabled = false + await t.test('should remove `host` and `port_path_or_id` if disabled', function (t, end) { + t.nr.agent.config.datastore_tracer.instance_reporting.enabled = false run( + t, { host: 'localhost', port_path_or_id: 1234, database_name: 'foobar' }, function (segment) { - t.ok(segment.attributes) + assert.ok(segment.attributes) const attributes = segment.getAttributes() - t.notOk(attributes.host) - t.notOk(attributes.port_path_or_id) - t.equal(attributes.database_name, 'foobar') - t.end() + assert.ok(!attributes.host) + assert.ok(!attributes.port_path_or_id) + assert.equal(attributes.database_name, 'foobar') + end() } ) }) }) - t.test('recorder', function (t) { - t.autoend() - t.beforeEach(function () { - beforeEach() - shim.recordOperation(wrappable, 'getActiveSegment', function () { - return new OperationSpec({ - name: 'op', - parameters: { - host: 'some_host', - port_path_or_id: 1234, - database_name: 'foobar' - } - }) - }) - - return new Promise((resolve) => { - helper.runInTransaction(agent, function (tx) { - wrappable.getActiveSegment() - tx.end() - resolve() - }) + await t.test('recorder should create unscoped datastore metrics', function (t, end) { + beforeEach(t) + const { agent, shim, wrappable } = t.nr + t.after(afterEach) + shim.recordOperation(wrappable, 'getActiveSegment', function () { + return new OperationSpec({ + name: 'op', + parameters: { + host: 'some_host', + port_path_or_id: 1234, + database_name: 'foobar' + } }) }) - t.afterEach(afterEach) - - t.test('should create unscoped datastore metrics', function (t) { + helper.runInTransaction(agent, function (tx) { + wrappable.getActiveSegment() + tx.end() const { unscoped: metrics } = helper.getMetrics(agent) - t.ok(metrics['Datastore/all']) - t.ok(metrics['Datastore/allWeb']) - t.ok(metrics['Datastore/Cassandra/all']) - t.ok(metrics['Datastore/Cassandra/allWeb']) - t.ok(metrics['Datastore/operation/Cassandra/op']) - t.ok(metrics['Datastore/instance/Cassandra/some_host/1234']) - t.end() + assert.ok(metrics['Datastore/all']) + assert.ok(metrics['Datastore/allWeb']) + assert.ok(metrics['Datastore/Cassandra/all']) + assert.ok(metrics['Datastore/Cassandra/allWeb']) + assert.ok(metrics['Datastore/operation/Cassandra/op']) + assert.ok(metrics['Datastore/instance/Cassandra/some_host/1234']) + end() }) }) - t.test('#recordQuery', function (t) { + await t.test('#recordQuery', async function (t) { const query = 'SELECT property FROM my_table' - t.autoend() + t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordQuery(wrappable) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.ok(!shim.isWrapped(wrapped)) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordQuery(wrappable.bar, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordQuery(wrappable.bar, null, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordQuery(wrappable, 'bar', {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordQuery(wrappable, 'name', {}) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.ok(!shim.isWrapped(wrappable.name)) }) - t.test( + await t.test( 'should create a datastore query segment but no metric when `record` is false', - function (t) { + function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordQuery( wrappable, 'getActiveSegment', @@ -641,16 +649,17 @@ test('DatastoreShim', function (t) { helper.runInTransaction(agent, function (tx) { const startingSegment = agent.tracer.getSegment() const segment = wrappable.getActiveSegment(query) - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'getActiveSegment') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'getActiveSegment') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() }) } ) - t.test('should create a datastore query metric when `record` is true', function (t) { + await t.test('should create a datastore query metric when `record` is true', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordQuery( wrappable, 'getActiveSegment', @@ -660,29 +669,34 @@ test('DatastoreShim', function (t) { helper.runInTransaction(agent, function (tx) { const startingSegment = agent.tracer.getSegment() const segment = wrappable.getActiveSegment(query) - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'Datastore/statement/Cassandra/my_table/select') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'Datastore/statement/Cassandra/my_table/select') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() }) }) - t.test('should create a datastore query metric when `record` is defaulted', function (t) { - shim.recordQuery(wrappable, 'getActiveSegment', new QuerySpec({ query: shim.FIRST })) + await t.test( + 'should create a datastore query metric when `record` is defaulted', + function (t, end) { + const { agent, shim, wrappable } = t.nr + shim.recordQuery(wrappable, 'getActiveSegment', new QuerySpec({ query: shim.FIRST })) - helper.runInTransaction(agent, function (tx) { - const startingSegment = agent.tracer.getSegment() - const segment = wrappable.getActiveSegment(query) - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'Datastore/statement/Cassandra/my_table/select') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() - }) - }) + helper.runInTransaction(agent, function (tx) { + const startingSegment = agent.tracer.getSegment() + const segment = wrappable.getActiveSegment(query) + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'Datastore/statement/Cassandra/my_table/select') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() + }) + } + ) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t, end) { + const { agent, shim } = t.nr let executed = false const toWrap = function () { executed = true @@ -690,14 +704,15 @@ test('DatastoreShim', function (t) { const wrapped = shim.recordQuery(toWrap, {}) helper.runInTransaction(agent, function () { - t.notOk(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) + end() }) }) - t.test('should allow after handlers to be specified', function (t) { + await t.test('should allow after handlers to be specified', function (t, end) { + const { agent, shim } = t.nr let executed = false const toWrap = function () {} const wrapped = shim.recordQuery( @@ -713,17 +728,17 @@ test('DatastoreShim', function (t) { ) helper.runInTransaction(agent, function () { - t.notOk(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) + end() }) }) - t.test('should bind the callback if there is one', function (t) { - const cb = function () {} + await t.test('should bind the callback if there is one', function (t, end) { + const { agent, shim } = t.nr const wrapped = shim.recordQuery( - helper.checkWrappedCb.bind(t, shim, cb), + checkWrappedCb.bind(null, shim, end), new QuerySpec({ query: shim.FIRST, callback: shim.LAST @@ -731,15 +746,14 @@ test('DatastoreShim', function (t) { ) helper.runInTransaction(agent, function () { - wrapped(query, cb) + wrapped(query, end) }) }) - t.test('should bind the row callback if there is one', function (t) { - const cb = function () {} - + await t.test('should bind the row callback if there is one', function (t, end) { + const { agent, shim } = t.nr const wrapped = shim.recordQuery( - helper.checkWrappedCb.bind(t, shim, cb), + checkWrappedCb.bind(null, shim, end), new QuerySpec({ query: shim.FIRST, rowCallback: shim.LAST @@ -747,11 +761,12 @@ test('DatastoreShim', function (t) { ) helper.runInTransaction(agent, function () { - wrapped(query, cb) + wrapped(query, end) }) }) - t.test('should execute inContext function when specified in spec', function (t) { + await t.test('should execute inContext function when specified in spec', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordQuery( wrappable, 'bar', @@ -767,147 +782,151 @@ test('DatastoreShim', function (t) { wrappable.bar() const rootSegment = agent.tracer.getSegment() const attrs = rootSegment.children[0].getAttributes() - t.equal(attrs['test-attr'], 'unit-test', 'should add attribute to segment while in context') + assert.equal( + attrs['test-attr'], + 'unit-test', + 'should add attribute to segment while in context' + ) tx.end() - t.end() + end() }) }) }) - t.test('#recordBatchQuery', function (t) { + await t.test('#recordBatchQuery', async function (t) { const query = 'SELECT property FROM my_table' - t.autoend() + t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordBatchQuery(wrappable) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.ok(!shim.isWrapped(wrapped)) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordBatchQuery(wrappable.bar, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordBatchQuery(wrappable.bar, null, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordBatchQuery(wrappable, 'bar', {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordBatchQuery(wrappable, 'name', {}) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should create a datastore batch query metric', function (t) { + await t.test('should create a datastore batch query metric', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordBatchQuery(wrappable, 'getActiveSegment', new QuerySpec({ query: shim.FIRST })) helper.runInTransaction(agent, function (tx) { const startingSegment = agent.tracer.getSegment() const segment = wrappable.getActiveSegment(query) - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'Datastore/statement/Cassandra/my_table/select/batch') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'Datastore/statement/Cassandra/my_table/select/batch') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() }) }) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t) { + const { shim } = t.nr let executed = false const toWrap = function () { executed = true } const wrapped = shim.recordBatchQuery(toWrap, {}) - t.notOk(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) }) }) - t.test('#parseQuery', function (t) { - t.autoend() + await t.test('#parseQuery', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should parse a query string into a ParsedStatement', function (t) { + await t.test('should parse a query string into a ParsedStatement', function (t) { + const { shim } = t.nr const statement = shim.parseQuery('SELECT * FROM table') - t.ok(statement instanceof ParsedStatement) - t.end() + assert.ok(statement instanceof ParsedStatement) }) - t.test('should strip enclosing special characters from collection', function (t) { - t.equal(shim.parseQuery('select * from [table]').collection, 'table') - t.equal(shim.parseQuery('select * from {table}').collection, 'table') - t.equal(shim.parseQuery("select * from 'table'").collection, 'table') - t.equal(shim.parseQuery('select * from "table"').collection, 'table') - t.equal(shim.parseQuery('select * from `table`').collection, 'table') - t.end() + await t.test('should strip enclosing special characters from collection', function (t) { + const { shim } = t.nr + assert.equal(shim.parseQuery('select * from [table]').collection, 'table') + assert.equal(shim.parseQuery('select * from {table}').collection, 'table') + assert.equal(shim.parseQuery("select * from 'table'").collection, 'table') + assert.equal(shim.parseQuery('select * from "table"').collection, 'table') + assert.equal(shim.parseQuery('select * from `table`').collection, 'table') }) }) - t.test('#bindRowCallbackSegment', function (t) { - t.autoend() + await t.test('#bindRowCallbackSegment', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should wrap the identified argument', function (t) { + await t.test('should wrap the identified argument', function (t) { + const { shim, wrappable } = t.nr const args = [1, 2, wrappable.bar] shim.bindRowCallbackSegment(args, shim.LAST) - t.not(args[2], wrappable.bar) - t.ok(shim.isWrapped(args[2])) - t.equal(shim.unwrap(args[2]), wrappable.bar) - t.end() + assert.notEqual(args[2], wrappable.bar) + assert.equal(shim.isWrapped(args[2]), true) + assert.equal(shim.unwrap(args[2]), wrappable.bar) }) - t.test('should not wrap if the index is invalid', function (t) { + await t.test('should not wrap if the index is invalid', function (t) { + const { shim, wrappable } = t.nr const args = [1, 2, wrappable.bar] - t.doesNotThrow(function () { + assert.doesNotThrow(function () { shim.bindRowCallbackSegment(args, 50) }) - t.equal(args[2], wrappable.bar) - t.notOk(shim.isWrapped(args[2])) - t.end() + assert.equal(args[2], wrappable.bar) + assert.ok(!shim.isWrapped(args[2])) }) - t.test('should not wrap the argument if it is not a function', function (t) { + await t.test('should not wrap the argument if it is not a function', function (t) { + const { shim, wrappable } = t.nr const args = [1, 2, wrappable.bar] - t.doesNotThrow(function () { + assert.doesNotThrow(function () { shim.bindRowCallbackSegment(args, 1) }) - t.equal(args[1], 2) - t.notOk(shim.isWrapped(args[1])) - t.equal(args[2], wrappable.bar) - t.notOk(shim.isWrapped(args[2])) - t.end() + assert.equal(args[1], 2) + assert.ok(!shim.isWrapped(args[1])) + assert.equal(args[2], wrappable.bar) + assert.ok(!shim.isWrapped(args[2])) }) - t.test('should create a new segment on the first call', function (t) { + await t.test('should create a new segment on the first call', function (t, end) { + const { agent, shim, wrappable } = t.nr helper.runInTransaction(agent, function () { const args = [1, 2, wrappable.getActiveSegment] shim.bindRowCallbackSegment(args, shim.LAST) @@ -915,13 +934,14 @@ test('DatastoreShim', function (t) { // Check the segment const segment = shim.getSegment() const cbSegment = args[2]() - t.not(cbSegment, segment) - t.not(segment.children.includes(cbSegment)) - t.end() + assert.notEqual(cbSegment, segment) + assert.ok(segment.children.includes(cbSegment)) + end() }) }) - t.test('should not create a new segment for calls after the first', function (t) { + await t.test('should not create a new segment for calls after the first', function (t, end) { + const { agent, shim, wrappable } = t.nr helper.runInTransaction(agent, function () { const args = [1, 2, wrappable.getActiveSegment] shim.bindRowCallbackSegment(args, shim.LAST) @@ -929,53 +949,54 @@ test('DatastoreShim', function (t) { // Check the segment from the first call. const segment = shim.getSegment() const cbSegment = args[2]() - t.not(cbSegment, segment) - t.ok(segment.children.includes(cbSegment)) - t.equal(segment.children.length, 1) + assert.notEqual(cbSegment, segment) + assert.ok(segment.children.includes(cbSegment)) + assert.equal(segment.children.length, 1) // Call it a second time and see if we have the same segment. const cbSegment2 = args[2]() - t.equal(cbSegment2, cbSegment) - t.equal(segment.children.length, 1) - t.end() + assert.equal(cbSegment2, cbSegment) + assert.equal(segment.children.length, 1) + end() }) }) - t.test('should name the segment based on number of calls', function (t) { + await t.test('should name the segment based on number of calls', function (t, end) { + const { agent, shim, wrappable } = t.nr helper.runInTransaction(agent, function () { const args = [1, 2, wrappable.getActiveSegment] shim.bindRowCallbackSegment(args, shim.LAST) // Check the segment from the first call. const cbSegment = args[2]() - t.match(cbSegment.name, /^Callback: getActiveSegment/) - t.equal(cbSegment.getAttributes().count, 1) + assert.match(cbSegment.name, /^Callback: getActiveSegment/) + assert.equal(cbSegment.getAttributes().count, 1) // Call it a second time and see if the name changed. args[2]() - t.equal(cbSegment.getAttributes().count, 2) + assert.equal(cbSegment.getAttributes().count, 2) // And a third time, why not? args[2]() - t.equal(cbSegment.getAttributes().count, 3) - t.end() + assert.equal(cbSegment.getAttributes().count, 3) + end() }) }) }) - t.test('#captureInstanceAttributes', function (t) { - t.autoend() + await t.test('#captureInstanceAttributes', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not crash outside of a transaction', function (t) { - t.doesNotThrow(function () { + await t.test('should not crash outside of a transaction', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.captureInstanceAttributes('foo', 123, 'bar') }) - t.end() }) - t.test('should not add parameters to segments it did not create', function (t) { + await t.test('should not add parameters to segments it did not create', function (t, end) { + const { agent, shim } = t.nr const bound = agent.tracer.wrapFunction( 'foo', null, @@ -990,16 +1011,17 @@ test('DatastoreShim', function (t) { helper.runInTransaction(agent, function () { const segment = bound('foobar', 123, 'bar') - t.ok(segment.attributes) + assert.ok(segment.attributes) const attributes = segment.getAttributes() - t.notOk(attributes.host) - t.notOk(attributes.port_path_or_id) - t.notOk(attributes.database_name) - t.end() + assert.ok(!attributes.host) + assert.ok(!attributes.port_path_or_id) + assert.ok(!attributes.database_name) + end() }) }) - t.test('should add normalized attributes to its own segments', function (t) { + await t.test('should add normalized attributes to its own segments', function (t, end) { + const { agent, shim } = t.nr const wrapped = shim.recordOperation(function (host, port, db) { shim.captureInstanceAttributes(host, port, db) return shim.getSegment() @@ -1007,58 +1029,57 @@ test('DatastoreShim', function (t) { helper.runInTransaction(agent, function () { const segment = wrapped('foobar', 123, 'bar') - t.ok(segment.attributes) + assert.ok(segment.attributes) const attributes = segment.getAttributes() - t.equal(attributes.host, 'foobar') - t.equal(attributes.port_path_or_id, '123') - t.equal(attributes.database_name, 'bar') - t.end() + assert.equal(attributes.host, 'foobar') + assert.equal(attributes.port_path_or_id, '123') + assert.equal(attributes.database_name, 'bar') + end() }) }) }) - t.test('#getDatabaseNameFromUseQuery', (t) => { - t.autoend() + await t.test('#getDatabaseNameFromUseQuery', async (t) => { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should match single statement use expressions', (t) => { - t.equal(shim.getDatabaseNameFromUseQuery('use test_db;'), 'test_db') - t.equal(shim.getDatabaseNameFromUseQuery('USE INIT'), 'INIT') - t.end() + await t.test('should match single statement use expressions', (t) => { + const { shim } = t.nr + assert.equal(shim.getDatabaseNameFromUseQuery('use test_db;'), 'test_db') + assert.equal(shim.getDatabaseNameFromUseQuery('USE INIT'), 'INIT') }) - t.test('should not be sensitive to ; omission', (t) => { - t.equal(shim.getDatabaseNameFromUseQuery('use test_db'), 'test_db') - t.end() + await t.test('should not be sensitive to ; omission', (t) => { + const { shim } = t.nr + assert.equal(shim.getDatabaseNameFromUseQuery('use test_db'), 'test_db') }) - t.test('should not be sensitive to extra ;', (t) => { - t.equal(shim.getDatabaseNameFromUseQuery('use test_db;;;;;;'), 'test_db') - t.end() + await t.test('should not be sensitive to extra ;', (t) => { + const { shim } = t.nr + assert.equal(shim.getDatabaseNameFromUseQuery('use test_db;;;;;;'), 'test_db') }) - t.test('should not be sensitive to extra white space', (t) => { - t.equal(shim.getDatabaseNameFromUseQuery(' use test_db;'), 'test_db') - t.equal(shim.getDatabaseNameFromUseQuery('use test_db;'), 'test_db') - t.equal(shim.getDatabaseNameFromUseQuery('use test_db ;'), 'test_db') - t.equal(shim.getDatabaseNameFromUseQuery('use test_db; '), 'test_db') - t.end() + await t.test('should not be sensitive to extra white space', (t) => { + const { shim } = t.nr + assert.equal(shim.getDatabaseNameFromUseQuery(' use test_db;'), 'test_db') + assert.equal(shim.getDatabaseNameFromUseQuery('use test_db;'), 'test_db') + assert.equal(shim.getDatabaseNameFromUseQuery('use test_db ;'), 'test_db') + assert.equal(shim.getDatabaseNameFromUseQuery('use test_db; '), 'test_db') }) - t.test('should match backtick expressions', (t) => { - t.equal(shim.getDatabaseNameFromUseQuery('use `test_db`;'), '`test_db`') - t.equal(shim.getDatabaseNameFromUseQuery('use `☃☃☃☃☃☃`;'), '`☃☃☃☃☃☃`') - t.end() + await t.test('should match backtick expressions', (t) => { + const { shim } = t.nr + assert.equal(shim.getDatabaseNameFromUseQuery('use `test_db`;'), '`test_db`') + assert.equal(shim.getDatabaseNameFromUseQuery('use `☃☃☃☃☃☃`;'), '`☃☃☃☃☃☃`') }) - t.test('should not match malformed use expressions', (t) => { - t.equal(shim.getDatabaseNameFromUseQuery('use cxvozicjvzocixjv`oasidfjaosdfij`;'), null) - t.equal(shim.getDatabaseNameFromUseQuery('use `oasidfjaosdfij`123;'), null) - t.equal(shim.getDatabaseNameFromUseQuery('use `oasidfjaosdfij` 123;'), null) - t.equal(shim.getDatabaseNameFromUseQuery('use \u0001;'), null) - t.equal(shim.getDatabaseNameFromUseQuery('use oasidfjaosdfij 123;'), null) - t.end() + await t.test('should not match malformed use expressions', (t) => { + const { shim } = t.nr + assert.equal(shim.getDatabaseNameFromUseQuery('use cxvozicjvzocixjv`oasidfjaosdfij`;'), null) + assert.equal(shim.getDatabaseNameFromUseQuery('use `oasidfjaosdfij`123;'), null) + assert.equal(shim.getDatabaseNameFromUseQuery('use `oasidfjaosdfij` 123;'), null) + assert.equal(shim.getDatabaseNameFromUseQuery('use \u0001;'), null) + assert.equal(shim.getDatabaseNameFromUseQuery('use oasidfjaosdfij 123;'), null) }) }) }) diff --git a/test/unit/shim/message-shim.test.js b/test/unit/shim/message-shim.test.js index 2f4e86543d..30e578c960 100644 --- a/test/unit/shim/message-shim.test.js +++ b/test/unit/shim/message-shim.test.js @@ -4,43 +4,33 @@ */ 'use strict' -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') +const { tspl } = require('@matteo.collina/tspl') const API = require('../../../api') const DESTINATIONS = require('../../../lib/config/attribute-filter').DESTINATIONS const hashes = require('../../../lib/util/hashes') const helper = require('../../lib/agent_helper') const MessageShim = require('../../../lib/shim/message-shim') const { MessageSpec, MessageSubscribeSpec } = require('../../../lib/shim/specs') - -tap.test('MessageShim', function (t) { - t.autoend() - let agent = null - let shim = null - let wrappable = null - let interval = null - const tasks = [] - - t.before(function () { - interval = setInterval(function () { - if (tasks.length) { - tasks.pop()() - } - }, 10) - }) - - t.teardown(function () { - clearInterval(interval) - }) - - function beforeEach() { - agent = helper.instrumentMockedAgent({ +const { + compareSegments, + checkWrappedCb, + isNonWritable, + match +} = require('../../lib/custom-assertions') + +test('MessageShim', async function (t) { + function beforeEach(ctx) { + ctx.nr = {} + const agent = helper.instrumentMockedAgent({ span_events: { attributes: { enabled: true, include: ['message.parameters.*'] } } }) - shim = new MessageShim(agent, 'test-module') + const shim = new MessageShim(agent, 'test-module') shim.setLibrary(shim.RABBITMQ) - wrappable = { + ctx.nr.wrappable = { name: 'this is a name', bar: function barsName(unused, params) { return 'bar' }, // eslint-disable-line fiz: function fizsName() { @@ -66,142 +56,123 @@ tap.test('MessageShim', function (t) { agent.config.trusted_account_ids = [9876, 6789] agent.config._fromServer(params, 'encoding_key') agent.config._fromServer(params, 'cross_process_id') + ctx.nr.agent = agent + ctx.nr.shim = shim } - function afterEach() { - helper.unloadAgent(agent) - agent = null - shim = null + function afterEach(ctx) { + helper.unloadAgent(ctx.nr.agent) } - t.test('constructor', function (t) { - t.autoend() + await t.test('constructor', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should require an agent parameter', function (t) { - t.throws(function () { + await t.test('should require an agent parameter', function () { + assert.throws(function () { return new MessageShim() - }, /^Shim must be initialized with .*? agent/) - t.end() + }, 'Shim must be initialized with agent and module name') }) - t.test('should require a module name parameter', function (t) { - t.throws(function () { + await t.test('should require a module name parameter', function (t) { + const { agent } = t.nr + assert.throws(function () { return new MessageShim(agent) - }, /^Shim must be initialized with .*? module name/) - t.end() + }, 'Error: Shim must be initialized with agent and module name') }) - t.test('should assign properties from parent', (t) => { + await t.test('should assign properties from parent', (t) => { + const { agent } = t.nr const mod = 'test-mod' const name = mod const version = '1.0.0' const shim = new MessageShim(agent, mod, mod, name, version) - t.equal(shim.moduleName, mod) - t.equal(agent, shim._agent) - t.equal(shim.pkgVersion, version) - t.end() - }) - }) - - t.test('well-known message libraries', function (t) { - t.autoend() - t.beforeEach(beforeEach) - t.afterEach(afterEach) - const messageLibs = ['RABBITMQ'] - - t.test('should be enumerated on the class and prototype', function (t) { - messageLibs.forEach(function (lib) { - t.isNonWritable({ obj: MessageShim, key: lib }) - t.isNonWritable({ obj: shim, key: lib }) - }) - t.end() + assert.equal(shim.moduleName, mod) + assert.equal(agent, shim._agent) + assert.equal(shim.pkgVersion, version) }) }) - t.test('well-known destination types', function (t) { - t.autoend() + await t.test('well-known libraries/destination types', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - const messageLibs = ['EXCHANGE', 'QUEUE', 'TOPIC'] + const messageLibs = ['RABBITMQ', 'EXCHANGE', 'QUEUE', 'TOPIC'] - t.test('should be enumerated on the class and prototype', function (t) { - messageLibs.forEach(function (lib) { - t.isNonWritable({ obj: MessageShim, key: lib }) - t.isNonWritable({ obj: shim, key: lib }) + for (const lib of messageLibs) { + await t.test(`should be enumerated on the class and prototype of ${lib}`, function (t) { + const { shim } = t.nr + isNonWritable({ obj: MessageShim, key: lib }) + isNonWritable({ obj: shim, key: lib }) }) - t.end() - }) + } }) - t.test('#setLibrary', function (t) { - t.autoend() + await t.test('#setLibrary', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should create broker metric names', function (t) { + await t.test('should create broker metric names', function (t) { + const { agent } = t.nr const s = new MessageShim(agent, 'test') - t.notOk(s._metrics) + assert.ok(!s._metrics) s.setLibrary('foobar') - t.equal(s._metrics.PREFIX, 'MessageBroker/') - t.equal(s._metrics.LIBRARY, 'foobar') - t.end() + assert.equal(s._metrics.PREFIX, 'MessageBroker/') + assert.equal(s._metrics.LIBRARY, 'foobar') }) - t.test("should update the shim's logger", function (t) { + await t.test("should update the shim's logger", function (t) { + const { agent } = t.nr const s = new MessageShim(agent, 'test') const { logger } = s s.setLibrary('foobar') - t.not(s.logger, logger) - t.end() + assert.notEqual(s.logger, logger) }) }) - t.test('#recordProduce', function (t) { - t.autoend() + await t.test('#recordProduce', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordProduce(wrappable, function () {}) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.ok(!shim.isWrapped(wrapped)) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordProduce(wrappable.bar, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(helper.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(helper.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordProduce(wrappable.bar, null, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(helper.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(helper.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordProduce(wrappable, 'bar', function () {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(helper.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(helper.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordProduce(wrappable, 'name', function () {}) - t.not(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should create a produce segment', function (t) { + await t.test('should create a produce segment', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordProduce(wrappable, 'getActiveSegment', function () { return new MessageSpec({ destinationName: 'foobar' }) }) @@ -209,15 +180,16 @@ tap.test('MessageShim', function (t) { helper.runInTransaction(agent, function (tx) { const startingSegment = agent.tracer.getSegment() const segment = wrappable.getActiveSegment() - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Produce/Named/foobar') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Produce/Named/foobar') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() }) }) - t.test('should add parameters to segment', function (t) { + await t.test('should add parameters to segment', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordProduce(wrappable, 'getActiveSegment', function () { return new MessageSpec({ routingKey: 'foo.bar', @@ -228,14 +200,15 @@ tap.test('MessageShim', function (t) { helper.runInTransaction(agent, function () { const segment = wrappable.getActiveSegment() const attributes = segment.getAttributes() - t.equal(attributes.routing_key, 'foo.bar') - t.equal(attributes.a, 'a') - t.equal(attributes.b, 'b') - t.end() + assert.equal(attributes.routing_key, 'foo.bar') + assert.equal(attributes.a, 'a') + assert.equal(attributes.b, 'b') + end() }) }) - t.test('should not add parameters when disabled', function (t) { + await t.test('should not add parameters when disabled', function (t, end) { + const { agent, shim, wrappable } = t.nr agent.config.message_tracer.segment_parameters.enabled = false shim.recordProduce(wrappable, 'getActiveSegment', function () { return new MessageSpec({ @@ -249,13 +222,14 @@ tap.test('MessageShim', function (t) { helper.runInTransaction(agent, function () { const segment = wrappable.getActiveSegment() const attributes = segment.getAttributes() - t.notOk(attributes.a) - t.notOk(attributes.b) - t.end() + assert.ok(!attributes.a) + assert.ok(!attributes.b) + end() }) }) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t, end) { + const { agent, shim } = t.nr let executed = false const toWrap = function () { executed = true @@ -263,44 +237,49 @@ tap.test('MessageShim', function (t) { const wrapped = shim.recordProduce(toWrap, function () {}) helper.runInTransaction(agent, function () { - t.notOk(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) + end() }) }) - t.test('should invoke the spec in the context of the wrapped function', function (t) { - const original = wrappable.bar - let executed = false - shim.recordProduce(wrappable, 'bar', function (_, fn, name, args) { - executed = true - t.equal(fn, original) - t.equal(name, 'bar') - t.equal(this, wrappable) - t.same(args, ['a', 'b', 'c']) + await t.test( + 'should invoke the spec in the context of the wrapped function', + function (t, end) { + const { agent, shim, wrappable } = t.nr + const original = wrappable.bar + let executed = false + shim.recordProduce(wrappable, 'bar', function (_, fn, name, args) { + executed = true + assert.equal(fn, original) + assert.equal(name, 'bar') + assert.equal(this, wrappable) + assert.deepEqual(args, ['a', 'b', 'c']) - return new MessageSpec({ destinationName: 'foobar' }) - }) + return new MessageSpec({ destinationName: 'foobar' }) + }) - helper.runInTransaction(agent, function () { - wrappable.bar('a', 'b', 'c') - t.ok(executed) - t.end() - }) - }) + helper.runInTransaction(agent, function () { + wrappable.bar('a', 'b', 'c') + assert.equal(executed, true) + end() + }) + } + ) - t.test('should bind the callback if there is one', function (t) { + await t.test('should bind the callback if there is one', function (t, end) { + const { agent, shim } = t.nr const cb = function () {} const toWrap = function (wrappedCB) { - t.not(wrappedCB, cb) - t.ok(shim.isWrapped(wrappedCB)) - t.equal(shim.unwrap(wrappedCB), cb) + assert.notEqual(wrappedCB, cb) + assert.equal(shim.isWrapped(wrappedCB), true) + assert.equal(shim.unwrap(wrappedCB), cb) - t.doesNotThrow(function () { + assert.doesNotThrow(function () { wrappedCB() }) - t.end() + end() } const wrapped = shim.recordProduce(toWrap, function () { @@ -312,7 +291,8 @@ tap.test('MessageShim', function (t) { }) }) - t.test('should link the promise if one is returned', function (t) { + await t.test('should link the promise if one is returned', async function (t) { + const { agent, shim } = t.nr const DELAY = 25 let segment = null const val = {} @@ -329,9 +309,9 @@ tap.test('MessageShim', function (t) { return helper.runInTransaction(agent, function () { return wrapped().then(function (v) { - t.equal(v, val) + assert.equal(v, val) const duration = segment.getDurationInMillis() - t.ok( + assert.ok( duration > DELAY - 1, `Segment duration: ${duration} should be > Timer duration: ${DELAY - 1}` ) @@ -339,39 +319,42 @@ tap.test('MessageShim', function (t) { }) }) - t.test('should create a child segment when `opaque` is false', function (t) { + await t.test('should create a child segment when `opaque` is false', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordProduce(wrappable, 'withNested', function () { return new MessageSpec({ destinationName: 'foobar', opaque: false }) }) helper.runInTransaction(agent, (tx) => { const segment = wrappable.withNested() - t.equal(segment.transaction, tx) - t.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Produce/Named/foobar') + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Produce/Named/foobar') - t.equal(segment.children.length, 1) + assert.equal(segment.children.length, 1) const [childSegment] = segment.children - t.equal(childSegment.name, 'ChildSegment') - t.end() + assert.equal(childSegment.name, 'ChildSegment') + end() }) }) - t.test('should not create a child segment when `opaque` is true', function (t) { + await t.test('should not create a child segment when `opaque` is true', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordProduce(wrappable, 'withNested', function () { return new MessageSpec({ destinationName: 'foobar', opaque: true }) }) helper.runInTransaction(agent, (tx) => { const segment = wrappable.withNested() - t.equal(segment.transaction, tx) - t.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Produce/Named/foobar') + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Produce/Named/foobar') - t.equal(segment.children.length, 0) - t.end() + assert.equal(segment.children.length, 0) + end() }) }) - t.test('should insert CAT request headers', function (t) { + await t.test('should insert CAT request headers', function (t, end) { + const { agent, shim, wrappable } = t.nr agent.config.cross_application_tracer.enabled = true agent.config.distributed_tracing.enabled = false const headers = {} @@ -381,14 +364,15 @@ tap.test('MessageShim', function (t) { helper.runInTransaction(agent, function () { wrappable.getActiveSegment() - t.ok(headers.NewRelicID) - t.ok(headers.NewRelicTransaction) - t.end() + assert.ok(headers.NewRelicID) + assert.ok(headers.NewRelicTransaction) + end() }) }) - t.test('should insert distributed trace headers in all messages', function (t) { - t.plan(1) + await t.test('should insert distributed trace headers in all messages', function (t, end) { + const plan = tspl(t, { plan: 1 }) + const { agent, shim, wrappable } = t.nr const messages = [{}, { headers: { foo: 'foo' } }, {}] shim.recordProduce( @@ -409,8 +393,10 @@ tap.test('MessageShim', function (t) { }) ) + let called = 0 agent.on('transactionFinished', () => { - t.match(messages, [ + called++ + match(messages, [ { headers: { newrelic: '', @@ -431,7 +417,8 @@ tap.test('MessageShim', function (t) { } } ]) - t.end() + plan.equal(called, 1) + end() }) helper.runInTransaction(agent, (tx) => { @@ -440,7 +427,8 @@ tap.test('MessageShim', function (t) { }) }) - t.test('should create message broker metrics', function (t) { + await t.test('should create message broker metrics', function (t, end) { + const { agent, shim, wrappable } = t.nr let transaction = null shim.recordProduce(wrappable, 'getActiveSegment', function () { @@ -453,86 +441,86 @@ tap.test('MessageShim', function (t) { tx.end() const { unscoped } = helper.getMetrics(agent) const scoped = transaction.metrics.unscoped - t.ok(unscoped['MessageBroker/RabbitMQ/Exchange/Produce/Named/my-queue']) - t.ok(scoped['MessageBroker/RabbitMQ/Exchange/Produce/Named/my-queue']) - t.end() + assert.ok(unscoped['MessageBroker/RabbitMQ/Exchange/Produce/Named/my-queue']) + assert.ok(scoped['MessageBroker/RabbitMQ/Exchange/Produce/Named/my-queue']) + end() }) }) }) - t.test('#recordConsume', function (t) { - t.autoend() + await t.test('#recordConsume', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordConsume(wrappable, function () {}) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.ok(!shim.isWrapped(wrapped)) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordConsume(wrappable.bar, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordConsume(wrappable.bar, null, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordConsume(wrappable, 'bar', function () {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordConsume(wrappable, 'name', function () {}) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should create a consume segment', function (t) { + await t.test('should create a consume segment', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordConsume(wrappable, 'getActiveSegment', function () { - t.same(this, wrappable, 'make sure this is in tact') + assert.deepEqual(this, wrappable, 'make sure this is in tact') return new MessageSpec({ destinationName: 'foobar' }) }) helper.runInTransaction(agent, function (tx) { const startingSegment = agent.tracer.getSegment() const segment = wrappable.getActiveSegment() - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Consume/Named/foobar') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Consume/Named/foobar') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() }) }) - t.test('should bind the callback if there is one', function (t) { - const cb = function () {} - - const wrapped = shim.recordConsume(helper.checkWrappedCb.bind(t, shim, cb), function () { + await t.test('should bind the callback if there is one', function (t, end) { + const { agent, shim } = t.nr + const wrapped = shim.recordConsume(checkWrappedCb.bind(t, shim, end), function () { return new MessageSpec({ callback: shim.LAST }) }) helper.runInTransaction(agent, function () { - wrapped(cb) + wrapped(end) }) }) - t.test('should be able to get destinationName from arguments', function (t) { + await t.test('should be able to get destinationName from arguments', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordConsume(wrappable, 'getActiveSegment', { destinationName: shim.FIRST, destinationType: shim.EXCHANGE @@ -541,15 +529,16 @@ tap.test('MessageShim', function (t) { helper.runInTransaction(agent, function (tx) { const startingSegment = agent.tracer.getSegment() const segment = wrappable.getActiveSegment('fizzbang') - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Consume/Named/fizzbang') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Consume/Named/fizzbang') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() }) }) - t.test('should handle promise-based APIs', function (t) { + await t.test('should handle promise-based APIs', async function (t) { + const { agent, shim } = t.nr const msg = {} let segment = null const DELAY = 25 @@ -567,20 +556,21 @@ tap.test('MessageShim', function (t) { destinationName: shim.FIRST, promise: true, after: function ({ result }) { - t.equal(result, msg) + assert.equal(result, msg) } }) return helper.runInTransaction(agent, function () { return wrapped('foo', function () {}).then(function (message) { const duration = segment.getDurationInMillis() - t.ok(duration > DELAY - 1, 'segment duration should be at least 100 ms') - t.equal(message, msg) + assert.ok(duration > DELAY - 1, 'segment duration should be at least 100 ms') + assert.equal(message, msg) }) }) }) - t.test('should bind promise even without messageHandler', function (t) { + await t.test('should bind promise even without messageHandler', async function (t) { + const { agent, shim } = t.nr const msg = {} let segment = null const DELAY = 25 @@ -603,13 +593,14 @@ tap.test('MessageShim', function (t) { return helper.runInTransaction(agent, function () { return wrapped('foo', function () {}).then(function (message) { const duration = segment.getDurationInMillis() - t.ok(duration > DELAY - 1, 'segment duration should be at least 100 ms') - t.equal(message, msg) + assert.ok(duration > DELAY - 1, 'segment duration should be at least 100 ms') + assert.equal(message, msg) }) }) }) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t, end) { + const { agent, shim } = t.nr let executed = false const toWrap = function () { executed = true @@ -619,45 +610,48 @@ tap.test('MessageShim', function (t) { }) helper.runInTransaction(agent, function () { - t.notOk(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) + end() }) }) - t.test('should create a child segment when `opaque` is false', function (t) { + await t.test('should create a child segment when `opaque` is false', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordConsume(wrappable, 'withNested', function () { return new MessageSpec({ destinationName: 'foobar', opaque: false }) }) helper.runInTransaction(agent, function (tx) { const segment = wrappable.withNested() - t.equal(segment.transaction, tx) - t.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Consume/Named/foobar') + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Consume/Named/foobar') - t.equal(segment.children.length, 1) + assert.equal(segment.children.length, 1) const [childSegment] = segment.children - t.equal(childSegment.name, 'ChildSegment') - t.end() + assert.equal(childSegment.name, 'ChildSegment') + end() }) }) - t.test('should not create a child segment when `opaque` is true', function (t) { + await t.test('should not create a child segment when `opaque` is true', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordConsume(wrappable, 'withNested', function () { return new MessageSpec({ destinationName: 'foobar', opaque: true }) }) helper.runInTransaction(agent, function (tx) { const segment = wrappable.withNested() - t.equal(segment.transaction, tx) - t.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Consume/Named/foobar') - t.equal(segment.children.length, 0) - t.end() + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'MessageBroker/RabbitMQ/Exchange/Consume/Named/foobar') + assert.equal(segment.children.length, 0) + end() }) }) - t.test('should create message broker metrics', function (t) { + await t.test('should create message broker metrics', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordConsume(wrappable, 'getActiveSegment', function () { return new MessageSpec({ destinationName: 'foobar' }) }) @@ -670,75 +664,76 @@ tap.test('MessageShim', function (t) { agent.on('transactionFinished', function () { const metrics = helper.getMetrics(agent) - t.ok(metrics.unscoped['MessageBroker/RabbitMQ/Exchange/Consume/Named/foobar']) - t.ok( + assert.ok(metrics.unscoped['MessageBroker/RabbitMQ/Exchange/Consume/Named/foobar']) + assert.ok( metrics.scoped['WebTransaction/test-transaction'][ 'MessageBroker/RabbitMQ/Exchange/Consume/Named/foobar' ] ) - t.end() + end() }) }) }) - t.test('#recordPurgeQueue', function (t) { - t.autoend() + await t.test('#recordPurgeQueue', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordPurgeQueue(wrappable, {}) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.ok(!shim.isWrapped(wrapped)) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordPurgeQueue(wrappable.bar, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordPurgeQueue(wrappable.bar, null, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordPurgeQueue(wrappable, 'bar', {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordPurgeQueue(wrappable, 'name', {}) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should create a purge segment and metric', function (t) { + await t.test('should create a purge segment and metric', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordPurgeQueue(wrappable, 'getActiveSegment', new MessageSpec({ queue: shim.FIRST })) helper.runInTransaction(agent, function (tx) { const startingSegment = agent.tracer.getSegment() const segment = wrappable.getActiveSegment('foobar') - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'MessageBroker/RabbitMQ/Queue/Purge/Named/foobar') - t.equal(agent.tracer.getSegment(), startingSegment) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'MessageBroker/RabbitMQ/Queue/Purge/Named/foobar') + assert.equal(agent.tracer.getSegment(), startingSegment) + end() }) }) - t.test('should call the spec if it is not static', function (t) { + await t.test('should call the spec if it is not static', function (t, end) { + const { agent, shim, wrappable } = t.nr let called = false shim.recordPurgeQueue(wrappable, 'getActiveSegment', function () { @@ -747,14 +742,15 @@ tap.test('MessageShim', function (t) { }) helper.runInTransaction(agent, function () { - t.notOk(called) + assert.equal(called, false) wrappable.getActiveSegment('foobar') - t.ok(called) - t.end() + assert.equal(called, true) + end() }) }) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t, end) { + const { agent, shim } = t.nr let executed = false const toWrap = function () { executed = true @@ -762,29 +758,29 @@ tap.test('MessageShim', function (t) { const wrapped = shim.recordPurgeQueue(toWrap, {}) helper.runInTransaction(agent, function () { - t.notOk(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) + end() }) }) - t.test('should bind the callback if there is one', function (t) { - const cb = function () {} - + await t.test('should bind the callback if there is one', function (t, end) { + const { agent, shim } = t.nr const wrapped = shim.recordPurgeQueue( - helper.checkWrappedCb.bind(t, shim, cb), + checkWrappedCb.bind(null, shim, end), new MessageSpec({ callback: shim.LAST }) ) helper.runInTransaction(agent, function () { - wrapped(cb) + wrapped(end) }) }) - t.test('should link the promise if one is returned', function (t) { + await t.test('should link the promise if one is returned', async function (t) { + const { agent, shim } = t.nr const DELAY = 25 const val = {} let segment = null @@ -798,9 +794,9 @@ tap.test('MessageShim', function (t) { return helper.runInTransaction(agent, function () { return wrapped().then(function (v) { - t.equal(v, val) + assert.equal(v, val) const duration = segment.getDurationInMillis() - t.ok( + assert.ok( duration > DELAY - 1, `Segment duration: ${duration} should be > Timer duration: ${DELAY - 1}` ) @@ -808,7 +804,8 @@ tap.test('MessageShim', function (t) { }) }) - t.test('should create message broker metrics', function (t) { + await t.test('should create message broker metrics', function (t, end) { + const { agent, shim, wrappable } = t.nr let transaction = null shim.recordPurgeQueue(wrappable, 'getActiveSegment', new MessageSpec({ queue: shim.FIRST })) @@ -818,123 +815,117 @@ tap.test('MessageShim', function (t) { tx.end() const { unscoped } = helper.getMetrics(agent) const scoped = transaction.metrics.unscoped - t.ok(unscoped['MessageBroker/RabbitMQ/Queue/Purge/Named/my-queue']) - t.ok(scoped['MessageBroker/RabbitMQ/Queue/Purge/Named/my-queue']) - t.end() + assert.ok(unscoped['MessageBroker/RabbitMQ/Queue/Purge/Named/my-queue']) + assert.ok(scoped['MessageBroker/RabbitMQ/Queue/Purge/Named/my-queue']) + end() }) }) }) - t.test('#recordSubscribedConsume', function (t) { - t.autoend() + await t.test('#recordSubscribedConsume', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordSubscribedConsume(wrappable, { consumer: shim.FIRST, messageHandler: function () {} }) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.ok(!shim.isWrapped(wrapped)) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordSubscribedConsume(wrappable.bar, { consumer: shim.FIRST, messageHandler: function () {}, wrapper: function () {} }) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(helper.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(helper.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordSubscribedConsume(wrappable.bar, null, { consumer: shim.FIRST, messageHandler: function () {}, wrapper: function () {} }) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(helper.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(helper.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordSubscribedConsume(wrappable, 'bar', { consumer: shim.FIRST, messageHandler: function () {}, wrapper: function () {} }) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(helper.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(helper.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordSubscribedConsume(wrappable, 'name', { consumer: shim.FIRST, messageHandler: function () {}, wrapper: function () {} }) - t.not(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should allow spec to be a function', function (t) { + await t.test('should allow spec to be a function', function (t, end) { + const { shim, wrappable } = t.nr shim.recordSubscribedConsume(wrappable, 'name', function () { - t.same(this, wrappable, 'should preserve this context') + assert.deepEqual(this, wrappable, 'should preserve this context') return { consumer: shim.FIRST, messageHandler: function () {}, wrapper: function () {} } }) - t.not(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) + end() }) }) - t.test('#recordSubscribedConsume wrapper', function (t) { - let message = null - let messageHandler = null - let subscriber = null - let wrapped = null - let handlerCalled = false - let subscriberCalled = false + await t.test('#recordSubscribedConsume wrapper', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { shim } = ctx.nr - t.autoend() - - t.beforeEach(function () { - beforeEach() - - message = {} - subscriber = function consumeSubscriber(queue, consumer, cb) { - subscriberCalled = true + ctx.nr.message = {} + ctx.nr.handlerCalled = false + ctx.nr.subscriberCalled = false + const subscriber = function consumeSubscriber(queue, consumer, cb) { + ctx.nr.subscriberCalled = true if (cb) { setImmediate(cb) } if (consumer) { - setImmediate(consumer, message) + setImmediate(consumer, ctx.nr.message) } return shim.getSegment() } - wrapped = shim.recordSubscribedConsume(subscriber, { + ctx.nr.wrapped = shim.recordSubscribedConsume(subscriber, { name: 'Channel#subscribe', queue: shim.FIRST, consumer: shim.SECOND, callback: shim.LAST, messageHandler: function (shim) { - handlerCalled = true - if (messageHandler) { - return messageHandler.apply(this, arguments) + ctx.nr.handlerCalled = true + if (ctx.nr.messageHandler) { + return ctx.nr.messageHandler.apply(this, arguments) } return new MessageSubscribeSpec({ destinationName: 'exchange.foo', @@ -947,64 +938,61 @@ tap.test('MessageShim', function (t) { }) } }) + ctx.nr.subscriber = subscriber }) - t.afterEach(function () { - afterEach() - message = null - subscriber = null - wrapped = null - messageHandler = null - subscriberCalled = false - handlerCalled = false - }) + t.afterEach(afterEach) - t.test('should start a new transaction in the consumer', function (t) { + await t.test('should start a new transaction in the consumer', function (t, end) { + const { shim, wrapped } = t.nr const parent = wrapped('my.queue', function consumer() { const segment = shim.getSegment() - t.not(segment.name, 'Callback: consumer') - t.equal(segment.transaction.type, 'message') - t.end() + assert.notEqual(segment.name, 'Callback: consumer') + assert.equal(segment.transaction.type, 'message') + end() }) - t.notOk(parent) + assert.ok(!parent) }) - t.test('should end the transaction immediately if not handled', function (t) { + await t.test('should end the transaction immediately if not handled', function (t, end) { + const { shim, wrapped } = t.nr wrapped('my.queue', function consumer() { const tx = shim.getSegment().transaction - t.ok(tx.isActive()) + assert.equal(tx.isActive(), true) setTimeout(function () { - t.notOk(tx.isActive()) - t.end() + assert.equal(tx.isActive(), false) + end() }, 5) }) }) - t.test('should end the transaction based on a promise', function (t) { - messageHandler = function () { + await t.test('should end the transaction based on a promise', function (t, end) { + const { shim, wrapped } = t.nr + t.nr.messageHandler = function () { return new MessageSpec({ promise: true }) } wrapped('my.queue', function consumer() { const tx = shim.getSegment().transaction - t.ok(tx.isActive()) + assert.equal(tx.isActive(), true) return new Promise(function (resolve) { - t.ok(tx.isActive()) + assert.equal(tx.isActive(), true) setImmediate(resolve) }).then(function () { - t.ok(tx.isActive()) + assert.equal(tx.isActive(), true) setTimeout(function () { - t.notOk(tx.isActive()) - t.end() + assert.equal(tx.isActive(), false) + end() }, 5) }) }) }) - t.test('should properly time promise based consumers', function (t) { - messageHandler = function () { + await t.test('should properly time promise based consumers', function (t, end) { + const { shim, wrapped } = t.nr + t.nr.messageHandler = function () { return new MessageSpec({ promise: true }) } @@ -1017,76 +1005,82 @@ tap.test('MessageShim', function (t) { }).then(function () { setImmediate(() => { const duration = segment.getDurationInMillis() - t.ok(duration > DELAY - 1, 'promised based consumers should be timed properly') - t.end() + assert.ok(duration > DELAY - 1, 'promised based consumers should be timed properly') + end() }) }) }) }) - t.test('should end the transaction when the handle says to', function (t) { + await t.test('should end the transaction when the handle says to', function (t, end) { + const { agent, shim, wrapped } = t.nr const api = new API(agent) wrapped('my.queue', function consumer() { const tx = shim.getSegment().transaction const handle = api.getTransaction() - t.ok(tx.isActive()) + assert.equal(tx.isActive(), true) setTimeout(function () { - t.ok(tx.isActive()) + assert.equal(tx.isActive(), true) handle.end() setTimeout(function () { - t.notOk(tx.isActive()) - t.end() + assert.equal(tx.isActive(), false) + end() }, 5) }, 5) }) }) - t.test('should call spec.messageHandler before consumer is invoked', function (t) { + await t.test('should call spec.messageHandler before consumer is invoked', function (t, end) { + const { wrapped } = t.nr wrapped('my.queue', function consumer() { - t.ok(handlerCalled) - t.end() + assert.equal(t.nr.handlerCalled, true) + end() }) - t.notOk(handlerCalled) + assert.equal(t.nr.handlerCalled, false) }) - t.test('should add agent attributes (e.g. routing key)', function (t) { + await t.test('should add agent attributes (e.g. routing key)', function (t, end) { + const { shim, wrapped } = t.nr wrapped('my.queue', function consumer() { const segment = shim.getSegment() const tx = segment.transaction const traceParams = tx.trace.attributes.get(DESTINATIONS.TRANS_TRACE) - t.equal(traceParams['message.routingKey'], 'routing.key') - t.equal(traceParams['message.queueName'], 'my.queue') - t.end() + assert.equal(traceParams['message.routingKey'], 'routing.key') + assert.equal(traceParams['message.queueName'], 'my.queue') + end() }) }) - t.test('should add agent attributes (e.g. routing key) to Spans', function (t) { + await t.test('should add agent attributes (e.g. routing key) to Spans', function (t, end) { + const { shim, wrapped } = t.nr wrapped('my.queue', function consumer() { const segment = shim.getSegment() const spanParams = segment.attributes.get(DESTINATIONS.SPAN_EVENT) - t.equal(spanParams['message.routingKey'], 'routing.key') - t.equal(spanParams['message.queueName'], 'my.queue') - t.end() + assert.equal(spanParams['message.routingKey'], 'routing.key') + assert.equal(spanParams['message.queueName'], 'my.queue') + end() }) }) - t.test('should add message.paremeters.* attributes to Spans', function (t) { + await t.test('should add message.parameters.* attributes to Spans', function (t, end) { + const { shim, wrapped } = t.nr wrapped('my.queue', function consumer() { const segment = shim.getSegment() const spanParams = segment.attributes.get(DESTINATIONS.SPAN_EVENT) - t.equal(spanParams['message.parameters.a'], 'a') - t.equal(spanParams['message.parameters.b'], 'b') - t.end() + assert.equal(spanParams['message.parameters.a'], 'a') + assert.equal(spanParams['message.parameters.b'], 'b') + end() }) }) - t.test('should create message transaction metrics', function (t) { + await t.test('should create message transaction metrics', function (t, end) { + const { agent, wrapped } = t.nr const metricNames = [ 'OtherTransaction/Message/RabbitMQ/Exchange/Named/exchange.foo', 'OtherTransactionTotalTime/Message/RabbitMQ/Exchange/Named/exchange.foo', @@ -1099,14 +1093,15 @@ tap.test('MessageShim', function (t) { setTimeout(function () { const metrics = helper.getMetrics(agent) metricNames.forEach(function (name) { - t.equal(metrics.unscoped[name].callCount, 1) + assert.equal(metrics.unscoped[name].callCount, 1) }) - t.end() + end() }, 15) // Let tx end from instrumentation }) }) - t.test('should be able to get destinationName from arguments', function (t) { + await t.test('should be able to get destinationName from arguments', function (t, end) { + const { agent, shim, subscriber } = t.nr const metricNames = [ 'OtherTransaction/Message/RabbitMQ/Exchange/Named/my.exchange', 'OtherTransactionTotalTime/Message/RabbitMQ/Exchange/Named/my.exchange' @@ -1127,20 +1122,21 @@ tap.test('MessageShim', function (t) { setTimeout(function () { const metrics = helper.getMetrics(agent) metricNames.forEach(function (name) { - t.equal(metrics.unscoped[name].callCount, 1) + assert.equal(metrics.unscoped[name].callCount, 1) }) - t.end() + end() }, 15) // Let tx end from instrumentation }) }) - t.test('should handle a missing destination name as temp', function (t) { + await t.test('should handle a missing destination name as temp', function (t, end) { + const { agent, shim, wrapped } = t.nr const metricNames = [ 'OtherTransaction/Message/RabbitMQ/Exchange/Temp', 'OtherTransactionTotalTime/Message/RabbitMQ/Exchange/Temp' ] - messageHandler = function () { + t.nr.messageHandler = function () { return new MessageSpec({ destinationName: null, destinationType: shim.EXCHANGE @@ -1151,14 +1147,15 @@ tap.test('MessageShim', function (t) { setTimeout(function () { const metrics = helper.getMetrics(agent) metricNames.forEach(function (name) { - t.equal(metrics.unscoped[name].callCount, 1) + assert.equal(metrics.unscoped[name].callCount, 1) }) - t.end() + end() }, 15) // Let tx end from instrumentation }) }) - t.test('should extract CAT headers from the message', function (t) { + await t.test('should extract CAT headers from the message', function (t, end) { + const { agent, shim, wrapped } = t.nr agent.config.cross_application_tracer.enabled = true agent.config.distributed_tracing.enabled = false const params = { @@ -1173,7 +1170,7 @@ tap.test('MessageShim', function (t) { let txHeader = JSON.stringify(['trans id', false, 'trip id', 'path hash']) txHeader = hashes.obfuscateNameUsingKey(txHeader, agent.config.encoding_key) - messageHandler = function () { + t.nr.messageHandler = function () { const catHeaders = { NewRelicID: idHeader, NewRelicTransaction: txHeader @@ -1181,7 +1178,7 @@ tap.test('MessageShim', function (t) { return new MessageSpec({ destinationName: 'foo', - destingationType: shim.EXCHANGE, + destinationType: shim.EXCHANGE, headers: catHeaders }) } @@ -1189,59 +1186,64 @@ tap.test('MessageShim', function (t) { wrapped('my.queue', function consumer() { const tx = shim.getSegment().transaction - t.equal(tx.incomingCatId, '9876#id') - t.equal(tx.referringTransactionGuid, 'trans id') - t.equal(tx.tripId, 'trip id') - t.equal(tx.referringPathHash, 'path hash') - t.equal(tx.invalidIncomingExternalTransaction, false) - t.end() + assert.equal(tx.incomingCatId, '9876#id') + assert.equal(tx.referringTransactionGuid, 'trans id') + assert.equal(tx.tripId, 'trip id') + assert.equal(tx.referringPathHash, 'path hash') + assert.equal(tx.invalidIncomingExternalTransaction, false) + end() }) }) - t.test('should invoke the consumer with the correct arguments', function (t) { + await t.test('should invoke the consumer with the correct arguments', function (t, end) { + const { wrapped } = t.nr wrapped('my.queue', function consumer(msg) { - t.equal(msg, message) - t.end() + assert.equal(msg, t.nr.message) + end() }) }) - t.test('should create a subscribe segment', function (t) { + await t.test('should create a subscribe segment', function (t, end) { + const { agent, wrapped } = t.nr helper.runInTransaction(agent, function () { - t.notOk(subscriberCalled) + assert.equal(t.nr.subscriberCalled, false) const segment = wrapped('my.queue') - t.ok(subscriberCalled) - t.equal(segment.name, 'Channel#subscribe') - t.end() + assert.equal(t.nr.subscriberCalled, true) + assert.equal(segment.name, 'Channel#subscribe') + end() }) }) - t.test('should bind the subscribe callback', function (t) { + await t.test('should bind the subscribe callback', function (t, end) { + const { agent, shim, wrapped } = t.nr helper.runInTransaction(agent, function () { const parent = wrapped('my.queue', null, function subCb() { const segment = shim.getSegment() - t.equal(segment.name, 'Callback: subCb') - t.compareSegments(parent, [segment]) - t.end() + assert.equal(segment.name, 'Callback: subCb') + compareSegments(parent, [segment]) + end() }) - t.ok(parent) + assert.ok(parent) }) }) - t.test('should still start a new transaction in the consumer', function (t) { + await t.test('should still start a new transaction in the consumer', function (t, end) { + const { agent, shim, wrapped } = t.nr helper.runInTransaction(agent, function () { const parent = wrapped('my.queue', function consumer() { const segment = shim.getSegment() - t.not(segment.name, 'Callback: consumer') - t.ok(segment.transaction.id) - t.not(segment.transaction.id, parent.transaction.id) - t.end() + assert.notEqual(segment.name, 'Callback: consumer') + assert.ok(segment.transaction.id) + assert.notEqual(segment.transaction.id, parent.transaction.id) + end() }) - t.ok(parent) + assert.ok(parent) }) }) - t.test('should wrap object key of consumer', function (t) { - t.plan(4) + await t.test('should wrap object key of consumer', function (t, end) { + const plan = tspl(t, { plan: 4 }) + const { shim } = t.nr const message = { foo: 'bar' } const subscriber = function subscriber(consumer) { consumer.eachMessage(message) @@ -1251,7 +1253,7 @@ tap.test('MessageShim', function (t) { consumer: shim.FIRST, functions: ['eachMessage'], messageHandler: function (shim, args) { - t.same(args[0], message) + plan.deepEqual(args[0], message) return new MessageSpec({ destinationName: 'exchange.foo', destinationType: shim.EXCHANGE @@ -1261,11 +1263,11 @@ tap.test('MessageShim', function (t) { const handler = { eachMessage: function consumer(msg) { - t.same(this, handler) + plan.deepEqual(this, handler) const segment = shim.getSegment() - t.equal(segment.name, 'OtherTransaction/Message/RabbitMQ/Exchange/Named/exchange.foo') - t.equal(msg, message) - t.end() + plan.equal(segment.name, 'OtherTransaction/Message/RabbitMQ/Exchange/Named/exchange.foo') + plan.equal(msg, message) + end() } } wrapped(handler) diff --git a/test/unit/shim/promise-shim.test.js b/test/unit/shim/promise-shim.test.js index fbd16a90bd..a9d3d0e17b 100644 --- a/test/unit/shim/promise-shim.test.js +++ b/test/unit/shim/promise-shim.test.js @@ -4,183 +4,178 @@ */ 'use strict' -const tap = require('tap') - +const assert = require('node:assert') +const test = require('node:test') const helper = require('../../lib/agent_helper') const PromiseShim = require('../../../lib/shim/promise-shim') const Shim = require('../../../lib/shim/shim') -tap.Test.prototype.addAssert('sameTransaction', 2, function expectSameTransaction(tx1, tx2) { - this.ok(tx1, 'current transaction exists') - this.ok(tx2, 'active transaction exists') - this.equal(tx1.id, tx2.id, 'current transaction id should match active transaction id') -}) - -tap.test('PromiseShim', (t) => { - t.autoend() +function sameTransaction(tx1, tx2) { + assert.ok(tx1, 'current transaction exists') + assert.ok(tx2, 'active transaction exists') + assert.equal(tx1.id, tx2.id, 'current transaction id should match active transaction id') +} +test('PromiseShim', async (t) => { // ensure the test does not exist before all pending // runOutOfContext tasks are executed helper.outOfContextQueueInterval.ref() // unref the runOutOfContext interval // so other tests can run unencumbered - t.teardown(() => { + t.after(() => { helper.outOfContextQueueInterval.unref() }) - let agent = null - let shim = null - let TestPromise = null + function beforeTest(ctx) { + ctx.nr = {} + ctx.nr.TestPromise = require('./promise-shim')() - function beforeTest() { - TestPromise = require('./promise-shim')() - - agent = helper.loadMockedAgent() - shim = new PromiseShim(agent, 'test-promise', null) + const agent = helper.loadMockedAgent() + ctx.nr.shim = new PromiseShim(agent, 'test-promise', null) + ctx.nr.agent = agent } - function afterTest() { - helper.unloadAgent(agent) - agent = null - shim = null - TestPromise = null + function afterTest(ctx) { + helper.unloadAgent(ctx.nr.agent) } - t.test('constructor', (t) => { - t.autoend() + await t.test('constructor', async (t) => { t.beforeEach(beforeTest) t.afterEach(afterTest) - t.test('should inherit from Shim', (t) => { - t.ok(shim instanceof PromiseShim) - t.ok(shim instanceof Shim) - t.end() + await t.test('should inherit from Shim', (t) => { + const { shim } = t.nr + assert.ok(shim instanceof PromiseShim) + assert.ok(shim instanceof Shim) }) - t.test('should require the `agent` parameter', (t) => { - t.throws(() => new PromiseShim(), /^Shim must be initialized with .*? agent/) - t.end() + await t.test('should require the `agent` parameter', () => { + assert.throws( + () => new PromiseShim(), + 'Error: Shim must be initialized with agent and module name' + ) }) - t.test('should require the `moduleName` parameter', (t) => { - t.throws(() => new PromiseShim(agent), /^Shim must be initialized with .*? module name/) - t.end() + await t.test('should require the `moduleName` parameter', (t) => { + const { agent } = t.nr + assert.throws( + () => new PromiseShim(agent), + 'Error: Shim must be initialized with agent and module name' + ) }) - t.test('should assign properties from parent', (t) => { + await t.test('should assign properties from parent', (t) => { + const { agent } = t.nr const mod = 'test-mod' const name = mod const version = '1.0.0' const shim = new PromiseShim(agent, mod, mod, name, version) - t.equal(shim.moduleName, mod) - t.equal(agent, shim._agent) - t.equal(shim.pkgVersion, version) - t.end() + assert.equal(shim.moduleName, mod) + assert.equal(agent, shim._agent) + assert.equal(shim.pkgVersion, version) }) }) - t.test('.Contextualizer', (t) => { - t.autoend() + await t.test('.Contextualizer', async (t) => { t.beforeEach(beforeTest) t.afterEach(afterTest) - t.test('should be the underlying contextualization class', (t) => { - t.ok(PromiseShim.Contextualizer) - t.ok(PromiseShim.Contextualizer instanceof Function) - t.end() + await t.test('should be the underlying contextualization class', () => { + assert.ok(PromiseShim.Contextualizer) + assert.ok(PromiseShim.Contextualizer instanceof Function) }) }) - t.test('#logger', (t) => { - t.autoend() + await t.test('#logger', async (t) => { t.beforeEach(beforeTest) t.afterEach(afterTest) - t.test('should be a non-writable property', (t) => { - t.throws(() => (shim.logger = 'foobar')) - t.not(shim.logger, 'foobar') - t.end() - }) - - t.test('should have expected log levels', (t) => { - t.ok(shim.logger.trace) - t.ok(shim.logger.trace instanceof Function) - t.ok(shim.logger.debug) - t.ok(shim.logger.debug instanceof Function) - t.ok(shim.logger.info) - t.ok(shim.logger.info instanceof Function) - t.ok(shim.logger.warn) - t.ok(shim.logger.warn instanceof Function) - t.ok(shim.logger.error) - t.ok(shim.logger.error instanceof Function) - t.end() + await t.test('should be a non-writable property', (t) => { + const { shim } = t.nr + assert.throws(() => (shim.logger = 'foobar')) + assert.notStrictEqual(shim.logger, 'foobar') + }) + + await t.test('should have expected log levels', (t) => { + const { shim } = t.nr + assert.ok(shim.logger.trace) + assert.ok(shim.logger.trace instanceof Function) + assert.ok(shim.logger.debug) + assert.ok(shim.logger.debug instanceof Function) + assert.ok(shim.logger.info) + assert.ok(shim.logger.info instanceof Function) + assert.ok(shim.logger.warn) + assert.ok(shim.logger.warn instanceof Function) + assert.ok(shim.logger.error) + assert.ok(shim.logger.error instanceof Function) }) }) - t.test('#setClass', (t) => { - t.autoend() + await t.test('#setClass', async (t) => { t.beforeEach(beforeTest) t.afterEach(afterTest) - t.test('should set the class used for instance checks', (t) => { + await t.test('should set the class used for instance checks', (t) => { + const { shim, TestPromise } = t.nr const p = new TestPromise(() => {}) - t.notOk(shim.isPromiseInstance(p)) + assert.equal(shim.isPromiseInstance(p), false) shim.setClass(TestPromise) - t.ok(shim.isPromiseInstance(p)) - t.end() + assert.equal(shim.isPromiseInstance(p), true) }) - t.test('should detect if an object is an instance of the instrumented class', (t) => { + await t.test('should detect if an object is an instance of the instrumented class', (t) => { + const { shim, TestPromise } = t.nr shim.setClass(TestPromise) - t.notOk(shim.isPromiseInstance(TestPromise)) - t.ok(shim.isPromiseInstance(new TestPromise(() => {}))) - t.notOk(shim.isPromiseInstance(new Promise(() => {}))) - t.notOk(shim.isPromiseInstance({})) - t.end() + assert.ok(!shim.isPromiseInstance(TestPromise)) + assert.equal(shim.isPromiseInstance(new TestPromise(() => {})), true) + assert.ok(!shim.isPromiseInstance(new Promise(() => {}))) + assert.ok(!shim.isPromiseInstance({})) }) }) - t.test('#wrapConstructor', (t) => { - t.autoend() + await t.test('#wrapConstructor', async (t) => { t.beforeEach(beforeTest) t.afterEach(afterTest) - t.test('should accept just a class constructor', (t) => { + await t.test('should accept just a class constructor', async (t) => { + const { shim, TestPromise } = t.nr const WrappedPromise = shim.wrapConstructor(TestPromise) - t.not(WrappedPromise, TestPromise) - t.ok(shim.isWrapped(WrappedPromise)) + assert.notEqual(WrappedPromise, TestPromise) + assert.equal(shim.isWrapped(WrappedPromise), true) const p = new WrappedPromise((resolve, reject) => { - t.equal(typeof resolve, 'function') - t.equal(typeof reject, 'function') + assert.equal(typeof resolve, 'function') + assert.equal(typeof reject, 'function') resolve() }) - t.ok(p instanceof WrappedPromise, 'instance of wrapped promise') - t.ok(p instanceof TestPromise, 'instance of test promise') + assert.ok(p instanceof WrappedPromise, 'instance of wrapped promise') + assert.ok(p instanceof TestPromise, 'instance of test promise') return p }) - t.test('should accept a nodule and property', (t) => { + await t.test('should accept a nodule and property', async (t) => { + const { shim, TestPromise } = t.nr const testing = { TestPromise } shim.wrapConstructor(testing, 'TestPromise') - t.ok(testing.TestPromise) - t.not(testing.TestPromise, TestPromise) - t.ok(shim.isWrapped(testing.TestPromise)) + assert.ok(testing.TestPromise) + assert.notEqual(testing.TestPromise, TestPromise) + assert.equal(shim.isWrapped(testing.TestPromise), true) const p = new testing.TestPromise((resolve, reject) => { - t.equal(typeof resolve, 'function') - t.equal(typeof reject, 'function') + assert.equal(typeof resolve, 'function') + assert.equal(typeof reject, 'function') resolve() }) - t.ok(p instanceof testing.TestPromise) - t.ok(p instanceof TestPromise) + assert.ok(p instanceof testing.TestPromise) + assert.ok(p instanceof TestPromise) return p }) - t.test('should execute the executor', (t) => { + await t.test('should execute the executor', async (t) => { + const { agent, shim, TestPromise } = t.nr return helper.runInTransaction(agent, () => { let executed = false @@ -190,13 +185,14 @@ tap.test('PromiseShim', (t) => { resolve() }) - t.ok(executed) + assert.equal(executed, true) return p }) }) - t.test('should not change resolve values', (t) => { + await t.test('should not change resolve values', (t, end) => { + const { agent, shim, TestPromise } = t.nr helper.runInTransaction(agent, () => { const resolution = {} @@ -206,13 +202,14 @@ tap.test('PromiseShim', (t) => { }) p.then((val) => { - t.equal(val, resolution) - t.end() + assert.equal(val, resolution) + end() }) }) }) - t.test('should not change reject values', (t) => { + await t.test('should not change reject values', (t, end) => { + const { agent, shim, TestPromise } = t.nr helper.runInTransaction(agent, () => { const rejection = {} @@ -222,33 +219,35 @@ tap.test('PromiseShim', (t) => { }) p.catch((val) => { - t.equal(val, rejection) - t.end() + assert.equal(val, rejection) + end() }) }) }) - t.test('should capture errors thrown in the executor', (t) => { + await t.test('should capture errors thrown in the executor', (t, end) => { + const { agent, shim, TestPromise } = t.nr helper.runInTransaction(agent, () => { const WrappedPromise = shim.wrapConstructor(TestPromise) let p = null - t.doesNotThrow(() => { + assert.doesNotThrow(() => { p = new WrappedPromise(() => { throw new Error('this should be caught') }) }) p.catch((err) => { - t.ok(err instanceof Error) - t.ok(err.message) - t.end() + assert.ok(err instanceof Error) + assert.ok(err.message) + end() }) }) }) - t.test('should reinstate lost context', async (t) => { - t.autoend() + await t.test('should reinstate lost context', async (t) => { + const { agent, shim, TestPromise } = t.nr + helper.runInTransaction(agent, async (tx) => { shim.setClass(TestPromise) const WrappedPromise = shim.wrapConstructor(TestPromise) @@ -258,9 +257,9 @@ tap.test('PromiseShim', (t) => { shim.wrapThen(TestPromise.prototype, 'then') const txTest = async (runOutOfContext, runNext) => { - t.sameTransaction(agent.getTransaction(), tx) + sameTransaction(agent.getTransaction(), tx) return new WrappedPromise((resolve) => { - t.sameTransaction(agent.getTransaction(), tx) + sameTransaction(agent.getTransaction(), tx) if (runOutOfContext) { helper.runOutOfContext(resolve) // <-- Context loss before resolve. } else { @@ -268,13 +267,13 @@ tap.test('PromiseShim', (t) => { } }) .then(() => { - t.sameTransaction(agent.getTransaction(), tx) + sameTransaction(agent.getTransaction(), tx) if (runNext) { return runNext() // < a cheap way of chaining these without async } }) .catch((err) => { - t.notOk(err, 'Promise context restore should not error.') + assert.ok(!err, 'Promise context restore should not error.') }) } @@ -283,42 +282,44 @@ tap.test('PromiseShim', (t) => { }) }) - t.test('#wrapExecutorCaller', (t) => { - t.autoend() + await t.test('#wrapExecutorCaller', async (t) => { t.beforeEach(beforeTest) t.afterEach(afterTest) - t.test('should accept just a function', (t) => { + await t.test('should accept just a function', (t) => { + const { shim, TestPromise } = t.nr const wrappedCaller = shim.wrapExecutorCaller(TestPromise.prototype.executorCaller) - t.not(wrappedCaller, TestPromise.prototype.executorCaller) - t.ok(shim.isWrapped(wrappedCaller)) + assert.notEqual(wrappedCaller, TestPromise.prototype.executorCaller) + assert.equal(shim.isWrapped(wrappedCaller), true) TestPromise.prototype.executorCaller = wrappedCaller const p = new TestPromise((resolve, reject) => { - t.equal(typeof resolve, 'function') - t.equal(typeof reject, 'function') + assert.equal(typeof resolve, 'function') + assert.equal(typeof reject, 'function') resolve() }) - t.ok(p instanceof TestPromise) + assert.ok(p instanceof TestPromise) return p }) - t.test('should accept a nodule and property', (t) => { + await t.test('should accept a nodule and property', (t) => { + const { shim, TestPromise } = t.nr shim.wrapExecutorCaller(TestPromise.prototype, 'executorCaller') - t.ok(shim.isWrapped(TestPromise.prototype.executorCaller)) + assert.equal(shim.isWrapped(TestPromise.prototype.executorCaller), true) const p = new TestPromise((resolve, reject) => { - t.equal(typeof resolve, 'function') - t.equal(typeof reject, 'function') + assert.equal(typeof resolve, 'function') + assert.equal(typeof reject, 'function') resolve() }) - t.ok(p instanceof TestPromise) + assert.ok(p instanceof TestPromise) return p }) - t.test('should execute the executor', (t) => { + await t.test('should execute the executor', (t) => { + const { agent, shim, TestPromise } = t.nr return helper.runInTransaction(agent, () => { let executed = false @@ -328,12 +329,13 @@ tap.test('PromiseShim', (t) => { resolve() }) - t.ok(executed) + assert.equal(executed, true) return p }) }) - t.test('should not change resolve values', (t) => { + await t.test('should not change resolve values', (t, end) => { + const { agent, shim, TestPromise } = t.nr helper.runInTransaction(agent, () => { const resolution = {} @@ -343,13 +345,14 @@ tap.test('PromiseShim', (t) => { }) p.then((val) => { - t.equal(val, resolution) - t.end() + assert.equal(val, resolution) + end() }) }) }) - t.test('should not change reject values', (t) => { + await t.test('should not change reject values', (t, end) => { + const { agent, shim, TestPromise } = t.nr helper.runInTransaction(agent, () => { const rejection = {} @@ -359,32 +362,34 @@ tap.test('PromiseShim', (t) => { }) p.catch((val) => { - t.equal(val, rejection) - t.end() + assert.equal(val, rejection) + end() }) }) }) - t.test('should capture errors thrown in the executor', (t) => { + await t.test('should capture errors thrown in the executor', (t, end) => { + const { agent, shim, TestPromise } = t.nr helper.runInTransaction(agent, () => { shim.wrapExecutorCaller(TestPromise.prototype, 'executorCaller') let p = null - t.doesNotThrow(() => { + assert.doesNotThrow(() => { p = new TestPromise(() => { throw new Error('this should be caught') }) }) p.catch((err) => { - t.ok(err instanceof Error) - t.ok(err.message) - t.end() + assert.ok(err instanceof Error) + assert.ok(err.message) + end() }) }) }) - t.test('should reinstate lost context', (t) => { + await t.test('should reinstate lost context', (t, end) => { + const { agent, shim, TestPromise } = t.nr helper.runInTransaction(agent, async (tx) => { shim.setClass(TestPromise) shim.wrapExecutorCaller(TestPromise.prototype, 'executorCaller') @@ -394,23 +399,23 @@ tap.test('PromiseShim', (t) => { shim.wrapThen(TestPromise.prototype, 'then') const txTest = async (runOutOfContext, runNext) => { - t.sameTransaction(agent.getTransaction(), tx) + sameTransaction(agent.getTransaction(), tx) return new TestPromise((resolve) => { - t.sameTransaction(agent.getTransaction(), tx) + sameTransaction(agent.getTransaction(), tx) if (runOutOfContext) { return helper.runOutOfContext(resolve) // <-- Context loss before resolve. } return resolve() // <-- Resolve will lose context. }) .then(() => { - t.sameTransaction(agent.getTransaction(), tx) + sameTransaction(agent.getTransaction(), tx) if (runNext) { return runNext() } - t.end() + end() }) .catch((err) => { - t.notOk(err, 'Promise context restore should not error.') + assert.ok(!err, 'Promise context restore should not error.') }) } txTest(false, () => txTest(true)) @@ -418,99 +423,104 @@ tap.test('PromiseShim', (t) => { }) }) - t.test('#wrapCast', (t) => { - t.autoend() + await t.test('#wrapCast', async (t) => { t.beforeEach(beforeTest) t.afterEach(afterTest) - t.test('should accept just a function', (t) => { + await t.test('should accept just a function', (t, end) => { + const { shim, TestPromise } = t.nr const wrappedResolve = shim.wrapCast(TestPromise.resolve) - t.equal(typeof wrappedResolve, 'function') - t.not(wrappedResolve, TestPromise.resolve) - t.ok(shim.isWrapped(wrappedResolve)) + assert.ok(typeof wrappedResolve, 'function') + assert.notEqual(wrappedResolve, TestPromise.resolve) + assert.equal(shim.isWrapped(wrappedResolve), true) const p = wrappedResolve('foo') - t.ok(p instanceof TestPromise) + assert.ok(p instanceof TestPromise) p.then((val) => { - t.equal(val, 'foo') - t.end() + assert.equal(val, 'foo') + end() }) }) - t.test('should accept a nodule and property', (t) => { + await t.test('should accept a nodule and property', (t, end) => { + const { shim, TestPromise } = t.nr shim.wrapCast(TestPromise, 'resolve') - t.equal(typeof TestPromise.resolve, 'function') - t.ok(shim.isWrapped(TestPromise.resolve)) + assert.equal(typeof TestPromise.resolve, 'function') + assert.equal(shim.isWrapped(TestPromise.resolve), true) const p = TestPromise.resolve('foo') - t.ok(p instanceof TestPromise) + assert.ok(p instanceof TestPromise) p.then((val) => { - t.equal(val, 'foo') - t.end() + assert.equal(val, 'foo') + end() }) }) - t.test('should link context through to thenned callbacks', (t) => { + await t.test('should link context through to thenned callbacks', (t, end) => { + const { agent, shim, TestPromise } = t.nr shim.setClass(TestPromise) shim.wrapCast(TestPromise, 'resolve') shim.wrapThen(TestPromise.prototype, 'then') helper.runInTransaction(agent, (tx) => { TestPromise.resolve().then(() => { - t.sameTransaction(agent.getTransaction(), tx) - t.end() + sameTransaction(agent.getTransaction(), tx) + end() }) }) }) }) - t.test('#wrapThen', (t) => { - t.autoend() + await t.test('#wrapThen', async (t) => { t.beforeEach(beforeTest) t.afterEach(afterTest) - t.test('should accept just a function', (t) => { + await t.test('should accept just a function', (t, end) => { + const { shim, TestPromise } = t.nr shim.setClass(TestPromise) const wrappedThen = shim.wrapThen(TestPromise.prototype.then) - t.equal(typeof wrappedThen, 'function') - t.not(wrappedThen, TestPromise.prototype.then) - t.ok(shim.isWrapped(wrappedThen)) + assert.equal(typeof wrappedThen, 'function') + assert.notEqual(wrappedThen, TestPromise.prototype.then) + assert.equal(shim.isWrapped(wrappedThen), true) const p = TestPromise.resolve('foo') - t.ok(p instanceof TestPromise) + assert.ok(p instanceof TestPromise) wrappedThen.call(p, (val) => { - t.equal(val, 'foo') - t.end() + assert.equal(val, 'foo') + end() }) }) - t.test('should accept a nodule and property', (t) => { + await t.test('should accept a nodule and property', (t, end) => { + const { shim, TestPromise } = t.nr shim.setClass(TestPromise) shim.wrapThen(TestPromise.prototype, 'then') - t.equal(typeof TestPromise.prototype.then, 'function') - t.ok(shim.isWrapped(TestPromise.prototype.then)) + assert.equal(typeof TestPromise.prototype.then, 'function') + assert.equal(shim.isWrapped(TestPromise.prototype.then), true) const p = TestPromise.resolve('foo') - t.ok(p instanceof TestPromise) + assert.ok(p instanceof TestPromise) p.then((val) => { - t.equal(val, 'foo') - t.end() + assert.equal(val, 'foo') + end() }) }) - t.test('should link context through to thenned callbacks', (t) => { + await t.test('should link context through to thenned callbacks', (t, end) => { + const { agent, shim, TestPromise } = t.nr shim.setClass(TestPromise) shim.wrapThen(TestPromise.prototype, 'then') helper.runInTransaction(agent, (tx) => { TestPromise.resolve().then(() => { - t.sameTransaction(agent.getTransaction(), tx) - t.end() + sameTransaction(agent.getTransaction(), tx) + end() }) }) }) - t.test('should wrap both handlers', (t) => { + await t.test('should wrap both handlers', (t) => { + const { shim, TestPromise } = t.nr shim.setClass(TestPromise) shim.wrapThen(TestPromise.prototype, 'then') function resolve() {} @@ -519,61 +529,63 @@ tap.test('PromiseShim', (t) => { const p = TestPromise.resolve() p.then(resolve, reject) - t.equal(typeof p.res, 'function') - t.not(p.res, resolve) - t.equal(typeof p.rej, 'function') - t.not(p.rej, reject) - t.end() + assert.equal(typeof p.res, 'function') + assert.notEqual(p.res, resolve) + assert.equal(typeof p.rej, 'function') + assert.notEqual(p.rej, reject) }) }) - t.test('#wrapCatch', (t) => { - t.autoend() + await t.test('#wrapCatch', async (t) => { t.beforeEach(beforeTest) t.afterEach(afterTest) - t.test('should accept just a function', (t) => { + await t.test('should accept just a function', (t, end) => { + const { shim, TestPromise } = t.nr shim.setClass(TestPromise) const wrappedCatch = shim.wrapCatch(TestPromise.prototype.catch) - t.equal(typeof wrappedCatch, 'function') - t.not(wrappedCatch, TestPromise.prototype.catch) - t.ok(shim.isWrapped(wrappedCatch)) + assert.equal(typeof wrappedCatch, 'function') + assert.notEqual(wrappedCatch, TestPromise.prototype.catch) + assert.equal(shim.isWrapped(wrappedCatch), true) const p = TestPromise.reject('foo') - t.ok(p instanceof TestPromise) + assert.ok(p instanceof TestPromise) wrappedCatch.call(p, (val) => { - t.equal(val, 'foo') - t.end() + assert.equal(val, 'foo') + end() }) }) - t.test('should accept a nodule and property', (t) => { + await t.test('should accept a nodule and property', (t, end) => { + const { shim, TestPromise } = t.nr shim.setClass(TestPromise) shim.wrapCatch(TestPromise.prototype, 'catch') - t.equal(typeof TestPromise.prototype.catch, 'function') - t.ok(shim.isWrapped(TestPromise.prototype.catch)) + assert.equal(typeof TestPromise.prototype.catch, 'function') + assert.equal(shim.isWrapped(TestPromise.prototype.catch), true) const p = TestPromise.reject('foo') - t.ok(p instanceof TestPromise) + assert.ok(p instanceof TestPromise) p.catch((val) => { - t.equal(val, 'foo') - t.end() + assert.equal(val, 'foo') + end() }) }) - t.test('should link context through to thenned callbacks', (t) => { + await t.test('should link context through to thenned callbacks', (t, end) => { + const { agent, shim, TestPromise } = t.nr shim.setClass(TestPromise) shim.wrapCatch(TestPromise.prototype, 'catch') helper.runInTransaction(agent, (tx) => { TestPromise.reject().catch(() => { - t.sameTransaction(agent.getTransaction(), tx) - t.end() + sameTransaction(agent.getTransaction(), tx) + end() }) }) }) - t.test('should only wrap the rejection handler', (t) => { + await t.test('should only wrap the rejection handler', (t) => { + const { shim, TestPromise } = t.nr shim.setClass(TestPromise) shim.wrapCatch(TestPromise.prototype, 'catch') @@ -581,19 +593,16 @@ tap.test('PromiseShim', (t) => { function reject() {} p.catch(Error, reject) - t.ok(p.ErrorClass) - t.equal(typeof p.rej, 'function') - t.not(p.rej, reject) - t.end() + assert.ok(p.ErrorClass) + assert.equal(typeof p.rej, 'function') + assert.notEqual(p.rej, reject) }) }) - t.test('#wrapPromisify', (t) => { - t.autoend() - let asyncFn = null - t.beforeEach(() => { - beforeTest() - asyncFn = (val, cb) => { + await t.test('#wrapPromisify', async (t) => { + t.beforeEach((ctx) => { + beforeTest(ctx) + ctx.nr.asyncFn = (val, cb) => { helper.runOutOfContext(() => { if (val instanceof Error) { cb(val) @@ -606,30 +615,31 @@ tap.test('PromiseShim', (t) => { t.afterEach(afterTest) - t.test('should accept just a function', (t) => { + await t.test('should accept just a function', (t) => { + const { asyncFn, shim, TestPromise } = t.nr const wrappedPromisify = shim.wrapPromisify(TestPromise.promisify) - t.equal(typeof wrappedPromisify, 'function') - t.not(wrappedPromisify, TestPromise.promisify) - t.ok(shim.isWrapped(wrappedPromisify)) + assert.equal(typeof wrappedPromisify, 'function') + assert.notEqual(wrappedPromisify, TestPromise.promisify) + assert.equal(shim.isWrapped(wrappedPromisify), true) const promised = wrappedPromisify(shim, asyncFn) - t.equal(typeof promised, 'function') - t.not(promised, asyncFn) - t.end() + assert.equal(typeof promised, 'function') + assert.notEqual(promised, asyncFn) }) - t.test('should accept a nodule and property', (t) => { + await t.test('should accept a nodule and property', (t) => { + const { asyncFn, shim, TestPromise } = t.nr shim.wrapPromisify(TestPromise, 'promisify') - t.equal(typeof TestPromise.promisify, 'function') - t.ok(shim.isWrapped(TestPromise.promisify)) + assert.equal(typeof TestPromise.promisify, 'function') + assert.equal(shim.isWrapped(TestPromise.promisify), true) const promised = TestPromise.promisify(shim, asyncFn) - t.equal(typeof promised, 'function') - t.not(promised, asyncFn) - t.end() + assert.equal(typeof promised, 'function') + assert.notEqual(promised, asyncFn) }) - t.test('should propagate transaction context', (t) => { + await t.test('should propagate transaction context', (t, end) => { + const { agent, asyncFn, shim, TestPromise } = t.nr shim.setClass(TestPromise) shim.wrapPromisify(TestPromise, 'promisify') shim.wrapThen(TestPromise.prototype, 'then') @@ -638,9 +648,9 @@ tap.test('PromiseShim', (t) => { helper.runInTransaction(agent, (tx) => { promised('foobar').then((val) => { - t.sameTransaction(agent.getTransaction(), tx) - t.equal(val, 'foobar') - t.end() + sameTransaction(agent.getTransaction(), tx) + assert.equal(val, 'foobar') + end() }) }) }) diff --git a/test/unit/shim/shim.test.js b/test/unit/shim/shim.test.js index 226bf507f7..0e50498b9f 100644 --- a/test/unit/shim/shim.test.js +++ b/test/unit/shim/shim.test.js @@ -4,26 +4,30 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') const { EventEmitter } = require('events') const helper = require('../../lib/agent_helper') const Shim = require('../../../lib/shim/shim') const symbols = require('../../../lib/symbols') const { RecorderSpec } = require('../../../lib/shim/specs') - -tap.test('Shim', function (t) { - t.autoend() - let agent = null - let contextManager = null - let shim = null - let wrappable = null - - function beforeEach() { - agent = helper.loadMockedAgent() - contextManager = helper.getContextManager() - shim = new Shim(agent, 'test-module') - wrappable = { +const { + checkWrappedCb, + checkNotWrappedCb, + compareSegments, + isNonWritable +} = require('../../lib/custom-assertions') +const promiseResolvers = require('../../lib/promise-resolvers') +const { tspl } = require('@matteo.collina/tspl') +const tempOverrideUncaught = require('../../lib/temp-override-uncaught') + +test('Shim', async function (t) { + function beforeEach(ctx) { + ctx.nr = {} + const agent = helper.loadMockedAgent() + ctx.nr.contextManager = helper.getContextManager() + ctx.nr.shim = new Shim(agent, 'test-module') + ctx.nr.wrappable = { name: 'this is a name', bar: function barsName(unused, params) { return 'bar' }, // eslint-disable-line fiz: function fizsName() { @@ -31,73 +35,57 @@ tap.test('Shim', function (t) { }, anony: function () {}, getActiveSegment: function () { - return contextManager.getContext() + return ctx.nr.contextManager.getContext() } } + ctx.nr.agent = agent } - function afterEach() { - helper.unloadAgent(agent) - agent = null - contextManager = null - shim = null - } - - /** - * Helper that verifies the original callback - * and wrapped callback are the same - */ - function checkNotWrapped(cb, wrappedCB) { - this.equal(wrappedCB, cb) - this.notOk(shim.isWrapped(wrappedCB)) - this.end() + function afterEach(ctx) { + helper.unloadAgent(ctx.nr.agent) } - t.test('constructor', function (t) { - t.autoend() + await t.test('constructor', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should require an agent parameter', function (t) { - t.throws(function () { + await t.test('should require an agent parameter', function () { + assert.throws(function () { return new Shim() }) - t.end() }) - t.test('should require a module name parameter', function (t) { - t.throws(function () { + await t.test('should require a module name parameter', function (t) { + const { agent } = t.nr + assert.throws(function () { return new Shim(agent) }) - t.end() }) - t.test('should assign properties from parent', (t) => { + await t.test('should assign properties from parent', (t) => { + const { agent } = t.nr const mod = 'test-mod' const name = mod const version = '1.0.0' const shim = new Shim(agent, mod, mod, name, version) - t.equal(shim.moduleName, mod) - t.equal(agent, shim._agent) - t.equal(shim.pkgVersion, version) - t.end() + assert.equal(shim.moduleName, mod) + assert.equal(agent, shim._agent) + assert.equal(shim.pkgVersion, version) }) }) - t.test('.defineProperty', function (t) { - t.autoend() + await t.test('.defineProperty', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should create a non-writable property', function (t) { + await t.test('should create a non-writable property', function () { const foo = {} Shim.defineProperty(foo, 'bar', 'foobar') - t.equal(foo.bar, 'foobar') - t.isNonWritable({ obj: foo, key: 'bar', value: 'foobar' }) - t.end() + assert.equal(foo.bar, 'foobar') + isNonWritable({ obj: foo, key: 'bar', value: 'foobar' }) }) - t.test('should create a getter', function (t) { + await t.test('should create a getter', function () { const foo = {} let getterCalled = false Shim.defineProperty(foo, 'bar', function () { @@ -105,19 +93,17 @@ tap.test('Shim', function (t) { return 'foobar' }) - t.notOk(getterCalled) - t.equal(foo.bar, 'foobar') - t.ok(getterCalled) - t.end() + assert.equal(getterCalled, false) + assert.equal(foo.bar, 'foobar') + assert.equal(getterCalled, true) }) }) - t.test('.defineProperties', function (t) { - t.autoend() + await t.test('.defineProperties', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should create all the properties specified', function (t) { + await t.test('should create all the properties specified', function () { const foo = {} Shim.defineProperties(foo, { bar: 'foobar', @@ -126,118 +112,113 @@ tap.test('Shim', function (t) { } }) - t.same(Object.keys(foo), ['bar', 'fiz']) - t.end() + assert.deepEqual(Object.keys(foo), ['bar', 'fiz']) }) }) - t.test('#FIRST through #LAST', function (t) { - t.autoend() + await t.test('#FIRST through #LAST', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) const keys = ['FIRST', 'SECOND', 'THIRD', 'FOURTH', 'LAST'] - keys.forEach((key, i) => { - t.test(`${key} should be a non-writable property`, function (t) { - t.isNonWritable({ obj: shim, key }) - t.end() + let i = 0 + for (const key of keys) { + await t.test(`${key} should be a non-writable property`, function (t) { + const { shim } = t.nr + isNonWritable({ obj: shim, key }) }) - t.test(`${key} should be an array index value`, function (t) { - t.equal(shim[key], key === 'LAST' ? -1 : i) - t.end() + await t.test(`${key} should be an array index value`, function (t) { + const { shim } = t.nr + assert.equal(shim[key], key === 'LAST' ? -1 : i) }) - }) + i++ + } }) - t.test('#agent', function (t) { - t.autoend() + await t.test('#agent', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should be a non-writable property', function (t) { - t.isNonWritable({ obj: shim, key: 'agent', value: agent }) - t.end() + await t.test('should be a non-writable property', function (t) { + const { agent, shim } = t.nr + isNonWritable({ obj: shim, key: 'agent', value: agent }) }) - t.test('should be the agent handed to the constructor', function (t) { + await t.test('should be the agent handed to the constructor', function () { const foo = {} const s = new Shim(foo, 'test-module') - t.equal(s.agent, foo) - t.end() + assert.equal(s.agent, foo) }) }) - t.test('#tracer', function (t) { - t.autoend() + await t.test('#tracer', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should be a non-writable property', function (t) { - t.isNonWritable({ obj: shim, key: 'tracer', value: agent.tracer }) - t.end() + await t.test('should be a non-writable property', function (t) { + const { agent, shim } = t.nr + isNonWritable({ obj: shim, key: 'tracer', value: agent.tracer }) }) - t.test('should be the tracer from the agent', function (t) { + await t.test('should be the tracer from the agent', function () { const foo = { tracer: {} } const s = new Shim(foo, 'test-module') - t.equal(s.tracer, foo.tracer) - t.end() + assert.equal(s.tracer, foo.tracer) }) }) - t.test('#moduleName', function (t) { - t.autoend() + await t.test('#moduleName', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should be a non-writable property', function (t) { - t.isNonWritable({ obj: shim, key: 'moduleName', value: 'test-module' }) - t.end() + await t.test('should be a non-writable property', function (t) { + const { shim } = t.nr + isNonWritable({ obj: shim, key: 'moduleName', value: 'test-module' }) }) - t.test('should be the name handed to the constructor', function (t) { + await t.test('should be the name handed to the constructor', function (t) { + const { agent } = t.nr const s = new Shim(agent, 'some-module-name') - t.equal(s.moduleName, 'some-module-name') - t.end() + assert.equal(s.moduleName, 'some-module-name') }) }) - t.test('#logger', function (t) { - t.autoend() + await t.test('#logger', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should be a non-writable property', function (t) { - t.isNonWritable({ obj: shim, key: 'logger' }) - t.end() + await t.test('should be a non-writable property', function (t) { + const { shim } = t.nr + isNonWritable({ obj: shim, key: 'logger' }) }) - t.test('should be a logger to use with the shim', function (t) { - t.ok(shim.logger.trace instanceof Function) - t.ok(shim.logger.debug instanceof Function) - t.ok(shim.logger.info instanceof Function) - t.ok(shim.logger.warn instanceof Function) - t.ok(shim.logger.error instanceof Function) - t.end() + await t.test('should be a logger to use with the shim', function (t) { + const { shim } = t.nr + assert.ok(shim.logger.trace instanceof Function) + assert.ok(shim.logger.debug instanceof Function) + assert.ok(shim.logger.info instanceof Function) + assert.ok(shim.logger.warn instanceof Function) + assert.ok(shim.logger.error instanceof Function) }) }) - t.test('#wrap', function (t) { - t.autoend() + await t.test('#wrap', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should call the spec with the to-be-wrapped item', function (t) { + await t.test('should call the spec with the to-be-wrapped item', function (t, end) { + const { shim, wrappable } = t.nr shim.wrap(wrappable, function (_shim, toWrap, name) { - t.equal(_shim, shim) - t.equal(toWrap, wrappable) - t.equal(name, wrappable.name) - t.end() + assert.equal(_shim, shim) + assert.equal(toWrap, wrappable) + assert.equal(name, wrappable.name) + end() }) }) - t.test('should match the arity and name of the original when specified', function (t) { + await t.test('should match the arity and name of the original when specified', function (t) { + const { shim } = t.nr // eslint-disable-next-line no-unused-vars function toWrap(a, b) {} const wrapped = shim.wrap(toWrap, { @@ -246,150 +227,142 @@ tap.test('Shim', function (t) { }, matchArity: true }) - t.not(wrapped, toWrap) - t.equal(wrapped.length, toWrap.length) - t.equal(wrapped.name, toWrap.name) - t.end() + assert.notEqual(wrapped, toWrap) + assert.equal(wrapped.length, toWrap.length) + assert.equal(wrapped.name, toWrap.name) }) - t.test('should pass items in the `args` parameter to the spec', function (t) { + await t.test('should pass items in the `args` parameter to the spec', function (t, end) { /* eslint-disable max-params */ + const { shim, wrappable } = t.nr shim.wrap( wrappable, function (_shim, toWrap, name, arg1, arg2, arg3) { - t.equal(arguments.length, 6) - t.equal(arg1, 'a') - t.equal(arg2, 'b') - t.equal(arg3, 'c') - t.end() + assert.equal(arguments.length, 6) + assert.equal(arg1, 'a') + assert.equal(arg2, 'b') + assert.equal(arg3, 'c') + end() }, ['a', 'b', 'c'] ) /* eslint-enable max-params */ }) - t.test('should wrap the first parameter', function (t) { + await t.test('should wrap the first parameter', function (t, end) { + const { shim, wrappable } = t.nr shim.wrap(wrappable, function (_, toWrap) { - t.equal(toWrap, wrappable) - t.end() + assert.equal(toWrap, wrappable) + end() }) }) - t.test('should wrap the first parameter when properties is `null`', function (t) { + await t.test('should wrap the first parameter when properties is `null`', function (t, end) { + const { shim, wrappable } = t.nr shim.wrap(wrappable, null, function (_, toWrap) { - t.equal(toWrap, wrappable) - t.end() + assert.equal(toWrap, wrappable) + end() }) }) - t.test('should mark the first parameter as wrapped', function (t) { + await t.test('should mark the first parameter as wrapped', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.wrap(wrappable, function (_, toWrap) { return { wrappable: toWrap } }) - t.not(wrapped, wrappable) - t.equal(wrapped.wrappable, wrappable) - t.ok(shim.isWrapped(wrapped)) - t.end() + assert.notEqual(wrapped, wrappable) + assert.equal(wrapped.wrappable, wrappable) + assert.equal(shim.isWrapped(wrapped), true) }) }) - t.test('#wrap with properties', function (t) { - let barTestWrapper = null - let originalBar = null - let ret = null - t.autoend() - - t.beforeEach(function () { - beforeEach() - barTestWrapper = function () {} - originalBar = wrappable.bar - ret = shim.wrap(wrappable, 'bar', function () { + await t.test('#wrap with properties', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { shim } = ctx.nr + const barTestWrapper = function () {} + ctx.nr.originalBar = ctx.nr.wrappable.bar + ctx.nr.ret = shim.wrap(ctx.nr.wrappable, 'bar', function () { return barTestWrapper }) }) t.afterEach(afterEach) - t.test('should accept a single property', function (t) { + await t.test('should accept a single property', function (t) { + const { ret, shim, wrappable } = t.nr const originalFiz = wrappable.fiz shim.wrap(wrappable, 'fiz', function (_, toWrap, name) { - t.equal(toWrap, wrappable.fiz) - t.equal(name, 'fiz', 'should use property as name') + assert.equal(toWrap, wrappable.fiz) + assert.equal(name, 'fiz', 'should use property as name') }) - t.equal(ret, wrappable) - t.equal(wrappable.fiz, originalFiz, 'should not replace unwrapped') - t.end() + assert.equal(ret, wrappable) + assert.equal(wrappable.fiz, originalFiz, 'should not replace unwrapped') }) - t.test('should accept an array of properties', function (t) { + await t.test('should accept an array of properties', function (t) { + const { shim, wrappable } = t.nr let specCalled = 0 shim.wrap(wrappable, ['fiz', 'anony'], function (_, toWrap, name) { ++specCalled if (specCalled === 1) { - t.equal(toWrap, wrappable.fiz) - t.equal(name, 'fiz') + assert.equal(toWrap, wrappable.fiz) + assert.equal(name, 'fiz') } else if (specCalled === 2) { - t.equal(toWrap, wrappable.anony) - t.equal(name, 'anony') + assert.equal(toWrap, wrappable.anony) + assert.equal(name, 'anony') } }) - t.equal(specCalled, 2) - t.end() + assert.equal(specCalled, 2) }) - t.test('should replace wrapped properties on the original object', function (t) { - t.not(wrappable.bar, originalBar) - t.end() + await t.test('should replace wrapped properties on the original object', function (t) { + const { originalBar, wrappable } = t.nr + assert.notEqual(wrappable.bar, originalBar) }) - t.test('should mark wrapped properties as such', function (t) { - t.ok(shim.isWrapped(wrappable, 'bar')) - t.end() + await t.test('should mark wrapped properties as such', function (t) { + const { shim, originalBar, wrappable } = t.nr + assert.notEqual(wrappable.bar, originalBar) + assert.equal(shim.isWrapped(wrappable, 'bar'), true) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { - t.notOk(shim.isWrapped(wrappable, 'fiz')) - t.end() + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr + assert.equal(shim.isWrapped(wrappable, 'fiz'), false) }) }) - t.test('with a function', function (t) { - t.autoend() - let wrapper = null - - t.beforeEach(function () { - beforeEach() - wrapper = function wrapperFunc() { + await t.test('with a function', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const wrapper = function wrapperFunc() { return function wrapped() {} } - shim.wrap(wrappable, 'bar', wrapper) + ctx.nr.shim.wrap(ctx.nr.wrappable, 'bar', wrapper) }) t.afterEach(afterEach) - t.test('should not maintain the name', function (t) { - t.equal(wrappable.bar.name, 'wrapped') - t.end() + await t.test('should not maintain the name', function (t) { + const { wrappable } = t.nr + assert.equal(wrappable.bar.name, 'wrapped') }) - t.test('should not maintain the arity', function (t) { - t.equal(wrappable.bar.length, 0) - t.end() + await t.test('should not maintain the arity', function (t) { + const { wrappable } = t.nr + assert.equal(wrappable.bar.length, 0) }) }) - t.test('#bindSegment', function (t) { - t.autoend() - let segment - let startingSegment + await t.test('#bindSegment', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) - t.beforeEach(function () { - beforeEach() - - segment = { + ctx.nr.segment = { started: false, touched: false, probed: false, @@ -404,69 +377,70 @@ tap.test('Shim', function (t) { } } - startingSegment = contextManager.getContext() + ctx.nr.startingSegment = ctx.nr.contextManager.getContext() }) t.afterEach(afterEach) - t.test('should not wrap non-functions', function (t) { + await t.test('should not wrap non-functions', function (t) { + const { shim, wrappable } = t.nr shim.bindSegment(wrappable, 'name') - t.notOk(shim.isWrapped(wrappable, 'name')) - t.end() + assert.equal(shim.isWrapped(wrappable, 'name'), false) }) - t.test('should not error if `nodule` is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if `nodule` is `null`', function (t) { + const { segment, shim } = t.nr + assert.doesNotThrow(function () { shim.bindSegment(null, 'foobar', segment) }) - t.end() }) - t.test('should wrap the first parameter if `property` is not given', function (t) { + await t.test('should wrap the first parameter if `property` is not given', function (t) { + const { segment, shim, wrappable } = t.nr const wrapped = shim.bindSegment(wrappable.getActiveSegment, segment) - t.not(wrapped, wrappable.getActiveSegment) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.getActiveSegment) - t.end() + assert.notEqual(wrapped, wrappable.getActiveSegment) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.getActiveSegment) }) - t.test('should wrap the first parameter if `property` is `null`', function (t) { + await t.test('should wrap the first parameter if `property` is `null`', function (t) { + const { segment, shim, wrappable } = t.nr const wrapped = shim.bindSegment(wrappable.getActiveSegment, null, segment) - t.not(wrapped, wrappable.getActiveSegment) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.getActiveSegment) - t.end() + assert.notEqual(wrapped, wrappable.getActiveSegment) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.getActiveSegment) }) - t.test('should not wrap the function at all with no segment', function (t) { + await t.test('should not wrap the function at all with no segment', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.bindSegment(wrappable.getActiveSegment) - t.equal(wrapped, wrappable.getActiveSegment) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable.getActiveSegment) + assert.equal(shim.isWrapped(wrapped), false) }) - t.test('should be safe to pass a full param with not segment', function (t) { + await t.test('should be safe to pass a full param with not segment', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.bindSegment(wrappable.getActiveSegment, null, true) - t.equal(wrapped, wrappable.getActiveSegment) - t.notOk(shim.isWrapped(wrapped)) - t.doesNotThrow(wrapped) - t.end() + assert.equal(wrapped, wrappable.getActiveSegment) + assert.equal(shim.isWrapped(wrapped), false) + assert.doesNotThrow(wrapped) }) - t.test('should make the given segment active while executing', function (t) { - t.not(startingSegment, segment, 'test should start in clean condition') + await t.test('should make the given segment active while executing', function (t) { + const { contextManager, segment, shim, startingSegment, wrappable } = t.nr + assert.notEqual(startingSegment, segment, 'test should start in clean condition') shim.bindSegment(wrappable, 'getActiveSegment', segment) - t.equal(contextManager.getContext(), startingSegment) - t.equal(wrappable.getActiveSegment(), segment) - t.equal(contextManager.getContext(), startingSegment) - t.end() + assert.equal(contextManager.getContext(), startingSegment) + assert.equal(wrappable.getActiveSegment(), segment) + assert.equal(contextManager.getContext(), startingSegment) }) - t.test('should not require any arguments except a function', function (t) { - t.not(startingSegment, segment, 'test should start in clean condition') + await t.test('should not require any arguments except a function', function (t) { + const { contextManager, segment, shim, startingSegment, wrappable } = t.nr + assert.notEqual(startingSegment, segment, 'test should start in clean condition') // bindSegment will not wrap if there is no segment active and // no segment is passed in. To get around this we set the @@ -476,94 +450,96 @@ tap.test('Shim', function (t) { const wrapped = shim.bindSegment(wrappable.getActiveSegment) contextManager.setContext(startingSegment) - t.equal(wrapped(), segment) - t.equal(contextManager.getContext(), startingSegment) - t.end() + assert.equal(wrapped(), segment) + assert.equal(contextManager.getContext(), startingSegment) }) - t.test('should default `full` to false', function (t) { + await t.test('should default `full` to false', function (t) { + const { segment, shim, wrappable } = t.nr shim.bindSegment(wrappable, 'getActiveSegment', segment) wrappable.getActiveSegment() - t.notOk(segment.started) - t.notOk(segment.touched) - t.end() + assert.equal(segment.started, false) + assert.equal(segment.touched, false) }) - t.test('should start and touch the segment if `full` is `true`', function (t) { + await t.test('should start and touch the segment if `full` is `true`', function (t) { + const { segment, shim, wrappable } = t.nr shim.bindSegment(wrappable, 'getActiveSegment', segment, true) wrappable.getActiveSegment() - t.ok(segment.started) - t.ok(segment.touched) - t.end() + assert.equal(segment.started, true) + assert.equal(segment.touched, true) }) - t.test('should default to the current segment', function (t) { + await t.test('should default to the current segment', function (t) { + const { contextManager, segment, shim, wrappable } = t.nr contextManager.setContext(segment) shim.bindSegment(wrappable, 'getActiveSegment') const activeSegment = wrappable.getActiveSegment() - t.equal(activeSegment, segment) - t.end() + assert.equal(activeSegment, segment) }) }) - t.test('#wrapReturn', function (t) { - t.autoend() + await t.test('#wrapReturn', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr shim.wrapReturn(wrappable, 'name', function () {}) - t.notOk(shim.isWrapped(wrappable, 'name')) - t.end() + assert.equal(shim.isWrapped(wrappable, 'name'), false) }) - t.test('should not blow up when wrapping a non-object prototype', function (t) { + await t.test('should not blow up when wrapping a non-object prototype', function (t) { + const { shim } = t.nr function noProto() {} noProto.prototype = undefined const instance = shim.wrapReturn(noProto, function () {}).bind({}) - t.doesNotThrow(instance) - t.end() + assert.doesNotThrow(instance) }) - t.test('should not blow up when wrapping a non-object prototype, null bind', function (t) { - function noProto() {} - noProto.prototype = undefined - const instance = shim.wrapReturn(noProto, function () {}).bind(null) - t.doesNotThrow(instance) - t.end() - }) + await t.test( + 'should not blow up when wrapping a non-object prototype, null bind', + function (t) { + const { shim } = t.nr + function noProto() {} + noProto.prototype = undefined + const instance = shim.wrapReturn(noProto, function () {}).bind(null) + assert.doesNotThrow(instance) + } + ) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.wrapReturn(wrappable.bar, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.wrapReturn(wrappable.bar, null, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.wrapReturn(wrappable, 'bar', function () {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable, 'bar')) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable, 'bar'), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should wrap child instance properly', function (t) { + await t.test('should wrap child instance properly', function (t) { + const { shim } = t.nr class ParentTest { constructor() { this.parent = true @@ -583,334 +559,329 @@ tap.test('Shim', function (t) { } const child = new ChildTest() - t.ok(typeof child.childMethod === 'function', 'should have child methods') - t.ok(typeof child.parentMethod === 'function', 'should have parent methods') - t.end() + assert.equal(typeof child.childMethod, 'function', 'should have child methods') + assert.equal(typeof child.parentMethod, 'function', 'should have parent methods') }) }) - t.test('#wrapReturn wrapper', function (t) { - t.autoend() - let executed - let toWrap - let returned - - t.beforeEach(function () { - beforeEach() - executed = false - toWrap = { + await t.test('#wrapReturn wrapper', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { shim } = ctx.nr + ctx.nr.executed = false + ctx.nr.toWrap = { foo: function () { - executed = true - returned = { + ctx.nr.executed = true + ctx.nr.returned = { context: this, args: shim.toArray(arguments) } - return returned + return ctx.nr.returned } } }) t.afterEach(afterEach) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t) { + const { shim, toWrap } = t.nr shim.wrapReturn(toWrap, 'foo', function () {}) const res = toWrap.foo('a', 'b', 'c') - t.ok(executed) - t.equal(res.context, toWrap) - t.same(res.args, ['a', 'b', 'c']) - t.end() + assert.equal(t.nr.executed, true) + assert.equal(res.context, toWrap) + assert.deepEqual(res.args, ['a', 'b', 'c']) }) - t.test('should pass properties through', function (t) { + await t.test('should pass properties through', function (t) { + const { shim, toWrap } = t.nr const original = toWrap.foo original.testSymbol = Symbol('test') shim.wrapReturn(toWrap, 'foo', function () {}) // wrapper is not the same function reference - t.not(original, toWrap.foo) + assert.notEqual(original, toWrap.foo) // set on original - t.equal(toWrap.foo.testSymbol, original.testSymbol) - t.end() + assert.equal(toWrap.foo.testSymbol, original.testSymbol) }) - t.test('should pass assignments to the wrapped method', function (t) { + await t.test('should pass assignments to the wrapped method', function (t) { + const { shim, toWrap } = t.nr const original = toWrap.foo shim.wrapReturn(toWrap, 'foo', function () {}) toWrap.foo.testProp = 1 // wrapper is not the same function reference - t.not(original, toWrap.foo) + assert.notEqual(original, toWrap.foo) // set via wrapper - t.equal(original.testProp, 1) - t.end() + assert.equal(original.testProp, 1) }) - t.test('should pass defined properties to the wrapped method', function (t) { + await t.test('should pass defined properties to the wrapped method', function (t) { + const { shim, toWrap } = t.nr const original = toWrap.foo shim.wrapReturn(toWrap, 'foo', function () {}) Object.defineProperty(toWrap.foo, 'testDefProp', { value: 4 }) // wrapper is not the same function reference - t.not(original, toWrap.foo) + assert.notEqual(original, toWrap.foo) // set with defineProperty via wrapper - t.equal(original.testDefProp, 4) - t.end() + assert.equal(original.testDefProp, 4) }) - t.test('should have the same key enumeration', function (t) { + await t.test('should have the same key enumeration', function (t) { + const { shim, toWrap } = t.nr const original = toWrap.foo original.testSymbol = Symbol('test') shim.wrapReturn(toWrap, 'foo', function () {}) toWrap.foo.testProp = 1 // wrapper is not the same function reference - t.not(original, toWrap.foo) + assert.notEqual(original, toWrap.foo) // should have the same keys - t.same(Object.keys(original), Object.keys(toWrap.foo)) - t.end() + assert.deepEqual(Object.keys(original), Object.keys(toWrap.foo)) }) - t.test('should call the spec with returned value', function (t) { + await t.test('should call the spec with returned value', function (t) { + const { shim, toWrap } = t.nr let specExecuted = false shim.wrapReturn(toWrap, 'foo', function (_, fn, name, ret) { specExecuted = true - t.equal(ret, returned) + assert.equal(ret, t.nr.returned) }) toWrap.foo() - t.ok(specExecuted) - t.end() + assert.equal(specExecuted, true) }) - t.test('should invoke the spec in the context of the wrapped function', function (t) { - shim.wrapReturn(toWrap, 'foo', function () { - t.equal(this, toWrap) - }) + await t.test( + 'should invoke the spec in the context of the wrapped function', + function (t, end) { + const { shim, toWrap } = t.nr + shim.wrapReturn(toWrap, 'foo', function () { + assert.equal(this, toWrap) + end() + }) - toWrap.foo() - t.end() - }) + toWrap.foo() + } + ) - t.test('should invoke the spec with `new` if itself is invoked with `new`', function (t) { + await t.test('should invoke the spec with `new` if itself is invoked with `new`', function (t) { + const { shim } = t.nr function Foo() { - t.ok(this instanceof Foo) + assert.equal(this instanceof Foo, true) } Foo.prototype.method = function () {} const WrappedFoo = shim.wrapReturn(Foo, function () { - t.ok(this instanceof Foo) + assert.equal(this instanceof Foo, true) }) const foo = new WrappedFoo() - t.ok(foo instanceof Foo) - t.ok(foo instanceof WrappedFoo) - t.ok(typeof foo.method === 'function') - t.end() + assert.equal(foo instanceof Foo, true) + assert.equal(foo instanceof WrappedFoo, true) + assert.equal(typeof foo.method, 'function') }) - t.test('should pass items in the `args` parameter to the spec', function (t) { + await t.test('should pass items in the `args` parameter to the spec', function (t, end) { + const { shim, toWrap } = t.nr /* eslint-disable max-params */ shim.wrapReturn( toWrap, 'foo', function (_, fn, name, ret, a, b, c) { - t.equal(arguments.length, 7) - t.equal(a, 'a') - t.equal(b, 'b') - t.equal(c, 'c') + assert.equal(arguments.length, 7) + assert.equal(a, 'a') + assert.equal(b, 'b') + assert.equal(c, 'c') + end() }, ['a', 'b', 'c'] ) /* eslint-enable max-params */ toWrap.foo() - t.end() }) }) - t.test('#wrapClass', function (t) { - t.autoend() + await t.test('#wrapClass', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr shim.wrapClass(wrappable, 'name', function () {}) - t.notOk(shim.isWrapped(wrappable, 'name')) - t.end() + assert.equal(shim.isWrapped(wrappable, 'name'), false) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.wrapClass(wrappable.bar, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.wrapClass(wrappable.bar, null, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.wrapClass(wrappable, 'bar', function () {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable, 'bar')) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable, 'bar'), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) }) - t.test('#wrapClass wrapper', function (t) { - t.autoend() - let executed = null - let toWrap = null - let original = null - - t.beforeEach(function () { - beforeEach() - executed = false - toWrap = { + await t.test('#wrapClass wrapper', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { shim } = ctx.nr + ctx.nr.executed = false + const toWrap = { Foo: function () { - this.executed = executed = true + this.executed = ctx.nr.executed = true this.context = this this.args = shim.toArray(arguments) } } - original = toWrap.Foo + ctx.nr.original = toWrap.Foo + ctx.nr.toWrap = toWrap }) t.afterEach(afterEach) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t) { + const { shim, toWrap } = t.nr shim.wrapClass(toWrap, 'Foo', function () {}) const res = new toWrap.Foo('a', 'b', 'c') - t.ok(executed) - t.equal(res.context, res) - t.same(res.args, ['a', 'b', 'c']) - t.end() + assert.equal(t.nr.executed, true) + assert.equal(res.context, res) + assert.deepEqual(res.args, ['a', 'b', 'c']) }) - t.test('should call the hooks in the correct order', function (t) { + await t.test('should call the hooks in the correct order', function (t) { + const { original, shim, toWrap } = t.nr let preExecuted = false let postExecuted = false shim.wrapClass(toWrap, 'Foo', { pre: function () { preExecuted = true - t.not(this) + assert.equal(this, undefined) }, post: function () { postExecuted = true - t.ok(this.executed) - t.ok(this instanceof toWrap.Foo) - t.ok(this instanceof original) + assert.equal(this.executed, true) + assert.equal(this instanceof toWrap.Foo, true) + assert.equal(this instanceof original, true) } }) const foo = new toWrap.Foo() - t.ok(preExecuted) - t.ok(foo.executed) - t.ok(postExecuted) - t.end() + assert.equal(preExecuted, true) + assert.equal(foo.executed, true) + assert.equal(postExecuted, true) }) - t.test('should pass items in the `args` parameter to the spec', function (t) { + await t.test('should pass items in the `args` parameter to the spec', function (t) { + const { shim, toWrap } = t.nr /* eslint-disable max-params */ shim.wrapClass( toWrap, 'Foo', function (_, fn, name, args, a, b, c) { - t.equal(arguments.length, 7) - t.equal(a, 'a') - t.equal(b, 'b') - t.equal(c, 'c') + assert.equal(arguments.length, 7) + assert.equal(a, 'a') + assert.equal(b, 'b') + assert.equal(c, 'c') }, ['a', 'b', 'c'] ) /* eslint-enable max-params */ const foo = new toWrap.Foo() - t.ok(foo) - t.end() + assert.ok(foo) }) }) - t.test('#wrapExport', function (t) { - t.autoend() + await t.test('#wrapExport', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should execute the given wrap function', function (t) { + await t.test('should execute the given wrap function', function (t) { + const { shim } = t.nr let executed = false shim.wrapExport({}, function () { executed = true }) - t.ok(executed) - t.end() + assert.equal(executed, true) }) - t.test('should store the wrapped version for later retrival', function (t) { + await t.test('should store the wrapped version for later retrival', function (t) { + const { shim } = t.nr const original = {} const wrapped = shim.wrapExport(original, function () { return {} }) const xport = shim.getExport() - t.equal(xport, wrapped) - t.not(xport, original) - t.end() + assert.equal(xport, wrapped) + assert.notEqual(xport, original) }) }) - t.test('#record', function (t) { - t.autoend() + await t.test('#record', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.record(wrappable, function () {}) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.equal(shim.isWrapped(wrapped), false) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.record(wrappable.bar, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.record(wrappable.bar, null, function () {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.record(wrappable, 'bar', function () {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.record(wrappable, 'name', function () {}) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should not create a child segment', function (t) { + await t.test('should not create a child segment', function (t, end) { + const { agent, contextManager, shim, wrappable } = t.nr shim.record(wrappable, 'getActiveSegment', function () { return new RecorderSpec({ name: 'internal test segment', internal: true }) }) @@ -920,19 +891,20 @@ tap.test('Shim', function (t) { startingSegment.internal = true startingSegment.shim = shim const segment = wrappable.getActiveSegment() - t.equal(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'ROOT') - t.equal(contextManager.getContext(), startingSegment) - t.end() + assert.equal(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'ROOT') + assert.equal(contextManager.getContext(), startingSegment) + end() }) }) - t.test('should still bind the callback', function (t) { + await t.test('should still bind the callback', function (t, end) { + const { agent, contextManager, shim } = t.nr const wrapped = shim.record( function (cb) { - t.ok(shim.isWrapped(cb)) - t.end() + assert.equal(shim.isWrapped(cb), true) + end() }, function () { return new RecorderSpec({ name: 'test segment', internal: true, callback: shim.LAST }) @@ -947,13 +919,14 @@ tap.test('Shim', function (t) { }) }) - t.test('should not throw when using an ended segment as parent', function (t) { + await t.test('should not throw when using an ended segment as parent', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function (tx) { tx.end() const wrapped = shim.record( function (cb) { - t.notOk(shim.isWrapped(cb)) - t.equal(agent.getTransaction(), null) + assert.equal(shim.isWrapped(cb), false) + assert.equal(agent.getTransaction(), null) }, function () { return new RecorderSpec({ @@ -964,43 +937,48 @@ tap.test('Shim', function (t) { }) } ) - t.doesNotThrow(function () { + assert.doesNotThrow(function () { wrapped(function () {}) }) - t.end() + end() }) }) - t.test('should call after hook on record when function is done executing', function (t) { - helper.runInTransaction(agent, function () { - function testAfter() { - return 'result' - } - const wrapped = shim.record(testAfter, function () { - return new RecorderSpec({ - name: 'test segment', - callback: shim.LAST, - after(args) { - t.equal(Object.keys(args).length, 6, 'should have 6 args to after hook') - const { fn, name, error, result, segment } = args - t.equal(segment.name, 'test segment') - t.not(error) - t.same(fn, testAfter) - t.equal(name, testAfter.name) - t.equal(result, 'result') - } + await t.test( + 'should call after hook on record when function is done executing', + function (t, end) { + const { agent, shim } = t.nr + helper.runInTransaction(agent, function () { + function testAfter() { + return 'result' + } + const wrapped = shim.record(testAfter, function () { + return new RecorderSpec({ + name: 'test segment', + callback: shim.LAST, + after(args) { + assert.equal(Object.keys(args).length, 6, 'should have 6 args to after hook') + const { fn, name, error, result, segment } = args + assert.equal(segment.name, 'test segment') + assert.equal(error, undefined) + assert.deepEqual(fn, testAfter) + assert.equal(name, testAfter.name) + assert.equal(result, 'result') + } + }) }) + assert.doesNotThrow(function () { + wrapped() + }) + end() }) - t.doesNotThrow(function () { - wrapped() - }) - t.end() - }) - }) + } + ) - t.test( + await t.test( 'should call after hook on record when the function is done executing after failure', - function (t) { + function (t, end) { + const { agent, shim } = t.nr const err = new Error('test err') helper.runInTransaction(agent, function () { function testAfter() { @@ -1011,215 +989,204 @@ tap.test('Shim', function (t) { name: 'test segment', callback: shim.LAST, after(args) { - t.equal(Object.keys(args).length, 6, 'should have 6 args to after hook') + assert.equal(Object.keys(args).length, 6, 'should have 6 args to after hook') const { fn, name, error, result, segment } = args - t.equal(segment.name, 'test segment') - t.same(error, err) - t.equal(result, undefined) - t.same(fn, testAfter) - t.equal(name, testAfter.name) + assert.equal(segment.name, 'test segment') + assert.deepEqual(error, err) + assert.equal(result, undefined) + assert.deepEqual(fn, testAfter) + assert.equal(name, testAfter.name) } }) }) - t.throws(function () { + assert.throws(function () { wrapped() }) - t.end() + end() }) } ) }) - t.test('#record with a stream', function (t) { - t.autoend() - let stream = null - let toWrap = null - - t.beforeEach(function () { - beforeEach() - stream = new EventEmitter() - toWrap = function () { - stream.segment = contextManager.getContext() + await t.test('#record with a stream', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const stream = new EventEmitter() + ctx.nr.toWrap = function () { + stream.segment = ctx.nr.contextManager.getContext() return stream } + ctx.nr.stream = stream }) - t.afterEach(function () { - afterEach() - stream = null - toWrap = null - }) + t.afterEach(afterEach) - t.test('should make the segment translucent when `end` is emitted', function (t) { + await t.test('should make the segment translucent when `end` is emitted', function (t, end) { + const { agent, shim, stream, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', stream: true, opaque: true }) }) helper.runInTransaction(agent, function () { const ret = wrapped() - t.equal(ret, stream) + assert.equal(ret, stream) }) - t.ok(stream.segment.opaque) + assert.equal(stream.segment.opaque, true) setTimeout(function () { stream.emit('end') - t.notOk(stream.segment.opaque) - t.end() + assert.equal(stream.segment.opaque, false) + end() }, 5) }) - t.test('should touch the segment when `end` is emitted', function (t) { + await t.test('should touch the segment when `end` is emitted', function (t, end) { + const { agent, shim, stream, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', stream: true }) }) helper.runInTransaction(agent, function () { const ret = wrapped() - t.equal(ret, stream) + assert.equal(ret, stream) }) const oldDur = stream.segment.timer.getDurationInMillis() setTimeout(function () { stream.emit('end') - t.ok(stream.segment.timer.getDurationInMillis() > oldDur) - t.end() + assert.ok(stream.segment.timer.getDurationInMillis() > oldDur) + end() }, 5) }) - t.test('should make the segment translucent when `error` is emitted', function (t) { + await t.test('should make the segment translucent when `error` is emitted', function (t, end) { + const { agent, shim, stream, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', stream: true, opaque: true }) }) helper.runInTransaction(agent, function () { const ret = wrapped() - t.equal(ret, stream) + assert.equal(ret, stream) }) stream.on('error', function () {}) // to prevent the error being thrown - t.ok(stream.segment.opaque) + assert.equal(stream.segment.opaque, true) setTimeout(function () { stream.emit('error', 'foobar') - t.notOk(stream.segment.opaque) - t.end() + assert.equal(stream.segment.opaque, false) + end() }, 5) }) - t.test('should touch the segment when `error` is emitted', function (t) { + await t.test('should touch the segment when `error` is emitted', function (t, end) { + const { agent, shim, stream, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', stream: true }) }) helper.runInTransaction(agent, function () { const ret = wrapped() - t.equal(ret, stream) + assert.equal(ret, stream) }) stream.on('error', function () {}) // to prevent the error being thrown const oldDur = stream.segment.timer.getDurationInMillis() setTimeout(function () { stream.emit('error', 'foobar') - t.ok(stream.segment.timer.getDurationInMillis() > oldDur) - t.end() + assert.ok(stream.segment.timer.getDurationInMillis() > oldDur) + end() }, 5) }) - t.test('should throw if there are no other `error` handlers', function (t) { + await t.test('should throw if there are no other `error` handlers', function (t) { + const { agent, shim, stream, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', stream: true }) }) helper.runInTransaction(agent, function () { const ret = wrapped() - t.equal(ret, stream) + assert.equal(ret, stream) }) - t.throws(function () { + assert.throws(function () { stream.emit('error', new Error('foobar')) - }, 'foobar') - t.end() + }, 'Error: foobar') }) - t.test('should bind emit to a child segment', function (t) { + await t.test('should bind emit to a child segment', function (t, end) { + const { agent, shim, stream, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', stream: 'foobar' }) }) helper.runInTransaction(agent, function () { const ret = wrapped() - t.equal(ret, stream) + assert.equal(ret, stream) }) stream.on('foobar', function () { const emitSegment = shim.getSegment() - t.equal(emitSegment.parent, stream.segment) - t.end() + assert.equal(emitSegment.parent, stream.segment) + end() }) stream.emit('foobar') }) - t.test('should create an event segment if an event name is given', function (t) { + await t.test('should create an event segment if an event name is given', function (t) { + const { agent, shim, stream, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', stream: 'foobar' }) }) helper.runInTransaction(agent, function () { const ret = wrapped() - t.equal(ret, stream) + assert.equal(ret, stream) }) // Emit the event and check the segment name. - t.equal(stream.segment.children.length, 0) + assert.equal(stream.segment.children.length, 0) stream.emit('foobar') - t.equal(stream.segment.children.length, 1) + assert.equal(stream.segment.children.length, 1) const [eventSegment] = stream.segment.children - t.match(eventSegment.name, /Event callback: foobar/) - t.equal(eventSegment.getAttributes().count, 1) + assert.match(eventSegment.name, /Event callback: foobar/) + assert.equal(eventSegment.getAttributes().count, 1) // Emit it again and see if the name updated. stream.emit('foobar') - t.equal(stream.segment.children.length, 1) - t.equal(stream.segment.children[0], eventSegment) - t.equal(eventSegment.getAttributes().count, 2) + assert.equal(stream.segment.children.length, 1) + assert.equal(stream.segment.children[0], eventSegment) + assert.equal(eventSegment.getAttributes().count, 2) // Emit it once more and see if the name updated again. stream.emit('foobar') - t.equal(stream.segment.children.length, 1) - t.equal(stream.segment.children[0], eventSegment) - t.equal(eventSegment.getAttributes().count, 3) - t.end() + assert.equal(stream.segment.children.length, 1) + assert.equal(stream.segment.children[0], eventSegment) + assert.equal(eventSegment.getAttributes().count, 3) }) }) - t.test('#record with a promise', function (t) { - t.autoend() - let promise = null - let toWrap = null - - t.beforeEach(function () { - beforeEach() - const defer = {} - promise = new Promise(function (resolve, reject) { - defer.resolve = resolve - defer.reject = reject - }) - promise.resolve = defer.resolve - promise.reject = defer.reject - - toWrap = function () { - promise.segment = contextManager.getContext() + await t.test('#record with a promise', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { promise, resolve, reject } = promiseResolvers() + const toWrap = function () { + promise.segment = ctx.nr.contextManager.getContext() return promise } + ctx.nr.promise = promise + ctx.nr.toWrap = toWrap + ctx.nr.resolve = resolve + ctx.nr.reject = reject }) - t.afterEach(function () { - afterEach() - promise = null - toWrap = null - }) + t.afterEach(afterEach) - t.test('should make the segment translucent when promise resolves', function (t) { + await t.test('should make the segment translucent when promise resolves', function (t, end) { + const plan = tspl(t, { plan: 4 }) + const { agent, promise, resolve, shim, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', promise: true, opaque: true }) }) @@ -1227,24 +1194,26 @@ tap.test('Shim', function (t) { const result = {} helper.runInTransaction(agent, function () { const ret = wrapped() - t.ok(ret instanceof Object.getPrototypeOf(promise).constructor) + plan.ok(ret instanceof Object.getPrototypeOf(promise).constructor) ret .then(function (val) { - t.equal(result, val) - t.notOk(promise.segment.opaque) - t.end() + plan.equal(result, val) + plan.equal(promise.segment.opaque, false) + end() }) - .catch(t.end) + .catch(end) }) - t.ok(promise.segment.opaque) + plan.equal(promise.segment.opaque, true) setTimeout(function () { - promise.resolve(result) + resolve(result) }, 5) }) - t.test('should touch the segment when promise resolves', function (t) { + await t.test('should touch the segment when promise resolves', function (t, end) { + const plan = tspl(t, { plan: 3 }) + const { agent, promise, resolve, shim, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', promise: true }) }) @@ -1253,108 +1222,119 @@ tap.test('Shim', function (t) { helper.runInTransaction(agent, function () { const ret = wrapped() const oldDur = promise.segment.timer.getDurationInMillis() - t.ok(ret instanceof Object.getPrototypeOf(promise).constructor) + plan.ok(ret instanceof Object.getPrototypeOf(promise).constructor) ret .then(function (val) { - t.equal(result, val) - t.ok(promise.segment.timer.getDurationInMillis() > oldDur) - t.end() + plan.equal(result, val) + plan.ok(promise.segment.timer.getDurationInMillis() > oldDur) + end() }) - .catch(t.end) + .catch(end) }) setTimeout(function () { - promise.resolve(result) + resolve(result) }, 5) }) - t.test('should make the segment translucent when promise rejects', function (t) { + await t.test('should make the segment translucent when promise rejects', function (t, end) { + const plan = tspl(t, { plan: 4 }) + const { agent, promise, reject, shim, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', promise: true, opaque: true }) }) - const result = {} + const result = new Error('translucent when promise rejects') helper.runInTransaction(agent, function () { const ret = wrapped() - t.ok(ret instanceof Object.getPrototypeOf(promise).constructor) + plan.ok(ret instanceof Object.getPrototypeOf(promise).constructor) ret .then( function () { - t.end(new Error('Should not have resolved!')) + end(new Error('Should not have resolved!')) }, function (err) { - t.equal(err, result) - t.notOk(promise.segment.opaque) - t.end() + plan.equal(err, result) + plan.equal(promise.segment.opaque, false) + end() } ) - .catch(t.end) + .catch(end) }) - t.ok(promise.segment.opaque) + plan.equal(promise.segment.opaque, true) setTimeout(function () { - promise.reject(result) + reject(result) }, 5) }) - t.test('should touch the segment when promise rejects', function (t) { + await t.test('should touch the segment when promise rejects', function (t, end) { + const plan = tspl(t, { plan: 3 }) + const { agent, promise, reject, shim, toWrap } = t.nr const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', promise: true }) }) - const result = {} + const result = new Error('touch segment when promise rejects') helper.runInTransaction(agent, function () { const ret = wrapped() const oldDur = promise.segment.timer.getDurationInMillis() - t.ok(ret instanceof Object.getPrototypeOf(promise).constructor) - - ret - .then( - function () { - t.end(new Error('Should not have resolved!')) - }, - function (err) { - t.equal(err, result) - t.ok(promise.segment.timer.getDurationInMillis() > oldDur) - t.end() - } - ) - .catch(t.end) + plan.ok(ret instanceof Object.getPrototypeOf(promise).constructor) + + ret.then( + function () {}, + function (err) { + plan.equal(err, result) + plan.ok(promise.segment.timer.getDurationInMillis() > oldDur) + end() + } + ) }) setTimeout(function () { - promise.reject(result) + reject(result) }, 5) }) - t.test('should not affect unhandledRejection event', function (t) { + await t.test('should not affect unhandledRejection event', async (t) => { + const plan = tspl(t, { plan: 2 }) + const { agent, promise, reject, shim, toWrap } = t.nr + const { promise: testPromise, resolve: testResolve } = promiseResolvers() + const result = new Error('unhandled rejection test') + + tempOverrideUncaught({ + t, + type: tempOverrideUncaught.REJECTION, + handler(err) { + plan.deepEqual(err, result) + testResolve() + } + }) + const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: 'test segment', promise: true }) }) - const result = {} helper.runInTransaction(agent, function () { const ret = wrapped() - t.ok(ret instanceof Object.getPrototypeOf(promise).constructor) - - process.on('unhandledRejection', function (err) { - t.equal(err, result) - t.end() - }) + plan.ok(ret instanceof Object.getPrototypeOf(promise).constructor) - ret.then(() => { - t.end(new Error('Should not have resolved')) - }) + ret.then(() => {}) }) setTimeout(function () { - promise.reject(result) + reject(result) }, 5) + + await testPromise }) - t.test('should call after hook when promise resolves', (t) => { + await t.test('should call after hook when promise resolves', async (t) => { + const plan = tspl(t, { plan: 7 }) + const { agent, promise, resolve, shim, toWrap } = t.nr + const { promise: testPromise, resolve: testResolve } = promiseResolvers() const segmentName = 'test segment' const expectedResult = { returned: true } const wrapped = shim.record(toWrap, function () { @@ -1362,73 +1342,79 @@ tap.test('Shim', function (t) { name: segmentName, promise: true, after(args) { - t.equal(Object.keys(args).length, 6, 'should have 6 args to after hook') + plan.equal(Object.keys(args).length, 6, 'should have 6 args to after hook') const { fn, name, error, result, segment } = args - t.same(fn, toWrap) - t.equal(name, toWrap.name) - t.not(error) - t.same(result, expectedResult) - t.equal(segment.name, segmentName) - t.end() + plan.deepEqual(fn, toWrap) + plan.equal(name, toWrap.name) + plan.equal(error, null) + plan.deepEqual(result, expectedResult) + plan.equal(segment.name, segmentName) + testResolve() } }) }) helper.runInTransaction(agent, function () { const ret = wrapped() - t.ok(ret instanceof Object.getPrototypeOf(promise).constructor) + plan.ok(ret instanceof Object.getPrototypeOf(promise).constructor) }) setTimeout(function () { - promise.resolve(expectedResult) + resolve(expectedResult) }, 5) + + await testPromise }) - t.test('should call after hook when promise reject', (t) => { + await t.test('should call after hook when promise reject', async (t) => { + const plan = tspl(t, { plan: 6 }) + const { agent, promise, reject, shim, toWrap } = t.nr + const { promise: testPromise, resolve: testResolve } = promiseResolvers() const segmentName = 'test segment' - const expectedResult = { returned: true } + const expectedResult = new Error('should call after hook when promise rejects') const wrapped = shim.record(toWrap, function () { return new RecorderSpec({ name: segmentName, promise: true, after(args) { - t.equal(Object.keys(args).length, 5, 'should have 6 args to after hook') + plan.equal(Object.keys(args).length, 5, 'should have 6 args to after hook') const { fn, name, error, segment } = args - t.same(fn, toWrap) - t.equal(name, toWrap.name) - t.same(error, expectedResult) - t.equal(segment.name, segmentName) - t.end() + plan.deepEqual(fn, toWrap) + plan.equal(name, toWrap.name) + plan.deepEqual(error, expectedResult) + plan.equal(segment.name, segmentName) + testResolve() } }) }) helper.runInTransaction(agent, function () { const ret = wrapped() - t.ok(ret instanceof Object.getPrototypeOf(promise).constructor) + plan.ok(ret instanceof Object.getPrototypeOf(promise).constructor) }) setTimeout(function () { - promise.reject(expectedResult) + reject(expectedResult) }, 5) + await testPromise }) }) - t.test('#record wrapper when called without a transaction', function (t) { - t.autoend() + await t.test('#record wrapper when called without a transaction', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not create a segment', function (t) { + await t.test('should not create a segment', function (t) { + const { shim, wrappable } = t.nr shim.record(wrappable, 'getActiveSegment', function () { return new RecorderSpec({ name: 'test segment' }) }) const segment = wrappable.getActiveSegment() - t.equal(segment, null) - t.end() + assert.equal(segment, null) }) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t) { + const { shim } = t.nr let executed = false const toWrap = function () { executed = true @@ -1437,30 +1423,30 @@ tap.test('Shim', function (t) { return new RecorderSpec({ name: 'test segment' }) }) - t.notOk(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) }) - t.test('should still invoke the spec', function (t) { + await t.test('should still invoke the spec', function (t) { + const { shim, wrappable } = t.nr let executed = false shim.record(wrappable, 'bar', function () { executed = true }) - t.notOk(executed) + assert.equal(executed, false) wrappable.bar('a', 'b', 'c') - t.ok(executed) - t.end() + assert.equal(executed, true) }) - t.test('should not bind the callback if there is one', function (t) { + await t.test('should not bind the callback if there is one', function (t, end) { + const { shim } = t.nr const cb = function () {} const toWrap = function (wrappedCB) { - t.equal(wrappedCB, cb) - t.notOk(shim.isWrapped(wrappedCB)) - t.end() + assert.equal(wrappedCB, cb) + assert.ok(!shim.isWrapped(wrappedCB)) + end() } const wrapped = shim.record(toWrap, function () { @@ -1469,21 +1455,20 @@ tap.test('Shim', function (t) { wrapped(cb) }) - t.test('should not bind the rowCallback if there is one', function (t) { - const cb = function () {} - - const wrapped = shim.record(checkNotWrapped.bind(t, cb), function () { + await t.test('should not bind the rowCallback if there is one', function (t, end) { + const { shim } = t.nr + const wrapped = shim.record(checkNotWrappedCb.bind(null, shim, end), function () { return new RecorderSpec({ name: 'test segment', rowCallback: shim.LAST }) }) - wrapped(cb) + wrapped(end) }) }) - t.test('#record wrapper when called in an active transaction', function (t) { - t.autoend() + await t.test('#record wrapper when called in an active transaction', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should create a segment', function (t) { + await t.test('should create a segment', function (t, end) { + const { agent, contextManager, shim, wrappable } = t.nr shim.record(wrappable, 'getActiveSegment', function () { return new RecorderSpec({ name: 'test segment' }) }) @@ -1491,15 +1476,16 @@ tap.test('Shim', function (t) { helper.runInTransaction(agent, function (tx) { const startingSegment = contextManager.getContext() const segment = wrappable.getActiveSegment() - t.not(segment, startingSegment) - t.equal(segment.transaction, tx) - t.equal(segment.name, 'test segment') - t.equal(contextManager.getContext(), startingSegment) - t.end() + assert.notEqual(segment, startingSegment) + assert.equal(segment.transaction, tx) + assert.equal(segment.name, 'test segment') + assert.equal(contextManager.getContext(), startingSegment) + end() }) }) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t, end) { + const { agent, shim } = t.nr let executed = false const toWrap = function () { executed = true @@ -1509,43 +1495,48 @@ tap.test('Shim', function (t) { }) helper.runInTransaction(agent, function () { - t.notOk(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) + end() }) }) - t.test('should invoke the spec in the context of the wrapped function', function (t) { - const original = wrappable.bar - let executed = false - shim.record(wrappable, 'bar', function (_, fn, name, args) { - executed = true - t.equal(fn, original) - t.equal(name, 'bar') - t.equal(this, wrappable) - t.same(args, ['a', 'b', 'c']) - }) + await t.test( + 'should invoke the spec in the context of the wrapped function', + function (t, end) { + const { agent, shim, wrappable } = t.nr + const original = wrappable.bar + let executed = false + shim.record(wrappable, 'bar', function (_, fn, name, args) { + executed = true + assert.equal(fn, original) + assert.equal(name, 'bar') + assert.equal(this, wrappable) + assert.deepEqual(args, ['a', 'b', 'c']) + }) - helper.runInTransaction(agent, function () { - t.notOk(executed) - wrappable.bar('a', 'b', 'c') - t.ok(executed) - t.end() - }) - }) + helper.runInTransaction(agent, function () { + assert.equal(executed, false) + wrappable.bar('a', 'b', 'c') + assert.equal(executed, true) + end() + }) + } + ) - t.test('should bind the callback if there is one', function (t) { + await t.test('should bind the callback if there is one', function (t, end) { + const { agent, shim } = t.nr const cb = function () {} const toWrap = function (wrappedCB) { - t.not(wrappedCB, cb) - t.ok(shim.isWrapped(wrappedCB)) - t.equal(shim.unwrap(wrappedCB), cb) + assert.notEqual(wrappedCB, cb) + assert.equal(shim.isWrapped(wrappedCB), true) + assert.equal(shim.unwrap(wrappedCB), cb) - t.doesNotThrow(function () { + assert.doesNotThrow(function () { wrappedCB() }) - t.end() + end() } const wrapped = shim.record(toWrap, function () { @@ -1557,31 +1548,31 @@ tap.test('Shim', function (t) { }) }) - t.test('should bind the rowCallback if there is one', function (t) { - const cb = function () {} + await t.test('should bind the rowCallback if there is one', function (t, end) { + const { agent, shim } = t.nr - const wrapped = shim.record(helper.checkWrappedCb.bind(t, shim, cb), function () { + const wrapped = shim.record(checkWrappedCb.bind(null, shim, end), function () { return new RecorderSpec({ name: 'test segment', rowCallback: shim.LAST }) }) helper.runInTransaction(agent, function () { - wrapped(cb) + wrapped(end) }) }) }) - t.test('#record wrapper when callback required', function (t) { - t.autoend() + await t.test('#record wrapper when callback required', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should create segment if method has callback', function (t) { + await t.test('should create segment if method has callback', function (t, end) { + const { agent, shim } = t.nr const cb = function () {} const toWrap = function (wrappedCB) { - t.not(wrappedCB, cb) - t.ok(shim.isWrapped(wrappedCB)) - t.equal(shim.unwrap(wrappedCB), cb) + assert.notEqual(wrappedCB, cb) + assert.equal(shim.isWrapped(wrappedCB), true) + assert.equal(shim.unwrap(wrappedCB), cb) - t.doesNotThrow(function () { + assert.doesNotThrow(function () { wrappedCB() }) @@ -1600,15 +1591,16 @@ tap.test('Shim', function (t) { const parentSegment = shim.getSegment() const resultingSegment = wrapped(cb) - t.ok(resultingSegment !== parentSegment) - t.ok(parentSegment.children.includes(resultingSegment)) - t.end() + assert.notEqual(resultingSegment, parentSegment) + assert.ok(parentSegment.children.includes(resultingSegment)) + end() }) }) - t.test('should not create segment if method missing callback', function (t) { + await t.test('should not create segment if method missing callback', function (t, end) { + const { agent, shim } = t.nr const toWrap = function (wrappedCB) { - t.notOk(wrappedCB) + assert.ok(!wrappedCB) return shim.getSegment() } @@ -1625,18 +1617,18 @@ tap.test('Shim', function (t) { const parentSegment = shim.getSegment() const resultingSegment = wrapped() - t.ok(resultingSegment === parentSegment) - t.notOk(parentSegment.children.includes(resultingSegment)) - t.end() + assert.equal(resultingSegment, parentSegment) + assert.ok(!parentSegment.children.includes(resultingSegment)) + end() }) }) }) - t.test('#record wrapper when called with an inactive transaction', function (t) { - t.autoend() + await t.test('#record wrapper when called with an inactive transaction', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not create a segment', function (t) { + await t.test('should not create a segment', function (t, end) { + const { agent, contextManager, shim, wrappable } = t.nr shim.record(wrappable, 'getActiveSegment', function () { return new RecorderSpec({ name: 'test segment' }) }) @@ -1645,12 +1637,13 @@ tap.test('Shim', function (t) { const startingSegment = contextManager.getContext() tx.end() const segment = wrappable.getActiveSegment() - t.equal(segment, startingSegment) - t.end() + assert.equal(segment, startingSegment) + end() }) }) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t, end) { + const { agent, shim } = t.nr let executed = false const toWrap = function () { executed = true @@ -1661,14 +1654,15 @@ tap.test('Shim', function (t) { helper.runInTransaction(agent, function (tx) { tx.end() - t.notOk(executed) + assert.equal(executed, false) wrapped() - t.ok(executed) - t.end() + assert.equal(executed, true) + end() }) }) - t.test('should still invoke the spec', function (t) { + await t.test('should still invoke the spec', function (t, end) { + const { agent, shim, wrappable } = t.nr let executed = false shim.record(wrappable, 'bar', function () { executed = true @@ -1677,287 +1671,277 @@ tap.test('Shim', function (t) { helper.runInTransaction(agent, function (tx) { tx.end() wrappable.bar('a', 'b', 'c') - t.ok(executed) - t.end() + assert.equal(executed, true) + end() }) }) - t.test('should not bind the callback if there is one', function (t) { - const cb = function () {} - const wrapped = shim.record(checkNotWrapped.bind(t, cb), function () { + await t.test('should not bind the callback if there is one', function (t, end) { + const { agent, shim } = t.nr + const wrapped = shim.record(checkNotWrappedCb.bind(null, shim, end), function () { return new RecorderSpec({ name: 'test segment', callback: shim.LAST }) }) helper.runInTransaction(agent, function (tx) { tx.end() - wrapped(cb) + wrapped(end) }) }) - t.test('should not bind the rowCallback if there is one', function (t) { - const cb = function () {} - const wrapped = shim.record(checkNotWrapped.bind(t, cb), function () { + await t.test('should not bind the rowCallback if there is one', function (t, end) { + const { agent, shim } = t.nr + const wrapped = shim.record(checkNotWrappedCb.bind(null, shim, end), function () { return new RecorderSpec({ name: 'test segment', rowCallback: shim.LAST }) }) helper.runInTransaction(agent, function (tx) { tx.end() - wrapped(cb) + wrapped(end) }) }) }) - t.test('#isWrapped', function (t) { - t.autoend() + await t.test('#isWrapped', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should return true if the object was wrapped', function (t) { + await t.test('should return true if the object was wrapped', function (t) { + const { shim } = t.nr const toWrap = function () {} - t.notOk(shim.isWrapped(toWrap)) + assert.equal(shim.isWrapped(toWrap), false) const wrapped = shim.wrap(toWrap, function () { return function () {} }) - t.ok(shim.isWrapped(wrapped)) - t.end() + assert.equal(shim.isWrapped(wrapped), true) }) - t.test('should not error if the object is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if the object is `null`', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.isWrapped(null) }) - t.notOk(shim.isWrapped(null)) - t.end() + assert.equal(shim.isWrapped(null), false) }) - t.test('should return true if the property was wrapped', function (t) { - t.notOk(shim.isWrapped(wrappable, 'bar')) + await t.test('should return true if the property was wrapped', function (t) { + const { shim, wrappable } = t.nr + assert.equal(shim.isWrapped(wrappable, 'bar'), false) shim.wrap(wrappable, 'bar', function () { return function () {} }) - t.ok(shim.isWrapped(wrappable, 'bar')) - t.end() + assert.equal(shim.isWrapped(wrappable, 'bar'), true) }) - t.test('should not error if the object is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if the object is `null`', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.isWrapped(null, 'bar') }) - t.notOk(shim.isWrapped(null, 'bar')) - t.end() + assert.equal(shim.isWrapped(null, 'bar'), false) }) - t.test('should not error if the property is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if the property is `null`', function (t) { + const { shim, wrappable } = t.nr + assert.doesNotThrow(function () { shim.isWrapped(wrappable, 'this does not exist') }) - t.notOk(shim.isWrapped(wrappable, 'this does not exist')) - t.end() + assert.equal(shim.isWrapped(wrappable, 'this does not exist'), false) }) }) - t.test('#unwrap', function (t) { - t.autoend() - let original - let wrapped - - t.beforeEach(function () { - beforeEach() - original = function () {} - wrapped = shim.wrap(original, function () { + await t.test('#unwrap', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { shim, wrappable } = ctx.nr + const original = function () {} + ctx.nr.wrapped = shim.wrap(original, function () { return function () {} }) shim.wrap(wrappable, ['bar', 'fiz', 'getActiveSegment'], function () { return function () {} }) + ctx.nr.original = original }) t.afterEach(afterEach) - t.test('should not error if the item is not wrapped', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if the item is not wrapped', function (t) { + const { original, shim } = t.nr + assert.doesNotThrow(function () { shim.unwrap(original) }) - t.equal(shim.unwrap(original), original) - t.end() + assert.equal(shim.unwrap(original), original) }) - t.test('should unwrap the first parameter', function (t) { - t.equal(shim.unwrap(wrapped), original) - t.end() + await t.test('should unwrap the first parameter', function (t) { + const { original, shim, wrapped } = t.nr + assert.equal(shim.unwrap(wrapped), original) }) - t.test('should not error if `nodule` is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if `nodule` is `null`', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.unwrap(null) }) - t.end() }) - t.test('should accept a single property', function (t) { - t.ok(shim.isWrapped(wrappable.bar)) - t.doesNotThrow(function () { + await t.test('should accept a single property', function (t) { + const { shim, wrappable } = t.nr + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.doesNotThrow(function () { shim.unwrap(wrappable, 'bar') }) - t.notOk(shim.isWrapped(wrappable.bar)) - t.end() + assert.equal(shim.isWrapped(wrappable.bar), false) }) - t.test('should accept an array of properties', function (t) { - t.ok(shim.isWrapped(wrappable.bar)) - t.ok(shim.isWrapped(wrappable.fiz)) - t.ok(shim.isWrapped(wrappable.getActiveSegment)) - t.doesNotThrow(function () { + await t.test('should accept an array of properties', function (t) { + const { shim, wrappable } = t.nr + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.isWrapped(wrappable.fiz), true) + assert.equal(shim.isWrapped(wrappable.getActiveSegment), true) + assert.doesNotThrow(function () { shim.unwrap(wrappable, ['bar', 'fiz', 'getActiveSegment']) }) - t.notOk(shim.isWrapped(wrappable.bar)) - t.notOk(shim.isWrapped(wrappable.fiz)) - t.notOk(shim.isWrapped(wrappable.getActiveSegment)) - t.end() + assert.equal(shim.isWrapped(wrappable.bar), false) + assert.equal(shim.isWrapped(wrappable.fiz), false) + assert.equal(shim.isWrapped(wrappable.getActiveSegment), false) }) - t.test('should not error if a nodule is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if a nodule is `null`', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.unwrap(null, 'bar') }) - t.end() }) - t.test('should not error if a property is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if a property is `null`', function (t) { + const { shim, wrappable } = t.nr + assert.doesNotThrow(function () { shim.unwrap(wrappable, 'this does not exist') }) - t.end() }) }) - t.test('#unwrapOnce', function (t) { - t.autoend() - let original - let wrapped - - t.beforeEach(function () { - beforeEach() - original = function () {} - wrapped = shim.wrap(original, function () { + await t.test('#unwrapOnce', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { shim, wrappable } = ctx.nr + const original = function () {} + ctx.nr.wrapped = shim.wrap(original, function () { return function () {} }) shim.wrap(wrappable, ['bar', 'fiz', 'getActiveSegment'], function () { return function () {} }) + ctx.nr.original = original }) t.afterEach(afterEach) - t.test('should not error if the item is not wrapped', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if the item is not wrapped', function (t) { + const { original, shim } = t.nr + assert.doesNotThrow(function () { shim.unwrapOnce(original) }) - t.equal(shim.unwrapOnce(original), original) - t.end() + assert.equal(shim.unwrapOnce(original), original) }) - t.test('should not fully unwrap multiple nested wrappers', function (t) { + await t.test('should not fully unwrap multiple nested wrappers', function (t) { + const { original, shim } = t.nr + let { wrapped } = t.nr for (let i = 0; i < 10; ++i) { wrapped = shim.wrap(wrapped, function () { return function () {} }) } - t.not(wrapped, original) - t.not(wrapped[symbols.original], original) - t.not(shim.unwrapOnce(wrapped), original) - t.end() + assert.notEqual(wrapped, original) + assert.notEqual(wrapped[symbols.original], original) + assert.notEqual(shim.unwrapOnce(wrapped), original) }) - t.test('should unwrap the first parameter', function (t) { - t.equal(shim.unwrapOnce(wrapped), original) - t.end() + await t.test('should unwrap the first parameter', function (t) { + const { original, shim, wrapped } = t.nr + assert.equal(shim.unwrapOnce(wrapped), original) }) - t.test('should not error if `nodule` is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if `nodule` is `null`', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.unwrapOnce(null) }) - t.end() }) - t.test('should accept a single property', function (t) { - t.ok(shim.isWrapped(wrappable.bar)) - t.doesNotThrow(function () { + await t.test('should accept a single property', function (t) { + const { shim, wrappable } = t.nr + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.doesNotThrow(function () { shim.unwrapOnce(wrappable, 'bar') }) - t.notOk(shim.isWrapped(wrappable.bar)) - t.end() + assert.equal(shim.isWrapped(wrappable.bar), false) }) - t.test('should accept an array of properties', function (t) { - t.ok(shim.isWrapped(wrappable.bar)) - t.ok(shim.isWrapped(wrappable.fiz)) - t.ok(shim.isWrapped(wrappable.getActiveSegment)) - t.doesNotThrow(function () { + await t.test('should accept an array of properties', function (t) { + const { shim, wrappable } = t.nr + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.isWrapped(wrappable.fiz), true) + assert.equal(shim.isWrapped(wrappable.getActiveSegment), true) + assert.doesNotThrow(function () { shim.unwrapOnce(wrappable, ['bar', 'fiz', 'getActiveSegment']) }) - t.notOk(shim.isWrapped(wrappable.bar)) - t.notOk(shim.isWrapped(wrappable.fiz)) - t.notOk(shim.isWrapped(wrappable.getActiveSegment)) - t.end() + assert.equal(shim.isWrapped(wrappable.bar), false) + assert.equal(shim.isWrapped(wrappable.fiz), false) + assert.equal(shim.isWrapped(wrappable.getActiveSegment), false) }) - t.test('should not error if a nodule is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if a nodule is `null`', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.unwrapOnce(null, 'bar') }) - t.end() }) - t.test('should not error if a property is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if a property is `null`', function (t) { + const { shim, wrappable } = t.nr + assert.doesNotThrow(function () { shim.unwrapOnce(wrappable, 'this does not exist') }) - t.end() }) }) - t.test('#getSegment', function (t) { - t.autoend() - let segment = null - - t.beforeEach(function () { - beforeEach() - segment = { probe: function () {} } + await t.test('#getSegment', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + ctx.nr.segment = { probe: function () {} } }) t.afterEach(afterEach) - t.test('should return the segment a function is bound to', function (t) { + await t.test('should return the segment a function is bound to', function (t) { + const { segment, shim } = t.nr const bound = shim.bindSegment(function () {}, segment) - t.equal(shim.getSegment(bound), segment) - t.end() + assert.equal(shim.getSegment(bound), segment) }) - t.test('should return the current segment if the function is not bound', function (t) { + await t.test('should return the current segment if the function is not bound', function (t) { + const { contextManager, segment, shim } = t.nr contextManager.setContext(segment) - t.equal( + assert.equal( shim.getSegment(function () {}), segment ) - t.end() }) - t.test('should return the current segment if no object is provided', function (t) { + await t.test('should return the current segment if no object is provided', function (t) { + const { contextManager, segment, shim } = t.nr contextManager.setContext(segment) - t.equal(shim.getSegment(), segment) - t.end() + assert.equal(shim.getSegment(), segment) }) }) - t.test('#getActiveSegment', function (t) { - t.autoend() - let segment = null - - t.beforeEach(function () { - beforeEach() - segment = { + await t.test('#getActiveSegment', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + ctx.nr.segment = { probe: function () {}, transaction: { active: true, @@ -1969,174 +1953,173 @@ tap.test('Shim', function (t) { }) t.afterEach(afterEach) - t.test( + await t.test( 'should return the segment a function is bound to when transaction is active', function (t) { + const { segment, shim } = t.nr const bound = shim.bindSegment(function () {}, segment) - t.equal(shim.getActiveSegment(bound), segment) - t.end() + assert.equal(shim.getActiveSegment(bound), segment) } ) - t.test( + await t.test( 'should return the current segment if the function is not bound when transaction is active', function (t) { + const { contextManager, segment, shim } = t.nr contextManager.setContext(segment) - t.equal( + assert.equal( shim.getActiveSegment(function () {}), segment ) - t.end() } ) - t.test( + await t.test( 'should return the current segment if no object is provided when transaction is active', function (t) { + const { contextManager, segment, shim } = t.nr contextManager.setContext(segment) - t.equal(shim.getActiveSegment(), segment) - t.end() + assert.equal(shim.getActiveSegment(), segment) } ) - t.test('should return null for a bound function when transaction is not active', function (t) { - segment.transaction.active = false - const bound = shim.bindSegment(function () {}, segment) - t.equal(shim.getActiveSegment(bound), null) - t.end() - }) + await t.test( + 'should return null for a bound function when transaction is not active', + function (t) { + const { segment, shim } = t.nr + segment.transaction.active = false + const bound = shim.bindSegment(function () {}, segment) + assert.equal(shim.getActiveSegment(bound), null) + } + ) - t.test( + await t.test( 'should return null if the function is not bound when transaction is not active', function (t) { + const { contextManager, segment, shim } = t.nr segment.transaction.active = false contextManager.setContext(segment) - t.equal( + assert.equal( shim.getActiveSegment(function () {}), null ) - t.end() } ) - t.test( + await t.test( 'should return null if no object is provided when transaction is not active', function (t) { + const { contextManager, segment, shim } = t.nr segment.transaction.active = false contextManager.setContext(segment) - t.equal(shim.getActiveSegment(), null) - t.end() + assert.equal(shim.getActiveSegment(), null) } ) }) - t.test('#storeSegment', function (t) { - t.autoend() + await t.test('#storeSegment', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should store the segment on the object', function (t) { + await t.test('should store the segment on the object', function (t) { + const { shim, wrappable } = t.nr const segment = { probe: function () {} } shim.storeSegment(wrappable, segment) - t.equal(shim.getSegment(wrappable), segment) - t.end() + assert.equal(shim.getSegment(wrappable), segment) }) - t.test('should default to the current segment', function (t) { + await t.test('should default to the current segment', function (t) { + const { contextManager, shim, wrappable } = t.nr const segment = { probe: function () {} } contextManager.setContext(segment) shim.storeSegment(wrappable) - t.equal(shim.getSegment(wrappable), segment) - t.end() + assert.equal(shim.getSegment(wrappable), segment) }) - t.test('should not fail if the object is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not fail if the object is `null`', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.storeSegment(null) }) - t.end() }) }) - t.test('#bindCallbackSegment', function (t) { - t.autoend() - let cbCalled = false - let cb = null - - t.beforeEach(function () { - beforeEach() - cbCalled = false - cb = function () { - cbCalled = true + await t.test('#bindCallbackSegment', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + ctx.nr.cbCalled = false + ctx.nr.cb = function () { + ctx.nr.cbCalled = true } }) t.afterEach(afterEach) - t.test('should wrap the callback in place', function (t) { + await t.test('should wrap the callback in place', function (t) { + const { cb, shim } = t.nr const args = ['a', cb, 'b'] shim.bindCallbackSegment({}, args, shim.SECOND) const [, wrapped] = args - t.ok(wrapped instanceof Function) - t.not(wrapped, cb) - t.same(args, ['a', wrapped, 'b']) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), cb) - t.end() + assert.ok(wrapped instanceof Function) + assert.notEqual(wrapped, cb) + assert.deepEqual(args, ['a', wrapped, 'b']) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), cb) }) - t.test('should work with an array and numeric index', function (t) { + await t.test('should work with an array and numeric index', function (t) { + const { cb, shim } = t.nr const args = ['a', cb, 'b'] shim.bindCallbackSegment({}, args, 1) - t.ok(shim.isWrapped(args[1])) - t.end() + assert.equal(shim.isWrapped(args[1]), true) }) - t.test('should work with an object and a string index', function (t) { + await t.test('should work with an object and a string index', function (t) { + const { cb, shim } = t.nr const opts = { a: 'a', cb: cb, b: 'b' } shim.bindCallbackSegment({}, opts, 'cb') - t.ok(shim.isWrapped(opts, 'cb')) - t.end() + assert.equal(shim.isWrapped(opts, 'cb'), true) }) - t.test('should not error if `args` is `null`', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if `args` is `null`', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.bindCallbackSegment({}, null, 1) }) - t.end() }) - t.test('should not error if the callback does not exist', function (t) { - t.doesNotThrow(function () { + await t.test('should not error if the callback does not exist', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { const args = ['a'] shim.bindCallbackSegment({}, args, 1) }) - t.end() }) - t.test('should not bind if the "callback" is not a function', function (t) { + await t.test('should not bind if the "callback" is not a function', function (t) { + const { shim } = t.nr let args - t.doesNotThrow(function () { + assert.doesNotThrow(function () { args = ['a'] shim.bindCallbackSegment({}, args, 0) }) - t.notOk(shim.isWrapped(args[0])) - t.equal(args[0], 'a') - t.end() + assert.equal(shim.isWrapped(args[0]), false) + assert.equal(args[0], 'a') }) - t.test('should execute the callback', function (t) { + await t.test('should execute the callback', function (t) { + const { shim, cb } = t.nr const args = ['a', 'b', cb] shim.bindCallbackSegment({}, args, shim.LAST) - t.notOk(cbCalled) + assert.equal(t.nr.cbCalled, false) args[2]() - t.ok(cbCalled) - t.end() + assert.equal(t.nr.cbCalled, true) }) - t.test('should create a new segment', function (t) { + await t.test('should create a new segment', function (t, end) { + const { agent, shim, wrappable } = t.nr helper.runInTransaction(agent, function () { const args = [wrappable.getActiveSegment] const segment = wrappable.getActiveSegment() @@ -2144,14 +2127,15 @@ tap.test('Shim', function (t) { shim.bindCallbackSegment({}, args, shim.LAST, parent) const cbSegment = args[0]() - t.not(cbSegment, segment) - t.not(cbSegment, parent) - t.compareSegments(parent, [cbSegment]) - t.end() + assert.notEqual(cbSegment, segment) + assert.notEqual(cbSegment, parent) + compareSegments(parent, [cbSegment]) + end() }) }) - t.test('should make the `parentSegment` translucent after running', function (t) { + await t.test('should make the `parentSegment` translucent after running', function (t, end) { + const { agent, shim, wrappable } = t.nr helper.runInTransaction(agent, function () { const args = [wrappable.getActiveSegment] const parent = shim.createSegment('test segment') @@ -2159,27 +2143,29 @@ tap.test('Shim', function (t) { shim.bindCallbackSegment({}, args, shim.LAST, parent) const cbSegment = args[0]() - t.not(cbSegment, parent) - t.compareSegments(parent, [cbSegment]) - t.notOk(parent.opaque) - t.end() + assert.notEqual(cbSegment, parent) + compareSegments(parent, [cbSegment]) + assert.equal(parent.opaque, false) + end() }) }) - t.test('should default the `parentSegment` to the current one', function (t) { + await t.test('should default the `parentSegment` to the current one', function (t, end) { + const { agent, shim, wrappable } = t.nr helper.runInTransaction(agent, function () { const args = [wrappable.getActiveSegment] const segment = wrappable.getActiveSegment() shim.bindCallbackSegment({}, args, shim.LAST) const cbSegment = args[0]() - t.not(cbSegment, segment) - t.compareSegments(segment, [cbSegment]) - t.end() + assert.notEqual(cbSegment, segment) + compareSegments(segment, [cbSegment]) + end() }) }) - t.test('should call the after hook if specified on the spec', function (t) { + await t.test('should call the after hook if specified on the spec', function (t, end) { + const { agent, shim, wrappable } = t.nr let executed = false const spec = { after() { @@ -2192,21 +2178,18 @@ tap.test('Shim', function (t) { shim.bindCallbackSegment(spec, args, shim.LAST) const cbSegment = args[0]() - t.not(cbSegment, segment) - t.compareSegments(segment, [cbSegment]) - t.ok(executed) - t.end() + assert.notEqual(cbSegment, segment) + compareSegments(segment, [cbSegment]) + assert.equal(executed, true) + end() }) }) }) - t.test('#applySegment', function (t) { - t.autoend() - let segment - - t.beforeEach(function () { - beforeEach() - segment = { + await t.test('#applySegment', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + ctx.nr.segment = { name: 'segment', started: false, touched: false, @@ -2223,16 +2206,17 @@ tap.test('Shim', function (t) { }) t.afterEach(afterEach) - t.test('should call the function with the `context` and `args`', function (t) { + await t.test('should call the function with the `context` and `args`', function (t) { + const { segment, shim } = t.nr const context = { name: 'context' } const value = { name: 'value' } const ret = shim.applySegment( function (a, b, c) { - t.equal(this, context) - t.equal(arguments.length, 3) - t.equal(a, 'a') - t.equal(b, 'b') - t.equal(c, 'c') + assert.equal(this, context) + assert.equal(arguments.length, 3) + assert.equal(a, 'a') + assert.equal(b, 'b') + assert.equal(c, 'c') return value }, segment, @@ -2241,159 +2225,166 @@ tap.test('Shim', function (t) { ['a', 'b', 'c'] ) - t.equal(ret, value) - t.end() - }) - - t.test('should execute the inContext callback under the produced segment', function (t) { - shim.applySegment( - function () {}, - segment, - false, - {}, - [], - function checkSegment(activeSegment) { - t.equal(activeSegment, segment) - t.equal(contextManager.getContext(), segment) - t.end() - } - ) - }) + assert.equal(ret, value) + }) + + await t.test( + 'should execute the inContext callback under the produced segment', + function (t, end) { + const { contextManager, segment, shim } = t.nr + shim.applySegment( + function () {}, + segment, + false, + {}, + [], + function checkSegment(activeSegment) { + assert.equal(activeSegment, segment) + assert.equal(contextManager.getContext(), segment) + end() + } + ) + } + ) - t.test('should make the segment active for the duration of execution', function (t) { + await t.test('should make the segment active for the duration of execution', function (t) { + const { contextManager, segment, shim, wrappable } = t.nr const prevSegment = { name: 'prevSegment', probe: function () {} } contextManager.setContext(prevSegment) const activeSegment = shim.applySegment(wrappable.getActiveSegment, segment) - t.equal(contextManager.getContext(), prevSegment) - t.equal(activeSegment, segment) - t.notOk(segment.touched) - t.notOk(segment.started) - t.end() + assert.equal(contextManager.getContext(), prevSegment) + assert.equal(activeSegment, segment) + assert.equal(segment.touched, false) + assert.equal(segment.started, false) }) - t.test('should start and touch the segment if `full` is `true`', function (t) { + await t.test('should start and touch the segment if `full` is `true`', function (t) { + const { segment, shim, wrappable } = t.nr shim.applySegment(wrappable.getActiveSegment, segment, true) - t.ok(segment.touched) - t.ok(segment.started) - t.end() + assert.equal(segment.touched, true) + assert.equal(segment.started, true) }) - t.test('should not change the active segment if `segment` is `null`', function (t) { + await t.test('should not change the active segment if `segment` is `null`', function (t) { + const { contextManager, segment, shim, wrappable } = t.nr contextManager.setContext(segment) let activeSegment = null - t.doesNotThrow(function () { + assert.doesNotThrow(function () { activeSegment = shim.applySegment(wrappable.getActiveSegment, null) }) - t.equal(contextManager.getContext(), segment) - t.equal(activeSegment, segment) - t.end() + assert.equal(contextManager.getContext(), segment) + assert.equal(activeSegment, segment) }) - t.test('should not throw in a transaction when `func` has no `.apply` method', (t) => { + await t.test('should not throw in a transaction when `func` has no `.apply` method', (t) => { + const { segment, shim } = t.nr const func = function () {} func.__proto__ = {} - t.notOk(func.apply) - t.doesNotThrow(() => shim.applySegment(func, segment)) - t.end() + assert.ok(!func.apply) + assert.doesNotThrow(() => shim.applySegment(func, segment)) }) - t.test('should not throw out of a transaction', (t) => { + await t.test('should not throw out of a transaction', (t) => { + const { shim } = t.nr const func = function () {} func.__proto__ = {} - t.notOk(func.apply) - t.doesNotThrow(() => shim.applySegment(func, null)) - t.end() + assert.ok(!func.apply) + assert.doesNotThrow(() => shim.applySegment(func, null)) }) - t.test('should not swallow the exception when `func` throws an exception', function (t) { + await t.test('should not swallow the exception when `func` throws an exception', function (t) { + const { segment, shim } = t.nr const func = function () { throw new Error('test error') } - t.throws(function () { + assert.throws(function () { shim.applySegment(func, segment) - }, 'test error') - t.end() + }, 'Error: test error') }) - t.test( + await t.test( 'should still return the active segment to the previous one when `func` throws an exception', function (t) { + const { contextManager, segment, shim } = t.nr const func = function () { throw new Error('test error') } const prevSegment = { name: 'prevSegment', probe: function () {} } contextManager.setContext(prevSegment) - t.throws(function () { + assert.throws(function () { shim.applySegment(func, segment) - }, 'test error') + }, 'Error: test error') - t.equal(contextManager.getContext(), prevSegment) - t.end() + assert.equal(contextManager.getContext(), prevSegment) } ) - t.test( + await t.test( 'should still touch the segment if `full` is `true` when `func` throws an exception', function (t) { + const { segment, shim } = t.nr const func = function () { throw new Error('test error') } - t.throws(function () { + assert.throws(function () { shim.applySegment(func, segment, true) - }, 'test error') + }, 'Error: test error') - t.ok(segment.touched) - t.end() + assert.equal(segment.touched, true) } ) }) - t.test('#createSegment', function (t) { - t.autoend() + await t.test('#createSegment', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should create a segment with the correct name', function (t) { + await t.test('should create a segment with the correct name', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const segment = shim.createSegment('foobar') - t.equal(segment.name, 'foobar') - t.end() + assert.equal(segment.name, 'foobar') + end() }) }) - t.test('should allow `recorder` to be omitted', function (t) { + await t.test('should allow `recorder` to be omitted', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const parent = shim.createSegment('parent') const child = shim.createSegment('child', parent) - t.equal(child.name, 'child') - t.compareSegments(parent, [child]) - t.end() + assert.equal(child.name, 'child') + compareSegments(parent, [child]) + end() }) }) - t.test('should allow `recorder` to be null', function (t) { + await t.test('should allow `recorder` to be null', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const parent = shim.createSegment('parent') const child = shim.createSegment('child', null, parent) - t.equal(child.name, 'child') - t.compareSegments(parent, [child]) - t.end() + assert.equal(child.name, 'child') + compareSegments(parent, [child]) + end() }) }) - t.test('should not create children for opaque segments', function (t) { + await t.test('should not create children for opaque segments', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const parent = shim.createSegment('parent') parent.opaque = true const child = shim.createSegment('child', parent) - t.equal(child.name, 'parent') - t.same(parent.children, []) - t.end() + assert.equal(child.name, 'parent') + assert.deepEqual(parent.children, []) + end() }) }) - t.test('should not modify returned parent for opaque segments', (t) => { + await t.test('should not modify returned parent for opaque segments', (t, end) => { + const { agent, shim } = t.nr helper.runInTransaction(agent, () => { const parent = shim.createSegment('parent') parent.opaque = true @@ -2401,23 +2392,25 @@ tap.test('Shim', function (t) { const child = shim.createSegment('child', parent) - t.equal(child, parent) - t.ok(parent.opaque) - t.ok(parent.internal) - t.end() + assert.equal(child, parent) + assert.equal(parent.opaque, true) + assert.equal(parent.internal, true) + end() }) }) - t.test('should default to the current segment as the parent', function (t) { + await t.test('should default to the current segment as the parent', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const parent = shim.getSegment() const child = shim.createSegment('child') - t.compareSegments(parent, [child]) - t.end() + compareSegments(parent, [child]) + end() }) }) - t.test('should not modify returned parent for opaque segments', (t) => { + await t.test('should not modify returned parent for opaque segments', (t, end) => { + const { agent, shim } = t.nr helper.runInTransaction(agent, () => { const parent = shim.createSegment('parent') parent.opaque = true @@ -2427,32 +2420,30 @@ tap.test('Shim', function (t) { const child = shim.createSegment('child') - t.equal(child, parent) - t.ok(parent.opaque) - t.ok(parent.internal) - t.end() + assert.equal(child, parent) + assert.equal(parent.opaque, true) + assert.equal(parent.internal, true) + end() }) }) - t.test('should work with all parameters in an object', function (t) { + await t.test('should work with all parameters in an object', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const parent = shim.createSegment('parent') const child = shim.createSegment({ name: 'child', parent }) - t.equal(child.name, 'child') - t.compareSegments(parent, [child]) - t.end() + assert.equal(child.name, 'child') + compareSegments(parent, [child]) + end() }) }) }) - t.test('#createSegment when an `parameters` object is provided', function (t) { - t.autoend() - let segment = null - let parameters = null - - t.beforeEach(function () { - beforeEach() - parameters = { + await t.test('#createSegment when an `parameters` object is provided', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { agent, shim } = ctx.nr + const parameters = { host: 'my awesome host', port_path_or_id: 1234, database_name: 'my_db', @@ -2465,523 +2456,507 @@ tap.test('Shim', function (t) { agent.config.emit('attributes.exclude') agent.config.attributes.enabled = true helper.runInTransaction(agent, function () { - segment = shim.createSegment({ name: 'child', parameters: parameters }) + ctx.nr.segment = shim.createSegment({ name: 'child', parameters }) }) + ctx.nr.parameters = parameters }) t.afterEach(afterEach) - t.test( + await t.test( 'should copy parameters provided into `segment.parameters` and `attributes.enabled` is true', function (t) { - t.ok(segment.attributes) + const { segment } = t.nr + assert.ok(segment.attributes) const attributes = segment.getAttributes() - t.equal(attributes.foo, 'bar') - t.equal(attributes.fiz, 'bang') - t.end() + assert.equal(attributes.foo, 'bar') + assert.equal(attributes.fiz, 'bang') } ) - t.test( + await t.test( 'should be affected by `attributes.exclude` and `attributes.enabled` is true', function (t) { - t.ok(segment.attributes) + const { segment } = t.nr + assert.ok(segment.attributes) const attributes = segment.getAttributes() - t.equal(attributes.foo, 'bar') - t.equal(attributes.fiz, 'bang') - t.notOk(attributes.ignore_me) - t.notOk(attributes.host) - t.notOk(attributes.port_path_or_id) - t.notOk(attributes.database_name) - t.end() + assert.equal(attributes.foo, 'bar') + assert.equal(attributes.fiz, 'bang') + assert.ok(!attributes.ignore_me) + assert.ok(!attributes.host) + assert.ok(!attributes.port_path_or_id) + assert.ok(!attributes.database_name) } ) - t.test( + await t.test( 'should not copy parameters into segment attributes when `attributes.enabled` is fale', function (t) { + const { agent, parameters, shim } = t.nr + let segment agent.config.attributes.enabled = false helper.runInTransaction(agent, function () { segment = shim.createSegment({ name: 'child', parameters }) }) - t.ok(segment.attributes) + assert.ok(segment.attributes) const attributes = segment.getAttributes() - t.notOk(attributes.foo) - t.notOk(attributes.fiz) - t.notOk(attributes.ignore_me) - t.notOk(attributes.host) - t.notOk(attributes.port_path_or_id) - t.notOk(attributes.database_name) - t.end() + assert.ok(!attributes.foo) + assert.ok(!attributes.fiz) + assert.ok(!attributes.ignore_me) + assert.ok(!attributes.host) + assert.ok(!attributes.port_path_or_id) + assert.ok(!attributes.database_name) } ) }) - t.test('#getName', function (t) { - t.autoend() + await t.test('#getName', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should return the `name` property of an object if it has one', function (t) { - t.equal(shim.getName({ name: 'foo' }), 'foo') - t.equal( + await t.test('should return the `name` property of an object if it has one', function (t) { + const { shim } = t.nr + assert.equal(shim.getName({ name: 'foo' }), 'foo') + assert.equal( shim.getName(function bar() {}), 'bar' ) - t.end() }) - t.test('should return "" if the object has no name', function (t) { - t.equal(shim.getName({}), '') - t.equal( + await t.test('should return "" if the object has no name', function (t) { + const { shim } = t.nr + assert.equal(shim.getName({}), '') + assert.equal( shim.getName(function () {}), '' ) - t.end() }) }) - t.test('#isObject', function (t) { - t.autoend() + await t.test('#isObject', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should detect if an item is an object', function (t) { - t.equal(shim.isObject({}), true) - t.equal(shim.isObject([]), true) - t.equal(shim.isObject(arguments), true) - t.equal( + await t.test('should detect if an item is an object', function (t) { + const { shim } = t.nr + assert.equal(shim.isObject({}), true) + assert.equal(shim.isObject([]), true) + assert.equal(shim.isObject(arguments), true) + assert.equal( shim.isObject(function () {}), true ) - t.equal(shim.isObject(Object.create(null)), true) - t.equal(shim.isObject(true), false) - t.equal(shim.isObject(false), false) - t.equal(shim.isObject('foobar'), false) - t.equal(shim.isObject(1234), false) - t.equal(shim.isObject(null), false) - t.equal(shim.isObject(undefined), false) - t.end() + assert.equal(shim.isObject(Object.create(null)), true) + assert.equal(shim.isObject(true), false) + assert.equal(shim.isObject(false), false) + assert.equal(shim.isObject('foobar'), false) + assert.equal(shim.isObject(1234), false) + assert.equal(shim.isObject(null), false) + assert.equal(shim.isObject(undefined), false) }) }) - t.test('#isFunction', function (t) { - t.autoend() + await t.test('#isFunction', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should detect if an item is a function', function (t) { - t.ok(shim.isFunction(function () {})) - t.notOk(shim.isFunction({})) - t.notOk(shim.isFunction([])) - t.notOk(shim.isFunction(arguments)) - t.notOk(shim.isFunction(true)) - t.notOk(shim.isFunction(false)) - t.notOk(shim.isFunction('foobar')) - t.notOk(shim.isFunction(1234)) - t.notOk(shim.isFunction(null)) - t.notOk(shim.isFunction(undefined)) - t.end() + await t.test('should detect if an item is a function', function (t) { + const { shim } = t.nr + assert.ok(shim.isFunction(function () {})) + assert.ok(!shim.isFunction({})) + assert.ok(!shim.isFunction([])) + assert.ok(!shim.isFunction(arguments)) + assert.ok(!shim.isFunction(true)) + assert.ok(!shim.isFunction(false)) + assert.ok(!shim.isFunction('foobar')) + assert.ok(!shim.isFunction(1234)) + assert.ok(!shim.isFunction(null)) + assert.ok(!shim.isFunction(undefined)) }) }) - t.test('#isString', function (t) { - t.autoend() + await t.test('#isString', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should detect if an item is a string', function (t) { - t.ok(shim.isString('foobar')) - t.ok(shim.isString(new String('foobar'))) - t.notOk(shim.isString({})) - t.notOk(shim.isString([])) - t.notOk(shim.isString(arguments)) - t.notOk(shim.isString(function () {})) - t.notOk(shim.isString(true)) - t.notOk(shim.isString(false)) - t.notOk(shim.isString(1234)) - t.notOk(shim.isString(null)) - t.notOk(shim.isString(undefined)) - t.end() + await t.test('should detect if an item is a string', function (t) { + const { shim } = t.nr + assert.ok(shim.isString('foobar')) + assert.ok(shim.isString(new String('foobar'))) + assert.ok(!shim.isString({})) + assert.ok(!shim.isString([])) + assert.ok(!shim.isString(arguments)) + assert.ok(!shim.isString(function () {})) + assert.ok(!shim.isString(true)) + assert.ok(!shim.isString(false)) + assert.ok(!shim.isString(1234)) + assert.ok(!shim.isString(null)) + assert.ok(!shim.isString(undefined)) }) }) - t.test('#isNumber', function (t) { - t.autoend() + await t.test('#isNumber', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should detect if an item is a number', function (t) { - t.ok(shim.isNumber(1234)) - t.notOk(shim.isNumber({})) - t.notOk(shim.isNumber([])) - t.notOk(shim.isNumber(arguments)) - t.notOk(shim.isNumber(function () {})) - t.notOk(shim.isNumber(true)) - t.notOk(shim.isNumber(false)) - t.notOk(shim.isNumber('foobar')) - t.notOk(shim.isNumber(null)) - t.notOk(shim.isNumber(undefined)) - t.end() + await t.test('should detect if an item is a number', function (t) { + const { shim } = t.nr + assert.ok(shim.isNumber(1234)) + assert.ok(!shim.isNumber({})) + assert.ok(!shim.isNumber([])) + assert.ok(!shim.isNumber(arguments)) + assert.ok(!shim.isNumber(function () {})) + assert.ok(!shim.isNumber(true)) + assert.ok(!shim.isNumber(false)) + assert.ok(!shim.isNumber('foobar')) + assert.ok(!shim.isNumber(null)) + assert.ok(!shim.isNumber(undefined)) }) }) - t.test('#isBoolean', function (t) { - t.autoend() + await t.test('#isBoolean', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should detect if an item is a boolean', function (t) { - t.ok(shim.isBoolean(true)) - t.ok(shim.isBoolean(false)) - t.notOk(shim.isBoolean({})) - t.notOk(shim.isBoolean([])) - t.notOk(shim.isBoolean(arguments)) - t.notOk(shim.isBoolean(function () {})) - t.notOk(shim.isBoolean('foobar')) - t.notOk(shim.isBoolean(1234)) - t.notOk(shim.isBoolean(null)) - t.notOk(shim.isBoolean(undefined)) - t.end() + await t.test('should detect if an item is a boolean', function (t) { + const { shim } = t.nr + assert.ok(shim.isBoolean(true)) + assert.ok(shim.isBoolean(false)) + assert.ok(!shim.isBoolean({})) + assert.ok(!shim.isBoolean([])) + assert.ok(!shim.isBoolean(arguments)) + assert.ok(!shim.isBoolean(function () {})) + assert.ok(!shim.isBoolean('foobar')) + assert.ok(!shim.isBoolean(1234)) + assert.ok(!shim.isBoolean(null)) + assert.ok(!shim.isBoolean(undefined)) }) }) - t.test('#isArray', function (t) { - t.autoend() + await t.test('#isArray', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should detect if an item is an array', function (t) { - t.ok(shim.isArray([])) - t.notOk(shim.isArray({})) - t.notOk(shim.isArray(arguments)) - t.notOk(shim.isArray(function () {})) - t.notOk(shim.isArray(true)) - t.notOk(shim.isArray(false)) - t.notOk(shim.isArray('foobar')) - t.notOk(shim.isArray(1234)) - t.notOk(shim.isArray(null)) - t.notOk(shim.isArray(undefined)) - t.end() + await t.test('should detect if an item is an array', function (t) { + const { shim } = t.nr + assert.ok(shim.isArray([])) + assert.ok(!shim.isArray({})) + assert.ok(!shim.isArray(arguments)) + assert.ok(!shim.isArray(function () {})) + assert.ok(!shim.isArray(true)) + assert.ok(!shim.isArray(false)) + assert.ok(!shim.isArray('foobar')) + assert.ok(!shim.isArray(1234)) + assert.ok(!shim.isArray(null)) + assert.ok(!shim.isArray(undefined)) }) }) - t.test('#isNull', function (t) { - t.autoend() + await t.test('#isNull', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should detect if an item is null', function (t) { - t.ok(shim.isNull(null)) - t.notOk(shim.isNull({})) - t.notOk(shim.isNull([])) - t.notOk(shim.isNull(arguments)) - t.notOk(shim.isNull(function () {})) - t.notOk(shim.isNull(true)) - t.notOk(shim.isNull(false)) - t.notOk(shim.isNull('foobar')) - t.notOk(shim.isNull(1234)) - t.notOk(shim.isNull(undefined)) - t.end() + await t.test('should detect if an item is null', function (t) { + const { shim } = t.nr + assert.ok(shim.isNull(null)) + assert.ok(!shim.isNull({})) + assert.ok(!shim.isNull([])) + assert.ok(!shim.isNull(arguments)) + assert.ok(!shim.isNull(function () {})) + assert.ok(!shim.isNull(true)) + assert.ok(!shim.isNull(false)) + assert.ok(!shim.isNull('foobar')) + assert.ok(!shim.isNull(1234)) + assert.ok(!shim.isNull(undefined)) }) }) - t.test('#toArray', function (t) { - t.autoend() + await t.test('#toArray', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should convert array-like objects into arrays', function (t) { + await t.test('should convert array-like objects into arrays', function (t) { + const { shim } = t.nr const res = ['a', 'b', 'c', 'd'] const resToArray = shim.toArray(res) - t.same(resToArray, res) - t.ok(resToArray instanceof Array) + assert.deepEqual(resToArray, res) + assert.ok(resToArray instanceof Array) const strToArray = shim.toArray('abcd') - t.same(strToArray, res) - t.ok(strToArray instanceof Array) + assert.deepEqual(strToArray, res) + assert.ok(strToArray instanceof Array) argumentsTest.apply(null, res) function argumentsTest() { const argsToArray = shim.toArray(arguments) - t.same(argsToArray, res) - t.ok(argsToArray instanceof Array) + assert.deepEqual(argsToArray, res) + assert.ok(argsToArray instanceof Array) } - t.end() }) }) - t.test('#normalizeIndex', function (t) { - t.autoend() - let args = null - - t.beforeEach(function () { - beforeEach() - args = [1, 2, 3, 4] + await t.test('#normalizeIndex', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + ctx.nr.args = [1, 2, 3, 4] }) t.afterEach(afterEach) - t.test('should return the index if it is already normal', function (t) { - t.equal(shim.normalizeIndex(args.length, 0), 0) - t.equal(shim.normalizeIndex(args.length, 1), 1) - t.equal(shim.normalizeIndex(args.length, 3), 3) - t.end() + await t.test('should return the index if it is already normal', function (t) { + const { args, shim } = t.nr + assert.equal(shim.normalizeIndex(args.length, 0), 0) + assert.equal(shim.normalizeIndex(args.length, 1), 1) + assert.equal(shim.normalizeIndex(args.length, 3), 3) }) - t.test('should offset negative indexes from the end of the array', function (t) { - t.equal(shim.normalizeIndex(args.length, -1), 3) - t.equal(shim.normalizeIndex(args.length, -2), 2) - t.equal(shim.normalizeIndex(args.length, -4), 0) - t.end() + await t.test('should offset negative indexes from the end of the array', function (t) { + const { args, shim } = t.nr + assert.equal(shim.normalizeIndex(args.length, -1), 3) + assert.equal(shim.normalizeIndex(args.length, -2), 2) + assert.equal(shim.normalizeIndex(args.length, -4), 0) }) - t.test('should return `null` for invalid indexes', function (t) { - t.equal(shim.normalizeIndex(args.length, 4), null) - t.equal(shim.normalizeIndex(args.length, 10), null) - t.equal(shim.normalizeIndex(args.length, -5), null) - t.equal(shim.normalizeIndex(args.length, -10), null) - t.end() + await t.test('should return `null` for invalid indexes', function (t) { + const { args, shim } = t.nr + assert.equal(shim.normalizeIndex(args.length, 4), null) + assert.equal(shim.normalizeIndex(args.length, 10), null) + assert.equal(shim.normalizeIndex(args.length, -5), null) + assert.equal(shim.normalizeIndex(args.length, -10), null) }) }) - t.test('#defineProperty', function (t) { - t.autoend() + await t.test('#defineProperty', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should create an enumerable, configurable property', function (t) { + await t.test('should create an enumerable, configurable property', function (t) { + const { shim } = t.nr const obj = {} shim.defineProperty(obj, 'foo', 'bar') const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo') - t.ok(descriptor.configurable) - t.ok(descriptor.enumerable) - t.end() + assert.equal(descriptor.configurable, true) + assert.equal(descriptor.enumerable, true) }) - t.test('should create an unwritable property when `value` is not a function', function (t) { - const obj = {} - shim.defineProperty(obj, 'foo', 'bar') - const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo') - - t.notOk(descriptor.writable) - t.notOk(descriptor.get) - t.equal(descriptor.value, 'bar') - t.end() - }) + await t.test( + 'should create an unwritable property when `value` is not a function', + function (t) { + const { shim } = t.nr + const obj = {} + shim.defineProperty(obj, 'foo', 'bar') + const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo') + + assert.ok(!descriptor.writable) + assert.ok(!descriptor.get) + assert.equal(descriptor.value, 'bar') + } + ) - t.test('should create a getter when `value` is a function', function (t) { + await t.test('should create a getter when `value` is a function', function (t) { + const { shim } = t.nr const obj = {} shim.defineProperty(obj, 'foo', function () { return 'bar' }) const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo') - t.ok(descriptor.configurable) - t.ok(descriptor.enumerable) - t.ok(descriptor.get instanceof Function) - t.notOk(descriptor.value) - t.end() + assert.equal(descriptor.configurable, true) + assert.equal(descriptor.enumerable, true) + assert.ok(descriptor.get instanceof Function) + assert.ok(!descriptor.value) }) }) - t.test('#defineProperties', function (t) { - t.autoend() + await t.test('#defineProperties', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should create properties for each key on `props`', function (t) { + await t.test('should create properties for each key on `props`', function (t) { + const { shim } = t.nr const obj = {} const props = { foo: 'bar', fiz: 'bang' } shim.defineProperties(obj, props) - t.equal(obj.foo, 'bar') - t.equal(obj.fiz, 'bang') - t.end() + assert.equal(obj.foo, 'bar') + assert.equal(obj.fiz, 'bang') }) }) - t.test('#setDefaults', function (t) { - t.autoend() + await t.test('#setDefaults', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should copy over defaults when provided object is null', function (t) { + await t.test('should copy over defaults when provided object is null', function (t) { + const { shim } = t.nr const obj = null const defaults = { foo: 1, bar: 2 } const defaulted = shim.setDefaults(obj, defaults) - t.not(obj, defaults) - t.not(obj, defaulted) - t.same(defaulted, defaults) - t.end() + assert.notEqual(obj, defaults) + assert.notEqual(obj, defaulted) + assert.deepEqual(defaulted, defaults) }) - t.test('should copy each key over', function (t) { + await t.test('should copy each key over', function (t) { + const { shim } = t.nr const obj = {} const defaults = { foo: 1, bar: 2 } const defaulted = shim.setDefaults(obj, defaults) - t.equal(obj, defaulted) - t.not(obj, defaults) - t.same(defaulted, defaults) - t.end() + assert.equal(obj, defaulted) + assert.notEqual(obj, defaults) + assert.deepEqual(defaulted, defaults) }) - t.test('should update existing if existing is null', function (t) { + await t.test('should update existing if existing is null', function (t) { + const { shim } = t.nr const obj = { foo: null } const defaults = { foo: 1, bar: 2 } const defaulted = shim.setDefaults(obj, defaults) - t.equal(obj, defaulted) - t.not(obj, defaults) - t.same(defaulted, { foo: 1, bar: 2 }) - t.end() + assert.equal(obj, defaulted) + assert.notEqual(obj, defaults) + assert.deepEqual(defaulted, { foo: 1, bar: 2 }) }) }) - t.test('#proxy', function (t) { - t.autoend() - let original = null - let proxied = null - - t.beforeEach(function () { - beforeEach() - original = { foo: 1, bar: 2, biz: 3, baz: 4 } - proxied = {} + await t.test('#proxy', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + ctx.nr.original = { foo: 1, bar: 2, biz: 3, baz: 4 } + ctx.nr.proxied = {} }) - t.afterEach(function () { - afterEach() - original = null - proxied = null - }) + t.afterEach(afterEach) - t.test('should proxy individual properties', function (t) { + await t.test('should proxy individual properties', function (t) { + const { original, proxied, shim } = t.nr shim.proxy(original, 'foo', proxied) - t.ok(original.foo, 1) - t.ok(proxied.foo, 1) - t.notOk(proxied.bar) - t.notOk(proxied.biz) + assert.equal(original.foo, 1) + assert.equal(proxied.foo, 1) + assert.ok(!proxied.bar) + assert.ok(!proxied.biz) proxied.foo = 'other' - t.equal(original.foo, 'other') - t.end() + assert.equal(original.foo, 'other') }) - t.test('should proxy arrays of properties', function (t) { + await t.test('should proxy arrays of properties', function (t) { + const { original, proxied, shim } = t.nr shim.proxy(original, ['foo', 'bar'], proxied) - t.equal(original.foo, 1) - t.equal(original.bar, 2) - t.equal(proxied.foo, 1) - t.equal(proxied.bar, 2) - t.notOk(proxied.biz) + assert.equal(original.foo, 1) + assert.equal(original.bar, 2) + assert.equal(proxied.foo, 1) + assert.equal(proxied.bar, 2) + assert.ok(!proxied.biz) proxied.foo = 'other' - t.equal(original.foo, 'other') - t.equal(original.bar, 2) + assert.equal(original.foo, 'other') + assert.equal(original.bar, 2) proxied.bar = 'another' - t.equal(original.foo, 'other') - t.equal(original.bar, 'another') - t.end() + assert.equal(original.foo, 'other') + assert.equal(original.bar, 'another') }) }) - t.test('assignOriginal', (t) => { + await t.test('assignOriginal', async (t) => { const mod = 'originalShimTests' - t.autoend() - t.beforeEach(beforeEach) + + t.beforeEach((ctx) => { + beforeEach(ctx) + const { agent } = ctx.nr + ctx.nr.shim = new Shim(agent, mod, mod) + }) t.afterEach(afterEach) - t.test('should assign shim id to wrapped item as symbol', (t) => { - const shim = new Shim(agent, mod, mod) + await t.test('should assign shim id to wrapped item as symbol', (t) => { + const { shim } = t.nr const wrapped = function wrapped() {} const original = function original() {} shim.assignOriginal(wrapped, original) - t.equal(wrapped[symbols.wrapped], shim.id) - t.end() + assert.equal(wrapped[symbols.wrapped], shim.id) }) - t.test('should assign original on wrapped item as symbol', (t) => { - const shim = new Shim(agent, mod, mod) + await t.test('should assign original on wrapped item as symbol', (t) => { + const { shim } = t.nr const wrapped = function wrapped() {} const original = function original() {} shim.assignOriginal(wrapped, original) - t.equal(wrapped[symbols.original], original) - t.end() + assert.equal(wrapped[symbols.original], original) }) - t.test('should should overwrite original when forceOrig is true', (t) => { - const shim = new Shim(agent, mod, mod) + await t.test('should should overwrite original when forceOrig is true', (t) => { + const { shim } = t.nr const wrapped = function wrapped() {} const original = function original() {} const firstOriginal = function firstOriginal() {} wrapped[symbols.original] = firstOriginal shim.assignOriginal(wrapped, original, true) - t.equal(wrapped[symbols.original], original) - t.end() + assert.equal(wrapped[symbols.original], original) }) - t.test('should not assign original if symbol already exists on wrapped item', (t) => { - const shim = new Shim(agent, mod, mod) + await t.test('should not assign original if symbol already exists on wrapped item', (t) => { + const { shim } = t.nr const wrapped = function wrapped() {} const original = function original() {} const firstOriginal = function firstOriginal() {} wrapped[symbols.original] = firstOriginal shim.assignOriginal(wrapped, original) - t.not(wrapped[symbols.original], original) - t.equal(wrapped[symbols.original], firstOriginal) - t.end() + assert.notEqual(wrapped[symbols.original], original) + assert.equal(wrapped[symbols.original], firstOriginal) }) }) - t.test('assignId', (t) => { + await t.test('assignId', async (t) => { const mod1 = 'mod1' const mod2 = 'mod2' - t.autoend() + t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should assign an id to a shim instance', (t) => { + await t.test('should assign an id to a shim instance', (t) => { + const { agent } = t.nr const shim = new Shim(agent, mod1, mod1) - t.ok(shim.id) - t.end() + assert.ok(shim.id) }) - t.test('should associate same id to a different shim instance when shimName matches', (t) => { - const shim = new Shim(agent, mod1, mod1, mod1) - const shim2 = new Shim(agent, mod2, mod2, mod1) - t.equal(shim.id, shim2.id, 'ids should be the same') - t.end() - }) + await t.test( + 'should associate same id to a different shim instance when shimName matches', + (t) => { + const { agent } = t.nr + const shim = new Shim(agent, mod1, mod1, mod1) + const shim2 = new Shim(agent, mod2, mod2, mod1) + assert.equal(shim.id, shim2.id, 'ids should be the same') + } + ) - t.test('should not associate id when shimName does not match', (t) => { + await t.test('should not associate id when shimName does not match', (t) => { + const { agent } = t.nr const shim = new Shim(agent, mod1, mod1, mod1) const shim2 = new Shim(agent, mod2, mod2, mod2) - t.not(shim.id, shim2.id, 'ids should not be the same') - t.end() + assert.notEqual(shim.id, shim2.id, 'ids should not be the same') }) }) - t.test('prefixRouteParameters', (t) => { - t.autoend() + await t.test('prefixRouteParameters', async (t) => { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not prefix parameters when given invalid input', (t) => { + await t.test('should not prefix parameters when given invalid input', (t) => { + const { shim } = t.nr const resultNull = shim.prefixRouteParameters(null) - t.equal(resultNull, undefined) + assert.equal(resultNull, undefined) const resultString = shim.prefixRouteParameters('parameters') - t.equal(resultString, undefined) - t.end() + assert.equal(resultString, undefined) }) - t.test('should return the object with route param prefix applied to keys', (t) => { + await t.test('should return the object with route param prefix applied to keys', (t) => { + const { shim } = t.nr const result = shim.prefixRouteParameters({ id: '123abc', foo: 'bar' }) - t.same(result, { + assert.deepEqual(result, { 'request.parameters.route.id': '123abc', 'request.parameters.route.foo': 'bar' }) - t.end() }) }) - t.test('getOriginalOnce', (t) => { - t.autoend() + await t.test('getOriginalOnce', async (t) => { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should return the function on original symbol', (t) => { + await t.test('should return the function on original symbol', (t) => { + const { shim, wrappable } = t.nr const orig = wrappable.bar shim.wrap(wrappable, 'bar', function wrapBar(_shim, fn) { return function wrappedBar() { @@ -2990,13 +2965,13 @@ tap.test('Shim', function (t) { } }) - t.same(orig, shim.getOriginalOnce(wrappable.bar), 'should get original') - t.end() + assert.deepEqual(orig, shim.getOriginalOnce(wrappable.bar), 'should get original') }) - t.test( + await t.test( 'should return the function on original symbol for a given property of a module', (t) => { + const { shim, wrappable } = t.nr const orig = wrappable.bar shim.wrap(wrappable, 'bar', function wrapBar(_shim, fn) { return function wrappedBar() { @@ -3005,12 +2980,12 @@ tap.test('Shim', function (t) { } }) - t.same(orig, shim.getOriginalOnce(wrappable, 'bar'), 'should get original') - t.end() + assert.deepEqual(orig, shim.getOriginalOnce(wrappable, 'bar'), 'should get original') } ) - t.test('should not return original if wrapped twice', (t) => { + await t.test('should not return original if wrapped twice', (t) => { + const { shim, wrappable } = t.nr const orig = wrappable.bar shim.wrap(wrappable, 'bar', function wrapBar(_shim, fn) { return function wrappedBar() { @@ -3027,24 +3002,23 @@ tap.test('Shim', function (t) { }) const notOrig = shim.getOriginalOnce(wrappable.bar) - t.not(orig, notOrig, 'should not be original but first wrapped') - t.equal(notOrig.name, 'wrappedBar', 'should be the first wrapped function name') - t.end() + assert.notEqual(orig, notOrig, 'should not be original but first wrapped') + assert.equal(notOrig.name, 'wrappedBar', 'should be the first wrapped function name') }) - t.test('should not return if module is undefined', (t) => { + await t.test('should not return if module is undefined', (t) => { + const { shim } = t.nr const nodule = undefined - t.equal(shim.getOriginalOnce(nodule), undefined) - t.end() + assert.equal(shim.getOriginalOnce(nodule), undefined) }) }) - t.test('getOriginal', (t) => { - t.autoend() + await t.test('getOriginal', async (t) => { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should return the function on original symbol', (t) => { + await t.test('should return the function on original symbol', (t) => { + const { shim, wrappable } = t.nr const orig = wrappable.bar shim.wrap(wrappable, 'bar', function wrapBar(_shim, fn) { return function wrappedBar() { @@ -3060,13 +3034,13 @@ tap.test('Shim', function (t) { } }) - t.same(orig, shim.getOriginal(wrappable.bar), 'should get original') - t.end() + assert.deepEqual(orig, shim.getOriginal(wrappable.bar), 'should get original') }) - t.test( + await t.test( 'should return the function on original symbol for a given property of a module', (t) => { + const { shim, wrappable } = t.nr const orig = wrappable.bar shim.wrap(wrappable, 'bar', function wrapBar(_shim, fn) { return function wrappedBar() { @@ -3082,90 +3056,84 @@ tap.test('Shim', function (t) { } }) - t.same(orig, shim.getOriginal(wrappable, 'bar'), 'should get original') - t.end() + assert.deepEqual(orig, shim.getOriginal(wrappable, 'bar'), 'should get original') } ) - t.test('should not return if module is undefined', (t) => { + await t.test('should not return if module is undefined', (t) => { + const { shim } = t.nr const nodule = undefined - t.equal(shim.getOriginal(nodule), undefined) - t.end() + assert.equal(shim.getOriginal(nodule), undefined) }) }) - t.test('_moduleRoot', (t) => { - t.beforeEach((t) => { - t.context.agent = helper.loadMockedAgent() + await t.test('_moduleRoot', async (t) => { + t.beforeEach((ctx) => { + ctx.nr = {} + ctx.nr.agent = helper.loadMockedAgent() }) - t.afterEach((t) => { - helper.unloadAgent(t.context.agent) + t.afterEach((ctx) => { + helper.unloadAgent(ctx.nr.agent) }) - t.test('should set _moduleRoot to `.` if resolvedName is a built-in', (t) => { - const { agent } = t.context + await t.test('should set _moduleRoot to `.` if resolvedName is a built-in', (t) => { + const { agent } = t.nr const shim = new Shim(agent, 'http', 'http') - t.equal(shim._moduleRoot, '.') - t.end() + assert.equal(shim._moduleRoot, '.') }) - t.test( + await t.test( 'should set _moduleRoot to `.` if resolvedName is undefined but moduleName is a built-in', (t) => { - const { agent } = t.context + const { agent } = t.nr const shim = new Shim(agent, 'http') - t.equal(shim._moduleRoot, '.') - t.end() + assert.equal(shim._moduleRoot, '.') } ) - t.test('should set _moduleRoot to resolvedName not a built-in', (t) => { - const { agent } = t.context + await t.test('should set _moduleRoot to resolvedName not a built-in', (t) => { + const { agent } = t.nr const root = '/path/to/app/node_modules/rando-mod' const shim = new Shim(agent, 'rando-mod', root) - t.equal(shim._moduleRoot, root) - t.end() + assert.equal(shim._moduleRoot, root) }) - t.test('should properly resolve _moduleRoot as windows path', (t) => { - const { agent } = t.context + await t.test('should properly resolve _moduleRoot as windows path', (t) => { + const { agent } = t.nr const root = `c:\\path\\to\\app\\node_modules\\@scope\\test` const shim = new Shim(agent, '@scope/test', root) - t.equal(shim._moduleRoot, root) - t.end() + assert.equal(shim._moduleRoot, root) }) - t.end() }) - t.test('shim.specs', (t) => { + await t.test('shim.specs', (t) => { const agent = helper.loadMockedAgent() - t.teardown(() => { + t.after(() => { helper.unloadAgent(agent) }) const shim = new Shim(agent, 'test-mod') - t.ok(shim.specs, 'should assign specs to an instance of shim') - t.ok(shim.specs.ClassWrapSpec) - t.ok(shim.specs.MessageSpec) - t.ok(shim.specs.MessageSubscribeSpec) - t.ok(shim.specs.MiddlewareMounterSpec) - t.ok(shim.specs.MiddlewareSpec) - t.ok(shim.specs.OperationSpec) - t.ok(shim.specs.QuerySpec) - t.ok(shim.specs.RecorderSpec) - t.ok(shim.specs.RenderSpec) - t.ok(shim.specs.SegmentSpec) - t.ok(shim.specs.TransactionSpec) - t.ok(shim.specs.WrapSpec) - t.ok(shim.specs.params.DatastoreParameters) - t.ok(shim.specs.params.QueueMessageParameters) - t.end() + assert.ok(shim.specs, 'should assign specs to an instance of shim') + assert.ok(shim.specs.ClassWrapSpec) + assert.ok(shim.specs.MessageSpec) + assert.ok(shim.specs.MessageSubscribeSpec) + assert.ok(shim.specs.MiddlewareMounterSpec) + assert.ok(shim.specs.MiddlewareSpec) + assert.ok(shim.specs.OperationSpec) + assert.ok(shim.specs.QuerySpec) + assert.ok(shim.specs.RecorderSpec) + assert.ok(shim.specs.RenderSpec) + assert.ok(shim.specs.SegmentSpec) + assert.ok(shim.specs.TransactionSpec) + assert.ok(shim.specs.WrapSpec) + assert.ok(shim.specs.params.DatastoreParameters) + assert.ok(shim.specs.params.QueueMessageParameters) }) - t.test('should not use functions in MessageSubscribeSpec if it is not an array', (t) => { + await t.test('should not use functions in MessageSubscribeSpec if it is not an array', (t) => { const agent = helper.loadMockedAgent() - t.teardown(() => { + t.after(() => { helper.unloadAgent(agent) }) @@ -3173,7 +3141,6 @@ tap.test('Shim', function (t) { const spec = new shim.specs.MessageSubscribeSpec({ functions: 'foo-bar' }) - t.notOk(spec.functions) - t.end() + assert.ok(!spec.functions) }) }) diff --git a/test/unit/shim/transaction-shim.test.js b/test/unit/shim/transaction-shim.test.js index d9bac27da2..06766ff21e 100644 --- a/test/unit/shim/transaction-shim.test.js +++ b/test/unit/shim/transaction-shim.test.js @@ -4,8 +4,9 @@ */ 'use strict' - -const tap = require('tap') +const assert = require('node:assert') +const test = require('node:test') +const { isNonWritable } = require('../../lib/custom-assertions') const hashes = require('../../../lib/util/hashes') const helper = require('../../lib/agent_helper') const { TransactionSpec } = require('../../../lib/shim/specs') @@ -50,17 +51,12 @@ function createCATHeaders(config, altNames) { } } -tap.test('TransactionShim', function (t) { - t.autoend() - let agent = null - let shim = null - let wrappable = null - - function beforeEach() { - // implicitly disabling distributed tracing to match original config base settings - agent = helper.loadMockedAgent() - shim = new TransactionShim(agent, 'test-module') - wrappable = { +test('TransactionShim', async function (t) { + function beforeEach(ctx) { + ctx.nr = {} + const agent = helper.loadMockedAgent() + ctx.nr.shim = new TransactionShim(agent, 'test-module') + ctx.nr.wrappable = { name: 'this is a name', bar: function barsName(unused, params) { return 'bar' }, // eslint-disable-line fiz: function fizsName() { @@ -82,140 +78,135 @@ tap.test('TransactionShim', function (t) { agent.config.trusted_account_ids = [9876, 6789] agent.config._fromServer(params, 'encoding_key') agent.config._fromServer(params, 'cross_process_id') + ctx.nr.agent = agent } - function afterEach() { - helper.unloadAgent(agent) - agent = null - shim = null + function afterEach(ctx) { + helper.unloadAgent(ctx.nr.agent) } - t.test('constructor', function (t) { - t.autoend() + await t.test('constructor', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should require an agent parameter', function (t) { - t.throws(function () { + await t.test('should require an agent parameter', function () { + assert.throws(function () { return new TransactionShim() - }, /^Shim must be initialized with .*? agent/) - t.end() + }, 'Error: Shim must be initialized with agent and module name') }) - t.test('should require a module name parameter', function (t) { - t.throws(function () { + await t.test('should require a module name parameter', function (t) { + const { agent } = t.nr + assert.throws(function () { return new TransactionShim(agent) - }, /^Shim must be initialized with .*? module name/) - t.end() + }, 'Error: Shim must be initialized with agent and module name') }) - t.test('should assign properties from parent', (t) => { + await t.test('should assign properties from parent', (t) => { + const { agent } = t.nr const mod = 'test-mod' const name = mod const version = '1.0.0' const shim = new TransactionShim(agent, mod, mod, name, version) - t.equal(shim.moduleName, mod) - t.equal(agent, shim._agent) - t.equal(shim.pkgVersion, version) - t.end() + assert.equal(shim.moduleName, mod) + assert.equal(agent, shim._agent) + assert.equal(shim.pkgVersion, version) }) }) - t.test('#WEB, #BG, #MESSAGE', function (t) { - t.autoend() + await t.test('#WEB, #BG, #MESSAGE', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) const keys = ['WEB', 'BG', 'MESSAGE'] - keys.forEach((key) => { - t.test(`${key} should be a non-writable property`, function (t) { - t.isNonWritable({ obj: shim, key }) - t.end() + for (const key of keys) { + await t.test(`${key} should be a non-writable property`, function (t) { + const { shim } = t.nr + isNonWritable({ obj: shim, key }) }) - t.test(`${key} should be transaction types`, function (t) { - t.equal(shim[key], key.toLowerCase()) - t.end() + await t.test(`${key} should be transaction types`, function (t) { + const { shim } = t.nr + assert.equal(shim[key], key.toLowerCase()) }) - }) + } }) - t.test('#bindCreateTransaction', function (t) { - t.autoend() + await t.test('#bindCreateTransaction', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-functions', function (t) { + await t.test('should not wrap non-functions', function (t) { + const { shim, wrappable } = t.nr shim.bindCreateTransaction(wrappable, 'name', new TransactionSpec({ type: shim.WEB })) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.bindCreateTransaction( wrappable.bar, new TransactionSpec({ type: shim.WEB }) ) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.bindCreateTransaction( wrappable.bar, null, new TransactionSpec({ type: shim.WEB }) ) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.bindCreateTransaction(wrappable, 'bar', new TransactionSpec({ type: shim.WEB })) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable, 'bar')) - t.equal(shim.unwrap(wrappable, 'bar'), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable, 'bar'), true) + assert.equal(shim.unwrap(wrappable, 'bar'), original) }) }) - t.test('#bindCreateTransaction wrapper', function (t) { - t.autoend() + await t.test('#bindCreateTransaction wrapper', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should execute the wrapped function', function (t) { + await t.test('should execute the wrapped function', function (t) { + const { shim } = t.nr let executed = false const context = {} const value = {} const wrapped = shim.bindCreateTransaction(function (a, b, c) { executed = true - t.equal(this, context) - t.equal(a, 'a') - t.equal(b, 'b') - t.equal(c, 'c') + assert.equal(this, context) + assert.equal(a, 'a') + assert.equal(b, 'b') + assert.equal(c, 'c') return value }, new TransactionSpec({ type: shim.WEB })) - t.notOk(executed) + assert.ok(!executed) const ret = wrapped.call(context, 'a', 'b', 'c') - t.ok(executed) - t.equal(ret, value) - t.end() + assert.equal(executed, true) + assert.equal(ret, value) }) - t.test('should create a transaction with the correct type', function (t) { + await t.test('should create a transaction with the correct type', function (t) { + const { shim, wrappable } = t.nr shim.bindCreateTransaction( wrappable, 'getActiveSegment', new TransactionSpec({ type: shim.WEB }) ) const segment = wrappable.getActiveSegment() - t.equal(segment.transaction.type, shim.WEB) + assert.equal(segment.transaction.type, shim.WEB) shim.unwrap(wrappable, 'getActiveSegment') shim.bindCreateTransaction( @@ -224,11 +215,11 @@ tap.test('TransactionShim', function (t) { new TransactionSpec({ type: shim.BG }) ) const bgSegment = wrappable.getActiveSegment() - t.equal(bgSegment.transaction.type, shim.BG) - t.end() + assert.equal(bgSegment.transaction.type, shim.BG) }) - t.test('should not create a nested transaction when `spec.nest` is false', function (t) { + await t.test('should not create a nested transaction when `spec.nest` is false', function (t) { + const { shim } = t.nr let webTx = null let bgTx = null let webCalled = false @@ -244,14 +235,14 @@ tap.test('TransactionShim', function (t) { }, new TransactionSpec({ type: shim.WEB })) web() - t.ok(webCalled) - t.ok(bgCalled) - t.equal(webTx, bgTx) - t.end() + assert.equal(webCalled, true) + assert.equal(bgCalled, true) + assert.equal(webTx, bgTx) }) - notRunningStates.forEach((agentState) => { - t.test(`should not create transaction when agent state is ${agentState}`, (t) => { + for (const agentState of notRunningStates) { + await t.test(`should not create transaction when agent state is ${agentState}`, (t) => { + const { agent, shim } = t.nr agent.setState(agentState) let callbackCalled = false @@ -263,78 +254,74 @@ tap.test('TransactionShim', function (t) { wrapped() - t.ok(callbackCalled) - t.equal(transaction, null) - t.end() + assert.equal(callbackCalled, true) + assert.equal(transaction, null) }) - }) + } }) - t.test('#bindCreateTransaction when `spec.nest` is `true`', function (t) { - t.autoend() - - let transactions = null - let web = null - let bg = null - - t.beforeEach(function () { - beforeEach() - transactions = [] - web = shim.bindCreateTransaction(function (cb) { - transactions.push(shim.getSegment().transaction) + await t.test('#bindCreateTransaction when `spec.nest` is `true`', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { shim } = ctx.nr + ctx.nr.transactions = [] + ctx.nr.web = shim.bindCreateTransaction(function (cb) { + ctx.nr.transactions.push(shim.getSegment().transaction) if (cb) { cb() } }, new TransactionSpec({ type: shim.WEB, nest: true })) - bg = shim.bindCreateTransaction(function (cb) { - transactions.push(shim.getSegment().transaction) + ctx.nr.bg = shim.bindCreateTransaction(function (cb) { + ctx.nr.transactions.push(shim.getSegment().transaction) if (cb) { cb() } }, new TransactionSpec({ type: shim.BG, nest: true })) }) + t.afterEach(afterEach) - t.test('should create a nested transaction if the types differ', function (t) { + await t.test('should create a nested transaction if the types differ', function (t) { + const { bg, web } = t.nr web(bg) - t.equal(transactions.length, 2) - t.not(transactions[0], transactions[1]) + assert.equal(t.nr.transactions.length, 2) + assert.notEqual(t.nr.transactions[0], t.nr.transactions[1]) - transactions = [] + t.nr.transactions = [] bg(web) - t.equal(transactions.length, 2) - t.not(transactions[0], transactions[1]) - t.end() + assert.equal(t.nr.transactions.length, 2) + assert.notEqual(t.nr.transactions[0], t.nr.transactions[1]) }) - t.test('should not create nested transactions if the types are the same', function (t) { + await t.test('should not create nested transactions if the types are the same', function (t) { + const { bg, web } = t.nr web(web) - t.equal(transactions.length, 2) - t.equal(transactions[0], transactions[1]) + assert.equal(t.nr.transactions.length, 2) + assert.equal(t.nr.transactions[0], t.nr.transactions[1]) - transactions = [] + t.nr.transactions = [] bg(bg) - t.equal(transactions.length, 2) - t.equal(transactions[0], transactions[1]) - t.end() + assert.equal(t.nr.transactions.length, 2) + assert.equal(t.nr.transactions[0], t.nr.transactions[1]) }) - t.test('should create transactions if the types alternate', function (t) { + await t.test('should create transactions if the types alternate', function (t) { + const { bg, web } = t.nr web(bg.bind(null, web.bind(null, bg))) - t.equal(transactions.length, 4) - for (let i = 0; i < transactions.length; ++i) { - const tx1 = transactions[i] - for (let j = i + 1; j < transactions.length; ++j) { - const tx2 = transactions[j] - t.not(tx1, tx2, `tx ${i} should not equal tx ${j}`) + assert.equal(t.nr.transactions.length, 4) + for (let i = 0; i < t.nr.transactions.length; ++i) { + const tx1 = t.nr.transactions[i] + for (let j = i + 1; j < t.nr.transactions.length; ++j) { + const tx2 = t.nr.transactions[j] + assert.notEqual(tx1, tx2, `tx ${i} should noassert.equal tx ${j}`) } } - t.end() }) - notRunningStates.forEach((agentState) => { - t.test(`should not create transaction when agent state is ${agentState}`, (t) => { + for (const agentState of notRunningStates) { + await t.test(`should not create transaction when agent state is ${agentState}`, (t) => { + const { agent, shim } = t.nr agent.setState(agentState) let callbackCalled = false @@ -346,251 +333,257 @@ tap.test('TransactionShim', function (t) { wrapped() - t.ok(callbackCalled) - t.equal(transaction, null) - t.end() + assert.equal(callbackCalled, true) + assert.equal(transaction, null) }) - }) + } }) - t.test('#pushTransactionName', function (t) { - t.autoend() + await t.test('#pushTransactionName', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not fail when called outside of a transaction', function (t) { - t.doesNotThrow(function () { + await t.test('should not fail when called outside of a transaction', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.pushTransactionName('foobar') }) - t.end() }) - t.test('should append the given string to the name state stack', function (t) { + await t.test('should append the given string to the name state stack', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function (tx) { shim.pushTransactionName('foobar') - t.equal(tx.nameState.getName(), '/foobar') - t.end() + assert.equal(tx.nameState.getName(), '/foobar') + end() }) }) }) - t.test('#popTransactionName', function (t) { - t.autoend() + await t.test('#popTransactionName', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not fail when called outside of a transaction', function (t) { - t.doesNotThrow(function () { + await t.test('should not fail when called outside of a transaction', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.popTransactionName('foobar') }) - t.end() }) - t.test('should pop to the given string in the name state stack', function (t) { + await t.test('should pop to the given string in the name state stack', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function (tx) { shim.pushTransactionName('foo') shim.pushTransactionName('bar') shim.pushTransactionName('bazz') - t.equal(tx.nameState.getName(), '/foo/bar/bazz') + assert.equal(tx.nameState.getName(), '/foo/bar/bazz') shim.popTransactionName('bar') - t.equal(tx.nameState.getName(), '/foo') - t.end() + assert.equal(tx.nameState.getName(), '/foo') + end() }) }) - t.test('should pop just the last item if no string is given', function (t) { + await t.test('should pop just the last item if no string is given', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function (tx) { shim.pushTransactionName('foo') shim.pushTransactionName('bar') shim.pushTransactionName('bazz') - t.equal(tx.nameState.getName(), '/foo/bar/bazz') + assert.equal(tx.nameState.getName(), '/foo/bar/bazz') shim.popTransactionName() - t.equal(tx.nameState.getName(), '/foo/bar') - t.end() + assert.equal(tx.nameState.getName(), '/foo/bar') + end() }) }) }) - t.test('#setTransactionName', function (t) { - t.autoend() + await t.test('#setTransactionName', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not fail when called outside of a transaction', function (t) { - t.doesNotThrow(function () { + await t.test('should not fail when called outside of a transaction', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.setTransactionName('foobar') }) - t.end() }) - t.test('should set the transaction partial name', function (t) { + await t.test('should set the transaction partial name', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function (tx) { shim.setTransactionName('fizz bang') - t.equal(tx.getName(), 'fizz bang') - t.end() + assert.equal(tx.getName(), 'fizz bang') + end() }) }) }) - t.test('#handleMqTracingHeaders', function (t) { - t.autoend() - - t.beforeEach(() => { - beforeEach() + await t.test('#handleMqTracingHeaders', async function (t) { + t.beforeEach((ctx) => { + beforeEach(ctx) + const { agent } = ctx.nr agent.config.cross_application_tracer.enabled = true agent.config.distributed_tracing.enabled = false }) t.afterEach(afterEach) - t.test('should not run if disabled', function (t) { + await t.test('should not run if disabled', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function (tx) { agent.config.cross_application_tracer.enabled = false const headers = createCATHeaders(agent.config) const segment = shim.getSegment() - t.notOk(tx.incomingCatId) - t.notOk(tx.referringTransactionGuid) - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) + assert.ok(!tx.incomingCatId) + assert.ok(!tx.referringTransactionGuid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) shim.handleMqTracingHeaders(headers, segment) - t.notOk(tx.incomingCatId) - t.notOk(tx.referringTransactionGuid) - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) - t.end() + assert.ok(!tx.incomingCatId) + assert.ok(!tx.referringTransactionGuid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) + end() }) }) - t.test('should not run if the encoding key is missing', function (t) { + await t.test('should not run if the encoding key is missing', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function (tx) { const headers = createCATHeaders(agent.config) const segment = shim.getSegment() delete agent.config.encoding_key - t.notOk(tx.incomingCatId) - t.notOk(tx.referringTransactionGuid) - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) + assert.ok(!tx.incomingCatId) + assert.ok(!tx.referringTransactionGuid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) shim.handleMqTracingHeaders(headers, segment) - t.notOk(tx.incomingCatId) - t.notOk(tx.referringTransactionGuid) - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) - t.end() + assert.ok(!tx.incomingCatId) + assert.ok(!tx.referringTransactionGuid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) + end() }) }) - t.test('should fail gracefully when no headers are given', function (t) { + await t.test('should fail gracefully when no headers are given', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function (tx) { const segment = shim.getSegment() - t.notOk(tx.incomingCatId) - t.notOk(tx.referringTransactionGuid) - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) + assert.ok(!tx.incomingCatId) + assert.ok(!tx.referringTransactionGuid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) - t.doesNotThrow(function () { + assert.doesNotThrow(function () { shim.handleMqTracingHeaders(null, segment) }) - t.notOk(tx.incomingCatId) - t.notOk(tx.referringTransactionGuid) - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) - t.end() + assert.ok(!tx.incomingCatId) + assert.ok(!tx.referringTransactionGuid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) + end() }) }) - t.test( + await t.test( 'should attach the CAT info to the provided segment transaction - DT disabled, id and transaction are provided', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, shim.WEB, function (tx) { const headers = createCATHeaders(agent.config) const segment = shim.getSegment() delete headers['X-NewRelic-App-Data'] - t.notOk(tx.incomingCatId) - t.notOk(tx.referringTransactionGuid) - t.notOk(tx.tripId) - t.notOk(tx.referringPathHash) + assert.ok(!tx.incomingCatId) + assert.ok(!tx.referringTransactionGuid) + assert.ok(!tx.tripId) + assert.ok(!tx.referringPathHash) helper.runInTransaction(agent, shim.BG, function (tx2) { - t.not(tx2, tx) + assert.notEqual(tx2, tx) shim.handleMqTracingHeaders(headers, segment) }) - t.equal(tx.incomingCatId, '9876#id') - t.equal(tx.referringTransactionGuid, 'trans id') - t.equal(tx.tripId, 'trip id') - t.equal(tx.referringPathHash, 'path hash') - t.end() + assert.equal(tx.incomingCatId, '9876#id') + assert.equal(tx.referringTransactionGuid, 'trans id') + assert.equal(tx.tripId, 'trip id') + assert.equal(tx.referringPathHash, 'path hash') + end() }) } ) - t.test( + await t.test( 'should attach the CAT info to current transaction if not provided - DT disabled, id and transaction are provided', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function (tx) { const headers = createCATHeaders(agent.config) delete headers['X-NewRelic-App-Data'] - t.notOk(tx.incomingCatId) - t.notOk(tx.referringTransactionGuid) - t.notOk(tx.tripId) - t.notOk(tx.referringPathHash) + assert.ok(!tx.incomingCatId) + assert.ok(!tx.referringTransactionGuid) + assert.ok(!tx.tripId) + assert.ok(!tx.referringPathHash) shim.handleMqTracingHeaders(headers) - t.equal(tx.incomingCatId, '9876#id') - t.equal(tx.referringTransactionGuid, 'trans id') - t.equal(tx.tripId, 'trip id') - t.equal(tx.referringPathHash, 'path hash') - t.end() + assert.equal(tx.incomingCatId, '9876#id') + assert.equal(tx.referringTransactionGuid, 'trans id') + assert.equal(tx.tripId, 'trip id') + assert.equal(tx.referringPathHash, 'path hash') + end() }) } ) - t.test( + await t.test( 'should work with alternate header names - DT disabled, id and transaction are provided', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, shim.WEB, function (tx) { const headers = createCATHeaders(agent.config, true) const segment = shim.getSegment() delete headers.NewRelicAppData - t.notOk(tx.incomingCatId) - t.notOk(tx.referringTransactionGuid) - t.notOk(tx.tripId) - t.notOk(tx.referringPathHash) + assert.ok(!tx.incomingCatId) + assert.ok(!tx.referringTransactionGuid) + assert.ok(!tx.tripId) + assert.ok(!tx.referringPathHash) helper.runInTransaction(agent, shim.BG, function (tx2) { - t.not(tx2, tx) + assert.notEqual(tx2, tx) shim.handleMqTracingHeaders(headers, segment) }) - t.equal(tx.incomingCatId, '9876#id') - t.equal(tx.referringTransactionGuid, 'trans id') - t.equal(tx.tripId, 'trip id') - t.equal(tx.referringPathHash, 'path hash') - t.end() + assert.equal(tx.incomingCatId, '9876#id') + assert.equal(tx.referringTransactionGuid, 'trans id') + assert.equal(tx.tripId, 'trip id') + assert.equal(tx.referringPathHash, 'path hash') + end() }) } ) - t.test( + await t.test( 'Should propagate w3c tracecontext header when present, id and transaction are provided', - function (t) { + function (t, end) { + const { agent, shim } = t.nr agent.config.distributed_tracing.enabled = true const traceparent = '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00' @@ -604,16 +597,17 @@ tap.test('TransactionShim', function (t) { const outboundHeaders = {} tx.insertDistributedTraceHeaders(outboundHeaders) - t.ok(outboundHeaders.traceparent.startsWith('00-4bf92f3577b3')) - t.ok(outboundHeaders.tracestate.endsWith(tracestate)) - t.end() + assert.ok(outboundHeaders.traceparent.startsWith('00-4bf92f3577b3')) + assert.ok(outboundHeaders.tracestate.endsWith(tracestate)) + end() }) } ) - t.test( + await t.test( 'Should propagate w3c tracecontext header when no tracestate, id and transaction are provided', - function (t) { + function (t, end) { + const { agent, shim } = t.nr agent.config.distributed_tracing.enabled = true const traceparent = '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00' @@ -626,15 +620,16 @@ tap.test('TransactionShim', function (t) { const outboundHeaders = {} tx.insertDistributedTraceHeaders(outboundHeaders) - t.ok(outboundHeaders.traceparent.startsWith('00-4bf92f3577b3')) - t.end() + assert.ok(outboundHeaders.traceparent.startsWith('00-4bf92f3577b3')) + end() }) } ) - t.test( + await t.test( 'Should propagate w3c tracecontext header when tracestate empty string, id and transaction are provided', - function (t) { + function (t, end) { + const { agent, shim } = t.nr agent.config.distributed_tracing.enabled = true const traceparent = '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00' @@ -648,13 +643,14 @@ tap.test('TransactionShim', function (t) { const outboundHeaders = {} tx.insertDistributedTraceHeaders(outboundHeaders) - t.ok(outboundHeaders.traceparent.startsWith('00-4bf92f3577b3')) - t.end() + assert.ok(outboundHeaders.traceparent.startsWith('00-4bf92f3577b3')) + end() }) } ) - t.test('should propagate w3c headers when CAT expicitly disabled', (t) => { + await t.test('should propagate w3c headers when CAT explicitly disabled', (t, end) => { + const { agent, shim } = t.nr agent.config.cross_application_tracer.enabled = false agent.config.distributed_tracing.enabled = true @@ -669,90 +665,94 @@ tap.test('TransactionShim', function (t) { const outboundHeaders = {} tx.insertDistributedTraceHeaders(outboundHeaders) - t.ok(outboundHeaders.traceparent.startsWith('00-4bf92f3577b3')) - t.ok(outboundHeaders.tracestate.endsWith(tracestate)) - t.end() + assert.ok(outboundHeaders.traceparent.startsWith('00-4bf92f3577b3')) + assert.ok(outboundHeaders.tracestate.endsWith(tracestate)) + end() }) }) - t.test( + await t.test( 'should attach the CAT info to the provided segment - DT disabled, app data is provided', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, shim.WEB, function (tx) { const headers = createCATHeaders(agent.config) const segment = shim.getSegment() delete headers['X-NewRelic-Id'] delete headers['X-NewRelic-Transaction'] - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) helper.runInTransaction(agent, shim.BG, function (tx2) { - t.not(tx2, tx) + assert.notEqual(tx2, tx) shim.handleMqTracingHeaders(headers, segment) }) - t.equal(segment.catId, '6789#app') - t.equal(segment.catTransaction, 'app data transaction name') - t.equal(segment.getAttributes().transaction_guid, 'app trans id') - t.end() + assert.equal(segment.catId, '6789#app') + assert.equal(segment.catTransaction, 'app data transaction name') + assert.equal(segment.getAttributes().transaction_guid, 'app trans id') + end() }) } ) - t.test( + await t.test( 'should attach the CAT info to current segment if not provided - DT disabled, app data is provided', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const headers = createCATHeaders(agent.config) const segment = shim.getSegment() delete headers['X-NewRelic-Id'] delete headers['X-NewRelic-Transaction'] - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) shim.handleMqTracingHeaders(headers) - t.equal(segment.catId, '6789#app') - t.equal(segment.catTransaction, 'app data transaction name') - t.equal(segment.getAttributes().transaction_guid, 'app trans id') - t.end() + assert.equal(segment.catId, '6789#app') + assert.equal(segment.catTransaction, 'app data transaction name') + assert.equal(segment.getAttributes().transaction_guid, 'app trans id') + end() }) } ) - t.test( + await t.test( 'should work with alternate header names - DT disabled, app data is provided', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, shim.WEB, function (tx) { const headers = createCATHeaders(agent.config, true) const segment = shim.getSegment() delete headers.NewRelicID delete headers.NewRelicTransaction - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) helper.runInTransaction(agent, shim.BG, function (tx2) { - t.not(tx2, tx) + assert.notEqual(tx2, tx) shim.handleMqTracingHeaders(headers, segment) }) - t.equal(segment.catId, '6789#app') - t.equal(segment.catTransaction, 'app data transaction name') - t.equal(segment.getAttributes().transaction_guid, 'app trans id') - t.end() + assert.equal(segment.catId, '6789#app') + assert.equal(segment.catTransaction, 'app data transaction name') + assert.equal(segment.getAttributes().transaction_guid, 'app trans id') + end() }) } ) - t.test( + await t.test( 'should not attach any CAT data to the segment, app data is for an untrusted application', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const headers = createCATHeaders(agent.config) const segment = shim.getSegment() @@ -760,118 +760,131 @@ tap.test('TransactionShim', function (t) { delete headers['X-NewRelic-Transaction'] agent.config.trusted_account_ids = [] - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) shim.handleMqTracingHeaders(headers) - t.notOk(segment.catId) - t.notOk(segment.catTransaction) - t.notOk(segment.getAttributes().transaction_guid) - t.end() + assert.ok(!segment.catId) + assert.ok(!segment.catTransaction) + assert.ok(!segment.getAttributes().transaction_guid) + end() }) } ) }) - t.test('#insertCATRequestHeaders', function (t) { - t.autoend() - t.beforeEach(() => { - beforeEach() + await t.test('#insertCATRequestHeaders', async function (t) { + t.beforeEach((ctx) => { + beforeEach(ctx) + const { agent } = ctx.nr agent.config.cross_application_tracer.enabled = true agent.config.distributed_tracing.enabled = false }) t.afterEach(afterEach) - t.test('should not run if disabled', function (t) { + await t.test('should not run if disabled', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { agent.config.cross_application_tracer.enabled = false const headers = {} shim.insertCATRequestHeaders(headers) - t.notOk(headers['X-NewRelic-Id']) - t.notOk(headers['X-NewRelic-Transaction']) - t.end() + assert.ok(!headers['X-NewRelic-Id']) + assert.ok(!headers['X-NewRelic-Transaction']) + end() }) }) - t.test('should not run if the encoding key is missing', function (t) { + await t.test('should not run if the encoding key is missing', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { delete agent.config.encoding_key const headers = {} shim.insertCATRequestHeaders(headers) - t.notOk(headers['X-NewRelic-Id']) - t.notOk(headers['X-NewRelic-Transaction']) - t.end() + assert.ok(!headers['X-NewRelic-Id']) + assert.ok(!headers['X-NewRelic-Transaction']) + end() }) }) - t.test('should fail gracefully when no headers are given', function (t) { + await t.test('should fail gracefully when no headers are given', function (t) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { - t.doesNotThrow(function () { + assert.doesNotThrow(function () { shim.insertCATRequestHeaders(null) }) - t.end() }) }) - t.test('should use X-Http-Style-Headers when useAlt is false - DT disabled', function (t) { - helper.runInTransaction(agent, function () { - const headers = {} - shim.insertCATRequestHeaders(headers) + await t.test( + 'should use X-Http-Style-Headers when useAlt is false - DT disabled', + function (t, end) { + const { agent, shim } = t.nr + helper.runInTransaction(agent, function () { + const headers = {} + shim.insertCATRequestHeaders(headers) - t.notOk(headers.NewRelicID) - t.notOk(headers.NewRelicTransaction) - t.equal(headers['X-NewRelic-Id'], 'RVpaRwNdQBJQ') - t.match(headers['X-NewRelic-Transaction'], /^[a-zA-Z0-9/-]{60,80}={0,2}$/) - t.end() - }) - }) + assert.ok(!headers.NewRelicID) + assert.ok(!headers.NewRelicTransaction) + assert.equal(headers['X-NewRelic-Id'], 'RVpaRwNdQBJQ') + assert.match(headers['X-NewRelic-Transaction'], /^[a-zA-Z0-9/-]{60,80}={0,2}$/) + end() + }) + } + ) - t.test( + await t.test( 'should use MessageQueueStyleHeaders when useAlt is true with DT disabled', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const headers = {} shim.insertCATRequestHeaders(headers, true) - t.notOk(headers['X-NewRelic-Id']) - t.notOk(headers['X-NewRelic-Transaction']) - t.equal(headers.NewRelicID, 'RVpaRwNdQBJQ') - t.match(headers.NewRelicTransaction, /^[a-zA-Z0-9/-]{60,80}={0,2}$/) - t.end() + assert.ok(!headers['X-NewRelic-Id']) + assert.ok(!headers['X-NewRelic-Transaction']) + assert.equal(headers.NewRelicID, 'RVpaRwNdQBJQ') + assert.match(headers.NewRelicTransaction, /^[a-zA-Z0-9/-]{60,80}={0,2}$/) + end() }) } ) - t.test('should append the current path hash to the transaction - DT disabled', function (t) { - helper.runInTransaction(agent, function (tx) { - tx.nameState.appendPath('foobar') - t.equal(tx.pathHashes.length, 0) + await t.test( + 'should append the current path hash to the transaction - DT disabled', + function (t, end) { + const { agent, shim } = t.nr + helper.runInTransaction(agent, function (tx) { + tx.nameState.appendPath('foobar') + assert.equal(tx.pathHashes.length, 0) - const headers = {} - shim.insertCATRequestHeaders(headers) + const headers = {} + shim.insertCATRequestHeaders(headers) - t.equal(tx.pathHashes.length, 1) - t.equal(tx.pathHashes[0], '0f9570a6') - t.end() - }) - }) + assert.equal(tx.pathHashes.length, 1) + assert.equal(tx.pathHashes[0], '0f9570a6') + end() + }) + } + ) - t.test('should be an obfuscated value - DT disabled, id header', function (t) { + await t.test('should be an obfuscated value - DT disabled, id header', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const headers = {} shim.insertCATRequestHeaders(headers) - t.match(headers['X-NewRelic-Id'], /^[a-zA-Z0-9/-]+={0,2}$/) - t.end() + assert.match(headers['X-NewRelic-Id'], /^[a-zA-Z0-9/-]+={0,2}$/) + end() }) }) - t.test('should deobfuscate to the app id - DT disabled, id header', function (t) { + await t.test('should deobfuscate to the app id - DT disabled, id header', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const headers = {} shim.insertCATRequestHeaders(headers) @@ -880,24 +893,29 @@ tap.test('TransactionShim', function (t) { headers['X-NewRelic-Id'], agent.config.encoding_key ) - t.equal(id, '1234#4321') - t.end() + assert.equal(id, '1234#4321') + end() }) }) - t.test('should be an obfuscated value - DT disabled, transaction header', function (t) { - helper.runInTransaction(agent, function () { - const headers = {} - shim.insertCATRequestHeaders(headers) + await t.test( + 'should be an obfuscated value - DT disabled, transaction header', + function (t, end) { + const { agent, shim } = t.nr + helper.runInTransaction(agent, function () { + const headers = {} + shim.insertCATRequestHeaders(headers) - t.match(headers['X-NewRelic-Transaction'], /^[a-zA-Z0-9/-]{60,80}={0,2}$/) - t.end() - }) - }) + assert.match(headers['X-NewRelic-Transaction'], /^[a-zA-Z0-9/-]{60,80}={0,2}$/) + end() + }) + } + ) - t.test( + await t.test( 'should deobfuscate to transaction information - DT disabled, transaction header', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const headers = {} shim.insertCATRequestHeaders(headers) @@ -907,95 +925,107 @@ tap.test('TransactionShim', function (t) { agent.config.encoding_key ) - t.doesNotThrow(function () { + assert.doesNotThrow(function () { txInfo = JSON.parse(txInfo) }) - t.ok(Array.isArray(txInfo)) - t.equal(txInfo.length, 4) - t.end() + assert.ok(Array.isArray(txInfo)) + assert.equal(txInfo.length, 4) + end() }) } ) }) - t.test('#insertCATReplyHeader', function (t) { - t.autoend() - t.beforeEach(() => { - beforeEach() + await t.test('#insertCATReplyHeader', async function (t) { + t.beforeEach((ctx) => { + beforeEach(ctx) + const { agent } = ctx.nr agent.config.cross_application_tracer.enabled = true agent.config.distributed_tracing.enabled = false }) t.afterEach(afterEach) - t.test('should not run if disabled', function (t) { + await t.test('should not run if disabled', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { agent.config.cross_application_tracer.enabled = false const headers = {} shim.insertCATReplyHeader(headers) - t.notOk(headers['X-NewRelic-App-Data']) - t.end() + assert.ok(!headers['X-NewRelic-App-Data']) + end() }) }) - t.test('should not run if the encoding key is missing', function (t) { + await t.test('should not run if the encoding key is missing', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { delete agent.config.encoding_key const headers = {} shim.insertCATReplyHeader(headers) - t.notOk(headers['X-NewRelic-App-Data']) - t.end() + assert.ok(!headers['X-NewRelic-App-Data']) + end() }) }) - t.test('should fail gracefully when no headers are given', function (t) { + await t.test('should fail gracefully when no headers are given', function (t) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { - t.doesNotThrow(function () { + assert.doesNotThrow(function () { shim.insertCATReplyHeader(null) }) - t.end() }) }) - t.test('should use X-Http-Style-Headers when useAlt is false - DT disabled', function (t) { - helper.runInTransaction(agent, function () { - const headers = {} - shim.insertCATReplyHeader(headers) + await t.test( + 'should use X-Http-Style-Headers when useAlt is false - DT disabled', + function (t, end) { + const { agent, shim } = t.nr + helper.runInTransaction(agent, function () { + const headers = {} + shim.insertCATReplyHeader(headers) - t.notOk(headers.NewRelicAppData) - t.match(headers['X-NewRelic-App-Data'], /^[a-zA-Z0-9/-]{60,80}={0,2}$/) - t.end() - }) - }) + assert.ok(!headers.NewRelicAppData) + assert.match(headers['X-NewRelic-App-Data'], /^[a-zA-Z0-9/-]{60,80}={0,2}$/) + end() + }) + } + ) - t.test('should use MessageQueueStyleHeaders when useAlt is true - DT disabled', function (t) { - helper.runInTransaction(agent, function () { - const headers = {} - shim.insertCATReplyHeader(headers, true) + await t.test( + 'should use MessageQueueStyleHeaders when useAlt is true - DT disabled', + function (t, end) { + const { agent, shim } = t.nr + helper.runInTransaction(agent, function () { + const headers = {} + shim.insertCATReplyHeader(headers, true) - t.notOk(headers['X-NewRelic-App-Data']) - t.match(headers.NewRelicAppData, /^[a-zA-Z0-9/-]{60,80}={0,2}$/) - t.end() - }) - }) + assert.ok(!headers['X-NewRelic-App-Data']) + assert.match(headers.NewRelicAppData, /^[a-zA-Z0-9/-]{60,80}={0,2}$/) + end() + }) + } + ) - t.test('should be an obfuscated value - DT disabled, app data header', function (t) { + await t.test('should be an obfuscated value - DT disabled, app data header', function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const headers = {} shim.insertCATReplyHeader(headers) - t.match(headers['X-NewRelic-App-Data'], /^[a-zA-Z0-9/-]{60,80}={0,2}$/) - t.end() + assert.match(headers['X-NewRelic-App-Data'], /^[a-zA-Z0-9/-]{60,80}={0,2}$/) + end() }) }) - t.test( + await t.test( 'should deobfuscate to CAT application data - DT disabled, app data header', - function (t) { + function (t, end) { + const { agent, shim } = t.nr helper.runInTransaction(agent, function () { const headers = {} shim.insertCATReplyHeader(headers) @@ -1005,13 +1035,13 @@ tap.test('TransactionShim', function (t) { agent.config.encoding_key ) - t.doesNotThrow(function () { + assert.doesNotThrow(function () { appData = JSON.parse(appData) }) - t.equal(appData.length, 7) - t.ok(Array.isArray(appData)) - t.end() + assert.equal(appData.length, 7) + assert.ok(Array.isArray(appData)) + end() }) } ) diff --git a/test/unit/shim/webframework-shim.test.js b/test/unit/shim/webframework-shim.test.js index 09cc192f09..ec1fe6f1ee 100644 --- a/test/unit/shim/webframework-shim.test.js +++ b/test/unit/shim/webframework-shim.test.js @@ -4,30 +4,64 @@ */ 'use strict' -const { test } = require('tap') - +const assert = require('node:assert') +const test = require('node:test') const sinon = require('sinon') const helper = require('../../lib/agent_helper') const Shim = require('../../../lib/shim/shim') const WebFrameworkShim = require('../../../lib/shim/webframework-shim') const symbols = require('../../../lib/symbols') const { MiddlewareSpec, RenderSpec } = require('../../../lib/shim/specs') +const tsplan = require('@matteo.collina/tspl') + +function createMiddleware({ ctx, path }) { + const { txInfo, shim } = ctx.nr + const unwrappedTimeout = shim.unwrap(setTimeout) + return function middleware(_req, err, next) { + ctx.nr.segment = shim.getSegment() + return new Promise(function (resolve, reject) { + unwrappedTimeout(function () { + try { + assert.equal(txInfo.transaction.nameState.getPath(), path) + if (next) { + return next().then( + function () { + assert.equal(txInfo.transaction.nameState.getPath(), path) + resolve() + }, + function (err) { + assert.equal(txInfo.transaction.nameState.getPath(), '/') + + if (err && err.name === 'AssertionError') { + // Reject assertion errors from promises to fail the test + reject(err) + } else { + // Resolve for errors purposely triggered for tests. + resolve() + } + } + ) + } + if (err) { + throw err + } else { + resolve() + } + } catch (e) { + reject(err) + } + }, 20) + }) + } +} -test.runOnly = true - -test('WebFrameworkShim', function (t) { - t.autoend() - let agent = null - let shim = null - let wrappable = null - let req = null - let txInfo = null - - function beforeEach() { - agent = helper.loadMockedAgent() - shim = new WebFrameworkShim(agent, 'test-restify') +test('WebFrameworkShim', async function (t) { + function beforeEach(ctx) { + ctx.nr = {} + const agent = helper.loadMockedAgent() + const shim = new WebFrameworkShim(agent, 'test-restify') shim.setFramework(WebFrameworkShim.RESTIFY) - wrappable = { + ctx.nr.wrappable = { name: 'this is a name', bar: function barsName(unused, params) { return 'bar' }, // eslint-disable-line fiz: function fizsName() { @@ -42,115 +76,111 @@ test('WebFrameworkShim', function (t) { } } - txInfo = { + const txInfo = { transaction: null, segmentStack: [], errorHandled: false, error: null } - req = { [symbols.transactionInfo]: txInfo, params: { foo: 'bar', biz: 'bang' } } + ctx.nr.req = { [symbols.transactionInfo]: txInfo, params: { foo: 'bar', biz: 'bang' } } + ctx.nr.agent = agent + ctx.nr.shim = shim + ctx.nr.txInfo = txInfo } - function afterEach() { - helper.unloadAgent(agent) - agent = null - shim = null - req = null - txInfo = null + function afterEach(ctx) { + helper.unloadAgent(ctx.nr.agent) } - t.test('constructor', function (t) { - t.autoend() + await t.test('constructor', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should inherit from Shim', function (t) { - t.ok(shim instanceof WebFrameworkShim) - t.ok(shim instanceof Shim) - t.end() + await t.test('should inherit from Shim', function (t) { + const { shim } = t.nr + assert.ok(shim instanceof WebFrameworkShim) + assert.ok(shim instanceof Shim) }) - t.test('should require the `agent` parameter', function (t) { - t.throws(function () { + await t.test('should require the `agent` parameter', function () { + assert.throws(function () { return new WebFrameworkShim() - }, /^Shim must be initialized with .*? agent/) - t.end() + }, 'Error: Shim must be initialized with agent and module name') }) - t.test('should require the `moduleName` parameter', function (t) { - t.throws(function () { + await t.test('should require the `moduleName` parameter', function (t) { + const { agent } = t.nr + assert.throws(function () { return new WebFrameworkShim(agent) - }, /^Shim must be initialized with .*? module name/) - t.end() + }, 'Error: Shim must be initialized with agent and module name') }) - t.test('should assign properties from parent', (t) => { + await t.test('should assign properties from parent', (t) => { + const { agent } = t.nr const mod = 'test-mod' const name = mod const version = '1.0.0' const shim = new WebFrameworkShim(agent, mod, mod, name, version) - t.equal(shim.moduleName, mod) - t.equal(agent, shim._agent) - t.equal(shim.pkgVersion, version) - t.end() + assert.equal(shim.moduleName, mod) + assert.equal(agent, shim._agent) + assert.equal(shim.pkgVersion, version) }) }) - t.test('enumerations', function (t) { - t.autoend() + await t.test('enumerations', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should enumerate well-known frameworks on the class and prototype', function (t) { + await t.test('should enumerate well-known frameworks on the class and prototype', function (t) { + const { shim } = t.nr const frameworks = ['CONNECT', 'DIRECTOR', 'EXPRESS', 'HAPI', 'RESTIFY'] frameworks.forEach(function (fw) { - t.ok(WebFrameworkShim[fw]) - t.ok(shim[fw]) + assert.ok(WebFrameworkShim[fw]) + assert.ok(shim[fw]) }) - t.end() }) - t.test('should enumerate middleware types on the class and prototype', function (t) { + await t.test('should enumerate middleware types on the class and prototype', function (t) { + const { shim } = t.nr const types = ['MIDDLEWARE', 'APPLICATION', 'ROUTER', 'ROUTE', 'ERRORWARE', 'PARAMWARE'] types.forEach(function (type) { - t.ok(WebFrameworkShim[type]) - t.ok(shim[type]) + assert.ok(WebFrameworkShim[type]) + assert.ok(shim[type]) }) - t.end() }) }) - t.test('#logger', function (t) { - t.autoend() + await t.test('#logger', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should be a non-writable property', function (t) { - t.throws(function () { + await t.test('should be a non-writable property', function (t) { + const { shim } = t.nr + assert.throws(function () { shim.logger = 'foobar' }) - t.not(shim.logger, 'foobar') - t.end() + assert.notDeepEqual(shim.logger, 'foobar') }) - t.test('should be a logger to use with the shim', function (t) { - t.ok(shim.logger.trace instanceof Function) - t.ok(shim.logger.debug instanceof Function) - t.ok(shim.logger.info instanceof Function) - t.ok(shim.logger.warn instanceof Function) - t.ok(shim.logger.error instanceof Function) - t.end() + await t.test('should be a logger to use with the shim', function (t) { + const { shim } = t.nr + assert.ok(shim.logger.trace instanceof Function) + assert.ok(shim.logger.debug instanceof Function) + assert.ok(shim.logger.info instanceof Function) + assert.ok(shim.logger.warn instanceof Function) + assert.ok(shim.logger.error instanceof Function) }) }) - t.test('#setRouteParser', function (t) { - t.autoend() + await t.test('#setRouteParser', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should set the function used to parse routes', function (t) { + + await t.test('should set the function used to parse routes', function (t) { + const { shim, wrappable } = t.nr let called = false shim.setRouteParser(function (shim, fn, fnName, route) { called = true - t.equal(route, '/foo/bar') + assert.equal(route, '/foo/bar') return route }) @@ -162,127 +192,125 @@ test('WebFrameworkShim', function (t) { }) wrappable.bar('/foo/bar', function () {}) - t.ok(called) - t.end() + assert.equal(called, true) }) }) - t.test('#setFramework', function (t) { - t.autoend() - - t.beforeEach(function () { - beforeEach() + await t.test('#setFramework', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { agent } = ctx.nr // Use a shim without a datastore set for these tests. - shim = new WebFrameworkShim(agent, 'test-cassandra') + ctx.nr.shim = new WebFrameworkShim(agent, 'test-cassandra') }) t.afterEach(afterEach) - t.test('should accept the id of a well-known framework', function (t) { - t.doesNotThrow(function () { + await t.test('should accept the id of a well-known framework', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.setFramework(shim.RESTIFY) }) - t.equal(shim._metrics.PREFIX, 'Restify/') - t.end() + assert.equal(shim._metrics.PREFIX, 'Restify/') }) - t.test('should create custom metric names if the `framework` is a string', function (t) { - t.doesNotThrow(function () { + await t.test('should create custom metric names if the `framework` is a string', function (t) { + const { shim } = t.nr + assert.doesNotThrow(function () { shim.setFramework('Fake Web Framework') }) - t.equal(shim._metrics.PREFIX, 'Fake Web Framework/') - t.end() + assert.equal(shim._metrics.PREFIX, 'Fake Web Framework/') }) - t.test("should update the shim's logger", function (t) { + await t.test("should update the shim's logger", function (t) { + const { shim } = t.nr const original = shim.logger shim.setFramework(shim.RESTIFY) - t.not(shim.logger, original) - t.equal(shim.logger.extra.framework, 'Restify') - t.end() + assert.notEqual(shim.logger, original) + assert.equal(shim.logger.extra.framework, 'Restify') }) - t.test('should set the Framework environment setting', function (t) { + await t.test('should set the Framework environment setting', function (t) { + const { agent, shim } = t.nr const env = agent.environment env.clearFramework() shim.setFramework(shim.RESTIFY) - t.same(env.get('Framework'), ['Restify']) - t.end() + assert.deepEqual(env.get('Framework'), ['Restify']) }) }) - t.test('#wrapMiddlewareMounter', function (t) { - t.autoend() + await t.test('#wrapMiddlewareMounter', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.wrapMiddlewareMounter(wrappable, {}) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.equal(shim.isWrapped(wrapped), false) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.wrapMiddlewareMounter(wrappable.bar, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.wrapMiddlewareMounter(wrappable.bar, null, {}) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.wrapMiddlewareMounter(wrappable, 'bar', {}) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.wrapMiddlewareMounter(wrappable, 'name', {}) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should call the middleware method for each function parameter', function (t) { + await t.test('should call the middleware method for each function parameter', function (t) { + const { shim, wrappable } = t.nr let callCount = 0 const args = [function a() {}, function b() {}, function c() {}] shim.wrapMiddlewareMounter(wrappable, 'bar', { wrapper: function (shim, fn, name) { - t.equal(fn, args[callCount]) - t.equal(name, args[callCount].name) + assert.equal(fn, args[callCount]) + assert.equal(name, args[callCount].name) ++callCount } }) wrappable.bar.apply(wrappable, args) - t.equal(callCount, args.length) - t.end() + assert.equal(callCount, args.length) }) - t.test('should call the original function with the wrapped middleware', function (t) { + await t.test('should call the original function with the wrapped middleware', function (t) { + const { shim } = t.nr let originalCallCount = 0 let wrapperCallCount = 0 const wrapped = shim.wrapMiddlewareMounter( function (a, b, c) { ++originalCallCount - t.equal(a, 1) - t.equal(b, 2) - t.equal(c, 3) + assert.equal(a, 1) + assert.equal(b, 2) + assert.equal(c, 3) }, { wrapper: function () { @@ -296,58 +324,67 @@ test('WebFrameworkShim', function (t) { function () {}, function () {} ) - t.equal(originalCallCount, 1) - t.equal(wrapperCallCount, 3) - t.end() + assert.equal(originalCallCount, 1) + assert.equal(wrapperCallCount, 3) }) - t.test('should pass the route to the middleware wrapper', function (t) { + await t.test('should pass the route to the middleware wrapper', function (t) { + const { shim, wrappable } = t.nr const realRoute = '/my/great/route' + let callCount = 0 shim.wrapMiddlewareMounter(wrappable, 'bar', { route: shim.FIRST, wrapper: function (shim, fn, name, route) { - t.equal(route, realRoute) + assert.equal(route, realRoute) + ++callCount } }) wrappable.bar(realRoute, function () {}) - t.end() + assert.equal(callCount, 1) }) - t.test('should pass an array of routes to the middleware wrapper', (t) => { + await t.test('should pass an array of routes to the middleware wrapper', (t) => { + const { shim, wrappable } = t.nr const routes = ['/my/great/route', '/another/great/route'] + let callCount = 0 shim.wrapMiddlewareMounter(wrappable, 'bar', { route: shim.FIRST, wrapper: (shim, fn, name, route) => { - t.same(route, routes) + assert.deepEqual(route, routes) + ++callCount } }) wrappable.bar(routes, () => {}) - t.end() + assert.equal(callCount, 1) }) - t.test('should not overwrite regex entries in the array of routes', (t) => { + await t.test('should not overwrite regex entries in the array of routes', (t) => { + const { shim, wrappable } = t.nr const routes = [/a\/b\/$/, /anotherRegex/, /a/] + let callCount = 0 shim.wrapMiddlewareMounter(wrappable, 'bar', { route: shim.FIRST, wrapper: () => { routes.forEach((r) => { - t.ok(r instanceof RegExp) + assert.ok(r instanceof RegExp) + ++callCount }) } }) wrappable.bar(routes, () => {}) - t.end() + assert.equal(callCount, 3) }) - t.test('should pass null if the route parameter is a middleware', function (t) { + await t.test('should pass null if the route parameter is a middleware', function (t) { + const { shim, wrappable } = t.nr let callCount = 0 shim.wrapMiddlewareMounter(wrappable, 'bar', { route: shim.FIRST, wrapper: function (shim, fn, name, route) { - t.equal(route, null) + assert.equal(route, null) ++callCount } }) @@ -356,16 +393,16 @@ test('WebFrameworkShim', function (t) { function () {}, function () {} ) - t.equal(callCount, 2) - t.end() + assert.equal(callCount, 2) }) - t.test('should pass null if the spec says there is no route', function (t) { + await t.test('should pass null if the spec says there is no route', function (t) { + const { shim, wrappable } = t.nr let callCount = 0 shim.wrapMiddlewareMounter(wrappable, 'bar', { route: null, wrapper: function (shim, fn, name, route) { - t.equal(route, null) + assert.equal(route, null) ++callCount } }) @@ -374,137 +411,142 @@ test('WebFrameworkShim', function (t) { function () {}, function () {} ) - t.equal(callCount, 2) - t.end() + assert.equal(callCount, 2) }) - t.test('should iterate through the contents of the array', function (t) { + await t.test('should iterate through the contents of the array', function (t) { + const { shim, wrappable } = t.nr let callCount = 0 const funcs = [function a() {}, function b() {}, function c() {}] const args = [[funcs[0], funcs[1]], funcs[2]] shim.wrapMiddlewareMounter(wrappable, 'bar', { wrapper: function (shim, fn, name) { - t.equal(fn, funcs[callCount]) - t.equal(name, funcs[callCount].name) + assert.equal(fn, funcs[callCount]) + assert.equal(name, funcs[callCount].name) ++callCount } }) wrappable.bar.apply(wrappable, args) - t.equal(funcs.length, callCount) - t.end() + assert.equal(funcs.length, callCount) }) - t.test('should iterate through the contents of nested arrays too', function (t) { + await t.test('should iterate through the contents of nested arrays too', function (t) { + const { shim, wrappable } = t.nr let callCount = 0 const funcs = [function a() {}, function b() {}, function c() {}] const args = [[[[[funcs[0], [[funcs[1]]]]], funcs[2]]]] shim.wrapMiddlewareMounter(wrappable, 'bar', { wrapper: function (shim, fn, name) { - t.equal(fn, funcs[callCount]) - t.equal(name, funcs[callCount].name) + assert.equal(fn, funcs[callCount]) + assert.equal(name, funcs[callCount].name) ++callCount } }) wrappable.bar.apply(wrappable, args) - t.equal(funcs.length, callCount) - t.end() + assert.equal(funcs.length, callCount) }) }) - t.test('#recordMiddleware', function (t) { - t.autoend() + await t.test('#recordMiddleware', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordMiddleware(wrappable, new MiddlewareSpec({})) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.ok(!shim.isWrapped(wrapped)) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordMiddleware(wrappable.bar, new MiddlewareSpec({})) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordMiddleware(wrappable.bar, null, new MiddlewareSpec({})) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordMiddleware(wrappable, 'bar', new MiddlewareSpec({})) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordMiddleware(wrappable, 'name', new MiddlewareSpec({})) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should call the wrapped function', function (t) { + await t.test('should call the wrapped function', function (t, end) { + const { agent, req, shim, txInfo } = t.nr let called = false const wrapped = shim.recordMiddleware(function (_req, a, b, c) { called = true - t.equal(_req, req) - t.equal(a, 'a') - t.equal(b, 'b') - t.equal(c, 'c') + assert.equal(_req, req) + assert.equal(a, 'a') + assert.equal(b, 'b') + assert.equal(c, 'c') }, new MiddlewareSpec({})) helper.runInTransaction(agent, function (tx) { txInfo.transaction = tx - t.notOk(called) + assert.equal(called, false) wrapped(req, 'a', 'b', 'c') - t.ok(called) - t.end() + assert.equal(called, true) + end() }) }) - t.test('should not affect transaction name state if type is errorware', function (t) { - testType(shim.ERRORWARE, 'Nodejs/Middleware/Restify/getActiveSegment//foo/bar') - - function testType(type, expectedName) { - const wrapped = shim.recordMiddleware( - wrappable.getActiveSegment, - new MiddlewareSpec({ - type: type, - route: '/foo/bar' + await t.test( + 'should not affect transaction name state if type is errorware', + function (t, end) { + const { agent, req, shim, txInfo, wrappable } = t.nr + testType(shim.ERRORWARE, 'Nodejs/Middleware/Restify/getActiveSegment//foo/bar') + + function testType(type, expectedName) { + const wrapped = shim.recordMiddleware( + wrappable.getActiveSegment, + new MiddlewareSpec({ + type: type, + route: '/foo/bar' + }) + ) + helper.runInTransaction(agent, function (tx) { + txInfo.transaction = tx + sinon.spy(tx.nameState, 'appendPath') + sinon.spy(tx.nameState, 'popPath') + const segment = wrapped(req) + + assert.ok(!tx.nameState.appendPath.called) + assert.ok(!tx.nameState.popPath.called) + assert.equal(segment.name, expectedName) + end() }) - ) - helper.runInTransaction(agent, function (tx) { - txInfo.transaction = tx - sinon.spy(tx.nameState, 'appendPath') - sinon.spy(tx.nameState, 'popPath') - const segment = wrapped(req) - - t.notOk(tx.nameState.appendPath.called) - t.notOk(tx.nameState.popPath.called) - t.equal(segment.name, expectedName) - }) + } } - t.end() - }) + ) - t.test('should name the segment according to the middleware type', function (t) { + await t.test('should name the segment according to the middleware type', function (t) { + const plan = tsplan(t, { plan: 6 }) + const { agent, req, shim, txInfo, wrappable } = t.nr testType(shim.MIDDLEWARE, 'Nodejs/Middleware/Restify/getActiveSegment//foo/bar') testType(shim.APPLICATION, 'Restify/Mounted App: /foo/bar') testType(shim.ROUTER, 'Restify/Router: /foo/bar') @@ -524,13 +566,14 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx const segment = wrapped(req) - t.equal(segment.name, expectedName) + plan.equal(segment.name, expectedName) }) } - t.end() }) - t.test('should not append a route if one is not given', function (t) { + await t.test('should not append a route if one is not given', function (t) { + const plan = tsplan(t, { plan: 6 }) + const { agent, req, shim, txInfo, wrappable } = t.nr testType(shim.MIDDLEWARE, 'Nodejs/Middleware/Restify/getActiveSegment') testType(shim.APPLICATION, 'Restify/Mounted App: /') testType(shim.ROUTER, 'Restify/Router: /') @@ -550,13 +593,14 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx const segment = wrapped(req) - t.equal(segment.name, expectedName) + plan.equal(segment.name, expectedName) }) } - t.end() }) - t.test('should not prepend root if the value is an array', function (t) { + await t.test('should not prepend root if the value is an array', function (t) { + const plan = tsplan(t, { plan: 6 }) + const { agent, req, shim, txInfo, wrappable } = t.nr testType(shim.MIDDLEWARE, 'Nodejs/Middleware/Restify/getActiveSegment//one,/two') testType(shim.APPLICATION, 'Restify/Mounted App: /one,/two') testType(shim.ROUTER, 'Restify/Router: /one,/two') @@ -576,13 +620,13 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx const segment = wrapped(req) - t.equal(segment.name, expectedName) + plan.equal(segment.name, expectedName) }) } - t.end() }) - t.test('should reinstate its own context', function (t) { + await t.test('should reinstate its own context', function (t, end) { + const { agent, req, shim, txInfo, wrappable } = t.nr testType(shim.MIDDLEWARE, 'Nodejs/Middleware/Restify/getActiveSegment') function testType(type, expectedName) { @@ -601,12 +645,13 @@ test('WebFrameworkShim', function (t) { const segment = wrapped(req) - t.equal(segment.name, expectedName) + assert.equal(segment.name, expectedName) + end() } - t.end() }) - t.test('should capture route parameters when high_security is off', function (t) { + await t.test('should capture route parameters when high_security is off', function (t, end) { + const { agent, req, shim, txInfo, wrappable } = t.nr agent.config.high_security = false const wrapped = shim.recordMiddleware( wrappable.getActiveSegment, @@ -619,20 +664,21 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx const segment = wrapped(req) - t.ok(segment.attributes) + assert.ok(segment.attributes) const attrs = segment.getAttributes() - t.equal(attrs['request.parameters.route.foo'], 'bar') - t.equal(attrs['request.parameters.route.biz'], 'bang') + assert.equal(attrs['request.parameters.route.foo'], 'bar') + assert.equal(attrs['request.parameters.route.biz'], 'bang') const filePathSplit = attrs['code.filepath'].split('/') - t.equal(filePathSplit[filePathSplit.length - 1], 'webframework-shim.test.js') - t.equal(attrs['code.function'], 'getActiveSegment') - t.equal(attrs['code.lineno'], 40) - t.equal(attrs['code.column'], 50) - t.end() + assert.equal(filePathSplit[filePathSplit.length - 1], 'webframework-shim.test.js') + assert.equal(attrs['code.function'], 'getActiveSegment') + assert.equal(attrs['code.lineno'], 74) + assert.equal(attrs['code.column'], 50) + end() }) }) - t.test('should not capture route parameters when high_security is on', function (t) { + await t.test('should not capture route parameters when high_security is on', function (t, end) { + const { agent, req, shim, txInfo, wrappable } = t.nr agent.config.high_security = true const wrapped = shim.recordMiddleware( wrappable.getActiveSegment, @@ -645,67 +691,77 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx const segment = wrapped(req) - t.ok(segment.attributes) + assert.ok(segment.attributes) const attrs = Object.keys(segment.getAttributes()) const requestParameters = /request\.parameters.*/ - t.notOk(attrs.some((attr) => requestParameters.test(attr))) - t.end() + assert.ok(!attrs.some((attr) => requestParameters.test(attr))) + end() }) }) - t.test('should notice thrown exceptions', function (t) { + await t.test('should notice thrown exceptions', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordMiddleware(function () { throw new Error('foobar') }, new MiddlewareSpec({})) helper.runInTransaction(agent, function (tx) { txInfo.transaction = tx - t.throws(() => { + assert.throws(() => { wrapped(req) - }, 'foobar') + }, 'Error: foobar') - t.match(txInfo.error, /foobar/) - t.notOk(txInfo.errorHandled) - t.end() + assert.equal(txInfo.error, 'Error: foobar') + assert.equal(txInfo.errorHandled, false) + end() }) }) - t.test('pops the name if error was thrown and there is no next handler', function (t) { - const wrapped = shim.recordMiddleware(function () { - throw new Error('foobar') - }, new MiddlewareSpec({ route: '/foo/bar' })) + await t.test( + 'pops the name if error was thrown and there is no next handler', + function (t, end) { + const { agent, req, shim, txInfo } = t.nr + const wrapped = shim.recordMiddleware(function () { + throw new Error('foobar') + }, new MiddlewareSpec({ route: '/foo/bar' })) - helper.runInTransaction(agent, function (tx) { - tx.nameState.appendPath('/') - txInfo.transaction = tx - t.throws(() => { - wrapped(req) + helper.runInTransaction(agent, function (tx) { + tx.nameState.appendPath('/') + txInfo.transaction = tx + assert.throws(() => { + wrapped(req) + }) + + assert.equal(tx.nameState.getPath(), '/foo/bar') + end() }) + } + ) - t.equal(tx.nameState.getPath(), '/foo/bar') - t.end() - }) - }) + await t.test( + 'does not pop the name if there was an error and a next handler', + function (t, end) { + const { agent, req, shim, txInfo } = t.nr + const wrapped = shim.recordMiddleware(function () { + throw new Error('foobar') + }, new MiddlewareSpec({ route: '/foo/bar', next: shim.SECOND })) - t.test('does not pop the name if there was an error and a next handler', function (t) { - const wrapped = shim.recordMiddleware(function () { - throw new Error('foobar') - }, new MiddlewareSpec({ route: '/foo/bar', next: shim.SECOND })) + helper.runInTransaction(agent, function (tx) { + tx.nameState.appendPath('/') + txInfo.transaction = tx + assert.throws(() => { + wrapped(req, function () {}) + }) - helper.runInTransaction(agent, function (tx) { - tx.nameState.appendPath('/') - txInfo.transaction = tx - t.throws(() => { - wrapped(req, function () {}) + assert.equal(tx.nameState.getPath(), '/foo/bar') + end() }) + } + ) - t.equal(tx.nameState.getPath(), '/foo/bar') - t.end() - }) - }) - - t.test('should pop the namestate if there was no error', function (t) { + await t.test('should pop the namestate if there was no error', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordMiddleware(function () {}, new MiddlewareSpec({ route: '/foo/bar' })) @@ -714,12 +770,13 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx wrapped(req) - t.equal(tx.nameState.getPath(), '/') - t.end() + assert.equal(tx.nameState.getPath(), '/') + end() }) }) - t.test('should pop the namestate if error is not an error', function (t) { + await t.test('should pop the namestate if error is not an error', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordMiddleware(function (r, obj, next) { next(obj) }, new MiddlewareSpec({ route: '/foo/bar' })) @@ -734,14 +791,15 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx wrapped(req, {}, function () {}) // Not an error! - t.equal(tx.nameState.getPath(), '/') + assert.equal(tx.nameState.getPath(), '/') wrapped(req, err, function () {}) // Error! - t.equal(tx.nameState.getPath(), '/foo/bar') - t.end() + assert.equal(tx.nameState.getPath(), '/foo/bar') + end() }) }) - t.test('should notice errors handed to the callback', function (t) { + await t.test('should notice errors handed to the callback', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordMiddleware(function (_req, next) { setTimeout(next, 10, new Error('foobar')) }, new MiddlewareSpec({ next: shim.LAST })) @@ -749,17 +807,18 @@ test('WebFrameworkShim', function (t) { helper.runInTransaction(agent, function (tx) { txInfo.transaction = tx wrapped(req, function (err) { - t.ok(err instanceof Error) - t.equal(err.message, 'foobar') + assert.ok(err instanceof Error) + assert.equal(err.message, 'foobar') - t.equal(txInfo.error, err) - t.notOk(txInfo.errorHandled) - t.end() + assert.equal(txInfo.error, err) + assert.equal(txInfo.errorHandled, false) + end() }) }) }) - t.test('should not pop the name if there was an error', function (t) { + await t.test('should not pop the name if there was an error', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordMiddleware(function (_req, next) { setTimeout(next, 10, new Error('foobar')) }, new MiddlewareSpec({ route: '/foo/bar', next: shim.LAST })) @@ -768,16 +827,17 @@ test('WebFrameworkShim', function (t) { tx.nameState.appendPath('/') txInfo.transaction = tx wrapped(req, function () { - t.equal(tx.nameState.getPath(), '/foo/bar') - t.end() + assert.equal(tx.nameState.getPath(), '/foo/bar') + end() }) }) }) - t.test('should pop the namestate if there was no error', function (t) { + await t.test('should pop the namestate if there was no error', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordMiddleware(function (_req, next) { setTimeout(function () { - t.equal(txInfo.transaction.nameState.getPath(), '/foo/bar') + assert.equal(txInfo.transaction.nameState.getPath(), '/foo/bar') next() }, 10) }, new MiddlewareSpec({ route: '/foo/bar', next: shim.LAST })) @@ -786,13 +846,14 @@ test('WebFrameworkShim', function (t) { tx.nameState.appendPath('/') txInfo.transaction = tx wrapped(req, function () { - t.equal(tx.nameState.getPath(), '/') - t.end() + assert.equal(tx.nameState.getPath(), '/') + end() }) }) }) - t.test('should not append path and should not pop path', function (t) { + await t.test('should not append path and should not pop path', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const spec = new MiddlewareSpec({ route: '/foo/bar', appendPath: false, @@ -802,7 +863,7 @@ test('WebFrameworkShim', function (t) { const wrapped = shim.recordMiddleware(function (_req, next) { setTimeout(function () { // verify did not append the path - t.equal(txInfo.transaction.nameState.getPath(), '/expected') + assert.equal(txInfo.transaction.nameState.getPath(), '/expected') next() }, 10) }, spec) @@ -814,13 +875,14 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx wrapped(req, function () { // verify did not pop back to '/' from '/expected' - t.equal(tx.nameState.getPath(), '/expected') - t.end() + assert.equal(tx.nameState.getPath(), '/expected') + end() }) }) }) - t.test('should mark the error as handled', function (t) { + await t.test('should mark the error as handled', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordMiddleware(function () { throw new Error('foobar') }, new MiddlewareSpec({})) @@ -838,18 +900,19 @@ test('WebFrameworkShim', function (t) { try { wrapped(req) } catch (err) { - t.equal(txInfo.error, err) - t.notOk(txInfo.errorHandled) + assert.equal(txInfo.error, err) + assert.equal(txInfo.errorHandled, false) errorware(err, req) - t.equal(txInfo.error, err) - t.ok(txInfo.errorHandled) - t.end() + assert.equal(txInfo.error, err) + assert.equal(txInfo.errorHandled, true) + end() } }) }) - t.test('should notice if the errorware errors', function (t) { + await t.test('should notice if the errorware errors', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordMiddleware(function () { throw new Error('foobar') }, new MiddlewareSpec({})) @@ -863,69 +926,27 @@ test('WebFrameworkShim', function (t) { try { wrapped(req) } catch (err) { - t.equal(txInfo.error, err) - t.notOk(txInfo.errorHandled) + assert.equal(txInfo.error, err) + assert.equal(txInfo.errorHandled, false) try { errorware(err, req) } catch (err2) { - t.equal(txInfo.error, err2) - t.notOk(txInfo.errorHandled) - t.end() + assert.equal(txInfo.error, err2) + assert.equal(txInfo.errorHandled, false) + end() } } }) }) }) - t.test('#recordMiddleware when middleware returns a promise', function (t) { - t.autoend() - let unwrappedTimeout = null - let middleware = null - let wrapped = null - let segment = null - - t.beforeEach(function () { - beforeEach() - unwrappedTimeout = shim.unwrap(setTimeout) - middleware = function (_req, err, next) { - segment = shim.getSegment() - return new Promise(function (resolve, reject) { - unwrappedTimeout(function () { - try { - t.equal(txInfo.transaction.nameState.getPath(), '/foo/bar') - if (next) { - return next().then( - function () { - t.equal(txInfo.transaction.nameState.getPath(), '/foo/bar') - resolve() - }, - function (err) { - t.equal(txInfo.transaction.nameState.getPath(), '/') - - if (err && err.name === 'AssertionError') { - // Reject assertion errors from promises to fail the test - reject(err) - } else { - // Resolve for errors purposely triggered for tests. - resolve() - } - } - ) - } - if (err) { - throw err - } else { - resolve() - } - } catch (e) { - reject(err) - } - }, 20) - }) - } - - wrapped = shim.recordMiddleware( + await t.test('#recordMiddleware when middleware returns a promise', async function (t) { + t.beforeEach(function (ctx) { + beforeEach(ctx) + const { shim } = ctx.nr + const middleware = createMiddleware({ ctx, path: '/foo/bar' }) + ctx.nr.wrapped = shim.recordMiddleware( middleware, new MiddlewareSpec({ route: '/foo/bar', @@ -933,85 +954,92 @@ test('WebFrameworkShim', function (t) { promise: true }) ) + ctx.nr.middleware = middleware }) t.afterEach(afterEach) - t.test('should notice errors from rejected promises', function (t) { + await t.test('should notice errors from rejected promises', async function (t) { + const { agent, req, txInfo, wrapped } = t.nr return helper.runInTransaction(agent, function (tx) { txInfo.transaction = tx return wrapped(req, new Error('foobar')).catch(function (err) { - t.ok(err instanceof Error) - t.equal(err.message, 'foobar') - t.equal(txInfo.error, err) - t.notOk(txInfo.errorHandled) + assert.ok(err instanceof Error) + assert.equal(err.message, 'foobar') + assert.equal(txInfo.error, err) + assert.ok(!txInfo.errorHandled) - t.ok(segment.timer.getDurationInMillis() > 18) + assert.ok(t.nr.segment.timer.getDurationInMillis() > 18) }) }) }) - t.test('should not pop the name if there was an error', function (t) { + await t.test('should not pop the name if there was an error', async function (t) { + const { agent, req, txInfo, wrapped } = t.nr return helper.runInTransaction(agent, function (tx) { tx.nameState.appendPath('/') txInfo.transaction = tx return wrapped(req, new Error('foobar')).catch(function () { - t.equal(tx.nameState.getPath(), '/foo/bar') - t.ok(segment.timer.getDurationInMillis() > 18) + assert.equal(tx.nameState.getPath(), '/foo/bar') + assert.ok(t.nr.segment.timer.getDurationInMillis() > 18) }) }) }) - t.test('should pop the namestate if there was no error', function (t) { + await t.test('should pop the namestate if there was no error', async function (t) { + const { agent, req, txInfo, wrapped } = t.nr return helper.runInTransaction(agent, function (tx) { tx.nameState.appendPath('/') txInfo.transaction = tx return wrapped(req).then(function () { - t.equal(tx.nameState.getPath(), '/') - t.ok(segment.timer.getDurationInMillis() > 18) + assert.equal(tx.nameState.getPath(), '/') + assert.ok(t.nr.segment.timer.getDurationInMillis() > 18) }) }) }) - t.test('should pop the name of the handler off when next is called', function (t) { + await t.test('should pop the name of the handler off when next is called', async function (t) { + const { agent, req, txInfo, wrapped } = t.nr return helper.runInTransaction(agent, function (tx) { tx.nameState.appendPath('/') txInfo.transaction = tx return wrapped(req, null, function next() { - t.equal(tx.nameState.getPath(), '/') + assert.equal(tx.nameState.getPath(), '/') return new Promise(function (resolve) { - t.equal(agent.tracer.getTransaction(), tx) + assert.equal(agent.tracer.getTransaction(), tx) resolve() }) }) }) }) - t.test('should have the right name when the next handler errors', function (t) { + await t.test('should have the right name when the next handler errors', async function (t) { + const { agent, req, txInfo, wrapped } = t.nr return helper.runInTransaction(agent, function (tx) { tx.nameState.appendPath('/') txInfo.transaction = tx return wrapped(req, null, function next() { - t.equal(tx.nameState.getPath(), '/') + assert.equal(tx.nameState.getPath(), '/') return new Promise(function (resolve, reject) { - t.equal(agent.tracer.getTransaction(), tx) + assert.equal(agent.tracer.getTransaction(), tx) reject() }) }) }) }) - t.test('should appropriately parent child segments in promise', () => { + await t.test('should appropriately parent child segments in promise', async (t) => { + const { agent, req, txInfo, wrapped } = t.nr return helper.runInTransaction(agent, (tx) => { tx.nameState.appendPath('/') txInfo.transaction = tx return wrapped(req, null, () => { return new Promise((resolve) => { const _tx = agent.tracer.getTransaction() - t.equal(_tx, tx) - t.equal(_tx.nameState.getPath(), '/') + assert.equal(_tx, tx) + assert.equal(_tx.nameState.getPath(), '/') const childSegment = _tx.agent.tracer.createSegment('childSegment') - t.equal(childSegment.parent.name, 'Nodejs/Middleware/Restify/middleware//foo/bar') + assert.equal(childSegment.parent.name, 'Nodejs/Middleware/Restify/middleware//foo/bar') resolve() }) @@ -1020,142 +1048,107 @@ test('WebFrameworkShim', function (t) { }) }) - t.test('#recordMiddleware when middleware returns promise and spec.appendPath is false', (t) => { - t.autoend() - let unwrappedTimeout = null - let middleware = null - let wrapped = null - - t.beforeEach(() => { - beforeEach() - unwrappedTimeout = shim.unwrap(setTimeout) - middleware = (_req, err, next) => { - return new Promise((resolve, reject) => { - unwrappedTimeout(() => { - try { - t.equal(txInfo.transaction.nameState.getPath(), '/') - if (next) { - return next().then( - () => { - t.equal(txInfo.transaction.nameState.getPath(), '/') - resolve() - }, - (err) => { - t.equal(txInfo.transaction.nameState.getPath(), '/') - - if (err && err.name === 'AssertionError') { - // Reject assertion errors from promises to fail the test - reject(err) - } else { - // Resolve for errors purposely triggered for tests. - resolve() - } - } - ) - } - if (err) { - throw err - } else { - resolve() - } - } catch (e) { - reject(err) - } - }, 20) - }) - } - }) - t.afterEach(afterEach) + await t.test( + '#recordMiddleware when middleware returns promise and spec.appendPath is false', + async (t) => { + t.beforeEach((ctx) => { + beforeEach(ctx) + ctx.nr.middleware = createMiddleware({ ctx, path: '/' }) + }) + t.afterEach(afterEach) - t.test('should not append path when spec.appendPath is false', () => { - wrapped = shim.recordMiddleware( - middleware, - new MiddlewareSpec({ - route: '/foo/bar', - appendPath: false, - next: shim.LAST, - promise: true - }) - ) - return helper.runInTransaction(agent, (tx) => { - tx.nameState.appendPath('/') - txInfo.transaction = tx - return wrapped(req, null, () => { - t.equal(tx.nameState.getPath(), '/') - return new Promise((resolve) => { - const _tx = agent.tracer.getTransaction() - t.equal(_tx, tx) - t.equal(_tx.nameState.getPath(), '/') - resolve() + await t.test('should not append path when spec.appendPath is false', async (t) => { + const { agent, middleware, req, shim, txInfo } = t.nr + const wrapped = shim.recordMiddleware( + middleware, + new MiddlewareSpec({ + route: '/foo/bar', + appendPath: false, + next: shim.LAST, + promise: true + }) + ) + return helper.runInTransaction(agent, (tx) => { + tx.nameState.appendPath('/') + txInfo.transaction = tx + return wrapped(req, null, () => { + assert.equal(tx.nameState.getPath(), '/') + return new Promise((resolve) => { + const _tx = agent.tracer.getTransaction() + assert.equal(_tx, tx) + assert.equal(_tx.nameState.getPath(), '/') + resolve() + }) }) }) }) - }) - }) + } + ) - t.test('#recordParamware', function (t) { - t.autoend() + await t.test('#recordParamware', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordParamware(wrappable, new MiddlewareSpec({})) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.equal(shim.isWrapped(wrapped), false) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordParamware(wrappable.bar, new MiddlewareSpec({})) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordParamware(wrappable.bar, null, new MiddlewareSpec({})) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordParamware(wrappable, 'bar', new MiddlewareSpec({})) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordParamware(wrappable, 'name', new MiddlewareSpec({})) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should call the wrapped function', function (t) { + await t.test('should call the wrapped function', function (t, end) { + const { agent, req, shim, txInfo } = t.nr let called = false const wrapped = shim.recordParamware(function (_req, a, b, c) { called = true - t.equal(_req, req) - t.equal(a, 'a') - t.equal(b, 'b') - t.equal(c, 'c') + assert.equal(_req, req) + assert.equal(a, 'a') + assert.equal(b, 'b') + assert.equal(c, 'c') }, new MiddlewareSpec({})) helper.runInTransaction(agent, function (tx) { txInfo.transaction = tx - t.notOk(called) + assert.equal(called, false) wrapped(req, 'a', 'b', 'c') - t.ok(called) - t.end() + assert.equal(called, true) + end() }) }) - t.test('should name the segment as a paramware', function (t) { + await t.test('should name the segment as a paramware', function (t, end) { + const { agent, req, shim, wrappable, txInfo } = t.nr testType(shim.PARAMWARE, 'Nodejs/Middleware/Restify/getActiveSegment//[param handler :foo]') function testType(type, expectedName) { @@ -1170,13 +1163,14 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx const segment = wrapped(req) - t.equal(segment.name, expectedName) + assert.equal(segment.name, expectedName) + end() }) } - t.end() }) - t.test('should notice thrown exceptions', function (t) { + await t.test('should notice thrown exceptions', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordParamware(function () { throw new Error('foobar') }, new MiddlewareSpec({})) @@ -1188,16 +1182,17 @@ test('WebFrameworkShim', function (t) { wrapped(req) } catch (e) { err = e - t.ok(e instanceof Error) - t.equal(e.message, 'foobar') + assert.ok(e instanceof Error) + assert.equal(e.message, 'foobar') } - t.equal(txInfo.error, err) - t.notOk(txInfo.errorHandled) - t.end() + assert.equal(txInfo.error, err) + assert.ok(!txInfo.errorHandled) + end() }) }) - t.test('should not pop the name if there was an error', function (t) { + await t.test('should not pop the name if there was an error', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordParamware(function () { throw new Error('foobar') }, new MiddlewareSpec({ name: 'bar' })) @@ -1205,16 +1200,17 @@ test('WebFrameworkShim', function (t) { helper.runInTransaction(agent, function (tx) { tx.nameState.appendPath('/foo/') txInfo.transaction = tx - t.throws(() => { + assert.throws(() => { wrapped(req) }) - t.equal(tx.nameState.getPath(), '/foo/[param handler :bar]') - t.end() + assert.equal(tx.nameState.getPath(), '/foo/[param handler :bar]') + end() }) }) - t.test('should pop the namestate if there was no error', function (t) { + await t.test('should pop the namestate if there was no error', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordParamware(function () {}, new MiddlewareSpec({ name: 'bar' })) helper.runInTransaction(agent, function (tx) { @@ -1222,12 +1218,13 @@ test('WebFrameworkShim', function (t) { txInfo.transaction = tx wrapped(req) - t.equal(tx.nameState.getPath(), '/foo') - t.end() + assert.equal(tx.nameState.getPath(), '/foo') + end() }) }) - t.test('should notice errors handed to the callback', function (t) { + await t.test('should notice errors handed to the callback', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordParamware(function (_req, next) { setTimeout(next, 10, new Error('foobar')) }, new MiddlewareSpec({ next: shim.LAST })) @@ -1235,17 +1232,18 @@ test('WebFrameworkShim', function (t) { helper.runInTransaction(agent, function (tx) { txInfo.transaction = tx wrapped(req, function (err) { - t.ok(err instanceof Error) - t.equal(err.message, 'foobar') + assert.ok(err instanceof Error) + assert.equal(err.message, 'foobar') - t.equal(txInfo.error, err) - t.notOk(txInfo.errorHandled) - t.end() + assert.equal(txInfo.error, err) + assert.ok(!txInfo.errorHandled) + end() }) }) }) - t.test('should not pop the name if there was an error', function (t) { + await t.test('should not pop the name if there was an error', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordParamware(function (_req, next) { setTimeout(next, 10, new Error('foobar')) }, new MiddlewareSpec({ name: 'bar', next: shim.LAST })) @@ -1254,16 +1252,17 @@ test('WebFrameworkShim', function (t) { tx.nameState.appendPath('/foo') txInfo.transaction = tx wrapped(req, function () { - t.equal(tx.nameState.getPath(), '/foo/[param handler :bar]') - t.end() + assert.equal(tx.nameState.getPath(), '/foo/[param handler :bar]') + end() }) }) }) - t.test('should pop the namestate if there was no error', function (t) { + await t.test('should pop the namestate if there was no error', function (t, end) { + const { agent, req, shim, txInfo } = t.nr const wrapped = shim.recordParamware(function (_req, next) { setTimeout(function () { - t.equal(txInfo.transaction.nameState.getPath(), '/foo/[param handler :bar]') + assert.equal(txInfo.transaction.nameState.getPath(), '/foo/[param handler :bar]') next() }, 10) }, new MiddlewareSpec({ name: 'bar', next: shim.LAST })) @@ -1272,183 +1271,181 @@ test('WebFrameworkShim', function (t) { tx.nameState.appendPath('/foo') txInfo.transaction = tx wrapped(req, function () { - t.equal(tx.nameState.getPath(), '/foo') - t.end() + assert.equal(tx.nameState.getPath(), '/foo') + end() }) }) }) }) - t.test('#recordRender', function (t) { - t.autoend() + await t.test('#recordRender', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should not wrap non-function objects', function (t) { + await t.test('should not wrap non-function objects', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordRender(wrappable, new RenderSpec({ view: shim.FIRST })) - t.equal(wrapped, wrappable) - t.notOk(shim.isWrapped(wrapped)) - t.end() + assert.equal(wrapped, wrappable) + assert.equal(shim.isWrapped(wrapped), false) }) - t.test('should wrap the first parameter if no properties are given', function (t) { + await t.test('should wrap the first parameter if no properties are given', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordRender(wrappable.bar, new RenderSpec({ view: shim.FIRST })) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should wrap the first parameter if `null` is given for properties', function (t) { + await t.test('should wrap the first parameter if `null` is given for properties', function (t) { + const { shim, wrappable } = t.nr const wrapped = shim.recordRender(wrappable.bar, null, new RenderSpec({ view: shim.FIRST })) - t.not(wrapped, wrappable.bar) - t.ok(shim.isWrapped(wrapped)) - t.equal(shim.unwrap(wrapped), wrappable.bar) - t.end() + assert.notEqual(wrapped, wrappable.bar) + assert.equal(shim.isWrapped(wrapped), true) + assert.equal(shim.unwrap(wrapped), wrappable.bar) }) - t.test('should replace wrapped properties on the original object', function (t) { + await t.test('should replace wrapped properties on the original object', function (t) { + const { shim, wrappable } = t.nr const original = wrappable.bar shim.recordRender(wrappable, 'bar', new RenderSpec({ view: shim.FIRST })) - t.not(wrappable.bar, original) - t.ok(shim.isWrapped(wrappable.bar)) - t.equal(shim.unwrap(wrappable.bar), original) - t.end() + assert.notEqual(wrappable.bar, original) + assert.equal(shim.isWrapped(wrappable.bar), true) + assert.equal(shim.unwrap(wrappable.bar), original) }) - t.test('should not mark unwrapped properties as wrapped', function (t) { + await t.test('should not mark unwrapped properties as wrapped', function (t) { + const { shim, wrappable } = t.nr shim.recordRender(wrappable, 'name', new RenderSpec({ view: shim.FIRST })) - t.notOk(shim.isWrapped(wrappable.name)) - t.end() + assert.equal(shim.isWrapped(wrappable.name), false) }) - t.test('should call the wrapped function', function (t) { + await t.test('should call the wrapped function', function (t, end) { + const { shim } = t.nr let called = false const wrapped = shim.recordRender(function () { called = true }, new RenderSpec({ view: shim.FIRST })) - t.notOk(called) + assert.equal(called, false) wrapped() - t.ok(called) - t.end() + assert.equal(called, true) + end() }) - t.test('should create a segment', function (t) { + await t.test('should create a segment', function (t, end) { + const { agent, shim, wrappable } = t.nr shim.recordRender(wrappable, 'getActiveSegment', new RenderSpec({ view: shim.FIRST })) helper.runInTransaction(agent, function () { const segment = wrappable.getActiveSegment('viewToRender') - t.equal(segment.name, 'View/viewToRender/Rendering') - t.end() + assert.equal(segment.name, 'View/viewToRender/Rendering') + end() }) }) }) - t.test('#savePossibleTransactionName', function (t) { - t.autoend() + await t.test('#savePossibleTransactionName', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should mark the path on the namestate', function (t) { + await t.test('should mark the path on the namestate', function (t, end) { + const { agent, req, shim, txInfo } = t.nr helper.runInTransaction(agent, function (tx) { txInfo.transaction = tx const ns = tx.nameState ns.appendPath('asdf') shim.savePossibleTransactionName(req) ns.popPath() - t.equal(ns.getPath(), '/asdf') - t.end() + assert.equal(ns.getPath(), '/asdf') + end() }) }) - t.test('should not explode when no req object is passed in', function (t) { - t.doesNotThrow(() => { + await t.test('should not explode when no req object is passed in', function (t) { + const { shim } = t.nr + assert.doesNotThrow(() => { shim.savePossibleTransactionName() }) - t.end() }) }) - t.test('#noticeError', function (t) { - t.autoend() + await t.test('#noticeError', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should cache errors in the transaction info', function (t) { + await t.test('should cache errors in the transaction info', function (t) { + const { req, shim, txInfo } = t.nr const err = new Error('test error') shim.noticeError(req, err) - t.equal(txInfo.error, err) - t.end() + assert.equal(txInfo.error, err) }) - t.test('should set handled to false', function (t) { + await t.test('should set handled to false', function (t) { + const { req, shim, txInfo } = t.nr const err = new Error('test error') txInfo.errorHandled = true shim.noticeError(req, err) - t.notOk(txInfo.errorHandled) - t.end() + assert.equal(txInfo.errorHandled, false) }) - t.test('should not change the error state for non-errors', function (t) { + await t.test('should not change the error state for non-errors', function (t) { + const { req, shim, txInfo } = t.nr shim.noticeError(req, null) - t.equal(txInfo.error, null) - t.notOk(txInfo.errorHandled) + assert.equal(txInfo.error, null) + assert.ok(!txInfo.errorHandled) const err = new Error('test error') txInfo.error = err txInfo.errorHandled = true shim.noticeError(req, null) - t.equal(txInfo.error, err) - t.ok(txInfo.errorHandled) - t.end() + assert.equal(txInfo.error, err) + assert.equal(txInfo.errorHandled, true) }) }) - t.test('#errorHandled', function (t) { - t.autoend() + await t.test('#errorHandled', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should mark the error as handled', function (t) { + await t.test('should mark the error as handled', function (t) { + const { req, shim, txInfo } = t.nr txInfo.error = new Error('err1') txInfo.errorHandled = false shim.errorHandled(req, txInfo.error) - t.ok(txInfo.errorHandled) - t.end() + assert.equal(txInfo.errorHandled, true) }) - t.test('should not mark as handled if the error is not the cached one', function (t) { + await t.test('should not mark as handled if the error is not the cached one', function (t) { + const { req, shim, txInfo } = t.nr txInfo.error = new Error('err1') txInfo.errorHandled = false shim.errorHandled(req, new Error('err2')) - t.notOk(txInfo.errorHandled) - t.end() + assert.equal(txInfo.errorHandled, false) }) }) - t.test('#setErrorPredicate', function (t) { - t.autoend() + await t.test('#setErrorPredicate', async function (t) { t.beforeEach(beforeEach) t.afterEach(afterEach) - t.test('should set the function used to determine errors', function (t) { + await t.test('should set the function used to determine errors', function (t) { + const { req, shim } = t.nr let called = false shim.setErrorPredicate(function () { called = true return true }) - t.notOk(called) + assert.equal(called, false) shim.noticeError(req, new Error('test error')) - t.ok(called) - t.end() + assert.equal(called, true) }) }) })