Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Unit tests for Accumulative grading strategy logic
  19   *
  20   * @package    workshopform_accumulative
  21   * @category   phpunit
  22   * @copyright  2009 David Mudrak <david.mudrak@gmail.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  // Include the code to test
  29  global $CFG;
  30  require_once($CFG->dirroot . '/mod/workshop/locallib.php');
  31  require_once($CFG->dirroot . '/mod/workshop/form/accumulative/lib.php');
  32  
  33  
  34  class workshop_accumulative_strategy_testcase extends advanced_testcase {
  35      /** workshop instance emulation */
  36      protected $workshop;
  37  
  38      /** @var testable_workshop_accumulative_strategy instance of the strategy logic class being tested */
  39      protected $strategy;
  40  
  41      /**
  42       * Setup testing environment
  43       */
  44      protected function setUp() {
  45          parent::setUp();
  46          $this->resetAfterTest();
  47          $this->setAdminUser();
  48          $course = $this->getDataGenerator()->create_course();
  49          $workshop = $this->getDataGenerator()->create_module('workshop', array('strategy' => 'accumulative', 'course' => $course));
  50          $cm = get_fast_modinfo($course)->instances['workshop'][$workshop->id];
  51          $this->workshop = new workshop($workshop, $cm, $course);
  52          $this->strategy = new testable_workshop_accumulative_strategy($this->workshop);
  53      }
  54  
  55      protected function tearDown() {
  56          $this->workshop = null;
  57          $this->strategy = null;
  58          parent::tearDown();
  59      }
  60  
  61      public function test_calculate_peer_grade_null_grade() {
  62          // fixture set-up
  63          $this->strategy->dimensions = array();
  64          $grades = array();
  65          // exercise SUT
  66          $suggested = $this->strategy->calculate_peer_grade($grades);
  67          // validate
  68          $this->assertNull($suggested);
  69      }
  70  
  71      public function test_calculate_peer_grade_one_numerical() {
  72          // fixture set-up
  73          $this->strategy->dimensions[1003] = (object)array('grade' => '20', 'weight' => '1');
  74          $grades[] = (object)array('dimensionid' => 1003, 'grade' => '5.00000');
  75          // exercise SUT
  76          $suggested = $this->strategy->calculate_peer_grade($grades);
  77          // validate
  78          $this->assertEquals(grade_floatval(5/20 * 100), $suggested);
  79      }
  80  
  81      /**
  82       * @expectedException coding_exception
  83       */
  84      public function test_calculate_peer_grade_negative_weight() {
  85          // fixture set-up
  86          $this->strategy->dimensions[1003] = (object)array('grade' => '20', 'weight' => '-1');
  87          $grades[] = (object)array('dimensionid' => 1003, 'grade' => '20');
  88          // exercise SUT
  89          $suggested = $this->strategy->calculate_peer_grade($grades);
  90      }
  91  
  92      public function test_calculate_peer_grade_one_numerical_weighted() {
  93          // fixture set-up
  94          $this->strategy->dimensions[1003] = (object)array('grade' => '20', 'weight' => '3');
  95          $grades[] = (object)array('dimensionid' => '1003', 'grade' => '5');
  96          // exercise SUT
  97          $suggested = $this->strategy->calculate_peer_grade($grades);
  98          // validate
  99          $this->assertEquals(grade_floatval(5/20 * 100), $suggested);
 100      }
 101  
 102      public function test_calculate_peer_grade_three_numericals_same_weight() {
 103          // fixture set-up
 104          $this->strategy->dimensions[1003] = (object)array('grade' => '20', 'weight' => '2');
 105          $this->strategy->dimensions[1004] = (object)array('grade' => '100', 'weight' => '2');
 106          $this->strategy->dimensions[1005] = (object)array('grade' => '10', 'weight' => '2');
 107          $grades[] = (object)array('dimensionid' => 1003, 'grade' => '11.00000');
 108          $grades[] = (object)array('dimensionid' => 1004, 'grade' => '87.00000');
 109          $grades[] = (object)array('dimensionid' => 1005, 'grade' => '10.00000');
 110  
 111          // exercise SUT
 112          $suggested = $this->strategy->calculate_peer_grade($grades);
 113  
 114          // validate
 115          $this->assertEquals(grade_floatval((11/20 + 87/100 + 10/10)/3 * 100), $suggested);
 116      }
 117  
 118      public function test_calculate_peer_grade_three_numericals_different_weights() {
 119          // fixture set-up
 120          $this->strategy->dimensions[1003] = (object)array('grade' => '15', 'weight' => 3);
 121          $this->strategy->dimensions[1004] = (object)array('grade' => '80', 'weight' => 1);
 122          $this->strategy->dimensions[1005] = (object)array('grade' => '5', 'weight' => 2);
 123          $grades[] = (object)array('dimensionid' => 1003, 'grade' => '7.00000');
 124          $grades[] = (object)array('dimensionid' => 1004, 'grade' => '66.00000');
 125          $grades[] = (object)array('dimensionid' => 1005, 'grade' => '4.00000');
 126  
 127          // exercise SUT
 128          $suggested = $this->strategy->calculate_peer_grade($grades);
 129  
 130          // validate
 131          $this->assertEquals(grade_floatval((7/15*3 + 66/80*1 + 4/5*2)/6 * 100), $suggested);
 132      }
 133  
 134      public function test_calculate_peer_grade_one_scale_max() {
 135          $this->resetAfterTest(true);
 136  
 137          // fixture set-up
 138          $scale11 = $this->getDataGenerator()->create_scale(array('scale'=>'E,D,C,B,A', 'id'=>11));
 139          $this->strategy->dimensions[1008] = (object)array('grade' => (-$scale11->id), 'weight' => 1);
 140          $grades[] = (object)array('dimensionid' => 1008, 'grade' => '5.00000');
 141  
 142          // exercise SUT
 143          $suggested = $this->strategy->calculate_peer_grade($grades);
 144  
 145          // validate
 146          $this->assertEquals(100.00000, $suggested);
 147      }
 148  
 149      public function test_calculate_peer_grade_one_scale_min_with_scale_caching() {
 150          $this->resetAfterTest(true);
 151  
 152          // fixture set-up
 153          $scale11 = $this->getDataGenerator()->create_scale(array('scale'=>'E,D,C,B,A', 'id'=>11));
 154          $this->strategy->dimensions[1008] = (object)array('grade' => (-$scale11->id), 'weight' => 1);
 155          $grades[] = (object)array('dimensionid' => 1008, 'grade' => '1.00000');
 156  
 157          // exercise SUT
 158          $suggested = $this->strategy->calculate_peer_grade($grades);
 159  
 160          // validate
 161          $this->assertEquals(0.00000, $suggested);
 162      }
 163  
 164      public function test_calculate_peer_grade_two_scales_weighted() {
 165          $this->resetAfterTest(true);
 166          // fixture set-up
 167          $scale13 = $this->getDataGenerator()->create_scale(array('scale'=>'Poor,Good,Excellent', 'id'=>13));
 168          $scale17 = $this->getDataGenerator()->create_scale(array('scale'=>'-,*,**,***,****,*****,******', 'id'=>17));
 169          $this->strategy->dimensions[1012] = (object)array('grade' => (-$scale13->id), 'weight' => 2);
 170          $this->strategy->dimensions[1019] = (object)array('grade' => (-$scale17->id), 'weight' => 3);
 171          $grades[] = (object)array('dimensionid' => 1012, 'grade' => '2.00000'); // "Good"
 172          $grades[] = (object)array('dimensionid' => 1019, 'grade' => '5.00000'); // "****"
 173  
 174          // exercise SUT
 175          $suggested = $this->strategy->calculate_peer_grade($grades);
 176  
 177          // validate
 178          $this->assertEquals(grade_floatval((1/2*2 + 4/6*3)/5 * 100), $suggested);
 179      }
 180  
 181      /**
 182       * @expectedException coding_exception
 183       */
 184      public function test_calculate_peer_grade_scale_exception() {
 185          $this->resetAfterTest(true);
 186          // fixture set-up
 187          $scale13 = $this->getDataGenerator()->create_scale(array('scale'=>'Poor,Good,Excellent', 'id'=>13));
 188          $this->strategy->dimensions[1012] = (object)array('grade' => (-$scale13->id), 'weight' => 1);
 189          $grades[] = (object)array('dimensionid' => 1012, 'grade' => '4.00000'); // exceeds the number of scale items
 190  
 191          // Exercise SUT.
 192          $suggested = $this->strategy->calculate_peer_grade($grades);
 193      }
 194  }
 195  
 196  
 197  /**
 198   * Test subclass that makes all the protected methods we want to test public
 199   */
 200  class testable_workshop_accumulative_strategy extends workshop_accumulative_strategy {
 201  
 202      /** allows to set dimensions manually */
 203      public $dimensions = array();
 204  
 205      /**
 206       * This is where the calculation of suggested grade for submission is done
 207       */
 208      public function calculate_peer_grade(array $grades) {
 209          return parent::calculate_peer_grade($grades);
 210      }
 211  }