Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1509,6 +1509,9 @@ record response {
}
```

A case may name a proto-bound record. Its payload is that record's model, which
converts with the record's own converter.

Python represents a protobuf oneof-backed variant as a union of slotted case
dataclasses. Each case contains its payload in a `value` field. For example, the
variant above generates `OutcomeSuccess(value)` and `OutcomeFailure(value)`. The
Expand Down
11 changes: 8 additions & 3 deletions advanced/samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,18 @@ crate omits from the API of a resource method's request is left out of the
model. nexgen ignores the directives that it doesn't know yet, such as
`@nexus.varargs` and `@nexus.close`.

Python and TypeScript don't generate the service. They panic on the read item, a
`oneof` of proto-bound records, and Python can't import the protos. .NET types
each case of the read item as its proto class.
Some of the output doesn't type-check. Python imports the Stream protos from
`temporalio`, which doesn't have them, so basedpyright skips the service.
TypeScript passes a `number` where a resource method's proto request wants a
`Long`. So `tsc` skips the service, but the test still checks its models.

- WIT: [`inputs/stream-service.wit`](inputs/stream-service.wit)
- .NET: [`dotnet/wit/stream-service/`](dotnet/wit/stream-service/),
[`dotnet/tests/StreamServiceChecks.cs`](dotnet/tests/StreamServiceChecks.cs)
- Python: [`python/wit/stream_service/`](python/wit/stream_service/)
- TypeScript:
[`typescript/wit/stream-service/`](typescript/wit/stream-service/),
[`typescript/tests/stream-service.test.ts`](typescript/tests/stream-service.test.ts)

## Supporting files

Expand Down
53 changes: 53 additions & 0 deletions advanced/samples/dotnet/tests/StreamServiceChecks.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
extern alias Streams;

using System.Linq;
using Temporalio.Converters;
using Xunit;
using static Nexgen.DotNetExamples.Tests.TransferTypeTestSupport;
using StreamServiceExample = Streams::Temporalio.Workflows;
using WireReadRecordsResponse = Streams::Temporalio.Api.StreamService.V1.ReadRecordsResponse;
using WireStreamRecord = Streams::Temporalio.Api.Stream.V1.StreamRecord;

namespace Nexgen.DotNetExamples.Tests
{
Expand All @@ -18,5 +22,54 @@ public void StreamWithItsOwnFieldNameRoundTrips()

Assert.Equal("stream-1", decoded.StreamValue.Id);
}

// A data item's body goes through the payload converter of the sample assembly, which a
// test can't set. The TypeScript test covers data items.
[Fact]
public void ReadItemsRoundTripAsTheirRecords()
{
var model = new StreamServiceExample.ReadRecordsResponse(new[]
{
new StreamServiceExample.StreamRecord
{
Item = new StreamServiceExample.StreamItem.Superseded(
new StreamServiceExample.Supersession("workflow-1", new long[] { 7 })),
Offset = 2,
},
new StreamServiceExample.StreamRecord
{
Item = new StreamServiceExample.StreamItem.Close(
new StreamServiceExample.StreamClose
{
Status = StreamServiceExample.StreamCloseStatus
.StreamCloseStatusCompleted,
}),
Offset = 3,
},
});

var wire = Assert.IsType<WireReadRecordsResponse>(
CreateSdkConverter(typeof(StreamServiceExample.ReadRecordsResponse))
.ToTransferType(model));
Assert.Equal(
new[]
{
WireStreamRecord.ItemOneofCase.Superseded,
WireStreamRecord.ItemOneofCase.Close,
},
wire.Records.Select(record => record.ItemCase));

var decoded = FromPayload<StreamServiceExample.ReadRecordsResponse>(ToPayload(model));
var superseded = Assert.IsType<StreamServiceExample.StreamItem.Superseded>(
decoded.Records[0].Item);
Assert.Equal("workflow-1", superseded.Value.ProducerId);
Assert.Equal(new long[] { 7 }, superseded.Value.FailedTasks);
var close = Assert.IsType<StreamServiceExample.StreamItem.Close>(
decoded.Records[1].Item);
Assert.Equal(
StreamServiceExample.StreamCloseStatus.StreamCloseStatusCompleted,
close.Value.Status);
Assert.Equal(3, decoded.Records[1].Offset);
}
}
}
Loading
Loading