Skip to content

Commit

Permalink
tighten tests further.
Browse files Browse the repository at this point in the history
  • Loading branch information
igalklebanov committed Oct 5, 2024
1 parent a43c328 commit c24a251
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 33 deletions.
6 changes: 0 additions & 6 deletions src/dialect/mssql/mssql-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,6 @@ export class MssqlDriver implements Driver {
await connection.rollbackTransaction(savepointName)
}

async releaseSavepoint(): Promise<void> {
throw new Error(
'MS SQL Server (mssql) does not support releasing savepoints',
)
}

async releaseConnection(connection: MssqlConnection): Promise<void> {
await connection[PRIVATE_RELEASE_METHOD]()
this.#pool.release(connection)
Expand Down
12 changes: 12 additions & 0 deletions src/driver/dummy-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ export class DummyDriver implements Driver {
async destroy(): Promise<void> {
// Nothing to do here.
}

async releaseSavepoint(): Promise<void> {
// Nothing to do here.
}

async rollbackToSavepoint(): Promise<void> {
// Nothing to do here.
}

async savepoint(): Promise<void> {
// Nothing to do here.
}
}

class DummyConnection implements DatabaseConnection {
Expand Down
10 changes: 7 additions & 3 deletions src/driver/runtime-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class RuntimeDriver implements Driver {
return this.#driver.savepoint(connection, savepointName, compileQuery)
}

throw new Error('savepoints are not supported by this driver')
throw new Error('The `savepoint` method is not supported by this driver')
}

rollbackToSavepoint(
Expand All @@ -111,7 +111,9 @@ export class RuntimeDriver implements Driver {
)
}

throw new Error('savepoints are not supported by this driver')
throw new Error(
'The `rollbackToSavepoint` method is not supported by this driver',
)
}

releaseSavepoint(
Expand All @@ -127,7 +129,9 @@ export class RuntimeDriver implements Driver {
)
}

throw new Error('savepoints are not supported by this driver')
throw new Error(
'The `releaseSavepoint` method is not supported by this driver',
)
}

async destroy(): Promise<void> {
Expand Down
131 changes: 107 additions & 24 deletions test/node/src/controlled-transaction.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import * as sinon from 'sinon'
import { Connection } from 'tedious'
import { CompiledQuery, IsolationLevel, Kysely } from '../../../'
import {
CompiledQuery,
ControlledTransaction,
Driver,
DummyDriver,
IsolationLevel,
Kysely,
SqliteDialect,
} from '../../../'
import {
DIALECTS,
Database,
Expand Down Expand Up @@ -501,14 +509,30 @@ for (const dialect of DIALECTS) {
})
}

if (dialect === 'mssql') {
it('should throw an error when trying to release a savepoint as it is not supported', async () => {
const trx = await ctx.db.startTransaction().execute()

await expect(
trx.releaseSavepoint('foo' as never).execute(),
).to.be.rejectedWith(
'The `releaseSavepoint` method is not supported by this driver',
)

await trx.rollback().execute()
})
}

it('should throw an error when trying to execute a query after the transaction has been committed', async () => {
const trx = await ctx.db.startTransaction().execute()

await insertSomething(trx)

await trx.commit().execute()

await expect(insertSomethingElse(trx)).to.be.rejected
await expect(insertSomethingElse(trx)).to.be.rejectedWith(
'Transaction is already committed',
)
})

it('should throw an error when trying to execute a query after the transaction has been rolled back', async () => {
Expand All @@ -518,29 +542,88 @@ for (const dialect of DIALECTS) {

await trx.rollback().execute()

await expect(insertSomethingElse(trx)).to.be.rejected
await expect(insertSomethingElse(trx)).to.be.rejectedWith(
'Transaction is already rolled back',
)
})
})
}

async function insertSomething(db: Kysely<Database>) {
return await db
.insertInto('person')
.values({
first_name: 'Foo',
last_name: 'Barson',
gender: 'male',
})
.executeTakeFirstOrThrow()
}

async function insertSomethingElse(db: Kysely<Database>) {
return await db
.insertInto('person')
.values({
first_name: 'Fizz',
last_name: 'Buzzson',
gender: 'female',
})
.executeTakeFirstOrThrow()
}
describe('custom dialect: controlled transaction', () => {
const db = new Kysely<Database>({
dialect: new (class extends SqliteDialect {
createDriver(): Driver {
const driver = class extends DummyDriver {}

// @ts-ignore
driver.prototype.releaseSavepoint = undefined
// @ts-ignore
driver.prototype.rollbackToSavepoint = undefined
// @ts-ignore
driver.prototype.savepoint = undefined

return new driver()
}
// @ts-ignore
})({}),
})
let trx: ControlledTransaction<Database>

before(async () => {
trx = await db.startTransaction().execute()
})

after(async () => {
await trx.rollback().execute()
})

it('should throw an error when trying to savepoint on a dialect that does not support it', async () => {
const trx = await db.startTransaction().execute()

await expect(trx.savepoint('foo').execute()).to.be.rejectedWith(
'The `savepoint` method is not supported by this driver',
)
})

it('should throw an error when trying to rollback to a savepoint on a dialect that does not support it', async () => {
const trx = await db.startTransaction().execute()

await expect(
trx.rollbackToSavepoint('foo' as never).execute(),
).to.be.rejectedWith(
'The `rollbackToSavepoint` method is not supported by this driver',
)
})

it('should throw an error when trying to release a savepoint on a dialect that does not support it', async () => {
const trx = await db.startTransaction().execute()

await expect(
trx.releaseSavepoint('foo' as never).execute(),
).to.be.rejectedWith(
'The `releaseSavepoint` method is not supported by this driver',
)
})
})

async function insertSomething(db: Kysely<Database>) {
return await db
.insertInto('person')
.values({
first_name: 'Foo',
last_name: 'Barson',
gender: 'male',
})
.executeTakeFirstOrThrow()
}

async function insertSomethingElse(db: Kysely<Database>) {
return await db
.insertInto('person')
.values({
first_name: 'Fizz',
last_name: 'Buzzson',
gender: 'female',
})
.executeTakeFirstOrThrow()
}

0 comments on commit c24a251

Please sign in to comment.