class TestTagFilters(unittest.TestCase): def setUp(self): self.parser = Parser() bank_account = self.parser.parse_account("Assets:Bank") books_account = self.parser.parse_account("Expenses:Books") bank_account.tags["foo"] = "bar" self.bank = bank_account - self.parser.parse_value("33 $") self.books = books_account + self.parser.parse_value("33 $") self.tr = Transaction([self.bank, self.books]) self.tr.tags["baz"] = "hello world" self.books.tags["title"] = "Necronomicon" def testAccountTagFilter(self): filter = Account.tag_filter("foo", "bar") self.assertTrue(filter(self.tr, self.bank)) self.assertFalse(filter(self.tr, self.books)) def testAccountTagFilterEmpty(self): filter = Account.tag_filter("foo") self.assertTrue(filter(self.tr, self.bank)) self.assertFalse(filter(self.tr, self.books)) def testAccountTagFilterWrong(self): filter = Account.tag_filter("baz") self.assertFalse(filter(self.tr, self.bank)) self.assertFalse(filter(self.tr, self.books)) def testTransactionTagFilter(self): filter = Transaction.tag_filter("baz", "hello world") self.assertTrue(filter(self.tr, self.bank)) self.assertTrue(filter(self.tr, self.books)) self.assertTrue(filter(self.tr, None)) def testTransactionTagFilterEmpty(self): filter = Transaction.tag_filter("baz", None) self.assertTrue(filter(self.tr, self.bank)) self.assertTrue(filter(self.tr, self.books)) self.assertTrue(filter(self.tr, None)) def testTransactionTagFilterWrong(self): filter = Transaction.tag_filter("foo", None) self.assertFalse(filter(self.tr, self.bank)) self.assertFalse(filter(self.tr, self.books)) self.assertFalse(filter(self.tr, None)) def testTransactionAccountFilter(self): filter = Transaction.account_tag_filter("foo", "bar") self.assertTrue(filter(self.tr, None)) def testEntryTagFilter(self): filter = Entry.tag_filter("title", "Necronomicon") self.assertTrue(filter(self.tr, self.books)) self.assertFalse(filter(self.tr, self.bank)) self.assertFalse(filter(self.tr, None))
class TestFilter(unittest.TestCase): def setUp(self): self.three_entries = Filter(lambda tr, entry: len(tr.entries) == 3) self.in_euro = Filter(lambda tr, entry: list(entry.amount.currencies()) == ["EUR"]) self.parser = Parser() bank_account = self.parser.parse_account("Assets:Bank") books_account = self.parser.parse_account("Expenses:Books") cash_account = self.parser.parse_account("Assets:Cash") bank = bank_account - self.parser.parse_value("33 EUR") books = books_account + self.parser.parse_value("33 EUR") self.tr1 = Transaction([bank, books]) bank = bank_account - self.parser.parse_value("91 $") books = books_account + self.parser.parse_value("40 $") cash = cash_account + self.parser.parse_value("51 $") self.tr2 = Transaction([bank, books, cash]) def testFilter(self): self.assertFalse(self.three_entries(self.tr1, self.tr1.entries[0])) self.assertTrue(self.three_entries(self.tr2, self.tr2.entries[0])) self.assertTrue(self.in_euro(self.tr1, self.tr1.entries[0])) self.assertFalse(self.in_euro(self.tr2, self.tr2.entries[0])) def testFilterParse(self): filter = Filter.parse(self.parser, lambda tr, entry: entry.account.name.startswith("Assets")) self.assertTrue(filter(self.tr1, self.tr1.entries[0])) self.assertFalse(filter(self.tr1, self.tr1.entries[1])) def testFilterInvert(self): self.assertTrue((~self.three_entries)(self.tr1, self.tr1.entries[0])) self.assertFalse((~self.three_entries)(self.tr2, self.tr2.entries[0])) self.assertFalse((~self.in_euro)(self.tr1, self.tr1.entries[0])) self.assertTrue((~self.in_euro)(self.tr2, self.tr2.entries[0])) def testFilterAnd(self): filter = self.three_entries & self.in_euro self.assertFalse(filter(self.tr1, self.tr1.entries[0])) self.assertFalse(filter(self.tr2, self.tr2.entries[0])) def testFilterOr(self): filter = self.three_entries | self.in_euro self.assertTrue(filter(self.tr1, self.tr1.entries[0])) self.assertTrue(filter(self.tr2, self.tr2.entries[0])) def testHasAccountFilter(self): filter = Filter.has_account(self.parser.parse_account("Assets:Bank")) self.assertTrue(filter(self.tr1, self.tr1.entries[0])) self.assertFalse(filter(self.tr1, self.tr1.entries[1])) def testMatchesFilter(self): filter = Filter.matches(re.compile(r"ank")) self.assertTrue(filter(self.tr1, self.tr1.entries[0])) self.assertFalse(filter(self.tr1, self.tr1.entries[1]))
class TestCLIFilters(unittest.TestCase): def setUp(self): self.parser = Parser() bank_account = self.parser.parse_account("Assets:Bank") books_account = self.parser.parse_account("Expenses:Books") cash_account = self.parser.parse_account("Assets:Cash") bank = bank_account - self.parser.parse_value("33 EUR") books = books_account + self.parser.parse_value("33 EUR") books.tags["foo"] = "bar" self.tr1 = Transaction([bank, books], date=date(2009, 12, 31)) bank = bank_account - self.parser.parse_value("91 $") books = books_account + self.parser.parse_value("40 $") books.tags["date"] = date(2009, 3, 1) cash = cash_account + self.parser.parse_value("51 $") self.tr2 = Transaction([bank, books, cash], date=date(2010, 1, 1)) def testDateFilter(self): filter = DateFilter.parse(self.parser, "2010/10/01") self.assertEqual(date(2010, 10, 1), filter.date) self.assertRaises(ValueError, DateFilter.parse, self.parser, "foo") self.assertRaises(ValueError, DateFilter.parse, self.parser, "2011/15/12") def testBeginFilter(self): filter = BeginFilter.parse(self.parser, "2010") self.assertFalse(filter(self.tr1, self.tr1.entries[0])) self.assertTrue(filter(self.tr2, self.tr2.entries[0])) self.assertFalse(filter(self.tr2, self.tr2.entries[1])) def testEndFilter(self): filter = EndFilter.parse(self.parser, "2010") self.assertTrue(filter(self.tr1, self.tr1.entries[0])) self.assertFalse(filter(self.tr2, self.tr2.entries[0])) self.assertTrue(filter(self.tr2, self.tr2.entries[1])) def testExpressionFilter(self): filter = ExpressionFilter.parse(self.parser, "entry.account.name.startswith('Assets')") self.assertTrue(filter(self.tr1, self.tr1.entries[0])) self.assertFalse(filter(self.tr1, self.tr1.entries[1])) def testExpressionFilterDate(self): filter = ExpressionFilter.parse(self.parser, "entry.date < date('2010')") self.assertTrue(filter(self.tr1, self.tr1.entries[0])) self.assertFalse(filter(self.tr2, self.tr2.entries[0])) self.assertTrue(filter(self.tr2, self.tr2.entries[1])) def testExpressionFilterTag(self): filter = ExpressionFilter.parse(self.parser, "entry.foo") self.assertFalse(filter(self.tr1, self.tr1.entries[0])) self.assertTrue(filter(self.tr1, self.tr1.entries[1]))
class RuleTest(unittest.TestCase): def setUp(self): self.parser = Parser() self.bank_account = self.parser.parse_account("Assets:Bank") self.books_account = self.parser.parse_account("Expenses:Books") self.cash_account = self.parser.parse_account("Assets:Cash") bank = self.bank_account - self.parser.parse_value("33 EUR") books = self.books_account + self.parser.parse_value("33 EUR") self.tr = Transaction([bank, books]) self.rules = RuleCollection() @Generator def discount(entry): amount = entry.amount * Decimal("0.1") yield entry.account - amount yield self.cash_account + amount self.discount = discount def testRuleOnLedger(self): rule = Rule(Filter.has_account(self.books_account), self.discount) self.rules.add_rule(rule) result = [] result += self.rules.apply(self.tr, self.tr.entries[0]) result += self.rules.apply(self.tr, self.tr.entries[1]) expected = [self.bank_account - self.parser.parse_value("33.00 EUR"), self.books_account + self.parser.parse_value("33.00 EUR"), self.cash_account + self.parser.parse_value("3.30 EUR"), self.books_account - self.parser.parse_value("3.30 EUR")] self.assertItemsEqual(expected, result) def testAccountTagRule(self): self.books_account.tags["discount"] = self.discount self.rules.add_rule(Account.tag_rule("discount")) result = [] result += self.rules.apply(self.tr, self.tr.entries[0]) result += self.rules.apply(self.tr, self.tr.entries[1]) expected = [self.bank_account - self.parser.parse_value("33.00 EUR"), self.books_account + self.parser.parse_value("33.00 EUR"), self.cash_account + self.parser.parse_value("3.30 EUR"), self.books_account - self.parser.parse_value("3.30 EUR")] self.assertItemsEqual(expected, result)
class AccountTest(unittest.TestCase): def setUp(self): self.parser = Parser() self.account = self.parser.parse_account("Assets:Bank") def testAccountAdd(self): amount = self.parser.parse_value("150 EUR") entry = self.account + amount self.assertEqual(self.account, entry.account) self.assertEqual(amount, entry.amount) def testAccountSub(self): amount = self.parser.parse_value("150 EUR") entry = self.account - amount self.assertEqual(self.account, entry.account) self.assertEqual(-amount, entry.amount) def testRoot(self): self.assertEqual(self.parser.accounts["Assets"], self.account.root()) def testShortenedName(self): account = self.account["Joint:Savings:Yearly:Interest:Compound:Open"] size = 30 name = account.shortened_name(size) self.assertLessEqual(len(name), size) self.assertEqual(7, len(filter(lambda x: x == ':', name))) def testSubName(self): account = self.account["Checking"] self.assertEqual(u'Bank:Checking', self.account.parent.sub_name(account)) self.assertIsNone(self.account.sub_name(self.parser.accounts["Test"]))
class EntryTest(unittest.TestCase): def setUp(self): self.parser = Parser() def testParsing(self): value = self.parser.parse_value("34 EUR") account = self.parser.parse_account("Test Account") entry = Entry(account, value) self.assertEqual(entry, self.parser.parse_entry(" Test Account 34 EUR")) def testEquality(self): value1 = self.parser.parse_value("34 EUR") value2 = self.parser.parse_value("12 $") account1 = self.parser.parse_account("Test") account2 = self.parser.parse_account("Bank") self.assertEqual(Entry(account1, value1), Entry(account1, value1)) self.assertNotEqual(Entry(account1, value1), Entry(account2, value1)) self.assertNotEqual(Entry(account1, value1), Entry(account1, value2)) def testEntryParser(self): entry = self.parser.parse_entry(" Expenses:Books 61 EUR ; :gift:") self.assertEqual("Expenses:Books", entry.account.name) self.assertEqual(Value.parse("61 EUR"), entry.amount) self.assertItemsEqual(["gift"], entry.tags.keys()) def testEntryDict(self): entry = self.parser.parse_entry(" Expenses:Books 61 EUR ; :gift:") entry2 = self.parser.parse_entry(" Expenses:Books 61 EUR") entry3 = self.parser.parse_entry(" Expenses:Books 51 EUR") entry4 = self.parser.parse_entry(" Expenses:Books 51 EUR") d = {} d[entry] = True d[entry2] = True d[entry3] = True d[entry4] = True self.assertItemsEqual([entry, entry2, entry3], d.keys()) def testRepr(self): entry = self.parser.parse_entry(" Expenses:Books 55 EUR") s = str(entry) self.assertRegexpMatches(s, "Expenses:Books") self.assertRegexpMatches(s, "55.00 EUR") def testEntryDate(self): entry = self.parser.parse_entry(" Expenses:Books 61 EUR ; [2011/03/03]") entry2 = self.parser.parse_entry(" Expenses:Books 61 EUR") transaction = FakeTransaction(date=date(2011, 03, 01)) self.assertEqual(date(2011, 03, 03), entry.date(transaction)) self.assertEqual(date(2011, 03, 01), entry2.date(transaction)) def testEntryOfTransaction(self): transaction = FakeTransaction(date=date(2011, 03, 01)) entry = self.parser.parse_entry(" Expenses:Books 61 EUR ; [2011/03/03]").of(transaction) entry2 = self.parser.parse_entry(" Expenses:Books 61 EUR").of(transaction) self.assertEqual(date(2011, 03, 03), entry.date) self.assertEqual(date(2011, 03, 01), entry2.date)