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
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Cucumber.Messages
namespace Cucumber.Messages.Specs
{
internal class CucumberMessageEnumConverter<T> : JsonConverter<T> where T : struct, Enum
{
private readonly Dictionary<T, string> _enumToString = new Dictionary<T, string>();
private readonly Dictionary<string, T> _stringToEnum = new Dictionary<string, T>();
private readonly Dictionary<T, string> _enumToString = new();
private readonly Dictionary<string, T> _stringToEnum = new();

protected internal CucumberMessageEnumConverter()
{
Expand Down
17 changes: 17 additions & 0 deletions dotnet/Cucumber.Messages.Specs/MessageToNdjsonWriterSUT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Io.Cucumber.Messages.Types;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cucumber.Messages.Specs
{
internal class MessageToNdjsonWriterSUT : MessageToNdjsonWriter
{
public MessageToNdjsonWriterSUT(Stream stream) : base(stream, (StreamWriter streamWriter, Envelope envelope) => streamWriter.Write(NdjsonSerializer.Serialize(envelope)))
{
}
}
}
16 changes: 16 additions & 0 deletions dotnet/Cucumber.Messages.Specs/NdJsonMessageReaderSUT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cucumber.Messages.Specs
{
internal class NdjsonMessageReaderSUT : NdjsonMessageReader
{
public NdjsonMessageReaderSUT(Stream inputStream) : base(inputStream, (string line) => NdjsonSerializer.Deserialize(line))
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@
using System;
using System.Text.Json;

namespace Cucumber.Messages
namespace Cucumber.Messages.Specs
{
/// <summary>
/// When using System.Text.Json to serialize a Cucumber Message Envelope, the following serialization options are used.
/// Consumers of Cucumber.Messages should use these options, or their serialization library's equivalent options.
/// These options should work with System.Text.Json v6 or above.
/// </summary>
public class NdjsonSerializer
{
private static Lazy<JsonSerializerOptions> _jsonOptions = new Lazy<JsonSerializerOptions>(() =>
private static readonly Lazy<JsonSerializerOptions> _jsonOptions = new(() =>
{
var options = new JsonSerializerOptions();
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
Expand Down
12 changes: 6 additions & 6 deletions dotnet/Cucumber.Messages.Specs/NdjsonStreamSerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class NdjsonStreamSerializationTests
public void WritesSourceEnvelope()
{
MemoryStream memoryStream = new MemoryStream();
var writer = new MessageToNdjsonWriter(memoryStream);
var writer = new MessageToNdjsonWriterSUT(memoryStream);
writer.Write(Envelope.Create(new Source("hello.feature", "Feature: Hello", SourceMediaType.TEXT_X_CUCUMBER_GHERKIN_PLAIN)));

var json = Encoding.UTF8.GetString(memoryStream.ToArray());
Expand All @@ -29,7 +29,7 @@ public void WritesSourceEnvelope()
public void DoesNotSerializeNullFields()
{
MemoryStream memoryStream = new MemoryStream();
var writer = new MessageToNdjsonWriter(memoryStream);
var writer = new MessageToNdjsonWriterSUT(memoryStream);
writer.Write(new Envelope(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null));

var json = Encoding.UTF8.GetString(memoryStream.ToArray());
Expand All @@ -40,7 +40,7 @@ public void DoesNotSerializeNullFields()
public void IgnoresEmptyLines()
{
MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes("{}\n{}\n\n{}\n"));
var enumerator = new NdjsonMessageReader(memoryStream).GetEnumerator();
var enumerator = new NdjsonMessageReaderSUT(memoryStream).GetEnumerator();

var expectedEnvelope = new Envelope(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
for (int i = 0; i < 3; i++)
Expand All @@ -56,7 +56,7 @@ public void IgnoresEmptyLines()
public void Handles_Enums()
{
MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes("{\"attachment\":{\"contentEncoding\":\"BASE64\", \"body\":\"the-body\", \"mediaType\":\"text/plain\"}}\n"));
var enumerator = new NdjsonMessageReader(memoryStream).GetEnumerator();
var enumerator = new NdjsonMessageReaderSUT(memoryStream).GetEnumerator();
Assert.True(enumerator.MoveNext());
Envelope envelope = enumerator.Current;

Expand All @@ -70,7 +70,7 @@ public void Handles_Enums()
public void Handles_Single_Argument_Constructor()
{
MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes("{\"testRunStarted\": {\"timestamp\":{\"nanos\":0,\"seconds\":0}}}\n"));
var enumerator = new NdjsonMessageReader(memoryStream).GetEnumerator();
var enumerator = new NdjsonMessageReaderSUT(memoryStream).GetEnumerator();
Assert.True(enumerator.MoveNext());
Envelope envelope = enumerator.Current;
Envelope expected = Envelope.Create(new TestRunStarted(new Timestamp(0, 0)));
Expand All @@ -83,7 +83,7 @@ public void Handles_Single_Argument_Constructor()
public void Includes_Offending_Line_In_Error_Message()
{
MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes("BLA BLA"));
var enumerator = new NdjsonMessageReader(memoryStream).GetEnumerator();
var enumerator = new NdjsonMessageReaderSUT(memoryStream).GetEnumerator();
var exception = Assert.Throws<InvalidOperationException>( () => enumerator.MoveNext());
Assert.Equal("Could not parse JSON: BLA BLA", exception.Message);
}
Expand Down
4 changes: 2 additions & 2 deletions dotnet/Cucumber.Messages/Converters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ namespace Cucumber.Messages
{
public class Converters
{
private static DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
private static long NanoSecondsPerTick = 100L;
private static readonly DateTime EpochStart = new(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
private static readonly long NanoSecondsPerTick = 100L;

public static Timestamp ToTimestamp(DateTime dateTime)
{
Expand Down
4 changes: 0 additions & 4 deletions dotnet/Cucumber.Messages/Cucumber.Messages.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,4 @@
<Visible>true</Visible>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Text.Json" Version="6.0.9" />
</ItemGroup>
</Project>
12 changes: 7 additions & 5 deletions dotnet/Cucumber.Messages/MessageToNdjsonWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@

namespace Cucumber.Messages
{
/// <summary>
/// The NdjsonMessageWriter class provides a stream based interface for writing Cucumber messages in ndjson format
///
/// The actual serialization is delegated to a Action&lt;StreamWriter, Envelope&gt;. This is done to avoid tying this library to any specific JSON library or library version.
/// </summary>
public class MessageToNdjsonWriter : IDisposable
{
private StreamWriter _streamWriter;
private Action<StreamWriter, Envelope> _serializer;
private readonly StreamWriter _streamWriter;
private readonly Action<StreamWriter, Envelope> _serializer;

public MessageToNdjsonWriter(Stream stream) : this(stream, (StreamWriter streamWriter, Envelope envelope) => streamWriter.Write(NdjsonSerializer.Serialize(envelope)))
{
}
public MessageToNdjsonWriter(Stream stream, Action<StreamWriter, Envelope> serializer)
{
if (stream == null)
Expand Down
12 changes: 8 additions & 4 deletions dotnet/Cucumber.Messages/NdjsonMessageReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@

namespace Cucumber.Messages
{
/// <summary>
/// The NdjsonMessageReader class provides a stream based interface for reading Cucumber messages in ndjson format and produces Cucumber messages (Envelope)
///
/// The actual deserialization is delegated to a Func&lt;string, Envelope&gt;. This is done to avoid tying this library to any specific JSON library or library version.
/// </summary>
public class NdjsonMessageReader : IDisposable, System.Collections.Generic.IEnumerable<Envelope>
{
private StreamReader _inputStreamReader;
private Func<string, Envelope> _deserializer;
private readonly StreamReader _inputStreamReader;
private readonly Func<string, Envelope> _deserializer;

public NdjsonMessageReader(Stream inputStream) : this( inputStream, (string line) => NdjsonSerializer.Deserialize(line)) { }
public NdjsonMessageReader(Stream inputStream, Func<string, Envelope> deserializer)
{
if (inputStream == null)
Expand Down Expand Up @@ -41,7 +45,7 @@ public System.Collections.Generic.IEnumerator<Envelope> GetEnumerator()
{
envelope = _deserializer(line);
}
catch (System.Text.Json.JsonException e)
catch (System.Exception e)
{
throw new InvalidOperationException($"Could not parse JSON: {line}", e);
}
Expand Down