From 0f1c23a15bd43fec53d3359cfce5bca9c00c89a4 Mon Sep 17 00:00:00 2001 From: Cameron Brandon White Date: Mon, 17 Feb 2014 03:58:55 -0800 Subject: [PATCH 1/4] Redisgned `modules/acmbot.py` decoupled code A lot of functionality has been moved out of the AcmBotModule class. * The loading of `events.yaml` is now done with the `load_yaml` function. * There are now filter functions which are responsible for sorting and selecting which events are wanted. There filters are built opon the select_events and sort_events functions * `select_events` * `sort_events` * `filter_take_date_range` * `filter_take_date` * There are now command functions which implement the verious things the acmbot can do. * `command_date` * `command_today` * `command_tomorrow` * `command_next` * `command_events` * `command_day` * utility functions have been added * `weekday_difference` The AcmBotModule is now responsible for responding to irc events, loading configuration, calling global function above, constructing messages, and responding to the irc event. --- modules/acmbot.py | 314 ++++++++++++++++++++++++++-------------------- 1 file changed, 178 insertions(+), 136 deletions(-) diff --git a/modules/acmbot.py b/modules/acmbot.py index 7ac034e..6a773da 100644 --- a/modules/acmbot.py +++ b/modules/acmbot.py @@ -1,6 +1,6 @@ #!/usr/bin/env python2 # -*- coding: utf-8 -*- -# Copyright (C) 2013, Cameron White +# Copyright (C) 2014, Cameron White import logging import argparse @@ -10,7 +10,8 @@ import yaml import datetime import urllib -from itertools import takewhile +from contextlib import closing +from itertools import takewhile, dropwhile _log = logging.getLogger(__name__) @@ -44,7 +45,7 @@ def messages(self, client, actor, recipient, message): self.recipient = recipient self.message = message - config = self.controller.config + self.read_config() # Only pay attention if addressed directly in channels try: @@ -57,119 +58,37 @@ def messages(self, client, actor, recipient, message): # http://docs.python.org/2/library/logging.html _log.info("Responding to %r in %r", self.actor, self.recipient) - messages = [] - if self.args.command == "!events": if self.args.help: messages = command_events.format_help().split('\n') else: - def sort(events): - events = sorted(events, key=lambda x: x['date'], reverse=True) - events = list(enumerate(takewhile( - lambda x: x['date'] >= datetime.date.today(), - events, - ))) - return events - messages = self.get_event_messages(sort) + messages = self.do_command(command_events) elif self.args.command == '!today': if self.args.help: - messages = command_events.format_help().split('\n') + messages = command_today.format_help().split('\n') else: - def today_sort(events): - events = sorted(events, key=lambda x: x['date'], reverse=True) - events = list(enumerate(takewhile( - lambda x: x['date'] >= datetime.date.today(), - events, - ))) - events = filter( - lambda (i, event): event['date'] == datetime.date.today(), - events - ) - return events - messages = self.get_event_messages(today_sort) + messages = self.do_command(command_today) elif self.args.command == '!tomorrow': if self.args.help: - messages = command_events.format_help().split('\n') + messages = command_tomorrow.format_help().split('\n') else: - def tomorrow_sort(events): - events = sorted(events, key=lambda x: x['date'], reverse=True) - events = list(enumerate(takewhile( - lambda x: x['date'] >= datetime.date.today() + datetime.timedelta(days=1), - events, - ))) - events = filter( - lambda (i, event): event['date'] == datetime.date.today() + datetime.timedelta(days=1), - events - ) - return events - messages = self.get_event_messages(tomorrow_sort) + messages = self.do_command(command_tomorrow) elif self.args.command == '!next': if self.args.help: - messages = command_events.format_help().split('\n') + messages = command_next.format_help().split('\n') else: - def tomorrow_sort(events): - events = sorted(events, key=lambda x: x['date'], reverse=True) - events = list(enumerate(takewhile( - lambda x: x['date'] >= datetime.date.today(), - events, - ))) - return [ events[-1] ] - messages = self.get_event_messages(tomorrow_sort) + messages = self.do_command(command_next) elif self.args.command == '!day': if self.args.help: - messages = command_events.format_help().split('\n') + messages = command_day.format_help().split('\n') elif self.args.day: - # The date to filter by will be constructed. - - today = datetime.date.today() - - # Get the int encoding of the day of the week. - # Monday = 0 ... Sunday = 6 - today_weekday = today.weekday() - - - wanted_weekday = [ - 'monday', 'tuesday', 'wednesday', 'thursday', - 'friday', 'saturday', 'sunday', - ].index(self.args.day[0].lower()) - - if wanted_weekday >= today_weekday: - # If today is Wednesday and Wednesday is wanted then - # the day should not be changed. - # Wednesday - Wednesday = 2 - 2 = 0 - # If today is Tuesday and Friday is wanted then - # the day should be increased by 3 - # Friday - Tuesday = 4 - 1 = 3 - days = wanted_weekday - today_weekday - else: - # If today is Friday and Monday is wanted then the - # day should be increased by 3. - # 7 - Friday + Monday = 7 - 4 + 0 = 3 - # If today is Thursday and Tuesday is wanted then the - # day should be increased by 5. - # 7 - Thursday + Tuesday = 7 - 3 + 1 = 5 - days = 7 - today_weekday + wanted_weekday - - # Construct the date by adding the calculated number of - # days. - date = today + datetime.timedelta(days=days) - - def day_sort(events): - events = sorted(events, key=lambda x: x['date'], reverse=True) - events = list(enumerate(takewhile( - lambda x: x['date'] >= date, - events, - ))) - events = filter( - lambda (i, event): event['date'] == date, - events - ) - return events - messages = self.get_event_messages(day_sort) + messages = self.do_command( + lambda events: command_day(events, self.args.day), + ) elif self.args.command == "!help": messages = parser.format_help().split('\n') @@ -180,20 +99,16 @@ def day_sort(events): # Stop any other modules from handling this message. return True + + def do_command(self, command): - def get_event_messages(self, func=None): - config = self.controller.config + events = self.get_events() - if not config.has_section("acmbot"): - _log.info("No config section for acmbot") - return + events = command(events) - if config.has_option("acmbot", "base_url"): - base_url = config.get("acmbot", "base_url") - else: - return + config = self.controller.config - if getattr(self.args, 'limit', None): + if hasattr(self.args, 'limit'): events_limit = self.args.limit elif config.has_option("acmbot", "events_limit"): try: @@ -203,44 +118,171 @@ def get_event_messages(self, func=None): else: events_limit = None - events_html = urllib.urlopen( - '{}/files/events.yaml'.format(base_url) - ).read() - - events = yaml.load(events_html) - length_events = len(events) - - if func: - events = func(events) - if events_limit and events_limit >= 0 and len(events) >= events_limit: events = events[len(events)-events_limit:] - - messages = [] + for i, event in reversed(events): - - if 'time' in event: - time = get_time(event['time']) - elif config.has_option("acmbot", "default_time"): - time = get_time(config.get("acmbot", "default_time")) - else: - time = None + yield self.construct_message(i, event) + + def construct_message(self, event_id, event): + + if 'time' in event: + time = get_time(event['time']) + else: + time = None + + message = '{} - {:%a, %b %d}'.format( + event['title'], event['date'], + ) + + if time: + message += ' @ {:%I:%M%p}'.format(time) + + message += ' - {}/event.php?event={}'.format( + self.base_url, str(self.number_of_events - event_id - 1), + ) + + return message + + + def get_events(self): + events = load_yaml( + '{}/{}'.format(self.base_url, self.events_yaml_url) + ) + self.number_of_events = len(events) + return events + + def read_config(self): + config = self.controller.config - message = '{} - {:%a, %b %d}'.format( - event['title'], event['date'], - ) + if not config.has_section("acmbot"): + _log.error("config has no `acmbot` section") + return + + if config.has_option("acmbot", "base_url"): + self.base_url = config.get("acmbot", "base_url") + else: + _log.error("config `acmbot` section has no `base_url` option") + return + + if config.has_option("acmbot", "events_yaml_url"): + self.events_yaml_url = config.get("acmbot", "events_yaml_url") + else: + _log.error("config `acmbot` section has no `events_yaml_url") + return + + +def load_yaml(url): + with closing(urllib.urlopen(url)) as yaml_raw: + return yaml.load(yaml_raw.read()) + +def select_events(events, filter_function): + # Sort events from newest to oldest. + # Attach an id to each event [(id, event)]. + events = enumerate(sort_events(events)) + # Apply filtering function + events = filter_function(events) + return list(events) + +def sort_events(events): + """ Sort events from newest to oldest """ + return sorted(events, key=lambda x: x['date'], reverse=True) + +def filter_take_date_range(events, start_date, end_date): + """ Events filter which takes events which dates in the range + from start_date to end_date inclusively. start_date >= end_date. + events must be a list of the form [(id, event)]. """ + + if start_date: + events = dropwhile( + lambda x: x[1]['date'] > start_date, + events + ) + + if end_date: + events = takewhile( + lambda x: x[1]['date'] >= end_date, + events + ) + + return events - if time: - message += ' @ {:%I:%M%p}'.format(time) +def filter_take_date(events, date): + return filter_take_date_range(events, date, date) - message += ' - {}/event.php?event={}'.format( - base_url, str(length_events - i - 1), - ) +def command_date(events, date): + return select_events( + events, + lambda x: filter_take_date(x, date) + ) - messages.append(message) - return messages +def command_today(events): + date = datetime.date.today() + return command_date(events, date) + +def command_tomorrow(events): + date = datetime.date.today() + datetime.timedelta(days=1) + return command_date(events, date) + +def command_day(events, weekday): + # The date to filter by will be constructed. + + today = datetime.date.today() + + # Get the int encoding of the day of the week. + # Monday = 0 ... Sunday = 6 + today_weekday = today.weekday() + + days = weekday_difference(today_weekday, weekday[0]) + + # Construct the date by adding the calculated number of + # days. + date = today + datetime.timedelta(days=days) + return command_date(events, date) + +def command_events(events): + date = datetime.date.today() + return select_events( + events, + lambda events: filter_take_date_range(events, None, date) + ) + +def command_next(events): + return command_events(events)[-1:] + +def weekday_difference(from_weekday, to_weekday): + + def get_weekday_index(weekday): + if weekday not in range(7): + weekday = [ + 'monday', 'tuesday', 'wednesday', 'thursday', + 'friday', 'saturday', 'sunday', + ].index(weekday.lower()) + return weekday + + from_weekday = get_weekday_index(from_weekday) + to_weekday = get_weekday_index(to_weekday) + + if to_weekday >= from_weekday: + # If from is Wednesday and Wednesday is to then + # the day should not be changed. + # Wednesday - Wednesday = 2 - 2 = 0 + # If from is Tuesday and Friday is to then + # the day should be increased by 3 + # Friday - Tuesday = 4 - 1 = 3 + days = to_weekday - from_weekday + else: + # If from is Friday and Monday is to then the + # day should be increased by 3. + # 7 - Friday + Monday = 7 - 4 + 0 = 3 + # If from is Thursday and Tuesday is to then the + # day should be increased by 5. + # 7 - Thursday + Tuesday = 7 - 3 + 1 = 5 + days = 7 - from_weekday + to_weekday + + return days def get_time(time_str): return datetime.datetime.strptime(time_str, '%H:%M').time() - + module = AcmBotModule From e97f50b2ec23a790e0d03be8a344513598ebc164 Mon Sep 17 00:00:00 2001 From: Cameron Brandon White Date: Mon, 17 Feb 2014 04:02:28 -0800 Subject: [PATCH 2/4] (gh-22) Added unittesting --- setup.py | 1 + tests/events0.yaml | 28 ++++ tests/test_acmbot.py | 344 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 373 insertions(+) create mode 100644 tests/events0.yaml create mode 100644 tests/test_acmbot.py diff --git a/setup.py b/setup.py index 7af3a03..43b0830 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ 'kitnirc', 'BotParse', 'pyyaml', + 'nose', ], include_package_data=True, ) diff --git a/tests/events0.yaml b/tests/events0.yaml new file mode 100644 index 0000000..5dfe123 --- /dev/null +++ b/tests/events0.yaml @@ -0,0 +1,28 @@ +--- +- title: "Title 0" + date: 2014-03-14 + time: '16:30' + speaker: Cameron White + description: | + "Description 0" + +- title: "Title 1" + date: 2014-03-13 + time: '17:31' + speaker: Adam Curry + description: | + "Description 1" + +- title: "Title 2" + date: 2014-02-21 + time: '15:12' + speaker: John C. Dvorak + description: | + "Description 2" + +- title: "Title 3" + date: 2014-01-14 + time: '02:44' + speaker: Bart Massey + description: | + "Description 3" diff --git a/tests/test_acmbot.py b/tests/test_acmbot.py new file mode 100644 index 0000000..785f82d --- /dev/null +++ b/tests/test_acmbot.py @@ -0,0 +1,344 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +# Copyright © 2014 Cameron Brandon White + +import unittest +import datetime +import yaml +from modules.acmbot import * + +class TestAcmBot(unittest.TestCase): + + + def setUp(self): + with open('./tests/events0.yaml') as f: + self.events = yaml.load(f.read()) + + def test_load_yaml(self): + """ Makes sure that load_yaml will at least run """ + load_yaml( + 'http://acm.pdx.edu/files/events.yaml' + ) + + def test_events0_entrys(self): + self.assertEqual(len(self.events), 4) + event = self.events[0] + self.assertEqual(event['title'], "Title 0") + self.assertEqual(event['date'], datetime.date(2014, 3, 14)) + self.assertEqual(event['time'], '16:30') + self.assertEqual(event['speaker'], 'Cameron White') + self.assertEqual(event['description'], '"Description 0"\n') + event = self.events[1] + self.assertEqual(event['title'], "Title 1") + self.assertEqual(event['date'], datetime.date(2014, 3, 13)) + self.assertEqual(event['time'], '17:31') + self.assertEqual(event['speaker'], 'Adam Curry') + self.assertEqual(event['description'], '"Description 1"\n') + event = self.events[2] + self.assertEqual(event['title'], "Title 2") + self.assertEqual(event['date'], datetime.date(2014, 2, 21)) + self.assertEqual(event['time'], '15:12') + self.assertEqual(event['speaker'], 'John C. Dvorak') + self.assertEqual(event['description'], '"Description 2"\n') + event = self.events[3] + self.assertEqual(event['title'], "Title 3") + self.assertEqual(event['date'], datetime.date(2014, 1, 14)) + self.assertEqual(event['time'], '02:44') + self.assertEqual(event['speaker'], 'Bart Massey') + self.assertEqual(event['description'], '"Description 3"\n') + + def test_events0_filter_take_date_0(self): + # 2014-3-14 + date = datetime.date(2014, 3, 14) + events = select_events( + self.events, + lambda x: filter_take_date(x, date) + ) + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(event[1]['title'], "Title 0") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 14)) + self.assertEqual(event[1]['time'], '16:30') + self.assertEqual(event[1]['speaker'], 'Cameron White') + self.assertEqual(event[1]['description'], '"Description 0"\n') + + def test_events0_filter_take_date_1(self): + # 2014-3-14 + date = datetime.date(2014, 3, 13) + events = select_events( + self.events, + lambda x: filter_take_date(x, date) + ) + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(event[1]['title'], "Title 1") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 13)) + self.assertEqual(event[1]['time'], '17:31') + self.assertEqual(event[1]['speaker'], 'Adam Curry') + self.assertEqual(event[1]['description'], '"Description 1"\n') + + def test_events0_filter_take_date_2(self): + # 2014-3-14 + date = datetime.date(2014, 2, 21) + events = select_events( + self.events, + lambda x: filter_take_date(x, date) + ) + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(event[1]['title'], "Title 2") + self.assertEqual(event[1]['date'], datetime.date(2014, 2, 21)) + self.assertEqual(event[1]['time'], '15:12') + self.assertEqual(event[1]['speaker'], 'John C. Dvorak') + self.assertEqual(event[1]['description'], '"Description 2"\n') + + def test_events0_filter_take_date_3(self): + # 2014-3-14 + date = datetime.date(2014, 1, 14) + events = select_events( + self.events, + lambda x: filter_take_date(x, date) + ) + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(event[1]['title'], "Title 3") + self.assertEqual(event[1]['date'], datetime.date(2014, 1, 14)) + self.assertEqual(event[1]['time'], '02:44') + self.assertEqual(event[1]['speaker'], 'Bart Massey') + self.assertEqual(event[1]['description'], '"Description 3"\n') + + def test_events0_command_date_0(self): + # 2014-3-14 + events = command_date(self.events, datetime.date(2014, 3, 14)) + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(event[1]['title'], "Title 0") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 14)) + self.assertEqual(event[1]['time'], '16:30') + self.assertEqual(event[1]['speaker'], 'Cameron White') + self.assertEqual(event[1]['description'], '"Description 0"\n') + + def test_events0_command_date_1(self): + # 2014-3-13 + events = command_date(self.events, datetime.date(2014, 3, 13)) + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(event[1]['title'], "Title 1") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 13)) + self.assertEqual(event[1]['time'], '17:31') + self.assertEqual(event[1]['speaker'], 'Adam Curry') + self.assertEqual(event[1]['description'], '"Description 1"\n') + + def test_events0_command_date_2(self): + # 2014-2-21 + events = command_date(self.events, datetime.date(2014, 2, 21)) + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(event[1]['title'], "Title 2") + self.assertEqual(event[1]['date'], datetime.date(2014, 2, 21)) + self.assertEqual(event[1]['time'], '15:12') + self.assertEqual(event[1]['speaker'], 'John C. Dvorak') + self.assertEqual(event[1]['description'], '"Description 2"\n') + + def test_events0_command_date_3(self): + # 2014-1-14 + events = command_date(self.events, datetime.date(2014, 1, 14)) + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(event[1]['title'], "Title 3") + self.assertEqual(event[1]['date'], datetime.date(2014, 1, 14)) + self.assertEqual(event[1]['time'], '02:44') + self.assertEqual(event[1]['speaker'], 'Bart Massey') + self.assertEqual(event[1]['description'], '"Description 3"\n') + + def test_events0_filter_take_date_range_0(self): + """ Everything after 2014-1-1 """ + date = datetime.date(2014,1,1) + events = select_events( + self.events, + lambda x: filter_take_date_range(x, None, date) + ) + self.assertEqual(len(events), 4) + event = events[0] + self.assertEqual(event[1]['title'], "Title 0") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 14)) + self.assertEqual(event[1]['time'], '16:30') + self.assertEqual(event[1]['speaker'], 'Cameron White') + self.assertEqual(event[1]['description'], '"Description 0"\n') + event = events[1] + self.assertEqual(event[1]['title'], "Title 1") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 13)) + self.assertEqual(event[1]['time'], '17:31') + self.assertEqual(event[1]['speaker'], 'Adam Curry') + self.assertEqual(event[1]['description'], '"Description 1"\n') + event = events[2] + self.assertEqual(event[1]['title'], "Title 2") + self.assertEqual(event[1]['date'], datetime.date(2014, 2, 21)) + self.assertEqual(event[1]['time'], '15:12') + self.assertEqual(event[1]['speaker'], 'John C. Dvorak') + self.assertEqual(event[1]['description'], '"Description 2"\n') + event = events[3] + self.assertEqual(event[1]['title'], "Title 3") + self.assertEqual(event[1]['date'], datetime.date(2014, 1, 14)) + self.assertEqual(event[1]['time'], '02:44') + self.assertEqual(event[1]['speaker'], 'Bart Massey') + self.assertEqual(event[1]['description'], '"Description 3"\n') + + def test_events0_filter_take_date_range_1(self): + """ Everything after 2014-1-14 """ + date = datetime.date(2014,1,14) + events = select_events( + self.events, + lambda x: filter_take_date_range(x, None, date) + ) + self.assertEqual(len(events), 4) + event = events[0] + self.assertEqual(event[1]['title'], "Title 0") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 14)) + self.assertEqual(event[1]['time'], '16:30') + self.assertEqual(event[1]['speaker'], 'Cameron White') + self.assertEqual(event[1]['description'], '"Description 0"\n') + event = events[1] + self.assertEqual(event[1]['title'], "Title 1") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 13)) + self.assertEqual(event[1]['time'], '17:31') + self.assertEqual(event[1]['speaker'], 'Adam Curry') + self.assertEqual(event[1]['description'], '"Description 1"\n') + event = events[2] + self.assertEqual(event[1]['title'], "Title 2") + self.assertEqual(event[1]['date'], datetime.date(2014, 2, 21)) + self.assertEqual(event[1]['time'], '15:12') + self.assertEqual(event[1]['speaker'], 'John C. Dvorak') + self.assertEqual(event[1]['description'], '"Description 2"\n') + event = events[3] + self.assertEqual(event[1]['title'], "Title 3") + self.assertEqual(event[1]['date'], datetime.date(2014, 1, 14)) + self.assertEqual(event[1]['time'], '02:44') + self.assertEqual(event[1]['speaker'], 'Bart Massey') + self.assertEqual(event[1]['description'], '"Description 3"\n') + + def test_events0_filter_take_date_range_2(self): + """ Everything after 2014-1-14 """ + date = datetime.date(2014,1,15) + events = select_events( + self.events, + lambda x: filter_take_date_range(x, None, date) + ) + self.assertEqual(len(events), 3) + event = events[0] + self.assertEqual(event[1]['title'], "Title 0") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 14)) + self.assertEqual(event[1]['time'], '16:30') + self.assertEqual(event[1]['speaker'], 'Cameron White') + self.assertEqual(event[1]['description'], '"Description 0"\n') + event = events[1] + self.assertEqual(event[1]['title'], "Title 1") + self.assertEqual(event[1]['date'], datetime.date(2014, 3, 13)) + self.assertEqual(event[1]['time'], '17:31') + self.assertEqual(event[1]['speaker'], 'Adam Curry') + self.assertEqual(event[1]['description'], '"Description 1"\n') + event = events[2] + self.assertEqual(event[1]['title'], "Title 2") + self.assertEqual(event[1]['date'], datetime.date(2014, 2, 21)) + self.assertEqual(event[1]['time'], '15:12') + self.assertEqual(event[1]['speaker'], 'John C. Dvorak') + self.assertEqual(event[1]['description'], '"Description 2"\n') + + def test_events0_filter_take_date_range_3(self): + """ Everything before 2014-1-1 """ + date = datetime.date(2014,1,1) + events = select_events( + self.events, + lambda x: filter_take_date_range(x, date, None) + ) + self.assertEqual(len(events), 0) + + def test_events0_filter_take_date_range_4(self): + """ Everything before 2014-1-14 """ + date = datetime.date(2014,1,14) + events = select_events( + self.events, + lambda x: filter_take_date_range(x, date, None) + ) + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(event[1]['title'], "Title 3") + self.assertEqual(event[1]['date'], datetime.date(2014, 1, 14)) + self.assertEqual(event[1]['time'], '02:44') + self.assertEqual(event[1]['speaker'], 'Bart Massey') + self.assertEqual(event[1]['description'], '"Description 3"\n') + + def test_events0_filter_take_date_range_5(self): + """ Everything before 2014-1-14 """ + date = datetime.date(2014,2,25) + events = select_events( + self.events, + lambda x: filter_take_date_range(x, date, None) + ) + self.assertEqual(len(events), 2) + event = events[0] + self.assertEqual(event[1]['title'], "Title 2") + self.assertEqual(event[1]['date'], datetime.date(2014, 2, 21)) + self.assertEqual(event[1]['time'], '15:12') + self.assertEqual(event[1]['speaker'], 'John C. Dvorak') + self.assertEqual(event[1]['description'], '"Description 2"\n') + event = events[1] + self.assertEqual(event[1]['title'], "Title 3") + self.assertEqual(event[1]['date'], datetime.date(2014, 1, 14)) + self.assertEqual(event[1]['time'], '02:44') + self.assertEqual(event[1]['speaker'], 'Bart Massey') + self.assertEqual(event[1]['description'], '"Description 3"\n') + + def test_weekday_difference(self): + self.assertEqual(weekday_difference(0,0), 0) + self.assertEqual(weekday_difference(0,1), 1) + self.assertEqual(weekday_difference(0,2), 2) + self.assertEqual(weekday_difference(0,3), 3) + self.assertEqual(weekday_difference(0,4), 4) + self.assertEqual(weekday_difference(0,5), 5) + self.assertEqual(weekday_difference(0,6), 6) + self.assertEqual(weekday_difference(1,0), 6) + self.assertEqual(weekday_difference(1,1), 0) + self.assertEqual(weekday_difference(1,2), 1) + self.assertEqual(weekday_difference(1,3), 2) + self.assertEqual(weekday_difference(1,4), 3) + self.assertEqual(weekday_difference(1,5), 4) + self.assertEqual(weekday_difference(1,6), 5) + self.assertEqual(weekday_difference(2,0), 5) + self.assertEqual(weekday_difference(2,1), 6) + self.assertEqual(weekday_difference(2,2), 0) + self.assertEqual(weekday_difference(2,3), 1) + self.assertEqual(weekday_difference(2,4), 2) + self.assertEqual(weekday_difference(2,5), 3) + self.assertEqual(weekday_difference(2,6), 4) + self.assertEqual(weekday_difference(3,0), 4) + self.assertEqual(weekday_difference(3,1), 5) + self.assertEqual(weekday_difference(3,2), 6) + self.assertEqual(weekday_difference(3,3), 0) + self.assertEqual(weekday_difference(3,4), 1) + self.assertEqual(weekday_difference(3,5), 2) + self.assertEqual(weekday_difference(3,6), 3) + self.assertEqual(weekday_difference(4,0), 3) + self.assertEqual(weekday_difference(4,1), 4) + self.assertEqual(weekday_difference(4,2), 5) + self.assertEqual(weekday_difference(4,3), 6) + self.assertEqual(weekday_difference(4,4), 0) + self.assertEqual(weekday_difference(4,5), 1) + self.assertEqual(weekday_difference(4,6), 2) + self.assertEqual(weekday_difference(5,0), 2) + self.assertEqual(weekday_difference(5,1), 3) + self.assertEqual(weekday_difference(5,2), 4) + self.assertEqual(weekday_difference(5,3), 5) + self.assertEqual(weekday_difference(5,4), 6) + self.assertEqual(weekday_difference(5,5), 0) + self.assertEqual(weekday_difference(5,6), 1) + self.assertEqual(weekday_difference(6,0), 1) + self.assertEqual(weekday_difference(6,1), 2) + self.assertEqual(weekday_difference(6,2), 3) + self.assertEqual(weekday_difference(6,3), 4) + self.assertEqual(weekday_difference(6,4), 5) + self.assertEqual(weekday_difference(6,5), 6) + self.assertEqual(weekday_difference(6,6), 0) + +if __name__ == '__main__': + unittest.main() From 4858482481cc1d995e1e2e5f4326117d2108dd56 Mon Sep 17 00:00:00 2001 From: Cameron Brandon White Date: Mon, 17 Feb 2014 04:05:17 -0800 Subject: [PATCH 3/4] (gh-22) Setup Travis CI --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b7dfb93 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: python +python: + - "2.7" +# command to run tests +script: python setup.py nosetests From fa2038f8978f88b99117f4fa464d60a2a6bf0221 Mon Sep 17 00:00:00 2001 From: Cameron Brandon White Date: Mon, 17 Feb 2014 04:14:07 -0800 Subject: [PATCH 4/4] Updated config.cfg defaults --- config.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/config.cfg b/config.cfg index f33ae5e..ac6092d 100644 --- a/config.cfg +++ b/config.cfg @@ -57,5 +57,6 @@ nightfly!nightfly@destiny.cat.pdx.edu [acmbot] base_url = http://acm.pdx.edu +events_yaml_url = files/events.yaml events_limit = 5 default_time = 16:00