private int ProcessParams() { if (_params.Any()) { var paramSub = new ParameterSubstitution(); foreach (var param in _params) { paramSub.AddParameter(param.ParameterName, param.Value); } this.Aml = paramSub.Substitute(this.Aml, _conn.CoreConnection.AmlContext.LocalizationContext); return paramSub.ItemCount; } return 1; }
internal void GenerateTestMethodBody(TestClassGenerationContext generationContext, StepsContainer scenario, CodeMemberMethod testMethod, ParameterSubstitution paramToIdentifier, SpecFlowFeature feature) { var statementsWhenScenarioIsIgnored = new CodeStatement[] { new CodeExpressionStatement(CreateTestRunnerSkipScenarioCall()) }; var statementsWhenScenarioIsExecuted = new List <CodeStatement> { new CodeExpressionStatement( new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), generationContext.ScenarioStartMethod.Name)) }; if (generationContext.Feature.HasFeatureBackground()) { using (new SourceLineScope(_specFlowConfiguration, _codeDomHelper, statementsWhenScenarioIsExecuted, generationContext.Document.SourceFilePath, generationContext.Feature.Background.Location)) { statementsWhenScenarioIsExecuted.Add(new CodeExpressionStatement( new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), generationContext.FeatureBackgroundMethod.Name))); } } foreach (var scenarioStep in scenario.Steps) { _scenarioPartHelper.GenerateStep(generationContext, statementsWhenScenarioIsExecuted, scenarioStep, paramToIdentifier); } var isScenarioIgnoredVariable = new CodeVariableDeclarationStatement(typeof(bool), "isScenarioIgnored", new CodeDefaultValueExpression(new CodeTypeReference(typeof(bool)))); var isFeatureIgnoredVariable = new CodeVariableDeclarationStatement(typeof(bool), "isFeatureIgnored", new CodeDefaultValueExpression(new CodeTypeReference(typeof(bool)))); testMethod.Statements.Add(isScenarioIgnoredVariable); testMethod.Statements.Add(isFeatureIgnoredVariable); var tagsOfScenarioVariableReferenceExpression = new CodeVariableReferenceExpression("tagsOfScenario"); var isScenarioIgnoredVariableReferenceExpression = new CodeVariableReferenceExpression("isScenarioIgnored"); var featureFileTagFieldReferenceExpression = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "_featureTags"); var isFeatureIgnoredVariableReferenceExpression = new CodeVariableReferenceExpression("isFeatureIgnored"); var ignoreLinqStatement = "Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, \"ignore\", StringComparison.CurrentCultureIgnoreCase)).Any"; if (_codeDomHelper.TargetLanguage == CodeDomProviderLanguage.VB) { ignoreLinqStatement = "Where(Function(__entry) __entry IsNot Nothing).Where(Function(__entry) String.Equals(__entry, \"ignore\", StringComparison.CurrentCultureIgnoreCase)).Any"; } var ifIsNullStatement = new CodeConditionStatement(CreateCheckForNullExpression(tagsOfScenarioVariableReferenceExpression), new CodeAssignStatement(isScenarioIgnoredVariableReferenceExpression, new CodeMethodInvokeExpression(tagsOfScenarioVariableReferenceExpression, ignoreLinqStatement))); var ifIsFeatureTagsNullStatement = new CodeConditionStatement(CreateCheckForNullExpression(featureFileTagFieldReferenceExpression), new CodeAssignStatement(isFeatureIgnoredVariableReferenceExpression, new CodeMethodInvokeExpression(featureFileTagFieldReferenceExpression, ignoreLinqStatement))); testMethod.Statements.Add(ifIsNullStatement); testMethod.Statements.Add(ifIsFeatureTagsNullStatement); var isScenarioOrFeatureIgnoredExpression = new CodeBinaryOperatorExpression(isScenarioIgnoredVariableReferenceExpression, CodeBinaryOperatorType.BooleanOr, isFeatureIgnoredVariableReferenceExpression); var ifIsIgnoredStatement = new CodeConditionStatement(isScenarioOrFeatureIgnoredExpression, statementsWhenScenarioIsIgnored, statementsWhenScenarioIsExecuted.ToArray()); testMethod.Statements.Add(ifIsIgnoredStatement); }
private CodeMemberMethod CreateScenatioOutlineTestMethod(TestClassGenerationContext generationContext, ScenarioOutline scenarioOutline, ParameterSubstitution paramToIdentifier) { var testMethod = _codeDomHelper.CreateMethod(generationContext.TestClass); testMethod.Attributes = MemberAttributes.Public; testMethod.Name = string.Format(GeneratorConstants.TEST_NAME_FORMAT, scenarioOutline.Name.ToIdentifier()); foreach (var pair in paramToIdentifier) { testMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), pair.Value)); } testMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string[]), GeneratorConstants.SCENARIO_OUTLINE_EXAMPLE_TAGS_PARAMETER)); return(testMethod); }
public void GenerateStep(TestClassGenerationContext generationContext, List <CodeStatement> statements, Step gherkinStep, ParameterSubstitution paramToIdentifier) { var testRunnerField = GetTestRunnerExpression(); var scenarioStep = AsSpecFlowStep(gherkinStep); //testRunner.Given("something"); var arguments = new List <CodeExpression> { GetSubstitutedString(scenarioStep.Text, paramToIdentifier), GetDocStringArgExpression(scenarioStep.Argument as DocString, paramToIdentifier), GetTableArgExpression(scenarioStep.Argument as DataTable, statements, paramToIdentifier), new CodePrimitiveExpression(scenarioStep.Keyword) }; using (new SourceLineScope(_specFlowConfiguration, _codeDomHelper, statements, generationContext.Document.SourceFilePath, gherkinStep.Location)) { var expression = new CodeMethodInvokeExpression( testRunnerField, scenarioStep.StepKeyword + "Async", arguments.ToArray()); _codeDomHelper.MarkCodeMethodInvokeExpressionAsAwait(expression); statements.Add(new CodeExpressionStatement(expression)); } }
private void GenerateTestBody( TestClassGenerationContext generationContext, StepsContainer scenario, CodeMemberMethod testMethod, SpecFlowFeature feature, CodeExpression additionalTagsExpression = null, ParameterSubstitution paramToIdentifier = null) { //call test setup //ScenarioInfo scenarioInfo = new ScenarioInfo("xxxx", tags...); CodeExpression tagsExpression; if (additionalTagsExpression == null) { tagsExpression = _scenarioPartHelper.GetStringArrayExpression(scenario.GetTags()); } else if (!scenario.HasTags()) { tagsExpression = additionalTagsExpression; } else { // merge tags list // var tags = tags1 // if (tags2 != null) // tags = Enumerable.ToArray(Enumerable.Concat(tags1, tags1)); testMethod.Statements.Add( new CodeVariableDeclarationStatement(typeof(string[]), "__tags", _scenarioPartHelper.GetStringArrayExpression(scenario.GetTags()))); tagsExpression = new CodeVariableReferenceExpression("__tags"); testMethod.Statements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( additionalTagsExpression, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), new CodeAssignStatement( tagsExpression, new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(typeof(Enumerable)), "ToArray", new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(typeof(Enumerable)), "Concat", tagsExpression, additionalTagsExpression))))); } AddVariableForTags(testMethod, tagsExpression); AddVariableForArguments(testMethod, paramToIdentifier); testMethod.Statements.Add( new CodeVariableDeclarationStatement(typeof(ScenarioInfo), "scenarioInfo", new CodeObjectCreateExpression(typeof(ScenarioInfo), new CodePrimitiveExpression(scenario.Name), new CodePrimitiveExpression(scenario.Description), new CodeVariableReferenceExpression(GeneratorConstants.SCENARIO_TAGS_VARIABLE_NAME), new CodeVariableReferenceExpression(GeneratorConstants.SCENARIO_ARGUMENTS_VARIABLE_NAME)))); GenerateScenarioInitializeCall(generationContext, scenario, testMethod); GenerateTestMethodBody(generationContext, scenario, testMethod, paramToIdentifier, feature); GenerateScenarioCleanupMethodCall(generationContext, testMethod); }
private CodeExpression GetDocStringArgExpression(DocString docString, ParameterSubstitution paramToIdentifier) { return(GetSubstitutedString(docString == null ? null : docString.Content, paramToIdentifier)); }
private CodeExpression GetStringArrayExpression(IEnumerable <string> items, ParameterSubstitution paramToIdentifier) { return(new CodeArrayCreateExpression(typeof(string[]), items.Select(item => GetSubstitutedString(item, paramToIdentifier)).ToArray())); }
private CodeExpression GetMultilineTextArgExpression(string multiLineTextArgument, ParameterSubstitution paramToIdentifier) { return(GetSubstitutedString(multiLineTextArgument, paramToIdentifier)); }
private CodeExpression GetTableArgExpression(DataTable tableArg, List <CodeStatement> statements, ParameterSubstitution paramToIdentifier) { if (tableArg == null) { return(new CodeCastExpression(typeof(Table), new CodePrimitiveExpression(null))); } _tableCounter++; //TODO[Gherkin3]: remove dependency on having the first row as header var header = tableArg.Rows.First(); var body = tableArg.Rows.Skip(1).ToArray(); //Table table0 = new Table(header...); var tableVar = new CodeVariableReferenceExpression("table" + _tableCounter); statements.Add( new CodeVariableDeclarationStatement(typeof(Table), tableVar.VariableName, new CodeObjectCreateExpression( typeof(Table), GetStringArrayExpression(header.Cells.Select(c => c.Value), paramToIdentifier)))); foreach (var row in body) { //table0.AddRow(cells...); statements.Add(new CodeExpressionStatement( new CodeMethodInvokeExpression( tableVar, "AddRow", GetStringArrayExpression(row.Cells.Select(c => c.Value), paramToIdentifier)))); } return(tableVar); }
private CodeExpression GetTableArgExpression(GherkinTable tableArg, CodeStatementCollection statements, ParameterSubstitution paramToIdentifier) { if (tableArg == null) { return(new CodeCastExpression(typeof(Table), new CodePrimitiveExpression(null))); } tableCounter++; //Table table0 = new Table(header...); var tableVar = new CodeVariableReferenceExpression("table" + tableCounter); statements.Add( new CodeVariableDeclarationStatement(typeof(Table), tableVar.VariableName, new CodeObjectCreateExpression( typeof(Table), GetStringArrayExpression(tableArg.Header.Cells.Select(c => c.Value), paramToIdentifier)))); foreach (var row in tableArg.Body) { //table0.AddRow(cells...); statements.Add( new CodeMethodInvokeExpression( tableVar, "AddRow", GetStringArrayExpression(row.Cells.Select(c => c.Value), paramToIdentifier))); } return(tableVar); }
private void GenerateStep(CodeMemberMethod testMethod, ScenarioStep scenarioStep, ParameterSubstitution paramToIdentifier) { var testRunnerField = GetTestRunnerExpression(); //testRunner.Given("something"); List <CodeExpression> arguments = new List <CodeExpression>(); arguments.Add( 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)); arguments.Add(new CodePrimitiveExpression(scenarioStep.Keyword)); AddLineDirective(testMethod.Statements, scenarioStep); testMethod.Statements.Add( new CodeMethodInvokeExpression( testRunnerField, scenarioStep.GetType().Name, arguments.ToArray())); }
private void GenerateTestBody(TestClassGenerationContext generationContext, Scenario scenario, CodeMemberMethod testMethod, CodeExpression additionalTagsExpression = null, ParameterSubstitution paramToIdentifier = null) { //call test setup //ScenarioInfo scenarioInfo = new ScenarioInfo("xxxx", tags...); CodeExpression tagsExpression; if (additionalTagsExpression == null) { tagsExpression = GetStringArrayExpression(scenario.Tags); } else if (scenario.Tags == null) { tagsExpression = additionalTagsExpression; } else { // merge tags list // var tags = tags1 // if (tags2 != null) // tags = Enumerable.ToArray(Enumerable.Concat(tags1, tags1)); testMethod.Statements.Add( new CodeVariableDeclarationStatement(typeof(string[]), "__tags", GetStringArrayExpression(scenario.Tags))); tagsExpression = new CodeVariableReferenceExpression("__tags"); testMethod.Statements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( additionalTagsExpression, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), new CodeAssignStatement( tagsExpression, new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(typeof(Enumerable)), "ToArray", new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(typeof(Enumerable)), "Concat", tagsExpression, additionalTagsExpression))))); } testMethod.Statements.Add( new CodeVariableDeclarationStatement(typeof(ScenarioInfo), "scenarioInfo", new CodeObjectCreateExpression(typeof(ScenarioInfo), new CodePrimitiveExpression(scenario.Title), tagsExpression))); AddLineDirective(testMethod.Statements, scenario); testMethod.Statements.Add( new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), generationContext.ScenarioInitializeMethod.Name, new CodeVariableReferenceExpression("scenarioInfo"))); if (HasFeatureBackground(generationContext.Feature)) { AddLineDirective(testMethod.Statements, generationContext.Feature.Background); testMethod.Statements.Add( new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), generationContext.FeatureBackgroundMethod.Name)); } foreach (var scenarioStep in scenario.Steps) { GenerateStep(testMethod, scenarioStep, paramToIdentifier); } AddLineDirectiveHidden(testMethod.Statements); // call scenario cleanup testMethod.Statements.Add( new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), generationContext.ScenarioCleanupMethod.Name)); }
private void GenerateScenarioOutlineExamplesAsIndividualMethods(ScenarioOutline scenarioOutline, TestClassGenerationContext generationContext, CodeMemberMethod scenatioOutlineTestMethod, ParameterSubstitution paramToIdentifier) { int exampleSetIndex = 0; foreach (var exampleSet in scenarioOutline.Examples.ExampleSets) { bool useFirstColumnAsName = CanUseFirstColumnAsName(exampleSet.Table); string exampleSetIdentifier = string.IsNullOrEmpty(exampleSet.Title) ? scenarioOutline.Examples.ExampleSets.Count(es => string.IsNullOrEmpty(es.Title)) > 1 ? string.Format("ExampleSet {0}", exampleSetIndex).ToIdentifier() : null : exampleSet.Title.ToIdentifier(); for (int rowIndex = 0; rowIndex < exampleSet.Table.Body.Length; rowIndex++) { var row = exampleSet.Table.Body[rowIndex]; string variantName = useFirstColumnAsName ? row.Cells[0].Value : string.Format("Variant {0}", rowIndex); GenerateScenarioOutlineTestVariant(generationContext, scenarioOutline, scenatioOutlineTestMethod, paramToIdentifier, exampleSet.Title ?? "", exampleSetIdentifier, row, exampleSet.Tags, variantName); } exampleSetIndex++; } }
/// <summary>Closes one element and pops the corresponding namespace scope.</summary> /// <exception cref="InvalidOperationException">This results in an invalid XML document.</exception> /// <exception cref="InvalidOperationException">An <see cref="XmlWriter" /> method was called before a previous asynchronous operation finished. In this case, <see cref="InvalidOperationException" /> is thrown with the message “An asynchronous operation is already in progress.”</exception> public override void WriteEndElement() { if (_stack.Count > 0) { var value = _buffer.ToString() ?? ""; _buffer.Length = 0; var last = _stack.Pop(); if (_attrBuffer.TryGetValue(ParameterSubstitution.DateRangeAttribute, out var dateRange) && ParameterSubstitution.TryDeserializeDateRange(dateRange, out var dateStart, out var dateEnd) && (dateStart.HasValue || dateEnd.HasValue)) { var property = (last as BinaryOperator)?.Left ?? (last as BetweenOperator)?.Left; if (property == null) { throw new NotSupportedException(); } if (dateStart.HasValue && dateEnd.HasValue) { last = new BetweenOperator() { Left = property, Min = new DateOffsetLiteral(_context, dateStart.Value, false), Max = new DateOffsetLiteral(_context, dateEnd.Value, true), }.Normalize(); } else if (dateStart.HasValue) { last = new GreaterThanOrEqualsOperator() { Left = property, Right = new DateOffsetLiteral(_context, dateStart.Value, false) }.Normalize(); } else { last = new LessThanOrEqualsOperator() { Left = property, Right = new DateOffsetLiteral(_context, dateEnd.Value, true) }.Normalize(); } } else { if (last is IsOperator isOp) { switch (value) { case "defined": isOp.Right = IsOperand.Defined; break; case "not defined": isOp.Right = IsOperand.NotDefined; break; case "not null": isOp.Right = IsOperand.NotNull; break; case "null": isOp.Right = IsOperand.Null; break; case "": break; default: throw new NotSupportedException(); } } else if (last is InOperator inOp) { inOp.Right = ListExpression.FromSqlInClause(value); } else if (last is BetweenOperator betweenOp) { betweenOp.SetMinMaxFromSql(value); } else if (last is PropertyReference property) { if (_stack.OfType <Join>().Last().Right.Joins.Any(j => j.Right.TypeProvider == property)) { last = null; } else { last = new EqualsOperator() { Left = property }; } } if (!(last is ILogical) && last is BinaryOperator binOp) { if (value == "__now()") { binOp.Right = new Functions.CurrentDateTime(); } else if (binOp is LikeOperator) { binOp.Right = AmlLikeParser.Instance.Parse(value); } else { binOp.Right = NormalizeLiteral((PropertyReference)binOp.Left, value, _context); } } } if (last is BinaryOperator genOp && genOp.Left is PropertyReference prop && (prop.Name == "generation" || prop.Name == "id")) { Query.Version = new VersionCriteria() { Condition = genOp }; if (prop.Name == "id") { AddToCondition(genOp); } }