From 3534a3788033c95d1fc0c3021fb399453c95b691 Mon Sep 17 00:00:00 2001 From: Gurpreet Singh Date: Sat, 25 Oct 2025 23:03:58 +0100 Subject: [PATCH 1/2] Allow setting up custom Humanizer --- ...tringTests.cs => DefaultHumanizerTests.cs} | 22 +++++----- .../FluentScanner/BDDfyUsingFluentApi.cs | 2 +- ...ttributeAndMethodNamingConventionIsUsed.cs | 4 +- ...NamingConventionsOtherThanGivenWhenThen.cs | 2 +- .../WhenStepsAreDefinedInABaseClass.cs | 4 +- .../WhenTestClassUsesExecutableAttributes.cs | 2 +- src/TestStack.BDDfy/BDDfyExtensions.cs | 8 ++-- .../Configuration/Configurator.cs | 41 ++++--------------- .../Configuration/IHumanizer.cs | 7 ++++ src/TestStack.BDDfy/Configuration/Scanners.cs | 2 - .../{NetToString.cs => DefaultHumanizer.cs} | 22 ++++++---- src/TestStack.BDDfy/Reporters/TextReporter.cs | 2 +- .../ScenarioScanners/FluentScenarioScanner.cs | 2 +- .../ReflectiveScenarioScanner.cs | 2 +- .../ExecutableAttributeStepScanner.cs | 4 +- .../StepScanners/Fluent/FluentScanner.cs | 2 +- .../MethodName/MethodNameStepScanner.cs | 2 +- src/TestStack.BDDfy/Scanners/StoryMetadata.cs | 2 +- 18 files changed, 58 insertions(+), 74 deletions(-) rename src/TestStack.BDDfy.Tests/{NetToStringTests.cs => DefaultHumanizerTests.cs} (76%) create mode 100644 src/TestStack.BDDfy/Configuration/IHumanizer.cs rename src/TestStack.BDDfy/{NetToString.cs => DefaultHumanizer.cs} (79%) diff --git a/src/TestStack.BDDfy.Tests/NetToStringTests.cs b/src/TestStack.BDDfy.Tests/DefaultHumanizerTests.cs similarity index 76% rename from src/TestStack.BDDfy.Tests/NetToStringTests.cs rename to src/TestStack.BDDfy.Tests/DefaultHumanizerTests.cs index eeaa5667..7a5d7baf 100644 --- a/src/TestStack.BDDfy.Tests/NetToStringTests.cs +++ b/src/TestStack.BDDfy.Tests/DefaultHumanizerTests.cs @@ -5,51 +5,53 @@ namespace TestStack.BDDfy.Tests { - public class NetToStringTests + public class DefaultHumanizerTests { + private static DefaultHumanizer Humanizer => new(); + [Fact] public void PascalCaseInputStringIsTurnedIntoSentence() { - Configurator.Scanners.Humanize("PascalCaseInputStringIsTurnedIntoSentence") + Humanizer.Humanize("PascalCaseInputStringIsTurnedIntoSentence") .ShouldBe("Pascal case input string is turned into sentence"); } [Fact] public void WhenInputStringContainsConsequtiveCaptialLetters_ThenTheyAreTurnedIntoOneLetterWords() { - Configurator.Scanners.Humanize("WhenIUseAnInputAHere").ShouldBe("When I use an input a here"); + Humanizer.Humanize("WhenIUseAnInputAHere").ShouldBe("When I use an input a here"); } [Fact] public void WhenInputStringStartsWithANumber_ThenNumberIsDealtWithLikeAWord() { - Configurator.Scanners.Humanize("10NumberIsInTheBegining").ShouldBe("10 number is in the begining"); + Humanizer.Humanize("10NumberIsInTheBegining").ShouldBe("10 number is in the begining"); } [Fact] public void WhenInputStringEndWithANumber_ThenNumberIsDealtWithLikeAWord() { - Configurator.Scanners.Humanize("NumberIsAtTheEnd100").ShouldBe("Number is at the end 100"); + Humanizer.Humanize("NumberIsAtTheEnd100").ShouldBe("Number is at the end 100"); } [Fact] public void UnderscoredInputStringIsTurnedIntoSentence() { - Configurator.Scanners.Humanize("Underscored_input_string_is_turned_into_sentence") + Humanizer.Humanize("Underscored_input_string_is_turned_into_sentence") .ShouldBe("Underscored input string is turned into sentence"); } [Fact] public void UnderscoredInputStringPreservesCasing() { - Configurator.Scanners.Humanize("Underscored_input_String_is_turned_INTO_sentence") + Humanizer.Humanize("Underscored_input_String_is_turned_INTO_sentence") .ShouldBe("Underscored input String is turned INTO sentence"); } [Fact] public void OneLetterWordInTheBeginningOfStringIsTurnedIntoAWord() { - Configurator.Scanners.Humanize("XIsFirstPlayer").ShouldBe("X is first player"); + Humanizer.Humanize("XIsFirstPlayer").ShouldBe("X is first player"); } [Theory] @@ -67,14 +69,14 @@ public void OneLetterWordInTheBeginningOfStringIsTurnedIntoAWord() [InlineData("WhenMethodTakes__one__and__two__parameters", "When method takes and parameters")] public void CanDealWithExampleStepNames(string stepName, string expectedStepTitle) { - NetToString.Convert(stepName).ShouldBe(expectedStepTitle); + Humanizer.Humanize(stepName).ShouldBe(expectedStepTitle); } [Theory] [InlineData("GivenThereAre__två__Cucumbers", "Given there are cucumbers")] public void ReportsIllegalExampleStepNames(string stepName, string expectedStepTitle) { var exception = Record.Exception(() => { - NetToString.Convert(stepName).ShouldBe(expectedStepTitle); + Humanizer.Humanize(stepName).ShouldBe(expectedStepTitle); }); exception.ShouldNotBeNull(); diff --git a/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/BDDfyUsingFluentApi.cs b/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/BDDfyUsingFluentApi.cs index bfc913ca..08e10ab2 100644 --- a/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/BDDfyUsingFluentApi.cs +++ b/src/TestStack.BDDfy.Tests/Scanner/FluentScanner/BDDfyUsingFluentApi.cs @@ -279,7 +279,7 @@ public void WhenTitleIsNotProvidedItIsFetchedFromMethodName() .BDDfy(); var scenario = story.Scenarios.First(); - scenario.Title.ShouldBe(Configurator.Scanners.Humanize(nameof(WhenTitleIsNotProvidedItIsFetchedFromMethodName))); + scenario.Title.ShouldBe(Configurator.Humanizer.Humanize(nameof(WhenTitleIsNotProvidedItIsFetchedFromMethodName))); } [Fact] diff --git a/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenCombinationOfExecutableAttributeAndMethodNamingConventionIsUsed.cs b/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenCombinationOfExecutableAttributeAndMethodNamingConventionIsUsed.cs index 764812bb..2d80844e 100644 --- a/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenCombinationOfExecutableAttributeAndMethodNamingConventionIsUsed.cs +++ b/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenCombinationOfExecutableAttributeAndMethodNamingConventionIsUsed.cs @@ -125,7 +125,7 @@ public void LegacyConsecutiveAssertionStepIsScanned() void VerifyStepAndItsProperties(Expression stepMethodAction, ExecutionOrder expectedOrder, int expectedCount = 1) { - var matchingSteps = _scenario.Steps.Where(s => s.Title.Trim() == Configurator.Scanners.Humanize(Helpers.GetMethodInfo(stepMethodAction).Name)); + var matchingSteps = _scenario.Steps.Where(s => s.Title.Trim() == Configurator.Humanizer.Humanize(Helpers.GetMethodInfo(stepMethodAction).Name)); matchingSteps.Count().ShouldBe(expectedCount); matchingSteps.All(s => s.ExecutionOrder == expectedOrder).ShouldBe(true); } @@ -133,7 +133,7 @@ void VerifyStepAndItsProperties(Expression stepMethodAction, ExecutionOr [Fact] public void IgnoredMethodShouldNotBeAddedToSteps() { - var matchingSteps = _scenario.Steps.Where(s => s.Title == Configurator.Scanners.Humanize(Helpers.GetMethodInfo(() => _sut.ThenIAmNotAStep()).Name)); + var matchingSteps = _scenario.Steps.Where(s => s.Title == Configurator.Humanizer.Humanize(Helpers.GetMethodInfo(() => _sut.ThenIAmNotAStep()).Name)); matchingSteps.ShouldBeEmpty(); } } diff --git a/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenMethodNamesFollowNamingConventionsOtherThanGivenWhenThen.cs b/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenMethodNamesFollowNamingConventionsOtherThanGivenWhenThen.cs index 2ac3fded..9693ecad 100644 --- a/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenMethodNamesFollowNamingConventionsOtherThanGivenWhenThen.cs +++ b/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenMethodNamesFollowNamingConventionsOtherThanGivenWhenThen.cs @@ -89,7 +89,7 @@ public void IncorrectSpecificationStepIsNotAdded() void AssertSpecificationStepIsScannedProperly(Expression getSpecMethod) { - var specMethods = _steps.Where(s => s.Title.Trim() == Configurator.Scanners.Humanize(Helpers.GetMethodInfo(getSpecMethod).Name)); + var specMethods = _steps.Where(s => s.Title.Trim() == Configurator.Humanizer.Humanize(Helpers.GetMethodInfo(getSpecMethod).Name)); specMethods.Count().ShouldBe(1); var specStep = specMethods.First(); specStep.Asserts.ShouldBe(false); diff --git a/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenStepsAreDefinedInABaseClass.cs b/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenStepsAreDefinedInABaseClass.cs index 9b225776..8131d8f7 100644 --- a/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenStepsAreDefinedInABaseClass.cs +++ b/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenStepsAreDefinedInABaseClass.cs @@ -41,7 +41,7 @@ Scenario Scenario [RunStepWithArgs("ThenInTheBaseClass")] void ThenTheFollowingStepFromBaseClassIsScanned(string stepName) { - Scenario.Steps.Count(s => s.Title == Configurator.Scanners.Humanize(stepName)).ShouldBe(1); + Scenario.Steps.Count(s => s.Title == Configurator.Humanizer.Humanize(stepName)).ShouldBe(1); } [RunStepWithArgs("GivenInTheSubClass")] @@ -49,7 +49,7 @@ void ThenTheFollowingStepFromBaseClassIsScanned(string stepName) [RunStepWithArgs("ThenInTheSubClass")] void ThenTheFollowingStepFromSubClassScanned(string stepName) { - Scenario.Steps.Count(s => s.Title == Configurator.Scanners.Humanize(stepName)).ShouldBe(1); + Scenario.Steps.Count(s => s.Title == Configurator.Humanizer.Humanize(stepName)).ShouldBe(1); } [Fact] diff --git a/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenTestClassUsesExecutableAttributes.cs b/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenTestClassUsesExecutableAttributes.cs index 0061e313..12a8c0fc 100644 --- a/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenTestClassUsesExecutableAttributes.cs +++ b/src/TestStack.BDDfy.Tests/Scanner/ReflectiveScanner/WhenTestClassUsesExecutableAttributes.cs @@ -68,7 +68,7 @@ public WhenTestClassUsesExecutableAttributes() private static string GetStepTextFromMethodName(Expression methodInfoAction) { - return Configurator.Scanners.Humanize(Helpers.GetMethodInfo(methodInfoAction).Name); + return Configurator.Humanizer.Humanize(Helpers.GetMethodInfo(methodInfoAction).Name); } [Fact] diff --git a/src/TestStack.BDDfy/BDDfyExtensions.cs b/src/TestStack.BDDfy/BDDfyExtensions.cs index 90f69cb4..3340f3fa 100644 --- a/src/TestStack.BDDfy/BDDfyExtensions.cs +++ b/src/TestStack.BDDfy/BDDfyExtensions.cs @@ -52,12 +52,12 @@ public static Engine LazyBDDfy(this object testObject, string scenarioTi /// public static Story BDDfy(this object testObject, string scenarioTitle = null, [System.Runtime.CompilerServices.CallerMemberName] string caller = null) { - return InternalLazyBDDfy(testObject, scenarioTitle ?? Configurator.Scanners.Humanize(caller)).Run(); + return InternalLazyBDDfy(testObject, scenarioTitle ?? Configurator.Humanizer.Humanize(caller)).Run(); } public static Engine LazyBDDfy(this object testObject, string scenarioTitle = null, [System.Runtime.CompilerServices.CallerMemberName] string caller = null) { - return InternalLazyBDDfy(testObject, scenarioTitle ?? Configurator.Scanners.Humanize(caller)); + return InternalLazyBDDfy(testObject, scenarioTitle ?? Configurator.Humanizer.Humanize(caller)); } /// @@ -71,13 +71,13 @@ public static Engine LazyBDDfy(this object testObject, string scenarioTitle = nu public static Story BDDfy(this object testObject, string scenarioTitle = null, [System.Runtime.CompilerServices.CallerMemberName] string caller = null) where TStory : class { - return InternalLazyBDDfy(testObject, scenarioTitle ?? Configurator.Scanners.Humanize(caller), typeof(TStory)).Run(); + return InternalLazyBDDfy(testObject, scenarioTitle ?? Configurator.Humanizer.Humanize(caller), typeof(TStory)).Run(); } public static Engine LazyBDDfy(this object testObject, string scenarioTitle = null, [System.Runtime.CompilerServices.CallerMemberName] string caller = null) where TStory : class { - return InternalLazyBDDfy(testObject, scenarioTitle ?? Configurator.Scanners.Humanize(caller), typeof(TStory)); + return InternalLazyBDDfy(testObject, scenarioTitle ?? Configurator.Humanizer.Humanize(caller), typeof(TStory)); } #endif diff --git a/src/TestStack.BDDfy/Configuration/Configurator.cs b/src/TestStack.BDDfy/Configuration/Configurator.cs index 42018936..7ff99aef 100644 --- a/src/TestStack.BDDfy/Configuration/Configurator.cs +++ b/src/TestStack.BDDfy/Configuration/Configurator.cs @@ -2,45 +2,18 @@ namespace TestStack.BDDfy.Configuration { public static class Configurator { - static Configurator() - { - AsyncVoidSupportEnabled = true; - } + public static bool AsyncVoidSupportEnabled { get; set; } = true; - public static bool AsyncVoidSupportEnabled { get; set; } + public static Processors Processors { get; } = new(); - private static readonly Processors ProcessorsFactory = new(); - public static Processors Processors - { - get { return ProcessorsFactory; } - } + public static BatchProcessors BatchProcessors { get; } = new(); - private static readonly BatchProcessors BatchProcessorFactory = new(); - public static BatchProcessors BatchProcessors - { - get { return BatchProcessorFactory; } - } + public static Scanners Scanners { get; } = new(); - private static readonly Scanners ScannersFactory = new(); - public static Scanners Scanners - { - get { return ScannersFactory; } - } + public static IKeyGenerator IdGenerator { get; set; } = new SequentialKeyGenerator(); - private static IKeyGenerator _idGenerator = new SequentialKeyGenerator(); - public static IKeyGenerator IdGenerator - { - get { return _idGenerator; } - set { _idGenerator = value; } - } - - - private static IStepExecutor _stepExecutor = new StepExecutor(); - public static IStepExecutor StepExecutor - { - get { return _stepExecutor; } - set { _stepExecutor = value; } - } + public static IStepExecutor StepExecutor { get; set; } = new StepExecutor(); + public static IHumanizer Humanizer { get; set; } = new DefaultHumanizer(); } } \ No newline at end of file diff --git a/src/TestStack.BDDfy/Configuration/IHumanizer.cs b/src/TestStack.BDDfy/Configuration/IHumanizer.cs new file mode 100644 index 00000000..02c4583c --- /dev/null +++ b/src/TestStack.BDDfy/Configuration/IHumanizer.cs @@ -0,0 +1,7 @@ +namespace TestStack.BDDfy.Configuration +{ + public interface IHumanizer + { + string Humanize(string input); + } +} \ No newline at end of file diff --git a/src/TestStack.BDDfy/Configuration/Scanners.cs b/src/TestStack.BDDfy/Configuration/Scanners.cs index ce1b5a2c..22c2c845 100644 --- a/src/TestStack.BDDfy/Configuration/Scanners.cs +++ b/src/TestStack.BDDfy/Configuration/Scanners.cs @@ -35,7 +35,5 @@ public IEnumerable GetStepScanners(object objectUnderTest) } public Func StoryMetadataScanner = () => new StoryAttributeMetadataScanner(); - - public Func Humanize = NetToString.Convert; } } \ No newline at end of file diff --git a/src/TestStack.BDDfy/NetToString.cs b/src/TestStack.BDDfy/DefaultHumanizer.cs similarity index 79% rename from src/TestStack.BDDfy/NetToString.cs rename to src/TestStack.BDDfy/DefaultHumanizer.cs index 59f3114c..feeec380 100644 --- a/src/TestStack.BDDfy/NetToString.cs +++ b/src/TestStack.BDDfy/DefaultHumanizer.cs @@ -2,10 +2,12 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using System.Xml.Linq; +using TestStack.BDDfy.Configuration; namespace TestStack.BDDfy { - public class NetToString + internal partial class DefaultHumanizer: IHumanizer { static readonly Func FromUnderscoreSeparatedWords = methodName => string.Join(" ", methodName.Split(new[] { '_' })); static string FromPascalCase(string name) @@ -49,21 +51,17 @@ private static bool ShouldAddSpace(char lastChar, char currentChar) return false; } - public static readonly Func Convert = name => { - return name.Contains("__") ? ExampleTitle(name) : ConvertNonExample(name); - }; - private static readonly Func ConvertNonExample = name => { - if (name.Contains("_")) + if (name.Contains('_')) return FromUnderscoreSeparatedWords(name); return FromPascalCase(name); }; - private static string ExampleTitle(string name) + private string ExampleTitle(string name) { // Compare contains("__") with a regex match - string newName = Regex.Replace(name, "__([a-zA-Z][a-zA-Z0-9]*)__", " <$1> "); + string newName = TitleCleanerRegex().Replace(name, " <$1> "); if (newName == name) { throw new ArgumentException("Illegal example title in name '" + name + "'!"); @@ -71,7 +69,13 @@ private static string ExampleTitle(string name) // for when there are two consequetive example placeholders in the word; e.g. Given__one____two__parameters newName = newName.Replace(" ", " "); - return Convert(newName).Trim(); + return Humanize(newName).Trim(); } + + public string Humanize(string input) + => input.Contains("__") ? ExampleTitle(input) : ConvertNonExample(input); + + [GeneratedRegex("__([a-zA-Z][a-zA-Z0-9]*)__")] + private static partial Regex TitleCleanerRegex(); } } \ No newline at end of file diff --git a/src/TestStack.BDDfy/Reporters/TextReporter.cs b/src/TestStack.BDDfy/Reporters/TextReporter.cs index 0650b57a..69bf89c1 100644 --- a/src/TestStack.BDDfy/Reporters/TextReporter.cs +++ b/src/TestStack.BDDfy/Reporters/TextReporter.cs @@ -170,7 +170,7 @@ void ReportOnStep(Scenario scenario, Tuple stepAndLines, bool in } var step = stepAndLines.Item1; - var humanizedResult = Configurator.Scanners.Humanize(step.Result.ToString()); + var humanizedResult = Configurator.Humanizer.Humanize(step.Result.ToString()); string message; if (scenario.Result == Result.Passed) diff --git a/src/TestStack.BDDfy/Scanners/ScenarioScanners/FluentScenarioScanner.cs b/src/TestStack.BDDfy/Scanners/ScenarioScanners/FluentScenarioScanner.cs index 0d1021b2..826dd55b 100644 --- a/src/TestStack.BDDfy/Scanners/ScenarioScanners/FluentScenarioScanner.cs +++ b/src/TestStack.BDDfy/Scanners/ScenarioScanners/FluentScenarioScanner.cs @@ -38,7 +38,7 @@ private static string GetTitleFromMethodNameInStackTrace(object testObject) if (initiatingFrame == null) return null; - return Configurator.Scanners.Humanize(initiatingFrame.GetMethod().Name); + return Configurator.Humanizer.Humanize(initiatingFrame.GetMethod().Name); #else return null; #endif diff --git a/src/TestStack.BDDfy/Scanners/ScenarioScanners/ReflectiveScenarioScanner.cs b/src/TestStack.BDDfy/Scanners/ScenarioScanners/ReflectiveScenarioScanner.cs index ef419166..21ca2330 100644 --- a/src/TestStack.BDDfy/Scanners/ScenarioScanners/ReflectiveScenarioScanner.cs +++ b/src/TestStack.BDDfy/Scanners/ScenarioScanners/ReflectiveScenarioScanner.cs @@ -47,7 +47,7 @@ public virtual IEnumerable Scan(ITestContext testContext) static string GetScenarioText(Type scenarioType) { - return Configurator.Scanners.Humanize(scenarioType.Name); + return Configurator.Humanizer.Humanize(scenarioType.Name); } protected virtual IEnumerable ScanScenarioForSteps(ITestContext testContext) diff --git a/src/TestStack.BDDfy/Scanners/StepScanners/ExecutableAttribute/ExecutableAttributeStepScanner.cs b/src/TestStack.BDDfy/Scanners/StepScanners/ExecutableAttribute/ExecutableAttributeStepScanner.cs index a1a59d14..748fe08f 100644 --- a/src/TestStack.BDDfy/Scanners/StepScanners/ExecutableAttribute/ExecutableAttributeStepScanner.cs +++ b/src/TestStack.BDDfy/Scanners/StepScanners/ExecutableAttribute/ExecutableAttributeStepScanner.cs @@ -34,7 +34,7 @@ public IEnumerable Scan(ITestContext testContext, MethodInfo candidateMeth var stepTitle = new StepTitle(executableAttribute.StepTitle); if(string.IsNullOrEmpty(stepTitle)) - stepTitle = new StepTitle(Configurator.Scanners.Humanize(candidateMethod.Name)); + stepTitle = new StepTitle(Configurator.Humanizer.Humanize(candidateMethod.Name)); var stepAsserts = IsAssertingByAttribute(candidateMethod); var shouldReport = executableAttribute.ShouldReport; @@ -78,7 +78,7 @@ public IEnumerable Scan(ITestContext testContext, MethodInfo method, Examp string stepTitle = executableAttribute.StepTitle; if (string.IsNullOrEmpty(stepTitle)) - stepTitle = Configurator.Scanners.Humanize(method.Name); + stepTitle = Configurator.Humanizer.Humanize(method.Name); var stepAsserts = IsAssertingByAttribute(method); var shouldReport = executableAttribute.ShouldReport; diff --git a/src/TestStack.BDDfy/Scanners/StepScanners/Fluent/FluentScanner.cs b/src/TestStack.BDDfy/Scanners/StepScanners/Fluent/FluentScanner.cs index 1a09ab1d..50510085 100644 --- a/src/TestStack.BDDfy/Scanners/StepScanners/Fluent/FluentScanner.cs +++ b/src/TestStack.BDDfy/Scanners/StepScanners/Fluent/FluentScanner.cs @@ -190,7 +190,7 @@ private StepTitle CreateTitle(string stepTextTemplate, bool includeInputsInStepT includeInputsInStepTitle = titleAttribute.IncludeInputsInStepTitle.Value; } - var stepTitle = AppendPrefix(Configurator.Scanners.Humanize(name), stepPrefix); + var stepTitle = AppendPrefix(Configurator.Humanizer.Humanize(name), stepPrefix); if (!string.IsNullOrEmpty(stepTextTemplate)) stepTitle = string.Format(stepTextTemplate, flatInputArray); else if (includeInputsInStepTitle) diff --git a/src/TestStack.BDDfy/Scanners/StepScanners/MethodName/MethodNameStepScanner.cs b/src/TestStack.BDDfy/Scanners/StepScanners/MethodName/MethodNameStepScanner.cs index 28c289ad..88546e38 100644 --- a/src/TestStack.BDDfy/Scanners/StepScanners/MethodName/MethodNameStepScanner.cs +++ b/src/TestStack.BDDfy/Scanners/StepScanners/MethodName/MethodNameStepScanner.cs @@ -135,7 +135,7 @@ private string GetStepTitle(MethodInfo method, object testObject, RunStepWithArg private string GetStepTitleFromMethodName(MethodInfo method, RunStepWithArgsAttribute argAttribute) { - var methodName = _stepTextTransformer(Configurator.Scanners.Humanize(method.Name)); + var methodName = _stepTextTransformer(Configurator.Humanizer.Humanize(method.Name)); object[] inputs = null; if (argAttribute != null && argAttribute.InputArguments != null) diff --git a/src/TestStack.BDDfy/Scanners/StoryMetadata.cs b/src/TestStack.BDDfy/Scanners/StoryMetadata.cs index cd8ac3df..66c9c07e 100644 --- a/src/TestStack.BDDfy/Scanners/StoryMetadata.cs +++ b/src/TestStack.BDDfy/Scanners/StoryMetadata.cs @@ -11,7 +11,7 @@ public StoryMetadata(Type storyType, StoryNarrativeAttribute narrative) } public Type Type { get; private set; } = storyType; - public string Title { get; private set; } = title ?? Configurator.Scanners.Humanize(storyType.Name); + public string Title { get; private set; } = title ?? Configurator.Humanizer.Humanize(storyType.Name); public string TitlePrefix { get; private set; } = titlePrefix ?? "Story: "; public string Narrative1 { get; private set; } = narrative1; public string Narrative2 { get; private set; } = narrative2; From e8441f28043d74f589310f953e08af38044f6936 Mon Sep 17 00:00:00 2001 From: Gurpreet Singh Date: Sat, 25 Oct 2025 23:13:46 +0100 Subject: [PATCH 2/2] Change DefaultHumanizer class to public --- src/TestStack.BDDfy/DefaultHumanizer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TestStack.BDDfy/DefaultHumanizer.cs b/src/TestStack.BDDfy/DefaultHumanizer.cs index feeec380..576ea423 100644 --- a/src/TestStack.BDDfy/DefaultHumanizer.cs +++ b/src/TestStack.BDDfy/DefaultHumanizer.cs @@ -7,7 +7,7 @@ namespace TestStack.BDDfy { - internal partial class DefaultHumanizer: IHumanizer + public partial class DefaultHumanizer: IHumanizer { static readonly Func FromUnderscoreSeparatedWords = methodName => string.Join(" ", methodName.Split(new[] { '_' })); static string FromPascalCase(string name) @@ -78,4 +78,4 @@ public string Humanize(string input) [GeneratedRegex("__([a-zA-Z][a-zA-Z0-9]*)__")] private static partial Regex TitleCleanerRegex(); } -} \ No newline at end of file +}