ObjectListFilter filter values to target type coercion#589
Merged
Conversation
Test Results 3 files 3 suites 10m 16s ⏱️ Results for commit 47cf92e. ♻️ This comment has been updated with latest results. |
xperiandri
commented
Jul 9, 2026
- Moved filter operators and LINQ logic to ObjectListFilterModule.fs - Added `TypeCoercion.fs` for automatic filter value coercion (`Guid`, `DateTime`, F# DUs, etc.) - Introduced `FilterValueCoercer` and extended `ObjectListFilterLinqOptions` for custom coercion - Centralized filter suffix constants in `FilterSuffixConstants.fs` - Updated `SchemaDefinitions.fs` to use new suffix constants - Added `vtryFind` and `vtryPick` utilities for arrays/lists in `Extensions.fs` - Improved code style, documentation, and function signatures
Replaces custom value coercers with 'System.Text.Json'-based coercion in 'ObjectListFilter', supporting advanced scenarios like F# DUs and CLR enums via 'JsonSerializerOptions'. Updates 'ObjectListFilterLinqOptions' to accept 'JsonSerializerOptions'. Refactors 'TypeCoercion' module to use JSON serialization/deserialization for all type conversions. Updates filter application logic and expands the test suite with new files to cover a wide range of coercion scenarios. Updates documentation and usage examples accordingly.
* Added bug report for InputObject array type mismatch with analysis and test cases * Added type coercion guide for ObjectListFilter with usage and API docs * Introduced format-changed-files.ps1 to batch-format changed F# files via Fantomas * Updated schema snapshots for relay-style connections and new scalars * Refactored field_aliases.fsx for relay-style friends connection * Optimized TypeCoercion.fs to use Utf8JsonWriter for value coercion * Added prompt template for automated PR/issue description generation
Updated all string comparison operations in `ObjectListFilter` and filter parsing logic to use `StringComparer.CurrentCulture` or `StringComparer.CurrentCultureIgnoreCase` instead of `Ordinal`/`OrdinalIgnoreCase`. Adjusted related test expectations to match. This ensures string-based filters now respect the current culture's case rules.
c882576 to
2b531ac
Compare
e1fc28f to
01fb5ee
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces automatic coercion of ObjectListFilter primitive values to the target CLR property types (e.g., Guid, date/time types, enums, and F# DUs) during LINQ filter application, and adds a dedicated test suite to validate coercion behavior.
Changes:
- Added
TypeCoercionmiddleware helper to coerceObjectListFiltervalues based on reflected entity property types (including option/voption unwrapping and enumerable element coercion). - Refactored/moved ObjectListFilter LINQ implementation into
ObjectListFilterModule.fsand extendedObjectListFilterLinqOptionsto carryJsonSerializerOptions. - Added comprehensive coercion unit/integration tests and test categorization traits for LINQ/ObjectListFilter.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/FSharp.Data.GraphQL.Tests/TestAttributes.fs | Adds shared xUnit trait constants for categorizing tests. |
| tests/FSharp.Data.GraphQL.Tests/SelectLinqTests.fs | Adds LINQ category trait to existing LINQ tests. |
| tests/FSharp.Data.GraphQL.Tests/ObjectListFilter/TypeCoercionValueTests.fs | New unit tests for primitive/value coercion via STJ. |
| tests/FSharp.Data.GraphQL.Tests/ObjectListFilter/TypeCoercionTests.Common.fs | New shared test types/data and helpers for coercion scenarios. |
| tests/FSharp.Data.GraphQL.Tests/ObjectListFilter/TypeCoercionFilterTests.fs | New integration-style tests validating coercion through ObjectListFilter.ApplyTo. |
| tests/FSharp.Data.GraphQL.Tests/ObjectListFilter/ObjectListFilterLinqTests.fs | Moves/renames module and adds traits for categorization. |
| tests/FSharp.Data.GraphQL.Tests/ObjectListFilter/ObjectListFilterLinqGenerateTests.fs | Moves/renames module and adds traits for categorization. |
| tests/FSharp.Data.GraphQL.Tests/FSharp.Data.GraphQL.Tests.fsproj | Updates compile includes for moved/new test files. |
| src/FSharp.Data.GraphQL.Shared/Helpers/Extensions.fs | Adds Array/List.vtryFind and vtryPick helpers used by coercion. |
| src/FSharp.Data.GraphQL.Server.Middleware/TypeSystemExtensions.fs | Removes unused opens (cleanup). |
| src/FSharp.Data.GraphQL.Server.Middleware/TypeCoercion.fs | New module implementing filter/value coercion. |
| src/FSharp.Data.GraphQL.Server.Middleware/SchemaDefinitions.fs | Minor doc tweak for ObjectListFilter description string. |
| src/FSharp.Data.GraphQL.Server.Middleware/ObjectListFilterModule.fs | New module containing LINQ translation + ApplyTo extension with coercion. |
| src/FSharp.Data.GraphQL.Server.Middleware/ObjectListFilter.fs | Extends LINQ options to include JSON options; removes embedded LINQ implementation. |
| src/FSharp.Data.GraphQL.Server.Middleware/FSharp.Data.GraphQL.Server.Middleware.fsproj | Adds new middleware source files to compilation. |
|
|
||
| let hasEqualityOperator (``type`` : Type) = | ||
| ``type``.GetMethods (BindingFlags.Public ||| BindingFlags.Static) | ||
| |> Seq.exists (fun m -> m.Name = " op_Equality") |
| let enumerableQueryType = typedefof<EnumerableQuery<_>> | ||
|
|
||
| let apply (options : ObjectListFilterLinqOptions<'T, 'D>) (filter : ObjectListFilter) (query : IQueryable<'T>) = | ||
| let isEnumerableQuery = query.GetType().GetGenericTypeDefinition () = enumerableQueryType |
Comment on lines
+282
to
+286
| match getCollectionInstanceContainsMethod memberType with | ||
| | ValueNone -> | ||
| let enumerableContains = getEnumerableContainsMethod valueType | ||
| Expression.Call (enumerableContains, castedMember, Expression.Constant (normalizedValue)) | ||
| | ValueSome instanceContainsMethod -> Expression.Call (castedMember, instanceContainsMethod, Expression.Constant (normalizedValue)) |
MykytaHoncharov
approved these changes
Jul 9, 2026
xperiandri
added a commit
that referenced
this pull request
Jul 10, 2026
xperiandri
added a commit
that referenced
this pull request
Jul 10, 2026
xperiandri
added a commit
that referenced
this pull request
Jul 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.