From 85be8375c7483898cefb4fd6dbbb752922dde573 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 22 Dec 2011 18:02:24 +0000 Subject: [PATCH] MDL-30766 mod_quiz: fix edge cases of repaginate function. --- mod/quiz/locallib.php | 27 ++++++++++++++--------- mod/quiz/simpletest/testlocallib.php | 32 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index 3d4858133ec..21b5aaf7a4e 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -246,22 +246,29 @@ function quiz_number_of_questions_in_quiz($layout) { * @return string the new layout string */ function quiz_repaginate($layout, $perpage, $shuffle = false) { - $layout = str_replace(',0', '', $layout); // remove existing page breaks - $questions = explode(',', $layout); + $questions = quiz_questions_in_quiz($layout); + if (!$questions) { + return '0'; + } + + $questions = explode(',', quiz_questions_in_quiz($layout)); if ($shuffle) { shuffle($questions); } - $i = 1; - $layout = ''; + + $onthispage = 0; + $layout = array(); foreach ($questions as $question) { - if ($perpage and $i > $perpage) { - $layout .= '0,'; - $i = 1; + if ($perpage and $onthispage >= $perpage) { + $layout[] = 0; + $onthispage = 0; } - $layout .= $question.','; - $i++; + $layout[] = $question; + $onthispage += 1; } - return $layout.'0'; + + $layout[] = 0; + return implode(',', $layout); } /// Functions to do with quiz grades ////////////////////////////////////////// diff --git a/mod/quiz/simpletest/testlocallib.php b/mod/quiz/simpletest/testlocallib.php index 25d0e032cea..13117e1394a 100644 --- a/mod/quiz/simpletest/testlocallib.php +++ b/mod/quiz/simpletest/testlocallib.php @@ -96,6 +96,38 @@ class quiz_locallib_test extends UnitTestCase { $this->assertEqual(quiz_clean_layout('0,1,0,0,2,0', true), '1,0,2,0'); } + public function test_quiz_repaginate() { + // Test starting with 1 question per page. + $this->assertEqual(quiz_repaginate('1,0,2,0,3,0', 0), '1,2,3,0'); + $this->assertEqual(quiz_repaginate('1,0,2,0,3,0', 3), '1,2,3,0'); + $this->assertEqual(quiz_repaginate('1,0,2,0,3,0', 2), '1,2,0,3,0'); + $this->assertEqual(quiz_repaginate('1,0,2,0,3,0', 1), '1,0,2,0,3,0'); + + // Test starting with all on one page page. + $this->assertEqual(quiz_repaginate('1,2,3,0', 0), '1,2,3,0'); + $this->assertEqual(quiz_repaginate('1,2,3,0', 3), '1,2,3,0'); + $this->assertEqual(quiz_repaginate('1,2,3,0', 2), '1,2,0,3,0'); + $this->assertEqual(quiz_repaginate('1,2,3,0', 1), '1,0,2,0,3,0'); + + // Test single question case. + $this->assertEqual(quiz_repaginate('100,0', 0), '100,0'); + $this->assertEqual(quiz_repaginate('100,0', 1), '100,0'); + + // No questions case. + $this->assertEqual(quiz_repaginate('0', 0), '0'); + + // Test empty pages are removed. + $this->assertEqual(quiz_repaginate('1,2,3,0,0,0', 0), '1,2,3,0'); + $this->assertEqual(quiz_repaginate('1,0,0,0,2,3,0', 0), '1,2,3,0'); + $this->assertEqual(quiz_repaginate('0,0,0,1,2,3,0', 0), '1,2,3,0'); + + // Test shuffle option. + $this->assertTrue(in_array(quiz_repaginate('1,2,0', 0, true), + array('1,2,0', '2,1,0'))); + $this->assertTrue(in_array(quiz_repaginate('1,2,0', 1, true), + array('1,0,2,0', '2,0,1,0'))); + } + public function test_quiz_rescale_grade() { $quiz = new stdClass(); $quiz->decimalpoints = 2;