diff --git a/.github/workflows/test-dotnet.yml b/.github/workflows/test-dotnet.yml index cc62a820..d6c8325d 100644 --- a/.github/workflows/test-dotnet.yml +++ b/.github/workflows/test-dotnet.yml @@ -18,9 +18,9 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: - dotnet-version: '5.0.x' + dotnet-version: '8.0.x' - name: run tests run: | - make + dotnet test working-directory: dotnet diff --git a/CHANGELOG.md b/CHANGELOG.md index 571cf94a..98e15a5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - +- [Dotnet] **Breaking Change** Rewritten to align with the code generation techniques used for the other languages. Added support classes aligned with what is provided for the Java implementation. Upgraded from .NET 5 to .NET 8. Dropped .NET Framework 4.x as a target (but did retain .NET Standard 2.0 as the primary target framework). (https://github.com/cucumber/messages/pull/233) [clrudolphi](https://github.com/clrudolphi) ## [25.0.1] - 2024-06-13 ### Fixed - [Php] Fixed a workflow issue with publishing the package diff --git a/Makefile b/Makefile index 11a201dd..c74466b8 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ schemas = \ ./jsonschema/UndefinedParameterType.json \ ./jsonschema/Envelope.json -languages = cpp go java javascript perl php ruby +languages = cpp go java javascript perl php ruby dotnet .DEFAULT_GOAL = help diff --git a/dotnet/.devcontainer/devcontainer.json b/dotnet/.devcontainer/devcontainer.json new file mode 100644 index 00000000..b10c3ba3 --- /dev/null +++ b/dotnet/.devcontainer/devcontainer.json @@ -0,0 +1,21 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ruby +{ + "name": "Ruby", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/ruby:1-3.3-bullseye", + "features": { + "ghcr.io/jungaretti/features/make:1": {}, + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "8.0" + } + } + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "ruby --version", + // Configure tool-specific properties. + // "customizations": {}, + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} \ No newline at end of file diff --git a/dotnet/Cucumber.Messages.Specs/BasicMessageSerializationTests.cs b/dotnet/Cucumber.Messages.Specs/BasicMessageSerializationTests.cs new file mode 100644 index 00000000..af4006c0 --- /dev/null +++ b/dotnet/Cucumber.Messages.Specs/BasicMessageSerializationTests.cs @@ -0,0 +1,36 @@ +using Xunit; +using System.IO; +using Io.Cucumber.Messages.Types; +using System.Text.Json; +using System.Collections.Generic; +using System.Reflection; +using System.Text.Json.Serialization; +using System; +using System.ComponentModel; +using Cucumber.Messages; + +namespace Cucumber.Messages.Specs +{ + public class BasicMessageSerializationTests + { + + [Fact] + public void SerializesAnEnvelopeToNDJSONCorrectly() + { + var stepDefinitionNDJSON = @"{""stepDefinition"":{""id"":""0"",""pattern"":{""source"":""I have {int} cukes in my belly"",""type"":""CUCUMBER_EXPRESSION""},""sourceReference"":{""location"":{""line"":3},""uri"":""samples/minimal/minimal.feature.ts""}}} +"; + var sourceReference = new SourceReference("samples/minimal/minimal.feature.ts", + null, null, new Location(3, null)); + var stepDefPattern = new StepDefinitionPattern("I have {int} cukes in my belly", StepDefinitionPatternType.CUCUMBER_EXPRESSION); + var stepDefinition = new StepDefinition("0", stepDefPattern, sourceReference); + var env = new Envelope(null, null, null, null, null, null, null, null, stepDefinition, null, null, null, null, null, null, null, null); + + var serializedStepDefinition = NdjsonSerializer.Serialize(env); + var reconstructedStepDefinition = NdjsonSerializer.Deserialize(serializedStepDefinition); + + var expectedStepDefinition = NdjsonSerializer.Deserialize(stepDefinitionNDJSON); + Assert.Equal(expectedStepDefinition, reconstructedStepDefinition); + } + + } +} diff --git a/dotnet/Cucumber.Messages.Specs/ConvertersTests.cs b/dotnet/Cucumber.Messages.Specs/ConvertersTests.cs new file mode 100644 index 00000000..35e02926 --- /dev/null +++ b/dotnet/Cucumber.Messages.Specs/ConvertersTests.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Cucumber.Messages.Specs +{ + public class ConvertersTests + { + + [Fact] + public void ConvertsToAndFromTimestamp() + { + var current = DateTime.Parse("2024-06-29T17:29:47.1537257Z", null, System.Globalization.DateTimeStyles.RoundtripKind); + var timestamp = Converters.ToTimestamp(current); + + var dt = Converters.ToDateTime(timestamp); + + Assert.Equal(current, dt); + } + + [Fact] + public void ConvertsToAndFromDuration() + { + var current = TimeSpan.FromSeconds(3.000161); + var duration = Converters.ToDuration(current); + + var ts = Converters.ToTimeSpan(duration); + + Assert.Equal(current, ts); + } + } +} diff --git a/dotnet/Cucumber.Messages.Specs/Cucumber.Messages.Specs.csproj b/dotnet/Cucumber.Messages.Specs/Cucumber.Messages.Specs.csproj index 0524aae4..b2fbaa9a 100644 --- a/dotnet/Cucumber.Messages.Specs/Cucumber.Messages.Specs.csproj +++ b/dotnet/Cucumber.Messages.Specs/Cucumber.Messages.Specs.csproj @@ -1,7 +1,7 @@  - net5.0 + net8.0 False diff --git a/dotnet/Cucumber.Messages.Specs/MessagesSpec.cs b/dotnet/Cucumber.Messages.Specs/MessagesSpec.cs deleted file mode 100644 index 001af19b..00000000 --- a/dotnet/Cucumber.Messages.Specs/MessagesSpec.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Xunit; -using System.IO; -using static Io.Cucumber.Messages.PickleStepArgument.Types; - -namespace Io.Cucumber.Messages.Specs -{ - public class MessagesSpec - { - [Fact] - public void SerializesPickeDocString() - { - var pickleDocSring = new PickleDocString - { - MediaType = "text/plain", - Content = "some\ncontent\n" - }; - - byte[] serializedBytes; - using (MemoryStream stream = new MemoryStream()) - { - var codedOutputStream = new Google.Protobuf.CodedOutputStream(stream); - codedOutputStream.WriteMessage(pickleDocSring); - codedOutputStream.Flush(); - serializedBytes = stream.ToArray(); - } - - PickleDocString parsedCopy = PickleDocString.Parser.ParseDelimitedFrom(new MemoryStream(serializedBytes)); - Assert.Equal(pickleDocSring, parsedCopy); - } - } -} diff --git a/dotnet/Cucumber.Messages.Specs/MessagesTest.cs b/dotnet/Cucumber.Messages.Specs/MessagesTest.cs new file mode 100644 index 00000000..eeb4e64a --- /dev/null +++ b/dotnet/Cucumber.Messages.Specs/MessagesTest.cs @@ -0,0 +1,27 @@ +using Io.Cucumber.Messages.Types; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Cucumber.Messages.Specs +{ + public class MessagesTest + { + + [Fact] + public void ThrowsWhenRequiredFieldsAreMissing() + { + Assert.Throws(() => new Background(null, null, null, null, null, null)); + } + + [Fact] + public void IsValidWhenNoRequiredFieldsAreMissing() + { + // This should succeed as no constructor arguments to an Envelope are required. + var env = new Envelope(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); + } + } +} diff --git a/dotnet/Cucumber.Messages.Specs/NdjsonStreamSerializationTests.cs b/dotnet/Cucumber.Messages.Specs/NdjsonStreamSerializationTests.cs new file mode 100644 index 00000000..4b9c882a --- /dev/null +++ b/dotnet/Cucumber.Messages.Specs/NdjsonStreamSerializationTests.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +using Cucumber.Messages; +using Io.Cucumber.Messages.Types; + +namespace Cucumber.Messages.Specs +{ + public class NdjsonStreamSerializationTests + { + + [Fact] + public void WritesSourceEnvelope() + { + MemoryStream memoryStream = new MemoryStream(); + var writer = new MessageToNdjsonWriter(memoryStream); + writer.Write(Envelope.Create(new Source("hello.feature", "Feature: Hello", SourceMediaType.TEXT_X_CUCUMBER_GHERKIN_PLAIN))); + + var json = Encoding.UTF8.GetString(memoryStream.ToArray()); + Assert.Equal(@"{""source"":{""uri"":""hello.feature"",""data"":""Feature: Hello"",""mediaType"":""text/x.cucumber.gherkin+plain""}}"+Environment.NewLine, json); + } + + [Fact] + public void DoesNotSerializeNullFields() + { + MemoryStream memoryStream = new MemoryStream(); + var writer = new MessageToNdjsonWriter(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()); + Assert.Equal("{}"+Environment.NewLine, json); + } + + [Fact] + public void IgnoresEmptyLines() + { + MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes("{}\n{}\n\n{}\n")); + var enumerator = new NdjsonMessageReader(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++) + { + Assert.True(enumerator.MoveNext()); + Assert.Equal(expectedEnvelope, enumerator.Current); + } + + Assert.False(enumerator.MoveNext()); + } + + [Fact] + 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(); + Assert.True(enumerator.MoveNext()); + Envelope envelope = enumerator.Current; + + Assert.Equal(AttachmentContentEncoding.BASE64, envelope.Attachment.ContentEncoding); + Assert.Equal("the-body", envelope.Attachment.Body); + Assert.Equal("text/plain", envelope.Attachment.MediaType); + Assert.False(enumerator.MoveNext()); + } + + [Fact] + 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(); + Assert.True(enumerator.MoveNext()); + Envelope envelope = enumerator.Current; + Envelope expected = Envelope.Create(new TestRunStarted(new Timestamp(0, 0))); + + Assert.Equal(expected, envelope); + Assert.False(enumerator.MoveNext()); + } + + [Fact] + public void Includes_Offending_Line_In_Error_Message() + { + MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes("BLA BLA")); + var enumerator = new NdjsonMessageReader(memoryStream).GetEnumerator(); + var exception = Assert.Throws( () => enumerator.MoveNext()); + Assert.Equal("Could not parse JSON: BLA BLA", exception.Message); + } + } +} diff --git a/dotnet/Cucumber.Messages.Specs/ProtocolVersionTest.cs b/dotnet/Cucumber.Messages.Specs/ProtocolVersionTest.cs new file mode 100644 index 00000000..5f3c404b --- /dev/null +++ b/dotnet/Cucumber.Messages.Specs/ProtocolVersionTest.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Xunit; + +namespace Cucumber.Messages.Specs +{ + public class ProtocolVersionTest + { + [Fact] + public void ProtocolVersionIsCorrect() + { + Assert.Matches(@"\d+\.\d+\.\d+(-[0-9A-Za-z-](\.[0-9A-Za-z-])*)?", Cucumber.Messages.ProtocolVersion.Version); + } + } +} diff --git a/dotnet/Cucumber.Messages.sln b/dotnet/Cucumber.Messages.sln index 7edd8eba..79cd0999 100644 --- a/dotnet/Cucumber.Messages.sln +++ b/dotnet/Cucumber.Messages.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28803.156 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35013.160 MinimumVisualStudioVersion = 15.0.26124.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cucumber.Messages", "Cucumber.Messages\Cucumber.Messages.csproj", "{E90670B3-6B40-4844-9D8F-0C19F89A9B45}" EndProject @@ -10,7 +10,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .gitignore = .gitignore ..\..\LICENSE = ..\..\LICENSE - ..\messages.proto = ..\messages.proto EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{A0B27547-2117-480F-9572-BF004AC570A1}" diff --git a/dotnet/Cucumber.Messages/Converters.cs b/dotnet/Cucumber.Messages/Converters.cs new file mode 100644 index 00000000..f3eb7407 --- /dev/null +++ b/dotnet/Cucumber.Messages/Converters.cs @@ -0,0 +1,48 @@ +using Io.Cucumber.Messages.Types; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; + +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; + + public static Timestamp ToTimestamp(DateTime dateTime) + { + var timeSpan = (dateTime.Subtract(EpochStart)); + long seconds = timeSpan.Ticks / TimeSpan.TicksPerSecond; + long nanos = (timeSpan.Ticks % TimeSpan.TicksPerSecond) * NanoSecondsPerTick; + return new Timestamp( + seconds, + nanos); + } + + public static Duration ToDuration(TimeSpan timeSpan) + { + return new Duration( + (long) timeSpan.TotalSeconds, + (timeSpan.Ticks % TimeSpan.TicksPerSecond) * NanoSecondsPerTick); + } + + public static DateTime ToDateTime(Timestamp timestamp) + { + var seconds = timestamp.Seconds; + var time = EpochStart.AddSeconds(seconds).ToUniversalTime(); + time = time.AddTicks(timestamp.Nanos / NanoSecondsPerTick); + + return time; + } + + public static TimeSpan ToTimeSpan(Duration duration) + { + var ts = new TimeSpan(0, 0, 0, (int)duration.Seconds); + ts = ts.Add(TimeSpan.FromTicks(duration.Nanos / NanoSecondsPerTick)); + + return ts; + } + } +} diff --git a/dotnet/Cucumber.Messages/Cucumber.Messages.csproj b/dotnet/Cucumber.Messages/Cucumber.Messages.csproj index c11fd247..7a478bee 100644 --- a/dotnet/Cucumber.Messages/Cucumber.Messages.csproj +++ b/dotnet/Cucumber.Messages/Cucumber.Messages.csproj @@ -1,6 +1,7 @@ - + - netstandard2.0;net45 + netstandard2.0 + 10.0 true 1591 false @@ -18,9 +19,9 @@ Cucumber.Messages Cucumber.Messages Cucumber Ltd, TechTalk - Copyright © Cucumber Ltd, TechTalk - Protocol Buffer messages for Cucumber's and SpecFlow's inter-process communication - cucumber-messages cucumber specflow gherkin + Copyright © Cucumber Ltd, TechTalk + JSON schema-based messages for Cucumber's inter-process communication + cucumber-messages cucumber reqnroll specflow gherkin https://github.com/cucumber/messages https://github.com/cucumber/messages git @@ -31,24 +32,6 @@ bin/$(Configuration)/NuGet - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - True @@ -56,4 +39,8 @@ true + + + + diff --git a/dotnet/Cucumber.Messages/CucumberMessagEnumConverter.cs b/dotnet/Cucumber.Messages/CucumberMessagEnumConverter.cs new file mode 100644 index 00000000..9da68504 --- /dev/null +++ b/dotnet/Cucumber.Messages/CucumberMessagEnumConverter.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Cucumber.Messages +{ + internal class CucumberMessageEnumConverter : JsonConverter where T : struct, Enum + { + private readonly Dictionary _enumToString = new Dictionary(); + private readonly Dictionary _stringToEnum = new Dictionary(); + + protected internal CucumberMessageEnumConverter() + { + var type = typeof(T); + foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static)) + { + var value = (T)field.GetValue(null); + var attribute = field.GetCustomAttribute(); + var name = attribute?.Description ?? field.Name; + _enumToString[value] = name; + _stringToEnum[name] = value; + } + } + + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var stringValue = reader.GetString(); + return _stringToEnum.TryGetValue(stringValue, out var enumValue) ? enumValue : default; + } + + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + writer.WriteStringValue(_enumToString.TryGetValue(value, out var stringValue) ? stringValue : value.ToString()); + } + } + +} diff --git a/dotnet/Cucumber.Messages/MessageToNdjsonWriter.cs b/dotnet/Cucumber.Messages/MessageToNdjsonWriter.cs new file mode 100644 index 00000000..19b3aa46 --- /dev/null +++ b/dotnet/Cucumber.Messages/MessageToNdjsonWriter.cs @@ -0,0 +1,42 @@ +using Io.Cucumber.Messages.Types; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Cucumber.Messages +{ + public class MessageToNdjsonWriter : IDisposable + { + private StreamWriter _streamWriter; + private Action _serializer; + + public MessageToNdjsonWriter(Stream stream) : this(stream, (StreamWriter streamWriter, Envelope envelope) => streamWriter.Write(NdjsonSerializer.Serialize(envelope))) + { + } + public MessageToNdjsonWriter(Stream stream, Action serializer) + { + if (stream == null) + throw new ArgumentNullException(nameof(stream)); + if (serializer == null) + throw new ArgumentNullException(nameof(serializer)); + _streamWriter = new StreamWriter(stream); + _serializer = serializer; + } + + public void Dispose() + { + _streamWriter.Close(); + _streamWriter.Dispose(); + } + + public void Write(Envelope message) + { + if (message == null) + throw new ArgumentNullException(nameof(message)); + _serializer(_streamWriter, message); + _streamWriter.WriteLine(); + _streamWriter.Flush(); + } + } +} diff --git a/dotnet/Cucumber.Messages/NdjsonMessageReader.cs b/dotnet/Cucumber.Messages/NdjsonMessageReader.cs new file mode 100644 index 00000000..e21aabad --- /dev/null +++ b/dotnet/Cucumber.Messages/NdjsonMessageReader.cs @@ -0,0 +1,57 @@ +using Io.Cucumber.Messages.Types; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Cucumber.Messages +{ + public class NdjsonMessageReader : IDisposable, System.Collections.Generic.IEnumerable + { + private StreamReader _inputStreamReader; + private Func _deserializer; + + public NdjsonMessageReader(Stream inputStream) : this( inputStream, (string line) => NdjsonSerializer.Deserialize(line)) { } + public NdjsonMessageReader(Stream inputStream, Func deserializer) + { + if (inputStream == null) + throw new ArgumentNullException(nameof(inputStream)); + if (deserializer == null) + throw new ArgumentNullException(nameof(deserializer)); + + _inputStreamReader = new StreamReader(inputStream); + _deserializer = deserializer; + } + + public void Dispose() + { + _inputStreamReader.Close(); + _inputStreamReader.Dispose(); + } + + public System.Collections.Generic.IEnumerator GetEnumerator() + { + while(!_inputStreamReader.EndOfStream) + { + var line = _inputStreamReader.ReadLine(); + if (String.IsNullOrEmpty(line)) continue; + Envelope envelope; + try + { + envelope = _deserializer(line); + } + catch (System.Text.Json.JsonException e) + { + throw new InvalidOperationException($"Could not parse JSON: {line}", e); + } + yield return envelope; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/dotnet/Cucumber.Messages/NdjsonSerializer.cs b/dotnet/Cucumber.Messages/NdjsonSerializer.cs new file mode 100644 index 00000000..26656a22 --- /dev/null +++ b/dotnet/Cucumber.Messages/NdjsonSerializer.cs @@ -0,0 +1,51 @@ +using Io.Cucumber.Messages.Types; +using System; +using System.Text.Json; + +namespace Cucumber.Messages +{ + public class NdjsonSerializer + { + private static Lazy _jsonOptions = new Lazy(() => + { + var options = new JsonSerializerOptions(); + options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + options.Converters.Add(new CucumberMessageEnumConverter()); + options.Converters.Add(new CucumberMessageEnumConverter()); + options.Converters.Add(new CucumberMessageEnumConverter()); + options.Converters.Add(new CucumberMessageEnumConverter()); + options.Converters.Add(new CucumberMessageEnumConverter()); + options.Converters.Add(new CucumberMessageEnumConverter()); + options.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull; + options.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping; + + return options; + }); + + private static JsonSerializerOptions JsonOptions { get + { + return _jsonOptions.Value; + } + } + + public static string Serialize(Envelope message) + { + return NdjsonSerializer.Serialize(message); + } + + internal static string Serialize(T message) + { + return JsonSerializer.Serialize(message, JsonOptions); + } + + public static Envelope Deserialize(string json) + { + return NdjsonSerializer.Deserialize(json); + } + + internal static T Deserialize(string json) + { + return JsonSerializer.Deserialize(json, JsonOptions); + } + } +} diff --git a/dotnet/Cucumber.Messages/ProtocolVersion.cs b/dotnet/Cucumber.Messages/ProtocolVersion.cs new file mode 100644 index 00000000..e131231e --- /dev/null +++ b/dotnet/Cucumber.Messages/ProtocolVersion.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +namespace Cucumber.Messages +{ + public class ProtocolVersion + { + public static string Version + { + get + { + return GetPackageVersion(typeof(ProtocolVersion).GetTypeInfo().Assembly); + } + } + + private static string GetPackageVersion(Assembly assembly) + { + var version = assembly.GetCustomAttribute()?.InformationalVersion; + return version?.Split(new char['+'], 2)[0]; + } + } +} diff --git a/dotnet/Cucumber.Messages/generated/Attachment.cs b/dotnet/Cucumber.Messages/generated/Attachment.cs new file mode 100644 index 00000000..acb11b5d --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Attachment.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Attachment message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * //// Attachments (parse errors, execution errors, screenshots, links...) + * + * An attachment represents any kind of data associated with a line in a + * [Source](#io.cucumber.messages.Source) file. It can be used for: + * + * * Syntax errors during parse time + * * Screenshots captured and attached during execution + * * Logs captured and attached during execution + * + * It is not to be used for runtime errors raised/thrown during execution. This + * is captured in `TestResult`. + */ + +public sealed class Attachment +{ + /** + * The body of the attachment. If `contentEncoding` is `IDENTITY`, the attachment + * is simply the string. If it's `BASE64`, the string should be Base64 decoded to + * obtain the attachment. + */ + public string Body { get; private set; } + /** + * Whether to interpret `body` "as-is" (IDENTITY) or if it needs to be Base64-decoded (BASE64). + * + * Content encoding is *not* determined by the media type, but rather by the type + * of the object being attached: + * + * - string: IDENTITY + * - byte array: BASE64 + * - stream: BASE64 + */ + public AttachmentContentEncoding ContentEncoding { get; private set; } + /** + * Suggested file name of the attachment. (Provided by the user as an argument to `attach`) + */ + public string FileName { get; private set; } + /** + * The media type of the data. This can be any valid + * [IANA Media Type](https://www.iana.org/assignments/media-types/media-types.xhtml) + * as well as Cucumber-specific media types such as `text/x.cucumber.gherkin+plain` + * and `text/x.cucumber.stacktrace+plain` + */ + public string MediaType { get; private set; } + public Source Source { get; private set; } + public string TestCaseStartedId { get; private set; } + public string TestStepId { get; private set; } + /** + * A URL where the attachment can be retrieved. This field should not be set by Cucumber. + * It should be set by a program that reads a message stream and does the following for + * each Attachment message: + * + * - Writes the body (after base64 decoding if necessary) to a new file. + * - Sets `body` and `contentEncoding` to `null` + * - Writes out the new attachment message + * + * This will result in a smaller message stream, which can improve performance and + * reduce bandwidth of message consumers. It also makes it easier to process and download attachments + * separately from reports. + */ + public string Url { get; private set; } + + + public Attachment( + string body, + AttachmentContentEncoding contentEncoding, + string fileName, + string mediaType, + Source source, + string testCaseStartedId, + string testStepId, + string url + ) + { + RequireNonNull(body, "Body", "Attachment.Body cannot be null"); + this.Body = body; + RequireNonNull(contentEncoding, "ContentEncoding", "Attachment.ContentEncoding cannot be null"); + this.ContentEncoding = contentEncoding; + this.FileName = fileName; + RequireNonNull(mediaType, "MediaType", "Attachment.MediaType cannot be null"); + this.MediaType = mediaType; + this.Source = source; + this.TestCaseStartedId = testCaseStartedId; + this.TestStepId = testStepId; + this.Url = url; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Attachment that = (Attachment) o; + return + Body.Equals(that.Body) && + ContentEncoding.Equals(that.ContentEncoding) && + Object.Equals(FileName, that.FileName) && + MediaType.Equals(that.MediaType) && + Object.Equals(Source, that.Source) && + Object.Equals(TestCaseStartedId, that.TestCaseStartedId) && + Object.Equals(TestStepId, that.TestStepId) && + Object.Equals(Url, that.Url); + } + + public override int GetHashCode() + { + int hash = 17; + if (Body != null) + hash = hash * 31 + Body.GetHashCode(); + hash = hash * 31 + ContentEncoding.GetHashCode(); + if (FileName != null) + hash = hash * 31 + FileName.GetHashCode(); + if (MediaType != null) + hash = hash * 31 + MediaType.GetHashCode(); + if (Source != null) + hash = hash * 31 + Source.GetHashCode(); + if (TestCaseStartedId != null) + hash = hash * 31 + TestCaseStartedId.GetHashCode(); + if (TestStepId != null) + hash = hash * 31 + TestStepId.GetHashCode(); + if (Url != null) + hash = hash * 31 + Url.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Attachment{" + + "body=" + Body + + ", contentEncoding=" + ContentEncoding + + ", fileName=" + FileName + + ", mediaType=" + MediaType + + ", source=" + Source + + ", testCaseStartedId=" + TestCaseStartedId + + ", testStepId=" + TestStepId + + ", url=" + Url + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/AttachmentContentEncoding.cs b/dotnet/Cucumber.Messages/generated/AttachmentContentEncoding.cs new file mode 100644 index 00000000..84f2ca03 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/AttachmentContentEncoding.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel; +using System.Reflection; + +namespace Io.Cucumber.Messages.Types; + +// Generated code +public enum AttachmentContentEncoding { + + [Description("IDENTITY")] + IDENTITY, + + [Description("BASE64")] + BASE64 +} + +public static class AttachmentContentEncodingExtensions +{ + public static string Value(this AttachmentContentEncoding v) { + var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); + return attribute == null ? v.ToString() : attribute.Description; + } +} diff --git a/dotnet/Cucumber.Messages/generated/Background.cs b/dotnet/Cucumber.Messages/generated/Background.cs new file mode 100644 index 00000000..83bbfd0c --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Background.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Background message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class Background +{ + /** + * The location of the `Background` keyword + */ + public Location Location { get; private set; } + public string Keyword { get; private set; } + public string Name { get; private set; } + public string Description { get; private set; } + public List Steps { get; private set; } + public string Id { get; private set; } + + + public Background( + Location location, + string keyword, + string name, + string description, + List steps, + string id + ) + { + RequireNonNull(location, "Location", "Background.Location cannot be null"); + this.Location = location; + RequireNonNull(keyword, "Keyword", "Background.Keyword cannot be null"); + this.Keyword = keyword; + RequireNonNull(name, "Name", "Background.Name cannot be null"); + this.Name = name; + RequireNonNull(description, "Description", "Background.Description cannot be null"); + this.Description = description; + RequireNonNull>(steps, "Steps", "Background.Steps cannot be null"); + this.Steps = new List(steps); + RequireNonNull(id, "Id", "Background.Id cannot be null"); + this.Id = id; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Background that = (Background) o; + return + Location.Equals(that.Location) && + Keyword.Equals(that.Keyword) && + Name.Equals(that.Name) && + Description.Equals(that.Description) && + Steps.Equals(that.Steps) && + Id.Equals(that.Id); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Keyword != null) + hash = hash * 31 + Keyword.GetHashCode(); + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (Description != null) + hash = hash * 31 + Description.GetHashCode(); + if (Steps != null) + hash = hash * 31 + Steps.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Background{" + + "location=" + Location + + ", keyword=" + Keyword + + ", name=" + Name + + ", description=" + Description + + ", steps=" + Steps + + ", id=" + Id + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Ci.cs b/dotnet/Cucumber.Messages/generated/Ci.cs new file mode 100644 index 00000000..8275b29c --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Ci.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Ci message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * CI environment + */ + +public sealed class Ci +{ + /** + * Name of the CI product, e.g. "Jenkins", "CircleCI" etc. + */ + public string Name { get; private set; } + /** + * Link to the build + */ + public string Url { get; private set; } + /** + * The build number. Some CI servers use non-numeric build numbers, which is why this is a string + */ + public string BuildNumber { get; private set; } + public Git Git { get; private set; } + + + public Ci( + string name, + string url, + string buildNumber, + Git git + ) + { + RequireNonNull(name, "Name", "Ci.Name cannot be null"); + this.Name = name; + this.Url = url; + this.BuildNumber = buildNumber; + this.Git = git; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Ci that = (Ci) o; + return + Name.Equals(that.Name) && + Object.Equals(Url, that.Url) && + Object.Equals(BuildNumber, that.BuildNumber) && + Object.Equals(Git, that.Git); + } + + public override int GetHashCode() + { + int hash = 17; + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (Url != null) + hash = hash * 31 + Url.GetHashCode(); + if (BuildNumber != null) + hash = hash * 31 + BuildNumber.GetHashCode(); + if (Git != null) + hash = hash * 31 + Git.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Ci{" + + "name=" + Name + + ", url=" + Url + + ", buildNumber=" + BuildNumber + + ", git=" + Git + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Comment.cs b/dotnet/Cucumber.Messages/generated/Comment.cs new file mode 100644 index 00000000..c55601f9 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Comment.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Comment message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A comment in a Gherkin document + */ + +public sealed class Comment +{ + /** + * The location of the comment + */ + public Location Location { get; private set; } + /** + * The text of the comment + */ + public string Text { get; private set; } + + + public Comment( + Location location, + string text + ) + { + RequireNonNull(location, "Location", "Comment.Location cannot be null"); + this.Location = location; + RequireNonNull(text, "Text", "Comment.Text cannot be null"); + this.Text = text; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Comment that = (Comment) o; + return + Location.Equals(that.Location) && + Text.Equals(that.Text); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Text != null) + hash = hash * 31 + Text.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Comment{" + + "location=" + Location + + ", text=" + Text + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/DataTable.cs b/dotnet/Cucumber.Messages/generated/DataTable.cs new file mode 100644 index 00000000..891fc8f6 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/DataTable.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the DataTable message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class DataTable +{ + public Location Location { get; private set; } + public List Rows { get; private set; } + + + public DataTable( + Location location, + List rows + ) + { + RequireNonNull(location, "Location", "DataTable.Location cannot be null"); + this.Location = location; + RequireNonNull>(rows, "Rows", "DataTable.Rows cannot be null"); + this.Rows = new List(rows); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + DataTable that = (DataTable) o; + return + Location.Equals(that.Location) && + Rows.Equals(that.Rows); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Rows != null) + hash = hash * 31 + Rows.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "DataTable{" + + "location=" + Location + + ", rows=" + Rows + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/DocString.cs b/dotnet/Cucumber.Messages/generated/DocString.cs new file mode 100644 index 00000000..f24d9cda --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/DocString.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the DocString message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class DocString +{ + public Location Location { get; private set; } + public string MediaType { get; private set; } + public string Content { get; private set; } + public string Delimiter { get; private set; } + + + public DocString( + Location location, + string mediaType, + string content, + string delimiter + ) + { + RequireNonNull(location, "Location", "DocString.Location cannot be null"); + this.Location = location; + this.MediaType = mediaType; + RequireNonNull(content, "Content", "DocString.Content cannot be null"); + this.Content = content; + RequireNonNull(delimiter, "Delimiter", "DocString.Delimiter cannot be null"); + this.Delimiter = delimiter; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + DocString that = (DocString) o; + return + Location.Equals(that.Location) && + Object.Equals(MediaType, that.MediaType) && + Content.Equals(that.Content) && + Delimiter.Equals(that.Delimiter); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (MediaType != null) + hash = hash * 31 + MediaType.GetHashCode(); + if (Content != null) + hash = hash * 31 + Content.GetHashCode(); + if (Delimiter != null) + hash = hash * 31 + Delimiter.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "DocString{" + + "location=" + Location + + ", mediaType=" + MediaType + + ", content=" + Content + + ", delimiter=" + Delimiter + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Duration.cs b/dotnet/Cucumber.Messages/generated/Duration.cs new file mode 100644 index 00000000..4bc3e46f --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Duration.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Duration message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * The structure is pretty close of the Timestamp one. For clarity, a second type + * of message is used. + */ + +public sealed class Duration +{ + public long Seconds { get; private set; } + /** + * Non-negative fractions of a second at nanosecond resolution. Negative + * second values with fractions must still have non-negative nanos values + * that count forward in time. Must be from 0 to 999,999,999 + * inclusive. + */ + public long Nanos { get; private set; } + + + public Duration( + long seconds, + long nanos + ) + { + RequireNonNull(seconds, "Seconds", "Duration.Seconds cannot be null"); + this.Seconds = seconds; + RequireNonNull(nanos, "Nanos", "Duration.Nanos cannot be null"); + this.Nanos = nanos; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Duration that = (Duration) o; + return + Seconds.Equals(that.Seconds) && + Nanos.Equals(that.Nanos); + } + + public override int GetHashCode() + { + int hash = 17; + hash = hash * 31 + Seconds.GetHashCode(); + hash = hash * 31 + Nanos.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Duration{" + + "seconds=" + Seconds + + ", nanos=" + Nanos + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Envelope.cs b/dotnet/Cucumber.Messages/generated/Envelope.cs new file mode 100644 index 00000000..8c193a40 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Envelope.cs @@ -0,0 +1,572 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Envelope message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * When removing a field, replace it with reserved, rather than deleting the line. + * When adding a field, add it to the end and increment the number by one. + * See https://developers.google.com/protocol-buffers/docs/proto#updating for details + * + * All the messages that are passed between different components/processes are Envelope + * messages. + */ + +public sealed class Envelope +{ + public Attachment Attachment { get; private set; } + public GherkinDocument GherkinDocument { get; private set; } + public Hook Hook { get; private set; } + public Meta Meta { get; private set; } + public ParameterType ParameterType { get; private set; } + public ParseError ParseError { get; private set; } + public Pickle Pickle { get; private set; } + public Source Source { get; private set; } + public StepDefinition StepDefinition { get; private set; } + public TestCase TestCase { get; private set; } + public TestCaseFinished TestCaseFinished { get; private set; } + public TestCaseStarted TestCaseStarted { get; private set; } + public TestRunFinished TestRunFinished { get; private set; } + public TestRunStarted TestRunStarted { get; private set; } + public TestStepFinished TestStepFinished { get; private set; } + public TestStepStarted TestStepStarted { get; private set; } + public UndefinedParameterType UndefinedParameterType { get; private set; } + + + public static Envelope Create(Attachment attachment) + { + return new Envelope( + Require(attachment, "Attachment", "Envelope.Attachment cannot be null"), + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(GherkinDocument gherkinDocument) + { + return new Envelope( + null, + Require(gherkinDocument, "GherkinDocument", "Envelope.GherkinDocument cannot be null"), + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(Hook hook) + { + return new Envelope( + null, + null, + Require(hook, "Hook", "Envelope.Hook cannot be null"), + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(Meta meta) + { + return new Envelope( + null, + null, + null, + Require(meta, "Meta", "Envelope.Meta cannot be null"), + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(ParameterType parameterType) + { + return new Envelope( + null, + null, + null, + null, + Require(parameterType, "ParameterType", "Envelope.ParameterType cannot be null"), + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(ParseError parseError) + { + return new Envelope( + null, + null, + null, + null, + null, + Require(parseError, "ParseError", "Envelope.ParseError cannot be null"), + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(Pickle pickle) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + Require(pickle, "Pickle", "Envelope.Pickle cannot be null"), + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(Source source) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + Require(source, "Source", "Envelope.Source cannot be null"), + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(StepDefinition stepDefinition) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + null, + Require(stepDefinition, "StepDefinition", "Envelope.StepDefinition cannot be null"), + null, + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(TestCase testCase) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + null, + null, + Require(testCase, "TestCase", "Envelope.TestCase cannot be null"), + null, + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(TestCaseFinished testCaseFinished) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + Require(testCaseFinished, "TestCaseFinished", "Envelope.TestCaseFinished cannot be null"), + null, + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(TestCaseStarted testCaseStarted) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + Require(testCaseStarted, "TestCaseStarted", "Envelope.TestCaseStarted cannot be null"), + null, + null, + null, + null, + null + ); + } + + public static Envelope Create(TestRunFinished testRunFinished) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + Require(testRunFinished, "TestRunFinished", "Envelope.TestRunFinished cannot be null"), + null, + null, + null, + null + ); + } + + public static Envelope Create(TestRunStarted testRunStarted) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + Require(testRunStarted, "TestRunStarted", "Envelope.TestRunStarted cannot be null"), + null, + null, + null + ); + } + + public static Envelope Create(TestStepFinished testStepFinished) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + Require(testStepFinished, "TestStepFinished", "Envelope.TestStepFinished cannot be null"), + null, + null + ); + } + + public static Envelope Create(TestStepStarted testStepStarted) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + Require(testStepStarted, "TestStepStarted", "Envelope.TestStepStarted cannot be null"), + null + ); + } + + public static Envelope Create(UndefinedParameterType undefinedParameterType) + { + return new Envelope( + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + Require(undefinedParameterType, "UndefinedParameterType", "Envelope.UndefinedParameterType cannot be null") + ); + } + + public Envelope( + Attachment attachment, + GherkinDocument gherkinDocument, + Hook hook, + Meta meta, + ParameterType parameterType, + ParseError parseError, + Pickle pickle, + Source source, + StepDefinition stepDefinition, + TestCase testCase, + TestCaseFinished testCaseFinished, + TestCaseStarted testCaseStarted, + TestRunFinished testRunFinished, + TestRunStarted testRunStarted, + TestStepFinished testStepFinished, + TestStepStarted testStepStarted, + UndefinedParameterType undefinedParameterType + ) + { + this.Attachment = attachment; + this.GherkinDocument = gherkinDocument; + this.Hook = hook; + this.Meta = meta; + this.ParameterType = parameterType; + this.ParseError = parseError; + this.Pickle = pickle; + this.Source = source; + this.StepDefinition = stepDefinition; + this.TestCase = testCase; + this.TestCaseFinished = testCaseFinished; + this.TestCaseStarted = testCaseStarted; + this.TestRunFinished = testRunFinished; + this.TestRunStarted = testRunStarted; + this.TestStepFinished = testStepFinished; + this.TestStepStarted = testStepStarted; + this.UndefinedParameterType = undefinedParameterType; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Envelope that = (Envelope) o; + return + Object.Equals(Attachment, that.Attachment) && + Object.Equals(GherkinDocument, that.GherkinDocument) && + Object.Equals(Hook, that.Hook) && + Object.Equals(Meta, that.Meta) && + Object.Equals(ParameterType, that.ParameterType) && + Object.Equals(ParseError, that.ParseError) && + Object.Equals(Pickle, that.Pickle) && + Object.Equals(Source, that.Source) && + Object.Equals(StepDefinition, that.StepDefinition) && + Object.Equals(TestCase, that.TestCase) && + Object.Equals(TestCaseFinished, that.TestCaseFinished) && + Object.Equals(TestCaseStarted, that.TestCaseStarted) && + Object.Equals(TestRunFinished, that.TestRunFinished) && + Object.Equals(TestRunStarted, that.TestRunStarted) && + Object.Equals(TestStepFinished, that.TestStepFinished) && + Object.Equals(TestStepStarted, that.TestStepStarted) && + Object.Equals(UndefinedParameterType, that.UndefinedParameterType); + } + + public override int GetHashCode() + { + int hash = 17; + if (Attachment != null) + hash = hash * 31 + Attachment.GetHashCode(); + if (GherkinDocument != null) + hash = hash * 31 + GherkinDocument.GetHashCode(); + if (Hook != null) + hash = hash * 31 + Hook.GetHashCode(); + if (Meta != null) + hash = hash * 31 + Meta.GetHashCode(); + if (ParameterType != null) + hash = hash * 31 + ParameterType.GetHashCode(); + if (ParseError != null) + hash = hash * 31 + ParseError.GetHashCode(); + if (Pickle != null) + hash = hash * 31 + Pickle.GetHashCode(); + if (Source != null) + hash = hash * 31 + Source.GetHashCode(); + if (StepDefinition != null) + hash = hash * 31 + StepDefinition.GetHashCode(); + if (TestCase != null) + hash = hash * 31 + TestCase.GetHashCode(); + if (TestCaseFinished != null) + hash = hash * 31 + TestCaseFinished.GetHashCode(); + if (TestCaseStarted != null) + hash = hash * 31 + TestCaseStarted.GetHashCode(); + if (TestRunFinished != null) + hash = hash * 31 + TestRunFinished.GetHashCode(); + if (TestRunStarted != null) + hash = hash * 31 + TestRunStarted.GetHashCode(); + if (TestStepFinished != null) + hash = hash * 31 + TestStepFinished.GetHashCode(); + if (TestStepStarted != null) + hash = hash * 31 + TestStepStarted.GetHashCode(); + if (UndefinedParameterType != null) + hash = hash * 31 + UndefinedParameterType.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Envelope{" + + "attachment=" + Attachment + + ", gherkinDocument=" + GherkinDocument + + ", hook=" + Hook + + ", meta=" + Meta + + ", parameterType=" + ParameterType + + ", parseError=" + ParseError + + ", pickle=" + Pickle + + ", source=" + Source + + ", stepDefinition=" + StepDefinition + + ", testCase=" + TestCase + + ", testCaseFinished=" + TestCaseFinished + + ", testCaseStarted=" + TestCaseStarted + + ", testRunFinished=" + TestRunFinished + + ", testRunStarted=" + TestRunStarted + + ", testStepFinished=" + TestStepFinished + + ", testStepStarted=" + TestStepStarted + + ", undefinedParameterType=" + UndefinedParameterType + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Examples.cs b/dotnet/Cucumber.Messages/generated/Examples.cs new file mode 100644 index 00000000..768c36d4 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Examples.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Examples message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class Examples +{ + /** + * The location of the `Examples` keyword + */ + public Location Location { get; private set; } + public List Tags { get; private set; } + public string Keyword { get; private set; } + public string Name { get; private set; } + public string Description { get; private set; } + public TableRow TableHeader { get; private set; } + public List TableBody { get; private set; } + public string Id { get; private set; } + + + public Examples( + Location location, + List tags, + string keyword, + string name, + string description, + TableRow tableHeader, + List tableBody, + string id + ) + { + RequireNonNull(location, "Location", "Examples.Location cannot be null"); + this.Location = location; + RequireNonNull>(tags, "Tags", "Examples.Tags cannot be null"); + this.Tags = new List(tags); + RequireNonNull(keyword, "Keyword", "Examples.Keyword cannot be null"); + this.Keyword = keyword; + RequireNonNull(name, "Name", "Examples.Name cannot be null"); + this.Name = name; + RequireNonNull(description, "Description", "Examples.Description cannot be null"); + this.Description = description; + this.TableHeader = tableHeader; + RequireNonNull>(tableBody, "TableBody", "Examples.TableBody cannot be null"); + this.TableBody = new List(tableBody); + RequireNonNull(id, "Id", "Examples.Id cannot be null"); + this.Id = id; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Examples that = (Examples) o; + return + Location.Equals(that.Location) && + Tags.Equals(that.Tags) && + Keyword.Equals(that.Keyword) && + Name.Equals(that.Name) && + Description.Equals(that.Description) && + Object.Equals(TableHeader, that.TableHeader) && + TableBody.Equals(that.TableBody) && + Id.Equals(that.Id); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Tags != null) + hash = hash * 31 + Tags.GetHashCode(); + if (Keyword != null) + hash = hash * 31 + Keyword.GetHashCode(); + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (Description != null) + hash = hash * 31 + Description.GetHashCode(); + if (TableHeader != null) + hash = hash * 31 + TableHeader.GetHashCode(); + if (TableBody != null) + hash = hash * 31 + TableBody.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Examples{" + + "location=" + Location + + ", tags=" + Tags + + ", keyword=" + Keyword + + ", name=" + Name + + ", description=" + Description + + ", tableHeader=" + TableHeader + + ", tableBody=" + TableBody + + ", id=" + Id + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Exception.cs b/dotnet/Cucumber.Messages/generated/Exception.cs new file mode 100644 index 00000000..106245ed --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Exception.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Exception message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A simplified representation of an exception + */ + +public sealed class Exception +{ + /** + * The type of the exception that caused this result. E.g. "Error" or "org.opentest4j.AssertionFailedError" + */ + public string Type { get; private set; } + /** + * The message of exception that caused this result. E.g. expected: "a" but was: "b" + */ + public string Message { get; private set; } + /** + * The stringified stack trace of the exception that caused this result + */ + public string StackTrace { get; private set; } + + + public Exception( + string type, + string message, + string stackTrace + ) + { + RequireNonNull(type, "Type", "Exception.Type cannot be null"); + this.Type = type; + this.Message = message; + this.StackTrace = stackTrace; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Exception that = (Exception) o; + return + Type.Equals(that.Type) && + Object.Equals(Message, that.Message) && + Object.Equals(StackTrace, that.StackTrace); + } + + public override int GetHashCode() + { + int hash = 17; + if (Type != null) + hash = hash * 31 + Type.GetHashCode(); + if (Message != null) + hash = hash * 31 + Message.GetHashCode(); + if (StackTrace != null) + hash = hash * 31 + StackTrace.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Exception{" + + "type=" + Type + + ", message=" + Message + + ", stackTrace=" + StackTrace + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Feature.cs b/dotnet/Cucumber.Messages/generated/Feature.cs new file mode 100644 index 00000000..8d1ae1de --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Feature.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Feature message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class Feature +{ + /** + * The location of the `Feature` keyword + */ + public Location Location { get; private set; } + /** + * All the tags placed above the `Feature` keyword + */ + public List Tags { get; private set; } + /** + * The [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code of the Gherkin document + */ + public string Language { get; private set; } + /** + * The text of the `Feature` keyword (in the language specified by `language`) + */ + public string Keyword { get; private set; } + /** + * The name of the feature (the text following the `keyword`) + */ + public string Name { get; private set; } + /** + * The line(s) underneath the line with the `keyword` that are used as description + */ + public string Description { get; private set; } + /** + * Zero or more children + */ + public List Children { get; private set; } + + + public Feature( + Location location, + List tags, + string language, + string keyword, + string name, + string description, + List children + ) + { + RequireNonNull(location, "Location", "Feature.Location cannot be null"); + this.Location = location; + RequireNonNull>(tags, "Tags", "Feature.Tags cannot be null"); + this.Tags = new List(tags); + RequireNonNull(language, "Language", "Feature.Language cannot be null"); + this.Language = language; + RequireNonNull(keyword, "Keyword", "Feature.Keyword cannot be null"); + this.Keyword = keyword; + RequireNonNull(name, "Name", "Feature.Name cannot be null"); + this.Name = name; + RequireNonNull(description, "Description", "Feature.Description cannot be null"); + this.Description = description; + RequireNonNull>(children, "Children", "Feature.Children cannot be null"); + this.Children = new List(children); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Feature that = (Feature) o; + return + Location.Equals(that.Location) && + Tags.Equals(that.Tags) && + Language.Equals(that.Language) && + Keyword.Equals(that.Keyword) && + Name.Equals(that.Name) && + Description.Equals(that.Description) && + Children.Equals(that.Children); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Tags != null) + hash = hash * 31 + Tags.GetHashCode(); + if (Language != null) + hash = hash * 31 + Language.GetHashCode(); + if (Keyword != null) + hash = hash * 31 + Keyword.GetHashCode(); + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (Description != null) + hash = hash * 31 + Description.GetHashCode(); + if (Children != null) + hash = hash * 31 + Children.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Feature{" + + "location=" + Location + + ", tags=" + Tags + + ", language=" + Language + + ", keyword=" + Keyword + + ", name=" + Name + + ", description=" + Description + + ", children=" + Children + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/FeatureChild.cs b/dotnet/Cucumber.Messages/generated/FeatureChild.cs new file mode 100644 index 00000000..77b86b88 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/FeatureChild.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the FeatureChild message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A child node of a `Feature` node + */ + +public sealed class FeatureChild +{ + public Rule Rule { get; private set; } + public Background Background { get; private set; } + public Scenario Scenario { get; private set; } + + + public static FeatureChild Create(Rule rule) + { + return new FeatureChild( + Require(rule, "Rule", "FeatureChild.Rule cannot be null"), + null, + null + ); + } + + public static FeatureChild Create(Background background) + { + return new FeatureChild( + null, + Require(background, "Background", "FeatureChild.Background cannot be null"), + null + ); + } + + public static FeatureChild Create(Scenario scenario) + { + return new FeatureChild( + null, + null, + Require(scenario, "Scenario", "FeatureChild.Scenario cannot be null") + ); + } + + public FeatureChild( + Rule rule, + Background background, + Scenario scenario + ) + { + this.Rule = rule; + this.Background = background; + this.Scenario = scenario; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + FeatureChild that = (FeatureChild) o; + return + Object.Equals(Rule, that.Rule) && + Object.Equals(Background, that.Background) && + Object.Equals(Scenario, that.Scenario); + } + + public override int GetHashCode() + { + int hash = 17; + if (Rule != null) + hash = hash * 31 + Rule.GetHashCode(); + if (Background != null) + hash = hash * 31 + Background.GetHashCode(); + if (Scenario != null) + hash = hash * 31 + Scenario.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "FeatureChild{" + + "rule=" + Rule + + ", background=" + Background + + ", scenario=" + Scenario + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/GherkinDocument.cs b/dotnet/Cucumber.Messages/generated/GherkinDocument.cs new file mode 100644 index 00000000..162c5e51 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/GherkinDocument.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the GherkinDocument message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * The [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) of a Gherkin document. + * Cucumber implementations should *not* depend on `GherkinDocument` or any of its + * children for execution - use [Pickle](#io.cucumber.messages.Pickle) instead. + * + * The only consumers of `GherkinDocument` should only be formatters that produce + * "rich" output, resembling the original Gherkin document. + */ + +public sealed class GherkinDocument +{ + /** + * The [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) + * of the source, typically a file path relative to the root directory + */ + public string Uri { get; private set; } + public Feature Feature { get; private set; } + /** + * All the comments in the Gherkin document + */ + public List Comments { get; private set; } + + + public GherkinDocument( + string uri, + Feature feature, + List comments + ) + { + this.Uri = uri; + this.Feature = feature; + RequireNonNull>(comments, "Comments", "GherkinDocument.Comments cannot be null"); + this.Comments = new List(comments); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + GherkinDocument that = (GherkinDocument) o; + return + Object.Equals(Uri, that.Uri) && + Object.Equals(Feature, that.Feature) && + Comments.Equals(that.Comments); + } + + public override int GetHashCode() + { + int hash = 17; + if (Uri != null) + hash = hash * 31 + Uri.GetHashCode(); + if (Feature != null) + hash = hash * 31 + Feature.GetHashCode(); + if (Comments != null) + hash = hash * 31 + Comments.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "GherkinDocument{" + + "uri=" + Uri + + ", feature=" + Feature + + ", comments=" + Comments + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Git.cs b/dotnet/Cucumber.Messages/generated/Git.cs new file mode 100644 index 00000000..08e160a3 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Git.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Git message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * Information about Git, provided by the Build/CI server as environment + * variables. + */ + +public sealed class Git +{ + public string Remote { get; private set; } + public string Revision { get; private set; } + public string Branch { get; private set; } + public string Tag { get; private set; } + + + public Git( + string remote, + string revision, + string branch, + string tag + ) + { + RequireNonNull(remote, "Remote", "Git.Remote cannot be null"); + this.Remote = remote; + RequireNonNull(revision, "Revision", "Git.Revision cannot be null"); + this.Revision = revision; + this.Branch = branch; + this.Tag = tag; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Git that = (Git) o; + return + Remote.Equals(that.Remote) && + Revision.Equals(that.Revision) && + Object.Equals(Branch, that.Branch) && + Object.Equals(Tag, that.Tag); + } + + public override int GetHashCode() + { + int hash = 17; + if (Remote != null) + hash = hash * 31 + Remote.GetHashCode(); + if (Revision != null) + hash = hash * 31 + Revision.GetHashCode(); + if (Branch != null) + hash = hash * 31 + Branch.GetHashCode(); + if (Tag != null) + hash = hash * 31 + Tag.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Git{" + + "remote=" + Remote + + ", revision=" + Revision + + ", branch=" + Branch + + ", tag=" + Tag + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Group.cs b/dotnet/Cucumber.Messages/generated/Group.cs new file mode 100644 index 00000000..eedde3c6 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Group.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Group message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class Group +{ + public List Children { get; private set; } + public Nullable Start { get; private set; } + public string Value { get; private set; } + + + public Group( + List children, + Nullable start, + string value + ) + { + RequireNonNull>(children, "Children", "Group.Children cannot be null"); + this.Children = new List(children); + this.Start = start; + this.Value = value; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Group that = (Group) o; + return + Children.Equals(that.Children) && + Object.Equals(Start, that.Start) && + Object.Equals(Value, that.Value); + } + + public override int GetHashCode() + { + int hash = 17; + if (Children != null) + hash = hash * 31 + Children.GetHashCode(); + if (Start.HasValue) + hash = hash * 31 + Start.Value.GetHashCode(); + if (Value != null) + hash = hash * 31 + Value.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Group{" + + "children=" + Children + + (Start.HasValue ? ", start=" + Start.Value : "") + + ", value=" + Value + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Hook.cs b/dotnet/Cucumber.Messages/generated/Hook.cs new file mode 100644 index 00000000..4c5e5c77 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Hook.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Hook message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class Hook +{ + public string Id { get; private set; } + public string Name { get; private set; } + public SourceReference SourceReference { get; private set; } + public string TagExpression { get; private set; } + + + public Hook( + string id, + string name, + SourceReference sourceReference, + string tagExpression + ) + { + RequireNonNull(id, "Id", "Hook.Id cannot be null"); + this.Id = id; + this.Name = name; + RequireNonNull(sourceReference, "SourceReference", "Hook.SourceReference cannot be null"); + this.SourceReference = sourceReference; + this.TagExpression = tagExpression; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Hook that = (Hook) o; + return + Id.Equals(that.Id) && + Object.Equals(Name, that.Name) && + SourceReference.Equals(that.SourceReference) && + Object.Equals(TagExpression, that.TagExpression); + } + + public override int GetHashCode() + { + int hash = 17; + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (SourceReference != null) + hash = hash * 31 + SourceReference.GetHashCode(); + if (TagExpression != null) + hash = hash * 31 + TagExpression.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Hook{" + + "id=" + Id + + ", name=" + Name + + ", sourceReference=" + SourceReference + + ", tagExpression=" + TagExpression + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/JavaMethod.cs b/dotnet/Cucumber.Messages/generated/JavaMethod.cs new file mode 100644 index 00000000..b8284942 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/JavaMethod.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the JavaMethod message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class JavaMethod +{ + public string ClassName { get; private set; } + public string MethodName { get; private set; } + public List MethodParameterTypes { get; private set; } + + + public JavaMethod( + string className, + string methodName, + List methodParameterTypes + ) + { + RequireNonNull(className, "ClassName", "JavaMethod.ClassName cannot be null"); + this.ClassName = className; + RequireNonNull(methodName, "MethodName", "JavaMethod.MethodName cannot be null"); + this.MethodName = methodName; + RequireNonNull>(methodParameterTypes, "MethodParameterTypes", "JavaMethod.MethodParameterTypes cannot be null"); + this.MethodParameterTypes = new List(methodParameterTypes); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + JavaMethod that = (JavaMethod) o; + return + ClassName.Equals(that.ClassName) && + MethodName.Equals(that.MethodName) && + MethodParameterTypes.Equals(that.MethodParameterTypes); + } + + public override int GetHashCode() + { + int hash = 17; + if (ClassName != null) + hash = hash * 31 + ClassName.GetHashCode(); + if (MethodName != null) + hash = hash * 31 + MethodName.GetHashCode(); + if (MethodParameterTypes != null) + hash = hash * 31 + MethodParameterTypes.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "JavaMethod{" + + "className=" + ClassName + + ", methodName=" + MethodName + + ", methodParameterTypes=" + MethodParameterTypes + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/JavaStackTraceElement.cs b/dotnet/Cucumber.Messages/generated/JavaStackTraceElement.cs new file mode 100644 index 00000000..6c4276de --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/JavaStackTraceElement.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the JavaStackTraceElement message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class JavaStackTraceElement +{ + public string ClassName { get; private set; } + public string FileName { get; private set; } + public string MethodName { get; private set; } + + + public JavaStackTraceElement( + string className, + string fileName, + string methodName + ) + { + RequireNonNull(className, "ClassName", "JavaStackTraceElement.ClassName cannot be null"); + this.ClassName = className; + RequireNonNull(fileName, "FileName", "JavaStackTraceElement.FileName cannot be null"); + this.FileName = fileName; + RequireNonNull(methodName, "MethodName", "JavaStackTraceElement.MethodName cannot be null"); + this.MethodName = methodName; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + JavaStackTraceElement that = (JavaStackTraceElement) o; + return + ClassName.Equals(that.ClassName) && + FileName.Equals(that.FileName) && + MethodName.Equals(that.MethodName); + } + + public override int GetHashCode() + { + int hash = 17; + if (ClassName != null) + hash = hash * 31 + ClassName.GetHashCode(); + if (FileName != null) + hash = hash * 31 + FileName.GetHashCode(); + if (MethodName != null) + hash = hash * 31 + MethodName.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "JavaStackTraceElement{" + + "className=" + ClassName + + ", fileName=" + FileName + + ", methodName=" + MethodName + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Location.cs b/dotnet/Cucumber.Messages/generated/Location.cs new file mode 100644 index 00000000..ef935bd3 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Location.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Location message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * Points to a line and a column in a text file + */ + +public sealed class Location +{ + public long Line { get; private set; } + public Nullable Column { get; private set; } + + + public Location( + long line, + Nullable column + ) + { + RequireNonNull(line, "Line", "Location.Line cannot be null"); + this.Line = line; + this.Column = column; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Location that = (Location) o; + return + Line.Equals(that.Line) && + Object.Equals(Column, that.Column); + } + + public override int GetHashCode() + { + int hash = 17; + hash = hash * 31 + Line.GetHashCode(); + if (Column.HasValue) + hash = hash * 31 + Column.Value.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Location{" + + "line=" + Line + + (Column.HasValue ? ", column=" + Column.Value : "") + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Meta.cs b/dotnet/Cucumber.Messages/generated/Meta.cs new file mode 100644 index 00000000..0116baa1 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Meta.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Meta message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * This message contains meta information about the environment. Consumers can use + * this for various purposes. + */ + +public sealed class Meta +{ + /** + * The [SEMVER](https://semver.org/) version number of the protocol + */ + public string ProtocolVersion { get; private set; } + /** + * SpecFlow, Cucumber-JVM, Cucumber.js, Cucumber-Ruby, Behat etc. + */ + public Product Implementation { get; private set; } + /** + * Java, Ruby, Node.js etc + */ + public Product Runtime { get; private set; } + /** + * Windows, Linux, MacOS etc + */ + public Product Os { get; private set; } + /** + * 386, arm, amd64 etc + */ + public Product Cpu { get; private set; } + public Ci Ci { get; private set; } + + + public Meta( + string protocolVersion, + Product implementation, + Product runtime, + Product os, + Product cpu, + Ci ci + ) + { + RequireNonNull(protocolVersion, "ProtocolVersion", "Meta.ProtocolVersion cannot be null"); + this.ProtocolVersion = protocolVersion; + RequireNonNull(implementation, "Implementation", "Meta.Implementation cannot be null"); + this.Implementation = implementation; + RequireNonNull(runtime, "Runtime", "Meta.Runtime cannot be null"); + this.Runtime = runtime; + RequireNonNull(os, "Os", "Meta.Os cannot be null"); + this.Os = os; + RequireNonNull(cpu, "Cpu", "Meta.Cpu cannot be null"); + this.Cpu = cpu; + this.Ci = ci; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Meta that = (Meta) o; + return + ProtocolVersion.Equals(that.ProtocolVersion) && + Implementation.Equals(that.Implementation) && + Runtime.Equals(that.Runtime) && + Os.Equals(that.Os) && + Cpu.Equals(that.Cpu) && + Object.Equals(Ci, that.Ci); + } + + public override int GetHashCode() + { + int hash = 17; + if (ProtocolVersion != null) + hash = hash * 31 + ProtocolVersion.GetHashCode(); + if (Implementation != null) + hash = hash * 31 + Implementation.GetHashCode(); + if (Runtime != null) + hash = hash * 31 + Runtime.GetHashCode(); + if (Os != null) + hash = hash * 31 + Os.GetHashCode(); + if (Cpu != null) + hash = hash * 31 + Cpu.GetHashCode(); + if (Ci != null) + hash = hash * 31 + Ci.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Meta{" + + "protocolVersion=" + ProtocolVersion + + ", implementation=" + Implementation + + ", runtime=" + Runtime + + ", os=" + Os + + ", cpu=" + Cpu + + ", ci=" + Ci + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/ParameterType.cs b/dotnet/Cucumber.Messages/generated/ParameterType.cs new file mode 100644 index 00000000..be0c64ae --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/ParameterType.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the ParameterType message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class ParameterType +{ + /** + * The name is unique, so we don't need an id. + */ + public string Name { get; private set; } + public List RegularExpressions { get; private set; } + public bool PreferForRegularExpressionMatch { get; private set; } + public bool UseForSnippets { get; private set; } + public string Id { get; private set; } + public SourceReference SourceReference { get; private set; } + + + public ParameterType( + string name, + List regularExpressions, + bool preferForRegularExpressionMatch, + bool useForSnippets, + string id, + SourceReference sourceReference + ) + { + RequireNonNull(name, "Name", "ParameterType.Name cannot be null"); + this.Name = name; + RequireNonNull>(regularExpressions, "RegularExpressions", "ParameterType.RegularExpressions cannot be null"); + this.RegularExpressions = new List(regularExpressions); + RequireNonNull(preferForRegularExpressionMatch, "PreferForRegularExpressionMatch", "ParameterType.PreferForRegularExpressionMatch cannot be null"); + this.PreferForRegularExpressionMatch = preferForRegularExpressionMatch; + RequireNonNull(useForSnippets, "UseForSnippets", "ParameterType.UseForSnippets cannot be null"); + this.UseForSnippets = useForSnippets; + RequireNonNull(id, "Id", "ParameterType.Id cannot be null"); + this.Id = id; + this.SourceReference = sourceReference; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + ParameterType that = (ParameterType) o; + return + Name.Equals(that.Name) && + RegularExpressions.Equals(that.RegularExpressions) && + PreferForRegularExpressionMatch.Equals(that.PreferForRegularExpressionMatch) && + UseForSnippets.Equals(that.UseForSnippets) && + Id.Equals(that.Id) && + Object.Equals(SourceReference, that.SourceReference); + } + + public override int GetHashCode() + { + int hash = 17; + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (RegularExpressions != null) + hash = hash * 31 + RegularExpressions.GetHashCode(); + hash = hash * 31 + PreferForRegularExpressionMatch.GetHashCode(); + hash = hash * 31 + UseForSnippets.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + if (SourceReference != null) + hash = hash * 31 + SourceReference.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "ParameterType{" + + "name=" + Name + + ", regularExpressions=" + RegularExpressions + + ", preferForRegularExpressionMatch=" + PreferForRegularExpressionMatch + + ", useForSnippets=" + UseForSnippets + + ", id=" + Id + + ", sourceReference=" + SourceReference + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/ParseError.cs b/dotnet/Cucumber.Messages/generated/ParseError.cs new file mode 100644 index 00000000..68cac6ff --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/ParseError.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the ParseError message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class ParseError +{ + public SourceReference Source { get; private set; } + public string Message { get; private set; } + + + public ParseError( + SourceReference source, + string message + ) + { + RequireNonNull(source, "Source", "ParseError.Source cannot be null"); + this.Source = source; + RequireNonNull(message, "Message", "ParseError.Message cannot be null"); + this.Message = message; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + ParseError that = (ParseError) o; + return + Source.Equals(that.Source) && + Message.Equals(that.Message); + } + + public override int GetHashCode() + { + int hash = 17; + if (Source != null) + hash = hash * 31 + Source.GetHashCode(); + if (Message != null) + hash = hash * 31 + Message.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "ParseError{" + + "source=" + Source + + ", message=" + Message + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Pickle.cs b/dotnet/Cucumber.Messages/generated/Pickle.cs new file mode 100644 index 00000000..dddf1203 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Pickle.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Pickle message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * //// Pickles + * + * A `Pickle` represents a template for a `TestCase`. It is typically derived + * from another format, such as [GherkinDocument](#io.cucumber.messages.GherkinDocument). + * In the future a `Pickle` may be derived from other formats such as Markdown or + * Excel files. + * + * By making `Pickle` the main data structure Cucumber uses for execution, the + * implementation of Cucumber itself becomes simpler, as it doesn't have to deal + * with the complex structure of a [GherkinDocument](#io.cucumber.messages.GherkinDocument). + * + * Each `PickleStep` of a `Pickle` is matched with a `StepDefinition` to create a `TestCase` + */ + +public sealed class Pickle +{ + /** + * A unique id for the pickle + */ + public string Id { get; private set; } + /** + * The uri of the source file + */ + public string Uri { get; private set; } + /** + * The name of the pickle + */ + public string Name { get; private set; } + /** + * The language of the pickle + */ + public string Language { get; private set; } + /** + * One or more steps + */ + public List Steps { get; private set; } + /** + * One or more tags. If this pickle is constructed from a Gherkin document, + * It includes inherited tags from the `Feature` as well. + */ + public List Tags { get; private set; } + /** + * Points to the AST node locations of the pickle. The last one represents the unique + * id of the pickle. A pickle constructed from `Examples` will have the first + * id originating from the `Scenario` AST node, and the second from the `TableRow` AST node. + */ + public List AstNodeIds { get; private set; } + + + public Pickle( + string id, + string uri, + string name, + string language, + List steps, + List tags, + List astNodeIds + ) + { + RequireNonNull(id, "Id", "Pickle.Id cannot be null"); + this.Id = id; + RequireNonNull(uri, "Uri", "Pickle.Uri cannot be null"); + this.Uri = uri; + RequireNonNull(name, "Name", "Pickle.Name cannot be null"); + this.Name = name; + RequireNonNull(language, "Language", "Pickle.Language cannot be null"); + this.Language = language; + RequireNonNull>(steps, "Steps", "Pickle.Steps cannot be null"); + this.Steps = new List(steps); + RequireNonNull>(tags, "Tags", "Pickle.Tags cannot be null"); + this.Tags = new List(tags); + RequireNonNull>(astNodeIds, "AstNodeIds", "Pickle.AstNodeIds cannot be null"); + this.AstNodeIds = new List(astNodeIds); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Pickle that = (Pickle) o; + return + Id.Equals(that.Id) && + Uri.Equals(that.Uri) && + Name.Equals(that.Name) && + Language.Equals(that.Language) && + Steps.Equals(that.Steps) && + Tags.Equals(that.Tags) && + AstNodeIds.Equals(that.AstNodeIds); + } + + public override int GetHashCode() + { + int hash = 17; + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + if (Uri != null) + hash = hash * 31 + Uri.GetHashCode(); + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (Language != null) + hash = hash * 31 + Language.GetHashCode(); + if (Steps != null) + hash = hash * 31 + Steps.GetHashCode(); + if (Tags != null) + hash = hash * 31 + Tags.GetHashCode(); + if (AstNodeIds != null) + hash = hash * 31 + AstNodeIds.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Pickle{" + + "id=" + Id + + ", uri=" + Uri + + ", name=" + Name + + ", language=" + Language + + ", steps=" + Steps + + ", tags=" + Tags + + ", astNodeIds=" + AstNodeIds + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/PickleDocString.cs b/dotnet/Cucumber.Messages/generated/PickleDocString.cs new file mode 100644 index 00000000..8afc2da5 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/PickleDocString.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the PickleDocString message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class PickleDocString +{ + public string MediaType { get; private set; } + public string Content { get; private set; } + + + public PickleDocString( + string mediaType, + string content + ) + { + this.MediaType = mediaType; + RequireNonNull(content, "Content", "PickleDocString.Content cannot be null"); + this.Content = content; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + PickleDocString that = (PickleDocString) o; + return + Object.Equals(MediaType, that.MediaType) && + Content.Equals(that.Content); + } + + public override int GetHashCode() + { + int hash = 17; + if (MediaType != null) + hash = hash * 31 + MediaType.GetHashCode(); + if (Content != null) + hash = hash * 31 + Content.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "PickleDocString{" + + "mediaType=" + MediaType + + ", content=" + Content + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/PickleStep.cs b/dotnet/Cucumber.Messages/generated/PickleStep.cs new file mode 100644 index 00000000..b55028a1 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/PickleStep.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the PickleStep message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * An executable step + */ + +public sealed class PickleStep +{ + public PickleStepArgument Argument { get; private set; } + /** + * References the IDs of the source of the step. For Gherkin, this can be + * the ID of a Step, and possibly also the ID of a TableRow + */ + public List AstNodeIds { get; private set; } + /** + * A unique ID for the PickleStep + */ + public string Id { get; private set; } + /** + * The context in which the step was specified: context (Given), action (When) or outcome (Then). + * + * Note that the keywords `But` and `And` inherit their meaning from prior steps and the `*` 'keyword' doesn't have specific meaning (hence Unknown) + */ + public PickleStepType Type { get; private set; } + public string Text { get; private set; } + + + public PickleStep( + PickleStepArgument argument, + List astNodeIds, + string id, + PickleStepType type, + string text + ) + { + this.Argument = argument; + RequireNonNull>(astNodeIds, "AstNodeIds", "PickleStep.AstNodeIds cannot be null"); + this.AstNodeIds = new List(astNodeIds); + RequireNonNull(id, "Id", "PickleStep.Id cannot be null"); + this.Id = id; + this.Type = type; + RequireNonNull(text, "Text", "PickleStep.Text cannot be null"); + this.Text = text; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + PickleStep that = (PickleStep) o; + return + Object.Equals(Argument, that.Argument) && + AstNodeIds.Equals(that.AstNodeIds) && + Id.Equals(that.Id) && + Object.Equals(Type, that.Type) && + Text.Equals(that.Text); + } + + public override int GetHashCode() + { + int hash = 17; + if (Argument != null) + hash = hash * 31 + Argument.GetHashCode(); + if (AstNodeIds != null) + hash = hash * 31 + AstNodeIds.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + hash = hash * 31 + Type.GetHashCode(); + if (Text != null) + hash = hash * 31 + Text.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "PickleStep{" + + "argument=" + Argument + + ", astNodeIds=" + AstNodeIds + + ", id=" + Id + + ", type=" + Type + + ", text=" + Text + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/PickleStepArgument.cs b/dotnet/Cucumber.Messages/generated/PickleStepArgument.cs new file mode 100644 index 00000000..81201941 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/PickleStepArgument.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the PickleStepArgument message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * An optional argument + */ + +public sealed class PickleStepArgument +{ + public PickleDocString DocString { get; private set; } + public PickleTable DataTable { get; private set; } + + + public static PickleStepArgument Create(PickleDocString docString) + { + return new PickleStepArgument( + Require(docString, "DocString", "PickleStepArgument.DocString cannot be null"), + null + ); + } + + public static PickleStepArgument Create(PickleTable dataTable) + { + return new PickleStepArgument( + null, + Require(dataTable, "DataTable", "PickleStepArgument.DataTable cannot be null") + ); + } + + public PickleStepArgument( + PickleDocString docString, + PickleTable dataTable + ) + { + this.DocString = docString; + this.DataTable = dataTable; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + PickleStepArgument that = (PickleStepArgument) o; + return + Object.Equals(DocString, that.DocString) && + Object.Equals(DataTable, that.DataTable); + } + + public override int GetHashCode() + { + int hash = 17; + if (DocString != null) + hash = hash * 31 + DocString.GetHashCode(); + if (DataTable != null) + hash = hash * 31 + DataTable.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "PickleStepArgument{" + + "docString=" + DocString + + ", dataTable=" + DataTable + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/PickleStepType.cs b/dotnet/Cucumber.Messages/generated/PickleStepType.cs new file mode 100644 index 00000000..4c064362 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/PickleStepType.cs @@ -0,0 +1,29 @@ +using System; +using System.ComponentModel; +using System.Reflection; + +namespace Io.Cucumber.Messages.Types; + +// Generated code +public enum PickleStepType { + + [Description("Unknown")] + UNKNOWN, + + [Description("Context")] + CONTEXT, + + [Description("Action")] + ACTION, + + [Description("Outcome")] + OUTCOME +} + +public static class PickleStepTypeExtensions +{ + public static string Value(this PickleStepType v) { + var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); + return attribute == null ? v.ToString() : attribute.Description; + } +} diff --git a/dotnet/Cucumber.Messages/generated/PickleTable.cs b/dotnet/Cucumber.Messages/generated/PickleTable.cs new file mode 100644 index 00000000..cc68ac1b --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/PickleTable.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the PickleTable message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class PickleTable +{ + public List Rows { get; private set; } + + + public PickleTable( + List rows + ) + { + RequireNonNull>(rows, "Rows", "PickleTable.Rows cannot be null"); + this.Rows = new List(rows); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + PickleTable that = (PickleTable) o; + return + Rows.Equals(that.Rows); + } + + public override int GetHashCode() + { + int hash = 17; + if (Rows != null) + hash = hash * 31 + Rows.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "PickleTable{" + + "rows=" + Rows + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/PickleTableCell.cs b/dotnet/Cucumber.Messages/generated/PickleTableCell.cs new file mode 100644 index 00000000..cc850abe --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/PickleTableCell.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the PickleTableCell message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class PickleTableCell +{ + public string Value { get; private set; } + + + public PickleTableCell( + string value + ) + { + RequireNonNull(value, "Value", "PickleTableCell.Value cannot be null"); + this.Value = value; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + PickleTableCell that = (PickleTableCell) o; + return + Value.Equals(that.Value); + } + + public override int GetHashCode() + { + int hash = 17; + if (Value != null) + hash = hash * 31 + Value.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "PickleTableCell{" + + "value=" + Value + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/PickleTableRow.cs b/dotnet/Cucumber.Messages/generated/PickleTableRow.cs new file mode 100644 index 00000000..121050ff --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/PickleTableRow.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the PickleTableRow message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class PickleTableRow +{ + public List Cells { get; private set; } + + + public PickleTableRow( + List cells + ) + { + RequireNonNull>(cells, "Cells", "PickleTableRow.Cells cannot be null"); + this.Cells = new List(cells); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + PickleTableRow that = (PickleTableRow) o; + return + Cells.Equals(that.Cells); + } + + public override int GetHashCode() + { + int hash = 17; + if (Cells != null) + hash = hash * 31 + Cells.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "PickleTableRow{" + + "cells=" + Cells + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/PickleTag.cs b/dotnet/Cucumber.Messages/generated/PickleTag.cs new file mode 100644 index 00000000..2f07e815 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/PickleTag.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the PickleTag message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A tag + */ + +public sealed class PickleTag +{ + public string Name { get; private set; } + /** + * Points to the AST node this was created from + */ + public string AstNodeId { get; private set; } + + + public PickleTag( + string name, + string astNodeId + ) + { + RequireNonNull(name, "Name", "PickleTag.Name cannot be null"); + this.Name = name; + RequireNonNull(astNodeId, "AstNodeId", "PickleTag.AstNodeId cannot be null"); + this.AstNodeId = astNodeId; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + PickleTag that = (PickleTag) o; + return + Name.Equals(that.Name) && + AstNodeId.Equals(that.AstNodeId); + } + + public override int GetHashCode() + { + int hash = 17; + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (AstNodeId != null) + hash = hash * 31 + AstNodeId.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "PickleTag{" + + "name=" + Name + + ", astNodeId=" + AstNodeId + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Product.cs b/dotnet/Cucumber.Messages/generated/Product.cs new file mode 100644 index 00000000..dc398ff7 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Product.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Product message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * Used to describe various properties of Meta + */ + +public sealed class Product +{ + /** + * The product name + */ + public string Name { get; private set; } + /** + * The product version + */ + public string Version { get; private set; } + + + public Product( + string name, + string version + ) + { + RequireNonNull(name, "Name", "Product.Name cannot be null"); + this.Name = name; + this.Version = version; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Product that = (Product) o; + return + Name.Equals(that.Name) && + Object.Equals(Version, that.Version); + } + + public override int GetHashCode() + { + int hash = 17; + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (Version != null) + hash = hash * 31 + Version.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Product{" + + "name=" + Name + + ", version=" + Version + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Rule.cs b/dotnet/Cucumber.Messages/generated/Rule.cs new file mode 100644 index 00000000..a9843168 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Rule.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Rule message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class Rule +{ + /** + * The location of the `Rule` keyword + */ + public Location Location { get; private set; } + /** + * All the tags placed above the `Rule` keyword + */ + public List Tags { get; private set; } + public string Keyword { get; private set; } + public string Name { get; private set; } + public string Description { get; private set; } + public List Children { get; private set; } + public string Id { get; private set; } + + + public Rule( + Location location, + List tags, + string keyword, + string name, + string description, + List children, + string id + ) + { + RequireNonNull(location, "Location", "Rule.Location cannot be null"); + this.Location = location; + RequireNonNull>(tags, "Tags", "Rule.Tags cannot be null"); + this.Tags = new List(tags); + RequireNonNull(keyword, "Keyword", "Rule.Keyword cannot be null"); + this.Keyword = keyword; + RequireNonNull(name, "Name", "Rule.Name cannot be null"); + this.Name = name; + RequireNonNull(description, "Description", "Rule.Description cannot be null"); + this.Description = description; + RequireNonNull>(children, "Children", "Rule.Children cannot be null"); + this.Children = new List(children); + RequireNonNull(id, "Id", "Rule.Id cannot be null"); + this.Id = id; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Rule that = (Rule) o; + return + Location.Equals(that.Location) && + Tags.Equals(that.Tags) && + Keyword.Equals(that.Keyword) && + Name.Equals(that.Name) && + Description.Equals(that.Description) && + Children.Equals(that.Children) && + Id.Equals(that.Id); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Tags != null) + hash = hash * 31 + Tags.GetHashCode(); + if (Keyword != null) + hash = hash * 31 + Keyword.GetHashCode(); + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (Description != null) + hash = hash * 31 + Description.GetHashCode(); + if (Children != null) + hash = hash * 31 + Children.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Rule{" + + "location=" + Location + + ", tags=" + Tags + + ", keyword=" + Keyword + + ", name=" + Name + + ", description=" + Description + + ", children=" + Children + + ", id=" + Id + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/RuleChild.cs b/dotnet/Cucumber.Messages/generated/RuleChild.cs new file mode 100644 index 00000000..daf5465f --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/RuleChild.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the RuleChild message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A child node of a `Rule` node + */ + +public sealed class RuleChild +{ + public Background Background { get; private set; } + public Scenario Scenario { get; private set; } + + + public static RuleChild Create(Background background) + { + return new RuleChild( + Require(background, "Background", "RuleChild.Background cannot be null"), + null + ); + } + + public static RuleChild Create(Scenario scenario) + { + return new RuleChild( + null, + Require(scenario, "Scenario", "RuleChild.Scenario cannot be null") + ); + } + + public RuleChild( + Background background, + Scenario scenario + ) + { + this.Background = background; + this.Scenario = scenario; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + RuleChild that = (RuleChild) o; + return + Object.Equals(Background, that.Background) && + Object.Equals(Scenario, that.Scenario); + } + + public override int GetHashCode() + { + int hash = 17; + if (Background != null) + hash = hash * 31 + Background.GetHashCode(); + if (Scenario != null) + hash = hash * 31 + Scenario.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "RuleChild{" + + "background=" + Background + + ", scenario=" + Scenario + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Scenario.cs b/dotnet/Cucumber.Messages/generated/Scenario.cs new file mode 100644 index 00000000..67c81dcc --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Scenario.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Scenario message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class Scenario +{ + /** + * The location of the `Scenario` keyword + */ + public Location Location { get; private set; } + public List Tags { get; private set; } + public string Keyword { get; private set; } + public string Name { get; private set; } + public string Description { get; private set; } + public List Steps { get; private set; } + public List Examples { get; private set; } + public string Id { get; private set; } + + + public Scenario( + Location location, + List tags, + string keyword, + string name, + string description, + List steps, + List examples, + string id + ) + { + RequireNonNull(location, "Location", "Scenario.Location cannot be null"); + this.Location = location; + RequireNonNull>(tags, "Tags", "Scenario.Tags cannot be null"); + this.Tags = new List(tags); + RequireNonNull(keyword, "Keyword", "Scenario.Keyword cannot be null"); + this.Keyword = keyword; + RequireNonNull(name, "Name", "Scenario.Name cannot be null"); + this.Name = name; + RequireNonNull(description, "Description", "Scenario.Description cannot be null"); + this.Description = description; + RequireNonNull>(steps, "Steps", "Scenario.Steps cannot be null"); + this.Steps = new List(steps); + RequireNonNull>(examples, "Examples", "Scenario.Examples cannot be null"); + this.Examples = new List(examples); + RequireNonNull(id, "Id", "Scenario.Id cannot be null"); + this.Id = id; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Scenario that = (Scenario) o; + return + Location.Equals(that.Location) && + Tags.Equals(that.Tags) && + Keyword.Equals(that.Keyword) && + Name.Equals(that.Name) && + Description.Equals(that.Description) && + Steps.Equals(that.Steps) && + Examples.Equals(that.Examples) && + Id.Equals(that.Id); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Tags != null) + hash = hash * 31 + Tags.GetHashCode(); + if (Keyword != null) + hash = hash * 31 + Keyword.GetHashCode(); + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (Description != null) + hash = hash * 31 + Description.GetHashCode(); + if (Steps != null) + hash = hash * 31 + Steps.GetHashCode(); + if (Examples != null) + hash = hash * 31 + Examples.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Scenario{" + + "location=" + Location + + ", tags=" + Tags + + ", keyword=" + Keyword + + ", name=" + Name + + ", description=" + Description + + ", steps=" + Steps + + ", examples=" + Examples + + ", id=" + Id + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Source.cs b/dotnet/Cucumber.Messages/generated/Source.cs new file mode 100644 index 00000000..7f5857bd --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Source.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Source message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * //// Source + * + * A source file, typically a Gherkin document or Java/Ruby/JavaScript source code + */ + +public sealed class Source +{ + /** + * The [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) + * of the source, typically a file path relative to the root directory + */ + public string Uri { get; private set; } + /** + * The contents of the file + */ + public string Data { get; private set; } + /** + * The media type of the file. Can be used to specify custom types, such as + * text/x.cucumber.gherkin+plain + */ + public SourceMediaType MediaType { get; private set; } + + + public Source( + string uri, + string data, + SourceMediaType mediaType + ) + { + RequireNonNull(uri, "Uri", "Source.Uri cannot be null"); + this.Uri = uri; + RequireNonNull(data, "Data", "Source.Data cannot be null"); + this.Data = data; + RequireNonNull(mediaType, "MediaType", "Source.MediaType cannot be null"); + this.MediaType = mediaType; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Source that = (Source) o; + return + Uri.Equals(that.Uri) && + Data.Equals(that.Data) && + MediaType.Equals(that.MediaType); + } + + public override int GetHashCode() + { + int hash = 17; + if (Uri != null) + hash = hash * 31 + Uri.GetHashCode(); + if (Data != null) + hash = hash * 31 + Data.GetHashCode(); + hash = hash * 31 + MediaType.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Source{" + + "uri=" + Uri + + ", data=" + Data + + ", mediaType=" + MediaType + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/SourceMediaType.cs b/dotnet/Cucumber.Messages/generated/SourceMediaType.cs new file mode 100644 index 00000000..4bd99e21 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/SourceMediaType.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel; +using System.Reflection; + +namespace Io.Cucumber.Messages.Types; + +// Generated code +public enum SourceMediaType { + + [Description("text/x.cucumber.gherkin+plain")] + TEXT_X_CUCUMBER_GHERKIN_PLAIN, + + [Description("text/x.cucumber.gherkin+markdown")] + TEXT_X_CUCUMBER_GHERKIN_MARKDOWN +} + +public static class SourceMediaTypeExtensions +{ + public static string Value(this SourceMediaType v) { + var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); + return attribute == null ? v.ToString() : attribute.Description; + } +} diff --git a/dotnet/Cucumber.Messages/generated/SourceReference.cs b/dotnet/Cucumber.Messages/generated/SourceReference.cs new file mode 100644 index 00000000..6e3c03b5 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/SourceReference.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the SourceReference message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * Points to a [Source](#io.cucumber.messages.Source) identified by `uri` and a + * [Location](#io.cucumber.messages.Location) within that file. + */ + +public sealed class SourceReference +{ + public string Uri { get; private set; } + public JavaMethod JavaMethod { get; private set; } + public JavaStackTraceElement JavaStackTraceElement { get; private set; } + public Location Location { get; private set; } + + + public static SourceReference Create(string uri) + { + return new SourceReference( + Require(uri, "Uri", "SourceReference.Uri cannot be null"), + null, + null, + null + ); + } + + public static SourceReference Create(JavaMethod javaMethod) + { + return new SourceReference( + null, + Require(javaMethod, "JavaMethod", "SourceReference.JavaMethod cannot be null"), + null, + null + ); + } + + public static SourceReference Create(JavaStackTraceElement javaStackTraceElement) + { + return new SourceReference( + null, + null, + Require(javaStackTraceElement, "JavaStackTraceElement", "SourceReference.JavaStackTraceElement cannot be null"), + null + ); + } + + public static SourceReference Create(Location location) + { + return new SourceReference( + null, + null, + null, + Require(location, "Location", "SourceReference.Location cannot be null") + ); + } + + public SourceReference( + string uri, + JavaMethod javaMethod, + JavaStackTraceElement javaStackTraceElement, + Location location + ) + { + this.Uri = uri; + this.JavaMethod = javaMethod; + this.JavaStackTraceElement = javaStackTraceElement; + this.Location = location; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + SourceReference that = (SourceReference) o; + return + Object.Equals(Uri, that.Uri) && + Object.Equals(JavaMethod, that.JavaMethod) && + Object.Equals(JavaStackTraceElement, that.JavaStackTraceElement) && + Object.Equals(Location, that.Location); + } + + public override int GetHashCode() + { + int hash = 17; + if (Uri != null) + hash = hash * 31 + Uri.GetHashCode(); + if (JavaMethod != null) + hash = hash * 31 + JavaMethod.GetHashCode(); + if (JavaStackTraceElement != null) + hash = hash * 31 + JavaStackTraceElement.GetHashCode(); + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "SourceReference{" + + "uri=" + Uri + + ", javaMethod=" + JavaMethod + + ", javaStackTraceElement=" + JavaStackTraceElement + + ", location=" + Location + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Step.cs b/dotnet/Cucumber.Messages/generated/Step.cs new file mode 100644 index 00000000..cf781728 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Step.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Step message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A step + */ + +public sealed class Step +{ + /** + * The location of the steps' `keyword` + */ + public Location Location { get; private set; } + /** + * The actual keyword as it appeared in the source. + */ + public string Keyword { get; private set; } + /** + * The test phase signalled by the keyword: Context definition (Given), Action performance (When), Outcome assertion (Then). Other keywords signal Continuation (And and But) from a prior keyword. Please note that all translations which a dialect maps to multiple keywords (`*` is in this category for all dialects), map to 'Unknown'. + */ + public StepKeywordType KeywordType { get; private set; } + public string Text { get; private set; } + public DocString DocString { get; private set; } + public DataTable DataTable { get; private set; } + /** + * Unique ID to be able to reference the Step from PickleStep + */ + public string Id { get; private set; } + + + public Step( + Location location, + string keyword, + StepKeywordType keywordType, + string text, + DocString docString, + DataTable dataTable, + string id + ) + { + RequireNonNull(location, "Location", "Step.Location cannot be null"); + this.Location = location; + RequireNonNull(keyword, "Keyword", "Step.Keyword cannot be null"); + this.Keyword = keyword; + this.KeywordType = keywordType; + RequireNonNull(text, "Text", "Step.Text cannot be null"); + this.Text = text; + this.DocString = docString; + this.DataTable = dataTable; + RequireNonNull(id, "Id", "Step.Id cannot be null"); + this.Id = id; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Step that = (Step) o; + return + Location.Equals(that.Location) && + Keyword.Equals(that.Keyword) && + Object.Equals(KeywordType, that.KeywordType) && + Text.Equals(that.Text) && + Object.Equals(DocString, that.DocString) && + Object.Equals(DataTable, that.DataTable) && + Id.Equals(that.Id); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Keyword != null) + hash = hash * 31 + Keyword.GetHashCode(); + hash = hash * 31 + KeywordType.GetHashCode(); + if (Text != null) + hash = hash * 31 + Text.GetHashCode(); + if (DocString != null) + hash = hash * 31 + DocString.GetHashCode(); + if (DataTable != null) + hash = hash * 31 + DataTable.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Step{" + + "location=" + Location + + ", keyword=" + Keyword + + ", keywordType=" + KeywordType + + ", text=" + Text + + ", docString=" + DocString + + ", dataTable=" + DataTable + + ", id=" + Id + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/StepDefinition.cs b/dotnet/Cucumber.Messages/generated/StepDefinition.cs new file mode 100644 index 00000000..6a898fbd --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/StepDefinition.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the StepDefinition message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class StepDefinition +{ + public string Id { get; private set; } + public StepDefinitionPattern Pattern { get; private set; } + public SourceReference SourceReference { get; private set; } + + + public StepDefinition( + string id, + StepDefinitionPattern pattern, + SourceReference sourceReference + ) + { + RequireNonNull(id, "Id", "StepDefinition.Id cannot be null"); + this.Id = id; + RequireNonNull(pattern, "Pattern", "StepDefinition.Pattern cannot be null"); + this.Pattern = pattern; + RequireNonNull(sourceReference, "SourceReference", "StepDefinition.SourceReference cannot be null"); + this.SourceReference = sourceReference; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + StepDefinition that = (StepDefinition) o; + return + Id.Equals(that.Id) && + Pattern.Equals(that.Pattern) && + SourceReference.Equals(that.SourceReference); + } + + public override int GetHashCode() + { + int hash = 17; + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + if (Pattern != null) + hash = hash * 31 + Pattern.GetHashCode(); + if (SourceReference != null) + hash = hash * 31 + SourceReference.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "StepDefinition{" + + "id=" + Id + + ", pattern=" + Pattern + + ", sourceReference=" + SourceReference + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/StepDefinitionPattern.cs b/dotnet/Cucumber.Messages/generated/StepDefinitionPattern.cs new file mode 100644 index 00000000..6691a521 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/StepDefinitionPattern.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the StepDefinitionPattern message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class StepDefinitionPattern +{ + public string Source { get; private set; } + public StepDefinitionPatternType Type { get; private set; } + + + public StepDefinitionPattern( + string source, + StepDefinitionPatternType type + ) + { + RequireNonNull(source, "Source", "StepDefinitionPattern.Source cannot be null"); + this.Source = source; + RequireNonNull(type, "Type", "StepDefinitionPattern.Type cannot be null"); + this.Type = type; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + StepDefinitionPattern that = (StepDefinitionPattern) o; + return + Source.Equals(that.Source) && + Type.Equals(that.Type); + } + + public override int GetHashCode() + { + int hash = 17; + if (Source != null) + hash = hash * 31 + Source.GetHashCode(); + hash = hash * 31 + Type.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "StepDefinitionPattern{" + + "source=" + Source + + ", type=" + Type + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/StepDefinitionPatternType.cs b/dotnet/Cucumber.Messages/generated/StepDefinitionPatternType.cs new file mode 100644 index 00000000..91b8d26a --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/StepDefinitionPatternType.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel; +using System.Reflection; + +namespace Io.Cucumber.Messages.Types; + +// Generated code +public enum StepDefinitionPatternType { + + [Description("CUCUMBER_EXPRESSION")] + CUCUMBER_EXPRESSION, + + [Description("REGULAR_EXPRESSION")] + REGULAR_EXPRESSION +} + +public static class StepDefinitionPatternTypeExtensions +{ + public static string Value(this StepDefinitionPatternType v) { + var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); + return attribute == null ? v.ToString() : attribute.Description; + } +} diff --git a/dotnet/Cucumber.Messages/generated/StepKeywordType.cs b/dotnet/Cucumber.Messages/generated/StepKeywordType.cs new file mode 100644 index 00000000..436988c3 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/StepKeywordType.cs @@ -0,0 +1,32 @@ +using System; +using System.ComponentModel; +using System.Reflection; + +namespace Io.Cucumber.Messages.Types; + +// Generated code +public enum StepKeywordType { + + [Description("Unknown")] + UNKNOWN, + + [Description("Context")] + CONTEXT, + + [Description("Action")] + ACTION, + + [Description("Outcome")] + OUTCOME, + + [Description("Conjunction")] + CONJUNCTION +} + +public static class StepKeywordTypeExtensions +{ + public static string Value(this StepKeywordType v) { + var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); + return attribute == null ? v.ToString() : attribute.Description; + } +} diff --git a/dotnet/Cucumber.Messages/generated/StepMatchArgument.cs b/dotnet/Cucumber.Messages/generated/StepMatchArgument.cs new file mode 100644 index 00000000..8f26fa8b --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/StepMatchArgument.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the StepMatchArgument message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * Represents a single argument extracted from a step match and passed to a step definition. + * This is used for the following purposes: + * - Construct an argument to pass to a step definition (possibly through a parameter type transform) + * - Highlight the matched parameter in rich formatters such as the HTML formatter + * + * This message closely matches the `Argument` class in the `cucumber-expressions` library. + */ + +public sealed class StepMatchArgument +{ + /** + * Represents the outermost capture group of an argument. This message closely matches the + * `Group` class in the `cucumber-expressions` library. + */ + public Group Group { get; private set; } + public string ParameterTypeName { get; private set; } + + + public StepMatchArgument( + Group group, + string parameterTypeName + ) + { + RequireNonNull(group, "Group", "StepMatchArgument.Group cannot be null"); + this.Group = group; + this.ParameterTypeName = parameterTypeName; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + StepMatchArgument that = (StepMatchArgument) o; + return + Group.Equals(that.Group) && + Object.Equals(ParameterTypeName, that.ParameterTypeName); + } + + public override int GetHashCode() + { + int hash = 17; + if (Group != null) + hash = hash * 31 + Group.GetHashCode(); + if (ParameterTypeName != null) + hash = hash * 31 + ParameterTypeName.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "StepMatchArgument{" + + "group=" + Group + + ", parameterTypeName=" + ParameterTypeName + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/StepMatchArgumentsList.cs b/dotnet/Cucumber.Messages/generated/StepMatchArgumentsList.cs new file mode 100644 index 00000000..acf9a932 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/StepMatchArgumentsList.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the StepMatchArgumentsList message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class StepMatchArgumentsList +{ + public List StepMatchArguments { get; private set; } + + + public StepMatchArgumentsList( + List stepMatchArguments + ) + { + RequireNonNull>(stepMatchArguments, "StepMatchArguments", "StepMatchArgumentsList.StepMatchArguments cannot be null"); + this.StepMatchArguments = new List(stepMatchArguments); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + StepMatchArgumentsList that = (StepMatchArgumentsList) o; + return + StepMatchArguments.Equals(that.StepMatchArguments); + } + + public override int GetHashCode() + { + int hash = 17; + if (StepMatchArguments != null) + hash = hash * 31 + StepMatchArguments.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "StepMatchArgumentsList{" + + "stepMatchArguments=" + StepMatchArguments + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TableCell.cs b/dotnet/Cucumber.Messages/generated/TableCell.cs new file mode 100644 index 00000000..42cfe5d2 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TableCell.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TableCell message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A cell in a `TableRow` + */ + +public sealed class TableCell +{ + /** + * The location of the cell + */ + public Location Location { get; private set; } + /** + * The value of the cell + */ + public string Value { get; private set; } + + + public TableCell( + Location location, + string value + ) + { + RequireNonNull(location, "Location", "TableCell.Location cannot be null"); + this.Location = location; + RequireNonNull(value, "Value", "TableCell.Value cannot be null"); + this.Value = value; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TableCell that = (TableCell) o; + return + Location.Equals(that.Location) && + Value.Equals(that.Value); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Value != null) + hash = hash * 31 + Value.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TableCell{" + + "location=" + Location + + ", value=" + Value + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TableRow.cs b/dotnet/Cucumber.Messages/generated/TableRow.cs new file mode 100644 index 00000000..3aa1a717 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TableRow.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TableRow message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A row in a table + */ + +public sealed class TableRow +{ + /** + * The location of the first cell in the row + */ + public Location Location { get; private set; } + /** + * Cells in the row + */ + public List Cells { get; private set; } + public string Id { get; private set; } + + + public TableRow( + Location location, + List cells, + string id + ) + { + RequireNonNull(location, "Location", "TableRow.Location cannot be null"); + this.Location = location; + RequireNonNull>(cells, "Cells", "TableRow.Cells cannot be null"); + this.Cells = new List(cells); + RequireNonNull(id, "Id", "TableRow.Id cannot be null"); + this.Id = id; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TableRow that = (TableRow) o; + return + Location.Equals(that.Location) && + Cells.Equals(that.Cells) && + Id.Equals(that.Id); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Cells != null) + hash = hash * 31 + Cells.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TableRow{" + + "location=" + Location + + ", cells=" + Cells + + ", id=" + Id + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Tag.cs b/dotnet/Cucumber.Messages/generated/Tag.cs new file mode 100644 index 00000000..09b1a08e --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Tag.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Tag message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A tag + */ + +public sealed class Tag +{ + /** + * Location of the tag + */ + public Location Location { get; private set; } + /** + * The name of the tag (including the leading `@`) + */ + public string Name { get; private set; } + /** + * Unique ID to be able to reference the Tag from PickleTag + */ + public string Id { get; private set; } + + + public Tag( + Location location, + string name, + string id + ) + { + RequireNonNull(location, "Location", "Tag.Location cannot be null"); + this.Location = location; + RequireNonNull(name, "Name", "Tag.Name cannot be null"); + this.Name = name; + RequireNonNull(id, "Id", "Tag.Id cannot be null"); + this.Id = id; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Tag that = (Tag) o; + return + Location.Equals(that.Location) && + Name.Equals(that.Name) && + Id.Equals(that.Id); + } + + public override int GetHashCode() + { + int hash = 17; + if (Location != null) + hash = hash * 31 + Location.GetHashCode(); + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Tag{" + + "location=" + Location + + ", name=" + Name + + ", id=" + Id + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestCase.cs b/dotnet/Cucumber.Messages/generated/TestCase.cs new file mode 100644 index 00000000..440457b8 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestCase.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TestCase message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * //// TestCases + * + * A `TestCase` contains a sequence of `TestStep`s. + */ + +public sealed class TestCase +{ + public string Id { get; private set; } + /** + * The ID of the `Pickle` this `TestCase` is derived from. + */ + public string PickleId { get; private set; } + public List TestSteps { get; private set; } + + + public TestCase( + string id, + string pickleId, + List testSteps + ) + { + RequireNonNull(id, "Id", "TestCase.Id cannot be null"); + this.Id = id; + RequireNonNull(pickleId, "PickleId", "TestCase.PickleId cannot be null"); + this.PickleId = pickleId; + RequireNonNull>(testSteps, "TestSteps", "TestCase.TestSteps cannot be null"); + this.TestSteps = new List(testSteps); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TestCase that = (TestCase) o; + return + Id.Equals(that.Id) && + PickleId.Equals(that.PickleId) && + TestSteps.Equals(that.TestSteps); + } + + public override int GetHashCode() + { + int hash = 17; + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + if (PickleId != null) + hash = hash * 31 + PickleId.GetHashCode(); + if (TestSteps != null) + hash = hash * 31 + TestSteps.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TestCase{" + + "id=" + Id + + ", pickleId=" + PickleId + + ", testSteps=" + TestSteps + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestCaseFinished.cs b/dotnet/Cucumber.Messages/generated/TestCaseFinished.cs new file mode 100644 index 00000000..3aeab92c --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestCaseFinished.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TestCaseFinished message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class TestCaseFinished +{ + public string TestCaseStartedId { get; private set; } + public Timestamp Timestamp { get; private set; } + public bool WillBeRetried { get; private set; } + + + public TestCaseFinished( + string testCaseStartedId, + Timestamp timestamp, + bool willBeRetried + ) + { + RequireNonNull(testCaseStartedId, "TestCaseStartedId", "TestCaseFinished.TestCaseStartedId cannot be null"); + this.TestCaseStartedId = testCaseStartedId; + RequireNonNull(timestamp, "Timestamp", "TestCaseFinished.Timestamp cannot be null"); + this.Timestamp = timestamp; + RequireNonNull(willBeRetried, "WillBeRetried", "TestCaseFinished.WillBeRetried cannot be null"); + this.WillBeRetried = willBeRetried; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TestCaseFinished that = (TestCaseFinished) o; + return + TestCaseStartedId.Equals(that.TestCaseStartedId) && + Timestamp.Equals(that.Timestamp) && + WillBeRetried.Equals(that.WillBeRetried); + } + + public override int GetHashCode() + { + int hash = 17; + if (TestCaseStartedId != null) + hash = hash * 31 + TestCaseStartedId.GetHashCode(); + if (Timestamp != null) + hash = hash * 31 + Timestamp.GetHashCode(); + hash = hash * 31 + WillBeRetried.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TestCaseFinished{" + + "testCaseStartedId=" + TestCaseStartedId + + ", timestamp=" + Timestamp + + ", willBeRetried=" + WillBeRetried + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestCaseStarted.cs b/dotnet/Cucumber.Messages/generated/TestCaseStarted.cs new file mode 100644 index 00000000..5d483616 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestCaseStarted.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TestCaseStarted message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class TestCaseStarted +{ + /** + * The first attempt should have value 0, and for each retry the value + * should increase by 1. + */ + public long Attempt { get; private set; } + /** + * Because a `TestCase` can be run multiple times (in case of a retry), + * we use this field to group messages relating to the same attempt. + */ + public string Id { get; private set; } + public string TestCaseId { get; private set; } + /** + * An identifier for the worker process running this test case, if test cases are being run in parallel. The identifier will be unique per worker, but no particular format is defined - it could be an index, uuid, machine name etc - and as such should be assumed that it's not human readable. + */ + public string WorkerId { get; private set; } + public Timestamp Timestamp { get; private set; } + + + public TestCaseStarted( + long attempt, + string id, + string testCaseId, + string workerId, + Timestamp timestamp + ) + { + RequireNonNull(attempt, "Attempt", "TestCaseStarted.Attempt cannot be null"); + this.Attempt = attempt; + RequireNonNull(id, "Id", "TestCaseStarted.Id cannot be null"); + this.Id = id; + RequireNonNull(testCaseId, "TestCaseId", "TestCaseStarted.TestCaseId cannot be null"); + this.TestCaseId = testCaseId; + this.WorkerId = workerId; + RequireNonNull(timestamp, "Timestamp", "TestCaseStarted.Timestamp cannot be null"); + this.Timestamp = timestamp; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TestCaseStarted that = (TestCaseStarted) o; + return + Attempt.Equals(that.Attempt) && + Id.Equals(that.Id) && + TestCaseId.Equals(that.TestCaseId) && + Object.Equals(WorkerId, that.WorkerId) && + Timestamp.Equals(that.Timestamp); + } + + public override int GetHashCode() + { + int hash = 17; + hash = hash * 31 + Attempt.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + if (TestCaseId != null) + hash = hash * 31 + TestCaseId.GetHashCode(); + if (WorkerId != null) + hash = hash * 31 + WorkerId.GetHashCode(); + if (Timestamp != null) + hash = hash * 31 + Timestamp.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TestCaseStarted{" + + "attempt=" + Attempt + + ", id=" + Id + + ", testCaseId=" + TestCaseId + + ", workerId=" + WorkerId + + ", timestamp=" + Timestamp + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestRunFinished.cs b/dotnet/Cucumber.Messages/generated/TestRunFinished.cs new file mode 100644 index 00000000..f5d56804 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestRunFinished.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TestRunFinished message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class TestRunFinished +{ + /** + * An informative message about the test run. Typically additional information about failure, but not necessarily. + */ + public string Message { get; private set; } + /** + * A test run is successful if all steps are either passed or skipped, all before/after hooks passed and no other exceptions where thrown. + */ + public bool Success { get; private set; } + /** + * Timestamp when the TestRun is finished + */ + public Timestamp Timestamp { get; private set; } + /** + * Any exception thrown during the test run, if any. Does not include exceptions thrown while executing steps. + */ + public Exception Exception { get; private set; } + + + public TestRunFinished( + string message, + bool success, + Timestamp timestamp, + Exception exception + ) + { + this.Message = message; + RequireNonNull(success, "Success", "TestRunFinished.Success cannot be null"); + this.Success = success; + RequireNonNull(timestamp, "Timestamp", "TestRunFinished.Timestamp cannot be null"); + this.Timestamp = timestamp; + this.Exception = exception; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TestRunFinished that = (TestRunFinished) o; + return + Object.Equals(Message, that.Message) && + Success.Equals(that.Success) && + Timestamp.Equals(that.Timestamp) && + Object.Equals(Exception, that.Exception); + } + + public override int GetHashCode() + { + int hash = 17; + if (Message != null) + hash = hash * 31 + Message.GetHashCode(); + hash = hash * 31 + Success.GetHashCode(); + if (Timestamp != null) + hash = hash * 31 + Timestamp.GetHashCode(); + if (Exception != null) + hash = hash * 31 + Exception.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TestRunFinished{" + + "message=" + Message + + ", success=" + Success + + ", timestamp=" + Timestamp + + ", exception=" + Exception + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestRunStarted.cs b/dotnet/Cucumber.Messages/generated/TestRunStarted.cs new file mode 100644 index 00000000..4cf6ac69 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestRunStarted.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TestRunStarted message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class TestRunStarted +{ + public Timestamp Timestamp { get; private set; } + + + public TestRunStarted( + Timestamp timestamp + ) + { + RequireNonNull(timestamp, "Timestamp", "TestRunStarted.Timestamp cannot be null"); + this.Timestamp = timestamp; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TestRunStarted that = (TestRunStarted) o; + return + Timestamp.Equals(that.Timestamp); + } + + public override int GetHashCode() + { + int hash = 17; + if (Timestamp != null) + hash = hash * 31 + Timestamp.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TestRunStarted{" + + "timestamp=" + Timestamp + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestStep.cs b/dotnet/Cucumber.Messages/generated/TestStep.cs new file mode 100644 index 00000000..f59719de --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestStep.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TestStep message in Cucumber's message protocol + * @see Github - Cucumber - Messages + * + * A `TestStep` is derived from either a `PickleStep` + * combined with a `StepDefinition`, or from a `Hook`. + */ + +public sealed class TestStep +{ + /** + * Pointer to the `Hook` (if derived from a Hook) + */ + public string HookId { get; private set; } + public string Id { get; private set; } + /** + * Pointer to the `PickleStep` (if derived from a `PickleStep`) + */ + public string PickleStepId { get; private set; } + /** + * Pointer to all the matching `StepDefinition`s (if derived from a `PickleStep`) + */ + public List StepDefinitionIds { get; private set; } + /** + * A list of list of StepMatchArgument (if derived from a `PickleStep`). + * Each element represents a matching step definition. A size of 0 means `UNDEFINED`, + * and a size of 2+ means `AMBIGUOUS` + */ + public List StepMatchArgumentsLists { get; private set; } + + + public TestStep( + string hookId, + string id, + string pickleStepId, + List stepDefinitionIds, + List stepMatchArgumentsLists + ) + { + this.HookId = hookId; + RequireNonNull(id, "Id", "TestStep.Id cannot be null"); + this.Id = id; + this.PickleStepId = pickleStepId; + this.StepDefinitionIds = new List(stepDefinitionIds); + this.StepMatchArgumentsLists = new List(stepMatchArgumentsLists); + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TestStep that = (TestStep) o; + return + Object.Equals(HookId, that.HookId) && + Id.Equals(that.Id) && + Object.Equals(PickleStepId, that.PickleStepId) && + Object.Equals(StepDefinitionIds, that.StepDefinitionIds) && + Object.Equals(StepMatchArgumentsLists, that.StepMatchArgumentsLists); + } + + public override int GetHashCode() + { + int hash = 17; + if (HookId != null) + hash = hash * 31 + HookId.GetHashCode(); + if (Id != null) + hash = hash * 31 + Id.GetHashCode(); + if (PickleStepId != null) + hash = hash * 31 + PickleStepId.GetHashCode(); + if (StepDefinitionIds != null) + hash = hash * 31 + StepDefinitionIds.GetHashCode(); + if (StepMatchArgumentsLists != null) + hash = hash * 31 + StepMatchArgumentsLists.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TestStep{" + + "hookId=" + HookId + + ", id=" + Id + + ", pickleStepId=" + PickleStepId + + ", stepDefinitionIds=" + StepDefinitionIds + + ", stepMatchArgumentsLists=" + StepMatchArgumentsLists + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestStepFinished.cs b/dotnet/Cucumber.Messages/generated/TestStepFinished.cs new file mode 100644 index 00000000..b5e3d6cd --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestStepFinished.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TestStepFinished message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class TestStepFinished +{ + public string TestCaseStartedId { get; private set; } + public string TestStepId { get; private set; } + public TestStepResult TestStepResult { get; private set; } + public Timestamp Timestamp { get; private set; } + + + public TestStepFinished( + string testCaseStartedId, + string testStepId, + TestStepResult testStepResult, + Timestamp timestamp + ) + { + RequireNonNull(testCaseStartedId, "TestCaseStartedId", "TestStepFinished.TestCaseStartedId cannot be null"); + this.TestCaseStartedId = testCaseStartedId; + RequireNonNull(testStepId, "TestStepId", "TestStepFinished.TestStepId cannot be null"); + this.TestStepId = testStepId; + RequireNonNull(testStepResult, "TestStepResult", "TestStepFinished.TestStepResult cannot be null"); + this.TestStepResult = testStepResult; + RequireNonNull(timestamp, "Timestamp", "TestStepFinished.Timestamp cannot be null"); + this.Timestamp = timestamp; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TestStepFinished that = (TestStepFinished) o; + return + TestCaseStartedId.Equals(that.TestCaseStartedId) && + TestStepId.Equals(that.TestStepId) && + TestStepResult.Equals(that.TestStepResult) && + Timestamp.Equals(that.Timestamp); + } + + public override int GetHashCode() + { + int hash = 17; + if (TestCaseStartedId != null) + hash = hash * 31 + TestCaseStartedId.GetHashCode(); + if (TestStepId != null) + hash = hash * 31 + TestStepId.GetHashCode(); + if (TestStepResult != null) + hash = hash * 31 + TestStepResult.GetHashCode(); + if (Timestamp != null) + hash = hash * 31 + Timestamp.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TestStepFinished{" + + "testCaseStartedId=" + TestCaseStartedId + + ", testStepId=" + TestStepId + + ", testStepResult=" + TestStepResult + + ", timestamp=" + Timestamp + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestStepResult.cs b/dotnet/Cucumber.Messages/generated/TestStepResult.cs new file mode 100644 index 00000000..2a39a789 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestStepResult.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TestStepResult message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class TestStepResult +{ + public Duration Duration { get; private set; } + /** + * An arbitrary bit of information that explains this result. This can be a stack trace of anything else. + */ + public string Message { get; private set; } + public TestStepResultStatus Status { get; private set; } + /** + * Exception thrown while executing this step, if any. + */ + public Exception Exception { get; private set; } + + + public TestStepResult( + Duration duration, + string message, + TestStepResultStatus status, + Exception exception + ) + { + RequireNonNull(duration, "Duration", "TestStepResult.Duration cannot be null"); + this.Duration = duration; + this.Message = message; + RequireNonNull(status, "Status", "TestStepResult.Status cannot be null"); + this.Status = status; + this.Exception = exception; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TestStepResult that = (TestStepResult) o; + return + Duration.Equals(that.Duration) && + Object.Equals(Message, that.Message) && + Status.Equals(that.Status) && + Object.Equals(Exception, that.Exception); + } + + public override int GetHashCode() + { + int hash = 17; + if (Duration != null) + hash = hash * 31 + Duration.GetHashCode(); + if (Message != null) + hash = hash * 31 + Message.GetHashCode(); + hash = hash * 31 + Status.GetHashCode(); + if (Exception != null) + hash = hash * 31 + Exception.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TestStepResult{" + + "duration=" + Duration + + ", message=" + Message + + ", status=" + Status + + ", exception=" + Exception + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestStepResultStatus.cs b/dotnet/Cucumber.Messages/generated/TestStepResultStatus.cs new file mode 100644 index 00000000..b7ed6809 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestStepResultStatus.cs @@ -0,0 +1,38 @@ +using System; +using System.ComponentModel; +using System.Reflection; + +namespace Io.Cucumber.Messages.Types; + +// Generated code +public enum TestStepResultStatus { + + [Description("UNKNOWN")] + UNKNOWN, + + [Description("PASSED")] + PASSED, + + [Description("SKIPPED")] + SKIPPED, + + [Description("PENDING")] + PENDING, + + [Description("UNDEFINED")] + UNDEFINED, + + [Description("AMBIGUOUS")] + AMBIGUOUS, + + [Description("FAILED")] + FAILED +} + +public static class TestStepResultStatusExtensions +{ + public static string Value(this TestStepResultStatus v) { + var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); + return attribute == null ? v.ToString() : attribute.Description; + } +} diff --git a/dotnet/Cucumber.Messages/generated/TestStepStarted.cs b/dotnet/Cucumber.Messages/generated/TestStepStarted.cs new file mode 100644 index 00000000..e7b33f50 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/TestStepStarted.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the TestStepStarted message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class TestStepStarted +{ + public string TestCaseStartedId { get; private set; } + public string TestStepId { get; private set; } + public Timestamp Timestamp { get; private set; } + + + public TestStepStarted( + string testCaseStartedId, + string testStepId, + Timestamp timestamp + ) + { + RequireNonNull(testCaseStartedId, "TestCaseStartedId", "TestStepStarted.TestCaseStartedId cannot be null"); + this.TestCaseStartedId = testCaseStartedId; + RequireNonNull(testStepId, "TestStepId", "TestStepStarted.TestStepId cannot be null"); + this.TestStepId = testStepId; + RequireNonNull(timestamp, "Timestamp", "TestStepStarted.Timestamp cannot be null"); + this.Timestamp = timestamp; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + TestStepStarted that = (TestStepStarted) o; + return + TestCaseStartedId.Equals(that.TestCaseStartedId) && + TestStepId.Equals(that.TestStepId) && + Timestamp.Equals(that.Timestamp); + } + + public override int GetHashCode() + { + int hash = 17; + if (TestCaseStartedId != null) + hash = hash * 31 + TestCaseStartedId.GetHashCode(); + if (TestStepId != null) + hash = hash * 31 + TestStepId.GetHashCode(); + if (Timestamp != null) + hash = hash * 31 + Timestamp.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "TestStepStarted{" + + "testCaseStartedId=" + TestCaseStartedId + + ", testStepId=" + TestStepId + + ", timestamp=" + Timestamp + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/Timestamp.cs b/dotnet/Cucumber.Messages/generated/Timestamp.cs new file mode 100644 index 00000000..03860520 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/Timestamp.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the Timestamp message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class Timestamp +{ + /** + * Represents seconds of UTC time since Unix epoch + * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + * 9999-12-31T23:59:59Z inclusive. + */ + public long Seconds { get; private set; } + /** + * Non-negative fractions of a second at nanosecond resolution. Negative + * second values with fractions must still have non-negative nanos values + * that count forward in time. Must be from 0 to 999,999,999 + * inclusive. + */ + public long Nanos { get; private set; } + + + public Timestamp( + long seconds, + long nanos + ) + { + RequireNonNull(seconds, "Seconds", "Timestamp.Seconds cannot be null"); + this.Seconds = seconds; + RequireNonNull(nanos, "Nanos", "Timestamp.Nanos cannot be null"); + this.Nanos = nanos; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + Timestamp that = (Timestamp) o; + return + Seconds.Equals(that.Seconds) && + Nanos.Equals(that.Nanos); + } + + public override int GetHashCode() + { + int hash = 17; + hash = hash * 31 + Seconds.GetHashCode(); + hash = hash * 31 + Nanos.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "Timestamp{" + + "seconds=" + Seconds + + ", nanos=" + Nanos + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Cucumber.Messages/generated/UndefinedParameterType.cs b/dotnet/Cucumber.Messages/generated/UndefinedParameterType.cs new file mode 100644 index 00000000..c20f43d4 --- /dev/null +++ b/dotnet/Cucumber.Messages/generated/UndefinedParameterType.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the UndefinedParameterType message in Cucumber's message protocol + * @see Github - Cucumber - Messages + */ + +public sealed class UndefinedParameterType +{ + public string Expression { get; private set; } + public string Name { get; private set; } + + + public UndefinedParameterType( + string expression, + string name + ) + { + RequireNonNull(expression, "Expression", "UndefinedParameterType.Expression cannot be null"); + this.Expression = expression; + RequireNonNull(name, "Name", "UndefinedParameterType.Name cannot be null"); + this.Name = name; + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + UndefinedParameterType that = (UndefinedParameterType) o; + return + Expression.Equals(that.Expression) && + Name.Equals(that.Name); + } + + public override int GetHashCode() + { + int hash = 17; + if (Expression != null) + hash = hash * 31 + Expression.GetHashCode(); + if (Name != null) + hash = hash * 31 + Name.GetHashCode(); + return hash; + } + + public override string ToString() + { + return "UndefinedParameterType{" + + "expression=" + Expression + + ", name=" + Name + + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} diff --git a/dotnet/Makefile b/dotnet/Makefile index ba45623a..9fc67873 100644 --- a/dotnet/Makefile +++ b/dotnet/Makefile @@ -1,18 +1,24 @@ -include default.mk +schemas = $(shell find ../jsonschema -name "*.json") -.generated: .fixprotoc +.DEFAULT_GOAL = help -.fixprotoc: -ifdef ALPINE - # The protoc bundled in the grpc.tools nuget package doesn't work on Alpine, - # so we overwrite it with the one bundled inside the Docker image. - # In order to prevent nuget from overwriting it again, we first - # download the nuget packages, then we do the copy. - dotnet restore - mkdir -p ~/.nuget/packages/grpc.tools/1.20.1/tools/linux_x64 - cp /usr/bin/protoc ~/.nuget/packages/grpc.tools/1.20.1/tools/linux_x64/protoc -endif - touch $@ +help: ## Show this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \n\nWhere is one of:\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) -clean: - rm -f Cucumber.Messages/Messages.cs .fixprotoc +generate: require .generate-messages ## Generate c# code based on the schemas found in ../jsonschema and using the scripts in ../jsonschema/scripts for the generation + +require: ## Check requirements for the code generation (ruby, csplit and tail are required) + @ruby --version >/dev/null 2>&1 || (echo "ERROR: ruby is required."; exit 1) + @csplit --version >/dev/null 2>&1 || (echo "ERROR: csplit is required."; exit 1) + @tail --version >/dev/null 2>&1 || (echo "ERROR: tail is required."; exit 1) + +clean: ## Remove automatically generated files and related artifacts + rm -rf Cucumber.Messages/generated/*.cs + +.generate-messages: $(schemas) ../jsonschema/scripts/codegen.rb ../jsonschema/scripts/templates/dotnet.dotnet.erb ../jsonschema/scripts/templates/dotnet.enum.dotnet.erb + ruby ../jsonschema/scripts/codegen.rb Dotnet ../jsonschema dotnet.dotnet.erb > Generated.dotnet.tmp + ruby ../jsonschema/scripts/codegen.rb Dotnet ../jsonschema dotnet.enum.dotnet.erb >> Generated.dotnet.tmp + csplit --quiet --prefix=Generated --suffix-format=%02d.dotnet.tmp --elide-empty-files Generated.dotnet.tmp /^[A-Za-z.]*[.]cs/ {*} + rm Generated.dotnet.tmp + rm -rf Cucumber.Messages/generated/*.cs + for file in Generated**; do tail -n +2 $$file > Cucumber.Messages/generated/$$(head -n 1 $$file | tr -d '\r\n'); rm $$file; done \ No newline at end of file diff --git a/dotnet/default.mk b/dotnet/default.mk deleted file mode 100644 index c72d0900..00000000 --- a/dotnet/default.mk +++ /dev/null @@ -1,77 +0,0 @@ -# Please update /.templates/dotnet/default.mk and sync: -# -# source scripts/functions.sh && rsync_files -# -SHELL := /usr/bin/env bash -ALPINE := $(shell which apk 2> /dev/null) -SLN_FILES = $(shell find . -name "*.sln") -CSPROJ_FILES = $(shell find . -name "*.csproj") -CSHARP_SOURCE_FILES = $(shell find . -name "*.cs") - -# https://stackoverflow.com/questions/2483182/recursive-wildcards-in-gnu-make -rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) - -default: .packed -.PHONY: default - -update-dependencies: - @echo -e "\033[0;31mPlease update dependencies for dotnet manually!!\033[0m" -.PHONY: update-dependencies - -pre-release: update-version update-dependencies clean default -.PHONY: pre-release - -update-version: -ifdef NEW_VERSION - ./scripts/update-version -else - @echo -e "\033[0;31mNEW_VERSION is not defined. Can't update version :-(\033[0m" - exit 1 -endif - -.built: $(SLN_FILES) $(CSPROJ_FILES) $(CSHARP_SOURCE_FILES) .generated - dotnet build -c Release -p:SnapshotSuffix="$(SNAPSHOT_SUFFIX)" - touch $@ - -.generated: - touch $@ - -.tested: .built - dotnet test - touch $@ - -.packed: .tested - touch $@ - -# Define SNAPSHOT_SUFFIX to make pre-release: export SNAPSHOT_SUFFIX=beta-1 make publish -publish: .packed -ifdef NUGET_API_KEY - # https://circleci.com/gh/cucumber/cucumber/edit#env-vars - @dotnet nuget push --source https://api.nuget.org/v3/index.json --api-key "${NUGET_API_KEY}" $(shell find */bin/Release/NuGet -name "*.$(NEW_VERSION).nupkg") -else - @echo -e "\033[0;31mNUGET_API_KEY is not defined. Can't publish :-(\033[0m" - exit 1 -endif - -post-release: - @echo "No post-release needed for dotnet" -.PHONY: post-release - -clean: clean-dotnet -.PHONY: clean - -clean-dotnet: - rm -rf .generated .tested .built .packed GeneratedNuGetPackages - rm -rf */bin - rm -rf */obj -.PHONY: clean-dotnet - -### COMMON stuff for all platforms - -BERP_VERSION = 1.3.0 -BERP_GRAMMAR = gherkin.berp - -define berp-generate-parser = --! dotnet tool list --tool-path /usr/bin | grep "berp\s*$(BERP_VERSION)" && dotnet tool update Berp --version $(BERP_VERSION) --tool-path /usr/bin -berp -g $(BERP_GRAMMAR) -t $< -o $@ --noBOM -endef diff --git a/dotnet/messages.proto b/dotnet/messages.proto deleted file mode 100644 index 443fe0c7..00000000 --- a/dotnet/messages.proto +++ /dev/null @@ -1,696 +0,0 @@ -syntax = "proto3"; -package io.cucumber.messages; -option go_package = "messages"; - -// When removing a field, replace it with reserved, rather than deleting the line. -// When adding a field, add it to the end and increment the number by one. -// See https://developers.google.com/protocol-buffers/docs/proto#updating for details - -/** - * All the messages that are passed between different components/processes are Envelope - * messages. - */ -message Envelope { - oneof message { - // Gherkin - Source source = 1; - GherkinDocument gherkin_document = 2; - - // Compiler(s) - Pickle pickle = 3; - - // - StepDefinition step_definition = 4; - Hook hook = 5; - ParameterType parameter_type = 6; - TestCase test_case = 7; - UndefinedParameterType undefined_parameter_type = 8; - - // Execution - TestRunStarted test_run_started = 9; - TestCaseStarted test_case_started = 10; - TestStepStarted test_step_started = 11; - Attachment attachment = 12; - TestStepFinished test_step_finished = 13; - TestCaseFinished test_case_finished = 14; - TestRunFinished test_run_finished = 15; - - // Parsing - ParseError parse_error = 16; - - Meta meta = 17; - } -} - -/** - * This message contains meta information about the environment. Consumers can use - * this for various purposes. - */ -message Meta { - /** - * The [SEMVER](https://semver.org/) version number of the protocol - */ - string protocol_version = 1; - - // SpecFlow, Cucumber-JVM, Cucumber.js, Cucumber-Ruby, Behat etc. - Product implementation = 2; - - // Java, Ruby, Node.js etc - Product runtime = 3; - - // Windows, Linux, MacOS etc - Product os = 4; - - // 386, arm, amd64 etc - Product cpu = 5; - - // CI environment - CI ci = 6; - - // A product has a name and a version - message Product { - // The product name - string name = 1; - // The product version - string version = 2; - } - - message CI { - // Name of the CI product, e.g. "Jenkins", "CircleCI" etc. - string name = 1; - - // Link to the build - string url = 2; - - // Information about Git, provided by the Build/CI server as environment - // variables. - Git git = 3; - - message Git { - string remote = 1; - string revision = 2; - string branch = 3; - string tag = 4; - } - } -} - - -////// Common types - -// From https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/timestamp.proto -message Timestamp { - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - int64 seconds = 1; - - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - int32 nanos = 2; -} - -// The structure is pretty close of the Timestamp one. For clarity, a second type -// of message is used. -message Duration { - int64 seconds = 1; - - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - int32 nanos = 2; -} - -/** - * Points to a line and a column in a text file - */ -message Location { - uint32 line = 1; - uint32 column = 2; -} - -/** - * Points to a [Source](#io.cucumber.messages.Source) identified by `uri` and a - * [Location](#io.cucumber.messages.Location) within that file. - */ -message SourceReference { - oneof reference { - string uri = 1; - JavaMethod java_method = 3; - JavaStackTraceElement java_stack_trace_element = 4; - } - Location location = 2; - - message JavaMethod { - string class_name = 1; - string method_name = 2; - repeated string method_parameter_types = 3; - } - - message JavaStackTraceElement { - string class_name = 1; - string method_name = 2; - string file_name = 3; - } -} - -////// Source - -/** - * A source file, typically a Gherkin document or Java/Ruby/JavaScript source code - */ -message Source { - /** - * The [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) - * of the source, typically a file path relative to the root directory - */ - string uri = 1; - // The contents of the file - string data = 2; - // The media type of the file. Can be used to specify custom types, such as - // text/x.cucumber.gherkin+plain - string media_type = 3; -} - -/** - * The [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) of a Gherkin document. - * Cucumber implementations should *not* depend on `GherkinDocument` or any of its - * children for execution - use [Pickle](#io.cucumber.messages.Pickle) instead. - * - * The only consumers of `GherkinDocument` should only be formatters that produce - * "rich" output, resembling the original Gherkin document. - */ -message GherkinDocument { - /** - * The [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) - * of the source, typically a file path relative to the root directory - */ - string uri = 1; - Feature feature = 2; - // All the comments in the Gherkin document - repeated Comment comments = 3; - - /** - * A comment in a Gherkin document - */ - message Comment { - // The location of the comment - Location location = 1; - // The text of the comment - string text = 2; - } - - /** - * The top level node in the AST - */ - message Feature { - // The location of the `Feature` keyword - Location location = 1; - // All the tags placed above the `Feature` keyword - repeated Tag tags = 2; - // The [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code of the Gherkin document - string language = 3; - // The text of the `Feature` keyword (in the language specified by `language`) - string keyword = 4; - // The name of the feature (the text following the `keyword`) - string name = 5; - // The line(s) underneath the line with the `keyword` that are used as description - string description = 6; - // Zero or more children - repeated FeatureChild children = 7; - - /** - * A tag - */ - message Tag { - // Location of the tag - Location location = 1; - // The name of the tag (including the leading `@`) - string name = 2; - // Unique ID to be able to reference the Tag from PickleTag - string id = 3; - } - - /** - * A child node of a `Feature` node - */ - message FeatureChild { - oneof value { - Rule rule = 1; - Background background = 2; - Scenario scenario = 3; - } - - /** - * A `Rule` node - */ - message Rule { - // The location of the `Rule` keyword - Location location = 1; - string keyword = 2; - string name = 3; - string description = 4; - repeated RuleChild children = 5; - string id = 6; - repeated Tag tags = 7; - } - - message RuleChild { - oneof value { - Background background = 1; - Scenario scenario = 2; - } - } - } - - message Background { - // The location of the `Background` keyword - Location location = 1; - string keyword = 2; - string name = 3; - string description = 4; - repeated Step steps = 5; - string id = 6; - } - - message Scenario { - // The location of the `Scenario` keyword - Location location = 1; - repeated Tag tags = 2; - string keyword = 3; - string name = 4; - string description = 5; - repeated Step steps = 6; - repeated Examples examples = 7; - string id = 8; - - message Examples { - // The location of the `Examples` keyword - Location location = 1; - repeated Tag tags = 2; - string keyword = 3; - string name = 4; - string description = 5; - TableRow table_header = 6; - repeated TableRow table_body = 7; - string id = 8; - } - } - - // A row in a table - message TableRow { - // The location of the first cell in the row - Location location = 1; - // Cells in the row - repeated TableCell cells = 2; - string id = 3; - - // A cell in a `TableRow` - message TableCell { - // The location of the cell - Location location = 1; - // The value of the cell - string value = 2; - } - } - - // A step - message Step { - // The location of the steps' `keyword` - Location location = 1; - string keyword = 2; - string text = 3; - oneof argument { - DocString doc_string = 4; - DataTable data_table = 5; - } - // Unique ID to be able to reference the Step from PickleStep - string id = 6; - - message DataTable { - Location location = 1; - repeated TableRow rows = 2; - } - - message DocString { - Location location = 1; - string media_type = 2; - string content = 3; - string delimiter = 4; - } - } - } -} - -////// Attachments (parse errors, execution errors, screenshots, links...) - -/** - * An attachment represents any kind of data associated with a line in a - * [Source](#io.cucumber.messages.Source) file. It can be used for: - * - * * Syntax errors during parse time - * * Screenshots captured and attached during execution - * * Logs captured and attached during execution - * - * It is not to be used for runtime errors raised/thrown during execution. This - * is captured in `TestResult`. - */ -message Attachment { - SourceReference source = 1; - string testStepId = 2; - string test_case_started_id = 3; - - /** - * The body of the attachment. If `content_encoding` is `IDENTITY`, the attachment - * is simply the string. If it's `BASE64`, the string should be Base64 decoded to - * obtain the attachment. - */ - string body = 4; - - /** - * The media type of the data. This can be any valid - * [IANA Media Type](https://www.iana.org/assignments/media-types/media-types.xhtml) - * as well as Cucumber-specific media types such as `text/x.cucumber.gherkin+plain` - * and `text/x.cucumber.stacktrace+plain` - */ - string media_type = 5; - - /** - * Whether to interpret `body` "as-is" (IDENTITY) or if it needs to be Base64-decoded (BASE64). - * - * Content encoding is *not* determined by the media type, but rather by the type - * of the object being attached: - * - * - string => IDENTITY - * - byte array => BASE64 - * - stream => BASE64 - */ - ContentEncoding content_encoding = 6; - - /** - * Suggested file name of the attachment. (Provided by the user as an argument to `attach`) - */ - string file_name = 7; - - /** - * A URL where the attachment can be retrieved. This field should not be set by Cucumber. - * It should be set by a program that reads a message stream and does the following for - * each Attachment message: - * - * - Writes the body (after base64 decoding if necessary) to a new file. - * - Sets `body` and `content_encoding` to `null` - * - Writes out the new attachment message - * - * This will result in a smaller message stream, which can improve performance and - * reduce bandwidth of message consumers. It also makes it easier to process and download attachments - * separately from reports. - */ - string url = 8; - - enum ContentEncoding { - IDENTITY = 0; - // When this is used, the data field is a single line base64 string - BASE64 = 1; - } -} - -////// Pickles - -/** - * A `Pickle` represents a template for a `TestCase`. It is typically derived - * from another format, such as [GherkinDocument](#io.cucumber.messages.GherkinDocument). - * In the future a `Pickle` may be derived from other formats such as Markdown or - * Excel files. - * - * By making `Pickle` the main data structure Cucumber uses for execution, the - * implementation of Cucumber itself becomes simpler, as it doesn't have to deal - * with the complex structure of a [GherkinDocument](#io.cucumber.messages.GherkinDocument). - * - * Each `PickleStep` of a `Pickle` is matched with a `StepDefinition` to create a `TestCase` - */ -message Pickle { - /** - * A unique id for the pickle - */ - string id = 1; - // The uri of the source file - string uri = 2; - // The name of the pickle - string name = 3; - // The language of the pickle - string language = 4; - // One or more steps - repeated PickleStep steps = 5; - /** - * One or more tags. If this pickle is constructed from a Gherkin document, - * It includes inherited tags from the `Feature` as well. - */ - repeated PickleTag tags = 6; - /** - * Points to the AST node locations of the pickle. The last one represents the unique - * id of the pickle. A pickle constructed from `Examples` will have the first - * id originating from the `Scenario` AST node, and the second from the `TableRow` AST node. - */ - repeated string ast_node_ids = 7; - - /** - * A tag - */ - message PickleTag { - string name = 1; - // Points to the AST node this was created from - string ast_node_id = 2; - } - - /** - * An executable step - */ - message PickleStep { - string text = 1; - // An optional argument - PickleStepArgument argument = 2; - // A unique ID for the PickleStep - string id = 3; - // References the IDs of the source of the step. For Gherkin, this can be - // the ID of a Step, and possibly also the ID of a TableRow - repeated string ast_node_ids = 4; - } -} - -/** - * A wrapper for either a doc string or a table. - */ -message PickleStepArgument { - oneof message { - PickleDocString doc_string = 1; - PickleTable data_table = 2; - } - - message PickleDocString { - string media_type = 1; - string content = 2; - } - - message PickleTable { - repeated PickleTableRow rows = 1; - - message PickleTableRow { - repeated PickleTableCell cells = 1; - - message PickleTableCell { - string value = 1; - } - } - } -} - -////// TestCases - -/** - * A `TestCase` contains a sequence of `TestStep`s. - */ -message TestCase { - string id = 1; - // The ID of the `Pickle` this `TestCase` is derived from. - string pickle_id = 2; - repeated TestStep test_steps = 3; - - /** - * A `TestStep` is derived from either a `PickleStep` - * combined with a `StepDefinition`, or from a `Hook`. - */ - message TestStep { - string id = 1; - // Pointer to the `PickleStep` (if derived from a PickleStep) - string pickle_step_id = 2; - // Pointer to all the matching `StepDefinition`s (if derived from a PickleStep) - repeated string step_definition_ids = 3; - // A list of list of StepMatchArgument (if derived from a `StepDefinition`). - // Each element represents a matching step definition. A size of 0 means `UNDEFINED`, - // and a size of 2+ means `AMBIGUOUS` - repeated StepMatchArgumentsList step_match_arguments_lists = 4; - // Pointer to the `Hook` (if derived from a Hook) - string hook_id = 5; - - message StepMatchArgumentsList { - repeated StepMatchArgument step_match_arguments = 1; - - /** - * Represents a single argument extracted from a step match and passed to a step definition. - * This is used for the following purposes: - * - Construct an argument to pass to a step definition (possibly through a parameter type transform) - * - Highlight the matched parameter in rich formatters such as the HTML formatter - * - * This message closely matches the `Argument` class in the `cucumber-expressions` library. - */ - message StepMatchArgument { - string parameter_type_name = 1; - /** - * Represents the outermost capture group of an argument. This message closely matches the - * `Group` class in the `cucumber-expressions` library. - */ - Group group = 2; - - message Group { - uint32 start = 1; - string value = 2; - repeated Group children = 3; - } - } - } - } -} - -message TestRunStarted { - Timestamp timestamp = 1; -} - -message TestCaseStarted { - Timestamp timestamp = 1; - reserved 2; - /** - * The first attempt should have value 0, and for each retry the value - * should increase by 1. - */ - uint32 attempt = 3; - string test_case_id = 4; - /** - * Because a `TestCase` can be run multiple times (in case of a retry), - * we use this field to group messages relating to the same attempt. - */ - string id = 5; -} - -message TestCaseFinished { - Timestamp timestamp = 1; - reserved 2; - string test_case_started_id = 3; -} - -message TestStepStarted { - Timestamp timestamp = 1; - string testStepId = 2; - string test_case_started_id = 3; -} - -message TestStepFinished { - TestStepResult test_step_result = 1; - Timestamp timestamp = 2; - string testStepId = 3; - string test_case_started_id = 4; - - - message TestStepResult { - Status status = 1; - string message = 2; - Duration duration = 3; - bool will_be_retried = 4; - - /** - * Status of a `TestStep`. - * - * The ordinal values of statuses are significant. The status of a TestCase - * is computed by picking the status with the highest value for all of its steps. - * - * For example, if a TestCase has steps with statuses passed, undefined and skipped, - * then the pickle's status is undefined. - */ - enum Status { - // The step hasn't been matched or executed. - UNKNOWN = 0; - // The step matched one step definition and passed execution. - PASSED = 1; - // The step matched one step definition but was not executed because the - // previous step was not PASSED. - SKIPPED = 2; - // The step matched one step definition and signalled pending during execution. - // This is the default behaviour of generated step definitions, which either - // throw a special PendingException, or return a special value indicating that it's - // pending. How to signal the pending status depends on the Cucumber implementation. - PENDING = 3; - // The step matched no step definitions. - UNDEFINED = 4; - // The step matched two or more step definitions. - AMBIGUOUS = 5; - // The step matched one step definition and failed execution. - FAILED = 6; - } - } -} - -message TestRunFinished { - // success = StrictModeEnabled ? (failed_count == 0 && ambiguous_count == 0 && undefined_count == 0 && pending_count == 0) : (failed_count == 0 && ambiguous_count == 0) - bool success = 1; - // Timestamp when the TestRun is finished - Timestamp timestamp = 2; - // Error message. Can be a stack trace from a failed `BeforeAll` or `AfterAll`. - // If there are undefined parameter types, the message is simply - // "The following parameter type(s() are not defined: xxx, yyy". - // The independent `UndefinedParameterType` messages can be used to generate - // snippets for those parameter types. - string message = 3; -} - -message Hook { - string id = 1; - string tag_expression = 2; - SourceReference source_reference = 3; -} - -message StepDefinition { - string id = 1; - StepDefinitionPattern pattern = 2; - SourceReference source_reference = 3; - - message StepDefinitionPattern { - string source = 1; - StepDefinitionPatternType type = 2; - - enum StepDefinitionPatternType { - CUCUMBER_EXPRESSION = 0; - REGULAR_EXPRESSION = 1; - } - } -} - -message ParameterType { - // The name is unique, so we don't need an id. - string name = 1; - repeated string regular_expressions = 2; - bool prefer_for_regular_expression_match = 3; - bool use_for_snippets = 4; - string id = 5; -} - -message UndefinedParameterType { - string name = 1; - string expression = 2; -} - -message ParseError { - SourceReference source = 1; - string message = 2; -} diff --git a/dotnet/scripts/update-version b/dotnet/scripts/update-version deleted file mode 100755 index 003a904f..00000000 --- a/dotnet/scripts/update-version +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -# -# Updates the version number in a .csproj file -# There must be a .releasable file next to the .csproj file -# so the script knows which one to update. -# - -releaseable_file=$(find . -type f -name "*.releaseable") -releaseable_dir=$(dirname ${releaseable_file}) -csproj_file=$(find ${releaseable_dir} -type f -name "*.csproj") - -xmlstarlet ed --inplace --ps \ - --update "/Project/PropertyGroup/VersionNumber" \ - --value "${NEW_VERSION}" \ - "${csproj_file}" diff --git a/jsonschema/scripts/codegen.rb b/jsonschema/scripts/codegen.rb index c05dd7e9..2a743862 100644 --- a/jsonschema/scripts/codegen.rb +++ b/jsonschema/scripts/codegen.rb @@ -214,6 +214,33 @@ def format_description(raw_description, indent_string: "") end end +class Dotnet < Codegen + def initialize(paths) + language_type_by_schema_type = { + 'integer' => 'long', + 'string' => 'string', + 'boolean' => 'bool', + } + + super(paths, language_type_by_schema_type) + end + + def array_type_for(type_name) + "List<#{type_name}>" + end + + def format_description(raw_description, indent_string: '') + return '' if raw_description.nil? + + raw_description + .split("\n") + .map { |line| line.strip } + .filter { |line| line != '*' } + .map { |line| " * #{line}".rstrip() } + .join("\n#{indent_string}") + end +end + class Perl < Codegen def initialize(paths) language_type_by_schema_type = { diff --git a/jsonschema/scripts/templates/dotnet.dotnet.erb b/jsonschema/scripts/templates/dotnet.dotnet.erb new file mode 100644 index 00000000..9cc7f0d2 --- /dev/null +++ b/jsonschema/scripts/templates/dotnet.dotnet.erb @@ -0,0 +1,150 @@ +<%- @schemas.each do |key, schema| -%> +<%= class_name(key) -%>.cs +using System; +using System.Collections.Generic; + +// ------------------------------------------------------------------------------ +// This code was generated based on the Cucumber JSON schema +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// ------------------------------------------------------------------------------ + +namespace Io.Cucumber.Messages.Types; + +/** + * Represents the <%= class_name(key) %> message in Cucumber's message protocol + * @see Github - Cucumber - Messages + <%- unless (schema['description'] || []).empty? -%> + * +<%= format_description(schema['description'], indent_string: '') %> +<%- end -%> + */ + +public sealed class <%= class_name(key) %> +{ + <%- schema['properties'].each do |property_name, property| + required = (schema['required'] || []).index(property_name) + isValueType = type_for(class_name(key), property_name, property) == "long" || type_for(class_name(key), property_name, property) == "bool" + -%> + <%- unless (property['description'] || []).empty? -%> + /** + <%= format_description(property['description'], indent_string: ' ') %> + */ + <%- end -%> + <%- if isValueType && !required -%> + public Nullable<<%= type_for(class_name(key), property_name, property) -%>> <%= capitalize(property_name) %> { get; private set; } + <%- else -%> + public <%= type_for(class_name(key), property_name, property) -%> <%= capitalize(property_name) %> { get; private set; } + <%- end -%> + <%- end -%> + + <%- if (schema['required'] || []).empty? -%> + <%- schema['properties'].each do |property_name, property| -%> + + public static <%= class_name(key) %> Create(<%= type_for(class_name(key), property_name, property) -%> <%= property_name %>) + { + return new <%= class_name(key) %>( + <%- schema['properties'].each_with_index do |(property_name_2, property_2), index| -%> + <%- if property_name_2 == property_name -%> + Require<<%= type_for(class_name(key), property_name, property) -%>>(<%= property_name %>, "<%= capitalize(property_name) %>", "<%= class_name(key) %>.<%= capitalize(property_name) %> cannot be null")<%= index < schema['properties'].length - 1 ? ',' : '' %> + <%- else -%> + null<%= index < schema['properties'].length - 1 ? ',' : '' %> + <%- end -%> + <%- end -%> + ); + } + <%- end -%> + <%- end -%> + + public <%= class_name(key) %>( + <%- schema['properties'].each_with_index do |(property_name, property), index| + isValueType = type_for(class_name(key), property_name, property) == "long" || type_for(class_name(key), property_name, property) == "bool" + required = (schema['required'] || []).index(property_name) + -%> + <%- if isValueType && !required -%> + Nullable<<%= type_for(class_name(key), property_name, property) -%>> <%= property_name %><%= index < schema['properties'].length - 1 ? ',' : ''%> + <%- else -%> + <%= type_for(class_name(key), property_name, property) -%> <%= property_name %><%= index < schema['properties'].length - 1 ? ',' : ''%> + <%- end -%> + <%- end -%> + ) + { + <%- schema['properties'].each_with_index do |(property_name, property), index| + required = (schema['required'] || []).index(property_name) + -%> + <% if required -%> + RequireNonNull<<%= type_for(class_name(key), property_name, property) -%>>(<%= property_name %>, "<%= capitalize(property_name) %>", "<%= class_name(key) %>.<%= capitalize(property_name) %> cannot be null"); + <%- end -%> + <%- if property['items'] -%> + this.<%= capitalize(property_name) %> = new <%= type_for(class_name(key), property_name, property) -%>(<%= property_name %>); + <%- else -%> + this.<%= capitalize(property_name) %> = <%= property_name %>; + <%- end -%> + <%- end -%> + } + + public override bool Equals(Object o) + { + if (this == o) return true; + if (o == null || this.GetType() != o.GetType()) return false; + <%= class_name(key) %> that = (<%= class_name(key) %>) o; + return <%- schema['properties'].each_with_index do |(property_name, property), index| %> + <%- if (schema['required'] || []).index(property_name) -%> + <%= capitalize(property_name) -%>.Equals(that.<%= capitalize(property_name) -%>)<%= index < schema['properties'].length-1 ? ' && ' : ';' -%> + <%- else -%> + Object.Equals(<%= capitalize(property_name) -%>, that.<%= capitalize(property_name) -%>)<%= index < schema['properties'].length-1 ? ' && ' : ';' -%> + <%- end -%> + <% end -%> + + } + + public override int GetHashCode() + { + int hash = 17; + <%- schema['properties'].each_with_index do |(property_name, property), index| + required = (schema['required'] || []).index(property_name) + isValueType = type_for(class_name(key), property_name, property) == "long" || type_for(class_name(key), property_name, property) == "bool" + isEnum = property['enum'] + -%> + <%- if isEnum -%> + hash = hash * 31 + <%= capitalize(property_name) -%>.GetHashCode(); + <%- elsif isValueType && !required -%> + if (<%= capitalize(property_name) -%>.HasValue) + hash = hash * 31 + <%= capitalize(property_name) -%>.Value.GetHashCode(); + <%- elsif isValueType -%> + hash = hash * 31 + <%= capitalize(property_name) -%>.GetHashCode(); + <%- else -%> + if (<%= capitalize(property_name) -%> != null) + hash = hash * 31 + <%= capitalize(property_name) -%>.GetHashCode(); + <%- end -%> + <%- end -%> + return hash; + } + + public override string ToString() + { + return "<%= class_name(key) %>{" + + <%- schema['properties'].each_with_index do |(property_name, property), index| + required = (schema['required'] || []).index(property_name) + isValueType = type_for(class_name(key), property_name, property) == "long" || type_for(class_name(key), property_name, property) == "bool" + -%> + <%- if isValueType && !required -%> + (<%= capitalize(property_name) -%>.HasValue ? "<%= index == 0 ? '' : ', '%><%= property_name %>=" + <%= capitalize(property_name) %>.Value : "") + + <%- else -%> + "<%= index == 0 ? '' : ', '%><%= property_name %>=" + <%= capitalize(property_name) %> + + <%- end -%> + <%- end -%> + '}'; + } + + private static T Require(T property, string propertyName, string errorMessage) + { + RequireNonNull(property, propertyName, errorMessage); + return property; + } + private static void RequireNonNull(T property, string propertyName, string errorMessage) + { + if (property == null) throw new ArgumentNullException(propertyName, errorMessage); + } +} +<% end -%> \ No newline at end of file diff --git a/jsonschema/scripts/templates/dotnet.enum.dotnet.erb b/jsonschema/scripts/templates/dotnet.enum.dotnet.erb new file mode 100644 index 00000000..5b97ae47 --- /dev/null +++ b/jsonschema/scripts/templates/dotnet.enum.dotnet.erb @@ -0,0 +1,25 @@ +<% @enums.each do |enum| -%> +<%= enum[:name] %>.cs +using System; +using System.ComponentModel; +using System.Reflection; + +namespace Io.Cucumber.Messages.Types; + +// Generated code +public enum <%= enum[:name] %> { +<% enum[:values].each_with_index do |value, index| -%> + + [Description("<%= value%>")] + <%= enum_constant(value) %><%= index < enum[:values].length - 1 ? ',' : '' %> +<% end -%> +} + +public static class <%= enum[:name] -%>Extensions +{ + public static string Value(this <%= enum[:name] %> v) { + var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); + return attribute == null ? v.ToString() : attribute.Description; + } +} +<% end -%>