Skip to content

Commit

Permalink
Refactored the FakeFaker class (#118)
Browse files Browse the repository at this point in the history
* Removed the FormatException if using null or an empty string.

* Created a separate method for extracting the match.

* Added extra local variables to reduce the length of the result assignment.

* Created the FakerMatch struct that holds the match information

* Added the private modifier to the FakerMatch struct

* Refactored the GetFaker method.

* Refactored the GetValue method.
  • Loading branch information
mrstebo committed Feb 19, 2019
1 parent b5c3d78 commit 0a531ed
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 31 deletions.
63 changes: 41 additions & 22 deletions src/FakerDotNet/Fakers/FakeFaker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,58 @@ public FakeFaker(IFakerContainer fakerContainer)

public string F(string format)
{
if (string.IsNullOrEmpty(format)) throw new FormatException("A string must be specified");
if (string.IsNullOrEmpty(format)) return string.Empty;

var result = format;
Match match;
while ((match = Regex.Match(result, @"\{(\w+).(\w+)\}")).Success)
FakerMatch match;
while ((match = ExtractMatchFrom(result)).Success)
{
var matchData = ExtractMatchDataFrom(match);
var faker = GetFaker(matchData.faker);
var value = GetValue(faker, matchData.method);
var faker = GetFaker(match.Name);
var value = GetValue(faker, match.Method);
var start = result.Substring(0, match.Index);
var end = result.Substring(match.Index + match.Length);

result = $"{result.Substring(0, match.Index)}{value}{result.Substring(match.Index + match.Length)}";
result = $"{start}{value}{end}";
}

return result;
}
private static (string faker, string method) ExtractMatchDataFrom(Match match)

private static FakerMatch ExtractMatchFrom(string input)
{
var className = match.Groups[1].Value;
var methodName = match.Groups[2].Value;
const string pattern = @"\{(\w+).(\w+)\}";
var match = Regex.Match(input, pattern);

return (className, methodName);
return match.Success
? new FakerMatch
{
Success = true,
Index = match.Index,
Length = match.Length,
Name = match.Groups[1].Value,
Method = match.Groups[2].Value
}
: new FakerMatch();
}

private PropertyInfo GetFaker(string name)
{
var propertyInfo = _fakerContainer.GetType()
.GetProperty(name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

return propertyInfo ?? throw new FormatException($"Invalid module: {name}");
const BindingFlags flags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance;

return _fakerContainer.GetType().GetProperty(name, flags)
?? throw new FormatException($"Invalid module: {name}");
}

private string GetValue(PropertyInfo propertyInfo, string methodName)
{
var method = propertyInfo.PropertyType
.GetMethod(methodName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

if (method == null) throw new FormatException($"Invalid method: {propertyInfo.Name}.{methodName}");

const BindingFlags flags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance;
var method = propertyInfo.PropertyType.GetMethod(methodName, flags)
?? throw new FormatException($"Invalid method: {propertyInfo.Name}.{methodName}");

var parameters = method.GetParameters().Select(DefaultValue).ToArray();
var value = method.Invoke(propertyInfo.GetValue(_fakerContainer, null), parameters);

return Convert.ToString(method.Invoke(propertyInfo.GetValue(_fakerContainer, null), parameters));
return Convert.ToString(value);
}

private static object DefaultValue(ParameterInfo parameterInfo)
Expand All @@ -71,5 +81,14 @@ private static object DefaultValue(ParameterInfo parameterInfo)
? Activator.CreateInstance(parameterInfo.ParameterType)
: null;
}

private struct FakerMatch
{
public bool Success;
public int Index;
public int Length;
public string Name;
public string Method;
}
}
}
14 changes: 5 additions & 9 deletions tests/FakerDotNet.Tests/Fakers/FakeFakerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,11 @@ public void F_is_not_case_sensitive()
}

[Test]
public void F_with_empty_string_throws_FormatException()
public void F_with_empty_string_returns_back_the_empty_string()
{
const string format = "";

var ex = Assert.Throws<FormatException>(() => _fakeFaker.F(format));

Assert.AreEqual("A string must be specified", ex.Message);

Assert.AreEqual(format, _fakeFaker.F(format));
}

[Test]
Expand All @@ -82,11 +80,9 @@ public void F_with_invalid_method_throws_FormatException()
}

[Test]
public void F_with_null_throws_FormatException()
public void F_with_null_returns_an_empty_string()
{
var ex = Assert.Throws<FormatException>(() => _fakeFaker.F(null));

Assert.AreEqual("A string must be specified", ex.Message);
Assert.AreEqual(string.Empty, _fakeFaker.F(null));
}
}
}

0 comments on commit 0a531ed

Please sign in to comment.