diff --git a/package.json b/package.json index 9e0274b..f264477 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,9 @@ "load-data": "docker exec -it fastify-postgres psql -c 'CREATE TABLE users(id serial PRIMARY KEY, username VARCHAR (50) NOT NULL);' -U postgres -d postgres", "postgres": "docker run -p 5432:5432 --name fastify-postgres -e POSTGRES_PASSWORD=postgres -d postgres:11-alpine", "test": "npm run test:unit && npm run test:typescript", - "test:unit": "tap test/*.test.js", - "test:report": "standard && tap --coverage-report=html test/*.test.js", - "test:typescript": "tsd", - "test:verbose": "standard && tap test/*.test.js -Rspec" + "test:unit": "c8 --100 node --test", + "test:report": "standard && c8 --reporter html node --test", + "test:typescript": "tsd" }, "repository": { "type": "git", @@ -41,11 +40,11 @@ "devDependencies": { "@tsconfig/node10": "^1.0.9", "@types/pg": "^8.11.4", + "c8": "^10.1.2", "fastify": "^5.0.0", "pg": "^8.11.3", "pg-native": "^3.0.1", "standard": "^17.1.0", - "tap": "^18.7.1", "tsd": "^0.31.1", "typescript": "~5.4.3" }, diff --git a/test/add-handler.test.js b/test/add-handler.test.js index 72ab91e..3de258c 100644 --- a/test/add-handler.test.js +++ b/test/add-handler.test.js @@ -1,10 +1,10 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const addHandler = require('../lib/add-handler') -test('The addHandler lib should return the right handlers structure', t => { - t.test('When the existingHandler argument is undefined', t => { +test('The addHandler lib should return the right handlers structure', async t => { + await t.test('When the existingHandler argument is undefined', t => { t.plan(1) const handlers = addHandler( @@ -12,10 +12,10 @@ test('The addHandler lib should return the right handlers structure', t => { 'test' ) - t.same(handlers, ['test']) + t.assert.deepStrictEqual(handlers, ['test']) }) - t.test('When the existingHandler argument is an array', t => { + await t.test('When the existingHandler argument is an array', t => { t.plan(1) const handlers = addHandler( @@ -23,10 +23,10 @@ test('The addHandler lib should return the right handlers structure', t => { 'again' ) - t.same(handlers, ['test', 'again']) + t.assert.deepStrictEqual(handlers, ['test', 'again']) }) - t.test('When the existingHandler argument is a function', t => { + await t.test('When the existingHandler argument is a function', t => { t.plan(2) const stub = () => 'test' @@ -36,9 +36,7 @@ test('The addHandler lib should return the right handlers structure', t => { 'again' ) - t.same(handlers[0](), 'test') - t.same(handlers[1], 'again') + t.assert.deepStrictEqual(handlers[0](), 'test') + t.assert.deepStrictEqual(handlers[1], 'again') }) - - t.end() }) diff --git a/test/initialization-log.test.js b/test/initialization-log.test.js new file mode 100644 index 0000000..a97fea0 --- /dev/null +++ b/test/initialization-log.test.js @@ -0,0 +1,46 @@ +const { test } = require('node:test') +const Fastify = require('fastify') +const pg = require('pg') +const fastifyPostgres = require('../index') +const { connectionString } = require('./helpers') + +test('Initalization log tests', async (t) => { + const realConsole = global.console + const ctx = {} + + test.beforeEach(() => { + ctx.fastify = require('fastify')() + ctx.pg = { + ...require('pg'), + native: null + } + ctx.native = pg.native + }) + + test.afterEach(() => { + // Really would just remove the module from the + // cache. + ctx.pg.native = ctx.native + global.console = realConsole + }) + + await t.test('Should print warning when native module not installed', async (t) => { + t.plan(2) + + global.console.warn = (msg) => t.assert.strictEqual(msg, "pg-native not installed, can't use native option - fallback to pg module") + + const fastify = Fastify() + t.after(() => { + fastify.close() + }) + + await ctx.fastify.register(fastifyPostgres, { + connectionString, + native: true, + pg: ctx.pg + }) + + const ready = await ctx.fastify.ready() + t.assert.ok(ready) + }) +}) diff --git a/test/initialization.test.js b/test/initialization.test.js index 0eaeec3..ff75f71 100644 --- a/test/initialization.test.js +++ b/test/initialization.test.js @@ -1,103 +1,57 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const Fastify = require('fastify') -const pg = require('pg') const fastifyPostgres = require('../index') const { connectionString } = require('./helpers') -test('Should be able to use native module', (t) => { +test('Should be able to use native module', async (t) => { t.plan(2) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, native: true }) - fastify.ready((err) => { - t.error(err) - - fastify.pg - .query('SELECT 1 AS one') - .then((result) => { - t.equal(result.rows[0].one, 1) - }) - .catch((err) => { - t.fail(err) - }) - }) -}) - -test('Should print warning when native module not installed', (t) => { - t.plan(3) - - const mockedFastifyPostgres = t.mock('../index', { - pg: { ...pg, native: null } - }) - const realConsole = global.console - global.console.warn = (msg) => t.equal(msg, "pg-native not installed, can't use native option - fallback to pg module") - - const fastify = Fastify() - t.teardown(() => { - fastify.close() - global.console = realConsole - }) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.register(mockedFastifyPostgres, { - connectionString, - native: true - }) + const result = await fastify.pg + .query('SELECT 1 AS one') - fastify.ready((err) => { - t.error(err) - - fastify.pg - .query('SELECT 1 AS one') - .then((result) => { - t.equal(result.rows[0].one, 1) - }) - .catch((err) => { - t.fail(err) - }) - }) + t.assert.strictEqual(result.rows[0].one, 1) }) -test('Should be able to use an alternative pg module', (t) => { +test('Should be able to use an alternative pg module', async (t) => { t.plan(2) const altPg = require('pg') const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, pg: altPg }) - fastify.ready((err) => { - t.error(err) - - fastify.pg - .query('SELECT 1 AS one') - .then((result) => { - t.equal(result.rows[0].one, 1) - }) - .catch((err) => { - t.fail(err) - }) - }) + const ready = await fastify.ready() + t.assert.ok(ready) + + const result = await fastify.pg + .query('SELECT 1 AS one') + t.assert.strictEqual(result.rows[0].one, 1) }) -test('Should not throw if registered within different scopes (with and without named instances)', (t) => { +test('Should not throw if registered within different scopes (with and without named instances)', async (t) => { t.plan(1) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(function scopeOne (instance, opts, next) { + await fastify.register(function scopeOne (instance, opts, next) { instance.register(fastifyPostgres, { connectionString }) @@ -105,7 +59,7 @@ test('Should not throw if registered within different scopes (with and without n next() }) - fastify.register(function scopeTwo (instance, opts, next) { + await fastify.register(function scopeTwo (instance, opts, next) { instance.register(fastifyPostgres, { connectionString, name: 'one' @@ -119,139 +73,142 @@ test('Should not throw if registered within different scopes (with and without n next() }) - fastify.ready((err) => { - t.error(err) - }) + const ready = await fastify.ready() + t.assert.ok(ready) }) -test('Should throw when trying to register multiple instances without giving a name', (t) => { - t.plan(2) +test('Should throw when trying to register multiple instances without giving a name', async (t) => { + t.plan(3) const fastify = Fastify() - t.teardown(() => fastify.close()) - - fastify.register(fastifyPostgres, { - connectionString - }) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString }) - fastify.ready((err) => { - t.ok(err) - t.equal((err || {}).message, 'fastify-postgres has already been registered') - }) + await t.assert.rejects( + async () => await fastify.register(fastifyPostgres, { + connectionString + }), + (err) => { + t.assert.ok(err) + t.assert.strictEqual((err || {}).message, 'fastify-postgres has already been registered') + return true + } + ) }) -test('Should not throw when registering a named instance and an unnamed instance', (t) => { +test('Should not throw when registering a named instance and an unnamed instance', async (t) => { t.plan(1) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'one' }) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString }) - fastify.ready((err) => { - t.error(err) - }) + const ready = await fastify.ready() + t.assert.ok(ready) }) -test('Should throw when trying to register duplicate connection names', (t) => { - t.plan(2) +test('Should throw when trying to register duplicate connection names', async (t) => { + t.plan(3) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) const name = 'test' - fastify + await fastify .register(fastifyPostgres, { connectionString, name }) - fastify.register(fastifyPostgres, { - connectionString, - name - }) - fastify.ready((err) => { - t.ok(err) - t.equal((err || {}).message, `fastify-postgres '${name}' instance name has already been registered`) - }) + await t.assert.rejects( + async () => await fastify.register(fastifyPostgres, { + connectionString, + name + }), + (err) => { + t.assert.ok(err) + t.assert.strictEqual((err || {}).message, `fastify-postgres '${name}' instance name has already been registered`) + return true + } + ) }) -test('Should throw when trying to register a named connection with a reserved keyword', (t) => { - t.plan(2) +test('Should throw when trying to register a named connection with a reserved keyword', async (t) => { + t.plan(3) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) const name = 'Client' - fastify.register(fastifyPostgres, { - connectionString, - name - }) - - fastify.ready((err) => { - t.ok(err) - t.equal((err || {}).message, `fastify-postgres '${name}' is a reserved keyword`) - }) + await t.assert.rejects( + async () => await fastify.register(fastifyPostgres, { + connectionString, + name + }), + (err) => { + t.assert.ok(err) + t.assert.strictEqual((err || {}).message, `fastify-postgres '${name}' is a reserved keyword`) + return true + } + ) }) -test('fastify.pg namespace should exist', (t) => { +test('const result = await fastify.pg namespace should exist', async (t) => { t.plan(5) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - t.ok(fastify.pg) - t.ok(fastify.pg.connect) - t.ok(fastify.pg.pool) - t.ok(fastify.pg.Client) - }) + t.assert.ok(fastify.pg) + t.assert.ok(fastify.pg.connect) + t.assert.ok(fastify.pg.pool) + t.assert.ok(fastify.pg.Client) }) -test('fastify.pg custom namespace should exist if a name is set', (t) => { +test('const result = await fastify.pg custom namespace should exist if a name is set', async (t) => { t.plan(6) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test' }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - t.ok(fastify.pg) - t.ok(fastify.pg.test) - t.ok(fastify.pg.test.connect) - t.ok(fastify.pg.test.pool) - t.ok(fastify.pg.test.Client) - }) + t.assert.ok(fastify.pg) + t.assert.ok(fastify.pg.test) + t.assert.ok(fastify.pg.test.connect) + t.assert.ok(fastify.pg.test.pool) + t.assert.ok(fastify.pg.test.Client) }) -test('fastify.pg and a fastify.pg custom namespace should exist when registering a named instance before an unnamed instance)', async (t) => { - t.plan(10) +test('const result = await fastify.pg and a fastify.pg custom namespace should exist when registering a named instance before an unnamed instance)', async (t) => { + t.plan(11) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) await fastify.register(fastifyPostgres, { connectionString, @@ -262,20 +219,21 @@ test('fastify.pg and a fastify.pg custom namespace should exist when registering connectionString }) - await fastify.ready().catch(err => t.error(err)) + const ready = await fastify.ready() + t.assert.ok(ready) - t.ok(fastify.pg) - t.ok(fastify.pg.connect) - t.ok(fastify.pg.pool) - t.ok(fastify.pg.Client) + t.assert.ok(fastify.pg) + t.assert.ok(fastify.pg.connect) + t.assert.ok(fastify.pg.pool) + t.assert.ok(fastify.pg.Client) - t.ok(fastify.pg.one) - t.ok(fastify.pg.one.connect) - t.ok(fastify.pg.one.pool) - t.ok(fastify.pg.one.Client) + t.assert.ok(fastify.pg.one) + t.assert.ok(fastify.pg.one.connect) + t.assert.ok(fastify.pg.one.pool) + t.assert.ok(fastify.pg.one.Client) const result = await fastify.pg.query('SELECT NOW()') const resultOne = await fastify.pg.one.query('SELECT NOW()') - t.same(result.rowCount, 1) - t.same(resultOne.rowCount, 1) + t.assert.deepStrictEqual(result.rowCount, 1) + t.assert.deepStrictEqual(resultOne.rowCount, 1) }) diff --git a/test/query.test.js b/test/query.test.js index e963003..0d1a26e 100644 --- a/test/query.test.js +++ b/test/query.test.js @@ -1,7 +1,6 @@ 'use strict' -const t = require('tap') -const test = t.test +const { test } = require('node:test') const Fastify = require('fastify') const fastifyPostgres = require('../index') @@ -11,253 +10,215 @@ const { connectionStringBadDbName } = require('./helpers') -test('When fastify.pg root namespace is used:', (t) => { - t.test('Should be able to connect and perform a query with a callback', (t) => { +test('When fastify.pg root namespace is used:', async t => { + await t.test('Should be able to connect and perform a query with a callback', async (t) => { t.plan(4) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.connect(onConnect) - }) - - function onConnect (err, client, done) { - t.error(err) - - client.query('SELECT NOW()', (err, result) => { - done() - t.error(err) - t.ok(result.rows) - }) - } + const client = await fastify.pg.connect() + t.assert.ok(client) + const result = await client.query('SELECT NOW()') + t.assert.ok(result) + t.assert.ok(result.rows) + client.release() }) - t.test('Should be able to use the query util with a callback', (t) => { + await t.test('Should be able to use the query util with a callback', async (t) => { t.plan(3) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.query('SELECT NOW()', (err, result) => { - t.error(err) - t.ok(result.rows) - }) - }) + const result = await fastify.pg.query('SELECT NOW()') + t.assert.ok(result) + t.assert.ok(result.rows) }) - t.test('Should be able to use the query util with promises', (t) => { + await t.test('Should be able to use the query util with promises', async (t) => { t.plan(2) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString }) - fastify.ready((err) => { - t.error(err) - - fastify.pg - .query('SELECT NOW()') - .then((result) => { - t.ok(result.rows) - }) - .catch((err) => { - t.fail(err) - }) - }) + const ready = await fastify.ready() + t.assert.ok(ready) + + const result = await fastify.pg + .query('SELECT NOW()') + t.assert.ok(result.rows) }) - t.test( + await t.test( 'query util should return an error when pg fails to perform an operation using a callback', - (t) => { + async (t) => { t.plan(4) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString: connectionStringBadDbName }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.query('SELECT NOW()', (err, result) => { - t.equal(result, undefined) - t.ok(err) - t.equal(err.message, `database "${BAD_DB_NAME}" does not exist`) - }) - }) + await t.assert.rejects( + async () => await fastify.pg.query('SELECT NOW()'), + (err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, `database "${BAD_DB_NAME}" does not exist`) + + return true + } + ) } ) - t.test('Should throw when pg fails to perform operation with promises', (t) => { - t.plan(3) + await t.test('Should throw when pg fails to perform operation with promises', async (t) => { + t.plan(4) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString: connectionStringBadDbName }) - fastify.ready((err) => { - t.error(err) - - fastify.pg - .query('SELECT NOW()') - .then((result) => { - t.fail(result) - }) - .catch((err) => { - t.ok(err) - t.equal(err.message, `database "${BAD_DB_NAME}" does not exist`) - }) - }) - }) + const ready = await fastify.ready() + t.assert.ok(ready) - t.end() + await t.assert.rejects( + async () => await fastify.pg + .query('SELECT NOW()'), + (err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, `database "${BAD_DB_NAME}" does not exist`) + return true + }) + }) }) -test('When fastify.pg custom namespace is used:', (t) => { - t.test('Should be able to connect and perform a query', (t) => { - t.plan(4) +test('When fastify.pg custom namespace is used:', async t => { + await t.test('Should be able to connect and perform a query', async (t) => { + t.plan(3) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test' }) - fastify.ready((err) => { - t.error(err) - fastify.pg.test.connect(onConnect) - }) + const ready = await fastify.ready() + t.assert.ok(ready) + const client = await fastify.pg.test.connect() - function onConnect (err, client, done) { - t.error(err) - client.query('SELECT NOW()', (err, result) => { - done() - t.error(err) - t.ok(result.rows) - }) - } + const result = await client.query('SELECT NOW()') + t.assert.ok(ready) + t.assert.ok(result.rows) + + client.release() }) - t.test('Should be able to use query util with a callback', (t) => { - t.plan(3) + await t.test('Should be able to use query util with a callback', async (t) => { + t.plan(2) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test' }) - fastify.ready((err) => { - t.error(err) - fastify.pg.test.query('SELECT NOW()', (err, result) => { - t.error(err) - t.ok(result.rows) - }) - }) + const ready = await fastify.ready() + t.assert.ok(ready) + const result = await fastify.pg.test.query('SELECT NOW()') + t.assert.ok(result.rows) }) - t.test('Should be able to use query util with promises', (t) => { + await t.test('Should be able to use query util with promises', async (t) => { t.plan(2) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test' }) - fastify.ready((err) => { - t.error(err) - - fastify.pg.test - .query('SELECT NOW()') - .then((result) => { - t.ok(result.rows) - }) - .catch((err) => { - t.fail(err) - }) - }) + const ready = await fastify.ready() + t.assert.ok(ready) + + const result = await fastify.pg.test + .query('SELECT NOW()') + t.assert.ok(result.rows) }) - t.test('Should be able to use native module', (t) => { + await t.test('Should be able to use native module', async (t) => { t.plan(2) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test', native: true }) - fastify.ready((err) => { - t.error(err) - - fastify.pg.test - .query('SELECT 1 AS one') - .then((result) => { - t.equal(result.rows[0].one, 1) - }) - .catch((err) => { - t.fail(err) - }) - }) + const ready = await fastify.ready() + t.assert.ok(ready) + + const result = await fastify.pg.test + .query('SELECT 1 AS one') + t.assert.strictEqual(result.rows[0].one, 1) }) - t.test('Should throw when pg fails to perform an operation with promises', (t) => { - t.plan(3) + await t.test('Should throw when pg fails to perform an operation with promises', async (t) => { + t.plan(4) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString: connectionStringBadDbName, name: 'test' }) - fastify.ready((err) => { - t.error(err) - - fastify.pg.test - .query('SELECT NOW()') - .then((result) => { - t.fail(result) - }) - .catch((err) => { - t.ok(err) - t.equal(err.message, `database "${BAD_DB_NAME}" does not exist`) - }) - }) - }) + const ready = await fastify.ready() + t.assert.ok(ready) - t.end() + await t.assert.rejects( + async () => await fastify.pg.test + .query('SELECT NOW()'), + (err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, `database "${BAD_DB_NAME}" does not exist`) + return true + }) + }) }) diff --git a/test/req-initialization.test.js b/test/req-initialization.test.js index acacc14..485b815 100644 --- a/test/req-initialization.test.js +++ b/test/req-initialization.test.js @@ -1,16 +1,16 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const Fastify = require('fastify') const fastifyPostgres = require('../index') const { connectionString } = require('./helpers') const extractUserCount = response => parseInt(JSON.parse(response.payload).rows[0].userCount) -test('When we use the fastify-postgres transaction route option', t => { - t.test('Should be able to execute queries provided to the request pg decorator', async t => { +test('When we use the fastify-postgres transaction route option', async t => { + await t.test('Should be able to execute queries provided to the request pg decorator', async t => { const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) await fastify.register(fastifyPostgres, { connectionString @@ -37,12 +37,12 @@ test('When we use the fastify-postgres transaction route option', t => { url: '/count-users' }) - t.equal(extractUserCount(response), 2) + t.assert.strictEqual(extractUserCount(response), 2) }) - t.test('Should be able to execute queries provided to a namespaced request pg decorator', async t => { + await t.test('Should be able to execute queries provided to a namespaced request pg decorator', async t => { const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) await fastify.register(fastifyPostgres, { connectionString, @@ -71,12 +71,12 @@ test('When we use the fastify-postgres transaction route option', t => { url: '/count-users' }) - t.equal(extractUserCount(response), 2) + t.assert.strictEqual(extractUserCount(response), 2) }) - t.test('Should trigger a rollback when failing to execute a query provided to the request pg decorator', async t => { + await t.test('Should trigger a rollback when failing to execute a query provided to the request pg decorator', async t => { const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) await fastify.register(fastifyPostgres, { connectionString @@ -105,12 +105,12 @@ test('When we use the fastify-postgres transaction route option', t => { url: '/count-users' }) - t.equal(extractUserCount(response), 0) + t.assert.strictEqual(extractUserCount(response), 0) }) - t.test('Should trigger a rollback when failing to execute a query provided to a namespaced request pg decorator', async t => { + await t.test('Should trigger a rollback when failing to execute a query provided to a namespaced request pg decorator', async t => { const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) await fastify.register(fastifyPostgres, { connectionString, @@ -140,12 +140,12 @@ test('When we use the fastify-postgres transaction route option', t => { url: '/count-users' }) - t.equal(extractUserCount(response), 0) + t.assert.strictEqual(extractUserCount(response), 0) }) - t.test('Should work properly with `schema` option and validation failure', async t => { + await t.test('Should work properly with `schema` option and validation failure', async t => { const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) await fastify.register(fastifyPostgres, { connectionString @@ -163,7 +163,7 @@ test('When we use the fastify-postgres transaction route option', t => { }, pg: { transact: true } }, async (req, reply) => { - t.fail('should never execute the handler') + t.assert.fail('should never execute the handler') }) const response = await fastify.inject({ @@ -171,108 +171,99 @@ test('When we use the fastify-postgres transaction route option', t => { method: 'POST', body: { notValid: 'json input' } }) - t.not(response.body, 'never success') - t.equal(response.json().code, 'FST_ERR_VALIDATION') + t.assert.notStrictEqual(response.body, 'never success') + t.assert.strictEqual(response.json().code, 'FST_ERR_VALIDATION') }) - - t.end() }) -test('Should not add hooks with combinations of registration `options.name` and route options `pg.transact`', t => { - t.test('Should not add hooks when `transact` is not set', t => { +test('Should not add hooks with combinations of registration `options.name` and route options `pg.transact`', async t => { + await t.test('Should not add hooks when `transact` is not set', async t => { t.plan(1) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString - }).after(() => { - fastify.get('/', (req, reply) => { - t.equal(req.pg, null) - }) }) - fastify.inject({ url: '/' }) + fastify.get('/', async (req, reply) => { + t.assert.strictEqual(req.pg, null) + }) + await fastify.inject({ url: '/' }) }) - t.test('Should not add hooks when `name` is set and `transact` is not set', t => { + await t.test('Should not add hooks when `name` is set and `transact` is not set', async t => { t.plan(1) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test' - }).after(() => { - fastify.get('/', (req, reply) => { - t.equal(req.pg, null) - }) + }) + fastify.get('/', async (req, reply) => { + t.assert.strictEqual(req.pg, null) }) - fastify.inject({ url: '/' }) + await fastify.inject({ url: '/' }) }) - t.test('Should not add hooks when `name` is set and `transact` is set to `true`', t => { + await t.test('Should not add hooks when `name` is set and `transact` is set to `true`', async t => { t.plan(1) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test' - }).after(() => { - fastify.get('/', { pg: { transact: true } }, (req, reply) => { - t.equal(req.pg, null) - }) + }) + fastify.get('/', { pg: { transact: true } }, async (req, reply) => { + t.assert.strictEqual(req.pg, null) }) - fastify.inject({ url: '/' }) + await fastify.inject({ url: '/' }) }) - t.test('Should not add hooks when `name` is not set and `transact` is set and is a string', t => { + await t.test('Should not add hooks when `name` is not set and `transact` is set and is a string', async t => { t.plan(1) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString - }).after(() => { - fastify.get('/', { pg: { transact: 'test' } }, (req, reply) => { - t.equal(req.pg, null) - }) + }) + fastify.get('/', { pg: { transact: 'test' } }, async (req, reply) => { + t.assert.strictEqual(req.pg, null) }) - fastify.inject({ url: '/' }) + await fastify.inject({ url: '/' }) }) - t.test('Should not add hooks when `name` and `transact` are set to different strings', t => { + await t.test('Should not add hooks when `name` and `transact` are set to different strings', async t => { t.plan(1) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test' - }).after(() => { - fastify.get('/', { pg: { transact: 'different' } }, (req, reply) => { - t.equal(req.pg, null) - }) + }) + fastify.get('/', { pg: { transact: 'different' } }, async (req, reply) => { + t.assert.strictEqual(req.pg, null) }) - fastify.inject({ url: '/' }) + await fastify.inject({ url: '/' }) }) - - t.end() }) -test('Should throw errors with incorrect combinations of registration `options.name` and route options `pg.transact`', t => { - t.test('Should throw an error when `name` is set as reserved keyword', async t => { +test('Should throw errors with incorrect combinations of registration `options.name` and route options `pg.transact`', async t => { + await t.test('Should throw an error when `name` is set as reserved keyword', async t => { const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) const name = 'user' @@ -281,19 +272,19 @@ test('Should throw errors with incorrect combinations of registration `options.n name }) - fastify.get('/', { pg: { transact: name } }, (req, reply) => {}) + fastify.get('/', { pg: { transact: name } }, async (req, reply) => {}) const response = await fastify.inject({ url: '/' }) - t.same(response.json(), { + t.assert.deepStrictEqual(response.json(), { statusCode: 500, error: 'Internal Server Error', message: `request client '${name}' does not exist` }) }) - t.test('Should throw an error when pg client has already been registered with the same name', async t => { + await t.test('Should throw an error when pg client has already been registered with the same name', async t => { const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) const name = 'test' @@ -304,19 +295,19 @@ test('Should throw errors with incorrect combinations of registration `options.n fastify.addHook('onRequest', async (req, reply) => { req.pg = { [name]: await fastify.pg[name].connect() } }) - fastify.get('/', { pg: { transact: name } }, (req, reply) => {}) + fastify.get('/', { pg: { transact: name } }, async (req, reply) => {}) const response = await fastify.inject({ url: '/' }) - t.same(response.json(), { + t.assert.deepStrictEqual(response.json(), { statusCode: 500, error: 'Internal Server Error', message: `request client '${name}' has already been registered` }) }) - t.test('Should throw an error when pg client has already been registered', async t => { + await t.test('Should throw an error when pg client has already been registered', async t => { const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) await fastify.register(fastifyPostgres, { connectionString @@ -324,15 +315,13 @@ test('Should throw errors with incorrect combinations of registration `options.n fastify.addHook('onRequest', async (req, reply) => { req.pg = await fastify.pg.connect() }) - fastify.get('/', { pg: { transact: true } }, (req, reply) => {}) + fastify.get('/', { pg: { transact: true } }, async (req, reply) => {}) const response = await fastify.inject({ url: '/' }) - t.same(response.json(), { + t.assert.deepStrictEqual(response.json(), { statusCode: 500, error: 'Internal Server Error', message: 'request client has already been registered' }) }) - - t.end() }) diff --git a/test/test-reporter.mjs b/test/test-reporter.mjs new file mode 100644 index 0000000..bf7087e --- /dev/null +++ b/test/test-reporter.mjs @@ -0,0 +1,68 @@ +function colorize (type, text) { + if (type === 'pass') { + const blackText = `\x1b[30m${text}` + const boldblackText = `\x1b[1m${blackText}` + // Green background with black text + return `\x1b[42m${boldblackText}\x1b[0m` + } + + if (type === 'fail') { + const whiteText = `\x1b[37m${text}` + const boldWhiteText = `\x1b[1m${whiteText}` + // Red background with white text + return `\x1b[41m${boldWhiteText}\x1b[0m` + } + + return text +} + +function formatDiagnosticStr (str) { + return str.replace(/^(\w+)(\s*\d*)/i, (_, firstWord, rest) => { + return firstWord.charAt(0).toUpperCase() + firstWord.slice(1).toLowerCase() + ':' + rest + }) +} + +async function * reporter (source) { + const failed = new Set() + const diagnostics = new Set() + + for await (const event of source) { + switch (event.type) { + case 'test:pass': { + yield `${colorize('pass', 'PASSED')}: ${event.data.file || event.data.name}\n` + break + } + + case 'test:fail': { + failed.add(event.data.name || event.data.file) + yield `${colorize('fail', 'FAILED')}: ${event.data.file || event.data.name}\n` + break + } + + case 'test:diagnostic': { + diagnostics.add(`${formatDiagnosticStr(event.data.message)}\n`) + break + } + + default: { + yield '' + } + } + } + + if (failed.size > 0) { + yield `\n\n${colorize('fail', 'Failed tests:')}\n` + for (const file of failed) { + yield `${file}\n` + } + } + + yield '\n' + + for (const diagnostic of diagnostics) { + yield `${diagnostic}` + } + yield '\n' +} + +export default reporter diff --git a/test/transaction.test.js b/test/transaction.test.js index de636d6..49ef630 100644 --- a/test/transaction.test.js +++ b/test/transaction.test.js @@ -1,7 +1,6 @@ 'use strict' -const t = require('tap') -const test = t.test +const { test } = require('node:test') const Fastify = require('fastify') const pg = require('pg') const fastifyPostgres = require('../index') @@ -11,243 +10,208 @@ const { connectionStringBadDbName } = require('./helpers') -test('When fastify.pg root namespace is used:', (t) => { - t.test('Should be able to use transact util with a callback', (t) => { - t.plan(4) +test('When fastify.pg root namespace is used:', async (t) => { + await t.test('Should be able to use transact util with a callback', async (t) => { + t.plan(3) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { connectionString }) + await fastify.register(fastifyPostgres, { connectionString }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.transact( - (client) => - client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [ - 'root-with-callback' - ]), - function (err, result) { - t.error(err) - t.equal(result.rows.length, 1) + const result = await fastify.pg.transact( + (client) => + client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [ + 'root-with-callback' + ]) + ) + t.assert.strictEqual(result.rows.length, 1) - const userId = result.rows[0].id + const userId = result.rows[0].id - fastify.pg - .query('SELECT * FROM users WHERE id = $1', [userId]) - .then((result) => { - t.equal(result.rows[0].username, 'root-with-callback') - }) - .catch((err) => { - t.fail(err) - }) - } - ) - }) + const result2 = await fastify.pg + .query('SELECT * FROM users WHERE id = $1', [userId]) + t.assert.strictEqual(result2.rows[0].username, 'root-with-callback') }) - t.test('Should be able to use transact util with promises', (t) => { + await t.test('Should be able to use transact util with promises', async (t) => { t.plan(3) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { connectionString }) + await fastify.register(fastifyPostgres, { connectionString }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg - .transact((client) => - client.query('INSERT INTO users(username) VALUES($1) RETURNING id', ['root-with-promise']) - ) - .then((result) => { - t.equal(result.rows.length, 1) + const result = await fastify.pg + .transact((client) => + client.query('INSERT INTO users(username) VALUES($1) RETURNING id', ['root-with-promise']) + ) + t.assert.strictEqual(result.rows.length, 1) - const userId = result.rows[0].id + const userId = result.rows[0].id - fastify.pg - .query('SELECT * FROM users WHERE id = $1', [userId]) - .then((result) => { - t.equal(result.rows[0].username, 'root-with-promise') - }) - .catch((err) => { - t.fail(err) - }) - }) - .catch((err) => { - t.fail(err) - }) - }) + const result2 = await fastify.pg + .query('SELECT * FROM users WHERE id = $1', [userId]) + t.assert.strictEqual(result2.rows[0].username, 'root-with-promise') }) - t.test('Should be able to use transact util with a commit callback', (t) => { + await t.test('Should be able to use transact util with a commit callback', async (t) => { t.plan(4) const fastify = Fastify() - t.teardown(() => fastify.close()) - - fastify.register(fastifyPostgres, { connectionString }) - - fastify.ready((err) => { - t.error(err) - - fastify.pg.transact( - (client, commit) => - client.query( - 'INSERT INTO users(username) VALUES($1) RETURNING id', - ['root-commit-callback'], - (err, id) => { - commit(err, id) - } - ), - function (err, result) { - t.error(err) - t.equal(result.rows.length, 1) - - const userId = result.rows[0].id - - fastify.pg - .query('SELECT * FROM users WHERE id = $1', [userId]) - .then((result) => { - t.equal(result.rows[0].username, 'root-commit-callback') - }) - .catch((err) => { - t.fail(err) - }) - } - ) - }) + t.after(() => fastify.close()) + + await fastify.register(fastifyPostgres, { connectionString }) + + const ready = await fastify.ready() + t.assert.ok(ready) + + const result = await fastify.pg.transact( + (client, commit) => + client.query( + 'INSERT INTO users(username) VALUES($1) RETURNING id', + ['root-commit-callback'], + (err, id) => { + commit(err, id) + } + )) + t.assert.ok(ready) + t.assert.strictEqual(result.rows.length, 1) + + const userId = result.rows[0].id + + const result2 = await fastify.pg + .query('SELECT * FROM users WHERE id = $1', [userId]) + t.assert.strictEqual(result2.rows[0].username, 'root-commit-callback') }) - t.test('Should trigger a rollback when something goes wrong (with callback)', (t) => { + await t.test('Should trigger a rollback when something goes wrong (with callback)', async (t) => { t.plan(9) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { connectionString }) + await fastify.register(fastifyPostgres, { connectionString }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.transact( - (client) => { - return client + await t.assert.rejects( + async () => await fastify.pg.transact( + async (client) => { + const result = await client .query('INSERT INTO users(username) VALUES($1) RETURNING id', [ 'root-rollback-user-callback' ]) - .then((result) => { - t.ok(result) + t.assert.ok(result) - const userId = result.rows[0].id + const userId = result.rows[0].id - return client - .query('SELECT * FROM users WHERE id = $1', [userId]) - .then((result) => { - t.ok(result) - t.equal(result.rows[0].username, 'root-rollback-user-callback') - }) - .then(() => { - throw new Error('We make it throw on purpose to trigger a rollback') - }) - }) - }, - function (err, result) { - t.ok(err) - t.equal(err.message, 'We make it throw on purpose to trigger a rollback') - t.equal(result, undefined) - - fastify.pg - .query('SELECT * FROM users WHERE username = \'root-rollback-user-callback\'') - .then((result) => { - t.ok(result) - t.equal(result.rows.length, 0) - }) - .catch((err) => { - t.fail(err) - }) - } - ) - }) + const result2 = await client + .query('SELECT * FROM users WHERE id = $1', [userId]) + t.assert.ok(result2) + t.assert.strictEqual(result2.rows[0].username, 'root-rollback-user-callback') + throw new Error('We make it throw on purpose to trigger a rollback') + }), + (err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, 'We make it throw on purpose to trigger a rollback') + return true + } + ) + + const result3 = await fastify.pg + .query('SELECT * FROM users WHERE username = \'root-rollback-user-callback\'') + t.assert.ok(result3) + t.assert.strictEqual(result3.rows.length, 0) }) - t.test('Should trigger a rollback when something goes wrong (with promises)', (t) => { + await t.test('Should trigger a rollback when something goes wrong (with promises)', async (t) => { t.plan(8) - const fastify = Fastify() - t.teardown(() => fastify.close()) - - fastify.register(fastifyPostgres, { connectionString }) - - fastify.ready((err) => { - t.error(err) - - fastify.pg - .transact((client) => - client - .query('INSERT INTO users(username) VALUES($1) RETURNING id', [ - 'root-rollback-user-promise' - ]) - .then((result) => { - t.ok(result) - - const userId = result.rows[0].id - - return client - .query('SELECT * FROM users WHERE id = $1', [userId]) - .then((result) => { - t.ok(result) - t.equal(result.rows[0].username, 'root-rollback-user-promise') - }) - .then(() => { - throw new Error('We make it throw on purpose to trigger a rollback') - }) - }) - ) - .catch((err) => { - t.ok(err) - t.equal(err.message, 'We make it throw on purpose to trigger a rollback') - - fastify.pg - .query('SELECT * FROM users WHERE username = \'root-rollback-user-promise\'') - .then((result) => { - t.ok(result) - t.equal(result.rows.length, 0) - }) - .catch((err) => { - t.fail(err) - }) - }) + await new Promise((resolve) => { + const fastify = Fastify() + t.after(() => fastify.close()) + + fastify.register(fastifyPostgres, { connectionString }) + + fastify.ready((err) => { + t.assert.ifError(err) + + fastify.pg + .transact((client) => + client + .query('INSERT INTO users(username) VALUES($1) RETURNING id', [ + 'root-rollback-user-promise' + ]) + .then((result) => { + t.assert.ok(result) + + const userId = result.rows[0].id + + return client + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.assert.ok(result) + t.assert.strictEqual(result.rows[0].username, 'root-rollback-user-promise') + }) + .then(() => { + throw new Error('We make it throw on purpose to trigger a rollback') + }) + }) + ) + .catch((err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, 'We make it throw on purpose to trigger a rollback') + + fastify.pg + .query('SELECT * FROM users WHERE username = \'root-rollback-user-promise\'') + .then((result) => { + t.assert.ok(result) + t.assert.strictEqual(result.rows.length, 0) + resolve() + }) + .catch((err) => { + t.assert.ifError(err) + }) + }) + }) }) }) - t.test('Should throw if the pool connection throws an error', (t) => { - t.plan(3) + await t.test('Should throw if the pool connection throws an error', async (t) => { + t.plan(4) const fastify = Fastify() - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString: connectionStringBadDbName }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.transact((client) => client.query('SELECT NOW()')) - .catch((err) => { - t.ok(err) - t.equal(err.message, `database "${BAD_DB_NAME}" does not exist`) - }) - }) + await t.assert.rejects( + async () => await fastify.pg.transact((client) => client.query('SELECT NOW()')), + (err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, `database "${BAD_DB_NAME}" does not exist`) + return true + } + ) }) - t.test('Should trigger a rollback when it is impossible to begin transaction', (t) => { + await t.test('Should trigger a rollback when it is impossible to begin transaction', async (t) => { t.plan(4) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) class FakeClient extends pg.Client { query (cmd, cb) { @@ -269,27 +233,26 @@ test('When fastify.pg root namespace is used:', (t) => { } } - fastify.register(fastifyPostgres, { connectionString, pg: { ...pg, Pool: FakePool } }) + await fastify.register(fastifyPostgres, { connectionString, pg: { ...pg, Pool: FakePool } }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.transact( - (client) => {}, - function (err, result) { - t.ok(err) - t.equal(err.message, 'Boom') - t.equal(result, undefined) - } - ) - }) + await t.assert.rejects( + async () => await fastify.pg.transact((client) => {}), + (err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, 'Boom') + return true + } + ) }) - t.test('Should trigger a rollback when it is impossible to commit transaction', (t) => { - t.plan(3) + await t.test('Should trigger a rollback when it is impossible to commit transaction', async (t) => { + t.plan(4) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) class FakeClient extends pg.Client { query (queryText, values, cb) { @@ -314,12 +277,13 @@ test('When fastify.pg root namespace is used:', (t) => { } } - fastify.register(fastifyPostgres, { connectionString, pg: { ...pg, Pool: FakePool } }) + await fastify.register(fastifyPostgres, { connectionString, pg: { ...pg, Pool: FakePool } }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.transact( + await t.assert.rejects( + async () => await fastify.pg.transact( (client, commit) => { return client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [ 'root-rollback-commit' @@ -327,225 +291,213 @@ test('When fastify.pg root namespace is used:', (t) => { commit(err, res) }) } - ).then((result) => { - t.equal(result, undefined) - }).catch(err => { - t.ok(err) - t.equal(err.message, 'Boom') + ), + (err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, 'Boom') + return true }) - }) }) - - t.end() }) -test('When fastify.pg.test namespace is used:', (t) => { - t.test('Should be able to use transact util with a callback', (t) => { +test('When fastify.pg.test namespace is used:', async (t) => { + await t.test('Should be able to use transact util with a callback', async (t) => { t.plan(4) - const fastify = Fastify() - t.teardown(() => fastify.close()) - - fastify.register(fastifyPostgres, { - connectionString, - name: 'test' - }) + await new Promise((resolve) => { + const fastify = Fastify() + t.after(() => fastify.close()) - fastify.ready((err) => { - t.error(err) - - fastify.pg.test.transact( - (client) => - client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [ - 'namespace-with-callback' - ]), - function (err, result) { - t.error(err) - t.equal(result.rows.length, 1) - - const userId = result.rows[0].id + fastify.register(fastifyPostgres, { + connectionString, + name: 'test' + }) - fastify.pg.test - .query('SELECT * FROM users WHERE id = $1', [userId]) - .then((result) => { - t.equal(result.rows[0].username, 'namespace-with-callback') - }) - .catch((err) => { - t.fail(err) - }) - } - ) + fastify.ready((err) => { + t.assert.ifError(err) + + fastify.pg.test.transact( + (client) => + client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [ + 'namespace-with-callback' + ]), + function (err, result) { + t.assert.ifError(err) + t.assert.strictEqual(result.rows.length, 1) + + const userId = result.rows[0].id + + fastify.pg.test + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.assert.strictEqual(result.rows[0].username, 'namespace-with-callback') + resolve() + }) + .catch((err) => { + t.fail(err) + }) + } + ) + }) }) }) - t.test('Should be able to use transact util with promises', (t) => { + await t.test('Should be able to use transact util with promises', async (t) => { t.plan(3) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test' }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.test - .transact((client) => - client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [ - 'namespace-with-promise' - ]) - ) - .then((result) => { - t.equal(result.rows.length, 1) + const result = await fastify.pg.test + .transact((client) => + client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [ + 'namespace-with-promise' + ]) + ) + t.assert.strictEqual(result.rows.length, 1) - const userId = result.rows[0].id + const userId = result.rows[0].id - fastify.pg.test - .query('SELECT * FROM users WHERE id = $1', [userId]) - .then((result) => { - t.equal(result.rows[0].username, 'namespace-with-promise') - }) - .catch((err) => { - t.fail(err) - }) - }) - .catch((err) => { - t.fail(err) - }) - }) + const result2 = await fastify.pg.test + .query('SELECT * FROM users WHERE id = $1', [userId]) + t.assert.strictEqual(result2.rows[0].username, 'namespace-with-promise') }) - t.test('Should trigger a rollback when something goes wrong (with callback)', (t) => { + await t.test('Should trigger a rollback when something goes wrong (with callback)', async (t) => { t.plan(9) - const fastify = Fastify() - t.teardown(() => fastify.close()) + await new Promise((resolve) => { + const fastify = Fastify() + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { - connectionString, - name: 'test' - }) - - fastify.ready((err) => { - t.error(err) - - fastify.pg.test.transact( - (client) => { - return client - .query('INSERT INTO users(username) VALUES($1) RETURNING id', [ - 'namespace-rollback-user-callback' - ]) - .then((result) => { - t.ok(result) - - const userId = result.rows[0].id + fastify.register(fastifyPostgres, { + connectionString, + name: 'test' + }) - return client - .query('SELECT * FROM users WHERE id = $1', [userId]) - .then((result) => { - t.ok(result) - t.equal(result.rows[0].username, 'namespace-rollback-user-callback') - }) - .then(() => { - throw new Error('We make it throw on purpose to trigger a rollback') - }) - }) - }, - function (err, result) { - t.ok(err) - t.equal(err.message, 'We make it throw on purpose to trigger a rollback') - t.equal(result, undefined) - - fastify.pg.test - .query('SELECT * FROM users WHERE username = \'namespace-rollback-user-callback\'') - .then((result) => { - t.ok(result) - t.equal(result.rows.length, 0) - }) - .catch((err) => { - t.fail(err) - }) - } - ) + fastify.ready((err) => { + t.assert.ifError(err) + + fastify.pg.test.transact( + (client) => { + return client + .query('INSERT INTO users(username) VALUES($1) RETURNING id', [ + 'namespace-rollback-user-callback' + ]) + .then((result) => { + t.assert.ok(result) + + const userId = result.rows[0].id + + return client + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.assert.ok(result) + t.assert.strictEqual(result.rows[0].username, 'namespace-rollback-user-callback') + }) + .then(() => { + throw new Error('We make it throw on purpose to trigger a rollback') + }) + }) + }, + function (err, result) { + t.assert.ok(err) + t.assert.strictEqual(err.message, 'We make it throw on purpose to trigger a rollback') + t.assert.strictEqual(result, undefined) + + fastify.pg.test + .query('SELECT * FROM users WHERE username = \'namespace-rollback-user-callback\'') + .then((result) => { + t.assert.ok(result) + t.assert.strictEqual(result.rows.length, 0) + resolve() + }) + .catch((err) => { + t.fail(err) + }) + } + ) + }) }) }) - t.test('Should trigger a rollback when something goes wrong (with promises)', (t) => { - t.plan(8) + await t.test('Should trigger a rollback when something goes wrong (with promises)', async (t) => { + t.plan(9) const fastify = Fastify() - t.teardown(() => fastify.close()) + t.after(() => fastify.close()) - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString, name: 'test' }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.test - .transact((client) => + await t.assert.rejects( + async () => await fastify.pg.test + .transact(async (client) => client .query('INSERT INTO users(username) VALUES($1) RETURNING id', [ 'namespace-rollback-user-promise' ]) .then((result) => { - t.ok(result) + t.assert.ok(result) const userId = result.rows[0].id return client .query('SELECT * FROM users WHERE id = $1', [userId]) .then((result) => { - t.ok(result) - t.equal(result.rows[0].username, 'namespace-rollback-user-promise') + t.assert.ok(result) + t.assert.strictEqual(result.rows[0].username, 'namespace-rollback-user-promise') }) .then(() => { throw new Error('We make it throw on purpose to trigger a rollback') }) }) - ) - .catch((err) => { - t.ok(err) - t.equal(err.message, 'We make it throw on purpose to trigger a rollback') + ), + (err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, 'We make it throw on purpose to trigger a rollback') + return true + }) - fastify.pg.test - .query('SELECT * FROM users WHERE username = \'namespace-rollback-user-promise\'') - .then((result) => { - t.ok(result) - t.equal(result.rows.length, 0) - }) - .catch((err) => { - t.fail(err) - }) - }) - }) + const result = await fastify.pg.test + .query('SELECT * FROM users WHERE username = \'namespace-rollback-user-promise\'') + t.assert.ok(result) + t.assert.strictEqual(result.rows.length, 0) }) - t.test('Should throw if the pool connection throws an error', (t) => { - t.plan(3) + await t.test('Should throw if the pool connection throws an error', async (t) => { + t.plan(4) const fastify = Fastify() - fastify.register(fastifyPostgres, { + await fastify.register(fastifyPostgres, { connectionString: connectionStringBadDbName, name: 'test' }) - fastify.ready((err) => { - t.error(err) + const ready = await fastify.ready() + t.assert.ok(ready) - fastify.pg.test.transact((client) => client.query('SELECT NOW()')) - .catch((err) => { - t.ok(err) - t.equal(err.message, `database "${BAD_DB_NAME}" does not exist`) - }) - }) + await t.assert.rejects( + async () => await fastify.pg.test.transact((client) => client.query('SELECT NOW()')), + (err) => { + t.assert.ok(err) + t.assert.strictEqual(err.message, `database "${BAD_DB_NAME}" does not exist`) + return true + } + ) }) - - t.end() })