def load_from_string(self, string): """ Load a menu from a YAML description >>> loader = YAMLLoader() >>> menu = loader.load_from_string(\"\"\" ... - question: What is your favorite color? ... options: ... - red ... - white ... - blue ... \"\"\") >>> index, item = menu.next() >>> index # the index of the next menu 1 >>> item.next() # manually advance >>> item.send((None, {})) # fake feed of menu and session store ('What is your favorite color?\\n1: red\\n2: white\\n3: blue', False) >>> """ import yaml menu = MenuSystem() for item in yaml.safe_load(string): menu.append(self.load_from_dict(item)) return menu
def setUp(self): self.menu = MenuSystem( prompt("Prompt 1"), prompt("Prompt 2"), prompt("Prompt 3") )
class MenuSystemTestCase(TestCase): def setUp(self): self.menu = MenuSystem( prompt("Prompt 1"), prompt("Prompt 2"), prompt("Prompt 3") ) def test_cloning(self): """The menu system should be able to clone itself without any pass by reference nastiness""" menu_clone = self.menu.clone() self.assertNotEquals(self.menu, menu_clone) self.assertNotEquals(self.menu.stack, menu_clone.stack) def test_appending(self): """ append() should clone the menu system and append the given items """ menu = self.menu.append( prompt("Prompt 4"), prompt("Prompt 5") ) self.assertNotEquals(menu, self.menu) self.assertEquals(len(menu.stack), 5) def test_fast_forwarding(self): """The menu system should be able to fast forward to any point in the stack""" menu = self.menu.clone() self.assertEquals(menu.get_current_index(), 0) menu.fast_forward(1) index, next_prompt = menu.next() # fast forwarded self.assertEquals(index, 2) # advance next_prompt.next() session_store = {} prompt_2, end_of_session = next_prompt.send((menu, session_store)) self.assertEquals(prompt_2, "Prompt 2") self.assertFalse(end_of_session) def test_repeat_current_item(self): """ repeat_current_item() should repeat the current coroutine by rewiding the stack by 1 and restarting """ menu = self.menu.clone() def _test_repeated_coroutine(index, coroutine): # index is always 1 ahead self.assertEquals(index, 1) # advance coroutine.next() text, end_of_session = coroutine.send((MenuSystem(), {})) self.assertEquals(text, "Prompt 1") self.assertFalse(end_of_session) _test_repeated_coroutine(*menu.next()) _test_repeated_coroutine(*menu.repeat_current_item()) def test_next_after(self): """ next_after() should return the next prompt coming after the given index """ menu = self.menu.clone() index, prompt = menu.next_after(1) self.assertEquals(index, 2) def _test_coroutine(coroutine): # advance coroutine.next() text, end_of_session = coroutine.send((MenuSystem(), {})) self.assertEquals(text, "Prompt 2") self.assertFalse(end_of_session) _test_coroutine(prompt) # these should both return the same text _test_coroutine(menu.stack[1]) # since they should be the same prompt def test_end_of_stack(self): """ next() should return None for the next item if the end of the stack has been reached """ menu = self.menu.clone() menu.fast_forward(3) index, none = menu.next() self.assertEquals(index, 4) self.assertEquals(none, None) def test_iteration(self): """ the menu system should support the normal iterator pattern and raise a StopIteration when the end of the stack has been reached Not sure if this is even useful. """ for index, coroutine in iter(self.menu.clone()): a,b = index, coroutine