From f2da98f2312f91230ed40e819198626c202bebd1 Mon Sep 17 00:00:00 2001 From: Howard van Rooijen Date: Mon, 16 Jun 2025 21:26:55 +0100 Subject: [PATCH 01/15] Update NuGet packages and refactor test lifecycle Updated several NuGet packages in `Ais.Net.Models.Specs.csproj` to their latest versions, including `coverlet.msbuild`, `Microsoft.NET.Test.Sdk`, `NUnit3TestAdapter`, `Reqnroll.NUnit`, and `Shouldly`. Added `[NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)]` to `AisMessageType18Feature` for improved test fixture management. Refactored `FeatureSetupAsync` and `FeatureTearDownAsync` methods to be static, enhancing test setup practices. Enhanced `TestInitializeAsync`, `ScenarioStartAsync`, and `ScenarioCleanupAsync` methods for better error handling and resource management. Updated `packages.lock.json` to reflect new package versions and modified `Ais.Net.Models.csproj` to upgrade `Endjin.RecommendedPractices.GitHub` from `2.1.13` to `2.1.18`. --- .../Ais.Net.Models.Specs.csproj | 10 +- .../Features/AisMessageType18.feature.cs | 68 +++-- .../Ais.Net.Models.Specs/packages.lock.json | 243 ++++++++---------- .../Ais.Net.Models/Ais.Net.Models.csproj | 2 +- 4 files changed, 161 insertions(+), 162 deletions(-) diff --git a/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj b/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj index 1eea670..5e1b7c0 100644 --- a/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj +++ b/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj @@ -20,14 +20,14 @@ - + contentfiles; analyzers - - - - + + + + diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature.cs index aab3790..74a8519 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature.cs +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature.cs @@ -10,17 +10,16 @@ // ------------------------------------------------------------------------------ #region Designer generated code #pragma warning disable +using Reqnroll; namespace Ais.Net.Models.Specs.Features { - using Reqnroll; - using System; - using System.Linq; - [System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] - [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] [NUnit.Framework.DescriptionAttribute("AisMessageType18")] + [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] public partial class AisMessageType18Feature { @@ -28,34 +27,63 @@ public partial class AisMessageType18Feature private static string[] featureTags = ((string[])(null)); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType18", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + #line 1 "AisMessageType18.feature" #line hidden [NUnit.Framework.OneTimeSetUpAttribute()] - public virtual async System.Threading.Tasks.Task FeatureSetupAsync() + public static async global::System.Threading.Tasks.Task FeatureSetupAsync() { - testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(); - global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType18", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); - await testRunner.OnFeatureStartAsync(featureInfo); } [NUnit.Framework.OneTimeTearDownAttribute()] - public virtual async System.Threading.Tasks.Task FeatureTearDownAsync() + public static async global::System.Threading.Tasks.Task FeatureTearDownAsync() { - await testRunner.OnFeatureEndAsync(); - global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner); - testRunner = null; } [NUnit.Framework.SetUpAttribute()] - public async System.Threading.Tasks.Task TestInitializeAsync() + public async global::System.Threading.Tasks.Task TestInitializeAsync() { + testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo); + try + { + if (((testRunner.FeatureContext != null) + && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false))) + { + await testRunner.OnFeatureEndAsync(); + } + } + finally + { + if (((testRunner.FeatureContext != null) + && testRunner.FeatureContext.BeforeFeatureHookFailed)) + { + throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error"); + } + if ((testRunner.FeatureContext == null)) + { + await testRunner.OnFeatureStartAsync(featureInfo); + } + } } [NUnit.Framework.TearDownAttribute()] - public async System.Threading.Tasks.Task TestTearDownAsync() + public async global::System.Threading.Tasks.Task TestTearDownAsync() { - await testRunner.OnScenarioEndAsync(); + if ((testRunner == null)) + { + return; + } + try + { + await testRunner.OnScenarioEndAsync(); + } + finally + { + global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner); + testRunner = null; + } } public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) @@ -64,22 +92,22 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); } - public async System.Threading.Tasks.Task ScenarioStartAsync() + public async global::System.Threading.Tasks.Task ScenarioStartAsync() { await testRunner.OnScenarioStartAsync(); } - public async System.Threading.Tasks.Task ScenarioCleanupAsync() + public async global::System.Threading.Tasks.Task ScenarioCleanupAsync() { await testRunner.CollectScenarioErrorsAsync(); } [NUnit.Framework.TestAttribute()] [NUnit.Framework.DescriptionAttribute("Create AisMessageType18 record")] - public async System.Threading.Tasks.Task CreateAisMessageType18Record() + public async global::System.Threading.Tasks.Task CreateAisMessageType18Record() { string[] tagsOfScenario = ((string[])(null)); - System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); + global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType18 record", null, tagsOfScenario, argumentsOfScenario, featureTags); #line 3 this.ScenarioInitialize(scenarioInfo); diff --git a/Solutions/Ais.Net.Models.Specs/packages.lock.json b/Solutions/Ais.Net.Models.Specs/packages.lock.json index e2b9594..bb1041e 100644 --- a/Solutions/Ais.Net.Models.Specs/packages.lock.json +++ b/Solutions/Ais.Net.Models.Specs/packages.lock.json @@ -4,42 +4,46 @@ "net8.0": { "coverlet.msbuild": { "type": "Direct", - "requested": "[6.0.2, )", - "resolved": "6.0.2", - "contentHash": "8b4jBNH7mcQy1otyQErjjIUuGD74XxKZ1wvDufbY7jhWwckl7wIa+icjwdPYeI0aYMS4Tp63LIZvyMFjWwOMDw==" + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "Qa7Hg+wrOMDKpXVn2dw4Wlun490bIWsFW0fdNJQFJLZnbU27MCP0HJ2mPgS+3EQBQUb0zKlkwiQzP+j38Hc3Iw==" }, "Microsoft.NET.Test.Sdk": { "type": "Direct", - "requested": "[17.11.1, )", - "resolved": "17.11.1", - "contentHash": "U3Ty4BaGoEu+T2bwSko9tWqWUOU16WzSFkq6U8zve75oRBMSLTBdMAZrVNNz1Tq12aCdDom9fcOcM9QZaFHqFg==", + "requested": "[17.14.1, )", + "resolved": "17.14.1", + "contentHash": "HJKqKOE+vshXra2aEHpi2TlxYX7Z9VFYkr+E5rwEvHC8eIXiyO+K9kNm8vmNom3e2rA56WqxU+/N9NJlLGXsJQ==", "dependencies": { - "Microsoft.CodeCoverage": "17.11.1", - "Microsoft.TestPlatform.TestHost": "17.11.1" + "Microsoft.CodeCoverage": "17.14.1", + "Microsoft.TestPlatform.TestHost": "17.14.1" } }, "NUnit3TestAdapter": { "type": "Direct", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "R7e1+a4vuV/YS+ItfL7f//rG+JBvVeVLX4mHzFEZo4W1qEKl8Zz27AqvQSAqo+BtIzUCo4aAJMYa56VXS4hudw==" + "requested": "[5.0.0, )", + "resolved": "5.0.0", + "contentHash": "sy4cLoUAdE6TDM4wNX5gmNCyhMev5wUz4cA6ZRf/aON9vf9t4xTVGLj/4huhDKcS4dFfmVVcgcP70yC7WC9kKg==", + "dependencies": { + "Microsoft.Testing.Extensions.VSTestBridge": "1.5.3", + "Microsoft.Testing.Platform.MSBuild": "1.5.3" + } }, "Reqnroll.NUnit": { "type": "Direct", - "requested": "[2.1.1, )", - "resolved": "2.1.1", - "contentHash": "VcacexjyMd32HmbiYX/QD5vynid+xLjXym835KR68q0vVAA2PWCCRY+bZkLoGb0k/wsddsTQ+w2lCRq1+U2Z7A==", + "requested": "[2.4.1, )", + "resolved": "2.4.1", + "contentHash": "IbP1uVirMVpopeRwjvtz2b0PO9oQtHcDnAQigTpZY9lxSRYBycQSYQaZ6fbkkg/mG/azkPPGV3YIjNILQ8jWrw==", "dependencies": { "NUnit": "3.13.1", - "Reqnroll": "[2.1.1]", - "Reqnroll.Tools.MsBuild.Generation": "[2.1.1]" + "Reqnroll": "[2.4.1]", + "Reqnroll.Tools.MsBuild.Generation": "[2.4.1]" } }, "Shouldly": { "type": "Direct", - "requested": "[4.2.1, )", - "resolved": "4.2.1", - "contentHash": "dKAKiSuhLKqD2TXwLKtqNg1nwzJcIKOOMncZjk9LYe4W+h+SCftpWdxwR79YZUIHMH+3Vu9s0s0UHNrgICLwRQ==", + "requested": "[4.3.0, )", + "resolved": "4.3.0", + "contentHash": "sDetrWXrl6YXZ4HeLsdBoNk3uIa7K+V4uvIJ+cqdRa5DrFxeTED7VkjoxCuU1kJWpUuBDZz2QXFzSxBtVXLwRQ==", "dependencies": { "DiffEngine": "11.3.0", "EmptyFiles": "4.4.0" @@ -74,48 +78,89 @@ }, "Gherkin": { "type": "Transitive", - "resolved": "29.0.0", - "contentHash": "az9zmD5V72UZUzYcDyHoZHFRT5eSLOg1Co2r3AtlshPe41Am7iMwOJG+xHxZ1Pfn6agGoWw1dhm6Pn8Dg6QBUg==" + "resolved": "30.0.0", + "contentHash": "jZM9zm9eg62vRSAOtYvcmQh4w0oYqjP6myKxMaJAlQq9VCKm4wnTfHhS5QRnLhx/sH3R5jTaoQAKLs5hhjuq7g==" + }, + "Microsoft.ApplicationInsights": { + "type": "Transitive", + "resolved": "2.22.0", + "contentHash": "3AOM9bZtku7RQwHyMEY3tQMrHIgjcfRDa6YQpd/QG2LDGvMydSlL9Di+8LLMt7J2RDdfJ7/2jdYv6yHcMJAnNw==", + "dependencies": { + "System.Diagnostics.DiagnosticSource": "5.0.0" + } }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "17.11.1", - "contentHash": "nPJqrcA5iX+Y0kqoT3a+pD/8lrW/V7ayqnEJQsTonSoPz59J8bmoQhcSN4G8+UJ64Hkuf0zuxnfuj2lkHOq4cA==" + "resolved": "17.14.1", + "contentHash": "pmTrhfFIoplzFVbhVwUquT+77CbGH+h4/3mBpdmIlYtBi9nAB+kKI6dN3A/nV4DFi3wLLx/BlHIPK+MkbQ6Tpg==" }, "Microsoft.Extensions.DependencyModel": { "type": "Transitive", - "resolved": "8.0.1", - "contentHash": "5Ou6varcxLBzQ+Agfm0k0pnH7vrEITYlXMDuE6s7ZHlZHz6/G8XJ3iISZDr5rfwfge6RnXJ1+Wc479mMn52vjA==", - "dependencies": { - "System.Text.Encodings.Web": "8.0.0", - "System.Text.Json": "8.0.4" - } + "resolved": "8.0.2", + "contentHash": "mUBDZZRgZrSyFOsJ2qJJ9fXfqd/kXJwf3AiDoqLD9m6TjY5OO/vLNOb9fb4juC0487eq4hcGN/M2Rh/CKS7QYw==" }, "Microsoft.NETCore.Platforms": { "type": "Transitive", "resolved": "1.1.0", "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" }, - "Microsoft.NETCore.Targets": { + "Microsoft.Testing.Extensions.Telemetry": { "type": "Transitive", - "resolved": "1.1.0", - "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + "resolved": "1.5.3", + "contentHash": "U9pGd5DQuX1PfkrdFI+xH34JGgQ2nes5QAwIITTk+MQfLvRITqsZjJeHTjpGWh33D/0q1l7aA8/LQHR7UuCgLQ==", + "dependencies": { + "Microsoft.ApplicationInsights": "2.22.0", + "Microsoft.Testing.Platform": "1.5.3" + } + }, + "Microsoft.Testing.Extensions.TrxReport.Abstractions": { + "type": "Transitive", + "resolved": "1.5.3", + "contentHash": "h34zKNpGyni66VH738mRHeXSnf3klSShUdavUWNhSfWICUUi5aXeI0LBvoX/ad93N0+9xBDU3Fyi6WfxrwKQGw==", + "dependencies": { + "Microsoft.Testing.Platform": "1.5.3" + } + }, + "Microsoft.Testing.Extensions.VSTestBridge": { + "type": "Transitive", + "resolved": "1.5.3", + "contentHash": "cJD67YfDT98wEWyazKVD/yPVW6+H1usXeuselCnRes7JZBTIYWtrCchcOzOahnmajT79eDKqt9sta7DXwTDU4Q==", + "dependencies": { + "Microsoft.ApplicationInsights": "2.22.0", + "Microsoft.TestPlatform.ObjectModel": "17.12.0", + "Microsoft.Testing.Extensions.Telemetry": "1.5.3", + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.5.3", + "Microsoft.Testing.Platform": "1.5.3" + } + }, + "Microsoft.Testing.Platform": { + "type": "Transitive", + "resolved": "1.5.3", + "contentHash": "WqJydnJ99dEKtquR9HwINz104ehWJKTXbQQrydGatlLRw14bmsx0pa8+E6KUXMYXZAimN0swWlDmcJGjjW4TIg==" + }, + "Microsoft.Testing.Platform.MSBuild": { + "type": "Transitive", + "resolved": "1.5.3", + "contentHash": "bOtpRMSPeT5YLQo+NNY8EtdNTphAUcmALjW4ABU7P0rb6yR2XAZau3TzNieLmR3lRuwudguWzzBhgcLRXwZh0A==", + "dependencies": { + "Microsoft.Testing.Platform": "1.5.3" + } }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", - "resolved": "17.11.1", - "contentHash": "E2jZqAU6JeWEVsyOEOrSW1o1bpHLgb25ypvKNB/moBXPVsFYBPd/Jwi7OrYahG50J83LfHzezYI+GaEkpAotiA==", + "resolved": "17.14.1", + "contentHash": "xTP1W6Mi6SWmuxd3a+jj9G9UoC850WGwZUps1Wah9r1ZxgXhdJfj1QqDLJkFjHDCvN42qDL2Ps5KjQYWUU0zcQ==", "dependencies": { - "System.Reflection.Metadata": "1.6.0" + "System.Reflection.Metadata": "8.0.0" } }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", - "resolved": "17.11.1", - "contentHash": "DnG+GOqJXO/CkoqlJWeDFTgPhqD/V6VqUIL3vINizCWZ3X+HshCtbbyDdSHQQEjrc2Sl/K3yaxX6s+5LFEdYuw==", + "resolved": "17.14.1", + "contentHash": "d78LPzGKkJwsJXAQwsbJJ7LE7D1wB+rAyhHHAaODF+RDSQ0NgMjDFkSA1Djw18VrxO76GlKAjRUhl+H8NL8Z+Q==", "dependencies": { - "Microsoft.TestPlatform.ObjectModel": "17.11.1", - "Newtonsoft.Json": "13.0.1" + "Microsoft.TestPlatform.ObjectModel": "17.14.1", + "Newtonsoft.Json": "13.0.3" } }, "NETStandard.Library": { @@ -128,8 +173,8 @@ }, "Newtonsoft.Json": { "type": "Transitive", - "resolved": "13.0.1", - "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" }, "NUnit": { "type": "Transitive", @@ -141,45 +186,37 @@ }, "Reqnroll": { "type": "Transitive", - "resolved": "2.1.1", - "contentHash": "RhV5B0lxVXzP+0U9OUkWf3nMGfSlWnxQdUp0mcatvuQISxB8ZPjdhJB3T4Vjo3bFMiQb/0LUXUmNZ0IqBPZldw==", + "resolved": "2.4.1", + "contentHash": "Ui229q21Kmkrv3L89THgsxGMXooJGK5OrFPLvYDXfE2nO/u4tqYsbmMRddyEE3fsR40IDP++HsRrDxlkR6reVw==", "dependencies": { "Cucumber.CucumberExpressions": "17.1.0", - "Gherkin": "29.0.0", - "Microsoft.Extensions.DependencyModel": "8.0.1", - "SpecFlow.Internal.Json": "1.0.8", - "System.Runtime.Loader": "4.3.0" + "Gherkin": "30.0.0", + "Microsoft.Extensions.DependencyModel": "8.0.2", + "System.Text.Json": "8.0.5" } }, "Reqnroll.Tools.MsBuild.Generation": { "type": "Transitive", - "resolved": "2.1.1", - "contentHash": "xjv2ihoRHpAAjhZX9d964/0R8mhgHiquPBjnJmhc2sYQnemDCkHIsb4d2VAMKS/HeiXLi6NAxujjgAYFBcxDKg==", + "resolved": "2.4.1", + "contentHash": "+Up0eUWnKRKPdRIttE52DYzwayUd4bGMyRytYeeCwtqwZA4tLhK2NspOZJ8axPcmATOM9QSTCUHUlyp9pgcfQg==", "dependencies": { - "Reqnroll": "[2.1.1]" + "Reqnroll": "[2.4.1]" } }, - "SpecFlow.Internal.Json": { - "type": "Transitive", - "resolved": "1.0.8", - "contentHash": "lVCC/Rie7N5rFoc7YxPS0nneLfsWSTIMMlkndwxhaD8MxBp3Bsv1HeiVjVwXCjWaQeoqZcvIy52fF5Xit00ZLw==" - }, "System.CodeDom": { "type": "Transitive", "resolved": "6.0.0", "contentHash": "CPc6tWO1LAer3IzfZufDBRL+UZQcj5uS207NHALQzP84Vp/z6wF0Aa0YZImOQY8iStY0A2zI/e3ihKNPfUm8XA==" }, - "System.IO": { + "System.Collections.Immutable": { "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.NETCore.Targets": "1.1.0", - "System.Runtime": "4.3.0", - "System.Text.Encoding": "4.3.0", - "System.Threading.Tasks": "4.3.0" - } + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "tCQTzPsGZh/A9LhhA6zrqCRV4hOHsK90/G7q3Khxmn6tnB1PuNU0cRaKANP2AWcF9bn0zsuOoZOSrHuJk6oNBA==" }, "System.IO.Pipelines": { "type": "Transitive", @@ -194,84 +231,18 @@ "System.CodeDom": "6.0.0" } }, - "System.Reflection": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.NETCore.Targets": "1.1.0", - "System.IO": "4.3.0", - "System.Reflection.Primitives": "4.3.0", - "System.Runtime": "4.3.0" - } - }, "System.Reflection.Metadata": { - "type": "Transitive", - "resolved": "1.6.0", - "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ==" - }, - "System.Reflection.Primitives": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.NETCore.Targets": "1.1.0", - "System.Runtime": "4.3.0" - } - }, - "System.Runtime": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.NETCore.Targets": "1.1.0" - } - }, - "System.Runtime.Loader": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "DHMaRn8D8YCK2GG2pw+UzNxn/OHVfaWx7OTLBD/hPegHZZgcZh3H6seWegrC4BYwsfuGrywIuT+MQs+rPqRLTQ==", - "dependencies": { - "System.IO": "4.3.0", - "System.Reflection": "4.3.0", - "System.Runtime": "4.3.0" - } - }, - "System.Text.Encoding": { - "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.NETCore.Targets": "1.1.0", - "System.Runtime": "4.3.0" - } - }, - "System.Text.Encodings.Web": { "type": "Transitive", "resolved": "8.0.0", - "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==" - }, - "System.Text.Json": { - "type": "Transitive", - "resolved": "8.0.4", - "contentHash": "bAkhgDJ88XTsqczoxEMliSrpijKZHhbJQldhAmObj/RbrN3sU5dcokuXmWJWsdQAhiMJ9bTayWsL1C9fbbCRhw==", + "contentHash": "ptvgrFh7PvWI8bcVqG5rsA/weWM09EnthFHR5SCnS6IN+P4mj6rE1lBDC4U8HL9/57htKAqy4KQ3bBj84cfYyQ==", "dependencies": { - "System.Text.Encodings.Web": "8.0.0" + "System.Collections.Immutable": "8.0.0" } }, - "System.Threading.Tasks": { + "System.Text.Json": { "type": "Transitive", - "resolved": "4.3.0", - "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.0", - "Microsoft.NETCore.Targets": "1.1.0", - "System.Runtime": "4.3.0" - } + "resolved": "8.0.5", + "contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg==" }, "ais.net.models": { "type": "Project", diff --git a/Solutions/Ais.Net.Models/Ais.Net.Models.csproj b/Solutions/Ais.Net.Models/Ais.Net.Models.csproj index debd8fd..3d1147f 100644 --- a/Solutions/Ais.Net.Models/Ais.Net.Models.csproj +++ b/Solutions/Ais.Net.Models/Ais.Net.Models.csproj @@ -22,7 +22,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 4d638c8646389febea4c45166afd66d7d8890290 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Tue, 17 Jun 2025 11:58:54 +0100 Subject: [PATCH 02/15] Migrate to ZF --- .devops/config.ps1 | 42 ----------- .github/workflows/build.yml | 147 ++++++++++++++++++++++-------------- .gitignore | 1 + .zf/config.ps1 | 68 +++++++++++++++++ build.ps1 | 59 +++++++-------- 5 files changed, 185 insertions(+), 132 deletions(-) delete mode 100644 .devops/config.ps1 create mode 100644 .zf/config.ps1 diff --git a/.devops/config.ps1 b/.devops/config.ps1 deleted file mode 100644 index 34e1621..0000000 --- a/.devops/config.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -$devopsExtensions = @( - @{ - Name = "Endjin.RecommendedPractices.Build" - Version = "[1.5.10,2.0)" - Process = "tasks/build.process.ps1" - } -) - -# Load the tasks and process -. endjin-devops.tasks - -# -# Build process configuration -# -$SolutionToBuild = (Resolve-Path (Join-Path $here "./Solutions/Ais.Net.Models.sln")).Path -$SkipBuildModuleVersionCheck = $true # currently doesn't work properly with endjin-devops - -# Set default build task -task . FullBuild - -# -# Build Process Extensibility Points - uncomment and implement as required -# - -# task RunFirst {} -# task PreInit {} -# task PostInit {} -# task PreVersion {} -# task PostVersion {} -# task PreBuild {} -# task PostBuild {} -# task PreTest {} -# task PostTest {} -# task PreTestReport {} -# task PostTestReport {} -# task PreAnalysis {} -# task PostAnalysis {} -# task PrePackage {} -# task PostPackage {} -# task PrePublish {} -# task PostPublish {} -# task RunLast {} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1354ad0..af5460f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,58 +1,89 @@ -name: build -on: - push: - branches: - - main - tags: - - '*' - pull_request: - branches: - - main - workflow_dispatch: - inputs: - forcePublish: - description: When true the Publish stage will always be run, otherwise it only runs for tagged versions. - required: false - default: false - type: boolean - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - checks: write # enable test result annotations - contents: write # enable creating releases - issues: read - packages: write # enable publishing packages - pull-requests: write # enable test result annotations - -jobs: - prepareConfig: - name: Prepare Configuration - runs-on: ubuntu-latest - outputs: - RESOLVED_ENV_VARS: ${{ steps.prepareEnvVarsAndSecrets.outputs.environmentVariablesYamlBase64 }} - RESOLVED_SECRETS: ${{ steps.prepareEnvVarsAndSecrets.outputs.secretsYamlBase64 }} - steps: - # Declare any environment variables and/or secrets that need to be available inside the build process - - uses: endjin/Endjin.RecommendedPractices.GitHubActions/actions/prepare-env-vars-and-secrets@main - id: prepareEnvVarsAndSecrets - with: - environmentVariablesYaml: | - BUILDVAR_NuGetPublishSource: "${{ startsWith(github.ref, 'refs/tags/') && 'https://api.nuget.org/v3/index.json' || 'https://nuget.pkg.github.com/ais-dotnet/index.json' }}" - BUILDVAR_Configuration: "Release" - secretsYaml: | - NUGET_API_KEY: "${{ startsWith(github.ref, 'refs/tags/') && secrets.NUGET_APIKEY || secrets.BUILD_PUBLISHER_PAT }}" - - build: - needs: prepareConfig - uses: endjin/Endjin.RecommendedPractices.GitHubActions/.github/workflows/scripted-build-single-job-pipeline.yml@main - with: - netSdkVersion: '8.0.x' - # workflow_dispatch inputs are always strings, the type property is just for the UI - forcePublish: ${{ github.event.inputs.forcePublish == 'true' }} - buildEnv: ${{ needs.prepareConfig.outputs.RESOLVED_ENV_VARS }} - secrets: - buildAzureCredentials: ${{ secrets.AZURE_READER_CREDENTIALS }} - buildSecrets: ${{ needs.prepareConfig.outputs.RESOLVED_SECRETS }} +name: build +on: + push: + branches: + - main + tags: + - '*' + pull_request: + branches: + - main + workflow_dispatch: + inputs: + forcePublish: + description: When true the Publish stage will always be run, otherwise it only runs for tagged versions. + required: false + default: false + type: boolean + forcePublicNugetDestination: + description: When true the NuGet Publish destination will always be set to nuget.org. (Normally, force publishing publishes to the private feed on GitHub.) + required: false + default: false + type: boolean + skipCleanup: + description: When true the pipeline clean-up stage will not be run. For example, the cache used between pipeline stages will be retained. + required: false + default: false + type: boolean + +concurrency: + group: ${{ github.workflow }}-${{ github.sha }} + cancel-in-progress: true + +permissions: + actions: write # enable cache clean-up + checks: write # enable test result annotations + contents: write # enable creating releases + issues: read + packages: write # enable publishing packages + pull-requests: write # enable test result annotations + +jobs: + prepareConfig: + name: Prepare Configuration + runs-on: ubuntu-latest + outputs: + RESOLVED_ENV_VARS: ${{ steps.prepareEnvVarsAndSecrets.outputs.environmentVariablesYamlBase64 }} + RESOLVED_SECRETS: ${{ steps.prepareEnvVarsAndSecrets.outputs.secretsYamlBase64 }} + steps: + # Declare any environment variables and/or secrets that need to be available inside the build process + - uses: endjin/Endjin.RecommendedPractices.GitHubActions/actions/prepare-env-vars-and-secrets@main + id: prepareEnvVarsAndSecrets + with: + environmentVariablesYaml: | + ZF_NUGET_PUBLISH_SOURCE: ${{ (startsWith(github.ref, 'refs/tags/') || github.event.inputs.forcePublicNugetDestination == 'true') && 'https://api.nuget.org/v3/index.json' || format('https://nuget.pkg.github.com/{0}/index.json', github.repository_owner) }} + secretsYaml: | + NUGET_API_KEY: "${{ startsWith(github.ref, 'refs/tags/') && secrets.NUGET_APIKEY || secrets.BUILD_PUBLISHER_PAT }}" + secretsEncryptionKey: ${{ secrets.SHARED_WORKFLOW_KEY }} + + build: + needs: prepareConfig + uses: endjin/Endjin.RecommendedPractices.GitHubActions/.github/workflows/scripted-build-matrix-pipeline.yml@main + with: + netSdkVersion: '8.x' + # additionalNetSdkVersion: '9.x' + # workflow_dispatch inputs are always strings, the type property is just for the UI + forcePublish: ${{ github.event.inputs.forcePublish == 'true' }} + skipCleanup: ${{ github.event.inputs.skipCleanup == 'true' }} + enableCrossOsCaching: true + testPhaseMatrixJson: | + { + "os": ["windows-latest", "ubuntu-latest"], + "dotnetFramework": ["net8.0"] + } + # testArtifactName: '' + # testArtifactPath: '' + compilePhaseEnv: ${{ needs.prepareConfig.outputs.RESOLVED_ENV_VARS }} + testPhaseEnv: ${{ needs.prepareConfig.outputs.RESOLVED_ENV_VARS }} + packagePhaseEnv: ${{ needs.prepareConfig.outputs.RESOLVED_ENV_VARS }} + publishPhaseEnv: ${{ needs.prepareConfig.outputs.RESOLVED_ENV_VARS }} + secrets: + compilePhaseAzureCredentials: ${{ secrets.AZURE_READER_CREDENTIALS }} + # testPhaseAzureCredentials: ${{ secrets.TESTS_KV_READER_CREDENTIALS }} + # packagePhaseAzureCredentials: ${{ secrets.AZURE_PUBLISH_CREDENTIALS }} + # publishPhaseAzureCredentials: ${{ secrets.AZURE_PUBLISH_CREDENTIALS }} + # compilePhaseSecrets: ${{ needs.prepareConfig.outputs.RESOLVED_SECRETS }} + # testPhaseSecrets: ${{ needs.prepareConfig.outputs.RESOLVED_SECRETS }} + # packagePhaseSecrets: ${{ needs.prepareConfig.outputs.RESOLVED_SECRETS }} + publishPhaseSecrets: ${{ needs.prepareConfig.outputs.RESOLVED_SECRETS }} + secretsEncryptionKey: ${{ secrets.SHARED_WORKFLOW_KEY }} diff --git a/.gitignore b/.gitignore index 8ee7fb9..52b09d1 100644 --- a/.gitignore +++ b/.gitignore @@ -401,4 +401,5 @@ FodyWeavers.xsd # Build outputs _codeCoverage/ _packages/ +.zf/extensions/ *.sbom.* \ No newline at end of file diff --git a/.zf/config.ps1 b/.zf/config.ps1 new file mode 100644 index 0000000..5b4eaf1 --- /dev/null +++ b/.zf/config.ps1 @@ -0,0 +1,68 @@ +<# +This example demonstrates a software build process using the 'ZeroFailed.Build.DotNet' extension +to provide the features needed when building a .NET solutions. +#> + +$zerofailedExtensions = @( + @{ + # References the extension from its GitHub repository. If not already installed, use latest version from 'main' will be downloaded. + Name = "ZeroFailed.Build.DotNet" + GitRepository = "https://github.com/zerofailed/ZeroFailed.Build.DotNet" + GitRef = "main" + } +) + +# Load the tasks and process +. ZeroFailed.tasks -ZfPath $here/.zf + + +# +# Build process control options +# +$SkipInit = $false +$SkipVersion = $false +$SkipBuild = $false +$CleanBuild = $Clean +$SkipTest = $false +$SkipTestReport = $false +$SkipAnalysis = $false +$SkipPackage = $false + +# +# Build process configuration +# +$SolutionToBuild = (Resolve-Path (Join-Path $here "./Solutions/Ais.Net.Models.sln")).Path +$ProjectsToPublish = @() +$NuSpecFilesToPackage = @() +$NugetPublishSource = property ZF_NUGET_PUBLISH_SOURCE "$here/_local-nuget-feed" +$IncludeAssembliesInCodeCoverage = "Ais.Net.Models" +$ExcludeAssembliesInCodeCoverage = "" + + +# Customise the build process + +task . FullBuild + + +# +# Build Process Extensibility Points - uncomment and implement as required +# + +# task RunFirst {} +# task PreInit {} +# task PostInit {} +# task PreVersion {} +# task PostVersion {} +# task PreBuild {} +# task PostBuild {} +# task PreTest {} +# task PostTest {} +# task PreTestReport {} +# task PostTestReport {} +# task PreAnalysis {} +# task PostAnalysis {} +# task PrePackage {} +# task PostPackage {} +# task PrePublish {} +# task PostPublish {} +# task RunLast {} diff --git a/build.ps1 b/build.ps1 index aa78da4..bb95a74 100644 --- a/build.ps1 +++ b/build.ps1 @@ -3,11 +3,11 @@ .SYNOPSIS Runs a .NET flavoured build process. .DESCRIPTION - This script was scaffolded using a template from the Endjin.RecommendedPractices.Build PowerShell module. - It uses the InvokeBuild module to orchestrate an opinonated software build process for .NET solutions. + This script was scaffolded using a template from the ZeroFailed project. + It uses the InvokeBuild module to orchestrate an opinionated software build process for .NET solutions. .EXAMPLE PS C:\> ./build.ps1 - Downloads any missing module dependencies (Endjin.RecommendedPractices.Build & InvokeBuild) and executes + Downloads any missing module dependencies (ZeroFailed & InvokeBuild) and executes the build process. .PARAMETER Tasks Optionally override the default task executed as the entry-point of the build. @@ -27,14 +27,12 @@ The logging verbosity. .PARAMETER Clean When true, the .NET solution will be cleaned and all output/intermediate folders deleted. -.PARAMETER BuildModulePath - The path to import the Endjin.RecommendedPractices.Build module from. This is useful when - testing pre-release versions of the Endjin.RecommendedPractices.Build that are not yet - available in the PowerShell Gallery. -.PARAMETER BuildModuleVersion - The version of the Endjin.RecommendedPractices.Build module to import. This is useful when - testing pre-release versions of the Endjin.RecommendedPractices.Build that are not yet - available in the PowerShell Gallery. +.PARAMETER ZfModulePath + The path to import the ZeroFailed module from. This is useful when testing pre-release + versions of ZeroFailed that are not yet available in the PowerShell Gallery. +.PARAMETER ZfModuleVersion + The version of the ZeroFailed module to import. This is useful when testing pre-release + versions of ZeroFailed that are not yet available in the PowerShell Gallery. .PARAMETER InvokeBuildModuleVersion The version of the InvokeBuild module to be used. #> @@ -69,13 +67,13 @@ param ( [switch] $Clean, [Parameter()] - [string] $BuildModulePath, + [string] $ZfModulePath, [Parameter()] - [string] $BuildModuleVersion = "1.0.0-preview0020", + [string] $ZfModuleVersion = "1.0.5", [Parameter()] - [version] $InvokeBuildModuleVersion = "5.11.3" + [version] $InvokeBuildModuleVersion = "5.12.1" ) $ErrorActionPreference = 'Stop' $here = Split-Path -Parent $PSCommandPath @@ -89,14 +87,6 @@ if ($MyInvocation.ScriptName -notlike '*Invoke-Build.ps1') { Invoke-Build $Tasks $MyInvocation.MyCommand.Path @PSBoundParameters } catch { - if ($env:GITHUB_ACTIONS) { - Write-Host ("::error file={0},line={1},col={2}::{3}" -f ` - $_.InvocationInfo.ScriptName, - $_.InvocationInfo.ScriptLineNumber, - $_.InvocationInfo.OffsetInLine, - $_.Exception.Message - ) - } Write-Host -f Yellow "`n`n***`n*** Build Failure Summary - check previous logs for more details`n***" Write-Host -f Yellow $_.Exception.Message Write-Host -f Yellow $_.ScriptStackTrace @@ -106,21 +96,26 @@ if ($MyInvocation.ScriptName -notlike '*Invoke-Build.ps1') { } #endregion -#region Import shared tasks and initialise build framework +#region Initialise build framework $splat = @{ Force = $true; Verbose = $false} -if (!($BuildModulePath)) { - Install-PSResource endjin-devops -Version $BuildModuleVersion -Scope CurrentUser -TrustRepository -Reinstall:$($BuildModuleVersion -match '-') | Out-Null - $BuildModulePath = "endjin-devops" - $splat.Add("RequiredVersion", ($BuildModuleVersion -split '-')[0]) +Import-Module Microsoft.PowerShell.PSResourceGet +if (!($ZfModulePath)) { + Install-PSResource ZeroFailed -Version $ZfModuleVersion -Scope CurrentUser -TrustRepository | Out-Null + $ZfModulePath = "ZeroFailed" + $splat.Add("RequiredVersion", ($ZfModuleVersion -split '-')[0]) } else { - Write-Host "BuildModulePath: $BuildModulePath" + Write-Host "ZfModulePath: $ZfModulePath" } -$splat.Add("Name", $BuildModulePath) +$splat.Add("Name", $ZfModulePath) +# Ensure only 1 version of the module is loaded +Get-Module ZeroFailed | Remove-Module Import-Module @splat -$ver = "{0} {1}" -f (Get-Module endjin-devops).Version, (Get-Module endjin-devops).PrivateData.PsData.PreRelease -Write-Host "Using Build module version: $ver" +$ver = "{0} {1}" -f (Get-Module ZeroFailed).Version, (Get-Module ZeroFailed).PrivateData.PsData.PreRelease +Write-Host "Using ZeroFailed module version: $ver" #endregion +$PSModuleAutoloadingPreference = 'none' + # Load the build configuration -. $here/.devops/config.ps1 +. $here/.zf/config.ps1 From 91eca261ba26a54f9dc8ff70f0bd3747ca603994 Mon Sep 17 00:00:00 2001 From: Howard van Rooijen Date: Wed, 18 Jun 2025 09:06:16 +0100 Subject: [PATCH 03/15] Add new step definitions and update project file Updated `Ais.Net.Models.Specs.csproj` to include new compile and feature item groups for `.feature.cs` and `.feature` files. Introduced nullable types and null checks in `AisMessageType18StepDefinitions.cs` for better data integrity. Added new step definition classes for `AisMessageType19`, `AisMessageType1Through3`, `AisMessageType24Part0`, `AisMessageType24Part1`, `AisMessageType27`, and `AisMessageType5`, each with methods for creating records and validating properties. Corresponding feature files were auto-generated to define scenarios for testing the new message types. --- .../Ais.Net.Models.Specs.csproj | 9 + .../AisMessageType18StepDefinitions.cs | 21 +- .../AisMessageType19StepDefinitions.cs | 118 +++++++++++ .../AisMessageType1Through3StepDefinitions.cs | 106 ++++++++++ .../AisMessageType24Part0StepDefinitions.cs | 52 +++++ .../AisMessageType24Part1StepDefinitions.cs | 86 ++++++++ .../AisMessageType27StepDefinitions.cs | 82 ++++++++ .../AisMessageType5StepDefinitions.cs | 102 ++++++++++ .../Features/AisMessageType19.feature | 8 + .../Features/AisMessageType19.feature.cs | 183 ++++++++++++++++++ .../Features/AisMessageType1Through3.feature | 8 + .../AisMessageType1Through3.feature.cs | 175 +++++++++++++++++ .../Features/AisMessageType24Part0.feature | 8 + .../Features/AisMessageType24Part0.feature.cs | 147 ++++++++++++++ .../Features/AisMessageType24Part1.feature | 8 + .../Features/AisMessageType24Part1.feature.cs | 169 ++++++++++++++++ .../Features/AisMessageType27.feature | 8 + .../Features/AisMessageType27.feature.cs | 159 +++++++++++++++ .../Features/AisMessageType5.feature | 8 + .../Features/AisMessageType5.feature.cs | 179 +++++++++++++++++ 20 files changed, 1628 insertions(+), 8 deletions(-) create mode 100644 Solutions/Ais.Net.Models.Specs/AisMessageType19StepDefinitions.cs create mode 100644 Solutions/Ais.Net.Models.Specs/AisMessageType1Through3StepDefinitions.cs create mode 100644 Solutions/Ais.Net.Models.Specs/AisMessageType24Part0StepDefinitions.cs create mode 100644 Solutions/Ais.Net.Models.Specs/AisMessageType24Part1StepDefinitions.cs create mode 100644 Solutions/Ais.Net.Models.Specs/AisMessageType27StepDefinitions.cs create mode 100644 Solutions/Ais.Net.Models.Specs/AisMessageType5StepDefinitions.cs create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature.cs create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature.cs create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature.cs create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature.cs create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature.cs create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature create mode 100644 Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature.cs diff --git a/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj b/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj index 5e1b7c0..4e626e1 100644 --- a/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj +++ b/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj @@ -42,4 +42,13 @@ PreserveNewest + + + %(Filename) + + + + + + diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType18StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType18StepDefinitions.cs index aa37e8a..9d3245d 100644 --- a/Solutions/Ais.Net.Models.Specs/AisMessageType18StepDefinitions.cs +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType18StepDefinitions.cs @@ -9,8 +9,8 @@ namespace Ais.Net.Models.Specs; [Binding] public class AisMessageType18StepDefinitions { - private AisMessageType18 sut; - private AisMessageType18Data data; + private AisMessageType18? sut; + private AisMessageType18Data? data; [Given("a new AisMessageType18 record with the following properties:")] public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable table) @@ -28,18 +28,23 @@ public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable ta [When("the AisMessageType is created")] public void WhenTheAisMessageTypeIsCreated() { + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + this.sut = new AisMessageType18( CanAcceptMessage22ChannelAssignment: this.data.CanAcceptMessage22ChannelAssignment, CanSwitchBands: this.data.CanSwitchBands, CourseOverGround: this.data.CourseOverGroundDegrees, - CsUnit: Enum.Parse(this.data.CsUnit), + CsUnit: Enum.Parse(this.data.CsUnit ?? throw new InvalidOperationException()), HasDisplay: this.data.HasDisplay, IsAssigned: this.data.IsAssigned, IsDscAttached: this.data.IsDscAttached, Mmsi: this.data.Mmsi, - Position: new Position(this.data.Position.Latitude, this.data.Position.Longitude), + Position: new Position(this.data.Position?.Latitude ?? 0, this.data.Position?.Longitude ?? 0), PositionAccuracy: this.data.PositionAccuracy, - RadioStatusType: Enum.Parse(this.data.RadioStatusType), + RadioStatusType: Enum.Parse(this.data.RadioStatusType ?? throw new InvalidOperationException()), RaimFlag: this.data.RaimFlag, RegionalReserved139: this.data.RegionalReserved139, RegionalReserved38: this.data.RegionalReserved38, @@ -79,14 +84,14 @@ private class AisMessageType18Data public bool CanAcceptMessage22ChannelAssignment { get; set; } public bool CanSwitchBands { get; set; } public float? CourseOverGroundDegrees { get; set; } - public string CsUnit { get; set; } + public string? CsUnit { get; set; } public bool HasDisplay { get; set; } public bool IsAssigned { get; set; } public bool IsDscAttached { get; set; } public uint Mmsi { get; set; } - public PositionData Position { get; set; } + public PositionData? Position { get; set; } public bool PositionAccuracy { get; set; } - public string RadioStatusType { get; set; } + public string? RadioStatusType { get; set; } public bool RaimFlag { get; set; } public int RegionalReserved139 { get; set; } public int RegionalReserved38 { get; set; } diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType19StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType19StepDefinitions.cs new file mode 100644 index 0000000..2931898 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType19StepDefinitions.cs @@ -0,0 +1,118 @@ +namespace Ais.Net.Models.Specs; + +using Abstractions; +using System; + +using Reqnroll; +using Shouldly; + +[Binding] +public class AisMessageType19StepDefinitions +{ + private AisMessageType19? sut; + private AisMessageType19Data? data; + + [Given("a new AisMessageType19 record with the following properties:")] + public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable table) + { + PositionData position = new() + { + Latitude = Convert.ToInt32(table.Rows[0]["Position_Latitude"]), + Longitude = Convert.ToInt32(table.Rows[0]["Position_Longitude"]) + }; + + this.data = table.CreateInstance(); + this.data.Position = position; + } + + [When("the AisMessageType19 is created")] + public void WhenTheAisMessageTypeIsCreated() + { + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + this.sut = new AisMessageType19( + CourseOverGround: this.data.CourseOverGround, + DimensionToBow: this.data.DimensionToBow, + DimensionToPort: this.data.DimensionToPort, + DimensionToStarboard: this.data.DimensionToStarboard, + DimensionToStern: this.data.DimensionToStern, + IsAssigned: this.data.IsAssigned, + IsDteNotReady: this.data.IsDteNotReady, + Mmsi: this.data.Mmsi, + Position: new Position(this.data.Position?.Latitude ?? 0, this.data.Position?.Longitude ?? 0), + PositionAccuracy: this.data.PositionAccuracy, + PositionFixType: Enum.Parse(this.data.PositionFixType ?? throw new InvalidOperationException()), + RaimFlag: this.data.RaimFlag, + RegionalReserved139: this.data.RegionalReserved139, + RegionalReserved38: this.data.RegionalReserved38, + RepeatIndicator: this.data.RepeatIndicator, + ShipName: this.data.ShipName ?? throw new InvalidOperationException(), + ShipType: (ShipType)this.data.ShipType, + Spare308: this.data.Spare308, + SpeedOverGround: this.data.SpeedOverGround, + TimeStampSecond: this.data.TimeStampSecond, + TrueHeadingDegrees: this.data.TrueHeadingDegrees + ); + } + + [Then("the AisMessageType19 properties should be set correctly")] + public void ThenThePropertiesShouldBeSetCorrectly() + { + this.sut.ShouldNotBeNull(); + this.sut.CourseOverGround.ShouldBe(123.45f); + this.sut.DimensionToBow.ShouldBe(1u); + this.sut.DimensionToPort.ShouldBe(2u); + this.sut.DimensionToStarboard.ShouldBe(3u); + this.sut.DimensionToStern.ShouldBe(4u); + this.sut.IsAssigned.ShouldBeTrue(); + this.sut.IsDteNotReady.ShouldBeTrue(); + this.sut.Mmsi.ShouldBe(12345u); + this.sut.Position.ShouldBe(new Position(1.0, 2.0)); + this.sut.PositionAccuracy.ShouldBeTrue(); + this.sut.PositionFixType.ShouldBe(EpfdFixType.Gps); + this.sut.RaimFlag.ShouldBeTrue(); + this.sut.RegionalReserved139.ShouldBe(1); + this.sut.RegionalReserved38.ShouldBe(2); + this.sut.RepeatIndicator.ShouldBe(3u); + this.sut.ShipName.ShouldBe("SHIP"); + ((int)this.sut.ShipType).ShouldBe(60); + this.sut.Spare308.ShouldBe(1u); + this.sut.SpeedOverGround.ShouldBe(12.34f); + this.sut.TimeStampSecond.ShouldBe(56u); + this.sut.TrueHeadingDegrees.ShouldBe(78u); + } + + private class AisMessageType19Data + { + public float? CourseOverGround { get; set; } + public uint DimensionToBow { get; set; } + public uint DimensionToPort { get; set; } + public uint DimensionToStarboard { get; set; } + public uint DimensionToStern { get; set; } + public bool IsAssigned { get; set; } + public bool IsDteNotReady { get; set; } + public uint Mmsi { get; set; } + public PositionData? Position { get; set; } + public bool PositionAccuracy { get; set; } + public string? PositionFixType { get; set; } + public bool RaimFlag { get; set; } + public int RegionalReserved139 { get; set; } + public int RegionalReserved38 { get; set; } + public uint RepeatIndicator { get; set; } + public string? ShipName { get; set; } + public int ShipType { get; set; } + public uint Spare308 { get; set; } + public float? SpeedOverGround { get; set; } + public uint TimeStampSecond { get; set; } + public uint TrueHeadingDegrees { get; set; } + } + + private class PositionData + { + public int Latitude { get; set; } + public int Longitude { get; set; } + } +} \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType1Through3StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType1Through3StepDefinitions.cs new file mode 100644 index 0000000..0a8f2aa --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType1Through3StepDefinitions.cs @@ -0,0 +1,106 @@ +namespace Ais.Net.Models.Specs; + +using Abstractions; +using System; + +using Reqnroll; +using Shouldly; + +[Binding] +public class AisMessageType1Through3StepDefinitions +{ + private AisMessageType1Through3? sut; + private AisMessageType1Through3Data? data; + + [Given("a new AisMessageType1Through3 record with the following properties:")] + public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable table) + { + PositionData position = new() + { + Latitude = Convert.ToInt32(table.Rows[0]["Position_Latitude"]), + Longitude = Convert.ToInt32(table.Rows[0]["Position_Longitude"]) + }; + + this.data = table.CreateInstance(); + this.data.Position = position; + } + + [When("the AisMessageType1Through3 is created")] + public void WhenTheAisMessageTypeIsCreated() + { + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + this.sut = new AisMessageType1Through3( + CourseOverGround: this.data.CourseOverGround, + ManoeuvreIndicator: Enum.Parse(this.data.ManoeuvreIndicator ?? throw new InvalidOperationException()), + MessageType: this.data.MessageType, + Mmsi: this.data.Mmsi, + NavigationStatus: Enum.Parse(this.data.NavigationStatus ?? throw new InvalidOperationException()), + Position: new Position(this.data.Position?.Latitude ?? 0, this.data.Position?.Longitude ?? 0), + PositionAccuracy: this.data.PositionAccuracy, + RadioSlotTimeout: this.data.RadioSlotTimeout, + RadioSubMessage: this.data.RadioSubMessage, + RadioSyncState: Enum.Parse(this.data.RadioSyncState ?? throw new InvalidOperationException()), + RateOfTurn: this.data.RateOfTurn, + RaimFlag: this.data.RaimFlag, + RepeatIndicator: this.data.RepeatIndicator, + SpareBits145: this.data.SpareBits145, + SpeedOverGround: this.data.SpeedOverGround, + TimeStampSecond: this.data.TimeStampSecond, + TrueHeadingDegrees: this.data.TrueHeadingDegrees + ); + } + + [Then("the AisMessageType1Through3 properties should be set correctly")] + public void ThenThePropertiesShouldBeSetCorrectly() + { + this.sut.ShouldNotBeNull(); + this.sut.CourseOverGround.ShouldBe(123.45f); + this.sut.ManoeuvreIndicator.ShouldBe(ManoeuvreIndicator.NotAvailable); + this.sut.MessageType.ShouldBe(1); + this.sut.Mmsi.ShouldBe(12345u); + this.sut.NavigationStatus.ShouldBe(NavigationStatus.UnderwayUsingEngine); + this.sut.Position.ShouldBe(new Position(1.0, 2.0)); + this.sut.PositionAccuracy.ShouldBeTrue(); + this.sut.RadioSlotTimeout.ShouldBe(1u); + this.sut.RadioSubMessage.ShouldBe(2u); + this.sut.RadioSyncState.ShouldBe(RadioSyncState.UtcDirect); + this.sut.RateOfTurn.ShouldBe(1); + this.sut.RaimFlag.ShouldBeTrue(); + this.sut.RepeatIndicator.ShouldBe(3u); + this.sut.SpareBits145.ShouldBe(4u); + this.sut.SpeedOverGround.ShouldBe(12.34f); + this.sut.TimeStampSecond.ShouldBe(56u); + this.sut.TrueHeadingDegrees.ShouldBe(78u); + } + + private class AisMessageType1Through3Data + { + public float? CourseOverGround { get; set; } + public string? ManoeuvreIndicator { get; set; } + public int MessageType { get; set; } + public uint Mmsi { get; set; } + public string? NavigationStatus { get; set; } + public PositionData? Position { get; set; } + public bool PositionAccuracy { get; set; } + public uint RadioSlotTimeout { get; set; } + public uint RadioSubMessage { get; set; } + public string? RadioSyncState { get; set; } + public int RateOfTurn { get; set; } + public bool RaimFlag { get; set; } + public uint RepeatIndicator { get; set; } + public uint SpareBits145 { get; set; } + public float? SpeedOverGround { get; set; } + public uint TimeStampSecond { get; set; } + public uint TrueHeadingDegrees { get; set; } + } + + private class PositionData + { + public int Latitude { get; set; } + public int Longitude { get; set; } + } +} \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType24Part0StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType24Part0StepDefinitions.cs new file mode 100644 index 0000000..a87c466 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType24Part0StepDefinitions.cs @@ -0,0 +1,52 @@ +namespace Ais.Net.Models.Specs; + +using System; +using Reqnroll; +using Shouldly; + +[Binding] +public class AisMessageType24Part0StepDefinitions +{ + private AisMessageType24Part0? sut; + private AisMessageType24Part0Data? data; + + [Given("a new AisMessageType24Part0 record with the following properties:")] + public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable table) + { + this.data = table.CreateInstance(); + } + + [When("the AisMessageType24Part0 is created")] + public void WhenTheAisMessageTypeIsCreated() + { + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + this.sut = new AisMessageType24Part0( + Mmsi: this.data.Mmsi, + PartNumber: this.data.PartNumber, + RepeatIndicator: this.data.RepeatIndicator, + Spare160: this.data.Spare160 + ); + } + + [Then("the AisMessageType24Part0 properties should be set correctly")] + public void ThenThePropertiesShouldBeSetCorrectly() + { + this.sut.ShouldNotBeNull(); + this.sut.Mmsi.ShouldBe(12345u); + this.sut.PartNumber.ShouldBe(0u); + this.sut.RepeatIndicator.ShouldBe(3u); + this.sut.Spare160.ShouldBe(1u); + } + + private class AisMessageType24Part0Data + { + public uint Mmsi { get; set; } + public uint PartNumber { get; set; } + public uint RepeatIndicator { get; set; } + public uint Spare160 { get; set; } + } +} \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType24Part1StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType24Part1StepDefinitions.cs new file mode 100644 index 0000000..5671333 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType24Part1StepDefinitions.cs @@ -0,0 +1,86 @@ +namespace Ais.Net.Models.Specs; + +using Abstractions; +using System; +using Reqnroll; +using Shouldly; + +[Binding] +public class AisMessageType24Part1StepDefinitions +{ + private AisMessageType24Part1? sut; + private AisMessageType24Part1Data? data; + + [Given("a new AisMessageType24Part1 record with the following properties:")] + public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable table) + { + this.data = table.CreateInstance(); + } + + [When("the AisMessageType24Part1 is created")] + public void WhenTheAisMessageTypeIsCreated() + { + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + this.sut = new AisMessageType24Part1( + CallSign: this.data.CallSign ?? throw new InvalidOperationException(), + DimensionToBow: this.data.DimensionToBow, + DimensionToPort: this.data.DimensionToPort, + DimensionToStarboard: this.data.DimensionToStarboard, + DimensionToStern: this.data.DimensionToStern, + Mmsi: this.data.Mmsi, + MothershipMmsi: this.data.MothershipMmsi, + PartNumber: this.data.PartNumber, + RepeatIndicator: this.data.RepeatIndicator, + SerialNumber: this.data.SerialNumber, + Spare162: this.data.Spare162, + ShipType: (ShipType)this.data.ShipType, + UnitModelCode: this.data.UnitModelCode, + VendorIdRev3: this.data.VendorIdRev3 ?? throw new InvalidOperationException(), + VendorIdRev4: this.data.VendorIdRev4 ?? throw new InvalidOperationException() + ); + } + + [Then("the AisMessageType24Part1 properties should be set correctly")] + public void ThenThePropertiesShouldBeSetCorrectly() + { + this.sut.ShouldNotBeNull(); + this.sut.CallSign.ShouldBe("CALL"); + this.sut.DimensionToBow.ShouldBe(1u); + this.sut.DimensionToPort.ShouldBe(2u); + this.sut.DimensionToStarboard.ShouldBe(3u); + this.sut.DimensionToStern.ShouldBe(4u); + this.sut.Mmsi.ShouldBe(12345u); + this.sut.MothershipMmsi.ShouldBe(54321u); + this.sut.PartNumber.ShouldBe(1u); + this.sut.RepeatIndicator.ShouldBe(3u); + this.sut.SerialNumber.ShouldBe(123u); + this.sut.Spare162.ShouldBe(1u); + ((int)this.sut.ShipType).ShouldBe(60); + this.sut.UnitModelCode.ShouldBe(1u); + this.sut.VendorIdRev3.ShouldBe("VEN"); + this.sut.VendorIdRev4.ShouldBe("DOR"); + } + + private class AisMessageType24Part1Data + { + public string? CallSign { get; set; } + public uint DimensionToBow { get; set; } + public uint DimensionToPort { get; set; } + public uint DimensionToStarboard { get; set; } + public uint DimensionToStern { get; set; } + public uint Mmsi { get; set; } + public uint MothershipMmsi { get; set; } + public uint PartNumber { get; set; } + public uint RepeatIndicator { get; set; } + public uint SerialNumber { get; set; } + public uint Spare162 { get; set; } + public int ShipType { get; set; } + public uint UnitModelCode { get; set; } + public string? VendorIdRev3 { get; set; } + public string? VendorIdRev4 { get; set; } + } +} \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType27StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType27StepDefinitions.cs new file mode 100644 index 0000000..77e202e --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType27StepDefinitions.cs @@ -0,0 +1,82 @@ +namespace Ais.Net.Models.Specs; + +using Abstractions; +using System; + +using Reqnroll; +using Shouldly; + +[Binding] +public class AisMessageType27StepDefinitions +{ + private AisMessageType27? sut; + private AisMessageType27Data? data; + + [Given("a new AisMessageType27 record with the following properties:")] + public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable table) + { + PositionData position = new() + { + Latitude = Convert.ToInt32(table.Rows[0]["Position_Latitude"]), + Longitude = Convert.ToInt32(table.Rows[0]["Position_Longitude"]) + }; + + this.data = table.CreateInstance(); + this.data.Position = position; + } + + [When("the AisMessageType27 is created")] + public void WhenTheAisMessageTypeIsCreated() + { + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + this.sut = new AisMessageType27( + CourseOverGround: this.data.CourseOverGround, + GnssPositionStatus: this.data.GnssPositionStatus, + Mmsi: this.data.Mmsi, + NavigationStatus: Enum.Parse(this.data.NavigationStatus ?? throw new InvalidOperationException()), + Position: new Position(this.data.Position?.Latitude ?? 0, this.data.Position?.Longitude ?? 0), + PositionAccuracy: this.data.PositionAccuracy, + RaimFlag: this.data.RaimFlag, + RepeatIndicator: this.data.RepeatIndicator, + SpeedOverGround: this.data.SpeedOverGround + ); + } + + [Then("the AisMessageType27 properties should be set correctly")] + public void ThenThePropertiesShouldBeSetCorrectly() + { + this.sut.ShouldNotBeNull(); + this.sut.CourseOverGround.ShouldBe(123.45f); + this.sut.GnssPositionStatus.ShouldBeTrue(); + this.sut.Mmsi.ShouldBe(12345u); + this.sut.NavigationStatus.ShouldBe(NavigationStatus.UnderwayUsingEngine); + this.sut.Position.ShouldBe(new Position(1.0, 2.0)); + this.sut.PositionAccuracy.ShouldBeTrue(); + this.sut.RaimFlag.ShouldBeTrue(); + this.sut.RepeatIndicator.ShouldBe(3u); + this.sut.SpeedOverGround.ShouldBe(12.34f); + } + + private class AisMessageType27Data + { + public float? CourseOverGround { get; set; } + public bool GnssPositionStatus { get; set; } + public uint Mmsi { get; set; } + public string? NavigationStatus { get; set; } + public PositionData? Position { get; set; } + public bool PositionAccuracy { get; set; } + public bool RaimFlag { get; set; } + public uint RepeatIndicator { get; set; } + public float? SpeedOverGround { get; set; } + } + + private class PositionData + { + public int Latitude { get; set; } + public int Longitude { get; set; } + } +} \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType5StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType5StepDefinitions.cs new file mode 100644 index 0000000..ffd48f5 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType5StepDefinitions.cs @@ -0,0 +1,102 @@ +namespace Ais.Net.Models.Specs; + +using Abstractions; +using System; + +using Reqnroll; +using Shouldly; + +[Binding] +public class AisMessageType5StepDefinitions +{ + private AisMessageType5? sut; + private AisMessageType5Data? data; + + [Given("a new AisMessageType5 record with the following properties:")] + public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable table) + { + this.data = table.CreateInstance(); + } + + [When("the AisMessageType5 is created")] + public void WhenTheAisMessageTypeIsCreated() + { + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + this.sut = new AisMessageType5( + AisVersion: this.data.AisVersion, + CallSign: this.data.CallSign ?? throw new InvalidOperationException(), + Destination: this.data.Destination ?? throw new InvalidOperationException(), + DimensionToBow: this.data.DimensionToBow, + DimensionToPort: this.data.DimensionToPort, + DimensionToStarboard: this.data.DimensionToStarboard, + DimensionToStern: this.data.DimensionToStern, + Draught10thMetres: this.data.Draught10thMetres, + EtaDay: this.data.EtaDay, + EtaHour: this.data.EtaHour, + EtaMinute: this.data.EtaMinute, + EtaMonth: this.data.EtaMonth, + IsDteNotReady: this.data.IsDteNotReady, + ImoNumber: this.data.ImoNumber, + Mmsi: this.data.Mmsi, + PositionFixType: Enum.Parse(this.data.PositionFixType ?? throw new InvalidOperationException()), + RepeatIndicator: this.data.RepeatIndicator, + ShipType: (ShipType)this.data.ShipType, + Spare423: this.data.Spare423, + VesselName: this.data.VesselName ?? throw new InvalidOperationException() + ); + } + + [Then("the AisMessageType5 properties should be set correctly")] + public void ThenThePropertiesShouldBeSetCorrectly() + { + this.sut.ShouldNotBeNull(); + this.sut.AisVersion.ShouldBe(1u); + this.sut.CallSign.ShouldBe("CALL"); + this.sut.Destination.ShouldBe("DEST"); + this.sut.DimensionToBow.ShouldBe(1u); + this.sut.DimensionToPort.ShouldBe(2u); + this.sut.DimensionToStarboard.ShouldBe(3u); + this.sut.DimensionToStern.ShouldBe(4u); + this.sut.Draught10thMetres.ShouldBe(5u); + this.sut.EtaDay.ShouldBe(6u); + this.sut.EtaHour.ShouldBe(7u); + this.sut.EtaMinute.ShouldBe(8u); + this.sut.EtaMonth.ShouldBe(9u); + this.sut.IsDteNotReady.ShouldBeTrue(); + this.sut.ImoNumber.ShouldBe(123u); + this.sut.Mmsi.ShouldBe(12345u); + this.sut.PositionFixType.ShouldBe(EpfdFixType.Gps); + this.sut.RepeatIndicator.ShouldBe(3u); + ((int)this.sut.ShipType).ShouldBe(60); + this.sut.Spare423.ShouldBe(1u); + this.sut.VesselName.ShouldBe("VESSEL"); + } + + private class AisMessageType5Data + { + public uint AisVersion { get; set; } + public string? CallSign { get; set; } + public string? Destination { get; set; } + public uint DimensionToBow { get; set; } + public uint DimensionToPort { get; set; } + public uint DimensionToStarboard { get; set; } + public uint DimensionToStern { get; set; } + public uint Draught10thMetres { get; set; } + public uint EtaDay { get; set; } + public uint EtaHour { get; set; } + public uint EtaMinute { get; set; } + public uint EtaMonth { get; set; } + public bool IsDteNotReady { get; set; } + public uint ImoNumber { get; set; } + public uint Mmsi { get; set; } + public string? PositionFixType { get; set; } + public uint RepeatIndicator { get; set; } + public int ShipType { get; set; } + public uint Spare423 { get; set; } + public string? VesselName { get; set; } + } +} \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature new file mode 100644 index 0000000..3cde8ac --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature @@ -0,0 +1,8 @@ +Feature: AisMessageType19 + +Scenario: Create AisMessageType19 record + Given a new AisMessageType19 record with the following properties: + | CourseOverGround | DimensionToBow | DimensionToPort | DimensionToStarboard | DimensionToStern | IsAssigned | IsDteNotReady | Mmsi | Position_Latitude | Position_Longitude | PositionAccuracy | PositionFixType | RaimFlag | RegionalReserved139 | RegionalReserved38 | RepeatIndicator | ShipName | ShipType | Spare308 | SpeedOverGround | TimeStampSecond | TrueHeadingDegrees | + | 123.45 | 1 | 2 | 3 | 4 | true | true | 12345 | 1 | 2 | true | Gps | true | 1 | 2 | 3 | SHIP | 60 | 1 | 12.34 | 56 | 78 | + When the AisMessageType19 is created + Then the AisMessageType19 properties should be set correctly \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature.cs new file mode 100644 index 0000000..e5600cd --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature.cs @@ -0,0 +1,183 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by Reqnroll (https://www.reqnroll.net/). +// Reqnroll Version:2.0.0.0 +// Reqnroll Generator Version:2.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +#region Designer generated code +#pragma warning disable +using Reqnroll; +namespace Ais.Net.Models.Specs.Features +{ + + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [NUnit.Framework.TestFixtureAttribute()] + [NUnit.Framework.DescriptionAttribute("AisMessageType19")] + [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] + public partial class AisMessageType19Feature + { + + private global::Reqnroll.ITestRunner testRunner; + + private static string[] featureTags = ((string[])(null)); + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType19", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + +#line 1 "AisMessageType19.feature" +#line hidden + + [NUnit.Framework.OneTimeSetUpAttribute()] + public static async global::System.Threading.Tasks.Task FeatureSetupAsync() + { + } + + [NUnit.Framework.OneTimeTearDownAttribute()] + public static async global::System.Threading.Tasks.Task FeatureTearDownAsync() + { + } + + [NUnit.Framework.SetUpAttribute()] + public async global::System.Threading.Tasks.Task TestInitializeAsync() + { + testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo); + try + { + if (((testRunner.FeatureContext != null) + && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false))) + { + await testRunner.OnFeatureEndAsync(); + } + } + finally + { + if (((testRunner.FeatureContext != null) + && testRunner.FeatureContext.BeforeFeatureHookFailed)) + { + throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error"); + } + if ((testRunner.FeatureContext == null)) + { + await testRunner.OnFeatureStartAsync(featureInfo); + } + } + } + + [NUnit.Framework.TearDownAttribute()] + public async global::System.Threading.Tasks.Task TestTearDownAsync() + { + if ((testRunner == null)) + { + return; + } + try + { + await testRunner.OnScenarioEndAsync(); + } + finally + { + global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner); + testRunner = null; + } + } + + public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) + { + testRunner.OnScenarioInitialize(scenarioInfo); + testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); + } + + public async global::System.Threading.Tasks.Task ScenarioStartAsync() + { + await testRunner.OnScenarioStartAsync(); + } + + public async global::System.Threading.Tasks.Task ScenarioCleanupAsync() + { + await testRunner.CollectScenarioErrorsAsync(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Create AisMessageType19 record")] + public async global::System.Threading.Tasks.Task CreateAisMessageType19Record() + { + string[] tagsOfScenario = ((string[])(null)); + global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType19 record", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 3 +this.ScenarioInitialize(scenarioInfo); +#line hidden + if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) + { + testRunner.SkipScenario(); + } + else + { + await this.ScenarioStartAsync(); + global::Reqnroll.Table table2 = new global::Reqnroll.Table(new string[] { + "CourseOverGround", + "DimensionToBow", + "DimensionToPort", + "DimensionToStarboard", + "DimensionToStern", + "IsAssigned", + "IsDteNotReady", + "Mmsi", + "Position_Latitude", + "Position_Longitude", + "PositionAccuracy", + "PositionFixType", + "RaimFlag", + "RegionalReserved139", + "RegionalReserved38", + "RepeatIndicator", + "ShipName", + "ShipType", + "Spare308", + "SpeedOverGround", + "TimeStampSecond", + "TrueHeadingDegrees"}); + table2.AddRow(new string[] { + "123.45", + "1", + "2", + "3", + "4", + "true", + "true", + "12345", + "1", + "2", + "true", + "Gps", + "true", + "1", + "2", + "3", + "SHIP", + "60", + "1", + "12.34", + "56", + "78"}); +#line 4 + await testRunner.GivenAsync("a new AisMessageType19 record with the following properties:", ((string)(null)), table2, "Given "); +#line hidden +#line 7 + await testRunner.WhenAsync("the AisMessageType19 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 8 + await testRunner.ThenAsync("the AisMessageType19 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden + } + await this.ScenarioCleanupAsync(); + } + } +} +#pragma warning restore +#endregion diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature new file mode 100644 index 0000000..4d33927 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature @@ -0,0 +1,8 @@ +Feature: AisMessageType1Through3 + +Scenario: Create AisMessageType1Through3 record + Given a new AisMessageType1Through3 record with the following properties: + | CourseOverGround | ManoeuvreIndicator | MessageType | Mmsi | NavigationStatus | Position_Latitude | Position_Longitude | PositionAccuracy | RadioSlotTimeout | RadioSubMessage | RadioSyncState | RateOfTurn | RaimFlag | RepeatIndicator | SpareBits145 | SpeedOverGround | TimeStampSecond | TrueHeadingDegrees | + | 123.45 | NotAvailable | 1 | 12345 | UnderwayUsingEngine | 1 | 2 | true | 1 | 2 | UtcDirect | 1 | true | 3 | 4 | 12.34 | 56 | 78 | + When the AisMessageType1Through3 is created + Then the AisMessageType1Through3 properties should be set correctly \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature.cs new file mode 100644 index 0000000..bc1090f --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature.cs @@ -0,0 +1,175 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by Reqnroll (https://www.reqnroll.net/). +// Reqnroll Version:2.0.0.0 +// Reqnroll Generator Version:2.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +#region Designer generated code +#pragma warning disable +using Reqnroll; +namespace Ais.Net.Models.Specs.Features +{ + + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [NUnit.Framework.TestFixtureAttribute()] + [NUnit.Framework.DescriptionAttribute("AisMessageType1Through3")] + [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] + public partial class AisMessageType1Through3Feature + { + + private global::Reqnroll.ITestRunner testRunner; + + private static string[] featureTags = ((string[])(null)); + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType1Through3", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + +#line 1 "AisMessageType1Through3.feature" +#line hidden + + [NUnit.Framework.OneTimeSetUpAttribute()] + public static async global::System.Threading.Tasks.Task FeatureSetupAsync() + { + } + + [NUnit.Framework.OneTimeTearDownAttribute()] + public static async global::System.Threading.Tasks.Task FeatureTearDownAsync() + { + } + + [NUnit.Framework.SetUpAttribute()] + public async global::System.Threading.Tasks.Task TestInitializeAsync() + { + testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo); + try + { + if (((testRunner.FeatureContext != null) + && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false))) + { + await testRunner.OnFeatureEndAsync(); + } + } + finally + { + if (((testRunner.FeatureContext != null) + && testRunner.FeatureContext.BeforeFeatureHookFailed)) + { + throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error"); + } + if ((testRunner.FeatureContext == null)) + { + await testRunner.OnFeatureStartAsync(featureInfo); + } + } + } + + [NUnit.Framework.TearDownAttribute()] + public async global::System.Threading.Tasks.Task TestTearDownAsync() + { + if ((testRunner == null)) + { + return; + } + try + { + await testRunner.OnScenarioEndAsync(); + } + finally + { + global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner); + testRunner = null; + } + } + + public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) + { + testRunner.OnScenarioInitialize(scenarioInfo); + testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); + } + + public async global::System.Threading.Tasks.Task ScenarioStartAsync() + { + await testRunner.OnScenarioStartAsync(); + } + + public async global::System.Threading.Tasks.Task ScenarioCleanupAsync() + { + await testRunner.CollectScenarioErrorsAsync(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Create AisMessageType1Through3 record")] + public async global::System.Threading.Tasks.Task CreateAisMessageType1Through3Record() + { + string[] tagsOfScenario = ((string[])(null)); + global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType1Through3 record", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 3 +this.ScenarioInitialize(scenarioInfo); +#line hidden + if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) + { + testRunner.SkipScenario(); + } + else + { + await this.ScenarioStartAsync(); + global::Reqnroll.Table table3 = new global::Reqnroll.Table(new string[] { + "CourseOverGround", + "ManoeuvreIndicator", + "MessageType", + "Mmsi", + "NavigationStatus", + "Position_Latitude", + "Position_Longitude", + "PositionAccuracy", + "RadioSlotTimeout", + "RadioSubMessage", + "RadioSyncState", + "RateOfTurn", + "RaimFlag", + "RepeatIndicator", + "SpareBits145", + "SpeedOverGround", + "TimeStampSecond", + "TrueHeadingDegrees"}); + table3.AddRow(new string[] { + "123.45", + "NotAvailable", + "1", + "12345", + "UnderwayUsingEngine", + "1", + "2", + "true", + "1", + "2", + "UtcDirect", + "1", + "true", + "3", + "4", + "12.34", + "56", + "78"}); +#line 4 + await testRunner.GivenAsync("a new AisMessageType1Through3 record with the following properties:", ((string)(null)), table3, "Given "); +#line hidden +#line 7 + await testRunner.WhenAsync("the AisMessageType1Through3 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 8 + await testRunner.ThenAsync("the AisMessageType1Through3 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden + } + await this.ScenarioCleanupAsync(); + } + } +} +#pragma warning restore +#endregion diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature new file mode 100644 index 0000000..e4acf4c --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature @@ -0,0 +1,8 @@ +Feature: AisMessageType24Part0 + +Scenario: Create AisMessageType24Part0 record + Given a new AisMessageType24Part0 record with the following properties: + | Mmsi | PartNumber | RepeatIndicator | Spare160 | + | 12345 | 0 | 3 | 1 | + When the AisMessageType24Part0 is created + Then the AisMessageType24Part0 properties should be set correctly \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature.cs new file mode 100644 index 0000000..25abb75 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature.cs @@ -0,0 +1,147 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by Reqnroll (https://www.reqnroll.net/). +// Reqnroll Version:2.0.0.0 +// Reqnroll Generator Version:2.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +#region Designer generated code +#pragma warning disable +using Reqnroll; +namespace Ais.Net.Models.Specs.Features +{ + + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [NUnit.Framework.TestFixtureAttribute()] + [NUnit.Framework.DescriptionAttribute("AisMessageType24Part0")] + [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] + public partial class AisMessageType24Part0Feature + { + + private global::Reqnroll.ITestRunner testRunner; + + private static string[] featureTags = ((string[])(null)); + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType24Part0", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + +#line 1 "AisMessageType24Part0.feature" +#line hidden + + [NUnit.Framework.OneTimeSetUpAttribute()] + public static async global::System.Threading.Tasks.Task FeatureSetupAsync() + { + } + + [NUnit.Framework.OneTimeTearDownAttribute()] + public static async global::System.Threading.Tasks.Task FeatureTearDownAsync() + { + } + + [NUnit.Framework.SetUpAttribute()] + public async global::System.Threading.Tasks.Task TestInitializeAsync() + { + testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo); + try + { + if (((testRunner.FeatureContext != null) + && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false))) + { + await testRunner.OnFeatureEndAsync(); + } + } + finally + { + if (((testRunner.FeatureContext != null) + && testRunner.FeatureContext.BeforeFeatureHookFailed)) + { + throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error"); + } + if ((testRunner.FeatureContext == null)) + { + await testRunner.OnFeatureStartAsync(featureInfo); + } + } + } + + [NUnit.Framework.TearDownAttribute()] + public async global::System.Threading.Tasks.Task TestTearDownAsync() + { + if ((testRunner == null)) + { + return; + } + try + { + await testRunner.OnScenarioEndAsync(); + } + finally + { + global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner); + testRunner = null; + } + } + + public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) + { + testRunner.OnScenarioInitialize(scenarioInfo); + testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); + } + + public async global::System.Threading.Tasks.Task ScenarioStartAsync() + { + await testRunner.OnScenarioStartAsync(); + } + + public async global::System.Threading.Tasks.Task ScenarioCleanupAsync() + { + await testRunner.CollectScenarioErrorsAsync(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Create AisMessageType24Part0 record")] + public async global::System.Threading.Tasks.Task CreateAisMessageType24Part0Record() + { + string[] tagsOfScenario = ((string[])(null)); + global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType24Part0 record", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 3 +this.ScenarioInitialize(scenarioInfo); +#line hidden + if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) + { + testRunner.SkipScenario(); + } + else + { + await this.ScenarioStartAsync(); + global::Reqnroll.Table table4 = new global::Reqnroll.Table(new string[] { + "Mmsi", + "PartNumber", + "RepeatIndicator", + "Spare160"}); + table4.AddRow(new string[] { + "12345", + "0", + "3", + "1"}); +#line 4 + await testRunner.GivenAsync("a new AisMessageType24Part0 record with the following properties:", ((string)(null)), table4, "Given "); +#line hidden +#line 7 + await testRunner.WhenAsync("the AisMessageType24Part0 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 8 + await testRunner.ThenAsync("the AisMessageType24Part0 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden + } + await this.ScenarioCleanupAsync(); + } + } +} +#pragma warning restore +#endregion diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature new file mode 100644 index 0000000..0827626 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature @@ -0,0 +1,8 @@ +Feature: AisMessageType24Part1 + +Scenario: Create AisMessageType24Part1 record + Given a new AisMessageType24Part1 record with the following properties: + | CallSign | DimensionToBow | DimensionToPort | DimensionToStarboard | DimensionToStern | Mmsi | MothershipMmsi | PartNumber | RepeatIndicator | SerialNumber | Spare162 | ShipType | UnitModelCode | VendorIdRev3 | VendorIdRev4 | + | CALL | 1 | 2 | 3 | 4 | 12345 | 54321 | 1 | 3 | 123 | 1 | 60 | 1 | VEN | DOR | + When the AisMessageType24Part1 is created + Then the AisMessageType24Part1 properties should be set correctly \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature.cs new file mode 100644 index 0000000..e78f712 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature.cs @@ -0,0 +1,169 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by Reqnroll (https://www.reqnroll.net/). +// Reqnroll Version:2.0.0.0 +// Reqnroll Generator Version:2.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +#region Designer generated code +#pragma warning disable +using Reqnroll; +namespace Ais.Net.Models.Specs.Features +{ + + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [NUnit.Framework.TestFixtureAttribute()] + [NUnit.Framework.DescriptionAttribute("AisMessageType24Part1")] + [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] + public partial class AisMessageType24Part1Feature + { + + private global::Reqnroll.ITestRunner testRunner; + + private static string[] featureTags = ((string[])(null)); + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType24Part1", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + +#line 1 "AisMessageType24Part1.feature" +#line hidden + + [NUnit.Framework.OneTimeSetUpAttribute()] + public static async global::System.Threading.Tasks.Task FeatureSetupAsync() + { + } + + [NUnit.Framework.OneTimeTearDownAttribute()] + public static async global::System.Threading.Tasks.Task FeatureTearDownAsync() + { + } + + [NUnit.Framework.SetUpAttribute()] + public async global::System.Threading.Tasks.Task TestInitializeAsync() + { + testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo); + try + { + if (((testRunner.FeatureContext != null) + && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false))) + { + await testRunner.OnFeatureEndAsync(); + } + } + finally + { + if (((testRunner.FeatureContext != null) + && testRunner.FeatureContext.BeforeFeatureHookFailed)) + { + throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error"); + } + if ((testRunner.FeatureContext == null)) + { + await testRunner.OnFeatureStartAsync(featureInfo); + } + } + } + + [NUnit.Framework.TearDownAttribute()] + public async global::System.Threading.Tasks.Task TestTearDownAsync() + { + if ((testRunner == null)) + { + return; + } + try + { + await testRunner.OnScenarioEndAsync(); + } + finally + { + global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner); + testRunner = null; + } + } + + public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) + { + testRunner.OnScenarioInitialize(scenarioInfo); + testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); + } + + public async global::System.Threading.Tasks.Task ScenarioStartAsync() + { + await testRunner.OnScenarioStartAsync(); + } + + public async global::System.Threading.Tasks.Task ScenarioCleanupAsync() + { + await testRunner.CollectScenarioErrorsAsync(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Create AisMessageType24Part1 record")] + public async global::System.Threading.Tasks.Task CreateAisMessageType24Part1Record() + { + string[] tagsOfScenario = ((string[])(null)); + global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType24Part1 record", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 3 +this.ScenarioInitialize(scenarioInfo); +#line hidden + if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) + { + testRunner.SkipScenario(); + } + else + { + await this.ScenarioStartAsync(); + global::Reqnroll.Table table5 = new global::Reqnroll.Table(new string[] { + "CallSign", + "DimensionToBow", + "DimensionToPort", + "DimensionToStarboard", + "DimensionToStern", + "Mmsi", + "MothershipMmsi", + "PartNumber", + "RepeatIndicator", + "SerialNumber", + "Spare162", + "ShipType", + "UnitModelCode", + "VendorIdRev3", + "VendorIdRev4"}); + table5.AddRow(new string[] { + "CALL", + "1", + "2", + "3", + "4", + "12345", + "54321", + "1", + "3", + "123", + "1", + "60", + "1", + "VEN", + "DOR"}); +#line 4 + await testRunner.GivenAsync("a new AisMessageType24Part1 record with the following properties:", ((string)(null)), table5, "Given "); +#line hidden +#line 7 + await testRunner.WhenAsync("the AisMessageType24Part1 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 8 + await testRunner.ThenAsync("the AisMessageType24Part1 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden + } + await this.ScenarioCleanupAsync(); + } + } +} +#pragma warning restore +#endregion diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature new file mode 100644 index 0000000..bab76c0 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature @@ -0,0 +1,8 @@ +Feature: AisMessageType27 + +Scenario: Create AisMessageType27 record + Given a new AisMessageType27 record with the following properties: + | CourseOverGround | GnssPositionStatus | Mmsi | NavigationStatus | Position_Latitude | Position_Longitude | PositionAccuracy | RaimFlag | RepeatIndicator | SpeedOverGround | + | 123.45 | true | 12345 | UnderwayUsingEngine | 1 | 2 | true | true | 3 | 12.34 | + When the AisMessageType27 is created + Then the AisMessageType27 properties should be set correctly \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature.cs new file mode 100644 index 0000000..67c6cc2 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature.cs @@ -0,0 +1,159 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by Reqnroll (https://www.reqnroll.net/). +// Reqnroll Version:2.0.0.0 +// Reqnroll Generator Version:2.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +#region Designer generated code +#pragma warning disable +using Reqnroll; +namespace Ais.Net.Models.Specs.Features +{ + + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [NUnit.Framework.TestFixtureAttribute()] + [NUnit.Framework.DescriptionAttribute("AisMessageType27")] + [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] + public partial class AisMessageType27Feature + { + + private global::Reqnroll.ITestRunner testRunner; + + private static string[] featureTags = ((string[])(null)); + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType27", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + +#line 1 "AisMessageType27.feature" +#line hidden + + [NUnit.Framework.OneTimeSetUpAttribute()] + public static async global::System.Threading.Tasks.Task FeatureSetupAsync() + { + } + + [NUnit.Framework.OneTimeTearDownAttribute()] + public static async global::System.Threading.Tasks.Task FeatureTearDownAsync() + { + } + + [NUnit.Framework.SetUpAttribute()] + public async global::System.Threading.Tasks.Task TestInitializeAsync() + { + testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo); + try + { + if (((testRunner.FeatureContext != null) + && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false))) + { + await testRunner.OnFeatureEndAsync(); + } + } + finally + { + if (((testRunner.FeatureContext != null) + && testRunner.FeatureContext.BeforeFeatureHookFailed)) + { + throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error"); + } + if ((testRunner.FeatureContext == null)) + { + await testRunner.OnFeatureStartAsync(featureInfo); + } + } + } + + [NUnit.Framework.TearDownAttribute()] + public async global::System.Threading.Tasks.Task TestTearDownAsync() + { + if ((testRunner == null)) + { + return; + } + try + { + await testRunner.OnScenarioEndAsync(); + } + finally + { + global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner); + testRunner = null; + } + } + + public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) + { + testRunner.OnScenarioInitialize(scenarioInfo); + testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); + } + + public async global::System.Threading.Tasks.Task ScenarioStartAsync() + { + await testRunner.OnScenarioStartAsync(); + } + + public async global::System.Threading.Tasks.Task ScenarioCleanupAsync() + { + await testRunner.CollectScenarioErrorsAsync(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Create AisMessageType27 record")] + public async global::System.Threading.Tasks.Task CreateAisMessageType27Record() + { + string[] tagsOfScenario = ((string[])(null)); + global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType27 record", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 3 +this.ScenarioInitialize(scenarioInfo); +#line hidden + if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) + { + testRunner.SkipScenario(); + } + else + { + await this.ScenarioStartAsync(); + global::Reqnroll.Table table6 = new global::Reqnroll.Table(new string[] { + "CourseOverGround", + "GnssPositionStatus", + "Mmsi", + "NavigationStatus", + "Position_Latitude", + "Position_Longitude", + "PositionAccuracy", + "RaimFlag", + "RepeatIndicator", + "SpeedOverGround"}); + table6.AddRow(new string[] { + "123.45", + "true", + "12345", + "UnderwayUsingEngine", + "1", + "2", + "true", + "true", + "3", + "12.34"}); +#line 4 + await testRunner.GivenAsync("a new AisMessageType27 record with the following properties:", ((string)(null)), table6, "Given "); +#line hidden +#line 7 + await testRunner.WhenAsync("the AisMessageType27 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 8 + await testRunner.ThenAsync("the AisMessageType27 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden + } + await this.ScenarioCleanupAsync(); + } + } +} +#pragma warning restore +#endregion diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature new file mode 100644 index 0000000..f090714 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature @@ -0,0 +1,8 @@ +Feature: AisMessageType5 + +Scenario: Create AisMessageType5 record + Given a new AisMessageType5 record with the following properties: + | AisVersion | CallSign | Destination | DimensionToBow | DimensionToPort | DimensionToStarboard | DimensionToStern | Draught10thMetres | EtaDay | EtaHour | EtaMinute | EtaMonth | IsDteNotReady | ImoNumber | Mmsi | PositionFixType | RepeatIndicator | ShipType | Spare423 | VesselName | + | 1 | CALL | DEST | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | true | 123 | 12345 | Gps | 3 | 60 | 1 | VESSEL | + When the AisMessageType5 is created + Then the AisMessageType5 properties should be set correctly \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature.cs new file mode 100644 index 0000000..9dc2d55 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature.cs @@ -0,0 +1,179 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by Reqnroll (https://www.reqnroll.net/). +// Reqnroll Version:2.0.0.0 +// Reqnroll Generator Version:2.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +#region Designer generated code +#pragma warning disable +using Reqnroll; +namespace Ais.Net.Models.Specs.Features +{ + + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [NUnit.Framework.TestFixtureAttribute()] + [NUnit.Framework.DescriptionAttribute("AisMessageType5")] + [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] + public partial class AisMessageType5Feature + { + + private global::Reqnroll.ITestRunner testRunner; + + private static string[] featureTags = ((string[])(null)); + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType5", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + +#line 1 "AisMessageType5.feature" +#line hidden + + [NUnit.Framework.OneTimeSetUpAttribute()] + public static async global::System.Threading.Tasks.Task FeatureSetupAsync() + { + } + + [NUnit.Framework.OneTimeTearDownAttribute()] + public static async global::System.Threading.Tasks.Task FeatureTearDownAsync() + { + } + + [NUnit.Framework.SetUpAttribute()] + public async global::System.Threading.Tasks.Task TestInitializeAsync() + { + testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo); + try + { + if (((testRunner.FeatureContext != null) + && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false))) + { + await testRunner.OnFeatureEndAsync(); + } + } + finally + { + if (((testRunner.FeatureContext != null) + && testRunner.FeatureContext.BeforeFeatureHookFailed)) + { + throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error"); + } + if ((testRunner.FeatureContext == null)) + { + await testRunner.OnFeatureStartAsync(featureInfo); + } + } + } + + [NUnit.Framework.TearDownAttribute()] + public async global::System.Threading.Tasks.Task TestTearDownAsync() + { + if ((testRunner == null)) + { + return; + } + try + { + await testRunner.OnScenarioEndAsync(); + } + finally + { + global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner); + testRunner = null; + } + } + + public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) + { + testRunner.OnScenarioInitialize(scenarioInfo); + testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(NUnit.Framework.TestContext.CurrentContext); + } + + public async global::System.Threading.Tasks.Task ScenarioStartAsync() + { + await testRunner.OnScenarioStartAsync(); + } + + public async global::System.Threading.Tasks.Task ScenarioCleanupAsync() + { + await testRunner.CollectScenarioErrorsAsync(); + } + + [NUnit.Framework.TestAttribute()] + [NUnit.Framework.DescriptionAttribute("Create AisMessageType5 record")] + public async global::System.Threading.Tasks.Task CreateAisMessageType5Record() + { + string[] tagsOfScenario = ((string[])(null)); + global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType5 record", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 3 +this.ScenarioInitialize(scenarioInfo); +#line hidden + if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) + { + testRunner.SkipScenario(); + } + else + { + await this.ScenarioStartAsync(); + global::Reqnroll.Table table7 = new global::Reqnroll.Table(new string[] { + "AisVersion", + "CallSign", + "Destination", + "DimensionToBow", + "DimensionToPort", + "DimensionToStarboard", + "DimensionToStern", + "Draught10thMetres", + "EtaDay", + "EtaHour", + "EtaMinute", + "EtaMonth", + "IsDteNotReady", + "ImoNumber", + "Mmsi", + "PositionFixType", + "RepeatIndicator", + "ShipType", + "Spare423", + "VesselName"}); + table7.AddRow(new string[] { + "1", + "CALL", + "DEST", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "true", + "123", + "12345", + "Gps", + "3", + "60", + "1", + "VESSEL"}); +#line 4 + await testRunner.GivenAsync("a new AisMessageType5 record with the following properties:", ((string)(null)), table7, "Given "); +#line hidden +#line 7 + await testRunner.WhenAsync("the AisMessageType5 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 8 + await testRunner.ThenAsync("the AisMessageType5 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden + } + await this.ScenarioCleanupAsync(); + } + } +} +#pragma warning restore +#endregion From 0bb850983e87ab350270925049103cc2bcdac8a9 Mon Sep 17 00:00:00 2001 From: Howard van Rooijen Date: Wed, 18 Jun 2025 10:39:21 +0100 Subject: [PATCH 04/15] Refactor AIS step definitions and improve structure This commit refactors several AIS message type step definition classes to inherit from a new base class `StepDefinitionBase`, introducing a common `Message` property for better management of created AIS messages. The `PositionData` class is updated to use `double` for `Latitude` and `Longitude` for improved precision. A new `CommonStepDefinitions` class is added for shared background steps, and feature files are renamed for clarity, utilizing parameterized examples. Additionally, a `Hooks` class is introduced to handle pre- and post-scenario logic, enhancing the overall structure and maintainability of the tests. --- .../AisMessageType18StepDefinitions.cs | 60 +++++---- .../AisMessageType19StepDefinitions.cs | 66 +++++----- .../AisMessageType1Through3StepDefinitions.cs | 58 ++++---- .../AisMessageType24Part0StepDefinitions.cs | 24 ++-- .../AisMessageType24Part1StepDefinitions.cs | 47 ++++--- .../AisMessageType27StepDefinitions.cs | 44 ++++--- .../AisMessageType5StepDefinitions.cs | 56 ++++---- .../CommonStepDefinitions.cs | 15 +++ .../Features/AisMessageType18.feature | 15 ++- .../Features/AisMessageType18.feature.cs | 112 +++++++++++----- .../Features/AisMessageType19.feature | 15 ++- .../Features/AisMessageType19.feature.cs | 124 +++++++++++++----- .../Features/AisMessageType1Through3.feature | 18 ++- .../AisMessageType1Through3.feature.cs | 60 ++++++--- .../Features/AisMessageType24Part0.feature | 15 ++- .../Features/AisMessageType24Part0.feature.cs | 47 ++++--- .../Features/AisMessageType24Part1.feature | 15 ++- .../Features/AisMessageType24Part1.feature.cs | 96 ++++++++++---- .../Features/AisMessageType27.feature | 15 ++- .../Features/AisMessageType27.feature.cs | 65 ++++++--- .../Features/AisMessageType5.feature | 15 ++- .../Features/AisMessageType5.feature.cs | 116 +++++++++++----- Solutions/Ais.Net.Models.Specs/Hooks.cs | 20 +++ .../StepDefinitionBase.cs | 9 ++ 24 files changed, 769 insertions(+), 358 deletions(-) create mode 100644 Solutions/Ais.Net.Models.Specs/CommonStepDefinitions.cs create mode 100644 Solutions/Ais.Net.Models.Specs/Hooks.cs create mode 100644 Solutions/Ais.Net.Models.Specs/StepDefinitionBase.cs diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType18StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType18StepDefinitions.cs index 9d3245d..97a007a 100644 --- a/Solutions/Ais.Net.Models.Specs/AisMessageType18StepDefinitions.cs +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType18StepDefinitions.cs @@ -1,15 +1,16 @@ namespace Ais.Net.Models.Specs; -using Abstractions; using System; +using Abstractions; + using Reqnroll; + using Shouldly; [Binding] -public class AisMessageType18StepDefinitions +public class AisMessageType18StepDefinitions : StepDefinitionBase { - private AisMessageType18? sut; private AisMessageType18Data? data; [Given("a new AisMessageType18 record with the following properties:")] @@ -17,8 +18,8 @@ public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable ta { PositionData position = new() { - Latitude = Convert.ToInt32(table.Rows[0]["Position_Latitude"]), - Longitude = Convert.ToInt32(table.Rows[0]["Position_Longitude"]) + Latitude = Convert.ToDouble(table.Rows[0]["Position_Latitude"]), + Longitude = Convert.ToDouble(table.Rows[0]["Position_Longitude"]) }; this.data = table.CreateInstance(); @@ -33,7 +34,7 @@ public void WhenTheAisMessageTypeIsCreated() throw new InvalidOperationException("Data is not set"); } - this.sut = new AisMessageType18( + this.Message = new AisMessageType18( CanAcceptMessage22ChannelAssignment: this.data.CanAcceptMessage22ChannelAssignment, CanSwitchBands: this.data.CanSwitchBands, CourseOverGround: this.data.CourseOverGroundDegrees, @@ -58,25 +59,30 @@ public void WhenTheAisMessageTypeIsCreated() [Then("the properties should be set correctly")] public void ThenThePropertiesShouldBeSetCorrectly() { - this.sut.ShouldNotBeNull(); - this.sut.CanAcceptMessage22ChannelAssignment.ShouldBeTrue(); - this.sut.CanSwitchBands.ShouldBeTrue(); - this.sut.CourseOverGround.ShouldBe(123.45f); - this.sut.CsUnit.ShouldBe(ClassBUnit.Cstdma); - this.sut.HasDisplay.ShouldBeTrue(); - this.sut.IsAssigned.ShouldBeTrue(); - this.sut.IsDscAttached.ShouldBeTrue(); - this.sut.Mmsi.ShouldBe(12345u); - this.sut.Position.ShouldBe(new Position(1.0, 2.0)); - this.sut.PositionAccuracy.ShouldBeTrue(); - this.sut.RadioStatusType.ShouldBe(ClassBRadioStatusType.Itdma); - this.sut.RaimFlag.ShouldBeTrue(); - this.sut.RegionalReserved139.ShouldBe(1); - this.sut.RegionalReserved38.ShouldBe(2); - this.sut.RepeatIndicator.ShouldBe(3u); - this.sut.SpeedOverGround.ShouldBe(12.34f); - this.sut.TimeStampSecond.ShouldBe(56u); - this.sut.TrueHeadingDegrees.ShouldBe(78u); + var sut = (AisMessageType18?)this.Message; + sut.ShouldNotBeNull(); + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + sut.CanAcceptMessage22ChannelAssignment.ShouldBe(this.data.CanAcceptMessage22ChannelAssignment); + sut.CanSwitchBands.ShouldBe(this.data.CanSwitchBands); + sut.CourseOverGround.ShouldBe(this.data.CourseOverGroundDegrees); + sut.CsUnit.ShouldBe(Enum.Parse(this.data.CsUnit ?? throw new InvalidOperationException())); + sut.HasDisplay.ShouldBe(this.data.HasDisplay); + sut.IsAssigned.ShouldBe(this.data.IsAssigned); + sut.IsDscAttached.ShouldBe(this.data.IsDscAttached); + sut.Mmsi.ShouldBe(this.data.Mmsi); + sut.Position.ShouldBe(new Position(this.data.Position?.Latitude ?? 0, this.data.Position?.Longitude ?? 0)); + sut.PositionAccuracy.ShouldBe(this.data.PositionAccuracy); + sut.RadioStatusType.ShouldBe(Enum.Parse(this.data.RadioStatusType ?? throw new InvalidOperationException())); + sut.RaimFlag.ShouldBe(this.data.RaimFlag); + sut.RegionalReserved139.ShouldBe(this.data.RegionalReserved139); + sut.RegionalReserved38.ShouldBe(this.data.RegionalReserved38); + sut.RepeatIndicator.ShouldBe(this.data.RepeatIndicator); + sut.SpeedOverGround.ShouldBe(this.data.SpeedOverGround); + sut.TimeStampSecond.ShouldBe(this.data.TimeStampSecond); + sut.TrueHeadingDegrees.ShouldBe(this.data.TrueHeadingDegrees); } private class AisMessageType18Data @@ -103,7 +109,7 @@ private class AisMessageType18Data private class PositionData { - public int Latitude { get; set; } - public int Longitude { get; set; } + public double Latitude { get; set; } + public double Longitude { get; set; } } } \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType19StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType19StepDefinitions.cs index 2931898..ab5298a 100644 --- a/Solutions/Ais.Net.Models.Specs/AisMessageType19StepDefinitions.cs +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType19StepDefinitions.cs @@ -1,15 +1,16 @@ namespace Ais.Net.Models.Specs; -using Abstractions; using System; +using Abstractions; + using Reqnroll; + using Shouldly; [Binding] -public class AisMessageType19StepDefinitions +public class AisMessageType19StepDefinitions : StepDefinitionBase { - private AisMessageType19? sut; private AisMessageType19Data? data; [Given("a new AisMessageType19 record with the following properties:")] @@ -17,8 +18,8 @@ public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable ta { PositionData position = new() { - Latitude = Convert.ToInt32(table.Rows[0]["Position_Latitude"]), - Longitude = Convert.ToInt32(table.Rows[0]["Position_Longitude"]) + Latitude = Convert.ToDouble(table.Rows[0]["Position_Latitude"]), + Longitude = Convert.ToDouble(table.Rows[0]["Position_Longitude"]) }; this.data = table.CreateInstance(); @@ -33,7 +34,7 @@ public void WhenTheAisMessageTypeIsCreated() throw new InvalidOperationException("Data is not set"); } - this.sut = new AisMessageType19( + this.Message = new AisMessageType19( CourseOverGround: this.data.CourseOverGround, DimensionToBow: this.data.DimensionToBow, DimensionToPort: this.data.DimensionToPort, @@ -61,28 +62,33 @@ public void WhenTheAisMessageTypeIsCreated() [Then("the AisMessageType19 properties should be set correctly")] public void ThenThePropertiesShouldBeSetCorrectly() { - this.sut.ShouldNotBeNull(); - this.sut.CourseOverGround.ShouldBe(123.45f); - this.sut.DimensionToBow.ShouldBe(1u); - this.sut.DimensionToPort.ShouldBe(2u); - this.sut.DimensionToStarboard.ShouldBe(3u); - this.sut.DimensionToStern.ShouldBe(4u); - this.sut.IsAssigned.ShouldBeTrue(); - this.sut.IsDteNotReady.ShouldBeTrue(); - this.sut.Mmsi.ShouldBe(12345u); - this.sut.Position.ShouldBe(new Position(1.0, 2.0)); - this.sut.PositionAccuracy.ShouldBeTrue(); - this.sut.PositionFixType.ShouldBe(EpfdFixType.Gps); - this.sut.RaimFlag.ShouldBeTrue(); - this.sut.RegionalReserved139.ShouldBe(1); - this.sut.RegionalReserved38.ShouldBe(2); - this.sut.RepeatIndicator.ShouldBe(3u); - this.sut.ShipName.ShouldBe("SHIP"); - ((int)this.sut.ShipType).ShouldBe(60); - this.sut.Spare308.ShouldBe(1u); - this.sut.SpeedOverGround.ShouldBe(12.34f); - this.sut.TimeStampSecond.ShouldBe(56u); - this.sut.TrueHeadingDegrees.ShouldBe(78u); + var sut = (AisMessageType19?)this.Message; + sut.ShouldNotBeNull(); + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + sut.CourseOverGround.ShouldBe(this.data.CourseOverGround); + sut.DimensionToBow.ShouldBe(this.data.DimensionToBow); + sut.DimensionToPort.ShouldBe(this.data.DimensionToPort); + sut.DimensionToStarboard.ShouldBe(this.data.DimensionToStarboard); + sut.DimensionToStern.ShouldBe(this.data.DimensionToStern); + sut.IsAssigned.ShouldBe(this.data.IsAssigned); + sut.IsDteNotReady.ShouldBe(this.data.IsDteNotReady); + sut.Mmsi.ShouldBe(this.data.Mmsi); + sut.Position.ShouldBe(new Position(this.data.Position?.Latitude ?? 0, this.data.Position?.Longitude ?? 0)); + sut.PositionAccuracy.ShouldBe(this.data.PositionAccuracy); + sut.PositionFixType.ShouldBe(Enum.Parse(this.data.PositionFixType ?? throw new InvalidOperationException())); + sut.RaimFlag.ShouldBe(this.data.RaimFlag); + sut.RegionalReserved139.ShouldBe(this.data.RegionalReserved139); + sut.RegionalReserved38.ShouldBe(this.data.RegionalReserved38); + sut.RepeatIndicator.ShouldBe(this.data.RepeatIndicator); + sut.ShipName.ShouldBe(this.data.ShipName); + ((int)sut.ShipType).ShouldBe(this.data.ShipType); + sut.Spare308.ShouldBe(this.data.Spare308); + sut.SpeedOverGround.ShouldBe(this.data.SpeedOverGround); + sut.TimeStampSecond.ShouldBe(this.data.TimeStampSecond); + sut.TrueHeadingDegrees.ShouldBe(this.data.TrueHeadingDegrees); } private class AisMessageType19Data @@ -112,7 +118,7 @@ private class AisMessageType19Data private class PositionData { - public int Latitude { get; set; } - public int Longitude { get; set; } + public double Latitude { get; set; } + public double Longitude { get; set; } } } \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType1Through3StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType1Through3StepDefinitions.cs index 0a8f2aa..fb2e9b4 100644 --- a/Solutions/Ais.Net.Models.Specs/AisMessageType1Through3StepDefinitions.cs +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType1Through3StepDefinitions.cs @@ -1,15 +1,16 @@ namespace Ais.Net.Models.Specs; -using Abstractions; using System; +using Abstractions; + using Reqnroll; + using Shouldly; [Binding] -public class AisMessageType1Through3StepDefinitions +public class AisMessageType1Through3StepDefinitions : StepDefinitionBase { - private AisMessageType1Through3? sut; private AisMessageType1Through3Data? data; [Given("a new AisMessageType1Through3 record with the following properties:")] @@ -17,8 +18,8 @@ public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable ta { PositionData position = new() { - Latitude = Convert.ToInt32(table.Rows[0]["Position_Latitude"]), - Longitude = Convert.ToInt32(table.Rows[0]["Position_Longitude"]) + Latitude = Convert.ToDouble(table.Rows[0]["Position_Latitude"]), + Longitude = Convert.ToDouble(table.Rows[0]["Position_Longitude"]) }; this.data = table.CreateInstance(); @@ -33,7 +34,7 @@ public void WhenTheAisMessageTypeIsCreated() throw new InvalidOperationException("Data is not set"); } - this.sut = new AisMessageType1Through3( + this.Message = new AisMessageType1Through3( CourseOverGround: this.data.CourseOverGround, ManoeuvreIndicator: Enum.Parse(this.data.ManoeuvreIndicator ?? throw new InvalidOperationException()), MessageType: this.data.MessageType, @@ -57,24 +58,29 @@ public void WhenTheAisMessageTypeIsCreated() [Then("the AisMessageType1Through3 properties should be set correctly")] public void ThenThePropertiesShouldBeSetCorrectly() { - this.sut.ShouldNotBeNull(); - this.sut.CourseOverGround.ShouldBe(123.45f); - this.sut.ManoeuvreIndicator.ShouldBe(ManoeuvreIndicator.NotAvailable); - this.sut.MessageType.ShouldBe(1); - this.sut.Mmsi.ShouldBe(12345u); - this.sut.NavigationStatus.ShouldBe(NavigationStatus.UnderwayUsingEngine); - this.sut.Position.ShouldBe(new Position(1.0, 2.0)); - this.sut.PositionAccuracy.ShouldBeTrue(); - this.sut.RadioSlotTimeout.ShouldBe(1u); - this.sut.RadioSubMessage.ShouldBe(2u); - this.sut.RadioSyncState.ShouldBe(RadioSyncState.UtcDirect); - this.sut.RateOfTurn.ShouldBe(1); - this.sut.RaimFlag.ShouldBeTrue(); - this.sut.RepeatIndicator.ShouldBe(3u); - this.sut.SpareBits145.ShouldBe(4u); - this.sut.SpeedOverGround.ShouldBe(12.34f); - this.sut.TimeStampSecond.ShouldBe(56u); - this.sut.TrueHeadingDegrees.ShouldBe(78u); + var sut = (AisMessageType1Through3?)this.Message; + sut.ShouldNotBeNull(); + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + sut.CourseOverGround.ShouldBe(this.data.CourseOverGround); + sut.ManoeuvreIndicator.ShouldBe(Enum.Parse(this.data.ManoeuvreIndicator ?? throw new InvalidOperationException())); + sut.MessageType.ShouldBe(this.data.MessageType); + sut.Mmsi.ShouldBe(this.data.Mmsi); + sut.NavigationStatus.ShouldBe(Enum.Parse(this.data.NavigationStatus ?? throw new InvalidOperationException())); + sut.Position.ShouldBe(new Position(this.data.Position?.Latitude ?? 0, this.data.Position?.Longitude ?? 0)); + sut.PositionAccuracy.ShouldBe(this.data.PositionAccuracy); + sut.RadioSlotTimeout.ShouldBe(this.data.RadioSlotTimeout); + sut.RadioSubMessage.ShouldBe(this.data.RadioSubMessage); + sut.RadioSyncState.ShouldBe(Enum.Parse(this.data.RadioSyncState ?? throw new InvalidOperationException())); + sut.RateOfTurn.ShouldBe(this.data.RateOfTurn); + sut.RaimFlag.ShouldBe(this.data.RaimFlag); + sut.RepeatIndicator.ShouldBe(this.data.RepeatIndicator); + sut.SpareBits145.ShouldBe(this.data.SpareBits145); + sut.SpeedOverGround.ShouldBe(this.data.SpeedOverGround); + sut.TimeStampSecond.ShouldBe(this.data.TimeStampSecond); + sut.TrueHeadingDegrees.ShouldBe(this.data.TrueHeadingDegrees); } private class AisMessageType1Through3Data @@ -100,7 +106,7 @@ private class AisMessageType1Through3Data private class PositionData { - public int Latitude { get; set; } - public int Longitude { get; set; } + public double Latitude { get; set; } + public double Longitude { get; set; } } } \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType24Part0StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType24Part0StepDefinitions.cs index a87c466..dc72039 100644 --- a/Solutions/Ais.Net.Models.Specs/AisMessageType24Part0StepDefinitions.cs +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType24Part0StepDefinitions.cs @@ -1,13 +1,14 @@ namespace Ais.Net.Models.Specs; using System; + using Reqnroll; + using Shouldly; [Binding] -public class AisMessageType24Part0StepDefinitions +public class AisMessageType24Part0StepDefinitions : StepDefinitionBase { - private AisMessageType24Part0? sut; private AisMessageType24Part0Data? data; [Given("a new AisMessageType24Part0 record with the following properties:")] @@ -24,7 +25,7 @@ public void WhenTheAisMessageTypeIsCreated() throw new InvalidOperationException("Data is not set"); } - this.sut = new AisMessageType24Part0( + this.Message = new AisMessageType24Part0( Mmsi: this.data.Mmsi, PartNumber: this.data.PartNumber, RepeatIndicator: this.data.RepeatIndicator, @@ -35,11 +36,18 @@ public void WhenTheAisMessageTypeIsCreated() [Then("the AisMessageType24Part0 properties should be set correctly")] public void ThenThePropertiesShouldBeSetCorrectly() { - this.sut.ShouldNotBeNull(); - this.sut.Mmsi.ShouldBe(12345u); - this.sut.PartNumber.ShouldBe(0u); - this.sut.RepeatIndicator.ShouldBe(3u); - this.sut.Spare160.ShouldBe(1u); + AisMessageType24Part0? sut = this.Message as AisMessageType24Part0; + + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + sut.ShouldNotBeNull(); + sut.Mmsi.ShouldBe(this.data.Mmsi); + sut.PartNumber.ShouldBe(this.data.PartNumber); + sut.RepeatIndicator.ShouldBe(this.data.RepeatIndicator); + sut.Spare160.ShouldBe(this.data.Spare160); } private class AisMessageType24Part0Data diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType24Part1StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType24Part1StepDefinitions.cs index 5671333..96a2443 100644 --- a/Solutions/Ais.Net.Models.Specs/AisMessageType24Part1StepDefinitions.cs +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType24Part1StepDefinitions.cs @@ -1,14 +1,14 @@ namespace Ais.Net.Models.Specs; -using Abstractions; using System; + using Reqnroll; + using Shouldly; [Binding] -public class AisMessageType24Part1StepDefinitions +public class AisMessageType24Part1StepDefinitions : StepDefinitionBase { - private AisMessageType24Part1? sut; private AisMessageType24Part1Data? data; [Given("a new AisMessageType24Part1 record with the following properties:")] @@ -25,7 +25,7 @@ public void WhenTheAisMessageTypeIsCreated() throw new InvalidOperationException("Data is not set"); } - this.sut = new AisMessageType24Part1( + this.Message = new AisMessageType24Part1( CallSign: this.data.CallSign ?? throw new InvalidOperationException(), DimensionToBow: this.data.DimensionToBow, DimensionToPort: this.data.DimensionToPort, @@ -47,22 +47,29 @@ public void WhenTheAisMessageTypeIsCreated() [Then("the AisMessageType24Part1 properties should be set correctly")] public void ThenThePropertiesShouldBeSetCorrectly() { - this.sut.ShouldNotBeNull(); - this.sut.CallSign.ShouldBe("CALL"); - this.sut.DimensionToBow.ShouldBe(1u); - this.sut.DimensionToPort.ShouldBe(2u); - this.sut.DimensionToStarboard.ShouldBe(3u); - this.sut.DimensionToStern.ShouldBe(4u); - this.sut.Mmsi.ShouldBe(12345u); - this.sut.MothershipMmsi.ShouldBe(54321u); - this.sut.PartNumber.ShouldBe(1u); - this.sut.RepeatIndicator.ShouldBe(3u); - this.sut.SerialNumber.ShouldBe(123u); - this.sut.Spare162.ShouldBe(1u); - ((int)this.sut.ShipType).ShouldBe(60); - this.sut.UnitModelCode.ShouldBe(1u); - this.sut.VendorIdRev3.ShouldBe("VEN"); - this.sut.VendorIdRev4.ShouldBe("DOR"); + AisMessageType24Part1? sut = this.Message as AisMessageType24Part1; + + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + sut.ShouldNotBeNull(); + sut.CallSign.ShouldBe(this.data.CallSign); + sut.DimensionToBow.ShouldBe(this.data.DimensionToBow); + sut.DimensionToPort.ShouldBe(this.data.DimensionToPort); + sut.DimensionToStarboard.ShouldBe(this.data.DimensionToStarboard); + sut.DimensionToStern.ShouldBe(this.data.DimensionToStern); + sut.Mmsi.ShouldBe(this.data.Mmsi); + sut.MothershipMmsi.ShouldBe(this.data.MothershipMmsi); + sut.PartNumber.ShouldBe(this.data.PartNumber); + sut.RepeatIndicator.ShouldBe(this.data.RepeatIndicator); + sut.SerialNumber.ShouldBe(this.data.SerialNumber); + sut.Spare162.ShouldBe(this.data.Spare162); + ((int)sut.ShipType).ShouldBe(this.data.ShipType); + sut.UnitModelCode.ShouldBe(this.data.UnitModelCode); + sut.VendorIdRev3.ShouldBe(this.data.VendorIdRev3); + sut.VendorIdRev4.ShouldBe(this.data.VendorIdRev4); } private class AisMessageType24Part1Data diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType27StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType27StepDefinitions.cs index 77e202e..0f640c6 100644 --- a/Solutions/Ais.Net.Models.Specs/AisMessageType27StepDefinitions.cs +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType27StepDefinitions.cs @@ -1,15 +1,16 @@ namespace Ais.Net.Models.Specs; -using Abstractions; using System; +using Abstractions; + using Reqnroll; + using Shouldly; [Binding] -public class AisMessageType27StepDefinitions +public class AisMessageType27StepDefinitions : StepDefinitionBase { - private AisMessageType27? sut; private AisMessageType27Data? data; [Given("a new AisMessageType27 record with the following properties:")] @@ -17,8 +18,8 @@ public void GivenANewAisMessageTypeRecordWithTheFollowingProperties(DataTable ta { PositionData position = new() { - Latitude = Convert.ToInt32(table.Rows[0]["Position_Latitude"]), - Longitude = Convert.ToInt32(table.Rows[0]["Position_Longitude"]) + Latitude = Convert.ToDouble(table.Rows[0]["Position_Latitude"]), + Longitude = Convert.ToDouble(table.Rows[0]["Position_Longitude"]) }; this.data = table.CreateInstance(); @@ -33,7 +34,7 @@ public void WhenTheAisMessageTypeIsCreated() throw new InvalidOperationException("Data is not set"); } - this.sut = new AisMessageType27( + this.Message = new AisMessageType27( CourseOverGround: this.data.CourseOverGround, GnssPositionStatus: this.data.GnssPositionStatus, Mmsi: this.data.Mmsi, @@ -49,16 +50,23 @@ public void WhenTheAisMessageTypeIsCreated() [Then("the AisMessageType27 properties should be set correctly")] public void ThenThePropertiesShouldBeSetCorrectly() { - this.sut.ShouldNotBeNull(); - this.sut.CourseOverGround.ShouldBe(123.45f); - this.sut.GnssPositionStatus.ShouldBeTrue(); - this.sut.Mmsi.ShouldBe(12345u); - this.sut.NavigationStatus.ShouldBe(NavigationStatus.UnderwayUsingEngine); - this.sut.Position.ShouldBe(new Position(1.0, 2.0)); - this.sut.PositionAccuracy.ShouldBeTrue(); - this.sut.RaimFlag.ShouldBeTrue(); - this.sut.RepeatIndicator.ShouldBe(3u); - this.sut.SpeedOverGround.ShouldBe(12.34f); + AisMessageType27? sut = this.Message as AisMessageType27; + + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + sut.ShouldNotBeNull(); + sut.CourseOverGround.ShouldBe(this.data.CourseOverGround); + sut.GnssPositionStatus.ShouldBe(this.data.GnssPositionStatus); + sut.Mmsi.ShouldBe(this.data.Mmsi); + sut.NavigationStatus.ShouldBe(Enum.Parse(this.data.NavigationStatus ?? throw new InvalidOperationException())); + sut.Position.ShouldBe(new Position(this.data.Position?.Latitude ?? 0, this.data.Position?.Longitude ?? 0)); + sut.PositionAccuracy.ShouldBe(this.data.PositionAccuracy); + sut.RaimFlag.ShouldBe(this.data.RaimFlag); + sut.RepeatIndicator.ShouldBe(this.data.RepeatIndicator); + sut.SpeedOverGround.ShouldBe(this.data.SpeedOverGround); } private class AisMessageType27Data @@ -76,7 +84,7 @@ private class AisMessageType27Data private class PositionData { - public int Latitude { get; set; } - public int Longitude { get; set; } + public double Latitude { get; set; } + public double Longitude { get; set; } } } \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/AisMessageType5StepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/AisMessageType5StepDefinitions.cs index ffd48f5..12f7d7c 100644 --- a/Solutions/Ais.Net.Models.Specs/AisMessageType5StepDefinitions.cs +++ b/Solutions/Ais.Net.Models.Specs/AisMessageType5StepDefinitions.cs @@ -1,15 +1,14 @@ namespace Ais.Net.Models.Specs; -using Abstractions; using System; using Reqnroll; + using Shouldly; [Binding] -public class AisMessageType5StepDefinitions +public class AisMessageType5StepDefinitions : StepDefinitionBase { - private AisMessageType5? sut; private AisMessageType5Data? data; [Given("a new AisMessageType5 record with the following properties:")] @@ -26,7 +25,7 @@ public void WhenTheAisMessageTypeIsCreated() throw new InvalidOperationException("Data is not set"); } - this.sut = new AisMessageType5( + this.Message = new AisMessageType5( AisVersion: this.data.AisVersion, CallSign: this.data.CallSign ?? throw new InvalidOperationException(), Destination: this.data.Destination ?? throw new InvalidOperationException(), @@ -53,27 +52,34 @@ public void WhenTheAisMessageTypeIsCreated() [Then("the AisMessageType5 properties should be set correctly")] public void ThenThePropertiesShouldBeSetCorrectly() { - this.sut.ShouldNotBeNull(); - this.sut.AisVersion.ShouldBe(1u); - this.sut.CallSign.ShouldBe("CALL"); - this.sut.Destination.ShouldBe("DEST"); - this.sut.DimensionToBow.ShouldBe(1u); - this.sut.DimensionToPort.ShouldBe(2u); - this.sut.DimensionToStarboard.ShouldBe(3u); - this.sut.DimensionToStern.ShouldBe(4u); - this.sut.Draught10thMetres.ShouldBe(5u); - this.sut.EtaDay.ShouldBe(6u); - this.sut.EtaHour.ShouldBe(7u); - this.sut.EtaMinute.ShouldBe(8u); - this.sut.EtaMonth.ShouldBe(9u); - this.sut.IsDteNotReady.ShouldBeTrue(); - this.sut.ImoNumber.ShouldBe(123u); - this.sut.Mmsi.ShouldBe(12345u); - this.sut.PositionFixType.ShouldBe(EpfdFixType.Gps); - this.sut.RepeatIndicator.ShouldBe(3u); - ((int)this.sut.ShipType).ShouldBe(60); - this.sut.Spare423.ShouldBe(1u); - this.sut.VesselName.ShouldBe("VESSEL"); + AisMessageType5? sut = this.Message as AisMessageType5; + + if (this.data is null) + { + throw new InvalidOperationException("Data is not set"); + } + + sut.ShouldNotBeNull(); + sut.AisVersion.ShouldBe(this.data.AisVersion); + sut.CallSign.ShouldBe(this.data.CallSign); + sut.Destination.ShouldBe(this.data.Destination); + sut.DimensionToBow.ShouldBe(this.data.DimensionToBow); + sut.DimensionToPort.ShouldBe(this.data.DimensionToPort); + sut.DimensionToStarboard.ShouldBe(this.data.DimensionToStarboard); + sut.DimensionToStern.ShouldBe(this.data.DimensionToStern); + sut.Draught10thMetres.ShouldBe(this.data.Draught10thMetres); + sut.EtaDay.ShouldBe(this.data.EtaDay); + sut.EtaHour.ShouldBe(this.data.EtaHour); + sut.EtaMinute.ShouldBe(this.data.EtaMinute); + sut.EtaMonth.ShouldBe(this.data.EtaMonth); + sut.IsDteNotReady.ShouldBe(this.data.IsDteNotReady); + sut.ImoNumber.ShouldBe(this.data.ImoNumber); + sut.Mmsi.ShouldBe(this.data.Mmsi); + sut.PositionFixType.ShouldBe(Enum.Parse(this.data.PositionFixType ?? throw new InvalidOperationException())); + sut.RepeatIndicator.ShouldBe(this.data.RepeatIndicator); + ((int)sut.ShipType).ShouldBe(this.data.ShipType); + sut.Spare423.ShouldBe(this.data.Spare423); + sut.VesselName.ShouldBe(this.data.VesselName); } private class AisMessageType5Data diff --git a/Solutions/Ais.Net.Models.Specs/CommonStepDefinitions.cs b/Solutions/Ais.Net.Models.Specs/CommonStepDefinitions.cs new file mode 100644 index 0000000..81d1b04 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/CommonStepDefinitions.cs @@ -0,0 +1,15 @@ +using Reqnroll; + +namespace Ais.Net.Models.Specs +{ + [Binding] + public class CommonStepDefinitions + { + [Given(@"I have an AIS message")] + public void GivenIHaveAnAisMessage() + { + // This is a common background step that does nothing + // The actual message creation happens in the specific "Given" steps + } + } +} \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature index f01dd46..3bbf1d5 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature @@ -1,8 +1,15 @@ -Feature: AisMessageType18 +Feature: Class B "CS" Position Report -Scenario: Create AisMessageType18 record +Background: + Given I have an AIS message + +Scenario Outline: Decoding a Class B "CS" position report Given a new AisMessageType18 record with the following properties: | CanAcceptMessage22ChannelAssignment | CanSwitchBands | CourseOverGroundDegrees | CsUnit | HasDisplay | IsAssigned | IsDscAttached | Mmsi | Position_Latitude | Position_Longitude | PositionAccuracy | RadioStatusType | RaimFlag | RegionalReserved139 | RegionalReserved38 | RepeatIndicator | SpeedOverGround | TimeStampSecond | TrueHeadingDegrees | - | true | true | 123.45 | Cstdma | true | true | true | 12345 | 1 | 2 | true | Itdma | true | 1 | 2 | 3 | 12.34 | 56 | 78 | + | | | | | | | | | | | | | | | | | | | | When the AisMessageType is created - Then the properties should be set correctly \ No newline at end of file + Then the properties should be set correctly + + Examples: + | can_accept_msg22 | can_switch_bands | course | cs_unit | has_display | is_assigned | is_dsc_attached | mmsi | lat | long | pos_accuracy | radio_status | raim | reg_res_139 | reg_res_38 | repeat | speed | timestamp | true_heading | + | true | true | 123.45 | Cstdma | true | true | true | 12345 | 1.0 | 2.0 | true | Itdma | true | 1 | 2 | 3 | 12.34 | 56 | 78 | \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature.cs index 74a8519..e3988d0 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature.cs +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType18.feature.cs @@ -18,16 +18,16 @@ namespace Ais.Net.Models.Specs.Features [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("AisMessageType18")] + [NUnit.Framework.DescriptionAttribute("Class B \"CS\" Position Report")] [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] - public partial class AisMessageType18Feature + public partial class ClassBCSPositionReportFeature { private global::Reqnroll.ITestRunner testRunner; private static string[] featureTags = ((string[])(null)); - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType18", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "Class B \"CS\" Position Report", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); #line 1 "AisMessageType18.feature" #line hidden @@ -102,14 +102,63 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) await testRunner.CollectScenarioErrorsAsync(); } + public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync() + { +#line 3 +#line hidden +#line 4 + await testRunner.GivenAsync("I have an AIS message", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); +#line hidden + } + [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create AisMessageType18 record")] - public async global::System.Threading.Tasks.Task CreateAisMessageType18Record() + [NUnit.Framework.DescriptionAttribute("Decoding a Class B \"CS\" position report")] + [NUnit.Framework.TestCaseAttribute("true", "true", "123.45", "Cstdma", "true", "true", "true", "12345", "1.0", "2.0", "true", "Itdma", "true", "1", "2", "3", "12.34", "56", "78", null)] + public async global::System.Threading.Tasks.Task DecodingAClassBCSPositionReport( + string can_Accept_Msg22, + string can_Switch_Bands, + string course, + string cs_Unit, + string has_Display, + string is_Assigned, + string is_Dsc_Attached, + string mmsi, + string lat, + string @long, + string pos_Accuracy, + string radio_Status, + string raim, + string reg_Res_139, + string reg_Res_38, + string repeat, + string speed, + string timestamp, + string true_Heading, + string[] exampleTags) { - string[] tagsOfScenario = ((string[])(null)); + string[] tagsOfScenario = exampleTags; global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); - global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType18 record", null, tagsOfScenario, argumentsOfScenario, featureTags); -#line 3 + argumentsOfScenario.Add("can_accept_msg22", can_Accept_Msg22); + argumentsOfScenario.Add("can_switch_bands", can_Switch_Bands); + argumentsOfScenario.Add("course", course); + argumentsOfScenario.Add("cs_unit", cs_Unit); + argumentsOfScenario.Add("has_display", has_Display); + argumentsOfScenario.Add("is_assigned", is_Assigned); + argumentsOfScenario.Add("is_dsc_attached", is_Dsc_Attached); + argumentsOfScenario.Add("mmsi", mmsi); + argumentsOfScenario.Add("lat", lat); + argumentsOfScenario.Add("long", @long); + argumentsOfScenario.Add("pos_accuracy", pos_Accuracy); + argumentsOfScenario.Add("radio_status", radio_Status); + argumentsOfScenario.Add("raim", raim); + argumentsOfScenario.Add("reg_res_139", reg_Res_139); + argumentsOfScenario.Add("reg_res_38", reg_Res_38); + argumentsOfScenario.Add("repeat", repeat); + argumentsOfScenario.Add("speed", speed); + argumentsOfScenario.Add("timestamp", timestamp); + argumentsOfScenario.Add("true_heading", true_Heading); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Decoding a Class B \"CS\" position report", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 6 this.ScenarioInitialize(scenarioInfo); #line hidden if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) @@ -119,6 +168,9 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) else { await this.ScenarioStartAsync(); +#line 3 +await this.FeatureBackgroundAsync(); +#line hidden global::Reqnroll.Table table1 = new global::Reqnroll.Table(new string[] { "CanAcceptMessage22ChannelAssignment", "CanSwitchBands", @@ -140,32 +192,32 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) "TimeStampSecond", "TrueHeadingDegrees"}); table1.AddRow(new string[] { - "true", - "true", - "123.45", - "Cstdma", - "true", - "true", - "true", - "12345", - "1", - "2", - "true", - "Itdma", - "true", - "1", - "2", - "3", - "12.34", - "56", - "78"}); -#line 4 + string.Format("{0}", can_Accept_Msg22), + string.Format("{0}", can_Switch_Bands), + string.Format("{0}", course), + string.Format("{0}", cs_Unit), + string.Format("{0}", has_Display), + string.Format("{0}", is_Assigned), + string.Format("{0}", is_Dsc_Attached), + string.Format("{0}", mmsi), + string.Format("{0}", lat), + string.Format("{0}", @long), + string.Format("{0}", pos_Accuracy), + string.Format("{0}", radio_Status), + string.Format("{0}", raim), + string.Format("{0}", reg_Res_139), + string.Format("{0}", reg_Res_38), + string.Format("{0}", repeat), + string.Format("{0}", speed), + string.Format("{0}", timestamp), + string.Format("{0}", true_Heading)}); +#line 7 await testRunner.GivenAsync("a new AisMessageType18 record with the following properties:", ((string)(null)), table1, "Given "); #line hidden -#line 7 +#line 10 await testRunner.WhenAsync("the AisMessageType is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); #line hidden -#line 8 +#line 11 await testRunner.ThenAsync("the properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden } diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature index 3cde8ac..4cd3dea 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature @@ -1,8 +1,15 @@ -Feature: AisMessageType19 +Feature: Class B "SO" Position Report -Scenario: Create AisMessageType19 record +Background: + Given I have an AIS message + +Scenario Outline: Decoding a Class B "SO" position report Given a new AisMessageType19 record with the following properties: | CourseOverGround | DimensionToBow | DimensionToPort | DimensionToStarboard | DimensionToStern | IsAssigned | IsDteNotReady | Mmsi | Position_Latitude | Position_Longitude | PositionAccuracy | PositionFixType | RaimFlag | RegionalReserved139 | RegionalReserved38 | RepeatIndicator | ShipName | ShipType | Spare308 | SpeedOverGround | TimeStampSecond | TrueHeadingDegrees | - | 123.45 | 1 | 2 | 3 | 4 | true | true | 12345 | 1 | 2 | true | Gps | true | 1 | 2 | 3 | SHIP | 60 | 1 | 12.34 | 56 | 78 | + | | | | | | | | | | | | | | | | | | | | | | | When the AisMessageType19 is created - Then the AisMessageType19 properties should be set correctly \ No newline at end of file + Then the AisMessageType19 properties should be set correctly + + Examples: + | course | dim_bow | dim_port | dim_starboard | dim_stern | is_assigned | dte_not_ready | mmsi | lat | long | pos_accuracy | pos_fix | raim | reg_res_139 | reg_res_38 | repeat | ship_name | ship_type | spare | speed | timestamp | true_heading | + | 123.45 | 1 | 2 | 3 | 4 | true | true | 12345 | 1.0 | 2.0 | true | Gps | true | 1 | 2 | 3 | SHIP | 60 | 1 | 12.34 | 56 | 78 | \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature.cs index e5600cd..1ec9637 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature.cs +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType19.feature.cs @@ -18,16 +18,16 @@ namespace Ais.Net.Models.Specs.Features [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("AisMessageType19")] + [NUnit.Framework.DescriptionAttribute("Class B \"SO\" Position Report")] [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] - public partial class AisMessageType19Feature + public partial class ClassBSOPositionReportFeature { private global::Reqnroll.ITestRunner testRunner; private static string[] featureTags = ((string[])(null)); - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType19", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "Class B \"SO\" Position Report", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); #line 1 "AisMessageType19.feature" #line hidden @@ -102,14 +102,69 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) await testRunner.CollectScenarioErrorsAsync(); } + public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync() + { +#line 3 +#line hidden +#line 4 + await testRunner.GivenAsync("I have an AIS message", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); +#line hidden + } + [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create AisMessageType19 record")] - public async global::System.Threading.Tasks.Task CreateAisMessageType19Record() + [NUnit.Framework.DescriptionAttribute("Decoding a Class B \"SO\" position report")] + [NUnit.Framework.TestCaseAttribute("123.45", "1", "2", "3", "4", "true", "true", "12345", "1.0", "2.0", "true", "Gps", "true", "1", "2", "3", "SHIP", "60", "1", "12.34", "56", "78", null)] + public async global::System.Threading.Tasks.Task DecodingAClassBSOPositionReport( + string course, + string dim_Bow, + string dim_Port, + string dim_Starboard, + string dim_Stern, + string is_Assigned, + string dte_Not_Ready, + string mmsi, + string lat, + string @long, + string pos_Accuracy, + string pos_Fix, + string raim, + string reg_Res_139, + string reg_Res_38, + string repeat, + string ship_Name, + string ship_Type, + string spare, + string speed, + string timestamp, + string true_Heading, + string[] exampleTags) { - string[] tagsOfScenario = ((string[])(null)); + string[] tagsOfScenario = exampleTags; global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); - global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType19 record", null, tagsOfScenario, argumentsOfScenario, featureTags); -#line 3 + argumentsOfScenario.Add("course", course); + argumentsOfScenario.Add("dim_bow", dim_Bow); + argumentsOfScenario.Add("dim_port", dim_Port); + argumentsOfScenario.Add("dim_starboard", dim_Starboard); + argumentsOfScenario.Add("dim_stern", dim_Stern); + argumentsOfScenario.Add("is_assigned", is_Assigned); + argumentsOfScenario.Add("dte_not_ready", dte_Not_Ready); + argumentsOfScenario.Add("mmsi", mmsi); + argumentsOfScenario.Add("lat", lat); + argumentsOfScenario.Add("long", @long); + argumentsOfScenario.Add("pos_accuracy", pos_Accuracy); + argumentsOfScenario.Add("pos_fix", pos_Fix); + argumentsOfScenario.Add("raim", raim); + argumentsOfScenario.Add("reg_res_139", reg_Res_139); + argumentsOfScenario.Add("reg_res_38", reg_Res_38); + argumentsOfScenario.Add("repeat", repeat); + argumentsOfScenario.Add("ship_name", ship_Name); + argumentsOfScenario.Add("ship_type", ship_Type); + argumentsOfScenario.Add("spare", spare); + argumentsOfScenario.Add("speed", speed); + argumentsOfScenario.Add("timestamp", timestamp); + argumentsOfScenario.Add("true_heading", true_Heading); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Decoding a Class B \"SO\" position report", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 6 this.ScenarioInitialize(scenarioInfo); #line hidden if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) @@ -119,6 +174,9 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) else { await this.ScenarioStartAsync(); +#line 3 +await this.FeatureBackgroundAsync(); +#line hidden global::Reqnroll.Table table2 = new global::Reqnroll.Table(new string[] { "CourseOverGround", "DimensionToBow", @@ -143,35 +201,35 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) "TimeStampSecond", "TrueHeadingDegrees"}); table2.AddRow(new string[] { - "123.45", - "1", - "2", - "3", - "4", - "true", - "true", - "12345", - "1", - "2", - "true", - "Gps", - "true", - "1", - "2", - "3", - "SHIP", - "60", - "1", - "12.34", - "56", - "78"}); -#line 4 + string.Format("{0}", course), + string.Format("{0}", dim_Bow), + string.Format("{0}", dim_Port), + string.Format("{0}", dim_Starboard), + string.Format("{0}", dim_Stern), + string.Format("{0}", is_Assigned), + string.Format("{0}", dte_Not_Ready), + string.Format("{0}", mmsi), + string.Format("{0}", lat), + string.Format("{0}", @long), + string.Format("{0}", pos_Accuracy), + string.Format("{0}", pos_Fix), + string.Format("{0}", raim), + string.Format("{0}", reg_Res_139), + string.Format("{0}", reg_Res_38), + string.Format("{0}", repeat), + string.Format("{0}", ship_Name), + string.Format("{0}", ship_Type), + string.Format("{0}", spare), + string.Format("{0}", speed), + string.Format("{0}", timestamp), + string.Format("{0}", true_Heading)}); +#line 7 await testRunner.GivenAsync("a new AisMessageType19 record with the following properties:", ((string)(null)), table2, "Given "); #line hidden -#line 7 +#line 10 await testRunner.WhenAsync("the AisMessageType19 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); #line hidden -#line 8 +#line 11 await testRunner.ThenAsync("the AisMessageType19 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden } diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature index 4d33927..cc49f35 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature @@ -1,8 +1,16 @@ -Feature: AisMessageType1Through3 +Feature: Class A Vessel Position Report -Scenario: Create AisMessageType1Through3 record +Background: + Given I have an AIS message + +Scenario Outline: Decoding a Class A vessel position report Given a new AisMessageType1Through3 record with the following properties: - | CourseOverGround | ManoeuvreIndicator | MessageType | Mmsi | NavigationStatus | Position_Latitude | Position_Longitude | PositionAccuracy | RadioSlotTimeout | RadioSubMessage | RadioSyncState | RateOfTurn | RaimFlag | RepeatIndicator | SpareBits145 | SpeedOverGround | TimeStampSecond | TrueHeadingDegrees | - | 123.45 | NotAvailable | 1 | 12345 | UnderwayUsingEngine | 1 | 2 | true | 1 | 2 | UtcDirect | 1 | true | 3 | 4 | 12.34 | 56 | 78 | + | CourseOverGround | ManoeuvreIndicator | MessageType | Mmsi | NavigationStatus | Position_Latitude | Position_Longitude | PositionAccuracy | RadioSlotTimeout | RadioSubMessage | RadioSyncState | RateOfTurn | RaimFlag | RepeatIndicator | SpareBits145 | SpeedOverGround | TimeStampSecond | TrueHeadingDegrees | + | | | 1 | | | | | | 1 | 2 | UtcDirect | 1 | true | 3 | 4 | | 56 | 78 | When the AisMessageType1Through3 is created - Then the AisMessageType1Through3 properties should be set correctly \ No newline at end of file + Then the AisMessageType1Through3 properties should be set correctly + + Examples: + | course | manoeuvre | mmsi | nav_status | lat | long | pos_accuracy | speed | + | 123.45 | NotAvailable | 12345 | UnderwayUsingEngine | 1.0 | 2.0 | true | 12.34 | + | 234.56 | NotAvailable | 54321 | AtAnchor | 3.0 | 4.0 | true | 0.0 | \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature.cs index bc1090f..5043597 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature.cs +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType1Through3.feature.cs @@ -18,16 +18,16 @@ namespace Ais.Net.Models.Specs.Features [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("AisMessageType1Through3")] + [NUnit.Framework.DescriptionAttribute("Class A Vessel Position Report")] [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] - public partial class AisMessageType1Through3Feature + public partial class ClassAVesselPositionReportFeature { private global::Reqnroll.ITestRunner testRunner; private static string[] featureTags = ((string[])(null)); - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType1Through3", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "Class A Vessel Position Report", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); #line 1 "AisMessageType1Through3.feature" #line hidden @@ -102,14 +102,33 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) await testRunner.CollectScenarioErrorsAsync(); } + public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync() + { +#line 3 +#line hidden +#line 4 + await testRunner.GivenAsync("I have an AIS message", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); +#line hidden + } + [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create AisMessageType1Through3 record")] - public async global::System.Threading.Tasks.Task CreateAisMessageType1Through3Record() + [NUnit.Framework.DescriptionAttribute("Decoding a Class A vessel position report")] + [NUnit.Framework.TestCaseAttribute("123.45", "NotAvailable", "12345", "UnderwayUsingEngine", "1.0", "2.0", "true", "12.34", null)] + [NUnit.Framework.TestCaseAttribute("234.56", "NotAvailable", "54321", "AtAnchor", "3.0", "4.0", "true", "0.0", null)] + public async global::System.Threading.Tasks.Task DecodingAClassAVesselPositionReport(string course, string manoeuvre, string mmsi, string nav_Status, string lat, string @long, string pos_Accuracy, string speed, string[] exampleTags) { - string[] tagsOfScenario = ((string[])(null)); + string[] tagsOfScenario = exampleTags; global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); - global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType1Through3 record", null, tagsOfScenario, argumentsOfScenario, featureTags); -#line 3 + argumentsOfScenario.Add("course", course); + argumentsOfScenario.Add("manoeuvre", manoeuvre); + argumentsOfScenario.Add("mmsi", mmsi); + argumentsOfScenario.Add("nav_status", nav_Status); + argumentsOfScenario.Add("lat", lat); + argumentsOfScenario.Add("long", @long); + argumentsOfScenario.Add("pos_accuracy", pos_Accuracy); + argumentsOfScenario.Add("speed", speed); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Decoding a Class A vessel position report", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 6 this.ScenarioInitialize(scenarioInfo); #line hidden if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) @@ -119,6 +138,9 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) else { await this.ScenarioStartAsync(); +#line 3 +await this.FeatureBackgroundAsync(); +#line hidden global::Reqnroll.Table table3 = new global::Reqnroll.Table(new string[] { "CourseOverGround", "ManoeuvreIndicator", @@ -139,14 +161,14 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) "TimeStampSecond", "TrueHeadingDegrees"}); table3.AddRow(new string[] { - "123.45", - "NotAvailable", + string.Format("{0}", course), + string.Format("{0}", manoeuvre), "1", - "12345", - "UnderwayUsingEngine", - "1", - "2", - "true", + string.Format("{0}", mmsi), + string.Format("{0}", nav_Status), + string.Format("{0}", lat), + string.Format("{0}", @long), + string.Format("{0}", pos_Accuracy), "1", "2", "UtcDirect", @@ -154,16 +176,16 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) "true", "3", "4", - "12.34", + string.Format("{0}", speed), "56", "78"}); -#line 4 +#line 7 await testRunner.GivenAsync("a new AisMessageType1Through3 record with the following properties:", ((string)(null)), table3, "Given "); #line hidden -#line 7 +#line 10 await testRunner.WhenAsync("the AisMessageType1Through3 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); #line hidden -#line 8 +#line 11 await testRunner.ThenAsync("the AisMessageType1Through3 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden } diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature index e4acf4c..3b65ae4 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature @@ -1,8 +1,15 @@ -Feature: AisMessageType24Part0 +Feature: Static Data Report Part A -Scenario: Create AisMessageType24Part0 record +Background: + Given I have an AIS message + +Scenario Outline: Decoding a Static Data Report Part A Given a new AisMessageType24Part0 record with the following properties: | Mmsi | PartNumber | RepeatIndicator | Spare160 | - | 12345 | 0 | 3 | 1 | + | | | | | When the AisMessageType24Part0 is created - Then the AisMessageType24Part0 properties should be set correctly \ No newline at end of file + Then the AisMessageType24Part0 properties should be set correctly + + Examples: + | mmsi | part_no | repeat | spare | + | 12345 | 0 | 3 | 1 | \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature.cs index 25abb75..0c170d2 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature.cs +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part0.feature.cs @@ -18,16 +18,16 @@ namespace Ais.Net.Models.Specs.Features [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("AisMessageType24Part0")] + [NUnit.Framework.DescriptionAttribute("Static Data Report Part A")] [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] - public partial class AisMessageType24Part0Feature + public partial class StaticDataReportPartAFeature { private global::Reqnroll.ITestRunner testRunner; private static string[] featureTags = ((string[])(null)); - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType24Part0", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "Static Data Report Part A", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); #line 1 "AisMessageType24Part0.feature" #line hidden @@ -102,14 +102,28 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) await testRunner.CollectScenarioErrorsAsync(); } + public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync() + { +#line 3 +#line hidden +#line 4 + await testRunner.GivenAsync("I have an AIS message", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); +#line hidden + } + [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create AisMessageType24Part0 record")] - public async global::System.Threading.Tasks.Task CreateAisMessageType24Part0Record() + [NUnit.Framework.DescriptionAttribute("Decoding a Static Data Report Part A")] + [NUnit.Framework.TestCaseAttribute("12345", "0", "3", "1", null)] + public async global::System.Threading.Tasks.Task DecodingAStaticDataReportPartA(string mmsi, string part_No, string repeat, string spare, string[] exampleTags) { - string[] tagsOfScenario = ((string[])(null)); + string[] tagsOfScenario = exampleTags; global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); - global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType24Part0 record", null, tagsOfScenario, argumentsOfScenario, featureTags); -#line 3 + argumentsOfScenario.Add("mmsi", mmsi); + argumentsOfScenario.Add("part_no", part_No); + argumentsOfScenario.Add("repeat", repeat); + argumentsOfScenario.Add("spare", spare); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Decoding a Static Data Report Part A", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 6 this.ScenarioInitialize(scenarioInfo); #line hidden if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) @@ -119,23 +133,26 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) else { await this.ScenarioStartAsync(); +#line 3 +await this.FeatureBackgroundAsync(); +#line hidden global::Reqnroll.Table table4 = new global::Reqnroll.Table(new string[] { "Mmsi", "PartNumber", "RepeatIndicator", "Spare160"}); table4.AddRow(new string[] { - "12345", - "0", - "3", - "1"}); -#line 4 + string.Format("{0}", mmsi), + string.Format("{0}", part_No), + string.Format("{0}", repeat), + string.Format("{0}", spare)}); +#line 7 await testRunner.GivenAsync("a new AisMessageType24Part0 record with the following properties:", ((string)(null)), table4, "Given "); #line hidden -#line 7 +#line 10 await testRunner.WhenAsync("the AisMessageType24Part0 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); #line hidden -#line 8 +#line 11 await testRunner.ThenAsync("the AisMessageType24Part0 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden } diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature index 0827626..1760325 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature @@ -1,8 +1,15 @@ -Feature: AisMessageType24Part1 +Feature: Static Data Report Part B -Scenario: Create AisMessageType24Part1 record +Background: + Given I have an AIS message + +Scenario Outline: Decoding a Static Data Report Part B Given a new AisMessageType24Part1 record with the following properties: | CallSign | DimensionToBow | DimensionToPort | DimensionToStarboard | DimensionToStern | Mmsi | MothershipMmsi | PartNumber | RepeatIndicator | SerialNumber | Spare162 | ShipType | UnitModelCode | VendorIdRev3 | VendorIdRev4 | - | CALL | 1 | 2 | 3 | 4 | 12345 | 54321 | 1 | 3 | 123 | 1 | 60 | 1 | VEN | DOR | + | | | | | | | | | | | | | | | | When the AisMessageType24Part1 is created - Then the AisMessageType24Part1 properties should be set correctly \ No newline at end of file + Then the AisMessageType24Part1 properties should be set correctly + + Examples: + | call_sign | dim_bow | dim_port | dim_starboard | dim_stern | mmsi | mothership_mmsi | part_no | repeat | serial_no | spare | ship_type | unit_model | vendor_rev3 | vendor_rev4 | + | CALL | 1 | 2 | 3 | 4 | 12345 | 54321 | 1 | 3 | 123 | 1 | 60 | 1 | VEN | DOR | \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature.cs index e78f712..69a6230 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature.cs +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType24Part1.feature.cs @@ -18,16 +18,16 @@ namespace Ais.Net.Models.Specs.Features [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("AisMessageType24Part1")] + [NUnit.Framework.DescriptionAttribute("Static Data Report Part B")] [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] - public partial class AisMessageType24Part1Feature + public partial class StaticDataReportPartBFeature { private global::Reqnroll.ITestRunner testRunner; private static string[] featureTags = ((string[])(null)); - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType24Part1", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "Static Data Report Part B", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); #line 1 "AisMessageType24Part1.feature" #line hidden @@ -102,14 +102,55 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) await testRunner.CollectScenarioErrorsAsync(); } + public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync() + { +#line 3 +#line hidden +#line 4 + await testRunner.GivenAsync("I have an AIS message", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); +#line hidden + } + [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create AisMessageType24Part1 record")] - public async global::System.Threading.Tasks.Task CreateAisMessageType24Part1Record() + [NUnit.Framework.DescriptionAttribute("Decoding a Static Data Report Part B")] + [NUnit.Framework.TestCaseAttribute("CALL", "1", "2", "3", "4", "12345", "54321", "1", "3", "123", "1", "60", "1", "VEN", "DOR", null)] + public async global::System.Threading.Tasks.Task DecodingAStaticDataReportPartB( + string call_Sign, + string dim_Bow, + string dim_Port, + string dim_Starboard, + string dim_Stern, + string mmsi, + string mothership_Mmsi, + string part_No, + string repeat, + string serial_No, + string spare, + string ship_Type, + string unit_Model, + string vendor_Rev3, + string vendor_Rev4, + string[] exampleTags) { - string[] tagsOfScenario = ((string[])(null)); + string[] tagsOfScenario = exampleTags; global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); - global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType24Part1 record", null, tagsOfScenario, argumentsOfScenario, featureTags); -#line 3 + argumentsOfScenario.Add("call_sign", call_Sign); + argumentsOfScenario.Add("dim_bow", dim_Bow); + argumentsOfScenario.Add("dim_port", dim_Port); + argumentsOfScenario.Add("dim_starboard", dim_Starboard); + argumentsOfScenario.Add("dim_stern", dim_Stern); + argumentsOfScenario.Add("mmsi", mmsi); + argumentsOfScenario.Add("mothership_mmsi", mothership_Mmsi); + argumentsOfScenario.Add("part_no", part_No); + argumentsOfScenario.Add("repeat", repeat); + argumentsOfScenario.Add("serial_no", serial_No); + argumentsOfScenario.Add("spare", spare); + argumentsOfScenario.Add("ship_type", ship_Type); + argumentsOfScenario.Add("unit_model", unit_Model); + argumentsOfScenario.Add("vendor_rev3", vendor_Rev3); + argumentsOfScenario.Add("vendor_rev4", vendor_Rev4); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Decoding a Static Data Report Part B", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 6 this.ScenarioInitialize(scenarioInfo); #line hidden if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) @@ -119,6 +160,9 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) else { await this.ScenarioStartAsync(); +#line 3 +await this.FeatureBackgroundAsync(); +#line hidden global::Reqnroll.Table table5 = new global::Reqnroll.Table(new string[] { "CallSign", "DimensionToBow", @@ -136,28 +180,28 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) "VendorIdRev3", "VendorIdRev4"}); table5.AddRow(new string[] { - "CALL", - "1", - "2", - "3", - "4", - "12345", - "54321", - "1", - "3", - "123", - "1", - "60", - "1", - "VEN", - "DOR"}); -#line 4 + string.Format("{0}", call_Sign), + string.Format("{0}", dim_Bow), + string.Format("{0}", dim_Port), + string.Format("{0}", dim_Starboard), + string.Format("{0}", dim_Stern), + string.Format("{0}", mmsi), + string.Format("{0}", mothership_Mmsi), + string.Format("{0}", part_No), + string.Format("{0}", repeat), + string.Format("{0}", serial_No), + string.Format("{0}", spare), + string.Format("{0}", ship_Type), + string.Format("{0}", unit_Model), + string.Format("{0}", vendor_Rev3), + string.Format("{0}", vendor_Rev4)}); +#line 7 await testRunner.GivenAsync("a new AisMessageType24Part1 record with the following properties:", ((string)(null)), table5, "Given "); #line hidden -#line 7 +#line 10 await testRunner.WhenAsync("the AisMessageType24Part1 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); #line hidden -#line 8 +#line 11 await testRunner.ThenAsync("the AisMessageType24Part1 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden } diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature index bab76c0..dc862a1 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature @@ -1,8 +1,15 @@ -Feature: AisMessageType27 +Feature: Long-Range AIS Broadcast message -Scenario: Create AisMessageType27 record +Background: + Given I have an AIS message + +Scenario Outline: Decoding a Long-Range AIS Broadcast message Given a new AisMessageType27 record with the following properties: | CourseOverGround | GnssPositionStatus | Mmsi | NavigationStatus | Position_Latitude | Position_Longitude | PositionAccuracy | RaimFlag | RepeatIndicator | SpeedOverGround | - | 123.45 | true | 12345 | UnderwayUsingEngine | 1 | 2 | true | true | 3 | 12.34 | + | | | | | | | | | | | When the AisMessageType27 is created - Then the AisMessageType27 properties should be set correctly \ No newline at end of file + Then the AisMessageType27 properties should be set correctly + + Examples: + | course | gnss_status | mmsi | nav_status | lat | long | pos_accuracy | raim | repeat | speed | + | 123.45 | true | 12345 | UnderwayUsingEngine | 1.0 | 2.0 | true | true | 3 | 12.34 | \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature.cs index 67c6cc2..6fe11cf 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature.cs +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType27.feature.cs @@ -18,16 +18,16 @@ namespace Ais.Net.Models.Specs.Features [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("AisMessageType27")] + [NUnit.Framework.DescriptionAttribute("Long-Range AIS Broadcast message")] [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] - public partial class AisMessageType27Feature + public partial class Long_RangeAISBroadcastMessageFeature { private global::Reqnroll.ITestRunner testRunner; private static string[] featureTags = ((string[])(null)); - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType27", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "Long-Range AIS Broadcast message", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); #line 1 "AisMessageType27.feature" #line hidden @@ -102,14 +102,34 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) await testRunner.CollectScenarioErrorsAsync(); } + public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync() + { +#line 3 +#line hidden +#line 4 + await testRunner.GivenAsync("I have an AIS message", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); +#line hidden + } + [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create AisMessageType27 record")] - public async global::System.Threading.Tasks.Task CreateAisMessageType27Record() + [NUnit.Framework.DescriptionAttribute("Decoding a Long-Range AIS Broadcast message")] + [NUnit.Framework.TestCaseAttribute("123.45", "true", "12345", "UnderwayUsingEngine", "1.0", "2.0", "true", "true", "3", "12.34", null)] + public async global::System.Threading.Tasks.Task DecodingALong_RangeAISBroadcastMessage(string course, string gnss_Status, string mmsi, string nav_Status, string lat, string @long, string pos_Accuracy, string raim, string repeat, string speed, string[] exampleTags) { - string[] tagsOfScenario = ((string[])(null)); + string[] tagsOfScenario = exampleTags; global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); - global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType27 record", null, tagsOfScenario, argumentsOfScenario, featureTags); -#line 3 + argumentsOfScenario.Add("course", course); + argumentsOfScenario.Add("gnss_status", gnss_Status); + argumentsOfScenario.Add("mmsi", mmsi); + argumentsOfScenario.Add("nav_status", nav_Status); + argumentsOfScenario.Add("lat", lat); + argumentsOfScenario.Add("long", @long); + argumentsOfScenario.Add("pos_accuracy", pos_Accuracy); + argumentsOfScenario.Add("raim", raim); + argumentsOfScenario.Add("repeat", repeat); + argumentsOfScenario.Add("speed", speed); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Decoding a Long-Range AIS Broadcast message", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 6 this.ScenarioInitialize(scenarioInfo); #line hidden if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) @@ -119,6 +139,9 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) else { await this.ScenarioStartAsync(); +#line 3 +await this.FeatureBackgroundAsync(); +#line hidden global::Reqnroll.Table table6 = new global::Reqnroll.Table(new string[] { "CourseOverGround", "GnssPositionStatus", @@ -131,23 +154,23 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) "RepeatIndicator", "SpeedOverGround"}); table6.AddRow(new string[] { - "123.45", - "true", - "12345", - "UnderwayUsingEngine", - "1", - "2", - "true", - "true", - "3", - "12.34"}); -#line 4 + string.Format("{0}", course), + string.Format("{0}", gnss_Status), + string.Format("{0}", mmsi), + string.Format("{0}", nav_Status), + string.Format("{0}", lat), + string.Format("{0}", @long), + string.Format("{0}", pos_Accuracy), + string.Format("{0}", raim), + string.Format("{0}", repeat), + string.Format("{0}", speed)}); +#line 7 await testRunner.GivenAsync("a new AisMessageType27 record with the following properties:", ((string)(null)), table6, "Given "); #line hidden -#line 7 +#line 10 await testRunner.WhenAsync("the AisMessageType27 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); #line hidden -#line 8 +#line 11 await testRunner.ThenAsync("the AisMessageType27 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden } diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature index f090714..0a1f11b 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature @@ -1,8 +1,15 @@ -Feature: AisMessageType5 +Feature: Static and Voyage Related Data -Scenario: Create AisMessageType5 record +Background: + Given I have an AIS message + +Scenario Outline: Decoding static and voyage related data Given a new AisMessageType5 record with the following properties: | AisVersion | CallSign | Destination | DimensionToBow | DimensionToPort | DimensionToStarboard | DimensionToStern | Draught10thMetres | EtaDay | EtaHour | EtaMinute | EtaMonth | IsDteNotReady | ImoNumber | Mmsi | PositionFixType | RepeatIndicator | ShipType | Spare423 | VesselName | - | 1 | CALL | DEST | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | true | 123 | 12345 | Gps | 3 | 60 | 1 | VESSEL | + | | | | | | | | | | | | | | | | | | | | | When the AisMessageType5 is created - Then the AisMessageType5 properties should be set correctly \ No newline at end of file + Then the AisMessageType5 properties should be set correctly + + Examples: + | ais_version | call_sign | destination | dim_bow | dim_port | dim_starboard | dim_stern | draught | eta_day | eta_hour | eta_min | eta_month | dte_not_ready | imo | mmsi | pos_fix | repeat | ship_type | spare | vessel_name | + | 1 | CALL | DEST | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | true | 123 | 12345 | Gps | 3 | 60 | 1 | VESSEL | \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature.cs b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature.cs index 9dc2d55..9fbe344 100644 --- a/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature.cs +++ b/Solutions/Ais.Net.Models.Specs/Features/AisMessageType5.feature.cs @@ -18,16 +18,16 @@ namespace Ais.Net.Models.Specs.Features [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "2.0.0.0")] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [NUnit.Framework.TestFixtureAttribute()] - [NUnit.Framework.DescriptionAttribute("AisMessageType5")] + [NUnit.Framework.DescriptionAttribute("Static and Voyage Related Data")] [NUnit.Framework.FixtureLifeCycleAttribute(NUnit.Framework.LifeCycle.InstancePerTestCase)] - public partial class AisMessageType5Feature + public partial class StaticAndVoyageRelatedDataFeature { private global::Reqnroll.ITestRunner testRunner; private static string[] featureTags = ((string[])(null)); - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "AisMessageType5", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "Static and Voyage Related Data", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags); #line 1 "AisMessageType5.feature" #line hidden @@ -102,14 +102,65 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) await testRunner.CollectScenarioErrorsAsync(); } + public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync() + { +#line 3 +#line hidden +#line 4 + await testRunner.GivenAsync("I have an AIS message", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); +#line hidden + } + [NUnit.Framework.TestAttribute()] - [NUnit.Framework.DescriptionAttribute("Create AisMessageType5 record")] - public async global::System.Threading.Tasks.Task CreateAisMessageType5Record() + [NUnit.Framework.DescriptionAttribute("Decoding static and voyage related data")] + [NUnit.Framework.TestCaseAttribute("1", "CALL", "DEST", "1", "2", "3", "4", "5", "6", "7", "8", "9", "true", "123", "12345", "Gps", "3", "60", "1", "VESSEL", null)] + public async global::System.Threading.Tasks.Task DecodingStaticAndVoyageRelatedData( + string ais_Version, + string call_Sign, + string destination, + string dim_Bow, + string dim_Port, + string dim_Starboard, + string dim_Stern, + string draught, + string eta_Day, + string eta_Hour, + string eta_Min, + string eta_Month, + string dte_Not_Ready, + string imo, + string mmsi, + string pos_Fix, + string repeat, + string ship_Type, + string spare, + string vessel_Name, + string[] exampleTags) { - string[] tagsOfScenario = ((string[])(null)); + string[] tagsOfScenario = exampleTags; global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); - global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Create AisMessageType5 record", null, tagsOfScenario, argumentsOfScenario, featureTags); -#line 3 + argumentsOfScenario.Add("ais_version", ais_Version); + argumentsOfScenario.Add("call_sign", call_Sign); + argumentsOfScenario.Add("destination", destination); + argumentsOfScenario.Add("dim_bow", dim_Bow); + argumentsOfScenario.Add("dim_port", dim_Port); + argumentsOfScenario.Add("dim_starboard", dim_Starboard); + argumentsOfScenario.Add("dim_stern", dim_Stern); + argumentsOfScenario.Add("draught", draught); + argumentsOfScenario.Add("eta_day", eta_Day); + argumentsOfScenario.Add("eta_hour", eta_Hour); + argumentsOfScenario.Add("eta_min", eta_Min); + argumentsOfScenario.Add("eta_month", eta_Month); + argumentsOfScenario.Add("dte_not_ready", dte_Not_Ready); + argumentsOfScenario.Add("imo", imo); + argumentsOfScenario.Add("mmsi", mmsi); + argumentsOfScenario.Add("pos_fix", pos_Fix); + argumentsOfScenario.Add("repeat", repeat); + argumentsOfScenario.Add("ship_type", ship_Type); + argumentsOfScenario.Add("spare", spare); + argumentsOfScenario.Add("vessel_name", vessel_Name); + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Decoding static and voyage related data", null, tagsOfScenario, argumentsOfScenario, featureTags); +#line 6 this.ScenarioInitialize(scenarioInfo); #line hidden if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) @@ -119,6 +170,9 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) else { await this.ScenarioStartAsync(); +#line 3 +await this.FeatureBackgroundAsync(); +#line hidden global::Reqnroll.Table table7 = new global::Reqnroll.Table(new string[] { "AisVersion", "CallSign", @@ -141,33 +195,33 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo) "Spare423", "VesselName"}); table7.AddRow(new string[] { - "1", - "CALL", - "DEST", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "true", - "123", - "12345", - "Gps", - "3", - "60", - "1", - "VESSEL"}); -#line 4 + string.Format("{0}", ais_Version), + string.Format("{0}", call_Sign), + string.Format("{0}", destination), + string.Format("{0}", dim_Bow), + string.Format("{0}", dim_Port), + string.Format("{0}", dim_Starboard), + string.Format("{0}", dim_Stern), + string.Format("{0}", draught), + string.Format("{0}", eta_Day), + string.Format("{0}", eta_Hour), + string.Format("{0}", eta_Min), + string.Format("{0}", eta_Month), + string.Format("{0}", dte_Not_Ready), + string.Format("{0}", imo), + string.Format("{0}", mmsi), + string.Format("{0}", pos_Fix), + string.Format("{0}", repeat), + string.Format("{0}", ship_Type), + string.Format("{0}", spare), + string.Format("{0}", vessel_Name)}); +#line 7 await testRunner.GivenAsync("a new AisMessageType5 record with the following properties:", ((string)(null)), table7, "Given "); #line hidden -#line 7 +#line 10 await testRunner.WhenAsync("the AisMessageType5 is created", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); #line hidden -#line 8 +#line 11 await testRunner.ThenAsync("the AisMessageType5 properties should be set correctly", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); #line hidden } diff --git a/Solutions/Ais.Net.Models.Specs/Hooks.cs b/Solutions/Ais.Net.Models.Specs/Hooks.cs new file mode 100644 index 0000000..87ebbe9 --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/Hooks.cs @@ -0,0 +1,20 @@ +using Reqnroll; + +namespace Ais.Net.Models.Specs +{ + [Binding] + public class Hooks + { + [BeforeScenario] + public void BeforeScenario() + { + //TODO: implement logic that has to run before executing each scenario + } + + [AfterScenario] + public void AfterScenario() + { + //TODO: implement logic that has to run after executing each scenario + } + } +} \ No newline at end of file diff --git a/Solutions/Ais.Net.Models.Specs/StepDefinitionBase.cs b/Solutions/Ais.Net.Models.Specs/StepDefinitionBase.cs new file mode 100644 index 0000000..d5795bc --- /dev/null +++ b/Solutions/Ais.Net.Models.Specs/StepDefinitionBase.cs @@ -0,0 +1,9 @@ +using Ais.Net.Models.Abstractions; + +namespace Ais.Net.Models.Specs +{ + public class StepDefinitionBase + { + protected IAisMessage? Message { get; set; } + } +} \ No newline at end of file From 29429e40a1d67c70322150787be79bb56733e837 Mon Sep 17 00:00:00 2001 From: Howard van Rooijen Date: Wed, 18 Jun 2025 10:42:50 +0100 Subject: [PATCH 05/15] Refactor project file by removing unnecessary elements Removed `` elements for settings files and eliminated `` and `` elements related to feature files. This simplifies the project structure and may streamline the build process. --- .../Ais.Net.Models.Specs.csproj | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj b/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj index 4e626e1..616ce97 100644 --- a/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj +++ b/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj @@ -32,23 +32,6 @@ - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - %(Filename) - - - - From 8a74a352e18ba92733ccfd128a9a559857ca5a3c Mon Sep 17 00:00:00 2001 From: James Dawson Date: Wed, 18 Jun 2025 11:27:17 +0100 Subject: [PATCH 06/15] Test linux-only build --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index af5460f..c8dea3e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,9 +66,10 @@ jobs: forcePublish: ${{ github.event.inputs.forcePublish == 'true' }} skipCleanup: ${{ github.event.inputs.skipCleanup == 'true' }} enableCrossOsCaching: true + compilePhaseRunnerOs: ubuntu-latest testPhaseMatrixJson: | { - "os": ["windows-latest", "ubuntu-latest"], + "os": ["ubuntu-latest"], "dotnetFramework": ["net8.0"] } # testArtifactName: '' From 19624244fea84b3240e3d61b98be4daa2432cbd9 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Wed, 18 Jun 2025 11:33:49 +0100 Subject: [PATCH 07/15] Re-enable windows tests --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c8dea3e..ad8491c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,7 +69,7 @@ jobs: compilePhaseRunnerOs: ubuntu-latest testPhaseMatrixJson: | { - "os": ["ubuntu-latest"], + "os": ["windows-latest", "ubuntu-latest"], "dotnetFramework": ["net8.0"] } # testArtifactName: '' From 95cd268367796dec7f021883ed481e3b5085acd6 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Wed, 18 Jun 2025 13:41:32 +0100 Subject: [PATCH 08/15] Ensure packaging phase runs on same OS compilation --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad8491c..2a35188 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -67,6 +67,7 @@ jobs: skipCleanup: ${{ github.event.inputs.skipCleanup == 'true' }} enableCrossOsCaching: true compilePhaseRunnerOs: ubuntu-latest + packagePhaseRunnerOs: ubuntu-latest testPhaseMatrixJson: | { "os": ["windows-latest", "ubuntu-latest"], From 38f5ed487ae50ee8441ff118e715ba8e140e3170 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Wed, 18 Jun 2025 13:44:30 +0100 Subject: [PATCH 09/15] Debug files available from cache --- .zf/config.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.zf/config.ps1 b/.zf/config.ps1 index 5b4eaf1..d515202 100644 --- a/.zf/config.ps1 +++ b/.zf/config.ps1 @@ -55,7 +55,12 @@ task . FullBuild # task PostVersion {} # task PreBuild {} # task PostBuild {} -# task PreTest {} +task PreTest { + Write-Build Green "Repo Root:" + gci $here | Out-String | Write-Host + Write-Build Green "Available specs" + gci -Recurse $here/*.Specs.dll | Out-String | Write-Host +} # task PostTest {} # task PreTestReport {} # task PostTestReport {} From 0a7ea27d038882e4ec5d08f5e14a125bd15d9f50 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Wed, 18 Jun 2025 14:21:54 +0100 Subject: [PATCH 10/15] Test experimental workflow changes re: caching --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a35188..2a9f4e0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,7 +58,7 @@ jobs: build: needs: prepareConfig - uses: endjin/Endjin.RecommendedPractices.GitHubActions/.github/workflows/scripted-build-matrix-pipeline.yml@main + uses: endjin/Endjin.RecommendedPractices.GitHubActions/.github/workflows/scripted-build-matrix-pipeline.yml@feature/update-ci-builds with: netSdkVersion: '8.x' # additionalNetSdkVersion: '9.x' From 297ea90706b6ee5618a07ad17fa691921070e804 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Wed, 18 Jun 2025 14:29:36 +0100 Subject: [PATCH 11/15] Force build From e7f380b1aeeeca13b23a851a2795a250b4a0e462 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Wed, 18 Jun 2025 14:36:11 +0100 Subject: [PATCH 12/15] Force build From 1b84cfe549cb52a22be9095659e3f5f0e8f82251 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Wed, 18 Jun 2025 15:38:44 +0100 Subject: [PATCH 13/15] Add 'IsTestProject' property --- Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj b/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj index 616ce97..1b41614 100644 --- a/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj +++ b/Solutions/Ais.Net.Models.Specs/Ais.Net.Models.Specs.csproj @@ -12,6 +12,7 @@ --> RCS1029;SA0001;SA1204;SA1600;SA1602;CS1591 enable + true From a3c3925e07ab613c0ca4c4b83dfe7f5ddc66fbd4 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Thu, 19 Jun 2025 17:13:22 +0100 Subject: [PATCH 14/15] Force build From 0270c1b9eec567162ea4cfca663c2eb1dae935b1 Mon Sep 17 00:00:00 2001 From: James Dawson Date: Thu, 19 Jun 2025 17:38:16 +0100 Subject: [PATCH 15/15] Revert debugging changes --- .github/workflows/build.yml | 2 +- .zf/config.ps1 | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a9f4e0..2a35188 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,7 +58,7 @@ jobs: build: needs: prepareConfig - uses: endjin/Endjin.RecommendedPractices.GitHubActions/.github/workflows/scripted-build-matrix-pipeline.yml@feature/update-ci-builds + uses: endjin/Endjin.RecommendedPractices.GitHubActions/.github/workflows/scripted-build-matrix-pipeline.yml@main with: netSdkVersion: '8.x' # additionalNetSdkVersion: '9.x' diff --git a/.zf/config.ps1 b/.zf/config.ps1 index d515202..5b4eaf1 100644 --- a/.zf/config.ps1 +++ b/.zf/config.ps1 @@ -55,12 +55,7 @@ task . FullBuild # task PostVersion {} # task PreBuild {} # task PostBuild {} -task PreTest { - Write-Build Green "Repo Root:" - gci $here | Out-String | Write-Host - Write-Build Green "Available specs" - gci -Recurse $here/*.Specs.dll | Out-String | Write-Host -} +# task PreTest {} # task PostTest {} # task PreTestReport {} # task PostTestReport {}