Skip to content

Commit

Permalink
- Added additional F# unit tests for good measure
Browse files Browse the repository at this point in the history
- Required putting the Target type in a separate shared library to avoid a circular dependency
- Moved Fsharp acceptance tests to different test classes to avoid affecting other tests due to the specific serializer used for F#
  • Loading branch information
nkosi23 committed Dec 11, 2024
1 parent 5217d11 commit d3b20b4
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 272 deletions.
6 changes: 5 additions & 1 deletion src/FSharpTypes/FSharpTypes.fsproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<LangVersion>8.0</LangVersion>
<TargetFrameworks>net8.0;net7.0;net9.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<Compile Include="Library.fs"/>
</ItemGroup>

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

</Project>
24 changes: 24 additions & 0 deletions src/FSharpTypes/Library.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
module FSharpTypes

open System
open System.Linq.Expressions
open Marten.Testing.Documents
open Microsoft.FSharp.Linq.RuntimeHelpers

type OrderId = Id of Guid

Expand All @@ -14,3 +17,24 @@ type RecordTypeOrderId = { Part1: string; Part2: string }

type ArbitraryClass() =
member this.Value = "ok"

let rec stripFSharpFunc (expression: Expression) =
match expression with
| :? MethodCallExpression as callExpression when callExpression.Method.Name = "ToFSharpFunc" ->
stripFSharpFunc callExpression.Arguments.[0]
| _ -> expression

let toLinqExpression expr =
expr
|> LeafExpressionConverter.QuotationToExpression
|> stripFSharpFunc
|> unbox<System.Linq.Expressions.Expression<System.Func<Target, bool>>>
let greaterThanWithFsharpDateOption =
<@ fun (o1: Target) -> o1.FSharpDateTimeOffsetOption >= Some DateTimeOffset.UtcNow @> |> toLinqExpression
let lesserThanWithFsharpDateOption = <@ (fun (o1: Target) -> o1.FSharpDateTimeOffsetOption <= Some DateTimeOffset.UtcNow ) @> |> toLinqExpression
let greaterThanWithFsharpDecimalOption = <@ (fun (o1: Target) -> o1.FSharpDecimalOption >= Some 5m ) @> |> toLinqExpression
let lesserThanWithFsharpDecimalOption = <@ (fun (o1: Target) -> o1.FSharpDecimalOption <= Some 5m ) @> |> toLinqExpression
let greaterThanWithFsharpStringOption = <@ (fun (o1: Target) -> o1.FSharpStringOption >= Some "MyString" ) @> |> toLinqExpression
let lesserThanWithFsharpStringOption = <@ (fun (o1: Target) -> o1.FSharpStringOption <= Some "MyString" ) @> |> toLinqExpression


40 changes: 34 additions & 6 deletions src/LinqTests/Acceptance/Support/DefaultQueryFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,31 @@ public class DefaultQueryFixture: TargetSchemaFixture
{
public DefaultQueryFixture()
{
Store = ProvisionStore("linq_querying", options =>
Store = ProvisionStore("linq_querying");

DuplicatedFieldStore = ProvisionStore("duplicate_fields", o =>
{
o.Schema.For<Target>()
.Duplicate(x => x.Number)
.Duplicate(x => x.Long)
.Duplicate(x => x.String)
.Duplicate(x => x.Date)
.Duplicate(x => x.Double)
.Duplicate(x => x.Flag)
.Duplicate(x => x.Color)
.Duplicate(x => x.NumberArray);
});

FSharpFriendlyStore = ProvisionStore("linq_querying", options =>
{
options.RegisterFSharpOptionValueTypes();
var serializerOptions = JsonFSharpOptions.Default().WithUnwrapOption().ToJsonSerializerOptions();
options.UseSystemTextJsonForSerialization(serializerOptions);
});


DuplicatedFieldStore = ProvisionStore("duplicate_fields", o =>
FSharpFriendlyStoreWithDuplicatedField = ProvisionStore("duplicate_fields", options =>
{
o.Schema.For<Target>()
options.Schema.For<Target>()
.Duplicate(x => x.Number)
.Duplicate(x => x.Long)
.Duplicate(x => x.String)
Expand All @@ -30,9 +44,9 @@ public DefaultQueryFixture()
.Duplicate(x => x.Color)
.Duplicate(x => x.NumberArray);

o.RegisterFSharpOptionValueTypes();
options.RegisterFSharpOptionValueTypes();
var serializerOptions = JsonFSharpOptions.Default().WithUnwrapOption().ToJsonSerializerOptions();
o.UseSystemTextJsonForSerialization(serializerOptions);
options.UseSystemTextJsonForSerialization(serializerOptions);
});

SystemTextJsonStore = ProvisionStore("stj_linq", o =>
Expand All @@ -45,5 +59,19 @@ public DefaultQueryFixture()

public DocumentStore DuplicatedFieldStore { get; set; }

public DocumentStore FSharpFriendlyStore { get; set; }
public DocumentStore FSharpFriendlyStoreWithDuplicatedField { get; set; }

public DocumentStore Store { get; set; }
}

public static class DefaultQueryFixtureExtensions
{
public static void UseFSharp(this DocumentStore store)
{
var o = store.Options;
o.RegisterFSharpOptionValueTypes();
var serializerOptions = JsonFSharpOptions.Default().WithUnwrapOption().ToJsonSerializerOptions();
o.UseSystemTextJsonForSerialization(serializerOptions);
}
}
8 changes: 1 addition & 7 deletions src/LinqTests/Acceptance/where_clauses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,6 @@ static where_clauses()
@where(x => !x.Flag == true);
@where(x => !x.Flag == false);

@where(x => x.FSharpBoolOption == FSharpOption<bool>.Some(true));
@where(x => x.FSharpBoolOption == FSharpOption<bool>.Some(false));
@where(x => x.FSharpDateOption == FSharpOption<DateTime>.Some(DateTime.Now));
@where(x => x.FSharpIntOption == FSharpOption<int>.Some(300));
@where(x => x.FSharpStringOption == FSharpOption<string>.Some("My String"));
@where(x => x.FSharpLongOption == FSharpOption<long>.Some(5_000_000));

// Comparing multiple fields
@where(x => x.Number == x.AnotherNumber);
@where(x => x.Number < x.AnotherNumber);
Expand Down Expand Up @@ -198,3 +191,4 @@ public Task with_duplicated_fields(string description)
return assertTestCase(description, Fixture.DuplicatedFieldStore);
}
}

48 changes: 48 additions & 0 deletions src/LinqTests/Acceptance/where_clauses_fsharp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Threading.Tasks;
using LinqTests.Acceptance.Support;
using Microsoft.FSharp.Core;
using Xunit.Abstractions;

namespace LinqTests.Acceptance;

public class where_clauses_fsharp: LinqTestContext<where_clauses_fsharp>
{
public where_clauses_fsharp(DefaultQueryFixture fixture, ITestOutputHelper output) : base(fixture)
{
TestOutput = output;
}

static where_clauses_fsharp()
{

@where(x => x.FSharpBoolOption == FSharpOption<bool>.Some(true));
@where(x => x.FSharpBoolOption == FSharpOption<bool>.Some(false));
@where(x => x.FSharpDateOption == FSharpOption<DateTime>.Some(DateTime.Now));
@where(x => x.FSharpIntOption == FSharpOption<int>.Some(300));
@where(x => x.FSharpStringOption == FSharpOption<string>.Some("My String"));
@where(x => x.FSharpLongOption == FSharpOption<long>.Some(5_000_000));

//Comparing options is not a valid syntax in C#, we therefore define these expressions in F#
@where(FSharpTypes.greaterThanWithFsharpDateOption);
@where(FSharpTypes.lesserThanWithFsharpDateOption);
@where(FSharpTypes.greaterThanWithFsharpStringOption);
@where(FSharpTypes.lesserThanWithFsharpStringOption);
@where(FSharpTypes.greaterThanWithFsharpDecimalOption);
@where(FSharpTypes.lesserThanWithFsharpDecimalOption);
}

[Theory]
[MemberData(nameof(GetDescriptions))]
public Task run_query(string description)
{
return assertTestCase(description, Fixture.FSharpFriendlyStore);
}

[Theory]
[MemberData(nameof(GetDescriptions))]
public Task with_duplicated_fields(string description)
{
return assertTestCase(description, Fixture.FSharpFriendlyStoreWithDuplicatedField);
}
}
5 changes: 2 additions & 3 deletions src/LinqTests/LinqTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\FSharpTypes\FSharpTypes.fsproj" />
<ProjectReference Include="..\LinqTestsTypes\LinqTestsTypes.csproj" />
<ProjectReference Include="..\Marten\Marten.csproj" />
<ProjectReference Include="..\Marten.Testing.OtherAssembly\Marten.Testing.OtherAssembly.csproj" />
<ProjectReference Include="..\Marten.Testing.ThirdAssembly\Marten.Testing.ThirdAssembly.csproj" />
Expand Down Expand Up @@ -56,9 +58,6 @@
<Compile Include="..\Marten.Testing\Documents\StringDoc.cs">
<Link>Documents\StringDoc.cs</Link>
</Compile>
<Compile Include="..\Marten.Testing\Documents\Target.cs">
<Link>Documents\Target.cs</Link>
</Compile>
<Compile Include="..\Marten.Testing\Documents\TargetIntId.cs">
<Link>Documents\TargetIntId.cs</Link>
</Compile>
Expand Down
Loading

0 comments on commit d3b20b4

Please sign in to comment.