diff --git a/tests/helper.php b/tests/helper.php index 34c780e9f07957220b4e68128fb54a4724661bc0..d28a605af4ba7233624f5aa91b902f09697dfd48 100644 --- a/tests/helper.php +++ b/tests/helper.php @@ -73,6 +73,7 @@ class qtype_stack_test_helper extends question_test_helper { 'validator', // Test teacher-defined input validators and language. 'feedback', // Test teacher-defined input feedback and complex numbers. 'ordergreat', // Test the ordergreat function at the question level, e.g. keyvals. + 'exdowncase', // Test the ordergreat function with exdowncase. // Test questions for all the various input types. 'algebraic_input', 'algebraic_input_right', @@ -4096,6 +4097,94 @@ class qtype_stack_test_helper extends question_test_helper { return $q; } + /** + * @return qtype_stack_question. + */ + public static function make_stack_question_exdowncase() { + $q = self::make_a_stack_question(); + + $q->name = 'exdowncase'; + $q->questionvariables = "ordergreat(x);\nveq: 5*y^2-8*x*y+13*x^2 = 49;"; + $q->questiontext = "What is {@veq@}? [[input:ansq]][[validation:ansq]]"; + $q->generalfeedback = ''; + $q->questionnote = ''; + + $q->specificfeedback = '[[feedback:firsttree]]'; + $q->penalty = 0.25; // Non-zero and not the default. + + $q->inputs['ansq'] = stack_input_factory::make( + 'algebraic', 'ansq', 'veq', null, + [ + 'boxWidth' => 20, 'forbidWords' => '' + ]); + + // By setting simp:true (the default) we check the re-ordering really happens. + $q->options->set_option('simplify', true); + + $prt = new stdClass; + $prt->name = 'firsttree'; + $prt->id = 0; + $prt->value = 1; + $prt->feedbackstyle = 1; + $prt->feedbackvariables = 'loweranseq:exdowncase(ansq);'; + $prt->firstnodename = '0'; + $prt->nodes = []; + $prt->autosimplify = true; + + $newnode = new stdClass; + $newnode->id = '0'; + $newnode->nodename = '0'; + $newnode->description = 'Use CasEqual as the test'; + $newnode->sans = 'loweranseq'; + $newnode->tans = 'veq'; + $newnode->answertest = 'CasEqual'; + $newnode->testoptions = ''; + $newnode->quiet = false; + $newnode->falsescore = '0'; + $newnode->falsescoremode = '='; + $newnode->falsepenalty = $q->penalty; + $newnode->falsefeedback = ""; + $newnode->falsefeedbackformat = '1'; + $newnode->falseanswernote = 'firsttree-0-0'; + $newnode->falsenextnode = '1'; + $newnode->truescore = '1'; + $newnode->truescoremode = '='; + $newnode->truepenalty = $q->penalty; + $newnode->truefeedback = ""; + $newnode->truefeedbackformat = '1'; + $newnode->trueanswernote = 'firsttree-0-1'; + $newnode->truenextnode = '1'; + $prt->nodes[] = $newnode; + $newnode = new stdClass; + $newnode->id = '1'; + $newnode->nodename = '1'; + $newnode->description = 'Use AlgEquiv as the test'; + $newnode->sans = 'loweranseq'; + $newnode->tans = 'veq'; + $newnode->answertest = 'AlgEquiv'; + $newnode->testoptions = ''; + $newnode->quiet = false; + $newnode->falsescore = '0'; + $newnode->falsescoremode = '='; + $newnode->falsepenalty = $q->penalty; + $newnode->falsefeedback = ""; + $newnode->falsefeedbackformat = '1'; + $newnode->falseanswernote = 'firsttree-1-0'; + $newnode->falsenextnode = '-1'; + $newnode->truescore = '1'; + $newnode->truescoremode = '='; + $newnode->truepenalty = $q->penalty; + $newnode->truefeedback = ""; + $newnode->truefeedbackformat = '1'; + $newnode->trueanswernote = 'firsttree-1-1'; + $newnode->truenextnode = '-1'; + $prt->nodes[] = $newnode; + + $q->prts[$prt->name] = new stack_potentialresponse_tree_lite($prt, $prt->value, $q); + + return $q; + } + /** * Make the data what would be received from the editing form for an algebraic input question. * diff --git a/tests/walkthrough_adaptive_test.php b/tests/walkthrough_adaptive_test.php index b99dfb128fc4589f6176315ded43bb4000baf39a..7bef19bec6345763593b3c27c974c374d00fbccb 100644 --- a/tests/walkthrough_adaptive_test.php +++ b/tests/walkthrough_adaptive_test.php @@ -4818,4 +4818,73 @@ class walkthrough_adaptive_test extends qtype_stack_walkthrough_test_base { $expected = 'Seed: 1; ansq: 3*x+5*y=1 [score]; firsttree: # = 1 | ATCASEqual_true. | firsttree-0-1'; $this->check_response_summary($expected); } + + public function test_input_validator_exdowncase() { + $q = test_question_maker::make_question('stack', 'exdowncase'); + $this->start_attempt_at_question($q, 'adaptive', 1); + + // Check the initial state. + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $this->check_prt_score('firsttree', null, null); + $this->render(); + $this->check_output_contains_text_input('ansq'); + $this->check_output_does_not_contain_input_validation(); + $this->check_output_does_not_contain_prt_feedback(); + $this->check_output_does_not_contain_stray_placeholders(); + $this->check_current_output( + new question_pattern_expectation('/What is/'), + $this->get_does_not_contain_feedback_expectation(), + $this->get_does_not_contain_num_parts_correct(), + $this->get_no_hint_visible_expectation() + ); + $this->assert_content_with_maths_contains('\({13\cdot x^2-8\cdot y\cdot x+5\cdot y^2=49}\)', + $this->currentoutput); + + // Process a validate request. + $ia = '13*x^2-8*y*x+5*y^2 = 49'; + $this->process_submission(['ansq' => $ia, '-submit' => 1]); + + $this->check_current_mark(null); + $this->check_prt_score('firsttree', null, null); + $this->render(); + + // Check order of variables in validation of answer matches what students type. + $expected = 'Seed: 1; ansq: 13*x^2-8*y*x+5*y^2 = 49 [valid]; firsttree: !'; + $this->check_response_summary($expected); + $this->check_output_contains_text_input('ansq', $ia); + $this->check_output_contains_input_validation('ansq'); + $this->check_output_does_not_contain_prt_feedback(); + $this->check_output_does_not_contain_stray_placeholders(); + $this->assert_content_with_maths_contains('\[ 13\cdot x^2-8\cdot y\cdot x+5\cdot y^2=49', + $this->currentoutput); + $ia = '13*x^2-8*y*x+5*y^2 = 49'; + $this->process_submission(['ansq' => $ia, 'ansq_val' => $ia, '-submit' => 1]); + $this->render(); + $this->assert_content_with_maths_contains('\[ 13\cdot x^2-8\cdot y\cdot x+5\cdot y^2=49', + $this->currentoutput); + $expected = 'Seed: 1; ansq: 13*x^2-8*y*x+5*y^2 = 49 [score]; firsttree: # = 1 | ' . + 'ATCASEqual_true. | firsttree-0-1 | ATEquation_sides | firsttree-1-1'; + $this->check_response_summary($expected); + + // New answer with upper case. + $ia = '13*X^2-8*y*x+5*y^2 = 49'; + $this->process_submission(['ansq' => $ia, 'ansq_val' => $ia, '-submit' => 1]); + $this->render(); + $this->assert_content_with_maths_contains('\[ 13\cdot X^2-8\cdot y\cdot x+5\cdot y^2=49', + $this->currentoutput); + $expected = 'Seed: 1; ansq: 13*X^2-8*y*x+5*y^2 = 49 [score]; firsttree: # = 1 | ' . + 'ATCASEqual_true. | firsttree-0-1 | ATEquation_sides | firsttree-1-1'; + $this->check_response_summary($expected); + + // New answer which is wrong. + $ia = '13*X^2-8*y*x+5*y^2 = 48'; + $this->process_submission(['ansq' => $ia, 'ansq_val' => $ia, '-submit' => 1]); + $this->render(); + $this->assert_content_with_maths_contains('\[ 13\cdot X^2-8\cdot y\cdot x+5\cdot y^2=48', + $this->currentoutput); + $expected = 'Seed: 1; ansq: 13*X^2-8*y*x+5*y^2 = 48 [score]; firsttree: # = 0 | ' . + 'ATCASEqual_false. | firsttree-0-0 | ATEquation_lhs_notrhs | firsttree-1-0'; + $this->check_response_summary($expected); + } }