import { expect } from 'chai' ; import Dexie from 'dexie' ; import { ulid } from 'ulid' ; import { personSchema , shouldHaveThrown } from '../utils/spec.utils' ; import { Database } from './db' ; const databaseName = 'database' ; describe ( 'ThreadDB' , function ( ) { context ( 'database' , function ( ) { describe ( 'construction and init' , async function ( ) { let db ; afterEach ( function ( ) { db . close ( ) ; } ) ; after ( async function ( ) { await db . delete ( ) ; } ) ; it ( 'should only allow version incrementing' , async function ( ) { db = new Database ( databaseName ) ; await db . open ( 2 ) ; expect ( db . verno ) . to . equal ( 2 ) ; db . close ( ) ; db = new Database ( databaseName , { name : 'Person' , schema : personSchema , indexes : [ { path : 'name' , unique : true } , { path : 'age' , unique : false } , ] , } , { name : 'Empty' , } ) ; try { await db . open ( 1 ) ; throw shouldHaveThrown ; } catch ( err ) { expect ( err . toString ( ) ) . to . include ( 'VersionError' ) ; } db . close ( ) ; await db . delete ( ) ; } ) ; it ( 'should not have a db id until the remote has been set and initialized' , function ( ) { db = new Database ( databaseName , { name : 'Person' , schema : personSchema , indexes : [ { path : 'name' , unique : true } , { path : 'age' , unique : false } , ] , } , { name : 'Empty' , } ) ; expect ( db . id ) . to . be . undefined ; } ) ; it ( 'should be able to pre-define collections' , async function ( ) { db = new Database ( databaseName , { name : 'Person' , schema : personSchema , indexes : [ { path : 'name' , unique : true } , { path : 'age' , unique : false } , ] , } , { name : 'Empty' , } ) ; await db . open ( ) ; expect ( db . collections ( ) . size ) . to . equal ( 2 ) ; const collection = db . collection ( 'Person' ) ; expect ( collection ) . to . not . be . undefined ; expect ( db . dexie . table ( 'Person' ) . schema . indexes ) . to . have . lengthOf ( 2 ) ; expect ( db . dexie . table ( 'Person' ) . schema . primKey ) . to . have . ownProperty ( 'name' , '_id' ) ; } ) ; it ( 'should be able to define collection configs prior to opening the db' , async function ( ) { db = new Database ( databaseName ) ; db . collectionConfig ( { name : 'Person' , schema : personSchema , indexes : [ { path : 'name' , unique : true } , { path : 'age' , unique : false } , ] , } ) . collectionConfig ( { name : 'Empty' , } ) ; await db . open ( ) ; expect ( db . collections ( ) . size ) . to . equal ( 2 ) ; const collection = db . collection ( 'Person' ) ; expect ( collection ) . to . not . be . undefined ; await collection ?. insert ( { name : 'toddler' , age : 4 } ) ; expect ( await collection ?. count ( ) ) . to . equal ( 1 ) ; expect ( db . dexie . table ( 'Person' ) . schema . indexes ) . to . have . lengthOf ( 2 ) ; expect ( db . dexie . table ( 'Person' ) . schema . primKey ) . to . have . ownProperty ( 'name' , '_id' ) ; } ) ; } ) ; describe ( 'methods' , async function ( ) { let db ; before ( async function ( ) { db = new Database ( databaseName , { name : 'Person' , schema : personSchema , indexes : [ { path : 'name' , unique : true } , { path : 'age' , unique : false } , ] , } , { name : 'Empty' , } ) ; await db . open ( ) ; } ) ; after ( async function ( ) { db . close ( ) ; await db . delete ( ) ; } ) ; it ( 'should have monotonically increasing ulid ids' , async function ( ) { const collection = db . collection ( 'Person' ) ; const first = ulid ( ) ; await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ; const obj = collection ?. create ( { name : 'baby' , age : 2 } ) ; expect ( obj ?. _id ) . to . have . lengthOf ( 26 ) ; expect ( first <= obj ! . _id ) . to . equal ( true ) ; } ) ; it ( 'should be able to list local collections' , function ( ) { const collections = db . collections ( ) ; expect ( collections . size ) . to . equal ( 2 ) ; expect ( [ ... collections . keys ( ) ] ) . to . deep . equal ( [ 'Person' , 'Empty' ] ) ; } ) ; it ( 'should be able to list local collections even if we lose them' , function ( ) { ; ( db as any ) . collectionMap . clear ( ) ; const collections = db . collections ( ) ; expect ( collections . size ) . to . equal ( 2 ) ; expect ( [ ... collections . keys ( ) ] ) . to . deep . equal ( [ 'Person' , 'Empty' ] ) ; } ) ; it ( 'should be able to get a specific collection by name' , function ( ) { const collection = db . collection ( 'Person' ) ; expect ( collection ?. name ) . to . equal ( 'Person' ) ; try { db . collection ( 'Missing' ) ; throw shouldHaveThrown ; } catch ( err ) { expect ( err ) . to . be . instanceOf ( Dexie . InvalidTableError ) ; } } ) ; it ( 'should be able to get specific collection, even by re-building cache' , function ( ) { ; ( db as any ) . collectionMap . clear ( ) ; const collection = db . collection ( 'Person' ) ; expect ( collection ?. name ) . to . equal ( 'Person' ) ; } ) ; } ) ; } ) ; } ) ;