示例#1
0
    def test_safe_eval_error(self):
        test_cases = [TCData("__import__('os')", "_value_")]

        for test_case in test_cases:
            with self.assertRaises(NameError):
                ConditionalAnswer.safe_eval(test_case.input[0],
                                            test_case.input[1])
示例#2
0
    def test_calculate_completion(self):
        test_cases = [
            TCData([], 0),
            TCData(['1', '1', '0'], 1),
            TCData([None, None, None], 0),
            TCData([None, '0', None, '1'], 0.5),
            TCData(['0', None, None, None], 0.25)
        ]

        for test_case in test_cases:
            conditional_answer = ConditionalAnswer(test_case.input, None)
            self.assertEqual(conditional_answer.calculate_completion(),
                             test_case.expected_output)
示例#3
0
    def test_calculate_mark(self):
        test_cases = [
            TCData([True, True, True], 1),
            TCData([False, False, False], 0),
            TCData([True, True, False, False], 0.5),
            TCData([True, False, False, False], 0.25),
            TCData([False, False, True, False], 0.25),
            TCData([False, True, True, False, True, False], 0.5)
        ]

        for test_case in test_cases:
            conditional_answer = ConditionalAnswer(None, test_case.input)
            self.assertEqual(conditional_answer.calculate_mark(),
                             test_case.expected_output)
示例#4
0
    def build_from_data(cls, data):
        # NOTE: A saved submission already has its questions and options ordered (subparts are ALWAYS ordered)
        questions = [QuestionDM.from_data(x) for x in data['questions']]

        answers_data = data['answers']
        assert len(questions) == len(answers_data)

        answers = []  # building a new list to store lists of Answer data models

        for i, answer_data in enumerate(answers_data):
            subparts_answers = []
            assert len(answer_data) == len(questions[i].subparts)

            for j, subpart_answer_data in enumerate(answer_data):
                subpart_answer = None
                subpart_type = questions[i].subparts[j].type

                if subpart_type == HWCentralQuestionType.MCSA:
                    subpart_answer = MCSAQAnswer.from_data(subpart_answer_data)
                elif subpart_type == HWCentralQuestionType.MCMA:
                    subpart_answer = MCMAQAnswer.from_data(subpart_answer_data)
                elif subpart_type == HWCentralQuestionType.NUMERIC:
                    subpart_answer = NumericAnswer.from_data(subpart_answer_data)
                elif subpart_type == HWCentralQuestionType.TEXTUAL:
                    subpart_answer = TextualAnswer.from_data(subpart_answer_data)
                elif subpart_type == HWCentralQuestionType.CONDITIONAL:
                    subpart_answer = ConditionalAnswer.from_data(subpart_answer_data,
                                                                 questions[i].subparts[j].answer.answer_format)
                else:
                    raise InvalidHWCentralQuestionTypeError(subpart_type)

                subparts_answers.append(subpart_answer)
            answers.append(subparts_answers)

        return cls(questions, answers)
示例#5
0
    def test_sanitize_for_eval(self):
        test_cases = [
            TCData('lambda', True),
            TCData('foo\nbar', True),
            TCData('__import__', True),
            TCData('def fun():\n\texit()', True),
            TCData('12*3', False),
            TCData('1.89', False),
            TCData('34/57', False),
            TCData('-56', False),
            TCData('Jawaharlal Nehru', False)
        ]

        for test_case in test_cases:
            if test_case.expected_output:
                with self.assertRaises(EvalSanitizationError):
                    ConditionalAnswer.sanitize_for_eval(test_case.input)
            else:
                self.assertEqual(
                    ConditionalAnswer.sanitize_for_eval(test_case.input),
                    test_case.input)
示例#6
0
    def test_check_answer(self):
        test_cases = [
            TCData((HWCentralConditionalAnswerFormat.NUMERIC, 1,
                    '_value_ < 10', []), [False]),
            TCData((HWCentralConditionalAnswerFormat.NUMERIC, 3,
                    '_value_ < 10', []), [False, False, False]),
            TCData((HWCentralConditionalAnswerFormat.NUMERIC, 3,
                    '_value_ < 10', ['5.1', '3/10', '- 5 / 56']),
                   [True, True, True]),
            TCData((HWCentralConditionalAnswerFormat.NUMERIC, 1,
                    '_value_ < 10', ['11.1']), [False]),
            TCData((HWCentralConditionalAnswerFormat.NUMERIC, 3,
                    '_value_ < 10', [None, '9', None]), [False, True, False]),
            TCData((HWCentralConditionalAnswerFormat.TEXTUAL, 1,
                    '_value_.isupper()', []), [False]),
            TCData((HWCentralConditionalAnswerFormat.TEXTUAL, 3,
                    '_value_.isupper()', []), [False, False, False]),
            TCData((HWCentralConditionalAnswerFormat.TEXTUAL, 3,
                    '_value_.isupper()',
                    [' FOO  BAR\t ', 'BANANA', 'W A T\t\t E   RMELON']),
                   [True, True, True]),
            TCData((HWCentralConditionalAnswerFormat.TEXTUAL, 1,
                    '_value_.isupper()', ['foobar']), [False]),
            TCData((HWCentralConditionalAnswerFormat.TEXTUAL, 3,
                    '_value_.isupper()', [None, '  FU BAR', None]),
                   [False, True, False])
        ]

        for test_case in test_cases:
            subpart_question_mock = NonCallableMagicMock(spec_set=['answer'])
            subpart_question_mock.answer = NonCallableMagicMock(
                spec_set=['answer_format', 'num_answers', 'condition'])
            subpart_question_mock.answer.answer_format = test_case.input[0]
            subpart_question_mock.answer.num_answers = test_case.input[1]
            subpart_question_mock.answer.condition = test_case.input[2]

            conditional_answer = ConditionalAnswer(test_case.input[3], None)
            conditional_answer.check_answer(subpart_question_mock)
            self.assertEqual(conditional_answer.correct,
                             test_case.expected_output)
示例#7
0
    def get_answers(self):
        """
        This method should only be called after validation.
        """
        # go through associated submission data model to find out the expected fields in the form
        # build 2-D answer list for every subpart answer

        answers = [
        ]  # building a new list to store lists of Answer data models

        for i, question in enumerate(self.submission_vm.questions):
            subparts_answers = []
            for j, subpart in enumerate(question.subparts):

                if subpart.type == HWCentralQuestionType.CONDITIONAL:
                    conditional_subpart_answers = []
                    for k in xrange(subpart.answer.num_answers):
                        field_key = SubmissionForm.build_conditional_subfield_key(
                            i, j, k)
                        conditional_subpart_answers.append(
                            self.cleaned_data[field_key])

                    subpart_answer = ConditionalAnswer.from_form_field(
                        conditional_subpart_answers)
                else:
                    field_key = SubmissionForm.build_subpart_field_key(i, j)
                    subpart_answer_data = self.cleaned_data[field_key]

                    if subpart.type == HWCentralQuestionType.MCSA:
                        subpart_answer = MCSAQAnswer.from_form_field(
                            subpart_answer_data)
                    elif subpart.type == HWCentralQuestionType.MCMA:
                        subpart_answer = MCMAQAnswer.from_form_field(
                            subpart_answer_data)
                    elif subpart.type == HWCentralQuestionType.NUMERIC:
                        subpart_answer = NumericAnswer.from_form_field(
                            subpart_answer_data)
                    elif subpart.type == HWCentralQuestionType.TEXTUAL:
                        subpart_answer = TextualAnswer.from_form_field(
                            subpart_answer_data)
                    else:
                        raise InvalidHWCentralQuestionTypeError(subpart.type)

                subparts_answers.append(subpart_answer)
            answers.append(subparts_answers)

        return answers
示例#8
0
    def test_safe_eval(self):
        test_cases = [
            TCData((Decimal(12), '_value_ < 15'), True),
            TCData((Decimal('1.05'), '_value_ - 1 == Decimal(str(0.05))'),
                   True),
            TCData(('foobar', 'len(_value_) > 0'), True),
            TCData(('foobar', '_value_.isupper()'), False),
            TCData((Decimal('1.666'), '_value_ > 1.5 and _value_ < 1.6'),
                   False),
            TCData(('banana', "_value_ in set(['watermelon', 'orange'])"),
                   False)
        ]

        for test_case in test_cases:
            self.assertEqual(
                ConditionalAnswer.safe_eval(test_case.input[0],
                                            test_case.input[1]),
                test_case.expected_output)