def testRunEnterDaysLessThanOne(self): schedulefiledata = FileTester.read_file( FileTester.test_enter_lessthan1 ) tempschedulefile = FileTester.write_to_temp_file( FileTester.test_enter_lessthan1, schedulefiledata ) schedulefile = ScheduleFile(tempschedulefile) templedgerfile = FileTester.create_temp_file('') ledgerfile = LedgerFile(templedgerfile) scheduler = Scheduler(ledgerfile, schedulefile) scheduler.run() ledgerfile.write_file() schedulefile.write_file() schedulefile_actual = FileTester.read_file(tempschedulefile) schedulefile_expected = FileTester.read_file( FileTester.test_enter_lessthan1 ) os.remove(templedgerfile) os.remove(tempschedulefile) self.assertEqual( schedulefile_expected, schedulefile_actual )
def setUp(self): super(MockRawInput, self).setUp() self.save_raw_input = raw_input reconciler.raw_input = self.mock_raw_input Reconciler.CACHE_FILE = FileTester.CACHE_FILE_TEST FileTester.delete_test_cache_file()
def cache_test(self, do_quit=True): self.init_test('test_reconciler_caching') with FileTester.temp_input(self.teststmt) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.responses = ['2030/03/30', '-30'] recon.do_statement('') if do_quit: recon.do_quit('') print('<<< test: restart >>>') with FileTester.temp_input(self.teststmt) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) recon.do_mark('1 2') recon.do_finish('') if do_quit: recon.do_quit('') print('<<< test: restart >>>') with FileTester.temp_input(self.testfinish) as tempfilename: Reconciler(LedgerFile(tempfilename, 'cash')) self.conclude_test(strip_ansi_color=True)
def test_parsed_file_unchanged_via_write(self): """file output after parsing should be identical to input""" expected = FileTester.read_file(FileTester.testfile) tempfile = FileTester.copy_to_temp_file(FileTester.testfile) ledgerfile = LedgerFile(tempfile) ledgerfile.write_file() actual = FileTester.read_file(tempfile) remove(tempfile) self.assertEqual(expected, actual)
def test_already_sorted_file_unchanged(self): """file output after sorting is identical to sorted input""" expected = FileTester.read_file(FileTester.sortedfile) tempfile = FileTester.copy_to_temp_file(FileTester.sortedfile) ledgerfile = LedgerFile(tempfile) ledgerfile.sort() ledgerfile.write_file() actual = FileTester.read_file(tempfile) remove(tempfile) self.assertEqual(expected, actual)
def test_sorting(self): """test sorting""" expected = FileTester.read_file(FileTester.alpha_sortedfile) tempfile = FileTester.copy_to_temp_file( FileTester.alpha_unsortedfile ) ledgerfile = LedgerFile(tempfile) ledgerfile.sort() ledgerfile.write_file() actual = FileTester.read_file(tempfile) remove(tempfile) self.assertEqual(expected, actual)
def test_next_scheduled_transaction_no_next(self): no_next = ''';; scheduler ; enter 45 days''' with FileTester.temp_input(no_next) as tempfilename: schedulefile = ScheduleFile(tempfilename) self.assertEqual('', schedulefile.next_scheduled_date())
def test_init_things(self): with FileTester.temp_input(testdata) as tempfilename: ledgerfile = LedgerFile(tempfilename, 'cash') recon = Reconciler(ledgerfile) self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-32.12, recon.total_pending) payees = { thing.payee for thing in recon.open_transactions } # all open transactions, including the future: self.assertEqual( ({'two', 'two pt five', 'three', 'four'}), payees ) payees = { thing.payee for k, thing in recon.current_listing.iteritems() } # future items included only if pending ('three') self.assertEqual( ({'two', 'two pt five', 'three'}), payees ) self.assertEqual(date.today(), recon.ending_date) self.assertIsNone(recon.ending_balance) self.assertEqual(3, len(recon.current_listing)) self.assertEqual( 'a: cash', ledgerfile.get_reconciliation_account() )
def test_parsed_file_unchanged_via_print(self): """file output after parsing should be identical to input""" expected = FileTester.read_file(FileTester.testfile) ledgerfile = LedgerFile(FileTester.testfile) ledgerfile.print_file() self.redirect.seek(0) self.assertEqual(expected, self.redirect.read()) self.assertIsNone(ledgerfile.get_reconciliation_account())
def test_next_scheduled_transaction(self): with FileTester.temp_input(self.scheduledata) as tempfilename: schedulefile = ScheduleFile(tempfilename) self.assertEqual( '2007/07/07', schedulefile.next_scheduled_date() )
def test_mark_and_unmark(self): with FileTester.temp_input(testdata) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-32.12, recon.total_pending) recon.do_mark('1') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-52.12, recon.total_pending) recon.do_unmark('1 2') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-30, recon.total_pending) recon.do_mark('1 2') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-52.12, recon.total_pending) recon.do_unmark('2') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-50, recon.total_pending) recon.do_mark('1 2 blurg') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-52.12, recon.total_pending) recon.do_unmark('blarg 2') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-50, recon.total_pending) recon.do_unmark('1 sdjfkljsdfkljsdl 2') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-30, recon.total_pending) recon.default('1') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-50, recon.total_pending) # entry with account on multiple lines with FileTester.temp_input(testdata) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'credit')) self.verify_equal_floats(0, recon.total_cleared) self.verify_equal_floats(0, recon.total_pending) recon.do_mark('1') self.verify_equal_floats(0, recon.total_cleared) self.verify_equal_floats(-33, recon.total_pending) recon.do_unmark('1') self.verify_equal_floats(0, recon.total_cleared) self.verify_equal_floats(0, recon.total_pending)
def test_syntax_error(self): with FileTester.temp_input(testdata) as tempfilename: interpreter = Reconciler(LedgerFile(tempfilename, 'cash')) self.reset_redirect() bad_command = 'cthulu' interpreter.onecmd(bad_command) self.assertEqual( Reconciler.UNKNOWN_SYNTAX + bad_command, self.redirect.getvalue().rstrip() )
def test_initial_non_transaction_date(self): """1st thing in file is a non-transaction, has default date""" tempfile = FileTester.create_temp_file('blah\nblah blah blah') ledgerfile = LedgerFile(tempfile) # non-transaction dates are only populated with sort ledgerfile.sort() remove(tempfile) self.assertEqual( LedgerFile.STARTING_DATE, ledgerfile.get_things()[0].thing_date )
def test_finish(self): self.init_test('test_reconcile_finish') with FileTester.temp_input(self.teststmt) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.responses = ['2016/10/30', '-30'] recon.do_statement('') recon.do_mark('1 2') recon.do_finish('') self.conclude_test(strip_ansi_color=True)
def test_get_key_and_cache_no_cache(self): assert not os.path.exists(FileTester.CACHE_FILE_TEST) with FileTester.temp_input(self.testcache) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) assert not os.path.exists(FileTester.CACHE_FILE_TEST) key, cache = recon.get_key_and_cache() self.assertEqual('a: cash', key) self.assertEqual({}, cache)
def test_count_initial_non_transaction(self): """counts initial non-transaction (probably a comment)""" testdata = '''; blah ; blah blah blah 2013/05/06 payee name expenses: misc liabilities: credit card $-50 ''' tempfile = FileTester.create_temp_file(testdata) ledgerfile = LedgerFile(tempfile) remove(tempfile) self.assertEquals(2, ledgerfile.thing_counter)
def test_mark_and_unmark_all(self): with FileTester.temp_input(testdata) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-32.12, recon.total_pending) recon.do_unmark('all') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(0, recon.total_pending) recon.do_mark('all') self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-22.12, recon.total_pending)
def test_save_cache_error(self): with FileTester.temp_input(self.testcache) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.reset_redirect() Reconciler.CACHE_FILE = '/not/a/real/path/dDFgMAEVRPcjMZ' recon.save_statement_info_to_cache() self.assertEqual( "Error writing reconciler cache: [Errno 2] No such file " "or directory: '/not/a/real/path/dDFgMAEVRPcjMZ'", self.redirect.getvalue().rstrip() )
def test_cancel_statement(self): self.init_test('test_cancel_statement_stuff') with FileTester.temp_input(self.teststmt) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.responses = ['2016/10/27', '50'] recon.do_statement('') self.responses = ['cAnCeL'] recon.do_statement('') self.assertIsNone(recon.ending_balance) print('<<< test: restart >>>') with FileTester.temp_input(self.teststmt) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.assertIsNone(recon.ending_balance) self.responses = ['2016/10/28', '40'] recon.do_statement('') self.responses = ['2016/10/28', 'cancel'] recon.do_statement('') self.assertIsNone(recon.ending_balance)
def run_it(self, before_date, after_date, schedule, enter_days=7): schedulefiledata = self.get_schedule_file( util.get_date_string(before_date), schedule, enter_days ) tempschedulefile = FileTester.write_to_temp_file( FileTester.testdir + 'run_it_schedule_file', schedulefiledata ) schedulefile = ScheduleFile(tempschedulefile) templedgerfile = FileTester.write_to_temp_file( FileTester.testdir + 'run_it_ledger_file', '' ) ledgerfile = LedgerFile(templedgerfile) scheduler = Scheduler(ledgerfile, schedulefile) scheduler.run() ledgerfile.write_file() schedulefile.write_file() schedulefile_actual = FileTester.read_file(tempschedulefile) schedulefile_expected = self.get_schedule_file( util.get_date_string(after_date), schedule, enter_days ) os.remove(templedgerfile) os.remove(tempschedulefile) self.assertEqual(schedulefile_expected, schedulefile_actual)
def test_count_initial_transaction(self): """counts initial transaction""" testdata = '''2013/05/06 payee name expenses: misc liabilities: credit card $-50 ; blah blah blah 2013/05/06 payee name expenses: misc liabilities: credit card $-50 2013/02/30 invalid date (bonus test for thing date checking coverage) (will be lumped with previous; note is invalid ledger file...) ''' tempfile = FileTester.create_temp_file(testdata) ledgerfile = LedgerFile(tempfile) remove(tempfile) self.assertEquals(2, ledgerfile.thing_counter)
def test_list(self): with FileTester.temp_input(testdata) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) recon.do_list('') payees = { thing.payee for k, thing in recon.current_listing.iteritems() } # future items included only if pending ('three') self.assertEqual( ({'two', 'two pt five', 'three'}), payees ) self.verify_equal_floats(-15, recon.total_cleared) self.verify_equal_floats(-32.12, recon.total_pending)
def test_get_key_and_cache_error(self): with FileTester.temp_input(self.testcache) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.reset_redirect() with open(Reconciler.CACHE_FILE, 'w') as cache_file: cache_file.write('bad json data') key, cache = recon.get_key_and_cache() self.assertEqual('a: cash', key) self.assertEqual({}, cache) self.assertEqual( 'Error getting reconciler cache: ' 'No JSON object could be decoded.', self.redirect.getvalue().rstrip() )
def test_setting_statement_date_and_balance(self): self.init_test('test_statement_stuff') with FileTester.temp_input(self.teststmt) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) # errors and no change self.responses = ['blurg', '', 'abc', ''] recon.do_statement('') # new settings self.responses = ['2016/10/30', '40'] recon.do_statement('') # use $ symbol, no change self.responses = ['2016/10/30', '$40'] recon.do_statement('') self.conclude_test(strip_ansi_color=True)
def test_finish_balancing_with_errors(self): """Verify things don't change when there are errors""" with FileTester.temp_input(testdata) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) recon.finish_balancing() payees = { thing.payee for thing in recon.open_transactions } self.assertEqual( ({'two', 'two pt five', 'three', 'four'}), payees ) payees = { thing.payee for k, thing in recon.current_listing.iteritems() } # future items included only if pending ('three') self.assertEqual( ({'two', 'two pt five', 'three'}), payees ) recon.ending_balance = -1234.56 recon.finish_balancing() self.assertEqual(-1234.56, recon.ending_balance) payees = { thing.payee for thing in recon.open_transactions } self.assertEqual( ({'two', 'two pt five', 'three', 'four'}), payees ) payees = { thing.payee for k, thing in recon.current_listing.iteritems() } # future items included only if pending ('three') self.assertEqual( ({'two', 'two pt five', 'three'}), payees )
def test_simple_help_check(self): commands = [ 'help help', 'help aliases', 'help quit', 'help q', 'help EOF', 'help list', 'help l', 'help ll', 'help account', 'help mark', 'help m', 'help unmark', 'help u', 'help start', 'help finish', ] with FileTester.temp_input(testdata) as tempfilename: interpreter = Reconciler(LedgerFile(tempfilename, 'cash')) for c in commands: self.reset_redirect() interpreter.onecmd(c) self.assertFalse( self.redirect.getvalue().startswith(Reconciler.NO_HELP) )
def test_finish_balancing_errors(self): with FileTester.temp_input(testdata) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.reset_redirect() recon.finish_balancing() self.assertEqual( '*** Ending balance must be set in order to finish', self.redirect.getvalue().rstrip() ) self.reset_redirect() recon.ending_balance = -1234.56 recon.finish_balancing() self.assertEqual( '"To zero" must be zero in order to finish', self.redirect.getvalue().rstrip() ) # confirms it didn't revert to None as on success self.assertEqual(-1234.56, recon.ending_balance)
def test_later_non_transaction_date(self): """later non-transaction things inherit preceding thing date""" testdata = '''2013/05/06 payee name expenses: misc liabilities: credit card $-1 2013/05/07 payee name expenses: misc liabilities: credit card $-2 ''' tempfile = FileTester.create_temp_file(testdata) ledgerfile = LedgerFile(tempfile) ledgerfile._add_thing_from_lines( ['; blah blah blah', '; and so on...'] ) # non-transaction dates are only populated with sort ledgerfile.sort() remove(tempfile) self.assertEqual( ledgerfile.get_things()[1].thing_date, ledgerfile.get_things()[2].thing_date )
def test_mark_and_unmark_errors(self): with FileTester.temp_input(testdata) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) self.reset_redirect() # none of these should result in a file write; we'll get out of # the context manager as an additional confirmation of this for command in [recon.do_mark, recon.do_unmark]: command('') self.assertEqual( '*** Transaction number(s) required', self.redirect.getvalue().rstrip() ) self.reset_redirect() command('ahchew') self.assertEqual( 'Transaction not found: ahchew', self.redirect.getvalue().rstrip() ) self.reset_redirect() recon.do_list('') self.reset_redirect() recon.do_mark('2') self.assertEqual( 'Already marked pending: 2', self.redirect.getvalue().rstrip() ) self.reset_redirect() recon.do_unmark('1') self.assertEqual( "Not marked; can't unmark: 1", self.redirect.getvalue().rstrip() )
def test_list_all(self): with FileTester.temp_input(testdata) as tempfilename: recon = Reconciler(LedgerFile(tempfilename, 'cash')) recon.do_list('') payees = { thing.payee for k, thing in recon.current_listing.iteritems() } # future items included only if pending ('three') self.assertEqual( ({'two', 'two pt five', 'three'}), payees ) recon.do_list('aLL') payees = { thing.payee for k, thing in recon.current_listing.iteritems() } self.assertEqual( ({'two', 'two pt five', 'three', 'four'}), payees )