Skip to content

Commit 616d62a

Browse files
committed
fixup! ObjectListFilter filter values to target type coercion (#589)
1 parent 5f932d9 commit 616d62a

4 files changed

Lines changed: 67 additions & 15 deletions

File tree

src/FSharp.Data.GraphQL.Server.Middleware/FSharp.Data.GraphQL.Server.Middleware.fsproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>-->
1515
</PropertyGroup>
1616

17+
<ItemGroup Label="InternalsVisibleTo">
18+
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
19+
<_Parameter1>FSharp.Data.GraphQL.Tests</_Parameter1>
20+
</AssemblyAttribute>
21+
</ItemGroup>
22+
1723
<ItemGroup>
1824
<PackageReference Include="FSharp.Control.Reactive" />
1925
<PackageReference Include="System.Reactive" />

src/FSharp.Data.GraphQL.Server.Middleware/ObjectListFilterModule.fs

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -195,25 +195,36 @@ module ObjectListFilter =
195195
|> Seq.head
196196

197197
/// Maps an IComparer to a StringComparison value.
198-
/// Returns ValueNone for null or Ordinal comparers (use default Expression.Equal path).
199-
let private comparerToStringComparison (comparer : IComparer) =
198+
/// Returns ValueNone for null or unsupported comparers.
199+
let internal comparerToStringComparison (comparer : IComparer) =
200200
match comparer with
201201
| null -> ValueNone
202202
| :? StringComparer as sc ->
203-
if obj.ReferenceEquals (sc, StringComparer.OrdinalIgnoreCase) then
204-
ValueSome StringComparison.OrdinalIgnoreCase
205-
elif obj.ReferenceEquals (sc, StringComparer.InvariantCultureIgnoreCase) then
206-
ValueSome StringComparison.InvariantCultureIgnoreCase
207-
elif obj.ReferenceEquals (sc, StringComparer.CurrentCultureIgnoreCase) then
208-
ValueSome StringComparison.CurrentCultureIgnoreCase
209-
elif obj.ReferenceEquals (sc, StringComparer.Ordinal) then
210-
ValueSome StringComparison.Ordinal
211-
elif obj.ReferenceEquals (sc, StringComparer.InvariantCulture) then
212-
ValueSome StringComparison.InvariantCulture
213-
elif obj.ReferenceEquals (sc, StringComparer.CurrentCulture) then
214-
ValueSome StringComparison.CurrentCulture
203+
let mutable isOrdinalIgnoreCase = false
204+
205+
if StringComparer.IsWellKnownOrdinalComparer (sc, &isOrdinalIgnoreCase) then
206+
if isOrdinalIgnoreCase then
207+
ValueSome StringComparison.OrdinalIgnoreCase
208+
else
209+
ValueSome StringComparison.Ordinal
215210
else
216-
ValueNone
211+
let mutable compareInfo = Unchecked.defaultof<Globalization.CompareInfo>
212+
let mutable compareOptions = Globalization.CompareOptions.None
213+
214+
if StringComparer.IsWellKnownCultureAwareComparer (sc, &compareInfo, &compareOptions) then
215+
let isCurrentCulture = compareInfo.Equals Globalization.CultureInfo.CurrentCulture.CompareInfo
216+
let isInvariantCulture = compareInfo.Equals Globalization.CultureInfo.InvariantCulture.CompareInfo
217+
218+
match compareOptions with
219+
| Globalization.CompareOptions.None when isCurrentCulture -> ValueSome StringComparison.CurrentCulture
220+
| Globalization.CompareOptions.IgnoreCase when isCurrentCulture ->
221+
ValueSome StringComparison.CurrentCultureIgnoreCase
222+
| Globalization.CompareOptions.None when isInvariantCulture -> ValueSome StringComparison.InvariantCulture
223+
| Globalization.CompareOptions.IgnoreCase when isInvariantCulture ->
224+
ValueSome StringComparison.InvariantCultureIgnoreCase
225+
| _ -> ValueNone
226+
else
227+
ValueNone
217228
| _ -> ValueNone
218229

219230
/// Gets the type from a MemberInfo (PropertyInfo or FieldInfo).

tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
<Compile Include="SelectLinqTests.fs" />
7878
<Compile Include="ObjectListFilter\ObjectListFilterLinqTests.fs" />
7979
<Compile Include="ObjectListFilter\ObjectListFilterLinqGenerateTests.fs" />
80+
<Compile Include="ObjectListFilter\ObjectListFilterComparerMappingTests.fs" />
8081
<Compile Include="ObjectListFilter\TypeCoercionTests.Common.fs" />
8182
<Compile Include="ObjectListFilter\TypeCoercionValueTests.fs" />
8283
<Compile Include="ObjectListFilter\TypeCoercionFilterTests.fs" />
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[<Xunit.Trait (Tests.TraitType.Category, Tests.TraitName.Linq)>]
2+
[<Xunit.Trait (Tests.TraitType.Category, Tests.TraitName.ObjectListFilter)>]
3+
module FSharp.Data.GraphQL.Tests.ObjectListFilter.ComparerMapping.Tests
4+
5+
open System
6+
open System.Collections
7+
open Xunit
8+
open FSharp.Data.GraphQL.Server.Middleware
9+
10+
[<Fact>]
11+
let ``comparerToStringComparison maps well-known StringComparer instances`` () =
12+
let testCases =
13+
[
14+
(StringComparer.OrdinalIgnoreCase :> IComparer, StringComparison.OrdinalIgnoreCase)
15+
(StringComparer.InvariantCultureIgnoreCase :> IComparer, StringComparison.InvariantCultureIgnoreCase)
16+
(StringComparer.CurrentCultureIgnoreCase :> IComparer, StringComparison.CurrentCultureIgnoreCase)
17+
(StringComparer.Ordinal :> IComparer, StringComparison.Ordinal)
18+
(StringComparer.InvariantCulture :> IComparer, StringComparison.InvariantCulture)
19+
(StringComparer.CurrentCulture :> IComparer, StringComparison.CurrentCulture)
20+
]
21+
22+
for comparer, expected in testCases do
23+
let actual = ObjectListFilter.comparerToStringComparison comparer |> wantValueSome
24+
actual |> equals expected
25+
26+
[<Fact>]
27+
let ``comparerToStringComparison returns ValueNone for unsupported comparers`` () =
28+
let customComparer =
29+
{ new IComparer with
30+
member _.Compare (_, _) = 0
31+
}
32+
33+
ObjectListFilter.comparerToStringComparison null |> wantValueNone
34+
ObjectListFilter.comparerToStringComparison customComparer |> wantValueNone

0 commit comments

Comments
 (0)