Merge branch 'MDL-87716-main-alt' of https://github.com/andrewnicols/moodle

This commit is contained in:
Adrian Greeve
2026-02-11 16:00:13 +08:00
100 changed files with 2618 additions and 2079 deletions
+117
View File
@@ -0,0 +1,117 @@
name: Run tests in a Composed Moodle Setup
on:
push:
branches-ignore:
- main
- MOODLE_[0-9]+_STABLE
tags-ignore:
- v[0-9]+.[0-9]+.[0-9]+*
workflow_dispatch:
inputs:
phpunit_extra_options:
description: Additional options to apply to PHPUnit
required: false
default: ''
env:
php: 8.4
jobs:
PHPUnit:
runs-on: ${{ matrix.os }}
services:
exttests:
image: moodlehq/moodle-exttests
ports:
- 8080:80
redis:
image: redis
ports:
- 6379:6379
strategy:
fail-fast: false
matrix:
include:
# MySQL builds always run with the lowest PHP supported version.
- os: ubuntu-24.04
php: 8.3
extensions:
db: mysqli
# PostgreSQL builds always run with the highest PHP supported version.
- os: ubuntu-24.04
php: 8.4
db: pgsql
steps:
- name: Setting up DB mysql
if: ${{ matrix.db == 'mysqli' }}
uses: moodlehq/mysql-action@v1
with:
collation server: utf8mb4_bin
mysql version: 8.4
mysql database: test
mysql user: test
mysql password: test
use tmpfs: true
tmpfs size: '1024M'
extra conf: --skip-log-bin
- name: Setting up DB pgsql
if: ${{ matrix.db == 'pgsql' }}
uses: m4nu56/postgresql-action@v1
with:
postgresql version: 16
postgresql db: test
postgresql user: test
postgresql password: test
- name: Configuring git vars
uses: rlespinasse/github-slug-action@v5
- name: Setting up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: ${{ matrix.extensions }}
ini-values: max_input_vars=5000
coverage: none
tools: composer
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v6
with:
path: 'moodle'
- name: 'Preparing the environment'
run: |
echo "pathtophp=$(which php)" >> $GITHUB_ENV # Inject installed pathtophp to env. The template config needs it.
sudo locale-gen en_AU.UTF-8
- name: Create the new Composer Project
run: |
mkdir testsite
cp moodle/.github/workflows/composed/composer.json testsite/composer.json
cp moodle/.github/workflows/composed/config.php testsite/config.php
mkdir -p testsite/data/moodledata
mkdir -p testsite/data/phpunitdata
- name: Install the Moodle test site
working-directory: testsite
run: |
composer install --no-interaction
- name: Setting up PHPUnit
working-directory: testsite
env:
dbtype: ${{ matrix.db }}
run: |
php moodle/public/admin/tool/phpunit/cli/init.php --no-composer-self-update
- name: Running PHPUnit tests
working-directory: testsite
env:
dbtype: ${{ matrix.db }}
phpunit_options: ${{ secrets.phpunit_options }}
run: |
vendor/bin/phpunit $phpunit_options ${{ inputs.phpunit_extra_options }}
+22
View File
@@ -0,0 +1,22 @@
{
"type": "project",
"require": {
"moodle/composer-installer": "^1",
"moodle/moodle-composer-scaffold": "^1",
"moodle/moodle": "@dev",
"moodle/moodle-testing": "^1.0"
},
"repositories": [
{
"name": "moodleundertest",
"type": "path",
"url": "../moodle"
}
],
"config": {
"allow-plugins": {
"moodle/composer-installer": true,
"moodle/moodle-composer-scaffold": true
}
}
}
+67
View File
@@ -0,0 +1,67 @@
<?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/>.
/**
* Template configuraton file for GitHub Actions CI/CD using Composer.
*
* @package core
* @copyright 2020 onwards Eloy Lafuente (stronk7) {@link https://stronk7.com}
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// This cannot be used out from a GitHub Actions workflow, so just exit.
getenv('GITHUB_WORKFLOW') || die; // phpcs:ignore moodle.Files.MoodleInternal.MoodleInternalGlobalState
unset($CFG);
global $CFG;
$CFG = new stdClass();
$CFG->dbtype = getenv('dbtype');
$CFG->dblibrary = 'native';
$CFG->dbhost = '127.0.0.1';
$CFG->dbname = 'test';
$CFG->dbuser = 'test';
$CFG->dbpass = 'test';
$CFG->prefix = 'm_';
$CFG->dboptions = ['dbcollation' => 'utf8mb4_bin'];
$host = 'localhost';
$CFG->wwwroot = "http://{$host}";
$CFG->dataroot = __DIR__ . '/data/moodledata';
$CFG->admin = 'admin';
$CFG->directorypermissions = 0777;
// Debug options - possible to be controlled by flag in future.
$CFG->debug = (E_ALL); // DEBUG_DEVELOPER.
$CFG->debugdisplay = 1;
$CFG->debugstringids = 1; // Add strings=1 to url to get string ids.
$CFG->perfdebug = 15;
$CFG->debugpageinfo = 1;
$CFG->allowthemechangeonurl = 1;
$CFG->passwordpolicy = 0;
$CFG->cronclionly = 0;
$CFG->pathtophp = getenv('pathtophp');
$CFG->phpunit_dataroot = __DIR__ . '/data/phpunitdata';
$CFG->phpunit_prefix = 't_';
$CFG->routerconfigured = true;
define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://localhost:8080');
define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://localhost:8080');
define('TEST_SESSION_REDIS_HOST', 'localhost');
define('TEST_CACHESTORE_REDIS_TESTSERVERS', 'localhost');
@@ -0,0 +1,18 @@
issueNumber: MDL-87716
notes:
core:
- message: |
The following classes have been renamed and now support autoloading.
The old names will be maintained without debugging until Moodle 6.0.
| Old class name | New class name |
| --- | --- |
| `\phpunit_coverage_info` | `\core\test\phpunit\coverage_info` |
| `\phpunit_event_mock` | `\core\test\phpunit\event_mock` |
| `\phpunit_event_sink` | `\core\test\phpunit\event_sink` |
| `\phpunit_message_sink` | `\core\test\phpunit\message_sink` |
| `\phpunit_phpmailer_sink` | `\core\test\phpunit\phpmailer_sink` |
| `\phpunit_util` | `\core\test\phpunit\phpunit_util` |
| `\testing_util` | `\core\test\testing_util` |
type: changed
+4 -2
View File
@@ -11,10 +11,12 @@
"filp/whoops": "^2.15",
"moodle/moodle-testing": "^1.0"
},
"autoload-dev": {
"autoload": {
"psr-0": {
"Moodle\\BehatExtension": "lib/behat/extension/"
},
}
},
"autoload-dev": {
"psr-4": {
"core_testing\\": "public/lib/testing/classes/",
"core_phpunit\\": "public/lib/phpunit/classes/"
+192 -192
View File
@@ -2,7 +2,7 @@
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
bootstrap="public/lib/phpunit/bootstrap.php"
bootstrap="@root@public/lib/phpunit/bootstrap.php"
processIsolation="false"
backupGlobals="false"
cacheResult="false"
@@ -38,315 +38,315 @@
<testsuites>
<testsuite name="core_phpunit_testsuite">
<directory suffix="_test.php">public/lib/phpunit/tests</directory>
<exclude>public/lib/phpunit/tests/classes</exclude>
<exclude>public/lib/phpunit/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/phpunit/tests</directory>
<exclude>@root@public/lib/phpunit/tests/classes</exclude>
<exclude>@root@public/lib/phpunit/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_test_testsuite">
<directory suffix="_test.php">public/lib/testing/tests</directory>
<exclude>public/lib/testing/tests/classes</exclude>
<exclude>public/lib/testing/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/testing/tests</directory>
<exclude>@root@public/lib/testing/tests/classes</exclude>
<exclude>@root@public/lib/testing/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_ddl_testsuite">
<directory suffix="_test.php">public/lib/ddl/tests</directory>
<exclude>public/lib/ddl/tests/classes</exclude>
<exclude>public/lib/ddl/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/ddl/tests</directory>
<exclude>@root@public/lib/ddl/tests/classes</exclude>
<exclude>@root@public/lib/ddl/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_dml_testsuite">
<directory suffix="_test.php">public/lib/dml/tests</directory>
<exclude>public/lib/dml/tests/classes</exclude>
<exclude>public/lib/dml/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/dml/tests</directory>
<exclude>@root@public/lib/dml/tests/classes</exclude>
<exclude>@root@public/lib/dml/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_testsuite">
<directory suffix="_test.php">public/lib/tests</directory>
<exclude>public/lib/tests/classes</exclude>
<exclude>public/lib/tests/fixtures</exclude>
<!-- <directory suffix="_test.php">public/lib/ajax/tests</directory> -->
<directory suffix="_test.php">@root@public/lib/tests</directory>
<exclude>@root@public/lib/tests/classes</exclude>
<exclude>@root@public/lib/tests/fixtures</exclude>
<!-- <directory suffix="_test.php">@root@public/lib/ajax/tests</directory> -->
</testsuite>
<testsuite name="core_external_testsuite">
<directory suffix="_test.php">public/lib/external/tests</directory>
<exclude>public/lib/external/tests/classes</exclude>
<exclude>public/lib/external/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/external/tests</directory>
<exclude>@root@public/lib/external/tests/classes</exclude>
<exclude>@root@public/lib/external/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_favourites_testsuite">
<directory suffix="_test.php">public/favourites/tests</directory>
<exclude>public/favourites/tests/classes</exclude>
<exclude>public/favourites/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/favourites/tests</directory>
<exclude>@root@public/favourites/tests/classes</exclude>
<exclude>@root@public/favourites/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_form_testsuite">
<directory suffix="_test.php">public/lib/form/tests</directory>
<exclude>public/lib/form/tests/classes</exclude>
<exclude>public/lib/form/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/form/tests</directory>
<exclude>@root@public/lib/form/tests/classes</exclude>
<exclude>@root@public/lib/form/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_files_testsuite">
<directory suffix="_test.php">public/lib/filestorage/tests</directory>
<directory suffix="_test.php">public/lib/filebrowser/tests</directory>
<directory suffix="_test.php">public/files/tests</directory>
<exclude>public/lib/filestorage/tests/classes</exclude>
<exclude>public/lib/filestorage/tests/fixtures</exclude>
<exclude>public/lib/filebrowser/tests/classes</exclude>
<exclude>public/lib/filebrowser/tests/fixtures</exclude>
<exclude>public/files/tests/classes</exclude>
<exclude>public/files/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/filestorage/tests</directory>
<directory suffix="_test.php">@root@public/lib/filebrowser/tests</directory>
<directory suffix="_test.php">@root@public/files/tests</directory>
<exclude>@root@public/lib/filestorage/tests/classes</exclude>
<exclude>@root@public/lib/filestorage/tests/fixtures</exclude>
<exclude>@root@public/lib/filebrowser/tests/classes</exclude>
<exclude>@root@public/lib/filebrowser/tests/fixtures</exclude>
<exclude>@root@public/files/tests/classes</exclude>
<exclude>@root@public/files/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_filter_testsuite">
<directory suffix="_test.php">public/filter/tests</directory>
<exclude>public/filter/tests/classes</exclude>
<exclude>public/filter/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/filter/tests</directory>
<exclude>@root@public/filter/tests/classes</exclude>
<exclude>@root@public/filter/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_role_testsuite">
<directory suffix="_test.php">public/admin/roles/tests</directory>
<exclude>public/admin/roles/tests/classes</exclude>
<directory suffix="_test.php">@root@public/admin/roles/tests</directory>
<exclude>@root@public/admin/roles/tests/classes</exclude>
</testsuite>
<testsuite name="core_cohort_testsuite">
<directory suffix="_test.php">public/cohort/tests</directory>
<exclude>public/cohort/tests/classes</exclude>
<directory suffix="_test.php">@root@public/cohort/tests</directory>
<exclude>@root@public/cohort/tests/classes</exclude>
</testsuite>
<testsuite name="core_grades_testsuite">
<directory suffix="_test.php">public/lib/grade/tests</directory>
<directory suffix="_test.php">public/grade/tests</directory>
<directory suffix="_test.php">public/grade/grading/tests</directory>
<exclude>public/lib/grade/tests/classes</exclude>
<exclude>public/grade/tests/classes</exclude>
<exclude>public/grade/grading/tests/classes</exclude>
<directory suffix="_test.php">@root@public/lib/grade/tests</directory>
<directory suffix="_test.php">@root@public/grade/tests</directory>
<directory suffix="_test.php">@root@public/grade/grading/tests</directory>
<exclude>@root@public/lib/grade/tests/classes</exclude>
<exclude>@root@public/grade/tests/classes</exclude>
<exclude>@root@public/grade/grading/tests/classes</exclude>
</testsuite>
<testsuite name="core_analytics_testsuite">
<directory suffix="_test.php">public/analytics/tests</directory>
<exclude>public/analytics/tests/classes</exclude>
<directory suffix="_test.php">@root@public/analytics/tests</directory>
<exclude>@root@public/analytics/tests/classes</exclude>
</testsuite>
<testsuite name="core_availability_testsuite">
<directory suffix="_test.php">public/availability/tests</directory>
<exclude>public/availability/tests/classes</exclude>
<directory suffix="_test.php">@root@public/availability/tests</directory>
<exclude>@root@public/availability/tests/classes</exclude>
</testsuite>
<testsuite name="core_backup_testsuite">
<directory suffix="_test.php">public/backup/controller/tests</directory>
<directory suffix="_test.php">public/backup/converter/moodle1/tests</directory>
<directory suffix="_test.php">public/backup/moodle2/tests</directory>
<directory suffix="_test.php">public/backup/tests</directory>
<directory suffix="_test.php">public/backup/util</directory>
<exclude>public/backup/controller/tests/classes</exclude>
<exclude>public/backup/converter/moodle1/tests/classes</exclude>
<exclude>public/backup/moodle2/tests/classes</exclude>
<exclude>public/backup/tests/classes</exclude>
<exclude>public/backup/util/classes</exclude>
<directory suffix="_test.php">@root@public/backup/controller/tests</directory>
<directory suffix="_test.php">@root@public/backup/converter/moodle1/tests</directory>
<directory suffix="_test.php">@root@public/backup/moodle2/tests</directory>
<directory suffix="_test.php">@root@public/backup/tests</directory>
<directory suffix="_test.php">@root@public/backup/util</directory>
<exclude>@root@public/backup/controller/tests/classes</exclude>
<exclude>@root@public/backup/converter/moodle1/tests/classes</exclude>
<exclude>@root@public/backup/moodle2/tests/classes</exclude>
<exclude>@root@public/backup/tests/classes</exclude>
<exclude>@root@public/backup/util/classes</exclude>
</testsuite>
<testsuite name="core_badges_testsuite">
<directory suffix="_test.php">public/badges/tests</directory>
<exclude>public/badges/tests/classes</exclude>
<directory suffix="_test.php">@root@public/badges/tests</directory>
<exclude>@root@public/badges/tests/classes</exclude>
</testsuite>
<testsuite name="core_blog_testsuite">
<directory suffix="_test.php">public/blog/tests</directory>
<exclude>public/blog/tests/classes</exclude>
<directory suffix="_test.php">@root@public/blog/tests</directory>
<exclude>@root@public/blog/tests/classes</exclude>
</testsuite>
<testsuite name="core_customfield_testsuite">
<directory suffix="_test.php">public/customfield/tests</directory>
<exclude>public/customfield/tests/classes</exclude>
<directory suffix="_test.php">@root@public/customfield/tests</directory>
<exclude>@root@public/customfield/tests/classes</exclude>
</testsuite>
<testsuite name="core_iplookup_testsuite">
<directory suffix="_test.php">public/iplookup/tests</directory>
<exclude>public/iplookup/tests/classes</exclude>
<directory suffix="_test.php">@root@public/iplookup/tests</directory>
<exclude>@root@public/iplookup/tests/classes</exclude>
</testsuite>
<testsuite name="core_course_testsuite">
<directory suffix="_test.php">public/course/tests</directory>
<exclude>public/course/tests/classes</exclude>
<directory suffix="_test.php">@root@public/course/tests</directory>
<exclude>@root@public/course/tests/classes</exclude>
</testsuite>
<testsuite name="core_courseformat_testsuite">
<directory suffix="_test.php">public/course/format/tests</directory>
<exclude>public/course/format/tests/classes</exclude>
<directory suffix="_test.php">@root@public/course/format/tests</directory>
<exclude>@root@public/course/format/tests/classes</exclude>
</testsuite>
<testsuite name="core_privacy_testsuite">
<directory suffix="_test.php">public/privacy/tests</directory>
<exclude>public/privacy/tests/classes</exclude>
<directory suffix="_test.php">@root@public/privacy/tests</directory>
<exclude>@root@public/privacy/tests/classes</exclude>
</testsuite>
<testsuite name="core_question_testsuite">
<directory suffix="_test.php">public/question/engine/tests</directory>
<directory suffix="_test.php">public/question/tests</directory>
<directory suffix="_test.php">public/question/type/tests</directory>
<directory suffix="_test.php">public/question/engine/upgrade/tests</directory>
<exclude>public/question/engine/tests/classes</exclude>
<exclude>public/question/tests/classes</exclude>
<exclude>public/question/type/tests/classes</exclude>
<exclude>public/question/engine/upgrade/tests/classes</exclude>
<directory suffix="_test.php">@root@public/question/engine/tests</directory>
<directory suffix="_test.php">@root@public/question/tests</directory>
<directory suffix="_test.php">@root@public/question/type/tests</directory>
<directory suffix="_test.php">@root@public/question/engine/upgrade/tests</directory>
<exclude>@root@public/question/engine/tests/classes</exclude>
<exclude>@root@public/question/tests/classes</exclude>
<exclude>@root@public/question/type/tests/classes</exclude>
<exclude>@root@public/question/engine/upgrade/tests/classes</exclude>
</testsuite>
<testsuite name="core_cache_testsuite">
<directory suffix="_test.php">public/cache/tests</directory>
<exclude>public/cache/tests/classes</exclude>
<exclude>public/cache/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/cache/tests</directory>
<exclude>@root@public/cache/tests/classes</exclude>
<exclude>@root@public/cache/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_calendar_testsuite">
<directory suffix="_test.php">public/calendar/tests</directory>
<exclude>public/calendar/tests/classes</exclude>
<exclude>public/calendar/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/calendar/tests</directory>
<exclude>@root@public/calendar/tests/classes</exclude>
<exclude>@root@public/calendar/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_enrol_testsuite">
<directory suffix="_test.php">public/enrol/tests</directory>
<exclude>public/enrol/tests/classes</exclude>
<exclude>public/enrol/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/enrol/tests</directory>
<exclude>@root@public/enrol/tests/classes</exclude>
<exclude>@root@public/enrol/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_group_testsuite">
<directory suffix="_test.php">public/group/tests</directory>
<exclude>public/group/tests/classes</exclude>
<exclude>public/group/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/group/tests</directory>
<exclude>@root@public/group/tests/classes</exclude>
<exclude>@root@public/group/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_message_testsuite">
<directory suffix="_test.php">public/message/tests</directory>
<exclude>public/message/tests/classes</exclude>
<exclude>public/message/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/message/tests</directory>
<exclude>@root@public/message/tests/classes</exclude>
<exclude>@root@public/message/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_notes_testsuite">
<directory suffix="_test.php">public/notes/tests</directory>
<exclude>public/notes/tests/classes</exclude>
<exclude>public/notes/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/notes/tests</directory>
<exclude>@root@public/notes/tests/classes</exclude>
<exclude>@root@public/notes/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_tag_testsuite">
<directory suffix="_test.php">public/tag/tests</directory>
<exclude>public/tag/tests/classes</exclude>
<exclude>public/tag/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/tag/tests</directory>
<exclude>@root@public/tag/tests/classes</exclude>
<exclude>@root@public/tag/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_rating_testsuite">
<directory suffix="_test.php">public/rating/tests</directory>
<exclude>public/rating/tests/classes</exclude>
<exclude>public/rating/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/rating/tests</directory>
<exclude>@root@public/rating/tests/classes</exclude>
<exclude>@root@public/rating/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_repository_testsuite">
<directory suffix="_test.php">public/repository/tests</directory>
<exclude>public/repository/tests/classes</exclude>
<exclude>public/repository/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/repository/tests</directory>
<exclude>@root@public/repository/tests/classes</exclude>
<exclude>@root@public/repository/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_userkey_testsuite">
<directory suffix="_test.php">public/lib/userkey/tests</directory>
<exclude>public/lib/userkey/tests/classes</exclude>
<exclude>public/lib/userkey/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/userkey/tests</directory>
<exclude>@root@public/lib/userkey/tests/classes</exclude>
<exclude>@root@public/lib/userkey/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_user_testsuite">
<directory suffix="_test.php">public/user/tests</directory>
<exclude>public/user/tests/classes</exclude>
<exclude>public/user/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/user/tests</directory>
<exclude>@root@public/user/tests/classes</exclude>
<exclude>@root@public/user/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_webservice_testsuite">
<directory suffix="_test.php">public/webservice/tests</directory>
<exclude>public/webservice/tests/classes</exclude>
<exclude>public/webservice/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/webservice/tests</directory>
<exclude>@root@public/webservice/tests/classes</exclude>
<exclude>@root@public/webservice/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_mnet_testsuite">
<directory suffix="_test.php">public/mnet/tests</directory>
<exclude>public/mnet/tests/classes</exclude>
<exclude>public/mnet/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/mnet/tests</directory>
<exclude>@root@public/mnet/tests/classes</exclude>
<exclude>@root@public/mnet/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_completion_testsuite">
<directory suffix="_test.php">public/completion/tests</directory>
<exclude>public/completion/tests/classes</exclude>
<exclude>public/completion/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/completion/tests</directory>
<exclude>@root@public/completion/tests/classes</exclude>
<exclude>@root@public/completion/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_comment_testsuite">
<directory suffix="_test.php">public/comment/tests</directory>
<exclude>public/comment/tests/classes</exclude>
<exclude>public/comment/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/comment/tests</directory>
<exclude>@root@public/comment/tests/classes</exclude>
<exclude>@root@public/comment/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_search_testsuite">
<directory suffix="_test.php">public/search/tests</directory>
<exclude>public/search/tests/classes</exclude>
<exclude>public/search/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/search/tests</directory>
<exclude>@root@public/search/tests/classes</exclude>
<exclude>@root@public/search/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_competency_testsuite">
<directory suffix="_test.php">public/competency/tests</directory>
<exclude>public/competency/tests/classes</exclude>
<exclude>public/competency/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/competency/tests</directory>
<exclude>@root@public/competency/tests/classes</exclude>
<exclude>@root@public/competency/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_my_testsuite">
<directory suffix="_test.php">public/my/tests</directory>
<exclude>public/my/tests/classes</exclude>
<exclude>public/my/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/my/tests</directory>
<exclude>@root@public/my/tests/classes</exclude>
<exclude>@root@public/my/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_auth_testsuite">
<directory suffix="_test.php">public/auth/tests</directory>
<exclude>public/auth/tests/classes</exclude>
<exclude>public/auth/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/auth/tests</directory>
<exclude>@root@public/auth/tests/classes</exclude>
<exclude>@root@public/auth/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_block_testsuite">
<directory suffix="_test.php">public/blocks/tests</directory>
<exclude>public/blocks/tests/classes</exclude>
<exclude>public/blocks/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/blocks/tests</directory>
<exclude>@root@public/blocks/tests/classes</exclude>
<exclude>@root@public/blocks/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_login_testsuite">
<directory suffix="_test.php">public/login/tests</directory>
<exclude>public/login/tests/classes</exclude>
<exclude>public/login/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/login/tests</directory>
<exclude>@root@public/login/tests/classes</exclude>
<exclude>@root@public/login/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_plagiarism_testsuite">
<directory suffix="_test.php">public/plagiarism/tests</directory>
<exclude>public/plagiarism/tests/classes</exclude>
<exclude>public/plagiarism/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/plagiarism/tests</directory>
<exclude>@root@public/plagiarism/tests/classes</exclude>
<exclude>@root@public/plagiarism/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_portfolio_testsuite">
<directory suffix="_test.php">public/portfolio/tests</directory>
<exclude>public/portfolio/tests/classes</exclude>
<exclude>public/portfolio/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/portfolio/tests</directory>
<exclude>@root@public/portfolio/tests/classes</exclude>
<exclude>@root@public/portfolio/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_editor_testsuite">
<directory suffix="_test.php">public/lib/editor/tests</directory>
<exclude>public/lib/editor/tests/classes</exclude>
<exclude>public/lib/editor/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/editor/tests</directory>
<exclude>@root@public/lib/editor/tests/classes</exclude>
<exclude>@root@public/lib/editor/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_rss_testsuite">
<directory suffix="_test.php">public/rss/tests</directory>
<exclude>public/rss/tests/classes</exclude>
<exclude>public/rss/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/rss/tests</directory>
<exclude>@root@public/rss/tests/classes</exclude>
<exclude>@root@public/rss/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_table_testsuite">
<directory suffix="_test.php">public/lib/table/tests</directory>
<exclude>public/lib/table/tests/classes</exclude>
<exclude>public/lib/table/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/table/tests</directory>
<exclude>@root@public/lib/table/tests/classes</exclude>
<exclude>@root@public/lib/table/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_h5p_testsuite">
<directory suffix="_test.php">public/h5p/tests</directory>
<exclude>public/h5p/tests/classes</exclude>
<exclude>public/h5p/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/h5p/tests</directory>
<exclude>@root@public/h5p/tests/classes</exclude>
<exclude>@root@public/h5p/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_xapi_testsuite">
<directory suffix="_test.php">public/lib/xapi/tests</directory>
<exclude>public/lib/xapi/tests/classes</exclude>
<exclude>public/lib/xapi/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/lib/xapi/tests</directory>
<exclude>@root@public/lib/xapi/tests/classes</exclude>
<exclude>@root@public/lib/xapi/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_contentbank_testsuite">
<directory suffix="_test.php">public/contentbank/tests</directory>
<exclude>public/contentbank/tests/classes</exclude>
<exclude>public/contentbank/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/contentbank/tests</directory>
<exclude>@root@public/contentbank/tests/classes</exclude>
<exclude>@root@public/contentbank/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_payment_testsuite">
<directory suffix="_test.php">public/payment/tests</directory>
<exclude>public/payment/tests/classes</exclude>
<exclude>public/payment/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/payment/tests</directory>
<exclude>@root@public/payment/tests/classes</exclude>
<exclude>@root@public/payment/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_reportbuilder_testsuite">
<directory suffix="_test.php">public/reportbuilder/tests</directory>
<exclude>public/reportbuilder/tests/classes</exclude>
<exclude>public/reportbuilder/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/reportbuilder/tests</directory>
<exclude>@root@public/reportbuilder/tests/classes</exclude>
<exclude>@root@public/reportbuilder/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_adminpresets_testsuite">
<directory suffix="_test.php">public/admin/presets/tests</directory>
<exclude>public/admin/presets/tests/classes</exclude>
<exclude>public/admin/presets/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/admin/presets/tests</directory>
<exclude>@root@public/admin/presets/tests/classes</exclude>
<exclude>@root@public/admin/presets/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_admin_testsuite">
<directory suffix="_test.php">public/admin/tests</directory>
<exclude>public/admin/tests/classes</exclude>
<exclude>public/admin/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/admin/tests</directory>
<exclude>@root@public/admin/tests/classes</exclude>
<exclude>@root@public/admin/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_communication_testsuite">
<directory suffix="_test.php">public/communication/tests</directory>
<exclude>public/communication/tests/classes</exclude>
<exclude>public/communication/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/communication/tests</directory>
<exclude>@root@public/communication/tests/classes</exclude>
<exclude>@root@public/communication/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_ai_testsuite">
<directory suffix="_test.php">public/ai/tests</directory>
<exclude>public/ai/tests/classes</exclude>
<exclude>public/ai/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/ai/tests</directory>
<exclude>@root@public/ai/tests/classes</exclude>
<exclude>@root@public/ai/tests/fixtures</exclude>
</testsuite>
<testsuite name="core_sms_testsuite">
<directory suffix="_test.php">public/sms/tests</directory>
<exclude>public/sms/tests/classes</exclude>
<exclude>public/sms/tests/fixtures</exclude>
<directory suffix="_test.php">@root@public/sms/tests</directory>
<exclude>@root@public/sms/tests/classes</exclude>
<exclude>@root@public/sms/tests/fixtures</exclude>
</testsuite>
<!--Plugin suites: use admin/tool/phpunit/cli/util.php to build phpunit.xml from
+5
View File
@@ -44,6 +44,11 @@ putenv('BEHAT_CLI=0');
require_once(__DIR__ . '/../../../../lib/clilib.php');
require_once(__DIR__ . '/../../../../lib/behat/lib.php');
$autoload = __DIR__ . '/../../../../../vendor/autoload.php';
if (file_exists($autoload)) {
require_once($autoload);
}
list($options, $unrecognized) = cli_get_params(
array(
'parallel' => 0,
+1 -1
View File
@@ -223,7 +223,7 @@ if (empty($parallelrun)) {
$runtestscommand .= ' ' . $extraoptstr;
$cmds['singlerun'] = $runtestscommand;
echo "Running single behat site:" . PHP_EOL;
echo "Running single behat site: with " . $runtestscommand . PHP_EOL;
passthru("php $runtestscommand", $status);
$exitcodes['singlerun'] = $status;
chdir($cwd);
@@ -40,6 +40,7 @@ putenv('BEHAT_CLI=0');
// Basic functions.
require_once(__DIR__ . '/../../../../lib/clilib.php');
require_once(__DIR__ . '/../../../../lib/behat/lib.php');
require_once(dirname(__DIR__, 5) . '/vendor/autoload.php');
// CLI options.
list($options, $unrecognized) = cli_get_params(
@@ -66,15 +66,11 @@ class behat_tool_dataprivacy extends behat_base {
* @param TableNode $data
*/
public function the_following_data_categories_exist($elementname, TableNode $data) {
// Now that we need them require the data generators.
require_once(__DIR__.'/../../../../../lib/phpunit/classes/util.php');
if (empty(self::$elements[$elementname])) {
throw new PendingException($elementname . ' data generator is not implemented');
}
$datagenerator = testing_util::get_data_generator();
$datagenerator = \core\test\testing_util::get_data_generator();
$dataprivacygenerator = $datagenerator->get_plugin_generator('tool_dataprivacy');
$elementdatagenerator = self::$elements[$elementname]['datagenerator'];
@@ -14,16 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* tool_generator course backend code.
*
* @package tool_generator
* @copyright 2013 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Backend code for the 'make large course' tool.
*
@@ -217,7 +207,6 @@ class tool_generator_course_backend extends tool_generator_backend {
*/
public function make() {
global $DB, $CFG, $USER;
require_once($CFG->dirroot . '/lib/phpunit/classes/util.php');
raise_memory_limit(MEMORY_EXTRA);
@@ -228,7 +217,7 @@ class tool_generator_course_backend extends tool_generator_backend {
$entirestart = microtime(true);
// Get generator.
$this->generator = phpunit_util::get_data_generator();
$this->generator = \core\test\phpunit\phpunit_util::get_data_generator();
// Make course.
$this->course = $this->create_course();
@@ -94,7 +94,9 @@ if (!empty($options['help'])) {
// The command will install composer if not present. Usually composer libraries are
// installed when behat or phpunit are installed, but we do not want to force users
// to create all phpunit or behat databases tables just to run a test scenario locally.
if (!file_exists($CFG->dirroot . '/../vendor/autoload.php')) {
require_once(dirname(__DIR__, 4) . '/autoload.php');
if (!class_exists(\Composer\Autoload\ClassLoader::class)) {
// Force OPcache reset if used, we do not want any stale caches
// when preparing test environment.
if (function_exists('opcache_reset')) {
@@ -25,8 +25,8 @@
require_once(__DIR__ . '/../../../../../lib/behat/behat_deprecated_base.php');
use Behat\Gherkin\Node\TableNode as TableNode;
use Behat\Behat\Tester\Exception\PendingException as PendingException;
use Behat\Gherkin\Node\TableNode;
use Behat\Behat\Tester\Exception\PendingException;
use core_competency\competency;
use core_competency\competency_framework;
use core_competency\plan;
@@ -114,14 +114,11 @@ class behat_tool_lp_deprecated extends behat_deprecated_base {
]);
// Now that we need them require the data generators.
require_once(__DIR__.'/../../../../../lib/phpunit/classes/util.php');
if (empty(self::$elements[$elementname])) {
throw new PendingException($elementname . ' data generator is not implemented');
}
$datagenerator = testing_util::get_data_generator();
$datagenerator = \core\test\testing_util::get_data_generator();
$this->datageneratorlp = $datagenerator->get_plugin_generator('core_competency');
$elementdatagenerator = self::$elements[$elementname]['datagenerator'];
@@ -411,9 +411,9 @@ final class eventobservers_test extends \advanced_testcase {
/**
* Verify that task was scheduled and a message was sent as expected.
*
* @param phpunit_message_sink $msgsink Message sink
* @param \core\test\phpunit\message_sink $msgsink Message sink
*/
protected function verify_processed_data(\phpunit_message_sink $msgsink) {
protected function verify_processed_data(\core\test\phpunit\message_sink $msgsink) {
global $DB, $USER;
$recordexists = $DB->count_records('task_adhoc', array('component' => 'tool_monitor'));
@@ -430,9 +430,9 @@ final class eventobservers_test extends \advanced_testcase {
/**
* Verify that a message was not sent.
*
* @param phpunit_message_sink $msgsink Message sink
* @param \core\test\phpunit\message_sink $msgsink Message sink
*/
protected function verify_message_not_sent_yet(\phpunit_message_sink $msgsink) {
protected function verify_message_not_sent_yet(\core\test\phpunit\message_sink $msgsink) {
$msgs = $msgsink->get_messages();
$this->assertCount(0, $msgs);
$msgsink->clear();
+5
View File
@@ -42,6 +42,11 @@ require_once(__DIR__.'/../../../../lib/clilib.php');
require_once(__DIR__.'/../../../../lib/phpunit/bootstraplib.php');
require_once(__DIR__.'/../../../../lib/testing/lib.php');
$autoload = __DIR__ . '/../../../../../vendor/autoload.php';
if (file_exists($autoload)) {
require_once($autoload);
}
list($options, $unrecognized) = cli_get_params(
[
'help' => false,
+17 -4
View File
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
use core\test\phpunit\phpunit_util;
/**
* PHPUnit related utilities.
*
@@ -55,10 +57,21 @@ list($options, $unrecognized) = cli_get_params(
);
// Basic check to see if phpunit is installed.
if (!file_exists(__DIR__.'/../../../../../vendor/phpunit/phpunit/composer.json') ||
!file_exists(__DIR__.'/../../../../../vendor/bin/phpunit') ||
!file_exists(__DIR__.'/../../../../../vendor/autoload.php')) {
phpunit_bootstrap_error(PHPUNIT_EXITCODE_PHPUNITMISSING);
$autoload = __DIR__ . '/../../../../../vendor/autoload.php';
if (file_exists($autoload)) {
require_once($autoload);
}
$requiredclasses = [
\Composer\Autoload\ClassLoader::class,
\PHPUnit\Runner\Version::class,
];
foreach ($requiredclasses as $requiredclass) {
if (!class_exists($requiredclass)) {
phpunit_bootstrap_error(PHPUNIT_EXITCODE_PHPUNITMISSING);
}
}
if ($options['install'] || $options['drop']) {
@@ -16,8 +16,6 @@
namespace core_analytics\tests;
use phpunit_util;
/**
* A trait to check machine learning configurations.
*
@@ -59,18 +57,18 @@ trait mlbackend_helper_trait {
for ($i = 0; $i < $ncourses; $i++) {
$name = 'a' . random_string(10);
$courseparams = ['shortname' => $name, 'fullname' => $name] + $params;
phpunit_util::get_data_generator()->create_course($courseparams);
\core\test\phpunit\phpunit_util::get_data_generator()->create_course($courseparams);
}
for ($i = 0; $i < $ncourses; $i++) {
$name = 'b' . random_string(10);
$courseparams = ['shortname' => $name, 'fullname' => $name] + $params;
phpunit_util::get_data_generator()->create_course($courseparams);
\core\test\phpunit\phpunit_util::get_data_generator()->create_course($courseparams);
}
if ($ismulticlass) {
for ($i = 0; $i < $ncourses; $i++) {
$name = 'c' . random_string(10);
$courseparams = ['shortname' => $name, 'fullname' => $name] + $params;
phpunit_util::get_data_generator()->create_course($courseparams);
\core\test\phpunit\phpunit_util::get_data_generator()->create_course($courseparams);
}
}
}
+14 -7
View File
@@ -16,6 +16,8 @@
namespace core_analytics;
use core_analytics\tests\mlbackend_helper_trait;
defined('MOODLE_INTERNAL') || die();
global $CFG;
@@ -28,11 +30,8 @@ require_once(__DIR__ . '/fixtures/test_indicator_multiclass.php');
require_once(__DIR__ . '/fixtures/test_target_shortname.php');
require_once(__DIR__ . '/fixtures/test_target_shortname_multiclass.php');
require_once(__DIR__ . '/fixtures/test_static_target_shortname.php');
require_once(__DIR__ . '/../../course/lib.php');
use core_analytics\tests\mlbackend_helper_trait;
/**
* Unit tests for evaluation, training and prediction.
*
@@ -745,8 +744,12 @@ final class prediction_test extends \advanced_testcase {
$samples,
$ranges
);
$dataset = \phpunit_util::call_internal_method($analysis, 'calculate_indicators', $params,
'\core_analytics\analysis');
$dataset = \core\test\phpunit\phpunit_util::call_internal_method(
$analysis,
'calculate_indicators',
$params,
\core_analytics\analysis::class,
);
$this->assertArrayHasKey('123-0', $dataset);
$this->assertArrayHasKey('123-1', $dataset);
$this->assertArrayHasKey('321-0', $dataset);
@@ -769,8 +772,12 @@ final class prediction_test extends \advanced_testcase {
$samples,
$ranges
);
$dataset = \phpunit_util::call_internal_method($analysis, 'calculate_indicators', $params,
'\core_analytics\analysis');
$dataset = \core\test\phpunit\phpunit_util::call_internal_method(
$analysis,
'calculate_indicators',
$params,
\core_analytics\analysis::class,
);
$this->assertArrayNotHasKey('123-0', $dataset);
$this->assertArrayNotHasKey('123-1', $dataset);
$this->assertArrayNotHasKey('321-0', $dataset);
+1 -2
View File
@@ -26,7 +26,6 @@
namespace core_backup;
use memory_xml_output;
use phpunit_util;
use xml_contenttransformer;
use xml_output;
use xml_writer;
@@ -333,7 +332,7 @@ final class writer_test extends \basic_testcase {
$fcontents = file_get_contents($CFG->dirroot . '/backup/util/xml/tests/fixtures/test1.xml');
// Normalise carriage return characters.
$fcontents = phpunit_util::normalise_line_endings($fcontents);
$fcontents = \core\test\phpunit\phpunit_util::normalise_line_endings($fcontents);
$this->assertEquals(trim($result), trim($fcontents));
}
}
+3 -1
View File
@@ -17,10 +17,12 @@
/**
* Coverage information for the core_block subsystem.
*
* @package core
* @category phpunit
* @copyright 2021 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
return new class extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of files relative to the plugin root to include in coverage generation. */
protected $includelistfiles = [
'moodleblock.class.php',
@@ -187,7 +187,7 @@ final class cachestore_cluster_redis_test extends \advanced_testcase {
$store = new cachestore_redis('TestCluster', $config);
$debugging = $this->getDebuggingMessages();
// Failed to connect should show a debugging message.
$this->assertCount(1, \phpunit_util::get_debugging_messages() );
$this->assertCount(1, \core\test\phpunit\phpunit_util::get_debugging_messages() );
$this->assertStringContainsString('Couldn\'t map cluster keyspace using any provided seed', $debugging[0]->message);
$this->resetDebugging();
$this->assertFalse($store->is_ready());
+1 -3
View File
@@ -28,7 +28,6 @@ use core_competency\competency_framework;
use core_competency\course_competency;
use core_competency\course_module_competency;
use core_competency\evidence;
use core_competency\external;
use core_competency\plan;
use core_competency\plan_competency;
use core_competency\related_competency;
@@ -41,7 +40,6 @@ use core_competency\user_competency_plan;
use core_competency\user_evidence;
use core_competency\user_evidence_competency;
defined('MOODLE_INTERNAL') || die();
global $CFG;
@@ -139,7 +137,7 @@ class core_competency_generator extends component_generator_base {
if (defined('BEHAT_TEST') && BEHAT_TEST) {
$generator = behat_util::get_data_generator();
} else {
$generator = phpunit_util::get_data_generator();
$generator = \core\test\phpunit\phpunit_util::get_data_generator();
}
$this->frameworkcount++;
$i = $this->frameworkcount;
+2 -11
View File
@@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
/**
* Coverage information for the core_completion.
*
@@ -24,14 +22,7 @@ defined('MOODLE_INTERNAL') || die();
* @copyright 2022 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Coverage information for the core subsystem.
*
* @copyright 2018 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
return new class extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of folders relative to the plugin root to include in coverage generation. */
protected $includelistfolders = [
'criteria',
@@ -42,6 +33,6 @@ return new class extends phpunit_coverage_info {
'completion_aggregation.php',
'completion_completion.php',
'completion_criteria_completion.php',
'data_object.php'
'data_object.php',
];
};
@@ -465,7 +465,7 @@ final class cmactions_test extends \advanced_testcase {
$sink = $this->redirectEvents();
// Now, run the adhoc task which performs the hard deletion.
\phpunit_util::run_all_adhoc_tasks();
\core\test\phpunit\phpunit_util::run_all_adhoc_tasks();
// Fetch and validate the event data.
$events = $sink->get_events();
@@ -508,7 +508,7 @@ final class sectionactions_test extends \advanced_testcase {
// Now, run the adhoc task to delete the modules from section 0.
$sink = $this->redirectEvents(); // To capture the events.
\phpunit_util::run_all_adhoc_tasks();
\core\test\phpunit\phpunit_util::run_all_adhoc_tasks();
// Confirm the modules have been deleted.
list($insql, $assignids) = $DB->get_in_or_equal([$assign0->cmid, $assign1->cmid, $assign2->cmid]);
+1 -3
View File
@@ -29,7 +29,6 @@ use context_course;
use context_module;
use context_system;
use context_coursecat;
use core\event\section_viewed;
use core_completion_external;
use core_courseformat\formatactions;
use core_external;
@@ -43,7 +42,6 @@ use grade_item;
use grading_manager;
use moodle_exception;
use moodle_url;
use phpunit_util;
use rating_manager;
use restore_controller;
use stdClass;
@@ -3880,7 +3878,7 @@ final class courselib_test extends advanced_testcase {
// Now, run the adhoc task to delete the modules from section 0.
$sink = $this->redirectEvents(); // To capture the events.
phpunit_util::run_all_adhoc_tasks();
\core\test\phpunit\phpunit_util::run_all_adhoc_tasks();
// Confirm the modules have been deleted.
list($insql, $assignids) = $DB->get_in_or_equal([$assign0->cmid, $assign1->cmid, $assign2->cmid]);
+1 -1
View File
@@ -20,7 +20,7 @@
* @copyright 2021 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
return new class extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of files relative to the plugin root to include in coverage generation. */
protected $includelistfiles = [
'dnduploadlib.php',
@@ -108,7 +108,7 @@ final class nofactivities_test extends advanced_testcase {
$this->assertEquals(3.0000, $course1customfield);
// Now, run the course module deletion adhoc task.
\phpunit_util::run_all_adhoc_tasks();
\core\test\phpunit\phpunit_util::run_all_adhoc_tasks();
$providers[0]->recalculate((int)$course1->id);
$course1customfield = $DB->get_field('customfield_data', 'decvalue', ['instanceid' => $course1->id]);
$this->assertEquals(3.0000, $course1customfield);
@@ -20,8 +20,6 @@ use enrol_lti\helper;
use Packback\Lti1p3\LtiAssignmentsGradesService;
use Packback\Lti1p3\LtiGrade;
use Packback\Lti1p3\LtiLineitem;
use core\task\manager;
use phpunit_util;
defined('MOODLE_INTERNAL') || die();
+25 -15
View File
@@ -119,24 +119,33 @@ class behat_command {
}
}
// If relative path then prefix relative path.
$command = [];
if ($absolutepath) {
$pathprefix = testing_cli_argument_path('/');
if (!empty($pathprefix)) {
$pathprefix .= $separator;
}
} else {
$pathprefix = '';
$command[] = realpath(\Composer\InstalledVersions::getRootPackage()['install_path']);
}
if ($parallerun) {
$command[] = rtrim(\core\test\testing_util::get_moodle_relative_to_root_package(), '/');
}
if (!$parallerun) {
$command = $pathprefix . 'vendor' . $separator . 'bin' . $separator . $exec;
} else {
$command = 'php ' . $pathprefix . 'admin' . $separator . 'tool' . $separator . 'behat' . $separator . 'cli'
. $separator . 'run.php';
if ($parallerun) {
$command = [
...$command,
'public',
'admin',
'tool',
'behat',
'cli',
'run.php',
];
return 'php ' . implode($separator, $command);
}
return $command;
// Not a parallel run.
// Return the vendor path without php command.
$command = [...$command, 'vendor', 'bin', $exec];
return implode($separator, $command);
}
/**
@@ -151,7 +160,8 @@ class behat_command {
global $CFG;
$currentcwd = getcwd();
chdir(dirname($CFG->dirroot));
$rootpath = realpath(\Composer\InstalledVersions::getRootPackage()['install_path']);
chdir($rootpath);
exec(self::get_behat_command() . ' ' . $options, $output, $code);
chdir($currentcwd);
@@ -237,7 +247,7 @@ class behat_command {
* @return bool
*/
public static function are_behat_dependencies_installed() {
if (!is_dir(__DIR__ . '/../../../../vendor/behat')) {
if (!\Composer\InstalledVersions::isInstalled('behat/behat')) {
return false;
}
return true;
@@ -26,7 +26,6 @@ defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../lib.php');
require_once(__DIR__ . '/behat_command.php');
require_once(__DIR__ . '/../../testing/classes/tests_finder.php');
/**
* Behat configuration manager
@@ -1064,7 +1063,7 @@ class behat_config_util {
/**
* Cleans the path returned by get_components_with_tests() to standarize it
*
* @see tests_finder::get_all_directories_with_tests() it returns the path including /tests/
* @see \core\test\test_finder::get_all_directories_with_tests() it returns the path including /tests/
* @param string $path
* @return string The string without the last /tests part
*/
@@ -1127,7 +1126,7 @@ class behat_config_util {
*/
protected function get_components_with_tests() {
if (empty($this->componentswithtests)) {
$this->componentswithtests = tests_finder::get_components_with_tests('behat');
$this->componentswithtests = \core\test\test_finder::get_components_with_tests('behat');
}
return $this->componentswithtests;
+7 -2
View File
@@ -26,7 +26,6 @@
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../lib.php');
require_once(__DIR__ . '/../../testing/classes/util.php');
require_once(__DIR__ . '/behat_command.php');
require_once(__DIR__ . '/behat_config_manager.php');
@@ -45,7 +44,7 @@ use Behat\Mink\Exception\ExpectationException;
* @copyright 2013 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_util extends testing_util {
class behat_util extends \core\test\testing_util {
/**
* The behat test site fullname and shortname.
@@ -531,4 +530,10 @@ EOF;
return $siteinfo;
}
#[\Override]
protected static function get_framework() {
return 'behat';
}
}
+2 -4
View File
@@ -16,8 +16,6 @@
namespace core\event;
defined('MOODLE_INTERNAL') || die();
/**
* Base event class.
*
@@ -786,9 +784,9 @@ abstract class base implements \IteratorAggregate {
$this->triggered = true;
if (PHPUNIT_TEST and \phpunit_util::is_redirecting_events()) {
if (PHPUNIT_TEST && \core\test\phpunit\phpunit_util::is_redirecting_events()) {
$this->dispatched = true;
\phpunit_util::event_triggered($this);
\core\test\phpunit\phpunit_util::event_triggered($this);
return;
}
@@ -0,0 +1,123 @@
<?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/>.
namespace core\test\phpunit;
use core\output\html_writer;
/**
* Coverage information for PHPUnit.
*
* @package core
* @category test
* @copyright 2018 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class coverage_info {
/** @var array The list of folders relative to the plugin root to include in coverage generation. */
protected $includelistfolders = [];
/** @var array The list of files relative to the plugin root to include in coverage generation. */
protected $includelistfiles = [];
/** @var array The list of folders relative to the plugin root to exclude from coverage generation. */
protected $excludelistfolders = [];
/** @var array The list of files relative to the plugin root to exclude from coverage generation. */
protected $excludelistfiles = [];
/** @var string The base directory to use */
protected string $basedir = "";
/**
* Specify the base directory to use for coverage.
*
* @param string $basedir
*/
final public function set_basedir(string $basedir): void {
if ($basedir === '') {
$this->basedir = '';
} else {
$this->basedir = trim($basedir, '/') . "/";
}
}
/**
* Get the formatted XML list of files and folders to include.
*
* @param string $plugindir The root of the plugin, relative to the dataroot.
* @return array
*/
final public function get_includelists(string $plugindir): array {
$coverages = [];
$includelistfolders = array_merge([
'classes',
'tests/generator',
], $this->includelistfolders);
$includelistfiles = array_merge([
'externallib.php',
'lib.php',
'locallib.php',
'renderer.php',
'rsslib.php',
], $this->includelistfiles);
if (!empty($plugindir)) {
$plugindir .= "/";
}
foreach (array_unique($includelistfolders) as $folder) {
$coverages[] = html_writer::tag('directory', "{$this->basedir}{$plugindir}{$folder}", ['suffix' => '.php']);
}
foreach (array_unique($includelistfiles) as $file) {
$coverages[] = html_writer::tag('file', "{$this->basedir}{$plugindir}{$file}");
}
return $coverages;
}
/**
* Get the formatted XML list of files and folders to exclude.
*
* @param string $plugindir The root of the plugin, relative to the dataroot.
* @return array
*/
final public function get_excludelists(string $plugindir): array {
$coverages = [];
if (!empty($plugindir)) {
$plugindir .= "/";
}
foreach ($this->excludelistfolders as $folder) {
$coverages[] = html_writer::tag('directory', "{$this->basedir}{$plugindir}{$folder}", ['suffix' => '.php']);
}
foreach ($this->excludelistfiles as $file) {
$coverages[] = html_writer::tag('file', "{$this->basedir}{$plugindir}{$file}");
}
return $coverages;
}
}
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(coverage_info::class, \phpunit_coverage_info::class);
@@ -0,0 +1,52 @@
<?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/>.
namespace core\test\phpunit;
/**
* Event mock class.
*
* @package core
* @category test
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class event_mock extends \core\event\base {
/**
* Returns event context.
*
* @param \core\event\base $event event to get context for.
* @return \core\context event context
*/
public static function testable_get_event_context($event) {
return $event->context;
}
/**
* Sets event context.
*
* @param \core\event\base $event event to set context for.
* @param \core\context $context context to set.
*/
public static function testable_set_event_context($event, $context) {
$event->context = $context;
}
}
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(event_mock::class, \phpunit_event_mock::class);
@@ -0,0 +1,83 @@
<?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/>.
namespace core\test\phpunit;
/**
* Event redirection sink.
*
* @package core
* @category test
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class event_sink {
/** @var \core\event\base[] array of events */
protected $events = [];
/**
* Stop event redirection.
*
* Use if you do not want event redirected any more.
*/
public function close() {
phpunit_util::stop_event_redirection();
}
/**
* To be called from phpunit_util only!
*
* @param \core\event\base $event record from event_read table
*/
public function add_event(\core\event\base $event) {
/* Number events from 0. */
$this->events[] = $event;
}
/**
* Returns all redirected events.
*
* The instances are records form the event_read table.
* The array indexes are numbered from 0 and the order is matching
* the creation of events.
*
* @return \core\event\base[]
*/
public function get_events() {
return $this->events;
}
/**
* Return number of events redirected to this sink.
*
* @return int
*/
public function count() {
return count($this->events);
}
/**
* Removes all previously stored events.
*/
public function clear() {
$this->events = [];
}
}
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(event_sink::class, \phpunit_event_sink::class);
@@ -0,0 +1,27 @@
<?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/>.
namespace core\test\phpunit\exception;
/**
* An exception thrown when an error is encountered in the setup, teardown, or other non-test parts of a unit test.
*
* @package core_testing
* @copyright Andrew Lyons <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class test_exception extends \core\exception\coding_exception {
}
@@ -0,0 +1,116 @@
<?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/>.
namespace core\test\phpunit;
/**
* Message sink.
*
* @package core
* @category test
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class message_sink {
/** @var array of records from messages table */
protected $messages = [];
/**
* Stop message redirection.
*
* Use if you do not want message redirected any more.
*/
public function close() {
phpunit_util::stop_message_redirection();
}
/**
* To be called from phpunit_util only!
*
* @param \stdClass $message record from messages table
*/
public function add_message($message) {
/* Number messages from 0. */
$this->messages[] = $message;
}
/**
* Returns all redirected messages.
*
* The instances are records from the messages table.
* The array indexes are numbered from 0 and the order is matching
* the creation of events.
*
* @param callable|null $filter Use to filter the messages.
* @return array
*/
public function get_messages(?callable $filter = null): array {
if ($filter) {
return array_filter($this->messages, $filter);
}
return $this->messages;
}
/**
* Return all redirected messages for a given component.
*
* @param string $component Component name.
* @return array List of messages.
*/
public function get_messages_by_component(string $component): array {
$component = \core\component::normalize_componentname($component);
return $this->get_messages(
fn ($message) => \core\component::normalize_componentname($message->component) === $component,
);
}
/**
* Return all redirected messages for a given component and type.
*
* @param string $component Component name.
* @param string $type Message type.
* @return array List of messages.
*/
public function get_messages_by_component_and_type(
string $component,
string $type,
): array {
return array_filter($this->get_messages_by_component($component), function ($message) use ($type) {
return $message->eventtype == $type;
});
}
/**
* Return number of messages redirected to this sink.
* @return int
*/
public function count() {
return count($this->messages);
}
/**
* Removes all previously stored messages.
*/
public function clear() {
$this->messages = [];
}
}
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(message_sink::class, \phpunit_message_sink::class);
@@ -0,0 +1,84 @@
<?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/>.
namespace core\test\phpunit;
/**
* Message sink for phpmailer.
*
* @package core
* @category test
* @copyright Andrew Nicols <[email protected]>.
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class phpmailer_sink {
/**
* @var array of records which would have been sent by phpmailer.
*/
protected $messages = [];
/**
* Stop message redirection.
*
* Use if you do not want message redirected any more.
*/
public function close() {
phpunit_util::stop_phpmailer_redirection();
}
/**
* To be called from phpunit_util only!
*
* @param stdClass $message record from messages table
*/
public function add_message($message) {
/* Number messages from 0. */
$this->messages[] = $message;
}
/**
* Returns all redirected messages.
*
* The instances are records from the messages table.
* The array indexes are numbered from 0 and the order is matching
* the creation of events.
*
* @return array
*/
public function get_messages() {
return $this->messages;
}
/**
* Return number of messages redirected to this sink.
* @return int
*/
public function count() {
return count($this->messages);
}
/**
* Removes all previously stored messages.
*/
public function clear() {
$this->messages = [];
}
}
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(phpmailer_sink::class, \phpunit_phpmailer_sink::class);
File diff suppressed because it is too large Load Diff
+206
View File
@@ -0,0 +1,206 @@
<?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/>.
namespace core\test;
/**
* Finds components and plugins with tests.
*
* @package core
* @category test
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class test_finder {
/**
* Returns all the components with tests of the specified type.
*
* @param string $testtype The kind of test we are looking for
* @return array
*/
public static function get_components_with_tests($testtype) {
// Get all the components.
$components = self::get_all_plugins_with_tests($testtype) + self::get_all_subsystems_with_tests($testtype);
// Get all the directories having tests.
$directories = self::get_all_directories_with_tests($testtype);
// Find any directory not covered by proper components.
$remaining = array_diff($directories, $components);
// Add them to the list of components.
$components += $remaining;
return $components;
}
/**
* Returns all the plugins having tests.
*
* @param string $testtype The kind of test we are looking for
* @return array all the plugins having tests
*/
private static function get_all_plugins_with_tests($testtype) {
$pluginswithtests = [];
$plugintypes = \core\component::get_plugin_types();
ksort($plugintypes);
foreach ($plugintypes as $type => $unused) {
$plugs = \core\component::get_plugin_list($type);
ksort($plugs);
foreach ($plugs as $plug => $fullplug) {
// Look for tests recursively.
if (self::directory_has_tests($fullplug, $testtype)) {
$pluginswithtests[$type . '_' . $plug] = $fullplug;
}
}
}
return $pluginswithtests;
}
/**
* Returns all the subsystems having tests
*
* Note we are hacking here the list of subsystems
* to cover some well-known subsystems that are not properly
* returned by the {@link get_core_subsystems()} function.
*
* @param string $testtype The kind of test we are looking for
* @return array all the subsystems having tests
*/
private static function get_all_subsystems_with_tests($testtype) {
global $CFG;
$subsystemswithtests = [];
$subsystems = \core\component::get_core_subsystems();
// Hack the list a bit to cover some well-known ones.
$subsystems['backup'] = $CFG->dirroot . '/backup';
$subsystems['db-dml'] = $CFG->dirroot . '/lib/dml';
$subsystems['db-ddl'] = $CFG->dirroot . '/lib/ddl';
ksort($subsystems);
foreach ($subsystems as $subsys => $fullsubsys) {
if ($fullsubsys === null) {
continue;
}
if (!is_dir($fullsubsys)) {
continue;
}
// Look for tests recursively.
if (self::directory_has_tests($fullsubsys, $testtype)) {
$subsystemswithtests['core_' . $subsys] = $fullsubsys;
}
}
return $subsystemswithtests;
}
/**
* Returns all the directories having tests
*
* @param string $testtype The kind of test we are looking for
* @return array all directories having tests
*/
private static function get_all_directories_with_tests($testtype) {
global $CFG;
// List of directories to exclude from test file searching.
$excludedir = ['node_modules', 'vendor'];
// Get first level directories in which tests should be searched.
$directoriestosearch = [];
$alldirs = glob($CFG->dirroot . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR);
foreach ($alldirs as $dir) {
if (!in_array(basename($dir), $excludedir) && (filetype($dir) != 'link')) {
$directoriestosearch[] = $dir;
}
}
// Search for tests in valid directories.
$dirs = [];
foreach ($directoriestosearch as $dir) {
$dirite = new \RecursiveDirectoryIterator($dir);
$iteite = new \RecursiveIteratorIterator($dirite);
$regexp = self::get_regexp($testtype);
$regite = new \RegexIterator($iteite, $regexp);
foreach ($regite as $path => $element) {
$key = dirname(dirname($path));
$value = trim(str_replace(DIRECTORY_SEPARATOR, '_', str_replace($CFG->dirroot, '', $key)), '_');
$dirs[$key] = $value;
}
}
ksort($dirs);
return array_flip($dirs);
}
/**
* Returns if a given directory has tests (recursively)
*
* @param string $dir full path to the directory to look for phpunit tests
* @param string $testtype phpunit|behat
* @return bool if a given directory has tests (true) or no (false)
*/
private static function directory_has_tests($dir, $testtype) {
if (!is_dir($dir)) {
return false;
}
$dirite = new \RecursiveDirectoryIterator($dir);
$iteite = new \RecursiveIteratorIterator($dirite);
$regexp = self::get_regexp($testtype);
$regite = new \RegexIterator($iteite, $regexp);
$regite->rewind();
if ($regite->valid()) {
return true;
}
return false;
}
/**
* Returns the regular expression to match by the test files
* @param string $testtype
* @return string
*/
private static function get_regexp($testtype) {
$sep = preg_quote(DIRECTORY_SEPARATOR, '|');
switch ($testtype) {
case 'phpunit':
$regexp = '|' . $sep . 'tests' . $sep . '.*_test\.php$|';
break;
case 'features':
$regexp = '|' . $sep . 'tests' . $sep . 'behat' . $sep . '.*\.feature$|';
break;
case 'stepsdefinitions':
$regexp = '|' . $sep . 'tests' . $sep . 'behat' . $sep . 'behat_.*\.php$|';
break;
case 'behat':
$regexp = '!' . $sep . 'tests' . $sep . 'behat' . $sep . '(.*\.feature)|(behat_.*\.php)$!';
break;
}
return $regexp;
}
}
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(test_finder::class, \tests_finder::class);
@@ -14,8 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core\test;
use testing_data_generator;
/**
* Testing util classes
* Testing utility classes.
*
* @package core
* @category test
@@ -69,7 +73,7 @@ abstract class testing_util {
private static $originaldatafilesjson = 'originaldatafiles.json';
/**
* @var boolean set to true once $originaldatafilesjson file is created.
* @var bool set to true once $originaldatafilesjson file is created.
*/
private static $originaldatafilesjsonadded = false;
@@ -78,10 +82,14 @@ abstract class testing_util {
*/
protected static $sequencenextstartingid = null;
/**
* @var array List of dataroot files and folders to not delete during reset_dataroot.
*/
protected static $datarootskiponreset = [];
/**
* Return the name of the JSON file containing the init filenames.
*
* @static
* @return string
*/
public static function get_originaldatafilesjson() {
@@ -91,7 +99,6 @@ abstract class testing_util {
/**
* Return the dataroot. It's useful when mocking the dataroot when unit testing this class itself.
*
* @static
* @return string the dataroot.
*/
public static function get_dataroot() {
@@ -109,7 +116,6 @@ abstract class testing_util {
* Set the dataroot. It's useful when mocking the dataroot when unit testing this class itself.
*
* @param string $dataroot the dataroot of the test framework.
* @static
*/
public static function set_dataroot($dataroot) {
self::$dataroot = $dataroot;
@@ -117,23 +123,34 @@ abstract class testing_util {
/**
* Returns the testing framework name
* @static
*
* @return string
*/
final protected static function get_framework() {
protected static function get_framework() {
debugging('You must override testing_util::get_framework in subclass', DEBUG_DEVELOPER);
$classname = get_called_class();
$reflectedclass = new \ReflectionClass($classname);
if ($reflectedclass->inNamespace()) {
$namespaces = explode('\\', $reflectedclass->getNamespaceName());
return array_shift($namespaces);
}
return substr($classname, 0, strpos($classname, '_'));
}
/**
* Get data generator
* @static
* @return testing_data_generator
*
* @return \testing_data_generator
*/
public static function get_data_generator() {
global $CFG;
if (is_null(self::$generator)) {
require_once(__DIR__ . '/../generator/lib.php');
self::$generator = new testing_data_generator();
require_once($CFG->libdir . '/testing/generator/lib.php');
self::$generator = new \testing_data_generator();
}
return self::$generator;
}
@@ -142,13 +159,12 @@ abstract class testing_util {
* Does this site (db and dataroot) appear to be used for production?
* We try very hard to prevent accidental damage done to production servers!!
*
* @static
* @return bool
*/
public static function is_test_site() {
global $DB, $CFG;
$framework = self::get_framework();
$framework = static::get_framework();
if (!file_exists(self::get_dataroot() . '/' . $framework . 'testdir.txt')) {
// This is already tested in bootstrap script,
@@ -177,7 +193,7 @@ abstract class testing_util {
public static function is_test_data_updated() {
global $DB;
$framework = self::get_framework();
$framework = static::get_framework();
$datarootpath = self::get_dataroot() . '/' . $framework;
if (!file_exists($datarootpath . '/tabledata.ser') || !file_exists($datarootpath . '/tablestructure.ser')) {
@@ -188,7 +204,7 @@ abstract class testing_util {
return false;
}
$hash = core_component::get_all_versions_hash();
$hash = \core\component::get_all_versions_hash();
$oldhash = file_get_contents($datarootpath . '/versionshash.txt');
if ($hash !== $oldhash) {
@@ -213,7 +229,7 @@ abstract class testing_util {
protected static function store_database_state() {
global $DB, $CFG;
$framework = self::get_framework();
$framework = static::get_framework();
// Store data for all tables.
$data = [];
@@ -246,8 +262,8 @@ abstract class testing_util {
protected static function store_versions_hash() {
global $CFG;
$framework = self::get_framework();
$hash = core_component::get_all_versions_hash();
$framework = static::get_framework();
$hash = \core\component::get_all_versions_hash();
// Add test db flag.
set_config($framework . 'test', $hash);
@@ -260,12 +276,12 @@ abstract class testing_util {
/**
* Returns contents of all tables right after installation.
* @static
*
* @return array $table=>$records
*/
protected static function get_tabledata() {
if (!isset(self::$tabledata)) {
$framework = self::get_framework();
$framework = static::get_framework();
$datafile = self::get_dataroot() . '/' . $framework . '/tabledata.ser';
if (!file_exists($datafile)) {
@@ -289,12 +305,12 @@ abstract class testing_util {
/**
* Returns structure of all tables right after installation.
* @static
*
* @return array $table=>$records
*/
public static function get_tablestructure() {
if (!isset(self::$tablestructure)) {
$framework = self::get_framework();
$framework = static::get_framework();
$structurefile = self::get_dataroot() . '/' . $framework . '/tablestructure.ser';
if (!file_exists($structurefile)) {
@@ -318,7 +334,7 @@ abstract class testing_util {
/**
* Returns the names of sequences for each autoincrementing id field in all standard tables.
* @static
*
* @return array $table=>$sequencename
*/
public static function get_sequencenames() {
@@ -334,7 +350,7 @@ abstract class testing_util {
self::$sequencenames = [];
foreach ($structure as $table => $ignored) {
$name = $DB->get_manager()->generator->getSequenceFromDB(new xmldb_table($table));
$name = $DB->get_manager()->generator->getSequenceFromDB(new \xmldb_table($table));
if ($name !== false) {
self::$sequencenames[$table] = $name;
}
@@ -346,7 +362,7 @@ abstract class testing_util {
/**
* Returns list of tables that are unmodified and empty.
*
* @static
*
* @return array of table names, empty if unknown
*/
protected static function guess_unmodified_empty_tables() {
@@ -401,7 +417,6 @@ abstract class testing_util {
/**
* Determine the next unique starting id sequences.
*
* @static
* @param array $records The records to use to determine the starting value for the table.
* @param string $table table name.
* @return int The value the sequence should be set to.
@@ -430,9 +445,7 @@ abstract class testing_util {
/**
* Reset all database sequences to initial values.
*
* @static
* @param array $empties tables that are known to be unmodified and empty
* @return void
*/
public static function reset_all_database_sequences(?array $empties = null) {
global $DB;
@@ -534,7 +547,7 @@ abstract class testing_util {
/**
* Reset all database tables to default values.
* @static
*
* @return bool true if reset done, false if skipped
*/
public static function reset_database() {
@@ -628,7 +641,7 @@ abstract class testing_util {
// Remove extra tables.
foreach ($tables as $table) {
if (!isset($data[$table])) {
$DB->get_manager()->drop_table(new xmldb_table($table));
$DB->get_manager()->drop_table(new \xmldb_table($table));
}
}
@@ -638,17 +651,13 @@ abstract class testing_util {
}
/**
* Purge dataroot directory
* @static
* @return void
* Purge dataroot directory.
*/
public static function reset_dataroot() {
global $CFG;
$childclassname = self::get_framework() . '_util';
// Do not delete automatically installed files.
self::skip_original_data_files($childclassname);
self::skip_original_data_files();
// Clear file status cache, before checking file_exists.
clearstatcache();
@@ -656,7 +665,7 @@ abstract class testing_util {
// Clean up the dataroot folder.
$handle = opendir(self::get_dataroot());
while (false !== ($item = readdir($handle))) {
if (in_array($item, $childclassname::$datarootskiponreset)) {
if (in_array($item, static::$datarootskiponreset)) {
continue;
}
if (is_dir(self::get_dataroot() . "/$item")) {
@@ -671,7 +680,7 @@ abstract class testing_util {
if (file_exists(self::get_dataroot() . '/filedir')) {
$handle = opendir(self::get_dataroot() . '/filedir');
while (false !== ($item = readdir($handle))) {
if (in_array('filedir' . DIRECTORY_SEPARATOR . $item, $childclassname::$datarootskiponreset)) {
if (in_array('filedir' . DIRECTORY_SEPARATOR . $item, static::$datarootskiponreset)) {
continue;
}
if (is_dir(self::get_dataroot() . "/filedir/$item")) {
@@ -689,11 +698,11 @@ abstract class testing_util {
make_localcache_directory('');
// Purge all data from the caches. This is required for consistency between tests.
// Any file caches that happened to be within the data root will have already been clearer (because we just deleted cache)
// and now we will purge any other caches as well. This must be done before the cache_factory::reset() as that
// and now we will purge any other caches as well. This must be done before the core_cache\factory::reset() as that
// removes all definitions of caches and purge does not have valid caches to operate on.
cache_helper::purge_all();
\core_cache\helper::purge_all();
// Reset the cache API so that it recreates it's required directories as well.
cache_factory::reset();
\core_cache\factory::reset();
}
/**
@@ -837,7 +846,7 @@ abstract class testing_util {
/**
* Drop the whole test database
* @static
*
* @param bool $displayprogress
*/
protected static function drop_database($displayprogress = false) {
@@ -855,7 +864,7 @@ abstract class testing_util {
}
$dotsonline = 0;
foreach ($tables as $tablename) {
$table = new xmldb_table($tablename);
$table = new \xmldb_table($tablename);
$DB->get_manager()->drop_table($table);
if ($dotsonline == 60) {
@@ -875,13 +884,12 @@ abstract class testing_util {
}
/**
* Drops the test framework dataroot
* @static
* Drops the test framework dataroot.
*/
protected static function drop_dataroot() {
global $CFG;
$framework = self::get_framework();
$framework = static::get_framework();
$childclassname = $framework . '_util';
$files = scandir(self::get_dataroot() . '/' . $framework);
@@ -908,11 +916,8 @@ abstract class testing_util {
/**
* Skip the original dataroot files to not been reset.
*
* @static
* @param string $utilclassname the util class name..
*/
protected static function skip_original_data_files($utilclassname) {
protected static function skip_original_data_files() {
$jsonfilepath = self::get_dataroot() . '/' . self::$originaldatafilesjson;
if (file_exists($jsonfilepath)) {
$listfiles = file_get_contents($jsonfilepath);
@@ -922,8 +927,8 @@ abstract class testing_util {
$originaldatarootfiles = json_decode($listfiles);
// Keep the json file. Only drop_dataroot() should delete it.
$originaldatarootfiles[] = self::$originaldatafilesjson;
$utilclassname::$datarootskiponreset = array_merge(
$utilclassname::$datarootskiponreset,
static::$datarootskiponreset = array_merge(
static::$datarootskiponreset,
$originaldatarootfiles
);
self::$originaldatafilesjsonadded = true;
@@ -949,8 +954,8 @@ abstract class testing_util {
$filedir = self::get_dataroot() . '/filedir';
if (file_exists($filedir)) {
$directory = new RecursiveDirectoryIterator($filedir);
foreach (new RecursiveIteratorIterator($directory) as $file) {
$directory = new \RecursiveDirectoryIterator($filedir);
foreach (new \RecursiveIteratorIterator($directory) as $file) {
if ($file->isDir()) {
$key = substr($file->getPath(), strlen(self::get_dataroot() . '/'));
} else {
@@ -1005,4 +1010,45 @@ abstract class testing_util {
return $env;
}
/**
* Get the path to the Moodle root, relative to the root package.
*
* @return string
*/
public static function get_moodle_relative_to_root_package(): string {
global $CFG;
$rootpackage = \Composer\InstalledVersions::getRootPackage();
$rootpath = realpath(\Composer\InstalledVersions::getRootPackage()['install_path']);
$moodlepath = realpath($CFG->root);
if ($rootpath === $moodlepath) {
// Moodle is the root package.
return '';
}
// At the moment there is no way to get the name of the Moodle core package from the provided package.
// So we need to get all installed moodle-core packages and check which one is installed.
// It's only really possible for a single moodle-core package to be installed.
$moodlecorepackages = \Composer\InstalledVersions::getInstalledPackagesByType('moodle-core');
if (count($moodlecorepackages) !== 1) {
throw new \core\exception\coding_exception('Unable to determine Moodle root relative to root package.');
}
$moodlecorepackage = reset($moodlecorepackages);
if (\Composer\InstalledVersions::isInstalled($moodlecorepackage)) {
$installpath = \Composer\InstalledVersions::getInstallPath($moodlecorepackage);
if ($installpath !== null) {
// Moodle core is installed as a composer package.
return basename($installpath) . '/';
}
}
throw new \core\exception\coding_exception('Unable to determine Moodle root relative to root package.');
}
}
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(testing_util::class, \testing_util::class);
+9
View File
@@ -376,4 +376,13 @@ $legacyclasses = [
'core_courseformat',
'output/local/content/activitychooserbutton.php',
],
\testing_util::class => 'test/testing_util.php',
\phpunit_util::class => 'test/phpunit/phpunit_util.php',
\phpunit_coverage_info::class => 'test/phpunit/coverage_info.php',
\phpunit_message_sink::class => 'test/phpunit/message_sink.php',
\phpunit_phpmailer_sink::class => 'test/phpunit/phpmailer_sink.php',
\phpunit_event_mock::class => 'test/phpunit/event_mock.php',
\phpunit_event_sink::class => 'test/phpunit/event_sink.php',
\tests_finder::class => 'test/test_finder.php',
];
-1
View File
@@ -454,7 +454,6 @@ abstract class moodle_database {
defined('BEHAT_SITE_RUNNING')) {
// Set list of tables that are updated.
require_once(__DIR__.'/../testing/classes/util.php');
testing_util::set_table_modified_by_sql($sql);
}
}
+3 -5
View File
@@ -22,8 +22,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core\url;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../message/lib.php');
@@ -356,7 +354,7 @@ function message_send(\core\message\message $eventdata) {
*/
function message_handle_phpunit_redirection(\core\message\message $eventdata, string $table, \stdClass $tabledata) {
global $DB;
if (PHPUNIT_TEST and class_exists('phpunit_util')) {
if (PHPUNIT_TEST && class_exists(\core\test\phpunit\phpunit_util::class)) {
// Add some more tests to make sure the normal code can actually work.
$componentdir = core_component::get_component_directory($eventdata->component);
if (!$componentdir or !is_dir($componentdir)) {
@@ -374,7 +372,7 @@ function message_handle_phpunit_redirection(\core\message\message $eventdata, st
unset($componentdir);
unset($messageproviders);
// Now ask phpunit if it wants to catch this message.
if (phpunit_util::is_redirecting_messages()) {
if (\core\test\phpunit\phpunit_util::is_redirecting_messages()) {
$messageid = $DB->insert_record($table, $tabledata);
$message = $DB->get_record($table, array('id' => $messageid));
@@ -402,7 +400,7 @@ function message_handle_phpunit_redirection(\core\message\message $eventdata, st
// Unit tests need this detail.
$message->notification = $eventdata->notification;
phpunit_util::message_sent($message);
\core\test\phpunit\phpunit_util::message_sent($message);
return $messageid;
}
}
+1 -1
View File
@@ -1259,7 +1259,7 @@ function purge_caches($options = []) {
* Purge all non-MUC caches not otherwise purged in purge_caches.
*
* IMPORTANT - If you are adding anything here to do with the cache directory you should also have a look at
* {@link phpunit_util::reset_dataroot()}
* {@link \core\test\phpunit\phpunit_util::reset_dataroot()}
*/
function purge_other_caches() {
global $DB, $CFG;
+2 -4
View File
@@ -22,8 +22,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
// PLEASE NOTE: we use the phpmailer class _unmodified_
// through the joys of OO. Distros are free to use their stock
// version of this file.
@@ -129,7 +127,7 @@ class moodle_phpmailer extends \PHPMailer\PHPMailer\PHPMailer {
public function postSend() {
// Now ask phpunit if it wants to catch this message.
if (PHPUNIT_TEST) {
if (!phpunit_util::is_redirecting_phpmailer()) {
if (!\core\test\phpunit\phpunit_util::is_redirecting_phpmailer()) {
debugging('Unit tests must not send real emails! Use $this->redirectEmails()');
return true;
}
@@ -139,7 +137,7 @@ class moodle_phpmailer extends \PHPMailer\PHPMailer\PHPMailer {
$mail->subject = $this->Subject;
$mail->from = $this->From;
$mail->to = $this->to[0][0];
phpunit_util::phpmailer_sent($mail);
\core\test\phpunit\phpunit_util::phpmailer_sent($mail);
return true;
} else {
return parent::postSend();
+3 -3
View File
@@ -267,12 +267,12 @@ if (PHPUNIT_UTIL) {
\core\hook\manager::get_instance();
// Is database and dataroot ready for testing?
[$errorcode, $message] = phpunit_util::testing_ready_problem();
[$errorcode, $message] = \core\test\phpunit\phpunit_util::testing_ready_problem();
// Print some version info.
phpunit_util::bootstrap_moodle_info();
\core\test\phpunit\phpunit_util::bootstrap_moodle_info();
if ($errorcode) {
phpunit_bootstrap_error($errorcode, $message);
}
// Prepare for the first test run - store fresh globals, reset database and dataroot, etc.
phpunit_util::bootstrap_init();
\core\test\phpunit\phpunit_util::bootstrap_init();
@@ -17,6 +17,7 @@
use core\di;
use core\hook;
use core\http_client;
use core\test\phpunit\phpunit_util;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
@@ -337,7 +338,7 @@ abstract class advanced_testcase extends base_testcase {
* @return void
*/
public function assertEventLegacyData($expected, \core\event\base $event, $message = '') {
$legacydata = phpunit_event_mock::testable_get_legacy_eventdata($event);
$legacydata = \core\test\phpunit\event_mock::testable_get_legacy_eventdata($event);
if ($message === '') {
$message = 'Event legacy data does not match expected value.';
}
@@ -353,7 +354,7 @@ abstract class advanced_testcase extends base_testcase {
* @return void
*/
public function assertEventLegacyLogData($expected, \core\event\base $event, $message = '') {
$legacydata = phpunit_event_mock::testable_get_legacy_logdata($event);
$legacydata = \core\test\phpunit\event_mock::testable_get_legacy_logdata($event);
if ($message === '') {
$message = 'Event legacy log data does not match expected value.';
}
@@ -372,8 +373,8 @@ abstract class advanced_testcase extends base_testcase {
*/
public function assertEventContextNotUsed(\core\event\base $event, $message = '') {
// Save current event->context and set it to false.
$eventcontext = phpunit_event_mock::testable_get_event_context($event);
phpunit_event_mock::testable_set_event_context($event, false);
$eventcontext = \core\test\phpunit\event_mock::testable_get_event_context($event);
\core\test\phpunit\event_mock::testable_set_event_context($event, false);
if ($message === '') {
$message = 'Event should not use context property of event in any method.';
}
@@ -383,7 +384,7 @@ abstract class advanced_testcase extends base_testcase {
$event->get_description();
// Restore event->context (note that this is unreachable when the event uses context). But ok for correct events.
phpunit_event_mock::testable_set_event_context($event, $eventcontext);
\core\test\phpunit\event_mock::testable_set_event_context($event, $eventcontext);
}
/**
@@ -417,7 +418,7 @@ abstract class advanced_testcase extends base_testcase {
* array in the returned messaging sink instance. The redirection
* can be stopped by calling $sink->close();
*
* @return phpunit_message_sink
* @return \core\test\phpunit\message_sink
*/
public function redirectMessages() {
return phpunit_util::start_message_redirection();
@@ -430,7 +431,7 @@ abstract class advanced_testcase extends base_testcase {
* array in the returned phpmailer sink instance. The redirection
* can be stopped by calling $sink->close();
*
* @return phpunit_message_sink
* @return \core\test\phpunit\message_sink
*/
public function redirectEmails() {
return phpunit_util::start_phpmailer_redirection();
@@ -443,7 +444,7 @@ abstract class advanced_testcase extends base_testcase {
* array in the returned event sink instance. The redirection
* can be stopped by calling $sink->close();
*
* @return phpunit_event_sink
* @return \core\test\phpunit\event_sink
*/
public function redirectEvents() {
return phpunit_util::start_event_redirection();
@@ -1,5 +1,4 @@
<?php
use PHPUnit\Framework\Attributes\After;
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -15,6 +14,8 @@ use PHPUnit\Framework\Attributes\After;
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
use PHPUnit\Framework\Attributes\After;
/**
* The simplest PHPUnit test case customised for Moodle
*
@@ -47,11 +48,11 @@ abstract class basic_testcase extends base_testcase {
global $DB;
if ($DB->is_transaction_started()) {
phpunit_util::reset_all_data();
\core\test\phpunit\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);
\core\test\phpunit\phpunit_util::reset_all_data(true);
}
/**
+8 -76
View File
@@ -18,82 +18,14 @@
* Coverage information for PHPUnit.
*
* @package core
* @category phpunit
* @copyright 2018 Andrew Nicols <[email protected]>
* @category test
* @copyright Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class phpunit_coverage_info {
/** @var array The list of folders relative to the plugin root to include in coverage generation. */
protected $includelistfolders = [];
/** @var array The list of files relative to the plugin root to include in coverage generation. */
protected $includelistfiles = [];
/** @var array The list of folders relative to the plugin root to exclude from coverage generation. */
protected $excludelistfolders = [];
/** @var array The list of files relative to the plugin root to exclude from coverage generation. */
protected $excludelistfiles = [];
/**
* Get the formatted XML list of files and folders to include.
*
* @param string $plugindir The root of the plugin, relative to the dataroot.
* @return array
*/
final public function get_includelists(string $plugindir): array {
$coverages = [];
$includelistfolders = array_merge([
'classes',
'tests/generator',
], $this->includelistfolders);;
$includelistfiles = array_merge([
'externallib.php',
'lib.php',
'locallib.php',
'renderer.php',
'rsslib.php',
], $this->includelistfiles);
if (!empty($plugindir)) {
$plugindir .= "/";
}
foreach (array_unique($includelistfolders) as $folder) {
$coverages[] = html_writer::tag('directory', "{$plugindir}{$folder}", ['suffix' => '.php']);
}
foreach (array_unique($includelistfiles) as $file) {
$coverages[] = html_writer::tag('file', "{$plugindir}{$file}");
}
return $coverages;
}
/**
* Get the formatted XML list of files and folders to exclude.
*
* @param string $plugindir The root of the plugin, relative to the dataroot.
* @return array
*/
final public function get_excludelists(string $plugindir): array {
$coverages = [];
if (!empty($plugindir)) {
$plugindir .= "/";
}
foreach ($this->excludelistfolders as $folder) {
$coverages[] = html_writer::tag('directory', "{$plugindir}{$folder}", ['suffix' => '.php']);
}
foreach ($this->excludelistfiles as $file) {
$coverages[] = html_writer::tag('file', "{$plugindir}{$file}");
}
return $coverages;
}
}
debugging(
'The coverage_info.php file is deprecated and will be removed in Moodle 6.0. ' .
'It should not be manually included. ' .
'The class can now be autoloaded from \core\test\phpunit\coverage_info.',
DEBUG_DEVELOPER
);
@@ -1,7 +1,5 @@
<?php
use PHPUnit\Framework\Attributes\After;
use PHPUnit\Framework\Attributes\Before;
// This file is part of Moodle - http://moodle.org/
// This file is part of Moodle - https://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
@@ -25,6 +23,9 @@ use PHPUnit\Framework\Attributes\Before;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core\test\phpunit\phpunit_util;
use PHPUnit\Framework\Attributes\After;
use PHPUnit\Framework\Attributes\Before;
/**
* Special test case for testing of DML drivers and DDL layer.
+6 -32
View File
@@ -14,17 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Event mock.
*
* @package core
* @category phpunit
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../classes/event/base.php');
/**
* Event mock class.
*
@@ -33,25 +22,10 @@ require_once(__DIR__ . '/../../classes/event/base.php');
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class phpunit_event_mock extends \core\event\base {
/**
* Returns event context.
*
* @param \core\event\base $event event to get context for.
* @return context event context
*/
public static function testable_get_event_context($event) {
return $event->context;
}
/**
* Sets event context.
*
* @param \core\event\base $event event to set context for.
* @param context $context context to set.
*/
public static function testable_set_event_context($event, $context) {
$event->context = $context;
}
}
debugging(
'The event_mock.php file is deprecated and will be removed in Moodle 6.0. ' .
'It should not be manually included. ' .
'The class can now be autoloaded from \core\test\phpunit\event_mock.',
DEBUG_DEVELOPER
);
+6 -62
View File
@@ -14,16 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Event sink.
*
* @package core
* @category phpunit
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Event redirection sink.
*
@@ -32,56 +22,10 @@
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class phpunit_event_sink {
/** @var \core\event\base[] array of events */
protected $events = array();
/**
* Stop event redirection.
*
* Use if you do not want event redirected any more.
*/
public function close() {
phpunit_util::stop_event_redirection();
}
/**
* To be called from phpunit_util only!
*
* @private
* @param \core\event\base $event record from event_read table
*/
public function add_event(\core\event\base $event) {
/* Number events from 0. */
$this->events[] = $event;
}
/**
* Returns all redirected events.
*
* The instances are records form the event_read table.
* The array indexes are numbered from 0 and the order is matching
* the creation of events.
*
* @return \core\event\base[]
*/
public function get_events() {
return $this->events;
}
/**
* Return number of events redirected to this sink.
*
* @return int
*/
public function count() {
return count($this->events);
}
/**
* Removes all previously stored events.
*/
public function clear() {
$this->events = array();
}
}
debugging(
'The event_sink.php file is deprecated and will be removed in Moodle 6.0. ' .
'It should not be manually included. ' .
'The class can now be autoloaded from \core\test\phpunit\event_sink.',
DEBUG_DEVELOPER
);
@@ -23,5 +23,5 @@ namespace core_phpunit\exception;
* @copyright Andrew Lyons <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class test_exception extends \core\exception\coding_exception {
}
class_alias(\core\test\phpunit\exception\test_exception::class, test_exception::class);
+6 -94
View File
@@ -23,97 +23,9 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Message sink.
*
* @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_message_sink {
/** @var array of records from messages table */
protected $messages = array();
/**
* Stop message redirection.
*
* Use if you do not want message redirected any more.
*/
public function close() {
phpunit_util::stop_message_redirection();
}
/**
* To be called from phpunit_util only!
*
* @param stdClass $message record from messages table
*/
public function add_message($message) {
/* Number messages from 0. */
$this->messages[] = $message;
}
/**
* Returns all redirected messages.
*
* The instances are records from the messages table.
* The array indexes are numbered from 0 and the order is matching
* the creation of events.
*
* @param callable|null $filter Use to filter the messages.
* @return array
*/
public function get_messages(?callable $filter = null): array {
if ($filter) {
return array_filter($this->messages, $filter);
}
return $this->messages;
}
/**
* Return all redirected messages for a given component.
*
* @param string $component Component name.
* @return array List of messages.
*/
public function get_messages_by_component(string $component): array {
$component = core_component::normalize_componentname($component);
return $this->get_messages(
fn ($message) => core_component::normalize_componentname($message->component) === $component,
);
}
/**
* Return all redirected messages for a given component and type.
*
* @param string $component Component name.
* @param string $type Message type.
* @return array List of messages.
*/
public function get_messages_by_component_and_type(
string $component,
string $type,
): array {
return array_filter($this->get_messages_by_component($component), function($message) use ($type) {
return $message->eventtype == $type;
});
}
/**
* Return number of messages redirected to this sink.
* @return int
*/
public function count() {
return count($this->messages);
}
/**
* Removes all previously stored messages.
*/
public function clear() {
$this->messages = array();
}
}
debugging(
'The message_sink.php file is deprecated and will be removed in Moodle 6.0. ' .
'It should not be manually included. ' .
'The class can now be autoloaded from \core\test\phpunit\message_sink.',
DEBUG_DEVELOPER
);
+6 -62
View File
@@ -23,65 +23,9 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* phpmailer message sink.
*
* @package core
* @category phpunit
* @copyright 2013 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class phpunit_phpmailer_sink {
/**
* @var array of records which would have been sent by phpmailer.
*/
protected $messages = array();
/**
* Stop message redirection.
*
* Use if you do not want message redirected any more.
*/
public function close() {
phpunit_util::stop_phpmailer_redirection();
}
/**
* To be called from phpunit_util only!
*
* @param stdClass $message record from messages table
*/
public function add_message($message) {
/* Number messages from 0. */
$this->messages[] = $message;
}
/**
* Returns all redirected messages.
*
* The instances are records from the messages table.
* The array indexes are numbered from 0 and the order is matching
* the creation of events.
*
* @return array
*/
public function get_messages() {
return $this->messages;
}
/**
* Return number of messages redirected to this sink.
* @return int
*/
public function count() {
return count($this->messages);
}
/**
* Removes all previously stored messages.
*/
public function clear() {
$this->messages = array();
}
}
debugging(
'The phpmailer_sink.php file is deprecated and will be removed in Moodle 6.0. ' .
'It should not be manually included. ' .
'The class can now be autoloaded from \core\test\phpunit\phpmailer_sink.',
DEBUG_DEVELOPER
);
@@ -32,6 +32,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
declare(strict_types=1);
/**
@@ -202,7 +203,7 @@ class phpunit_dataset {
}
}
$structure = phpunit_util::get_tablestructure();
$structure = \core\test\phpunit\phpunit_util::get_tablestructure();
foreach ($this->tables as $table) {
// Apply filter.
File diff suppressed because it is too large Load Diff
-6
View File
@@ -25,16 +25,10 @@
// NOTE: MOODLE_INTERNAL is not verified here because we load this before setup.php!
require_once(__DIR__.'/classes/util.php');
require_once(__DIR__.'/classes/phpunit_dataset.php');
require_once(__DIR__.'/classes/event_mock.php');
require_once(__DIR__.'/classes/event_sink.php');
require_once(__DIR__.'/classes/message_sink.php');
require_once(__DIR__.'/classes/phpmailer_sink.php');
require_once(__DIR__.'/classes/base_testcase.php');
require_once(__DIR__.'/classes/basic_testcase.php');
require_once(__DIR__.'/classes/database_driver_testcase.php');
require_once(__DIR__.'/classes/advanced_testcase.php');
require_once(__DIR__.'/classes/constraint_object_is_equal_with_exceptions.php');
require_once(__DIR__.'/../testing/classes/test_lock.php');
require_once(__DIR__.'/../testing/classes/tests_finder.php');
+6 -6
View File
@@ -16,7 +16,7 @@
namespace core;
use core_phpunit\exception\test_exception;
use core\test\phpunit\exception\test_exception;
/**
* Test advanced_testcase extra features.
@@ -455,7 +455,7 @@ final class advanced_test extends \advanced_testcase {
$this->assertEquals(count($processors1) + 1, count($processors3));
}
public function test_message_redirection(): \phpunit_message_sink {
public function test_message_redirection(): \core\test\phpunit\message_sink {
$this->preventResetByRollback(); // Messaging is not compatible with transactions...
$this->resetAfterTest(false);
@@ -570,14 +570,14 @@ final class advanced_test extends \advanced_testcase {
$this->assertEquals(1, $sink->count());
// Test if sink can be carried over to next test.
$this->assertTrue(\phpunit_util::is_redirecting_messages());
$this->assertTrue(\core\test\phpunit\phpunit_util::is_redirecting_messages());
return $sink;
}
/**
* @depends test_message_redirection
*/
public function test_message_redirection_noreset(\phpunit_message_sink $sink): void {
public function test_message_redirection_noreset(\core\test\phpunit\message_sink $sink): void {
if ($this->isInIsolation()) {
$this->markTestSkipped('State cannot be carried over between tests in isolated tests');
}
@@ -585,7 +585,7 @@ final class advanced_test extends \advanced_testcase {
$this->preventResetByRollback(); // Messaging is not compatible with transactions...
$this->resetAfterTest();
$this->assertTrue(\phpunit_util::is_redirecting_messages());
$this->assertTrue(\core\test\phpunit\phpunit_util::is_redirecting_messages());
$this->assertEquals(1, $sink->count());
$message = new \core\message\message();
@@ -609,7 +609,7 @@ final class advanced_test extends \advanced_testcase {
* @depends test_message_redirection_noreset
*/
public function test_message_redirection_reset(): void {
$this->assertFalse(\phpunit_util::is_redirecting_messages(), 'Test reset must stop message redirection.');
$this->assertFalse(\core\test\phpunit\phpunit_util::is_redirecting_messages(), 'Test reset must stop message redirection.');
}
public function test_set_timezone(): void {
+3 -3
View File
@@ -16,7 +16,7 @@
namespace core;
use phpunit_util;
use core\test\phpunit\phpunit_util;
/**
* Test basic_testcase extra features and PHPUnit Moodle integration.
@@ -27,7 +27,7 @@ use phpunit_util;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
#[\PHPUnit\Framework\Attributes\CoversClass(\basic_testcase::class)]
#[\PHPUnit\Framework\Attributes\CoversClass(\phpunit_util::class)]
#[\PHPUnit\Framework\Attributes\CoversClass(phpunit_util::class)]
final class basic_test extends \basic_testcase {
/** @var bool */
protected bool $testassertexecuted = false;
@@ -233,7 +233,7 @@ STRING;
global $DB;
$DB->set_field('user', 'confirmed', 1, ['id' => -1]);
$this->expectException(\core_phpunit\exception\test_exception::class);
$this->expectException(\core\test\phpunit\exception\test_exception::class);
$this->expectExceptionMessage('Warning: unexpected database modification');
phpunit_util::reset_all_data(true);
}
+4 -4
View File
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core;
namespace core\test\phpunit;
/**
* Test util extra features.
@@ -29,10 +29,10 @@ final class util_test extends \advanced_testcase {
* @dataProvider set_table_modified_by_sql_provider
*/
public function test_set_table_modified_by_sql($sql, $expectations): void {
\phpunit_util::reset_updated_table_list();
\phpunit_util::set_table_modified_by_sql($sql);
phpunit_util::reset_updated_table_list();
phpunit_util::set_table_modified_by_sql($sql);
foreach ($expectations as $table => $present) {
$this->assertEquals($present, !empty(\phpunit_util::$tableupdated[$table]));
$this->assertEquals($present, !empty(phpunit_util::$tableupdated[$table]));
}
}
+3 -3
View File
@@ -688,7 +688,7 @@ setup_DB();
if (PHPUNIT_TEST and !PHPUNIT_UTIL) {
// Make sure tests do not run in parallel.
$suffix = '';
if (phpunit_util::is_in_isolated_process()) {
if (\core\test\phpunit\phpunit_util::is_in_isolated_process()) {
$suffix = '.isolated';
}
test_lock::acquire('phpunit', $suffix);
@@ -696,7 +696,7 @@ if (PHPUNIT_TEST and !PHPUNIT_UTIL) {
try {
if ($dbhash = $DB->get_field('config', 'value', array('name'=>'phpunittest'))) {
// reset DB tables
phpunit_util::reset_database();
\core\test\phpunit\phpunit_util::reset_database();
}
} catch (Exception $e) {
if ($dbhash) {
@@ -736,7 +736,7 @@ if (is_readable($bootstraplocalfile)) {
// Load up any configuration from the config table or MUC cache.
if (PHPUNIT_TEST) {
phpunit_util::initialise_cfg();
\core\test\phpunit\phpunit_util::initialise_cfg();
} else {
initialise_cfg();
}
+2 -2
View File
@@ -472,7 +472,7 @@ function get_docs_url($path = null) {
*/
function format_backtrace($callers, $plaintext = false) {
// Do not use $CFG->dirroot because it might not be available in destructors.
$dirroot = dirname(__DIR__, 2);
$dirroot = realpath(dirname(__DIR__, 2));
if (empty($callers)) {
return '';
@@ -490,7 +490,7 @@ function format_backtrace($callers, $plaintext = false) {
$line .= sprintf(
'line %d of %s',
$caller['line'],
str_replace($dirroot, '', $caller['file']),
str_replace($dirroot, '', realpath($caller['file'])),
);
if (isset($caller['function'])) {
$line .= ': call to ';
+6 -182
View File
@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Tests finder
*
* @package core
* @category test
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Finds components and plugins with tests
*
@@ -31,177 +22,10 @@
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tests_finder {
/**
* Returns all the components with tests of the specified type
* @param string $testtype The kind of test we are looking for
* @return array
*/
public static function get_components_with_tests($testtype) {
// Get all the components
$components = self::get_all_plugins_with_tests($testtype) + self::get_all_subsystems_with_tests($testtype);
// Get all the directories having tests
$directories = self::get_all_directories_with_tests($testtype);
// Find any directory not covered by proper components
$remaining = array_diff($directories, $components);
// Add them to the list of components
$components += $remaining;
return $components;
}
/**
* Returns all the plugins having tests
* @param string $testtype The kind of test we are looking for
* @return array all the plugins having tests
*/
private static function get_all_plugins_with_tests($testtype) {
$pluginswithtests = array();
$plugintypes = core_component::get_plugin_types();
ksort($plugintypes);
foreach ($plugintypes as $type => $unused) {
$plugs = core_component::get_plugin_list($type);
ksort($plugs);
foreach ($plugs as $plug => $fullplug) {
// Look for tests recursively
if (self::directory_has_tests($fullplug, $testtype)) {
$pluginswithtests[$type . '_' . $plug] = $fullplug;
}
}
}
return $pluginswithtests;
}
/**
* Returns all the subsystems having tests
*
* Note we are hacking here the list of subsystems
* to cover some well-known subsystems that are not properly
* returned by the {@link get_core_subsystems()} function.
*
* @param string $testtype The kind of test we are looking for
* @return array all the subsystems having tests
*/
private static function get_all_subsystems_with_tests($testtype) {
global $CFG;
$subsystemswithtests = array();
$subsystems = core_component::get_core_subsystems();
// Hack the list a bit to cover some well-known ones
$subsystems['backup'] = $CFG->dirroot.'/backup';
$subsystems['db-dml'] = $CFG->dirroot.'/lib/dml';
$subsystems['db-ddl'] = $CFG->dirroot.'/lib/ddl';
ksort($subsystems);
foreach ($subsystems as $subsys => $fullsubsys) {
if ($fullsubsys === null) {
continue;
}
if (!is_dir($fullsubsys)) {
continue;
}
// Look for tests recursively
if (self::directory_has_tests($fullsubsys, $testtype)) {
$subsystemswithtests['core_' . $subsys] = $fullsubsys;
}
}
return $subsystemswithtests;
}
/**
* Returns all the directories having tests
*
* @param string $testtype The kind of test we are looking for
* @return array all directories having tests
*/
private static function get_all_directories_with_tests($testtype) {
global $CFG;
// List of directories to exclude from test file searching.
$excludedir = array('node_modules', 'vendor');
// Get first level directories in which tests should be searched.
$directoriestosearch = array();
$alldirs = glob($CFG->dirroot . DIRECTORY_SEPARATOR . '*' , GLOB_ONLYDIR);
foreach ($alldirs as $dir) {
if (!in_array(basename($dir), $excludedir) && (filetype($dir) != 'link')) {
$directoriestosearch[] = $dir;
}
}
// Search for tests in valid directories.
$dirs = array();
foreach ($directoriestosearch as $dir) {
$dirite = new RecursiveDirectoryIterator($dir);
$iteite = new RecursiveIteratorIterator($dirite);
$regexp = self::get_regexp($testtype);
$regite = new RegexIterator($iteite, $regexp);
foreach ($regite as $path => $element) {
$key = dirname(dirname($path));
$value = trim(str_replace(DIRECTORY_SEPARATOR, '_', str_replace($CFG->dirroot, '', $key)), '_');
$dirs[$key] = $value;
}
}
ksort($dirs);
return array_flip($dirs);
}
/**
* Returns if a given directory has tests (recursively)
*
* @param string $dir full path to the directory to look for phpunit tests
* @param string $testtype phpunit|behat
* @return bool if a given directory has tests (true) or no (false)
*/
private static function directory_has_tests($dir, $testtype) {
if (!is_dir($dir)) {
return false;
}
$dirite = new RecursiveDirectoryIterator($dir);
$iteite = new RecursiveIteratorIterator($dirite);
$regexp = self::get_regexp($testtype);
$regite = new RegexIterator($iteite, $regexp);
$regite->rewind();
if ($regite->valid()) {
return true;
}
return false;
}
/**
* Returns the regular expression to match by the test files
* @param string $testtype
* @return string
*/
private static function get_regexp($testtype) {
$sep = preg_quote(DIRECTORY_SEPARATOR, '|');
switch ($testtype) {
case 'phpunit':
$regexp = '|'.$sep.'tests'.$sep.'.*_test\.php$|';
break;
case 'features':
$regexp = '|'.$sep.'tests'.$sep.'behat'.$sep.'.*\.feature$|';
break;
case 'stepsdefinitions':
$regexp = '|'.$sep.'tests'.$sep.'behat'.$sep.'behat_.*\.php$|';
break;
case 'behat':
$regexp = '!'.$sep.'tests'.$sep.'behat'.$sep.'(.*\.feature)|(behat_.*\.php)$!';
break;
}
return $regexp;
}
}
debugging(
'The tests_finder.php file is deprecated and will be removed in Moodle 6.0. ' .
'It should not be manually included. ' .
'The class can now be autoloaded from \core\test\test_finder.',
DEBUG_DEVELOPER
);
+13
View File
@@ -184,6 +184,19 @@ function testing_error($errorcode, $text = '') {
* @param bool $updatedependencies Upgrade dependencies
*/
function testing_update_composer_dependencies(bool $selfupdate = true, bool $updatedependencies = true): void {
// Check if we are running inside another project that already loaded composer.
if (class_exists(\Composer\InstalledVersions::class)) {
// The Composer library is already loaded.
// Check to see if Moodle is the root package.
$rootpackage = \Composer\InstalledVersions::getRootPackage();
if ($rootpackage['name'] !== 'moodle/moodle') {
// Assume that the user has already run the composer commands manually.
echo " Composer library is already loaded by another project ({$rootpackage['name']}).\n";
echo " Skipping composer self-update and dependency update.\n";
return;
}
}
// To restore the value after finishing.
$cwd = getcwd();
@@ -47,7 +47,7 @@ final class data_provider_finished_subscriber implements DataProviderMethodFinis
}
if ($resetall) {
\phpunit_util::reset_all_data();
\core\test\phpunit\phpunit_util::reset_all_data();
$this->update_db_writes();
}
}
+1 -10
View File
@@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
/**
* Coverage information for the core subsystem.
*
@@ -24,14 +22,7 @@ defined('MOODLE_INTERNAL') || die();
* @copyright 2018 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Coverage information for the core subsystem.
*
* @copyright 2018 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
return new class extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of folders relative to the plugin root to include in coverage generation. */
protected $includelistfolders = [
// This is a legacy hangup which relates to parts of the file storage API being placed in the wrong location.
+18 -4
View File
@@ -203,8 +203,15 @@ final class curl_security_helper_test extends \advanced_testcase {
$this->resetAfterTest(true);
$helper = new \core\files\curl_security_helper();
set_config('curlsecurityblockedhosts', $blockedhosts);
$this->assertEquals($expected, \phpunit_util::call_internal_method($helper, 'host_is_blocked', [$host],
'\core\files\curl_security_helper'));
$this->assertEquals(
$expected,
\core\test\phpunit\phpunit_util::call_internal_method(
$helper,
'host_is_blocked',
[$host],
\core\files\curl_security_helper::class,
),
);
}
/**
@@ -257,8 +264,15 @@ final class curl_security_helper_test extends \advanced_testcase {
$this->resetAfterTest(true);
$helper = new \core\files\curl_security_helper();
set_config('curlsecurityallowedport', $allowedports);
$this->assertEquals($expected, \phpunit_util::call_internal_method($helper, 'port_is_blocked', [$port],
'\core\files\curl_security_helper'));
$this->assertEquals(
$expected,
\core\test\phpunit\phpunit_util::call_internal_method(
$helper,
'port_is_blocked',
[$port],
\core\files\curl_security_helper::class,
),
);
}
/**
+2 -2
View File
@@ -261,8 +261,8 @@ final class message_test extends \advanced_testcase {
/**
* Test get_messages_by_component method.
*
* @covers \phpunit_message_sink::get_messages_by_component
* @covers \phpunit_message_sink::get_messages_by_component_and_type
* @covers \core\test\phpunit\message_sink::get_messages_by_component
* @covers \core\test\phpunit\message_sink::get_messages_by_component_and_type
*/
public function test_get_messages_by_component(): void {
$this->resetAfterTest();
@@ -122,7 +122,7 @@ TBD;
TBC;
$loader = new mustache_template_source_loader();
$actual = \phpunit_util::call_internal_method(
$actual = \core\test\phpunit\phpunit_util::call_internal_method(
$loader,
'strip_template_comments',
[$templatewithcomment],
@@ -494,7 +494,7 @@ TEMPLATE;
* @param string $expected The expected output
*/
public function test_scan_template_source_for_dependencies($loader, $source, $expected): void {
$actual = \phpunit_util::call_internal_method(
$actual = \core\test\phpunit\phpunit_util::call_internal_method(
$loader,
'scan_template_source_for_dependencies',
[$source],
+1 -1
View File
@@ -123,7 +123,7 @@ CSS
*/
public function test_is_valid_file($path, $valid): void {
$scss = new \core_scss();
$pathvalid = \phpunit_util::call_internal_method($scss, 'is_valid_file', [$path], \core_scss::class);
$pathvalid = \core\test\phpunit\phpunit_util::call_internal_method($scss, 'is_valid_file', [$path], \core_scss::class);
$this->assertSame($valid, $pathvalid);
}
+6 -1
View File
@@ -557,6 +557,11 @@ final class setuplib_test extends \advanced_testcase {
$this->assertStringContainsString(' of /public/lib/tests/setuplib_test.php', $output);
// And a vendor path.
$this->assertStringContainsString(' of /vendor/', $output);
$rootdir = realpath(\Composer\InstalledVersions::getRootPackage()['install_path']);
// If the vendor directory is within the $CFG->root it won't be present.
if (str_starts_with($rootdir, realpath(dirname(__DIR__, 3)))) {
$rootdir = '';
}
$this->assertStringContainsString(" of {$rootdir}/vendor", $output);
}
}
+1 -1
View File
@@ -2505,7 +2505,7 @@ function debugging($message = '', $level = DEBUG_NORMAL, $backtrace = null) {
}
$from = format_backtrace($backtrace, CLI_SCRIPT || NO_DEBUG_DISPLAY);
if (PHPUNIT_TEST) {
if (phpunit_util::debugging_triggered($message, $level, $from)) {
if (\core\test\phpunit\phpunit_util::debugging_triggered($message, $level, $from)) {
// We are inside test, the debug message was logged.
return true;
}
+1 -2
View File
@@ -30,7 +30,6 @@ require_once($CFG->libdir . '/xhprof/xhprof_lib/utils/xhprof_runs.php');
require_once($CFG->libdir . '/tablelib.php');
require_once($CFG->libdir . '/setuplib.php');
require_once($CFG->libdir . '/filelib.php');
require_once($CFG->libdir . '/phpunit/classes/util.php');
require_once($CFG->dirroot . '/backup/util/xml/xml_writer.class.php');
require_once($CFG->dirroot . '/backup/util/xml/output/xml_output.class.php');
require_once($CFG->dirroot . '/backup/util/xml/output/file_xml_output.class.php');
@@ -679,7 +678,7 @@ function profiling_export_generate(array $runids, $tmpdir) {
$release = $CFG->release;
$version = $CFG->version;
$dbtype = $CFG->dbtype;
$githash = phpunit_util::get_git_hash();
$githash = \core\test\phpunit\phpunit_util::get_git_hash();
$date = time();
// Create the xml output and writer for the main file.
@@ -34,7 +34,7 @@ require_once($CFG->dirroot . '/message/output/popup/tests/base.php');
final class api_test extends \advanced_testcase {
use \message_popup_test_helper;
/** @var \phpunit_message_sink message redirection. */
/** @var \core\test\phpunit\message_sink message redirection. */
public $messagesink;
/**
@@ -37,7 +37,7 @@ require_once($CFG->dirroot . '/message/output/popup/tests/base.php');
final class externallib_test extends \advanced_testcase {
use message_popup_test_helper;
/** @var \phpunit_message_sink message redirection. */
/** @var \core\test\phpunit\message_sink message redirection. */
public $messagesink;
/**
+1 -1
View File
@@ -2157,7 +2157,7 @@ You can see it appended to your <a href="' . $assignurl .
$this->add_submission($student, $assign);
$this->submit_for_grading($student, $assign);
$this->mark_submission($teacher, $assign, $student);
\phpunit_util::stop_message_redirection();
\core\test\phpunit\phpunit_util::stop_message_redirection();
// Now run cron and see that one message was sent.
\core\cron::setup_user();
@@ -206,7 +206,7 @@ final class backup_restore_test extends restore_date_testcase {
// Delete the course module.
\core_courseformat\formatactions::cm($this->course->id)->delete($bbactivitycm->id);
// Now, run the course module deletion adhoc task.
\phpunit_util::run_all_adhoc_tasks();
\core\test\phpunit\phpunit_util::run_all_adhoc_tasks();
$currentinstances = instance::get_all_instances_in_course($this->course->id);
$this->assertEmpty($currentinstances);
// Try restoring.
+2 -15
View File
@@ -13,28 +13,16 @@
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Coverage information for the mod_bigbluebuttonbn component.
*
* @package mod_bigbluebuttonbn
* @copyright 2018 - present, Blindside Networks Inc
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Laurent David ([email protected])
*/
defined('MOODLE_INTERNAL') || die();
/**
* Class bbb_coverage information for the core subsystem.
*
* Note that we had to change the definition of this class due to a bug in local_moodlecheck
* https://github.com/moodlehq/moodle-local_moodlecheck/issues/50
* @package mod_bigbluebuttonbn
* @copyright 2018 - present, Blindside Networks Inc
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Laurent David ([email protected])
*/
class bbb_coverage extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of folders relative to the plugin root to includelist in coverage generation. */
protected $includelistfolders = [
'classes',
@@ -51,5 +39,4 @@ class bbb_coverage extends phpunit_coverage_info {
/** @var array The list of files relative to the plugin root to excludelist in coverage generation. */
protected $excludelistfiles = [];
}
return new bbb_coverage;
};
@@ -101,7 +101,8 @@ final class entries_export_test extends \advanced_testcase {
* @covers \mod_data\local\exporter\utils::data_exportdata
*/
public function test_export_csv(): void {
global $DB;
global $CFG, $DB;
[
'data' => $data,
'cm' => $cm,
@@ -151,9 +152,9 @@ final class entries_export_test extends \advanced_testcase {
// file stored in a file and picture field.
// So we expect that this file has to have the same content as sample.png.
// Also, the default value for the subdirectory in the zip archive containing the files is 'files/'.
'files/samplefile.png' => 'public/mod/data/field/picture/pix/sample.png',
'files/samplefile_1.png' => 'public/mod/data/field/picture/pix/sample.png',
'files/picturefile.png' => 'public/mod/data/field/picture/pix/sample.png',
'files/samplefile.png' => "{$CFG->root}/public/mod/data/field/picture/pix/sample.png",
'files/samplefile_1.png' => "{$CFG->root}/public/mod/data/field/picture/pix/sample.png",
'files/picturefile.png' => "{$CFG->root}/public/mod/data/field/picture/pix/sample.png",
// By checking that the content of the exported csv is identical to the fixture file it is verified
// that the filenames in the csv file correspond to the names of the exported file.
// It also verifies that files with identical file names in different fields (or records) will be numbered
-12
View File
@@ -14,21 +14,9 @@
// 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 class for mod_data.
*
* @package mod_data
* @category test
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use mod_data\manager;
use mod_data\preset;
defined('MOODLE_INTERNAL') || die();
/**
* Data generator class for mod_data.
*
-1
View File
@@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Forum module data generator class
*
+1 -1
View File
@@ -40,7 +40,7 @@ final class mail_group_test extends \advanced_testcase {
use mod_forum_tests_generator_trait;
/**
* @var \phpunit_message_sink
* @var \core\test\phpunit\message_sink
*/
protected $messagesink;
+3 -3
View File
@@ -43,16 +43,16 @@ final class mail_test extends \advanced_testcase {
use mod_forum_tests_generator_trait;
/**
* @var \phpunit_message_sink
* @var \core\test\phpunit\message_sink
*/
protected $messagesink;
/**
* @var \phpunit_mailer_sink
* @var \core\test\phpunit\phpmailer_sink
*/
protected $mailsink;
/** @var \phpunit_event_sink */
/** @var \core\test\phpunit\event_sink */
protected $eventsink;
public function setUp(): void {
+2 -2
View File
@@ -41,10 +41,10 @@ final class maildigest_test extends \advanced_testcase {
// Make use of the test generator trait.
use mod_forum_tests_generator_trait;
/** @var \phpunit_message_sink */
/** @var \core\test\phpunit\message_sink */
protected $messagesink;
/** @var \phpunit_message_sink */
/** @var \core\test\phpunit\message_sink */
protected $mailsink;
/**
+1 -1
View File
@@ -41,7 +41,7 @@ final class qanda_test extends \advanced_testcase {
use mod_forum_tests_generator_trait;
/**
* @var \phpunit_message_sink
* @var \core\test\phpunit\message_sink
*/
protected $messagesink;
@@ -14,21 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Unit Tests for the Moodle Content Writer.
*
* @package core_privacy
* @category test
* @copyright 2018 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
use \core_privacy\local\request\writer;
use \core_privacy\local\request\moodle_content_writer;
use core_privacy\local\request\moodle_content_writer;
use core_privacy\local\request\writer;
/**
* Tests for the \core_privacy API's moodle_content_writer functionality.
@@ -38,7 +25,6 @@ use \core_privacy\local\request\moodle_content_writer;
* @coversDefaultClass \core_privacy\local\request\moodle_content_writer
*/
final class moodle_content_writer_test extends advanced_testcase {
/**
* Test that exported data is saved correctly within the system context.
*
@@ -1373,8 +1359,12 @@ final class moodle_content_writer_test extends advanced_testcase {
$file->storedfile = $fs->create_file_from_string($record, $file->content);
$writer->set_context($context)->export_area_files([], 'core_privacy', 'tests', 0);
list($tree, $treelist, $indexdata) = phpunit_util::call_internal_method($writer, 'prepare_for_export', [],
'\core_privacy\local\request\moodle_content_writer');
[$tree, $treelist, $indexdata] = \core\test\phpunit\phpunit_util::call_internal_method(
$writer,
'prepare_for_export',
[],
moodle_content_writer::class,
);
$expectedtreeoutput = [
'System _.1' => [
@@ -1422,8 +1412,12 @@ final class moodle_content_writer_test extends advanced_testcase {
];
$this->assertEquals($expectedindex, $indexdata);
$richtree = phpunit_util::call_internal_method($writer, 'make_tree_object', [$tree, $treelist],
'\core_privacy\local\request\moodle_content_writer');
$richtree = \core\test\phpunit\phpunit_util::call_internal_method(
$writer,
'make_tree_object',
[$tree, $treelist],
moodle_content_writer::class,
);
// This is a big one.
$expectedrichtree = [
+1 -4
View File
@@ -14,15 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
/**
* Coverage information for the question_engine.
*
* @copyright 2022 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
return new class extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of files relative to the plugin root to include in coverage generation. */
protected $includelistfiles = [
'bank.php',
@@ -33,6 +31,5 @@ return new class extends phpunit_coverage_info {
'questionattemptstep.php',
'questionusage.php',
'renderer.php',
];
};
+2 -4
View File
@@ -23,14 +23,12 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once(__DIR__ . '/../lib.php');
require_once($CFG->dirroot . '/lib/phpunit/lib.php');
/**
* Makes some protected methods of question_attempt public to facilitate testing.
*
@@ -612,8 +610,8 @@ abstract class question_testcase extends advanced_testcase {
*/
public function assert_same_xml($expectedxml, $xml) {
$this->assertEquals(
phpunit_util::normalise_line_endings($expectedxml),
phpunit_util::normalise_line_endings($xml)
\core\test\phpunit\phpunit_util::normalise_line_endings($expectedxml),
\core\test\phpunit\phpunit_util::normalise_line_endings($xml)
);
}
}
@@ -48,8 +48,8 @@ final class qformat_aiken_export_test extends advanced_testcase {
*/
public function assert_same_aiken($expectedtext, $text) {
$this->assertEquals(
phpunit_util::normalise_line_endings($expectedtext),
phpunit_util::normalise_line_endings($text)
\core\test\phpunit\phpunit_util::normalise_line_endings($expectedtext),
\core\test\phpunit\phpunit_util::normalise_line_endings($text)
);
}
@@ -16,7 +16,7 @@
namespace qformat_gift;
use phpunit_util;
use core\test\phpunit\phpunit_util;
use qformat_gift;
use question_bank;
use question_check_specified_fields_expectation;
@@ -21,7 +21,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->libdir . '/questionlib.php');
@@ -85,7 +84,7 @@ final class qformat_xml_import_export_test extends advanced_testcase {
*/
protected function normalise_xml($xml) {
// Normalise line endings.
$xml = phpunit_util::normalise_line_endings($xml);
$xml = \core\test\phpunit\phpunit_util::normalise_line_endings($xml);
$xml = preg_replace("~\n$~", "", $xml); // Strip final newline in file.
// Replace all numbers in question id comments with 0.
+1 -3
View File
@@ -14,15 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
/**
* Coverage information for the core_question.
*
* @copyright 2022 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
return new class extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of files relative to the plugin root to include in coverage generation. */
protected $includelistfiles = [
'category_class.php',
@@ -14,15 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
/**
* Coverage information for the qtype_numerical.
*
* @copyright 2022 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
return new class extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of files relative to the plugin root to include in coverage generation. */
protected $includelistfiles = [
'question.php',
@@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
/**
* Coverage information for the qtype_ordering subsystem.
*
@@ -23,7 +21,7 @@ defined('MOODLE_INTERNAL') || die();
* @copyright 2023 Mathew May <mathew.solutions>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
return new class extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of folders relative to the plugin root to include in coverage generation. */
protected $includelistfolders = [
'backup',
@@ -16,8 +16,7 @@
namespace qtype_ordering;
use core_question_generator;
use phpunit_util;
use core\test\phpunit\phpunit_util;
use qtype_ordering;
use qtype_ordering_test_helper;
use qtype_ordering_edit_form;
@@ -23,10 +23,9 @@
*/
namespace repository_nextcloud;
use PHPUnit\Framework\MockObject\MockObject;
use repository;
use repository_nextcloud;
use webdav_client;
use PHPUnit\Framework\MockObject\MockObject;
defined('MOODLE_INTERNAL') || die();
@@ -615,7 +614,7 @@ JSON;
$oauthmock->expects($this->once())->method('get_accesstoken')->will($this->returnValue($fakeaccesstoken));
$this->set_private_property($oauthmock, 'client');
$dav = \phpunit_util::call_internal_method($this->repo, "initiate_webdavclient", [], 'repository_nextcloud');
$dav = \core\test\phpunit\phpunit_util::call_internal_method($this->repo, "initiate_webdavclient", [], 'repository_nextcloud');
// Verify that port is set correctly (private property).
$refclient = new \ReflectionClass($dav);
+1 -1
View File
@@ -20,7 +20,7 @@
* @copyright 2021 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
return new class extends phpunit_coverage_info {
return new class extends \core\test\phpunit\coverage_info {
/** @var array The list of files relative to the plugin root to include in coverage generation. */
protected $includelistfiles = [
'editlib.php',