Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,12 @@ private SelectionSet BuildSelectionSet(
var includeFlags = new List<ulong>();
var deferUsages = new List<DeferUsage>();
var selectionSetId = ++lastId;
var alwaysIncluded = false;

foreach (var (responseName, nodes) in fieldMap)
{
includeFlags.Clear();
deferUsages.Clear();

var alwaysIncluded = false;
var first = nodes[0];
var isInternal = IsInternal(first.Node);
var hasNonDeferredNode = first.DeferUsage is null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -758,12 +758,134 @@ fragment B on Person {
""");
}

[Fact]
public async Task Complementary_Fragment_Spreads_Should_Use_Full_Fragment_When_Minimal_Is_False()
{
// arrange
var result = await ExecuteComplementaryFragmentQueryAsync(minimal: false);

// assert
result.MatchInlineSnapshot(
"""
{
"data": {
"series": [
{
"streams": [
{
"__typename": "Stream",
"id": "stream-1",
"hasDrm": true,
"title": "Stream One",
"publishedAt": "2026-01-01"
}
]
}
]
}
}
""");
}

[Fact]
public async Task Complementary_Fragment_Spreads_Should_Use_Minimal_Fragment_When_Minimal_Is_True()
{
// arrange
var result = await ExecuteComplementaryFragmentQueryAsync(minimal: true);

// assert
result.MatchInlineSnapshot(
"""
{
"data": {
"series": [
{
"streams": [
{
"__typename": "Stream",
"id": "stream-1",
"hasDrm": true
}
]
}
]
}
}
""");
}

private static async Task<IExecutionResult> ExecuteComplementaryFragmentQueryAsync(bool minimal)
{
var schema = SchemaBuilder.New()
.AddDocumentFromString(
"""
type Query {
series: [Series!]!
}

type Series {
id: ID!
streams: [Stream!]!
}

type Stream {
id: ID!
title: String
hasDrm: Boolean
publishedAt: String
}
""")
.AddResolver<Query>()
.Create();

return await schema.MakeExecutable().ExecuteAsync(
OperationRequestBuilder.New()
.SetDocument(
"""
query TestQuery($minimal: Boolean = false) {
series {
streams {
__typename
...streamFields
}
}
}

fragment streamFields on Stream {
__typename
...MinimalStream @include(if: $minimal)
...FullStream @skip(if: $minimal)
}

fragment MinimalStream on Stream {
id
hasDrm
}

fragment FullStream on Stream {
id
title
hasDrm
publishedAt
}
""")
.SetVariableValues(
$$"""
{
"minimal": {{minimal.ToString().ToLowerInvariant()}}
}
""")
.Build());
}

public sealed class Query
{
public Person Person() => new Person();

[UsePaging]
public Person[] Persons() => [new Person()];

public Series[] Series() => [new Series()];
}

public sealed class Person
Expand All @@ -772,4 +894,22 @@ public sealed class Person

public string Address { get; } = "world";
}

public sealed class Series
{
public string Id { get; } = "series-1";

public Stream[] Streams() => [new Stream()];
}

public sealed class Stream
{
public string Id { get; } = "stream-1";

public string Title { get; } = "Stream One";

public bool HasDrm { get; } = true;

public string PublishedAt { get; } = "2026-01-01";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,10 @@ public ulong CreateIncludeFlags(IVariableValueCollection variables)
{
if (includeCondition.IsIncluded(variables))
{
includeFlags |= 1ul << index++;
includeFlags |= 1ul << index;
}

index++;
}

return includeFlags;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,16 @@ private SelectionSet BuildSelectionSet(
includeFlags.Clear();
deliveryGroups.Clear();

var alwaysIncluded = false;
var first = nodes[0];
var isInternal = IsInternal(first.Node);
var hasImmediateNode = first.DeliveryGroup is null;

if (first.PathIncludeFlags > 0)
if (first.PathIncludeFlags == 0)
{
alwaysIncluded = true;
}
else
{
includeFlags.Add(first.PathIncludeFlags);
}
Expand All @@ -271,7 +276,15 @@ private SelectionSet BuildSelectionSet(
$"The syntax nodes for the response name {responseName} are not all the same.");
}

if (next.PathIncludeFlags > 0)
if (next.PathIncludeFlags == 0)
{
alwaysIncluded = true;
if (includeFlags.Count > 0)
{
includeFlags.Clear();
}
}
else if (!alwaysIncluded)
{
includeFlags.Add(next.PathIncludeFlags);
}
Expand Down
Loading
Loading