Skip to content

Commit

Permalink
Tests are now using Util.Run
Browse files Browse the repository at this point in the history
  • Loading branch information
romfir committed Sep 26, 2023
1 parent 222b2ed commit b27552b
Show file tree
Hide file tree
Showing 21 changed files with 668 additions and 225 deletions.
3 changes: 3 additions & 0 deletions OpenApiLINQPadDriver.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeEditing/SuppressUninitializedWarningFix/Enabled/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Deps/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
9 changes: 9 additions & 0 deletions OpenApiLINQPadDriver/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;
using System.Linq;

namespace OpenApiLINQPadDriver.Extensions;
internal static class EnumerableExtensions
{
public static IEnumerable<T> AppendIf<T>(this IEnumerable<T> enumerable, bool shouldAppend, T element)
=> shouldAppend ? enumerable.Append(element) : enumerable;
}
3 changes: 1 addition & 2 deletions OpenApiLINQPadDriver/OpenApiContextDriver.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Reflection;
Expand Down
2 changes: 1 addition & 1 deletion OpenApiLINQPadDriver/OpenApiContextDriverProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ private bool GetValue(bool defaultValue, [CallerMemberName] string callerMemberN

private T GetValue<T>(T defaultValue, [CallerMemberName] string callerMemberName = "")
where T : struct, Enum
=> (T)GetValue(v => Enum.TryParse<T>(v, out var val) ? val : defaultValue, defaultValue, callerMemberName);
=> GetValue(v => Enum.TryParse<T>(v, out var val) ? val : defaultValue, defaultValue, callerMemberName);

private void SetValue<T>(T value, [CallerMemberName] string callerMemberName = "")
{
Expand Down
7 changes: 7 additions & 0 deletions OpenApiLINQPadDriver/OpenApiLINQPadDriver.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
<Description>$(AssemblyTitle).</Description>
</PropertyGroup>

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>OpenApiLINQPadDriverTests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

<PropertyGroup>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
Expand Down Expand Up @@ -70,6 +76,7 @@
<PackageReference Include="NSwag.CodeGeneration.CSharp" Version="13.20.0" />
<PackageReference Include="NSwag.Core" Version="13.20.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
<PackageReference Include="Prism.Core" Version="8.1.97" />
</ItemGroup>

<ItemGroup>
Expand Down
19 changes: 13 additions & 6 deletions OpenApiLINQPadDriver/SchemaBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using LINQPad.Extensibility.DataContext;
Expand Down Expand Up @@ -30,15 +31,15 @@ internal static List<ExplorerItem> GetSchemaAndBuildAssembly(OpenApiContextDrive
#else
var stopWatch = Stopwatch.StartNew();
#endif

var document = OpenApiDocumentHelper.GetFromUri(new Uri(openApiContextDriverProperties.OpenApiDocumentUri!));

MeasureTimeAndAddTimeExecutionExplorerItem("Downloading document");

document.SetServer(openApiContextDriverProperties.ApiUri!);

var endpointGrouping = openApiContextDriverProperties.EndpointGrouping;
var settings = CreateCsharpClientGeneratorSettings(endpointGrouping, openApiContextDriverProperties.JsonLibrary, openApiContextDriverProperties.ClassStyle,
var classStyle = openApiContextDriverProperties.ClassStyle;
var settings = CreateCsharpClientGeneratorSettings(endpointGrouping, openApiContextDriverProperties.JsonLibrary, classStyle,
openApiContextDriverProperties.GenerateSyncMethods, mainContextType);

var generator = new CSharpClientGenerator(document, settings);
Expand All @@ -47,6 +48,7 @@ internal static List<ExplorerItem> GetSchemaAndBuildAssembly(OpenApiContextDrive

MeasureTimeAndAddTimeExecutionExplorerItem("Generating NSwag classes");

//possibly this switch should be an if based on SupportsMultipleClients?
var clientSourceCode = endpointGrouping switch
{
EndpointGrouping.SingleClientFromOperationIdOperationName => ClientGenerator.SingleClientFromOperationIdOperationNameGenerator(mainContextType),
Expand All @@ -58,6 +60,7 @@ internal static List<ExplorerItem> GetSchemaAndBuildAssembly(OpenApiContextDrive

var references = openApiContextDriverProperties.GetCoreFxReferenceAssemblies()
.Append(typeof(JsonConvert).Assembly.Location) //required for code generation, otherwise NSwag will use lowest possible version 10.0.1
.AppendIf(classStyle == ClassStyle.Prism, typeof(Prism.IActiveAware).Assembly.Location)
.ToArray();

#pragma warning disable SYSLIB0044 //this is the only way to read this assembly, LINQPad does not give any other reference to it
Expand Down Expand Up @@ -130,17 +133,21 @@ void MeasureTimeAndAddTimeExecutionExplorerItem(string name)
var elapsed = stopWatch.Elapsed;
stopWatch.Restart();
#endif
File.AppendAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "log.txt"), name + " " + elapsed + Environment.NewLine);
timeExplorerItem.Children.Add(ExplorerItemHelper.CreateForElapsedTime(name, elapsed));
}
}

private static CSharpClientGeneratorSettings CreateCsharpClientGeneratorSettings(EndpointGrouping endpointGrouping, JsonLibrary jsonLibrary, ClassStyle classStyle, bool generateSyncMethods,
TypeDescriptor type)
private static CSharpClientGeneratorSettings CreateCsharpClientGeneratorSettings(EndpointGrouping endpointGrouping, JsonLibrary jsonLibrary, ClassStyle classStyle,
bool generateSyncMethods, TypeDescriptor type)
{
var (operationNameGenerator, className) = endpointGrouping switch
{
EndpointGrouping.MultipleClientsFromFirstTagAndOperationName => ((IOperationNameGenerator)new MultipleClientsFromFirstTagAndOperationNameGenerator(), "{controller}" + ClientPostFix),
EndpointGrouping.SingleClientFromOperationIdOperationName => (new SingleClientFromOperationIdOperationNameGenerator(), type.Name),
EndpointGrouping.MultipleClientsFromFirstTagAndOperationName
=> ((IOperationNameGenerator)new MultipleClientsFromFirstTagAndOperationNameGenerator(), "{controller}" + ClientPostFix),

EndpointGrouping.SingleClientFromOperationIdOperationName
=> (new SingleClientFromOperationIdOperationNameGenerator(), type.Name),
_ => throw new InvalidOperationException()
};

Expand Down
12 changes: 12 additions & 0 deletions OpenApiLINQPadDriver/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@
"Newtonsoft.Json": "10.0.1"
}
},
"Prism.Core": {
"type": "Direct",
"requested": "[8.1.97, )",
"resolved": "8.1.97",
"contentHash": "EP5zrvWddw3eSq25Y7hHnDYdmLZEC2Z/gMrvmHzUuLbitmA1UaS7wQUlSwNr9Km8lzJNCvytFnaGBEFukHgoHg=="
},
"Fluid.Core": {
"type": "Transitive",
"resolved": "2.2.15",
Expand Down Expand Up @@ -1236,6 +1242,12 @@
"Newtonsoft.Json": "10.0.1"
}
},
"Prism.Core": {
"type": "Direct",
"requested": "[8.1.97, )",
"resolved": "8.1.97",
"contentHash": "EP5zrvWddw3eSq25Y7hHnDYdmLZEC2Z/gMrvmHzUuLbitmA1UaS7wQUlSwNr9Km8lzJNCvytFnaGBEFukHgoHg=="
},
"Fluid.Core": {
"type": "Transitive",
"resolved": "2.2.15",
Expand Down
52 changes: 52 additions & 0 deletions Tests/OpenApiLINQPadDriverTests/AuthTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace OpenApiLINQPadDriverTests;
public class AuthTests : BaseDriverApiTest
{
[Theory] //todo test both global and local setter
[MemberData(nameof(EnumInlineData.Data), MemberType = typeof(EnumInlineData))]
public async Task Setting_Headers_In_PrepareRequestFunction_For_MultipleClientsFromFirstTagAndOperationName(JsonLibrary jsonLibrary, ClassStyle classStyle)
{
MapGet("Header", "/replay", "Replay", static (HttpContext context) => context.Request.Headers);
StartApi();

await ExecuteScriptAsync(
"""
var tokenValue = "fakeBearer";
this.PrepareRequestFunction = (a, requestMessage, c) =>
{
requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokenValue);
};

var replayedHeaders = await this.HeaderClient.ReplayAsync();

replayedHeaders.Should()
.Contain(h => h.Key == "Authorization" && h.Value.Any(v => v == $"Bearer {tokenValue}"));
// return 1;
""", EndpointGrouping.MultipleClientsFromFirstTagAndOperationName, jsonLibrary, classStyle);
}

[Theory] //todo test both global and local setter
[MemberData(nameof(EnumInlineData.Data), MemberType = typeof(EnumInlineData))]
public async Task Setting_Headers_In_PrepareRequestFunction_For_SingleClientFromOperationIdOperationName(JsonLibrary jsonLibrary, ClassStyle classStyle)
{
MapGet("Header", "/replay", "Replay", static (HttpContext context) => context.Request.Headers);
StartApi();

await ExecuteScriptAsync(
"""
var tokenValue = "fakeBearer";
this.PrepareRequestFunction = (a, requestMessage, c) =>
{
requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokenValue);
};

var replayedHeaders = await this.ReplayAsync();

replayedHeaders.Should()
.Contain(h => h.Key == "Authorization" && h.Value.Any(v => v == $"Bearer {tokenValue}"));

//replayedHeaders.Dump();
return replayedHeaders;
""", EndpointGrouping.SingleClientFromOperationIdOperationName, jsonLibrary, classStyle);

}
}
74 changes: 74 additions & 0 deletions Tests/OpenApiLINQPadDriverTests/CustomResponseBody.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
namespace OpenApiLINQPadDriverTests;
public class CustomResponseBody : BaseDriverApiTest
{
[Theory]
[MemberData(nameof(EnumInlineData.Data), MemberType = typeof(EnumInlineData))]
public async Task MultipleClientsFromFirstTagAndOperationName(JsonLibrary jsonLibrary, ClassStyle classStyle)
{
MapGet("CustomResponseAndRequest", "/First", "first", static ([FromBody] CustomRequest request) => new CustomResponse(request.Foo, request.Bar));
StartApi();

var requestConstructor = GetRequestCtor(classStyle);
var responseConstructor = GetResponseCtor(classStyle);

await ExecuteScriptAsync(
$"""
{nameof(CustomRequest)} request = {requestConstructor};

var response = await this.CustomResponseAndRequestClient.FirstAsync(request);
response.Should().BeEquivalentTo({responseConstructor});

""", EndpointGrouping.MultipleClientsFromFirstTagAndOperationName, jsonLibrary, classStyle);
}

[Theory]
[MemberData(nameof(EnumInlineData.Data), MemberType = typeof(EnumInlineData))]
public async Task SingleClientFromOperationIdOperationName(JsonLibrary jsonLibrary, ClassStyle classStyle)
{
MapGet("CustomResponseAndRequest", "/First", "first", static ([FromBody] CustomRequest request) => new CustomResponse(request.Foo, request.Bar));
StartApi();

var requestConstructor = GetRequestCtor(classStyle);
var responseConstructor = GetResponseCtor(classStyle);

await ExecuteScriptAsync(
$"""
{nameof(CustomRequest)} request = {requestConstructor};

var response = await this.FirstAsync(request);
response.Should().BeEquivalentTo({responseConstructor});

""", EndpointGrouping.SingleClientFromOperationIdOperationName, jsonLibrary, classStyle);
}

private record CustomResponse(string Foo, int Bar);
private record CustomRequest(string Foo, int Bar);

private static string GetResponseCtor(ClassStyle classStyle) => classStyle switch
{
ClassStyle.Poco or ClassStyle.Inpc or ClassStyle.Prism =>
"""
new CustomResponse()
{
Foo = "string",
Bar = 1
}
""",
ClassStyle.Record => "new CustomResponse(1, \"string\")",
_ => throw new InvalidOperationException()
};

private static string GetRequestCtor(ClassStyle classStyle) => classStyle switch
{
ClassStyle.Poco or ClassStyle.Inpc or ClassStyle.Prism =>
"""
new CustomRequest()
{
Foo = "string",
Bar = 1
}
""",
ClassStyle.Record => "new CustomRequest(1, \"string\")",
_ => throw new InvalidOperationException()
};
}
11 changes: 0 additions & 11 deletions Tests/OpenApiLINQPadDriverTests/LPRun/Templates/Test.linq

This file was deleted.

33 changes: 11 additions & 22 deletions Tests/OpenApiLINQPadDriverTests/OpenApiLINQPadDriverTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,42 @@
<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Deterministic>true</Deterministic>
<!--<Deterministic>true</Deterministic>-->
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
</PropertyGroup>

<ItemGroup>
<!--<PackageReference Include="FlaUI.UIA3" Version="4.0.0" />-->
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="LPRun" Version="7.8.5" />
<PackageReference Include="LINQPad.Runtime" Version="7.7.15" />
<!--possibly only on local?-->
<PackageReference Include="Meziantou.Xunit.ParallelTestFramework" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.11" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.11" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="Moq" Version="4.20.69" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PackageReference Include="xunit" Version="2.5.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<!--<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</PackageReference>-->
<!--<PackageReference Include="Xunit.StaFact" Version="1.1.11" />-->
</ItemGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<Folder Include="LPRun\Templates\" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\OpenApiLINQPadDriver\OpenApiLINQPadDriver.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="LPRun\Templates\Test.linq">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

<!--workaround-->
<!--<Target Name="TestTarget" AfterTargets="Build">
<Copy SourceFiles="$(OutputPath)\LPRun\Bin\LINQPad.Runtime.dll" DestinationFiles="$(OutputPath)\LINQPad.Runtime.dll" UseHardlinksIfPossible="true"/>
</Target>-->

</Project>
Loading

0 comments on commit b27552b

Please sign in to comment.