Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
14 changes: 14 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,17 @@ jobs:
config: '.markdownlint.json'
globs: |
**/*.md

- name: Setup Node
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: '24.x'

- name: Install Spectral
run: npm install --global "@stoplight/spectral-cli@${SPECTRAL_VERSION}"
env:
# renovate: datasource=npm packageName=@stoplight/spectral-cli
SPECTRAL_VERSION: '6.15.0'

- name: Run Spectral
run: spectral lint "./test/Swashbuckle.AspNetCore.IntegrationTests/snapshots/*" --display-only-failures --fail-severity error --format github-actions
1 change: 1 addition & 0 deletions .spectral.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extends: ['spectral:oas']
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="8.0.22" />
<PackageVersion Include="Microsoft.Build" Version="18.0.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="4.14.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.0" />
<PackageVersion Include="Microsoft.Kiota.Bundle" Version="1.21.0" />
<PackageVersion Include="Microsoft.OpenApi" Version="2.3.9" />
<PackageVersion Include="Microsoft.OpenApi.YamlReader" Version="2.3.9" />
<PackageVersion Include="Microsoft.Playwright" Version="1.56.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="MSBuild.ProjectCreation" Version="17.0.1" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="NJsonSchema" Version="11.5.2" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="NSwag.CodeGeneration.CSharp" Version="14.6.3" />
<PackageVersion Include="NSwag.MSBuild" Version="14.6.3" />
Expand Down
1 change: 1 addition & 0 deletions Swashbuckle.AspNetCore.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
<Project Path="test/WebSites/ReDoc/ReDoc.csproj" />
<Project Path="test/WebSites/TestFirst.IntegrationTests/TestFirst.IntegrationTests.csproj" />
<Project Path="test/WebSites/TestFirst/TestFirst.csproj" />
<Project Path="test/WebSites/TodoApp/TodoApp.csproj" />
<Project Path="test/WebSites/TopLevelSwaggerDoc/TopLevelSwaggerDoc.csproj" />
<Project Path="test/WebSites/WebApi.Aot/WebApi.Aot.csproj" />
<Project Path="test/WebSites/WebApi/WebApi.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,10 @@ private IOpenApiSchema GenerateSchemaForMember(
{
var requiredAttribute = customAttributes.OfType<RequiredAttribute>().FirstOrDefault();

var nullable = IsNullable(requiredAttribute, dataProperty, memberInfo);

if (usingAllOf)
{
// When using AllOf to extend reference schemas, we need to adjust the schema to represent
// nullability correctly as a property can't be null AND a specific type at the same time.
// See https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/3649.
if (nullable)
{
concrete.OneOf = schema.AllOf;
concrete.OneOf.Add(new OpenApiSchema { Type = JsonSchemaType.Null });
concrete.AllOf = null;
}
}
else
// "nullable" cannot be used without "type"
if (!usingAllOf)
{
var nullable = IsNullable(requiredAttribute, dataProperty, memberInfo);
SetNullable(concrete, nullable);
}

Expand Down
74 changes: 45 additions & 29 deletions test/Swashbuckle.AspNetCore.IntegrationTests/ClientGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,45 +73,61 @@ public async Task CompileAsync(string location)

public async Task<TemporaryDirectory> GenerateFromStringAsync(ClientGeneratorTool generator, string openApiDocument)
{
TemporaryDirectory project;
TemporaryDirectory project = null;

switch (generator)
try
{
switch (generator)
{
case ClientGeneratorTool.Kiota:
project = await GenerateProjectAsync(["Microsoft.Kiota.Bundle"]);
await GenerateClientFromStringWithKiotaAsync(project.Path, openApiDocument, outputHelper);
break;

case ClientGeneratorTool.NSwag:
project = await GenerateProjectAsync(["Newtonsoft.Json"]);
await GenerateClientFromStringWithNSwagAsync(project.Path, openApiDocument);
break;

default:
throw new ArgumentOutOfRangeException(nameof(generator), generator, $"The client generator tool '{generator}' is not supported.");
}
}
catch (Exception)
{
case ClientGeneratorTool.Kiota:
project = await GenerateProjectAsync(["Microsoft.Kiota.Bundle"]);
await GenerateClientFromStringWithKiotaAsync(project.Path, openApiDocument, outputHelper);
break;

case ClientGeneratorTool.NSwag:
project = await GenerateProjectAsync(["Newtonsoft.Json"]);
await GenerateClientFromStringWithNSwagAsync(project.Path, openApiDocument);
break;

default:
throw new ArgumentOutOfRangeException(nameof(generator), generator, $"The client generator tool '{generator}' is not supported.");
project?.Dispose();
throw;
}

return project;
}

public async Task<TemporaryDirectory> GenerateFromUrlAsync(ClientGeneratorTool generator, string openApiDocumentUrl)
{
TemporaryDirectory project;
TemporaryDirectory project = null;

switch (generator)
try
{
switch (generator)
{
case ClientGeneratorTool.Kiota:
project = await GenerateProjectAsync(["Microsoft.Kiota.Bundle"]);
await GenerateClientFromUrlWithKiotaAsync(project.Path, openApiDocumentUrl, outputHelper);
break;

case ClientGeneratorTool.NSwag:
project = await GenerateProjectAsync(["Newtonsoft.Json"]);
await GenerateClientFromUrlWithNSwagAsync(project.Path, openApiDocumentUrl);
break;

default:
throw new ArgumentOutOfRangeException(nameof(generator), generator, $"The client generator tool '{generator}' is not supported.");
}
}
catch (Exception)
{
case ClientGeneratorTool.Kiota:
project = await GenerateProjectAsync(["Microsoft.Kiota.Bundle"]);
await GenerateClientFromUrlWithKiotaAsync(project.Path, openApiDocumentUrl, outputHelper);
break;

case ClientGeneratorTool.NSwag:
project = await GenerateProjectAsync(["Newtonsoft.Json"]);
await GenerateClientFromUrlWithNSwagAsync(project.Path, openApiDocumentUrl);
break;

default:
throw new ArgumentOutOfRangeException(nameof(generator), generator, $"The client generator tool '{generator}' is not supported.");
project?.Dispose();
throw;
}

return project;
Expand Down Expand Up @@ -283,7 +299,7 @@ private static string GetNuGetPackageVersion(string name)
var ns = project.Root.GetDefaultNamespace();

var version = project
.Root?
.Root
.Elements(ns + "ItemGroup")
.Elements(ns + "PackageVersion")
.Select((p) =>
Expand Down
Loading
Loading