diff --git a/.github/workflows/dev-packages.yml b/.github/workflows/dev-packages.yml index 05a2f3b..c95de2f 100644 --- a/.github/workflows/dev-packages.yml +++ b/.github/workflows/dev-packages.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET SDK uses: actions/setup-dotnet@v4 with: - dotnet-version: "8.0.x" + dotnet-version: "10.0.x" - name: Install MAUI Workloads run: dotnet workload restore diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d270ffd..0134861 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET SDK uses: actions/setup-dotnet@v4 with: - dotnet-version: "8.0.x" + dotnet-version: "10.0.x" - name: Install MAUI Workloads run: dotnet workload restore diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 15bc561..110b65f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET SDK uses: actions/setup-dotnet@v5 with: - dotnet-version: '8.0' + dotnet-version: '10.0' - name: Install MAUI Workloads run: dotnet workload restore @@ -30,4 +30,4 @@ jobs: run: dotnet restore - name: Run tests - run: dotnet test -v n --framework net8.0 \ No newline at end of file + run: dotnet test -v n --framework net10.0 diff --git a/PowerSync/PowerSync.Common/PowerSync.Common.csproj b/PowerSync/PowerSync.Common/PowerSync.Common.csproj index bc69111..e49d5ec 100644 --- a/PowerSync/PowerSync.Common/PowerSync.Common.csproj +++ b/PowerSync/PowerSync.Common/PowerSync.Common.csproj @@ -1,7 +1,10 @@  - netstandard2.0;net6.0;net8.0;net9.0;net8.0-ios;net8.0-android;net8.0-maccatalyst;net9.0-ios;net9.0-android;net9.0-maccatalyst + net8.0;net9.0;net10.0;net9.0-android;net10.0-android + $(DefaultTargetFrameworks);net9.0-ios;net10.0-ios;net9.0-maccatalyst;net10.0-maccatalyst + $(DefaultTargetFrameworks) + 12 enable enable @@ -27,22 +30,26 @@ - - - - - - + + + + + - - + + - + + + + + + diff --git a/PowerSync/PowerSync.Maui/PowerSync.Maui.csproj b/PowerSync/PowerSync.Maui/PowerSync.Maui.csproj index 74e9a94..3b87666 100644 --- a/PowerSync/PowerSync.Maui/PowerSync.Maui.csproj +++ b/PowerSync/PowerSync.Maui/PowerSync.Maui.csproj @@ -1,7 +1,10 @@  - netstandard2.0;net6.0;net8.0;net9.0;net8.0-ios;net8.0-android;net8.0-maccatalyst;net9.0-ios;net9.0-android;net9.0-maccatalyst + net9.0;net10.0;net9.0-android;net10.0-android + $(DefaultTargetFrameworks);net9.0-ios;net10.0-ios;net9.0-maccatalyst;net10.0-maccatalyst + $(DefaultTargetFrameworks) + 12 enable enable diff --git a/README.md b/README.md index f71ef32..1eb878e 100644 --- a/README.md +++ b/README.md @@ -108,13 +108,13 @@ dotnet restore Run all tests ```bash -dotnet test -v n --framework net8.0 +dotnet test -v n --framework net10.0 ``` Run a specific test ```bash -dotnet test -v n --framework net8.0 --filter "test-file-pattern" +dotnet test -v n --framework net10.0 --filter "test-file-pattern" ``` ### Integration Tests @@ -122,26 +122,26 @@ Integration tests in `PowerSync.Common.IntegrationTests` are intended to run aga The integration tests are disabled by default, define the following environment variable when running the tests. ```bash -RUN_INTEGRATION_TESTS=true dotnet test -v n --framework net8.0 +RUN_INTEGRATION_TESTS=true dotnet test -v n --framework net10.0 ``` Only run integration tests, without any unit tests. ```bash -RUN_INTEGRATION_TESTS=true dotnet test -v n --framework net8.0 --filter "Category=Integration" +RUN_INTEGRATION_TESTS=true dotnet test -v n --framework net10.0 --filter "Category=Integration" ``` ### Performance Tests Performance tests in `PowerSync.Common.PerformanceTests` are disabled by default, define the following environment variable when running the tests. ```bash -RUN_PERFORMANCE_TESTS=true dotnet test -v n --framework net8.0 +RUN_PERFORMANCE_TESTS=true dotnet test -v n --framework net10.0 ``` Only run performance tests, without any unit tests. ```bash -RUN_PERFORMANCE_TESTS=true dotnet test -v n --framework net8.0 --filter "Category=Performance" +RUN_PERFORMANCE_TESTS=true dotnet test -v n --framework net10.0 --filter "Category=Performance" ``` ## Using the PowerSync.Common package in your project diff --git a/Tests/PowerSync/PowerSync.Common.IntegrationTests/NodeClient.cs b/Tests/PowerSync/PowerSync.Common.IntegrationTests/NodeClient.cs index dbd5073..5ce805b 100644 --- a/Tests/PowerSync/PowerSync.Common.IntegrationTests/NodeClient.cs +++ b/Tests/PowerSync/PowerSync.Common.IntegrationTests/NodeClient.cs @@ -1,161 +1,161 @@ -namespace PowerSync.Common.IntegrationTests; - -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; - -using PowerSync.Common.DB.Crud; - -public class NodeClient -{ - private readonly HttpClient _httpClient; - private readonly string _backendUrl; - private readonly string _userId; - - public NodeClient(string userId) - { - _httpClient = new HttpClient(); - _backendUrl = "http://localhost:6060"; - _userId = userId; - } - - public NodeClient(string backendUrl, string userId) - { - _httpClient = new HttpClient(); - _backendUrl = backendUrl; - _userId = userId; - } - - public Task CreateList(string id, string name) - { - return CreateItem("lists", id, name); - } - - async Task CreateItem(string table, string id, string name) - { - var data = new Dictionary - { - { "created_at", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") }, - { "name", name }, - { "owner_id", _userId } - }; - - var batch = new[] - { - new - { - op = UpdateType.PUT.ToString(), - table = table, - id = id, - data = data - } - }; - - var payload = JsonSerializer.Serialize(new { batch }); - var content = new StringContent(payload, Encoding.UTF8, "application/json"); - - HttpResponseMessage response = await _httpClient.PostAsync($"{_backendUrl}/api/data", content); - - if (!response.IsSuccessStatusCode) - { - Console.WriteLine(await response.Content.ReadAsStringAsync()); - throw new Exception( - $"Failed to create item. Status: {response.StatusCode}, " + - $"Response: {await response.Content.ReadAsStringAsync()}" - ); - } - - return await response.Content.ReadAsStringAsync(); - } - - public Task DeleteList(string id) - { - return DeleteItem("lists", id); - } - - public Task CreateTodo(string id, string listId, string description) - { - return CreateTodoItem("todos", id, listId, description); - } - - async Task CreateTodoItem(string table, string id, string listId, string description) - { - var data = new Dictionary - { - { "created_at", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") }, - { "description", description }, - { "list_id", listId }, - { "created_by", _userId }, - { "completed", 0 }, - }; - - var batch = new[] - { - new - { - op = UpdateType.PUT.ToString(), - table = table, - id = id, - data = data - } - }; - - var payload = JsonSerializer.Serialize(new { batch }); - var content = new StringContent(payload, Encoding.UTF8, "application/json"); - - HttpResponseMessage response = await _httpClient.PostAsync($"{_backendUrl}/api/data", content); - - if (!response.IsSuccessStatusCode) - { - Console.WriteLine(await response.Content.ReadAsStringAsync()); - throw new Exception( - $"Failed to create todo. Status: {response.StatusCode}, " + - $"Response: {await response.Content.ReadAsStringAsync()}" - ); - } - - return await response.Content.ReadAsStringAsync(); - } - - public Task DeleteTodo(string id) - { - return DeleteItem("todos", id); - } - - async Task DeleteItem(string table, string id) - { - var batch = new[] - { - new - { - op = UpdateType.DELETE.ToString(), - table = table, - id = id - } - }; - - var payload = JsonSerializer.Serialize(new { batch }); - var content = new StringContent(payload, Encoding.UTF8, "application/json"); - - HttpResponseMessage response = await _httpClient.PostAsync($"{_backendUrl}/api/data", content); - - if (!response.IsSuccessStatusCode) - { - Console.WriteLine(await response.Content.ReadAsStringAsync()); - throw new Exception( - $"Failed to delete item. Status: {response.StatusCode}, " + - $"Response: {await response.Content.ReadAsStringAsync()}" - ); - } - - return await response.Content.ReadAsStringAsync(); - } - - public void Dispose() - { - _httpClient?.Dispose(); - } +namespace PowerSync.Common.IntegrationTests; + +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +using PowerSync.Common.DB.Crud; + +public class NodeClient +{ + private readonly HttpClient _httpClient; + private readonly string _backendUrl; + private readonly string _userId; + + public NodeClient(string userId) + { + _httpClient = new HttpClient(); + _backendUrl = "http://localhost:6060"; + _userId = userId; + } + + public NodeClient(string backendUrl, string userId) + { + _httpClient = new HttpClient(); + _backendUrl = backendUrl; + _userId = userId; + } + + public Task CreateList(string id, string name) + { + return CreateItem("lists", id, name); + } + + async Task CreateItem(string table, string id, string name) + { + var data = new Dictionary + { + { "created_at", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") }, + { "name", name }, + { "owner_id", _userId } + }; + + var batch = new[] + { + new + { + op = UpdateType.PUT.ToString(), + table = table, + id = id, + data = data + } + }; + + var payload = JsonSerializer.Serialize(new { batch }); + var content = new StringContent(payload, Encoding.UTF8, "application/json"); + + HttpResponseMessage response = await _httpClient.PostAsync($"{_backendUrl}/api/data", content); + + if (!response.IsSuccessStatusCode) + { + Console.WriteLine(await response.Content.ReadAsStringAsync()); + throw new Exception( + $"Failed to create item. Status: {response.StatusCode}, " + + $"Response: {await response.Content.ReadAsStringAsync()}" + ); + } + + return await response.Content.ReadAsStringAsync(); + } + + public Task DeleteList(string id) + { + return DeleteItem("lists", id); + } + + public Task CreateTodo(string id, string listId, string description) + { + return CreateTodoItem("todos", id, listId, description); + } + + async Task CreateTodoItem(string table, string id, string listId, string description) + { + var data = new Dictionary + { + { "created_at", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") }, + { "description", description }, + { "list_id", listId }, + { "created_by", _userId }, + { "completed", 0 }, + }; + + var batch = new[] + { + new + { + op = UpdateType.PUT.ToString(), + table = table, + id = id, + data = data + } + }; + + var payload = JsonSerializer.Serialize(new { batch }); + var content = new StringContent(payload, Encoding.UTF8, "application/json"); + + HttpResponseMessage response = await _httpClient.PostAsync($"{_backendUrl}/api/data", content); + + if (!response.IsSuccessStatusCode) + { + Console.WriteLine(await response.Content.ReadAsStringAsync()); + throw new Exception( + $"Failed to create todo. Status: {response.StatusCode}, " + + $"Response: {await response.Content.ReadAsStringAsync()}" + ); + } + + return await response.Content.ReadAsStringAsync(); + } + + public Task DeleteTodo(string id) + { + return DeleteItem("todos", id); + } + + async Task DeleteItem(string table, string id) + { + var batch = new[] + { + new + { + op = UpdateType.DELETE.ToString(), + table = table, + id = id + } + }; + + var payload = JsonSerializer.Serialize(new { batch }); + var content = new StringContent(payload, Encoding.UTF8, "application/json"); + + HttpResponseMessage response = await _httpClient.PostAsync($"{_backendUrl}/api/data", content); + + if (!response.IsSuccessStatusCode) + { + Console.WriteLine(await response.Content.ReadAsStringAsync()); + throw new Exception( + $"Failed to delete item. Status: {response.StatusCode}, " + + $"Response: {await response.Content.ReadAsStringAsync()}" + ); + } + + return await response.Content.ReadAsStringAsync(); + } + + public void Dispose() + { + _httpClient?.Dispose(); + } } diff --git a/Tests/PowerSync/PowerSync.Common.IntegrationTests/NodeConnector.cs b/Tests/PowerSync/PowerSync.Common.IntegrationTests/NodeConnector.cs index ae2a1b2..6585a42 100644 --- a/Tests/PowerSync/PowerSync.Common.IntegrationTests/NodeConnector.cs +++ b/Tests/PowerSync/PowerSync.Common.IntegrationTests/NodeConnector.cs @@ -1,114 +1,114 @@ -namespace PowerSync.Common.IntegrationTests; - - -using System; -using System.Collections.Generic; -using System.IO; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; - -using PowerSync.Common.Client; -using PowerSync.Common.Client.Connection; -using PowerSync.Common.DB.Crud; - - -public class NodeConnector : IPowerSyncBackendConnector -{ - private readonly HttpClient _httpClient; - - public string BackendUrl { get; } - public string PowerSyncUrl { get; } - public string UserId { get; private set; } - private string? clientId; - - public NodeConnector(string userId) - { - _httpClient = new HttpClient(); - - // Load or generate User ID - UserId = userId; - - BackendUrl = "http://localhost:6060"; - PowerSyncUrl = "http://localhost:8080"; - - clientId = null; - } - - public async Task FetchCredentials() - { - string tokenEndpoint = "api/auth/token"; - string url = $"{BackendUrl}/{tokenEndpoint}?user_id={UserId}"; - - HttpResponseMessage response = await _httpClient.GetAsync(url); - if (!response.IsSuccessStatusCode) - { - throw new Exception($"Received {response.StatusCode} from {tokenEndpoint}: {await response.Content.ReadAsStringAsync()}"); - } - - string responseBody = await response.Content.ReadAsStringAsync(); - var jsonResponse = JsonSerializer.Deserialize>(responseBody); - - if (jsonResponse == null || !jsonResponse.ContainsKey("token")) - { - throw new Exception("Invalid response received from authentication endpoint."); - } - - return new PowerSyncCredentials(PowerSyncUrl, jsonResponse["token"]); - } - - public async Task UploadData(IPowerSyncDatabase database) - { - CrudTransaction? transaction; - try - { - transaction = await database.GetNextCrudTransaction(); - } - catch (Exception ex) - { - Console.WriteLine($"UploadData Error: {ex.Message}"); - return; - } - - if (transaction == null) - { - return; - } - - clientId ??= await database.GetClientId(); - - try - { - var batch = new List(); - - foreach (var operation in transaction.Crud) - { - batch.Add(new - { - op = operation.Op.ToString(), - table = operation.Table, - id = operation.Id, - data = operation.OpData - }); - } - - var payload = JsonSerializer.Serialize(new { batch }); - var content = new StringContent(payload, Encoding.UTF8, "application/json"); - - HttpResponseMessage response = await _httpClient.PostAsync($"{BackendUrl}/api/data", content); - - if (!response.IsSuccessStatusCode) - { - throw new Exception($"Received {response.StatusCode} from /api/data: {await response.Content.ReadAsStringAsync()}"); - } - - await transaction.Complete(); - } - catch (Exception ex) - { - Console.WriteLine($"UploadData Error: {ex.Message}"); - throw; - } - } +namespace PowerSync.Common.IntegrationTests; + + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +using PowerSync.Common.Client; +using PowerSync.Common.Client.Connection; +using PowerSync.Common.DB.Crud; + + +public class NodeConnector : IPowerSyncBackendConnector +{ + private readonly HttpClient _httpClient; + + public string BackendUrl { get; } + public string PowerSyncUrl { get; } + public string UserId { get; private set; } + private string? clientId; + + public NodeConnector(string userId) + { + _httpClient = new HttpClient(); + + // Load or generate User ID + UserId = userId; + + BackendUrl = "http://localhost:6060"; + PowerSyncUrl = "http://localhost:8080"; + + clientId = null; + } + + public async Task FetchCredentials() + { + string tokenEndpoint = "api/auth/token"; + string url = $"{BackendUrl}/{tokenEndpoint}?user_id={UserId}"; + + HttpResponseMessage response = await _httpClient.GetAsync(url); + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Received {response.StatusCode} from {tokenEndpoint}: {await response.Content.ReadAsStringAsync()}"); + } + + string responseBody = await response.Content.ReadAsStringAsync(); + var jsonResponse = JsonSerializer.Deserialize>(responseBody); + + if (jsonResponse == null || !jsonResponse.ContainsKey("token")) + { + throw new Exception("Invalid response received from authentication endpoint."); + } + + return new PowerSyncCredentials(PowerSyncUrl, jsonResponse["token"]); + } + + public async Task UploadData(IPowerSyncDatabase database) + { + CrudTransaction? transaction; + try + { + transaction = await database.GetNextCrudTransaction(); + } + catch (Exception ex) + { + Console.WriteLine($"UploadData Error: {ex.Message}"); + return; + } + + if (transaction == null) + { + return; + } + + clientId ??= await database.GetClientId(); + + try + { + var batch = new List(); + + foreach (var operation in transaction.Crud) + { + batch.Add(new + { + op = operation.Op.ToString(), + table = operation.Table, + id = operation.Id, + data = operation.OpData + }); + } + + var payload = JsonSerializer.Serialize(new { batch }); + var content = new StringContent(payload, Encoding.UTF8, "application/json"); + + HttpResponseMessage response = await _httpClient.PostAsync($"{BackendUrl}/api/data", content); + + if (!response.IsSuccessStatusCode) + { + throw new Exception($"Received {response.StatusCode} from /api/data: {await response.Content.ReadAsStringAsync()}"); + } + + await transaction.Complete(); + } + catch (Exception ex) + { + Console.WriteLine($"UploadData Error: {ex.Message}"); + throw; + } + } } diff --git a/Tests/PowerSync/PowerSync.Common.IntegrationTests/PowerSync.Common.IntegrationTests.csproj b/Tests/PowerSync/PowerSync.Common.IntegrationTests/PowerSync.Common.IntegrationTests.csproj index 3d029a9..eefd14e 100644 --- a/Tests/PowerSync/PowerSync.Common.IntegrationTests/PowerSync.Common.IntegrationTests.csproj +++ b/Tests/PowerSync/PowerSync.Common.IntegrationTests/PowerSync.Common.IntegrationTests.csproj @@ -1,7 +1,7 @@ - + - net8.0 + net8.0;net9.0;net10.0 12 enable enable diff --git a/Tests/PowerSync/PowerSync.Common.IntegrationTests/SyncIntegrationTests.cs b/Tests/PowerSync/PowerSync.Common.IntegrationTests/SyncIntegrationTests.cs index 699d9e4..4ee7c4d 100644 --- a/Tests/PowerSync/PowerSync.Common.IntegrationTests/SyncIntegrationTests.cs +++ b/Tests/PowerSync/PowerSync.Common.IntegrationTests/SyncIntegrationTests.cs @@ -9,9 +9,9 @@ namespace PowerSync.Common.IntegrationTests; [Trait("Category", "Integration")] public class SyncIntegrationTests : IAsyncLifetime { - private record ListResult(string id, string name, string owner_id, string created_at); + private record ListResult(string id, string created_at, string name, string owner_id); - private record TodoResult(string id, string list_id, string content, string owner_id, string created_at); + private record TodoResult(string id, string list_id, string created_at, string completed_at, string description, string created_by, string completed_by, int completed); private readonly string userId = Uuid(); @@ -33,12 +33,13 @@ public async Task InitializeAsync() nodeClient = new NodeClient(userId); db = new PowerSyncDatabase(new PowerSyncDatabaseOptions { - Database = new SQLOpenOptions { DbFilename = "powersync-sync-tests.db" }, + Database = new SQLOpenOptions { DbFilename = $"powersync-sync-tests-{userId}.db" }, Schema = TestSchema.PowerSyncSchema, Logger = logger }); await db.Init(); + await db.DisconnectAndClear(); var connector = new NodeConnector(userId); Console.WriteLine($"Using User ID: {userId}"); @@ -52,7 +53,6 @@ public async Task InitializeAsync() { "environment", "integration-tests" } } }); - await db.Connect(connector); await db.WaitForFirstSync(); } catch (Exception ex) @@ -68,6 +68,7 @@ public async Task DisposeAsync() await Task.Delay(2000); await db.DisconnectAndClear(); await db.Close(); + try { File.Delete($"powersync-sync-tests-{userId}.db"); } catch { } } [IntegrationFact(Timeout = 3000)] @@ -93,48 +94,39 @@ public async Task SyncDownCreateOperationTest() await watched.Task; } - [IntegrationFact(Timeout = 3000)] + [IntegrationFact(Timeout = 6000)] public async Task SyncDownDeleteOperationTest() { - var watched = new TaskCompletionSource(); + var created = new TaskCompletionSource(); + var deleted = new TaskCompletionSource(); var cts = new CancellationTokenSource(); var id = Uuid(); - await nodeClient.CreateList(id, name: "Test List to delete"); - + // Use a single Watch for the full create+delete lifecycle so the listener + // channel is registered before any events can be missed. _ = Task.Run(async () => { + bool sawCreate = false; await foreach (var x in db.Watch("select * from lists where id = ?", [id], new() { Signal = cts.Token })) { - // Verify that the item was added locally - if (x.Length == 1) + if (!sawCreate && x.Length == 1) { - watched.SetResult(true); - cts.Cancel(); + sawCreate = true; + created.SetResult(true); } - } - }); - - await watched.Task; - await nodeClient.DeleteList(id); - - watched = new TaskCompletionSource(); - cts = new CancellationTokenSource(); - - _ = Task.Run(async () => - { - await foreach (var x in db.Watch("select * from lists where id = ?", [id], new() { Signal = cts.Token })) - { - // Verify that the item was deleted locally - if (x.Length == 0) + else if (sawCreate && x.Length == 0) { - watched.SetResult(true); + deleted.SetResult(true); cts.Cancel(); } } }); - await watched.Task; + await nodeClient.CreateList(id, name: "Test List to delete"); + await created.Task; + + await nodeClient.DeleteList(id); + await deleted.Task; } [IntegrationFact(Timeout = 5000)] @@ -147,7 +139,7 @@ public async Task SyncDownLargeCreateOperationTest() _ = Task.Run(async () => { - await foreach (var x in db.Watch("select * from lists where id = ?", [id], new() { Signal = cts.Token })) + await foreach (var x in db.Watch("select * from lists where name = ?", [listName], new() { Signal = cts.Token })) { // Verify that the item was added locally if (x.Length == 100) @@ -176,7 +168,7 @@ public async Task SyncDownCreateOperationAfterLargeUploadTest() _ = Task.Run(async () => { - await foreach (var x in db.Watch("select * from lists where id = ?", [id], new() { Signal = cts.Token })) + await foreach (var x in db.Watch("select * from lists where name = ?", [listName], new() { Signal = cts.Token })) { // Verify that the items were added locally if (x.Length == 100) @@ -199,8 +191,11 @@ await db.Execute("insert into lists (id, name, owner_id, created_at) values (uui } await localInsertWatch.Task; - // let the crud upload finish - await Task.Delay(2000); + // Wait for CRUD upload to complete before creating backend item + while (db.CurrentStatus.DataFlowStatus.Uploading) + { + await Task.Delay(50); + } await nodeClient.CreateList(Uuid(), listName); await backendInsertWatch.Task; diff --git a/Tests/PowerSync/PowerSync.Common.IntegrationTests/xunit.runner.json b/Tests/PowerSync/PowerSync.Common.IntegrationTests/xunit.runner.json index fcdb064..27dcc91 100644 --- a/Tests/PowerSync/PowerSync.Common.IntegrationTests/xunit.runner.json +++ b/Tests/PowerSync/PowerSync.Common.IntegrationTests/xunit.runner.json @@ -1,5 +1,7 @@ { "methodDisplay": "method", "diagnosticMessages": true, - "longRunningTestSeconds": 10 -} \ No newline at end of file + "longRunningTestSeconds": 10, + "parallelizeTestCollections": false, + "maxParallelThreads": 1 +} diff --git a/Tests/PowerSync/PowerSync.Common.PerformanceTests/PowerSync.Common.PerformanceTests.csproj b/Tests/PowerSync/PowerSync.Common.PerformanceTests/PowerSync.Common.PerformanceTests.csproj index 25d9697..7773caa 100644 --- a/Tests/PowerSync/PowerSync.Common.PerformanceTests/PowerSync.Common.PerformanceTests.csproj +++ b/Tests/PowerSync/PowerSync.Common.PerformanceTests/PowerSync.Common.PerformanceTests.csproj @@ -1,7 +1,7 @@  - net6.0;net8.0;net9.0 + net8.0;net9.0;net10.0 12 enable enable @@ -11,10 +11,16 @@ - - - - + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/Tests/PowerSync/PowerSync.Common.Tests/Attachments/AttachmentTests.cs b/Tests/PowerSync/PowerSync.Common.Tests/Attachments/AttachmentTests.cs index af88334..9dfc49d 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/Attachments/AttachmentTests.cs +++ b/Tests/PowerSync/PowerSync.Common.Tests/Attachments/AttachmentTests.cs @@ -8,7 +8,7 @@ namespace PowerSync.Common.Tests.Attachments; using PowerSync.Common.Tests.Utils; /// -/// dotnet test -v n --framework net8.0 --filter "AttachmentTests" +/// dotnet test -v n --framework net10.0 --filter "AttachmentTests" /// [Collection("AttachmentTests")] public class AttachmentTests : IAsyncLifetime diff --git a/Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTests.cs b/Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTests.cs index 6af182e..9283bc5 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTests.cs +++ b/Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTests.cs @@ -9,7 +9,7 @@ namespace PowerSync.Common.Tests.Client; using PowerSync.Common.Tests.Utils; /// -/// dotnet test -v n --framework net8.0 --filter "PowerSyncDatabaseTests" +/// dotnet test -v n --framework net10.0 --filter "PowerSyncDatabaseTests" /// [Collection("PowerSyncDatabaseTests")] public class PowerSyncDatabaseTests : IAsyncLifetime diff --git a/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/CRUDTests.cs b/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/CRUDTests.cs index 58525fb..094a092 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/CRUDTests.cs +++ b/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/CRUDTests.cs @@ -11,7 +11,7 @@ namespace PowerSync.Common.Tests.Client.Sync; /// -/// dotnet test -v n --framework net8.0 --filter "CRUDTests" +/// dotnet test -v n --framework net10.0 --filter "CRUDTests" /// public class CRUDTests : IAsyncLifetime { diff --git a/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/StreamingSyncRetryTests.cs b/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/StreamingSyncRetryTests.cs index 659af87..ffd4b74 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/StreamingSyncRetryTests.cs +++ b/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/StreamingSyncRetryTests.cs @@ -9,7 +9,7 @@ namespace PowerSync.Common.Tests.Client.Sync; using PowerSync.Common.Tests.Utils.Sync; /// -/// dotnet test -v n --framework net8.0 --filter "StreamingSyncRetryTests" +/// dotnet test -v n --framework net10.0 --filter "StreamingSyncRetryTests" /// public class StreamingSyncRetryTests { diff --git a/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncStreamsTests.cs b/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncStreamsTests.cs index e646b07..9622581 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncStreamsTests.cs +++ b/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncStreamsTests.cs @@ -7,7 +7,7 @@ namespace PowerSync.Common.Tests.Client.Sync; using PowerSync.Common.Tests.Utils.Sync; /// -/// dotnet test -v n --framework net8.0 --filter "SyncStreamsTests" +/// dotnet test -v n --framework net10.0 --filter "SyncStreamsTests" /// public class SyncStreamsTests : IAsyncLifetime { diff --git a/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncTests.cs b/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncTests.cs index a10f3b4..09c5eff 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncTests.cs +++ b/Tests/PowerSync/PowerSync.Common.Tests/Client/Sync/SyncTests.cs @@ -6,7 +6,7 @@ namespace PowerSync.Common.Tests.Client.Sync; /// -/// dotnet test -v n --framework net8.0 --filter "SyncTests" +/// dotnet test -v n --framework net10.0 --filter "SyncTests" /// public class SyncTests : IAsyncLifetime { diff --git a/Tests/PowerSync/PowerSync.Common.Tests/DB/SchemaTests.cs b/Tests/PowerSync/PowerSync.Common.Tests/DB/SchemaTests.cs index 20c6e29..29aea94 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/DB/SchemaTests.cs +++ b/Tests/PowerSync/PowerSync.Common.Tests/DB/SchemaTests.cs @@ -7,7 +7,7 @@ namespace PowerSync.Common.Tests.DB.Schema; using PowerSync.Common.Tests; /// -/// dotnet test -v n --framework net8.0 --filter "SchemaTests" +/// dotnet test -v n --framework net10.0 --filter "SchemaTests" /// public class SchemaTests { @@ -201,7 +201,7 @@ public void AttributeParser_Logs_Test() class Invalid1 { public string id { get; set; } = ""; } [Fact] - public async void AttributeParser_InvalidSchema_1() + public async Task AttributeParser_InvalidSchema_1() { var ex = await Assert.ThrowsAsync(() => { @@ -214,7 +214,7 @@ public async void AttributeParser_InvalidSchema_1() [Table("invalid")] class Invalid2 { } [Fact] - public async void AttributeParser_InvalidSchema_2() + public async Task AttributeParser_InvalidSchema_2() { var ex = await Assert.ThrowsAsync(() => { @@ -227,7 +227,7 @@ public async void AttributeParser_InvalidSchema_2() [Table("invalid")] class Invalid3 { public int id { get; set; } } [Fact] - public async void AttributeParser_InvalidSchema_3() + public async Task AttributeParser_InvalidSchema_3() { var ex = await Assert.ThrowsAsync(() => { @@ -244,7 +244,7 @@ class Invalid4 public string id { get; set; } = ""; } [Fact] - public async void AttributeParser_InvalidSchema_4() + public async Task AttributeParser_InvalidSchema_4() { var ex = await Assert.ThrowsAsync(() => { @@ -261,7 +261,7 @@ class Invalid5 public Invalid1 invalid_type { get; set; } = default!; } [Fact] - public async void AttributeParser_InvalidSchema_5() + public async Task AttributeParser_InvalidSchema_5() { var ex = await Assert.ThrowsAsync(() => { @@ -277,7 +277,7 @@ class Invalid6 public string id { get; set; } = ""; } [Fact] - public async void AttributeParser_InvalidSchema_6() + public async Task AttributeParser_InvalidSchema_6() { var ex = await Assert.ThrowsAsync(() => { @@ -293,7 +293,7 @@ class Invalid7 public string id { get; set; } = ""; } [Fact] - public async void AttributeParser_InvalidSchema_7() + public async Task AttributeParser_InvalidSchema_7() { var ex = await Assert.ThrowsAsync(() => { diff --git a/Tests/PowerSync/PowerSync.Common.Tests/GlobalUsing.cs b/Tests/PowerSync/PowerSync.Common.Tests/GlobalUsing.cs deleted file mode 100644 index cca7737..0000000 --- a/Tests/PowerSync/PowerSync.Common.Tests/GlobalUsing.cs +++ /dev/null @@ -1 +0,0 @@ -global using FactAttribute = PowerSync.Common.Tests.Utils.FactAttribute; diff --git a/Tests/PowerSync/PowerSync.Common.Tests/MDSQLite/MDSQLiteAdapterTests.cs b/Tests/PowerSync/PowerSync.Common.Tests/MDSQLite/MDSQLiteAdapterTests.cs index 8789b7b..5efe8a7 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/MDSQLite/MDSQLiteAdapterTests.cs +++ b/Tests/PowerSync/PowerSync.Common.Tests/MDSQLite/MDSQLiteAdapterTests.cs @@ -8,7 +8,7 @@ namespace PowerSync.Common.Tests.MDSQLite; using PowerSync.Common.Utils; /// -/// dotnet test -v n --framework net8.0 --filter "MDSQLiteAdapterTests" +/// dotnet test -v n --framework net10.0 --filter "MDSQLiteAdapterTests" /// [Collection("MDSQLiteAdapterTests")] public class MDSQLiteAdapterTests diff --git a/Tests/PowerSync/PowerSync.Common.Tests/PowerSync.Common.Tests.csproj b/Tests/PowerSync/PowerSync.Common.Tests/PowerSync.Common.Tests.csproj index a153f06..c381b6a 100644 --- a/Tests/PowerSync/PowerSync.Common.Tests/PowerSync.Common.Tests.csproj +++ b/Tests/PowerSync/PowerSync.Common.Tests/PowerSync.Common.Tests.csproj @@ -1,7 +1,7 @@ - net6.0;net8.0;net9.0 + net8.0;net9.0;net10.0 12 enable enable @@ -11,14 +11,15 @@ - - - - - - - - + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/Tests/PowerSync/PowerSync.Common.Tests/Utils/FactAttribute.cs b/Tests/PowerSync/PowerSync.Common.Tests/Utils/FactAttribute.cs deleted file mode 100644 index 53c67cf..0000000 --- a/Tests/PowerSync/PowerSync.Common.Tests/Utils/FactAttribute.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace PowerSync.Common.Tests.Utils; - -[AttributeUsage(AttributeTargets.Method)] -public class FactAttribute : Xunit.FactAttribute -{ - public FactAttribute() - { - Timeout = 5000; - } -} diff --git a/Tools/Setup/Setup.csproj b/Tools/Setup/Setup.csproj index 83831b3..c5c3bf8 100644 --- a/Tools/Setup/Setup.csproj +++ b/Tools/Setup/Setup.csproj @@ -2,6 +2,6 @@ Exe - net8.0 + net10.0 - \ No newline at end of file + diff --git a/demos/CommandLine/CommandLine.csproj b/demos/CommandLine/CommandLine.csproj index c4bc4de..7cf868b 100644 --- a/demos/CommandLine/CommandLine.csproj +++ b/demos/CommandLine/CommandLine.csproj @@ -3,7 +3,7 @@ Exe 0.0.1 - net8.0;net9.0 + net8.0;net9.0;net10.0 12 enable enable @@ -12,13 +12,13 @@ - - - + + + - + diff --git a/demos/MAUITodo/MAUITodo.csproj b/demos/MAUITodo/MAUITodo.csproj index 56d224b..6d03d32 100644 --- a/demos/MAUITodo/MAUITodo.csproj +++ b/demos/MAUITodo/MAUITodo.csproj @@ -3,9 +3,10 @@ com.companyname.todo - net8.0-android;net9.0-android - $(TargetFrameworks);net8.0-windows10.0.19041.0 - $(TargetFrameworks);net8.0-ios;net8.0-maccatalyst;net9.0-ios;net9.0-maccatalyst + net9.0-android;net10.0-android + $(DefaultTargetFrameworks) + $(DefaultTargetFrameworks);net9.0-windows;net10.0-windows + $(DefaultTargetFrameworks);net9.0-ios;net9.0-maccatalyst;net10.0-ios;net10.0-maccatalyst Exe MAUITodo @@ -29,7 +30,7 @@ true true - 8.0.90 + 8.0.90 15.0 15.0 @@ -38,12 +39,6 @@ 10.0.19041.0 - - - iossimulator-x64 - true - - @@ -63,15 +58,13 @@ - - - - + + diff --git a/demos/MAUITodo/README.md b/demos/MAUITodo/README.md index ca474d8..de2762b 100644 --- a/demos/MAUITodo/README.md +++ b/demos/MAUITodo/README.md @@ -27,29 +27,29 @@ dotnet restore ### iOS ```sh -dotnet build -t:Run -f:net8.0-ios +dotnet build -t:Run -f:net10.0-ios ``` Specifyng an iOS simulator ```sh -dotnet build -t:Run -f:net8.0-ios -p:_DeviceName=:v2:udid=B1CA156A-56FC-4C3C-B35D-4BC349111FDF +dotnet build -t:Run -f:net10.0-ios -p:_DeviceName=:v2:udid=B1CA156A-56FC-4C3C-B35D-4BC349111FDF ``` ### Android ```sh -dotnet build -t:Run -f:net8.0-android +dotnet build -t:Run -f:net10.0-android ``` Specifying an Android emulator ```sh -dotnet build -t:Run -f:net8.0-android -p:_DeviceName=emulator-5554 +dotnet build -t:Run -f:net10.0-android -p:_DeviceName=emulator-5554 ``` ### MacCatalyst ```sh -dotnet build -t:Run -f:net8.0-maccatalyst +dotnet build -t:Run -f:net10.0-maccatalyst ``` diff --git a/global.json b/global.json index a2cd87e..c0c25fe 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,7 @@ { "sdk": { - "version": "9.0.200" + "version": "10.0.100", + "rollForward": "latestFeature", + "allowPrerelease": false } - } \ No newline at end of file + }