Skip to content

Commit

Permalink
Merge pull request #155 from JakeGinnivan/LongTitles
Browse files Browse the repository at this point in the history
Long titles
  • Loading branch information
MehdiK committed Jun 11, 2014
2 parents 25f0525 + 985d6e7 commit 570d70c
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Story: Text reporter tests

Scenario: Scenario Text
Given a normal length title [Not executed]
When something of normal length happens [Not executed]
Then some long state should be: #Title [Not executed]

Some more stuff which is quite long on the second line

And finally another really long line
And a normal length assertion [Not executed]


Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ Story: Unhappy examples
So that I can diagnose what's wrong

Scenario: Example Scenario
Given a <sign> account balance
Given a <sign> account balance
When the account holder requests money
Then money <action> dispensed
Then money <action> dispensed

Examples:
| sign | action | Result | Errors |
Expand All @@ -104,9 +104,9 @@ Story: Happy Examples
So that the report is clean and readable

Scenario: Example Scenario
Given a <sign> account balance
Given a <sign> account balance
When the account holder requests money
Then money <action> dispensed
Then money <action> dispensed

Examples:
| sign | action |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
So that I can be happy

Scenario: Example Scenario
Given a <sign> account balance
Given a <sign> account balance
When the account holder requests money
Then money <action> dispensed
Then money <action> dispensed

Examples:
| sign | action |
Expand All @@ -20,9 +20,9 @@ Story: Account holder withdraws cash
So that I can get money when the bank is closed

Scenario: Example Scenario
Given a <sign> account balance
Given a <sign> account balance
When the account holder requests money
Then money <action> dispensed
Then money <action> dispensed

Examples:
| sign | action | Result | Errors |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using ApprovalTests;
using NUnit.Framework;
Expand Down Expand Up @@ -42,5 +43,25 @@ public void ShouldProduceExpectedTextWithExamples()

Approvals.Verify(actual.ToString(), StackTraceScrubber.Scrub);
}

[Test]
[MethodImpl(MethodImplOptions.NoInlining)]
public void LongStepName()
{
var textReporter = new TextReporter();
var scenario = new Scenario(typeof(TextReporterTests), new List<Step>
{
new Step(o =>{ }, new StepTitle("Given a normal length title"), false, ExecutionOrder.SetupState, true, new List<StepArgument>()),
new Step(o =>{ }, new StepTitle("When something of normal length happens"), false, ExecutionOrder.Transition, true, new List<StepArgument>()),
new Step(o =>{ }, new StepTitle("Then some long state should be: #Title\r\n\r\nSome more stuff which is quite long on the second line\r\n\r\nAnd finally another really long line"),
true, ExecutionOrder.Assertion, true, new List<StepArgument>()),
new Step(o =>{ }, new StepTitle("And a normal length assertion"), true, ExecutionOrder.ConsecutiveAssertion, true, new List<StepArgument>())
}, "Scenario Text", new List<string>());
textReporter.Process(new Story(new StoryMetadata(typeof(TextReporterTests), new StoryNarrativeAttribute()),
scenario));
var actual = new StringBuilder();
actual.AppendLine(textReporter.ToString());
Approvals.Verify(actual.ToString(), StackTraceScrubber.Scrub);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

Scenario: Fluent can be used with examples
Given method taking <example int>
And method taking <example int>
Given method taking <example int>
And method taking <example int>
And a different method with random arg 2
And a different method with <Prop2>
When method using <example string>
And I use a <Multi word heading>
Then all is good
And a different method with <Prop2>
When method using <example string>
And I use a <Multi word heading>
Then all is good

Examples:
| Prop 1 | Prop2 | Prop 3 | Multi word heading |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

Scenario: Reflective with examples
Given step with <first example> passed as parameter
Given step with <first example> passed as parameter
Given step with <second example> accessed via property

Examples:
Expand Down
52 changes: 33 additions & 19 deletions TestStack.BDDfy/Reporters/TextReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ public void Process(Story story)
{
ReportStoryHeader(story);

var allSteps = story.Scenarios.SelectMany(s => s.Steps).ToList();
var allSteps = story.Scenarios.SelectMany(s => s.Steps)
.Select(GetStepWithLines)
.ToList();
if (allSteps.Any())
_longestStepSentence = allSteps.Max(s => PrefixWithSpaceIfRequired(s).Length);
_longestStepSentence = allSteps.SelectMany(s => s.Item2.Select(l => l.Length)).Max();

foreach (var scenarioGroup in story.Scenarios.GroupBy(s => s.Id))
{
Expand All @@ -31,7 +33,7 @@ public void Process(Story story)
if (exampleScenario.Steps.Any())
{
foreach (var step in exampleScenario.Steps.Where(s => s.ShouldReport))
ReportOnStep(exampleScenario, step, false);
ReportOnStep(exampleScenario, GetStepWithLines(step), false);
}

WriteLine();
Expand All @@ -47,7 +49,7 @@ public void Process(Story story)
if (scenario.Steps.Any())
{
foreach (var step in scenario.Steps.Where(s => s.ShouldReport))
ReportOnStep(scenario, step, true);
ReportOnStep(scenario, GetStepWithLines(step), true);
}
}

Expand All @@ -59,6 +61,11 @@ public void Process(Story story)
ReportExceptions();
}

private static Tuple<Step, string[]> GetStepWithLines(Step s)
{
return Tuple.Create(s, s.Title.Replace("\r\n", "\n").Split('\n').Select(l => PrefixWithSpaceIfRequired(l, s.ExecutionOrder)).ToArray());
}

private void ReportTags(List<string> tags)
{
if (!tags.Any())
Expand Down Expand Up @@ -141,36 +148,43 @@ private void ReportStoryHeader(Story story)
WriteLine("\t" + story.Metadata.Narrative3);
}

static string PrefixWithSpaceIfRequired(Step step)
static string PrefixWithSpaceIfRequired(string stepTitle, ExecutionOrder executionOrder)
{
var stepTitle = step.Title;
var executionOrder = step.ExecutionOrder;

if (executionOrder == ExecutionOrder.ConsecutiveAssertion ||
executionOrder == ExecutionOrder.ConsecutiveSetupState ||
executionOrder == ExecutionOrder.ConsecutiveTransition)
stepTitle = " " + stepTitle; // add two spaces in the front for indentation.

return stepTitle.Replace(Environment.NewLine, Environment.NewLine + "\t\t");
return stepTitle;
}

void ReportOnStep(Scenario scenario, Step step, bool includeResults)
void ReportOnStep(Scenario scenario, Tuple<Step, string[]> stepAndLines, bool includeResults)
{
if (!includeResults)
{
WriteLine("\t{0}", PrefixWithSpaceIfRequired(step).PadRight(_longestStepSentence));
foreach (var line in stepAndLines.Item2)
{
WriteLine("\t{0}", line);
}
return;
}

var message =
string.Format
("\t{0} [{1}] ",
PrefixWithSpaceIfRequired(step).PadRight(_longestStepSentence + 5),
Configurator.Scanners.Humanize(step.Result.ToString()));
var step = stepAndLines.Item1;
var humanizedResult = Configurator.Scanners.Humanize(step.Result.ToString());

// if all the steps have passed, there is no reason to make noise
string message;
if (scenario.Result == Result.Passed)
message = "\t" + PrefixWithSpaceIfRequired(step);
message = string.Format("\t{0}", stepAndLines.Item2[0]);
else
{
var paddedFirstLine = stepAndLines.Item2[0].PadRight(_longestStepSentence + 5);
message = string.Format("\t{0} [{1}] ", paddedFirstLine, humanizedResult);
}

if (stepAndLines.Item2.Length > 1)
{
message = string.Format("{0}\r\n{1}", message, string.Join("\r\n", stepAndLines.Item2.Skip(1)));
}

if (step.Exception != null)
message += CreateExceptionMessage(step);
Expand Down Expand Up @@ -226,7 +240,7 @@ static string FlattenExceptionMessage(string message)
{
return string.Join(" ", message
.Replace("\t", " ") // replace tab with one space
.Split(new[]{"\r\n", "\n"}, StringSplitOptions.None)
.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None)
.Select(s => s.Trim()))
.TrimEnd(','); // chop any , from the end
}
Expand Down
1 change: 1 addition & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
##V4 In Development

####Improvements
- [#155](https://github.com/TestStack/TestStack.BDDfy/pull/155) - Multi-line steps format nicely in TextReporter
- [#61](https://github.com/TestStack/TestStack.BDDfy/pull/61) & [#62](https://github.com/TestStack/TestStack.BDDfy/pull/62) - rationalized BDDfy namespaces to require less namespaces for some features and to make features more discoverable. **Breaking Change**
- Some long namespaces were removed from the framework so the API becomes more discoverable. You just need to delete the now-removed namespaces from your using statements.
- The `Reporters` namespaces that you would use when configuring BDDfy's reports through the `Configurator` class has been moved around to the root namespace.
Expand Down

0 comments on commit 570d70c

Please sign in to comment.