From 28ef2f4701dc0828838671181958a3a63105d407 Mon Sep 17 00:00:00 2001 From: darkgl0w <31093081+darkgl0w@users.noreply.github.com> Date: Thu, 9 May 2019 19:39:47 +0200 Subject: [PATCH 1/9] Delete test.js --- test.js | 375 -------------------------------------------------------- 1 file changed, 375 deletions(-) delete mode 100644 test.js diff --git a/test.js b/test.js deleted file mode 100644 index c34dbcb..0000000 --- a/test.js +++ /dev/null @@ -1,375 +0,0 @@ -'use strict' - -const t = require('tap') -const test = t.test -const Fastify = require('fastify') -const fastifyPostgres = require('./index') - -test('fastify.pg namespace should exist', t => { - t.plan(5) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - t.ok(fastify.pg) - t.ok(fastify.pg.connect) - t.ok(fastify.pg.pool) - t.ok(fastify.pg.Client) - fastify.close() - }) -}) - -test('should be able to connect and perform a query', t => { - t.plan(4) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - 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) - fastify.close() - }) - } -}) - -test('use query util', t => { - t.plan(3) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - fastify.pg.query('SELECT NOW()', (err, result) => { - t.error(err) - t.ok(result.rows) - fastify.close() - }) - }) -}) - -test('use query util with promises', t => { - t.plan(2) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - fastify.pg - .query('SELECT NOW()') - .then(result => { - t.ok(result.rows) - fastify.close() - }) - .catch(err => { - t.fail(err) - fastify.close() - }) - }) -}) - -test('use native module', t => { - t.plan(2) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - connectionString: 'postgres://postgres@localhost/postgres', - native: true - }) - - fastify.ready(err => { - t.error(err) - fastify.pg - .query('SELECT 1 AS one') - .then(result => { - t.ok(result.rows[0].one === 1) - fastify.close() - }) - .catch(err => { - t.fail(err) - fastify.close() - }) - }) -}) - -test('use alternative pg module', t => { - const altPg = require('pg') - t.plan(2) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - connectionString: 'postgres://postgres@localhost/postgres', - pg: altPg - }) - - fastify.ready(err => { - t.error(err) - fastify.pg - .query('SELECT 1 AS one') - .then(result => { - t.ok(result.rows[0].one === 1) - fastify.close() - }) - .catch(err => { - t.fail(err) - fastify.close() - }) - }) -}) - -test('fastify.pg.test namespace should exist', t => { - t.plan(6) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - 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) - fastify.close() - }) -}) - -test('fastify.pg.test should be able to connect and perform a query', t => { - t.plan(4) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - fastify.pg.test.connect(onConnect) - }) - - function onConnect (err, client, done) { - t.error(err) - client.query('SELECT NOW()', (err, result) => { - done() - t.error(err) - t.ok(result.rows) - fastify.close() - }) - } -}) - -test('fastify.pg.test use query util', t => { - t.plan(3) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - fastify.pg.test.query('SELECT NOW()', (err, result) => { - t.error(err) - t.ok(result.rows) - fastify.close() - }) - }) -}) - -test('fastify.pg.test use query util with promises', t => { - t.plan(2) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - fastify.pg.test - .query('SELECT NOW()') - .then(result => { - t.ok(result.rows) - fastify.close() - }) - .catch(err => { - t.fail(err) - fastify.close() - }) - }) -}) - -test('fastify.pg.test use native module', t => { - t.plan(2) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres', - native: true - }) - - fastify.ready(err => { - t.error(err) - fastify.pg.test - .query('SELECT 1 AS one') - .then(result => { - t.ok(result.rows[0].one === 1) - fastify.close() - }) - .catch(err => { - t.fail(err) - fastify.close() - }) - }) -}) - -test('fastify.pg.test should throw with duplicate connection names', t => { - t.plan(1) - - const fastify = Fastify() - - fastify.register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres' - }) - .register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.is(err.message, 'Connection name has already been registered: test') - }) -}) - -test('fastify.pg.test use transact util with promise', t => { - t.plan(3) - - const fastify = Fastify() - t.tearDown(fastify.close.bind(fastify)) - - fastify.register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - fastify.pg.test - .transact(client => client.query('INSERT INTO users(username) VALUES($1) RETURNING id', ['with-promise'])) - .then(result => { - t.equals(result.rows.length, 1) - fastify.pg.test - .query(`SELECT * FROM users WHERE username = 'with-promise'`) - .then(result => { - t.ok(result.rows[0].username === 'with-promise') - }).catch(err => { - t.fail(err) - }) - }) - .catch(err => { - t.fail(err) - }) - }) -}) - -test('fastify.pg.test use transact util with callback', t => { - t.plan(4) - - const fastify = Fastify() - t.tearDown(fastify.close.bind(fastify)) - - fastify.register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - - fastify.pg.test - .transact(client => client.query('INSERT INTO users(username) VALUES($1) RETURNING id', ['with-callback']), function (err, res) { - t.error(err) - t.equals(res.rows.length, 1) - - fastify.pg.test - .query(`SELECT * FROM users WHERE username = 'with-callback'`) - .then(result => { - t.ok(result.rows[0].username === 'with-callback') - }).catch(err => { - t.fail(err) - }) - }) - }) -}) - -test('fastify.pg.test use transact util with commit callback', t => { - t.plan(4) - - const fastify = Fastify() - t.tearDown(fastify.close.bind(fastify)) - - fastify.register(fastifyPostgres, { - name: 'test', - connectionString: 'postgres://postgres@localhost/postgres' - }) - - fastify.ready(err => { - t.error(err) - - fastify.pg.test.transact((client, commit) => { - client.query('INSERT INTO users(username) VALUES($1) RETURNING id', ['commit-callback'], (err, id) => { - commit(err, id) - }) - }, function (err, res) { - t.error(err) - t.equals(res.rows.length, 1) - - fastify.pg.test - .query(`SELECT * FROM users WHERE username = 'commit-callback'`) - .then(result => { - t.ok(result.rows[0].username === 'commit-callback') - }).catch(err => { - t.fail(err) - }) - }) - }) -}) From 58516ead1cad7f0dfb78480c8f06ceba2c1d572c Mon Sep 17 00:00:00 2001 From: darkgl0w <31093081+darkgl0w@users.noreply.github.com> Date: Thu, 9 May 2019 19:43:23 +0200 Subject: [PATCH 2/9] tests rework and code clean up - Code coverage raised to 94.83% --- index.js | 31 +-- package.json | 16 +- test/initialization.test.js | 176 +++++++++++++ test/query.test.js | 263 +++++++++++++++++++ test/transaction.test.js | 507 ++++++++++++++++++++++++++++++++++++ 5 files changed, 969 insertions(+), 24 deletions(-) create mode 100644 test/initialization.test.js create mode 100644 test/query.test.js create mode 100644 test/transaction.test.js diff --git a/index.js b/index.js index 3c2e405..acc11a0 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ 'use strict' +const defaultPg = require('pg') const fp = require('fastify-plugin') -var defaultPg = require('pg') function transactionUtil (pool, fn, cb) { pool.connect((err, client, done) => { @@ -9,10 +9,9 @@ function transactionUtil (pool, fn, cb) { const shouldAbort = (err) => { if (err) { - client.query('ROLLBACK', () => { - done() - }) + client.query('ROLLBACK', () => done()) } + return !!err } @@ -21,9 +20,8 @@ function transactionUtil (pool, fn, cb) { client.query('COMMIT', (err) => { done() - if (err) { - return cb(err) - } + if (err) return cb(err) + return cb(null, res) }) } @@ -34,9 +32,7 @@ function transactionUtil (pool, fn, cb) { const promise = fn(client, commit) if (promise && typeof promise.then === 'function') { - promise.then( - (res) => commit(null, res), - (e) => commit(e)) + promise.then((res) => commit(null, res), (e) => commit(e)) } }) }) @@ -49,7 +45,8 @@ function transact (fn, cb) { return new Promise((resolve, reject) => { transactionUtil(this, fn, function (err, res) { - if (err) { return reject(err) } + if (err) return reject(err) + return resolve(res) }) }) @@ -63,7 +60,7 @@ function fastifyPostgres (fastify, options, next) { if (options.native) { delete options.native if (!pg.native) { - console.warn('pg-native not installed, can\'t use native option - fallback to pg module') + console.warn(`pg-native not installed, can't use native option - fallback to pg module`) } else { pg = pg.native } @@ -81,26 +78,26 @@ function fastifyPostgres (fastify, options, next) { transact: transact.bind(pool) } + fastify.addHook('onClose', (fastify, done) => pool.end(done)) + if (name) { if (!fastify.pg) { fastify.decorate('pg', {}) } if (fastify.pg[name]) { - return next(new Error('Connection name has already been registered: ' + name)) + return next(new Error(`fastify-postgres '${name}' instance name has already been registered`)) } fastify.pg[name] = db } else { if (fastify.pg) { - next(new Error('fastify-postgres has already registered')) + return next(new Error('fastify-postgres has already been registered')) } else { - fastify.pg = db + fastify.decorate('pg', db) } } - fastify.addHook('onClose', (fastify, done) => pool.end(done)) - next() } diff --git a/package.json b/package.json index 869cba7..f01b4b1 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,11 @@ "description": "Fastify PostgreSQL connection plugin", "main": "index.js", "scripts": { - "test": "standard && tap test.js", - "load-data": "docker run --rm --link fastify-postgres:postgres postgres:11-alpine psql -h postgres -d postgres -c 'CREATE TABLE users(id serial PRIMARY KEY, username VARCHAR (50) NOT NULL);' -U postgres", - "postgres": "docker run --rm -p 5432:5432 --name fastify-postgres postgres:11-alpine" + "test": "standard && tap -J test/*.test.js", + "test:report": "standard && tap -J --coverage-report=html test/*.test.js", + "test:verbose": "standard && tap -J test/*.test.js -Rspec", + "load-data": "docker run --rm -d --link fastify-postgres:postgres postgres:11-alpine psql -h postgres -d postgres -c 'CREATE TABLE users(id serial PRIMARY KEY, username VARCHAR (50) NOT NULL);' -U postgres", + "postgres": "docker run --rm -d -p 5432:5432 --name fastify-postgres postgres:11-alpine" }, "repository": { "type": "git", @@ -27,14 +29,14 @@ }, "homepage": "https://github.com/fastify/fastify-postgres#readme", "dependencies": { - "fastify-plugin": "^1.4.0" + "fastify-plugin": "^1.5.0" }, "devDependencies": { - "fastify": "^2.0.0", + "fastify": "^2.3.0", "pg": "*", "pg-native": "^3.0.0", - "standard": "^12.0.0", - "tap": "^12.5.2" + "standard": "^12.0.1", + "tap": "^12.7.0" }, "peerDependencies": { "pg": ">=6.0.0" diff --git a/test/initialization.test.js b/test/initialization.test.js new file mode 100644 index 0000000..169dc4d --- /dev/null +++ b/test/initialization.test.js @@ -0,0 +1,176 @@ +'use strict' + +const t = require('tap') +const test = t.test +const Fastify = require('fastify') +const fastifyPostgres = require('../index') + +test('Should be able to use native module', (t) => { + t.plan(2) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + native: true + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg + .query('SELECT 1 AS one') + .then((result) => { + t.is(result.rows[0].one, 1) + }) + .catch((err) => { + t.fail(err) + }) + }) +}) + +test('Should be able to use an alternative pg module', (t) => { + t.plan(2) + + const altPg = require('pg') + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + pg: altPg + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg + .query('SELECT 1 AS one') + .then((result) => { + t.is(result.rows[0].one, 1) + }) + .catch((err) => { + t.fail(err) + }) + }) +}) + +test('Should not throw if registered within different scopes (with and without named instances)', (t) => { + t.plan(2) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(function scopeOne (instance, opts, next) { + instance.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + next() + }) + + fastify.register(function scopeTwo (instance, opts, next) { + instance.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'one' + }) + + instance.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'two' + }) + + next() + }) + + fastify.ready((err) => { + t.error(err) + t.is(err, null) + }) +}) + +test('Should throw when trying to register multiple instances without giving a name', (t) => { + t.plan(2) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + fastify.ready((err) => { + t.ok(err) + t.is(err.message, 'fastify-postgres has already been registered') + }) +}) + +test('Should throw when trying to register duplicate connection names', (t) => { + t.plan(2) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + const name = 'test' + + fastify + .register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name + }) + .register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name + }) + + fastify.ready((err) => { + t.ok(err) + t.is(err.message, `fastify-postgres '${name}' instance name has already been registered`) + }) +}) + +test('fastify.pg namespace should exist', (t) => { + t.plan(5) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + fastify.ready((err) => { + t.error(err) + + t.ok(fastify.pg) + t.ok(fastify.pg.connect) + t.ok(fastify.pg.pool) + t.ok(fastify.pg.Client) + }) +}) + +test('fastify.pg.test namespace should exist', (t) => { + t.plan(6) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'test' + }) + + fastify.ready((err) => { + t.error(err) + + 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) + }) +}) diff --git a/test/query.test.js b/test/query.test.js new file mode 100644 index 0000000..739ef7c --- /dev/null +++ b/test/query.test.js @@ -0,0 +1,263 @@ +'use strict' + +const t = require('tap') +const test = t.test +const Fastify = require('fastify') +const fastifyPostgres = require('../index') + +test('When fastify.pg root namespace is used:', (childTest) => { + childTest.test('Should be able to connect and perform a query with a callback', (t) => { + t.plan(4) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + fastify.ready((err) => { + t.error(err) + + 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) + }) + } + }) + + childTest.test('Should be able to use the query util with a callback', (t) => { + t.plan(3) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.query('SELECT NOW()', (err, result) => { + t.error(err) + t.ok(result.rows) + }) + }) + }) + + childTest.test('Should be able to use the query util with promises', (t) => { + t.plan(2) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg + .query('SELECT NOW()') + .then((result) => { + t.ok(result.rows) + }) + .catch((err) => { + t.fail(err) + }) + }) + }) + + childTest.test( + 'query util should return an error when pg fails to perform an operation using a callback', + (t) => { + t.plan(4) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + const DB_NAME = 'database_that_do_not_exist' + + fastify.register(fastifyPostgres, { + connectionString: `postgres://postgres@localhost/${DB_NAME}` + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.query('SELECT NOW()', (err, result) => { + t.is(result, undefined) + t.ok(err) + t.is(err.message, `database "${DB_NAME}" does not exist`) + }) + }) + } + ) + + childTest.test('Should throw when pg fails to perform operation with promises', (t) => { + t.plan(3) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + const DB_NAME = 'database_that_do_not_exist' + + fastify.register(fastifyPostgres, { + connectionString: `postgres://postgres@localhost/${DB_NAME}` + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg + .query('SELECT NOW()') + .then((result) => { + t.fail(result) + }) + .catch((err) => { + t.ok(err) + t.is(err.message, `database "${DB_NAME}" does not exist`) + }) + }) + }) + + childTest.end() +}) + +test('When a fastify.pg namespace is used:', (childTest) => { + childTest.test('Should be able to connect and perform a query', (t) => { + t.plan(4) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'test' + }) + + fastify.ready((err) => { + t.error(err) + fastify.pg.test.connect(onConnect) + }) + + function onConnect (err, client, done) { + t.error(err) + client.query('SELECT NOW()', (err, result) => { + done() + t.error(err) + t.ok(result.rows) + }) + } + }) + + childTest.test('Should be able to use query util with a callback', (t) => { + t.plan(3) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'test' + }) + + fastify.ready((err) => { + t.error(err) + fastify.pg.test.query('SELECT NOW()', (err, result) => { + t.error(err) + t.ok(result.rows) + }) + }) + }) + + childTest.test('Should be able to use query util with promises', (t) => { + t.plan(2) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + 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) + }) + }) + }) + + childTest.test('Should be able to use native module', (t) => { + t.plan(2) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'test', + native: true + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.test + .query('SELECT 1 AS one') + .then((result) => { + t.is(result.rows[0].one, 1) + }) + .catch((err) => { + t.fail(err) + }) + }) + }) + + childTest.test('Should throw when pg fails to perform an operation with promises', (t) => { + t.plan(3) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + const DB_NAME = 'database_that_do_not_exist' + + fastify.register(fastifyPostgres, { + connectionString: `postgres://postgres@localhost/${DB_NAME}`, + 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.is(err.message, `database "${DB_NAME}" does not exist`) + }) + }) + }) + + childTest.end() +}) diff --git a/test/transaction.test.js b/test/transaction.test.js new file mode 100644 index 0000000..8d73494 --- /dev/null +++ b/test/transaction.test.js @@ -0,0 +1,507 @@ +'use strict' + +const t = require('tap') +const test = t.test +const Fastify = require('fastify') +const fastifyPostgres = require('../index') + +test('When fastify.pg root namespace is used:', (childTest) => { + childTest.test('Should be able to use transact util with a callback', (t) => { + t.plan(3) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.transact( + (client) => + client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [ + 'root-with-callback' + ]), + function (err, result) { + t.error(err) + t.is(result.rows.length, 1) + + const userId = result.rows[0].id + + fastify.pg + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.is(result.rows[0].username, 'root-with-callback') + }) + .catch((err) => { + t.fail(err) + }) + } + ) + }) + }) + + childTest.test('Should be able to use transact util with promises', (t) => { + t.plan(3) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg + .transact((client) => + client.query('INSERT INTO users(username) VALUES($1) RETURNING id', ['root-with-promise']) + ) + .then((result) => { + t.is(result.rows.length, 1) + + const userId = result.rows[0].id + + fastify.pg + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.is(result.rows[0].username, 'root-with-promise') + }) + .catch((err) => { + t.fail(err) + }) + }) + .catch((err) => { + t.fail(err) + }) + }) + }) + + childTest.test('Should be able to use transact util with a commit callback', (t) => { + t.plan(4) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + 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.is(result.rows.length, 1) + + const userId = result.rows[0].id + + fastify.pg + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.is(result.rows[0].username, 'root-commit-callback') + }) + .catch((err) => { + t.fail(err) + }) + } + ) + }) + }) + + childTest.test('Should trigger a rollback when something goes wrong (with callback)', (t) => { + t.plan(9) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.transact( + (client) => { + return client + .query('INSERT INTO users(username) VALUES($1) RETURNING id', [ + 'root-rollback-user-callback' + ]) + .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.is(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.is(err.message, 'We make it throw on purpose to trigger a rollback') + t.is(result, undefined) + + fastify.pg + .query(`SELECT * FROM users WHERE username = 'root-rollback-user-callback'`) + .then((result) => { + t.ok(result) + t.is(result.rows.length, 0) + }) + .catch((err) => { + t.fail(err) + }) + } + ) + }) + }) + + childTest.test('Should trigger a rollback when something goes wrong (with promises)', (t) => { + t.plan(8) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres' + }) + + 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.is(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.is(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.is(result.rows.length, 0) + }) + .catch((err) => { + t.fail(err) + }) + }) + }) + }) + + childTest.test('Should throw if the pool connection throws an error', (t) => { + t.plan(3) + + const fastify = Fastify() + const BAD_DB_NAME = 'db_that_does_not_exist' + + fastify.register(fastifyPostgres, { + connectionString: `postgres://postgres@localhost/${BAD_DB_NAME}` + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.transact((client) => client.query('SELECT NOW()')) + .catch((err) => { + t.ok(err) + t.is(err.message, `database "${BAD_DB_NAME}" does not exist`) + }) + }) + }) + + childTest.end() +}) + +test('When fastify.pg.test namespace is used:', (childTest) => { + childTest.test('Should be able to use transact util with a callback', (t) => { + t.plan(4) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'test' + }) + + 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.is(result.rows.length, 1) + + const userId = result.rows[0].id + + fastify.pg.test + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.is(result.rows[0].username, 'namespace-with-callback') + }) + .catch((err) => { + t.fail(err) + }) + } + ) + }) + }) + + childTest.test('Should be able to use transact util with promises', (t) => { + t.plan(3) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'test' + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.test + .transact((client) => + client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [ + 'namespace-with-promise' + ]) + ) + .then((result) => { + t.is(result.rows.length, 1) + + const userId = result.rows[0].id + + fastify.pg.test + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.is(result.rows[0].username, 'namespace-with-promise') + }) + .catch((err) => { + t.fail(err) + }) + }) + .catch((err) => { + t.fail(err) + }) + }) + }) + + childTest.test('Should be able to use transact util with a commit callback', (t) => { + t.plan(4) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'test' + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.test.transact( + (client, commit) => { + client.query( + 'INSERT INTO users(username) VALUES($1) RETURNING id', + ['namespace-commit-callback'], + (err, id) => { + commit(err, id) + } + ) + }, + function (err, result) { + t.error(err) + t.is(result.rows.length, 1) + + const userId = result.rows[0].id + + fastify.pg.test + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.is(result.rows[0].username, 'namespace-commit-callback') + }) + .catch((err) => { + t.fail(err) + }) + } + ) + }) + }) + + childTest.test('Should trigger a rollback when something goes wrong (with callback)', (t) => { + t.plan(9) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + 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 + + return client + .query('SELECT * FROM users WHERE id = $1', [userId]) + .then((result) => { + t.ok(result) + t.is(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.is(err.message, 'We make it throw on purpose to trigger a rollback') + t.is(result, undefined) + + fastify.pg.test + .query(`SELECT * FROM users WHERE username = 'namespace-rollback-user-callback'`) + .then((result) => { + t.ok(result) + t.is(result.rows.length, 0) + }) + .catch((err) => { + t.fail(err) + }) + } + ) + }) + }) + + childTest.test('Should trigger a rollback when something goes wrong (with promises)', (t) => { + t.plan(8) + + const fastify = Fastify() + t.teardown(() => fastify.close()) + + fastify.register(fastifyPostgres, { + connectionString: 'postgres://postgres@localhost/postgres', + name: 'test' + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.test + .transact((client) => + client + .query('INSERT INTO users(username) VALUES($1) RETURNING id', [ + 'namespace-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.is(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.is(err.message, 'We make it throw on purpose to trigger a rollback') + + fastify.pg.test + .query(`SELECT * FROM users WHERE username = 'namespace-rollback-user-promise'`) + .then((result) => { + t.ok(result) + t.is(result.rows.length, 0) + }) + .catch((err) => { + t.fail(err) + }) + }) + }) + }) + + childTest.test('Should throw if the pool connection throws an error', (t) => { + t.plan(3) + + const fastify = Fastify() + const BAD_DB_NAME = 'db_that_does_not_exist' + + fastify.register(fastifyPostgres, { + connectionString: `postgres://postgres@localhost/${BAD_DB_NAME}`, + name: 'test' + }) + + fastify.ready((err) => { + t.error(err) + + fastify.pg.test.transact((client) => client.query('SELECT NOW()')) + .catch((err) => { + t.ok(err) + t.is(err.message, `database "${BAD_DB_NAME}" does not exist`) + }) + }) + }) + + childTest.end() +}) From ec48b77131b41006ebfbf4d52e251d958a227633 Mon Sep 17 00:00:00 2001 From: darkgl0w <31093081+darkgl0w@users.noreply.github.com> Date: Thu, 9 May 2019 20:02:34 +0200 Subject: [PATCH 3/9] Fix a typo --- test/query.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/query.test.js b/test/query.test.js index 739ef7c..1039de7 100644 --- a/test/query.test.js +++ b/test/query.test.js @@ -133,7 +133,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { childTest.end() }) -test('When a fastify.pg namespace is used:', (childTest) => { +test('When fastify.pg.test namespace is used:', (childTest) => { childTest.test('Should be able to connect and perform a query', (t) => { t.plan(4) From 5500355d6b25c016ba64340d924e4d9abcada249 Mon Sep 17 00:00:00 2001 From: darkgl0w <31093081+darkgl0w@users.noreply.github.com> Date: Thu, 9 May 2019 20:42:37 +0200 Subject: [PATCH 4/9] Add tap to Greenkeeper ignore list --- package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/package.json b/package.json index f01b4b1..3f8ae94 100644 --- a/package.json +++ b/package.json @@ -40,5 +40,10 @@ }, "peerDependencies": { "pg": ">=6.0.0" + }, + "greenkeeper": { + "ignore": [ + "tap" + ] } } From 75d1390f012962cdb38e8b92392a0d4201c35615 Mon Sep 17 00:00:00 2001 From: darkgl0w <31093081+darkgl0w@users.noreply.github.com> Date: Thu, 9 May 2019 21:37:54 +0200 Subject: [PATCH 5/9] Fix typo --- test/query.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/query.test.js b/test/query.test.js index 1039de7..88a138b 100644 --- a/test/query.test.js +++ b/test/query.test.js @@ -85,7 +85,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { const fastify = Fastify() t.teardown(() => fastify.close()) - const DB_NAME = 'database_that_do_not_exist' + const DB_NAME = 'db_that_does_not_exist' fastify.register(fastifyPostgres, { connectionString: `postgres://postgres@localhost/${DB_NAME}` @@ -109,7 +109,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { const fastify = Fastify() t.teardown(() => fastify.close()) - const DB_NAME = 'database_that_do_not_exist' + const DB_NAME = 'db_that_does_not_exist' fastify.register(fastifyPostgres, { connectionString: `postgres://postgres@localhost/${DB_NAME}` From be2dd32d4c9acda2da49a8daa81ece40ebd0b212 Mon Sep 17 00:00:00 2001 From: darkgl0w <31093081+darkgl0w@users.noreply.github.com> Date: Thu, 9 May 2019 22:34:51 +0200 Subject: [PATCH 6/9] Update index.js Co-Authored-By: Matteo Collina --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index acc11a0..a43992c 100644 --- a/index.js +++ b/index.js @@ -9,7 +9,7 @@ function transactionUtil (pool, fn, cb) { const shouldAbort = (err) => { if (err) { - client.query('ROLLBACK', () => done()) + client.query('ROLLBACK', done) } return !!err From d19ea5060ca74653f566a0ef48222dfb39691094 Mon Sep 17 00:00:00 2001 From: darkgl0w <31093081+darkgl0w@users.noreply.github.com> Date: Thu, 9 May 2019 22:39:26 +0200 Subject: [PATCH 7/9] Apply suggested changes --- index.js | 4 ++-- test/query.test.js | 32 ++++++++++++++++---------------- test/transaction.test.js | 32 ++++++++++++++++---------------- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/index.js b/index.js index a43992c..9efb0ad 100644 --- a/index.js +++ b/index.js @@ -9,7 +9,7 @@ function transactionUtil (pool, fn, cb) { const shouldAbort = (err) => { if (err) { - client.query('ROLLBACK', done) + client.query('ROLLBACK', () => done()) } return !!err @@ -60,7 +60,7 @@ function fastifyPostgres (fastify, options, next) { if (options.native) { delete options.native if (!pg.native) { - console.warn(`pg-native not installed, can't use native option - fallback to pg module`) + console.warn("pg-native not installed, can't use native option - fallback to pg module") } else { pg = pg.native } diff --git a/test/query.test.js b/test/query.test.js index 88a138b..5af59b4 100644 --- a/test/query.test.js +++ b/test/query.test.js @@ -5,8 +5,8 @@ const test = t.test const Fastify = require('fastify') const fastifyPostgres = require('../index') -test('When fastify.pg root namespace is used:', (childTest) => { - childTest.test('Should be able to connect and perform a query with a callback', (t) => { +test('When fastify.pg root namespace is used:', (t) => { + t.test('Should be able to connect and perform a query with a callback', (t) => { t.plan(4) const fastify = Fastify() @@ -33,7 +33,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { } }) - childTest.test('Should be able to use the query util with a callback', (t) => { + t.test('Should be able to use the query util with a callback', (t) => { t.plan(3) const fastify = Fastify() @@ -53,7 +53,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { }) }) - childTest.test('Should be able to use the query util with promises', (t) => { + t.test('Should be able to use the query util with promises', (t) => { t.plan(2) const fastify = Fastify() @@ -77,7 +77,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { }) }) - childTest.test( + t.test( 'query util should return an error when pg fails to perform an operation using a callback', (t) => { t.plan(4) @@ -85,7 +85,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { const fastify = Fastify() t.teardown(() => fastify.close()) - const DB_NAME = 'db_that_does_not_exist' + const DB_NAME = 'database_that_do_not_exist' fastify.register(fastifyPostgres, { connectionString: `postgres://postgres@localhost/${DB_NAME}` @@ -103,13 +103,13 @@ test('When fastify.pg root namespace is used:', (childTest) => { } ) - childTest.test('Should throw when pg fails to perform operation with promises', (t) => { + t.test('Should throw when pg fails to perform operation with promises', (t) => { t.plan(3) const fastify = Fastify() t.teardown(() => fastify.close()) - const DB_NAME = 'db_that_does_not_exist' + const DB_NAME = 'database_that_do_not_exist' fastify.register(fastifyPostgres, { connectionString: `postgres://postgres@localhost/${DB_NAME}` @@ -130,11 +130,11 @@ test('When fastify.pg root namespace is used:', (childTest) => { }) }) - childTest.end() + t.end() }) -test('When fastify.pg.test namespace is used:', (childTest) => { - childTest.test('Should be able to connect and perform a query', (t) => { +test('When fastify.pg.test namespace is used:', (t) => { + t.test('Should be able to connect and perform a query', (t) => { t.plan(4) const fastify = Fastify() @@ -160,7 +160,7 @@ test('When fastify.pg.test namespace is used:', (childTest) => { } }) - childTest.test('Should be able to use query util with a callback', (t) => { + t.test('Should be able to use query util with a callback', (t) => { t.plan(3) const fastify = Fastify() @@ -180,7 +180,7 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.test('Should be able to use query util with promises', (t) => { + t.test('Should be able to use query util with promises', (t) => { t.plan(2) const fastify = Fastify() @@ -205,7 +205,7 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.test('Should be able to use native module', (t) => { + t.test('Should be able to use native module', (t) => { t.plan(2) const fastify = Fastify() @@ -231,7 +231,7 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.test('Should throw when pg fails to perform an operation with promises', (t) => { + t.test('Should throw when pg fails to perform an operation with promises', (t) => { t.plan(3) const fastify = Fastify() @@ -259,5 +259,5 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.end() + t.end() }) diff --git a/test/transaction.test.js b/test/transaction.test.js index 8d73494..2646f52 100644 --- a/test/transaction.test.js +++ b/test/transaction.test.js @@ -5,8 +5,8 @@ const test = t.test const Fastify = require('fastify') const fastifyPostgres = require('../index') -test('When fastify.pg root namespace is used:', (childTest) => { - childTest.test('Should be able to use transact util with a callback', (t) => { +test('When fastify.pg root namespace is used:', (t) => { + t.test('Should be able to use transact util with a callback', (t) => { t.plan(3) const fastify = Fastify() @@ -43,7 +43,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { }) }) - childTest.test('Should be able to use transact util with promises', (t) => { + t.test('Should be able to use transact util with promises', (t) => { t.plan(3) const fastify = Fastify() @@ -80,7 +80,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { }) }) - childTest.test('Should be able to use transact util with a commit callback', (t) => { + t.test('Should be able to use transact util with a commit callback', (t) => { t.plan(4) const fastify = Fastify() @@ -121,7 +121,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { }) }) - childTest.test('Should trigger a rollback when something goes wrong (with callback)', (t) => { + t.test('Should trigger a rollback when something goes wrong (with callback)', (t) => { t.plan(9) const fastify = Fastify() @@ -175,7 +175,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { }) }) - childTest.test('Should trigger a rollback when something goes wrong (with promises)', (t) => { + t.test('Should trigger a rollback when something goes wrong (with promises)', (t) => { t.plan(8) const fastify = Fastify() @@ -227,7 +227,7 @@ test('When fastify.pg root namespace is used:', (childTest) => { }) }) - childTest.test('Should throw if the pool connection throws an error', (t) => { + t.test('Should throw if the pool connection throws an error', (t) => { t.plan(3) const fastify = Fastify() @@ -248,11 +248,11 @@ test('When fastify.pg root namespace is used:', (childTest) => { }) }) - childTest.end() + t.end() }) -test('When fastify.pg.test namespace is used:', (childTest) => { - childTest.test('Should be able to use transact util with a callback', (t) => { +test('When fastify.pg.test namespace is used:', (t) => { + t.test('Should be able to use transact util with a callback', (t) => { t.plan(4) const fastify = Fastify() @@ -290,7 +290,7 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.test('Should be able to use transact util with promises', (t) => { + t.test('Should be able to use transact util with promises', (t) => { t.plan(3) const fastify = Fastify() @@ -330,7 +330,7 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.test('Should be able to use transact util with a commit callback', (t) => { + t.test('Should be able to use transact util with a commit callback', (t) => { t.plan(4) const fastify = Fastify() @@ -373,7 +373,7 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.test('Should trigger a rollback when something goes wrong (with callback)', (t) => { + t.test('Should trigger a rollback when something goes wrong (with callback)', (t) => { t.plan(9) const fastify = Fastify() @@ -428,7 +428,7 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.test('Should trigger a rollback when something goes wrong (with promises)', (t) => { + t.test('Should trigger a rollback when something goes wrong (with promises)', (t) => { t.plan(8) const fastify = Fastify() @@ -481,7 +481,7 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.test('Should throw if the pool connection throws an error', (t) => { + t.test('Should throw if the pool connection throws an error', (t) => { t.plan(3) const fastify = Fastify() @@ -503,5 +503,5 @@ test('When fastify.pg.test namespace is used:', (childTest) => { }) }) - childTest.end() + t.end() }) From 1c781c4deb72c200baec1c736c37bf7e99bc205a Mon Sep 17 00:00:00 2001 From: darkgl0w <31093081+darkgl0w@users.noreply.github.com> Date: Thu, 9 May 2019 23:13:28 +0200 Subject: [PATCH 8/9] Revert back to single quotes --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 9efb0ad..2e34335 100644 --- a/index.js +++ b/index.js @@ -60,7 +60,7 @@ function fastifyPostgres (fastify, options, next) { if (options.native) { delete options.native if (!pg.native) { - console.warn("pg-native not installed, can't use native option - fallback to pg module") + console.warn('pg-native not installed, can\'t use native option - fallback to pg module') } else { pg = pg.native } From 7751e6e8948bc622eb6d0518e91e20c5b4ab240f Mon Sep 17 00:00:00 2001 From: darkgl0w <31093081+darkgl0w@users.noreply.github.com> Date: Thu, 9 May 2019 23:20:42 +0200 Subject: [PATCH 9/9] Update index.js Co-Authored-By: Matteo Collina --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 2e34335..bc79d75 100644 --- a/index.js +++ b/index.js @@ -9,7 +9,7 @@ function transactionUtil (pool, fn, cb) { const shouldAbort = (err) => { if (err) { - client.query('ROLLBACK', () => done()) + client.query('ROLLBACK', done) } return !!err