Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/mod/workshop/allocation/random/simpletest/testallocator.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00027 defined('MOODLE_INTERNAL') || die();
00028 
00029 // Include the code to test
00030 require_once($CFG->dirroot . '/mod/workshop/locallib.php');
00031 require_once($CFG->dirroot . '/mod/workshop/allocation/random/lib.php');
00032 
00036 class testable_workshop_random_allocator extends workshop_random_allocator {
00037     public function self_allocation($authors=array(), $reviewers=array(), $assessments=array()) {
00038         return parent::self_allocation($authors, $reviewers, $assessments);
00039     }
00040     public function get_author_ids($newallocations) {
00041         return parent::get_author_ids($newallocations);
00042     }
00043     public function index_submissions_by_authors($submissions) {
00044         return parent::index_submissions_by_authors($submissions);
00045     }
00046     public function get_unique_allocations($newallocations) {
00047         return parent::get_unique_allocations($newallocations);
00048     }
00049     public function get_unkept_assessments($assessments, $newallocations, $keepselfassessments) {
00050         return parent::get_unkept_assessments($assessments, $newallocations, $keepselfassessments);
00051     }
00052     public function convert_assessments_to_links($assessments) {
00053         return parent::convert_assessments_to_links($assessments);
00054     }
00055     public function get_element_with_lowest_workload($workload) {
00056         return parent::get_element_with_lowest_workload($workload);
00057     }
00058     public function filter_current_assessments(&$newallocations, $assessments) {
00059         return parent::filter_current_assessments($newallocations, $assessments);
00060     }
00061 }
00062 
00063 class workshop_allocation_random_test extends UnitTestCase {
00064 
00066     protected $workshop;
00067 
00069     protected $allocator;
00070 
00071     public function setUp() {
00072         $cm                 = new stdclass();
00073         $course             = new stdclass();
00074         $context            = new stdclass();
00075         $workshop           = (object)array('id' => 42);
00076         $this->workshop     = new workshop($workshop, $cm, $course, $context);
00077         $this->allocator    = new testable_workshop_random_allocator($this->workshop);
00078     }
00079 
00080     public function tearDown() {
00081         $this->allocator    = null;
00082         $this->workshop     = null;
00083     }
00084 
00085     public function test_self_allocation_empty_values() {
00086         // fixture setup & exercise SUT & verify
00087         $this->assertEqual(array(), $this->allocator->self_allocation());
00088     }
00089 
00090     public function test_self_allocation_equal_user_groups() {
00091         // fixture setup
00092         $authors    = array(0 => array_fill_keys(array(4, 6, 10), new stdclass()));
00093         $reviewers  = array(0 => array_fill_keys(array(4, 6, 10), new stdclass()));
00094         // exercise SUT
00095         $newallocations = $this->allocator->self_allocation($authors, $reviewers);
00096         // verify
00097         $this->assertEqual(array(array(4 => 4), array(6 => 6), array(10 => 10)), $newallocations);
00098     }
00099 
00100     public function test_self_allocation_different_user_groups() {
00101         // fixture setup
00102         $authors    = array(0 => array_fill_keys(array(1, 4, 5, 10, 13), new stdclass()));
00103         $reviewers  = array(0 => array_fill_keys(array(4, 7, 10), new stdclass()));
00104         // exercise SUT
00105         $newallocations = $this->allocator->self_allocation($authors, $reviewers);
00106         // verify
00107         $this->assertEqual(array(array(4 => 4), array(10 => 10)), $newallocations);
00108     }
00109 
00110     public function test_self_allocation_skip_existing() {
00111         // fixture setup
00112         $authors        = array(0 => array_fill_keys(array(3, 4, 10), new stdclass()));
00113         $reviewers      = array(0 => array_fill_keys(array(3, 4, 10), new stdclass()));
00114         $assessments    = array(23 => (object)array('authorid' => 3, 'reviewerid' => 3));
00115         // exercise SUT
00116         $newallocations = $this->allocator->self_allocation($authors, $reviewers, $assessments);
00117         // verify
00118         $this->assertEqual(array(array(4 => 4), array(10 => 10)), $newallocations);
00119     }
00120 
00121     public function test_get_author_ids() {
00122         // fixture setup
00123         $newallocations = array(array(1 => 3), array(2 => 1), array(3 => 1));
00124         // exercise SUT & verify
00125         $this->assertEqual(array(3, 1), $this->allocator->get_author_ids($newallocations));
00126     }
00127 
00128     public function test_index_submissions_by_authors() {
00129         // fixture setup
00130         $submissions = array(
00131                 676 => (object)array('id' => 676, 'authorid' => 23),
00132                 121 => (object)array('id' => 121, 'authorid' => 56),
00133                 );
00134         // exercise SUT
00135         $submissions = $this->allocator->index_submissions_by_authors($submissions);
00136         // verify
00137         $this->assertEqual(array(
00138                 23 => (object)array('id' => 676, 'authorid' => 23),
00139                 56 => (object)array('id' => 121, 'authorid' => 56),
00140                 ), $submissions);
00141     }
00142 
00143     public function test_index_submissions_by_authors_duplicate_author() {
00144         // fixture setup
00145         $submissions = array(
00146                 14 => (object)array('id' => 676, 'authorid' => 3),
00147                 87 => (object)array('id' => 121, 'authorid' => 3),
00148                 );
00149         // set expectation
00150         $this->expectException('moodle_exception');
00151         // exercise SUT
00152         $submissions = $this->allocator->index_submissions_by_authors($submissions);
00153     }
00154 
00155     public function test_get_unique_allocations() {
00156         // fixture setup
00157         $newallocations = array(array(4 => 5), array(6 => 6), array(1 => 16), array(4 => 5), array(16 => 1));
00158         // exercise SUT
00159         $newallocations = $this->allocator->get_unique_allocations($newallocations);
00160         // verify
00161         $this->assertEqual(array(array(4 => 5), array(6 => 6), array(1 => 16), array(16 => 1)), $newallocations);
00162     }
00163 
00164     public function test_get_unkept_assessments_no_keep_selfassessments() {
00165         // fixture setup
00166         $assessments = array(
00167                 23 => (object)array('authorid' => 3, 'reviewerid' => 3),
00168                 45 => (object)array('authorid' => 5, 'reviewerid' => 11),
00169                 12 => (object)array('authorid' => 6, 'reviewerid' => 3),
00170                 );
00171         $newallocations = array(array(4 => 5), array(11 => 5), array(1 => 16), array(4 => 5), array(16 => 1));
00172         // exercise SUT
00173         $delassessments = $this->allocator->get_unkept_assessments($assessments, $newallocations, false);
00174         // verify
00175         // we want to keep $assessments[45] because it has been re-allocated
00176         $this->assertEqual(array(23, 12), $delassessments);
00177     }
00178 
00179     public function test_get_unkept_assessments_keep_selfassessments() {
00180         // fixture setup
00181         $assessments = array(
00182                 23 => (object)array('authorid' => 3, 'reviewerid' => 3),
00183                 45 => (object)array('authorid' => 5, 'reviewerid' => 11),
00184                 12 => (object)array('authorid' => 6, 'reviewerid' => 3),
00185                 );
00186         $newallocations = array(array(4 => 5), array(11 => 5), array(1 => 16), array(4 => 5), array(16 => 1));
00187         // exercise SUT
00188         $delassessments = $this->allocator->get_unkept_assessments($assessments, $newallocations, true);
00189         // verify
00190         // we want to keep $assessments[45] because it has been re-allocated
00191         // we want to keep $assessments[23] because if is self assessment
00192         $this->assertEqual(array(12), $delassessments);
00193     }
00194 
00198     public function test_convert_assessments_to_links() {
00199         // fixture setup
00200         $assessments = array(
00201                 23 => (object)array('authorid' => 3, 'reviewerid' => 3),
00202                 45 => (object)array('authorid' => 5, 'reviewerid' => 11),
00203                 12 => (object)array('authorid' => 5, 'reviewerid' => 3),
00204                 );
00205         // exercise SUT
00206         list($authorlinks, $reviewerlinks) = $this->allocator->convert_assessments_to_links($assessments);
00207         // verify
00208         $this->assertEqual(array(3 => array(3), 5 => array(11, 3)), $authorlinks);
00209         $this->assertEqual(array(3 => array(3, 5), 11 => array(5)), $reviewerlinks);
00210     }
00211 
00215     public function test_convert_assessments_to_links_empty() {
00216         // fixture setup
00217         $assessments = array();
00218         // exercise SUT
00219         list($authorlinks, $reviewerlinks) = $this->allocator->convert_assessments_to_links($assessments);
00220         // verify
00221         $this->assertEqual(array(), $authorlinks);
00222         $this->assertEqual(array(), $reviewerlinks);
00223     }
00224 
00228     public function test_get_element_with_lowest_workload_deterministic() {
00229         // fixture setup
00230         $workload = array(4 => 6, 9 => 1, 10 => 2);
00231         // exercise SUT
00232         $chosen = $this->allocator->get_element_with_lowest_workload($workload);
00233         // verify
00234         $this->assertEqual(9, $chosen);
00235     }
00236 
00240     public function test_get_element_with_lowest_workload_impossible() {
00241         // fixture setup
00242         $workload = array();
00243         // exercise SUT
00244         $chosen = $this->allocator->get_element_with_lowest_workload($workload);
00245         // verify
00246         $this->assertTrue($chosen === false);
00247     }
00248 
00252     public function test_get_element_with_lowest_workload_random() {
00253         // fixture setup
00254         $workload = array(4 => 6, 9 => 2, 10 => 2);
00255         // exercise SUT
00256         $elements = $this->allocator->get_element_with_lowest_workload($workload);
00257         // verify
00258         // in theory, this test can fail even if the function works well. However, the probability of getting
00259         // a row of a hundred same ids in this use case is 1/pow(2, 100)
00260         // also, this just tests that each of the two elements has been chosen at least once. this is not to
00261         // measure the quality or randomness of the algorithm
00262         $counts = array(4 => 0, 9 => 0, 10 => 0);
00263         for ($i = 0; $i < 100; $i++) {
00264             $chosen = $this->allocator->get_element_with_lowest_workload($workload);
00265             if (!in_array($chosen, array(4, 9, 10))) {
00266                 $this->fail('Invalid element ' . var_export($chosen, true) . ' chosen');
00267                 break;
00268             } else {
00269                 $counts[$this->allocator->get_element_with_lowest_workload($workload)]++;
00270             }
00271         }
00272         $this->assertTrue(($counts[9] > 0) && ($counts[10] > 0));
00273     }
00274 
00280     public function test_get_element_with_lowest_workload_random_floats() {
00281         // fixture setup
00282         $workload = array(1 => 1/13, 2 => 0.0769230769231); // should be considered as the same value
00283         // exercise SUT
00284         $elements = $this->allocator->get_element_with_lowest_workload($workload);
00285         // verify
00286         $counts = array(1 => 0, 2 => 0);
00287         for ($i = 0; $i < 100; $i++) {
00288             $chosen = $this->allocator->get_element_with_lowest_workload($workload);
00289             if (!in_array($chosen, array(1, 2))) {
00290                 $this->fail('Invalid element ' . var_export($chosen, true) . ' chosen');
00291                 break;
00292             } else {
00293                 $counts[$this->allocator->get_element_with_lowest_workload($workload)]++;
00294             }
00295         }
00296         $this->assertTrue(($counts[1] > 0) && ($counts[2] > 0));
00297 
00298     }
00299 
00303     public function test_filter_current_assessments() {
00304         // fixture setup
00305         $newallocations = array(array(3 => 5), array(11 => 5), array(2 => 9), array(3 => 5));
00306         $assessments = array(
00307                 23 => (object)array('authorid' => 3, 'reviewerid' => 3),
00308                 45 => (object)array('authorid' => 5, 'reviewerid' => 11),
00309                 12 => (object)array('authorid' => 5, 'reviewerid' => 3),
00310                 );
00311         // exercise SUT
00312         $this->allocator->filter_current_assessments($newallocations, $assessments);
00313         // verify
00314         $this->assertEqual(array_values($newallocations), array(array(2 => 9)));
00315     }
00316 
00317 
00318 }
 All Data Structures Namespaces Files Functions Variables Enumerations