From cb9db3dc821e98bf01992b5469c4be0c41c30e11 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 30 Apr 2014 09:35:56 +0100 Subject: [PATCH 1/5] Supporting complex types in examples, and expanded expression parser to allow accessing properties on fields etc --- .../ExpressionExtensionsTests.cs | 66 +++++++++++++++---- ...hExamples.ExampleTypeMismatch.approved.txt | 1 + .../FluentScanner/FluentWithExamples.cs | 18 ++++- .../Examples/ExampleValueTests.cs | 18 +++++ .../TestStack.BDDfy.Tests.csproj | 1 + .../Reporters/Html/ClassicReportBuilder.cs | 2 +- .../Reporters/Html/MetroReportBuilder.cs | 2 +- TestStack.BDDfy/Reporters/TextReporter.cs | 2 +- .../StepScanners/Examples/ExampleValue.cs | 18 ++++- .../Examples/UnassignableExampleException.cs | 27 ++++++++ .../Fluent/ExpressionExtensions.cs | 17 ++++- .../StepScanners/StepScannerExtensions.cs | 26 ++++---- TestStack.BDDfy/TestStack.BDDfy.csproj | 1 + 13 files changed, 163 insertions(+), 36 deletions(-) create mode 100644 TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.ExampleTypeMismatch.approved.txt create mode 100644 TestStack.BDDfy.Tests/Scanner/StepScanners/Examples/ExampleValueTests.cs create mode 100644 TestStack.BDDfy/Scanners/StepScanners/Examples/UnassignableExampleException.cs diff --git a/TestStack.BDDfy.Tests/Scanner/FluentScanner/ExpressionExtensionsTests.cs b/TestStack.BDDfy.Tests/Scanner/FluentScanner/ExpressionExtensionsTests.cs index 38cb16a0..acc289ee 100644 --- a/TestStack.BDDfy.Tests/Scanner/FluentScanner/ExpressionExtensionsTests.cs +++ b/TestStack.BDDfy.Tests/Scanner/FluentScanner/ExpressionExtensionsTests.cs @@ -29,21 +29,40 @@ protected string[] InheritedArrayInput2 public class ExpressionExtensionsTests : BaseClass { + private class ContainerType + { + public int Target { get; set; } + + public string Target2 { get; set; } + + public ContainerType SubContainer { get; set; } + + public override string ToString() + { + return Target2; + } + } + class ClassUnderTest { public void MethodWithoutArguments() { - + } public void MethodWithInputs(int input1, string input2) { - + } public void MethodWithArrayInputs(int[] input1, string[] input2) { - + + } + + public void MethodWithInputs(ContainerType subContainer) + { + } } @@ -89,6 +108,8 @@ string GetInput2(string someInput) return someInput + " Input 2"; } + ContainerType container = new ContainerType(); + [Test] public void NoArguments() { @@ -96,11 +117,13 @@ public void NoArguments() Assert.That(arguments.Length, Is.EqualTo(0)); } - void AssertReturnedArguments(object[] arguments, object expectedArg1, object expectedArg2) + void AssertReturnedArguments(object[] arguments, params object[] expectedArgs) { - Assert.That(arguments.Length, Is.EqualTo(2)); - Assert.That(arguments[0], Is.EqualTo(expectedArg1)); - Assert.That(arguments[1], Is.EqualTo(expectedArg2)); + Assert.That(arguments.Length, Is.EqualTo(expectedArgs.Length)); + for (int i = 0; i < expectedArgs.Length; i++) + { + Assert.That(arguments[i], Is.EqualTo(expectedArgs[i])); + } } [Test] @@ -132,14 +155,14 @@ public void InputArgumentsProvidedUsingProperty() var arguments = GetArguments(x => x.MethodWithInputs(Input1, Input2), new ClassUnderTest()); AssertReturnedArguments(arguments, Input1, Input2); } - + [Test] public void InputArgumentsProvidedUsingInheritedFields() { var arguments = GetArguments(x => x.MethodWithInputs(InheritedInput1, InheritedInput2), new ClassUnderTest()); AssertReturnedArguments(arguments, InheritedInput1, InheritedInput2); } - + [Test] public void InputArgumentsProvidedUsingMethodCallDoesNotThrow() { @@ -150,14 +173,14 @@ public void InputArgumentsProvidedUsingMethodCallDoesNotThrow() public void ArrayInputsArgumentsProvidedInline() { var arguments = GetArguments(x => x.MethodWithArrayInputs(new[] { 1, 2 }, new[] { "3", "4" }), new ClassUnderTest()); - AssertReturnedArguments(arguments, new[] {1, 2}, new[] {"3", "4"}); + AssertReturnedArguments(arguments, new[] { 1, 2 }, new[] { "3", "4" }); } [Test] public void ArrayInputArgumentsProvidedUsingVariables() { - var input1 = new[] {1, 2}; - var input2 = new[] {"3", "4"}; + var input1 = new[] { 1, 2 }; + var input2 = new[] { "3", "4" }; var arguments = GetArguments(x => x.MethodWithArrayInputs(input1, input2), new ClassUnderTest()); AssertReturnedArguments(arguments, input1, input2); } @@ -176,6 +199,25 @@ public void ArrayInputArgumentsProvidedUsingProperty() AssertReturnedArguments(arguments, ArrayInput1, ArrayInput2); } + [Test] + public void ComplexArgument() + { + container.Target = 1; + container.SubContainer = new ContainerType { Target2 = "Foo" }; + + var arguments = GetArguments(x => x.MethodWithInputs(container.Target, container.SubContainer.Target2), new ClassUnderTest()); + AssertReturnedArguments(arguments, 1, "Foo"); + } + + [Test] + public void ComplexArgument2() + { + container.SubContainer = new ContainerType { Target2 = "Foo" }; + + var arguments = GetArguments(x => x.MethodWithInputs(container.SubContainer), new ClassUnderTest()); + AssertReturnedArguments(arguments, container.SubContainer); + } + [Test] public void ArrayInputArgumentsProvidedUsingInheritedProperty() { diff --git a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.ExampleTypeMismatch.approved.txt b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.ExampleTypeMismatch.approved.txt new file mode 100644 index 00000000..72072f7a --- /dev/null +++ b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.ExampleTypeMismatch.approved.txt @@ -0,0 +1 @@ +Wrong type: System.Object cannot be assigned to Int32 \ No newline at end of file diff --git a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs index 86750423..0707e211 100644 --- a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs +++ b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs @@ -31,6 +31,21 @@ public void FluentCanBeUsedWithExamples() Approvals.Verify(textReporter.ToString()); } + [Test] + public void ExampleTypeMismatch() + { + var ex = Should.Throw( + () => this.Given(() => WrongType.ShouldBe(1), "Given i use an example") + .WithExamples(new ExampleTable("Wrong type") + { + new object(), + new object[] { null } + }) + .BDDfy()); + + Approvals.Verify(ex.Message); + } + private void AndIUseA(string multiWordHeading) { multiWordHeading.ShouldBeOneOf("", "val2"); @@ -44,7 +59,7 @@ private void GivenADifferentMethodWith(string prop2) private void GivenADifferentMethodWithRandomArg(int foo) { - + } private void ThenAllIsGood() @@ -63,6 +78,7 @@ private void GivenMethodTaking__ExampleInt__(int exampleInt) exampleInt.ShouldBeInRange(1, 2); } + public int WrongType { get; set; } public int Prop1 { get; set; } private string _prop2 = null; private string multiWordHeading = null; diff --git a/TestStack.BDDfy.Tests/Scanner/StepScanners/Examples/ExampleValueTests.cs b/TestStack.BDDfy.Tests/Scanner/StepScanners/Examples/ExampleValueTests.cs new file mode 100644 index 00000000..28b0acde --- /dev/null +++ b/TestStack.BDDfy.Tests/Scanner/StepScanners/Examples/ExampleValueTests.cs @@ -0,0 +1,18 @@ +using System; +using NUnit.Framework; +using Shouldly; + +namespace TestStack.BDDfy.Tests.Scanner.StepScanners.Examples +{ + public class ExampleValueTests + { + [Test] + public void CanFormatAsStringTests() + { + new ExampleValue("Header", null, () => 0).GetValueAsString().ShouldBe("'null'"); + new ExampleValue("Header", 1, () => 0).GetValueAsString().ShouldBe("1"); + new ExampleValue("Header", new Object(), () => 0).GetValueAsString().ShouldBe("System.Object"); + new ExampleValue("Header", new[] {1, 2}, () => 0).GetValueAsString().ShouldBe("1, 2"); + } + } +} \ No newline at end of file diff --git a/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj b/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj index 1400d110..2d1ce722 100644 --- a/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj +++ b/TestStack.BDDfy.Tests/TestStack.BDDfy.Tests.csproj @@ -90,6 +90,7 @@ + diff --git a/TestStack.BDDfy/Reporters/Html/ClassicReportBuilder.cs b/TestStack.BDDfy/Reporters/Html/ClassicReportBuilder.cs index 74cd5f8a..cf43d5ee 100644 --- a/TestStack.BDDfy/Reporters/Html/ClassicReportBuilder.cs +++ b/TestStack.BDDfy/Reporters/Html/ClassicReportBuilder.cs @@ -241,7 +241,7 @@ private void AddExampleRow(Scenario scenario, Result scenarioResult) { AddLine(string.Format("", scenario.Result)); foreach (var exampleValue in scenario.Example.Values) - AddLine(string.Format("{0}", HttpUtility.HtmlEncode(exampleValue.GetValue(typeof(string))))); + AddLine(string.Format("{0}", HttpUtility.HtmlEncode(exampleValue.GetValueAsString()))); if (scenarioResult != Result.Failed) return; diff --git a/TestStack.BDDfy/Reporters/Html/MetroReportBuilder.cs b/TestStack.BDDfy/Reporters/Html/MetroReportBuilder.cs index 9c4018e4..1a0c96e2 100644 --- a/TestStack.BDDfy/Reporters/Html/MetroReportBuilder.cs +++ b/TestStack.BDDfy/Reporters/Html/MetroReportBuilder.cs @@ -284,7 +284,7 @@ private void AddExampleRow(Scenario scenario, Result scenarioResult) { AddLine(string.Format("", scenario.Result)); foreach (var exampleValue in scenario.Example.Values) - AddLine(string.Format("{0}", HttpUtility.HtmlEncode(exampleValue.GetValue(typeof(string))))); + AddLine(string.Format("{0}", HttpUtility.HtmlEncode(exampleValue.GetValueAsString()))); if (scenarioResult != Result.Failed) return; diff --git a/TestStack.BDDfy/Reporters/TextReporter.cs b/TestStack.BDDfy/Reporters/TextReporter.cs index 30cc176a..1793ce70 100644 --- a/TestStack.BDDfy/Reporters/TextReporter.cs +++ b/TestStack.BDDfy/Reporters/TextReporter.cs @@ -97,7 +97,7 @@ private void WriteExamples(Scenario exampleScenario, IEnumerable scena ? null : string.Format("Step: {0} failed with exception: {1}", failingStep.Title, CreateExceptionMessage(failingStep)); - addRow(scenario.Example.Values.Select(e => (string)e.GetValue(typeof(string))), scenario.Result.ToString(), error); + addRow(scenario.Example.Values.Select(e => e.GetValueAsString()), scenario.Result.ToString(), error); } foreach (var row in rows) diff --git a/TestStack.BDDfy/Scanners/StepScanners/Examples/ExampleValue.cs b/TestStack.BDDfy/Scanners/StepScanners/Examples/ExampleValue.cs index d86cc03b..d570e179 100644 --- a/TestStack.BDDfy/Scanners/StepScanners/Examples/ExampleValue.cs +++ b/TestStack.BDDfy/Scanners/StepScanners/Examples/ExampleValue.cs @@ -34,7 +34,7 @@ public object GetValue(Type targetType) var stringValue = _underlyingValue as string; if (_underlyingValue == null) { - if (targetType.IsValueType && !(targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof (Nullable<>))) + if (targetType.IsValueType && !(targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable<>))) { var valueAsString = string.IsNullOrEmpty(stringValue) ? "" : string.Format("\"{0}\"", _underlyingValue); throw new ArgumentException(string.Format("Cannot convert {0} to {1} (Column: '{2}', Row: {3})", valueAsString, targetType.Name, Header, Row)); @@ -49,10 +49,17 @@ public object GetValue(Type targetType) if (targetType.IsEnum && _underlyingValue is string) return Enum.Parse(targetType, (string)_underlyingValue); - if (targetType == typeof (DateTime)) + if (targetType == typeof(DateTime)) return DateTime.Parse(stringValue); - return Convert.ChangeType(_underlyingValue, targetType); + try + { + return Convert.ChangeType(_underlyingValue, targetType); + } + catch (InvalidCastException ex) + { + throw new UnassignableExampleException(string.Format("{0}: {1} cannot be assigned to {2}", Header, _underlyingValue == null ? "" : _underlyingValue.ToString(), targetType.Name), ex); + } } public bool ValueHasBeenUsed { get; private set; } @@ -61,5 +68,10 @@ public override string ToString() { return string.Join("{0}: {1}", Header, _underlyingValue); } + + public string GetValueAsString() + { + return _underlyingValue.FlattenArrays().ToString(); + } } } \ No newline at end of file diff --git a/TestStack.BDDfy/Scanners/StepScanners/Examples/UnassignableExampleException.cs b/TestStack.BDDfy/Scanners/StepScanners/Examples/UnassignableExampleException.cs new file mode 100644 index 00000000..82b09720 --- /dev/null +++ b/TestStack.BDDfy/Scanners/StepScanners/Examples/UnassignableExampleException.cs @@ -0,0 +1,27 @@ +using System; +using System.Runtime.Serialization; + +namespace TestStack.BDDfy +{ + [Serializable] + public class UnassignableExampleException : Exception + { + public UnassignableExampleException() + { + } + + public UnassignableExampleException(string message) : base(message) + { + } + + public UnassignableExampleException(string message, Exception inner) : base(message, inner) + { + } + + protected UnassignableExampleException( + SerializationInfo info, + StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs b/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs index edad581a..e3a8bc3a 100644 --- a/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs +++ b/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs @@ -152,7 +152,6 @@ private static IEnumerable ExtractConvertibleTypeArrayConstants(NewArray private static IEnumerable ExtractArguments(ConstantExpression constantExpression, T value) { - var expression = constantExpression.Value as Expression; if (expression != null) { @@ -220,7 +219,19 @@ private static IEnumerable ExtractConstant(MemberExpression memberExpres private static IEnumerable ExtractPropertyValue(MemberExpression expression, PropertyInfo member, T value) { - return new[] { member.GetValue(value, null) }; + var memberExpression = expression.Expression as MemberExpression; + if (memberExpression != null) + { + var extractArguments = ExtractArguments(memberExpression, value); + return new[] + { + member.GetValue(extractArguments.Single(), null) + }; + } + return new[] + { + member.GetValue(value, null) + }; } } -} +} \ No newline at end of file diff --git a/TestStack.BDDfy/Scanners/StepScanners/StepScannerExtensions.cs b/TestStack.BDDfy/Scanners/StepScanners/StepScannerExtensions.cs index 45f20e4b..e664a75f 100644 --- a/TestStack.BDDfy/Scanners/StepScanners/StepScannerExtensions.cs +++ b/TestStack.BDDfy/Scanners/StepScanners/StepScannerExtensions.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; namespace TestStack.BDDfy @@ -8,22 +7,21 @@ internal static class StepScannerExtensions { internal static object[] FlattenArrays(this object[] inputs) { - var flatArray = new List(); - foreach (var input in inputs) + return inputs.Select(FlattenArrays).ToArray(); + } + + public static object FlattenArrays(this object input) + { + var inputArray = input as Array; + if (inputArray != null) { - var inputArray = input as Array; - if (inputArray != null) - { - var temp = (from object arrElement in inputArray select GetSafeString(arrElement)).ToArray(); - flatArray.Add(string.Join(", ", temp)); - } - else if (input == null) - flatArray.Add("'null'"); - else - flatArray.Add(input); + var temp = (from object arrElement in inputArray select GetSafeString(arrElement)).ToArray(); + return string.Join(", ", temp); } - return flatArray.ToArray(); + if (input == null) return "'null'"; + + return input; } static string GetSafeString(object input) diff --git a/TestStack.BDDfy/TestStack.BDDfy.csproj b/TestStack.BDDfy/TestStack.BDDfy.csproj index f63b56f3..fda73c99 100644 --- a/TestStack.BDDfy/TestStack.BDDfy.csproj +++ b/TestStack.BDDfy/TestStack.BDDfy.csproj @@ -114,6 +114,7 @@ + True True From e09a23b8f16cbe1e4414efd661a6e4074820ee45 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 30 Apr 2014 10:09:56 +0100 Subject: [PATCH 2/5] Trying to fix failing approval test on build server --- .../Scanner/FluentScanner/FluentWithExamples.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs index 0707e211..4f80b415 100644 --- a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs +++ b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs @@ -1,4 +1,5 @@ -using ApprovalTests; +using System.Runtime.CompilerServices; +using ApprovalTests; using NUnit.Framework; using Shouldly; using TestStack.BDDfy.Reporters; @@ -32,6 +33,7 @@ public void FluentCanBeUsedWithExamples() } [Test] + [MethodImpl(MethodImplOptions.NoInlining)] public void ExampleTypeMismatch() { var ex = Should.Throw( From eb2f42ff8caf0d08ccbcbb5eefc2c9a28048de30 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 30 Apr 2014 11:13:58 +0100 Subject: [PATCH 3/5] Tollerate null references in Argument Expression --- .../Scanner/FluentScanner/ExpressionExtensionsTests.cs | 8 ++++++++ .../Scanners/StepScanners/Fluent/ExpressionExtensions.cs | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/TestStack.BDDfy.Tests/Scanner/FluentScanner/ExpressionExtensionsTests.cs b/TestStack.BDDfy.Tests/Scanner/FluentScanner/ExpressionExtensionsTests.cs index acc289ee..056fb917 100644 --- a/TestStack.BDDfy.Tests/Scanner/FluentScanner/ExpressionExtensionsTests.cs +++ b/TestStack.BDDfy.Tests/Scanner/FluentScanner/ExpressionExtensionsTests.cs @@ -218,6 +218,14 @@ public void ComplexArgument2() AssertReturnedArguments(arguments, container.SubContainer); } + [Test] + public void ComplexArgumentWhenContainerIsNull() + { + ContainerType nullContainer = null; + var arguments = GetArguments(x => x.MethodWithInputs(nullContainer.SubContainer), new ClassUnderTest()); + AssertReturnedArguments(arguments, new object[] { null }); + } + [Test] public void ArrayInputArgumentsProvidedUsingInheritedProperty() { diff --git a/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs b/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs index e3a8bc3a..afe96c04 100644 --- a/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs +++ b/TestStack.BDDfy/Scanners/StepScanners/Fluent/ExpressionExtensions.cs @@ -223,10 +223,17 @@ private static IEnumerable ExtractPropertyValue(MemberExpression expr if (memberExpression != null) { var extractArguments = ExtractArguments(memberExpression, value); - return new[] + try + { + return new[] { member.GetValue(extractArguments.Single(), null) }; + } + catch (TargetException) + { + return new object[] {null}; + } } return new[] { From cf0991a2e68c496ea29e8d7c657a5e5eab34b761 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 30 Apr 2014 18:42:00 +0100 Subject: [PATCH 4/5] Switched to normal assertion --- .../FluentWithExamples.ExampleTypeMismatch.approved.txt | 1 - .../Scanner/FluentScanner/FluentWithExamples.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.ExampleTypeMismatch.approved.txt diff --git a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.ExampleTypeMismatch.approved.txt b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.ExampleTypeMismatch.approved.txt deleted file mode 100644 index 72072f7a..00000000 --- a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.ExampleTypeMismatch.approved.txt +++ /dev/null @@ -1 +0,0 @@ -Wrong type: System.Object cannot be assigned to Int32 \ No newline at end of file diff --git a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs index 4f80b415..64da03e4 100644 --- a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs +++ b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs @@ -45,7 +45,7 @@ public void ExampleTypeMismatch() }) .BDDfy()); - Approvals.Verify(ex.Message); + ex.Message.ShouldBe("Wrong type: System.Object cannot be assigned to Int32"); } private void AndIUseA(string multiWordHeading) From 1b3b13598b8b8ceb04c990af38ff9fd027abff4a Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 30 Apr 2014 19:00:07 +0100 Subject: [PATCH 5/5] Fixing review feedback --- .../Scanner/FluentScanner/FluentWithExamples.cs | 2 +- ...rExtensions.cs => ArgumentCleaningExtensions.cs} | 6 +++--- .../Scanners/StepScanners/Examples/ExampleValue.cs | 7 +++++-- .../Examples/UnassignableExampleException.cs | 13 ++++--------- TestStack.BDDfy/TestStack.BDDfy.csproj | 2 +- 5 files changed, 14 insertions(+), 16 deletions(-) rename TestStack.BDDfy/Scanners/StepScanners/{StepScannerExtensions.cs => ArgumentCleaningExtensions.cs} (80%) diff --git a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs index 64da03e4..da8d6e04 100644 --- a/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs +++ b/TestStack.BDDfy.Tests/Scanner/FluentScanner/FluentWithExamples.cs @@ -45,7 +45,7 @@ public void ExampleTypeMismatch() }) .BDDfy()); - ex.Message.ShouldBe("Wrong type: System.Object cannot be assigned to Int32"); + ex.Message.ShouldBe("System.Object cannot be assigned to Int32 (Column: 'Wrong type', Row: 1)"); } private void AndIUseA(string multiWordHeading) diff --git a/TestStack.BDDfy/Scanners/StepScanners/StepScannerExtensions.cs b/TestStack.BDDfy/Scanners/StepScanners/ArgumentCleaningExtensions.cs similarity index 80% rename from TestStack.BDDfy/Scanners/StepScanners/StepScannerExtensions.cs rename to TestStack.BDDfy/Scanners/StepScanners/ArgumentCleaningExtensions.cs index e664a75f..4564c2f8 100644 --- a/TestStack.BDDfy/Scanners/StepScanners/StepScannerExtensions.cs +++ b/TestStack.BDDfy/Scanners/StepScanners/ArgumentCleaningExtensions.cs @@ -3,14 +3,14 @@ namespace TestStack.BDDfy { - internal static class StepScannerExtensions + internal static class ArgumentCleaningExtensions { internal static object[] FlattenArrays(this object[] inputs) { - return inputs.Select(FlattenArrays).ToArray(); + return inputs.Select(FlattenArray).ToArray(); } - public static object FlattenArrays(this object input) + public static object FlattenArray(this object input) { var inputArray = input as Array; if (inputArray != null) diff --git a/TestStack.BDDfy/Scanners/StepScanners/Examples/ExampleValue.cs b/TestStack.BDDfy/Scanners/StepScanners/Examples/ExampleValue.cs index d570e179..cfcc8bde 100644 --- a/TestStack.BDDfy/Scanners/StepScanners/Examples/ExampleValue.cs +++ b/TestStack.BDDfy/Scanners/StepScanners/Examples/ExampleValue.cs @@ -58,7 +58,10 @@ public object GetValue(Type targetType) } catch (InvalidCastException ex) { - throw new UnassignableExampleException(string.Format("{0}: {1} cannot be assigned to {2}", Header, _underlyingValue == null ? "" : _underlyingValue.ToString(), targetType.Name), ex); + throw new UnassignableExampleException(string.Format( + "{0} cannot be assigned to {1} (Column: '{2}', Row: {3})", + _underlyingValue == null ? "" : _underlyingValue.ToString(), + targetType.Name, Header, Row), ex, this); } } @@ -71,7 +74,7 @@ public override string ToString() public string GetValueAsString() { - return _underlyingValue.FlattenArrays().ToString(); + return _underlyingValue.FlattenArray().ToString(); } } } \ No newline at end of file diff --git a/TestStack.BDDfy/Scanners/StepScanners/Examples/UnassignableExampleException.cs b/TestStack.BDDfy/Scanners/StepScanners/Examples/UnassignableExampleException.cs index 82b09720..f374c272 100644 --- a/TestStack.BDDfy/Scanners/StepScanners/Examples/UnassignableExampleException.cs +++ b/TestStack.BDDfy/Scanners/StepScanners/Examples/UnassignableExampleException.cs @@ -6,16 +6,9 @@ namespace TestStack.BDDfy [Serializable] public class UnassignableExampleException : Exception { - public UnassignableExampleException() - { - } - - public UnassignableExampleException(string message) : base(message) - { - } - - public UnassignableExampleException(string message, Exception inner) : base(message, inner) + public UnassignableExampleException(string message, Exception inner, ExampleValue exampleValue) : base(message, inner) { + ExampleValue = exampleValue; } protected UnassignableExampleException( @@ -23,5 +16,7 @@ protected UnassignableExampleException( StreamingContext context) : base(info, context) { } + + public ExampleValue ExampleValue { get; private set; } } } \ No newline at end of file diff --git a/TestStack.BDDfy/TestStack.BDDfy.csproj b/TestStack.BDDfy/TestStack.BDDfy.csproj index fda73c99..67d992fd 100644 --- a/TestStack.BDDfy/TestStack.BDDfy.csproj +++ b/TestStack.BDDfy/TestStack.BDDfy.csproj @@ -162,7 +162,7 @@ - +