Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -67,14 +69,14 @@ public void OneLetterWordInTheBeginningOfStringIsTurnedIntoAWord()
[InlineData("WhenMethodTakes__one__and__two__parameters", "When method takes <one> and <two> 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 <två> cucumbers")]
public void ReportsIllegalExampleStepNames(string stepName, string expectedStepTitle) {
var exception = Record.Exception(() => {
NetToString.Convert(stepName).ShouldBe(expectedStepTitle);
Humanizer.Humanize(stepName).ShouldBe(expectedStepTitle);
});

exception.ShouldNotBeNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,15 @@ public void LegacyConsecutiveAssertionStepIsScanned()

void VerifyStepAndItsProperties(Expression<Action> 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);
}

[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();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public void IncorrectSpecificationStepIsNotAdded()

void AssertSpecificationStepIsScannedProperly(Expression<Action> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ 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")]
[RunStepWithArgs("WhenInTheSubClass")]
[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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public WhenTestClassUsesExecutableAttributes()

private static string GetStepTextFromMethodName(Expression<Action> methodInfoAction)
{
return Configurator.Scanners.Humanize(Helpers.GetMethodInfo(methodInfoAction).Name);
return Configurator.Humanizer.Humanize(Helpers.GetMethodInfo(methodInfoAction).Name);
}

[Fact]
Expand Down
8 changes: 4 additions & 4 deletions src/TestStack.BDDfy/BDDfyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ public static Engine LazyBDDfy<TStory>(this object testObject, string scenarioTi
/// <returns></returns>
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));
}

/// <summary>
Expand All @@ -71,13 +71,13 @@ public static Engine LazyBDDfy(this object testObject, string scenarioTitle = nu
public static Story BDDfy<TStory>(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<TStory>(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

Expand Down
41 changes: 7 additions & 34 deletions src/TestStack.BDDfy/Configuration/Configurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
7 changes: 7 additions & 0 deletions src/TestStack.BDDfy/Configuration/IHumanizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TestStack.BDDfy.Configuration
{
public interface IHumanizer
{
string Humanize(string input);
}
}
2 changes: 0 additions & 2 deletions src/TestStack.BDDfy/Configuration/Scanners.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,5 @@ public IEnumerable<IStepScanner> GetStepScanners(object objectUnderTest)
}

public Func<IStoryMetadataScanner> StoryMetadataScanner = () => new StoryAttributeMetadataScanner();

public Func<string, string> Humanize = NetToString.Convert;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
public partial class DefaultHumanizer: IHumanizer
{
static readonly Func<string, string> FromUnderscoreSeparatedWords = methodName => string.Join(" ", methodName.Split(new[] { '_' }));
static string FromPascalCase(string name)
Expand Down Expand Up @@ -49,29 +51,31 @@ private static bool ShouldAddSpace(char lastChar, char currentChar)
return false;
}

public static readonly Func<string, string> Convert = name => {
return name.Contains("__") ? ExampleTitle(name) : ConvertNonExample(name);
};

private static readonly Func<string, string> 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 + "'!");
}

// 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();
}
}
}
2 changes: 1 addition & 1 deletion src/TestStack.BDDfy/Reporters/TextReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ void ReportOnStep(Scenario scenario, Tuple<Step, string[]> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public virtual IEnumerable<Scenario> Scan(ITestContext testContext)

static string GetScenarioText(Type scenarioType)
{
return Configurator.Scanners.Humanize(scenarioType.Name);
return Configurator.Humanizer.Humanize(scenarioType.Name);
}

protected virtual IEnumerable<Step> ScanScenarioForSteps(ITestContext testContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public IEnumerable<Step> 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;
Expand Down Expand Up @@ -78,7 +78,7 @@ public IEnumerable<Step> 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/TestStack.BDDfy/Scanners/StoryMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading