Ejemplo n.º 1
0
 def test_error(self):
     v = Validator()
     v.validate('')
     assert v.error() == 'ERROR: Can not be empty.  Please provide a value.'
Ejemplo n.º 2
0
 def test_blank(self):
     v = Validator(blank=True)
     assert v.validate('') is True
     assert v.choice() == ''
Ejemplo n.º 3
0
class Question(object):
    _answers: Dict
    _questions: List

    def __init__(self, question: str, value: str, validator: 'Validator' = None,
                 multiple=False, printable_name=None) -> None:
        """ Basic Question class.

            Supports simple question and answer or question and multiple
            answers (note: list/hash validators have caveats).  Also
            support for one or more Validator classes to ensure the answer
            given meets the question criteria.
        """
        self.question = question
        self.value = value
        self.multiple = multiple
        if printable_name:
            self.printable_name = printable_name
        else:
            self.printable_name = value
        if validator is None:
            self.validator = Validator()
        else:
            self.validator = validator
        self._questions = []

    def __eq__(self, other: 'Question') -> bool:  # type: ignore
        if self.question == other.question and self.value == other.value:
            return True
        else:
            return False

    def __repr__(self) -> str:
        return self.value

    def _get_input(self, text) -> str:
        return input(text)

    def _ask(self, answers: Dict) -> Union[Dict, None]:
        """ Really ask the question.

            We may need to populate multiple validators with answers here.
            Then ask the question and insert the default value if
            appropriate.  Finally call the validate function to check all
            validators for this question and returning the answer.
        """
        if isinstance(self.validator, list):
            for v in self.validator:
                v.answers = answers
        else:
            self.validator.answers = answers
        while(True):
            q = self.question % answers

            if not self.choices():
                logger.warning('No choices were supplied for "%s"' % q)
                return None
            if self.value in answers:
                default = Validator.stringify(answers[self.value])
                answer = self._get_input("%s [%s]: " % (q, default))
                if answer == '':
                    answer = answers[self.value]
            else:
                answer = self._get_input("%s: " % q)
            # if we are in multiple mode and the answer is just the empty
            # string (enter/return pressed) then we will just answer None
            # to indicate we are done
            if answer == '.' and self.multiple:
                return None
            if self.validate(answer):
                return self.answer()
            else:
                if isinstance(self.validator, list):
                    for v in self.validator:
                        if v.error() != '':
                            print(v.error())
                else:
                    print(self.validator.error())

    def ask(self, answers: Dict = None) -> Dict:
        """ Ask the question, then ask any sub-questions.

            This returns a dict with the {value: answer} pairs for the current
            question plus all descendant questions.
        """
        if answers is None:
            answers = {}
        _answers: Dict = {}
        if self.multiple:
            print((bold('Multiple answers are supported for this question.  ' +
                        'Please enter a "."  character to finish.')))
            _answers[self.value] = []
            answer = self._ask(answers)
            while answer is not None:
                _answers[self.value].append(answer)
                answer = self._ask(answers)
        else:
            _answers[self.value] = self._ask(answers)
        if isinstance(self.validator, list):
            for v in self.validator:
                _answers = dict(_answers, **v.hints())
        else:
            _answers = dict(_answers, **self.validator.hints())
        for q in self._questions:
            answers = dict(answers, **_answers)
            _answers = dict(_answers, **q.ask(answers))
        return _answers

    def validate(self, answer: str) -> bool:
        """ Validate the answer with our Validator(s)

            This will support one or more validator classes being applied to
            this question.  If there are multiple, all validators must return
            True for the answer to be valid.
        """
        if answer is None:
            return False
        else:
            if isinstance(self.validator, list):
                for v in self.validator:
                    if not v.validate(answer):
                        return False
                return True
            else:
                return self.validator.validate(answer)

    def answer(self) -> Dict:
        """ Return the answer for the question from the validator.

            This will ultimately only be called on the first validator if
            multiple validators have been added.
        """
        if isinstance(self.validator, list):
            return self.validator[0].choice()
        return self.validator.choice()

    def choices(self) -> bool:
        """ Print the choices for this question.

            This may be a empty string and in the case of a list of validators
            we will only show the first validator's choices.
        """
        if isinstance(self.validator, list):
            return self.validator[0].print_choices()
        return self.validator.print_choices()

    def add(self, question: 'Question') -> None:
        if isinstance(question, Question):
            self._questions.append(question)
        else:
            # TODO this should raise a less generic exception
            raise Exception

    def remove(self, question: 'Question') -> None:
        if isinstance(question, Question):
            self._questions.remove(question)
        else:
            raise Exception
Ejemplo n.º 4
0
 def test_validate(self):
     v = Validator()
     assert v.validate('') is False
     assert v.error_message is not None
Ejemplo n.º 5
0
class Question(object):

    def __init__(self, question, value, validator=None, multiple=False,
                 printable_name=None):
        """ Basic Question class.

            Supports simple question and answer or question and multiple
            answers (note: list/hash validators have caveats).  Also
            support for one or more Validator classes to ensure the answer
            given meets the question criteria.
        """
        self.question = question
        self.value = value
        self.multiple = multiple
        if printable_name:
            self.printable_name = printable_name
        else:
            self.printable_name = value
        if validator is None:
            self.validator = Validator()
        else:
            self.validator = validator
        self._questions = []

    def __eq__(self, other):
        if self.question == other.question and self.value == other.value:
            return True
        else:
            return False

    def __repr__(self):
        return self.value

    def _ask(self, answers):
        """ Really ask the question.

            We may need to populate multiple validators with answers here.
            Then ask the question and insert the default value if
            appropriate.  Finally call the validate function to check all
            validators for this question and returning the answer.
        """
        if isinstance(self.validator, list):
            for v in self.validator:
                v.answers = answers
        else:
            self.validator.answers = answers
        while(True):
            q = self.question % answers

            if not self.choices():
                return None
            if self.value in answers:
                default = Validator.stringify(answers[self.value])
                answer = raw_input("%s [%s]: " % (q, default))
                if answer == '':
                    answer = answers[self.value]
            else:
                answer = raw_input("%s: " % q)
            # if we are in multiple mode and the answer is just the empty
            # string (enter/return pressed) then we will just answer None
            # to indicate we are done
            if answer == '.' and self.multiple:
                return None
            if self.validate(answer):
                return self.answer()
            else:
                if isinstance(self.validator, list):
                    for v in self.validator:
                        if v.error() != '':
                            print v.error()
                else:
                    print self.validator.error()

    def ask(self, answers=None):
        """ Ask the question, then ask any sub-questions.

            This returns a dict with the {value: answer} pairs for the current
            question plus all decendent questions.
        """
        if answers is None:
            answers = {}
        _answers = {}
        if self.multiple:
            print(bold('Multiple answers are supported for this question.  ' +
                       'Please enter a "."  character to finish.'))
            _answers[self.value] = []
            answer = self._ask(answers)
            while answer is not None:
                _answers[self.value].append(answer)
                answer = self._ask(answers)
        else:
            _answers[self.value] = self._ask(answers)
        if isinstance(self.validator, list):
            for v in self.validator:
                _answers = dict(_answers, **v.hints())
        else:
            _answers = dict(_answers, **self.validator.hints())
        for q in self._questions:
            answers = dict(answers, **_answers)
            _answers = dict(_answers, **q.ask(answers))
        return _answers

    def validate(self, answer):
        """ Validate the answer with our Validator(s)

            This will support one or more validator classes being applied to
            this question.  If there are multiple, all validators must return
            True for the answer to be valid.
        """
        if answer is None:
            return False
        else:
            if isinstance(self.validator, list):
                for v in self.validator:
                    if not v.validate(answer):
                        return False
                return True
            else:
                return self.validator.validate(answer)

    def answer(self):
        """ Return the answer for the question from the validator.

            This will ultimately only be called on the first validator if
            multiple validators have been added.  Since we ultimately we and
            all the validators this should not cause any issues.
        """
        if isinstance(self.validator, list):
            return self.validator[0].choice()
        return self.validator.choice()

    def choices(self):
        """ Print the choices for this question.

            This may be a empty string and in the case of a list of validators
            we will only show the first validator's choices.
        """
        if isinstance(self.validator, list):
            return self.validator[0].print_choices()
        return self.validator.print_choices()

    def add(self, question):
        if isinstance(question, Question):
            self._questions.append(question)
        else:
            raise Exception

    def remove(self, question):
        if isinstance(question, Question):
            self._questions.remove(question)
        else:
            raise Exception