Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetDiscreteEnum for when the enum is not used as property #798

Merged
merged 5 commits into from
May 20, 2020
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
20 changes: 16 additions & 4 deletions TechTalk.SpecFlow/Assist/RowExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,34 @@ public static char GetChar(this TableRow row, string id)
return Convert.ToChar(row[id]);
}

internal static Enum GetEnumFromSingleInstanceRow<T>(this TableRow row)
public static T GetDiscreteEnum<T>(this TableRow row, string id) where T : struct, IConvertible
{
return GetTheEnumValue<T>(row[1], row[0]);
var value = row[id].Replace(" ", string.Empty);
T @enum;
if (Enum.TryParse(value, true, out @enum))
return @enum;

throw new InvalidOperationException($"No enum with value {value} found in enum {typeof(T).Name}");
}

public static T GetDiscreteEnum<T>(this TableRow row, string id, T defaultValue) where T : struct, IConvertible
{
var value = row[id].Replace(" ", string.Empty);
T @enum;
return Enum.TryParse(value, true, out @enum) ? @enum : defaultValue;
}

public static TEnum GetEnumValue<TEnum>(this TableRow row, string id)
{
return (TEnum)Enum.Parse(typeof(TEnum), row[id]);
}

public static Enum GetEnum<T>(this TableRow row, string id)
public static Enum GetEnum<T>(this TableRow row, string id) where T : class
{
return GetTheEnumValue<T>(row[id], id);
}

private static Enum GetTheEnumValue<T>(string rowValue, string propertyName)
private static Enum GetTheEnumValue<T>(string rowValue, string propertyName) where T : class
{
var value = rowValue.Replace(" ", string.Empty);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using FluentAssertions;
using TechTalk.SpecFlow.Assist;
using TechTalk.SpecFlow.RuntimeTests.AssistTests.ExampleEntities;
using RowExtensionMethods = TechTalk.SpecFlow.Assist.RowExtensionMethods;

namespace TechTalk.SpecFlow.RuntimeTests.AssistTests
{
Expand Down Expand Up @@ -51,19 +50,55 @@ public void GetEnum_should_return_the_enum_value_from_the_row_even_when_i_mess_u
public void GetEnum_throws_exception_when_the_value_is_not_defined_in_any_Enum_in_the_type()
{
var table = new Table("Sex");
table.AddRow("NotDefinied");

var exceptionThrown = false;
try
{
RowExtensionMethods.GetEnum<Person>(table.Rows.First(), "Sex");
}
catch (InvalidOperationException exception)
{
if (exception.Message == "No enum with value NotDefinied found in type Person")
exceptionThrown = true;
}
exceptionThrown.Should().BeTrue();
table.AddRow("NotDefined");

Action getNotDefinedEnum = () => table.Rows.First().GetEnum<Person>("Sex");

getNotDefinedEnum.Should().Throw<InvalidOperationException>().WithMessage("No enum with value NotDefined found in type Person");
}

[Fact]
public void GetDiscreteEnum_should_return_enum_of_my_specified_type()
{
var table = new Table("Header Not Representing Property Of Any Class");
table.AddRow("Red");

var discreteEnum = table.Rows[0].GetDiscreteEnum<Colors>("Header Not Representing Property Of Any Class");

discreteEnum.Should().Be(Colors.Red);
}

[Fact]
public void GetDiscreteEnum_throws_exception_when_the_value_is_not_defined_in_enum()
{
var table = new Table("Header Not Representing Property Of Any Class");
table.AddRow("NotDefined");

Action getDiscreteEnum = () => table.Rows[0].GetDiscreteEnum<Colors>("Header Not Representing Property Of Any Class");

getDiscreteEnum.Should().Throw<InvalidOperationException>().WithMessage("No enum with value NotDefined found in enum Colors");
}

[Fact]
public void GetDiscreteEnum_should_return_not_default_enum_if_value_matched()
{
var table = new Table("Header Not Representing Property Of Any Class");
table.AddRow("Red");

var discreteEnum = table.Rows[0].GetDiscreteEnum("Header Not Representing Property Of Any Class", Colors.Green);

discreteEnum.Should().Be(Colors.Red);
}

[Fact]
public void GetDiscreteEnum_should_return_default_enum_if_value_is_not_defined_in_enum()
{
var table = new Table("Header Not Representing Property Of Any Class");
table.AddRow("NotDefined");

var discreteEnum = table.Rows[0].GetDiscreteEnum("Header Not Representing Property Of Any Class", Colors.Green);

discreteEnum.Should().Be(Colors.Green);
}

[Fact]
Expand Down Expand Up @@ -117,4 +152,4 @@ public enum ColorsAgain { Red, Green, Blue}

public enum ShirtSizes { Small, Medium, Large }
}
}
}
3 changes: 3 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Fixes for Development:

API Changes:
+ Now allows override of method categories in NUnit to allow for plugin development on this function
+ (breaking) tableRow.GetEnum<T>(..) has now a class contraint on T
+ (breaking) tableRow.GetTheEnumValue<T>(..) has now a class contraint on T
+ added tableRow.GetDiscreteEnum<T>
+ TechTalk.SpecFlow.Assist.ValueRetrievers.* public classes have undergone some refactoring. IValueRetriever interface remains unchanged.

Changes:
Expand Down