@@ -288,13 +288,13 @@ export function registerBaseTests() {
288288 } ) ;
289289 } ) ;
290290
291- it ( 'Async transaction, auto commit' , done => {
291+ it ( 'Async transaction, auto commit' , async ( ) => {
292292 const id = chance . integer ( ) ;
293293 const name = chance . name ( ) ;
294294 const age = chance . integer ( ) ;
295295 const networth = chance . floating ( ) ;
296296
297- db . transactionAsync ( async tx => {
297+ await db . transactionAsync ( async tx => {
298298 const res = await tx . executeAsync (
299299 'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)' ,
300300 [ id , name , age , networth ] ,
@@ -308,87 +308,156 @@ export function registerBaseTests() {
308308 expect ( res . rows . item ) . to . be . a ( 'function' ) ;
309309 } ) ;
310310
311- setTimeout ( ( ) => {
312- const res = db . execute ( 'SELECT * FROM User' ) ;
313- expect ( res . rows ?. _array ) . to . eql ( [
314- {
315- id,
316- name,
317- age,
318- networth,
319- } ,
320- ] ) ;
321- done ( ) ;
322- } , 200 ) ;
311+ const res = db . execute ( 'SELECT * FROM User' ) ;
312+ expect ( res . rows ?. _array ) . to . eql ( [
313+ {
314+ id,
315+ name,
316+ age,
317+ networth,
318+ } ,
319+ ] ) ;
323320 } ) ;
324321
325- it ( 'Async transaction, auto rollback' , done => {
326- const id = chance . string ( ) ;
322+ it ( 'Async transaction, auto rollback' , async ( ) => {
323+ const id = chance . string ( ) ; // Causes error because it should be an integer
327324 const name = chance . name ( ) ;
328325 const age = chance . integer ( ) ;
329326 const networth = chance . floating ( ) ;
330327
331- db . transactionAsync ( async tx => {
332- await tx . executeAsync (
333- 'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)' ,
334- [ id , name , age , networth ] ,
335- ) ;
336- } ) ;
328+ try {
329+ await db . transactionAsync ( async tx => {
330+ await tx . executeAsync (
331+ 'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)' ,
332+ [ id , name , age , networth ] ,
333+ ) ;
334+ } ) ;
335+ } catch ( error ) {
336+ expect ( error ) . to . be . instanceOf ( Error )
337+ expect ( ( error as Error ) . message )
338+ . to . include ( 'SQL execution error' )
339+ . and
340+ . to . include ( 'cannot store TEXT value in INT column User.id' ) ;
337341
338- setTimeout ( ( ) => {
339342 const res = db . execute ( 'SELECT * FROM User' ) ;
340343 expect ( res . rows ?. _array ) . to . eql ( [ ] ) ;
341- done ( ) ;
342- } , 200 ) ;
344+ }
343345 } ) ;
344346
345- it ( 'Async transaction, manual commit' , done => {
347+ it ( 'Async transaction, manual commit' , async ( ) => {
346348 const id = chance . integer ( ) ;
347349 const name = chance . name ( ) ;
348350 const age = chance . integer ( ) ;
349351 const networth = chance . floating ( ) ;
350352
351- db . transactionAsync ( async tx => {
353+ await db . transactionAsync ( async tx => {
352354 await tx . executeAsync (
353355 'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)' ,
354356 [ id , name , age , networth ] ,
355357 ) ;
356358 tx . commit ( ) ;
357359 } ) ;
358360
359- setTimeout ( ( ) => {
360- const res = db . execute ( 'SELECT * FROM User' ) ;
361- expect ( res . rows ?. _array ) . to . eql ( [
362- {
363- id,
364- name,
365- age,
366- networth,
367- } ,
368- ] ) ;
369- done ( ) ;
370- } , 1000 ) ;
361+ const res = db . execute ( 'SELECT * FROM User' ) ;
362+ expect ( res . rows ?. _array ) . to . eql ( [
363+ {
364+ id,
365+ name,
366+ age,
367+ networth,
368+ } ,
369+ ] ) ;
371370 } ) ;
372371
373- it ( 'Async transaction, manual rollback' , done => {
372+ it ( 'Async transaction, manual rollback' , async ( ) => {
374373 const id = chance . integer ( ) ;
375374 const name = chance . name ( ) ;
376375 const age = chance . integer ( ) ;
377376 const networth = chance . floating ( ) ;
378377
379- db . transactionAsync ( async tx => {
378+ await db . transactionAsync ( async tx => {
380379 await tx . executeAsync (
381380 'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)' ,
382381 [ id , name , age , networth ] ,
383382 ) ;
384383 tx . rollback ( ) ;
385384 } ) ;
386385
387- setTimeout ( ( ) => {
388- const res = db . execute ( 'SELECT * FROM User' ) ;
389- expect ( res . rows ?. _array ) . to . eql ( [ ] ) ;
390- done ( ) ;
391- } , 1000 ) ;
386+ const res = db . execute ( 'SELECT * FROM User' ) ;
387+ expect ( res . rows ?. _array ) . to . eql ( [ ] ) ;
388+ } ) ;
389+
390+ it ( 'Async transaction, upsert and select' , async ( ) => {
391+ // ARRANGE: Setup for multiple transactions
392+ const iterations = 10 ;
393+ const actual = new Set ( ) ;
394+
395+ // ARRANGE: Generate expected data
396+ const id = chance . integer ( ) ;
397+ const name = chance . name ( ) ;
398+ const age = chance . integer ( ) ;
399+
400+ // ACT: Start multiple async transactions to upsert and select the same record
401+ const promises = [ ] ;
402+ for ( let iteration = 1 ; iteration <= iterations ; iteration ++ ) {
403+ const promised = db . transactionAsync ( async ( tx ) => {
404+ // ACT: Upsert statement to create record / increment the value
405+ await tx . executeAsync ( `
406+ INSERT OR REPLACE INTO [User] ([id], [name], [age], [networth])
407+ SELECT ?, ?, ?,
408+ IFNULL((
409+ SELECT [networth] + 1000
410+ FROM [User]
411+ WHERE [id] = ?
412+ ), 1000)
413+ ` , [ id , name , age , id ] ) ;
414+
415+ // ACT: Select statement to get incremented value and store it for checking later
416+ const results = await tx . executeAsync ( 'SELECT [networth] FROM [User] WHERE [id] = ?' , [ id ] ) ;
417+
418+ actual . add ( results . rows . _array [ 0 ] . networth ) ;
419+ } )
420+
421+ promises . push ( promised ) ;
422+ }
423+
424+ // ACT: Wait for all transactions to complete
425+ await Promise . all ( promises ) ;
426+
427+ // ASSERT: That the expected values where returned
428+ expect ( actual . size ) . to . equal ( iterations , 'Each transaction should read a different value' ) ;
429+ } ) ;
430+
431+ it ( 'Async transaction, rejects on callback error' , async ( ) => {
432+ const promised = db . transactionAsync ( async ( tx ) => {
433+ throw new Error ( 'Error from callback' ) ;
434+ } ) ;
435+
436+ // ASSERT: should return a promise that eventually rejects
437+ expect ( promised ) . to . have . property ( 'then' ) . that . is . a ( 'function' ) ;
438+ try {
439+ await promised ;
440+ expect . fail ( 'Should not resolve' ) ;
441+ } catch ( e ) {
442+ expect ( e ) . to . be . a . instanceof ( Error ) ;
443+ expect ( ( e as Error ) ?. message ) . to . equal ( 'Error from callback' ) ;
444+ }
445+ } ) ;
446+
447+ it ( 'Async transaction, rejects on invalid query' , async ( ) => {
448+ const promised = db . transactionAsync ( async ( tx ) => {
449+ await tx . executeAsync ( 'SELECT * FROM [tableThatDoesNotExist];' ) ;
450+ } )
451+
452+ // ASSERT: should return a promise that eventually rejects
453+ expect ( promised ) . to . have . property ( 'then' ) . that . is . a ( 'function' ) ;
454+ try {
455+ await promised ;
456+ expect . fail ( 'Should not resolve' ) ;
457+ } catch ( e ) {
458+ expect ( e ) . to . be . a . instanceof ( Error ) ;
459+ expect ( ( e as Error ) ?. message ) . to . include ( 'no such table: tableThatDoesNotExist' ) ;
460+ }
392461 } ) ;
393462
394463 it ( 'Batch execute' , ( ) => {
0 commit comments