"""Unit Test for Money, using Jython and PyUnit

Translation of MoneTest.java from JUnit into Python, to demonstrate
how to unit test Java files using Jython and PyUnit
"""

__version__ = "$Revision: 1.2 $"
# $RCSfile: MoneyTest_py.html,v $

import sys
import unittest
from junit.samples.money import Money
from junit.samples.money import MoneyBag

MESSAGE_REGISTRY = """
__________________________________________________________________________
|                                                                          |
| In order to successfully run this unit test example, you need to set the |
| property "python.security.respectJavaAccessibility" to "false" in the    |
| jython registry file. The default location of the jython registry file   |
| is in the installation directory of jython, at the same level than       |
| jython.jar.                                                              |
|                                                                          |
| For more information about the jython registry, visit:                   |
| - http://www.jython.org/docs/registry.html                               |
|__________________________________________________________________________|

"""

class MoneyTest(unittest.TestCase):

  """PyUnit version of the original JUnit package example."""

  def __init__(self, test):
    unittest.TestCase.__init__(self, test)
    self.check_registry()
    self.assertTrue = self.assert_

  def check_registry(self):
    """Setting python.security.respectJavaAccessibility to false allows access
    to protected and private element of a Java class"""
    if sys.registry['python.security.respectJavaAccessibility'] == 'true':
      print MESSAGE_REGISTRY
      sys.exit(0)

  def assertFalse(self, expr, msg=None):
    """Fail the test if the expression is true."""
    if expr: raise self.failureException, msg

  def setUp(self):
    self.f12CHF = Money(12, "CHF")
    self.f14CHF = Money(14, "CHF")
    self.f7USD = Money(7, "USD")
    self.f21USD = Money(21, "USD")
    self.fMB1 = MoneyBag.create(self.f12CHF, self.f7USD)
    self.fMB2 = MoneyBag.create(self.f14CHF, self.f21USD)

  def testBagMultiply(self):
    """{[12 CHF][7 USD]} *2 == {[24 CHF][14 USD]}"""
    expected = MoneyBag.create(Money(24, "CHF"), Money(14, "USD"))
    self.assertEquals(expected, self.fMB1.multiply(2))
    self.assertEquals(self.fMB1, self.fMB1.multiply(1))
    self.assertTrue(self.fMB1.multiply(0).isZero())

  def testBagNegate(self):
    """{[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]}"""
    expected = MoneyBag.create(Money(-12, "CHF"), Money(-7, "USD"))
    self.assertEquals(expected, self.fMB1.negate())

  def testBagSimpleAdd(self):
    """{[12 CHF][7 USD]} + [14 CHF] == {[26 CHF][7 USD]}"""
    expected = MoneyBag.create(Money(26, "CHF"), Money(7, "USD"))
    self.assertEquals(expected, self.fMB1.add(self.f14CHF))

  def testBagSubtract(self):
    """{[12 CHF][7 USD]} - {[14 CHF][21 USD] == {[-2 CHF][-14 USD]}"""
    expected = MoneyBag.create(Money(-2, "CHF"), Money(-14, "USD"))
    self.assertEquals(expected, self.fMB1.subtract(self.fMB2))

  def testBagSumAdd(self):
    """{[12 CHF][7 USD]} + {[14 CHF][21 USD]} == {[26 CHF][28 USD]}"""
    expected = MoneyBag.create(Money(26, "CHF"), Money(28, "USD"))
    self.assertEquals(expected, self.fMB1.add(self.fMB2))

  def testIsZero(self):
    self.assertTrue(self.fMB1.subtract(self.fMB1).isZero())
    self.assertTrue(MoneyBag.create(Money(0, "CHF"), Money(0, "USD")).isZero())

  def testMixedSimpleAdd(self):
    """[12 CHF] + [7 USD] == {[12 CHF][7 USD]}"""
    expected = MoneyBag.create(self.f12CHF, self.f7USD)
    self.assertEquals(expected, self.f12CHF.add(self.f7USD))

  def testBagNotEquals(self):
    bag = MoneyBag.create(self.f12CHF, self.f7USD)
    self.assertFalse(bag.equals(Money(12, "DEM").add(self.f7USD)))

  def testMoneyBagEquals(self):
    self.assertTrue(not self.fMB1.equals(None))
    self.assertEquals(self.fMB1, self.fMB1)
    equal = MoneyBag.create(Money(12, "CHF"), Money(7, "USD"))
    self.assertTrue(self.fMB1.equals(equal))
    self.assertTrue(not self.fMB1.equals(self.f12CHF))
    self.assertTrue(not self.f12CHF.equals(self.fMB1))
    self.assertTrue(not self.fMB1.equals(self.fMB2))

  def testMoneyBagHash(self):
    equal = MoneyBag.create(Money(12, "CHF"), Money(7, "USD"))
    self.assertEquals(self.fMB1.hashCode(), equal.hashCode())

  def testMoneyEquals(self):
    self.assertTrue(not self.f12CHF.equals(None))
    equalMoney = Money(12, "CHF")
    self.assertEquals(self.f12CHF, self.f12CHF)
    self.assertEquals(self.f12CHF, equalMoney)
    self.assertEquals(self.f12CHF.hashCode(), equalMoney.hashCode())
    self.assertTrue(not self.f12CHF.equals(self.f14CHF))

  def testMoneyHash(self):
    self.assertTrue(not self.f12CHF.equals(None))
    equal = Money(12, "CHF")
    self.assertEquals(self.f12CHF.hashCode(), equal.hashCode())

  def testSimplify(self):
    money = MoneyBag.create(Money(26, "CHF"), Money(28, "CHF"))
    self.assertEquals(Money(54, "CHF"), money)

  def testNormalize2(self):
    """{[12 CHF][7 USD]} - [12 CHF] == [7 USD]"""
    expected = Money(7, "USD")
    self.assertEquals(expected, self.fMB1.subtract(self.f12CHF))

  def testNormalize3(self):
    """{[12 CHF][7 USD]} - {[12 CHF][3 USD]} == [4 USD]"""
    ms1 = MoneyBag.create(Money(12, "CHF"), Money(3, "USD"))
    expected = Money(4, "USD")
    self.assertEquals(expected, self.fMB1.subtract(ms1))

  def testNormalize4(self):
    """[12 CHF] - {[12 CHF][3 USD]} == [-3 USD]"""
    ms1 = MoneyBag.create(Money(12, "CHF"), Money(3, "USD"))
    expected = Money(-3, "USD")
    self.assertEquals(expected, self.f12CHF.subtract(ms1))

  def testPrint(self):
    self.assertEquals("[12 CHF]", self.f12CHF.toString())

  def testSimpleAdd(self):
    """[12 CHF] + [14 CHF] == [26 CHF]"""
    expected = Money(26, "CHF")
    self.assertEquals(expected, self.f12CHF.add(self.f14CHF))

  def testSimpleBagAdd(self):
    """[14 CHF] + {[12 CHF][7 USD]} == {[26 CHF][7 USD]}"""
    expected = MoneyBag.create(Money(26, "CHF"), Money(7, "USD"))
    self.assertEquals(expected, self.f14CHF.add(self.fMB1))

  def testSimpleMultiply(self):
    """[14 CHF] *2 == [28 CHF]"""
    expected = Money(28, "CHF")
    self.assertEquals(expected, self.f14CHF.multiply(2))

  def testSimpleNegate(self):
    """[14 CHF] negate == [-14 CHF]"""
    expected = Money(-14, "CHF")
    self.assertEquals(expected, self.f14CHF.negate())

  def testSimpleSubtract(self):
    """[14 CHF] - [12 CHF] == [2 CHF]"""
    expected= Money(2, "CHF")
    self.assertEquals(expected, self.f14CHF.subtract(self.f12CHF))

def suite():
  return unittest.makeSuite(MoneyTest)

if __name__ == '__main__':
  unittest.main()