133 lines
3.2 KiB
Python
133 lines
3.2 KiB
Python
import sys
|
|
import os
|
|
import unittest
|
|
|
|
import mock
|
|
|
|
# TODO: drop in test runner and get rid of this line.
|
|
sys.path.append(os.getcwd()) # noqa
|
|
|
|
from init.question import (Question, InvalidQuestion, InvalidAnswer,
|
|
AnswerNotImplemented)
|
|
|
|
|
|
##############################################################################
|
|
#
|
|
# Test Fixtures
|
|
#
|
|
##############################################################################
|
|
|
|
|
|
class InvalidTypeQuestion(Question):
|
|
_type = 'foo'
|
|
|
|
|
|
class GoodAutoQuestion(Question):
|
|
_type = 'auto'
|
|
|
|
def yes(self, answer):
|
|
return 'I am a good question!'
|
|
|
|
|
|
class GoodBooleanQuestion(Question):
|
|
_type = 'boolean'
|
|
|
|
def yes(self, answer):
|
|
return True
|
|
|
|
def no(self, answer):
|
|
return False
|
|
|
|
|
|
class GoodStringQuestion(Question):
|
|
"""Pass a string through to the output of Question.ask.
|
|
|
|
# TODO right now, we have separate handlers for Truthy and Falsey
|
|
answers, and this test class basically makes them do the same
|
|
thing. Is this a good pattern?
|
|
|
|
"""
|
|
_type = 'string'
|
|
|
|
def yes(self, answer):
|
|
return answer
|
|
|
|
def no(self, answer):
|
|
return answer
|
|
|
|
|
|
##############################################################################
|
|
#
|
|
# Tests Proper
|
|
#
|
|
##############################################################################
|
|
|
|
|
|
class TestQuestionClass(unittest.TestCase):
|
|
"""
|
|
Test basic features of the Question class.
|
|
|
|
"""
|
|
def test_invalid_type(self):
|
|
|
|
with self.assertRaises(InvalidQuestion):
|
|
InvalidTypeQuestion().ask()
|
|
|
|
def test_valid_type(self):
|
|
|
|
self.assertTrue(GoodBooleanQuestion())
|
|
|
|
@mock.patch('init.question.shell.check_output')
|
|
@mock.patch('init.question.shell.check')
|
|
def test_auto_question(self, mock_check, mock_check_output):
|
|
mock_check_output.return_value = ''
|
|
|
|
self.assertEqual(GoodAutoQuestion().ask(), True)
|
|
|
|
|
|
class TestInput(unittest.TestCase):
|
|
"""
|
|
Test input handling.
|
|
|
|
Takes advantage of the fact that we can override the Question
|
|
class's input handler.
|
|
|
|
"""
|
|
@mock.patch('init.question.shell.check_output')
|
|
@mock.patch('init.question.shell.check')
|
|
def test_boolean_question(self, mock_check, mock_check_output):
|
|
mock_check_output.return_value = 'true'
|
|
|
|
q = GoodBooleanQuestion()
|
|
|
|
for answer in ['yes', 'Yes', 'y']:
|
|
q._input_func = lambda x: answer
|
|
self.assertTrue(q.ask())
|
|
|
|
for answer in ['No', 'n', 'no']:
|
|
q._input_func = lambda x: answer
|
|
self.assertFalse(q.ask())
|
|
|
|
with self.assertRaises(InvalidAnswer):
|
|
q._input_func = lambda x: 'foo'
|
|
q.ask()
|
|
|
|
@mock.patch('init.question.shell.check_output')
|
|
@mock.patch('init.question.shell.check')
|
|
def test_string_question(self, mock_check, mock_check_output):
|
|
mock_check_output.return_value = 'somedefault'
|
|
|
|
q = GoodStringQuestion()
|
|
|
|
for answer in ['foo', 'bar', 'baz', 'yadayadayada']:
|
|
q._input_func = lambda x: answer
|
|
self.assertEqual(answer, q.ask())
|
|
|
|
# Verify that a blank answer defaults properly
|
|
q._input_func = lambda x: ''
|
|
self.assertEqual('somedefault', q.ask())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|