Skip to content

Commit

Permalink
first version of line pragmas
Browse files Browse the repository at this point in the history
  • Loading branch information
gasparnagy committed Nov 24, 2009
1 parent 2c43124 commit 3e3515b
Show file tree
Hide file tree
Showing 12 changed files with 443 additions and 305 deletions.
5 changes: 5 additions & 0 deletions Parser/Configuration/GeneratorConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public class GeneratorConfiguration

//unit test framework settings
public Type GeneratorUnitTestProviderType { get; set; }

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

public GeneratorConfiguration()
{
Expand All @@ -23,6 +26,8 @@ public GeneratorConfiguration()
CultureInfo.GetCultureInfo(ConfigDefaults.ToolLanguage);

SetUnitTestDefaultsByName(ConfigDefaults.UnitTestProviderName);

AllowDebugGeneratedFiles = ConfigDefaults.AllowDebugGeneratedFiles;
}

internal void UpdateFromConfigFile(ConfigurationSectionHandler configSection)
Expand Down
593 changes: 300 additions & 293 deletions Parser/Grammar/SpecFlowLangWalker.cs

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion Parser/Grammar/SpecFlowLangWalker.g
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ options {
language = CSharp2;
tokenVocab = SpecFlowLangParser;
ASTLabelType = CommonTree;
superClass = SpecFlowLangWalkerBase;
}

@namespace { TechTalk.SpecFlow.Parser.Grammar }
Expand Down Expand Up @@ -73,10 +74,18 @@ descriptionLine returns[DescriptionLine descriptionLine]
;

background returns[Background background]
@init {
FilePosition fp_ = null;
}
@after {
$background = new Background(title_, steps_);
$background.FilePosition = fp_;
}
: ^(BACKGROUND
:
{
fp_ = GetFilePosition();
}
^(BACKGROUND
(title_=text)?
steps_=steps
)
Expand Down
26 changes: 26 additions & 0 deletions Parser/Grammar/SpecFlowLangWalkerBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antlr.Runtime;
using Antlr.Runtime.Tree;
using TechTalk.SpecFlow.Parser.SyntaxElements;

namespace TechTalk.SpecFlow.Parser.Grammar
{
public abstract class SpecFlowLangWalkerBase : TreeParser
{
protected SpecFlowLangWalkerBase(ITreeNodeStream input) : base(input)
{
}

protected SpecFlowLangWalkerBase(ITreeNodeStream input, RecognizerSharedState state) : base(input, state)
{
}

protected FilePosition GetFilePosition()
{
return new FilePosition(((ITree)input.LT(1)).Line, ((ITree)input.LT(1)).CharPositionInLine);
}
}
}
2 changes: 1 addition & 1 deletion Parser/SpecFlowGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public CodeCompileUnit GenerateTestFileCode(string featureFileName, string conte

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

SpecFlowUnitTestConverter testConverter = new SpecFlowUnitTestConverter(generatorProvider);
SpecFlowUnitTestConverter testConverter = new SpecFlowUnitTestConverter(generatorProvider, project.GeneratorConfiguration.AllowDebugGeneratedFiles);
CodeCompileUnit codeCompileUnit = testConverter.GenerateUnitTestFixture(feature, null, targetNamespace);

return codeCompileUnit;
Expand Down
73 changes: 66 additions & 7 deletions Parser/SpecFlowUnitTestConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.CodeDom;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
Expand Down Expand Up @@ -31,10 +32,12 @@ public class SpecFlowUnitTestConverter
private const string SPECFLOW_NAMESPACE = "TechTalk.SpecFlow";

private readonly IUnitTestGeneratorProvider testGeneratorProvider;
private readonly bool allowDebugGeneratedFiles;

public SpecFlowUnitTestConverter(IUnitTestGeneratorProvider testGeneratorProvider)
public SpecFlowUnitTestConverter(IUnitTestGeneratorProvider testGeneratorProvider, bool allowDebugGeneratedFiles)
{
this.testGeneratorProvider = testGeneratorProvider;
this.allowDebugGeneratedFiles = allowDebugGeneratedFiles;
}

public CodeCompileUnit GenerateUnitTestFixture(Feature feature, string testClassName, string targetNamespace)
Expand All @@ -43,6 +46,7 @@ public CodeCompileUnit GenerateUnitTestFixture(Feature feature, string testClass
testClassName = testClassName ?? string.Format(FIXTURE_FORMAT, feature.Title.ToIdentifier());

CodeCompileUnit codeCompileUnit = new CodeCompileUnit();

CodeNamespace codeNamespace = new CodeNamespace(targetNamespace);
codeCompileUnit.Namespaces.Add(codeNamespace);

Expand All @@ -53,6 +57,8 @@ public CodeCompileUnit GenerateUnitTestFixture(Feature feature, string testClass
testType.TypeAttributes |= TypeAttributes.Public;
codeNamespace.Types.Add(testType);

AddLinePragmaInitial(testType, feature);

testGeneratorProvider.SetTestFixture(testType, feature.Title, feature.Description);
if (feature.Tags != null)
{
Expand Down Expand Up @@ -92,7 +98,6 @@ private void DeclareTestRunnerMember(CodeTypeDeclaration testType)
private CodeExpression GetTestRunnerExpression()
{
return new CodeVariableReferenceExpression(TESTRUNNER_FIELD);
//return new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), TESTRUNNER_FIELD);
}

private IEnumerable<string> GetNonIgnoreTags(IEnumerable<Tag> tags)
Expand Down Expand Up @@ -238,9 +243,13 @@ private void GenerateBackground(CodeTypeDeclaration testType, CodeMemberMethod t
backgroundMethod.Attributes = MemberAttributes.Public;
backgroundMethod.Name = BACKGROUND_NAME;

AddLineDirective(backgroundMethod.Statements, background);

foreach (var given in background.Steps)
GenerateStep(backgroundMethod, given, null);

AddLineDirectiveHidden(backgroundMethod.Statements);

testSetup.Statements.Add(
new CodeMethodInvokeExpression(
new CodeThisReferenceExpression(),
Expand Down Expand Up @@ -283,7 +292,7 @@ private void GenerateScenarioOutlineTest(CodeTypeDeclaration testType, CodeMembe
//TODO: check params
}

GenerateScenarioOutlineBody(scenarioOutline, paramToIdentifier, testType, testMethodName, testSetup);
GenerateScenarioOutlineBody(feature, scenarioOutline, paramToIdentifier, testType, testMethodName, testSetup);

int exampleSetIndex = 0;
foreach (var exampleSet in scenarioOutline.Examples.ExampleSets)
Expand Down Expand Up @@ -311,7 +320,7 @@ private bool CanUseFirstColumnAsName(Table table)
return table.Body.Select(r => r.Cells[0].Value.ToIdentifier()).Distinct().Count() == table.Body.Length;
}

private void GenerateScenarioOutlineBody(ScenarioOutline scenarioOutline, ParameterSubstitution paramToIdentifier, CodeTypeDeclaration testType, string testMethodName, CodeMemberMethod testSetup)
private void GenerateScenarioOutlineBody(Feature feature, ScenarioOutline scenarioOutline, ParameterSubstitution paramToIdentifier, CodeTypeDeclaration testType, string testMethodName, CodeMemberMethod testSetup)
{
CodeMemberMethod testMethod = new CodeMemberMethod();
testType.Members.Add(testMethod);
Expand All @@ -324,7 +333,7 @@ private void GenerateScenarioOutlineBody(ScenarioOutline scenarioOutline, Parame
testMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof (string), pair.Value));
}

GenerateTestBody(scenarioOutline, testMethod, testSetup, paramToIdentifier);
GenerateTestBody(feature, scenarioOutline, testMethod, testSetup, paramToIdentifier);
}

private void GenerateScenarioOutlineTestVariant(CodeTypeDeclaration testType, ScenarioOutline scenarioOutline, string testMethodName, List<KeyValuePair<string, string>> paramToIdentifier, string exampleSetTitle, Row row, string variantName)
Expand All @@ -350,10 +359,10 @@ private void GenerateScenarioOutlineTestVariant(CodeTypeDeclaration testType, Sc
private void GenerateTest(CodeTypeDeclaration testType, CodeMemberMethod testSetup, Scenario scenario, Feature feature)
{
CodeMemberMethod testMethod = GetTestMethodDeclaration(testType, scenario);
GenerateTestBody(scenario, testMethod, testSetup, null);
GenerateTestBody(feature, scenario, testMethod, testSetup, null);
}

private void GenerateTestBody(Scenario scenario, CodeMemberMethod testMethod, CodeMemberMethod testSetup, ParameterSubstitution paramToIdentifier)
private void GenerateTestBody(Feature feature, Scenario scenario, CodeMemberMethod testMethod, CodeMemberMethod testSetup, ParameterSubstitution paramToIdentifier)
{
//call test setup
//ScenarioInfo scenarioInfo = new ScenarioInfo("xxxx", tags...);
Expand All @@ -363,6 +372,7 @@ private void GenerateTestBody(Scenario scenario, CodeMemberMethod testMethod, Co
new CodePrimitiveExpression(scenario.Title),
GetStringArrayExpression(scenario.Tags))));

AddLineDirective(testMethod.Statements, scenario);
testMethod.Statements.Add(
new CodeMethodInvokeExpression(
new CodeThisReferenceExpression(),
Expand All @@ -374,6 +384,7 @@ private void GenerateTestBody(Scenario scenario, CodeMemberMethod testMethod, Co
GenerateStep(testMethod, scenarioStep, paramToIdentifier);
}

AddLineDirectiveHidden(testMethod.Statements);

// call collect errors
var testRunnerField = GetTestRunnerExpression();
Expand Down Expand Up @@ -453,12 +464,14 @@ private void GenerateStep(CodeMemberMethod testMethod, ScenarioStep scenarioStep
GetSubstitutedString(scenarioStep.Text, paramToIdentifier));
if (scenarioStep.MultiLineTextArgument != null || scenarioStep.TableArg != null)
{
AddLineDirectiveHidden(testMethod.Statements);
arguments.Add(
GetMultilineTextArgExpression(scenarioStep.MultiLineTextArgument, paramToIdentifier));
arguments.Add(
GetTableArgExpression(scenarioStep.TableArg, testMethod.Statements, paramToIdentifier));
}

AddLineDirective(testMethod.Statements, scenarioStep);
testMethod.Statements.Add(
new CodeMethodInvokeExpression(
testRunnerField,
Expand Down Expand Up @@ -498,5 +511,51 @@ private CodeExpression GetMultilineTextArgExpression(string multiLineTextArgumen
{
return GetSubstitutedString(multiLineTextArgument, paramToIdentifier);
}

#region Line pragma handling

private void AddLinePragmaInitial(CodeTypeDeclaration testType, Feature feature)
{
testType.Members.Add(new CodeSnippetTypeMember(string.Format("#line 1 \"{0}\"", feature.SourceFile)));
testType.Members.Add(new CodeSnippetTypeMember("#line hidden"));
}

private void AddLineDirectiveHidden(CodeStatementCollection statements)
{
if (allowDebugGeneratedFiles)
return;

statements.Add(new CodeSnippetStatement("#line hidden"));
}

private void AddLineDirective(CodeStatementCollection statements, Background background)
{
//AddLineDirective(statements, null, background.SourceFileLine);
}

private void AddLineDirective(CodeStatementCollection statements, Scenario scenario)
{
AddLineDirective(statements, null, scenario.SourceFileLine);
}

private void AddLineDirective(CodeStatementCollection statements, ScenarioStep step)
{
AddLineDirective(statements, null, step.SourceFileLine);
}

private void AddLineDirective(CodeStatementCollection statements, string sourceFile, int? sourceFileLine)
{
if (sourceFileLine == null || allowDebugGeneratedFiles)
return;

if (sourceFile == null)
statements.Add(new CodeSnippetStatement(
string.Format("#line {0}", sourceFileLine)));
else
statements.Add(new CodeSnippetStatement(
string.Format("#line {0} \"{1}\"", sourceFileLine, Path.GetFileName(sourceFile))));
}

#endregion
}
}
3 changes: 3 additions & 0 deletions Parser/SyntaxElements/Background.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Xml.Serialization;

namespace TechTalk.SpecFlow.Parser.SyntaxElements
{
Expand All @@ -8,6 +9,8 @@ public class Background
public string Title { get; set; }
public ScenarioSteps Steps { get; set; }

public FilePosition FilePosition { get; set; }

public Background()
{
}
Expand Down
24 changes: 24 additions & 0 deletions Parser/SyntaxElements/FilePosition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Linq;
using System.Xml.Serialization;

namespace TechTalk.SpecFlow.Parser.SyntaxElements
{
public class FilePosition
{
[XmlAttribute("line")]
public int Line;
[XmlAttribute("column")]
public int Column;

public FilePosition()
{
}

public FilePosition(int line, int column)
{
Line = line;
Column = column;
}
}
}
2 changes: 2 additions & 0 deletions Parser/TechTalk.SpecFlow.Parser.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
<Compile Include="Grammar\SpecFlowLangWalker.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Grammar\SpecFlowLangWalkerBase.cs" />
<Compile Include="SyntaxElements\FilePosition.cs" />
<Compile Include="UnitTestProvider\IUnitTestGeneratorProvider.cs" />
<Compile Include="SpecFlowGenerator.cs" />
<Compile Include="SpecFlowLangParser.cs" />
Expand Down
2 changes: 2 additions & 0 deletions Runtime/Configuration/ConfigurationSectionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public static class ConfigDefaults
internal const bool TraceSuccessfulSteps = true;
internal const bool TraceTimings = false;
internal const string MinTracedDuration = "0:0:0.1";

internal const bool AllowDebugGeneratedFiles = false;
}

partial class ConfigurationSectionHandler : ConfigurationSection
Expand Down
5 changes: 3 additions & 2 deletions Runtime/TestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,11 @@ public void OnScenarioStart(ScenarioInfo scenarioInfo)
FireScenarioEvents(BindingEvent.ScenarioStart);
}

//TODO: rename this method to OnAfterLastStep (breaking change in generation!)
public void CollectScenarioErrors()
{
HandleBlockSwitch(ScenarioBlock.None);

if (RuntimeConfiguration.Current.TraceTimings)
{
ObjectContainer.ScenarioContext.Stopwatch.Stop();
Expand Down Expand Up @@ -141,8 +144,6 @@ public void CollectScenarioErrors()

public void OnScenarioEnd()
{
HandleBlockSwitch(ScenarioBlock.None);

FireScenarioEvents(BindingEvent.ScenarioEnd);
ObjectContainer.ScenarioContext = null;
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/ParserTests/SuccessfulGenerationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ private void CompareWithExpectedResult(Feature feature, string expectedResultFil

private void GenerateCodeFromFeature(Feature feature, TextWriter writer)
{
SpecFlowUnitTestConverter converter = new SpecFlowUnitTestConverter(new NUnitTestConverter());
SpecFlowUnitTestConverter converter = new SpecFlowUnitTestConverter(new NUnitTestConverter(), true);
var compileUnit = converter.GenerateUnitTestFixture(feature, "TestClassName", "Target.Namespace");

CSharpCodeProvider codeProvider = new CSharpCodeProvider();
Expand Down

0 comments on commit 3e3515b

Please sign in to comment.