[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 * @package core_grades 19 * @category phpunit 20 * @copyright [email protected] 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 */ 23 24 defined('MOODLE_INTERNAL') || die(); 25 26 require_once (__DIR__.'/fixtures/lib.php'); 27 28 29 class core_grade_category_testcase extends grade_base_testcase { 30 31 public function test_grade_category() { 32 $this->sub_test_grade_category_construct(); 33 $this->sub_test_grade_category_build_path(); 34 $this->sub_test_grade_category_fetch(); 35 $this->sub_test_grade_category_fetch_all(); 36 $this->sub_test_grade_category_update(); 37 $this->sub_test_grade_category_delete(); 38 $this->sub_test_grade_category_insert(); 39 $this->sub_test_grade_category_qualifies_for_regrading(); 40 $this->sub_test_grade_category_force_regrading(); 41 $this->sub_test_grade_category_aggregate_grades(); 42 $this->sub_test_grade_category_apply_limit_rules(); 43 $this->sub_test_grade_category_is_aggregationcoef_used(); 44 $this->sub_test_grade_category_aggregation_uses_aggregationcoef(); 45 $this->sub_test_grade_category_fetch_course_tree(); 46 $this->sub_test_grade_category_get_children(); 47 $this->sub_test_grade_category_load_grade_item(); 48 $this->sub_test_grade_category_get_grade_item(); 49 $this->sub_test_grade_category_load_parent_category(); 50 $this->sub_test_grade_category_get_parent_category(); 51 $this->sub_test_grade_category_get_name(); 52 $this->sub_test_grade_category_set_parent(); 53 $this->sub_test_grade_category_get_final(); 54 $this->sub_test_grade_category_get_sortorder(); 55 $this->sub_test_grade_category_set_sortorder(); 56 $this->sub_test_grade_category_is_editable(); 57 $this->sub_test_grade_category_move_after_sortorder(); 58 $this->sub_test_grade_category_is_course_category(); 59 $this->sub_test_grade_category_fetch_course_category(); 60 $this->sub_test_grade_category_is_locked(); 61 $this->sub_test_grade_category_set_locked(); 62 $this->sub_test_grade_category_is_hidden(); 63 $this->sub_test_grade_category_set_hidden(); 64 $this->sub_test_grade_category_can_control_visibility(); 65 66 // This won't work until MDL-11837 is complete. 67 // $this->sub_test_grade_category_generate_grades(); 68 69 // Do this last as adding a second course category messes up the data. 70 $this->sub_test_grade_category_insert_course_category(); 71 $this->sub_test_grade_category_is_extracredit_used(); 72 $this->sub_test_grade_category_aggregation_uses_extracredit(); 73 } 74 75 // Adds 3 new grade categories at various depths. 76 protected function sub_test_grade_category_construct() { 77 $course_category = grade_category::fetch_course_category($this->courseid); 78 79 $params = new stdClass(); 80 81 $params->courseid = $this->courseid; 82 $params->fullname = 'unittestcategory4'; 83 84 $grade_category = new grade_category($params, false); 85 $grade_category->insert(); 86 $this->grade_categories[] = $grade_category; 87 88 $this->assertEquals($params->courseid, $grade_category->courseid); 89 $this->assertEquals($params->fullname, $grade_category->fullname); 90 $this->assertEquals(2, $grade_category->depth); 91 $this->assertEquals("/$course_category->id/$grade_category->id/", $grade_category->path); 92 $parentpath = $grade_category->path; 93 94 // Test a child category. 95 $params->parent = $grade_category->id; 96 $params->fullname = 'unittestcategory5'; 97 $grade_category = new grade_category($params, false); 98 $grade_category->insert(); 99 $this->grade_categories[] = $grade_category; 100 101 $this->assertEquals(3, $grade_category->depth); 102 $this->assertEquals($parentpath.$grade_category->id."/", $grade_category->path); 103 $parentpath = $grade_category->path; 104 105 // Test a third depth category. 106 $params->parent = $grade_category->id; 107 $params->fullname = 'unittestcategory6'; 108 $grade_category = new grade_category($params, false); 109 $grade_category->insert(); 110 $this->grade_categories[50] = $grade_category;// Going to delete this one later hence the special index. 111 112 $this->assertEquals(4, $grade_category->depth); 113 $this->assertEquals($parentpath.$grade_category->id."/", $grade_category->path); 114 } 115 116 protected function sub_test_grade_category_build_path() { 117 $grade_category = new grade_category($this->grade_categories[1]); 118 $this->assertTrue(method_exists($grade_category, 'build_path')); 119 $path = grade_category::build_path($grade_category); 120 $this->assertEquals($grade_category->path, $path); 121 } 122 123 protected function sub_test_grade_category_fetch() { 124 $grade_category = new grade_category(); 125 $this->assertTrue(method_exists($grade_category, 'fetch')); 126 127 $grade_category = grade_category::fetch(array('id'=>$this->grade_categories[0]->id)); 128 $this->assertEquals($this->grade_categories[0]->id, $grade_category->id); 129 $this->assertEquals($this->grade_categories[0]->fullname, $grade_category->fullname); 130 } 131 132 protected function sub_test_grade_category_fetch_all() { 133 $grade_category = new grade_category(); 134 $this->assertTrue(method_exists($grade_category, 'fetch_all')); 135 136 $grade_categories = grade_category::fetch_all(array('courseid'=>$this->courseid)); 137 $this->assertEquals(count($this->grade_categories), count($grade_categories)-1); 138 } 139 140 protected function sub_test_grade_category_update() { 141 global $DB; 142 $grade_category = new grade_category($this->grade_categories[0]); 143 $this->assertTrue(method_exists($grade_category, 'update')); 144 145 $grade_category->fullname = 'Updated info for this unittest grade_category'; 146 $grade_category->path = null; // Path must be recalculated if missing. 147 $grade_category->depth = null; 148 $grade_category->aggregation = GRADE_AGGREGATE_MAX; // Should force regrading. 149 150 $grade_item = $grade_category->get_grade_item(); 151 $this->assertEquals(0, $grade_item->needsupdate); 152 153 $this->assertTrue($grade_category->update()); 154 155 $fullname = $DB->get_field('grade_categories', 'fullname', array('id' => $this->grade_categories[0]->id)); 156 $this->assertEquals($grade_category->fullname, $fullname); 157 158 $path = $DB->get_field('grade_categories', 'path', array('id' => $this->grade_categories[0]->id)); 159 $this->assertEquals($grade_category->path, $path); 160 161 $depth = $DB->get_field('grade_categories', 'depth', array('id' => $this->grade_categories[0]->id)); 162 $this->assertEquals($grade_category->depth, $depth); 163 164 $grade_item = $grade_category->get_grade_item(); 165 $this->assertEquals(1, $grade_item->needsupdate); 166 } 167 168 protected function sub_test_grade_category_delete() { 169 global $DB; 170 171 $grade_category = new grade_category($this->grade_categories[50]); 172 $this->assertTrue(method_exists($grade_category, 'delete')); 173 174 $this->assertTrue($grade_category->delete()); 175 $this->assertFalse($DB->get_record('grade_categories', array('id' => $grade_category->id))); 176 } 177 178 protected function sub_test_grade_category_insert() { 179 $course_category = grade_category::fetch_course_category($this->courseid); 180 181 $grade_category = new grade_category(); 182 $this->assertTrue(method_exists($grade_category, 'insert')); 183 184 $grade_category->fullname = 'unittestcategory4'; 185 $grade_category->courseid = $this->courseid; 186 $grade_category->aggregation = GRADE_AGGREGATE_MEAN; 187 $grade_category->aggregateonlygraded = 1; 188 $grade_category->keephigh = 100; 189 $grade_category->droplow = 10; 190 $grade_category->hidden = 0; 191 $grade_category->parent = $this->grade_categories[1]->id; // sub_test_grade_category_delete() removed the category at 0. 192 193 $grade_category->insert(); 194 195 $this->assertEquals('/'.$course_category->id.'/'.$this->grade_categories[1]->parent.'/'.$this->grade_categories[1]->id.'/'.$grade_category->id.'/', $grade_category->path); 196 $this->assertEquals(4, $grade_category->depth); 197 198 $last_grade_category = end($this->grade_categories); 199 200 $this->assertFalse(empty($grade_category->grade_item)); 201 $this->assertEquals($grade_category->id, $grade_category->grade_item->iteminstance); 202 $this->assertEquals('category', $grade_category->grade_item->itemtype); 203 204 $this->assertEquals($grade_category->id, $last_grade_category->id + 1); 205 $this->assertFalse(empty($grade_category->timecreated)); 206 $this->assertFalse(empty($grade_category->timemodified)); 207 } 208 209 protected function sub_test_grade_category_qualifies_for_regrading() { 210 $grade_category = new grade_category($this->grade_categories[1]); 211 $this->assertTrue(method_exists($grade_category, 'qualifies_for_regrading')); 212 $this->assertFalse($grade_category->qualifies_for_regrading()); 213 214 $grade_category->aggregation = GRADE_AGGREGATE_MAX; 215 $this->assertTrue($grade_category->qualifies_for_regrading()); 216 217 $grade_category = new grade_category($this->grade_categories[1]); 218 $grade_category->droplow = 99; 219 $this->assertTrue($grade_category->qualifies_for_regrading()); 220 221 $grade_category = new grade_category($this->grade_categories[1]); 222 $grade_category->keephigh = 99; 223 $this->assertTrue($grade_category->qualifies_for_regrading()); 224 } 225 226 protected function sub_test_grade_category_force_regrading() { 227 $grade_category = new grade_category($this->grade_categories[1]); 228 $this->assertTrue(method_exists($grade_category, 'force_regrading')); 229 230 $grade_category->load_grade_item(); 231 $this->assertEquals(0, $grade_category->grade_item->needsupdate); 232 233 $grade_category->force_regrading(); 234 235 $grade_category->grade_item = null; 236 $grade_category->load_grade_item(); 237 238 $this->assertEquals(1, $grade_category->grade_item->needsupdate); 239 } 240 241 /** 242 * Tests the calculation of grades using the various aggregation methods with and without hidden grades 243 * This will not work entirely until MDL-11837 is done 244 */ 245 protected function sub_test_grade_category_generate_grades() { 246 global $DB; 247 248 // Inserting some special grade items to make testing the final grade calculation easier. 249 $params = new stdClass(); 250 $params->courseid = $this->courseid; 251 $params->fullname = 'unittestgradecalccategory'; 252 $params->aggregation = GRADE_AGGREGATE_MEAN; 253 $params->aggregateonlygraded = 0; 254 $grade_category = new grade_category($params, false); 255 $grade_category->insert(); 256 257 $this->assertTrue(method_exists($grade_category, 'generate_grades')); 258 259 $grade_category->load_grade_item(); 260 $cgi = $grade_category->get_grade_item(); 261 $cgi->grademin = 0; 262 $cgi->grademax = 20; // 3 grade items out of 10 but category is out of 20 to force scaling to occur. 263 $cgi->update(); 264 265 // 3 grade items each with a maximum grade of 10. 266 $grade_items = array(); 267 for ($i=0; $i<3; $i++) { 268 $grade_items[$i] = new grade_item(); 269 $grade_items[$i]->courseid = $this->courseid; 270 $grade_items[$i]->categoryid = $grade_category->id; 271 $grade_items[$i]->itemname = 'manual grade_item '.$i; 272 $grade_items[$i]->itemtype = 'manual'; 273 $grade_items[$i]->itemnumber = 0; 274 $grade_items[$i]->needsupdate = false; 275 $grade_items[$i]->gradetype = GRADE_TYPE_VALUE; 276 $grade_items[$i]->grademin = 0; 277 $grade_items[$i]->grademax = 10; 278 $grade_items[$i]->iteminfo = 'Manual grade item used for unit testing'; 279 $grade_items[$i]->timecreated = time(); 280 $grade_items[$i]->timemodified = time(); 281 282 // Used as the weight by weighted mean and as extra credit by mean with extra credit. 283 // Will be 0, 1 and 2. 284 $grade_items[$i]->aggregationcoef = $i; 285 286 $grade_items[$i]->insert(); 287 } 288 289 // A grade for each grade item. 290 $grade_grades = array(); 291 for ($i=0; $i<3; $i++) { 292 $grade_grades[$i] = new grade_grade(); 293 $grade_grades[$i]->itemid = $grade_items[$i]->id; 294 $grade_grades[$i]->userid = $this->userid; 295 $grade_grades[$i]->rawgrade = ($i+1)*2; // Produce grade grades of 2, 4 and 6. 296 $grade_grades[$i]->finalgrade = ($i+1)*2; 297 $grade_grades[$i]->timecreated = time(); 298 $grade_grades[$i]->timemodified = time(); 299 $grade_grades[$i]->information = '1 of 2 grade_grades'; 300 $grade_grades[$i]->informationformat = FORMAT_PLAIN; 301 $grade_grades[$i]->feedback = 'Good, but not good enough..'; 302 $grade_grades[$i]->feedbackformat = FORMAT_PLAIN; 303 304 $grade_grades[$i]->insert(); 305 } 306 307 // 3 grade items with 1 grade_grade each. 308 // grade grades have the values 2, 4 and 6. 309 310 // First correct answer is the aggregate with all 3 grades. 311 // Second correct answer is with the first grade (value 2) hidden. 312 313 $this->helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, GRADE_AGGREGATE_MEDIAN, 'GRADE_AGGREGATE_MEDIAN', 8, 8); 314 $this->helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, GRADE_AGGREGATE_MAX, 'GRADE_AGGREGATE_MAX', 12, 12); 315 $this->helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, GRADE_AGGREGATE_MODE, 'GRADE_AGGREGATE_MODE', 12, 12); 316 317 // Weighted mean. note grade totals are rounded to an int to prevent rounding discrepancies. correct final grade isnt actually exactly 10 318 // 3 items with grades 2, 4 and 6 with weights 0, 1 and 2 and all out of 10. then doubled to be out of 20. 319 $this->helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, GRADE_AGGREGATE_WEIGHTED_MEAN, 'GRADE_AGGREGATE_WEIGHTED_MEAN', 10, 10); 320 321 // Simple weighted mean. 322 // 3 items with grades 2, 4 and 6 equally weighted and all out of 10. then doubled to be out of 20. 323 $this->helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, GRADE_AGGREGATE_WEIGHTED_MEAN2, 'GRADE_AGGREGATE_WEIGHTED_MEAN2', 8, 10); 324 325 // Mean of grades with extra credit. 326 // 3 items with grades 2, 4 and 6 with extra credit 0, 1 and 2 equally weighted and all out of 10. then doubled to be out of 20. 327 $this->helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, GRADE_AGGREGATE_EXTRACREDIT_MEAN, 'GRADE_AGGREGATE_EXTRACREDIT_MEAN', 10, 13); 328 329 // Aggregation tests the are affected by a hidden grade currently dont work as we dont store the altered grade in the database 330 // instead an in memory recalculation is done. This should be remedied by MDL-11837. 331 332 // Fails with 1 grade hidden. still reports 8 as being correct. 333 $this->helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, GRADE_AGGREGATE_MEAN, 'GRADE_AGGREGATE_MEAN', 8, 10); 334 335 // Fails with 1 grade hidden. still reports 4 as being correct. 336 $this->helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, GRADE_AGGREGATE_MIN, 'GRADE_AGGREGATE_MIN', 4, 8); 337 338 // Fails with 1 grade hidden. still reports 12 as being correct. 339 $this->helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, GRADE_AGGREGATE_SUM, 'GRADE_AGGREGATE_SUM', 12, 10); 340 } 341 342 /** 343 * Test grade category aggregation using the supplied grade objects and aggregation method 344 * @param grade_category $grade_category the category to be tested 345 * @param array $grade_items array of instance of grade_item 346 * @param array $grade_grades array of instances of grade_grade 347 * @param int $aggmethod the aggregation method to apply ie GRADE_AGGREGATE_MEAN 348 * @param string $aggmethodname the name of the aggregation method to apply. Used to display any test failure messages 349 * @param int $correct1 the correct final grade for the category with NO items hidden 350 * @param int $correct2 the correct final grade for the category with the grade at $grade_grades[0] hidden 351 * @return void 352 */ 353 protected function helper_test_grade_agg_method($grade_category, $grade_items, $grade_grades, $aggmethod, $aggmethodname, $correct1, $correct2) { 354 $grade_category->aggregation = $aggmethod; 355 $grade_category->update(); 356 357 // Check grade_item isnt hidden from a previous test. 358 $grade_items[0]->set_hidden(0, true); 359 $this->helper_test_grade_aggregation_result($grade_category, $correct1, 'Testing aggregation method('.$aggmethodname.') with no items hidden %s'); 360 361 // Hide the grade item with grade of 2. 362 $grade_items[0]->set_hidden(1, true); 363 $this->helper_test_grade_aggregation_result($grade_category, $correct2, 'Testing aggregation method('.$aggmethodname.') with 1 item hidden %s'); 364 } 365 366 /** 367 * Verify the value of the category grade item for $this->userid 368 * @param grade_category $grade_category the category to be tested 369 * @param int $correctgrade the expected grade 370 * @param string msg The message that should be displayed if the correct grade is not found 371 * @return void 372 */ 373 protected function helper_test_grade_aggregation_result($grade_category, $correctgrade, $msg) { 374 global $DB; 375 376 $category_grade_item = $grade_category->get_grade_item(); 377 378 // This creates all the grade_grades we need. 379 grade_regrade_final_grades($this->courseid); 380 381 $grade = $DB->get_record('grade_grades', array('itemid'=>$category_grade_item->id, 'userid'=>$this->userid)); 382 $this->assertWithinMargin($grade->rawgrade, $grade->rawgrademin, $grade->rawgrademax); 383 $this->assertEquals(intval($correctgrade), intval($grade->finalgrade), $msg); 384 385 /* 386 * TODO this doesnt work as the grade_grades created by $grade_category->generate_grades(); dont 387 * observe the category's max grade 388 // delete the grade_grades for the category itself and check they get recreated correctly. 389 $DB->delete_records('grade_grades', array('itemid'=>$category_grade_item->id)); 390 $grade_category->generate_grades(); 391 392 $grade = $DB->get_record('grade_grades', array('itemid'=>$category_grade_item->id, 'userid'=>$this->userid)); 393 $this->assertWithinMargin($grade->rawgrade, $grade->rawgrademin, $grade->rawgrademax); 394 $this->assertEquals(intval($correctgrade), intval($grade->finalgrade), $msg); 395 * 396 */ 397 } 398 399 protected function sub_test_grade_category_aggregate_grades() { 400 $category = new grade_category($this->grade_categories[0]); 401 $this->assertTrue(method_exists($category, 'aggregate_grades')); 402 // Tested more fully via test_grade_category_generate_grades(). 403 } 404 405 protected function sub_test_grade_category_apply_limit_rules() { 406 $items[$this->grade_items[0]->id] = new grade_item($this->grade_items[0], false); 407 $items[$this->grade_items[1]->id] = new grade_item($this->grade_items[1], false); 408 $items[$this->grade_items[2]->id] = new grade_item($this->grade_items[2], false); 409 $items[$this->grade_items[4]->id] = new grade_item($this->grade_items[4], false); 410 411 // Test excluding the lowest 2 out of 4 grades from aggregation with no 0 grades. 412 $category = new grade_category(); 413 $category->droplow = 2; 414 $grades = array($this->grade_items[0]->id=>5.374, 415 $this->grade_items[1]->id=>9.4743, 416 $this->grade_items[2]->id=>2.5474, 417 $this->grade_items[4]->id=>7.3754); 418 $category->apply_limit_rules($grades, $items); 419 $this->assertEquals(count($grades), 2); 420 $this->assertEquals($grades[$this->grade_items[1]->id], 9.4743); 421 $this->assertEquals($grades[$this->grade_items[4]->id], 7.3754); 422 423 // Test aggregating only the highest 1 out of 4 grades. 424 $category = new grade_category(); 425 $category->keephigh = 1; 426 $category->droplow = 0; 427 $grades = array($this->grade_items[0]->id=>5.374, 428 $this->grade_items[1]->id=>9.4743, 429 $this->grade_items[2]->id=>2.5474, 430 $this->grade_items[4]->id=>7.3754); 431 $category->apply_limit_rules($grades, $items); 432 $this->assertEquals(count($grades), 1); 433 $grade = reset($grades); 434 $this->assertEquals(9.4743, $grade); 435 436 // Test excluding the lowest 2 out of 4 grades from aggregation with no 0 grades. 437 // An extra credit grade item should be kept even if droplow means it would otherwise be excluded. 438 $category = new grade_category(); 439 $category->droplow = 2; 440 $category->aggregation = GRADE_AGGREGATE_SUM; 441 $items[$this->grade_items[2]->id]->aggregationcoef = 1; // Mark grade item 2 as "extra credit". 442 $grades = array($this->grade_items[0]->id=>5.374, 443 $this->grade_items[1]->id=>9.4743, 444 $this->grade_items[2]->id=>2.5474, 445 $this->grade_items[4]->id=>7.3754); 446 $category->apply_limit_rules($grades, $items); 447 $this->assertEquals(count($grades), 2); 448 $this->assertEquals($grades[$this->grade_items[1]->id], 9.4743); 449 $this->assertEquals($grades[$this->grade_items[2]->id], 2.5474); 450 451 // Test only aggregating the highest 1 out of 4 grades. 452 // An extra credit grade item is retained in addition to the highest grade. 453 $category = new grade_category(); 454 $category->keephigh = 1; 455 $category->droplow = 0; 456 $category->aggregation = GRADE_AGGREGATE_SUM; 457 $items[$this->grade_items[2]->id]->aggregationcoef = 1; // Mark grade item 2 as "extra credit". 458 $grades = array($this->grade_items[0]->id=>5.374, 459 $this->grade_items[1]->id=>9.4743, 460 $this->grade_items[2]->id=>2.5474, 461 $this->grade_items[4]->id=>7.3754); 462 $category->apply_limit_rules($grades, $items); 463 $this->assertEquals(count($grades), 2); 464 $this->assertEquals($grades[$this->grade_items[1]->id], 9.4743); 465 $this->assertEquals($grades[$this->grade_items[2]->id], 2.5474); 466 467 // Test excluding the lowest 1 out of 4 grades from aggregation with two 0 grades. 468 $items[$this->grade_items[2]->id]->aggregationcoef = 0; // Undo marking grade item 2 as "extra credit". 469 $category = new grade_category(); 470 $category->droplow = 1; 471 $category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN2; // Simple weighted mean. 472 $grades = array($this->grade_items[0]->id=>0, // 0 out of 110. Should be excluded from aggregation. 473 $this->grade_items[1]->id=>5, // 5 out of 100. 474 $this->grade_items[2]->id=>2, // 0 out of 6. 475 $this->grade_items[4]->id=>0); // 0 out of 100. 476 $category->apply_limit_rules($grades, $items); 477 $this->assertEquals(count($grades), 3); 478 $this->assertEquals($grades[$this->grade_items[1]->id], 5); 479 $this->assertEquals($grades[$this->grade_items[2]->id], 2); 480 $this->assertEquals($grades[$this->grade_items[4]->id], 0); 481 482 // Test excluding the lowest 2 out of 4 grades from aggregation with three 0 grades. 483 $category = new grade_category(); 484 $category->droplow = 2; 485 $category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN2; // Simple weighted mean. 486 $grades = array($this->grade_items[0]->id=>0, // 0 out of 110. Should be excluded from aggregation. 487 $this->grade_items[1]->id=>5, // 5 out of 100. 488 $this->grade_items[2]->id=>0, // 0 out of 6. 489 $this->grade_items[4]->id=>0); // 0 out of 100. Should be excluded from aggregation. 490 $category->apply_limit_rules($grades, $items); 491 $this->assertEquals(count($grades), 2); 492 $this->assertEquals($grades[$this->grade_items[1]->id], 5); 493 $this->assertEquals($grades[$this->grade_items[2]->id], 0); 494 495 // Test excluding the lowest 5 out of 4 grades from aggregation. 496 // Just to check we handle this sensibly. 497 $category = new grade_category(); 498 $category->droplow = 5; 499 $category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN2; // Simple weighted mean. 500 $grades = array($this->grade_items[0]->id=>0, // 0 out of 110. Should be excluded from aggregation. 501 $this->grade_items[1]->id=>5, // 5 out of 100. 502 $this->grade_items[2]->id=>6, // 6 out of 6. 503 $this->grade_items[4]->id=>1);// 1 out of 100. Should be excluded from aggregation. 504 $category->apply_limit_rules($grades, $items); 505 $this->assertEquals(count($grades), 0); 506 507 // Test excluding the lowest 4 out of 4 grades from aggregation with one marked as extra credit. 508 $category = new grade_category(); 509 $category->droplow = 4; 510 $category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN2; // Simple weighted mean. 511 $items[$this->grade_items[2]->id]->aggregationcoef = 1; // Mark grade item 2 as "extra credit". 512 $grades = array($this->grade_items[0]->id=>0, // 0 out of 110. Should be excluded from aggregation. 513 $this->grade_items[1]->id=>5, // 5 out of 100. Should be excluded from aggregation. 514 $this->grade_items[2]->id=>6, // 6 out of 6. Extra credit. Should be retained. 515 $this->grade_items[4]->id=>1);// 1 out of 100. Should be excluded from aggregation. 516 $category->apply_limit_rules($grades, $items); 517 $this->assertEquals(count($grades), 1); 518 $this->assertEquals($grades[$this->grade_items[2]->id], 6); 519 520 // MDL-35667 - There was an infinite loop if several items had the same grade and at least one was extra credit. 521 $category = new grade_category(); 522 $category->droplow = 1; 523 $category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN2; // Simple weighted mean. 524 $items[$this->grade_items[1]->id]->aggregationcoef = 1; // Mark grade item 1 as "extra credit". 525 $grades = array($this->grade_items[0]->id=>1, // 1 out of 110. Should be excluded from aggregation. 526 $this->grade_items[1]->id=>1, // 1 out of 100. Extra credit. Should be retained. 527 $this->grade_items[2]->id=>1, // 1 out of 6. Should be retained. 528 $this->grade_items[4]->id=>1);// 1 out of 100. Should be retained. 529 $category->apply_limit_rules($grades, $items); 530 $this->assertEquals(count($grades), 3); 531 $this->assertEquals($grades[$this->grade_items[1]->id], 1); 532 $this->assertEquals($grades[$this->grade_items[2]->id], 1); 533 $this->assertEquals($grades[$this->grade_items[4]->id], 1); 534 535 } 536 537 protected function sub_test_grade_category_is_aggregationcoef_used() { 538 $category = new grade_category(); 539 // Following use aggregationcoef. 540 $category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN; 541 $this->assertTrue($category->is_aggregationcoef_used()); 542 $category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN2; 543 $this->assertTrue($category->is_aggregationcoef_used()); 544 $category->aggregation = GRADE_AGGREGATE_EXTRACREDIT_MEAN; 545 $this->assertTrue($category->is_aggregationcoef_used()); 546 $category->aggregation = GRADE_AGGREGATE_SUM; 547 $this->assertTrue($category->is_aggregationcoef_used()); 548 549 // Following don't use aggregationcoef. 550 $category->aggregation = GRADE_AGGREGATE_MAX; 551 $this->assertFalse($category->is_aggregationcoef_used()); 552 $category->aggregation = GRADE_AGGREGATE_MEAN; 553 $this->assertFalse($category->is_aggregationcoef_used()); 554 $category->aggregation = GRADE_AGGREGATE_MEDIAN; 555 $this->assertFalse($category->is_aggregationcoef_used()); 556 $category->aggregation = GRADE_AGGREGATE_MIN; 557 $this->assertFalse($category->is_aggregationcoef_used()); 558 $category->aggregation = GRADE_AGGREGATE_MODE; 559 $this->assertFalse($category->is_aggregationcoef_used()); 560 } 561 562 protected function sub_test_grade_category_aggregation_uses_aggregationcoef() { 563 564 $this->assertTrue(grade_category::aggregation_uses_aggregationcoef(GRADE_AGGREGATE_WEIGHTED_MEAN)); 565 $this->assertTrue(grade_category::aggregation_uses_aggregationcoef(GRADE_AGGREGATE_WEIGHTED_MEAN2)); 566 $this->assertTrue(grade_category::aggregation_uses_aggregationcoef(GRADE_AGGREGATE_EXTRACREDIT_MEAN)); 567 $this->assertTrue(grade_category::aggregation_uses_aggregationcoef(GRADE_AGGREGATE_SUM)); 568 569 $this->assertFalse(grade_category::aggregation_uses_aggregationcoef(GRADE_AGGREGATE_MAX)); 570 $this->assertFalse(grade_category::aggregation_uses_aggregationcoef(GRADE_AGGREGATE_MEAN)); 571 $this->assertFalse(grade_category::aggregation_uses_aggregationcoef(GRADE_AGGREGATE_MEDIAN)); 572 $this->assertFalse(grade_category::aggregation_uses_aggregationcoef(GRADE_AGGREGATE_MIN)); 573 $this->assertFalse(grade_category::aggregation_uses_aggregationcoef(GRADE_AGGREGATE_MODE)); 574 } 575 576 protected function sub_test_grade_category_fetch_course_tree() { 577 $category = new grade_category(); 578 $this->assertTrue(method_exists($category, 'fetch_course_tree')); 579 // TODO: add some tests. 580 } 581 582 protected function sub_test_grade_category_get_children() { 583 $course_category = grade_category::fetch_course_category($this->courseid); 584 585 $category = new grade_category($this->grade_categories[0]); 586 $this->assertTrue(method_exists($category, 'get_children')); 587 588 $children_array = $category->get_children(0); 589 590 $this->assertTrue(is_array($children_array)); 591 $this->assertFalse(empty($children_array[2])); 592 $this->assertFalse(empty($children_array[2]['object'])); 593 $this->assertFalse(empty($children_array[2]['children'])); 594 $this->assertEquals($this->grade_categories[1]->id, $children_array[2]['object']->id); 595 $this->assertEquals($this->grade_categories[2]->id, $children_array[5]['object']->id); 596 $this->assertEquals($this->grade_items[0]->id, $children_array[2]['children'][3]['object']->id); 597 $this->assertEquals($this->grade_items[1]->id, $children_array[2]['children'][4]['object']->id); 598 $this->assertEquals($this->grade_items[2]->id, $children_array[5]['children'][6]['object']->id); 599 } 600 601 protected function sub_test_grade_category_load_grade_item() { 602 $category = new grade_category($this->grade_categories[0]); 603 $this->assertTrue(method_exists($category, 'load_grade_item')); 604 $this->assertEquals(null, $category->grade_item); 605 $category->load_grade_item(); 606 $this->assertEquals($this->grade_items[3]->id, $category->grade_item->id); 607 } 608 609 protected function sub_test_grade_category_get_grade_item() { 610 $category = new grade_category($this->grade_categories[0]); 611 $this->assertTrue(method_exists($category, 'get_grade_item')); 612 $grade_item = $category->get_grade_item(); 613 $this->assertEquals($this->grade_items[3]->id, $grade_item->id); 614 } 615 616 protected function sub_test_grade_category_load_parent_category() { 617 $category = new grade_category($this->grade_categories[1]); 618 $this->assertTrue(method_exists($category, 'load_parent_category')); 619 $this->assertEquals(null, $category->parent_category); 620 $category->load_parent_category(); 621 $this->assertEquals($this->grade_categories[0]->id, $category->parent_category->id); 622 } 623 624 protected function sub_test_grade_category_get_parent_category() { 625 $category = new grade_category($this->grade_categories[1]); 626 $this->assertTrue(method_exists($category, 'get_parent_category')); 627 $parent_category = $category->get_parent_category(); 628 $this->assertEquals($this->grade_categories[0]->id, $parent_category->id); 629 } 630 631 protected function sub_test_grade_category_get_name() { 632 $category = new grade_category($this->grade_categories[0]); 633 $this->assertTrue(method_exists($category, 'get_name')); 634 $this->assertEquals($this->grade_categories[0]->fullname, $category->get_name()); 635 } 636 637 protected function sub_test_grade_category_set_parent() { 638 $category = new grade_category($this->grade_categories[1]); 639 $this->assertTrue(method_exists($category, 'set_parent')); 640 // TODO: implement detailed tests. 641 642 $course_category = grade_category::fetch_course_category($this->courseid); 643 $this->assertTrue($category->set_parent($course_category->id)); 644 $this->assertEquals($course_category->id, $category->parent); 645 } 646 647 protected function sub_test_grade_category_get_final() { 648 $category = new grade_category($this->grade_categories[0]); 649 $this->assertTrue(method_exists($category, 'get_final')); 650 $category->load_grade_item(); 651 $this->assertEquals($category->get_final(), $category->grade_item->get_final()); 652 } 653 654 protected function sub_test_grade_category_get_sortorder() { 655 $category = new grade_category($this->grade_categories[0]); 656 $this->assertTrue(method_exists($category, 'get_sortorder')); 657 $category->load_grade_item(); 658 $this->assertEquals($category->get_sortorder(), $category->grade_item->get_sortorder()); 659 } 660 661 protected function sub_test_grade_category_set_sortorder() { 662 $category = new grade_category($this->grade_categories[0]); 663 $this->assertTrue(method_exists($category, 'set_sortorder')); 664 $category->load_grade_item(); 665 $this->assertEquals($category->set_sortorder(10), $category->grade_item->set_sortorder(10)); 666 } 667 668 protected function sub_test_grade_category_move_after_sortorder() { 669 $category = new grade_category($this->grade_categories[0]); 670 $this->assertTrue(method_exists($category, 'move_after_sortorder')); 671 $category->load_grade_item(); 672 $this->assertEquals($category->move_after_sortorder(10), $category->grade_item->move_after_sortorder(10)); 673 } 674 675 protected function sub_test_grade_category_is_course_category() { 676 $category = grade_category::fetch_course_category($this->courseid); 677 $this->assertTrue(method_exists($category, 'is_course_category')); 678 $this->assertTrue($category->is_course_category()); 679 } 680 681 protected function sub_test_grade_category_fetch_course_category() { 682 $category = new grade_category(); 683 $this->assertTrue(method_exists($category, 'fetch_course_category')); 684 $category = grade_category::fetch_course_category($this->courseid); 685 $this->assertTrue(empty($category->parent)); 686 } 687 /** 688 * TODO implement 689 */ 690 protected function sub_test_grade_category_is_editable() { 691 692 } 693 694 protected function sub_test_grade_category_is_locked() { 695 $category = new grade_category($this->grade_categories[0]); 696 $this->assertTrue(method_exists($category, 'is_locked')); 697 $category->load_grade_item(); 698 $this->assertEquals($category->is_locked(), $category->grade_item->is_locked()); 699 } 700 701 protected function sub_test_grade_category_set_locked() { 702 $category = new grade_category($this->grade_categories[0]); 703 $this->assertTrue(method_exists($category, 'set_locked')); 704 705 // Will return false as cannot lock a grade that needs updating. 706 $this->assertFalse($category->set_locked(1)); 707 grade_regrade_final_grades($this->courseid); 708 709 // Get the category from the db again. 710 $category = new grade_category($this->grade_categories[0]); 711 $this->assertTrue($category->set_locked(1)); 712 } 713 714 protected function sub_test_grade_category_is_hidden() { 715 $category = new grade_category($this->grade_categories[0]); 716 $this->assertTrue(method_exists($category, 'is_hidden')); 717 $category->load_grade_item(); 718 $this->assertEquals($category->is_hidden(), $category->grade_item->is_hidden()); 719 } 720 721 protected function sub_test_grade_category_set_hidden() { 722 $category = new grade_category($this->grade_categories[0]); 723 $this->assertTrue(method_exists($category, 'set_hidden')); 724 $category->set_hidden(1); 725 $category->load_grade_item(); 726 $this->assertEquals(true, $category->grade_item->is_hidden()); 727 } 728 729 protected function sub_test_grade_category_can_control_visibility() { 730 $category = new grade_category($this->grade_categories[0]); 731 $this->assertTrue($category->can_control_visibility()); 732 } 733 734 protected function sub_test_grade_category_insert_course_category() { 735 // Beware: adding a duplicate course category messes up the data in a way that's hard to recover from. 736 $grade_category = new grade_category(); 737 $this->assertTrue(method_exists($grade_category, 'insert_course_category')); 738 739 $id = $grade_category->insert_course_category($this->courseid); 740 $this->assertNotNull($id); 741 $this->assertEquals('?', $grade_category->fullname); 742 $this->assertEquals(GRADE_AGGREGATE_WEIGHTED_MEAN2, $grade_category->aggregation); 743 $this->assertEquals("/$id/", $grade_category->path); 744 $this->assertEquals(1, $grade_category->depth); 745 $this->assertNull($grade_category->parent); 746 } 747 748 protected function generate_random_raw_grade($item, $userid) { 749 $grade = new grade_grade(); 750 $grade->itemid = $item->id; 751 $grade->userid = $userid; 752 $grade->grademin = 0; 753 $grade->grademax = 1; 754 $valuetype = "grade$item->gradetype"; 755 $grade->rawgrade = rand(0, 1000) / 1000; 756 $grade->insert(); 757 return $grade->rawgrade; 758 } 759 760 protected function sub_test_grade_category_is_extracredit_used() { 761 $category = new grade_category(); 762 // Following use aggregationcoef. 763 $category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN2; 764 $this->assertTrue($category->is_extracredit_used()); 765 $category->aggregation = GRADE_AGGREGATE_EXTRACREDIT_MEAN; 766 $this->assertTrue($category->is_extracredit_used()); 767 $category->aggregation = GRADE_AGGREGATE_SUM; 768 $this->assertTrue($category->is_extracredit_used()); 769 770 // Following don't use aggregationcoef. 771 $category->aggregation = GRADE_AGGREGATE_WEIGHTED_MEAN; 772 $this->assertFalse($category->is_extracredit_used()); 773 $category->aggregation = GRADE_AGGREGATE_MAX; 774 $this->assertFalse($category->is_extracredit_used()); 775 $category->aggregation = GRADE_AGGREGATE_MEAN; 776 $this->assertFalse($category->is_extracredit_used()); 777 $category->aggregation = GRADE_AGGREGATE_MEDIAN; 778 $this->assertFalse($category->is_extracredit_used()); 779 $category->aggregation = GRADE_AGGREGATE_MIN; 780 $this->assertFalse($category->is_extracredit_used()); 781 $category->aggregation = GRADE_AGGREGATE_MODE; 782 $this->assertFalse($category->is_extracredit_used()); 783 } 784 785 protected function sub_test_grade_category_aggregation_uses_extracredit() { 786 787 $this->assertTrue(grade_category::aggregation_uses_extracredit(GRADE_AGGREGATE_WEIGHTED_MEAN2)); 788 $this->assertTrue(grade_category::aggregation_uses_extracredit(GRADE_AGGREGATE_EXTRACREDIT_MEAN)); 789 $this->assertTrue(grade_category::aggregation_uses_extracredit(GRADE_AGGREGATE_SUM)); 790 791 $this->assertFalse(grade_category::aggregation_uses_extracredit(GRADE_AGGREGATE_WEIGHTED_MEAN)); 792 $this->assertFalse(grade_category::aggregation_uses_extracredit(GRADE_AGGREGATE_MAX)); 793 $this->assertFalse(grade_category::aggregation_uses_extracredit(GRADE_AGGREGATE_MEAN)); 794 $this->assertFalse(grade_category::aggregation_uses_extracredit(GRADE_AGGREGATE_MEDIAN)); 795 $this->assertFalse(grade_category::aggregation_uses_extracredit(GRADE_AGGREGATE_MIN)); 796 $this->assertFalse(grade_category::aggregation_uses_extracredit(GRADE_AGGREGATE_MODE)); 797 } 798 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |