def test_add_and_query(self): balances = Balances() balances.add('1', 1) self.assertRaises(AssertionError, balances.add, '1', 1) balances.addTo('1', 2) self.assertRaises(KeyError, balances.addTo, '2', 3) balances.addOrAddTo('1', 5) balances.addOrAddTo('2', 7) self.assertDictEqual(balances.balances, {'1': 8, '2': 7}) balances.add( '3', 0 ) # zero balances are allowed as far as Balances class is concerned self.assertDictEqual(balances.balances, {'1': 8, '2': 7, '3': 0}) self.assertTrue(balances.accountHasBalance('1')) self.assertFalse(balances.accountHasBalance('unusedAccount')) self.assertEqual(balances.balanceFor('1'), 8) self.assertRaises(KeyError, balances.balanceFor, 'unusedAccount') self.assertEqual(balances.balanceFor_IfAny('unusedAccount'), 0)
def test_single_forwarding(self): balances = Balances() self.assertRaises(AssertionError, balances.getEndOfForwardingChainFrom, 'a') balances.add('a', 1) balances.add('b', 2) balances.add('c', 3) balances.add('d', 4) balances.add('e', 5) balances.add('f', 6) self.assertRaises(KeyError, balances.consumeAndForward, ['a', 'b', 'c'], 'g') self.assertDictEqual(balances.balances, { 'a': 1, 'b': 2, 'c': 3, 'e': 5, 'd': 4, 'f': 6 }) self.assertEqual(balances.getEndOfForwardingChainFrom('a'), 'a') balances.addFirstRef('a') balances.addFirstRef('b') balances.consumeAndForward(['a', 'b', 'c'], 'e') self.assertEqual(balances.getEndOfForwardingChainFrom('a'), 'e') self.assertRaises(AssertionError, balances.isReferenced, 'a') self.assertEqual(balances.changeCounts['a'], 0) self.assertEqual(balances.changeCounts['b'], 0) self.assertTrue(balances.isReferenced('e')) self.assertFalse(balances.isReferenced('f')) # cannot start adding refs after a balance has been consumed self.assertRaises(AssertionError, balances.addFirstRef, 'c') balances.addRef('a') balances.removeRef('a') self.assertEqual(balances.changeCounts['a'], 0) balances.removeRef('a') self.assertFalse('a' in balances.changeCounts) self.assertTrue(balances.isReferenced('e')) self.assertDictEqual(balances.changeCounts, {'b': 0}) balances.removeRef('b') self.assertFalse(balances.isReferenced('e')) self.assertDictEqual(balances.balances, {'e': 11, 'd': 4, 'f': 6}) self.assertDictEqual(balances.changeCounts, {})
def test_direct_refs(self): balances = Balances() self.assertRaises(AssertionError, balances.isReferenced, 'a') balances.add('a', 1) # can only add state changes to direct ref targets self.assertRaises(KeyError, balances.addStateChange, 'a') # must add first ref explicitly self.assertRaises(AssertionError, balances.addRef, 'a') self.assertFalse(balances.isReferenced('a')) balances.addFirstRef('a') self.assertTrue(balances.isReferenced('a')) self.assertEqual(balances.changeCounts['a'], 0) balances.addStateChange('a') self.assertEqual(balances.changeCounts['a'], 1) balances.addRef('a') balances.addRef('a') balances.removeRef('a') self.assertTrue(balances.isReferenced('a')) self.assertEqual(balances.changeCounts['a'], 1) balances.removeRef('a') self.assertTrue(balances.isReferenced('a')) self.assertEqual(balances.changeCounts['a'], 1) balances.removeRef('a') self.assertFalse(balances.isReferenced('a')) self.assertFalse('a' in balances.changeCounts)
def test_consume_contents(self): balances = Balances() returnValue = balances.consumeContents_IfAny('2') self.assertEqual(returnValue, 0) balances.add('1', 5) balances.add('2', 7) balances.add('3', 9) balances.addFirstRef('1') returnValue = balances.consumeContents_IfAny('1') self.assertEqual(returnValue, 5) self.assertDictEqual(balances.balances, {'3': 9, '2': 7, '1': 0}) returnValue = balances.consumeContents_IfAny('1') self.assertEqual(returnValue, 0) self.assertDictEqual(balances.balances, {'3': 9, '2': 7, '1': 0}) returnValue = balances.consumeContents_IfAny('2') self.assertEqual(returnValue, 7) self.assertDictEqual(balances.balances, {'3': 9, '1': 0}) balances.removeRef('1') self.assertDictEqual(balances.balances, {'3': 9})
def test_triple_forwarding_and_direct_refs(self): balances = Balances() balances.add('a', 1) balances.add('c', 3) balances.add('e', 5) balances.add('f', 6) balances.add('g', 7) balances.addFirstRef('a') balances.consumeAndForward(['a', 'c'], 'e') balances.consumeAndForward(['e'], 'f') balances.addFirstRef('f') balances.consumeAndForward(['f'], 'g') balances.removeRef('a') self.assertDictEqual(balances.changeCounts, {'f': 0}) self.assertTrue(balances.isReferenced('g')) balances.removeRef('f') self.assertDictEqual(balances.changeCounts, {}) self.assertFalse(balances.isReferenced('g')) self.assertDictEqual(balances.balances, {'g': 22})
def test_double_forwarding(self): balances = Balances() balances.add('a', 1) balances.add('b', 2) balances.add('c', 3) balances.add('d', 4) balances.add('e', 5) balances.add('f', 6) balances.addFirstRef('a') balances.addFirstRef('b') balances.consumeAndForward(['a', 'b', 'c'], 'e') balances.consumeAndForward(['e'], 'f') self.assertEqual(balances.getEndOfForwardingChainFrom('a'), 'f') # can only forward from actual reference targets self.assertRaises(AssertionError, balances.getEndOfForwardingChainFrom, 'e') self.assertEqual(balances.getEndOfForwardingChainFrom('d'), 'd') self.assertEqual(balances.changeCounts['a'], 0) balances.removeRef('a') self.assertFalse('a' in balances.changeCounts) self.assertRaises(AssertionError, balances.getEndOfForwardingChainFrom, 'a') self.assertEqual(balances.getEndOfForwardingChainFrom('b'), 'f') self.assertTrue(balances.isReferenced('f')) self.assertDictEqual(balances.changeCounts, {'b': 0}) balances.removeRef('b') self.assertDictEqual(balances.changeCounts, {}) self.assertFalse('b' in balances.changeCounts) self.assertRaises(AssertionError, balances.getEndOfForwardingChainFrom, 'b') self.assertFalse(balances.isReferenced('f')) self.assertDictEqual(balances.balances, {'d': 4, 'f': 17})
def test_single_forwarding_zero_balance_cleanup(self): balances = Balances() balances.add('a', 1) balances.add('b', 2) balances.add('c', 3) balances.addFirstRef('a') balances.consumeContents_IfAny('a') self.assertDictEqual(balances.balances, {'a': 0, 'b': 2, 'c': 3}) balances.consumeAndForward(['a', 'b'], 'c') self.assertDictEqual(balances.balances, {'c': 5}) balances.consumeContents_IfAny('c') self.assertDictEqual(balances.balances, {'c': 0}) balances.removeRef('a') self.assertDictEqual(balances.balances, {})