diff --git a/src/CookieCrumble/src/CookieCrumble.HotChocolate/Extensions/SnapshotExtensions.cs b/src/CookieCrumble/src/CookieCrumble.HotChocolate/Extensions/SnapshotExtensions.cs
index b81a9c9eda0..238b1ddb904 100644
--- a/src/CookieCrumble/src/CookieCrumble.HotChocolate/Extensions/SnapshotExtensions.cs
+++ b/src/CookieCrumble/src/CookieCrumble.HotChocolate/Extensions/SnapshotExtensions.cs
@@ -24,34 +24,6 @@ public static void MatchSnapshot(
postFix,
formatter: CoreFormatters.PlainText);
- ///
- /// Matches a snapshot of an execution result, merging an incrementally delivered
- /// (@defer/@stream) response into its final aggregated form. The snapshot
- /// is identical whether the transport delivered the response across several payloads or
- /// as a single bundled payload, so it does not depend on delivery timing.
- ///
- public static void MatchAggregatedSnapshot(
- this IExecutionResult? value,
- string? postFix = null)
- => Snapshot.Match(
- value,
- postFix,
- formatter: SnapshotValueFormatters.ExecutionResultAggregated);
-
- ///
- /// Markdown counterpart of : matches a markdown
- /// snapshot of an execution result, merging an incrementally delivered
- /// (@defer/@stream) response into its final aggregated form so the snapshot
- /// does not depend on whether the transport delivered it incrementally or bundled.
- ///
- public static void MatchAggregatedMarkdownSnapshot(
- this IExecutionResult? value,
- object? postFix = null,
- string? extension = null)
- => Snapshot.Create(postFix?.ToString(), extension)
- .Add(value, formatter: SnapshotValueFormatters.ExecutionResultAggregated)
- .MatchMarkdown();
-
public static Snapshot AddResult(
this Snapshot snapshot,
IExecutionResult result,
diff --git a/src/CookieCrumble/src/CookieCrumble.HotChocolate/Formatters/ExecutionResultSnapshotValueFormatter.cs b/src/CookieCrumble/src/CookieCrumble.HotChocolate/Formatters/ExecutionResultSnapshotValueFormatter.cs
index 4937768fca0..2bd5aabd618 100644
--- a/src/CookieCrumble/src/CookieCrumble.HotChocolate/Formatters/ExecutionResultSnapshotValueFormatter.cs
+++ b/src/CookieCrumble/src/CookieCrumble.HotChocolate/Formatters/ExecutionResultSnapshotValueFormatter.cs
@@ -4,10 +4,11 @@
using CookieCrumble.Formatters;
using HotChocolate;
using HotChocolate.Execution;
+using static CookieCrumble.HotChocolate.Formatters.StableSnapshotHelpers;
namespace CookieCrumble.HotChocolate.Formatters;
-internal sealed class ExecutionResultSnapshotValueFormatter(bool alwaysAggregate = false)
+internal sealed class ExecutionResultSnapshotValueFormatter
: SnapshotValueFormatter
{
protected override void Format(IBufferWriter snapshot, IExecutionResult value)
@@ -18,7 +19,7 @@ protected override void Format(IBufferWriter snapshot, IExecutionResult va
}
else
{
- FormatStreamAsync(snapshot, (IResponseStream)value, alwaysAggregate).Wait();
+ FormatStreamAsync(snapshot, (IResponseStream)value).Wait();
}
}
@@ -34,7 +35,7 @@ protected override void FormatMarkdown(IBufferWriter snapshot, IExecutionR
{
snapshot.Append("```text");
snapshot.AppendLine();
- FormatStreamAsync(snapshot, (IResponseStream)value, alwaysAggregate).Wait();
+ FormatStreamAsync(snapshot, (IResponseStream)value).Wait();
}
snapshot.AppendLine();
@@ -42,65 +43,239 @@ protected override void FormatMarkdown(IBufferWriter snapshot, IExecutionR
snapshot.AppendLine();
}
- private static async Task FormatStreamAsync(
+ private static Task FormatStreamAsync(IBufferWriter snapshot, IResponseStream stream)
+ // Only @defer/@stream responses carry the incremental-delivery envelope. Other
+ // streams (subscriptions, batches) are sequences of independent results and are
+ // written out verbatim, one payload after another.
+ => stream.Kind is ExecutionResultKind.DeferredResult
+ ? FormatIncrementalAsync(snapshot, stream)
+ : FormatEventStreamAsync(snapshot, stream);
+
+ private static async Task FormatEventStreamAsync(IBufferWriter snapshot, IResponseStream stream)
+ {
+ await foreach (var result in stream.ReadResultsAsync().ConfigureAwait(false))
+ {
+ snapshot.Append(result.ToJson());
+ snapshot.AppendLine();
+ }
+ }
+
+ // Reconstructs a single, delivery-order-independent view of an incrementally
+ // delivered (@defer/@stream) response: the initial payload's non-protocol
+ // fields plus the `pending`, `incremental`, and `completed` entries collected
+ // across every payload and ordered by `id`. The snapshot is identical whether
+ // the transport bundled the response into one payload or split it across several.
+ private static async Task FormatIncrementalAsync(
IBufferWriter snapshot,
- IResponseStream stream,
- bool alwaysAggregate)
+ IResponseStream stream)
{
- var docs = new List();
- JsonResultPatcher? patcher = null;
- var first = true;
+ var accumulator = new StreamAccumulator();
- try
+ // StreamAccumulator deep-clones every element it retains, so each parsed
+ // document is only needed for the duration of its AddPayload call and can be
+ // disposed immediately afterwards.
+ await foreach (var result in stream.ReadResultsAsync().ConfigureAwait(false))
{
- await foreach (var queryResult in stream.ReadResultsAsync().ConfigureAwait(false))
- {
- if (first)
- {
- first = false;
+ using var document = JsonDocument.Parse(result.ToJson());
+ accumulator.AddPayload(document.RootElement);
+ }
- // When aggregating, the initial payload seeds the patcher regardless of
- // whether more payloads follow. This normalizes a response delivered as a
- // single bundled payload to the same merged form as an incrementally
- // delivered one, so the snapshot is independent of delivery batching.
- if (alwaysAggregate || (queryResult.HasNext ?? false))
- {
- var doc = JsonDocument.Parse(queryResult.ToJson());
- docs.Add(doc);
+ await using var writer = new Utf8JsonWriter(snapshot, IndentedWriterOptions);
+ WriteEnvelope(writer, accumulator);
+ writer.Flush();
+ snapshot.AppendLine();
+ }
- patcher = new JsonResultPatcher();
- patcher.SetResponse(doc);
- continue;
- }
- }
+ private static void WriteEnvelope(Utf8JsonWriter writer, StreamAccumulator accumulator)
+ {
+ writer.WriteStartObject();
- if (patcher is null)
+ // The initial payload's non-protocol fields (`data`, `errors`, `extensions`) in
+ // their original order; the incremental-delivery fields are rebuilt below.
+ if (accumulator.InitialPayload is { ValueKind: JsonValueKind.Object } initial)
+ {
+ foreach (var property in initial.EnumerateObject())
+ {
+ if (IsStreamField(property.Name))
{
- snapshot.Append(queryResult.ToJson());
- snapshot.AppendLine();
+ continue;
}
- else
- {
- var doc = JsonDocument.Parse(queryResult.ToJson());
- docs.Add(doc);
- patcher.ApplyPatch(doc);
+ writer.WritePropertyName(property.Name);
+ property.Value.WriteTo(writer);
+ }
+ }
+
+ WritePending(writer, accumulator.PendingById);
+ WriteIncremental(writer, accumulator.IncrementalEntries);
+ WriteCompleted(writer, accumulator.CompletedEntries);
+
+ writer.WriteBoolean("hasNext", false);
+
+ writer.WriteEndObject();
+ }
+
+ private static void WritePending(
+ Utf8JsonWriter writer,
+ Dictionary pendingById)
+ {
+ if (pendingById.Count == 0)
+ {
+ return;
+ }
+
+ var pending = pendingById.Values.ToList();
+ pending.Sort(static (x, y) => CompareIds(x.Id, y.Id));
+
+ writer.WritePropertyName("pending");
+ writer.WriteStartArray();
+
+ foreach (var entry in pending)
+ {
+ writer.WriteStartObject();
+ writer.WriteString("id", entry.Id);
+ writer.WritePropertyName("path");
+ entry.Path.WriteTo(writer);
+
+ if (!string.IsNullOrEmpty(entry.Label))
+ {
+ writer.WriteString("label", entry.Label);
+ }
+
+ writer.WriteEndObject();
+ }
+
+ writer.WriteEndArray();
+ }
+
+ private static void WriteIncremental(
+ Utf8JsonWriter writer,
+ List entries)
+ {
+ if (entries.Count == 0)
+ {
+ return;
+ }
+
+ // Group by `id` so a stream delivered across several payloads collapses into a
+ // single entry, independent of how many frames the transport used.
+ var order = new List();
+ var byId = new Dictionary>();
+
+ foreach (var entry in entries)
+ {
+ if (!byId.TryGetValue(entry.Id, out var group))
+ {
+ group = [];
+ byId.Add(entry.Id, group);
+ order.Add(entry.Id);
+ }
+
+ group.Add(entry);
+ }
+
+ order.Sort(CompareIds);
+
+ writer.WritePropertyName("incremental");
+ writer.WriteStartArray();
+
+ foreach (var id in order)
+ {
+ var group = byId[id];
+
+ writer.WriteStartObject();
+ writer.WriteString("id", id);
+
+ if (group.FirstOrDefault(e => e.SubPath is not null)?.SubPath is { } subPath)
+ {
+ writer.WritePropertyName("subPath");
+ subPath.WriteTo(writer);
+ }
+
+ if (group.Any(e => e.Items is not null))
+ {
+ writer.WritePropertyName("items");
+ writer.WriteStartArray();
+ foreach (var entry in group)
+ {
+ if (entry.Items is { } items)
+ {
+ foreach (var item in items.EnumerateArray())
+ {
+ item.WriteTo(writer);
+ }
+ }
}
+ writer.WriteEndArray();
+ }
+ else if (group.FirstOrDefault(e => e.Data is not null)?.Data is { } data)
+ {
+ writer.WritePropertyName("data");
+ data.WriteTo(writer);
}
- if (patcher is not null)
+ WriteMergedErrors(writer, group);
+
+ writer.WriteEndObject();
+ }
+
+ writer.WriteEndArray();
+ }
+
+ private static void WriteCompleted(
+ Utf8JsonWriter writer,
+ List entries)
+ {
+ if (entries.Count == 0)
+ {
+ return;
+ }
+
+ var completed = entries.ToList();
+ completed.Sort(static (x, y) => CompareIds(x.Id, y.Id));
+
+ writer.WritePropertyName("completed");
+ writer.WriteStartArray();
+
+ foreach (var entry in completed)
+ {
+ writer.WriteStartObject();
+ writer.WriteString("id", entry.Id);
+
+ if (entry.Errors is { } errors)
{
- patcher.WriteResponse(snapshot);
- snapshot.AppendLine();
+ writer.WritePropertyName("errors");
+ errors.WriteTo(writer);
}
+
+ writer.WriteEndObject();
}
- finally
+
+ writer.WriteEndArray();
+ }
+
+ private static void WriteMergedErrors(Utf8JsonWriter writer, List group)
+ {
+ if (!group.Any(e => e.Errors is not null))
{
- foreach (var doc in docs)
+ return;
+ }
+
+ writer.WritePropertyName("errors");
+ writer.WriteStartArray();
+
+ foreach (var entry in group)
+ {
+ if (entry.Errors is { } errors)
{
- doc.Dispose();
+ foreach (var error in errors.EnumerateArray())
+ {
+ error.WriteTo(writer);
+ }
}
}
+
+ writer.WriteEndArray();
}
}
diff --git a/src/CookieCrumble/src/CookieCrumble.HotChocolate/Formatters/SnapshotValueFormatters.cs b/src/CookieCrumble/src/CookieCrumble.HotChocolate/Formatters/SnapshotValueFormatters.cs
index b231a702801..cdea4bbc282 100644
--- a/src/CookieCrumble/src/CookieCrumble.HotChocolate/Formatters/SnapshotValueFormatters.cs
+++ b/src/CookieCrumble/src/CookieCrumble.HotChocolate/Formatters/SnapshotValueFormatters.cs
@@ -10,9 +10,6 @@ public static class SnapshotValueFormatters
public static ISnapshotValueFormatter ExecutionResult { get; } =
new ExecutionResultSnapshotValueFormatter();
- public static ISnapshotValueFormatter ExecutionResultAggregated { get; } =
- new ExecutionResultSnapshotValueFormatter(alwaysAggregate: true);
-
public static ISnapshotValueFormatter ExecutionResultStable { get; } =
new StableExecutionResultSnapshotValueFormatter();
diff --git a/src/HotChocolate/Core/test/Execution.Tests/DeferReferenceTests.cs b/src/HotChocolate/Core/test/Execution.Tests/DeferReferenceTests.cs
index 3eff7f17581..5518ebe3bd7 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/DeferReferenceTests.cs
+++ b/src/HotChocolate/Core/test/Execution.Tests/DeferReferenceTests.cs
@@ -34,7 +34,7 @@ ... @defer {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
///
@@ -232,7 +232,7 @@ ... @defer {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
// ========================================================================
@@ -430,7 +430,7 @@ ... @defer {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
///
@@ -513,7 +513,7 @@ ... @defer {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
// ========================================================================
@@ -670,7 +670,7 @@ ... on Hero @defer {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
///
diff --git a/src/HotChocolate/Core/test/Execution.Tests/DeferTests.cs b/src/HotChocolate/Core/test/Execution.Tests/DeferTests.cs
index b001a64cc2a..29513fc1bc5 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/DeferTests.cs
+++ b/src/HotChocolate/Core/test/Execution.Tests/DeferTests.cs
@@ -25,7 +25,7 @@ ... @defer {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
[Fact]
@@ -50,7 +50,7 @@ ... @defer {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
[Fact]
@@ -72,7 +72,7 @@ ... @defer(label: "abc") {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
[Fact]
@@ -149,7 +149,7 @@ fragment Foo on Query {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
[Fact]
@@ -176,7 +176,7 @@ ... @defer {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
[Fact]
@@ -200,7 +200,7 @@ fragment Foo on Query {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
[Fact]
@@ -286,7 +286,7 @@ ... @defer {
.Build(),
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
[Fact]
@@ -349,7 +349,7 @@ ... @defer {
.Build(),
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
[Fact]
@@ -382,7 +382,7 @@ ... @defer {
.Build(),
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedMarkdownSnapshot();
+ Assert.IsType(result).MatchMarkdownSnapshot();
}
private class StateRequestInterceptor : DefaultHttpRequestInterceptor
diff --git a/src/HotChocolate/Core/test/Execution.Tests/StreamTests.cs b/src/HotChocolate/Core/test/Execution.Tests/StreamTests.cs
index ab181bb66ee..fd1321b6b30 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/StreamTests.cs
+++ b/src/HotChocolate/Core/test/Execution.Tests/StreamTests.cs
@@ -30,7 +30,7 @@ persons @stream {
}",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedSnapshot();
+ Assert.IsType(result).MatchSnapshot();
}
[Fact]
@@ -55,7 +55,7 @@ ... @defer {
}",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedSnapshot();
+ Assert.IsType(result).MatchSnapshot();
}
[Fact]
@@ -76,7 +76,7 @@ persons @stream(initialCount: 1) {
}",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedSnapshot();
+ Assert.IsType(result).MatchSnapshot();
}
[Fact]
@@ -97,7 +97,7 @@ persons @stream(initialCount: 7) {
}",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedSnapshot();
+ Assert.IsType(result).MatchSnapshot();
}
[Fact]
@@ -120,7 +120,7 @@ persons @stream(label: "abc") {
""",
TestContext.Current.CancellationToken);
- Assert.IsType(result).MatchAggregatedSnapshot();
+ Assert.IsType(result).MatchSnapshot();
}
[Fact]
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Deduplicates_List_Fields_In_Initial_Payload.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Deduplicates_List_Fields_In_Initial_Payload.md
index 98b60c5c29b..6cff9811935 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Deduplicates_List_Fields_In_Initial_Payload.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Deduplicates_List_Fields_In_Initial_Payload.md
@@ -6,20 +6,75 @@
"hero": {
"friends": [
{
- "id": "friend-1",
- "name": "Han"
+ "id": "friend-1"
},
{
- "id": "friend-2",
- "name": "Leia"
+ "id": "friend-2"
},
{
- "id": "friend-3",
- "name": "C-3PO"
+ "id": "friend-3"
}
]
}
- }
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": [
+ "hero",
+ "friends",
+ 0
+ ]
+ },
+ {
+ "id": "3",
+ "path": [
+ "hero",
+ "friends",
+ 1
+ ]
+ },
+ {
+ "id": "4",
+ "path": [
+ "hero",
+ "friends",
+ 2
+ ]
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "name": "Han"
+ }
+ },
+ {
+ "id": "3",
+ "data": {
+ "name": "Leia"
+ }
+ },
+ {
+ "id": "4",
+ "data": {
+ "name": "C-3PO"
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ },
+ {
+ "id": "3"
+ },
+ {
+ "id": "4"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Defer_Fragment_With_Error.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Defer_Fragment_With_Error.md
index 9b3863248ec..0170da62e79 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Defer_Fragment_With_Error.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Defer_Fragment_With_Error.md
@@ -4,10 +4,40 @@
{
"data": {
"hero": {
- "id": "hero-1",
- "errorField": null
+ "id": "hero-1"
}
- }
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": [
+ "hero"
+ ]
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "errorField": null
+ },
+ "errors": [
+ {
+ "message": "resolver error",
+ "path": [
+ "hero",
+ "errorField"
+ ]
+ }
+ ]
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Defer_Fragment_With_Errors_On_Top_Level_Query_Field.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Defer_Fragment_With_Errors_On_Top_Level_Query_Field.md
index e6affe7312b..45715d2b419 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Defer_Fragment_With_Errors_On_Top_Level_Query_Field.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Defer_Fragment_With_Errors_On_Top_Level_Query_Field.md
@@ -2,9 +2,39 @@
```text
{
- "data": {
- "a": null
- }
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": []
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "a": null
+ },
+ "errors": [
+ {
+ "message": "Cannot return null for non-nullable field.",
+ "path": [
+ "a",
+ "nonNullErrorField"
+ ],
+ "extensions": {
+ "code": "HC0018"
+ }
+ }
+ ]
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Emits_Children_Of_Empty_Defer_Fragment.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Emits_Children_Of_Empty_Defer_Fragment.md
index 3f6957bcec3..b1180fb7eee 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Emits_Children_Of_Empty_Defer_Fragment.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.Emits_Children_Of_Empty_Defer_Fragment.md
@@ -4,10 +4,31 @@
{
"data": {
"hero": {
- "id": "hero-1",
- "name": "Luke"
+ "id": "hero-1"
}
- }
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": [
+ "hero"
+ ]
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "name": "Luke"
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.InlineFragment_Defer_With_TypeCondition.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.InlineFragment_Defer_With_TypeCondition.md
index ad4fb3ae36c..82c842d9d72 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.InlineFragment_Defer_With_TypeCondition.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferReferenceTests.InlineFragment_Defer_With_TypeCondition.md
@@ -4,10 +4,31 @@
{
"data": {
"hero": {
- "id": "hero-1",
- "name": "Luke"
+ "id": "hero-1"
}
- }
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": [
+ "hero"
+ ]
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "name": "Luke"
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Single_Defer.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Single_Defer.md
index 6efc6e6bfde..1be6d535c07 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Single_Defer.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Single_Defer.md
@@ -3,10 +3,30 @@
```text
{
"data": {
- "ensureState": {
- "state": "state 123"
+ "ensureState": {}
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": [
+ "ensureState"
+ ]
}
- }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "state": "state 123"
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Single_Defer_2.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Single_Defer_2.md
index d5f10272be4..d500667d0c9 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Single_Defer_2.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Single_Defer_2.md
@@ -2,11 +2,29 @@
```text
{
- "data": {
- "ensureState": {
- "state": "state 123"
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": []
}
- }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "ensureState": {
+ "state": "state 123"
+ }
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Stacked_Defer.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Stacked_Defer.md
index 7392a71cb38..60ac60fae53 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Stacked_Defer.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Stacked_Defer.md
@@ -2,11 +2,42 @@
```text
{
- "data": {
- "ensureState": {
- "state": "state 123"
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": []
+ },
+ {
+ "id": "3",
+ "path": [
+ "ensureState"
+ ]
}
- }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "ensureState": {}
+ }
+ },
+ {
+ "id": "3",
+ "data": {
+ "state": "state 123"
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ },
+ {
+ "id": "3"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Stacked_Defer_2.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Stacked_Defer_2.md
index 20f6822686e..5759f4f7e96 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Stacked_Defer_2.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.Ensure_GlobalState_Is_Passed_To_DeferContext_Stacked_Defer_2.md
@@ -2,13 +2,58 @@
```text
{
- "data": {
- "e": {
- "more": {
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": []
+ },
+ {
+ "id": "3",
+ "path": [
+ "e"
+ ]
+ },
+ {
+ "id": "4",
+ "path": [
+ "e",
+ "more"
+ ]
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "e": {}
+ }
+ },
+ {
+ "id": "3",
+ "data": {
+ "more": {}
+ }
+ },
+ {
+ "id": "4",
+ "data": {
"stuff": "state 123"
}
}
- }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ },
+ {
+ "id": "3"
+ },
+ {
+ "id": "4"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer.md
index 6660699b0bb..17ba210f21f 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer.md
@@ -2,11 +2,29 @@
```text
{
- "data": {
- "person": {
- "id": "UGVyc29uOjE="
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": []
}
- }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "person": {
+ "id": "UGVyc29uOjE="
+ }
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer_Label_Set_To_abc.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer_Label_Set_To_abc.md
index f506c45d484..8f9b491a176 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer_Label_Set_To_abc.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer_Label_Set_To_abc.md
@@ -2,11 +2,30 @@
```text
{
- "data": {
- "person": {
- "id": "UGVyc29uOjE="
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": [],
+ "label": "abc"
}
- }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "person": {
+ "id": "UGVyc29uOjE="
+ }
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer_Nested.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer_Nested.md
index 212b0c67482..fe0a14e2dd8 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer_Nested.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.FragmentSpread_Defer_Nested.md
@@ -2,12 +2,44 @@
```text
{
- "data": {
- "person": {
- "id": "UGVyc29uOjE=",
- "name": "Pascal"
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": []
+ },
+ {
+ "id": "3",
+ "path": [
+ "person"
+ ]
}
- }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "person": {
+ "id": "UGVyc29uOjE="
+ }
+ }
+ },
+ {
+ "id": "3",
+ "data": {
+ "name": "Pascal"
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ },
+ {
+ "id": "3"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer.md
index 203b8a7163f..873c24d68d9 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer.md
@@ -2,11 +2,29 @@
```text
{
- "data": {
- "person": {
- "id": "UGVyc29uOjE="
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": []
}
- }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "person": {
+ "id": "UGVyc29uOjE="
+ }
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer_Label_Set_To_abc.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer_Label_Set_To_abc.md
index 2539516c9f4..78a31aa2471 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer_Label_Set_To_abc.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer_Label_Set_To_abc.md
@@ -2,11 +2,30 @@
```text
{
- "data": {
- "person": {
- "id": "UGVyc29uOjE="
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": [],
+ "label": "abc"
}
- }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "person": {
+ "id": "UGVyc29uOjE="
+ }
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer_Nested.md b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer_Nested.md
index 84c20b20a12..f4c6bd26ca4 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer_Nested.md
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/DeferTests.InlineFragment_Defer_Nested.md
@@ -2,12 +2,44 @@
```text
{
- "data": {
- "person": {
- "id": "UGVyc29uOjE=",
- "name": "Pascal"
+ "data": {},
+ "pending": [
+ {
+ "id": "2",
+ "path": []
+ },
+ {
+ "id": "3",
+ "path": [
+ "person"
+ ]
}
- }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "person": {
+ "id": "UGVyc29uOjE="
+ }
+ }
+ },
+ {
+ "id": "3",
+ "data": {
+ "name": "Pascal"
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ },
+ {
+ "id": "3"
+ }
+ ],
+ "hasNext": false
}
```
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream.snap b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream.snap
index 4611896538f..4cbfe726e13 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream.snap
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream.snap
@@ -13,7 +13,26 @@
{
"id": "UGVyc29uOjQ="
}
- ],
- "wait": true
- }
+ ]
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": []
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "wait": true
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_InitialCount_Exceeds_Total_Count.snap b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_InitialCount_Exceeds_Total_Count.snap
index 4611896538f..4cbfe726e13 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_InitialCount_Exceeds_Total_Count.snap
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_InitialCount_Exceeds_Total_Count.snap
@@ -13,7 +13,26 @@
{
"id": "UGVyc29uOjQ="
}
- ],
- "wait": true
- }
+ ]
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": []
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "wait": true
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_InitialCount_Set_To_1.snap b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_InitialCount_Set_To_1.snap
index 4611896538f..4cbfe726e13 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_InitialCount_Set_To_1.snap
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_InitialCount_Set_To_1.snap
@@ -13,7 +13,26 @@
{
"id": "UGVyc29uOjQ="
}
- ],
- "wait": true
- }
+ ]
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": []
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "wait": true
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_Label_Set_To_abc.snap b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_Label_Set_To_abc.snap
index 4611896538f..4cbfe726e13 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_Label_Set_To_abc.snap
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_Label_Set_To_abc.snap
@@ -13,7 +13,26 @@
{
"id": "UGVyc29uOjQ="
}
- ],
- "wait": true
- }
+ ]
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": []
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "wait": true
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ }
+ ],
+ "hasNext": false
}
diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_Nested_Defer.snap b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_Nested_Defer.snap
index 0aa5b70503c..e4d80f4b65a 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_Nested_Defer.snap
+++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/StreamTests.Stream_Nested_Defer.snap
@@ -2,11 +2,45 @@
"data": {
"personNodes": {
"nodes": [
- {
- "name": "Pascal"
- }
+ {}
]
+ }
+ },
+ "pending": [
+ {
+ "id": "2",
+ "path": []
},
- "wait": true
- }
+ {
+ "id": "3",
+ "path": [
+ "personNodes",
+ "nodes",
+ 0
+ ]
+ }
+ ],
+ "incremental": [
+ {
+ "id": "2",
+ "data": {
+ "wait": true
+ }
+ },
+ {
+ "id": "3",
+ "data": {
+ "name": "Pascal"
+ }
+ }
+ ],
+ "completed": [
+ {
+ "id": "2"
+ },
+ {
+ "id": "3"
+ }
+ ],
+ "hasNext": false
}