Skip to content

Commit

Permalink
Managed to remove static calls from the core gradebook classes withou…
Browse files Browse the repository at this point in the history
…t removing support for such calls in gradebook interface code. I used a singleton pattern for this (get_instance in grade_object).
  • Loading branch information
nicolasconnault committed Nov 13, 2007
1 parent 9e47906 commit 795bee3
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 22 deletions.
6 changes: 4 additions & 2 deletions lib/grade/grade_category.php
Expand Up @@ -170,7 +170,8 @@ function build_path($grade_category) {
* @return object grade_category instance or false if none found.
*/
function fetch($params) {
return $this->fetch_helper('grade_categories', 'grade_category', $params);
$obj = grade_object::get_instance('grade_category');
return $obj->fetch_helper('grade_categories', 'grade_category', $params);
}

/**
Expand All @@ -181,7 +182,8 @@ function fetch($params) {
* @return array array of grade_category insatnces or false if none found.
*/
function fetch_all($params) {
return $this->fetch_all_helper('grade_categories', 'grade_category', $params);
$obj = grade_object::get_instance('grade_category');
return $obj->fetch_all_helper('grade_categories', 'grade_category', $params);
}

/**
Expand Down
6 changes: 4 additions & 2 deletions lib/grade/grade_item.php
Expand Up @@ -310,7 +310,8 @@ function qualifies_for_regrading() {
* @return object grade_item instance or false if none found.
*/
function fetch($params) {
return $this->fetch_helper('grade_items', 'grade_item', $params);
$obj = grade_object::get_instance('grade_item');
return $obj->fetch_helper('grade_items', 'grade_item', $params);
}

/**
Expand All @@ -321,7 +322,8 @@ function fetch($params) {
* @return array array of grade_item insatnces or false if none found.
*/
function fetch_all($params) {
return $this->fetch_all_helper('grade_items', 'grade_item', $params);
$obj = grade_object::get_instance('grade_item');
return $obj->fetch_all_helper('grade_items', 'grade_item', $params);
}

/**
Expand Down
48 changes: 37 additions & 11 deletions lib/grade/grade_object.php
Expand Up @@ -360,20 +360,46 @@ function set_properties(&$instance, $params) {
* The following function is a helper for making the code more testable. It allows
* unit tests to mock the objects instantiated and used within method bodies. If no params are given,
* a static instance is returned.
* @param string $class
* @param array $params
* @param bool $fetch
* @param bool $set Whether or not to set the instance instead of getting it
*/
function get_instance($class, $params=NULL, $fetch=true) {
function get_instance($class, $params=NULL, $fetch=true, $set=false, $object=null) {
static $grade_instances = array();
$classes = array('grade_item', 'grade_category', 'grade_grade', 'grade_outcome', 'grade_scale');
if (!in_array($class, $classes)) {
return false;
} elseif (is_null($params)) {
static $grade_instances = array();
if (!array_key_exists($class, $grade_instances)) {
$grade_instances[$class] =& new $class;

if ($set) {
if (!is_object($object)) {
debugging('grade_object::set_instance was given a non-object as parameter!');
return false;
}

if (in_array($class, $classes)) {
// Only set the static instance if it isn't already a mock object
if (!isset($grade_instances[$class]) || get_class($grade_instances[$class]) != get_class($object)) {
$grade_instances[$class] =& $object;
return true;
} else {
return false;
}
} else {
debugging("grade_object::set_instance was given an object that is not supported ($class)!");
return false;
}
$instance =& $grade_instances[$class];
return $instance;
} else {
return new $class($params, $fetch);

} else {
if (!in_array($class, $classes)) {
return false;
} elseif (is_null($params)) {
if (!array_key_exists($class, $grade_instances)) {
$grade_instances[$class] =& new $class;
}
$instance =& $grade_instances[$class];
return $instance;
} else {
return new $class($params, $fetch);
}
}
}
}
Expand Down
13 changes: 6 additions & 7 deletions lib/grade/simpletest/testgradecategory.php
Expand Up @@ -69,10 +69,9 @@ function test_grade_category_fetch() {
$grade_category->lib_wrapper = new mock_lib_wrapper();
$this->assertTrue(method_exists($grade_category, 'fetch'));

$grade_category->lib_wrapper->expectOnce('get_records_select');
$grade_category->lib_wrapper->setReturnValue('get_records_select', array($this->grade_categories[1]));

$grade_category = $grade_category->fetch(array('id'=>$this->grade_categories[1]->id));
$obj = grade_object::get_instance('grade_category');
$obj->setReturnValue('fetch', $this->grade_categories[1]);
$grade_category = $obj->fetch(array('id'=>$this->grade_categories[1]->id));
$this->assertEqual($this->grade_categories[1]->id, $grade_category->id);
$this->assertEqual($this->grade_categories[1]->fullname, $grade_category->fullname);
}
Expand All @@ -82,10 +81,10 @@ function test_grade_category_fetch_all() {
$grade_category->lib_wrapper = new mock_lib_wrapper();
$this->assertTrue(method_exists($grade_category, 'fetch_all'));

$grade_category->lib_wrapper->expectOnce('get_records_select');
$grade_category->lib_wrapper->setReturnValue('get_records_select', $this->grade_categories);
$obj = grade_object::get_instance('grade_category');
$obj->setReturnValue('fetch_all', $this->grade_categories);

$grade_categories = $grade_category->fetch_all(array('courseid'=>$this->courseid));
$grade_categories = $obj->fetch_all(array('courseid'=>$this->courseid));
$this->assertEqual(count($this->grade_categories), count($grade_categories));
}

Expand Down
12 changes: 12 additions & 0 deletions lib/simpletest/fixtures/gradetest.php
Expand Up @@ -46,6 +46,13 @@
Mock::generate('ADODB_' . $CFG->dbtype, 'mock_db');
Mock::generate('ADORecordSet_' . $CFG->dbtype, 'mock_rs');

// Prepare partial mocks for the static grade object instances
Mock::generatePartial('grade_category', 'mock_grade_category_partial', array('fetch', 'fetch_all'));
Mock::generatePartial('grade_item', 'mock_grade_item_partial', array('fetch', 'fetch_all'));
Mock::generatePartial('grade_grade', 'mock_grade_grade_partial', array('fetch', 'fetch_all'));
Mock::generatePartial('grade_outcome', 'mock_grade_outcome_partial', array('fetch', 'fetch_all'));
Mock::generatePartial('grade_scale', 'mock_grade_scale_partial', array('fetch', 'fetch_all'));

/**
* Here is a brief explanation of the test data set up in these unit tests.
* category1 => array(category2 => array(grade_item1, grade_item2), category3 => array(grade_item3))
Expand Down Expand Up @@ -106,6 +113,11 @@ function setUp() {
$CFG->disablegradehistory = false;
$this->real_db = fullclone($db);
// $this->reset_mocks();
grade_object::get_instance('grade_item', null, false, true, new mock_grade_item_partial($this));
grade_object::get_instance('grade_category', null, false, true, new mock_grade_category_partial($this));
grade_object::get_instance('grade_grade', null, false, true, new mock_grade_grade_partial($this));
grade_object::get_instance('grade_outcome', null, false, true, new mock_grade_outcome_partial($this));
grade_object::get_instance('grade_scale', null, false, true, new mock_grade_scale_partial($this));
}

/**
Expand Down

0 comments on commit 795bee3

Please sign in to comment.