Merge branch 'w20_MDL-32960_m23_phpunitref' of git://github.com/skodak/moodle
This commit is contained in:
@@ -0,0 +1,320 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Advanced test case.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Advanced PHPUnit test case customised for Moodle.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class advanced_testcase extends PHPUnit_Framework_TestCase {
|
||||
/** @var bool automatically reset everything? null means log changes */
|
||||
private $resetAfterTest;
|
||||
|
||||
/** @var moodle_transaction */
|
||||
private $testdbtransaction;
|
||||
|
||||
/**
|
||||
* Constructs a test case with the given name.
|
||||
*
|
||||
* Note: use setUp() or setUpBeforeClass() in your test cases.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param string $dataName
|
||||
*/
|
||||
final public function __construct($name = null, array $data = array(), $dataName = '') {
|
||||
parent::__construct($name, $data, $dataName);
|
||||
|
||||
$this->setBackupGlobals(false);
|
||||
$this->setBackupStaticAttributes(false);
|
||||
$this->setRunTestInSeparateProcess(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the bare test sequence.
|
||||
* @return void
|
||||
*/
|
||||
final public function runBare() {
|
||||
global $DB;
|
||||
|
||||
if (phpunit_util::$lastdbwrites != $DB->perf_get_writes()) {
|
||||
// this happens when previous test does not reset, we can not use transactions
|
||||
$this->testdbtransaction = null;
|
||||
|
||||
} else if ($DB->get_dbfamily() === 'postgres' or $DB->get_dbfamily() === 'mssql') {
|
||||
// database must allow rollback of DDL, so no mysql here
|
||||
$this->testdbtransaction = $DB->start_delegated_transaction();
|
||||
}
|
||||
|
||||
try {
|
||||
parent::runBare();
|
||||
// set DB reference in case somebody mocked it in test
|
||||
$DB = phpunit_util::get_global_backup('DB');
|
||||
} catch (Exception $e) {
|
||||
// cleanup after failed expectation
|
||||
phpunit_util::reset_all_data();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if (!$this->testdbtransaction or $this->testdbtransaction->is_disposed()) {
|
||||
$this->testdbtransaction = null;
|
||||
}
|
||||
|
||||
if ($this->resetAfterTest === true) {
|
||||
if ($this->testdbtransaction) {
|
||||
$DB->force_transaction_rollback();
|
||||
phpunit_util::reset_all_database_sequences();
|
||||
phpunit_util::$lastdbwrites = $DB->perf_get_writes(); // no db reset necessary
|
||||
}
|
||||
phpunit_util::reset_all_data();
|
||||
|
||||
} else if ($this->resetAfterTest === false) {
|
||||
if ($this->testdbtransaction) {
|
||||
$this->testdbtransaction->allow_commit();
|
||||
}
|
||||
// keep all data untouched for other tests
|
||||
|
||||
} else {
|
||||
// reset but log what changed
|
||||
if ($this->testdbtransaction) {
|
||||
try {
|
||||
$this->testdbtransaction->allow_commit();
|
||||
} catch (dml_transaction_exception $e) {
|
||||
phpunit_util::reset_all_data();
|
||||
throw new coding_exception('Invalid transaction state detected in test '.$this->getName());
|
||||
}
|
||||
}
|
||||
phpunit_util::reset_all_data(true);
|
||||
}
|
||||
|
||||
// make sure test did not forget to close transaction
|
||||
if ($DB->is_transaction_started()) {
|
||||
phpunit_util::reset_all_data();
|
||||
if ($this->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED
|
||||
or $this->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED
|
||||
or $this->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE) {
|
||||
throw new coding_exception('Test '.$this->getName().' did not close database transaction');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new FlatXmlDataSet with the given $xmlFile. (absolute path.)
|
||||
*
|
||||
* @param string $xmlFile
|
||||
* @return PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet
|
||||
*/
|
||||
protected function createFlatXMLDataSet($xmlFile) {
|
||||
return new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet($xmlFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XMLDataSet with the given $xmlFile. (absolute path.)
|
||||
*
|
||||
* @param string $xmlFile
|
||||
* @return PHPUnit_Extensions_Database_DataSet_XmlDataSet
|
||||
*/
|
||||
protected function createXMLDataSet($xmlFile) {
|
||||
return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($xmlFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new CsvDataSet from the given array of csv files. (absolute paths.)
|
||||
*
|
||||
* @param array $files array tablename=>cvsfile
|
||||
* @param string $delimiter
|
||||
* @param string $enclosure
|
||||
* @param string $escape
|
||||
* @return PHPUnit_Extensions_Database_DataSet_CsvDataSet
|
||||
*/
|
||||
protected function createCsvDataSet($files, $delimiter = ',', $enclosure = '"', $escape = '"') {
|
||||
$dataSet = new PHPUnit_Extensions_Database_DataSet_CsvDataSet($delimiter, $enclosure, $escape);
|
||||
foreach($files as $table=>$file) {
|
||||
$dataSet->addTable($table, $file);
|
||||
}
|
||||
return $dataSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new ArrayDataSet from given array
|
||||
*
|
||||
* @param array $data array of tables, first row in each table is columns
|
||||
* @return phpunit_ArrayDataSet
|
||||
*/
|
||||
protected function createArrayDataSet(array $data) {
|
||||
return new phpunit_ArrayDataSet($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load date into moodle database tables from standard PHPUnit data set.
|
||||
*
|
||||
* Note: it is usually better to use data generators
|
||||
*
|
||||
* @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
|
||||
* @return void
|
||||
*/
|
||||
protected function loadDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) {
|
||||
global $DB;
|
||||
|
||||
$structure = phpunit_util::get_tablestructure();
|
||||
|
||||
foreach($dataset->getTableNames() as $tablename) {
|
||||
$table = $dataset->getTable($tablename);
|
||||
$metadata = $dataset->getTableMetaData($tablename);
|
||||
$columns = $metadata->getColumns();
|
||||
|
||||
$doimport = false;
|
||||
if (isset($structure[$tablename]['id']) and $structure[$tablename]['id']->auto_increment) {
|
||||
$doimport = in_array('id', $columns);
|
||||
}
|
||||
|
||||
for($r=0; $r<$table->getRowCount(); $r++) {
|
||||
$record = $table->getRow($r);
|
||||
if ($doimport) {
|
||||
$DB->import_record($tablename, $record);
|
||||
} else {
|
||||
$DB->insert_record($tablename, $record);
|
||||
}
|
||||
}
|
||||
if ($doimport) {
|
||||
$DB->get_manager()->reset_sequence(new xmldb_table($tablename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method from test if you want to make sure that
|
||||
* the resetting of database is done the slow way without transaction
|
||||
* rollback.
|
||||
*
|
||||
* This is useful especially when testing stuff that is not compatible with transactions.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function preventResetByRollback() {
|
||||
if ($this->testdbtransaction and !$this->testdbtransaction->is_disposed()) {
|
||||
$this->testdbtransaction->allow_commit();
|
||||
$this->testdbtransaction = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset everything after current test.
|
||||
* @param bool $reset true means reset state back, false means keep all data for the next test,
|
||||
* null means reset state and show warnings if anything changed
|
||||
* @return void
|
||||
*/
|
||||
public function resetAfterTest($reset = true) {
|
||||
$this->resetAfterTest = $reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup after all tests are executed.
|
||||
*
|
||||
* Note: do not forget to call this if overridden...
|
||||
*
|
||||
* @static
|
||||
* @return void
|
||||
*/
|
||||
public static function tearDownAfterClass() {
|
||||
phpunit_util::reset_all_data();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all database tables, restore global state and clear caches and optionally purge dataroot dir.
|
||||
* @static
|
||||
* @return void
|
||||
*/
|
||||
public static function resetAllData() {
|
||||
phpunit_util::reset_all_data();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current $USER, reset access cache.
|
||||
* @static
|
||||
* @param null|int|stdClass $user user record, null means non-logged-in, integer means userid
|
||||
* @return void
|
||||
*/
|
||||
public static function setUser($user = null) {
|
||||
global $CFG, $DB;
|
||||
|
||||
if (is_object($user)) {
|
||||
$user = clone($user);
|
||||
} else if (!$user) {
|
||||
$user = new stdClass();
|
||||
$user->id = 0;
|
||||
$user->mnethostid = $CFG->mnet_localhost_id;
|
||||
} else {
|
||||
$user = $DB->get_record('user', array('id'=>$user));
|
||||
}
|
||||
unset($user->description);
|
||||
unset($user->access);
|
||||
|
||||
session_set_user($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data generator
|
||||
* @static
|
||||
* @return phpunit_data_generator
|
||||
*/
|
||||
public static function getDataGenerator() {
|
||||
return phpunit_util::get_data_generator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively visit all the files in the source tree. Calls the callback
|
||||
* function with the pathname of each file found.
|
||||
*
|
||||
* @param string $path the folder to start searching from.
|
||||
* @param string $callback the method of this class to call with the name of each file found.
|
||||
* @param string $fileregexp a regexp used to filter the search (optional).
|
||||
* @param bool $exclude If true, pathnames that match the regexp will be ignored. If false,
|
||||
* only files that match the regexp will be included. (default false).
|
||||
* @param array $ignorefolders will not go into any of these folders (optional).
|
||||
* @return void
|
||||
*/
|
||||
public function recurseFolders($path, $callback, $fileregexp = '/.*/', $exclude = false, $ignorefolders = array()) {
|
||||
$files = scandir($path);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$filepath = $path .'/'. $file;
|
||||
if (strpos($file, '.') === 0) {
|
||||
/// Don't check hidden files.
|
||||
continue;
|
||||
} else if (is_dir($filepath)) {
|
||||
if (!in_array($filepath, $ignorefolders)) {
|
||||
$this->recurseFolders($filepath, $callback, $fileregexp, $exclude, $ignorefolders);
|
||||
}
|
||||
} else if ($exclude xor preg_match($fileregexp, $filepath)) {
|
||||
$this->$callback($filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Array based data iterator.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Based on array iterator code from PHPUnit documentation by Sebastian Bergmann
|
||||
* with new constructor parameter for different array types.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class phpunit_ArrayDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $tables = array();
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data) {
|
||||
foreach ($data AS $tableName => $rows) {
|
||||
$firstrow = reset($rows);
|
||||
|
||||
if (array_key_exists(0, $firstrow)) {
|
||||
// columns in first row
|
||||
$columnsInFirstRow = true;
|
||||
$columns = $firstrow;
|
||||
$key = key($rows);
|
||||
unset($rows[$key]);
|
||||
} else {
|
||||
// column name is in each row as key
|
||||
$columnsInFirstRow = false;
|
||||
$columns = array_keys($firstrow);
|
||||
}
|
||||
|
||||
$metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns);
|
||||
$table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData);
|
||||
|
||||
foreach ($rows AS $row) {
|
||||
if ($columnsInFirstRow) {
|
||||
$row = array_combine($columns, $row);
|
||||
}
|
||||
$table->addRow($row);
|
||||
}
|
||||
$this->tables[$tableName] = $table;
|
||||
}
|
||||
}
|
||||
|
||||
protected function createIterator($reverse = FALSE) {
|
||||
return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
|
||||
}
|
||||
|
||||
public function getTable($tableName) {
|
||||
if (!isset($this->tables[$tableName])) {
|
||||
throw new InvalidArgumentException("$tableName is not a table in the current database.");
|
||||
}
|
||||
|
||||
return $this->tables[$tableName];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Basic test case.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The simplest PHPUnit test case customised for Moodle
|
||||
*
|
||||
* It is intended for isolated tests that do not modify database or any globals.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class basic_testcase extends PHPUnit_Framework_TestCase {
|
||||
|
||||
/**
|
||||
* Constructs a test case with the given name.
|
||||
*
|
||||
* Note: use setUp() or setUpBeforeClass() in your test cases.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param string $dataName
|
||||
*/
|
||||
final public function __construct($name = null, array $data = array(), $dataName = '') {
|
||||
parent::__construct($name, $data, $dataName);
|
||||
|
||||
$this->setBackupGlobals(false);
|
||||
$this->setBackupStaticAttributes(false);
|
||||
$this->setRunTestInSeparateProcess(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the bare test sequence and log any changes in global state or database.
|
||||
* @return void
|
||||
*/
|
||||
final public function runBare() {
|
||||
global $DB;
|
||||
|
||||
try {
|
||||
parent::runBare();
|
||||
} catch (Exception $e) {
|
||||
// cleanup after failed expectation
|
||||
phpunit_util::reset_all_data();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($DB->is_transaction_started()) {
|
||||
phpunit_util::reset_all_data();
|
||||
throw new coding_exception('basic_testcase '.$this->getName().' is not supposed to use database transactions!');
|
||||
}
|
||||
|
||||
phpunit_util::reset_all_data(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Block generator base class.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Block generator base class.
|
||||
*
|
||||
* Extend in blocks/xxxx/tests/generator/lib.php as class block_xxxx_generator.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class phpunit_block_generator {
|
||||
/** @var phpunit_data_generator@var */
|
||||
protected $datagenerator;
|
||||
|
||||
/** @var number of created instances */
|
||||
protected $instancecount = 0;
|
||||
|
||||
public function __construct(phpunit_data_generator $datagenerator) {
|
||||
$this->datagenerator = $datagenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called from data reset code only,
|
||||
* do not use in tests.
|
||||
* @return void
|
||||
*/
|
||||
public function reset() {
|
||||
$this->instancecount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns block name
|
||||
* @return string name of block that this class describes
|
||||
* @throws coding_exception if class invalid
|
||||
*/
|
||||
public function get_blockname() {
|
||||
$matches = null;
|
||||
if (!preg_match('/^block_([a-z0-9_]+)_generator$/', get_class($this), $matches)) {
|
||||
throw new coding_exception('Invalid block generator class name: '.get_class($this));
|
||||
}
|
||||
|
||||
if (empty($matches[1])) {
|
||||
throw new coding_exception('Invalid block generator class name: '.get_class($this));
|
||||
}
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in record defaults
|
||||
* @param stdClass $record
|
||||
* @return stdClass
|
||||
*/
|
||||
protected function prepare_record(stdClass $record) {
|
||||
$record->blockname = $this->get_blockname();
|
||||
if (!isset($record->parentcontextid)) {
|
||||
$record->parentcontextid = context_system::instance()->id;
|
||||
}
|
||||
if (!isset($record->showinsubcontexts)) {
|
||||
$record->showinsubcontexts = 1;
|
||||
}
|
||||
if (!isset($record->pagetypepattern)) {
|
||||
$record->pagetypepattern = '';
|
||||
}
|
||||
if (!isset($record->subpagepattern)) {
|
||||
$record->subpagepattern = null;
|
||||
}
|
||||
if (!isset($record->defaultregion)) {
|
||||
$record->defaultregion = '';
|
||||
}
|
||||
if (!isset($record->defaultweight)) {
|
||||
$record->defaultweight = '';
|
||||
}
|
||||
if (!isset($record->configdata)) {
|
||||
$record->configdata = null;
|
||||
}
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test block
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass activity record
|
||||
*/
|
||||
abstract public function create_instance($record = null, array $options = null);
|
||||
}
|
||||
@@ -0,0 +1,544 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Data generator.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Data generator class for unit tests and other tools
|
||||
* that need to create fake test sites.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class phpunit_data_generator {
|
||||
protected $usercounter = 0;
|
||||
protected $categorycount = 0;
|
||||
protected $coursecount = 0;
|
||||
protected $scalecount = 0;
|
||||
protected $groupcount = 0;
|
||||
protected $groupingcount = 0;
|
||||
|
||||
/** @var array list of plugin generators */
|
||||
protected $generators = array();
|
||||
|
||||
/** @var array lis of common last names */
|
||||
public $lastnames = array(
|
||||
'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Miller', 'Davis', 'García', 'Rodríguez', 'Wilson',
|
||||
'Müller', 'Schmidt', 'Schneider', 'Fischer', 'Meyer', 'Weber', 'Schulz', 'Wagner', 'Becker', 'Hoffmann',
|
||||
'Novák', 'Svoboda', 'Novotný', 'Dvořák', 'Černý', 'Procházková', 'Kučerová', 'Veselá', 'Horáková', 'Němcová',
|
||||
'Смирнов', 'Иванов', 'Кузнецов', 'Соколов', 'Попов', 'Лебедева', 'Козлова', 'Новикова', 'Морозова', 'Петрова',
|
||||
'王', '李', '张', '刘', '陈', '楊', '黃', '趙', '吳', '周',
|
||||
'佐藤', '鈴木', '高橋', '田中', '渡辺', '伊藤', '山本', '中村', '小林', '斎藤',
|
||||
);
|
||||
|
||||
/** @var array lis of common first names */
|
||||
public $firstnames = array(
|
||||
'Jacob', 'Ethan', 'Michael', 'Jayden', 'William', 'Isabella', 'Sophia', 'Emma', 'Olivia', 'Ava',
|
||||
'Lukas', 'Leon', 'Luca', 'Timm', 'Paul', 'Leonie', 'Leah', 'Lena', 'Hanna', 'Laura',
|
||||
'Jakub', 'Jan', 'Tomáš', 'Lukáš', 'Matěj', 'Tereza', 'Eliška', 'Anna', 'Adéla', 'Karolína',
|
||||
'Даниил', 'Максим', 'Артем', 'Иван', 'Александр', 'София', 'Анастасия', 'Дарья', 'Мария', 'Полина',
|
||||
'伟', '伟', '芳', '伟', '秀英', '秀英', '娜', '秀英', '伟', '敏',
|
||||
'翔', '大翔', '拓海', '翔太', '颯太', '陽菜', 'さくら', '美咲', '葵', '美羽',
|
||||
);
|
||||
|
||||
public $loremipsum = <<<EOD
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla non arcu lacinia neque faucibus fringilla. Vivamus porttitor turpis ac leo. Integer in sapien. Nullam eget nisl. Aliquam erat volutpat. Cras elementum. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Integer malesuada. Nullam lectus justo, vulputate eget mollis sed, tempor sed magna. Mauris elementum mauris vitae tortor. Aliquam erat volutpat.
|
||||
Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Pellentesque ipsum. Cras pede libero, dapibus nec, pretium sit amet, tempor quis. Aliquam ante. Proin in tellus sit amet nibh dignissim sagittis. Vivamus porttitor turpis ac leo. Duis bibendum, lectus ut viverra rhoncus, dolor nunc faucibus libero, eget facilisis enim ipsum id lacus. In sem justo, commodo ut, suscipit at, pharetra vitae, orci. Aliquam erat volutpat. Nulla est.
|
||||
Vivamus luctus egestas leo. Aenean fermentum risus id tortor. Mauris dictum facilisis augue. Aliquam erat volutpat. Aliquam ornare wisi eu metus. Aliquam id dolor. Duis condimentum augue id magna semper rutrum. Donec iaculis gravida nulla. Pellentesque ipsum. Etiam dictum tincidunt diam. Quisque tincidunt scelerisque libero. Etiam egestas wisi a erat.
|
||||
Integer lacinia. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris tincidunt sem sed arcu. Nullam feugiat, turpis at pulvinar vulputate, erat libero tristique tellus, nec bibendum odio risus sit amet ante. Aliquam id dolor. Maecenas sollicitudin. Et harum quidem rerum facilis est et expedita distinctio. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Nullam dapibus fermentum ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Pellentesque sapien. Duis risus. Mauris elementum mauris vitae tortor. Suspendisse nisl. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim.
|
||||
In laoreet, magna id viverra tincidunt, sem odio bibendum justo, vel imperdiet sapien wisi sed libero. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Nullam justo enim, consectetuer nec, ullamcorper ac, vestibulum in, elit. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Maecenas lorem. Etiam posuere lacus quis dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Curabitur ligula sapien, pulvinar a vestibulum quis, facilisis vel sapien. Nam sed tellus id magna elementum tincidunt. Suspendisse nisl. Vivamus luctus egestas leo. Nulla non arcu lacinia neque faucibus fringilla. Etiam dui sem, fermentum vitae, sagittis id, malesuada in, quam. Etiam dictum tincidunt diam. Etiam commodo dui eget wisi. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Duis ante orci, molestie vitae vehicula venenatis, tincidunt ac pede. Pellentesque sapien.
|
||||
EOD;
|
||||
|
||||
/**
|
||||
* To be called from data reset code only,
|
||||
* do not use in tests.
|
||||
* @return void
|
||||
*/
|
||||
public function reset() {
|
||||
$this->usercounter = 0;
|
||||
$this->categorycount = 0;
|
||||
$this->coursecount = 0;
|
||||
$this->scalecount = 0;
|
||||
|
||||
foreach($this->generators as $generator) {
|
||||
$generator->reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return generator for given plugin
|
||||
* @param string $component
|
||||
* @return mixed plugin data generator
|
||||
*/
|
||||
public function get_plugin_generator($component) {
|
||||
list($type, $plugin) = normalize_component($component);
|
||||
|
||||
if ($type !== 'mod' and $type !== 'block') {
|
||||
throw new coding_exception("Plugin type $type does not support generators yet");
|
||||
}
|
||||
|
||||
$dir = get_plugin_directory($type, $plugin);
|
||||
|
||||
if (!isset($this->generators[$type.'_'.$plugin])) {
|
||||
$lib = "$dir/tests/generator/lib.php";
|
||||
if (!include_once($lib)) {
|
||||
throw new coding_exception("Plugin $component does not support data generator, missing tests/generator/lib");
|
||||
}
|
||||
$classname = $type.'_'.$plugin.'_generator';
|
||||
$this->generators[$type.'_'.$plugin] = new $classname($this);
|
||||
}
|
||||
|
||||
return $this->generators[$type.'_'.$plugin];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test user
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass user record
|
||||
*/
|
||||
public function create_user($record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
|
||||
$this->usercounter++;
|
||||
$i = $this->usercounter;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['auth'])) {
|
||||
$record['auth'] = 'manual';
|
||||
}
|
||||
|
||||
if (!isset($record['firstname']) and !isset($record['lastname'])) {
|
||||
$country = rand(0, 5);
|
||||
$firstname = rand(0, 4);
|
||||
$lastname = rand(0, 4);
|
||||
$female = rand(0, 1);
|
||||
$record['firstname'] = $this->firstnames[($country*10) + $firstname + ($female*5)];
|
||||
$record['lastname'] = $this->lastnames[($country*10) + $lastname + ($female*5)];
|
||||
|
||||
} else if (!isset($record['firstname'])) {
|
||||
$record['firstname'] = 'Firstname'.$i;
|
||||
|
||||
} else if (!isset($record['lastname'])) {
|
||||
$record['lastname'] = 'Lastname'.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['idnumber'])) {
|
||||
$record['idnumber'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['mnethostid'])) {
|
||||
$record['mnethostid'] = $CFG->mnet_localhost_id;
|
||||
}
|
||||
|
||||
if (!isset($record['username'])) {
|
||||
$record['username'] = textlib::strtolower($record['firstname']).textlib::strtolower($record['lastname']);
|
||||
while ($DB->record_exists('user', array('username'=>$record['username'], 'mnethostid'=>$record['mnethostid']))) {
|
||||
$record['username'] = $record['username'].'_'.$i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($record['password'])) {
|
||||
$record['password'] = 'lala';
|
||||
}
|
||||
|
||||
if (!isset($record['email'])) {
|
||||
$record['email'] = $record['username'].'@example.com';
|
||||
}
|
||||
|
||||
if (!isset($record['confirmed'])) {
|
||||
$record['confirmed'] = 1;
|
||||
}
|
||||
|
||||
if (!isset($record['lang'])) {
|
||||
$record['lang'] = 'en';
|
||||
}
|
||||
|
||||
if (!isset($record['maildisplay'])) {
|
||||
$record['maildisplay'] = 1;
|
||||
}
|
||||
|
||||
if (!isset($record['deleted'])) {
|
||||
$record['deleted'] = 0;
|
||||
}
|
||||
|
||||
$record['timecreated'] = time();
|
||||
$record['timemodified'] = $record['timecreated'];
|
||||
$record['lastip'] = '0.0.0.0';
|
||||
|
||||
$record['password'] = hash_internal_user_password($record['password']);
|
||||
|
||||
if ($record['deleted']) {
|
||||
$delname = $record['email'].'.'.time();
|
||||
while ($DB->record_exists('user', array('username'=>$delname))) {
|
||||
$delname++;
|
||||
}
|
||||
$record['idnumber'] = '';
|
||||
$record['email'] = md5($record['username']);
|
||||
$record['username'] = $delname;
|
||||
$record['picture'] = 0;
|
||||
}
|
||||
|
||||
$userid = $DB->insert_record('user', $record);
|
||||
|
||||
if (!$record['deleted']) {
|
||||
context_user::instance($userid);
|
||||
}
|
||||
|
||||
return $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test course category
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass course category record
|
||||
*/
|
||||
function create_category($record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
require_once("$CFG->dirroot/course/lib.php");
|
||||
|
||||
$this->categorycount++;
|
||||
$i = $this->categorycount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'Course category '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['idnumber'])) {
|
||||
$record['idnumber'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = "Test course category $i\n$this->loremipsum";
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['description'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if (!isset($record['parent'])) {
|
||||
$record['descriptionformat'] = 0;
|
||||
}
|
||||
|
||||
if (empty($record['parent'])) {
|
||||
$parent = new stdClass();
|
||||
$parent->path = '';
|
||||
$parent->depth = 0;
|
||||
} else {
|
||||
$parent = $DB->get_record('course_categories', array('id'=>$record['parent']), '*', MUST_EXIST);
|
||||
}
|
||||
$record['depth'] = $parent->depth+1;
|
||||
|
||||
$record['sortorder'] = 0;
|
||||
$record['timemodified'] = time();
|
||||
$record['timecreated'] = $record['timemodified'];
|
||||
|
||||
$catid = $DB->insert_record('course_categories', $record);
|
||||
$path = $parent->path . '/' . $catid;
|
||||
$DB->set_field('course_categories', 'path', $path, array('id'=>$catid));
|
||||
context_coursecat::instance($catid);
|
||||
|
||||
fix_course_sortorder();
|
||||
|
||||
return $DB->get_record('course_categories', array('id'=>$catid), '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test course
|
||||
* @param array|stdClass $record
|
||||
* @param array $options with keys:
|
||||
* 'createsections'=>bool precreate all sections
|
||||
* @return stdClass course record
|
||||
*/
|
||||
function create_course($record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
require_once("$CFG->dirroot/course/lib.php");
|
||||
|
||||
$this->coursecount++;
|
||||
$i = $this->coursecount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['fullname'])) {
|
||||
$record['fullname'] = 'Test course '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['shortname'])) {
|
||||
$record['shortname'] = 'tc_'.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['idnumber'])) {
|
||||
$record['idnumber'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['format'])) {
|
||||
$record['format'] = 'topics';
|
||||
}
|
||||
|
||||
if (!isset($record['newsitems'])) {
|
||||
$record['newsitems'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($record['numsections'])) {
|
||||
$record['numsections'] = 5;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = "Test course $i\n$this->loremipsum";
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['description'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if (!isset($record['category'])) {
|
||||
$record['category'] = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
|
||||
}
|
||||
|
||||
$course = create_course((object)$record);
|
||||
context_course::instance($course->id);
|
||||
|
||||
if (!empty($options['createsections'])) {
|
||||
for($i=1; $i<$record['numsections']; $i++) {
|
||||
self::create_course_section(array('course'=>$course->id, 'section'=>$i));
|
||||
}
|
||||
}
|
||||
|
||||
return $course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create course section if does not exist yet
|
||||
* @param mixed $record
|
||||
* @param array|null $options
|
||||
* @return stdClass
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function create_course_section($record = null, array $options = null) {
|
||||
global $DB;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (empty($record['course'])) {
|
||||
throw new coding_exception('course must be present in phpunit_util::create_course_section() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['section'])) {
|
||||
throw new coding_exception('section must be present in phpunit_util::create_course_section() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['summary'])) {
|
||||
$record['summary'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['summaryformat'])) {
|
||||
$record['summaryformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if ($section = $DB->get_record('course_sections', array('course'=>$record['course'], 'section'=>$record['section']))) {
|
||||
return $section;
|
||||
}
|
||||
|
||||
$section = new stdClass();
|
||||
$section->course = $record['course'];
|
||||
$section->section = $record['section'];
|
||||
$section->name = $record['name'];
|
||||
$section->summary = $record['summary'];
|
||||
$section->summaryformat = $record['summaryformat'];
|
||||
$id = $DB->insert_record('course_sections', $section);
|
||||
|
||||
return $DB->get_record('course_sections', array('id'=>$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test block
|
||||
* @param string $blockname
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass block instance record
|
||||
*/
|
||||
public function create_block($blockname, $record=null, array $options=null) {
|
||||
$generator = $this->get_plugin_generator('block_'.$blockname);
|
||||
return $generator->create_instance($record, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test module
|
||||
* @param string $modulename
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass activity record
|
||||
*/
|
||||
public function create_module($modulename, $record=null, array $options=null) {
|
||||
$generator = $this->get_plugin_generator('mod_'.$modulename);
|
||||
return $generator->create_instance($record, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test group for the specified course
|
||||
*
|
||||
* $record should be either an array or a stdClass containing infomation about the group to create.
|
||||
* At the very least it needs to contain courseid.
|
||||
* Default values are added for name, description, and descriptionformat if they are not present.
|
||||
*
|
||||
* This function calls {@see groups_create_group()} to create the group within the database.
|
||||
*
|
||||
* @param array|stdClass $record
|
||||
* @return stdClass group record
|
||||
*/
|
||||
public function create_group($record) {
|
||||
global $DB, $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/group/lib.php');
|
||||
|
||||
$this->groupcount++;
|
||||
$i = $this->groupcount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (empty($record['courseid'])) {
|
||||
throw new coding_exception('courseid must be present in phpunit_util::create_group() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'group-' . $i;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = "Test Group $i\n{$this->loremipsum}";
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['descriptionformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
$id = groups_create_group((object)$record);
|
||||
|
||||
return $DB->get_record('groups', array('id'=>$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test grouping for the specified course
|
||||
*
|
||||
* $record should be either an array or a stdClass containing infomation about the grouping to create.
|
||||
* At the very least it needs to contain courseid.
|
||||
* Default values are added for name, description, and descriptionformat if they are not present.
|
||||
*
|
||||
* This function calls {@see groups_create_grouping()} to create the grouping within the database.
|
||||
*
|
||||
* @param array|stdClass $record
|
||||
* @return stdClass grouping record
|
||||
*/
|
||||
public function create_grouping($record) {
|
||||
global $DB, $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/group/lib.php');
|
||||
|
||||
$this->groupingcount++;
|
||||
$i = $this->groupingcount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (empty($record['courseid'])) {
|
||||
throw new coding_exception('courseid must be present in phpunit_util::create_grouping() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'grouping-' . $i;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = "Test Grouping $i\n{$this->loremipsum}";
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['descriptionformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
$id = groups_create_grouping((object)$record);
|
||||
|
||||
return $DB->get_record('groupings', array('id'=>$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test scale
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass block instance record
|
||||
*/
|
||||
public function create_scale($record=null, array $options=null) {
|
||||
global $DB;
|
||||
|
||||
$this->scalecount++;
|
||||
$i = $this->scalecount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'Test scale '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['scale'])) {
|
||||
$record['scale'] = 'A,B,C,D,F';
|
||||
}
|
||||
|
||||
if (!isset($record['courseid'])) {
|
||||
$record['courseid'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($record['userid'])) {
|
||||
$record['userid'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = 'Test scale description '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['descriptionformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
$record['timemodified'] = time();
|
||||
|
||||
if (isset($record['id'])) {
|
||||
$DB->import_record('scale', $record);
|
||||
$DB->get_manager()->reset_sequence('scale');
|
||||
$id = $record['id'];
|
||||
} else {
|
||||
$id = $DB->insert_record('scale', $record);
|
||||
}
|
||||
|
||||
return $DB->get_record('scale', array('id'=>$id), '*', MUST_EXIST);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Database driver test case.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Special test case for testing of DML drivers and DDL layer.
|
||||
*
|
||||
* Note: Use only 'test_table*' names when creating new tables.
|
||||
*
|
||||
* For DML/DDL developers: you can add following settings to config.php if you want to test different driver than the main one,
|
||||
* the reason is to allow testing of incomplete drivers that do not allow full PHPUnit environment
|
||||
* initialisation (the database can be empty).
|
||||
* $CFG->phpunit_extra_drivers = array(
|
||||
* 1=>array('dbtype'=>'mysqli', 'dbhost'=>'localhost', 'dbname'=>'moodle', 'dbuser'=>'root', 'dbpass'=>'', 'prefix'=>'phpu2_'),
|
||||
* 2=>array('dbtype'=>'pgsql', 'dbhost'=>'localhost', 'dbname'=>'moodle', 'dbuser'=>'postgres', 'dbpass'=>'', 'prefix'=>'phpu2_'),
|
||||
* 3=>array('dbtype'=>'sqlsrv', 'dbhost'=>'127.0.0.1', 'dbname'=>'moodle', 'dbuser'=>'sa', 'dbpass'=>'', 'prefix'=>'phpu2_'),
|
||||
* 4=>array('dbtype'=>'oci', 'dbhost'=>'127.0.0.1', 'dbname'=>'XE', 'dbuser'=>'sa', 'dbpass'=>'', 'prefix'=>'t_'),
|
||||
* );
|
||||
* define('PHPUNIT_TEST_DRIVER')=1; //number is index in the previous array
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class database_driver_testcase extends PHPUnit_Framework_TestCase {
|
||||
/** @var moodle_database connection to extra database */
|
||||
private static $extradb = null;
|
||||
|
||||
/** @var moodle_database used in these tests*/
|
||||
protected $tdb;
|
||||
|
||||
/**
|
||||
* Constructs a test case with the given name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param string $dataName
|
||||
*/
|
||||
final public function __construct($name = null, array $data = array(), $dataName = '') {
|
||||
parent::__construct($name, $data, $dataName);
|
||||
|
||||
$this->setBackupGlobals(false);
|
||||
$this->setBackupStaticAttributes(false);
|
||||
$this->setRunTestInSeparateProcess(false);
|
||||
}
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
global $CFG;
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
if (!defined('PHPUNIT_TEST_DRIVER')) {
|
||||
// use normal $DB
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER])) {
|
||||
throw new exception('Can not find driver configuration options with index: '.PHPUNIT_TEST_DRIVER);
|
||||
}
|
||||
|
||||
$dblibrary = empty($CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dblibrary']) ? 'native' : $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dblibrary'];
|
||||
$dbtype = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbtype'];
|
||||
$dbhost = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbhost'];
|
||||
$dbname = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbname'];
|
||||
$dbuser = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbuser'];
|
||||
$dbpass = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dbpass'];
|
||||
$prefix = $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['prefix'];
|
||||
$dboptions = empty($CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dboptions']) ? array() : $CFG->phpunit_extra_drivers[PHPUNIT_TEST_DRIVER]['dboptions'];
|
||||
|
||||
$classname = "{$dbtype}_{$dblibrary}_moodle_database";
|
||||
require_once("$CFG->libdir/dml/$classname.php");
|
||||
$d = new $classname();
|
||||
if (!$d->driver_installed()) {
|
||||
throw new exception('Database driver for '.$classname.' is not installed');
|
||||
}
|
||||
|
||||
$d->connect($dbhost, $dbuser, $dbpass, $dbname, $prefix, $dboptions);
|
||||
|
||||
self::$extradb = $d;
|
||||
}
|
||||
|
||||
protected function setUp() {
|
||||
global $DB;
|
||||
parent::setUp();
|
||||
|
||||
if (self::$extradb) {
|
||||
$this->tdb = self::$extradb;
|
||||
} else {
|
||||
$this->tdb = $DB;
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
// delete all test tables
|
||||
$dbman = $this->tdb->get_manager();
|
||||
$tables = $this->tdb->get_tables(false);
|
||||
foreach($tables as $tablename) {
|
||||
if (strpos($tablename, 'test_table') === 0) {
|
||||
$table = new xmldb_table($tablename);
|
||||
$dbman->drop_table($table);
|
||||
}
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass() {
|
||||
if (self::$extradb) {
|
||||
self::$extradb->dispose();
|
||||
self::$extradb = null;
|
||||
}
|
||||
phpunit_util::reset_all_data();
|
||||
parent::tearDownAfterClass();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Module generator base class.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Module generator base class.
|
||||
*
|
||||
* Extend in mod/xxxx/tests/generator/lib.php as class mod_xxxx_generator.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class phpunit_module_generator {
|
||||
/** @var phpunit_data_generator@var */
|
||||
protected $datagenerator;
|
||||
|
||||
/** @var number of created instances */
|
||||
protected $instancecount = 0;
|
||||
|
||||
public function __construct(phpunit_data_generator $datagenerator) {
|
||||
$this->datagenerator = $datagenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called from data reset code only,
|
||||
* do not use in tests.
|
||||
* @return void
|
||||
*/
|
||||
public function reset() {
|
||||
$this->instancecount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns module name
|
||||
* @return string name of module that this class describes
|
||||
* @throws coding_exception if class invalid
|
||||
*/
|
||||
public function get_modulename() {
|
||||
$matches = null;
|
||||
if (!preg_match('/^mod_([a-z0-9]+)_generator$/', get_class($this), $matches)) {
|
||||
throw new coding_exception('Invalid module generator class name: '.get_class($this));
|
||||
}
|
||||
|
||||
if (empty($matches[1])) {
|
||||
throw new coding_exception('Invalid module generator class name: '.get_class($this));
|
||||
}
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create course module and link it to course
|
||||
* @param int $courseid
|
||||
* @param array $options: section, visible
|
||||
* @return int $cm instance id
|
||||
*/
|
||||
protected function precreate_course_module($courseid, array $options) {
|
||||
global $DB, $CFG;
|
||||
require_once("$CFG->dirroot/course/lib.php");
|
||||
|
||||
$modulename = $this->get_modulename();
|
||||
|
||||
$cm = new stdClass();
|
||||
$cm->course = $courseid;
|
||||
$cm->module = $DB->get_field('modules', 'id', array('name'=>$modulename));
|
||||
$cm->instance = 0;
|
||||
$cm->section = isset($options['section']) ? $options['section'] : 0;
|
||||
$cm->idnumber = isset($options['idnumber']) ? $options['idnumber'] : 0;
|
||||
$cm->added = time();
|
||||
|
||||
$columns = $DB->get_columns('course_modules');
|
||||
foreach ($options as $key=>$value) {
|
||||
if ($key === 'id' or !isset($columns[$key])) {
|
||||
continue;
|
||||
}
|
||||
if (property_exists($cm, $key)) {
|
||||
continue;
|
||||
}
|
||||
$cm->$key = $value;
|
||||
}
|
||||
|
||||
$cm->id = $DB->insert_record('course_modules', $cm);
|
||||
$cm->coursemodule = $cm->id;
|
||||
|
||||
add_mod_to_section($cm);
|
||||
|
||||
return $cm->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after *_add_instance()
|
||||
* @param int $id
|
||||
* @param int $cmid
|
||||
* @return stdClass module instance
|
||||
*/
|
||||
protected function post_add_instance($id, $cmid) {
|
||||
global $DB;
|
||||
|
||||
$DB->set_field('course_modules', 'instance', $id, array('id'=>$cmid));
|
||||
|
||||
$instance = $DB->get_record($this->get_modulename(), array('id'=>$id), '*', MUST_EXIST);
|
||||
|
||||
$cm = get_coursemodule_from_id($this->get_modulename(), $cmid, $instance->course, true, MUST_EXIST);
|
||||
context_module::instance($cm->id);
|
||||
|
||||
$instance->cmid = $cm->id;
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test module
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass activity record
|
||||
*/
|
||||
abstract public function create_instance($record = null, array $options = null);
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Legacy SimpleTest layer.
|
||||
*
|
||||
* @deprecated since 2.3
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @author Petr Skoda
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Simplified emulation test case for legacy SimpleTest.
|
||||
*
|
||||
* Note: this is supposed to work for very simple tests only.
|
||||
*
|
||||
* @deprecated since 2.3
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @author Petr Skoda
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class UnitTestCase extends PHPUnit_Framework_TestCase {
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @param bool $expected
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function expectException($expected, $message = '') {
|
||||
// alternatively use phpdocs: @expectedException ExceptionClassName
|
||||
if (!$expected) {
|
||||
return;
|
||||
}
|
||||
$this->setExpectedException('moodle_exception', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @param bool $expected
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function expectError($expected = false, $message = '') {
|
||||
// alternatively use phpdocs: @expectedException PHPUnit_Framework_Error
|
||||
if (!$expected) {
|
||||
return;
|
||||
}
|
||||
$this->setExpectedException('PHPUnit_Framework_Error', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $actual
|
||||
* @param string $messages
|
||||
* @return void
|
||||
*/
|
||||
public static function assertTrue($actual, $messages = '') {
|
||||
parent::assertTrue((bool)$actual, $messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $actual
|
||||
* @param string $messages
|
||||
* @return void
|
||||
*/
|
||||
public static function assertFalse($actual, $messages = '') {
|
||||
parent::assertFalse((bool)$actual, $messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $expected
|
||||
* @param mixed $actual
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertEqual($expected, $actual, $message = '') {
|
||||
parent::assertEquals($expected, $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $expected
|
||||
* @param mixed $actual
|
||||
* @param float|int $margin
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertWithinMargin($expected, $actual, $margin, $message = '') {
|
||||
parent::assertEquals($expected, $actual, '', $margin, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $expected
|
||||
* @param mixed $actual
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertNotEqual($expected, $actual, $message = '') {
|
||||
parent::assertNotEquals($expected, $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $expected
|
||||
* @param mixed $actual
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertIdentical($expected, $actual, $message = '') {
|
||||
parent::assertSame($expected, $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $expected
|
||||
* @param mixed $actual
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertNotIdentical($expected, $actual, $message = '') {
|
||||
parent::assertNotSame($expected, $actual, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $actual
|
||||
* @param mixed $expected
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertIsA($actual, $expected, $message = '') {
|
||||
if ($expected === 'array') {
|
||||
parent::assertEquals('array', gettype($actual), $message);
|
||||
} else {
|
||||
parent::assertInstanceOf($expected, $actual, $message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $pattern
|
||||
* @param mixed $string
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertPattern($pattern, $string, $message = '') {
|
||||
parent::assertRegExp($pattern, $string, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.3
|
||||
* @static
|
||||
* @param mixed $pattern
|
||||
* @param mixed $string
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public static function assertNotPattern($pattern, $string, $message = '') {
|
||||
parent::assertNotRegExp($pattern, $string, $message);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* PHPUnit data generator class
|
||||
* PHPUnit data generator support
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
@@ -23,728 +23,9 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
// NOTE: MOODLE_INTERNAL is not verified here because we load this before setup.php!
|
||||
|
||||
require_once(__DIR__.'/classes/data_generator.php');
|
||||
require_once(__DIR__.'/classes/module_generator.php');
|
||||
require_once(__DIR__.'/classes/block_generator.php');
|
||||
|
||||
/**
|
||||
* Data generator for unit tests
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class phpunit_data_generator {
|
||||
protected $usercounter = 0;
|
||||
protected $categorycount = 0;
|
||||
protected $coursecount = 0;
|
||||
protected $scalecount = 0;
|
||||
protected $groupcount = 0;
|
||||
protected $groupingcount = 0;
|
||||
|
||||
/** @var array list of plugin generators */
|
||||
protected $generators = array();
|
||||
|
||||
/** @var array lis of common last names */
|
||||
public $lastnames = array(
|
||||
'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Miller', 'Davis', 'García', 'Rodríguez', 'Wilson',
|
||||
'Müller', 'Schmidt', 'Schneider', 'Fischer', 'Meyer', 'Weber', 'Schulz', 'Wagner', 'Becker', 'Hoffmann',
|
||||
'Novák', 'Svoboda', 'Novotný', 'Dvořák', 'Černý', 'Procházková', 'Kučerová', 'Veselá', 'Horáková', 'Němcová',
|
||||
'Смирнов', 'Иванов', 'Кузнецов', 'Соколов', 'Попов', 'Лебедева', 'Козлова', 'Новикова', 'Морозова', 'Петрова',
|
||||
'王', '李', '张', '刘', '陈', '楊', '黃', '趙', '吳', '周',
|
||||
'佐藤', '鈴木', '高橋', '田中', '渡辺', '伊藤', '山本', '中村', '小林', '斎藤',
|
||||
);
|
||||
|
||||
/** @var array lis of common first names */
|
||||
public $firstnames = array(
|
||||
'Jacob', 'Ethan', 'Michael', 'Jayden', 'William', 'Isabella', 'Sophia', 'Emma', 'Olivia', 'Ava',
|
||||
'Lukas', 'Leon', 'Luca', 'Timm', 'Paul', 'Leonie', 'Leah', 'Lena', 'Hanna', 'Laura',
|
||||
'Jakub', 'Jan', 'Tomáš', 'Lukáš', 'Matěj', 'Tereza', 'Eliška', 'Anna', 'Adéla', 'Karolína',
|
||||
'Даниил', 'Максим', 'Артем', 'Иван', 'Александр', 'София', 'Анастасия', 'Дарья', 'Мария', 'Полина',
|
||||
'伟', '伟', '芳', '伟', '秀英', '秀英', '娜', '秀英', '伟', '敏',
|
||||
'翔', '大翔', '拓海', '翔太', '颯太', '陽菜', 'さくら', '美咲', '葵', '美羽',
|
||||
);
|
||||
|
||||
public $loremipsum = <<<EOD
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla non arcu lacinia neque faucibus fringilla. Vivamus porttitor turpis ac leo. Integer in sapien. Nullam eget nisl. Aliquam erat volutpat. Cras elementum. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Integer malesuada. Nullam lectus justo, vulputate eget mollis sed, tempor sed magna. Mauris elementum mauris vitae tortor. Aliquam erat volutpat.
|
||||
Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Pellentesque ipsum. Cras pede libero, dapibus nec, pretium sit amet, tempor quis. Aliquam ante. Proin in tellus sit amet nibh dignissim sagittis. Vivamus porttitor turpis ac leo. Duis bibendum, lectus ut viverra rhoncus, dolor nunc faucibus libero, eget facilisis enim ipsum id lacus. In sem justo, commodo ut, suscipit at, pharetra vitae, orci. Aliquam erat volutpat. Nulla est.
|
||||
Vivamus luctus egestas leo. Aenean fermentum risus id tortor. Mauris dictum facilisis augue. Aliquam erat volutpat. Aliquam ornare wisi eu metus. Aliquam id dolor. Duis condimentum augue id magna semper rutrum. Donec iaculis gravida nulla. Pellentesque ipsum. Etiam dictum tincidunt diam. Quisque tincidunt scelerisque libero. Etiam egestas wisi a erat.
|
||||
Integer lacinia. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris tincidunt sem sed arcu. Nullam feugiat, turpis at pulvinar vulputate, erat libero tristique tellus, nec bibendum odio risus sit amet ante. Aliquam id dolor. Maecenas sollicitudin. Et harum quidem rerum facilis est et expedita distinctio. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Nullam dapibus fermentum ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Pellentesque sapien. Duis risus. Mauris elementum mauris vitae tortor. Suspendisse nisl. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim.
|
||||
In laoreet, magna id viverra tincidunt, sem odio bibendum justo, vel imperdiet sapien wisi sed libero. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Nullam justo enim, consectetuer nec, ullamcorper ac, vestibulum in, elit. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Maecenas lorem. Etiam posuere lacus quis dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Curabitur ligula sapien, pulvinar a vestibulum quis, facilisis vel sapien. Nam sed tellus id magna elementum tincidunt. Suspendisse nisl. Vivamus luctus egestas leo. Nulla non arcu lacinia neque faucibus fringilla. Etiam dui sem, fermentum vitae, sagittis id, malesuada in, quam. Etiam dictum tincidunt diam. Etiam commodo dui eget wisi. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Duis ante orci, molestie vitae vehicula venenatis, tincidunt ac pede. Pellentesque sapien.
|
||||
EOD;
|
||||
|
||||
/**
|
||||
* To be called from data reset code only,
|
||||
* do not use in tests.
|
||||
* @return void
|
||||
*/
|
||||
public function reset() {
|
||||
$this->usercounter = 0;
|
||||
$this->categorycount = 0;
|
||||
$this->coursecount = 0;
|
||||
$this->scalecount = 0;
|
||||
|
||||
foreach($this->generators as $generator) {
|
||||
$generator->reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return generator for given plugin
|
||||
* @param string $component
|
||||
* @return mixed plugin data generator
|
||||
*/
|
||||
public function get_plugin_generator($component) {
|
||||
list($type, $plugin) = normalize_component($component);
|
||||
|
||||
if ($type !== 'mod' and $type !== 'block') {
|
||||
throw new coding_exception("Plugin type $type does not support generators yet");
|
||||
}
|
||||
|
||||
$dir = get_plugin_directory($type, $plugin);
|
||||
|
||||
if (!isset($this->generators[$type.'_'.$plugin])) {
|
||||
$lib = "$dir/tests/generator/lib.php";
|
||||
if (!include_once($lib)) {
|
||||
throw new coding_exception("Plugin $component does not support data generator, missing tests/generator/lib");
|
||||
}
|
||||
$classname = $type.'_'.$plugin.'_generator';
|
||||
$this->generators[$type.'_'.$plugin] = new $classname($this);
|
||||
}
|
||||
|
||||
return $this->generators[$type.'_'.$plugin];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test user
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass user record
|
||||
*/
|
||||
public function create_user($record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
|
||||
$this->usercounter++;
|
||||
$i = $this->usercounter;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['auth'])) {
|
||||
$record['auth'] = 'manual';
|
||||
}
|
||||
|
||||
if (!isset($record['firstname']) and !isset($record['lastname'])) {
|
||||
$country = rand(0, 5);
|
||||
$firstname = rand(0, 4);
|
||||
$lastname = rand(0, 4);
|
||||
$female = rand(0, 1);
|
||||
$record['firstname'] = $this->firstnames[($country*10) + $firstname + ($female*5)];
|
||||
$record['lastname'] = $this->lastnames[($country*10) + $lastname + ($female*5)];
|
||||
|
||||
} else if (!isset($record['firstname'])) {
|
||||
$record['firstname'] = 'Firstname'.$i;
|
||||
|
||||
} else if (!isset($record['lastname'])) {
|
||||
$record['lastname'] = 'Lastname'.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['idnumber'])) {
|
||||
$record['idnumber'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['mnethostid'])) {
|
||||
$record['mnethostid'] = $CFG->mnet_localhost_id;
|
||||
}
|
||||
|
||||
if (!isset($record['username'])) {
|
||||
$record['username'] = textlib::strtolower($record['firstname']).textlib::strtolower($record['lastname']);
|
||||
while ($DB->record_exists('user', array('username'=>$record['username'], 'mnethostid'=>$record['mnethostid']))) {
|
||||
$record['username'] = $record['username'].'_'.$i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($record['password'])) {
|
||||
$record['password'] = 'lala';
|
||||
}
|
||||
|
||||
if (!isset($record['email'])) {
|
||||
$record['email'] = $record['username'].'@example.com';
|
||||
}
|
||||
|
||||
if (!isset($record['confirmed'])) {
|
||||
$record['confirmed'] = 1;
|
||||
}
|
||||
|
||||
if (!isset($record['lang'])) {
|
||||
$record['lang'] = 'en';
|
||||
}
|
||||
|
||||
if (!isset($record['maildisplay'])) {
|
||||
$record['maildisplay'] = 1;
|
||||
}
|
||||
|
||||
if (!isset($record['deleted'])) {
|
||||
$record['deleted'] = 0;
|
||||
}
|
||||
|
||||
$record['timecreated'] = time();
|
||||
$record['timemodified'] = $record['timecreated'];
|
||||
$record['lastip'] = '0.0.0.0';
|
||||
|
||||
$record['password'] = hash_internal_user_password($record['password']);
|
||||
|
||||
if ($record['deleted']) {
|
||||
$delname = $record['email'].'.'.time();
|
||||
while ($DB->record_exists('user', array('username'=>$delname))) {
|
||||
$delname++;
|
||||
}
|
||||
$record['idnumber'] = '';
|
||||
$record['email'] = md5($record['username']);
|
||||
$record['username'] = $delname;
|
||||
$record['picture'] = 0;
|
||||
}
|
||||
|
||||
$userid = $DB->insert_record('user', $record);
|
||||
|
||||
if (!$record['deleted']) {
|
||||
context_user::instance($userid);
|
||||
}
|
||||
|
||||
return $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test course category
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass course category record
|
||||
*/
|
||||
function create_category($record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
require_once("$CFG->dirroot/course/lib.php");
|
||||
|
||||
$this->categorycount++;
|
||||
$i = $this->categorycount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'Course category '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['idnumber'])) {
|
||||
$record['idnumber'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = "Test course category $i\n$this->loremipsum";
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['description'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if (!isset($record['parent'])) {
|
||||
$record['descriptionformat'] = 0;
|
||||
}
|
||||
|
||||
if (empty($record['parent'])) {
|
||||
$parent = new stdClass();
|
||||
$parent->path = '';
|
||||
$parent->depth = 0;
|
||||
} else {
|
||||
$parent = $DB->get_record('course_categories', array('id'=>$record['parent']), '*', MUST_EXIST);
|
||||
}
|
||||
$record['depth'] = $parent->depth+1;
|
||||
|
||||
$record['sortorder'] = 0;
|
||||
$record['timemodified'] = time();
|
||||
$record['timecreated'] = $record['timemodified'];
|
||||
|
||||
$catid = $DB->insert_record('course_categories', $record);
|
||||
$path = $parent->path . '/' . $catid;
|
||||
$DB->set_field('course_categories', 'path', $path, array('id'=>$catid));
|
||||
context_coursecat::instance($catid);
|
||||
|
||||
fix_course_sortorder();
|
||||
|
||||
return $DB->get_record('course_categories', array('id'=>$catid), '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test course
|
||||
* @param array|stdClass $record
|
||||
* @param array $options with keys:
|
||||
* 'createsections'=>bool precreate all sections
|
||||
* @return stdClass course record
|
||||
*/
|
||||
function create_course($record=null, array $options=null) {
|
||||
global $DB, $CFG;
|
||||
require_once("$CFG->dirroot/course/lib.php");
|
||||
|
||||
$this->coursecount++;
|
||||
$i = $this->coursecount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['fullname'])) {
|
||||
$record['fullname'] = 'Test course '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['shortname'])) {
|
||||
$record['shortname'] = 'tc_'.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['idnumber'])) {
|
||||
$record['idnumber'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['format'])) {
|
||||
$record['format'] = 'topics';
|
||||
}
|
||||
|
||||
if (!isset($record['newsitems'])) {
|
||||
$record['newsitems'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($record['numsections'])) {
|
||||
$record['numsections'] = 5;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = "Test course $i\n$this->loremipsum";
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['description'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if (!isset($record['category'])) {
|
||||
$record['category'] = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
|
||||
}
|
||||
|
||||
$course = create_course((object)$record);
|
||||
context_course::instance($course->id);
|
||||
|
||||
if (!empty($options['createsections'])) {
|
||||
for($i=1; $i<$record['numsections']; $i++) {
|
||||
self::create_course_section(array('course'=>$course->id, 'section'=>$i));
|
||||
}
|
||||
}
|
||||
|
||||
return $course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create course section if does not exist yet
|
||||
* @param mixed $record
|
||||
* @param array|null $options
|
||||
* @return stdClass
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function create_course_section($record = null, array $options = null) {
|
||||
global $DB;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (empty($record['course'])) {
|
||||
throw new coding_exception('course must be present in phpunit_util::create_course_section() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['section'])) {
|
||||
throw new coding_exception('section must be present in phpunit_util::create_course_section() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['summary'])) {
|
||||
$record['summary'] = '';
|
||||
}
|
||||
|
||||
if (!isset($record['summaryformat'])) {
|
||||
$record['summaryformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
if ($section = $DB->get_record('course_sections', array('course'=>$record['course'], 'section'=>$record['section']))) {
|
||||
return $section;
|
||||
}
|
||||
|
||||
$section = new stdClass();
|
||||
$section->course = $record['course'];
|
||||
$section->section = $record['section'];
|
||||
$section->name = $record['name'];
|
||||
$section->summary = $record['summary'];
|
||||
$section->summaryformat = $record['summaryformat'];
|
||||
$id = $DB->insert_record('course_sections', $section);
|
||||
|
||||
return $DB->get_record('course_sections', array('id'=>$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test block
|
||||
* @param string $blockname
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass block instance record
|
||||
*/
|
||||
public function create_block($blockname, $record=null, array $options=null) {
|
||||
$generator = $this->get_plugin_generator('block_'.$blockname);
|
||||
return $generator->create_instance($record, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test module
|
||||
* @param string $modulename
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass activity record
|
||||
*/
|
||||
public function create_module($modulename, $record=null, array $options=null) {
|
||||
$generator = $this->get_plugin_generator('mod_'.$modulename);
|
||||
return $generator->create_instance($record, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test group for the specified course
|
||||
*
|
||||
* $record should be either an array or a stdClass containing infomation about the group to create.
|
||||
* At the very least it needs to contain courseid.
|
||||
* Default values are added for name, description, and descriptionformat if they are not present.
|
||||
*
|
||||
* This function calls {@see groups_create_group()} to create the group within the database.
|
||||
*
|
||||
* @param array|stdClass $record
|
||||
* @return stdClass group record
|
||||
*/
|
||||
public function create_group($record) {
|
||||
global $DB, $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/group/lib.php');
|
||||
|
||||
$this->groupcount++;
|
||||
$i = $this->groupcount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (empty($record['courseid'])) {
|
||||
throw new coding_exception('courseid must be present in phpunit_util::create_group() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'group-' . $i;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = "Test Group $i\n{$this->loremipsum}";
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['descriptionformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
$id = groups_create_group((object)$record);
|
||||
|
||||
return $DB->get_record('groups', array('id'=>$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test grouping for the specified course
|
||||
*
|
||||
* $record should be either an array or a stdClass containing infomation about the grouping to create.
|
||||
* At the very least it needs to contain courseid.
|
||||
* Default values are added for name, description, and descriptionformat if they are not present.
|
||||
*
|
||||
* This function calls {@see groups_create_grouping()} to create the grouping within the database.
|
||||
*
|
||||
* @param array|stdClass $record
|
||||
* @return stdClass grouping record
|
||||
*/
|
||||
public function create_grouping($record) {
|
||||
global $DB, $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/group/lib.php');
|
||||
|
||||
$this->groupingcount++;
|
||||
$i = $this->groupingcount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (empty($record['courseid'])) {
|
||||
throw new coding_exception('courseid must be present in phpunit_util::create_grouping() $record');
|
||||
}
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'grouping-' . $i;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = "Test Grouping $i\n{$this->loremipsum}";
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['descriptionformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
$id = groups_create_grouping((object)$record);
|
||||
|
||||
return $DB->get_record('groupings', array('id'=>$id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test scale
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass block instance record
|
||||
*/
|
||||
public function create_scale($record=null, array $options=null) {
|
||||
global $DB;
|
||||
|
||||
$this->scalecount++;
|
||||
$i = $this->scalecount;
|
||||
|
||||
$record = (array)$record;
|
||||
|
||||
if (!isset($record['name'])) {
|
||||
$record['name'] = 'Test scale '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['scale'])) {
|
||||
$record['scale'] = 'A,B,C,D,F';
|
||||
}
|
||||
|
||||
if (!isset($record['courseid'])) {
|
||||
$record['courseid'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($record['userid'])) {
|
||||
$record['userid'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($record['description'])) {
|
||||
$record['description'] = 'Test scale description '.$i;
|
||||
}
|
||||
|
||||
if (!isset($record['descriptionformat'])) {
|
||||
$record['descriptionformat'] = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
$record['timemodified'] = time();
|
||||
|
||||
if (isset($record['id'])) {
|
||||
$DB->import_record('scale', $record);
|
||||
$DB->get_manager()->reset_sequence('scale');
|
||||
$id = $record['id'];
|
||||
} else {
|
||||
$id = $DB->insert_record('scale', $record);
|
||||
}
|
||||
|
||||
return $DB->get_record('scale', array('id'=>$id), '*', MUST_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Module generator base class.
|
||||
*
|
||||
* Extend in mod/xxxx/tests/generator/lib.php as class mod_xxxx_generator.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class phpunit_module_generator {
|
||||
/** @var phpunit_data_generator@var */
|
||||
protected $datagenerator;
|
||||
|
||||
/** @var number of created instances */
|
||||
protected $instancecount = 0;
|
||||
|
||||
public function __construct(phpunit_data_generator $datagenerator) {
|
||||
$this->datagenerator = $datagenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called from data reset code only,
|
||||
* do not use in tests.
|
||||
* @return void
|
||||
*/
|
||||
public function reset() {
|
||||
$this->instancecount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns module name
|
||||
* @return string name of module that this class describes
|
||||
* @throws coding_exception if class invalid
|
||||
*/
|
||||
public function get_modulename() {
|
||||
$matches = null;
|
||||
if (!preg_match('/^mod_([a-z0-9]+)_generator$/', get_class($this), $matches)) {
|
||||
throw new coding_exception('Invalid module generator class name: '.get_class($this));
|
||||
}
|
||||
|
||||
if (empty($matches[1])) {
|
||||
throw new coding_exception('Invalid module generator class name: '.get_class($this));
|
||||
}
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create course module and link it to course
|
||||
* @param int $courseid
|
||||
* @param array $options: section, visible
|
||||
* @return int $cm instance id
|
||||
*/
|
||||
protected function precreate_course_module($courseid, array $options) {
|
||||
global $DB, $CFG;
|
||||
require_once("$CFG->dirroot/course/lib.php");
|
||||
|
||||
$modulename = $this->get_modulename();
|
||||
|
||||
$cm = new stdClass();
|
||||
$cm->course = $courseid;
|
||||
$cm->module = $DB->get_field('modules', 'id', array('name'=>$modulename));
|
||||
$cm->instance = 0;
|
||||
$cm->section = isset($options['section']) ? $options['section'] : 0;
|
||||
$cm->idnumber = isset($options['idnumber']) ? $options['idnumber'] : 0;
|
||||
$cm->added = time();
|
||||
|
||||
$columns = $DB->get_columns('course_modules');
|
||||
foreach ($options as $key=>$value) {
|
||||
if ($key === 'id' or !isset($columns[$key])) {
|
||||
continue;
|
||||
}
|
||||
if (property_exists($cm, $key)) {
|
||||
continue;
|
||||
}
|
||||
$cm->$key = $value;
|
||||
}
|
||||
|
||||
$cm->id = $DB->insert_record('course_modules', $cm);
|
||||
$cm->coursemodule = $cm->id;
|
||||
|
||||
add_mod_to_section($cm);
|
||||
|
||||
return $cm->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after *_add_instance()
|
||||
* @param int $id
|
||||
* @param int $cmid
|
||||
* @return stdClass module instance
|
||||
*/
|
||||
protected function post_add_instance($id, $cmid) {
|
||||
global $DB;
|
||||
|
||||
$DB->set_field('course_modules', 'instance', $id, array('id'=>$cmid));
|
||||
|
||||
$instance = $DB->get_record($this->get_modulename(), array('id'=>$id), '*', MUST_EXIST);
|
||||
|
||||
$cm = get_coursemodule_from_id($this->get_modulename(), $cmid, $instance->course, true, MUST_EXIST);
|
||||
context_module::instance($cm->id);
|
||||
|
||||
$instance->cmid = $cm->id;
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test module
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass activity record
|
||||
*/
|
||||
abstract public function create_instance($record = null, array $options = null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Block generator base class.
|
||||
*
|
||||
* Extend in blocks/xxxx/tests/generator/lib.php as class block_xxxx_generator.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class phpunit_block_generator {
|
||||
/** @var phpunit_data_generator@var */
|
||||
protected $datagenerator;
|
||||
|
||||
/** @var number of created instances */
|
||||
protected $instancecount = 0;
|
||||
|
||||
public function __construct(phpunit_data_generator $datagenerator) {
|
||||
$this->datagenerator = $datagenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called from data reset code only,
|
||||
* do not use in tests.
|
||||
* @return void
|
||||
*/
|
||||
public function reset() {
|
||||
$this->instancecount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns block name
|
||||
* @return string name of block that this class describes
|
||||
* @throws coding_exception if class invalid
|
||||
*/
|
||||
public function get_blockname() {
|
||||
$matches = null;
|
||||
if (!preg_match('/^block_([a-z0-9_]+)_generator$/', get_class($this), $matches)) {
|
||||
throw new coding_exception('Invalid block generator class name: '.get_class($this));
|
||||
}
|
||||
|
||||
if (empty($matches[1])) {
|
||||
throw new coding_exception('Invalid block generator class name: '.get_class($this));
|
||||
}
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in record defaults
|
||||
* @param stdClass $record
|
||||
* @return stdClass
|
||||
*/
|
||||
protected function prepare_record(stdClass $record) {
|
||||
$record->blockname = $this->get_blockname();
|
||||
if (!isset($record->parentcontextid)) {
|
||||
$record->parentcontextid = context_system::instance()->id;
|
||||
}
|
||||
if (!isset($record->showinsubcontexts)) {
|
||||
$record->showinsubcontexts = 1;
|
||||
}
|
||||
if (!isset($record->pagetypepattern)) {
|
||||
$record->pagetypepattern = '';
|
||||
}
|
||||
if (!isset($record->subpagepattern)) {
|
||||
$record->subpagepattern = null;
|
||||
}
|
||||
if (!isset($record->defaultregion)) {
|
||||
$record->defaultregion = '';
|
||||
}
|
||||
if (!isset($record->defaultweight)) {
|
||||
$record->defaultweight = '';
|
||||
}
|
||||
if (!isset($record->configdata)) {
|
||||
$record->configdata = null;
|
||||
}
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test block
|
||||
* @param array|stdClass $record
|
||||
* @param array $options
|
||||
* @return stdClass activity record
|
||||
*/
|
||||
abstract public function create_instance($record = null, array $options = null);
|
||||
}
|
||||
|
||||
+10
-1797
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* PHPUnit integration unit tests
|
||||
* PHPUnit integration tests
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
@@ -26,135 +26,6 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Test basic_testcase extra features and PHPUnit Moodle integration.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_phpunit_basic_testcase extends basic_testcase {
|
||||
|
||||
/**
|
||||
* Tests that bootstrapping has occurred correctly
|
||||
* @return void
|
||||
*/
|
||||
public function test_bootstrap() {
|
||||
global $CFG;
|
||||
$this->assertTrue(isset($CFG->httpswwwroot));
|
||||
$this->assertEquals($CFG->httpswwwroot, $CFG->wwwroot);
|
||||
$this->assertEquals($CFG->prefix, $CFG->phpunit_prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is just a verification if I understand the PHPUnit assert docs right --skodak
|
||||
* @return void
|
||||
*/
|
||||
public function test_assert_behaviour() {
|
||||
// arrays
|
||||
$a = array('a', 'b', 'c');
|
||||
$b = array('a', 'c', 'b');
|
||||
$c = array('a', 'b', 'c');
|
||||
$d = array('a', 'b', 'C');
|
||||
$this->assertNotEquals($a, $b);
|
||||
$this->assertNotEquals($a, $d);
|
||||
$this->assertEquals($a, $c);
|
||||
$this->assertEquals($a, $b, '', 0, 10, true);
|
||||
|
||||
// objects
|
||||
$a = new stdClass();
|
||||
$a->x = 'x';
|
||||
$a->y = 'y';
|
||||
$b = new stdClass(); // switched order
|
||||
$b->y = 'y';
|
||||
$b->x = 'x';
|
||||
$c = $a;
|
||||
$d = new stdClass();
|
||||
$d->x = 'x';
|
||||
$d->y = 'y';
|
||||
$d->z = 'z';
|
||||
$this->assertEquals($a, $b);
|
||||
$this->assertNotSame($a, $b);
|
||||
$this->assertEquals($a, $c);
|
||||
$this->assertSame($a, $c);
|
||||
$this->assertNotEquals($a, $d);
|
||||
|
||||
// string comparison
|
||||
$this->assertEquals(1, '1');
|
||||
$this->assertEquals(null, '');
|
||||
|
||||
$this->assertNotEquals(1, '1 ');
|
||||
$this->assertNotEquals(0, '');
|
||||
$this->assertNotEquals(null, '0');
|
||||
$this->assertNotEquals(array(), '');
|
||||
|
||||
// other comparison
|
||||
$this->assertEquals(null, null);
|
||||
$this->assertEquals(false, null);
|
||||
$this->assertEquals(0, null);
|
||||
|
||||
// emptiness
|
||||
$this->assertEmpty(0);
|
||||
$this->assertEmpty(0.0);
|
||||
$this->assertEmpty('');
|
||||
$this->assertEmpty('0');
|
||||
$this->assertEmpty(false);
|
||||
$this->assertEmpty(null);
|
||||
$this->assertEmpty(array());
|
||||
|
||||
$this->assertNotEmpty(1);
|
||||
$this->assertNotEmpty(0.1);
|
||||
$this->assertNotEmpty(-1);
|
||||
$this->assertNotEmpty(' ');
|
||||
$this->assertNotEmpty('0 ');
|
||||
$this->assertNotEmpty(true);
|
||||
$this->assertNotEmpty(array(null));
|
||||
$this->assertNotEmpty(new stdClass());
|
||||
}
|
||||
|
||||
// Uncomment following tests to see logging of unexpected changes in global state and database
|
||||
/*
|
||||
public function test_db_modification() {
|
||||
global $DB;
|
||||
$DB->set_field('user', 'confirmed', 1, array('id'=>-1));
|
||||
}
|
||||
|
||||
public function test_cfg_modification() {
|
||||
global $CFG;
|
||||
$CFG->xx = 'yy';
|
||||
unset($CFG->admin);
|
||||
$CFG->rolesactive = 0;
|
||||
}
|
||||
|
||||
public function test_user_modification() {
|
||||
global $USER;
|
||||
$USER->id = 10;
|
||||
}
|
||||
|
||||
public function test_course_modification() {
|
||||
global $COURSE;
|
||||
$COURSE->id = 10;
|
||||
}
|
||||
|
||||
public function test_all_modifications() {
|
||||
global $DB, $CFG, $USER, $COURSE;
|
||||
$DB->set_field('user', 'confirmed', 1, array('id'=>-1));
|
||||
$CFG->xx = 'yy';
|
||||
unset($CFG->admin);
|
||||
$CFG->rolesactive = 0;
|
||||
$USER->id = 10;
|
||||
$COURSE->id = 10;
|
||||
}
|
||||
|
||||
public function test_transaction_problem() {
|
||||
global $DB;
|
||||
$DB->start_delegated_transaction();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test advanced_testcase extra features.
|
||||
*
|
||||
@@ -391,65 +262,3 @@ class core_phpunit_advanced_testcase extends advanced_testcase {
|
||||
$this->assertTrue($DB->record_exists('user', array('username'=>'onemore')));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test data generator
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_phpunit_generator_testcase extends advanced_testcase {
|
||||
public function test_create() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$count = $DB->count_records('user');
|
||||
$user = $generator->create_user();
|
||||
$this->assertEquals($count+1, $DB->count_records('user'));
|
||||
|
||||
$count = $DB->count_records('course_categories');
|
||||
$category = $generator->create_category();
|
||||
$this->assertEquals($count+1, $DB->count_records('course_categories'));
|
||||
|
||||
$count = $DB->count_records('course');
|
||||
$course = $generator->create_course();
|
||||
$this->assertEquals($count+1, $DB->count_records('course'));
|
||||
|
||||
$section = $generator->create_course_section(array('course'=>$course->id, 'section'=>3));
|
||||
$this->assertEquals($course->id, $section->course);
|
||||
|
||||
$scale = $generator->create_scale();
|
||||
$this->assertNotEmpty($scale);
|
||||
}
|
||||
|
||||
public function test_create_module() {
|
||||
global $CFG, $SITE;
|
||||
if (!file_exists("$CFG->dirroot/mod/page/")) {
|
||||
$this->markTestSkipped('Can not find standard Page module');
|
||||
}
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$page = $generator->create_module('page', array('course'=>$SITE->id));
|
||||
$this->assertNotEmpty($page);
|
||||
}
|
||||
|
||||
public function test_create_block() {
|
||||
global $CFG;
|
||||
if (!file_exists("$CFG->dirroot/blocks/online_users/")) {
|
||||
$this->markTestSkipped('Can not find standard Online users block');
|
||||
}
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$page = $generator->create_block('online_users');
|
||||
$this->assertNotEmpty($page);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* PHPUnit integration tests
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Test basic_testcase extra features and PHPUnit Moodle integration.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_phpunit_basic_testcase extends basic_testcase {
|
||||
|
||||
/**
|
||||
* Tests that bootstrapping has occurred correctly
|
||||
* @return void
|
||||
*/
|
||||
public function test_bootstrap() {
|
||||
global $CFG;
|
||||
$this->assertTrue(isset($CFG->httpswwwroot));
|
||||
$this->assertEquals($CFG->httpswwwroot, $CFG->wwwroot);
|
||||
$this->assertEquals($CFG->prefix, $CFG->phpunit_prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is just a verification if I understand the PHPUnit assert docs right --skodak
|
||||
* @return void
|
||||
*/
|
||||
public function test_assert_behaviour() {
|
||||
// arrays
|
||||
$a = array('a', 'b', 'c');
|
||||
$b = array('a', 'c', 'b');
|
||||
$c = array('a', 'b', 'c');
|
||||
$d = array('a', 'b', 'C');
|
||||
$this->assertNotEquals($a, $b);
|
||||
$this->assertNotEquals($a, $d);
|
||||
$this->assertEquals($a, $c);
|
||||
$this->assertEquals($a, $b, '', 0, 10, true);
|
||||
|
||||
// objects
|
||||
$a = new stdClass();
|
||||
$a->x = 'x';
|
||||
$a->y = 'y';
|
||||
$b = new stdClass(); // switched order
|
||||
$b->y = 'y';
|
||||
$b->x = 'x';
|
||||
$c = $a;
|
||||
$d = new stdClass();
|
||||
$d->x = 'x';
|
||||
$d->y = 'y';
|
||||
$d->z = 'z';
|
||||
$this->assertEquals($a, $b);
|
||||
$this->assertNotSame($a, $b);
|
||||
$this->assertEquals($a, $c);
|
||||
$this->assertSame($a, $c);
|
||||
$this->assertNotEquals($a, $d);
|
||||
|
||||
// string comparison
|
||||
$this->assertEquals(1, '1');
|
||||
$this->assertEquals(null, '');
|
||||
|
||||
$this->assertNotEquals(1, '1 ');
|
||||
$this->assertNotEquals(0, '');
|
||||
$this->assertNotEquals(null, '0');
|
||||
$this->assertNotEquals(array(), '');
|
||||
|
||||
// other comparison
|
||||
$this->assertEquals(null, null);
|
||||
$this->assertEquals(false, null);
|
||||
$this->assertEquals(0, null);
|
||||
|
||||
// emptiness
|
||||
$this->assertEmpty(0);
|
||||
$this->assertEmpty(0.0);
|
||||
$this->assertEmpty('');
|
||||
$this->assertEmpty('0');
|
||||
$this->assertEmpty(false);
|
||||
$this->assertEmpty(null);
|
||||
$this->assertEmpty(array());
|
||||
|
||||
$this->assertNotEmpty(1);
|
||||
$this->assertNotEmpty(0.1);
|
||||
$this->assertNotEmpty(-1);
|
||||
$this->assertNotEmpty(' ');
|
||||
$this->assertNotEmpty('0 ');
|
||||
$this->assertNotEmpty(true);
|
||||
$this->assertNotEmpty(array(null));
|
||||
$this->assertNotEmpty(new stdClass());
|
||||
}
|
||||
|
||||
// Uncomment following tests to see logging of unexpected changes in global state and database
|
||||
/*
|
||||
public function test_db_modification() {
|
||||
global $DB;
|
||||
$DB->set_field('user', 'confirmed', 1, array('id'=>-1));
|
||||
}
|
||||
|
||||
public function test_cfg_modification() {
|
||||
global $CFG;
|
||||
$CFG->xx = 'yy';
|
||||
unset($CFG->admin);
|
||||
$CFG->rolesactive = 0;
|
||||
}
|
||||
|
||||
public function test_user_modification() {
|
||||
global $USER;
|
||||
$USER->id = 10;
|
||||
}
|
||||
|
||||
public function test_course_modification() {
|
||||
global $COURSE;
|
||||
$COURSE->id = 10;
|
||||
}
|
||||
|
||||
public function test_all_modifications() {
|
||||
global $DB, $CFG, $USER, $COURSE;
|
||||
$DB->set_field('user', 'confirmed', 1, array('id'=>-1));
|
||||
$CFG->xx = 'yy';
|
||||
unset($CFG->admin);
|
||||
$CFG->rolesactive = 0;
|
||||
$USER->id = 10;
|
||||
$COURSE->id = 10;
|
||||
}
|
||||
|
||||
public function test_transaction_problem() {
|
||||
global $DB;
|
||||
$DB->start_delegated_transaction();
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* PHPUnit integration tests
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
/**
|
||||
* Test data generator
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2012 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_phpunit_generator_testcase extends advanced_testcase {
|
||||
public function test_create() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$count = $DB->count_records('user');
|
||||
$user = $generator->create_user();
|
||||
$this->assertEquals($count+1, $DB->count_records('user'));
|
||||
|
||||
$count = $DB->count_records('course_categories');
|
||||
$category = $generator->create_category();
|
||||
$this->assertEquals($count+1, $DB->count_records('course_categories'));
|
||||
|
||||
$count = $DB->count_records('course');
|
||||
$course = $generator->create_course();
|
||||
$this->assertEquals($count+1, $DB->count_records('course'));
|
||||
|
||||
$section = $generator->create_course_section(array('course'=>$course->id, 'section'=>3));
|
||||
$this->assertEquals($course->id, $section->course);
|
||||
|
||||
$scale = $generator->create_scale();
|
||||
$this->assertNotEmpty($scale);
|
||||
}
|
||||
|
||||
public function test_create_module() {
|
||||
global $CFG, $SITE;
|
||||
if (!file_exists("$CFG->dirroot/mod/page/")) {
|
||||
$this->markTestSkipped('Can not find standard Page module');
|
||||
}
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$page = $generator->create_module('page', array('course'=>$SITE->id));
|
||||
$this->assertNotEmpty($page);
|
||||
}
|
||||
|
||||
public function test_create_block() {
|
||||
global $CFG;
|
||||
if (!file_exists("$CFG->dirroot/blocks/online_users/")) {
|
||||
$this->markTestSkipped('Can not find standard Online users block');
|
||||
}
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$page = $generator->create_block('online_users');
|
||||
$this->assertNotEmpty($page);
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,9 @@
|
||||
<!--All core suites need to be manually added here-->
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="core_phpunit">
|
||||
<directory suffix="_test.php">lib/phpunit/tests</directory>
|
||||
</testsuite>
|
||||
<testsuite name="core_db">
|
||||
<directory suffix="_test.php">lib/ddl/tests</directory>
|
||||
<directory suffix="_test.php">lib/dml/tests</directory>
|
||||
|
||||
Reference in New Issue
Block a user