Best Gherkin-dotnet code snippet using Gherkin.Ast.Feature
ScenarioOutlineExecutorTests.cs
Source:ScenarioOutlineExecutorTests.cs
...10namespace UnitTests11{12 public sealed class ScenarioOutlineExecutorTests13 {14 private readonly Mock<IFeatureFileRepository> _featureFileRepository = new Mock<IFeatureFileRepository>();15 private readonly ScenarioOutlineExecutor _sut;16 public ScenarioOutlineExecutorTests()17 {18 _sut = new ScenarioOutlineExecutor(_featureFileRepository.Object);19 }20 [Fact]21 public async Task ExecuteScenarioOutlineAsync_Requires_FeatureInstance()22 {23 //act / assert.24 await Assert.ThrowsAsync<ArgumentNullException>(async () => await _sut.ExecuteScenarioOutlineAsync(null, "scenario name", "example name", 0));25 }26 [Theory]27 [InlineData(null, "example name", 0, typeof(ArgumentNullException))]28 [InlineData("", "example name", 0, typeof(ArgumentNullException))]29 [InlineData(" ", "example name", 0, typeof(ArgumentNullException))]30 [InlineData("scenario name", "example name", -1, typeof(ArgumentException))]31 public async Task ExecuteScenarioOutlineAsync_Requires_Arguments(32 string scenarioOutlineName,33 string exampleName,34 int exampleRowIndex,35 Type expectedExceptionType)36 {37 //arrange.38 var featureInstance = new FeatureForNullArgumentTests();39 //act / assert.40 await Assert.ThrowsAsync(expectedExceptionType, async () => await _sut.ExecuteScenarioOutlineAsync(featureInstance, scenarioOutlineName, exampleName, exampleRowIndex));41 }42 private sealed class FeatureForNullArgumentTests : Feature43 { }44 [Fact]45 public async Task ScenarioOutline_Runs_Background_Steps_First()46 {47 var feature = new GherkinFeatureBuilder()48 .WithBackground(sb => sb49 .Given("background", null))50 .WithScenarioOutline("test outline", sb => sb51 .Given("I chose <a> as first number", null)52 .And("I chose <b> as second number", null)53 .When("I press add", null)54 .Then("the result should be <sum> on the screen", null),55 eb => eb56 .WithExampleHeadings("a", "b", "sum")57 .WithExamples("", db => db.WithData("1", "2", "3")))58 .Build();59 60 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithScenarioSteps)}.feature"))61 .Returns(new FeatureFile(new Gherkin.Ast.GherkinDocument(feature, new Gherkin.Ast.Comment[0])))62 .Verifiable();63 var featureInstance = new FeatureWithScenarioSteps();64 var output = new Mock<ITestOutputHelper>();65 featureInstance.InternalOutput = output.Object;66 67 await _sut.ExecuteScenarioOutlineAsync(featureInstance, "test outline", "", 0);68 _featureFileRepository.Verify();69 Assert.Equal(5, featureInstance.CallStack.Count);70 Assert.Equal(nameof(FeatureWithScenarioSteps.BackgroundStep), featureInstance.CallStack[0].Key);71 }72 [Theory]73 [InlineData("", 0, 0, 1, 1)]74 [InlineData("", 1, 1, 9, 10)]75 [InlineData("of bigger numbers", 0, 99, 1, 100)]76 [InlineData("of bigger numbers", 1, 100, 200, 300)]77 [InlineData("of large numbers", 0, 999, 1, 1000)]78 [InlineData("of large numbers", 1, 9999, 1, 10000)]79 public async Task ExecuteScenarioOutlineAsync_Executes_All_Scenario_Steps(80 string exampleName,81 int exampleRowIndex,82 int a,83 int b,84 int sum85 )86 {87 //arrange.88 var step1Text = "Given " + FeatureWithScenarioSteps.ScenarioStep1Text.Replace(@"(\d+)", $"{a}", StringComparison.InvariantCultureIgnoreCase);89 var step2Text = "And " + FeatureWithScenarioSteps.ScenarioStep2Text.Replace(@"(\d+)", $"{b}", StringComparison.InvariantCultureIgnoreCase);90 var step3Text = "When " + FeatureWithScenarioSteps.ScenarioStep3Text;91 var step4Text = "Then " + FeatureWithScenarioSteps.ScenarioStep4Text.Replace(@"(\d+)", $"{sum}", StringComparison.InvariantCultureIgnoreCase);92 var scenarioOutlineName = "scenario 12345";93 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithScenarioSteps)}.feature"))94 .Returns(new FeatureFile(CreateGherkinDocument(scenarioOutlineName)))95 .Verifiable();96 var featureInstance = new FeatureWithScenarioSteps();97 var output = new Mock<ITestOutputHelper>();98 featureInstance.InternalOutput = output.Object;99 //act.100 await _sut.ExecuteScenarioOutlineAsync(featureInstance, scenarioOutlineName, exampleName, exampleRowIndex);101 //assert.102 _featureFileRepository.Verify();103 Assert.Equal(4, featureInstance.CallStack.Count);104 Assert.Equal(nameof(FeatureWithScenarioSteps.ScenarioStep1), featureInstance.CallStack[0].Key);105 Assert.NotNull(featureInstance.CallStack[0].Value);106 Assert.Single(featureInstance.CallStack[0].Value);107 Assert.Equal(a, featureInstance.CallStack[0].Value[0]);108 output.Verify(o => o.WriteLine($"{step1Text}: PASSED"), Times.Once);109 Assert.Equal(nameof(FeatureWithScenarioSteps.ScenarioStep2), featureInstance.CallStack[1].Key);110 Assert.NotNull(featureInstance.CallStack[1].Value);111 Assert.Single(featureInstance.CallStack[1].Value);112 Assert.Equal(b, featureInstance.CallStack[1].Value[0]);113 output.Verify(o => o.WriteLine($"{step2Text}: PASSED"), Times.Once);114 Assert.Equal(nameof(FeatureWithScenarioSteps.ScenarioStep3), featureInstance.CallStack[2].Key);115 Assert.Null(featureInstance.CallStack[2].Value);116 output.Verify(o => o.WriteLine($"{step3Text}: PASSED"), Times.Once);117 Assert.Equal(nameof(FeatureWithScenarioSteps.ScenarioStep4), featureInstance.CallStack[3].Key);118 Assert.NotNull(featureInstance.CallStack[3].Value);119 Assert.Single(featureInstance.CallStack[3].Value);120 Assert.Equal(sum, featureInstance.CallStack[3].Value[0]);121 output.Verify(o => o.WriteLine($"{step4Text}: PASSED"), Times.Once);122 }123 private static Gherkin.Ast.GherkinDocument CreateGherkinDocument(124 string outlineName,125 Gherkin.Ast.StepArgument stepArgument = null)126 {127 return new Gherkin.Ast.GherkinDocument(128 new GherkinFeatureBuilder() 129 .WithScenarioOutline(outlineName, sb => sb130 .Given("I chose <a> as first number", stepArgument)131 .And("I chose <b> as second number", stepArgument)132 .When("I press add", stepArgument)133 .Then("the result should be <sum> on the screen", stepArgument),134 eb => eb135 .WithExampleHeadings("a", "b", "sum")136 .WithExamples("", db => db137 .WithData(0, 1, 1)138 .WithData(1, 9, 10))139 .WithExamples("of bigger numbers", db => db140 .WithData(99, 1, 100)141 .WithData(100, 200, 300))142 .WithExamples("of large numbers", db => db143 .WithData(999, 1, 1000)144 .WithData(9999, 1, 10000)))145 .Build(), 146 new Gherkin.Ast.Comment[0]);147 }148 private sealed class FeatureWithScenarioSteps : Feature149 {150 public List<KeyValuePair<string, object[]>> CallStack { get; } = new List<KeyValuePair<string, object[]>>();151 [Given("background")]152 public void BackgroundStep()153 {154 CallStack.Add(new KeyValuePair<string, object[]>(nameof(BackgroundStep), null));155 }156 [Given("Non matching given")]157 public void NonMatchingStep1_before()158 {159 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_before), null));160 }161 public const string ScenarioStep1Text = @"I chose (\d+) as first number";162 [Given(ScenarioStep1Text)]163 public void ScenarioStep1(int firstNumber)164 {165 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep1), new object[] { firstNumber }));166 }167 [Given("Non matching given")]168 public void NonMatchingStep1_after()169 {170 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_after), null));171 }172 [And("Non matching and")]173 public void NonMatchingStep2_before()174 {175 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_before), null));176 }177 public const string ScenarioStep2Text = @"I chose (\d+) as second number";178 [And(ScenarioStep2Text)]179 public void ScenarioStep2(int secondNumber)180 {181 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep2), new object[] { secondNumber }));182 }183 [And("Non matching and")]184 public void NonMatchingStep2_after()185 {186 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_after), null));187 }188 [When("Non matching when")]189 public void NonMatchingStep3_before()190 {191 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_before), null));192 }193 public const string ScenarioStep3Text = "I press add";194 [When(ScenarioStep3Text)]195 public void ScenarioStep3()196 {197 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep3), null));198 }199 [When("Non matching when")]200 public void NonMatchingStep3_after()201 {202 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_after), null));203 }204 [Then("Non matching then")]205 public void NonMatchingStep4_before()206 {207 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_before), null));208 }209 public const string ScenarioStep4Text = @"the result should be (\d+) on the screen";210 [Then(ScenarioStep4Text)]211 public void ScenarioStep4(int result)212 {213 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep4), new object[] { result }));214 }215 [Then("Non matching then")]216 public void NonMatchingStep4_after()217 {218 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_after), null));219 }220 }221 [Theory]222 [InlineData("", 0, 0, 1, 1)]223 [InlineData("", 1, 1, 9, 10)]224 [InlineData("of bigger numbers", 0, 99, 1, 100)]225 [InlineData("of bigger numbers", 1, 100, 200, 300)]226 [InlineData("of large numbers", 0, 999, 1, 1000)]227 [InlineData("of large numbers", 1, 9999, 1, 10000)]228 public async Task ExecuteScenarioOutlineAsync_Executes_Successful_Scenario_Steps_And_Skips_The_Rest(229 string exampleName,230 int exampleRowIndex,231 int a,232 int b,233 int sum234 )235 {236 //arrange.237 var step1Text = "Given " + FeatureWithScenarioSteps_And_Throwing.ScenarioStep1Text.Replace(@"(\d+)", $"{a}", StringComparison.InvariantCultureIgnoreCase);238 var step2Text = "And " + FeatureWithScenarioSteps_And_Throwing.ScenarioStep2Text.Replace(@"(\d+)", $"{b}", StringComparison.InvariantCultureIgnoreCase);239 var step3Text = "When " + FeatureWithScenarioSteps_And_Throwing.ScenarioStep3Text;240 var step4Text = "Then " + FeatureWithScenarioSteps_And_Throwing.ScenarioStep4Text.Replace(@"(\d+)", $"{sum}", StringComparison.InvariantCultureIgnoreCase);241 var outlineName = "scenario 12345";242 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithScenarioSteps_And_Throwing)}.feature"))243 .Returns(new FeatureFile(CreateGherkinDocument(outlineName)))244 .Verifiable();245 var featureInstance = new FeatureWithScenarioSteps_And_Throwing();246 var output = new Mock<ITestOutputHelper>();247 featureInstance.InternalOutput = output.Object;248 //act.249 var exceptiion = await Assert.ThrowsAsync<TargetInvocationException>(async () => await _sut.ExecuteScenarioOutlineAsync(featureInstance, outlineName, exampleName, exampleRowIndex));250 Assert.IsType<InvalidOperationException>(exceptiion.InnerException);251 //assert.252 _featureFileRepository.Verify();253 Assert.Equal(2, featureInstance.CallStack.Count);254 Assert.Equal(nameof(FeatureWithScenarioSteps_And_Throwing.ScenarioStep1), featureInstance.CallStack[0].Key);255 Assert.NotNull(featureInstance.CallStack[0].Value);256 Assert.Single(featureInstance.CallStack[0].Value);257 Assert.Equal(a, featureInstance.CallStack[0].Value[0]);258 output.Verify(o => o.WriteLine($"{step1Text}: PASSED"), Times.Once);259 Assert.Equal(nameof(FeatureWithScenarioSteps_And_Throwing.ScenarioStep2), featureInstance.CallStack[1].Key);260 Assert.NotNull(featureInstance.CallStack[1].Value);261 Assert.Single(featureInstance.CallStack[1].Value);262 Assert.Equal(b, featureInstance.CallStack[1].Value[0]);263 output.Verify(o => o.WriteLine($"{step2Text}: FAILED"), Times.Once);264 output.Verify(o => o.WriteLine($"{step3Text}: SKIPPED"), Times.Once);265 output.Verify(o => o.WriteLine($"{step4Text}: SKIPPED"), Times.Once);266 }267 private sealed class FeatureWithScenarioSteps_And_Throwing : Feature268 {269 public List<KeyValuePair<string, object[]>> CallStack { get; } = new List<KeyValuePair<string, object[]>>();270 [Given("Non matching given")]271 public void NonMatchingStep1_before()272 {273 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_before), null));274 }275 public const string ScenarioStep1Text = @"I chose (\d+) as first number";276 [Given(ScenarioStep1Text)]277 public void ScenarioStep1(int firstNumber)278 {279 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep1), new object[] { firstNumber }));280 }281 [Given("Non matching given")]282 public void NonMatchingStep1_after()283 {284 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_after), null));285 }286 [And("Non matching and")]287 public void NonMatchingStep2_before()288 {289 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_before), null));290 }291 public const string ScenarioStep2Text = @"I chose (\d+) as second number";292 [And(ScenarioStep2Text)]293 public void ScenarioStep2(int secondNumber)294 {295 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep2), new object[] { secondNumber }));296 throw new InvalidOperationException("Some exception to stop execution of next steps.");297 }298 [And("Non matching and")]299 public void NonMatchingStep2_after()300 {301 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_after), null));302 }303 [When("Non matching when")]304 public void NonMatchingStep3_before()305 {306 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_before), null));307 }308 public const string ScenarioStep3Text = "I press add";309 [When(ScenarioStep3Text)]310 public void ScenarioStep3()311 {312 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep3), null));313 }314 [When("Non matching when")]315 public void NonMatchingStep3_after()316 {317 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_after), null));318 }319 [Then("Non matching then")]320 public void NonMatchingStep4_before()321 {322 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_before), null));323 }324 public const string ScenarioStep4Text = @"the result should be (\d+) on the screen";325 [Then(ScenarioStep4Text)]326 public void ScenarioStep4(int result)327 {328 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep4), new object[] { result }));329 }330 [Then("Non matching then")]331 public void NonMatchingStep4_after()332 {333 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_after), null));334 }335 }336 [Theory]337 [InlineData("", 0)]338 [InlineData("", 1)]339 [InlineData("of bigger numbers", 0)]340 [InlineData("of bigger numbers", 1)]341 [InlineData("of large numbers", 0)]342 [InlineData("of large numbers", 1)]343 public async Task ExecuteScenarioOutlineAsync_Executes_ScenarioStep_With_DataTable(344 string exampleName,345 int exampleRowIndex)346 {347 //arrange.348 var scenarioName = "scenario123";349 var featureInstance = new FeatureWithDataTableScenarioStep();350 var output = new Mock<ITestOutputHelper>();351 featureInstance.InternalOutput = output.Object;352 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithDataTableScenarioStep)}.feature"))353 .Returns(new FeatureFile(FeatureWithDataTableScenarioStep.CreateGherkinDocument(scenarioName,354 new Gherkin.Ast.DataTable(new Gherkin.Ast.TableRow[]355 {356 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]357 {358 new Gherkin.Ast.TableCell(null, "First argument"),359 new Gherkin.Ast.TableCell(null, "Second argument"),360 new Gherkin.Ast.TableCell(null, "Result"),361 }),362 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]363 {364 new Gherkin.Ast.TableCell(null, "1"),365 new Gherkin.Ast.TableCell(null, "2"),366 new Gherkin.Ast.TableCell(null, "3"),367 }),368 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]369 {370 new Gherkin.Ast.TableCell(null, "a"),371 new Gherkin.Ast.TableCell(null, "b"),372 new Gherkin.Ast.TableCell(null, "c"),373 })374 }))))375 .Verifiable();376 //act.377 await _sut.ExecuteScenarioOutlineAsync(featureInstance, scenarioName, exampleName, exampleRowIndex);378 //assert.379 _featureFileRepository.Verify();380 Assert.NotNull(featureInstance.ReceivedDataTable);381 Assert.Equal(3, featureInstance.ReceivedDataTable.Rows.Count());382 AssertDataTableCell(0, 0, "First argument");383 AssertDataTableCell(0, 1, "Second argument");384 AssertDataTableCell(0, 2, "Result");385 AssertDataTableCell(1, 0, "1");386 AssertDataTableCell(1, 1, "2");387 AssertDataTableCell(1, 2, "3");388 AssertDataTableCell(2, 0, "a");389 AssertDataTableCell(2, 1, "b");390 AssertDataTableCell(2, 2, "c");391 void AssertDataTableCell(int rowIndex, int cellIndex, string value)392 {393 Assert.True(featureInstance.ReceivedDataTable.Rows.Count() > rowIndex);394 Assert.NotNull(featureInstance.ReceivedDataTable.Rows.ElementAt(rowIndex));395 Assert.True(featureInstance.ReceivedDataTable.Rows.ElementAt(rowIndex).Cells.Count() > cellIndex);396 Assert.NotNull(featureInstance.ReceivedDataTable.Rows.ElementAt(rowIndex).Cells.ElementAt(cellIndex));397 Assert.Equal("First argument", featureInstance.ReceivedDataTable.Rows.ElementAt(0).Cells.ElementAt(0).Value);398 }399 }400 private sealed class FeatureWithDataTableScenarioStep : Feature401 {402 public Gherkin.Ast.DataTable ReceivedDataTable { get; private set; }403 public const string Steptext = @"Step text 1212121";404 [Given(Steptext)]405 public void When_DataTable_Is_Expected(Gherkin.Ast.DataTable dataTable)406 {407 ReceivedDataTable = dataTable;408 }409 public static Gherkin.Ast.GherkinDocument CreateGherkinDocument(410 string outlineName,411 Gherkin.Ast.StepArgument stepArgument = null)412 {413 return new Gherkin.Ast.GherkinDocument(414 new Gherkin.Ast.Feature(new Gherkin.Ast.Tag[0], null, null, null, null, null, new Gherkin.Ast.ScenarioDefinition[]415 {416 new Gherkin.Ast.ScenarioOutline(417 new Gherkin.Ast.Tag[0],418 null,419 null,420 outlineName,421 null,422 new Gherkin.Ast.Step[]423 {424 new Gherkin.Ast.Step(null, "Given", Steptext, stepArgument)425 },426 new Gherkin.Ast.Examples[]427 {428 new Gherkin.Ast.Examples(null, null, null, "", null,429 new Gherkin.Ast.TableRow(null,430 new Gherkin.Ast.TableCell[]431 {432 new Gherkin.Ast.TableCell(null, "a"),433 new Gherkin.Ast.TableCell(null, "b"),434 new Gherkin.Ast.TableCell(null, "sum"),435 }),436 new Gherkin.Ast.TableRow[]437 {438 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]439 {440 new Gherkin.Ast.TableCell(null, "0"),441 new Gherkin.Ast.TableCell(null, "1"),442 new Gherkin.Ast.TableCell(null, "1")443 }),444 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]445 {446 new Gherkin.Ast.TableCell(null, "1"),447 new Gherkin.Ast.TableCell(null, "9"),448 new Gherkin.Ast.TableCell(null, "10")449 })450 }),451 new Gherkin.Ast.Examples(null, null, null, "of bigger numbers", null,452 new Gherkin.Ast.TableRow(null,453 new Gherkin.Ast.TableCell[]454 {455 new Gherkin.Ast.TableCell(null, "a"),456 new Gherkin.Ast.TableCell(null, "b"),457 new Gherkin.Ast.TableCell(null, "sum"),458 }),459 new Gherkin.Ast.TableRow[]460 {461 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]462 {463 new Gherkin.Ast.TableCell(null, "99"),464 new Gherkin.Ast.TableCell(null, "1"),465 new Gherkin.Ast.TableCell(null, "100")466 }),467 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]468 {469 new Gherkin.Ast.TableCell(null, "100"),470 new Gherkin.Ast.TableCell(null, "200"),471 new Gherkin.Ast.TableCell(null, "300")472 })473 }),474 new Gherkin.Ast.Examples(null, null, null, "of large numbers", null,475 new Gherkin.Ast.TableRow(null,476 new Gherkin.Ast.TableCell[]477 {478 new Gherkin.Ast.TableCell(null, "a"),479 new Gherkin.Ast.TableCell(null, "b"),480 new Gherkin.Ast.TableCell(null, "sum"),481 }),482 new Gherkin.Ast.TableRow[]483 {484 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]485 {486 new Gherkin.Ast.TableCell(null, "999"),487 new Gherkin.Ast.TableCell(null, "1"),488 new Gherkin.Ast.TableCell(null, "1000")489 }),490 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]491 {492 new Gherkin.Ast.TableCell(null, "9999"),493 new Gherkin.Ast.TableCell(null, "1"),494 new Gherkin.Ast.TableCell(null, "10000")495 })496 })497 })498 }),499 new Gherkin.Ast.Comment[0]);500 }501 }502 [Theory]503 [InlineData("", 0)]504 [InlineData("", 1)]505 [InlineData("of bigger numbers", 0)]506 [InlineData("of bigger numbers", 1)]507 [InlineData("of large numbers", 0)]508 [InlineData("of large numbers", 1)]509 public async Task ExecuteScenarioOutlineAsync_Executes_ScenarioStep_With_DocString(510 string exampleName,511 int exampleRowIndex)512 {513 //arrange.514 var scenarioName = "scenario123";515 var featureInstance = new FeatureWithDocStringScenarioStep();516 var output = new Mock<ITestOutputHelper>();517 featureInstance.InternalOutput = output.Object;518 var docStringContent = "some content" + Environment.NewLine +519"+++" + Environment.NewLine +520"with multi lines" + Environment.NewLine +521"---" + Environment.NewLine +522"in it";523 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithDocStringScenarioStep)}.feature"))524 .Returns(new FeatureFile(FeatureWithDocStringScenarioStep.CreateGherkinDocument(scenarioName,525 new Gherkin.Ast.DocString(null, null, docStringContent))))526 .Verifiable();527 //act.528 await _sut.ExecuteScenarioOutlineAsync(featureInstance, scenarioName, exampleName, exampleRowIndex);529 //assert.530 _featureFileRepository.Verify();531 Assert.NotNull(featureInstance.ReceivedDocString);532 Assert.Equal(docStringContent, featureInstance.ReceivedDocString.Content);533 }534 private sealed class FeatureWithDocStringScenarioStep : Feature535 {536 public Gherkin.Ast.DocString ReceivedDocString { get; private set; }537 public const string Steptext = @"Step text 1212121";538 [Given(Steptext)]539 public void When_DocString_Is_Expected(Gherkin.Ast.DocString docString)540 {541 ReceivedDocString = docString;542 }543 public static Gherkin.Ast.GherkinDocument CreateGherkinDocument(544 string outlineName,545 Gherkin.Ast.StepArgument stepArgument = null)546 {547 return new Gherkin.Ast.GherkinDocument(548 new Gherkin.Ast.Feature(new Gherkin.Ast.Tag[0], null, null, null, null, null, new Gherkin.Ast.ScenarioDefinition[]549 {550 new Gherkin.Ast.ScenarioOutline(551 new Gherkin.Ast.Tag[0],552 null,553 null,554 outlineName,555 null,556 new Gherkin.Ast.Step[]557 {558 new Gherkin.Ast.Step(null, "Given", Steptext, stepArgument)559 },560 new Gherkin.Ast.Examples[]561 {562 new Gherkin.Ast.Examples(null, null, null, "", null,...
ScenarioExecutorTests.cs
Source:ScenarioExecutorTests.cs
...10namespace UnitTests11{12 public sealed class ScenarioExecutorTests13 {14 private readonly Mock<IFeatureFileRepository> _featureFileRepository = new Mock<IFeatureFileRepository>();15 private readonly ScenarioExecutor _sut;16 public ScenarioExecutorTests()17 {18 _sut = new ScenarioExecutor(_featureFileRepository.Object);19 }20 [Fact]21 public async Task ExecuteScenario_Requires_FeatureInstance()22 {23 //act / assert.24 await Assert.ThrowsAsync<ArgumentNullException>(async () => await _sut.ExecuteScenarioAsync(null, "valid scenario name"));25 }26 [Theory]27 [InlineData(null)]28 [InlineData("")]29 [InlineData(" ")]30 [InlineData(" ")]31 public async Task ExecuteScenario_Requires_ScenarioName(string scenarioName)32 {33 //arrange.34 var featureInstance = new UselessFeature();35 //act / assert.36 await Assert.ThrowsAsync<ArgumentNullException>(async () => await _sut.ExecuteScenarioAsync(featureInstance, scenarioName));37 }38 private sealed class UselessFeature : Feature { } 39 [Fact]40 public async Task ExecuteScenario_Executes_All_Scenario_Steps()41 {42 //arrange.43 var step1Text = "Given " + FeatureWithScenarioSteps.ScenarioStep1Text.Replace(@"(\d+)", "12", StringComparison.InvariantCultureIgnoreCase);44 var step2Text = "And " + FeatureWithScenarioSteps.ScenarioStep2Text.Replace(@"(\d+)", "15", StringComparison.InvariantCultureIgnoreCase);45 var step3Text = "When " + FeatureWithScenarioSteps.ScenarioStep3Text;46 var step4Text = "Then " + FeatureWithScenarioSteps.ScenarioStep4Text.Replace(@"(\d+)", "27", StringComparison.InvariantCultureIgnoreCase);47 var scenarioName = "scenario 12345";48 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithScenarioSteps)}.feature"))49 .Returns(new FeatureFile(CreateGherkinDocument(scenarioName,50 new string[] 51 {52 step1Text,53 step2Text,54 step3Text,55 step4Text56 })))57 .Verifiable();58 var featureInstance = new FeatureWithScenarioSteps();59 var output = new Mock<ITestOutputHelper>();60 featureInstance.InternalOutput = output.Object;61 //act.62 await _sut.ExecuteScenarioAsync(featureInstance, scenarioName);63 //assert.64 _featureFileRepository.Verify();65 Assert.Equal(4, featureInstance.CallStack.Count);66 Assert.Equal(nameof(FeatureWithScenarioSteps.ScenarioStep1), featureInstance.CallStack[0].Key);67 Assert.NotNull(featureInstance.CallStack[0].Value);68 Assert.Single(featureInstance.CallStack[0].Value);69 Assert.Equal(12, featureInstance.CallStack[0].Value[0]);70 output.Verify(o => o.WriteLine($"{step1Text}: PASSED"), Times.Once);71 Assert.Equal(nameof(FeatureWithScenarioSteps.ScenarioStep2), featureInstance.CallStack[1].Key);72 Assert.NotNull(featureInstance.CallStack[1].Value);73 Assert.Single(featureInstance.CallStack[1].Value);74 Assert.Equal(15, featureInstance.CallStack[1].Value[0]);75 output.Verify(o => o.WriteLine($"{step2Text}: PASSED"), Times.Once);76 Assert.Equal(nameof(FeatureWithScenarioSteps.ScenarioStep3), featureInstance.CallStack[2].Key);77 Assert.Null(featureInstance.CallStack[2].Value);78 output.Verify(o => o.WriteLine($"{step3Text}: PASSED"), Times.Once);79 Assert.Equal(nameof(FeatureWithScenarioSteps.ScenarioStep4), featureInstance.CallStack[3].Key);80 Assert.NotNull(featureInstance.CallStack[3].Value);81 Assert.Single(featureInstance.CallStack[3].Value);82 Assert.Equal(27, featureInstance.CallStack[3].Value[0]);83 output.Verify(o => o.WriteLine($"{step4Text}: PASSED"), Times.Once);84 }85 private static Gherkin.Ast.GherkinDocument CreateGherkinDocument(86 string scenario, 87 string[] steps,88 Gherkin.Ast.StepArgument stepArgument = null)89 {90 return new Gherkin.Ast.GherkinDocument(91 new Gherkin.Ast.Feature(new Gherkin.Ast.Tag[0], null, null, null, null, null, new Gherkin.Ast.ScenarioDefinition[] 92 {93 new Gherkin.Ast.Scenario(94 new Gherkin.Ast.Tag[0], 95 null, 96 null, 97 scenario, 98 null, 99 steps.Select(s => 100 {101 var spaceIndex = s.IndexOf(' ');102 return new Gherkin.Ast.Step(103 null, 104 s.Substring(0, spaceIndex).Trim(), 105 s.Substring(spaceIndex).Trim(), 106 stepArgument);107 }).ToArray())108 }),109 new Gherkin.Ast.Comment[0]);110 }111 private sealed class FeatureWithScenarioSteps : Feature112 {113 public List<KeyValuePair<string, object[]>> CallStack { get; } = new List<KeyValuePair<string, object[]>>();114 [Given("Non matching given")]115 public void NonMatchingStep1_before()116 {117 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_before), null));118 }119 public const string ScenarioStep1Text = @"I chose (\d+) as first number";120 [Given(ScenarioStep1Text)]121 public void ScenarioStep1(int firstNumber)122 {123 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep1), new object[] { firstNumber }));124 }125 [Given("Non matching given")]126 public void NonMatchingStep1_after()127 {128 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_after), null));129 }130 [And("Non matching and")]131 public void NonMatchingStep2_before()132 {133 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_before), null));134 }135 public const string ScenarioStep2Text = @"I chose (\d+) as second number";136 [And(ScenarioStep2Text)]137 public void ScenarioStep2(int secondNumber)138 {139 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep2), new object[] { secondNumber }));140 }141 [And("Non matching and")]142 public void NonMatchingStep2_after()143 {144 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_after), null));145 }146 [When("Non matching when")]147 public void NonMatchingStep3_before()148 {149 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_before), null));150 }151 public const string ScenarioStep3Text = "I press add";152 [When(ScenarioStep3Text)]153 public void ScenarioStep3()154 {155 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep3), null));156 }157 [When("Non matching when")]158 public void NonMatchingStep3_after()159 {160 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_after), null));161 }162 [Then("Non matching then")]163 public void NonMatchingStep4_before()164 {165 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_before), null));166 }167 public const string ScenarioStep4Text = @"the result should be (\d+) on the screen";168 [Then(ScenarioStep4Text)]169 public void ScenarioStep4(int result)170 {171 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep4), new object[] { result }));172 }173 [Then("Non matching then")]174 public void NonMatchingStep4_after()175 {176 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_after), null));177 }178 }179 [Fact]180 public async Task ExecuteScenario_Executes_Successful_Scenario_Steps_And_Skips_The_Rest()181 {182 //arrange.183 var step1Text = "Given " + FeatureWithScenarioSteps_And_Throwing.ScenarioStep1Text.Replace(@"(\d+)", "12", StringComparison.InvariantCultureIgnoreCase);184 var step2Text = "And " + FeatureWithScenarioSteps_And_Throwing.ScenarioStep2Text.Replace(@"(\d+)", "15", StringComparison.InvariantCultureIgnoreCase);185 var step3Text = "When " + FeatureWithScenarioSteps_And_Throwing.ScenarioStep3Text;186 var step4Text = "Then " + FeatureWithScenarioSteps_And_Throwing.ScenarioStep4Text.Replace(@"(\d+)", "27", StringComparison.InvariantCultureIgnoreCase);187 var scenarioName = "scenario 12345";188 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithScenarioSteps_And_Throwing)}.feature"))189 .Returns(new FeatureFile(CreateGherkinDocument(scenarioName,190 new string[] 191 {192 step1Text,193 step2Text,194 step3Text,195 step4Text196 })))197 .Verifiable();198 var featureInstance = new FeatureWithScenarioSteps_And_Throwing();199 var output = new Mock<ITestOutputHelper>();200 featureInstance.InternalOutput = output.Object;201 //act.202 var exceptiion = await Assert.ThrowsAsync<TargetInvocationException>(async () => await _sut.ExecuteScenarioAsync(featureInstance, scenarioName));203 Assert.IsType<InvalidOperationException>(exceptiion.InnerException);204 //assert.205 _featureFileRepository.Verify();206 Assert.Equal(2, featureInstance.CallStack.Count);207 Assert.Equal(nameof(FeatureWithScenarioSteps_And_Throwing.ScenarioStep1), featureInstance.CallStack[0].Key);208 Assert.NotNull(featureInstance.CallStack[0].Value);209 Assert.Single(featureInstance.CallStack[0].Value);210 Assert.Equal(12, featureInstance.CallStack[0].Value[0]);211 output.Verify(o => o.WriteLine($"{step1Text}: PASSED"), Times.Once);212 Assert.Equal(nameof(FeatureWithScenarioSteps_And_Throwing.ScenarioStep2), featureInstance.CallStack[1].Key);213 Assert.NotNull(featureInstance.CallStack[1].Value);214 Assert.Single(featureInstance.CallStack[1].Value);215 Assert.Equal(15, featureInstance.CallStack[1].Value[0]);216 output.Verify(o => o.WriteLine($"{step2Text}: FAILED"), Times.Once);217 output.Verify(o => o.WriteLine($"{step3Text}: SKIPPED"), Times.Once);218 output.Verify(o => o.WriteLine($"{step4Text}: SKIPPED"), Times.Once);219 }220 private sealed class FeatureWithScenarioSteps_And_Throwing : Feature221 {222 public List<KeyValuePair<string, object[]>> CallStack { get; } = new List<KeyValuePair<string, object[]>>();223 [Given("Non matching given")]224 public void NonMatchingStep1_before()225 {226 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_before), null));227 }228 public const string ScenarioStep1Text = @"I chose (\d+) as first number";229 [Given(ScenarioStep1Text)]230 public void ScenarioStep1(int firstNumber)231 {232 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep1), new object[] { firstNumber }));233 }234 [Given("Non matching given")]235 public void NonMatchingStep1_after()236 {237 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_after), null));238 }239 [And("Non matching and")]240 public void NonMatchingStep2_before()241 {242 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_before), null));243 }244 public const string ScenarioStep2Text = @"I chose (\d+) as second number";245 [And(ScenarioStep2Text)]246 public void ScenarioStep2(int secondNumber)247 {248 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep2), new object[] { secondNumber }));249 throw new InvalidOperationException("Some exception to stop execution of next steps.");250 }251 [And("Non matching and")]252 public void NonMatchingStep2_after()253 {254 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_after), null));255 }256 [When("Non matching when")]257 public void NonMatchingStep3_before()258 {259 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_before), null));260 }261 public const string ScenarioStep3Text = "I press add";262 [When(ScenarioStep3Text)]263 public void ScenarioStep3()264 {265 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep3), null));266 }267 [When("Non matching when")]268 public void NonMatchingStep3_after()269 {270 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_after), null));271 }272 [Then("Non matching then")]273 public void NonMatchingStep4_before()274 {275 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_before), null));276 }277 public const string ScenarioStep4Text = @"the result should be (\d+) on the screen";278 [Then(ScenarioStep4Text)]279 public void ScenarioStep4(int result)280 {281 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep4), new object[] { result }));282 }283 [Then("Non matching then")]284 public void NonMatchingStep4_after()285 {286 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_after), null));287 }288 }289 [Fact]290 public async Task ExecuteScenario_Executes_Background_Steps_First()291 {292 var gherkinFeaure = new GherkinFeatureBuilder()293 .WithBackground(sb => sb294 .Given("given background", null)295 .When("when background", null)296 .Then("then background", null))297 .WithScenario("test scenario", sb => sb298 .Then("step one", null))299 .Build();300 var gherkinDocument = new Gherkin.Ast.GherkinDocument(gherkinFeaure, new Gherkin.Ast.Comment[0]);301 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithBackgroundSteps)}.feature"))302 .Returns(new FeatureFile(gherkinDocument))303 .Verifiable();304 var featureInstance = new FeatureWithBackgroundSteps();305 var output = new Mock<ITestOutputHelper>();306 featureInstance.InternalOutput = output.Object;307 //act.308 await _sut.ExecuteScenarioAsync(featureInstance, "test scenario");309 //assert.310 _featureFileRepository.Verify();311 Assert.Equal("abcd", featureInstance.OrderValidator);312 output.Verify(o => o.WriteLine($"Given given background: PASSED"), Times.Once);313 output.Verify(o => o.WriteLine($"When when background: PASSED"), Times.Once);314 output.Verify(o => o.WriteLine($"Then then background: PASSED"), Times.Once);315 output.Verify(o => o.WriteLine($"Then step one: PASSED"), Times.Once);316 }317 private sealed class FeatureWithBackgroundSteps : Feature318 {319 public string OrderValidator = String.Empty;320 [Given("given background")]321 public void GivenBackground()322 {323 OrderValidator += "a";324 }325 [When("when background")]326 public void WhenBackground()327 {328 OrderValidator += "b";329 }330 [Then("then background")]331 public void ThenBackground()332 {333 OrderValidator += "c";334 }335 [Then("step one")]336 public void ThenScenario()337 {338 OrderValidator += "d";339 }340 }341 [Fact]342 public async Task ExecuteScenario_Executes_ScenarioStep_With_DataTable()343 {344 //arrange.345 var scenarioName = "scenario123";346 var featureInstance = new FeatureWithDataTableScenarioStep();347 var output = new Mock<ITestOutputHelper>();348 featureInstance.InternalOutput = output.Object;349 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithDataTableScenarioStep)}.feature"))350 .Returns(new FeatureFile(CreateGherkinDocument(scenarioName,351 new string[] 352 {353 "When " + FeatureWithDataTableScenarioStep.Steptext354 },355 new Gherkin.Ast.DataTable(new Gherkin.Ast.TableRow[]356 {357 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]358 {359 new Gherkin.Ast.TableCell(null, "First argument"),360 new Gherkin.Ast.TableCell(null, "Second argument"),361 new Gherkin.Ast.TableCell(null, "Result"),362 }),363 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]364 {365 new Gherkin.Ast.TableCell(null, "1"),366 new Gherkin.Ast.TableCell(null, "2"),367 new Gherkin.Ast.TableCell(null, "3"),368 }),369 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]370 {371 new Gherkin.Ast.TableCell(null, "a"),372 new Gherkin.Ast.TableCell(null, "b"),373 new Gherkin.Ast.TableCell(null, "c"),374 })375 }))))376 .Verifiable();377 378 //act.379 await _sut.ExecuteScenarioAsync(featureInstance, scenarioName);380 //assert.381 _featureFileRepository.Verify();382 Assert.NotNull(featureInstance.ReceivedDataTable);383 Assert.Equal(3, featureInstance.ReceivedDataTable.Rows.Count());384 AssertDataTableCell(0, 0, "First argument");385 AssertDataTableCell(0, 1, "Second argument");386 AssertDataTableCell(0, 2, "Result");387 AssertDataTableCell(1, 0, "1");388 AssertDataTableCell(1, 1, "2");389 AssertDataTableCell(1, 2, "3");390 AssertDataTableCell(2, 0, "a");391 AssertDataTableCell(2, 1, "b");392 AssertDataTableCell(2, 2, "c");393 void AssertDataTableCell(int rowIndex, int cellIndex, string value)394 {395 Assert.True(featureInstance.ReceivedDataTable.Rows.Count() > rowIndex);396 Assert.NotNull(featureInstance.ReceivedDataTable.Rows.ElementAt(rowIndex));397 Assert.True(featureInstance.ReceivedDataTable.Rows.ElementAt(rowIndex).Cells.Count() > cellIndex);398 Assert.NotNull(featureInstance.ReceivedDataTable.Rows.ElementAt(rowIndex).Cells.ElementAt(cellIndex));399 Assert.Equal("First argument", featureInstance.ReceivedDataTable.Rows.ElementAt(0).Cells.ElementAt(0).Value);400 }401 }402 private sealed class FeatureWithDataTableScenarioStep : Feature403 {404 public Gherkin.Ast.DataTable ReceivedDataTable { get; private set; }405 public const string Steptext = "Some step text";406 [When(Steptext)]407 public void When_DataTable_Is_Expected(Gherkin.Ast.DataTable dataTable)408 {409 ReceivedDataTable = dataTable;410 }411 }412 [Fact]413 public async Task ExecuteScenario_Executes_ScenarioStep_With_DocString()414 {415 //arrange.416 var featureInstance = new FeatureWithDocStringScenarioStep();417 var output = new Mock<ITestOutputHelper>();418 featureInstance.InternalOutput = output.Object;419 var docStringContent = "some content" + Environment.NewLine +420"+++" + Environment.NewLine +421"with multi lines" + Environment.NewLine +422"---" + Environment.NewLine +423"in it";424 var scenarioName = "scenario 1231121";425 _featureFileRepository.Setup(r => r.GetByFilePath(nameof(FeatureWithDocStringScenarioStep) + ".feature"))426 .Returns(new FeatureFile(CreateGherkinDocument(scenarioName,427 new string[] { "Given " + FeatureWithDocStringScenarioStep.StepWithDocStringText },428 new Gherkin.Ast.DocString(null, null, docStringContent))))429 .Verifiable();430 //act.431 await _sut.ExecuteScenarioAsync(featureInstance, scenarioName);432 //assert.433 _featureFileRepository.Verify();434 Assert.NotNull(featureInstance.ReceivedDocString);435 Assert.Equal(docStringContent, featureInstance.ReceivedDocString.Content);436 }437 private sealed class FeatureWithDocStringScenarioStep : Feature438 {439 public Gherkin.Ast.DocString ReceivedDocString { get; private set; }440 public const string StepWithDocStringText = "Step with docstirng";441 [Given(StepWithDocStringText)]442 public void Step_With_DocString_Argument(Gherkin.Ast.DocString docString)443 {444 ReceivedDocString = docString;445 }446 }447 [Fact]448 public async Task ExecuteScenario_Executes_Scenario_With_Shared_StepMethod()449 {450 //arrange.451 const string scenarioName = "scenario 123";452 var featureInstance = new FeatureWithSharedStepMethod();453 var output = new Mock<ITestOutputHelper>();454 featureInstance.InternalOutput = output.Object;455 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithSharedStepMethod)}.feature"))456 .Returns(new FeatureFile(CreateGherkinDocument(scenarioName, new string[]457 {458 "Given I chose 1 as first number",459 "And I chose 2 as second number",460 "And I chose 3 as third number",461 "When I choose 4 as fourth number",462 "And I choose 5 as fifth number",463 "And I choose 6 as sixth number",464 $"Then Result should be {1+2+3+4+5+6} on the screen"465 })));466 //act.467 await _sut.ExecuteScenarioAsync(featureInstance, scenarioName);468 //assert.469 Assert.Equal(7, featureInstance.CallStack.Count);470 Assert_Callback(0, nameof(FeatureWithSharedStepMethod.Selecting_numbers), 1);471 Assert_Callback(1, nameof(FeatureWithSharedStepMethod.Selecting_numbers), 2);472 Assert_Callback(2, nameof(FeatureWithSharedStepMethod.Selecting_numbers), 3);473 Assert_Callback(3, nameof(FeatureWithSharedStepMethod.Selecting_numbers), 4);474 Assert_Callback(4, nameof(FeatureWithSharedStepMethod.Selecting_numbers), 5);475 Assert_Callback(5, nameof(FeatureWithSharedStepMethod.Selecting_numbers), 6);476 Assert_Callback(6, nameof(FeatureWithSharedStepMethod.Result_should_be_x_on_the_screen), (1 + 2 + 3 + 4 + 5 + 6));477 void Assert_Callback(int index, string methodName, int value)478 {479 Assert.Equal(methodName, featureInstance.CallStack[index].Key);480 Assert.NotNull(featureInstance.CallStack[index].Value);481 Assert.Single(featureInstance.CallStack[index].Value);482 Assert.Equal(value, featureInstance.CallStack[index].Value[0]);483 }484 }485 private sealed class FeatureWithSharedStepMethod : Feature486 {487 public List<KeyValuePair<string, object[]>> CallStack { get; } = new List<KeyValuePair<string, object[]>>();488 [Given(@"I chose (\d+) as first number")]489 [And(@"I chose (\d+) as second number")]490 [And(@"I chose (\d+) as third number")]491 [When(@"I choose (\d+) as fourth number")]492 [And(@"I choose (\d+) as fifth number")]493 [And(@"I choose (\d+) as sixth number")]494 public void Selecting_numbers(int x)495 {496 CallStack.Add(new KeyValuePair<string, object[]>(nameof(Selecting_numbers), new object[] { x }));497 }498 [Then(@"Result should be (\d+) on the screen")]499 public void Result_should_be_x_on_the_screen(int x)500 {501 CallStack.Add(new KeyValuePair<string, object[]>(nameof(Result_should_be_x_on_the_screen), new object[] { x }));502 }503 }504 [Fact]505 public async Task ExecuteScenario_Executes_Scenario_With_Star_Notation()506 {507 //arrange.508 var gherkinFeature = new GherkinFeatureBuilder()509 .WithScenario("S", steps => steps.Star("I have some cukes", null))510 .Build();511512 _featureFileRepository.Setup(r => r.GetByFilePath($"{nameof(FeatureWithStarNotation)}.feature"))513 .Returns(new FeatureFile(new Gherkin.Ast.GherkinDocument(gherkinFeature, null)))514 .Verifiable();515516 var featureInstance = new FeatureWithStarNotation();517 var output = new Mock<ITestOutputHelper>();518 featureInstance.InternalOutput = output.Object;519520 //act.521 await _sut.ExecuteScenarioAsync(featureInstance, "S");522523 //assert.524 _featureFileRepository.Verify();525526 Assert.Single(featureInstance.CallStack);527 Assert.Equal(nameof(FeatureWithStarNotation.I_Have_Some_Cukes), featureInstance.CallStack[0].Key);528 }529 private sealed class FeatureWithStarNotation : Feature530 {531 public List<KeyValuePair<string, object[]>> CallStack { get; } = new List<KeyValuePair<string, object[]>>();532533 [Given("I have some cukes")]534 public void I_Have_Some_Cukes()535 {536 CallStack.Add(new KeyValuePair<string, object[]>(nameof(I_Have_Some_Cukes), null));537 }538 }539 [Fact]540 public async Task ExecuteScenario_DoesNotAllow_AsyncVoid_Steps()541 {542 //arrange.543 var feature = new FeatureWithAsyncVoidStep();544 var output = new Mock<ITestOutputHelper>();545 feature.InternalOutput = output.Object;546547 //act / assert.548 await Assert.ThrowsAsync<InvalidOperationException>(async () => await _sut.ExecuteScenarioAsync(feature, "S"));549 }550 private sealed class FeatureWithAsyncVoidStep : Feature551 {552 [Given("Any step text")]553 public async void StepWithAsyncVoid()554 {555 await Task.CompletedTask;556 }557 }558 }559}...
StepMethodInfoTests.cs
Source:StepMethodInfoTests.cs
...15 [Fact]16 public void Ctor_Initializes_Properties()17 {18 //arrange.19 var featureInstance = new FeatureForCtorTest();20 //act.21 var sut = StepMethodInfo.FromMethodInfo(featureInstance.GetType().GetMethod(nameof(FeatureForCtorTest.When_Something)), featureInstance);22 //assert.23 Assert.NotNull(sut);24 Assert.NotNull(sut.ScenarioStepPatterns);25 Assert.Single(sut.ScenarioStepPatterns);26 Assert.Equal(PatternKind.When, sut.ScenarioStepPatterns[0].Kind);27 Assert.Equal(FeatureForCtorTest.WhenStepText, sut.ScenarioStepPatterns[0].OriginalPattern);28 }29 private sealed class FeatureForCtorTest : Feature30 {31 public const string WhenStepText = "some text 123";32 [When(WhenStepText)]33 public void When_Something()34 {35 }36 }37 [Fact]38 public void Clone_Creates_Similar_Instance()39 {40 //arrange.41 var featureInstance = new FeatureForCtorTest();42 var sut = StepMethodInfo.FromMethodInfo(featureInstance.GetType().GetMethod(nameof(FeatureForCtorTest.When_Something)), featureInstance);43 //act.44 var clone = sut.Clone();45 //assert.46 Assert.NotNull(clone);47 Assert.True(clone.IsSameAs(sut));48 }49 [Fact]50 public void IsSameAs_Identifies_Similar_Instances()51 {52 //arrange.53 var featureInstance = new FeatureForCtorTest();54 var sut = StepMethodInfo.FromMethodInfo(featureInstance.GetType().GetMethod(nameof(FeatureForCtorTest.When_Something)), featureInstance);55 var clone = StepMethodInfo.FromMethodInfo(featureInstance.GetType().GetMethod(nameof(FeatureForCtorTest.When_Something)), featureInstance);56 //act.57 var same = sut.IsSameAs(clone) && clone.IsSameAs(sut);58 //assert.59 Assert.True(same);60 }61 [Fact]62 public void DigestScenarioStepValues_Expects_Exact_Number_Of_Groups_Not_Less()63 {64 //arrange.65 var featureInstance = new FeatureForApplyArgumentValues_LessThanNeededGroups();66 var sut = StepMethodInfo.FromMethodInfo(67 featureInstance.GetType().GetMethod(nameof(FeatureForApplyArgumentValues_LessThanNeededGroups.Method_With_Arguments)),68 featureInstance);69 var number = 123;70 var text = "Ana";71 var date = new DateTime(2018, 5, 23);72 var stepText = FeatureForApplyArgumentValues_LessThanNeededGroups.StepMethodText73 .Replace(@"(\d+)", $"{number}")74 .Replace(@"(\w+)", $"{text}");75 var step = new Gherkin.Ast.Step(null, "Then", stepText, null);76 //act / assert.77 Assert.Throws<InvalidOperationException>(() => sut.DigestScenarioStepValues(step));78 }79 private sealed class FeatureForApplyArgumentValues_LessThanNeededGroups : Feature80 {81 public const string StepMethodText = @"I should have (\d+) apples from (\w+) by 5/23/2018";82 [Then(StepMethodText)]83 public void Method_With_Arguments(int number, string text, DateTime date)84 { }85 }86 [Theory]87 [InlineData("Then")]88 [InlineData("*")]89 public void DigestScenarioStepValues_Sets_Primitive_Values(string keyword)90 {91 //arrange.92 var featureInstance = new FeatureForApplyArgumentValues();93 var sut = StepMethodInfo.FromMethodInfo(94 featureInstance.GetType().GetMethod(nameof(FeatureForApplyArgumentValues.Method_With_Arguments)),95 featureInstance);96 var number = 123;97 var text = "Ana";98 var date = new DateTime(2018, 5, 23);99 var stepText = FeatureForApplyArgumentValues.StepMethodText100 .Replace(@"(\d+)", $"{number}")101 .Replace(@"(\w+)", $"{text}")102 .Replace(@"([\d/]+)", $"{date.Month}/{date.Day}/{date.Year}");103 var step = new Gherkin.Ast.Step(null, keyword, stepText, null);104 //act.105 sut.DigestScenarioStepValues(step);106 //assert.107 var digestedText = sut.GetDigestedStepText();108 Assert.Equal(stepText, digestedText);109 }110 111 private sealed class FeatureForApplyArgumentValues : Feature112 {113 public const string StepMethodText = @"I should have (\d+) apples from (\w+) by ([\d/]+)";114 [Then(StepMethodText)]115 public void Method_With_Arguments(int number, string text, DateTime date)116 { }117 }118 [Fact]119 public async Task Execute_Invokes_StepMethod()120 {121 //arrange.122 var featureInstance = new FeatureForExecuteTest();123 var sut = StepMethodInfo.FromMethodInfo(featureInstance.GetType().GetMethod(nameof(FeatureForExecuteTest.Call_This_Method)), featureInstance);124 //act.125 await sut.ExecuteAsync();126 //assert.127 Assert.True(featureInstance.Called);128 }129 private sealed class FeatureForExecuteTest : Feature130 {131 public bool Called { get; private set; } = false;132 [And("Call this")]133 public void Call_This_Method()134 {135 Called = true;136 }137 }138 [Fact]139 public void GetDigestedStepText_Throws_Error_If_Not_Yet_Digested()140 {141 //arrange.142 var featureInstance = new Feature_For_GetDigestedStepTextTest();143 var sut = StepMethodInfo.FromMethodInfo(featureInstance.GetType().GetMethod(nameof(Feature_For_GetDigestedStepTextTest.When_Something_Method)), featureInstance);144 //act / assert.145 Assert.Throws<InvalidOperationException>(() => sut.GetDigestedStepText());146 }147 private sealed class Feature_For_GetDigestedStepTextTest : Feature148 {149 [When("something")]150 public void When_Something_Method() { }151 }152 [Fact]153 public void FromMethodInfo_Creates_StepMethodInfo_With_DataTable()154 {155 //arrange.156 var featureInstance = new FeatureWithDataTableScenarioStep();157 //act.158 var sut = StepMethodInfo.FromMethodInfo(159 featureInstance.GetType().GetMethod(nameof(FeatureWithDataTableScenarioStep.When_DataTable_Is_Expected)),160 featureInstance161 );162 //assert.163 Assert.NotNull(sut);164 }165 [Fact]166 public void DigestScenarioStepValues_Sets_DataTable_Value()167 {168 //arrange.169 var featureInstance = new FeatureWithDataTableScenarioStep();170 var sut = StepMethodInfo.FromMethodInfo(171 featureInstance.GetType().GetMethod(nameof(FeatureWithDataTableScenarioStep.When_DataTable_Is_Expected)),172 featureInstance173 );174 var step = new Gherkin.Ast.Step(175 null,176 "When",177 FeatureWithDataTableScenarioStep.Steptext,178 new Gherkin.Ast.DataTable(new Gherkin.Ast.TableRow[]179 {180 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]181 {182 new Gherkin.Ast.TableCell(null, "First argument"),183 new Gherkin.Ast.TableCell(null, "Second argument"),184 new Gherkin.Ast.TableCell(null, "Result"),185 }),186 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]187 {188 new Gherkin.Ast.TableCell(null, "1"),189 new Gherkin.Ast.TableCell(null, "2"),190 new Gherkin.Ast.TableCell(null, "3"),191 }),192 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]193 {194 new Gherkin.Ast.TableCell(null, "a"),195 new Gherkin.Ast.TableCell(null, "b"),196 new Gherkin.Ast.TableCell(null, "c"),197 })198 }));199 //act.200 sut.DigestScenarioStepValues(step);201 //assert.202 var digestedText = sut.GetDigestedStepText();203 Assert.Equal(FeatureWithDataTableScenarioStep.Steptext, digestedText);204 }205 private sealed class FeatureWithDataTableScenarioStep : Feature206 {207 public Gherkin.Ast.DataTable ReceivedDataTable { get; private set; }208 public const string Steptext = "Some step text";209 [When(Steptext)]210 public void When_DataTable_Is_Expected(Gherkin.Ast.DataTable dataTable)211 {212 ReceivedDataTable = dataTable;213 }214 }215 [Fact]216 public void FromMethodInfo_Creates_StepMethodInfo_With_DocString()217 {218 //arrange.219 var featureInstance = new FeatureWithDocStringScenarioStep();220 //act.221 var sut = StepMethodInfo.FromMethodInfo(222 featureInstance.GetType().GetMethod(nameof(FeatureWithDocStringScenarioStep.Step_With_DocString_Argument)),223 featureInstance224 );225 //assert.226 Assert.NotNull(sut);227 }228 private sealed class FeatureWithDocStringScenarioStep : Feature229 {230 public Gherkin.Ast.DocString ReceivedDocString { get; private set; }231 public const string StepWithDocStringText = "Step with docstirng";232 [Given(StepWithDocStringText)]233 public void Step_With_DocString_Argument(Gherkin.Ast.DocString docString)234 {235 ReceivedDocString = docString;236 }237 }238 [Fact]239 public void DigestScenarioStepValues_Sets_DocString_Value()240 {241 //arrange.242 var featureInstance = new FeatureWithDocStringScenarioStep();243 var sut = StepMethodInfo.FromMethodInfo(244 featureInstance.GetType().GetMethod(nameof(FeatureWithDocStringScenarioStep.Step_With_DocString_Argument)),245 featureInstance246 );247 var docStringContent = @"some content248+++249with multi lines250---251in it";252 var step = new Gherkin.Ast.Step(253 null,254 "Given",255 FeatureWithDocStringScenarioStep.StepWithDocStringText,256 new Gherkin.Ast.DocString(null, null, docStringContent));257 //act.258 sut.DigestScenarioStepValues(step);259 //assert.260 var digestedText = sut.GetDigestedStepText();261 Assert.Equal(FeatureWithDocStringScenarioStep.StepWithDocStringText, digestedText);262 }263 [Fact]264 public void FromMethodInfo_Creates_StepMethodInfo_With_Multiple_Patterns()265 {266 //arrange.267 var featureInstance = new FeatureWithMultipleStepPatterns();268 //act.269 var sut = StepMethodInfo.FromMethodInfo(270 featureInstance.GetType().GetMethod(nameof(FeatureWithMultipleStepPatterns.Step_With_Multiple_Patterns)),271 featureInstance);272 //assert.273 Assert.NotNull(sut);274 Assert.Equal(10, sut.ScenarioStepPatterns.Count);275 AssertPattern(0, PatternKind.Given, "something");276 AssertPattern(1, PatternKind.Given, "something else");277 AssertPattern(2, PatternKind.And, "something");278 AssertPattern(3, PatternKind.And, "something else");279 AssertPattern(4, PatternKind.When, "something");280 AssertPattern(5, PatternKind.When, "something else");281 AssertPattern(6, PatternKind.And, "something");282 AssertPattern(7, PatternKind.And, "something else");283 AssertPattern(8, PatternKind.But, "something");284 AssertPattern(9, PatternKind.But, "something else");285 void AssertPattern(int index, PatternKind patternKind, string pattern)286 {287 var thePattern = sut.ScenarioStepPatterns[index];288 Assert.NotNull(thePattern);289 Assert.Equal(patternKind, thePattern.Kind);290 Assert.Equal(pattern, thePattern.OriginalPattern);291 }292 }293 private sealed class FeatureWithMultipleStepPatterns : Feature294 {295 [Given("something")]296 [Given("something else")]297 [And("something")]298 [And("something else")]299 [When("something")]300 [When("something else")]301 [And("something")]302 [And("something else")]303 [But("something")]304 [But("something else")]305 public void Step_With_Multiple_Patterns()306 { }307 }308 [Fact]309 public void FromMethodInfo_DoesNotAllow_AsyncAvoid_Steps()310 {311 //arrange.312 var featureInstance = new FeatureWithAsyncVoidStep();313 var methodInfo = typeof(FeatureWithAsyncVoidStep).GetMethod(nameof(FeatureWithAsyncVoidStep.StepWithAsyncVoid));314315 //act / assert.316 Assert.Throws<InvalidOperationException>(() => StepMethodInfo.FromMethodInfo(methodInfo, featureInstance));317 }318 private sealed class FeatureWithAsyncVoidStep : Feature319 {320 [Given("Any step text")]321 public async void StepWithAsyncVoid()322 {323 await Task.CompletedTask;324 }325 }326 [Fact]327 public void GetMethodName_Returns_Wrapped_Method_Name()328 {329 //arrange.330 var featureInstance = new FeatureForMethodName();331 var sut = StepMethodInfo.FromMethodInfo(332 featureInstance.GetType().GetMethod(nameof(FeatureForMethodName.Step_Name_Must_Be_This)),333 featureInstance334 );335 //act.336 var methodName = sut.GetMethodName();337 //assert.338 Assert.Equal(nameof(FeatureForMethodName.Step_Name_Must_Be_This), methodName);339 }340 private sealed class FeatureForMethodName : Feature341 {342 [Given("something")]343 public void Step_Name_Must_Be_This()344 {345 }346 }347 [Theory]348 [InlineData("When")]349 [InlineData("*")]350 public void GetMatchingPattern_Finds_Match_For_Step(string keyword)351 {352 //arrange.353 var featureInstance = new FeatureForMatch();354 var sut = StepMethodInfo.FromMethodInfo(355 typeof(FeatureForMatch).GetMethod(nameof(FeatureForMatch.Method1)),356 featureInstance);357358 //act.359 var match = sut.GetMatchingPattern(new Gherkin.Ast.Step(null, keyword, "this matches", null));360361 //assert.362 Assert.NotNull(match);363 Assert.Equal(PatternKind.When, match.Kind);364 Assert.Equal("this matches", match.OriginalPattern);365 }366 [Fact]367 public void GetMatchingPattern_Finds_Nothing_When_No_Match()368 {369 //arrange.370 var featureInstance = new FeatureForMatch();371 var sut = StepMethodInfo.FromMethodInfo(372 typeof(FeatureForMatch).GetMethod(nameof(FeatureForMatch.Method1)),373 featureInstance);374375 //act.376 var match = sut.GetMatchingPattern(new Gherkin.Ast.Step(null, "When", "this does not matches", null));377378 //assert.379 Assert.Null(match);380 }381 [Theory]382 [InlineData("When")]383 [InlineData("*")]384 public void Match_IsPositive_For_Corresponding_Step(string keyword)385 {386 //arrange.387 var featureInstance = new FeatureForMatch();388 var sut = StepMethodInfo.FromMethodInfo(389 typeof(FeatureForMatch).GetMethod(nameof(FeatureForMatch.Method1)),390 featureInstance);391392 //act.393 var match = sut.Matches(new Gherkin.Ast.Step(null, keyword, "this matches", null));394395 //assert.396 Assert.True(match);397 }398399 [Fact]400 public void Match_IsNegative_For_Different_Step()401 {402 //arrange.403 var featureInstance = new FeatureForMatch();404 var sut = StepMethodInfo.FromMethodInfo(405 typeof(FeatureForMatch).GetMethod(nameof(FeatureForMatch.Method1)),406 featureInstance);407408 //act.409 var match = sut.Matches(new Gherkin.Ast.Step(null, "When", "this does not matches", null));410411 //assert.412 Assert.False(match);413 }414 private sealed class FeatureForMatch : Feature415 {416 [When("this matches")]417 public void Method1()418 {419 }420 }421 }422}...
GherkinFeatureTests.cs
Source:GherkinFeatureTests.cs
...3using Xunit;4using Xunit.Gherkin.Quick;5namespace UnitTests6{7 public sealed class GherkinFeatureTests8 {9 public static object[][] DataFor_Feature_And_Scenario_Null_Arguments10 {11 get12 {13 return new object[][] 14 {15 new object[]{ new Gherkin.Ast.Feature(null, null, null, null, null, null, null), null },16 new object[]{ null, "scenario name" }17 };18 }19 }20 [Theory]21 [MemberData(nameof(DataFor_Feature_And_Scenario_Null_Arguments))]22 public void GetScenarioTags_Requires_Arguments(23 Gherkin.Ast.Feature feature,24 string scenarioName25 )26 {27 //act / assert.28 Assert.Throws<ArgumentNullException>(() => feature.GetScenarioTags(scenarioName));29 }30 [Fact]31 public void GetScenarioTags_Retrieves_Tags_Of_Feature_And_Scenario_Combined()32 {33 //arrange.34 var featureTags = new Gherkin.Ast.Tag[] 35 {36 new Gherkin.Ast.Tag(null, "featuretag-1"),37 new Gherkin.Ast.Tag(null, "featuretag-2")38 };39 var scenarioTags = new Gherkin.Ast.Tag[] 40 {41 new Gherkin.Ast.Tag(null, "scenarioTag-1"),42 new Gherkin.Ast.Tag(null, "scenarioTag-2"),43 new Gherkin.Ast.Tag(null, "scenarioTag-3")44 };45 var scenarioName = "scenario name 123";46 var feature = new Gherkin.Ast.Feature(47 featureTags, null, null, null, null, null,48 new Gherkin.Ast.ScenarioDefinition[] 49 {50 new Gherkin.Ast.Scenario(scenarioTags, null, null, scenarioName, null, null)51 });52 //act.53 var scenarioTagNames = feature.GetScenarioTags(scenarioName);54 //assert.55 Assert.NotNull(scenarioTagNames);56 var expectedTagNames = featureTags.Union(scenarioTags).Select(t => t.Name);57 Assert.Equal(expectedTagNames, scenarioTagNames);58 }59 60 [Theory]61 [MemberData(nameof(DataFor_Feature_And_Scenario_Null_Arguments))]62 public void IsScenarioIgnored_Requires_Arguments(63 Gherkin.Ast.Feature feature,64 string scenarioName65 )66 {67 //act / assert.68 Assert.Throws<ArgumentNullException>(() => feature.IsScenarioIgnored(scenarioName));69 }70 [Fact]71 public void IsScenarioIgnored_Does_Not_Treat_Ignored_If_No_Ignore_Tag()72 {73 //arrange.74 var featureTags = new Gherkin.Ast.Tag[]75 {76 new Gherkin.Ast.Tag(null, "featuretag-1"),77 new Gherkin.Ast.Tag(null, "featuretag-2")78 };79 var scenarioTags = new Gherkin.Ast.Tag[]80 {81 new Gherkin.Ast.Tag(null, "scenarioTag-1"),82 new Gherkin.Ast.Tag(null, "scenarioTag-2"),83 new Gherkin.Ast.Tag(null, "scenarioTag-3")84 };85 var scenarioName = "scenario name 123";86 var feature = new Gherkin.Ast.Feature(87 featureTags, null, null, null, null, null,88 new Gherkin.Ast.ScenarioDefinition[]89 {90 new Gherkin.Ast.Scenario(scenarioTags, null, null, scenarioName, null, null)91 });92 //act.93 var isIgnored = feature.IsScenarioIgnored(scenarioName);94 //assert.95 Assert.False(isIgnored);96 }97 [Fact]98 public void IsScenarioIgnored_Treats_Ignored_If_Feature_Is_Ignored()99 {100 //arrange.101 var featureTags = new Gherkin.Ast.Tag[]102 {103 new Gherkin.Ast.Tag(null, "featuretag-1"),104 new Gherkin.Ast.Tag(null, GherkinFeatureExtensions.IgnoreTag)105 };106 var scenarioTags = new Gherkin.Ast.Tag[]107 {108 new Gherkin.Ast.Tag(null, "scenarioTag-1"),109 new Gherkin.Ast.Tag(null, "scenarioTag-2"),110 new Gherkin.Ast.Tag(null, "scenarioTag-3")111 };112 var scenarioName = "scenario name 123";113 var feature = new Gherkin.Ast.Feature(114 featureTags, null, null, null, null, null,115 new Gherkin.Ast.ScenarioDefinition[]116 {117 new Gherkin.Ast.Scenario(scenarioTags, null, null, scenarioName, null, null)118 });119 //act.120 var isIgnored = feature.IsScenarioIgnored(scenarioName);121 //assert.122 Assert.True(isIgnored);123 }124 [Fact]125 public void IsScenarioIgnored_Treats_Ignored_If_Scenario_Is_Ignored()126 {127 //arrange.128 var featureTags = new Gherkin.Ast.Tag[]129 {130 new Gherkin.Ast.Tag(null, "featuretag-1"),131 new Gherkin.Ast.Tag(null, "featuretag-2")132 };133 var scenarioTags = new Gherkin.Ast.Tag[]134 {135 new Gherkin.Ast.Tag(null, "scenarioTag-1"),136 new Gherkin.Ast.Tag(null, GherkinFeatureExtensions.IgnoreTag),137 new Gherkin.Ast.Tag(null, "scenarioTag-3")138 };139 var scenarioName = "scenario name 123";140 var feature = new Gherkin.Ast.Feature(141 featureTags, null, null, null, null, null,142 new Gherkin.Ast.ScenarioDefinition[]143 {144 new Gherkin.Ast.Scenario(scenarioTags, null, null, scenarioName, null, null)145 });146 //act.147 var isIgnored = feature.IsScenarioIgnored(scenarioName);148 //assert.149 Assert.True(isIgnored);150 }151 public static object[][] DataFor_Feature_And_ScenarioOutline_And_Examples_Null_Arguments152 {153 get154 {155 return new object[][]156 {157 new object[]{ null, "scenario outline name", "examples name" },158 new object[]{ new Gherkin.Ast.Feature(null, null, null, null, null, null, null), null, "examples name" },159 new object[]{ new Gherkin.Ast.Feature(null, null, null, null, null, null, null), "scenario outline name", null }160 };161 }162 }163 [Theory]164 [MemberData(nameof(DataFor_Feature_And_ScenarioOutline_And_Examples_Null_Arguments))]165 public void GetExamplesTags_Requires_Arguments(166 Gherkin.Ast.Feature feature,167 string scenarioOutlineName,168 string examplesName169 )170 {171 //act / assert.172 Assert.Throws<ArgumentNullException>(() => feature.GetExamplesTags(173 scenarioOutlineName,174 examplesName));175 }176 [Fact]177 public void GetExamplesTags_Retrieves_Tags_Of_Feature_And_OutLine_And_Examples_Combined()178 {179 //arrange.180 var featureTags = new Gherkin.Ast.Tag[]181 {182 new Gherkin.Ast.Tag(null, "featuretag-1"),183 new Gherkin.Ast.Tag(null, "featuretag-2")184 };185 var outlineTags = new Gherkin.Ast.Tag[]186 {187 new Gherkin.Ast.Tag(null, "outlinetag-1"),188 new Gherkin.Ast.Tag(null, "outlinetag-2"),189 new Gherkin.Ast.Tag(null, "outlinetag-3")190 };191 var examplesTags = new Gherkin.Ast.Tag[]192 {193 new Gherkin.Ast.Tag(null, "examplestag-1"),194 new Gherkin.Ast.Tag(null, "examplestag-2"),195 new Gherkin.Ast.Tag(null, "examplestag-2"),196 new Gherkin.Ast.Tag(null, "examplestag-3")197 };198 var scenarioOutlineName = "scenario name 123";199 var examplesName = "examples name 123";200 var feature = new Gherkin.Ast.Feature(201 featureTags, null, null, null, null, null,202 new Gherkin.Ast.ScenarioDefinition[]203 {204 new Gherkin.Ast.ScenarioOutline(outlineTags, null, null, scenarioOutlineName, null, null,205 new Gherkin.Ast.Examples[]206 {207 new Gherkin.Ast.Examples(examplesTags, null, null, examplesName, null, null, null)208 })209 });210 //act.211 var examplesTagNames = feature.GetExamplesTags(scenarioOutlineName, examplesName);212 //assert.213 Assert.NotNull(examplesTagNames);214 var expectedTagNames = featureTags.Union(outlineTags).Union(examplesTags).Select(t => t.Name);215 Assert.Equal(expectedTagNames, examplesTagNames);216 }217 [Theory]218 [MemberData(nameof(DataFor_Feature_And_ScenarioOutline_And_Examples_Null_Arguments))]219 public void IsExamplesIgnored_Requires_Arguments(220 Gherkin.Ast.Feature feature,221 string scenarioOutlineName,222 string examplesName223 )224 {225 //act / assert.226 Assert.Throws<ArgumentNullException>(() => feature.IsExamplesIgnored(scenarioOutlineName, examplesName));227 }228 [Fact]229 public void IsExamplesIgnored_Does_Not_Treat_Ignored_If_No_Ignore_Tag()230 {231 //arrange.232 var featureTags = new Gherkin.Ast.Tag[]233 {234 new Gherkin.Ast.Tag(null, "featuretag-1"),235 new Gherkin.Ast.Tag(null, "featuretag-2")236 };237 var outlineTags = new Gherkin.Ast.Tag[]238 {239 new Gherkin.Ast.Tag(null, "outlinetag-1"),240 new Gherkin.Ast.Tag(null, "outlinetag-2"),241 new Gherkin.Ast.Tag(null, "outlinetag-3")242 };243 var examplesTags = new Gherkin.Ast.Tag[]244 {245 new Gherkin.Ast.Tag(null, "examplestag-1"),246 new Gherkin.Ast.Tag(null, "examplestag-2"),247 new Gherkin.Ast.Tag(null, "examplestag-2"),248 new Gherkin.Ast.Tag(null, "examplestag-3")249 };250 var scenarioOutlineName = "scenario name 123";251 var examplesName = "examples name 123";252 var feature = new Gherkin.Ast.Feature(253 featureTags, null, null, null, null, null,254 new Gherkin.Ast.ScenarioDefinition[]255 {256 new Gherkin.Ast.ScenarioOutline(outlineTags, null, null, scenarioOutlineName, null, null,257 new Gherkin.Ast.Examples[]258 {259 new Gherkin.Ast.Examples(examplesTags, null, null, examplesName, null, null, null)260 })261 });262 //act.263 var isIgnored = feature.IsExamplesIgnored(scenarioOutlineName, examplesName);264 //assert.265 Assert.False(isIgnored);266 }267 [Fact]268 public void IsExamplesIgnored_Treats_Ignored_If_Feature_Is_Ignored()269 {270 //arrange.271 var featureTags = new Gherkin.Ast.Tag[]272 {273 new Gherkin.Ast.Tag(null, "featuretag-1"),274 new Gherkin.Ast.Tag(null, GherkinFeatureExtensions.IgnoreTag)275 };276 var outlineTags = new Gherkin.Ast.Tag[]277 {278 new Gherkin.Ast.Tag(null, "outlinetag-1"),279 new Gherkin.Ast.Tag(null, "outlinetag-2"),280 new Gherkin.Ast.Tag(null, "outlinetag-3")281 };282 var examplesTags = new Gherkin.Ast.Tag[]283 {284 new Gherkin.Ast.Tag(null, "examplestag-1"),285 new Gherkin.Ast.Tag(null, "examplestag-2"),286 new Gherkin.Ast.Tag(null, "examplestag-2"),287 new Gherkin.Ast.Tag(null, "examplestag-3")288 };289 var scenarioOutlineName = "scenario name 123";290 var examplesName = "examples name 123";291 var feature = new Gherkin.Ast.Feature(292 featureTags, null, null, null, null, null,293 new Gherkin.Ast.ScenarioDefinition[]294 {295 new Gherkin.Ast.ScenarioOutline(outlineTags, null, null, scenarioOutlineName, null, null,296 new Gherkin.Ast.Examples[]297 {298 new Gherkin.Ast.Examples(examplesTags, null, null, examplesName, null, null, null)299 })300 });301 //act.302 var isIgnored = feature.IsExamplesIgnored(scenarioOutlineName, examplesName);303 //assert.304 Assert.True(isIgnored);305 }306 [Fact]307 public void IsExamplesIgnored_Treats_Ignored_If_ScenarioOutline_Is_Ignored()308 {309 //arrange.310 var featureTags = new Gherkin.Ast.Tag[]311 {312 new Gherkin.Ast.Tag(null, "featuretag-1"),313 new Gherkin.Ast.Tag(null, "featuretag-1")314 };315 var outlineTags = new Gherkin.Ast.Tag[]316 {317 new Gherkin.Ast.Tag(null, "outlinetag-1"),318 new Gherkin.Ast.Tag(null, GherkinFeatureExtensions.IgnoreTag),319 new Gherkin.Ast.Tag(null, "outlinetag-3")320 };321 var examplesTags = new Gherkin.Ast.Tag[]322 {323 new Gherkin.Ast.Tag(null, "examplestag-1"),324 new Gherkin.Ast.Tag(null, "examplestag-2"),325 new Gherkin.Ast.Tag(null, "examplestag-2"),326 new Gherkin.Ast.Tag(null, "examplestag-3")327 };328 var scenarioOutlineName = "scenario name 123";329 var examplesName = "examples name 123";330 var feature = new Gherkin.Ast.Feature(331 featureTags, null, null, null, null, null,332 new Gherkin.Ast.ScenarioDefinition[]333 {334 new Gherkin.Ast.ScenarioOutline(outlineTags, null, null, scenarioOutlineName, null, null,335 new Gherkin.Ast.Examples[]336 {337 new Gherkin.Ast.Examples(examplesTags, null, null, examplesName, null, null, null)338 })339 });340 //act.341 var isIgnored = feature.IsExamplesIgnored(scenarioOutlineName, examplesName);342 //assert.343 Assert.True(isIgnored);344 }345 [Fact]346 public void IsExamplesIgnored_Treats_Ignored_If_Examples_Is_Ignored()347 {348 //arrange.349 var featureTags = new Gherkin.Ast.Tag[]350 {351 new Gherkin.Ast.Tag(null, "featuretag-1"),352 new Gherkin.Ast.Tag(null, "featuretag-2")353 };354 var outlineTags = new Gherkin.Ast.Tag[]355 {356 new Gherkin.Ast.Tag(null, "outlinetag-1"),357 new Gherkin.Ast.Tag(null, "outlinetag-2"),358 new Gherkin.Ast.Tag(null, "outlinetag-3")359 };360 var examplesTags = new Gherkin.Ast.Tag[]361 {362 new Gherkin.Ast.Tag(null, "examplestag-1"),363 new Gherkin.Ast.Tag(null, "examplestag-2"),364 new Gherkin.Ast.Tag(null, GherkinFeatureExtensions.IgnoreTag),365 new Gherkin.Ast.Tag(null, "examplestag-3")366 };367 var scenarioOutlineName = "scenario name 123";368 var examplesName = "examples name 123";369 var feature = new Gherkin.Ast.Feature(370 featureTags, null, null, null, null, null,371 new Gherkin.Ast.ScenarioDefinition[]372 {373 new Gherkin.Ast.ScenarioOutline(outlineTags, null, null, scenarioOutlineName, null, null,374 new Gherkin.Ast.Examples[]375 {376 new Gherkin.Ast.Examples(examplesTags, null, null, examplesName, null, null, null)377 })378 });379 //act.380 var isIgnored = feature.IsExamplesIgnored(scenarioOutlineName, examplesName);381 //assert.382 Assert.True(isIgnored);383 }...
FeatureClassTests.cs
Source:FeatureClassTests.cs
...5using Xunit;6using Xunit.Gherkin.Quick;7namespace UnitTests8{9 public sealed class FeatureClassTests10 {11 [Fact]12 public void FromFeatureInstance_Creates_FeatureClass_With_Default_FilePath_If_No_Attribute()13 {14 //arrange.15 var featureInstance = new FeatureWithoutFilePath();16 //act.17 var sut = FeatureClass.FromFeatureInstance(featureInstance);18 //assert.19 Assert.NotNull(sut);20 Assert.Equal($"{nameof(FeatureWithoutFilePath)}.feature", sut.FeatureFilePath);21 }22 private sealed class FeatureWithoutFilePath : Feature23 {24 }25 [Fact]26 public void FromFeatureInstance_Creates_FeatureClass_With_FilePath_From_Attribute()27 {28 //arrange.29 var featureInstance = new FeatureWithFilePath();30 //act.31 var sut = FeatureClass.FromFeatureInstance(featureInstance);32 //assert.33 Assert.NotNull(sut);34 Assert.Equal(FeatureWithFilePath.PathFor_FeatureWithFilePath, sut.FeatureFilePath);35 }36 [FeatureFile(PathFor_FeatureWithFilePath)]37 private sealed class FeatureWithFilePath : Feature38 {39 public const string PathFor_FeatureWithFilePath = "some file path const 123";40 }41 [Fact]42 public void FromFeatureInstance_DoesNotAllow_AsyncVoid_Steps()43 {44 var featureInstance = new FeatureWithAsyncVoidStep();4546 //act / assert.47 Assert.Throws<InvalidOperationException>(() => FeatureClass.FromFeatureInstance(featureInstance));48 }49 private sealed class FeatureWithAsyncVoidStep : Feature50 {51 [Given("Any step text")]52 public async void StepWithAsyncVoid()53 {54 await Task.CompletedTask;55 }56 }57 [Fact]58 public void ExtractScenario_Extracts_Scenario_Without_Background()59 {60 //arrange.61 var scenarioName = "some scenario name 123";62 var featureInstance = new FeatureWithMatchingScenarioStepsToExtract();63 var sut = FeatureClass.FromFeatureInstance(featureInstance);64 var gherkinScenario = CreateGherkinDocument(scenarioName,65 new string[]66 {67 "Given " + FeatureWithMatchingScenarioStepsToExtract.ScenarioStep1Text.Replace(@"(\d+)", "12", StringComparison.InvariantCultureIgnoreCase),68 "And " + FeatureWithMatchingScenarioStepsToExtract.ScenarioStep2Text.Replace(@"(\d+)", "15", StringComparison.InvariantCultureIgnoreCase),69 "When " + FeatureWithMatchingScenarioStepsToExtract.ScenarioStep3Text,70 "Then " + FeatureWithMatchingScenarioStepsToExtract.ScenarioStep4Text.Replace(@"(\d+)", "27", StringComparison.InvariantCultureIgnoreCase)71 }).Feature.Children.First() as Gherkin.Ast.Scenario;72 //act.73 var scenario = sut.ExtractScenario(gherkinScenario);74 //assert.75 Assert.NotNull(scenario);76 } 77 private static Gherkin.Ast.GherkinDocument CreateGherkinDocument(78 string scenario,79 string[] steps,80 Gherkin.Ast.StepArgument stepArgument = null,81 string[] backgroundSteps = null)82 {83 var definitions = new List<global::Gherkin.Ast.ScenarioDefinition>84 {85 new Gherkin.Ast.Scenario(86 new Gherkin.Ast.Tag[0],87 null,88 null,89 scenario,90 null,91 steps.Select(s =>92 {93 var spaceIndex = s.IndexOf(' ');94 return new Gherkin.Ast.Step(95 null,96 s.Substring(0, spaceIndex).Trim(),97 s.Substring(spaceIndex).Trim(),98 stepArgument);99 }).ToArray())100 };101 if(backgroundSteps != null)102 {103 definitions.Add(104 new Gherkin.Ast.Background(105 null,106 null,107 "background",108 null,109 backgroundSteps.Select(s =>110 {111 var spaceIndex = s.IndexOf(' ');112 return new Gherkin.Ast.Step(113 null,114 s.Substring(0, spaceIndex).Trim(),115 s.Substring(spaceIndex).Trim(),116 stepArgument);117 }).ToArray()));118 }119 return new Gherkin.Ast.GherkinDocument(120 new Gherkin.Ast.Feature(new Gherkin.Ast.Tag[0], null, null, null, null, null, definitions.ToArray()),121 new Gherkin.Ast.Comment[0]);122 }123 private sealed class FeatureWithMatchingScenarioStepsToExtract : Feature124 {125 public List<KeyValuePair<string, object[]>> CallStack { get; } = new List<KeyValuePair<string, object[]>>();126 [Given("a background step")]127 public void GivenBackground()128 {129 CallStack.Add(new KeyValuePair<string, object[]>(nameof(GivenBackground), null));130 }131 [Given("Non matching given")]132 public void NonMatchingStep1_before()133 {134 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_before), null));135 }136 public const string ScenarioStep1Text = @"I chose (\d+) as first number";137 [Given(ScenarioStep1Text)]138 public void ScenarioStep1(int firstNumber)139 {140 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep1), new object[] { firstNumber }));141 }142 [Given("Non matching given")]143 public void NonMatchingStep1_after()144 {145 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep1_after), null));146 }147 [And("Non matching and")]148 public void NonMatchingStep2_before()149 {150 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_before), null));151 }152 public const string ScenarioStep2Text = @"I chose (\d+) as second number";153 [And(ScenarioStep2Text)]154 public void ScenarioStep2(int secondNumber)155 {156 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep2), new object[] { secondNumber }));157 }158 [And("Non matching and")]159 public void NonMatchingStep2_after()160 {161 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep2_after), null));162 }163 [When("Non matching when")]164 public void NonMatchingStep3_before()165 {166 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_before), null));167 }168 public const string ScenarioStep3Text = "I press add";169 [When(ScenarioStep3Text)]170 public void ScenarioStep3()171 {172 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep3), null));173 }174 [When("Non matching when")]175 public void NonMatchingStep3_after()176 {177 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep3_after), null));178 }179 [Then("Non matching then")]180 public void NonMatchingStep4_before()181 {182 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_before), null));183 }184 public const string ScenarioStep4Text = @"the result should be (\d+) on the screen";185 [Then(ScenarioStep4Text)]186 public void ScenarioStep4(int result)187 {188 CallStack.Add(new KeyValuePair<string, object[]>(nameof(ScenarioStep4), new object[] { result }));189 }190 [Then("Non matching then")]191 public void NonMatchingStep4_after()192 {193 CallStack.Add(new KeyValuePair<string, object[]>(nameof(NonMatchingStep4_after), null));194 }195 }196 [Fact]197 public void ExtractScnario_Extracts_Scenario_With_DataTable()198 {199 //arrange.200 var scenarioName = "scenario213";201 var featureInstance = new FeatureWithDataTableScenarioStep();202 var sut = FeatureClass.FromFeatureInstance(featureInstance);203 var gherknScenario = CreateGherkinDocument(scenarioName,204 new string[]205 {206 "When " + FeatureWithDataTableScenarioStep.Steptext207 },208 new Gherkin.Ast.DataTable(new Gherkin.Ast.TableRow[]209 {210 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]211 {212 new Gherkin.Ast.TableCell(null, "First argument"),213 new Gherkin.Ast.TableCell(null, "Second argument"),214 new Gherkin.Ast.TableCell(null, "Result"),215 }),216 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]217 {218 new Gherkin.Ast.TableCell(null, "1"),219 new Gherkin.Ast.TableCell(null, "2"),220 new Gherkin.Ast.TableCell(null, "3"),221 }),222 new Gherkin.Ast.TableRow(null, new Gherkin.Ast.TableCell[]223 {224 new Gherkin.Ast.TableCell(null, "a"),225 new Gherkin.Ast.TableCell(null, "b"),226 new Gherkin.Ast.TableCell(null, "c"),227 })228 })).Feature.Children.First() as Gherkin.Ast.Scenario;229 //act.230 var scenario = sut.ExtractScenario(gherknScenario);231 //assert.232 Assert.NotNull(scenario);233 }234 private sealed class FeatureWithDataTableScenarioStep : Feature235 {236 public Gherkin.Ast.DataTable ReceivedDataTable { get; private set; }237 public const string Steptext = "Some step text";238 [When(Steptext)]239 public void When_DataTable_Is_Expected(Gherkin.Ast.DataTable dataTable)240 {241 ReceivedDataTable = dataTable;242 }243 }244 [Fact]245 public void ExtractScenario_Extracts_Scenario_With_DocString()246 {247 //arrange.248 var featureInstance = new FeatureWithDocStringScenarioStep();249 var sut = FeatureClass.FromFeatureInstance(featureInstance);250 var scenarioName = "scenario-121kh2";251 var docStringContent = @"some content252 +++253 with multi lines254 ---255 in it";256 var gherkinScenario = CreateGherkinDocument(scenarioName,257 new string[] { "Given " + FeatureWithDocStringScenarioStep.StepWithDocStringText },258 new Gherkin.Ast.DocString(null, null, docStringContent))259 .Feature.Children.First() as Gherkin.Ast.Scenario;260 //act.261 var scenario = sut.ExtractScenario(gherkinScenario);262 //assert.263 Assert.NotNull(scenario);264 }265 private sealed class FeatureWithDocStringScenarioStep : Feature266 {267 public Gherkin.Ast.DocString ReceivedDocString { get; private set; }268 public const string StepWithDocStringText = "Step with docstirng";269 [Given(StepWithDocStringText)]270 public void Step_With_DocString_Argument(Gherkin.Ast.DocString docString)271 {272 ReceivedDocString = docString;273 }274 }275 [Fact]276 public void ExtractScenario_Extracts_Steps_With_Multiple_Patterns()277 {278 //arrange.279 var sut = FeatureClass.FromFeatureInstance(new FeatureWithMultipleStepPatterns());280 //act.281 var scenario = sut.ExtractScenario(CreateGherkinDocument("scenario 123", new string[]282 {283 "Given something else"284 }).Feature.Children.OfType<Gherkin.Ast.Scenario>().First());285 //assert.286 Assert.NotNull(scenario);287 }288 private sealed class FeatureWithMultipleStepPatterns : Feature289 {290 [Given("something")]291 [Given("something else")]292 [And("something")]293 [And("something else")]294 [When("something")]295 [When("something else")]296 [And("something")]297 [And("something else")]298 [But("something")]299 [But("something else")]300 public void Step_With_Multiple_Patterns()301 { }302 }...
FeatureFileTests.cs
Source:FeatureFileTests.cs
2using Xunit;3using Xunit.Gherkin.Quick;4namespace UnitTests5{6 public sealed class FeatureFileTests7 {8 [Fact]9 public void Ctor_Initializes_Properties()10 {11 //arrange.12 var gherkinDocument = new Gherkin.Ast.GherkinDocument(null, null);13 //act.14 var sut = new FeatureFile(gherkinDocument);15 //assert.16 Assert.Same(gherkinDocument, sut.GherkinDocument);17 }18 [Fact]19 public void GetScenario_Retrieves_If_Found()20 {21 //arrange.22 var scenarioName = "name exists";23 var sut = new FeatureFile(CreateGherkinDocumentWithScenario(scenarioName));24 //act.25 var scenario = sut.GetScenario(scenarioName);26 //assert.27 Assert.NotNull(scenario);28 Assert.Same(sut.GherkinDocument.Feature.Children.First(), scenario);29 }30 [Fact]31 public void GetScenario_Gives_Null_If_Not_Found()32 {33 //arrange.34 var sut = new FeatureFile(CreateGherkinDocumentWithScenario("existing"));35 //act.36 var scenario = sut.GetScenario("non-existing");37 //assert.38 Assert.Null(scenario);39 }40 [Fact]41 public void GetScenarioOutline_Retrieves_If_Found()42 {43 //arrange.44 var scenarioName = "name exists";45 var sut = new FeatureFile(CreateGherkinDocumentWithScenarioOutline(scenarioName));46 //act.47 var scenario = sut.GetScenarioOutline(scenarioName);48 //assert.49 Assert.NotNull(scenario);50 Assert.Same(sut.GherkinDocument.Feature.Children.First(), scenario);51 }52 [Fact]53 public void GetScenarioOutline_Gives_Null_If_Not_Found()54 {55 //arrange.56 var sut = new FeatureFile(CreateGherkinDocumentWithScenarioOutline("existing"));57 //act.58 var scenario = sut.GetScenarioOutline("non-existing");59 //assert.60 Assert.Null(scenario);61 }62 [Fact]63 public void GetBackground_Retrieves_If_Present()64 {65 var sut = new FeatureFile(CreateGherkinDocumentWithBackground());66 var background = sut.GetBackground();67 Assert.NotNull(background);68 }69 [Fact]70 public void GetBackground_Gives_Null_If_Not_Present()71 {72 var sut = new FeatureFile(CreateGherkinDocumentWithScenario("test"));73 var background = sut.GetBackground();74 Assert.Null(background);75 }76 private static Gherkin.Ast.GherkinDocument CreateGherkinDocumentWithScenario(77 string scenario,78 Gherkin.Ast.StepArgument stepArgument = null)79 {80 return new Gherkin.Ast.GherkinDocument(81 new Gherkin.Ast.Feature(new Gherkin.Ast.Tag[0], null, null, null, null, null, new Gherkin.Ast.ScenarioDefinition[]82 {83 new Gherkin.Ast.Scenario(84 new Gherkin.Ast.Tag[0],85 null,86 null,87 scenario,88 null,89 new Gherkin.Ast.Step[]{ })90 }),91 new Gherkin.Ast.Comment[0]);92 }93 private static Gherkin.Ast.GherkinDocument CreateGherkinDocumentWithBackground()94 {95 return new Gherkin.Ast.GherkinDocument(96 new Gherkin.Ast.Feature(new Gherkin.Ast.Tag[0], null, null, null, null, null, new Gherkin.Ast.ScenarioDefinition[]97 {98 new Gherkin.Ast.Background(99 null,100 null,101 null,102 null,103 new Gherkin.Ast.Step[]{ })104 }),105 new Gherkin.Ast.Comment[0]);106 }107 private static Gherkin.Ast.GherkinDocument CreateGherkinDocumentWithScenarioOutline(108 string scenario,109 Gherkin.Ast.StepArgument stepArgument = null)110 {111 return new Gherkin.Ast.GherkinDocument(112 new Gherkin.Ast.Feature(new Gherkin.Ast.Tag[0], null, null, null, null, null, new Gherkin.Ast.ScenarioDefinition[]113 {114 new Gherkin.Ast.ScenarioOutline(115 new Gherkin.Ast.Tag[0],116 null,117 null,118 scenario,119 null,120 new Gherkin.Ast.Step[]{ },121 new Gherkin.Ast.Examples[]{ })122 }),123 new Gherkin.Ast.Comment[0]);124 }125 }126}...
GherkinFeatureExtensions.cs
Source:GherkinFeatureExtensions.cs
2using System.Collections.Generic;3using System.Linq;4namespace Xunit.Gherkin.Quick5{6 internal static class GherkinFeatureExtensions7 {8 public static List<string> GetScenarioTags(9 this global::Gherkin.Ast.Feature feature,10 string scenarioName)11 {12 if (feature == null)13 throw new ArgumentNullException(nameof(feature));14 if (string.IsNullOrWhiteSpace(scenarioName))15 throw new ArgumentNullException(nameof(scenarioName));16 var scenario = feature17 .Children18 .OfType<global::Gherkin.Ast.Scenario>()19 .FirstOrDefault(s => s.Name == scenarioName);20 if (scenario == null)21 throw new InvalidOperationException($"Cannot find scenario `{scenarioName}` under feature `{feature.Name}`.");22 var scenarioTags = feature.Tags23 ?.Union(scenario.Tags ?? new List<global::Gherkin.Ast.Tag>())24 ?.Select(t => t.Name)25 ?.ToList();26 return scenarioTags ?? new List<string>();27 }28 public const string IgnoreTag = "@ignore";29 public static bool IsScenarioIgnored(30 this global::Gherkin.Ast.Feature feature,31 string scenarioName)32 {33 var scenarioTags = feature.GetScenarioTags(scenarioName);34 return scenarioTags.Contains(IgnoreTag);35 }36 public static List<string> GetExamplesTags(37 this global::Gherkin.Ast.Feature feature,38 string scenarioOutlineName,39 string examplesName)40 {41 if (feature == null)42 throw new ArgumentNullException(nameof(feature));43 if (string.IsNullOrWhiteSpace(scenarioOutlineName))44 throw new ArgumentNullException(nameof(scenarioOutlineName));45 46 var scenarioOutline = feature.Children.OfType<global::Gherkin.Ast.ScenarioOutline>()47 .FirstOrDefault(o => o.Name == scenarioOutlineName);48 if (scenarioOutline == null)49 throw new InvalidOperationException($"Cannot find scenario outline `{scenarioOutlineName}` under feature `{feature.Name}`.");50 var examples = scenarioOutline.Examples.FirstOrDefault(e => e.Name == examplesName);51 if (examples == null)52 throw new InvalidOperationException($"Cannot find examples `{examplesName}` under scenario outline `{scenarioOutlineName}` and feature `{feature.Name}`.");53 var examplesTags = feature.Tags54 ?.Union(scenarioOutline.Tags ?? new List<global::Gherkin.Ast.Tag>())55 ?.Union(examples.Tags ?? new List<global::Gherkin.Ast.Tag>())56 ?.Select(t => t.Name)57 ?.ToList();58 return examplesTags ?? new List<string>();59 }60 public static bool IsExamplesIgnored(61 this global::Gherkin.Ast.Feature feature,62 string scenarioOutlineName,63 string examplesName)64 {65 var examplesTags = feature.GetExamplesTags(scenarioOutlineName, examplesName);66 return examplesTags.Contains(IgnoreTag);67 }68 }69}...
FeatureFile.cs
Source:FeatureFile.cs
1using Gherkin.Ast;2using System.Linq;3namespace Xunit.Gherkin.Quick4{5 internal sealed class FeatureFile6 {7 public GherkinDocument GherkinDocument { get; }8 public FeatureFile(GherkinDocument gherkinDocument)9 {10 GherkinDocument = gherkinDocument ?? throw new System.ArgumentNullException(nameof(gherkinDocument));11 }12 public global::Gherkin.Ast.Scenario GetScenario(string scenarioName)13 {14 return GherkinDocument.Feature.Children.FirstOrDefault(s => s.Name == scenarioName) as global::Gherkin.Ast.Scenario;15 }16 public global::Gherkin.Ast.Background GetBackground()17 {18 return GherkinDocument.Feature.Children.OfType<global::Gherkin.Ast.Background>().SingleOrDefault();19 }20 internal ScenarioOutline GetScenarioOutline(string scenarioOutlineName)21 {22 return GherkinDocument.Feature.Children.FirstOrDefault(s => s.Name == scenarioOutlineName) as global::Gherkin.Ast.ScenarioOutline;23 }24 }25}...
Feature
Using AI Code Generation
1using Gherkin.Ast;2using Gherkin.Ast;3using Gherkin.Ast;4using Gherkin.Ast;5using Gherkin.Ast;6using Gherkin.Ast;7using Gherkin.Ast;8using Gherkin.Ast;9using Gherkin.Ast;10using Gherkin.Ast;11using Gherkin.Ast;12using Gherkin.Ast;13using Gherkin.Ast;14using Gherkin.Ast;15using Gherkin.Ast;16using Gherkin.Ast;17using Gherkin.Ast;18using Gherkin.Ast;19using Gherkin.Ast;20using Gherkin.Ast;21using Gherkin.Ast;22using Gherkin.Token;23using Gherkin.TokenMatcher;
Feature
Using AI Code Generation
1using Gherkin.Ast;2using System;3using System.Collections.Generic;4using System.Linq;5using System.Text;6using System.Threading.Tasks;7{8 {9 static void Main(string[] args)10 {11 Feature feature = new Feature(new List<Tag>(), "Feature", "In order to avoid silly mistakes", "As a math idiot", "I want to be told the sum of two numbers", new List<ScenarioDefinition>(), new List<Comment>(), new List<ScenarioOutline>(), new List<Background>(), new List<Rule>());12 feature.Language = "en";13 string language = feature.Language;
Feature
Using AI Code Generation
1using Gherkin.Ast;2using Gherkin;3using System;4using System.Collections.Generic;5using System.Linq;6using System.Text;7using System.Threading.Tasks;8using System.IO;9using System.Text.RegularExpressions;10{11 {12 static void Main(string[] args)13 {14 var parser = new Parser();15 var feature = parser.Parse(@"C:\Users\user\Desktop\GherkinDemo\GherkinDemo\Feature1.feature");16 Console.WriteLine("Feature Name:" + feature.Name);17 Console.WriteLine("Feature Description:" + feature.Description);18 Console.WriteLine("Feature Background:" + feature.Background);19 Console.WriteLine("Feature Tags:" + feature.Tags);20 Console.WriteLine("Feature Language:" + feature.Language);21 Console.WriteLine("Feature Keyword:" + feature.Keyword);22 Console.WriteLine("Feature Location:" + feature.Location);23 Console.WriteLine("Feature Children:" + feature.Children);24 Console.WriteLine("Feature Comments:" + feature.Comments);25 Console.WriteLine("Feature Id:" + feature.Id);26 Console.WriteLine("Feature Keyword:" + feature.Keyword);27 Console.WriteLine("Feature Name:" + feature.Name);28 Console.WriteLine("Feature Tags:" + feature.Tags);29 Console.WriteLine("Feature Type:" + feature.Type);30 Console.WriteLine("Feature Steps:" + feature.Steps);31 Console.WriteLine("Feature Examples:" + feature.Examples);32 Console.WriteLine("Feature TableHeader:" + feature.TableHeader);33 Console.WriteLine("Feature TableBody:" + feature.TableBody);34 Console.WriteLine("Feature TableRows:" + feature.TableRows);35 Console.WriteLine("Feature TableCells:" + feature.TableCells);36 Console.WriteLine("Feature Description:" + feature.Description);37 Console.WriteLine("Feature Keyword:" + feature.Keyword);38 Console.WriteLine("Feature Name:" + feature.Name);39 Console.WriteLine("Feature Location:" + feature.Location);40 Console.WriteLine("Feature Tags:" + feature.Tags);41 Console.WriteLine("Feature Type:" + feature.Type);42 Console.WriteLine("Feature Steps:" + feature.Steps);43 Console.WriteLine("Feature Examples:" + feature.Examples);44 Console.WriteLine("Feature TableHeader:" + feature.TableHeader);45 Console.WriteLine("Feature TableBody:" + feature.TableBody);46 Console.WriteLine("Feature TableRows:" + feature.TableRows);47 Console.WriteLine("Feature TableCells:" + feature.TableCells);48 Console.WriteLine("Feature Description:" + feature.Description);
Feature
Using AI Code Generation
1using Gherkin.Ast;2using System;3using System.Collections.Generic;4using System.Linq;5using System.Text;6using System.Threading.Tasks;7{8 {9 public FeatureClass(Feature feature)10 {11 Console.WriteLine(feature.Name);12 }13 }14}15using Gherkin.Ast;16using System;
Feature
Using AI Code Generation
1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;6using Gherkin.Ast;7using TechTalk.SpecFlow.Parser;8{9 {10 static void Main(string[] args)11 {12 var parser = new GherkinParser();13 var feature = parser.Parse(@"C:\Users\user\Documents\Visual Studio 2013\Projects\SpecFlowProject1\SpecFlowProject1\Feature1.feature");14 Console.WriteLine(feature.Name);15 Console.WriteLine(feature.Description);16 Console.WriteLine(feature.Background.Name);17 Console.WriteLine(feature.Background.Description);18 Console.WriteLine(feature.Background.Steps[0].Text);19 Console.WriteLine(feature.Background.Steps[0].Argument);20 Console.WriteLine(feature.Background.Steps[1].Text);21 Console.WriteLine(feature.Background.Steps[1].Argument);22 Console.WriteLine(feature.ScenarioDefinitions[0].Name);23 Console.WriteLine(feature.ScenarioDefinitions[0].Description);24 Console.WriteLine(feature.ScenarioDefinitions[0].Steps[0].Text);25 Console.WriteLine(feature.ScenarioDefinitions[0].Steps[0].Argument);26 Console.WriteLine(feature.ScenarioDefinitions[0].Steps[1].Text);27 Console.WriteLine(feature.ScenarioDefinitions[0].Steps[1].Argument);28 Console.WriteLine(feature.ScenarioDefinitions[1].Name);29 Console.WriteLine(feature.ScenarioDefinitions[1].Description);30 Console.WriteLine(feature.ScenarioDefinitions[1].Steps[0].Text);31 Console.WriteLine(feature.ScenarioDefinitions[1].Steps[0].Argument);32 Console.WriteLine(feature.ScenarioDefinitions[1].Steps[1].Text);33 Console.WriteLine(feature.ScenarioDefinitions[1].Steps[1].Argument);34 Console.WriteLine(feature.ScenarioDefinitions[2].Name);35 Console.WriteLine(feature.ScenarioDefinitions[2].Description);36 Console.WriteLine(feature.ScenarioDefinitions[2].Steps[0].Text);37 Console.WriteLine(feature.ScenarioDefinitions[2].Steps[0].Argument);38 Console.WriteLine(feature.ScenarioDefinitions[2].Steps[1].Text);39 Console.WriteLine(feature.ScenarioDefinitions[2].Steps[1].Argument);40 Console.WriteLine(feature.ScenarioDefinitions[3].Name);41 Console.WriteLine(feature.ScenarioDefinitions[3].Description);42 Console.WriteLine(feature.ScenarioDefinitions[3].Steps[0].Text);43 Console.WriteLine(feature.ScenarioDefinitions[3].Steps[0].Argument
Feature
Using AI Code Generation
1using Gherkin.Ast;2using System;3using System.Collections.Generic;4using System.Linq;5using System.Text;6using System.Threading.Tasks;7{8 {9 public string Name { get; set; }10 public string Description { get; set; }11 public List<Scenario> Scenarios { get; set; }12 }13}14using Gherkin.Ast;15using System;16using System.Collections.Generic;17using System.Linq;18using System.Text;19using System.Threading.Tasks;20{21 {22 public string Name { get; set; }23 public string Description { get; set; }24 public List<Step> Steps { get; set; }25 }26}27using Gherkin.Ast;28using System;29using System.Collections.Generic;30using System.Linq;31using System.Text;32using System.Threading.Tasks;33{34 {35 public string Name { get; set; }36 public string Description { get; set; }37 public List<Table> Tables { get; set; }38 }39}40using Gherkin.Ast;41using System;42using System.Collections.Generic;43using System.Linq;44using System.Text;45using System.Threading.Tasks;46{47 {48 public List<Row> Rows { get; set; }49 }50}51using Gherkin.Ast;52using System;53using System.Collections.Generic;54using System.Linq;55using System.Text;56using System.Threading.Tasks;57{58 {59 public List<string> Cells { get; set; }60 }61}62using Gherkin;63using Gherkin.Ast;64using System;65using System.Collections.Generic;66using System.IO;67using System.Linq;68using System.Text;69using System.Threading.Tasks;70{
Feature
Using AI Code Generation
1using Gherkin.Ast;2using System;3using System.Collections.Generic;4using System.Linq;5using System.Text;6using System.Threading.Tasks;7{8 {9 private Feature _feature;10 public FeatureClass(Feature feature)11 {12 _feature = feature;13 }14 public void PrintFeature()15 {16 Console.WriteLine("Feature: " + _feature.Name);17 Console.WriteLine(_feature.Description);18 }19 }20}21using Gherkin.Ast;22using System;23using System.Collections.Generic;24using System.Linq;25using System.Text;26using System.Threading.Tasks;27{28 {29 private Scenario _scenario;30 public ScenarioClass(Scenario scenario)31 {32 _scenario = scenario;33 }34 public void PrintScenario()35 {36 Console.WriteLine("Scenario: " + _scenario.Name);37 Console.WriteLine(_scenario.Description);38 }39 }40}41using Gherkin.Ast;42using System;43using System.Collections.Generic;44using System.Linq;45using System.Text;46using System.Threading.Tasks;47{48 {49 private Step _step;50 public StepClass(Step step)51 {52 _step = step;53 }54 public void PrintStep()55 {56 Console.WriteLine(_step.Keyword + " " + _step.Text);57 }58 }59}60using Gherkin;61using Gherkin.Ast;62using System;63using System.Collections.Generic;64using System.Linq;65using System.Text;66using System.Threading.Tasks;67{68 {69 private Parser _parser;70 private GherkinDocument _document;71 public GherkinParser()72 {73 _parser = new Parser();74 }75 public void ParseGherkin(string gherkin)76 {77 _document = _parser.Parse(gherkin);78 }79 public FeatureClass GetFeature()80 {81 return new FeatureClass(_document.Feature);82 }83 public ScenarioClass GetScenario()84 {
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!