1+ import { Database , KeyPath , DataClass , Index , EntityRepository } from '../index' ;
2+
3+ // Test entities with different versions
4+ @DataClass ( { version : 1 } )
5+ class UserV1 {
6+ @KeyPath ( )
7+ id ! : string ;
8+
9+ @Index ( )
10+ email ! : string ;
11+
12+ name ! : string ;
13+
14+ constructor ( id : string , name : string , email : string ) {
15+ this . id = id ;
16+ this . name = name ;
17+ this . email = email ;
18+ }
19+ }
20+
21+ @DataClass ( { version : 2 } )
22+ class PostV2 {
23+ @KeyPath ( )
24+ id ! : string ;
25+
26+ @Index ( )
27+ authorId ! : string ;
28+
29+ title ! : string ;
30+ content ! : string ;
31+
32+ constructor ( id : string , authorId : string , title : string , content : string ) {
33+ this . id = id ;
34+ this . authorId = authorId ;
35+ this . title = title ;
36+ this . content = content ;
37+ }
38+ }
39+
40+ @DataClass ( { version : 4 } )
41+ class CommentV4 {
42+ @KeyPath ( )
43+ id ! : string ;
44+
45+ @Index ( )
46+ postId ! : string ;
47+
48+ @Index ( )
49+ userId ! : string ;
50+
51+ text ! : string ;
52+ timestamp ! : Date ;
53+
54+ constructor ( id : string , postId : string , userId : string , text : string ) {
55+ this . id = id ;
56+ this . postId = postId ;
57+ this . userId = userId ;
58+ this . text = text ;
59+ this . timestamp = new Date ( ) ;
60+ }
61+ }
62+
63+ // Test with default version (should be 1)
64+ @DataClass ( )
65+ class TagDefault {
66+ @KeyPath ( )
67+ id ! : string ;
68+
69+ name ! : string ;
70+
71+ constructor ( id : string , name : string ) {
72+ this . id = id ;
73+ this . name = name ;
74+ }
75+ }
76+
77+ describe ( 'Schema Versioning' , ( ) => {
78+ let db : any ;
79+
80+ beforeAll ( async ( ) => {
81+ // Clear any existing database
82+ const deleteRequest = indexedDB . deleteDatabase ( 'VersionTestDB' ) ;
83+ await new Promise < void > ( ( resolve ) => {
84+ deleteRequest . onsuccess = ( ) => resolve ( ) ;
85+ deleteRequest . onerror = ( ) => resolve ( ) ; // Continue even if deletion fails
86+ } ) ;
87+
88+ db = await Database . build ( 'VersionTestDB' , [ UserV1 , PostV2 , CommentV4 , TagDefault ] ) ;
89+ } ) ;
90+
91+ it ( 'should calculate correct database version from highest entity version' , ( ) => {
92+ expect ( db . getDatabaseVersion ( ) ) . toBe ( 4 ) ; // Highest version among entities
93+ } ) ;
94+
95+ it ( 'should track entity versions correctly' , ( ) => {
96+ const versions = db . getEntityVersions ( ) ;
97+ expect ( versions . get ( 'UserV1' ) ) . toBe ( 1 ) ;
98+ expect ( versions . get ( 'PostV2' ) ) . toBe ( 2 ) ;
99+ expect ( versions . get ( 'CommentV4' ) ) . toBe ( 4 ) ;
100+ expect ( versions . get ( 'TagDefault' ) ) . toBe ( 1 ) ; // Default version
101+ } ) ;
102+
103+ it ( 'should get individual entity version' , ( ) => {
104+ expect ( db . getEntityVersion ( 'UserV1' ) ) . toBe ( 1 ) ;
105+ expect ( db . getEntityVersion ( 'PostV2' ) ) . toBe ( 2 ) ;
106+ expect ( db . getEntityVersion ( 'CommentV4' ) ) . toBe ( 4 ) ;
107+ expect ( db . getEntityVersion ( 'TagDefault' ) ) . toBe ( 1 ) ;
108+ expect ( db . getEntityVersion ( 'NonExistent' ) ) . toBeUndefined ( ) ;
109+ } ) ;
110+
111+ it ( 'should create and manage entities with different versions' , async ( ) => {
112+ // Test UserV1 (version 1)
113+ const user = new UserV1 ( 'u1' , 'Alice' , 'alice@example.com' ) ;
114+ await db . UserV1 . create ( user ) ;
115+ const retrievedUser = await db . UserV1 . read ( 'u1' ) ;
116+ expect ( retrievedUser ) . toEqual ( user ) ;
117+
118+ // Test PostV2 (version 2)
119+ const post = new PostV2 ( 'p1' , 'u1' , 'Hello World' , 'This is my first post' ) ;
120+ await db . PostV2 . create ( post ) ;
121+ const retrievedPost = await db . PostV2 . read ( 'p1' ) ;
122+ expect ( retrievedPost ) . toEqual ( post ) ;
123+
124+ // Test CommentV4 (version 4)
125+ const comment = new CommentV4 ( 'c1' , 'p1' , 'u1' , 'Great post!' ) ;
126+ await db . CommentV4 . create ( comment ) ;
127+ const retrievedComment = await db . CommentV4 . read ( 'c1' ) ;
128+ expect ( retrievedComment ?. text ) . toBe ( 'Great post!' ) ;
129+
130+ // Test TagDefault (default version 1)
131+ const tag = new TagDefault ( 't1' , 'typescript' ) ;
132+ await db . TagDefault . create ( tag ) ;
133+ const retrievedTag = await db . TagDefault . read ( 't1' ) ;
134+ expect ( retrievedTag ) . toEqual ( tag ) ;
135+ } ) ;
136+
137+ it ( 'should handle indexes correctly for different versions' , async ( ) => {
138+ // Test finding by index in UserV1
139+ const users = await db . UserV1 . findByIndex ( 'email' , 'alice@example.com' ) ;
140+ expect ( users . length ) . toBe ( 1 ) ;
141+ expect ( users [ 0 ] . name ) . toBe ( 'Alice' ) ;
142+
143+ // Test finding by index in PostV2
144+ const posts = await db . PostV2 . findByIndex ( 'authorId' , 'u1' ) ;
145+ expect ( posts . length ) . toBe ( 1 ) ;
146+ expect ( posts [ 0 ] . title ) . toBe ( 'Hello World' ) ;
147+
148+ // Test finding by index in CommentV4
149+ const comments = await db . CommentV4 . findByIndex ( 'postId' , 'p1' ) ;
150+ expect ( comments . length ) . toBe ( 1 ) ;
151+ expect ( comments [ 0 ] . text ) . toBe ( 'Great post!' ) ;
152+ } ) ;
153+
154+ it ( 'should support query builder with versioned entities' , async ( ) => {
155+ const posts = await db . PostV2 . query ( )
156+ . where ( 'authorId' ) . equals ( 'u1' )
157+ . execute ( ) ;
158+
159+ expect ( posts . length ) . toBe ( 1 ) ;
160+ expect ( posts [ 0 ] . title ) . toBe ( 'Hello World' ) ;
161+
162+ const comments = await db . CommentV4 . query ( )
163+ . where ( 'userId' ) . equals ( 'u1' )
164+ . execute ( ) ;
165+
166+ expect ( comments . length ) . toBe ( 1 ) ;
167+ expect ( comments [ 0 ] . text ) . toBe ( 'Great post!' ) ;
168+ } ) ;
169+ } ) ;
0 commit comments