Created
October 2, 2012 23:51
-
-
Save kpol/3824076 to your computer and use it in GitHub Desktop.
SpecFlow custom generator plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.CodeDom; | |
using System.Collections.Generic; | |
using System.Linq; | |
using BoDi; | |
using TechTalk.SpecFlow.Generator; | |
using TechTalk.SpecFlow.Generator.Configuration; | |
using TechTalk.SpecFlow.Generator.Plugins; | |
using TechTalk.SpecFlow.Generator.UnitTestConverter; | |
using TechTalk.SpecFlow.Generator.UnitTestProvider; | |
using TechTalk.SpecFlow.Parser.SyntaxElements; | |
using TechTalk.SpecFlow.Utils; | |
// [assembly: TechTalk.SpecFlow.Infrastructure.GeneratorPlugin(typeof(CodeGenerator.Generator.SpecFlowPlugin.TagGeneratorPlugin))] | |
namespace CodeGenerator.Generator.SpecFlowPlugin | |
{ | |
public class TagGeneratorPlugin : IGeneratorPlugin | |
{ | |
public void RegisterConfigurationDefaults(SpecFlowProjectConfiguration specFlowConfiguration) | |
{ | |
} | |
public void RegisterCustomizations(ObjectContainer container, SpecFlowProjectConfiguration generatorConfiguration) | |
{ | |
} | |
public void RegisterDependencies(ObjectContainer container) | |
{ | |
container.RegisterTypeAs<TagFeatureGeneratorProvider, IFeatureGeneratorProvider>("default"); | |
} | |
} | |
public class TagFeatureGeneratorProvider : IFeatureGeneratorProvider | |
{ | |
private readonly ObjectContainer _container; | |
public TagFeatureGeneratorProvider(ObjectContainer container) | |
{ | |
_container = container; | |
} | |
public int Priority | |
{ | |
get { return int.MaxValue; } | |
} | |
public bool CanGenerate(Feature feature) | |
{ | |
return true; | |
} | |
public IFeatureGenerator CreateGenerator(Feature feature) | |
{ | |
return _container.Resolve<TagFeatureGenerator>(); | |
} | |
} | |
public class TagFeatureGenerator : IFeatureGenerator | |
{ | |
private const string UserAgent = "user-agent"; | |
private readonly UnitTestFeatureGenerator _unitTestFeatureGenerator; | |
public TagFeatureGenerator(IUnitTestGeneratorProvider testGeneratorProvider, CodeDomHelper codeDomHelper, GeneratorConfiguration generatorConfiguration, IDecoratorRegistry decoratorRegistry) | |
{ | |
_unitTestFeatureGenerator = new UnitTestFeatureGenerator(testGeneratorProvider, codeDomHelper, generatorConfiguration, decoratorRegistry); | |
} | |
public CodeNamespace GenerateUnitTestFixture(Feature feature, string testClassName, string targetNamespace) | |
{ | |
if (feature.Scenarios != null) | |
{ | |
feature.Scenarios = feature.Scenarios | |
.Where(s => s.Tags == null || s.Tags.Count(PatternPredicate) < 2) | |
.Concat(GetUserAgentsScenarios(feature)).ToArray(); | |
} | |
return _unitTestFeatureGenerator.GenerateUnitTestFixture(feature, testClassName, targetNamespace); | |
} | |
private static IEnumerable<Scenario> GetUserAgentsScenarios(Feature feature) | |
{ | |
var scenariosWithMultiple = | |
feature.Scenarios.Where(s => s.Tags != null && s.Tags.Count(PatternPredicate) > 1); | |
foreach (var scenario in scenariosWithMultiple) | |
{ | |
if (string.IsNullOrEmpty(scenario.Title)) | |
{ | |
throw new TestGeneratorException("The scenario must have a title specified."); | |
} | |
int index = 0; | |
foreach (var tag in scenario.Tags.Where(PatternPredicate)) | |
{ | |
var newScenario = CopyScenario(scenario, tag, index++); | |
yield return newScenario; | |
} | |
} | |
} | |
private static Scenario CopyScenario(Scenario scenario, Tag userAgentTag, int index) | |
{ | |
var title = string.Concat(scenario.Title, userAgentTag.Name, index); | |
var tags = new Tags(scenario.Tags.Where(t => !PatternPredicate(t)).Concat(new[] { userAgentTag }).ToArray()); | |
var steps = new ScenarioSteps(scenario.Steps.Select(step => step.Clone()).ToArray()); | |
var scenarioOutline = scenario as ScenarioOutline; | |
if (scenarioOutline != null) | |
{ | |
return new ScenarioOutline(scenario.Keyword, title, scenario.Description, tags, steps, | |
new Examples(scenarioOutline.Examples.ExampleSets)); | |
} | |
return new Scenario(scenario.Keyword, title, scenario.Description, tags, steps); | |
} | |
private static bool PatternPredicate(Tag tag) | |
{ | |
if (tag == null || tag.Name == null) | |
{ | |
return false; | |
} | |
return tag.Name.StartsWith(UserAgent, StringComparison.OrdinalIgnoreCase); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks, mate :)