slonik
Version:
A Node.js PostgreSQL client with strict types, detailed logging and assertions.
149 lines • 5.73 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const createPool_1 = require("../factories/createPool");
const createErrorWithCode_1 = require("../helpers.test/createErrorWithCode");
const createPoolWithSpy_1 = require("../helpers.test/createPoolWithSpy");
const createTestRunner_1 = require("../helpers.test/createTestRunner");
const pg_driver_1 = require("@slonik/pg-driver");
const sinon = __importStar(require("sinon"));
const driverFactory = (0, pg_driver_1.createPgDriverFactory)();
const { test } = (0, createTestRunner_1.createTestRunner)(driverFactory, 'pg');
test('commits successful transaction', async (t) => {
const { pool, spy } = await (0, createPoolWithSpy_1.createPoolWithSpy)(t.context.dsn, {
driverFactory,
});
await pool.transaction(async () => { });
t.is(spy.query.getCall(0).args[0], 'START TRANSACTION');
t.is(spy.query.getCall(1).args[0], 'COMMIT');
});
test('rollbacks unsuccessful transaction', async (t) => {
const { pool, spy } = await (0, createPoolWithSpy_1.createPoolWithSpy)(t.context.dsn, {
driverFactory,
});
await t.throwsAsync(pool.transaction(async () => {
return await Promise.reject(new Error('foo'));
}));
t.is(spy.query.getCall(0).args[0], 'START TRANSACTION');
t.is(spy.query.getCall(1).args[0], 'ROLLBACK');
});
test('retries a transaction that failed due to a transaction error', async (t) => {
const pool = await (0, createPool_1.createPool)(t.context.dsn);
const handlerStub = sinon.stub();
handlerStub
.onFirstCall()
.rejects((0, createErrorWithCode_1.createErrorWithCode)('40P01'))
.onSecondCall()
.resolves({
command: 'SELECT',
fields: [],
notices: [],
rowCount: 1,
rows: [
{
foo: 1,
},
],
});
const result = await pool.transaction(handlerStub);
t.is(handlerStub.callCount, 2);
t.deepEqual(result, {
command: 'SELECT',
fields: [],
notices: [],
rowCount: 1,
rows: [
{
foo: 1,
},
],
});
});
test('commits successful transaction with retries', async (t) => {
const { pool, spy } = await (0, createPoolWithSpy_1.createPoolWithSpy)(t.context.dsn, {
driverFactory,
});
const handlerStub = sinon.stub();
handlerStub
.onFirstCall()
.rejects((0, createErrorWithCode_1.createErrorWithCode)('40P01'))
.onSecondCall()
.resolves({
command: 'SELECT',
fields: [],
notices: [],
rowCount: 1,
rows: [
{
foo: 1,
},
],
});
await pool.transaction(handlerStub);
t.is(spy.query.getCall(0).args[0], 'START TRANSACTION');
t.is(spy.query.getCall(1).args[0], 'ROLLBACK');
t.is(spy.query.getCall(2).args[0], 'START TRANSACTION');
t.is(spy.query.getCall(3).args[0], 'COMMIT');
});
test('returns the thrown transaction error if the retry limit is reached', async (t) => {
const pool = await (0, createPool_1.createPool)(t.context.dsn);
const handlerStub = sinon.stub();
handlerStub
.onFirstCall()
.rejects((0, createErrorWithCode_1.createErrorWithCode)('40P01'))
.onSecondCall()
.rejects((0, createErrorWithCode_1.createErrorWithCode)('40P01'));
const error = await t.throwsAsync(pool.transaction(handlerStub, 1));
t.is(handlerStub.callCount, 2);
t.true(error instanceof Error);
t.is(error.code, '40P01');
});
test('rollbacks unsuccessful transaction with retries', async (t) => {
const { pool, spy } = await (0, createPoolWithSpy_1.createPoolWithSpy)(t.context.dsn, {
driverFactory,
});
const handlerStub = sinon.stub();
handlerStub
.onFirstCall()
.rejects((0, createErrorWithCode_1.createErrorWithCode)('40P01'))
.onSecondCall()
.rejects((0, createErrorWithCode_1.createErrorWithCode)('40P01'));
await t.throwsAsync(pool.transaction(handlerStub, 1));
t.is(spy.query.getCall(0).args[0], 'START TRANSACTION');
t.is(spy.query.getCall(1).args[0], 'ROLLBACK');
t.is(spy.query.getCall(2).args[0], 'START TRANSACTION');
t.is(spy.query.getCall(3).args[0], 'ROLLBACK');
});
//# sourceMappingURL=transaction.test.js.map
;