#! /usr/bin/env python

# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program.  If not, see <http://www.gnu.org/licenses/>.

"""Usage: test_ab.py [options] [test] [...]

Options:
  -h, --help       Show this message
  -v, --verbose    Verbose output
  -q, --quiet      Minimal output

Examples:
  test_ab.py                               - run default set of tests
  test_ab.py MyTestSuite                   - run suite 'MyTestSuite'
  test_ab.py MyTestCase.testSomething      - run MyTestCase.testSomething
  test_ab.py MyTestCase                    - run all 'test*' test methods
                                               in MyTestCase

"""

# To find valentine.delvian
import os
__path__ = [os.pardir]

import unittest

from valentine.delvian import ab

__author__ = ab.__author__
__version__ = ab.__version__


class AddressBook(unittest.TestCase):

    """Test AddressBook.

    ATTRIBUTES

    ab                  The address book.

    METHODS

    setUp               Create a new address book for every test.
    test_add            Assert that address books add contacts properly.
    test_edit           Assert that address books edit contacts properly.
    test_init           Assert that address books initialize properly.
    test_remove         Assert that address books remove contacts properly.
    test_search         Assert that address books search properly.

    """

    def setUp(self):
        """Create a new address book for every test."""
        self.ab = ab.AddressBook()

    def test_init(self):
        """Assert that address books initialize properly."""
        self.assertEqual(self.ab, {})

    def test_add(self):
        """Assert that address books add contacts properly."""
        self.ab.add(ab.Contact('name', 'email'))
        self.assertEqual(self.ab['name'], ab.Contact('name', 'email'))

    def test_edit(self):
        """Assert that address books edit contacts properly."""
        self.ab.add(ab.Contact('name', ''))
        self.ab.edit(ab.Contact('name', 'email'))
        self.assertEqual(self.ab['name'], ab.Contact('name', 'email'))

    def test_remove(self):
        """Assert that address books remove contacts properly."""
        self.ab.add(ab.Contact('name', 'email'))
        self.ab.remove('name')
        self.assert_('name' not in self.ab)

    def test_search(self):
        """Assert that address books search properly."""
        self.assertEqual(self.ab.search(['name']), [])


class AddressBookErrors(unittest.TestCase):

    """Test AddressBook errors.

    ATTRIBUTES

    ab                  The address book.

    METHODS

    setUp               Create a new address book for every test.
    test_add            Assert that address books raise ContactExistError.
    test_edit           Assert that address books raise ContactDoesNotExistError.
    test_remove         Assert that address books raise ContactDoesNotExistError.

    """

    def setUp(self):
        """Create a new address book for every test."""
        self.ab = ab.AddressBook()

    def test_add(self):
        """Assert that address books raise ContactExistsError."""
        self.ab.add(ab.Contact('name', 'email'))
        self.assertRaises(ab.ContactExistsError, self.ab.add,
                          ab.Contact('name', 'email'))

    def test_edit(self):
        """Assert that address books raise ContactDoesNotExistError."""
        self.assertRaises(ab.ContactDoesNotExistError, self.ab.edit,
                          ab.Contact('name', 'email'))

    def test_remove(self):
        """Assert that address books raise ContactDoesNotExistError."""
        self.assertRaises(ab.ContactDoesNotExistError, self.ab.remove, 'name')


class Contact(unittest.TestCase):

    """Test Contact.

    ATTRIBUTES

    contact             The contact.

    METHODS

    setUp               Create a new contact for every test.
    test_cmp            Assert that contacts compare properly.
    test_contains       Assert that contacts search properly.
    test_init           Assert that contacts inititialize properly.
    test_str            Assert that contacts print properly.

    """

    def setUp(self):
        """Create a new contact for every test."""
        self.contact = ab.Contact('name', 'email')

    def test_init(self):
        """Assert that contacts inititialize properly."""
        self.assertEqual((self.contact.name, self.contact.email),
                         ('name', 'email'))

    def test_cmp(self):
        """Assert that contacts compare properly."""
        self.assertEqual(self.contact, ab.Contact('name', 'email'))

    def test_contains(self):
        """Assert that contacts search properly."""
        self.assert_(['name'] in self.contact)

    def test_str(self):
        """Assert that contacts print properly."""
        self.assertEqual(str(self.contact), 'name: email')


class ContactDoesNotExistError(unittest.TestCase):

    """Test ContactDoesNotExistError.

    METHODS

    test_init           Assert that ContactDoesNotExistError initializes properly.

    """

    def test_init(self):
        """Assert that ContactDoesNotExistError inititializes properly."""
        self.assertEqual(ab.ContactDoesNotExistError('name').message,
                         'name is not in your address book')


class ContactExistsError(unittest.TestCase):

    """Test ContactExistsError.

    METHODS

    test_init           Assert that ContactExistsError initializes properly.

    """

    def test_init(self):
        """Assert that ContactExistsError initializes properly."""
        self.assertEqual(ab.ContactExistsError('name').message,
                         'name is already in your address book')


# Run the tests.
if __name__ == '__main__':
    unittest.main()

# (c) 2010 Delvian Valentine <djdvalentine@gmail.com>
