MDL-66748 gradingform_rubric: Add data generators
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Generator for the gradingforum_rubric plugin.
|
||||
*
|
||||
* @package gradingform_rubric
|
||||
* @category test
|
||||
* @copyright 2018 Adrian Greeve <adriangreeve.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tests\gradingform_rubric\generator;
|
||||
|
||||
/**
|
||||
* Convenience class to create rubric criterion.
|
||||
*
|
||||
* @package gradingform_rubric
|
||||
* @copyright 2018 Adrian Greeve <adriangreeve.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class criterion {
|
||||
/** @var string $description A description of the criterion. */
|
||||
public $description;
|
||||
|
||||
/** @var integer $sortorder sort order of the criterion. */
|
||||
public $sortorder = 0;
|
||||
|
||||
/** @var array $levels The levels for this criterion. */
|
||||
public $levels = [];
|
||||
|
||||
/**
|
||||
* Constructor for this test_criterion object
|
||||
*
|
||||
* @param string $description A description of this criterion.
|
||||
* @param array $levels
|
||||
*/
|
||||
public function __construct(string $description, array $levels = []) {
|
||||
$this->description = $description;
|
||||
foreach ($levels as $definition => $score) {
|
||||
$this->add_level($definition, $score);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds levels to the criterion.
|
||||
*
|
||||
* @param string $definition The definition for this level.
|
||||
* @param int $score The score received if this level is selected.
|
||||
* @return self
|
||||
*/
|
||||
public function add_level(string $definition, int $score): self {
|
||||
$this->levels[] = [
|
||||
'definition' => $definition,
|
||||
'score' => $score
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description for this criterion.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description(): string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the levels for this criterion.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_levels(): array {
|
||||
return $this->levels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values in an array for use when creating a new guide.
|
||||
*
|
||||
* @param int $sortorder
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_values(int $sortorder): array {
|
||||
return [
|
||||
'sortorder' => $sortorder,
|
||||
'description' => $this->get_description(),
|
||||
'levels' => $this->get_all_level_values(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all level values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_level_values(): array {
|
||||
$result = [];
|
||||
|
||||
foreach ($this->get_levels() as $index => $level) {
|
||||
$id = $index + 1;
|
||||
$result["NEWID{$id}"] = $level;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Generator for the gradingforum_rubric plugin.
|
||||
*
|
||||
* @package gradingform_rubric
|
||||
* @category test
|
||||
* @copyright 2019 Andrew Nicols <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once(__DIR__ . '/rubric.php');
|
||||
require_once(__DIR__ . '/criterion.php');
|
||||
|
||||
use tests\gradingform_rubric\generator\rubric;
|
||||
use tests\gradingform_rubric\generator\criterion;
|
||||
|
||||
/**
|
||||
* Generator for the gradingforum_rubric plugintype.
|
||||
*
|
||||
* @package gradingform_rubric
|
||||
* @category test
|
||||
* @copyright 2019 Andrew Nicols <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class gradingform_rubric_generator extends component_generator_base {
|
||||
|
||||
/**
|
||||
* Create an instance of a rubric.
|
||||
*
|
||||
* @param context $context
|
||||
* @param string $component
|
||||
* @param string $area
|
||||
* @param string $name
|
||||
* @param string $description
|
||||
* @param array $criteria The list of criteria to add to the generated rubric
|
||||
* @return gradingform_rubric_controller
|
||||
*/
|
||||
public function create_instance(
|
||||
context $context,
|
||||
string $component,
|
||||
string $area,
|
||||
string $name,
|
||||
string $description,
|
||||
array $criteria
|
||||
): gradingform_rubric_controller {
|
||||
global $USER;
|
||||
|
||||
if ($USER->id === 0) {
|
||||
throw new \coding_exception('Creation of a rubric must currently be run as a user.');
|
||||
}
|
||||
|
||||
// Fetch the controller for this context/component/area.
|
||||
$generator = \testing_util::get_data_generator();
|
||||
$gradinggenerator = $generator->get_plugin_generator('core_grading');
|
||||
$controller = $gradinggenerator->create_instance($context, $component, $area, 'rubric');
|
||||
|
||||
// Generate a definition for the supplied rubric.
|
||||
$rubric = $this->get_rubric($name, $description);
|
||||
foreach ($criteria as $name => $criterion) {
|
||||
$rubric->add_criteria($this->get_criterion($name, $criterion));
|
||||
}
|
||||
|
||||
// Update the controller wih the rubric definition.
|
||||
$controller->update_definition($rubric->get_definition());
|
||||
|
||||
return $controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new rubric for use with the rubric controller.
|
||||
*
|
||||
* Note: This is just a helper class used to build a new definition. It does not persist the data.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $description
|
||||
* @return rubric
|
||||
*/
|
||||
protected function get_rubric(string $name, string $description): rubric {
|
||||
return new rubric($name, $description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new rubric for use with a gradingform_rubric_generator_rubric.
|
||||
*
|
||||
* Note: This is just a helper class used to build a new definition. It does not persist the data.
|
||||
*
|
||||
* @param string $description
|
||||
* @param array $levels Set of levels in the form definition => score
|
||||
* @return gradingform_rubric_generator_criterion
|
||||
*/
|
||||
protected function get_criterion(string $description, array $levels = []): criterion {
|
||||
return new criterion($description, $levels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a controller instance, fetch the level and criterion information for the specified values.
|
||||
*
|
||||
* @param gradingform_controller $controller
|
||||
* @param string $description The description to match the criterion on
|
||||
* @param float $score The value to match the level on
|
||||
* @return array
|
||||
*/
|
||||
public function get_level_and_criterion_for_values(
|
||||
gradingform_controller $controller,
|
||||
string $description,
|
||||
float $score
|
||||
): array {
|
||||
$definition = $controller->get_definition();
|
||||
$criteria = $definition->rubric_criteria;
|
||||
|
||||
$criterion = $level = null;
|
||||
|
||||
$criterion = array_reduce($criteria, function($carry, $criterion) use ($description) {
|
||||
if ($criterion['description'] === $description) {
|
||||
$carry = $criterion;
|
||||
}
|
||||
|
||||
return $carry;
|
||||
}, null);
|
||||
|
||||
if ($criterion) {
|
||||
$criterion = (object) $criterion;
|
||||
$level = array_reduce($criterion->levels, function($carry, $level) use ($score) {
|
||||
if ($level['score'] == $score) {
|
||||
$carry = $level;
|
||||
}
|
||||
return $carry;
|
||||
});
|
||||
$level = $level ? (object) $level : null;
|
||||
}
|
||||
|
||||
return [
|
||||
'criterion' => $criterion,
|
||||
'level' => $level,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get submitted form data for the supplied controller, itemid, and values.
|
||||
* The returned data is in the format used by rubric when handling form submission.
|
||||
*
|
||||
* @param gradingform_rubric_controller $controller
|
||||
* @param int $itemid
|
||||
* @param array $values A set of array values where the array key is the name of the criterion, and the value is an
|
||||
* array with the desired score, and any remark.
|
||||
*/
|
||||
public function get_submitted_form_data(gradingform_rubric_controller $controller, int $itemid, array $values): array {
|
||||
$result = [
|
||||
'itemid' => $itemid,
|
||||
'criteria' => [],
|
||||
];
|
||||
foreach ($values as $criterionname => ['score' => $score, 'remark' => $remark]) {
|
||||
[
|
||||
'criterion' => $criterion,
|
||||
'level' => $level,
|
||||
] = $this->get_level_and_criterion_for_values($controller, $criterionname, $score);
|
||||
$result['criteria'][$criterion->id] = [
|
||||
'levelid' => $level->id,
|
||||
'remark' => $remark,
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a rubric controller with sample data required for testing of this class.
|
||||
*
|
||||
* @param context $context
|
||||
* @param string $component
|
||||
* @param string $area
|
||||
* @return gradingform_rubric_controller
|
||||
*/
|
||||
public function get_test_rubric(context $context, string $component, string $area): gradingform_rubric_controller {
|
||||
$criteria = [
|
||||
'Spelling is important' => [
|
||||
'Nothing but mistakes' => 0,
|
||||
'Several mistakes' => 1,
|
||||
'No mistakes' => 2,
|
||||
],
|
||||
'Pictures' => [
|
||||
'No pictures' => 0,
|
||||
'One picture' => 1,
|
||||
'More than one picture' => 2,
|
||||
],
|
||||
];
|
||||
|
||||
return $this->create_instance($context, $component, $area, 'testrubric', 'Description text', $criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a set of sample data.
|
||||
*
|
||||
* @param gradingform_rubric_controller $controller
|
||||
* @param int $itemid
|
||||
* @param float $spellingscore
|
||||
* @param string $spellingremark
|
||||
* @param float $picturescore
|
||||
* @param string $pictureremark
|
||||
* @return array
|
||||
*/
|
||||
public function get_test_form_data(
|
||||
gradingform_rubric_controller $controller,
|
||||
int $itemid,
|
||||
float $spellingscore,
|
||||
string $spellingremark,
|
||||
float $picturescore,
|
||||
string $pictureremark
|
||||
): array {
|
||||
$generator = \testing_util::get_data_generator();
|
||||
$rubricgenerator = $generator->get_plugin_generator('gradingform_rubric');
|
||||
return $rubricgenerator->get_submitted_form_data($controller, $itemid, [
|
||||
'Spelling is important' => [
|
||||
'score' => $spellingscore,
|
||||
'remark' => $spellingremark,
|
||||
],
|
||||
'Pictures' => [
|
||||
'score' => $picturescore,
|
||||
'remark' => $pictureremark,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Generator for the gradingforum_rubric plugin.
|
||||
*
|
||||
* @package gradingform_rubric
|
||||
* @category test
|
||||
* @copyright 2018 Adrian Greeve <adriangreeve.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tests\gradingform_rubric\generator;
|
||||
|
||||
use gradingform_controller;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Test rubric.
|
||||
*
|
||||
* @package gradingform_rubric
|
||||
* @category test
|
||||
* @copyright 2018 Adrian Greeve <adriangreeve.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class rubric {
|
||||
|
||||
/** @var array $criteria The criteria for this rubric. */
|
||||
protected $criteria = [];
|
||||
|
||||
/** @var string The name of this rubric. */
|
||||
protected $name;
|
||||
|
||||
/** @var string A description for this rubric. */
|
||||
protected $description;
|
||||
|
||||
/** @var array The rubric options. */
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* Create a new gradingform_rubric_generator_rubric.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $description
|
||||
*/
|
||||
public function __construct(string $name, string $description) {
|
||||
$this->name = $name;
|
||||
$this->description = $description;
|
||||
|
||||
$this->set_option('sortlevelsasc', 1);
|
||||
$this->set_option('lockzeropoints', 1);
|
||||
$this->set_option('showdescriptionteacher', 1);
|
||||
$this->set_option('showdescriptionstudent', 1);
|
||||
$this->set_option('showscoreteacher', 1);
|
||||
$this->set_option('showscorestudent', 1);
|
||||
$this->set_option('enableremarks', 1);
|
||||
$this->set_option('showremarksstudent', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the rubric using the appropriate APIs.
|
||||
*/
|
||||
public function get_definition(): stdClass {
|
||||
return (object) [
|
||||
'name' => $this->name,
|
||||
'description_editor' => [
|
||||
'text' => $this->description,
|
||||
'format' => FORMAT_HTML,
|
||||
'itemid' => 1
|
||||
],
|
||||
'rubric' => [
|
||||
'criteria' => $this->get_all_criterion_values(),
|
||||
'options' => $this->options,
|
||||
],
|
||||
'saverubric' => 'Save rubric and make it ready',
|
||||
'status' => gradingform_controller::DEFINITION_STATUS_READY,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an option for the rubric.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return self
|
||||
*/
|
||||
public function set_option(string $key, $value): self {
|
||||
$this->options[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a criterion to the rubric.
|
||||
*
|
||||
* @param criterion $criterion The criterion object (class below).
|
||||
* @return self
|
||||
*/
|
||||
public function add_criteria(criterion $criterion): self {
|
||||
$this->criteria[] = $criterion;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all criterion values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_all_criterion_values(): array {
|
||||
$result = [];
|
||||
|
||||
foreach ($this->criteria as $index => $criterion) {
|
||||
$id = $index + 1;
|
||||
$result["NEWID{$id}"] = $criterion->get_all_values($id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Generator testcase for the gradingforum_rubric generator.
|
||||
*
|
||||
* @package gradingform_rubric
|
||||
* @category test
|
||||
* @copyright 2019 Andrew Nicols <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tests\gradingform_rubric;
|
||||
|
||||
use advanced_testcase;
|
||||
use context_module;
|
||||
use gradingform_rubric_controller;
|
||||
use gradingform_controller;
|
||||
|
||||
/**
|
||||
* Generator testcase for the gradingforum_rubric generator.
|
||||
*
|
||||
* @package gradingform_rubric
|
||||
* @category test
|
||||
* @copyright 2019 Andrew Nicols <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class generator_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test rubric creation.
|
||||
*/
|
||||
public function test_rubric_creation(): void {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Fetch generators.
|
||||
$generator = \testing_util::get_data_generator();
|
||||
$rubricgenerator = $generator->get_plugin_generator('gradingform_rubric');
|
||||
|
||||
// Create items required for testing.
|
||||
$course = $generator->create_course();
|
||||
$module = $generator->create_module('assign', ['course' => $course]);
|
||||
$user = $generator->create_user();
|
||||
$context = context_module::instance($module->cmid);
|
||||
|
||||
// Data for testing.
|
||||
$name = 'myfirstrubric';
|
||||
$description = 'My first rubric';
|
||||
$criteria = [
|
||||
'Alphabet' => [
|
||||
'Not known' => 0,
|
||||
'Letters known but out of order' => 1,
|
||||
'Letters known in order ascending' => 2,
|
||||
'Letters known and can recite forwards and backwards' => 4,
|
||||
],
|
||||
'Times tables' => [
|
||||
'Not known' => 0,
|
||||
'2 times table known' => 2,
|
||||
'2 and 5 times table known' => 4,
|
||||
'2, 5, and 10 times table known' => 8,
|
||||
],
|
||||
];
|
||||
|
||||
// Unit under test.
|
||||
$this->setUser($user);
|
||||
$controller = $rubricgenerator->create_instance($context, 'mod_assign', 'submission', $name, $description, $criteria);
|
||||
|
||||
$this->assertInstanceOf(gradingform_rubric_controller::class, $controller);
|
||||
|
||||
$definition = $controller->get_definition();
|
||||
$this->assertNotEmpty($definition->id);
|
||||
$this->assertEquals($name, $definition->name);
|
||||
$this->assertEquals($description, $definition->description);
|
||||
$this->assertEquals(gradingform_controller::DEFINITION_STATUS_READY, $definition->status);
|
||||
$this->assertNotEmpty($definition->timecreated);
|
||||
$this->assertNotEmpty($definition->timemodified);
|
||||
$this->assertEquals($user->id, $definition->usercreated);
|
||||
|
||||
$this->assertNotEmpty($definition->rubric_criteria);
|
||||
$this->assertCount(2, $definition->rubric_criteria);
|
||||
|
||||
// Check the alphabet criteria.
|
||||
$criteriaids = array_keys($definition->rubric_criteria);
|
||||
|
||||
$alphabet = $definition->rubric_criteria[$criteriaids[0]];
|
||||
$this->assertNotEmpty($alphabet['id']);
|
||||
$this->assertEquals(1, $alphabet['sortorder']);
|
||||
$this->assertEquals('Alphabet', $alphabet['description']);
|
||||
|
||||
$this->assertNotEmpty($alphabet['levels']);
|
||||
$levels = $alphabet['levels'];
|
||||
$levelids = array_keys($levels);
|
||||
|
||||
$level = $levels[$levelids[0]];
|
||||
$this->assertEquals(0, $level['score']);
|
||||
$this->assertEquals('Not known', $level['definition']);
|
||||
|
||||
$level = $levels[$levelids[1]];
|
||||
$this->assertEquals(1, $level['score']);
|
||||
$this->assertEquals('Letters known but out of order', $level['definition']);
|
||||
|
||||
$level = $levels[$levelids[2]];
|
||||
$this->assertEquals(2, $level['score']);
|
||||
$this->assertEquals('Letters known in order ascending', $level['definition']);
|
||||
|
||||
$level = $levels[$levelids[3]];
|
||||
$this->assertEquals(4, $level['score']);
|
||||
$this->assertEquals('Letters known and can recite forwards and backwards', $level['definition']);
|
||||
|
||||
// Check the times tables criteria.
|
||||
$tables = $definition->rubric_criteria[$criteriaids[1]];
|
||||
$this->assertNotEmpty($tables['id']);
|
||||
$this->assertEquals(2, $tables['sortorder']);
|
||||
$this->assertEquals('Times tables', $tables['description']);
|
||||
|
||||
$this->assertNotEmpty($tables['levels']);
|
||||
$levels = $tables['levels'];
|
||||
$levelids = array_keys($levels);
|
||||
|
||||
$level = $levels[$levelids[0]];
|
||||
$this->assertEquals(0, $level['score']);
|
||||
$this->assertEquals('Not known', $level['definition']);
|
||||
|
||||
$level = $levels[$levelids[1]];
|
||||
$this->assertEquals(2, $level['score']);
|
||||
$this->assertEquals('2 times table known', $level['definition']);
|
||||
|
||||
$level = $levels[$levelids[2]];
|
||||
$this->assertEquals(4, $level['score']);
|
||||
$this->assertEquals('2 and 5 times table known', $level['definition']);
|
||||
|
||||
$level = $levels[$levelids[3]];
|
||||
$this->assertEquals(8, $level['score']);
|
||||
$this->assertEquals('2, 5, and 10 times table known', $level['definition']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the get_level_and_criterion_for_values function.
|
||||
* This is used for finding criterion and level information within a rubric.
|
||||
*/
|
||||
public function test_get_level_and_criterion_for_values(): void {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Fetch generators.
|
||||
$generator = \testing_util::get_data_generator();
|
||||
$rubricgenerator = $generator->get_plugin_generator('gradingform_rubric');
|
||||
|
||||
// Create items required for testing.
|
||||
$course = $generator->create_course();
|
||||
$module = $generator->create_module('assign', ['course' => $course]);
|
||||
$user = $generator->create_user();
|
||||
$context = context_module::instance($module->cmid);
|
||||
|
||||
// Data for testing.
|
||||
$description = 'My first rubric';
|
||||
$criteria = [
|
||||
'Alphabet' => [
|
||||
'Not known' => 0,
|
||||
'Letters known but out of order' => 1,
|
||||
'Letters known in order ascending' => 2,
|
||||
'Letters known and can recite forwards and backwards' => 4,
|
||||
],
|
||||
'Times tables' => [
|
||||
'Not known' => 0,
|
||||
'2 times table known' => 2,
|
||||
'2 and 5 times table known' => 4,
|
||||
'2, 5, and 10 times table known' => 8,
|
||||
],
|
||||
];
|
||||
|
||||
$this->setUser($user);
|
||||
$controller = $rubricgenerator->create_instance($context, 'mod_assign', 'submission', 'rubric', $description, $criteria);
|
||||
|
||||
// Valid criterion and level.
|
||||
$result = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Alphabet', 2);
|
||||
$this->assertEquals('Alphabet', $result['criterion']->description);
|
||||
$this->assertEquals('2', $result['level']->score);
|
||||
$this->assertEquals('Letters known in order ascending', $result['level']->definition);
|
||||
|
||||
// Valid criterion. Invalid level.
|
||||
$result = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Alphabet', 3);
|
||||
$this->assertEquals('Alphabet', $result['criterion']->description);
|
||||
$this->assertNull($result['level']);
|
||||
|
||||
// Invalid criterion.
|
||||
$result = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Foo', 0);
|
||||
$this->assertNull($result['criterion']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the get_test_rubric function.
|
||||
*/
|
||||
public function test_get_test_rubric(): void {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Fetch generators.
|
||||
$generator = \testing_util::get_data_generator();
|
||||
$rubricgenerator = $generator->get_plugin_generator('gradingform_rubric');
|
||||
|
||||
// Create items required for testing.
|
||||
$course = $generator->create_course();
|
||||
$module = $generator->create_module('assign', ['course' => $course]);
|
||||
$user = $generator->create_user();
|
||||
$context = context_module::instance($module->cmid);
|
||||
|
||||
$this->setUser($user);
|
||||
$rubric = $rubricgenerator->get_test_rubric($context, 'assign', 'submissions');
|
||||
$definition = $rubric->get_definition();
|
||||
|
||||
$this->assertEquals('testrubric', $definition->name);
|
||||
$this->assertEquals('Description text', $definition->description);
|
||||
$this->assertEquals(gradingform_controller::DEFINITION_STATUS_READY, $definition->status);
|
||||
|
||||
// Should create a rubric with 2 criterion.
|
||||
$this->assertCount(2, $definition->rubric_criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the get_submitted_form_data function.
|
||||
*/
|
||||
public function test_get_submitted_form_data(): void {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Fetch generators.
|
||||
$generator = \testing_util::get_data_generator();
|
||||
$rubricgenerator = $generator->get_plugin_generator('gradingform_rubric');
|
||||
|
||||
// Create items required for testing.
|
||||
$course = $generator->create_course();
|
||||
$module = $generator->create_module('assign', ['course' => $course]);
|
||||
$user = $generator->create_user();
|
||||
$context = context_module::instance($module->cmid);
|
||||
|
||||
$this->setUser($user);
|
||||
$controller = $rubricgenerator->get_test_rubric($context, 'assign', 'submissions');
|
||||
|
||||
$result = $rubricgenerator->get_submitted_form_data($controller, 93, [
|
||||
'Spelling is important' => [
|
||||
'score' => 1,
|
||||
'remark' => 'Good speeling',
|
||||
],
|
||||
'Pictures' => [
|
||||
'score' => 2,
|
||||
'remark' => 'Lots of nice pictures!',
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertIsArray($result);
|
||||
$this->assertEquals(93, $result['itemid']);
|
||||
$this->assertIsArray($result['criteria']);
|
||||
$this->assertCount(2, $result['criteria']);
|
||||
|
||||
$spelling = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Spelling is important', 1);
|
||||
$this->assertIsArray($result['criteria'][$spelling['criterion']->id]);
|
||||
$this->assertEquals($spelling['level']->id, $result['criteria'][$spelling['criterion']->id]['levelid']);
|
||||
$this->assertEquals('Good speeling', $result['criteria'][$spelling['criterion']->id]['remark']);
|
||||
|
||||
$pictures = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Pictures', 2);
|
||||
$this->assertIsArray($result['criteria'][$pictures['criterion']->id]);
|
||||
$this->assertEquals($pictures['level']->id, $result['criteria'][$pictures['criterion']->id]['levelid']);
|
||||
$this->assertEquals('Lots of nice pictures!', $result['criteria'][$pictures['criterion']->id]['remark']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the get_test_form_data function.
|
||||
*/
|
||||
public function test_get_test_form_data(): void {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Fetch generators.
|
||||
$generator = \testing_util::get_data_generator();
|
||||
$rubricgenerator = $generator->get_plugin_generator('gradingform_rubric');
|
||||
|
||||
// Create items required for testing.
|
||||
$course = $generator->create_course();
|
||||
$module = $generator->create_module('assign', ['course' => $course]);
|
||||
$user = $generator->create_user();
|
||||
$context = context_module::instance($module->cmid);
|
||||
|
||||
$this->setUser($user);
|
||||
$controller = $rubricgenerator->get_test_rubric($context, 'assign', 'submissions');
|
||||
|
||||
// Unit under test.
|
||||
$result = $rubricgenerator->get_test_form_data(
|
||||
$controller,
|
||||
1839,
|
||||
1, 'Propper good speling',
|
||||
0, 'ASCII art is not a picture'
|
||||
);
|
||||
|
||||
$this->assertIsArray($result);
|
||||
$this->assertEquals(1839, $result['itemid']);
|
||||
$this->assertIsArray($result['criteria']);
|
||||
$this->assertCount(2, $result['criteria']);
|
||||
|
||||
$spelling = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Spelling is important', 1);
|
||||
$this->assertIsArray($result['criteria'][$spelling['criterion']->id]);
|
||||
$this->assertEquals($spelling['level']->id, $result['criteria'][$spelling['criterion']->id]['levelid']);
|
||||
$this->assertEquals('Propper good speling', $result['criteria'][$spelling['criterion']->id]['remark']);
|
||||
|
||||
$pictures = $rubricgenerator->get_level_and_criterion_for_values($controller, 'Pictures', 0);
|
||||
$this->assertIsArray($result['criteria'][$pictures['criterion']->id]);
|
||||
$this->assertEquals($pictures['level']->id, $result['criteria'][$pictures['criterion']->id]['levelid']);
|
||||
$this->assertEquals('ASCII art is not a picture', $result['criteria'][$pictures['criterion']->id]['remark']);
|
||||
}
|
||||
}
|
||||
@@ -23,11 +23,13 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
namespace tests\gradingform_rubric;
|
||||
|
||||
use \core_privacy\tests\provider_testcase;
|
||||
use \core_privacy\local\request\writer;
|
||||
use \gradingform_rubric\privacy\provider;
|
||||
use core_privacy\tests\provider_testcase;
|
||||
use core_privacy\local\request\writer;
|
||||
use gradingform_rubric\privacy\provider;
|
||||
use gradingform_rubric_controller;
|
||||
use context_module;
|
||||
|
||||
/**
|
||||
* Privacy tests for gradingform_rubric
|
||||
@@ -35,7 +37,7 @@ use \gradingform_rubric\privacy\provider;
|
||||
* @copyright 2018 Adrian Greeve <adriangreeve.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class gradingform_rubric_privacy_testcase extends provider_testcase {
|
||||
class privacy_testcase extends provider_testcase {
|
||||
|
||||
/**
|
||||
* Test the export of rubric data.
|
||||
@@ -45,43 +47,23 @@ class gradingform_rubric_privacy_testcase extends provider_testcase {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$module = $this->getDataGenerator()->create_module('assign', ['course' => $course]);
|
||||
$modulecontext = context_module::instance($module->cmid);
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($user);
|
||||
|
||||
$modulecontext = context_module::instance($module->cmid);
|
||||
$rubric = new test_rubric($modulecontext, 'testrubrib', 'Description text');
|
||||
$criterion = new test_criterion('Spelling is important');
|
||||
$criterion->add_level('Nothing but mistakes', 0);
|
||||
$criterion->add_level('Several mistakes', 1);
|
||||
$criterion->add_level('No mistakes', 2);
|
||||
$rubric->add_criteria($criterion);
|
||||
$criterion = new test_criterion('Pictures');
|
||||
$criterion->add_level('No pictures', 0);
|
||||
$criterion->add_level('One picture', 1);
|
||||
$criterion->add_level('More than one picture', 2);
|
||||
$rubric->add_criteria($criterion);
|
||||
$rubric->create_rubric();
|
||||
// Generate a test rubric and get its controller.
|
||||
$controller = $this->get_test_rubric($modulecontext, 'assign', 'submissions');
|
||||
|
||||
$controller = $rubric->manager->get_controller('rubric');
|
||||
// In the situation of mod_assign this would be the id from assign_grades.
|
||||
$itemid = 1;
|
||||
$instance = $controller->create_instance($user->id, $itemid);
|
||||
// I need the ids for the criteria and there doesn't seem to be a nice method to get it.
|
||||
$criteria = $DB->get_records('gradingform_rubric_criteria');
|
||||
$data = ['criteria' => []];
|
||||
foreach ($criteria as $key => $value) {
|
||||
if ($value->description == 'Spelling is important') {
|
||||
$level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 1]);
|
||||
$data['criteria'][$key]['levelid'] = $level->id;
|
||||
$data['criteria'][$key]['remark'] = 'This user made several mistakes.';
|
||||
} else {
|
||||
$level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 0]);
|
||||
$data['criteria'][$key]['levelid'] = $level->id;
|
||||
$data['criteria'][$key]['remark'] = 'Please add more pictures.';
|
||||
}
|
||||
}
|
||||
$data['itemid'] = $itemid;
|
||||
|
||||
$data = $this->get_test_form_data(
|
||||
$controller,
|
||||
$itemid,
|
||||
1, 'This user made several mistakes.',
|
||||
0, 'Please add more pictures.'
|
||||
);
|
||||
|
||||
// Update this instance with data.
|
||||
$instance->update($data);
|
||||
@@ -105,43 +87,23 @@ class gradingform_rubric_privacy_testcase extends provider_testcase {
|
||||
$this->resetAfterTest();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$module = $this->getDataGenerator()->create_module('assign', ['course' => $course]);
|
||||
$modulecontext = context_module::instance($module->cmid);
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($user);
|
||||
|
||||
$modulecontext = context_module::instance($module->cmid);
|
||||
$rubric = new test_rubric($modulecontext, 'testrubrib', 'Description text');
|
||||
$criterion = new test_criterion('Spelling is important');
|
||||
$criterion->add_level('Nothing but mistakes', 0);
|
||||
$criterion->add_level('Several mistakes', 1);
|
||||
$criterion->add_level('No mistakes', 2);
|
||||
$rubric->add_criteria($criterion);
|
||||
$criterion = new test_criterion('Pictures');
|
||||
$criterion->add_level('No pictures', 0);
|
||||
$criterion->add_level('One picture', 1);
|
||||
$criterion->add_level('More than one picture', 2);
|
||||
$rubric->add_criteria($criterion);
|
||||
$rubric->create_rubric();
|
||||
// Generate a test rubric and get its controller.
|
||||
$controller = $this->get_test_rubric($modulecontext, 'assign', 'submissions');
|
||||
|
||||
$controller = $rubric->manager->get_controller('rubric');
|
||||
// In the situation of mod_assign this would be the id from assign_grades.
|
||||
$itemid = 1;
|
||||
$instance = $controller->create_instance($user->id, $itemid);
|
||||
// I need the ids for the criteria and there doesn't seem to be a nice method to get it.
|
||||
$criteria = $DB->get_records('gradingform_rubric_criteria');
|
||||
$data = ['criteria' => []];
|
||||
foreach ($criteria as $key => $value) {
|
||||
if ($value->description == 'Spelling is important') {
|
||||
$level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 1]);
|
||||
$data['criteria'][$key]['levelid'] = $level->id;
|
||||
$data['criteria'][$key]['remark'] = 'This user made several mistakes.';
|
||||
} else {
|
||||
$level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 0]);
|
||||
$data['criteria'][$key]['levelid'] = $level->id;
|
||||
$data['criteria'][$key]['remark'] = 'Please add more pictures.';
|
||||
}
|
||||
}
|
||||
$data['itemid'] = $itemid;
|
||||
|
||||
$data = $this->get_test_form_data(
|
||||
$controller,
|
||||
$itemid,
|
||||
1, 'This user made several mistakes.',
|
||||
0, 'Please add more pictures.'
|
||||
);
|
||||
|
||||
// Update this instance with data.
|
||||
$instance->update($data);
|
||||
@@ -149,21 +111,13 @@ class gradingform_rubric_privacy_testcase extends provider_testcase {
|
||||
// Second instance.
|
||||
$itemid = 2;
|
||||
$instance = $controller->create_instance($user->id, $itemid);
|
||||
// I need the ids for the criteria and there doesn't seem to be a nice method to get it.
|
||||
$criteria = $DB->get_records('gradingform_rubric_criteria');
|
||||
$data = ['criteria' => []];
|
||||
foreach ($criteria as $key => $value) {
|
||||
if ($value->description == 'Spelling is important') {
|
||||
$level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 0]);
|
||||
$data['criteria'][$key]['levelid'] = $level->id;
|
||||
$data['criteria'][$key]['remark'] = 'Too many mistakes. Please try again.';
|
||||
} else {
|
||||
$level = $DB->get_record('gradingform_rubric_levels', ['criterionid' => $key, 'score' => 2]);
|
||||
$data['criteria'][$key]['levelid'] = $level->id;
|
||||
$data['criteria'][$key]['remark'] = 'Great number of pictures. Well done.';
|
||||
}
|
||||
}
|
||||
$data['itemid'] = $itemid;
|
||||
|
||||
$data = $this->get_test_form_data(
|
||||
$controller,
|
||||
$itemid,
|
||||
0, 'Too many mistakes. Please try again.',
|
||||
2, 'Great number of pictures. Well done.'
|
||||
);
|
||||
|
||||
// Update this instance with data.
|
||||
$instance->update($data);
|
||||
@@ -179,135 +133,51 @@ class gradingform_rubric_privacy_testcase extends provider_testcase {
|
||||
$this->assertNotEquals($instance->get_id(), $record->instanceid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience class to create rubrics.
|
||||
*
|
||||
* @copyright 2018 Adrian Greeve <adriangreeve.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class test_rubric {
|
||||
|
||||
/** @var array $criteria The criteria for this rubric. */
|
||||
protected $criteria = [];
|
||||
/** @var context The context that this rubric is in. */
|
||||
protected $context;
|
||||
/** @var string The name of this rubric. */
|
||||
protected $name;
|
||||
/** @var string A description for this rubric. */
|
||||
protected $text;
|
||||
/** @var integer The current criterion ID. This is incremented when a new criterion is added. */
|
||||
protected $criterionid = 0;
|
||||
/** @var grading_manager An object for managing the rubric. */
|
||||
public $manager;
|
||||
|
||||
/**
|
||||
* Constuctor for this rubric.
|
||||
* Generate a rubric controller with sample data required for testing of this class.
|
||||
*
|
||||
* @param context $context The context that this rubric is being used in.
|
||||
* @param string $name Name of the rubric.
|
||||
* @param string $text Description of the rubric.
|
||||
* @param context_module $context
|
||||
* @param string $component
|
||||
* @param string $area
|
||||
* @return gradingform_rubric_controller
|
||||
*/
|
||||
public function __construct($context, $name, $text) {
|
||||
$this->context = $context;
|
||||
$this->name = $name;
|
||||
$this->text = $text;
|
||||
$this->manager = get_grading_manager();
|
||||
$this->manager->set_context($context);
|
||||
$this->manager->set_component('mod_assign');
|
||||
$this->manager->set_area('submission');
|
||||
protected function get_test_rubric(context_module $context, string $component, string $area): gradingform_rubric_controller {
|
||||
$generator = \testing_util::get_data_generator();
|
||||
$rubricgenerator = $generator->get_plugin_generator('gradingform_rubric');
|
||||
|
||||
return $rubricgenerator->get_test_rubric($context, $component, $area);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the rubric using the appropriate APIs.
|
||||
*/
|
||||
public function create_rubric() {
|
||||
|
||||
$data = (object) [
|
||||
'areaid' => $this->context->id,
|
||||
'returnurl' => '',
|
||||
'name' => $this->name,
|
||||
'description_editor' => [
|
||||
'text' => $this->text,
|
||||
'format' => 1,
|
||||
'itemid' => 1
|
||||
],
|
||||
'rubric' => [
|
||||
'criteria' => $this->criteria,
|
||||
'options' => [
|
||||
'sortlevelsasc' => 1,
|
||||
'lockzeropoints' => 1,
|
||||
'showdescriptionteacher' => 1,
|
||||
'showdescriptionstudent' => 1,
|
||||
'showscoreteacher' => 1,
|
||||
'showscorestudent' => 1,
|
||||
'enableremarks' => 1,
|
||||
'showremarksstudent' => 1
|
||||
]
|
||||
],
|
||||
'saverubric' => 'Save rubric and make it ready',
|
||||
'status' => 20
|
||||
];
|
||||
|
||||
$controller = $this->manager->get_controller('rubric');
|
||||
$controller->update_definition($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a criterion to the rubric.
|
||||
* Fetch a set of sample data.
|
||||
*
|
||||
* @param test_criterion $criterion The criterion object (class below).
|
||||
* @param gradingform_rubric_controller $controller
|
||||
* @param int $itemid
|
||||
* @param float $spellingscore
|
||||
* @param string $spellingremark
|
||||
* @param float $picturescore
|
||||
* @param string $pictureremark
|
||||
* @return array
|
||||
*/
|
||||
public function add_criteria($criterion) {
|
||||
protected function get_test_form_data(
|
||||
gradingform_rubric_controller $controller,
|
||||
int $itemid,
|
||||
float $spellingscore,
|
||||
string $spellingremark,
|
||||
float $picturescore,
|
||||
string $pictureremark
|
||||
): array {
|
||||
$generator = \testing_util::get_data_generator();
|
||||
$rubricgenerator = $generator->get_plugin_generator('gradingform_rubric');
|
||||
|
||||
$this->criterionid++;
|
||||
$this->criteria['NEWID' . $this->criterionid] = [
|
||||
'description' => $criterion->description,
|
||||
'sortorder' => $this->criterionid,
|
||||
'levels' => $criterion->levels
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience class to create rubric criterion.
|
||||
*
|
||||
* @copyright 2018 Adrian Greeve <adriangreeve.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class test_criterion {
|
||||
|
||||
/** @var string $description A description of the criterion. */
|
||||
public $description;
|
||||
/** @var integer $sortorder sort order of the criterion. */
|
||||
public $sortorder = 0;
|
||||
/** @var integer $levelid The current level id for this level*/
|
||||
public $levelid = 0;
|
||||
/** @var array $levels The levels for this criterion. */
|
||||
public $levels = [];
|
||||
|
||||
/**
|
||||
* Constructor for this test_criterion object
|
||||
*
|
||||
* @param string $description A description of this criterion.
|
||||
*/
|
||||
public function __construct($description) {
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds levels to the criterion.
|
||||
*
|
||||
* @param string $definition The definition for this level.
|
||||
* @param int $score The score received if this level is selected.
|
||||
*/
|
||||
public function add_level($definition, $score) {
|
||||
$this->levelid++;
|
||||
$this->levels['NEWID' . $this->levelid] = [
|
||||
'definition' => $definition,
|
||||
'score' => $score
|
||||
];
|
||||
return $rubricgenerator->get_test_form_data(
|
||||
$controller,
|
||||
$itemid,
|
||||
$spellingscore,
|
||||
$spellingremark,
|
||||
$picturescore,
|
||||
$pictureremark
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user