Skip to content

Commit 7f61915

Browse files
committed
Created StoryNarrativeAttribute to allow for simpler custom story attributes
1 parent fc8e7b9 commit 7f61915

8 files changed

Lines changed: 112 additions & 79 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using NUnit.Framework;
2+
3+
namespace TestStack.BDDfy.Tests.Stories
4+
{
5+
class InOrderToStoryAttribute : StoryNarrativeAttribute
6+
{
7+
// ReSharper disable InconsistentNaming
8+
private const string As_a_prefix = "As a";
9+
private const string In_order_to_prefix = "In order to";
10+
private const string I_want_prefix = "I want";
11+
// ReSharper restore InconsistentNaming
12+
13+
public string InOrderTo
14+
{
15+
get { return Narrative1; }
16+
set { Narrative1 = CleanseProperty(value, In_order_to_prefix); }
17+
}
18+
19+
public string AsA
20+
{
21+
get { return Narrative2; }
22+
set { Narrative2 = CleanseProperty(value, As_a_prefix); }
23+
}
24+
25+
public string IWant
26+
{
27+
get { return Narrative3; }
28+
set { Narrative3 = CleanseProperty(value, I_want_prefix); }
29+
}
30+
}
31+
32+
[TestFixture]
33+
[InOrderToStory(
34+
InOrderTo = "do something",
35+
AsA = "programmer",
36+
IWant = "this to work")]
37+
public class CanUseACustomStoryAttribute
38+
{
39+
[Test]
40+
public void When_InOrderTo_is_specified_the_InOrderTo_syntax_is_used()
41+
{
42+
var story = new DummyScenario().BDDfy<CanUseACustomStoryAttribute>();
43+
44+
Assert.That(story.Metadata.Narrative1, Is.EqualTo("In order to do something"));
45+
Assert.That(story.Metadata.Narrative2, Is.EqualTo("As a programmer"));
46+
Assert.That(story.Metadata.Narrative3, Is.EqualTo("I want this to work"));
47+
}
48+
}
49+
}

TestStack.BDDfy.Tests/Stories/CanUseInOrderToSyntax.cs

Lines changed: 0 additions & 22 deletions
This file was deleted.

TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
<Compile Include="Scanner\WhenCombinationOfExecutableAttributeAndMethodNamingConventionIsUsed.cs" />
100100
<Compile Include="Scanner\WhenStepsAreDefinedInABaseClass.cs" />
101101
<Compile Include="Scanner\WhenStepsReturnTheirText.cs" />
102-
<Compile Include="Stories\CanUseInOrderToSyntax.cs" />
102+
<Compile Include="Stories\CanUseACustomStoryAttribute.cs" />
103103
<Compile Include="Stories\WhenStoryAttibuteMissesDuplicateTextsInProperties.cs" />
104104
<Compile Include="Stories\WhenStoryAttibuteMissesSoThatTextInSoThatProperty.cs" />
105105
<Compile Include="Stories\WhenStoryAttibuteMissesIWantTextInIWantProperty.cs" />
Lines changed: 4 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
11
using System;
22
using System.Diagnostics;
33
using System.Linq;
4-
using System.Text;
54

65
namespace TestStack.BDDfy
76
{
87
public class StoryAttributeMetadataScanner : IStoryMetadataScanner
98
{
10-
// ReSharper disable InconsistentNaming
11-
private const string I_want_prefix = "I want";
12-
private const string So_that_prefix = "So that";
13-
private const string As_a_prefix = "As a";
14-
private const string In_order_to_prefix = "In order to";
15-
// ReSharper restore InconsistentNaming
16-
179
public virtual StoryMetadata Scan(object testObject, Type explicitStoryType = null)
1810
{
1911
return GetStoryMetadata(testObject, explicitStoryType) ?? GetStoryMetadataFromScenario(testObject);
@@ -26,7 +18,7 @@ static StoryMetadata GetStoryMetadataFromScenario(object testObject)
2618
if (storyAttribute == null)
2719
return null;
2820

29-
return CreateStoryMetadata(scenarioType, storyAttribute);
21+
return new StoryMetadata(scenarioType, storyAttribute);
3022
}
3123

3224
StoryMetadata GetStoryMetadata(object testObject, Type explicityStoryType)
@@ -39,45 +31,7 @@ StoryMetadata GetStoryMetadata(object testObject, Type explicityStoryType)
3931
if (storyAttribute == null)
4032
return null;
4133

42-
return CreateStoryMetadata(candidateStoryType, storyAttribute);
43-
}
44-
45-
static StoryMetadata CreateStoryMetadata(Type storyType, StoryAttribute storyAttribute)
46-
{
47-
var title = storyAttribute.Title;
48-
if (string.IsNullOrEmpty(title))
49-
title = NetToString.Convert(storyType.Name);
50-
51-
string narrative1, narrative2, narrative3;
52-
53-
if (!string.IsNullOrWhiteSpace(storyAttribute.InOrderTo))
54-
{
55-
narrative1 = CleanseProperty(storyAttribute.InOrderTo, In_order_to_prefix);
56-
narrative2 = CleanseProperty(storyAttribute.AsA, As_a_prefix);
57-
narrative3 = CleanseProperty(storyAttribute.IWant, I_want_prefix);
58-
}
59-
else
60-
{
61-
narrative1 = CleanseProperty(storyAttribute.AsA, As_a_prefix);
62-
narrative2 = CleanseProperty(storyAttribute.IWant, I_want_prefix);
63-
narrative3 = CleanseProperty(storyAttribute.SoThat, So_that_prefix);
64-
}
65-
66-
return new StoryMetadata(storyType, narrative1, narrative2, narrative3, title);
67-
}
68-
69-
static string CleanseProperty(string text, string prefix)
70-
{
71-
var property = new StringBuilder();
72-
73-
if (string.IsNullOrWhiteSpace(text))
74-
return null;
75-
76-
if (!text.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
77-
property.AppendFormat("{0} ", prefix);
78-
79-
property.Append(text);
80-
return property.ToString();
34+
return new StoryMetadata(candidateStoryType, storyAttribute);
8135
}
8236

8337
protected virtual Type GetCandidateStory(object testObject, Type explicitStoryType)
@@ -99,9 +53,9 @@ protected virtual Type GetCandidateStory(object testObject, Type explicitStoryTy
9953
return firstFrame.GetMethod().DeclaringType;
10054
}
10155

102-
static StoryAttribute GetStoryAttribute(Type candidateStoryType)
56+
static StoryNarrativeAttribute GetStoryAttribute(Type candidateStoryType)
10357
{
104-
return (StoryAttribute)candidateStoryType.GetCustomAttributes(typeof(StoryAttribute), true).FirstOrDefault();
58+
return (StoryNarrativeAttribute)candidateStoryType.GetCustomAttributes(typeof(StoryNarrativeAttribute), true).FirstOrDefault();
10559
}
10660
}
10761
}

TestStack.BDDfy/Scanners/StoryMetadata.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ namespace TestStack.BDDfy
44
{
55
public class StoryMetadata
66
{
7+
public StoryMetadata(Type storyType, StoryNarrativeAttribute narrative)
8+
: this(storyType, narrative.Narrative1, narrative.Narrative2, narrative.Narrative3, narrative.Title)
9+
{
10+
}
11+
712
public StoryMetadata(Type storyType, string narrative1, string narrative2, string narrative3, string storyTitle = null)
813
{
914
Title = storyTitle ?? NetToString.Convert(storyType.Name);

TestStack.BDDfy/StoryAttribute.cs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,30 @@
33
namespace TestStack.BDDfy
44
{
55
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
6-
public class StoryAttribute : Attribute
6+
public class StoryAttribute : StoryNarrativeAttribute
77
{
8-
public string Title { get; set; }
9-
public string AsA { get; set; }
10-
public string IWant { get; set; }
11-
public string SoThat { get; set; }
12-
public string InOrderTo { get; set; }
8+
// ReSharper disable InconsistentNaming
9+
private const string I_want_prefix = "I want";
10+
private const string So_that_prefix = "So that";
11+
private const string As_a_prefix = "As a";
12+
// ReSharper restore InconsistentNaming
13+
14+
public string AsA
15+
{
16+
get { return Narrative1; }
17+
set { Narrative1 = CleanseProperty(value, As_a_prefix); }
18+
}
19+
20+
public string IWant
21+
{
22+
get { return Narrative2; }
23+
set { Narrative2 = CleanseProperty(value, I_want_prefix); }
24+
}
25+
26+
public string SoThat
27+
{
28+
get { return Narrative3; }
29+
set { Narrative3 = CleanseProperty(value, So_that_prefix); }
30+
}
1331
}
1432
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Text;
3+
4+
namespace TestStack.BDDfy
5+
{
6+
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
7+
public class StoryNarrativeAttribute : Attribute
8+
{
9+
public string Title { get; set; }
10+
public string Narrative1 { get; set; }
11+
public string Narrative2 { get; set; }
12+
public string Narrative3 { get; set; }
13+
14+
protected string CleanseProperty(string text, string prefix)
15+
{
16+
var property = new StringBuilder();
17+
18+
if (string.IsNullOrWhiteSpace(text))
19+
return null;
20+
21+
if (!text.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
22+
property.AppendFormat("{0} ", prefix);
23+
24+
property.Append(text);
25+
return property.ToString();
26+
}
27+
}
28+
}

TestStack.BDDfy/TestStack.BDDfy.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@
152152
<Compile Include="Scanners\StepScanners\StepScannerExtensions.cs" />
153153
<Compile Include="Scanners\StepScanners\StepTitleException.cs" />
154154
<Compile Include="Scanners\StoryAttributeMetadataScanner.cs" />
155+
<Compile Include="StoryNarrativeAttribute.cs" />
155156
</ItemGroup>
156157
<ItemGroup>
157158
<None Include="BDDfy.snk" />

0 commit comments

Comments
 (0)