Search moodle.org's
Developer Documentation


  • Bug fixes for general core bugs in 2.8.x ended 9 November 2015 (12 months).
  • Bug fixes for security issues in 2.8.x ended 9 May 2016 (18 months).
  • minimum PHP 5.4.4 (always use latest PHP 5.4.x or 5.5.x on Windows - http://windows.php.net/download/), PHP 7 is NOT supported
  • Differences Between: [Versions 28 and 29] [Versions 28 and 30] [Versions 28 and 31] [Versions 28 and 32] [Versions 28 and 33] [Versions 28 and 34] [Versions 28 and 35] [Versions 28 and 36] [Versions 28 and 37]

       1  <?php
       2  // This file is part of Moodle - http://moodle.org/
       3  //
       4  // Moodle is free software: you can redistribute it and/or modify
       5  // it under the terms of the GNU General Public License as published by
       6  // the Free Software Foundation, either version 3 of the License, or
       7  // (at your option) any later version.
       8  //
       9  // Moodle is distributed in the hope that it will be useful,
      10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12  // GNU General Public License for more details.
      13  //
      14  // You should have received a copy of the GNU General Public License
      15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
      16  
      17  /**
      18   * Tests finder
      19   *
      20   * @package    core
      21   * @category   test
      22   * @copyright  2012 Petr Skoda {@link http://skodak.org}
      23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      24   */
      25  
      26  /**
      27   * Finds components and plugins with tests
      28   *
      29   * @package    core
      30   * @category   test
      31   * @copyright  2012 Petr Skoda {@link http://skodak.org}
      32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      33   */
      34  class tests_finder {
      35  
      36      /**
      37       * Returns all the components with tests of the specified type
      38       * @param string $testtype The kind of test we are looking for
      39       * @return array
      40       */
      41      public static function get_components_with_tests($testtype) {
      42  
      43          // Get all the components
      44          $components = self::get_all_plugins_with_tests($testtype) + self::get_all_subsystems_with_tests($testtype);
      45  
      46          // Get all the directories having tests
      47          $directories = self::get_all_directories_with_tests($testtype);
      48  
      49          // Find any directory not covered by proper components
      50          $remaining = array_diff($directories, $components);
      51  
      52          // Add them to the list of components
      53          $components += $remaining;
      54  
      55          return $components;
      56      }
      57  
      58      /**
      59       * Returns all the plugins having tests
      60       * @param string $testtype The kind of test we are looking for
      61       * @return array  all the plugins having tests
      62       */
      63      private static function get_all_plugins_with_tests($testtype) {
      64          $pluginswithtests = array();
      65  
      66          $plugintypes = core_component::get_plugin_types();
      67          ksort($plugintypes);
      68          foreach ($plugintypes as $type => $unused) {
      69              $plugs = core_component::get_plugin_list($type);
      70              ksort($plugs);
      71              foreach ($plugs as $plug => $fullplug) {
      72                  // Look for tests recursively
      73                  if (self::directory_has_tests($fullplug, $testtype)) {
      74                      $pluginswithtests[$type . '_' . $plug] = $fullplug;
      75                  }
      76              }
      77          }
      78          return $pluginswithtests;
      79      }
      80  
      81      /**
      82       * Returns all the subsystems having tests
      83       *
      84       * Note we are hacking here the list of subsystems
      85       * to cover some well-known subsystems that are not properly
      86       * returned by the {@link get_core_subsystems()} function.
      87       *
      88       * @param string $testtype The kind of test we are looking for
      89       * @return array all the subsystems having tests
      90       */
      91      private static function get_all_subsystems_with_tests($testtype) {
      92          global $CFG;
      93  
      94          $subsystemswithtests = array();
      95  
      96          $subsystems = core_component::get_core_subsystems();
      97  
      98          // Hack the list a bit to cover some well-known ones
      99          $subsystems['backup'] = $CFG->dirroot.'/backup';
     100          $subsystems['db-dml'] = $CFG->dirroot.'/lib/dml';
     101          $subsystems['db-ddl'] = $CFG->dirroot.'/lib/ddl';
     102  
     103          ksort($subsystems);
     104          foreach ($subsystems as $subsys => $fullsubsys) {
     105              if ($fullsubsys === null) {
     106                  continue;
     107              }
     108              if (!is_dir($fullsubsys)) {
     109                  continue;
     110              }
     111              // Look for tests recursively
     112              if (self::directory_has_tests($fullsubsys, $testtype)) {
     113                  $subsystemswithtests['core_' . $subsys] = $fullsubsys;
     114              }
     115          }
     116          return $subsystemswithtests;
     117      }
     118  
     119      /**
     120       * Returns all the directories having tests
     121       *
     122       * @param string $testtype The kind of test we are looking for
     123       * @return array all directories having tests
     124       */
     125      private static function get_all_directories_with_tests($testtype) {
     126          global $CFG;
     127  
     128          $dirs = array();
     129          $dirite = new RecursiveDirectoryIterator($CFG->dirroot);
     130          $iteite = new RecursiveIteratorIterator($dirite);
     131          $regexp = self::get_regexp($testtype);
     132          $regite = new RegexIterator($iteite, $regexp);
     133          foreach ($regite as $path => $element) {
     134              $key = dirname(dirname($path));
     135              $value = trim(str_replace('/', '_', str_replace($CFG->dirroot, '', $key)), '_');
     136              $dirs[$key] = $value;
     137          }
     138          ksort($dirs);
     139          return array_flip($dirs);
     140      }
     141  
     142      /**
     143       * Returns if a given directory has tests (recursively)
     144       *
     145       * @param string $dir full path to the directory to look for phpunit tests
     146       * @param string $testtype phpunit|behat
     147       * @return bool if a given directory has tests (true) or no (false)
     148       */
     149      private static function directory_has_tests($dir, $testtype) {
     150          if (!is_dir($dir)) {
     151              return false;
     152          }
     153  
     154          $dirite = new RecursiveDirectoryIterator($dir);
     155          $iteite = new RecursiveIteratorIterator($dirite);
     156          $regexp = self::get_regexp($testtype);
     157          $regite = new RegexIterator($iteite, $regexp);
     158          $regite->rewind();
     159          if ($regite->valid()) {
     160              return true;
     161          }
     162          return false;
     163      }
     164  
     165  
     166      /**
     167       * Returns the regular expression to match by the test files
     168       * @param string $testtype
     169       * @return string
     170       */
     171      private static function get_regexp($testtype) {
     172  
     173          $sep = preg_quote(DIRECTORY_SEPARATOR, '|');
     174  
     175          switch ($testtype) {
     176              case 'phpunit':
     177                  $regexp = '|'.$sep.'tests'.$sep.'.*_test\.php$|';
     178                  break;
     179              case 'features':
     180                  $regexp = '|'.$sep.'tests'.$sep.'behat'.$sep.'.*\.feature$|';
     181                  break;
     182              case 'stepsdefinitions':
     183                  $regexp = '|'.$sep.'tests'.$sep.'behat'.$sep.'behat_.*\.php$|';
     184                  break;
     185          }
     186  
     187          return $regexp;
     188      }
     189  }
    

    Search This Site: