using System.Collections.Generic;
private Dictionary<int, int> _amounts;
public AtmMachine(Dictionary<int, int> amounts)
public List<Tuple<int, int>> Withdraw(int amount)
throw new NotImplementedException();
public class VersionComparer
public int Compare(string versionOne, string versionTwo)
throw new NotImplementedException();
public static void Main()
private static void Run()
new AtmMachineTests().Start();
new VersionComparerTests().Start();
public class AtmMachineTests
Tests.Run($"{nameof(AtmMachine)} should", (it) =>
it.Should(() => NotProcessNegativeValues(), "Not process negative values");
it.Should(() => ReturnMultipleDenominationAmounts(), "Return multiple denomination amounts");
it.Should(() => NotProcessWithdrawalsWhenInventoryIsSmallerThanRequestedAmount(), "Not process witdrawals greater than inventory");
it.Should(() => ReturnAllAvailableMoney(), "Return all available money");
it.Should(() => KeepStateBetweenWithdrawals(), "Keep state between withdrawals");
it.Should(() => NotChangeStateIfWithdrawalIsntSuccessful(), "Not change state if withdrawal isn't successful");
private int CountMoney(List<Tuple<int, int>> amounts) => amounts.Aggregate(0, (a, i) => a + i.Item1 * i.Item2);
public void NotChangeStateIfWithdrawalIsntSuccessful()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 5 }, { 5, 5 }, { 10, 5 } });
var r1 = atm.Withdraw(50);
CountMoney(r1).ShouldBe(50);
var r2 = atm.Withdraw(50);
CountMoney(r2).ShouldBe(0);
var r3 = atm.Withdraw(20);
CountMoney(r3).ShouldBe(20);
public void NotProcessNegativeValues()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 5 } });
var result = atm.Withdraw(-5);
CountMoney(result).ShouldBe(0);
public void KeepStateBetweenWithdrawals()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 5 }, { 5, 5 } });
var r1 = atm.Withdraw(5);
CountMoney(r1).ShouldBe(5);
var r2 = atm.Withdraw(26);
CountMoney(r2).ShouldBe(0);
public void ReturnAllAvailableMoney()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 10 }, { 5, 10 }, { 10, 10 }, { 50, 10 }, { 100, 10 }, { 200, 10 }, { 500, 10 } });
var result = atm.Withdraw(8660);
var sum = CountMoney(result);
public void ReturnMultipleDenominationAmounts()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 10 }, { 5, 10 }, { 10, 10 } });
var result = atm.Withdraw(87);
CountMoney(result).ShouldBe(87);
public void NotProcessWithdrawalsWhenInventoryIsSmallerThanRequestedAmount()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 10 }, { 5, 10 }, { 10, 10 }, { 50, 10 }, { 100, 10 }, { 200, 10 }, { 500, 10 } });
var result = atm.Withdraw(8661);
CountMoney(result).ShouldBe(0);
public class VersionComparerTests
Tests.Run("VersionComparer should", (it) =>
it.Should(() => CompareEqualVersions(), "Compare equal versions");
it.Should(() => CompareDifferentVersions(), "Compare different versions");
public void CompareEqualVersions()
var comparer = new VersionComparer();
comparer.Compare("0", "0.0.0").ShouldBe(0);
comparer.Compare("0.01", "0.1").ShouldBe(0);
comparer.Compare("1.001", "1.1").ShouldBe(0);
comparer.Compare("7.015.84", "7.15.84").ShouldBe(0);
comparer.Compare("7.1", "7.1.0.0").ShouldBe(0);
public void CompareDifferentVersions()
var comparer = new VersionComparer();
comparer.Compare("01.0.1", "1.1.0").ShouldBe(-1);
comparer.Compare("33.1", "33.0.5").ShouldBe(1);
comparer.Compare("7.0105.84", "7.15.84").ShouldBe(-1);
public static void Run(string testGroup, Action<Tests> tests)
public static void StartTests(string testGroup)
Console.WriteLine("====================================================");
Console.WriteLine(testGroup);
Console.WriteLine("====================================================");
public void Should(Action test, string testName)
Console.WriteLine(testName);
Console.WriteLine(" Passed");
Console.WriteLine(" Failed");
Console.WriteLine(" " + e.Message);
public static void EndTests()