From b71344dc9fe680ba29cf685bbb694e3189d98a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20=C4=B0rgin?= Date: Sun, 18 Oct 2026 02:45:37 +0300 Subject: [PATCH 1/2] test: fourteen more declared-error doors become table rows in five new slices --- .../Common/Errors/DeclaredErrorTests.cs | 9 +++ .../LanguageModelsClientContractTests.cs | 50 -------------- .../LanguageModelsDeclaredErrors.cs | 59 +++++++++++++++++ .../OpenCodeClientContractTests.cs | 25 ------- .../OpenCodeClientDeclaredErrors.cs | 36 ++++++++++ .../PermissionsClientContractTests.cs | 26 -------- .../Permissions/PermissionsDeclaredErrors.cs | 36 ++++++++++ .../Projects/ProjectsClientContractTests.cs | 50 -------------- .../Projects/ProjectsDeclaredErrors.cs | 66 +++++++++++++++++++ .../Server/ServerClientContractTests.cs | 26 -------- .../Server/ServerDeclaredErrors.cs | 36 ++++++++++ 11 files changed, 242 insertions(+), 177 deletions(-) create mode 100644 tests/OpenCode.Sdk.Tests/LanguageModels/LanguageModelsDeclaredErrors.cs create mode 100644 tests/OpenCode.Sdk.Tests/OpenCodeClientDeclaredErrors.cs create mode 100644 tests/OpenCode.Sdk.Tests/Permissions/PermissionsDeclaredErrors.cs create mode 100644 tests/OpenCode.Sdk.Tests/Projects/ProjectsDeclaredErrors.cs create mode 100644 tests/OpenCode.Sdk.Tests/Server/ServerDeclaredErrors.cs diff --git a/tests/OpenCode.Sdk.Tests/Common/Errors/DeclaredErrorTests.cs b/tests/OpenCode.Sdk.Tests/Common/Errors/DeclaredErrorTests.cs index 54f42ac9..da82dbe9 100644 --- a/tests/OpenCode.Sdk.Tests/Common/Errors/DeclaredErrorTests.cs +++ b/tests/OpenCode.Sdk.Tests/Common/Errors/DeclaredErrorTests.cs @@ -10,6 +10,10 @@ using OpenCode.Sdk.Tests.Forms; using OpenCode.Sdk.Tests.Harness; using OpenCode.Sdk.Tests.Integrations; +using OpenCode.Sdk.Tests.LanguageModels; +using OpenCode.Sdk.Tests.Permissions; +using OpenCode.Sdk.Tests.Projects; +using OpenCode.Sdk.Tests.Server; using OpenCode.Sdk.Tests.Support; using OpenCode.Sdk.Tests.Vcs; using OpenCode.Sdk.Tests.Worktrees; @@ -29,6 +33,11 @@ .. FormsDeclaredErrors.Rows(), .. FileSystemDeclaredErrors.Rows(), .. IntegrationsDeclaredErrors.Rows(), .. VcsDeclaredErrors.Rows(), + .. LanguageModelsDeclaredErrors.Rows(), + .. OpenCodeClientDeclaredErrors.Rows(), + .. PermissionsDeclaredErrors.Rows(), + .. ProjectsDeclaredErrors.Rows(), + .. ServerDeclaredErrors.Rows(), ]; [Test] diff --git a/tests/OpenCode.Sdk.Tests/LanguageModels/LanguageModelsClientContractTests.cs b/tests/OpenCode.Sdk.Tests/LanguageModels/LanguageModelsClientContractTests.cs index a925f977..5aab4273 100644 --- a/tests/OpenCode.Sdk.Tests/LanguageModels/LanguageModelsClientContractTests.cs +++ b/tests/OpenCode.Sdk.Tests/LanguageModels/LanguageModelsClientContractTests.cs @@ -39,31 +39,6 @@ public async Task GetDefaultAsync_Should_Return_Null_When_No_Model_Is_Selected() await Assert.That(response.Default).IsNull(); } - [Test] - public async Task GetDefaultAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.LanguageModels.GetDefaultAsync()) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task GetDefaultAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.LanguageModels.GetDefaultAsync(requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } - [Test] public async Task ListModelsAsync_Should_Return_The_Typed_Models_With_Their_Location() { @@ -91,29 +66,4 @@ public async Task ListModelsAsync_Should_Return_An_Empty_List_With_Its_Location( await Assert.That(response.Models.Count).IsEqualTo(0); await Assert.That(response.Location.Directory).IsEqualTo(WireBodyData.ResolvedDirectory); } - - [Test] - public async Task ListModelsAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.LanguageModels.ListModelsAsync()) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task ListModelsAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.LanguageModels.ListModelsAsync(requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } } diff --git a/tests/OpenCode.Sdk.Tests/LanguageModels/LanguageModelsDeclaredErrors.cs b/tests/OpenCode.Sdk.Tests/LanguageModels/LanguageModelsDeclaredErrors.cs new file mode 100644 index 00000000..4fa9ecac --- /dev/null +++ b/tests/OpenCode.Sdk.Tests/LanguageModels/LanguageModelsDeclaredErrors.cs @@ -0,0 +1,59 @@ +using System.Net; +using OpenCode.Sdk.Models; +using OpenCode.Sdk.Tests.Common.Support; +using OpenCode.Sdk.Tests.Support; + +namespace OpenCode.Sdk.Tests.LanguageModels; + +public static class LanguageModelsDeclaredErrors +{ + private static readonly DeclaredErrorDoor GetDefaultDoor = new( + nameof(LanguageModelsClient.GetDefaultAsync), + "model.default", + "get", + "/api/model/default", + static async (client, options) => await client.LanguageModels.GetDefaultAsync(requestOptions: options)); + + private static readonly DeclaredErrorDoor ListModelsDoor = new( + nameof(LanguageModelsClient.ListModelsAsync), + "model.list", + "get", + "/api/model", + static async (client, options) => await client.LanguageModels.ListModelsAsync(requestOptions: options)); + + public static IEnumerable> Rows() => + [ + static () => new( + "model.default:400:InvalidRequestError", + GetDefaultDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1model~1default/get/responses/400/content/application~1json/schema"), + static () => new( + "model.default:401:UnauthorizedError", + GetDefaultDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1model~1default/get/responses/401/content/application~1json/schema"), + static () => new( + "model.list:400:InvalidRequestError", + ListModelsDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1model/get/responses/400/content/application~1json/schema"), + static () => new( + "model.list:401:UnauthorizedError", + ListModelsDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1model/get/responses/401/content/application~1json/schema"), + ]; +} diff --git a/tests/OpenCode.Sdk.Tests/OpenCodeClientContractTests.cs b/tests/OpenCode.Sdk.Tests/OpenCodeClientContractTests.cs index 822c0df1..996e93c9 100644 --- a/tests/OpenCode.Sdk.Tests/OpenCodeClientContractTests.cs +++ b/tests/OpenCode.Sdk.Tests/OpenCodeClientContractTests.cs @@ -157,31 +157,6 @@ await Assert.That(scenario.Requests.Single().RequestUri!.AbsoluteUri) .IsEqualTo("http://localhost:4096/api/location?location[directory]=%2Frepo"); } - [Test] - public async Task GetLocationAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.GetLocationAsync()) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task GetLocationAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.GetLocationAsync(requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } - [Test] public async Task GetMessageAsync_Should_Unwrap_The_Data_Envelope() { diff --git a/tests/OpenCode.Sdk.Tests/OpenCodeClientDeclaredErrors.cs b/tests/OpenCode.Sdk.Tests/OpenCodeClientDeclaredErrors.cs new file mode 100644 index 00000000..0c3455a2 --- /dev/null +++ b/tests/OpenCode.Sdk.Tests/OpenCodeClientDeclaredErrors.cs @@ -0,0 +1,36 @@ +using System.Net; +using OpenCode.Sdk.Models; +using OpenCode.Sdk.Tests.Common.Support; +using OpenCode.Sdk.Tests.Support; + +namespace OpenCode.Sdk.Tests; + +public static class OpenCodeClientDeclaredErrors +{ + private static readonly DeclaredErrorDoor GetLocationDoor = new( + nameof(OpenCodeClient.GetLocationAsync), + "location.get", + "get", + "/api/location", + static async (client, options) => await client.GetLocationAsync(requestOptions: options)); + + public static IEnumerable> Rows() => + [ + static () => new( + "location.get:400:InvalidRequestError", + GetLocationDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1location/get/responses/400/content/application~1json/schema"), + static () => new( + "location.get:401:UnauthorizedError", + GetLocationDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1location/get/responses/401/content/application~1json/schema"), + ]; +} diff --git a/tests/OpenCode.Sdk.Tests/Permissions/PermissionsClientContractTests.cs b/tests/OpenCode.Sdk.Tests/Permissions/PermissionsClientContractTests.cs index 46ed7dab..1e5f004a 100644 --- a/tests/OpenCode.Sdk.Tests/Permissions/PermissionsClientContractTests.cs +++ b/tests/OpenCode.Sdk.Tests/Permissions/PermissionsClientContractTests.cs @@ -1,5 +1,4 @@ using System.Net; -using OpenCode.Sdk.Models; using OpenCode.Sdk.Tests.Harness; using OpenCode.Sdk.Tests.Support; @@ -53,31 +52,6 @@ await Assert.That(scenario.Requests.Single().RequestUri) .IsEqualTo(new Uri("http://localhost:4096/api/permission/saved?projectID=prj_9")); } - [Test] - public async Task ListSavedAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.Permissions.ListSavedAsync()) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task ListSavedAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.Permissions.ListSavedAsync(requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } - [Test] public async Task RemoveSavedAsync_Should_Take_The_Id_As_An_Argument_On_The_204() { diff --git a/tests/OpenCode.Sdk.Tests/Permissions/PermissionsDeclaredErrors.cs b/tests/OpenCode.Sdk.Tests/Permissions/PermissionsDeclaredErrors.cs new file mode 100644 index 00000000..69c28530 --- /dev/null +++ b/tests/OpenCode.Sdk.Tests/Permissions/PermissionsDeclaredErrors.cs @@ -0,0 +1,36 @@ +using System.Net; +using OpenCode.Sdk.Models; +using OpenCode.Sdk.Tests.Common.Support; +using OpenCode.Sdk.Tests.Support; + +namespace OpenCode.Sdk.Tests.Permissions; + +public static class PermissionsDeclaredErrors +{ + private static readonly DeclaredErrorDoor ListSavedDoor = new( + nameof(PermissionsClient.ListSavedAsync), + "permission.saved.list", + "get", + "/api/permission/saved", + static async (client, options) => await client.Permissions.ListSavedAsync(requestOptions: options)); + + public static IEnumerable> Rows() => + [ + static () => new( + "permission.saved.list:400:InvalidRequestError", + ListSavedDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1permission~1saved/get/responses/400/content/application~1json/schema"), + static () => new( + "permission.saved.list:401:UnauthorizedError", + ListSavedDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1permission~1saved/get/responses/401/content/application~1json/schema"), + ]; +} diff --git a/tests/OpenCode.Sdk.Tests/Projects/ProjectsClientContractTests.cs b/tests/OpenCode.Sdk.Tests/Projects/ProjectsClientContractTests.cs index 98fc6460..77807d66 100644 --- a/tests/OpenCode.Sdk.Tests/Projects/ProjectsClientContractTests.cs +++ b/tests/OpenCode.Sdk.Tests/Projects/ProjectsClientContractTests.cs @@ -63,31 +63,6 @@ public async Task ListProjectsAsync_Should_Return_An_Empty_List() await Assert.That(response.Projects).IsEmpty(); } - [Test] - public async Task ListProjectsAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.Projects.ListProjectsAsync()) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task ListProjectsAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.Projects.ListProjectsAsync(requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } - [Test] public async Task UpdateProjectAsync_Should_Send_The_Typed_Body_And_Return_The_Updated_Project() { @@ -118,29 +93,4 @@ public async Task UpdateProjectAsync_Should_Send_An_Empty_Body_When_Omitted() await Assert.That(scenario.Requests.Single().Body).IsEqualTo("{}"); } - - [Test] - public async Task UpdateProjectAsync_Should_Throw_The_Declared_404_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.NotFound, WireBodyData.ProjectNotFoundError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.Projects.UpdateProjectAsync("prj_9")) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(404); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task UpdateProjectAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.Projects.UpdateProjectAsync("prj_1", requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } } diff --git a/tests/OpenCode.Sdk.Tests/Projects/ProjectsDeclaredErrors.cs b/tests/OpenCode.Sdk.Tests/Projects/ProjectsDeclaredErrors.cs new file mode 100644 index 00000000..a4bac985 --- /dev/null +++ b/tests/OpenCode.Sdk.Tests/Projects/ProjectsDeclaredErrors.cs @@ -0,0 +1,66 @@ +using System.Net; +using OpenCode.Sdk.Models; +using OpenCode.Sdk.Tests.Common.Support; +using OpenCode.Sdk.Tests.Support; + +namespace OpenCode.Sdk.Tests.Projects; + +public static class ProjectsDeclaredErrors +{ + private static readonly DeclaredErrorDoor ListProjectsDoor = new( + nameof(ProjectsClient.ListProjectsAsync), + "project.list", + "get", + "/api/project", + static async (client, options) => await client.Projects.ListProjectsAsync(requestOptions: options)); + + private static readonly DeclaredErrorDoor UpdateProjectPrj9Door = new( + nameof(ProjectsClient.UpdateProjectAsync), + "project.update", + "patch", + "/api/project/{projectID}", + static async (client, options) => await client.Projects.UpdateProjectAsync("prj_9", requestOptions: options)); + + private static readonly DeclaredErrorDoor UpdateProjectPrj1Door = new( + nameof(ProjectsClient.UpdateProjectAsync), + "project.update", + "patch", + "/api/project/{projectID}", + static async (client, options) => await client.Projects.UpdateProjectAsync("prj_1", requestOptions: options)); + + public static IEnumerable> Rows() => + [ + static () => new( + "project.list:400:InvalidRequestError", + ListProjectsDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1project/get/responses/400/content/application~1json/schema"), + static () => new( + "project.list:401:UnauthorizedError", + ListProjectsDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1project/get/responses/401/content/application~1json/schema"), + static () => new( + "project.update:404:ProjectNotFoundError", + UpdateProjectPrj9Door, + HttpStatusCode.NotFound, + WireBodyData.ProjectNotFoundError, + "ProjectNotFoundError", + typeof(ProjectNotFoundError), + "#/paths/~1api~1project~1{projectID}/patch/responses/404/content/application~1json/schema/anyOf/0"), + static () => new( + "project.update:401:UnauthorizedError", + UpdateProjectPrj1Door, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1project~1{projectID}/patch/responses/401/content/application~1json/schema"), + ]; +} diff --git a/tests/OpenCode.Sdk.Tests/Server/ServerClientContractTests.cs b/tests/OpenCode.Sdk.Tests/Server/ServerClientContractTests.cs index 1717e600..6aaf12bd 100644 --- a/tests/OpenCode.Sdk.Tests/Server/ServerClientContractTests.cs +++ b/tests/OpenCode.Sdk.Tests/Server/ServerClientContractTests.cs @@ -1,5 +1,4 @@ using System.Net; -using OpenCode.Sdk.Models; using OpenCode.Sdk.Tests.Support; namespace OpenCode.Sdk.Tests.Server; @@ -17,29 +16,4 @@ public async Task GetInfoAsync_Should_Return_The_Typed_Urls() await Assert.That(scenario.Requests.Single().RequestUri).IsEqualTo(new Uri("http://localhost:4096/api/info")); await Assert.That(scenario.Requests.Single().Method).IsEqualTo(HttpMethod.Get); } - - [Test] - public async Task GetInfoAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.Server.GetInfoAsync()) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task GetInfoAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.Server.GetInfoAsync(OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } } diff --git a/tests/OpenCode.Sdk.Tests/Server/ServerDeclaredErrors.cs b/tests/OpenCode.Sdk.Tests/Server/ServerDeclaredErrors.cs new file mode 100644 index 00000000..e5e95762 --- /dev/null +++ b/tests/OpenCode.Sdk.Tests/Server/ServerDeclaredErrors.cs @@ -0,0 +1,36 @@ +using System.Net; +using OpenCode.Sdk.Models; +using OpenCode.Sdk.Tests.Common.Support; +using OpenCode.Sdk.Tests.Support; + +namespace OpenCode.Sdk.Tests.Server; + +public static class ServerDeclaredErrors +{ + private static readonly DeclaredErrorDoor GetInfoDoor = new( + nameof(ServerClient.GetInfoAsync), + "server.info", + "get", + "/api/info", + static async (client, options) => await client.Server.GetInfoAsync(options)); + + public static IEnumerable> Rows() => + [ + static () => new( + "server.info:400:InvalidRequestError", + GetInfoDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1info/get/responses/400/content/application~1json/schema"), + static () => new( + "server.info:401:UnauthorizedError", + GetInfoDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1info/get/responses/401/content/application~1json/schema"), + ]; +} From e223af22b64d09201340b6d963a918beee67885d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20=C4=B0rgin?= Date: Sun, 18 Oct 2026 02:54:59 +0300 Subject: [PATCH 2/2] test: the clone baseline takes the conversions' regrouped pairs and drops the stale ones, and the tests ceiling falls to 5% --- docs/engineering/quality-gates.md | 2 +- .../Clones/CloneDetectorTests.cs | 2 +- .../Support/CloneScenario.cs | 2 +- .../OpenCode.Sdk.Tools/Clones/CloneScopes.cs | 4 +- tools/jscpd/tests.baseline.json | 46 ++++++------------- 5 files changed, 18 insertions(+), 38 deletions(-) diff --git a/docs/engineering/quality-gates.md b/docs/engineering/quality-gates.md index bbc2ba2f..5dbe7ca8 100644 --- a/docs/engineering/quality-gates.md +++ b/docs/engineering/quality-gates.md @@ -248,7 +248,7 @@ The lint job runs `dotnet run --file tools/opencode-tool.cs -- verify-clones`: t `tools/jscpd/`, installed with the machine's Bun from its own lockfile, at a 50-token minimum over four scopes. Hand-written `src/`, `tools/` and `tests/` are gated against the committed baselines in `tools/jscpd/`: a clone a baseline does not hold fails the job, `tools/` also fails above 3% -duplicated lines, and `tests/` above 5.5%. The tests ceiling is the measurement plus 0.25 points, +duplicated lines, and `tests/` above 5%. The tests ceiling is the measurement plus 0.25 points, rounded up to the next 0.5%, and it only ever falls: a change that removes test clones lowers it to that value when it is lower than the current ceiling. Generated output is reported, not gated. The generator's manifest decides which `src/` files are generated, so the split diff --git a/tests/OpenCode.Sdk.Tools.Tests/Clones/CloneDetectorTests.cs b/tests/OpenCode.Sdk.Tools.Tests/Clones/CloneDetectorTests.cs index 8b20b91f..116229fb 100644 --- a/tests/OpenCode.Sdk.Tools.Tests/Clones/CloneDetectorTests.cs +++ b/tests/OpenCode.Sdk.Tools.Tests/Clones/CloneDetectorTests.cs @@ -97,7 +97,7 @@ public async Task Arguments_Should_Gate_Tests_Against_Its_Baseline_And_The_Thres var arguments = CloneDetector.Arguments(Scope("tests"), Config, updateBaseline: false); await Assert.That(arguments).IsEquivalentTo( - [CloneDetector.RunnerPath, "tests", "--config", Config, FailOnEmpty, "--baseline", "tools/jscpd/tests.baseline.json", Fingerprints, "--threshold", "5.5"], CollectionOrdering.Matching); + [CloneDetector.RunnerPath, "tests", "--config", Config, FailOnEmpty, "--baseline", "tools/jscpd/tests.baseline.json", Fingerprints, "--threshold", "5"], CollectionOrdering.Matching); } [Test] diff --git a/tests/OpenCode.Sdk.Tools.Tests/Support/CloneScenario.cs b/tests/OpenCode.Sdk.Tools.Tests/Support/CloneScenario.cs index 255e254d..6721c1f8 100644 --- a/tests/OpenCode.Sdk.Tools.Tests/Support/CloneScenario.cs +++ b/tests/OpenCode.Sdk.Tools.Tests/Support/CloneScenario.cs @@ -227,7 +227,7 @@ public CloneScenario WithRun(string scope, int exitCode = 0, int clones = 0, int tokens.AddRange(!_baselines || updateBaseline ? ["--update-baseline"] : scope switch { "tools" => ["--fail-on-new-clones", "--threshold", "3"], - "tests" => ["--fail-on-new-clones", "--threshold", "5.5"], + "tests" => ["--fail-on-new-clones", "--threshold", "5"], _ => ["--fail-on-new-clones"], }); } diff --git a/tools/OpenCode.Sdk.Tools/Clones/CloneScopes.cs b/tools/OpenCode.Sdk.Tools/Clones/CloneScopes.cs index 64f958cf..96e049ef 100644 --- a/tools/OpenCode.Sdk.Tools/Clones/CloneScopes.cs +++ b/tools/OpenCode.Sdk.Tools/Clones/CloneScopes.cs @@ -2,7 +2,7 @@ namespace OpenCode.Sdk.Tools.Clones; /// /// The clone gate's fixed scopes. Hand-written SDK code, the tool and the tests are gated against -/// committed baselines, the tool also against a 3% ceiling and the tests against a 5.5% ceiling that +/// committed baselines, the tool also against a 3% ceiling and the tests against a 5% ceiling that /// only falls; generated output is reported only, because an emitter's template repeats on purpose. /// internal static class CloneScopes @@ -15,7 +15,7 @@ internal static class CloneScopes [ new("src", "src", CloneScopeFilter.Generated, [], DetectorFolder + "/src.baseline.json", Threshold: null), new("tools", "tools", CloneScopeFilter.None, [DetectorFolder + "/**"], DetectorFolder + "/tools.baseline.json", Threshold: 3m), - new("tests", "tests", CloneScopeFilter.None, [], DetectorFolder + "/tests.baseline.json", Threshold: 5.5m), + new("tests", "tests", CloneScopeFilter.None, [], DetectorFolder + "/tests.baseline.json", Threshold: 5m), new("generated", "src", CloneScopeFilter.HandWritten, [], Baseline: null, Threshold: null), ]; } diff --git a/tools/jscpd/tests.baseline.json b/tools/jscpd/tests.baseline.json index b27a8d58..2e6eb413 100644 --- a/tools/jscpd/tests.baseline.json +++ b/tools/jscpd/tests.baseline.json @@ -5,12 +5,10 @@ "00342d539c7b0bf9": 1, "01417d72ad1b123c": 1, "01b50a050ff5cb57": 1, - "02d421174ecab381": 1, "030445ef25b69be7": 1, "030b9be65c2b2225": 1, "032245d683ed5066": 1, "0341de072c280e0e": 2, - "0395a00037a917b8": 1, "03f0da59b2a78217": 1, "059dcd6e0a494338": 1, "060d60ecdc435655": 1, @@ -44,13 +42,11 @@ "10003a5ebdb1faa9": 1, "1035e50fc18d0089": 1, "10ae734f6c09cd4d": 1, - "10e65016e739cc98": 1, "113cc076f3fdaac2": 1, "116939c0012f36db": 1, "118f6000645c9441": 1, "11bf507ea1387ebc": 1, "11e6156620b2560f": 1, - "122567aef968827c": 1, "125ee26a2b20b167": 1, "13211ae1b77d178e": 1, "139a4466552f7894": 1, @@ -60,7 +56,6 @@ "14f3cf459e8fd59e": 1, "14f4b594979ef4be": 1, "15f72a1f46f3211c": 1, - "16abac940e1137ea": 1, "171c27993e2f8380": 1, "17537e2a94773132": 1, "18b20d9b8321f296": 1, @@ -106,6 +101,7 @@ "29e2d3f4c6ced0a9": 1, "2a2ea864e10f10a0": 1, "2bef63e501d18ed2": 1, + "2c808c41bd208339": 1, "2cce43ebc1614860": 1, "2cd64c5a0bd7b129": 1, "2d01f1bea1f9ea7e": 1, @@ -123,7 +119,6 @@ "30c6457c90ba767e": 1, "31079b601cabad85": 1, "325aedadc9c51610": 1, - "32813351a4512ab1": 1, "32a53e20ee7c711b": 1, "34812987b8a4a722": 1, "350995582d58fa70": 1, @@ -133,7 +128,6 @@ "37e7cf7d45ffba52": 1, "381a9b351137f9ca": 1, "3882460d4ac3aa39": 1, - "38da175c3f3263ab": 1, "395bcea3b3a0f37b": 1, "3a31a52bec51fb1d": 1, "3a87c8a45e85cc43": 1, @@ -163,12 +157,9 @@ "4372939ffb05b447": 1, "442313bd038e5928": 1, "44259b731f378b4b": 1, - "46838631f0c798bd": 1, "479fdc49d7da2d6e": 1, "47c6dec036a94d60": 1, "47d341670708569a": 1, - "4889b45748ec205e": 1, - "48c32c7eaffb48de": 1, "48c83373cc2d7d8d": 1, "492f8010b57edfcf": 1, "49432516d8bdce34": 1, @@ -176,10 +167,9 @@ "4a0c669010ce3ce8": 1, "4a6d9e9744168596": 1, "4a9224a89db2ae4d": 1, - "4aa9c49e32bbfeda": 1, "4aaa9d6fd117dacd": 1, + "4b508c95dae33199": 1, "4b7b758e168bab6a": 1, - "4b8e5202cfba2e1a": 1, "4ba929d61eb40117": 1, "4c3f0df710b0e5d4": 1, "4ccca39676639bbf": 1, @@ -217,13 +207,14 @@ "5c956c46330fb9c3": 1, "5cb2e7e9a7e11a37": 1, "5d5ef92942ea8a4b": 1, + "5dfe7c29964e0ff3": 1, "5e13371fd2b2249a": 1, "5f5853703072392b": 1, "5f76879862027b63": 1, - "5fbb8861f104dd86": 1, "5fc40824eff9ddbe": 1, "5fce21230688a4cc": 1, "5fea5678f28a491f": 1, + "618f44054dfd6c48": 1, "61e86a6218889bef": 1, "620efa04847bf466": 1, "621414e77f14a6ae": 1, @@ -255,7 +246,6 @@ "6ce49ad646f4a55d": 1, "6d2315e42adf5051": 1, "6d348ca9871cd43b": 1, - "6d93ccc53ef1ac50": 1, "6e28853461e0f610": 1, "6e3557268fbb6d7b": 1, "6e7989c97054cdff": 1, @@ -265,13 +255,13 @@ "6ee3e67f6a10362e": 1, "6efa92670898d4c4": 1, "7015815c99e52132": 1, - "706c80b864b19699": 1, "70b546f19e61694e": 1, "70e78f68bbb3f8b1": 1, "710c8abd019e2510": 1, "714507ef060378c2": 1, "7194ef683df831bc": 1, "729ecae0417d0f29": 1, + "72eabca9a45fa549": 1, "731af5ab97f97192": 1, "7348221dfe25068d": 1, "7383f1c75dba03da": 1, @@ -292,16 +282,14 @@ "7b16854634035afe": 1, "7b29c98f174c4aad": 1, "7b66455caf235ad7": 1, - "7ba3d80569d00387": 1, "7baca2d0e7c78a56": 1, - "7bdaf1f09dad093c": 1, "7c4d439b46ebc8bf": 1, "7cb3773f240a7d3b": 1, "7da92939d4cdca00": 1, "7e09a30a918c9d2f": 1, + "7e575a6c2aeb18ac": 1, "7ea14f75d7412427": 1, "7eda9e729d5869ca": 1, - "7ee9b7831ad8eeb9": 1, "7f8b8b1b7f8ac7c9": 1, "7ffcd9e9160f6b45": 1, "80cc7036ff095cb9": 1, @@ -314,7 +302,6 @@ "82d68551f5be56b4": 1, "83cf50adb5c58985": 1, "84029d744b2215c7": 1, - "8458e7946245ca5d": 1, "852958b905b8447d": 1, "852e00262bbefd12": 1, "859240ba1081004a": 1, @@ -326,11 +313,13 @@ "882a97e633e8c29d": 1, "8845f6d375146134": 1, "88490cc5463a3f5b": 1, + "88fe42638778bf29": 1, "8990b0dcf557805f": 1, "89b40759e47ca8db": 1, "8a46989d4cc28dc2": 1, "8a7412eb78a37817": 1, "8a7e47959ada7043": 1, + "8ac8ae90b684d355": 1, "8adcbd3f74c61e25": 1, "8d130dcf8156d446": 1, "8dbef398f2f6ca1a": 1, @@ -358,7 +347,6 @@ "96af7cbd3e81daa0": 1, "9720751d6958956a": 1, "97413e8ff5b212d1": 1, - "985a8783503aefa6": 1, "98c9c3613c3d13da": 1, "98cf46d5ad809549": 1, "99234a03fbba27b8": 1, @@ -372,10 +360,10 @@ "9c209e8b6e1de814": 1, "9cb8a77612db0cc1": 1, "9cfd4908ab13a49c": 1, + "9d1edf488b5b1757": 1, "9e3047781f98341c": 1, "9e6b559433dd1ad6": 1, "9ef5a8b0fb2c88e7": 1, - "9f37b8cd6d068f2b": 1, "9fafa1f7c850803c": 1, "a184ce7305097ded": 1, "a26cf9c1d71dd814": 1, @@ -391,15 +379,13 @@ "a7842c59f67aee3e": 1, "a7ce419852c3f4bb": 1, "a888b3cdad3d452d": 1, - "a90556221babeb5a": 1, "aa6af3c307cb3b1b": 1, "aa8c5d1539d3f39d": 1, + "aaa0d8768f696d3d": 1, "aac0860cac7db3e7": 1, "ab7663e0d5d61f22": 1, "abde2f4fe3b18cbc": 1, - "ad4e14f46a1fa4de": 1, "ad57d9f03fc15ff1": 1, - "adb8f429521df254": 1, "aeab9ff4f97a36dc": 1, "aed35329e94d587d": 1, "af1f63f59181ebb2": 1, @@ -407,8 +393,8 @@ "aff1b8c4442aff99": 1, "b03618789a68ee62": 1, "b04ce5425f684986": 1, - "b05721f4644d20a0": 1, "b0dcb57bb0a78e76": 1, + "b1154606320ddcc5": 1, "b11e207acaec82c8": 1, "b17bbc10f934e336": 1, "b26ec09aa9c7d788": 1, @@ -455,7 +441,6 @@ "c6cce4bd6bf12d59": 1, "c99b81e4ed3d76fb": 1, "c99b9aa8b9c89f27": 1, - "c9bbce25ca3ab0c1": 1, "ca23d20b55a208df": 1, "ca52433f79ca9adf": 1, "cb72f4a5d460e4a8": 1, @@ -467,7 +452,6 @@ "ce8da66742f7122d": 1, "ced268f3432a0391": 1, "ceed549c863ce378": 1, - "cf8f8d9f44328f15": 1, "d13f1005c59d1243": 1, "d20c4d175159aa90": 1, "d342abdc73d730f0": 1, @@ -491,6 +475,7 @@ "de1435ae5e214376": 1, "de25b177ad221b80": 1, "df712485fc9d33c5": 1, + "e0a48a326a297525": 1, "e17ab17b76a1e87f": 1, "e22e40dfd5665fc6": 1, "e241bd99b28fc221": 1, @@ -521,13 +506,11 @@ "ee052f70f2294a6c": 1, "ee1129d359884ce0": 1, "ee67ec3f21f2f9ce": 1, - "ee87169143e7aa75": 1, "ef106fb1d88f9f46": 1, "ef308469d0166e41": 1, "efef2b484435e6b7": 1, "f05e80092b0c0382": 1, "f102cbf1fab8a3d9": 1, - "f176cdac923927ee": 1, "f1812b941eb02542": 1, "f1f7493a31b45480": 1, "f23a5dc8edef52e2": 1, @@ -548,18 +531,15 @@ "f668e8d378c310b8": 1, "f742e38e8b79f879": 1, "f79fd5643e4c8d70": 1, - "f7da06bb4a76e08f": 1, + "f805f925827d9e12": 1, "f86d15fdd5782fbd": 1, - "f87f93239913891b": 1, "f92cfe72d5df13f4": 1, "f963eb3d6a7fe548": 1, "f97e3c6571c051bf": 1, "f981c9a75c497712": 1, - "faf56416bef9aae6": 1, "fc541ae4aa953e03": 1, "fd0c45c2afe9457e": 1, "fd0d3c8ea8788bd8": 1, - "fd4fcd6fb9ff2850": 1, "fd70d83572dba2c6": 1, "ff3cf605f2c42eb9": 1, "ff6242fa9aa38b74": 1,