Skip to content

Commit

Permalink
UUID id generation now working.
Browse files Browse the repository at this point in the history
ID Generation Style is configurable.
Modified parameter naming convention used during code generation to match recommendation from @gaspar
  • Loading branch information
clrudolphi committed Oct 4, 2024
1 parent 3a11a31 commit 44924c7
Show file tree
Hide file tree
Showing 29 changed files with 460 additions and 166 deletions.
6 changes: 6 additions & 0 deletions Reqnroll.Generator/DefaultDependencyProvider.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Reqnroll.BoDi;
using Reqnroll.Configuration;
using Reqnroll.CucumberMessages.Configuration;
using Reqnroll.EnvironmentAccess;
using Reqnroll.Generator.Configuration;
using Reqnroll.Generator.Generation;
using Reqnroll.Generator.Interfaces;
Expand All @@ -10,6 +12,7 @@
using Reqnroll.Plugins;
using Reqnroll.Tracing;
using Reqnroll.Utils;
using System.IO;

namespace Reqnroll.Generator
{
Expand Down Expand Up @@ -46,6 +49,9 @@ public virtual void RegisterDefaults(ObjectContainer container)

container.RegisterTypeAs<ConfigurationLoader, IConfigurationLoader>();

container.RegisterTypeAs<EnvironmentWrapper, IEnvironmentWrapper>();
container.RegisterTypeAs<CucumberConfiguration, ICucumberConfiguration>();

container.RegisterTypeAs<ReqnrollGherkinParserFactory, IGherkinParserFactory>();

container.RegisterTypeAs<ReqnrollJsonLocator, IReqnrollJsonLocator>();
Expand Down
4 changes: 2 additions & 2 deletions Reqnroll.Generator/Generation/GeneratorConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public class GeneratorConstants
public const string SCENARIO_TAGS_VARIABLE_NAME = "tagsOfScenario";
public const string SCENARIO_ARGUMENTS_VARIABLE_NAME = "argumentsOfScenario";
public const string FEATURE_TAGS_VARIABLE_NAME = "featureTags";
public const string PICKLEINDEX_PARAMETER_NAME = "generatedParameter_pickleIndex";
public const string PICKLEINDEX_PARAMETER_NAME = "__pickleIndex";
public const string PICKLEINDEX_VARIABLE_NAME = "m_pickleIndex";
public const string PICKLESTEPSEQUENCE_VARIABLE_NAME = "m_pickleStepSequence";
public const string PICKLESTEPSEQUENCE_PARAMETER_NAME = "pickleStepSequence";
public const string PICKLESTEPSEQUENCE_PARAMETER_NAME = "__pickleStepSequence";
}
}
1 change: 0 additions & 1 deletion Reqnroll.Generator/Generation/UnitTestFeatureGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ private void PersistStaticCucumberMessagesToFeatureInfo(TestClassGenerationConte
{
sourceFileLocation = Path.Combine(generationContext.Document.DocumentLocation.FeatureFolderPath, generationContext.Document.DocumentLocation.SourceFilePath);
//Generate Feature level Cucumber Messages, serialize them to strings, create a FeatureLevelCucumberMessages object and add it to featureInfo
//TODO: make the type of IDGenerator configurable
var IDGenStyle = _cucumberConfiguration.IDGenerationStyle;
var messageConverter = new CucumberMessagesConverter(IdGeneratorFactory.Create(IDGenStyle));
var featureSourceMessage = messageConverter.ConvertToCucumberMessagesSource(generationContext.Document);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Reqnroll.CucumberMessages.Configuration
{
public class CucumberConfiguration : ICucumberConfiguration
{
public static CucumberConfiguration Current { get; private set; }
public bool Enabled => _enablementOverrideFlag && _resolvedConfiguration.Value.Enabled;
public string BaseDirectory => _resolvedConfiguration.Value.BaseDirectory;
public string OutputDirectory => _resolvedConfiguration.Value.OutputDirectory;
Expand All @@ -29,6 +30,7 @@ public CucumberConfiguration(ITraceListener traceListener, IEnvironmentWrapper e
_trace = traceListener;
_environmentWrapper = environmentWrapper;
_resolvedConfiguration = new Lazy<ResolvedConfiguration>(ResolveConfiguration);
Current = this;
}

#region Override API
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ public interface ICucumberConfiguration
{
bool Enabled { get; }
string BaseDirectory { get; }
public string OutputDirectory { get; }
public string OutputFileName { get; }
public IDGenerationStyle IDGenerationStyle { get; }
string OutputDirectory { get; }
string OutputFileName { get; }
IDGenerationStyle IDGenerationStyle { get; }
}
}
5 changes: 5 additions & 0 deletions Reqnroll/CucumberMessages/ExecutionTracking/FeatureTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class FeatureTracker
internal Dictionary<string, string> StepDefinitionsByPattern = new();
public string FeatureName { get; set; }
public bool Enabled { get; private set; }
public Dictionary<string, string> PickleIds { get; } = new();

public FeatureTracker(FeatureStartedEvent featureStartedEvent)
{
Expand Down Expand Up @@ -57,6 +58,10 @@ private IEnumerable<Envelope> GenerateStaticMessages(FeatureStartedEvent feature

string lastID = ExtractLastID(pickles);
IDGenerator = IdGeneratorFactory.Create(lastID);
for(int i = 0; i < pickles.Count; i++)
{
PickleIds.Add(i.ToString(), pickles[i].Id);
}

foreach (var pickle in pickles)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Io.Cucumber.Messages.Types;
using Reqnroll.CucumberMessages.PayloadProcessing.Cucumber;
using Reqnroll.Events;
using System.Collections.Generic;
using System.Linq;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Gherkin.CucumberMessages;
using Io.Cucumber.Messages.Types;
using Reqnroll.Bindings;
using Reqnroll.CucumberMessages.PayloadProcessing.Cucumber;
using Reqnroll.CucumberMessages.RuntimeSupport;
using Reqnroll.Events;
using System;
Expand All @@ -23,15 +24,18 @@ public TestCaseCucumberMessageTracker(FeatureTracker featureTracker)
Enabled = featureTracker.Enabled;
IDGenerator = featureTracker.IDGenerator;
StepDefinitionsByPattern = featureTracker.StepDefinitionsByPattern;
PickleIdList = featureTracker.PickleIds;
}

// Feature FeatureInfo and Pickle ID make up a unique identifier for tracking execution of Test Cases
public string FeatureName { get; set; }
public string PickleId { get; set; } = string.Empty;
public string TestCaseTrackerId { get { return FeatureName + PickleId; } }
public string TestCaseTrackerId { get { return FeatureName +@"/" + PickleId; } }
public string TestCaseId { get; set; }
public string TestCaseStartedId { get; private set; }

private readonly Dictionary<string, string> PickleIdList;

// When this class is first created (on FeatureStarted), it will not yet be assigned a Scenario/Pickle;
// When a Scenario is started, the Publisher will assign the Scenario to the first UnAssigned TestCaseCucumberMessageTracker it finds
// This property will indicate that state
Expand Down Expand Up @@ -164,7 +168,7 @@ internal IEnumerable<Envelope> PostProcessEvent(FeatureFinishedEvent featureFini

internal void PreProcessEvent(ScenarioStartedEvent scenarioStartedEvent)
{
PickleId = scenarioStartedEvent.ScenarioContext.ScenarioInfo.PickleId;
PickleId = PickleIdList[scenarioStartedEvent.ScenarioContext.ScenarioInfo.PickleIdIndex];
scenarioStartedEvent.FeatureContext.FeatureInfo.CucumberMessages_TestCaseTrackerId = TestCaseTrackerId;
TestCaseId = IDGenerator.GetNewId();
TestCaseStartedId = IDGenerator.GetNewId();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Io.Cucumber.Messages.Types;
using Reqnroll.Assist;
using Reqnroll.Bindings;
using Reqnroll.CucumberMessages.PayloadProcessing.Cucumber;
using Reqnroll.Events;
using System;
using System.Collections.Generic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Reqnroll.Analytics;
using Reqnroll.Bindings;
using Reqnroll.CommonModels;
using Reqnroll.CucumberMessages.ExecutionTracking;
using Reqnroll.CucumberMessages.PayloadProcessing;
using Reqnroll.CucumberMessages.RuntimeSupport;
using Reqnroll.EnvironmentAccess;
Expand All @@ -17,8 +18,13 @@
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;

namespace Reqnroll.CucumberMessages.ExecutionTracking
namespace Reqnroll.CucumberMessages.PayloadProcessing.Cucumber
{
/// <summary>
/// This class provides functions to convert execution level detail (events) into Cucumber message elements
///
/// These are called after execution is completed for a Feature.
/// </summary>
internal class CucumberMessageFactory
{
public static TestRunStarted ToTestRunStarted(FeatureStartedEvent featureStartedEvent)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using Gherkin.CucumberMessages;
using Gherkin.CucumberMessages.Types;
using Reqnroll.CucumberMessages.Configuration;
using Reqnroll.CucumberMessages.RuntimeSupport;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Reqnroll.CucumberMessages.PayloadProcessing.Gherkin
{
internal class GherkinDocumentIDStyleReWriter : GherkinTypesGherkinDocumentVisitor
{
private IIdGenerator _idGenerator;
public Dictionary<string, string> IdMap = new();

public GherkinDocument ReWriteIds(GherkinDocument document, IDGenerationStyle targetStyle)
{
var existingIdStyle = ProbeForIdGenerationStyle(document);

if (existingIdStyle == targetStyle)
return document;

_idGenerator = IdGeneratorFactory.Create(targetStyle);

AcceptDocument(document);
return document;
}

private IDGenerationStyle ProbeForIdGenerationStyle(GherkinDocument document)
{
if (document.Feature == null) return IDGenerationStyle.UUID;
var child = document.Feature.Children.FirstOrDefault();
if (child == null) return IDGenerationStyle.UUID;

if (child.Rule != null)
return ParseStyle(child.Rule.Id);

if (child.Background != null)
return ParseStyle(child.Background.Id);

if (child.Scenario != null)
return ParseStyle(child.Scenario.Id);

return IDGenerationStyle.UUID;
}

private IDGenerationStyle ParseStyle(string id)
{
if (Guid.TryParse(id, out var _))
return IDGenerationStyle.UUID;

return IDGenerationStyle.Incrementing;
}

protected override void OnTagVisited(Tag tag)
{
base.OnTagVisited(tag);
var oldId = tag.Id;
var newId = _idGenerator.GetNewId();
IdMap[oldId] = newId;
tag.Id = newId;
}
protected override void OnScenarioOutlineVisited(Scenario scenarioOutline)
{
base.OnScenarioOutlineVisited(scenarioOutline);
var oldId = scenarioOutline.Id;
var newId = _idGenerator.GetNewId();
IdMap[oldId] = newId;
scenarioOutline.Id = newId;
}

protected override void OnScenarioVisited(Scenario scenario)
{
base.OnScenarioVisited(scenario);
var oldId = scenario.Id;
var newId = _idGenerator.GetNewId();
IdMap[oldId] = newId;
scenario.Id = newId;
}

protected override void OnRuleVisited(Rule rule)
{
base.OnRuleVisited(rule);
var oldId = rule.Id;
var newId = _idGenerator.GetNewId();
IdMap[oldId] = newId;
rule.Id = newId;
}
protected override void OnBackgroundVisited(Background background)
{
base.OnBackgroundVisited(background);
var oldId = background.Id;
var newId = _idGenerator.GetNewId();
IdMap[oldId] = newId;
background.Id = newId;

}
protected override void OnStepVisited(Step step)
{
base.OnStepVisited(step);
var oldId = step.Id;
var newId = _idGenerator.GetNewId();
IdMap[oldId] = newId;
step.Id = newId;
}
protected override void OnExamplesVisited(Examples examples)
{
base.OnExamplesVisited(examples);
var oldId = examples.Id;
var newId = _idGenerator.GetNewId();
IdMap[oldId] = newId;
examples.Id = newId;
}
protected override void OnTableHeaderVisited(TableRow header)
{
base.OnTableHeaderVisited(header);
var oldId = header.Id;
var newId = _idGenerator.GetNewId();
IdMap[oldId] = newId;
header.Id = newId;
}
protected override void OnTableRowVisited(TableRow row)
{
base.OnTableRowVisited(row);
var oldId = row.Id;
var newId = _idGenerator.GetNewId();
IdMap[oldId] = newId;
row.Id = newId;
}
}
}
Loading

0 comments on commit 44924c7

Please sign in to comment.