Skip to content

Commit 9b85e2b

Browse files
committed
Minor improvements
1 parent 38005f4 commit 9b85e2b

5 files changed

Lines changed: 66 additions & 107 deletions

File tree

Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTests.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,12 @@ public async Task InitializeAsync()
3434
public async Task DisposeAsync()
3535
{
3636
testCts.Cancel();
37+
testCts.Dispose();
3738

3839
await db.DisconnectAndClear();
3940
await db.Close();
4041

41-
try { File.Delete(dbName); }
42-
catch { }
43-
44-
testCts.Dispose();
45-
testCts = new();
42+
DatabaseUtils.CleanDb(dbName);
4643
}
4744

4845
private record IdResult(string id);

Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/CRUDTests.cs

Lines changed: 37 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,18 @@ private async Task ResetDB(PowerSyncDatabase db)
4444
DatabaseUtils.CleanDb(db.Database.Name);
4545
}
4646

47-
[Fact]
48-
public async Task IncludeMetadataTest()
47+
private async Task WithCustomAssetOptions(TableOptions options, Func<PowerSyncDatabase, Task> test)
4948
{
50-
var localDbName = $"IncludeMetadataTest-{Guid.NewGuid():N}.db";
49+
var localDbName = $"crud-custom-{Guid.NewGuid():N}.db";
5150
var db = new PowerSyncDatabase(new PowerSyncDatabaseOptions
5251
{
5352
Database = new SQLOpenOptions { DbFilename = localDbName },
54-
Schema = TestSchema.GetSchemaWithCustomAssetOptions(new TableOptions
55-
{
56-
TrackMetadata = true
57-
}),
53+
Schema = TestSchema.GetSchemaWithCustomAssetOptions(options),
5854
});
5955
try
6056
{
6157
await ResetDB(db);
62-
63-
await db.Execute("INSERT INTO assets (id, description, _metadata) VALUES(uuid(), 'xxxx', 'so meta');");
64-
65-
var batch = await db.GetNextCrudTransaction();
66-
Assert.Equal("so meta", batch?.Crud[0].Metadata);
58+
await test(db);
6759
}
6860
finally
6961
{
@@ -73,55 +65,41 @@ public async Task IncludeMetadataTest()
7365
}
7466

7567
[Fact]
76-
public async Task IncludeOldValuesTest()
77-
{
78-
var localDbName = $"IncludeOldValuesTest-{Guid.NewGuid():N}.db";
79-
var db = new PowerSyncDatabase(new PowerSyncDatabaseOptions
68+
public Task IncludeMetadataTest() => WithCustomAssetOptions(
69+
new TableOptions { TrackMetadata = true },
70+
async db =>
8071
{
81-
Database = new SQLOpenOptions { DbFilename = localDbName },
82-
Schema = TestSchema.GetSchemaWithCustomAssetOptions(new TableOptions
83-
{
84-
TrackPreviousValues = new TrackPreviousOptions()
85-
}),
72+
await db.Execute("INSERT INTO assets (id, description, _metadata) VALUES(uuid(), 'xxxx', 'so meta');");
73+
74+
var batch = await db.GetNextCrudTransaction();
75+
Assert.Equal("so meta", batch?.Crud[0].Metadata);
8676
});
87-
try
88-
{
89-
await ResetDB(db);
9077

78+
[Fact]
79+
public Task IncludeOldValuesTest() => WithCustomAssetOptions(
80+
new TableOptions { TrackPreviousValues = new TrackPreviousOptions() },
81+
async db =>
82+
{
9183
await db.Execute("INSERT INTO assets (id, description) VALUES(?, ?);", ["a185b7e1-dffa-4a9a-888c-15c0f0cac4b3", "entry"]);
9284
await db.Execute("DELETE FROM ps_crud;");
9385
await db.Execute("UPDATE assets SET description = ?", ["new name"]);
9486

9587
var batch = await db.GetNextCrudTransaction();
9688
Assert.True(batch?.Crud[0].PreviousValues?.ContainsKey("description"));
9789
Assert.Equal("entry", batch?.Crud[0].PreviousValues?["description"]);
98-
}
99-
finally
100-
{
101-
// await db.Close();
102-
// DatabaseUtils.CleanDb(localDbName);
103-
}
104-
}
90+
});
10591

10692
[Fact]
107-
public async Task IncludeOldValuesWithColumnFilterTest()
108-
{
109-
var localDbName = $"IncludeOldValuesWithColumnFilterTest-{Guid.NewGuid():N}.db";
110-
var db = new PowerSyncDatabase(new PowerSyncDatabaseOptions
93+
public Task IncludeOldValuesWithColumnFilterTest() => WithCustomAssetOptions(
94+
new TableOptions
11195
{
112-
Database = new SQLOpenOptions { DbFilename = localDbName },
113-
Schema = TestSchema.GetSchemaWithCustomAssetOptions(new TableOptions
96+
TrackPreviousValues = new TrackPreviousOptions
11497
{
115-
TrackPreviousValues = new TrackPreviousOptions
116-
{
117-
Columns = new List<string> { "description" }
118-
}
119-
}),
120-
});
121-
try
98+
Columns = new List<string> { "description" }
99+
}
100+
},
101+
async db =>
122102
{
123-
await ResetDB(db);
124-
125103
await db.Execute("INSERT INTO assets (id, description, make) VALUES(?, ?, ?);", ["a185b7e1-dffa-4a9a-888c-15c0f0cac4b3", "entry", "make1"]);
126104
await db.Execute("DELETE FROM ps_crud;");
127105
await db.Execute("UPDATE assets SET description = ?, make = ?", ["new name", "make2"]);
@@ -130,34 +108,20 @@ public async Task IncludeOldValuesWithColumnFilterTest()
130108
Assert.NotNull(batch?.Crud[0].PreviousValues);
131109
Assert.Equal("entry", batch?.Crud[0].PreviousValues?["description"]);
132110
Assert.False(batch?.Crud[0].PreviousValues!.ContainsKey("make"));
133-
}
134-
finally
135-
{
136-
await db.Close();
137-
DatabaseUtils.CleanDb(localDbName);
138-
}
139-
}
111+
});
140112

141113

142114
[Fact]
143-
public async Task IncludeOldValuesWhenChangedTest()
144-
{
145-
var localDbName = $"IncludeOldValuesWhenChangedTest-{Guid.NewGuid():N}.db";
146-
var db = new PowerSyncDatabase(new PowerSyncDatabaseOptions
115+
public Task IncludeOldValuesWhenChangedTest() => WithCustomAssetOptions(
116+
new TableOptions
147117
{
148-
Database = new SQLOpenOptions { DbFilename = localDbName },
149-
Schema = TestSchema.GetSchemaWithCustomAssetOptions(new TableOptions
118+
TrackPreviousValues = new TrackPreviousOptions
150119
{
151-
TrackPreviousValues = new TrackPreviousOptions
152-
{
153-
OnlyWhenChanged = true
154-
}
155-
}),
156-
});
157-
try
120+
OnlyWhenChanged = true
121+
}
122+
},
123+
async db =>
158124
{
159-
await ResetDB(db);
160-
161125
await db.Execute("INSERT INTO assets (id, description, make) VALUES(uuid(), ?, ?);", ["name", "make1"]);
162126
await db.Execute("DELETE FROM ps_crud;");
163127
await db.Execute("UPDATE assets SET description = ?", ["new name"]);
@@ -167,42 +131,20 @@ public async Task IncludeOldValuesWhenChangedTest()
167131
Assert.NotNull(batch.Crud[0].PreviousValues);
168132
Assert.Equal("name", batch.Crud[0].PreviousValues!["description"]);
169133
Assert.False(batch.Crud[0].PreviousValues!.ContainsKey("make"));
170-
}
171-
finally
172-
{
173-
await db.Close();
174-
DatabaseUtils.CleanDb(localDbName);
175-
}
176-
}
134+
});
177135

178136
[Fact]
179-
public async Task IgnoreEmptyUpdateTest()
180-
{
181-
var localDbName = $"IgnoreEmptyUpdateTest-{Guid.NewGuid():N}.db";
182-
var db = new PowerSyncDatabase(new PowerSyncDatabaseOptions
183-
{
184-
Database = new SQLOpenOptions { DbFilename = localDbName },
185-
Schema = TestSchema.GetSchemaWithCustomAssetOptions(new TableOptions
186-
{
187-
IgnoreEmptyUpdates = true
188-
}),
189-
});
190-
try
137+
public Task IgnoreEmptyUpdateTest() => WithCustomAssetOptions(
138+
new TableOptions { IgnoreEmptyUpdates = true },
139+
async db =>
191140
{
192-
await ResetDB(db);
193141
await db.Execute("INSERT INTO assets (id, description) VALUES(?, ?);", [testId, "name"]);
194142
await db.Execute("DELETE FROM ps_crud;");
195143
await db.Execute("UPDATE assets SET description = ?", ["name"]);
196144

197145
var batch = await db.GetNextCrudTransaction();
198146
Assert.Null(batch);
199-
}
200-
finally
201-
{
202-
await db.Close();
203-
DatabaseUtils.CleanDb(localDbName);
204-
}
205-
}
147+
});
206148

207149
[Fact]
208150
public async Task Insert_RecordCrudEntryTest()

Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncStreamsTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ public async Task SubscribesWithStreams()
108108
Assert.Null(statusForStream!.Subscription.LastSyncedAt);
109109
Assert.True(statusForStream!.Subscription.HasExplicitSubscription);
110110
}
111-
await Task.Delay(100);
111+
// Ensure the previous status update is fully settled before listening for the next one
112+
await Task.Yield();
112113
statusTask = MockSyncService.NextStatus(db);
113114

114115
syncService.PushLine(
@@ -158,7 +159,7 @@ public async Task ChangesSubscriptionsDynamically()
158159
)
159160
);
160161

161-
await Task.Delay(100);
162+
await statusTask;
162163
var subscription = await db.SyncStream("a").Subscribe();
163164

164165
await TestUtils.WaitForAsync(() => syncService.Requests.Count > 1);

Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncTests.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ public async Task SyncDeleteOperationTest()
7474
syncService.PushLine(line);
7575
}
7676

77-
await Task.Delay(500); // Wait for sync to process
77+
await TestUtils.WaitForAsync(async () =>
78+
{
79+
var rows = await db.GetAll<dynamic>("SELECT * FROM lists");
80+
return rows.Length == 0;
81+
});
7882

7983
var result = await db.GetAll<dynamic>("SELECT * FROM lists");
8084
Assert.Empty(result);
@@ -105,15 +109,15 @@ public async Task SyncLocalCreateOperationTest()
105109

106110
await db.Execute("insert into lists (id, name, owner_id, created_at) values (uuid(), 'New User', ?, datetime())", ["78bb787c-ff0b-41b2-a297-6a7701648f4a"]);
107111

108-
await Task.Delay(500); // Wait for local change to be registered
112+
await TestUtils.WaitForAsync(() => db.CurrentStatus.DataFlowStatus.Uploading == false);
109113
Assert.Null(db.CurrentStatus.DataFlowStatus.UploadError);
110114

111115
foreach (var line in syncAfterLocalCreate)
112116
{
113117
syncService.PushLine(line);
114118
}
115119

116-
await Task.Delay(500); // Wait for sync to process
120+
await TestUtils.WaitForAsync(() => db.CurrentStatus.DataFlowStatus.Downloading == false);
117121
Assert.Null(db.CurrentStatus.DataFlowStatus.DownloadError);
118122
}
119123

Tests/PowerSync/PowerSync.Common.Tests/Utils/TestUtils.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,30 @@ public static void DeepEquivalent(object? expected, object? actual, [CallerLineN
1919
}
2020
}
2121

22-
public static async Task WaitForAsync(Func<bool> condition, TimeSpan? timeout = null)
22+
public static async Task WaitForAsync(Func<bool> condition, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
2323
{
2424
timeout ??= TimeSpan.FromSeconds(5);
2525
var start = DateTime.UtcNow;
2626
while (DateTime.UtcNow - start < timeout)
2727
{
28+
cancellationToken.ThrowIfCancellationRequested();
2829
if (condition())
2930
return;
30-
await Task.Delay(50);
31+
await Task.Delay(50, cancellationToken);
32+
}
33+
throw new TimeoutException("Condition not met within timeout");
34+
}
35+
36+
public static async Task WaitForAsync(Func<Task<bool>> condition, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
37+
{
38+
timeout ??= TimeSpan.FromSeconds(5);
39+
var start = DateTime.UtcNow;
40+
while (DateTime.UtcNow - start < timeout)
41+
{
42+
cancellationToken.ThrowIfCancellationRequested();
43+
if (await condition())
44+
return;
45+
await Task.Delay(50, cancellationToken);
3146
}
3247
throw new TimeoutException("Condition not met within timeout");
3348
}

0 commit comments

Comments
 (0)