예제 #1
0
class TestLedger(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()

    def testFilename(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        self.assertEqual(fixture_path("test.dat"), ledger.absolute_filename("test.dat"))
예제 #2
0
class RegisterReportTest(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()
        self.report_factory = reports.get("register")

    def testSimpleReport(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        sorting = MapSorting(lambda x: x.date)
        report = self.report_factory(ledger, RuleCollection(), Filter.null, sorting)
        records = list(report.generate())

        self.assertEqual(4, len(records))
        self.assertEqual(
            [(u'Assets:Bank', Value.parse('1500 EUR'), Value.parse('1500 EUR')),
             (u'Equity:Capital', Value.parse('-1500 EUR'), ZERO),
             (u'Expenses:Books', Value.parse('35 EUR'), Value.parse('35 EUR')),
             (u'Assets:Bank', Value.parse('-35 EUR'), ZERO)],
            [(record.entry.account.name, record.entry.amount, record.total) for record in records])


    def testReportOrdering(self):
        ledger = self.parser.parse_ledger(fixture_path("sorting.dat"))
        sorting = MapSorting(lambda x: x.date)
        report = self.report_factory(ledger, RuleCollection(), Filter.null, sorting)

        self.assertEqual(
            [unicode(chr(i)) for i in xrange(ord('A'), ord('N') + 1) for _ in xrange(2)],
            [record.transaction.label for record in report.generate()])

    def testEmptyRegister(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        sorting = MapSorting(lambda x: x.date)
        filter = self.parser.accounts["Expenses"]["Clothing"].filter()
        report = self.report_factory(ledger, RuleCollection(), filter, sorting)
        records = list(report.generate())

        self.assertEqual(0, len(records))
예제 #3
0
class ParserTest(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()

    def testSimpleLedger(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        self.assertEqual(2, len(ledger.transactions))

    def testLedgerWithTags(self):
        ledger = self.parser.parse_ledger(fixture_path("tags.dat"))
        self.assertEqual(2, len(ledger.transactions))
        tr1 = ledger.transactions[0]
        self.assertIsNotNone(tr1.tags["balance"])
        self.assertEqual(date(2011, 1, 1), tr1.entries[1].date(tr1))
        tr2 = ledger.transactions[1]
        self.assertEqual("Dracula", tr2.entries[0].tags["title"])

    def testTags(self):
        self.assertEqual({ "foo":"bar" }, self.parser.parse_tags("; foo:bar \t "))
        self.assertEqual({ "foo":"1", "bar":"2", "baz":"" },
                self.parser.parse_tags("; :baz: foo:1 \tbar:2"))

    def testTagsWithSpaces(self):
        self.assertEqual({ "foo":"hello world" },
                self.parser.parse_tags('; foo:"hello world"'))
        self.assertEqual({ "foo":'hello "world"' },
                self.parser.parse_tags('; foo:\'hello "world"\''))
        self.assertEqual({ "foo":"hello world", "bar":"0", "baz":"5" },
                self.parser.parse_tags(';bar:0 foo:"hello world" baz:5'))

    def testParseError(self):
        with self.assertRaises(PledgerException) as cm:
            self.parser.parse_ledger(fixture_path("errors.dat"))

        self.assertEqual(3, cm.exception.line_number)
        self.assertEqual(fixture_path("errors.dat"), cm.exception.filename)
예제 #4
0
class BalanceReportTest(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()
        self.report_factory = reports.get("balance")

    def testSimpleReport(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        sorting = Sorting(lambda x: x)
        report = self.report_factory(ledger, RuleCollection(), Filter.null, sorting)

        self.assertEqual(
            [(u'Assets:Bank', Value.parse("1465 EUR")),
             (u'Equity:Capital', Value.parse("-1500 EUR")),
             (u'Expenses:Books', Value.parse("35 EUR"))],
            [(record.account, record.amount) for record in report.generate() if record.account])

    def testEmptyBalance(self):
        ledger = self.parser.parse_ledger("<test>", "")
        sorting = Sorting(lambda x: x)
        report = self.report_factory(ledger, RuleCollection(), Filter.null, sorting)
        records = list(report.generate())

        self.assertEqual(1, len(records))
        self.assertIsNone(records[0].level)
예제 #5
0
class TestLedgerProcessor(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()
        self.rules = RuleCollection()

    def testAccountPrefix(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        processor = LedgerProcessor(ledger, self.rules)
        collector = TransactionCollector()
        processor.add_listener(collector)

        processor.add_account_prefix("Business")
        processor.run()

        for transaction, entries in collector.transactions:
            for entry in entries:
                self.assertEqual("Business", entry.account.root().name)

    def testRemoveAccountPrefix(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        processor = LedgerProcessor(ledger, self.rules)
        collector = TransactionCollector()
        processor.add_listener(collector)

        self.assertEqual(2, len(ledger.transactions))

        processor.add_account_prefix("Business")
        ledger.transactions[0].execute(processor)

        for transaction, entries in collector.transactions:
            for entry in entries:
                self.assertEqual("Business", entry.account.root().name)

        collector.transactions = []
        processor.remove_account_prefix()

        ledger.transactions[0].execute(processor)

        for transaction, entries in collector.transactions:
            for entry in entries:
                self.assertNotEqual("Business", entry.account.root().name)

    def testInclude(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        processor = LedgerProcessor(ledger, self.rules)
        collector = TransactionCollector()
        processor.add_listener(collector)

        processor.run()
        processor.include("extra.dat")

        self.assertEqual(3, len(collector.transactions))

    def testCompact(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        processor = LedgerProcessor(ledger, self.rules)
        entry = ledger.transactions[1].entries[0]
        self.assertEqual(Value.parse("35 EUR"), entry.amount)
        # add entry
        entry2 = Entry(entry.account, Value.parse("-5 EUR"))
        ledger.transactions[1].entries.append(entry2)
        # rebalance transaction
        ledger.transactions[1].entries[1].amount += Value.parse("5 EUR")

        collector = TransactionCollector()
        processor.add_listener(collector)
        processor.run()

        self.assertEqual(2, len(collector.transactions))
        _, entries = collector.transactions[1]
        self.assertEqual(2, len(entries))

        self.assertEqual(Value.parse("30 EUR"), entries[0].amount)
예제 #6
0
class TemplateTest(unittest.TestCase):
    def setUp(self):
        self.template = FakeTemplate()
        self.parser = Parser()

    def testCall(self):
        lines = []
        report = FakeReport([1, 2, 3])
        self.template(report, lambda x: lines.append(x))
        self.assertEqual(["1", "2", "3"], lines)

    def testPad(self):
        text = self.template.pad("hello", 10)
        self.assertEqual("     hello", text)

    def testColoredPad(self):
        text = self.template.pad("hello", 10, 'red')
        self.assertRegexpMatches(text, "     .*hello.*")

    def testLPad(self):
        text = self.template.lpad("hello", 10)
        self.assertEqual("hello     ", text)

    def testColoredLPad(self):
        text = self.template.lpad("hello", 10, 'red')
        self.assertRegexpMatches(text, ".*hello.*     ")

    def testPrintValue(self):
        value = Value.parse("44 EUR")
        self.assertRegexpMatches(self.template.print_value(value), r'^ *44.00 EUR$')

    def testPrintNegativeValue(self):
        value = Value.parse("-44 EUR")
        self.assertRegexpMatches(self.template.print_value(value), r'^ *\S+-44.00 EUR\S+$')

    def testPrintNullValue(self):
        self.assertEqual("", self.template.print_value(None))

    def testPrintAccount(self):
        account = self.parser.accounts["Assets:Bank:Checking:Joint"]
        text = self.template.print_account(account, None)
        self.assertRegexpMatches(text, "Assets:Bank:Checking:Joint")

    def testPrintAccountShortened(self):
        account = self.parser.accounts["Assets:Bank:Checking:Joint"]
        text = self.template.print_account(account, 20)
        self.assertRegexpMatches(text, ".*:.*:.*:Joint")
        self.assertLessEqual(len(filter(unicode.isalpha, text)), 20)

    def testPrintLabel(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        transaction = ledger.transactions[1]
        self.assertEqual("Bookshop", transaction.label)
        text = self.template.print_label(transaction, 30)
        self.assertRegexpMatches(text, r' *\S+Bookshop')

    def testPrintClearedLabel(self):
        ledger = self.parser.parse_ledger(fixture_path("simple.dat"))
        transaction = ledger.transactions[1]
        transaction.tags["cleared"] = True
        self.assertEqual("Bookshop", transaction.label)
        text = self.template.print_label(transaction, 30)
        self.assertRegexpMatches(text, r' *Bookshop')