From 7e81c9560939ea884d7bc2a6d35f49fe62c9bacb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1sp=C3=A1r=20Nagy?= Date: Mon, 7 Oct 2024 12:39:02 +0200 Subject: [PATCH] Fix: Reqnroll generates invalid code for rule backgrounds in Visual Basic (#284) * Fix: Reqnroll generates invalid code for rule backgrounds in Visual Basic (#283) * Update changelog --- CHANGELOG.md | 11 +- Reqnroll.Generator/CodeDom/CodeDomHelper.cs | 4 +- .../Generation/ScenarioPartHelper.cs | 7 +- .../Generation/GenerationTestBase.cs | 12 ++ .../BindingsGenerator/VbBindingsGenerator.cs | 106 ++++++++++-------- 5 files changed, 83 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5ac467a4..ecf0b48e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,14 @@ # [vNext] -* Fix: Rule Backgounds cause External Data Plugin to fail (#271) @clrudolphi + ## Bug fixes: -* Modified VersionInfo class to force it to pull version information from the Reqnroll assembly + +* Fix: Rule Backgounds cause External Data Plugin to fail (#271) +* Fix: VersionInfo class might provide the version of the runner instead of the version of Reqnroll (#248) * Fix: Reqnroll.CustomPlugin NuGet package has a version mismatch for the System.CodeDom dependency (#244) -* Reqnroll.Verify fails to run parallel tests determinately (#254). See our [verify documentation](docs/integrations/verify.md) on how to set up your test code to enable parallel testing. +* Fix: Reqnroll.Verify fails to run parallel tests determinately (#254). See our [verify documentation](docs/integrations/verify.md) on how to set up your test code to enable parallel testing. +* Fix: Reqnroll generates invalid code for rule backgrounds in Visual Basic (#283) -*Contributors of this release (in alphabetical order):* @ajeckmans, @clrudolphi, @UL-ChrisGlew +*Contributors of this release (in alphabetical order):* @ajeckmans, @clrudolphi, @gasparnagy, @UL-ChrisGlew # v2.1.0 - 2024-08-30 diff --git a/Reqnroll.Generator/CodeDom/CodeDomHelper.cs b/Reqnroll.Generator/CodeDom/CodeDomHelper.cs index 9d649dbbb..407d49280 100644 --- a/Reqnroll.Generator/CodeDom/CodeDomHelper.cs +++ b/Reqnroll.Generator/CodeDom/CodeDomHelper.cs @@ -107,7 +107,7 @@ public CodeStatement GetDisableWarningsPragma() case CodeDomProviderLanguage.CSharp: return new CodeSnippetStatement("#pragma warning disable"); case CodeDomProviderLanguage.VB: - return new CodeCommentStatement("#pragma warning disable"); //not supported in VB + return new CodeSnippetStatement("#Disable Warning BC42356"); //in VB warning codes must be listed explicitly } return new CodeCommentStatement("#pragma warning disable"); } @@ -119,7 +119,7 @@ public CodeStatement GetEnableWarningsPragma() case CodeDomProviderLanguage.CSharp: return new CodeSnippetStatement("#pragma warning restore"); case CodeDomProviderLanguage.VB: - return new CodeCommentStatement("#pragma warning restore"); //not supported in VB + return new CodeSnippetStatement("#Enable Warning BC42356"); //in VB warning codes must be listed explicitly } return new CodeCommentStatement("#pragma warning restore"); } diff --git a/Reqnroll.Generator/Generation/ScenarioPartHelper.cs b/Reqnroll.Generator/Generation/ScenarioPartHelper.cs index 307b7d8a6..e8395f841 100644 --- a/Reqnroll.Generator/Generation/ScenarioPartHelper.cs +++ b/Reqnroll.Generator/Generation/ScenarioPartHelper.cs @@ -68,12 +68,9 @@ private IEnumerable GenerateBackgroundStatementsForRule(TestClass if (background == null) return new List(); var statements = new List(); - using (new SourceLineScope(_reqnrollConfiguration, _codeDomHelper, statements, context.Document.SourceFilePath, background.Location)) + foreach (var step in background.Steps) { - foreach (var step in background.Steps) - { - GenerateStep(context, statements, step, null); - } + GenerateStep(context, statements, step, null); } return statements; diff --git a/Tests/Reqnroll.SystemTests/Generation/GenerationTestBase.cs b/Tests/Reqnroll.SystemTests/Generation/GenerationTestBase.cs index c145706cb..04cd07cdf 100644 --- a/Tests/Reqnroll.SystemTests/Generation/GenerationTestBase.cs +++ b/Tests/Reqnroll.SystemTests/Generation/GenerationTestBase.cs @@ -21,6 +21,18 @@ public void GeneratorAllIn_sample_can_be_handled() ShouldAllScenariosPass(); } + [TestMethod] + public void GeneratorAllIn_sample_can_be_handled_with_VisualBasic() + { + _testRunConfiguration.ProgrammingLanguage = ProgrammingLanguage.VB; + + PrepareGeneratorAllInSamples(); + + ExecuteTests(); + + ShouldAllScenariosPass(); + } + [TestMethod] public void Handles_simple_scenarios_without_namespace_collisions() { diff --git a/Tests/TestProjectGenerator/Reqnroll.TestProjectGenerator/Factories/BindingsGenerator/VbBindingsGenerator.cs b/Tests/TestProjectGenerator/Reqnroll.TestProjectGenerator/Factories/BindingsGenerator/VbBindingsGenerator.cs index c6c0808e1..d21e1e102 100644 --- a/Tests/TestProjectGenerator/Reqnroll.TestProjectGenerator/Factories/BindingsGenerator/VbBindingsGenerator.cs +++ b/Tests/TestProjectGenerator/Reqnroll.TestProjectGenerator/Factories/BindingsGenerator/VbBindingsGenerator.cs @@ -20,52 +20,66 @@ Public Class {0} public override ProjectFile GenerateLoggerClass(string pathToLogFile) { - string fileContent = $@" -Imports System -Imports System.IO -Imports System.Runtime.CompilerServices -Imports System.Threading.Tasks - -Friend Module Log - Private Const LogFileLocation As String = ""{pathToLogFile}"" - - Friend Sub LogStep( Optional stepName As String = Nothing) - File.AppendAllText(LogFileLocation, $""-> step: {{stepName}}{{Environment.NewLine}}"") - End Sub - - Friend Sub LogHook( Optional stepName As String = Nothing) - File.AppendAllText(LogFileLocation, $""-> hook: {{stepName}}{{Environment.NewLine}}"") - End Sub - - Friend Async Function LogHookIncludingLockingAsync( - ByVal Optional stepName As String = Nothing) As Task - File.AppendAllText(LogFileLocation, $""->waiting for hook lock: {{stepName}}{{Environment.NewLine}}"") - Await WaitForLockAsync() - File.AppendAllText(LogFileLocation, $""-> hook: {{stepName}}{{Environment.NewLine}}"") - End Function - - Private Async Function WaitForLockAsync() As Task - Dim lockFile = LogFileLocation & "".lock"" - - While True - - Dim succeeded = True - Try - Using File.Open(lockFile, FileMode.CreateNew) - End Using - Exit While - Catch __unusedIOException1__ As IOException - succeeded = False - End Try - If Not succeeded Then - Await Task.Delay(1000) - End If - End While - - File.Delete(lockFile) - End Function -End Module -"; + string fileContent = + $$""" + Imports System + Imports System.IO + Imports System.Runtime.CompilerServices + Imports System.Threading.Tasks + + Friend Module Log + Private Const LogFileLocation As String = "{{pathToLogFile}}" + + Private Sub Retry(number As Integer, action As Action) + Try + action + Catch ex As Exception + Dim i = number - 1 + If (i = 0) + Throw + End If + System.Threading.Thread.Sleep(500) + Retry(i, action) + End Try + End Sub + + Friend Sub LogStep( Optional stepName As String = Nothing) + Retry(5, sub() File.AppendAllText(LogFileLocation, $"-> step: {stepName}{Environment.NewLine}")) + End Sub + + Friend Sub LogHook( Optional stepName As String = Nothing) + Retry(5, sub() File.AppendAllText(LogFileLocation, $"-> hook: {stepName}{Environment.NewLine}")) + End Sub + + Friend Async Function LogHookIncludingLockingAsync( + ByVal Optional stepName As String = Nothing) As Task + File.AppendAllText(LogFileLocation, $"->waiting for hook lock: {stepName}{Environment.NewLine}") + Await WaitForLockAsync() + File.AppendAllText(LogFileLocation, $"-> hook: {stepName}{Environment.NewLine}") + End Function + + Private Async Function WaitForLockAsync() As Task + Dim lockFile = LogFileLocation & ".lock" + + While True + + Dim succeeded = True + Try + Using File.Open(lockFile, FileMode.CreateNew) + End Using + Exit While + Catch __unusedIOException1__ As IOException + succeeded = False + End Try + If Not succeeded Then + Await Task.Delay(1000) + End If + End While + + File.Delete(lockFile) + End Function + End Module + """; return new ProjectFile("Log.vb", "Compile", fileContent); }