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);
}
}
}