Forked from anonymous/StringCalculatorTests.cs
Last active
December 14, 2015 15:58
-
-
Save druttka/5111493 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// I described the thought processes (SOLID violations, which to fix, how and why) | |
// in my post at http://thedevstop.wordpress.com/2013/03/07/roy-osheroves-solid-katastring-calculator-redux/ | |
// Note that I did this in LINQPad and so instead of NUnit tests, I dumped failures | |
// If I was to do this again, I'd either do it in VS with a test runner. | |
void Main() | |
{ | |
var parser = new IntsFromCommaSeparatedString(); | |
var none = parser.Parse("").ToArray(); | |
AssertEqual(0, none.Length); | |
var one = parser.Parse("1").ToArray(); | |
AssertEqual(1, one.Length); | |
AssertEqual(1, one[0]); | |
var two = parser.Parse("1,2").ToArray(); | |
AssertEqual(2, two.Length); | |
AssertEqual(1, two[0]); | |
AssertEqual(2, two[1]); | |
var calc = new StringCalculator(parser, new SimpleDefault<int>()); | |
AssertEqual(0, calc.Add("")); | |
AssertEqual(1, calc.Add("1")); | |
AssertEqual(3, calc.Add("1,2")); | |
} | |
public interface IParseInts | |
{ | |
IEnumerable<int> Parse(string input); | |
} | |
public interface IDefault<T> | |
{ | |
T GetDefault(string input); | |
} | |
public class SimpleDefault<T> : IDefault<T> | |
{ | |
public T GetDefault(string input) | |
{ | |
return default(T); | |
} | |
} | |
public class ExceptionDefault<TValue, TException> : IDefault<TValue> | |
where TException : Exception,new() | |
{ | |
public TValue GetDefault(string input) | |
{ | |
throw new TException(); | |
} | |
} | |
public class IntsFromCommaSeparatedString : IParseInts | |
{ | |
public IEnumerable<int> Parse(string input) | |
{ | |
int x; | |
foreach(var part in input.Split(',')) | |
{ | |
if (int.TryParse(part, out x)) | |
yield return x; | |
} | |
} | |
} | |
public class StringCalculator | |
{ | |
private readonly IDefault<int> defaulter; | |
private readonly IParseInts parser; | |
public StringCalculator(IParseInts parser, IDefault<int> defaulter) | |
{ | |
// you could guard against null if you want. Omitted for brevity | |
this.parser = parser; | |
this.defaulter = defaulter; | |
} | |
public int Add(string input) | |
{ | |
var ints = this.parser.Parse(input); | |
if (!ints.Any()) | |
return this.defaulter.GetDefault(input); | |
// Uh-oh. The way I’ve implemented this, I still pass the tests | |
// but I have eliminated the explicit check for empty=>0. | |
// It is only 0 by an implementation coincidence. This is however | |
// irrelevant to the SOLID part of this exercise, so I'll leave it | |
return ints.Sum(); | |
} | |
} | |
// Only for use in the LINQPad query to simulate tests | |
private void AssertEqual(object expected, object actual) | |
{ | |
if (!expected.Equals(actual)) | |
throw new Exception(string.Format("Expected {0} to equal {1}", actual, expected)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment