diff --git a/.gitignore b/.gitignore index 89b8131..7a37fb3 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ lib local bin error.log +nicks.csv diff --git a/bot.py b/bot.py index dd2e1e3..ba93181 100644 --- a/bot.py +++ b/bot.py @@ -3,17 +3,10 @@ # Import some necessary libraries. import socket, sys, time, csv, Queue, random, re, pdb, select, os.path from threading import Thread +import ConfigParser -# Some basic variables used to configure the bot. -server = "irc.freenode.net" -channel = "#openhatch" # Please use #openhatch-bots rather than #openhatch for testing -botnick = "WelcomeBot" -channel_greeters = ['shauna', 'paulproteus', 'marktraceur'] -wait_time = 60 -hello_list = [r'hello', r'hi', r'hey', r'yo', r'sup'] -help_list = [r'help', r'info', r'faq', r'explain yourself'] -registered = False # If users don't want to identify, change the value to false. - +# To configure bot, please make changes in bot_settings.py +import bot_settings as settings ######################### ### Class Definitions ### @@ -22,7 +15,11 @@ registered = False # If users don't want to identify, change the value to false. # Defines a bot class Bot(object): - def __init__(self, nick_source='nicks.csv', wait_time=wait_time): + def __init__(self, botnick=settings.botnick, welcome_message=settings.welcome_message, + nick_source=settings.nick_source, wait_time=settings.wait_time, + hello_list=settings.hello_list, help_list=settings.help_list): + self.botnick = botnick + self.welcome_message = welcome_message self.nick_source = nick_source self.wait_time = wait_time self.known_nicks = [] @@ -32,8 +29,8 @@ class Bot(object): row = clean_nick(row[0]) # Sends nicks to remove unnecessary decorators. Hacked to deal with list-of-string format. :( self.known_nicks.append([row]) self.newcomers = [] - self.hello_regex = re.compile(get_regex(hello_list), re.I) # Regexed version of hello list - self.help_regex = re.compile(get_regex(help_list), re.I) # Regexed version of help list + self.hello_regex = re.compile(get_regex(hello_list, botnick), re.I) # Regexed version of hello list + self.help_regex = re.compile(get_regex(help_list, botnick), re.I) # Regexed version of help list # Adds the current newcomer's nick to nicks.csv and known_nicks. def add_known_nick(self,new_known_nick): @@ -63,12 +60,12 @@ class NewComer(object): # Creates a socket that will be used to send and receive messages, # then connects the socket to an IRC server and joins the channel. -def irc_start(): # pragma: no cover (this excludes this function from testing) +def irc_start(server): # pragma: no cover (this excludes this function from testing) ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock.connect((server, 6667)) # Here we connect to server using port 6667. return ircsock -def join_irc(ircsock): +def join_irc(ircsock, botnick, channel): ircsock.send("USER {0} {0} {0} :This is http://openhatch.org/'s greeter bot" ".\n".format(botnick)) # bot authentication ircsock.send("NICK {}\n".format(botnick)) # Assign the nick to the bot. @@ -88,7 +85,7 @@ def msg_handler(ircsock): # pragma: no cover (this excludes this function from return new_msg # Called by bot on startup. Builds a regex that matches one of the options + (space) botnick. -def get_regex(options): +def get_regex(options, botnick): pattern = "(" for s in options: pattern += s @@ -103,7 +100,7 @@ def get_regex(options): ######################### # Welcomes the "person" passed to it. -def welcome_nick(newcomer, ircsock): +def welcome_nick(newcomer, ircsock, channel, channel_greeters): ircsock.send("PRIVMSG {0} :Welcome {1}! The channel is pretty quiet " "right now, so I thought I'd say hello, and ping some people " "(like {2}) that you're here. If no one responds for a " @@ -113,11 +110,11 @@ def welcome_nick(newcomer, ircsock): "\n".format(channel, newcomer, greeter_string(channel_greeters))) # Checks and manages the status of newcomers. -def process_newcomers(bot, newcomerlist, ircsock, welcome=1): +def process_newcomers(bot, newcomerlist, ircsock, channel, greeters, welcome=1): for person in newcomerlist: if welcome == 1: - welcome_nick(person.nick, ircsock) - bot.add_known_nick(person.clean_nick) + welcome_nick(person.nick, ircsock, channel, greeters) + bot.add_known_nick(person.nick) bot.newcomers.remove(person) # Checks for messages. @@ -141,19 +138,19 @@ def clean_nick(actor): return actor # Parses messages and responds to them appropriately. -def message_response(bot, ircmsg, actor, ircsock): +def message_response(bot, ircmsg, actor, ircsock, channel, greeters): # if someone other than a newcomer speaks into the channel - if ircmsg.find("PRIVMSG " + channel) != -1 and clean_nick(actor) not in [i.clean_nick for i in bot.newcomers]: - process_newcomers(bot,bot.newcomers, ircsock, welcome=0) # Process/check newcomers without welcoming them + if ircmsg.find("PRIVMSG " + channel) != -1 and actor not in [i.nick for i in bot.newcomers]: + process_newcomers(bot,bot.newcomers, ircsock, channel, greeters, welcome=0) # Process/check newcomers without welcoming them # if someone (other than the bot) joins the channel - if ircmsg.find("JOIN " + channel) != -1 and actor != botnick: - if [clean_nick(actor)] not in bot.known_nicks + [i.clean_nick for i in bot.newcomers]: # And they're new + if ircmsg.find("JOIN " + channel) != -1 and actor != bot.botnick: + if [actor.replace("_", "")] not in bot.known_nicks + [i.nick for i in bot.newcomers]: # And they're new NewComer(actor, bot) # if someone changes their nick while still in newcomers update that nick - if ircmsg.find("NICK :") != -1 and actor != botnick: + if ircmsg.find("NICK :") != -1 and actor != bot.botnick: for i in bot.newcomers: # if that person was in the newlist if i.nick == actor: i.nick = ircmsg.split(":")[2] # update to new nick (and clean up the nick) @@ -166,15 +163,15 @@ def message_response(bot, ircmsg, actor, ircsock): bot.newcomers.remove(i) # remove them from the list # If someone talks to (or refers to) the bot. - if botnick.lower() and "PRIVMSG".lower() in ircmsg.lower(): + if bot.botnick.lower() and "PRIVMSG".lower() in ircmsg.lower(): if bot.hello_regex.search(ircmsg): - bot_hello(random.choice(hello_list), actor, ircsock) + bot_hello(random.choice(settings.hello_list), actor, ircsock, channel) if bot.help_regex.search(ircmsg): - bot_help(ircsock) + bot_help(ircsock, channel) # If someone tries to change the wait time... - if ircmsg.find(botnick + " --wait-time ") != -1: - bot.wait_time = wait_time_change(actor, ircmsg, ircsock) # call this to check and change it + if ircmsg.find(bot.botnick + " --wait-time ") != -1: + bot.wait_time = wait_time_change(actor, ircmsg, ircsock, channel, greeters) # call this to check and change it # If the server pings us then we've got to respond! if ircmsg.find("PING :") != -1: @@ -186,11 +183,11 @@ def message_response(bot, ircmsg, actor, ircsock): ############################################################# # Responds to a user that inputs "Hello Mybot". -def bot_hello(greeting, actor, ircsock): +def bot_hello(greeting, actor, ircsock, channel): ircsock.send("PRIVMSG {0} :{1} {2}\n".format(channel, greeting, actor)) # Explains what the bot is when queried. -def bot_help(ircsock): +def bot_help(ircsock, channel): ircsock.send("PRIVMSG {} :I'm a bot! I'm from here . You can change my behavior by " "submitting a pull request or by talking to shauna" @@ -210,7 +207,7 @@ def greeter_string(greeters): return greeterstring # Changes the wait time from the channel. -def wait_time_change(actor, ircmsg, ircsock): +def wait_time_change(actor, ircmsg, ircsock, channel, channel_greeters): for admin in channel_greeters: if actor == admin: finder = re.search(r'\d\d*', re.search(r'--wait-time \d\d*', ircmsg) @@ -232,17 +229,17 @@ def pong(ircsock): ########################## def main(): - ircsock = irc_start() - join_irc(ircsock) + ircsock = irc_start(settings.server) + join_irc(ircsock, settings.botnick, settings.channel) WelcomeBot = Bot() while 1: # Loop forever ready_to_read, b, c = select.select([ircsock],[],[], 1) # b&c are ignored here - process_newcomers(WelcomeBot, [i for i in WelcomeBot.newcomers if i.around_for() > WelcomeBot.wait_time],ircsock) + process_newcomers(WelcomeBot, [i for i in WelcomeBot.newcomers if i.around_for() > WelcomeBot.wait_time], ircsock,settings.channel, settings.channel_greeters) if ready_to_read: ircmsg = msg_handler(ircsock) # gets message from ircsock ircmsg, actor = parse_messages(ircmsg) # parses it or returns None if ircmsg is not None: # If we were able to parse it - message_response(WelcomeBot, ircmsg, actor, ircsock) # Respond to the parsed message + message_response(WelcomeBot, ircmsg, actor, ircsock, settings.channel, settings.channel_greeters) # Respond to the parsed message if __name__ == "__main__": # This line tells the interpreter to only execute main() if the program is being run, not imported. sys.exit(main()) diff --git a/bot_settings.py b/bot_settings.py new file mode 100644 index 0000000..847cf22 --- /dev/null +++ b/bot_settings.py @@ -0,0 +1,17 @@ +# Replace these default settings with your own personal settings + +# IRC configuration +channel = "#openhatch-unlogged" +botnick = "parsewelcomebot" +server = "irc.freenode.net" +registered = False + +# Bot behavior +wait_time = 60 +channel_greeters = ["shauna", "paulproteus", "marktraceur"] +nick_source = "nicks.csv" + +# Bot text +hello_list = ["hello", "hi", "hey", "yo", "sup"] +help_list = ["help", "info", "faq", "explain_yourself"] +welcome_message = "Welcome! THe channel is pretty quiet right now, so I thought I'd say hello, and ping some people that you're here. If no one responds for a whle, try emailing us at hello@openhatch.org or just try coming back later. FYI, you're now on my list of known nicknames, so I won't bother you again." diff --git a/nicks.csv b/nicks.csv deleted file mode 100644 index 0e56c9e..0000000 --- a/nicks.csv +++ /dev/null @@ -1,75 +0,0 @@ -paulproteus -britta -aldeka -ArcTanSusan -aeva -daveeloo2 -ehashman -exor674 -glyph -GorillaWarfare -gregglind -IShadowed -JasonWoof -jdunck -jeremyb -jesstess -johnmorr -judytuna -keturn -klange -kxra -Kyzz[Mobile] -lfaraone -mandarg -marktraceur -mchua -mindspillage -mlinksva -openhatch_hudson -paroneayea -paulproteus|mobi -paultag -ptone -ptressel -pyrak -pythonian4000 -rmo -skay -sunu -ThomasWaldmann -Triskelios -wolftune -Rsouthee -rihnapstor -fijal -kstar -freedeb -aaron -reutest -willingc -romzy -ArcTanSusan -paroneayea -wolftune -reutest -IShadowed -FHaag -Eldanen -exor674 -shauna -Aaron1011 -FHaag1 -carbon -tricksy -zorkian -thunderbolt -daleharvey -tajys -TDJACR -gitcommits -sassyapril -MaraJade -achock -aaparella -abcqfiojqw diff --git a/test_bot.py b/test_bot.py index efe5757..682a709 100644 --- a/test_bot.py +++ b/test_bot.py @@ -6,21 +6,24 @@ import bot as botcode import time import pdb +# To configure bot, please make changes in bot_settings.py +import bot_settings as settings + ######################### -### FAKE IRCSOCK ### +### FAKE IRCSOCK ### ######################### class fake_ircsock(object): def __init__(self): self.sent_messages = [] - + def send(self, msg): self.sent_messages.append(msg) def sent_message(self): return self.sent_messages[-1] - + def has_sent_message(self): if self.sent_messages: return True @@ -29,7 +32,7 @@ class fake_ircsock(object): def fake_irc_start(): ircsock = fake_ircsock() - return ircsock + return ircsock class TestBotClass(unittest.TestCase): @@ -41,11 +44,11 @@ class TestBotClass(unittest.TestCase): self.assertEqual(self.bot.nick_source, 'nicks.csv') def test_known_nicks_setup(self): - bot = botcode.Bot('test_nicks.csv') + bot = botcode.Bot(nick_source='test_nicks.csv') self.assertEqual(bot.known_nicks, [['Alice'], ['Bob']]) def test_wait_time(self): - self.assertEqual(self.bot.wait_time, botcode.wait_time) + self.assertEqual(self.bot.wait_time, settings.wait_time) def test_custom_wait_time(self): bot = botcode.Bot(wait_time=30) @@ -65,7 +68,7 @@ class TestBotClass(unittest.TestCase): self.assertEqual(self.bot.known_nicks,[['Fluffy'], ['Spot'], ['Roger']]) def test_add_nick_to_csv(self): - bot = botcode.Bot('test_nicks.csv') + bot = botcode.Bot(nick_source='test_nicks.csv') bot.add_known_nick('Roger__') with open('test_nicks.csv', 'rb') as csv_file: known_nicks = [] @@ -102,16 +105,16 @@ class TestJoinIRC(unittest.TestCase): def setUp(self): self.ircsock = fake_irc_start() self.bot = botcode.Bot() - + def test_sent_messages(self): - botcode.join_irc(self.ircsock) - expected = ["USER {} {} {} :This is http://openhatch.org/'s greeter bot.\n".format(botcode.botnick, botcode.botnick, botcode.botnick), 'NICK {}\n'.format(botcode.botnick), 'JOIN {} \n'.format(botcode.channel)] + botcode.join_irc(self.ircsock, settings.botnick, settings.channel) + expected = ["USER {} {} {} :This is http://openhatch.org/'s greeter bot.\n".format(self.bot.botnick, self.bot.botnick, self.bot.botnick), 'NICK {}\n'.format(self.bot.botnick), 'JOIN {} \n'.format(settings.channel)] self.assertEqual(self.ircsock.sent_messages,expected) class TestProcessNewcomers(unittest.TestCase): def setUp(self): - self.bot = botcode.Bot('test_nicks.csv', wait_time=.1) + self.bot = botcode.Bot(nick_source='test_nicks.csv', wait_time=.1) botcode.NewComer('Harry', self.bot) botcode.NewComer('Hermione', self.bot) time.sleep(.15) @@ -119,17 +122,17 @@ class TestProcessNewcomers(unittest.TestCase): self.ircsock = fake_irc_start() def test_check_new_newcomers(self): - botcode.process_newcomers(self.bot, [i for i in self.bot.newcomers if i.around_for() > self.bot.wait_time], ircsock=self.ircsock, welcome=0) + botcode.process_newcomers(self.bot, [i for i in self.bot.newcomers if i.around_for() > self.bot.wait_time], ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters, welcome=0) self.assertEqual(len(self.bot.newcomers), 1) def test_check_new_known_nicks(self): - botcode.process_newcomers(self.bot, [i for i in self.bot.newcomers if i.around_for() > self.bot.wait_time], ircsock=self.ircsock, welcome=0) + botcode.process_newcomers(self.bot, [i for i in self.bot.newcomers if i.around_for() > self.bot.wait_time], ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters, welcome=0) self.assertEqual(self.bot.known_nicks,[['Alice'],['Bob'],['Harry'],['Hermione']]) - + def test_welcome_nick(self): - botcode.process_newcomers(bot=self.bot, newcomerlist=[i for i in self.bot.newcomers if i.around_for() > self.bot.wait_time], ircsock=self.ircsock, welcome=1) - self.assertEqual(self.ircsock.sent_message(), "PRIVMSG {0} :Welcome Hermione! The channel is pretty quiet right now, so I thought I'd say hello, and ping some people (like {1}) that you're here. If no one responds for a while, try emailing us at hello@openhatch.org or just try coming back later. FYI, you're now on my list of known nicknames, so I won't bother you again.\n".format(botcode.channel,botcode.greeter_string(botcode.channel_greeters))) - + botcode.process_newcomers(bot=self.bot, newcomerlist=[i for i in self.bot.newcomers if i.around_for() > self.bot.wait_time], ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters, welcome=1) + self.assertEqual(self.ircsock.sent_message(), "PRIVMSG {0} :Welcome Hermione! The channel is pretty quiet right now, so I thought I'd say hello, and ping some people (like {1}) that you're here. If no one responds for a while, try emailing us at hello@openhatch.org or just try coming back later. FYI, you're now on my list of known nicknames, so I won't bother you again.\n".format(settings.channel,botcode.greeter_string(settings.channel_greeters))) + def tearDown(self): with open('test_nicks.csv', 'w') as csv_file: csv_file.write('Alice\nBob\n') @@ -139,7 +142,7 @@ class TestParseMessages(unittest.TestCase): def test_good_string(self): ircmsg, actor = botcode.parse_messages(":vader!darth@darkside.org PRIVMSG #deathstar : I find your lack of faith disturbing") self.assertEqual([ircmsg, actor], [':vader!darth@darkside.org PRIVMSG #deathstar : I find your lack of faith disturbing', 'vader']) - + def test_bad_string(self): ircmsg, actor = botcode.parse_messages("we should probably replace this with a bad string more likely to occur") self.assertEqual([ircmsg, actor], [None, None]) @@ -152,69 +155,69 @@ class TestMessageResponse(unittest.TestCase): self.ircsock = fake_irc_start() def test_newcomer_speaking(self): - botcode.message_response(self.bot,"~q@r.m.us PRIVMSG {} :hah".format(botcode.channel),"Chappe", ircsock=self.ircsock) # Standard message by newcomer + botcode.message_response(self.bot,"~q@r.m.us PRIVMSG {} :hah".format(settings.channel),"Chappe", ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) # Standard message by newcomer nicklist = [i.nick for i in self.bot.newcomers] # Makes a list of newcomers nicks for easy asserting self.assertEqual(nicklist, ['Chappe']) def test_oldtimer_speaking(self): - botcode.message_response(self.bot,"~q@r.m.us PRIVMSG {} :hah".format(botcode.channel),"Alice", ircsock=self.ircsock) # Standard message by oldtimer + botcode.message_response(self.bot,"~q@r.m.us PRIVMSG {} :hah".format(settings.channel),"Alice", ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) # Standard message by oldtimer nicklist = [i.nick for i in self.bot.newcomers] # Makes a list of newcomers nicks for easy asserting self.assertEqual(nicklist, []) - + def test_join(self): - botcode.message_response(self.bot,"JOIN {} right now!".format(botcode.channel),"Shauna", ircsock=self.ircsock) # Replace with actual ping message + botcode.message_response(self.bot,"JOIN {} right now!".format(settings.channel),"Shauna", ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) # Replace with actual ping message self.assertEqual(self.bot.newcomers[1].nick,'Shauna') - + def test_part(self): - botcode.message_response(self.bot,"JOIN {} right now!".format(botcode.channel),"Shauna", ircsock=self.ircsock) # Replace with actual ping message + botcode.message_response(self.bot,"JOIN {} right now!".format(settings.channel),"Shauna", ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) # Replace with actual ping message self.assertEqual(len(self.bot.newcomers), 2) - botcode.message_response(self.bot,"PART {}".format(botcode.channel),"Shauna", ircsock=self.ircsock) # Replace with actual ping message - self.assertEqual(len(self.bot.newcomers), 1) - + botcode.message_response(self.bot,"PART {}".format(settings.channel),"Shauna", ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) # Replace with actual ping message + self.assertEqual(len(self.bot.newcomers), 1) + def test_hello(self): - botcode.message_response(self.bot,"PRIVMSG sup {}".format(botcode.botnick),"Shauna", ircsock=self.ircsock) + botcode.message_response(self.bot,"PRIVMSG sup {}".format(self.bot.botnick),"Shauna", ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) self.assertTrue(self.ircsock.has_sent_message()) - self.assertIn(self.ircsock.sent_message(), ["PRIVMSG {} :hello Shauna\n".format(botcode.channel), "PRIVMSG {} :hi Shauna\n".format(botcode.channel), "PRIVMSG {} :hey Shauna\n".format(botcode.channel), "PRIVMSG {} :yo Shauna\n".format(botcode.channel), "PRIVMSG {} :sup Shauna\n".format(botcode.channel)]) - + self.assertIn(self.ircsock.sent_message(), ["PRIVMSG {} :hello Shauna\n".format(settings.channel), "PRIVMSG {} :hi Shauna\n".format(settings.channel), "PRIVMSG {} :hey Shauna\n".format(settings.channel), "PRIVMSG {} :yo Shauna\n".format(settings.channel), "PRIVMSG {} :sup Shauna\n".format(settings.channel)]) + def test_help(self): - botcode.message_response(self.bot,"PRIVMSG info {}".format(botcode.botnick),"Shauna", ircsock=self.ircsock) + botcode.message_response(self.bot,"PRIVMSG info {}".format(self.bot.botnick),"Shauna", ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) self.assertTrue(self.ircsock.has_sent_message()) - self.assertEqual(self.ircsock.sent_message(), "PRIVMSG {} :I'm a bot! I'm from here . You can change my behavior by submitting a pull request or by talking to shauna.\n".format(botcode.channel)) - + self.assertEqual(self.ircsock.sent_message(), "PRIVMSG {} :I'm a bot! I'm from here . You can change my behavior by submitting a pull request or by talking to shauna.\n".format(settings.channel)) + def test_wait_time_from_admin(self): - botcode.message_response(self.bot,"{} --wait-time 40".format(botcode.botnick),"shauna",ircsock=self.ircsock) # Channel-greeters may also be changed. :( - self.assertEqual(self.ircsock.sent_message(), "PRIVMSG {} :shauna the wait time is changing to 40 seconds.\n".format(botcode.channel)) - - def test_wait_time_from_non_admin(self): - botcode.message_response(self.bot,"{} --wait-time 40".format(botcode.botnick),"Impostor",ircsock=self.ircsock) # Channel-greeters may also be changed. :( - self.assertEqual(self.ircsock.sent_message(), "PRIVMSG {0} :Impostor you are not authorized to make that change. Please contact one of the channel greeters, like {1}, for assistance.\n".format(botcode.channel,botcode.greeter_string(botcode.channel_greeters))) - + botcode.message_response(self.bot,"{} --wait-time 40".format(self.bot.botnick),"shauna",ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) # Channel-greeters may also be changed. :( + self.assertEqual(self.ircsock.sent_message(), "PRIVMSG {} :shauna the wait time is changing to 40 seconds.\n".format(settings.channel)) + + def test_wait_time_from_non_admin(self): + botcode.message_response(self.bot,"{} --wait-time 40".format(self.bot.botnick),"Impostor",ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) # Channel-greeters may also be changed. :( + self.assertEqual(self.ircsock.sent_message(), "PRIVMSG {0} :Impostor you are not authorized to make that change. Please contact one of the channel greeters, like {1}, for assistance.\n".format(settings.channel,botcode.greeter_string(settings.channel_greeters))) + def test_pong(self): - botcode.message_response(self.bot,"PING :","Shauna",ircsock=self.ircsock) # Replace this with actual ping message + botcode.message_response(self.bot,"PING :","Shauna",ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) # Replace this with actual ping message self.assertEqual(self.ircsock.sent_message(),"PONG :pingis\n") - + def test_bad_pong(self): - botcode.message_response(self.bot,"PING!!! :","Shauna",ircsock=self.ircsock) # Replace this with actual ping message - self.assertFalse(self.ircsock.has_sent_message()) + botcode.message_response(self.bot,"PING!!! :","Shauna",ircsock=self.ircsock, channel=settings.channel, greeters=settings.channel_greeters) # Replace this with actual ping message + self.assertFalse(self.ircsock.has_sent_message()) def tearDown(self): with open('test_nicks.csv', 'w') as csv_file: csv_file.write('Alice\nBob\n') -class TestGreeterString(unittest.TestCase): - +class TestGreeterString(unittest.TestCase): + def setUp(self): self.bot = botcode.Bot('test_nicks.csv') - - def test_one_greeter(self): + + def test_one_greeter(self): greeterstring = botcode.greeter_string(['shauna']) self.assertEqual(greeterstring, "shauna") - - def test_two_greeters(self): + + def test_two_greeters(self): greeters = botcode.greeter_string(['shauna','sauna']) self.assertEqual(greeters, "shauna and sauna") - def test_three_greeters(self): + def test_three_greeters(self): greeters = botcode.greeter_string(['shauna','sauna','megafauna']) self.assertEqual(greeters, "shauna, sauna, and megafauna")