From 9967741a82b76430c4dad0a683a9df89c637b213 Mon Sep 17 00:00:00 2001 From: MehdiK Date: Sat, 22 Mar 2014 13:34:52 +0430 Subject: [PATCH 1/3] makes StoryMetadata generic to allow different story narratives --- .../StoryClassAndScenarioClassAreTheSame.cs | 6 +-- ...StoryAttibuteMissesAsATextInAsAProperty.cs | 6 +-- ...ttibuteMissesDuplicateTextsInProperties.cs | 6 +-- ...yAttibuteMissesIWantTextInIWantProperty.cs | 6 +-- ...ttibuteMissesSoThatTextInSoThatProperty.cs | 6 +-- TestStack.BDDfy/Reporters/ConsoleReporter.cs | 6 +-- .../Reporters/Html/HtmlReportBuilder.cs | 8 +-- .../MarkDown/MarkDownReportBuilder.cs | 6 +-- .../Scanners/StoryAttributeMetaDataScanner.cs | 38 +++++++++++++- TestStack.BDDfy/Scanners/StoryMetadata.cs | 49 +++---------------- 10 files changed, 68 insertions(+), 69 deletions(-) diff --git a/TestStack.BDDfy.Tests/Stories/StoryClassAndScenarioClassAreTheSame.cs b/TestStack.BDDfy.Tests/Stories/StoryClassAndScenarioClassAreTheSame.cs index 6f9b42d2..de95a933 100644 --- a/TestStack.BDDfy.Tests/Stories/StoryClassAndScenarioClassAreTheSame.cs +++ b/TestStack.BDDfy.Tests/Stories/StoryClassAndScenarioClassAreTheSame.cs @@ -42,9 +42,9 @@ void andTheNarrativeIsReturnedAsExpected() { var expectedNarrative = (StoryAttribute)typeof(StoryAsScenario).GetCustomAttributes(typeof(StoryAttribute), false).First(); Assert.That(_story.Metadata, Is.Not.Null); - Assert.That(_story.Metadata.AsA, Is.EqualTo(expectedNarrative.AsA)); - Assert.That(_story.Metadata.IWant, Is.EqualTo(expectedNarrative.IWant)); - Assert.That(_story.Metadata.SoThat, Is.EqualTo(expectedNarrative.SoThat)); + Assert.That(_story.Metadata.Narrative1, Is.EqualTo(expectedNarrative.AsA)); + Assert.That(_story.Metadata.Narrative2, Is.EqualTo(expectedNarrative.IWant)); + Assert.That(_story.Metadata.Narrative3, Is.EqualTo(expectedNarrative.SoThat)); } [Test] diff --git a/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesAsATextInAsAProperty.cs b/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesAsATextInAsAProperty.cs index 953b4312..dcc58921 100644 --- a/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesAsATextInAsAProperty.cs +++ b/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesAsATextInAsAProperty.cs @@ -14,9 +14,9 @@ public void Then_it_is_injected_by_BDDfy() { var story = new DummyScenario().BDDfy(); - Assert.That(story.Metadata.AsA, Is.EqualTo("As a programmer")); - Assert.That(story.Metadata.IWant, Is.EqualTo("I want the missing 'As a' to be added to story metadata")); - Assert.That(story.Metadata.SoThat, Is.EqualTo("So that I don't have to duplicate it on the string")); + Assert.That(story.Metadata.Narrative1, Is.EqualTo("As a programmer")); + Assert.That(story.Metadata.Narrative2, Is.EqualTo("I want the missing 'As a' to be added to story metadata")); + Assert.That(story.Metadata.Narrative3, Is.EqualTo("So that I don't have to duplicate it on the string")); } } } \ No newline at end of file diff --git a/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesDuplicateTextsInProperties.cs b/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesDuplicateTextsInProperties.cs index ec698cf4..b6e84a08 100644 --- a/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesDuplicateTextsInProperties.cs +++ b/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesDuplicateTextsInProperties.cs @@ -14,9 +14,9 @@ public void Then_it_is_injected_by_BDDfy() { var story = new DummyScenario().BDDfy(); - Assert.That(story.Metadata.AsA, Is.EqualTo("As a programmer")); - Assert.That(story.Metadata.IWant, Is.EqualTo("I want the missing texts to be added to story metadata")); - Assert.That(story.Metadata.SoThat, Is.EqualTo("So that I don't have to duplicate it on the string")); + Assert.That(story.Metadata.Narrative1, Is.EqualTo("As a programmer")); + Assert.That(story.Metadata.Narrative2, Is.EqualTo("I want the missing texts to be added to story metadata")); + Assert.That(story.Metadata.Narrative3, Is.EqualTo("So that I don't have to duplicate it on the string")); } } } \ No newline at end of file diff --git a/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesIWantTextInIWantProperty.cs b/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesIWantTextInIWantProperty.cs index 55d9900a..cfc88b34 100644 --- a/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesIWantTextInIWantProperty.cs +++ b/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesIWantTextInIWantProperty.cs @@ -14,9 +14,9 @@ public void Then_it_is_injected_by_BDDfy() { var story = new DummyScenario().BDDfy(); - Assert.That(story.Metadata.AsA, Is.EqualTo("As a programmer")); - Assert.That(story.Metadata.IWant, Is.EqualTo("I want the missing 'I want' to be added to story metadata")); - Assert.That(story.Metadata.SoThat, Is.EqualTo("So that I don't have to duplicate it on the string")); + Assert.That(story.Metadata.Narrative1, Is.EqualTo("As a programmer")); + Assert.That(story.Metadata.Narrative2, Is.EqualTo("I want the missing 'I want' to be added to story metadata")); + Assert.That(story.Metadata.Narrative3, Is.EqualTo("So that I don't have to duplicate it on the string")); } } } \ No newline at end of file diff --git a/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesSoThatTextInSoThatProperty.cs b/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesSoThatTextInSoThatProperty.cs index 0fd04b70..2ed00999 100644 --- a/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesSoThatTextInSoThatProperty.cs +++ b/TestStack.BDDfy.Tests/Stories/WhenStoryAttibuteMissesSoThatTextInSoThatProperty.cs @@ -14,9 +14,9 @@ public void Then_it_is_injected_by_BDDfy() { var story = new DummyScenario().BDDfy(); - Assert.That(story.Metadata.AsA, Is.EqualTo("As a programmer")); - Assert.That(story.Metadata.IWant, Is.EqualTo("I want the missing 'So that' to be added to story metadata")); - Assert.That(story.Metadata.SoThat, Is.EqualTo("So that I don't have to duplicate it on the string")); + Assert.That(story.Metadata.Narrative1, Is.EqualTo("As a programmer")); + Assert.That(story.Metadata.Narrative2, Is.EqualTo("I want the missing 'So that' to be added to story metadata")); + Assert.That(story.Metadata.Narrative3, Is.EqualTo("So that I don't have to duplicate it on the string")); } } } \ No newline at end of file diff --git a/TestStack.BDDfy/Reporters/ConsoleReporter.cs b/TestStack.BDDfy/Reporters/ConsoleReporter.cs index aad89f1e..2713be34 100644 --- a/TestStack.BDDfy/Reporters/ConsoleReporter.cs +++ b/TestStack.BDDfy/Reporters/ConsoleReporter.cs @@ -38,9 +38,9 @@ private static void ReportStoryHeader(Story story) return; Console.WriteLine("Story: " + story.Metadata.Title); - Console.WriteLine("\t" + story.Metadata.AsA); - Console.WriteLine("\t" + story.Metadata.IWant); - Console.WriteLine("\t" + story.Metadata.SoThat); + Console.WriteLine("\t" + story.Metadata.Narrative1); + Console.WriteLine("\t" + story.Metadata.Narrative2); + Console.WriteLine("\t" + story.Metadata.Narrative3); } static string PrefixWithSpaceIfRequired(Step step) diff --git a/TestStack.BDDfy/Reporters/Html/HtmlReportBuilder.cs b/TestStack.BDDfy/Reporters/Html/HtmlReportBuilder.cs index 8638677f..85730da4 100644 --- a/TestStack.BDDfy/Reporters/Html/HtmlReportBuilder.cs +++ b/TestStack.BDDfy/Reporters/Html/HtmlReportBuilder.cs @@ -224,13 +224,13 @@ private void AddStoryMetadataAndNarrative(Story story) AddLine(string.Format("
{0}
", story.Metadata.Title)); } - if (story.Metadata != null && !string.IsNullOrEmpty(story.Metadata.AsA)) + if (story.Metadata != null && !string.IsNullOrEmpty(story.Metadata.Narrative1)) { using (OpenTag("
    ", HtmlTag.ul)) { - AddLine(string.Format("
  • {0}
  • ", story.Metadata.AsA)); - AddLine(string.Format("
  • {0}
  • ", story.Metadata.IWant)); - AddLine(string.Format("
  • {0}
  • ", story.Metadata.SoThat)); + AddLine(string.Format("
  • {0}
  • ", story.Metadata.Narrative1)); + AddLine(string.Format("
  • {0}
  • ", story.Metadata.Narrative2)); + AddLine(string.Format("
  • {0}
  • ", story.Metadata.Narrative3)); } } } diff --git a/TestStack.BDDfy/Reporters/MarkDown/MarkDownReportBuilder.cs b/TestStack.BDDfy/Reporters/MarkDown/MarkDownReportBuilder.cs index 63da78ee..b1fd1b75 100644 --- a/TestStack.BDDfy/Reporters/MarkDown/MarkDownReportBuilder.cs +++ b/TestStack.BDDfy/Reporters/MarkDown/MarkDownReportBuilder.cs @@ -13,9 +13,9 @@ public string CreateReport(FileReportModel model) if (story.Metadata != null) { report.AppendLine(string.Format("## Story: {0}", story.Metadata.Title)); - report.AppendLine(string.Format(" **{0}** ", story.Metadata.AsA)); - report.AppendLine(string.Format(" **{0}** ", story.Metadata.IWant)); - report.AppendLine(string.Format(" **{0}** ", story.Metadata.SoThat)); + report.AppendLine(string.Format(" **{0}** ", story.Metadata.Narrative1)); + report.AppendLine(string.Format(" **{0}** ", story.Metadata.Narrative2)); + report.AppendLine(string.Format(" **{0}** ", story.Metadata.Narrative3)); } report.AppendLine(); // separator diff --git a/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs b/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs index 2d02b615..90fc756f 100644 --- a/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs +++ b/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs @@ -1,11 +1,18 @@ using System; using System.Diagnostics; using System.Linq; +using System.Text; namespace TestStack.BDDfy { public class StoryAttributeMetadataScanner : IStoryMetadataScanner { + // ReSharper disable InconsistentNaming + private const string I_want_prefix = "I want"; + private const string So_that_prefix = "So that"; + private const string As_a_prefix = "As a"; + // ReSharper restore InconsistentNaming + public virtual StoryMetadata Scan(object testObject, Type explicitStoryType = null) { return GetStoryMetadata(testObject, explicitStoryType) ?? GetStoryMetadataFromScenario(testObject); @@ -18,7 +25,7 @@ static StoryMetadata GetStoryMetadataFromScenario(object testObject) if (storyAttribute == null) return null; - return new StoryMetadata(scenarioType, storyAttribute); + return CreateStoryMetadata(scenarioType, storyAttribute); } StoryMetadata GetStoryMetadata(object testObject, Type explicityStoryType) @@ -31,7 +38,34 @@ StoryMetadata GetStoryMetadata(object testObject, Type explicityStoryType) if (storyAttribute == null) return null; - return new StoryMetadata(candidateStoryType, storyAttribute); + return CreateStoryMetadata(candidateStoryType, storyAttribute); + } + + static StoryMetadata CreateStoryMetadata(Type storyType, StoryAttribute storyAttribute) + { + var title = storyAttribute.Title; + if (string.IsNullOrEmpty(title)) + title = NetToString.Convert(storyType.Name); + + var narrative1 = CleanseProperty(storyAttribute.AsA, As_a_prefix); + var narrative2 = CleanseProperty(storyAttribute.IWant, I_want_prefix); + var narrative3 = CleanseProperty(storyAttribute.SoThat, So_that_prefix); + + return new StoryMetadata(storyType, narrative1, narrative2, narrative3, title); + } + + static string CleanseProperty(string text, string prefix) + { + var property = new StringBuilder(); + + if (string.IsNullOrWhiteSpace(text)) + return null; + + if (!text.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) + property.AppendFormat("{0} ", prefix); + + property.Append(text); + return property.ToString(); } protected virtual Type GetCandidateStory(object testObject, Type explicitStoryType) diff --git a/TestStack.BDDfy/Scanners/StoryMetadata.cs b/TestStack.BDDfy/Scanners/StoryMetadata.cs index 1df8ae0c..72a851be 100644 --- a/TestStack.BDDfy/Scanners/StoryMetadata.cs +++ b/TestStack.BDDfy/Scanners/StoryMetadata.cs @@ -1,58 +1,23 @@ using System; -using System.Text; namespace TestStack.BDDfy { public class StoryMetadata { - // ReSharper disable InconsistentNaming - private const string I_want_prefix = "I want"; - private const string So_that_prefix = "So that"; - private const string As_a_prefix = "As a"; - // ReSharper restore InconsistentNaming - - public StoryMetadata(Type storyType, StoryAttribute storyAttribute) - { - var title = storyAttribute.Title; - if (string.IsNullOrEmpty(title)) - title = NetToString.Convert(storyType.Name); - - Type = storyType; - Title = title; - - AsA = CleanseProperty(storyAttribute.AsA, As_a_prefix); - IWant= CleanseProperty(storyAttribute.IWant, I_want_prefix); - SoThat = CleanseProperty(storyAttribute.SoThat, So_that_prefix); - } - - public StoryMetadata(Type storyType, string asA, string iWant, string soThat, string storyTitle = null) + public StoryMetadata(Type storyType, string narrative1, string narrative2, string narrative3, string storyTitle = null) { Title = storyTitle ?? NetToString.Convert(storyType.Name); Type = storyType; - AsA = CleanseProperty(asA, As_a_prefix); - IWant = CleanseProperty(iWant, I_want_prefix); - SoThat = CleanseProperty(soThat, So_that_prefix); - } - - string CleanseProperty(string text, string prefix) - { - var property = new StringBuilder(); - - if (string.IsNullOrWhiteSpace(text)) - return null; - - if (!text.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - property.AppendFormat("{0} ", prefix); - - property.Append(text); - return property.ToString(); + Narrative1 = narrative1; + Narrative2 = narrative2; + Narrative3 = narrative3; } public Type Type { get; private set; } public string Title { get; private set; } - public string AsA { get; private set; } - public string IWant { get; private set; } - public string SoThat { get; private set; } + public string Narrative1 { get; private set; } + public string Narrative2 { get; private set; } + public string Narrative3 { get; private set; } } } \ No newline at end of file From fc8e7b91664d719809489328ee58eba705466427 Mon Sep 17 00:00:00 2001 From: MehdiK Date: Sat, 22 Mar 2014 14:14:37 +0430 Subject: [PATCH 2/3] added In order to support --- .../Stories/CanUseInOrderToSyntax.cs | 22 +++++++++++++++++++ .../TestStack.BDDfy.Tests.csproj | 1 + .../Scanners/StoryAttributeMetaDataScanner.cs | 18 ++++++++++++--- TestStack.BDDfy/StoryAttribute.cs | 1 + 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 TestStack.BDDfy.Tests/Stories/CanUseInOrderToSyntax.cs diff --git a/TestStack.BDDfy.Tests/Stories/CanUseInOrderToSyntax.cs b/TestStack.BDDfy.Tests/Stories/CanUseInOrderToSyntax.cs new file mode 100644 index 00000000..2864b9c3 --- /dev/null +++ b/TestStack.BDDfy.Tests/Stories/CanUseInOrderToSyntax.cs @@ -0,0 +1,22 @@ +using NUnit.Framework; + +namespace TestStack.BDDfy.Tests.Stories +{ + [TestFixture] + [Story( + InOrderTo = "do something", + AsA = "programmer", + IWant = "this to work")] + public class CanUseInOrderToSyntax + { + [Test] + public void When_InOrderTo_is_specified_the_InOrderTo_syntax_is_used() + { + var story = new DummyScenario().BDDfy(); + + Assert.That(story.Metadata.Narrative1, Is.EqualTo("In order to do something")); + Assert.That(story.Metadata.Narrative2, Is.EqualTo("As a programmer")); + Assert.That(story.Metadata.Narrative3, Is.EqualTo("I want this to work")); + } + } +} diff --git a/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj b/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj index d27090bf..3d435986 100644 --- a/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj +++ b/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj @@ -99,6 +99,7 @@ + diff --git a/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs b/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs index 90fc756f..dd088a11 100644 --- a/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs +++ b/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs @@ -11,6 +11,7 @@ public class StoryAttributeMetadataScanner : IStoryMetadataScanner private const string I_want_prefix = "I want"; private const string So_that_prefix = "So that"; private const string As_a_prefix = "As a"; + private const string In_order_to_prefix = "In order to"; // ReSharper restore InconsistentNaming public virtual StoryMetadata Scan(object testObject, Type explicitStoryType = null) @@ -47,9 +48,20 @@ static StoryMetadata CreateStoryMetadata(Type storyType, StoryAttribute storyAtt if (string.IsNullOrEmpty(title)) title = NetToString.Convert(storyType.Name); - var narrative1 = CleanseProperty(storyAttribute.AsA, As_a_prefix); - var narrative2 = CleanseProperty(storyAttribute.IWant, I_want_prefix); - var narrative3 = CleanseProperty(storyAttribute.SoThat, So_that_prefix); + string narrative1, narrative2, narrative3; + + if (!string.IsNullOrWhiteSpace(storyAttribute.InOrderTo)) + { + narrative1 = CleanseProperty(storyAttribute.InOrderTo, In_order_to_prefix); + narrative2 = CleanseProperty(storyAttribute.AsA, As_a_prefix); + narrative3 = CleanseProperty(storyAttribute.IWant, I_want_prefix); + } + else + { + narrative1 = CleanseProperty(storyAttribute.AsA, As_a_prefix); + narrative2 = CleanseProperty(storyAttribute.IWant, I_want_prefix); + narrative3 = CleanseProperty(storyAttribute.SoThat, So_that_prefix); + } return new StoryMetadata(storyType, narrative1, narrative2, narrative3, title); } diff --git a/TestStack.BDDfy/StoryAttribute.cs b/TestStack.BDDfy/StoryAttribute.cs index 3341ef90..80537c90 100644 --- a/TestStack.BDDfy/StoryAttribute.cs +++ b/TestStack.BDDfy/StoryAttribute.cs @@ -9,5 +9,6 @@ public class StoryAttribute : Attribute public string AsA { get; set; } public string IWant { get; set; } public string SoThat { get; set; } + public string InOrderTo { get; set; } } } \ No newline at end of file From 7f61915d50340c08f685033cccb661932c5f1e60 Mon Sep 17 00:00:00 2001 From: MehdiK Date: Sun, 23 Mar 2014 02:07:44 +0430 Subject: [PATCH 3/3] Created StoryNarrativeAttribute to allow for simpler custom story attributes --- .../Stories/CanUseACustomStoryAttribute.cs | 49 +++++++++++++++++ .../Stories/CanUseInOrderToSyntax.cs | 22 -------- .../TestStack.BDDfy.Tests.csproj | 2 +- .../Scanners/StoryAttributeMetaDataScanner.cs | 54 ++----------------- TestStack.BDDfy/Scanners/StoryMetadata.cs | 5 ++ TestStack.BDDfy/StoryAttribute.cs | 30 ++++++++--- TestStack.BDDfy/StoryNarrativeAttribute.cs | 28 ++++++++++ TestStack.BDDfy/TestStack.BDDfy.csproj | 1 + 8 files changed, 112 insertions(+), 79 deletions(-) create mode 100644 TestStack.BDDfy.Tests/Stories/CanUseACustomStoryAttribute.cs delete mode 100644 TestStack.BDDfy.Tests/Stories/CanUseInOrderToSyntax.cs create mode 100644 TestStack.BDDfy/StoryNarrativeAttribute.cs diff --git a/TestStack.BDDfy.Tests/Stories/CanUseACustomStoryAttribute.cs b/TestStack.BDDfy.Tests/Stories/CanUseACustomStoryAttribute.cs new file mode 100644 index 00000000..b5540ec0 --- /dev/null +++ b/TestStack.BDDfy.Tests/Stories/CanUseACustomStoryAttribute.cs @@ -0,0 +1,49 @@ +using NUnit.Framework; + +namespace TestStack.BDDfy.Tests.Stories +{ + class InOrderToStoryAttribute : StoryNarrativeAttribute + { + // ReSharper disable InconsistentNaming + private const string As_a_prefix = "As a"; + private const string In_order_to_prefix = "In order to"; + private const string I_want_prefix = "I want"; + // ReSharper restore InconsistentNaming + + public string InOrderTo + { + get { return Narrative1; } + set { Narrative1 = CleanseProperty(value, In_order_to_prefix); } + } + + public string AsA + { + get { return Narrative2; } + set { Narrative2 = CleanseProperty(value, As_a_prefix); } + } + + public string IWant + { + get { return Narrative3; } + set { Narrative3 = CleanseProperty(value, I_want_prefix); } + } + } + + [TestFixture] + [InOrderToStory( + InOrderTo = "do something", + AsA = "programmer", + IWant = "this to work")] + public class CanUseACustomStoryAttribute + { + [Test] + public void When_InOrderTo_is_specified_the_InOrderTo_syntax_is_used() + { + var story = new DummyScenario().BDDfy(); + + Assert.That(story.Metadata.Narrative1, Is.EqualTo("In order to do something")); + Assert.That(story.Metadata.Narrative2, Is.EqualTo("As a programmer")); + Assert.That(story.Metadata.Narrative3, Is.EqualTo("I want this to work")); + } + } +} diff --git a/TestStack.BDDfy.Tests/Stories/CanUseInOrderToSyntax.cs b/TestStack.BDDfy.Tests/Stories/CanUseInOrderToSyntax.cs deleted file mode 100644 index 2864b9c3..00000000 --- a/TestStack.BDDfy.Tests/Stories/CanUseInOrderToSyntax.cs +++ /dev/null @@ -1,22 +0,0 @@ -using NUnit.Framework; - -namespace TestStack.BDDfy.Tests.Stories -{ - [TestFixture] - [Story( - InOrderTo = "do something", - AsA = "programmer", - IWant = "this to work")] - public class CanUseInOrderToSyntax - { - [Test] - public void When_InOrderTo_is_specified_the_InOrderTo_syntax_is_used() - { - var story = new DummyScenario().BDDfy(); - - Assert.That(story.Metadata.Narrative1, Is.EqualTo("In order to do something")); - Assert.That(story.Metadata.Narrative2, Is.EqualTo("As a programmer")); - Assert.That(story.Metadata.Narrative3, Is.EqualTo("I want this to work")); - } - } -} diff --git a/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj b/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj index 3d435986..cb27129d 100644 --- a/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj +++ b/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj @@ -99,7 +99,7 @@ - + diff --git a/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs b/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs index dd088a11..d89ea4fb 100644 --- a/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs +++ b/TestStack.BDDfy/Scanners/StoryAttributeMetaDataScanner.cs @@ -1,19 +1,11 @@ using System; using System.Diagnostics; using System.Linq; -using System.Text; namespace TestStack.BDDfy { public class StoryAttributeMetadataScanner : IStoryMetadataScanner { - // ReSharper disable InconsistentNaming - private const string I_want_prefix = "I want"; - private const string So_that_prefix = "So that"; - private const string As_a_prefix = "As a"; - private const string In_order_to_prefix = "In order to"; - // ReSharper restore InconsistentNaming - public virtual StoryMetadata Scan(object testObject, Type explicitStoryType = null) { return GetStoryMetadata(testObject, explicitStoryType) ?? GetStoryMetadataFromScenario(testObject); @@ -26,7 +18,7 @@ static StoryMetadata GetStoryMetadataFromScenario(object testObject) if (storyAttribute == null) return null; - return CreateStoryMetadata(scenarioType, storyAttribute); + return new StoryMetadata(scenarioType, storyAttribute); } StoryMetadata GetStoryMetadata(object testObject, Type explicityStoryType) @@ -39,45 +31,7 @@ StoryMetadata GetStoryMetadata(object testObject, Type explicityStoryType) if (storyAttribute == null) return null; - return CreateStoryMetadata(candidateStoryType, storyAttribute); - } - - static StoryMetadata CreateStoryMetadata(Type storyType, StoryAttribute storyAttribute) - { - var title = storyAttribute.Title; - if (string.IsNullOrEmpty(title)) - title = NetToString.Convert(storyType.Name); - - string narrative1, narrative2, narrative3; - - if (!string.IsNullOrWhiteSpace(storyAttribute.InOrderTo)) - { - narrative1 = CleanseProperty(storyAttribute.InOrderTo, In_order_to_prefix); - narrative2 = CleanseProperty(storyAttribute.AsA, As_a_prefix); - narrative3 = CleanseProperty(storyAttribute.IWant, I_want_prefix); - } - else - { - narrative1 = CleanseProperty(storyAttribute.AsA, As_a_prefix); - narrative2 = CleanseProperty(storyAttribute.IWant, I_want_prefix); - narrative3 = CleanseProperty(storyAttribute.SoThat, So_that_prefix); - } - - return new StoryMetadata(storyType, narrative1, narrative2, narrative3, title); - } - - static string CleanseProperty(string text, string prefix) - { - var property = new StringBuilder(); - - if (string.IsNullOrWhiteSpace(text)) - return null; - - if (!text.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - property.AppendFormat("{0} ", prefix); - - property.Append(text); - return property.ToString(); + return new StoryMetadata(candidateStoryType, storyAttribute); } protected virtual Type GetCandidateStory(object testObject, Type explicitStoryType) @@ -99,9 +53,9 @@ protected virtual Type GetCandidateStory(object testObject, Type explicitStoryTy return firstFrame.GetMethod().DeclaringType; } - static StoryAttribute GetStoryAttribute(Type candidateStoryType) + static StoryNarrativeAttribute GetStoryAttribute(Type candidateStoryType) { - return (StoryAttribute)candidateStoryType.GetCustomAttributes(typeof(StoryAttribute), true).FirstOrDefault(); + return (StoryNarrativeAttribute)candidateStoryType.GetCustomAttributes(typeof(StoryNarrativeAttribute), true).FirstOrDefault(); } } } \ No newline at end of file diff --git a/TestStack.BDDfy/Scanners/StoryMetadata.cs b/TestStack.BDDfy/Scanners/StoryMetadata.cs index 72a851be..a611193f 100644 --- a/TestStack.BDDfy/Scanners/StoryMetadata.cs +++ b/TestStack.BDDfy/Scanners/StoryMetadata.cs @@ -4,6 +4,11 @@ namespace TestStack.BDDfy { public class StoryMetadata { + public StoryMetadata(Type storyType, StoryNarrativeAttribute narrative) + : this(storyType, narrative.Narrative1, narrative.Narrative2, narrative.Narrative3, narrative.Title) + { + } + public StoryMetadata(Type storyType, string narrative1, string narrative2, string narrative3, string storyTitle = null) { Title = storyTitle ?? NetToString.Convert(storyType.Name); diff --git a/TestStack.BDDfy/StoryAttribute.cs b/TestStack.BDDfy/StoryAttribute.cs index 80537c90..cc449d2a 100644 --- a/TestStack.BDDfy/StoryAttribute.cs +++ b/TestStack.BDDfy/StoryAttribute.cs @@ -3,12 +3,30 @@ namespace TestStack.BDDfy { [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] - public class StoryAttribute : Attribute + public class StoryAttribute : StoryNarrativeAttribute { - public string Title { get; set; } - public string AsA { get; set; } - public string IWant { get; set; } - public string SoThat { get; set; } - public string InOrderTo { get; set; } + // ReSharper disable InconsistentNaming + private const string I_want_prefix = "I want"; + private const string So_that_prefix = "So that"; + private const string As_a_prefix = "As a"; + // ReSharper restore InconsistentNaming + + public string AsA + { + get { return Narrative1; } + set { Narrative1 = CleanseProperty(value, As_a_prefix); } + } + + public string IWant + { + get { return Narrative2; } + set { Narrative2 = CleanseProperty(value, I_want_prefix); } + } + + public string SoThat + { + get { return Narrative3; } + set { Narrative3 = CleanseProperty(value, So_that_prefix); } + } } } \ No newline at end of file diff --git a/TestStack.BDDfy/StoryNarrativeAttribute.cs b/TestStack.BDDfy/StoryNarrativeAttribute.cs new file mode 100644 index 00000000..ae82e0e6 --- /dev/null +++ b/TestStack.BDDfy/StoryNarrativeAttribute.cs @@ -0,0 +1,28 @@ +using System; +using System.Text; + +namespace TestStack.BDDfy +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] + public class StoryNarrativeAttribute : Attribute + { + public string Title { get; set; } + public string Narrative1 { get; set; } + public string Narrative2 { get; set; } + public string Narrative3 { get; set; } + + protected string CleanseProperty(string text, string prefix) + { + var property = new StringBuilder(); + + if (string.IsNullOrWhiteSpace(text)) + return null; + + if (!text.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) + property.AppendFormat("{0} ", prefix); + + property.Append(text); + return property.ToString(); + } + } +} diff --git a/TestStack.BDDfy/TestStack.BDDfy.csproj b/TestStack.BDDfy/TestStack.BDDfy.csproj index 1b346e0c..d2cdc795 100644 --- a/TestStack.BDDfy/TestStack.BDDfy.csproj +++ b/TestStack.BDDfy/TestStack.BDDfy.csproj @@ -152,6 +152,7 @@ +