From 4cc76fa4ff422c50e481ef5351236a68f7d57fe4 Mon Sep 17 00:00:00 2001 From: Gaspar Nagy Date: Fri, 16 Feb 2024 08:44:29 +0100 Subject: [PATCH] fix code generation in Reqnroll.Actions.Configuration --- .../TargetsGeneratorPlugin.cs | 3 +- .../UnitTestFeatureGeneratorBase.cs | 204 ------------------ .../UnitTestTargetFeatureGenerator.cs | 51 +++-- 3 files changed, 30 insertions(+), 228 deletions(-) delete mode 100644 Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/UnitTestFeatureGeneratorBase.cs diff --git a/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/TargetsGeneratorPlugin.cs b/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/TargetsGeneratorPlugin.cs index b084a05..67cf107 100644 --- a/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/TargetsGeneratorPlugin.cs +++ b/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/TargetsGeneratorPlugin.cs @@ -19,8 +19,7 @@ private void GeneratorPluginEvents_CustomizeDependencies(object sender, Customiz e.ObjectContainer.RegisterTypeAs(); e.ObjectContainer.RegisterTypeAs(); e.ObjectContainer.RegisterTypeAs(); - //TODO: the MultiFeatureGeneratorProvider is disabled temporarily to be able to make the code build - //e.ObjectContainer.RegisterTypeAs(); + e.ObjectContainer.RegisterTypeAs(); } } } \ No newline at end of file diff --git a/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/UnitTestFeatureGeneratorBase.cs b/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/UnitTestFeatureGeneratorBase.cs deleted file mode 100644 index f45b0aa..0000000 --- a/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/UnitTestFeatureGeneratorBase.cs +++ /dev/null @@ -1,204 +0,0 @@ -using System; -using System.CodeDom; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Reflection; -using Reqnroll; -using Reqnroll.Configuration; -using Reqnroll.Generator; -using Reqnroll.Generator.CodeDom; -using Reqnroll.Generator.Generation; -using Reqnroll.Generator.UnitTestConverter; -using Reqnroll.Generator.UnitTestProvider; -using Reqnroll.Parser; -using Reqnroll.Tracing; - -namespace Reqnroll.Actions.Configuration.Generation -{ - public abstract class UnitTestFeatureGeneratorBase : IFeatureGenerator - { - private readonly CodeDomHelper _codeDomHelper; - - private readonly IDecoratorRegistry _decoratorRegistry; - - internal readonly ScenarioPartHelper _scenarioPartHelper; - - private readonly ReqnrollConfiguration _reqnrollConfiguration; - - private readonly IUnitTestGeneratorProvider _testGeneratorProvider; - - private readonly UnitTestMethodGenerator _unitTestMethodGenerator; - - private readonly LinePragmaHandler _linePragmaHandler; - - public string TestClassNameFormat { get; set; } = "{0}Feature"; - - - public UnitTestFeatureGeneratorBase(IUnitTestGeneratorProvider testGeneratorProvider, CodeDomHelper codeDomHelper, ReqnrollConfiguration reqnrollConfiguration, IDecoratorRegistry decoratorRegistry) - { - _testGeneratorProvider = testGeneratorProvider; - _codeDomHelper = codeDomHelper; - _reqnrollConfiguration = reqnrollConfiguration; - _decoratorRegistry = decoratorRegistry; - _linePragmaHandler = new LinePragmaHandler(_reqnrollConfiguration, _codeDomHelper); - _scenarioPartHelper = new ScenarioPartHelper(_reqnrollConfiguration, _codeDomHelper); - _unitTestMethodGenerator = new UnitTestMethodGenerator(testGeneratorProvider, decoratorRegistry, _codeDomHelper, _scenarioPartHelper, _reqnrollConfiguration); - } - - public CodeNamespace GenerateUnitTestFixture(ReqnrollDocument document, string testClassName, string targetNamespace) - { - var codeNamespace = CreateNamespace(targetNamespace); - var reqnrollFeature = document.ReqnrollFeature; - testClassName = testClassName ?? string.Format(TestClassNameFormat, reqnrollFeature.Name.ToIdentifier()); - var generationContext = CreateTestClassStructure(codeNamespace, testClassName, document); - SetupTestClass(generationContext); - SetupTestClassInitializeMethod(generationContext); - SetupTestClassCleanupMethod(generationContext); - SetupScenarioStartMethod(generationContext); - SetupScenarioInitializeMethod(generationContext); - _scenarioPartHelper.SetupFeatureBackground(generationContext); - SetupScenarioCleanupMethod(generationContext); - SetupTestInitializeMethod(generationContext); - SetupTestCleanupMethod(generationContext); - _unitTestMethodGenerator.CreateUnitTests(reqnrollFeature, generationContext); - _testGeneratorProvider.FinalizeTestClass(generationContext); - return codeNamespace; - } - - private TestClassGenerationContext CreateTestClassStructure(CodeNamespace codeNamespace, string testClassName, ReqnrollDocument document) - { - var codeTypeDeclaration = _codeDomHelper.CreateGeneratedTypeDeclaration(testClassName); - codeNamespace.Types.Add(codeTypeDeclaration); - return new TestClassGenerationContext(_testGeneratorProvider, document, codeNamespace, codeTypeDeclaration, DeclareTestRunnerMember(codeTypeDeclaration), _codeDomHelper.CreateMethod(codeTypeDeclaration), _codeDomHelper.CreateMethod(codeTypeDeclaration), _codeDomHelper.CreateMethod(codeTypeDeclaration), _codeDomHelper.CreateMethod(codeTypeDeclaration), _codeDomHelper.CreateMethod(codeTypeDeclaration), _codeDomHelper.CreateMethod(codeTypeDeclaration), _codeDomHelper.CreateMethod(codeTypeDeclaration), document.ReqnrollFeature.HasFeatureBackground() ? _codeDomHelper.CreateMethod(codeTypeDeclaration) : null, _testGeneratorProvider.GetTraits().HasFlag(UnitTestGeneratorTraits.RowTests) && _reqnrollConfiguration.AllowRowTests); - } - - private CodeNamespace CreateNamespace(string targetNamespace) - { - targetNamespace = targetNamespace ?? "ReqnrollTests"; - if (!targetNamespace.StartsWith("global", StringComparison.CurrentCultureIgnoreCase) && _codeDomHelper.TargetLanguage == CodeDomProviderLanguage.VB) - { - targetNamespace = "GlobalVBNetNamespace." + targetNamespace; - } - - return new CodeNamespace(targetNamespace) - { - Imports = - { - new CodeNamespaceImport("Reqnroll"), - new CodeNamespaceImport("System"), - new CodeNamespaceImport("System.Linq"), - } - }; - } - - private void SetupScenarioCleanupMethod(TestClassGenerationContext generationContext) - { - var scenarioCleanupMethod = generationContext.ScenarioCleanupMethod; - scenarioCleanupMethod.Attributes = MemberAttributes.Public; - scenarioCleanupMethod.Name = "ScenarioCleanup"; - var testRunnerExpression = _scenarioPartHelper.GetTestRunnerExpression(); - scenarioCleanupMethod.Statements.Add(new CodeMethodInvokeExpression(testRunnerExpression, "CollectScenarioErrors")); - } - - private void SetupTestClass(TestClassGenerationContext generationContext) - { - generationContext.TestClass.IsPartial = true; - generationContext.TestClass.TypeAttributes |= TypeAttributes.Public; - _linePragmaHandler.AddLinePragmaInitial(generationContext.TestClass, generationContext.Document.SourceFilePath); - _testGeneratorProvider.SetTestClass(generationContext, generationContext.Feature.Name, generationContext.Feature.Description); - _decoratorRegistry.DecorateTestClass(generationContext, out var unprocessedTags); - if (unprocessedTags.Any()) - { - _testGeneratorProvider.SetTestClassCategories(generationContext, unprocessedTags); - } - - var codeMemberField = new CodeMemberField(typeof(string[]), "featureTags"); - codeMemberField.InitExpression = _scenarioPartHelper.GetStringArrayExpression(generationContext.Feature.Tags); - generationContext.TestClass.Members.Add(codeMemberField); - } - - private CodeMemberField DeclareTestRunnerMember(CodeTypeDeclaration type) - { - var codeMemberField = new CodeMemberField(typeof(ITestRunner), "testRunner"); - type.Members.Add(codeMemberField); - return codeMemberField; - } - - private void SetupTestClassInitializeMethod(TestClassGenerationContext generationContext) - { - var testClassInitializeMethod = generationContext.TestClassInitializeMethod; - testClassInitializeMethod.Attributes = MemberAttributes.Public; - testClassInitializeMethod.Name = "FeatureSetup"; - _testGeneratorProvider.SetTestClassInitializeMethod(generationContext); - var testRunnerExpression = _scenarioPartHelper.GetTestRunnerExpression(); - CodeExpression[] array2; - if (!_testGeneratorProvider.GetTraits().HasFlag(UnitTestGeneratorTraits.ParallelExecution)) - { - CodeExpression[] array = new CodePrimitiveExpression[2] - { - new CodePrimitiveExpression(null), - new CodePrimitiveExpression(0) - }; - array2 = array; - } - else - { - array2 = new CodeExpression[0]; - } - - var parameters = array2; - testClassInitializeMethod.Statements.Add(new CodeAssignStatement(testRunnerExpression, new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(TestRunnerManager)), "GetTestRunner", parameters))); - testClassInitializeMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(FeatureInfo), "featureInfo", new CodeObjectCreateExpression(typeof(FeatureInfo), new CodeObjectCreateExpression(typeof(CultureInfo), new CodePrimitiveExpression(generationContext.Feature.Language)), new CodePrimitiveExpression(generationContext.Document.DocumentLocation?.FeatureFolderPath), new CodePrimitiveExpression(generationContext.Feature.Name), new CodePrimitiveExpression(generationContext.Feature.Description), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("ProgrammingLanguage"), _codeDomHelper.TargetLanguage.ToString()), _scenarioPartHelper.GetStringArrayExpression(generationContext.Feature.Tags)))); - testClassInitializeMethod.Statements.Add(new CodeMethodInvokeExpression(testRunnerExpression, "OnFeatureStart", new CodeVariableReferenceExpression("featureInfo"))); - } - - private void SetupTestClassCleanupMethod(TestClassGenerationContext generationContext) - { - var testClassCleanupMethod = generationContext.TestClassCleanupMethod; - testClassCleanupMethod.Attributes = MemberAttributes.Public; - testClassCleanupMethod.Name = "FeatureTearDown"; - _testGeneratorProvider.SetTestClassCleanupMethod(generationContext); - var testRunnerExpression = _scenarioPartHelper.GetTestRunnerExpression(); - testClassCleanupMethod.Statements.Add(new CodeMethodInvokeExpression(testRunnerExpression, "OnFeatureEnd")); - testClassCleanupMethod.Statements.Add(new CodeAssignStatement(testRunnerExpression, new CodePrimitiveExpression(null))); - } - - private void SetupTestInitializeMethod(TestClassGenerationContext generationContext) - { - var testInitializeMethod = generationContext.TestInitializeMethod; - testInitializeMethod.Attributes = MemberAttributes.Public; - testInitializeMethod.Name = "TestInitialize"; - _testGeneratorProvider.SetTestInitializeMethod(generationContext); - } - - private void SetupTestCleanupMethod(TestClassGenerationContext generationContext) - { - var testCleanupMethod = generationContext.TestCleanupMethod; - testCleanupMethod.Attributes = MemberAttributes.Public; - testCleanupMethod.Name = "TestTearDown"; - _testGeneratorProvider.SetTestCleanupMethod(generationContext); - var testRunnerExpression = _scenarioPartHelper.GetTestRunnerExpression(); - testCleanupMethod.Statements.Add(new CodeMethodInvokeExpression(testRunnerExpression, "OnScenarioEnd")); - } - - internal virtual void SetupScenarioInitializeMethod(TestClassGenerationContext generationContext) - { - var scenarioInitializeMethod = generationContext.ScenarioInitializeMethod; - scenarioInitializeMethod.Attributes = MemberAttributes.Public; - scenarioInitializeMethod.Name = "ScenarioInitialize"; - scenarioInitializeMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(ScenarioInfo), "scenarioInfo")); - var testRunnerExpression = _scenarioPartHelper.GetTestRunnerExpression(); - scenarioInitializeMethod.Statements.Add(new CodeMethodInvokeExpression(testRunnerExpression, "OnScenarioInitialize", new CodeVariableReferenceExpression("scenarioInfo"))); - } - - private void SetupScenarioStartMethod(TestClassGenerationContext generationContext) - { - var scenarioStartMethod = generationContext.ScenarioStartMethod; - scenarioStartMethod.Attributes = MemberAttributes.Public; - scenarioStartMethod.Name = "ScenarioStart"; - var testRunnerExpression = _scenarioPartHelper.GetTestRunnerExpression(); - scenarioStartMethod.Statements.Add(new CodeMethodInvokeExpression(testRunnerExpression, "OnScenarioStart")); - } - } -} \ No newline at end of file diff --git a/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/UnitTestTargetFeatureGenerator.cs b/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/UnitTestTargetFeatureGenerator.cs index 876087f..63ddabe 100644 --- a/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/UnitTestTargetFeatureGenerator.cs +++ b/Plugins/Reqnroll.Actions.Configuration/Reqnroll.Actions.Configuration.Generation/UnitTestTargetFeatureGenerator.cs @@ -1,36 +1,43 @@ using System.CodeDom; -using Reqnroll; using Reqnroll.Configuration; -using Reqnroll.Generator; using Reqnroll.Generator.CodeDom; +using Reqnroll.Generator.Generation; using Reqnroll.Generator.UnitTestConverter; using Reqnroll.Generator.UnitTestProvider; +using Reqnroll.Parser; +using System.Linq; -namespace Reqnroll.Actions.Configuration.Generation +namespace Reqnroll.Actions.Configuration.Generation; + +internal class UnitTestTargetFeatureGenerator : UnitTestFeatureGenerator, IFeatureGenerator { - internal class UnitTestTargetFeatureGenerator : UnitTestFeatureGeneratorBase + private readonly string _target; + + public UnitTestTargetFeatureGenerator(IUnitTestGeneratorProvider testGeneratorProvider, + CodeDomHelper codeDomHelper, ReqnrollConfiguration reqnrollConfiguration, + IDecoratorRegistry decoratorRegistry, string target) + : base(testGeneratorProvider, codeDomHelper, reqnrollConfiguration, decoratorRegistry) { - private readonly string _target; + _target = target; + TestClassNameFormat += $"_{target.Replace(".", "_")}"; + } - public UnitTestTargetFeatureGenerator(IUnitTestGeneratorProvider testGeneratorProvider, - CodeDomHelper codeDomHelper, ReqnrollConfiguration reqnrollConfiguration, - IDecoratorRegistry decoratorRegistry, string target) - : base(testGeneratorProvider, codeDomHelper, reqnrollConfiguration, decoratorRegistry) - { - _target = target; - //base.TestClassNameFormat += $"_{_seleniumReqnrollJsonPart.Browser}"; - TestClassNameFormat += $"_{target.Replace(".", "_")}"; - } + public new CodeNamespace GenerateUnitTestFixture(ReqnrollDocument document, string testClassName, string targetNamespace) + { + var codeNamespace = base.GenerateUnitTestFixture(document, testClassName, targetNamespace); - internal override void SetupScenarioInitializeMethod(TestClassGenerationContext generationContext) + var testType = codeNamespace.Types.OfType().FirstOrDefault(); + if (testType != null) { - var scenarioInitializeMethod = generationContext.ScenarioInitializeMethod; - scenarioInitializeMethod.Attributes = MemberAttributes.Public; - scenarioInitializeMethod.Name = "ScenarioInitialize"; - scenarioInitializeMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(ScenarioInfo), "scenarioInfo")); - var testRunnerExpression = _scenarioPartHelper.GetTestRunnerExpression(); - scenarioInitializeMethod.Statements.Add(new CodeMethodInvokeExpression(testRunnerExpression, "OnScenarioInitialize", new CodeVariableReferenceExpression("scenarioInfo"))); - scenarioInitializeMethod.Statements.Add(new CodeSnippetStatement($"\t\t\ttestRunner.ScenarioContext[\"__ReqnrollActionsConfigurationTarget\"] = \"{_target}\";")); + var scenarioInitializeMethod = testType.Members.OfType() + .FirstOrDefault(m => m.Name == GeneratorConstants.SCENARIO_INITIALIZE_NAME); + if (scenarioInitializeMethod != null) + { + scenarioInitializeMethod.Statements.Add(new CodeSnippetStatement($"\t\t\ttestRunner.ScenarioContext[\"__ReqnrollActionsConfigurationTarget\"] = \"{_target}\";")); + } } + + + return codeNamespace; } } \ No newline at end of file