Last active
December 11, 2015 20:18
-
-
Save xerxesb/4654224 to your computer and use it in GitHub Desktop.
First run at a solution to the Call Recording/Ordering kata
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
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using NUnit.Framework; | |
using Shouldly; | |
using System.Linq; | |
namespace MethodInfos | |
{ | |
public class Formatter | |
{ | |
public static string DoIt(List<Call> list) | |
{ | |
list.Tap((x, i) => x.CallOrder = i) | |
.Distinct(new TargetComparer()) | |
.Each((c, i) => | |
{ | |
c.InstanceNumber = i + 1; | |
list.Where(x => x.Target == c.Target) | |
.Each((c2, i2) => c2.InstanceNumber = c.InstanceNumber); | |
}); | |
var callsByTargetType = list | |
.GroupBy(call => call.Target.GetType()) | |
.Select(targets => new { | |
targets.Key, | |
HasMoreThanOneInstanceOfType = targets.Distinct(new TargetComparer()).Count() > 1 | |
}); | |
if (callsByTargetType.Any(x => x.HasMoreThanOneInstanceOfType)) | |
{ | |
return String.Join("\r\n", list.Select(x => String.Format("{0}@{1}", x.InstanceNumber, x.MemberCall))); | |
} | |
return String.Join("\r\n", list.Select(x => x.MemberCall)); | |
} | |
} | |
public class TargetComparer : IEqualityComparer<Call> | |
{ | |
[DebuggerStepThrough] | |
public bool Equals(Call x, Call y) | |
{ | |
return x.Target == y.Target; | |
} | |
[DebuggerStepThrough] | |
public int GetHashCode(Call obj) | |
{ | |
return obj.Target.GetHashCode(); | |
} | |
} | |
public class A { } | |
public class B { } | |
[TestFixture] | |
public class MethodInfoTests | |
{ | |
[Test] | |
public void SingleItemShouldDisplaySingleCall() | |
{ | |
var list = new List<Call> { CreateCall(new A(), "Foo.Bar") }; | |
var result = Formatter.DoIt(list); | |
result.ShouldBe("Foo.Bar"); | |
} | |
[Test] | |
public void MultipleCallsOfTheSameObjectShouldDisplayMultipleCalls() | |
{ | |
var a = new A(); | |
var list = new List<Call> { CreateCall(a, "Foo.Bar"), CreateCall(a, "Foo.Baz") }; | |
var result = Formatter.DoIt(list); | |
result.ShouldBe("Foo.Bar\r\nFoo.Baz"); | |
} | |
[Test] | |
public void MultipleCallsOfDifferentObjectsShouldDisplayMultipleCalls() | |
{ | |
var a = new A(); | |
var b = new B(); | |
var list = new List<Call> { CreateCall(a, "Foo.Bar"), CreateCall(b, "Guff.Wot") }; | |
var result = Formatter.DoIt(list); | |
result.ShouldBe("Foo.Bar\r\nGuff.Wot"); | |
} | |
[Test] | |
public void MultipleCallsOfDifferentInstancesOfSameTypeShouldDisplayMultipleCallsWithPrefix() | |
{ | |
var a1 = new A(); | |
var a2 = new A(); | |
var list = new List<Call> { CreateCall(a1, "Foo.Bar"), CreateCall(a2, "Foo.Bar") }; | |
var result = Formatter.DoIt(list); | |
result.ShouldBe("[email protected]\r\[email protected]"); | |
} | |
[Test] | |
public void TheTchepak() | |
{ | |
var a = new A(); | |
var b = new A(); | |
var c = new B(); | |
/* | |
Calls = [ (a, Foo.Bar), (b, Foo.Zap), (c, List.ToString), (a, Foo.Bongo) ] | |
Output: | |
[email protected] | |
[email protected] | |
[email protected] | |
[email protected] | |
*/ | |
var list = new List<Call> | |
{ | |
CreateCall(a, "Foo.Bar"), | |
CreateCall(b, "Foo.Zap"), | |
CreateCall(c, "List.ToString"), | |
CreateCall(a, "Foo.Bongo") | |
}; | |
var result = Formatter.DoIt(list); | |
result.ShouldBe(@"[email protected] | |
[email protected] | |
[email protected] | |
[email protected]"); | |
} | |
[Test] | |
public void MultipleCallsDisDifferentInstancesOfDifferentTypesShouldDisplayMultipleCallsWithPrefix() | |
{ | |
var a1 = new A(); | |
var a2 = new A(); | |
var b1 = new B(); | |
var b2 = new B(); | |
var list = new List<Call>() | |
{ | |
CreateCall(a1, "Foo.Bar"), | |
CreateCall(a2, "Foo.Bar"), | |
CreateCall(b1, "Baz.Wak"), | |
CreateCall(a1, "Foooey.Bor"), | |
CreateCall(b2, "Fup.Wuz"), | |
CreateCall(b1, "Baz.Wuz"), | |
CreateCall(a1, "Foooey.Baz") | |
}; | |
var result = Formatter.DoIt(list); | |
result.ShouldBe(@"[email protected] | |
[email protected] | |
[email protected] | |
[email protected] | |
[email protected] | |
[email protected] | |
[email protected]"); | |
} | |
private static Call CreateCall(object a, string methodInfo) | |
{ | |
return new Call(a, methodInfo); | |
} | |
} | |
public class Call | |
{ | |
protected bool Equals(Call other) | |
{ | |
return Equals(_target, other._target) && string.Equals(_memberCall, other._memberCall); | |
} | |
public override bool Equals(object obj) | |
{ | |
if (ReferenceEquals(null, obj)) return false; | |
if (ReferenceEquals(this, obj)) return true; | |
if (obj.GetType() != this.GetType()) return false; | |
return Equals((Call) obj); | |
} | |
public override int GetHashCode() | |
{ | |
unchecked | |
{ | |
return ((_target != null ? _target.GetHashCode() : 0)*397) ^ (_memberCall != null ? _memberCall.GetHashCode() : 0); | |
} | |
} | |
private readonly object _target; | |
private readonly string _memberCall; | |
public Call(object target, string memberCall) | |
{ | |
_target = target; | |
_memberCall = memberCall; | |
} | |
public object Target { get { return _target; } } | |
public string MemberCall { get { return _memberCall; } } | |
public int CallOrder { get; set; } | |
public int InstanceNumber { get; set; } | |
public override string ToString() | |
{ | |
return string.Format("MemberCall: {0}, Target: {1}, CallOrder: {2}, InstanceNumber: {3}", MemberCall, Target, CallOrder, InstanceNumber); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also need these IEnumerable extensions: