public void Must_ReturnWhateverMatchesTheMatcherReturns(
            IList <Tuple <StatementEntry, TransactionDetails> > expectedMatches)
        {
            Setup_PrimaryItemMatcher_ToReturn(expectedMatches);

            var statementEntries = new StatementEntry[] { new StatementEntry() };
            var transactions     = new TransactionDetails[] { new TransactionDetails() };

            var matchGroups = target.Compare(statementEntries, transactions).MatchGroups;

            Assert.AreSame(expectedMatches, matchGroups.First());
        }
        private void DoAccountOperation(Account account, StatementEntry statementEntry)
        {
            if (statementEntry.MovementType == MovementType.Credit)
            {
                account.Balance += statementEntry.Value;
            }
            else
            {
                account.Balance -= statementEntry.Value;
            }

            statementEntryRepository.CreateOrUpdate(statementEntry);
            accountRepository.CreateOrUpdate(account);
        }
        static IEnumerable <TestCaseData> GetNoUnmatchedTransactionEntries()
        {
            var statement1 = new StatementEntry {
                Amount = 1, Details = "Statement 1"
            };
            var statement2 = new StatementEntry {
                Amount = 2, Details = "Statement 2"
            };
            var statement3 = new StatementEntry {
                Amount = 3, Details = "Statement 3"
            };

            var trans1 = new TransactionDetails {
                Amount = 1, Details = "Transaction 1"
            };
            var trans2 = new TransactionDetails {
                Amount = 2, Details = "Transaction 2"
            };
            var trans3 = new TransactionDetails {
                Amount = 3, Details = "Transaction 3"
            };

            // simple case with one unmatched item
            yield return(new TestCaseData(
                             new StatementEntry[] { statement1 },
                             new TransactionDetails[] { trans1 },
                             new List <Tuple <StatementEntry, TransactionDetails> >
            {
                new Tuple <StatementEntry, TransactionDetails>(statement1, trans1)
            }));

            // multiple matches
            yield return(new TestCaseData(
                             new StatementEntry[] { statement1, statement2, statement3 },
                             new TransactionDetails[] { trans1, trans2, trans3 },
                             new List <Tuple <StatementEntry, TransactionDetails> >
            {
                new Tuple <StatementEntry, TransactionDetails>(statement1, trans1),
                new Tuple <StatementEntry, TransactionDetails>(statement2, trans2),
                new Tuple <StatementEntry, TransactionDetails>(statement3, trans3)
            }));
        }
        public void MoreThanOneMatcher__Must_ReturnWhateverMatchesTheMatcherReturns(
            IList <Tuple <StatementEntry, TransactionDetails> > expectedMatches)
        {
            Setup_PrimaryItemMatcher_ToReturn(new List <Tuple <StatementEntry, TransactionDetails> > {
            });

            var secondaryMatcher = new Mock <IMatchFinder <StatementEntry, TransactionDetails> >();

            Setup_ItemMatcher_ToReturn(secondaryMatcher, expectedMatches);

            matchers.Add(secondaryMatcher.Object);

            var statementEntries = new StatementEntry[] { new StatementEntry() };
            var transactions     = new TransactionDetails[] { new TransactionDetails() };

            var matchGroups = target.Compare(statementEntries, transactions).MatchGroups;

            Assert.AreEqual(2, matchGroups.Count, "The must be two match groups");
            Assert.AreSame(expectedMatches, matchGroups.Skip(1).First());
        }
        public void Transfer(Account fromAccount, Account toAccount, double value)
        {
            if (fromAccount.Balance < value)
            {
                throw new Exception("Saldo Insuficiente");
            }
            var outStatementEntry = new StatementEntry()
            {
                AccountId    = fromAccount.Id,
                Date         = DateTime.Now,
                MovementType = MovementType.Debit,
                Value        = value
            };
            var inStatementEntry = new StatementEntry()
            {
                AccountId    = toAccount.Id,
                Date         = DateTime.Now,
                MovementType = MovementType.Credit,
                Value        = value
            };

            DoAccountOperation(fromAccount, outStatementEntry);
            DoAccountOperation(toAccount, inStatementEntry);
        }
        static IEnumerable <TestCaseData> GetNonMatchingStatementEntries()
        {
            var statement1 = new StatementEntry {
                Amount = 1, Details = "Statement 1"
            };
            var statement2 = new StatementEntry {
                Amount = 2, Details = "Statement 2"
            };
            var statement3 = new StatementEntry {
                Amount = 3, Details = "Statement 3"
            };
            var statement4 = new StatementEntry {
                Amount = 4, Details = "Statement 4"
            };

            var trans1 = new TransactionDetails {
                Amount = 1, Details = "Transaction 1"
            };
            var trans2 = new TransactionDetails {
                Amount = 2, Details = "Transaction 2"
            };
            var trans3 = new TransactionDetails {
                Amount = 3, Details = "Transaction 3"
            };
            var trans4 = new TransactionDetails {
                Amount = 4, Details = "Transaction 4"
            };

            // simple case with one unmatched item
            yield return(new TestCaseData(
                             new StatementEntry[] { statement1, statement2 },
                             new TransactionDetails[] { trans1 },
                             new List <Tuple <StatementEntry, TransactionDetails> >
            {
                new Tuple <StatementEntry, TransactionDetails>(statement1, trans1)
            },
                             new StatementEntry[] { statement2 }));

            // two unmatched items
            yield return(new TestCaseData(
                             new StatementEntry[] { statement1, statement2, statement3, statement4 },
                             new TransactionDetails[] { trans2 },
                             new List <Tuple <StatementEntry, TransactionDetails> >
            {
                new Tuple <StatementEntry, TransactionDetails>(statement2, trans2)
            },
                             new StatementEntry[] { statement1, statement3, statement4 }));

            // three unmatched items, returned in a different order
            yield return(new TestCaseData(
                             new StatementEntry[] { statement1, statement2, statement3, statement4 },
                             new TransactionDetails[] { trans2 },
                             new List <Tuple <StatementEntry, TransactionDetails> >
            {
                new Tuple <StatementEntry, TransactionDetails>(statement2, trans2)
            },
                             new StatementEntry[] { statement3, statement1, statement4 }));

            // two matched items, two unmatched items
            yield return(new TestCaseData(
                             new StatementEntry[] { statement2, statement3, statement1, statement4 },
                             new TransactionDetails[] { trans1, trans3 },
                             new List <Tuple <StatementEntry, TransactionDetails> >
            {
                new Tuple <StatementEntry, TransactionDetails>(statement1, trans1),
                new Tuple <StatementEntry, TransactionDetails>(statement3, trans3)
            },
                             new StatementEntry[] { statement2, statement4 }));

            // two matched items, two unmatched items, returned in a different order
            yield return(new TestCaseData(
                             new StatementEntry[] { statement2, statement3, statement1, statement4 },
                             new TransactionDetails[] { trans1, trans3 },
                             new List <Tuple <StatementEntry, TransactionDetails> >
            {
                new Tuple <StatementEntry, TransactionDetails>(statement1, trans1),
                new Tuple <StatementEntry, TransactionDetails>(statement3, trans3)
            },
                             new StatementEntry[] { statement4, statement2 }));
        }