@@ -89,7 +89,100 @@ void main() {
8989 expect (existsAfterDelete, isFalse);
9090 });
9191
92- test ('#migrate' , () {}, skip: 'Write test' );
92+ group ('#migrate' , () {
93+ late SqliteProvider cleanProvider;
94+
95+ setUp (() {
96+ cleanProvider = SqliteProvider (
97+ inMemoryDatabasePath,
98+ databaseFactory: databaseFactoryFfi,
99+ modelDictionary: dictionary,
100+ );
101+ });
102+
103+ tearDown (() async {
104+ await cleanProvider.resetDb ();
105+ });
106+
107+ test ('runs migrations for the first time' , () async {
108+ await cleanProvider.migrate ([const DemoModelMigration ()]);
109+
110+ final version = await cleanProvider.lastMigrationVersion ();
111+ expect (version, 1 );
112+
113+ // Verify tables were created
114+ final tables = await cleanProvider.rawQuery (
115+ "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'" ,
116+ );
117+ final tableNames = tables.map ((t) => t['name' ]).toList ();
118+ expect (tableNames, contains ('DemoModelAssoc' ));
119+ expect (tableNames, contains ('DemoModel' ));
120+ });
121+
122+ test ('skips migrations when already at latest version' , () async {
123+ // Run migration first time
124+ await cleanProvider.migrate ([const DemoModelMigration ()]);
125+ expect (await cleanProvider.lastMigrationVersion (), 1 );
126+
127+ // Run again - should skip
128+ await cleanProvider.migrate ([const DemoModelMigration ()]);
129+ expect (await cleanProvider.lastMigrationVersion (), 1 );
130+ });
131+
132+ test ('enables foreign keys pragma' , () async {
133+ const migration = DemoModelMigration ();
134+
135+ await cleanProvider.migrate ([migration]);
136+
137+ final result = await cleanProvider.rawQuery ('PRAGMA foreign_keys' );
138+ expect (result.first['foreign_keys' ], 1 );
139+ });
140+
141+ test ('tracks migration versions correctly' , () async {
142+ const migration1 = DemoModelMigration (2 , [], []);
143+ const migration2 = DemoModelMigration (3 , [], []);
144+
145+ // After first migration
146+ await cleanProvider.migrate ([migration1]);
147+ expect (await cleanProvider.lastMigrationVersion (), 2 );
148+
149+ // After second migration
150+ await cleanProvider.migrate ([migration2]);
151+ expect (await cleanProvider.lastMigrationVersion (), 3 );
152+
153+ // Verify version records exist
154+ // ignore: invalid_use_of_protected_member
155+ final db = await cleanProvider.getDb ();
156+ final versions = await db.query ('MigrationVersions' , orderBy: 'version' );
157+ expect (versions, hasLength (3 ));
158+ expect (versions[0 ]['version' ], 1 );
159+ expect (versions[1 ]['version' ], 2 );
160+ expect (versions[2 ]['version' ], 3 );
161+ });
162+
163+ test ('runs down migrations correctly' , () async {
164+ const migration1 = DemoModelMigration (2 , [], []);
165+ const migration2 = DemoModelMigration (3 , [], []);
166+
167+ // After first migration
168+ await cleanProvider.migrate ([migration1]);
169+ expect (await cleanProvider.lastMigrationVersion (), 2 );
170+
171+ // After second migration
172+ await cleanProvider.migrate ([migration2]);
173+ expect (await cleanProvider.lastMigrationVersion (), 3 );
174+
175+ await cleanProvider.migrate ([migration1, migration2], down: true );
176+ expect (await cleanProvider.lastMigrationVersion (), 1 );
177+
178+ // Verify version records exist
179+ // ignore: invalid_use_of_protected_member
180+ final db = await cleanProvider.getDb ();
181+ final versions = await db.query ('MigrationVersions' , orderBy: 'version' );
182+ expect (versions, hasLength (1 ));
183+ expect (versions[0 ]['version' ], 1 );
184+ });
185+ });
93186
94187 group ('#exists' , () {
95188 test ('specific' , () async {
0 commit comments