Skip to content

Commit

Permalink
Merge branch 'master' into gherkin-parser
Browse files Browse the repository at this point in the history
Conflicts:
	TechTalk.SpecFlow.sln
  • Loading branch information
gasparnagy committed May 5, 2010
2 parents 065dfd3 + 8b8d456 commit 1a62c53
Show file tree
Hide file tree
Showing 143 changed files with 4,765 additions and 5,158 deletions.
162 changes: 162 additions & 0 deletions Generator/CodeDomHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace TechTalk.SpecFlow.Generator
{
public enum GenerationTargetLanguage
{
CSharp,
VB,
Other
}

public interface ICodeDomHelperRequired
{
CodeDomHelper CodeDomHelper { get; set; }
}

public class CodeDomHelper
{
public GenerationTargetLanguage TargetLanguage { get; private set; }

public CodeDomHelper(CodeDomProvider codeComProvider)
{
switch (codeComProvider.FileExtension.ToLower(CultureInfo.InvariantCulture))
{
case "cs":
TargetLanguage = GenerationTargetLanguage.CSharp;
break;
case "vb":
TargetLanguage = GenerationTargetLanguage.VB;
break;
default:
TargetLanguage = GenerationTargetLanguage.Other;
break;
}
}

public CodeDomHelper(GenerationTargetLanguage targetLanguage)
{
TargetLanguage = targetLanguage;
}

public CodeTypeReference CreateNestedTypeReference(CodeTypeDeclaration baseTypeDeclaration, string nestedTypeName)
{
return new CodeTypeReference(baseTypeDeclaration.Name + "." + nestedTypeName);
}

public void SetTypeReferenceAsInterface(CodeTypeReference typeReference)
{
// this hack is necessary for VB.NET code generation

if (TargetLanguage == GenerationTargetLanguage.VB)
{
var isInterfaceField = typeReference.GetType().GetField("isInterface",
BindingFlags.Instance | BindingFlags.NonPublic);
if (isInterfaceField == null)
throw new InvalidOperationException("CodeDom version does not support VB.NET generation.");

isInterfaceField.SetValue(typeReference, true);
}
}

public void InjectIfRequired(object target)
{
ICodeDomHelperRequired codeDomHelperRequired = target as ICodeDomHelperRequired;
if (codeDomHelperRequired != null)
codeDomHelperRequired.CodeDomHelper = this;
}

public void AddCommentStatement(CodeStatementCollection statements, string comment)
{
switch (TargetLanguage)
{
case GenerationTargetLanguage.CSharp:
statements.Add(new CodeSnippetStatement("//" + comment));
break;
case GenerationTargetLanguage.VB:
statements.Add(new CodeSnippetStatement("'" + comment));
break;
}
}

public void BindTypeToSourceFile(CodeTypeDeclaration typeDeclaration, string fileName)
{
switch (TargetLanguage)
{
case GenerationTargetLanguage.CSharp:
typeDeclaration.Members.Add(new CodeSnippetTypeMember(string.Format("#line 1 \"{0}\"", fileName)));
typeDeclaration.Members.Add(new CodeSnippetTypeMember("#line hidden"));
break;
}
}

public void AddSourceLinePragmaStatement(CodeStatementCollection statements, int lineNo, int colNo)
{
switch (TargetLanguage)
{
case GenerationTargetLanguage.CSharp:
statements.Add(new CodeSnippetStatement(string.Format("#line {0}", lineNo)));
AddCommentStatement(statements, string.Format("#indentnext {0}", colNo - 1));
break;
}
}

public void AddDisableSourceLinePragmaStatement(CodeStatementCollection statements)
{
switch (TargetLanguage)
{
case GenerationTargetLanguage.CSharp:
statements.Add(new CodeSnippetStatement("#line hidden"));
break;
}
}

public CodeStatement GetStartRegionStatement(string regionText)
{
switch (TargetLanguage)
{
case GenerationTargetLanguage.CSharp:
return new CodeSnippetStatement("#region " + regionText);
case GenerationTargetLanguage.VB:
return new CodeSnippetStatement("#Region \"" + regionText + "\"");
}
return new CodeCommentStatement("#region " + regionText);
}

public CodeStatement GetEndRegionStatement()
{
switch (TargetLanguage)
{
case GenerationTargetLanguage.CSharp:
return new CodeSnippetStatement("#endregion");
case GenerationTargetLanguage.VB:
return new CodeSnippetStatement("#End Region");
}
return new CodeCommentStatement("#endregion");
}

private Version GetCurrentSpecFlowVersion()
{
return Assembly.GetExecutingAssembly().GetName().Version;
}

public CodeTypeDeclaration CreateGeneratedTypeDeclaration(string className)
{
var result = new CodeTypeDeclaration(className);
result.CustomAttributes.Add(
new CodeAttributeDeclaration(
new CodeTypeReference(typeof(GeneratedCodeAttribute)),
new CodeAttributeArgument(new CodePrimitiveExpression("TechTalk.SpecFlow")),
new CodeAttributeArgument(new CodePrimitiveExpression(GetCurrentSpecFlowVersion().ToString()))));
result.CustomAttributes.Add(
new CodeAttributeDeclaration(
new CodeTypeReference(typeof(CompilerGeneratedAttribute))));
return result;
}
}
}
15 changes: 8 additions & 7 deletions Generator/Configuration/GeneratorConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ public class GeneratorConfiguration

// generator settings
public bool AllowDebugGeneratedFiles { get; set; }

public GeneratorConfiguration()
{
FeatureLanguage = CultureInfo.GetCultureInfo(ConfigDefaults.FeatureLanguage);
ToolLanguage = string.IsNullOrEmpty(ConfigDefaults.ToolLanguage) ?
FeatureLanguage :
CultureInfo.GetCultureInfo(ConfigDefaults.ToolLanguage);
ToolLanguage = string.IsNullOrEmpty(ConfigDefaults.ToolLanguage) ? FeatureLanguage :
CultureInfo.GetCultureInfo(ConfigDefaults.ToolLanguage);

SetUnitTestDefaultsByName(ConfigDefaults.UnitTestProviderName);

Expand All @@ -37,9 +36,8 @@ internal void UpdateFromConfigFile(ConfigurationSectionHandler configSection)
if (configSection.Language != null)
{
FeatureLanguage = CultureInfo.GetCultureInfo(configSection.Language.Feature);
ToolLanguage = string.IsNullOrEmpty(configSection.Language.Tool) ?
FeatureLanguage :
CultureInfo.GetCultureInfo(configSection.Language.Tool);
ToolLanguage = string.IsNullOrEmpty(configSection.Language.Tool) ? FeatureLanguage :
CultureInfo.GetCultureInfo(configSection.Language.Tool);
}

if (configSection.UnitTestProvider != null)
Expand Down Expand Up @@ -71,6 +69,9 @@ private void SetUnitTestDefaultsByName(string name)
case "nunit":
GeneratorUnitTestProviderType = typeof(NUnitTestConverter);
break;
case "xunit":
GeneratorUnitTestProviderType = typeof(XUnitTestGeneratorProvider);
break;
case "mstest":
GeneratorUnitTestProviderType = typeof(MsTestGeneratorProvider);
break;
Expand Down
24 changes: 18 additions & 6 deletions Generator/SpecFlowGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.CSharp;
using TechTalk.SpecFlow.Configuration;
using TechTalk.SpecFlow.Generator.Configuration;
using TechTalk.SpecFlow.Generator.UnitTestConverter;
using TechTalk.SpecFlow.Generator.UnitTestProvider;
using TechTalk.SpecFlow.Parser;
using TechTalk.SpecFlow.Parser.SyntaxElements;
Expand Down Expand Up @@ -77,7 +78,7 @@ public override Encoding Encoding
get { return innerWriter.Encoding; }
}

static public readonly Regex indentNextRe = new Regex(@"^[\s\/\']*#indentnext (?<ind>\d+)\s*$");
static private readonly Regex indentNextRe = new Regex(@"^[\s\/\']*#indentnext (?<ind>\d+)\s*$");

public override void WriteLine(string text)
{
Expand Down Expand Up @@ -114,27 +115,31 @@ public void GenerateTestFile(SpecFlowFeatureFile featureFile, CodeDomProvider co
{
outputWriter = new HackedWriter(outputWriter);

var codeNamespace = GenerateTestFileCode(featureFile, inputReader);
CodeDomHelper codeDomHelper = new CodeDomHelper(codeProvider);

var codeNamespace = GenerateTestFileCode(featureFile, inputReader, codeProvider, codeDomHelper);
var options = new CodeGeneratorOptions
{
BracingStyle = "C"
};

AddSpecFlowHeader(codeProvider, outputWriter);
AddSpecFlowHeader(codeProvider, outputWriter, codeDomHelper);
codeProvider.GenerateCodeFromNamespace(codeNamespace, outputWriter, options);
AddSpecFlowFooter(codeProvider, outputWriter, codeDomHelper);
outputWriter.Flush();
}

public CodeNamespace GenerateTestFileCode(SpecFlowFeatureFile featureFile, TextReader inputReader)
public CodeNamespace GenerateTestFileCode(SpecFlowFeatureFile featureFile, TextReader inputReader, CodeDomProvider codeProvider, CodeDomHelper codeDomHelper)
{
string targetNamespace = GetTargetNamespace(featureFile);

SpecFlowLangParser parser = new SpecFlowLangParser(project.GeneratorConfiguration.FeatureLanguage);
Feature feature = parser.Parse(inputReader, featureFile.GetFullPath(project));

IUnitTestGeneratorProvider generatorProvider = ConfigurationServices.CreateInstance<IUnitTestGeneratorProvider>(project.GeneratorConfiguration.GeneratorUnitTestProviderType);
codeDomHelper.InjectIfRequired(generatorProvider);

SpecFlowUnitTestConverter testConverter = new SpecFlowUnitTestConverter(generatorProvider, project.GeneratorConfiguration.AllowDebugGeneratedFiles);
ISpecFlowUnitTestConverter testConverter = new SpecFlowUnitTestConverter(generatorProvider, codeDomHelper, project.GeneratorConfiguration.AllowDebugGeneratedFiles);

var codeNamespace = testConverter.GenerateUnitTestFixture(feature, null, targetNamespace);
return codeNamespace;
Expand Down Expand Up @@ -164,7 +169,7 @@ private string GetTargetNamespace(SpecFlowFeatureFile featureFile)
return targetNamespace;
}

private void AddSpecFlowHeader(CodeDomProvider codeProvider, TextWriter outputWriter)
private void AddSpecFlowHeader(CodeDomProvider codeProvider, TextWriter outputWriter, CodeDomHelper codeDomHelper)
{
var specFlowHeaderTemplate = @"------------------------------------------------------------------------------
<auto-generated>
Expand All @@ -187,6 +192,13 @@ the code is regenerated.
{
codeProvider.GenerateCodeFromStatement(new CodeCommentStatement(line), outputWriter, null);
}

codeProvider.GenerateCodeFromStatement(codeDomHelper.GetStartRegionStatement("Designer generated code"), outputWriter, null);
}

private void AddSpecFlowFooter(CodeDomProvider codeProvider, TextWriter outputWriter, CodeDomHelper codeDomHelper)
{
codeProvider.GenerateCodeFromStatement(codeDomHelper.GetEndRegionStatement(), outputWriter, null);
}

public Version GetCurrentSpecFlowVersion()
Expand Down
Loading

0 comments on commit 1a62c53

Please sign in to comment.