Exemplo n.º 1
0
def test_addressbook():
    ab = utils.open_addressbook('mybook')
    print ab
    ab.sort(['fname', 'lname']) 
    ab2 = AddressBook()
    ab2.import_contacts('Handsome')
    print ab2
Exemplo n.º 2
0
class TestAddressBookBasic(TestCase):
    def setUp(self):
        self.book = AddressBook()

    def test_create_address_book(self):
        assert len(self.book.persons) == 0
        assert len(self.book.groups) == 0

    def test_add_person(self):
        person = self.book.create_person(first_name="Test", last_name="Man")
        assert len(self.book.persons) == 1
        assert person.first_name == "Test"
        assert person.last_name == "Man"

    def test_add_person_with_attributes(self):
        emails = ["*****@*****.**", "*****@*****.**"]
        phones = ["123", "456"]
        addresses = ["Baker st", "Lenin st"]
        person = self.book.create_person(first_name="Test",
                                         last_name="Man",
                                         emails=emails,
                                         phones=phones,
                                         addresses=addresses)
        assert person.emails == emails
        assert person.phones == phones
        assert person.addresses == addresses

    def test_person_wrong_attribute_types(self):
        phones = [12345]
        with pytest.raises(AssertionError):
            self.book.create_person(first_name="Test",
                                    last_name="Man",
                                    phones=phones)

    def test_add_group(self):
        group = self.book.create_group(name="Friends")
        assert len(self.book.groups) == 1
        assert group.name == "Friends"

    def test_group_members(self):
        group = self.book.create_group(name="Friends")
        person1 = self.book.create_person(first_name="Test", last_name="Man")
        person2 = self.book.create_person(first_name="Test", last_name="Dog")
        group.add_member(person1)
        group.add_member(person2)
        assert len(group.members) == 2
        assert sorted(group.members,
                      key=lambda p: p.last_name) == [person2, person1]

    def test_person_groups(self):
        group1 = self.book.create_group(name="Friends")
        group2 = self.book.create_group(name="Foes")
        person = self.book.create_person(first_name="Test", last_name="Man")
        group1.add_member(person)
        group2.add_member(person)
        assert len(person.groups) == 2
        assert sorted(person.groups, key=lambda p: p.name) == [group2, group1]
Exemplo n.º 3
0
def main():
    '''Load settings, start status icon and get to work.'''
    from addressbook import AddressBook
    from status_icon import StatusIcon
    # try to load settings
    conf = Conf()

    # load data and fill AddressBook
    addressbook = AddressBook(conf)
    addressbook.reload()

    # show status icon
    status_icon = StatusIcon(addressbook, conf)

    # check every 60 seconds for new day
    # TODO: update until end of day according to current clock settings?
    #       (might not the best idea if user changes current time)
    import gobject
    gobject.timeout_add(60000, status_icon.check_new_day)
    gtk.main()
Exemplo n.º 4
0
def main():
    '''Load settings, start status icon and get to work.'''
    from addressbook import AddressBook
    from status_icon import StatusIcon
    # try to load settings
    conf = Conf()

    # load data and fill AddressBook
    addressbook = AddressBook(conf)
    addressbook.reload()

    # show status icon
    status_icon = StatusIcon(addressbook, conf)

    # check every 60 seconds for new day
    # TODO: update until end of day according to current clock settings?
    #       (might not the best idea if user changes current time)
    import gobject
    gobject.timeout_add(60000, status_icon.check_new_day)
    gtk.main()
Exemplo n.º 5
0
class TestAddressBookSearchByEmail(TestCase):
    def setUp(self):
        self.book = AddressBook()

    def test_find_person_by_email(self):
        person = self.book.create_person(first_name="Test",
                                         last_name="Man",
                                         emails=["*****@*****.**"])
        result = self.book.person_by_email("*****@*****.**")
        assert len(result) == 1
        assert result[0] == person

    def test_find_person_by_email_prefix(self):
        person = self.book.create_person(first_name="Test",
                                         last_name="Man",
                                         emails=["*****@*****.**"])
        result = self.book.person_by_email("test")
        assert len(result) == 1
        assert result[0] == person

    def test_find_person_by_email_no_result(self):
        person = self.book.create_person(first_name="Test",
                                         last_name="Man",
                                         emails=["*****@*****.**"])
        result = self.book.person_by_email("foo")
        assert len(result) == 0
Exemplo n.º 6
0
def create_list_append(Addresses, name):
    address_dict = Addresses
    address_list = []
    for address in address_dict['Addresses']:
        address_obj = PersonAddress(address['first_name'],address['last_name'],address['Address'],address['City'],address['State'],address['Zip_code'],address['Phone_number'])
        address_list.append(address_obj)
        print("\r")
        print(address_obj)
        print("\r")
    file_to_open = name.replace(".json","")
    file_to_open = AddressBook(file_to_open)
    while True:
        try:
            action = int(input("Enter 1 if you want to edit the addressbook(Enter any other digit to exit) : "))
        except ValueError as err:
            print(err)
        break
    if(action == 1):
        file_to_open.edit_already_existing_addressbook(address_list)
        addressbook_operation(file_to_open)
    else:
        mainmenu_operation()
Exemplo n.º 7
0
def get_name_from_address_book(phone_or_email):
    book = AddressBook()
    try:
        name = book.query_number(AddressBook.clean_number(phone_or_email))
        if not name:
            # try getting rid of the 1
            name = book.query_number(AddressBook.clean_number(phone_or_email)[1:])
    except KeyError:
        name = book.query_email(phone_or_email.lower())
    if not name:
        return phone_or_email
    return name
Exemplo n.º 8
0
def new_addressbook():
    Addressbook_name = str(input("Enter a name for your new addressbook : "))
    Addressbook_name = AddressBook(Addressbook_name)
    addressbook_operation(Addressbook_name)
Exemplo n.º 9
0
	def __init__(self, *args, **kwargs):
		self.addressbook = AddressBook()
		self.current_book_filename = ""
		Cmd.__init__(self, *args, **kwargs)
Exemplo n.º 10
0
class TestAddressBookApiMethods(unittest.TestCase):

    def setUp(self):
        self.address_book = AddressBook()

    def test_add_person(self):

        self.assertRaises(ValueError, self.address_book.add_person, {})

        person_dict = {
            'first_name': 'John',
            'last_name': 'Deer',
            'email_list': ['*****@*****.**'],
            'phone_list': ['999-999-9999'],
            'address_list': ['Anthony Benoit 490 E, Main Street Norwich, CT 06360, US'],
            'group_list': ['general'],
        }

        result = self.address_book.add_person(person_dict)
        self.assertTrue(result)

    def test_add_group(self):

        self.assertRaises(ValueError, self.address_book.add_group, None)

        result = self.address_book.add_group('general')
        self.assertTrue(result)

    def test_find(self):

        address_book = self.address_book

        john_dict = {
            'first_name': 'John',
            'last_name': 'Deer',
            'email_list': ['*****@*****.**'],
            'phone_list': ['999-999-9999'],
            'address_list': ['Anthony Benoit 490 E, Main Street Norwich, CT 06360, US'],
            'group_list': ['general'],
        }
        address_book.add_person(john_dict)

        bob_dict = {
            'first_name': 'Bob',
            'last_name': 'Dilan',
            'email_list': ['*****@*****.**', '*****@*****.**'],
            'phone_list': ['999-888-9999'],
            'address_list': ['Green 490 E, Main Street Norwich, CT 06360, US'],
            'group_list': ['general', 'friends'],
        }
        address_book.add_person(bob_dict)

        result1 = address_book.find_persons(first_name='Bob')
        self.assertEqual(result1, [bob_dict])

        result2 = address_book.find_persons(first_name='Bob', last_name='Dilan')
        self.assertEqual(result2, [bob_dict])

        result3 = address_book.find_persons(email='*****@*****.**')
        self.assertEqual(result3, [bob_dict])

        result4 = address_book.find_persons(email='john')
        self.assertEqual(result4, [john_dict])

        result5 = address_book.find_persons(group='general')
        self.assertEqual(result5, [john_dict, bob_dict])
Exemplo n.º 11
0
def main():
    """ Main """
    # fileConfig(
    #    'logging.conf',
    #    defaults={'logfilename': ''})

    log_format = ("[%(asctime)s] [%(levelname)s] "
                  "[%(name)s] [%(funcName)s():%(lineno)s] "
                  "[PID:%(process)d TID:%(thread)d] %(message)s")

    #    logging.basicConfig(
    #        level=logging.INFO,
    #        format=log_format,
    #        datefmt="%d/%m/%Y %H:%M:%S",
    #        filename=LOG_FILENAME,
    #        filemode='a')
    #
    #    logger = logging.getLogger(__name__)
    #    handler = logging.handlers.RotatingFileHandler(
    #        LOG_FILENAME,
    #        maxBytes=200,
    #        backupCount=5)
    #

    # TODO:
    # IN COLORED LOGS:
    # ADD OPTION FOR ERRSTREAM/FILE
    # ADD OPTION FOR LOGROTATE
    # CHANGE LEVEL NAME COLOUR ACCORDING TO CURRENT LEVEL
    coloredlogs.install(level=logging.INFO,
                        fmt=log_format,
                        isatty=True,
                        datefmt="%d/%m/%Y %H:%M:%S",
                        stream=open(LOG_FILENAME, "w+"))

    #    error_handler = logging.FileHandler(ERROR_FILENAME)
    #    error_handler.setLevel(logging.ERROR)

    # Initializes a thread lock which can be used to serialize access
    # to underlying I/O functionality which may not be threadsafe.
    #    handler.createLock()
    #    error_handler.createLock()

    # Acquires the thread lock created with createLock().
    #    handler.acquire()
    #    error_handler.acquire()

    # Add the log message handlers to the logger
    #    logger.addHandler(handler)
    #    logger.addHandler(error_handler)

    addr_book = AddressBook()
    person_args = {
        "lastname": "Mario",
        "name": "Luigi",
        "address": ["via alfa", "via beta"],
        "email": ["*****@*****.**", "*****@*****.**"],
        "phone": ["012345678", "8765431"],
        "groups": ["Alfa", "Gamma"]
    }
    person1 = Person(person_args)
    person_args = {
        "lastname": "Mario",
        "name": "Mario",
        "address": ["via alfa", "via beta"],
        "email": ["*****@*****.**", "*****@*****.**"],
        "phone": ["012345678", "8765431"],
        "groups": ["Alfa", "Gamma"]
    }
    person2 = Person(person_args)
    # Add a group to the address book.
    addr_book.add_group("Alfa")
    addr_book.add_group("Gamma")

    # Add a group to the address book.

    # Add a person to the address book.
    addr_book.add_person(person1)
    addr_book.add_person(person2)
    print("Persons:\n%s" % (addr_book.get_persons_str()))
    print("Groups:\n%s" % (addr_book.get_groups_str()))

    # Given a group we want to easily find its members
    for person in addr_book.get_group_members("Alfa"):
        print("Person: %s" % person.get_full_name())

    # Given a person we want to easily find the groups the person belongs to.
    print("Person: " + str(addr_book.get_person_group(person1)))

    # Find person by name (can supply either first name, last name, or both).
    persons_found = addr_book.find_person("Mario", "Luigi")
    if persons_found is not None:
        for person in persons_found:
            print(person.get_fmt_str())
    print("--------------------------")
    persons_found = addr_book.find_person("Mario")
    if persons_found is not None:
        for person in persons_found:
            print(person.get_fmt_str())
    print("--------------------------")
    persons_found = addr_book.find_person(None, "Luigi")
    if persons_found is not None:
        for person in persons_found:
            print(person.get_fmt_str())

    print("--------------------------")
    # Find person by email address (can supply either the exact string
    # or a prefix string,
    # ie. both "*****@*****.**" and "alex" should work).
    person_found = addr_book.find_person_by_email("*****@*****.**")
    if person_found is not None:
        print("Found:\n%s" % person_found.get_fmt_str())

    person = addr_book.find_person_by_email("luigi")
    if person is not None:
        print("Person found")
Exemplo n.º 12
0
class CommandLineInterface(Cmd):
	"""
	VALID COMMANDS:
	
	| add
	| edit
	| delete
	| display
	| display_mail
	| sort
	| open
	| save
	| save_as
	| import
	| export
	| options
	| help
	| quit

	VALID FLAGS (used with keywords edit, delete, display, sort):
	NOTE all flags must be followed by a single argument in quotes (eg: -a "123 Easy St"; -fn "Kevin").
	-fn (first name)
	-ln (last name)
	-a (address)
	-a2 (address line 2)
	-c (city)
	-s (state)
	-z (ZIP Code)
	-p (phone number)
	-e (email)
	"""

	intro = WELCOME_MESSAGE
	prompt = "> "

	def __init__(self, *args, **kwargs):
		self.addressbook = AddressBook()
		self.current_book_filename = ""
		Cmd.__init__(self, *args, **kwargs)

	def do_add(self, line):
		"""
		Add a new contact to the Address Book.
		"""
		new_contact = Contact()

		print "* denotes a required field.\nPress ctrl-c to cancel."
		for field in CONTACT_FIELDS:
			valid = FIELD_VALIDATORS[field[0]]
			try:
				data = None
				if field[0] in REQUIRED_FIELDS:
					while getattr(new_contact, field[0], '')=='' or not valid(data)[0]:
						data = raw_input("{0}: ".format(field[1]))
						setattr(new_contact, field[0], data)
						if not valid(data)[0]:
							print valid(data)[1]
				else:
					while not valid(data)[0]:
						data = raw_input("{0}: ".format(field[1]))
						setattr(new_contact, field[0], data)
						if not valid(data)[0]:
							print valid(data)[1]
			
			except KeyboardInterrupt:
				print "\nCancelling New Contact\n"
				return

		self.addressbook.add(new_contact)
		print "Your entry was successfully added."

	def do_edit(self, line):
		"""
		Edit an existing contact in the Address Book.
		It actually deletes the "edited " contact and adds a new contact with the changed (or not) fields
		"""
		if line == "":
			print EDIT_AND_DELETE_NEED_ARGS
			return

		# Get list of tuples of (field, arg)
		fields_args = get_field_and_args_from_input(line)
		if not fields_args: return

		# Search address book for specified contact
		lists = [] # a list of lists returned by search, each list the result of a search on one field
		for field_arg in fields_args:
			lists.append(self.addressbook.search(field_arg[0], field_arg[1]))

		# Intersect all resulting lists from field queries
		# This is a list of tuples (index, contact)
		search_results = list(set(lists[0]).intersection(*lists[1:]))

		# if more than one such contact, display list of said contacts
		# if exacly one such contact, that is the one we want
		# if no such contact, inform user
		if len(search_results) > 1:
			print NARROW_SEARCH_MESSAGE
			for result in search_results:
				print "-------------------------"
				print result[1]

		elif len(search_results) == 1:
			print "\nPress ctrl-c to cancel."

			contact = search_results[0] #tuple (index, contact)

			# TODO, create temp contact to hold edits, replace old contact with new
			temp = Contact()

			for field in CONTACT_FIELDS:
				valid = FIELD_VALIDATORS[field[0]]
				try:
					new_data = None
					old_data = getattr(contact[1], field[0], '')
					while not valid(new_data)[0]:
						user_input = raw_input("{0}: {1}".format(field[1], old_data) + chr(8)*len(old_data))
						# NOTE: 8 is the ASCII value of backspace
						if not user_input:
							user_input = old_data

						# My hacky way of having the newly added chars replace those of the old_data
						# for cases where user replaces some, but not all, of the old data's chars
						user_input = list(user_input)
						new_data = list(old_data)
						for i in range(len(user_input)):
							try:
								new_data[i] = user_input[i]
							except IndexError:
								new_data.extend(user_input[i:])
								break
						new_data = ''.join(new_data)
						if not valid(new_data)[0]:
							print valid(new_data)[1]

					# Update the temp Contact Info
					setattr(temp, field[0], new_data)
			
				except KeyboardInterrupt:
					print "\nCancelling Contact Edit, reverting to original.\n"
					return

			confirm = raw_input("Are you sure you want to make these changes to this entry? (y/n): ")
			if confirm in ('yes', 'y'):
				self.addressbook.delete(contact[0])
				self.addressbook.add(temp)
				print "Edit complete"
				return

			else:
				print "\nCancelling Contact Edit, reverting to original.\n"


		else:
			print "There were no contacts that met your specification. Please generalize your request."

	def do_delete(self, line):
		"""
		Deletes a contact from the Address Book.
		Or if more than one contact meets the user's specification, presents a list of said contacts.
		If no contacts meet the user's specification, then does nothing.
		**User can only delete one contact at a time.**
		"""
		if line == "":
			print EDIT_AND_DELETE_NEED_ARGS
			return

		# Get list of tuples of (field, arg)
		fields_args = get_field_and_args_from_input(line)
		if not fields_args: return

		# Search address book for specified contact
		lists = [] # a list of lists returned by search, each list the result of a search on one field
		for field_arg in fields_args:
			lists.append(self.addressbook.search(field_arg[0], field_arg[1]))

		# Intersect all resulting lists from field queries
		# This is a list of tuples (index, contact)
		search_results = list(set(lists[0]).intersection(*lists[1:]))

		# if more than one such contact, display list of said contacts
		# if exacly one such contact, that is the one we want
		# if no such contact, inform user
		if len(search_results) > 1:
			print NARROW_SEARCH_MESSAGE
			for result in search_results:
				print "-------------------------"
				print result[1]

		elif len(search_results) == 1:
			contact = search_results[0] #tuple (index, contact)
			print contact[1]
			yes_delete = raw_input("Is this the entry you want to delete? (y/n): ")
			if yes_delete in ('yes', 'y'):
				yes_delete = raw_input("*** Are you sure? (y/n): ")
				if yes_delete in ('yes', 'y'):
					try:
						self.addressbook.delete(contact[0])
						print "Contact deleted."
					except:
						print "*** Encountered an error while trying to delete, please make sure your input is correct."
					return
			print "No deletions."
		else:
			print "There were no contacts that met your specification. Please generalize your request."

	def do_display(self, line):
		"""
		If no flags are given, displays all contacts in the Address Book.
		If flags are present, then displays only contacts that meet all of the specifications given by flags.
		"""

		if self.addressbook.total == 0:
			print "The addressbook is empty."
			return

		# if no flags, arguments: 
		# Print entire address book
		if line == '':
			print "\n{0}".format(self.addressbook)

		# else find subset of addressbook
		else:
			# Get list of tuples (field, arg)
			fields_args = get_field_and_args_from_input(line)
			if not fields_args: return

			# Search address book for specified contacts
			lists = [] # a list of lists returned by search, each list the result of a search on one field
			for field_arg in fields_args:
				lists.append(self.addressbook.search(field_arg[0], field_arg[1]))

			# Intersect all resulting lists from field queries
			# This is a list of tuples (index, contact)
			search_results = list(set(lists[0]).intersection(*lists[1:]))

			if len(search_results) > 0:
				for result in search_results:
					print "\n{0}".format(result[1])
				print "\n"
			else:
				print "There were no contacts that met your specification. Please generalize/check your request."

	def do_display_mail(self, line):
		"""
		Same as 'display', but displays contact in mailing label format, as opposed to full contact.
		If no flags are given, displays all contacts in the Address Book.
		If flags are present, then displays only contacts that meet all of the specifications given by flags.
		"""

		if self.addressbook.total == 0:
			print "The addressbook is empty."
			return

		# if no flags, arguments: 
		# Print entire address book
		if line == '':
			print "\n{0}".format(self.addressbook.print_all_mailing())

		# else find subset of addressbook
		else:
			# Get list of tuples (field, arg)
			fields_args = get_field_and_args_from_input(line)
			if not fields_args: return

			# Search address book for specified contacts
			lists = [] # a list of lists returned by search, each list the result of a search on one field
			for field_arg in fields_args:
				lists.append(self.addressbook.search(field_arg[0], field_arg[1]))

			# Intersect all resulting lists from field queries
			# This is a list of tuples (index, contact)
			search_results = list(set(lists[0]).intersection(*lists[1:]))

			if len(search_results) > 0:
				for result in search_results:
					print "\n{0}".format(result[1].print_mailing())
				print "\n"
			else:
				print "There were no contacts that met your specification. Please generalize/check your request."
	
	def do_sort(self, line):
		"""
        Sort the address book by the given attributes (flags). The first
        attribute is used and ties are broken using the following attributes in
        the list.
        Defaults to sorting by last name.  Ties are broken by last name.
		"""

		# convert flags to list of attributes.
		flags = line.split()
		attrs = []

		for flag in flags:
			if flag not in VALID_FLAGS:
				print "'{0}' is not a valid flag. Enter \"options\" to view available flag options.\n".format(flag)
				return

			for field in CONTACT_FIELDS:
				if flag == field[2]:
					attrs.append(field[0])

		# Ties are broken by name
		attrs.extend(['lname', 'fname'])

		# Apply sort function
		try:
			self.addressbook.sort(attributes=attrs)
			print "Address book is now sorted.\n"
		except:
			print "*** Encountered an error while trying to sort, please make sure your input is correct."

	def do_open(self, line):
		"""
		Open an address book from file.
		"""

		confirm = raw_input("Are you sure you want to open a new address book? Changes since your last save will be lost. ('open' / 'cancel'): ")
		if confirm != 'open': return		

		file_name = raw_input("Please give the name/path of the file containing the address book you want to open (or leave blank to cancel): ")

		if file_name:
			try:
				self.addressbook = utils.open_addressbook(file_name)
				self.current_book_filename = file_name
				print "Now using address book from file '{0}'".format(file_name)
			except:
				print "*** Encountered an error while trying to open that file. Please make sure you provided a good file name."

	def do_save(self, line):
		"""
		Save an address book as an object to a file, to the file name inferred from current address book.
		"""

		if self.current_book_filename == '': 
			print "This seems to be a new address book."
			return self.do_save_as(line)


		file_name = self.current_book_filename

		confirm = raw_input("Are you sure you want to overwrite the existing file '{0}'? (y/n): ".format(file_name))
		if confirm in ['yes', 'y']:
			try:
				utils.save_addressbook(self.addressbook, file_name)
				print "Successfully saved your address book to the file '{0}'".format(file_name)
			except:
				print "in save"
				print "*** Encountered an error while trying to save. Sorry..."

		else:
			print "Cancelling save."
			return

	def do_save_as(self, line):
		"""
		Save an address book as an object to a file.
		"""

		file_name = raw_input("What do you want to call your file? (or leave blank to cancel): ")
			# "WARNING, I can't tell if you're overwritting a file that already exists, so choose the name carefully: ")

		if not file_name: return

		try:
			with open(file_name):
				overwrite = raw_input("There already seems to be a file with that name. Do you want to overwrite that file? (y/n): ")
		except IOError:
			overwrite = 'yes'

		if overwrite in ['yes', 'y']:
			try:
				utils.save_addressbook(self.addressbook, file_name)
				self.current_book_filename = file_name
				print "Successfully saved your address book to the file '{0}'".format(file_name)
			except:
				print "in save as"
				print "*** Encountered an error while trying to save. Sorry..."
	
	def do_import(self, line):
		"""
		Import a contacts list from a tsv file and add the contacts to the current book.
		The format of the file is as follows:
		
		| Last<tab>Delivery<tab>Second<tab>Recipient<tab>Phone<NL>
		| followed by a list of contacts with the same format.
		"""
		file_name = raw_input("Please give the name/path of the file from which you want to import contacts (or leave blank to cancel): ")

		if file_name:
			confirm = raw_input("Are you sure you want to try to merge the contacts from this file into your current book? (y/n): ")
			if confirm not in ['yes', 'y']: print "Cancelling import."; return
			try:
				self.addressbook.import_contacts(file_name)
				print "Successfully imported contacts from '{0}'".format(file_name)
			except:
				print "*** Encountered an error while trying to import from that file. " + \
					"Please make sure you provided a good file name and that the file matches the format described in 'help import'."
		else:
			print "Cancelling import."

	def do_export(self, line):	
		"""
		Export the contacts of the current AddressBook to a tsv file.
		The format of the file is as follows:
		
		| Last<tab>Delivery<tab>Second<tab>Recipient<tab>Phone<NL>
		| followed by a list of contacts with the same format.
		"""	
		file_name = raw_input("Please give the name of the file to which you want to export contacts (or leave blank to cancel): ")
			
		if file_name:
			try:
				self.addressbook.export_contacts(file_name)
				print "Successfully exported your address book to the file '{0}'".format(file_name)
			except:
				print "*** Encountered an error while trying to export. Sorry..."
		else:
			print "Cancelling export."


	def do_options(self, line):
		"""
		Displays the available keyword commands and flags used by the applet.
		"""
		print OPTIONS_MESSAGE

	def do_quit(self, line):
		"""
		quit the applet
		"""
		confirm = raw_input("Are you sure you want to quit? Changes since your last save will be lost. ('quit' to quit; anything else will cancel): ")
		if confirm != 'quit': 
			return
		else:
			sys.exit()

	def default(self, line):
		"""
		Method called on an input line when the command prefix is not recognized.
		"""
		if line != "":
			print "*** Invalid command.  Type \"options\" to view available command options."

	def emptyline(self):
		"""
		Method called when an empty line is entered in response to the prompt.
		If this method is not overridden, it repeats the last nonempty command entered.
		"""
		pass
Exemplo n.º 13
0
	def __init__(self, parent):
		"""Initiates the window, with the appropriate grid layout, buttons,
			Canvas and scroll bar. All class-wide variables defined here."""
		Frame.__init__(self, parent, background="#ffffff")
		self.parent = parent
		
		#Temporary Variables - remember to reset!
		self.searchState = None #Currently displaying search results?
		self.tempvars = []	#Temporary values for add and editing fields
		self.tempID = -1	#TemporaryID number for contact
		self.tempFile = None	#Temporary File for import/export
		self.mL = 0		#Mailing label flag
		
		# Some formatting for the grid layout
		self.grid_rowconfigure(1, weight=1)
		self.grid_columnconfigure(0, weight=2)
		self.grid_columnconfigure(1, weight=0)
		self.grid_columnconfigure(2, weight=0)
		self.grid_columnconfigure(3, weight=0)
		self.grid_columnconfigure(4, weight=7)

		#Logo Column
		logo = PhotoImage(file="logo.gif")
		imgCan = Label(self, image=logo)
		imgCan.image = logo
		imgCan.grid(sticky = N+W, row = 0, column = 0, padx=0)	
		
		# Add Button
		img1 = PhotoImage(file="add.gif")
		addBtn = Button(self, image= img1, command = self.clickAdd)
		addBtn.image = img1
		addBtn.grid(sticky = N+W, row = 0, column = 1, ipadx=5, padx=3, ipady=5, pady=8)
		
		# Edit Button
		img2 = PhotoImage(file="edit.gif")
		editBtn = Button(self, image=img2, command = self.clickEdit)
		editBtn.image = img2
		editBtn.grid(sticky = N+W, row = 0, column = 2, ipadx=5, padx=3, ipady=5, pady=8)

		#Delete Button
		img3 = PhotoImage(file="delete.gif")
		delBtn = Button(self, image=img3, command = self.clickDelete)
		delBtn.image = img3
		delBtn.grid(sticky = N+W, row = 0, column = 3, ipadx=5, padx=3, ipady=5, pady=8)
		
		#Search Box Input
		self.searchBox = Entry(self, relief=SUNKEN, border=2, width=20)
		self.searchBox.grid(sticky = N+E, row = 0, column = 4, padx=2, pady=20)

		#Search Button
		searchBtn = Button(self, text="Search", command = self.clickSearch)
		searchBtn.grid(sticky = N+E, row = 0, column = 5, padx=0, pady=20)
		
		#Return to view the full book Button
		search2Btn = Button(self, text="View Full Book", command = self.update)
		search2Btn.grid(sticky = N+E, row = 0, column = 6, padx=0, pady=20)
		
		#Main addressbook!
		self.addressbook = AddressBook()

		#Used for initial testing
		"""for i in range (0, 5):
			new_contact = Contact()
			setattr(new_contact, 'lname', "Yablok" + str(i))
			self.addressbook.add(new_contact)"""
		
		#Canvas and scrollbar configuration
		self.canvas=Canvas(self, relief=SUNKEN, border=2, bg='#c6c6c6')
		self.vbar=Scrollbar(self, command=self.canvas.yview)
		self.vbar.config(command=self.canvas.yview)
		self.vbar.grid(sticky=NS, columnspan=8, row = 1, column = 8)
		self.canvas.config(width=980,height=700)
		self.canvas.config(yscrollcommand=self.vbar.set)
		self.canvas.grid(sticky=N+E+S+W, columnspan=7, row = 1, column = 0)

		self.fill_book(self.addressbook.contacts)
		self.initUI()
Exemplo n.º 14
0
 def setUp(self):
     self.address_book = AddressBook()
Exemplo n.º 15
0
class GUI(Frame):
	"""Main class which represents our parent window for the GUI."""
	
	def __init__(self, parent):
		"""Initiates the window, with the appropriate grid layout, buttons,
			Canvas and scroll bar. All class-wide variables defined here."""
		Frame.__init__(self, parent, background="#ffffff")
		self.parent = parent
		
		#Temporary Variables - remember to reset!
		self.searchState = None #Currently displaying search results?
		self.tempvars = []	#Temporary values for add and editing fields
		self.tempID = -1	#TemporaryID number for contact
		self.tempFile = None	#Temporary File for import/export
		self.mL = 0		#Mailing label flag
		
		# Some formatting for the grid layout
		self.grid_rowconfigure(1, weight=1)
		self.grid_columnconfigure(0, weight=2)
		self.grid_columnconfigure(1, weight=0)
		self.grid_columnconfigure(2, weight=0)
		self.grid_columnconfigure(3, weight=0)
		self.grid_columnconfigure(4, weight=7)

		#Logo Column
		logo = PhotoImage(file="logo.gif")
		imgCan = Label(self, image=logo)
		imgCan.image = logo
		imgCan.grid(sticky = N+W, row = 0, column = 0, padx=0)	
		
		# Add Button
		img1 = PhotoImage(file="add.gif")
		addBtn = Button(self, image= img1, command = self.clickAdd)
		addBtn.image = img1
		addBtn.grid(sticky = N+W, row = 0, column = 1, ipadx=5, padx=3, ipady=5, pady=8)
		
		# Edit Button
		img2 = PhotoImage(file="edit.gif")
		editBtn = Button(self, image=img2, command = self.clickEdit)
		editBtn.image = img2
		editBtn.grid(sticky = N+W, row = 0, column = 2, ipadx=5, padx=3, ipady=5, pady=8)

		#Delete Button
		img3 = PhotoImage(file="delete.gif")
		delBtn = Button(self, image=img3, command = self.clickDelete)
		delBtn.image = img3
		delBtn.grid(sticky = N+W, row = 0, column = 3, ipadx=5, padx=3, ipady=5, pady=8)
		
		#Search Box Input
		self.searchBox = Entry(self, relief=SUNKEN, border=2, width=20)
		self.searchBox.grid(sticky = N+E, row = 0, column = 4, padx=2, pady=20)

		#Search Button
		searchBtn = Button(self, text="Search", command = self.clickSearch)
		searchBtn.grid(sticky = N+E, row = 0, column = 5, padx=0, pady=20)
		
		#Return to view the full book Button
		search2Btn = Button(self, text="View Full Book", command = self.update)
		search2Btn.grid(sticky = N+E, row = 0, column = 6, padx=0, pady=20)
		
		#Main addressbook!
		self.addressbook = AddressBook()

		#Used for initial testing
		"""for i in range (0, 5):
			new_contact = Contact()
			setattr(new_contact, 'lname', "Yablok" + str(i))
			self.addressbook.add(new_contact)"""
		
		#Canvas and scrollbar configuration
		self.canvas=Canvas(self, relief=SUNKEN, border=2, bg='#c6c6c6')
		self.vbar=Scrollbar(self, command=self.canvas.yview)
		self.vbar.config(command=self.canvas.yview)
		self.vbar.grid(sticky=NS, columnspan=8, row = 1, column = 8)
		self.canvas.config(width=980,height=700)
		self.canvas.config(yscrollcommand=self.vbar.set)
		self.canvas.grid(sticky=N+E+S+W, columnspan=7, row = 1, column = 0)

		self.fill_book(self.addressbook.contacts)
		self.initUI()


	def initUI(self):
		"""Setup the window and display it.""" 
		self.parent.title("Blue Book")
		self.pack(fill=BOTH, expand=1)


	def get_tagged_box(self, tag):
		"""Search through Canvas objects by tags, return the rectangle with the given tag."""
		id, = self.canvas.find_withtag(tag)
		tags = self.canvas.gettags(tag)
		if 'text' in tags: #if the current item is text
			id = self.canvas.find_withtag(self.canvas.itemcget(id,'text'))
		return id;
 

	def boxClicked(self, event):
		"""Give the rectangle the 'select' tag when clicked, and the highlight properties
			(outline and white background."""
		id = self.get_tagged_box('current')
		tags = self.canvas.gettags(id)
		for t in tags:
			if (t == "select"): #The box is already selected, clicking should deselect
				self.canvas.dtag(id, 'select')
				self.canvas.itemconfigure(id, width=0, fill=BOX_COLOR)
				return
		for en in self.canvas.find_withtag("select"):
			if (en != id): #Cycle through and make sure only one is selected at a time.
				self.canvas.dtag(en, 'select')
				self.canvas.itemconfigure(en, width=0, fill=BOX_COLOR)
		#Select the current box.
		self.canvas.addtag('select', 'withtag', id)
		self.canvas.itemconfigure(id, width=2, outline="#58a4cd", fill=BOX_HIGHLIGHT)


	def hover(self, event):
		"""Binding for when the user hovers over a rectangle. Changes the cursor."""
		id = self.get_tagged_box('current')
		self.config(cursor="pointinghand")


	def no_hover(self,event):
		"""Binding for when the user stops hovering over a rectangle. Changes the cursor."""
		id = self.get_tagged_box('current')
		self.config(cursor="")


	def fill_book(self, subset):
		"""Fill the Canvas with the info from adresses from the subset provided.
			for each entry add a rectangle to the canvas, and the associated address text within
			the rectangle. Bind these boxes to the boxClicked() function."""
		SCROLLAREA_HEIGHT = (BOX_HEIGHT + ROW_PAD)*int(math.ceil(len(subset)/3.0)) + ROW_PAD
		self.canvas.config(scrollregion=(0,0,SCROLLAREA_WIDTH, SCROLLAREA_HEIGHT))
		
		if len(subset) == 0 and self.searchState is None:
			self.canvas.create_text(980/2, 700/2, anchor='c', tags='text', text="The addressbook is currently empty.", )
		elif len(subset) == 0:
			self.canvas.create_text(980/2, 700/2, anchor='c', tags='text', text="No existing entries match your search.", )
		else:
			idn = 0 #ID Number
			r = 0 #row count
			y = COLUMN_PAD
			
			for c in range(0, len(subset)):
				if (idn%3 == 0 and idn != 0): #If in a new row
					#Update row count, x, and y.
					r += 1
					y = COLUMN_PAD+r*(BOX_HEIGHT+COLUMN_PAD)
					x = ROW_PAD
				else :
					x = ROW_PAD+((c%3)*(BOX_WIDTH+ROW_PAD))
					y = COLUMN_PAD+r*(BOX_HEIGHT+COLUMN_PAD)
				
				#If the index number exists in the addressbook
				if (idn < self.addressbook.total):
					#Create rectangle
					id = self.canvas.create_rectangle(x, y, x+BOX_WIDTH, y+BOX_HEIGHT, fill=BOX_COLOR, width=0, tags=('box', idn)) 
					con = ""
					#Generate Text
					for field in CONTACT_FIELDS:
						#Check for subset
						if (self.searchState is None): #default
							entry = self.addressbook.contacts[idn]
						else: #Data has been searched, get from tuple
							entry = subset[idn][1]
							
						if (getattr(entry, field[0], '') != ""):
							con += field[1] + ": " + str(getattr(entry, field[0], '') + "\n")
					#Check for Mailing Label Display
					if (self.mL):
						self.canvas.create_text(x+20, y+20, anchor='nw', text=entry.print_mailing(), tags='text', width=TEXT_WIDTH)
					else:
						self.canvas.create_text(x+20, y+20, anchor='nw', text=con, tags='text', width=TEXT_WIDTH)
				idn+= 1 #Increment ID Number
        	self.canvas.tag_bind('all', '<1>', self.boxClicked) #Check when box is clicked
        	self.canvas.tag_bind('all', '<Any-Enter>', self.hover) #Check when box is hovered over
        	self.canvas.tag_bind('all', '<Any-Leave>', self.no_hover) #Check when box is not hovered over


	def update(self):
		"""Update the canvas once a change has been made to the addressbook,
			to display changes in the addressbook we delete all entries and and
			re-fill the canvas via the fill_book() function."""
		self.searchState = None #reset searchState
		self.searchBox.delete(0, 10000)
		self.canvas.delete("all")
		self.fill_book(self.addressbook.contacts)


	def updateSearchState(self):
		"""Special update function which uses a subset of the full address
			book - the self.searchState which is the current search results."""
		self.canvas.delete("all")
		self.fill_book(self.searchState)
	

	def sort(self, att):
		"""Sort the addresses by last name. This search function only works
			on the full addressbook, not a subset, sort before searching."""
		#If we are not viewing search results, sort entire book
		if (self.addressbook.total == 0):
			return
		attrs = []
		attrs.append(att)
		attrs.extend(['lname', 'fname'])
		self.addressbook.sort(attributes=attrs)
		self.update()


	def clickSearch(self):
		"""General search for all of the fields and all of the contacts in the
			address book. It will look for exact matches in fields. For example search
			will accurately find '123 Easy St' but not just 'Easy St'. (Needs full search
			field."""
		results = []
		val = self.searchBox.get()
		if val == "":
			return
		for field in (CONTACT_FIELDS):
			results += self.addressbook.search(field[0], val)
		self.searchState = results
		self.updateSearchState()


	def clickAdd(self):
		"""Add an entry to the address book. Creates a new top level window with inputs, and refers
			to the addEntry function to add the new contact object."""
		self.tempvars = []
		self.searchState = None
		toplevel = Toplevel()
		toplevel.title("Add an Entry")
		count = 1
		tex = Label(toplevel, text="Please enter your new contact information in the inputs below.")
		tex.grid(row=0, column=0, columnspan=4, sticky=W+E+N+S, padx=10, pady=10)
		for label in (CONTACT_FIELDS):
			va = StringVar()
			l = Label(toplevel, text=label[1])
			l.grid(row=count,column=0, columnspan=1, sticky=W, padx=10, pady=3)
			e = Entry(toplevel, relief=SUNKEN, border=2, width=40, textvariable=va)
			e.grid(row=count,column=1, columnspan=3, sticky=W, padx=10, pady=3)
			self.tempvars.append(e)
			count += 1
		ok = Button(toplevel, text="Submit", command= lambda: self.addEntry(toplevel))
		can = Button(toplevel, text="Cancel", command=toplevel.destroy)
		can.grid(row=count,column=2, sticky=W, padx=0, pady=10)
		ok.grid(row=count,column=1, sticky=W, padx=0, pady=10)
		

	def addEntry(self, top):
		"""Get all of the fields entered by the user in the toplevel window
			Add the new contact object to the address book and update the canvas."""
		new_contact = Contact()
		count = 0
		go = 1
		for field in CONTACT_FIELDS:
			valid = FIELD_VALIDATORS[field[0]]
			if field[0] in REQUIRED_FIELDS:
				data = self.tempvars[count].get()
				if data == "":
					tkMessageBox.showinfo("Required Field Error", field[1] + " is a required field, please enter this info into the input box.")
					go = 0
					break
				if(go): setattr(new_contact, field[0], data)
			else:
				data = self.tempvars[count].get()
				if data != "" and not valid(data)[0]:
					tkMessageBox.showinfo("Input Error", valid(data)[1])
					go = 0
					break
				if(go): setattr(new_contact, field[0], data)
			count += 1
		if(go):
			self.addressbook.add(new_contact)
			self.update()
			top.destroy()		


	def clickEdit(self):
		"""Edit an existing entry in the address book. Creates a new top level window with
			inputs which automatically gets the existing fields from the contact selected by the user.
			It refers to the editEntry() function to make the edits in to the actual contact in the addressbook."""
		self.tempvars = [] #Temp values to get from the entry boxes
		self.tempID = -1 #Temp ID of the Contact being edited
		
		#ERROR: no contact selected by the user
		if (len(self.canvas.find_withtag('select')) == 0 or self.addressbook.total == 0):
			tkMessageBox.showinfo("Error: No Selection", "Please select an address to edit by clicking on its surrounding box. Selected addresses will have a blue outline.")
			return

		toplevel = Toplevel()
		toplevel.title("Edit an Entry")
		
		#Get the global ID of the contact based on
		#based on what is selected.
		id = self.get_tagged_box('select')
		tags=self.canvas.gettags(id)
		for t in tags:
			if t not in ('current','box', 'select'):
				box_name=t
		try:
			i = int(box_name)
		except ValueError:
			tkMessageBox.showinfo("Input error", "The ID of the contact is invalid, please delete and re-add this contact.")
			return
		self.tempID = i; #global ID
		
		#Layout configuration for the new toplevel window
		count = 1
		tex = Label(toplevel, text="Please edit the contact information in the inputs below.")
		tex.grid(row=0, column=0, columnspan=4, sticky=W+E+N+S, padx=10, pady=10)
		for label in (CONTACT_FIELDS): #Get all of the fields
			va = StringVar()
			l = Label(toplevel, text=label[1])
			l.grid(row=count,column=0, columnspan=1, sticky=W, padx=10, pady=3)
			
			#Special case for if searchState is activated.
			if (self.searchState is None):
				s = str(getattr(self.addressbook.contacts[i], label[0], ''))
			else:
				s = str(getattr(self.searchState[i][1], label[0], ''))
			
			va.set(s)
			e = Entry(toplevel, relief=SUNKEN, border=2, width=40, text=s, textvariable=va)
			e.grid(row=count,column=1, columnspan=3, sticky=W, padx=10, pady=3)
			self.tempvars.append(e) # add the values so we can .get() them later
			count += 1
		ok = Button(toplevel, text="Submit", command=lambda: self.editEntry(toplevel))
		can = Button(toplevel, text="Cancel", command=toplevel.destroy)
		can.grid(row=count,column=2, sticky=W, padx=0, pady=10)
		ok.grid(row=count,column=1, sticky=W, padx=0, pady=10)	


	def editEntry(self, top):
		"""Edit the entry id in self.tempID. Update all of the fields, and update the
			Canvas to reflect these changes."""
		if (self.tempID >= 0):
		
			#special case for searchState subset 
			if (self.searchState is None):
				en = self.addressbook.contacts[self.tempID]
			else:
				en = self.searchState[self.tempID][1]
			
			count = 0
			go = 1
			for field in CONTACT_FIELDS:
				valid = FIELD_VALIDATORS[field[0]]
				if field[0] in REQUIRED_FIELDS:
					data = self.tempvars[count].get()
					if data == "":
						tkMessageBox.showinfo("Required Field Error", field[1] + " is a required field, please enter this info into the input box.")
						go = 0
						break
					if(go): setattr(en, field[0], data)
				else:
					data = self.tempvars[count].get()
					if data != "" and not valid(data)[0]:
						tkMessageBox.showinfo("Input Error", valid(data)[1])
						go = 0
						break
					if(go): setattr(en, field[0], data)
				count += 1
			if (go):
				if (self.searchState is None):
					self.update()
				else:
					self.updateSearchState()
				top.destroy()
			
		else: 
			tkMessageBox.showinfo("Input error", "The ID of the contact is invalid, please delete and re-add this contact")
			return
	

	def clickDelete(self):
		"""Delete a contact from the address book, prompt a confirmation box which
			reviews the contact information, and proceeds to delete the entry from
			the addressbook, and update the Canvas"""
		self.tempvars = [] #Temp values to get from the entry boxes
		self.tempID = -1 #Temp ID of the Contact being edited

		#ERROR: no contact selected by the user
		if (len(self.canvas.find_withtag('select')) == 0 or self.addressbook.total == 0):
			tkMessageBox.showinfo("Error: No Selection", "Please select an address to delete by clicking on its surrounding box. Selected addresses will have a blue outline.")
			return
		
		#Get the global id of the selected contacts
		#through the tags options
		id = self.get_tagged_box('select')
		tags = self.canvas.gettags(id)
		for t in tags:
			if t not in ('current','box', 'select'):
				box_name=t
		try:
			i = int(box_name)
		except ValueError:
			tkMessageBox.showinfo("Input error", "Something was invalid")
			return
		self.tempID = i; #Gloabl ID

		con = ""
		for field in CONTACT_FIELDS:
			#Special case for  searchState subset
			if (self.searchState is None):
				con += field[1] + ": " + getattr(self.addressbook.contacts[i], field[0], '') + "\n"
			else:
				con += field[1] + ": " + str(getattr(self.searchState[i][1], field[0], '')) + "\n"
		#Confirmation box
		if tkMessageBox.askyesno("Delete an Entry", "Are you sure you want to delete this entry?\n" + con):
			if (self.searchState is None):
				self.addressbook.delete(self.tempID)
			else:
				self.addressbook.delete(self.searchState[self.tempID][0])
				self.searchState.pop(self.tempID)
			
			#Update the Canvas
			if (self.searchState is None):
				self.update()
			else:
				self.updateSearchState()


	def mailLabels(self):
		"""View the contact information in a mailing label format.
			Update the canvas to display new format"""
		self.mL = 1
		if (self.searchState is None):
			self.update()
		else:
			self.updateSearchState()


	def noMailLabels(self):
		"""View the contact information in the regular format.
			Update the canvas to display new format"""
		self.mL = 0
		if (self.searchState is None):
			self.update()
		else:
			self.updateSearchState()


	def new(self):
		"""Create a new blank address book, ask to save before creating new book.
			Update the Canvas with the new book."""
		self.tempFile = None
		if tkMessageBox.askyesno("New Address Book", "Do you want to save your current file first?"):
			self.save()
		self.addressbook.contacts = []
		self.addressbook.total = 0
		self.update()
	

	def open(self):
		"""Open a new address book and prompt the user to save changes."""
		if self.addressbook.contacts != []: 
			if tkMessageBox.askyesno("Open Address Book", "Do you want to save your current file first?"):
				self.save()
		dlg = tkFileDialog.Open(self)
		fl = dlg.show()

		if fl != '':
			self.addressbook = utils.open_addressbook(fl)
			self.tempFile = fl
			self.update()


	def close(self):
		"""Close an address book and prompt the user to save changes. If no address book is open,
		quit the program"""
		if self.addressbook.contacts == []: 
			root.quit()
			return
		if tkMessageBox.askyesno("Close Address Book", "Do you want to save your current file first?"):
			self.save()
		self.tempFile = None
		self.addressbook.contacts = []
		self.addressbook.total = 0
		self.update()


	def imp(self):
		"""Import a new address from a .tsv file. Prompt the user to select a file,
			update the Canvas with the imported addressbook"""	
		ftypes = [('TSV files', '*.tsv'), ('All files', '*')]
		dlg = tkFileDialog.Open(self, filetypes = ftypes)
		fl = dlg.show()
		if fl != '':
			self.addressbook.import_contacts(fl)
			if tkMessageBox.askyesno("Import Addresses", 
				"Do you want to merge addresses with the same first and last name?"):
				self.addressbook.merge_addressbook()
			self.update()
	

	def export(self):
		"""Export the current address book to a .tsv file. Prompt the user to select a file,
		update the Canvas with the imported addressbook"""
		self.tempFile = None
		f = tkFileDialog.asksaveasfile(mode='w', defaultextension=".tsv")
		if f is None:
			return
		self.tempFile = f.name
		self.addressbook.export_contacts(f.name)


	def save(self):
		"""Save an address book to the disk."""
		if (self.tempFile is None):
		    f = tkFileDialog.asksaveasfile()
		    if f != None and self.addressbook != None:
		    	utils.save_addressbook(self.addressbook, f.name)
		    	self.tempFile = f.name
		else:
			utils.save_addressbook(self.addressbook, self.tempFile)


	def save_as(self):
		"""Save an address book to the disk prompting for a file name."""
		f = tkFileDialog.asksaveasfile()
		if f != None and self.addressbook != None:
		    utils.save_addressbook(self.addressbook, f.name)


	def quit(self):
		"""Quit the program but make sure to save changes first."""
		self.close()
		root.quit()
Exemplo n.º 16
0
# -*- coding: utf-8 -*-

# Copyright (C) 2013 Sylvain Boily <*****@*****.**>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from flask import Blueprint
from addressbook import AddressBook

bp_addressbook = Blueprint('addressbook',
                           __name__,
                           template_folder='templates/addressbook',
                           static_folder='static',
                           static_url_path='/%s' % __name__)

addressbook = AddressBook()
Exemplo n.º 17
0
 def setUp(self):
     self.book = AddressBook()
Exemplo n.º 18
0
class TestAddressBookSearchByName(TestCase):
    def setUp(self):
        self.book = AddressBook()
        self.book.create_person(first_name="Test", last_name="Dog")
        self.book.create_person(first_name="Mike", last_name="Dog")

    def test_find_person_by_first_name(self):
        person = self.book.create_person(first_name="Test", last_name="Man")
        result = self.book.person_by_name(first_name="Test")
        assert len(result) == 2
        assert person in result

    def test_find_person_by_last_name(self):
        person = self.book.create_person(first_name="Test", last_name="Man")
        result = self.book.person_by_name(last_name="Man")
        assert len(result) == 1
        assert person in result

    def test_find_person_by_both(self):
        person = self.book.create_person(first_name="Test", last_name="Man")
        result = self.book.person_by_name(first_name="Test", last_name="Man")
        assert len(result) == 1
        assert person in result

    def test_find_person_no_result(self):
        self.book.create_person(first_name="Test", last_name="Man")
        result = self.book.person_by_name(first_name="George", last_name="Man")
        assert len(result) == 0

    def test_find_person_wrong_parameters(self):
        with pytest.raises(AssertionError):
            self.book.person_by_name(first_name=None, last_name=None)
Exemplo n.º 19
0
 def setUp(self):
     self.book = AddressBook()
     self.book.create_person(first_name="Test", last_name="Dog")
     self.book.create_person(first_name="Mike", last_name="Dog")