Skip to content

Instantly share code, notes, and snippets.

@gasparnagy
Last active September 1, 2025 14:02
Show Gist options
  • Select an option

  • Save gasparnagy/64fd317b8cb30b1ddeca4465b6c46739 to your computer and use it in GitHub Desktop.

Select an option

Save gasparnagy/64fd317b8cb30b1ddeca4465b6c46739 to your computer and use it in GitHub Desktop.
Feature: Exponentiation
Scenario: Exponentiation
When exponentiation is calculated
* with base 2
* and with power 10
Then the result should be 1024
using System.Text.RegularExpressions;
using Reqnroll.Bindings;
using Reqnroll.Infrastructure;
namespace ReqnrollCalculator.Specs.StepDefinitions;
[Binding]
public class ExponentiationStepDefinitions(WithContext withContext, Calculator calculator)
{
[When("exponentiation is calculated")]
public void WhenExponentiationIsCalculated() => withContext.InitWith();
[When("exponentiation is calculated with base {int} and with power {int}")]
public void WhenExponentiationIsCalculatedWithBaseWithPower(int baseNumber, int power)
{
calculator.Enter(baseNumber);
calculator.Enter(power);
calculator.Exponentiate();
}
}
// Infrastructure Code, only needed once
[Binding]
public class WithContext(ScenarioContext scenarioContext)
{
private const string PrefixRe = "^(?:and )?with ";
private const string WithContextKey = "__withContext";
[StepDefinition(PrefixRe + ".*$")]
public void With() => AppendWith();
[StepDefinition(PrefixRe + ".*$")]
public void WithDataTable(DataTable table) => AppendWith();
[StepDefinition(PrefixRe + ".*$")]
public void WithDocString(string docString) => AppendWith();
public void InitWith()
{
scenarioContext[WithContextKey] = new WithHandler(scenarioContext);
}
public void AppendWith()
{
if (!scenarioContext.TryGetValue(WithContextKey, out WithHandler withContext))
throw new InvalidOperationException("Missing init step");
withContext.AppendStep();
}
private async Task FlushWithContext()
{
if (scenarioContext.TryGetValue(WithContextKey, out WithHandler withContext))
{
scenarioContext.Remove(WithContextKey);
await withContext.ApplyStep();
}
}
class WithHandler
{
private readonly ScenarioContext _scenarioContext;
private readonly StepDefinitionKeyword _stepDefinitionKeyword;
private readonly string _keyword;
private string _text;
private string? _docString = null;
private Table? _dataTable = null;
private bool _appended = false;
public WithHandler(ScenarioContext scenarioContext)
{
_scenarioContext = scenarioContext;
_stepDefinitionKeyword = scenarioContext.StepContext.StepInfo.StepInstance.StepDefinitionKeyword;
_keyword = scenarioContext.StepContext.StepInfo.StepInstance.Keyword;
_text = scenarioContext.StepContext.StepInfo.StepInstance.Text;
_docString = scenarioContext.StepContext.StepInfo.StepInstance.MultilineTextArgument;
_dataTable = scenarioContext.StepContext.StepInfo.StepInstance.TableArgument;
}
public async Task ApplyStep()
{
var executionEngine = _scenarioContext.ScenarioContainer.Resolve<ITestExecutionEngine>();
await executionEngine.StepAsync(_stepDefinitionKeyword, _keyword, _text, _docString, _dataTable);
}
public void AppendStep()
{
_text += " " + (_appended && !_scenarioContext.StepContext.StepInfo.StepInstance.Text.StartsWith("and ") ? "and " : "") + _scenarioContext.StepContext.StepInfo.StepInstance.Text;
_docString ??= _scenarioContext.StepContext.StepInfo.StepInstance.MultilineTextArgument;
_dataTable ??= _scenarioContext.StepContext.StepInfo.StepInstance.TableArgument;
_appended = true;
}
}
[BeforeStep]
public async Task BeforeStep()
{
if (!Regex.IsMatch(scenarioContext.StepContext.StepInfo.Text, PrefixRe))
{
await FlushWithContext();
}
}
[AfterScenarioBlock]
public async Task AfterScenarioBlock()
{
await FlushWithContext();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment