code coverage report for the page run.'); } else { global $db_prefix; $db_prefix_testing = $db_prefix; $db_prefix = preg_replace('/s\d+$/m', '', $db_prefix); // Use the current test_id as the coverage set ID. $coverage_set = db_select('simpletest_test_id', 's') ->fields('s', 'test_id') ->orderBy('test_id', 'DESC') ->range(0, 1) ->execute() ->fetchField(); $db_prefix = $db_prefix_testing; } // Start Xdebug code coverage and register shutdown function to collect the // results and place them in the log table. xdebug_start_code_coverage(); drupal_register_shutdown_function('code_coverage_record', $coverage_set, !empty($_GET['code_coverage'])); } /** * Record code coverage results in log table. * * @param $coverage_set * Coverage set ID. * @param $process * If TRUE then process the log immediately, otherwise no not process. */ function code_coverage_record($coverage_set, $process) { global $db_prefix; $db_prefix_testing = $db_prefix; $db_prefix = preg_replace('/s\d+$/m', '', $db_prefix); $info = drupal_parse_info_file(DRUPAL_ROOT . '/' . drupal_get_path('module', 'code_coverage') . '/code_coverage.info'); // Cycle through the code coverage for each file. $coverage = xdebug_get_code_coverage(); foreach ($coverage as $file => $lines) { // Use the relative file path and ensure that the file is not part of the // code_coverage module. $relative = str_replace(DRUPAL_ROOT . '/', '', $file); // TODO Deal with symbolic links. $base = basename($relative); if (!in_array($base, $info['files']) && code_coverage_record_check($relative)) { // Determine the file_id if it has already been created. $file_id = db_select('code_coverage_file', 'f') ->fields('f', array('file_id')) ->condition('coverage_set', $coverage_set) ->condition('path', $relative) ->execute() ->fetchField(); // Create a file record if not already done. if (!$file_id) { $file = array( 'coverage_set' => $coverage_set, 'path' => $relative, ); drupal_write_record('code_coverage_file', $file); $file_id = $file['file_id']; } // Insert all line information into log table. $insert = db_insert('code_coverage_log')->fields(array('file_id', 'line')); foreach ($lines as $line => $count) { // Ignore line 0. if ($line) { $insert->values(array( 'file_id' => $file_id, 'line' => $line, )); } } $insert->execute(); } } // Process log immediately. if ($process) { module_load_include('process.inc', 'code_coverage'); code_coverage_process($coverage_set); } $db_prefix = $db_prefix_testing; } /** * Ensure that the path passes any filters if set. * * @param $path * Relative file path. * @return * TRUE if path passes, otherwise FALSE. */ function code_coverage_record_check($path) { static $variables; // Manually load variables from database to ensure the variables are loaded // from the current prefix and not cached. if (!isset($variables)) { $variables = db_query('SELECT name, value FROM {variable}')->fetchAllKeyed(); $variables = array( 'code_coverage_modules' => unserialize($variables['code_coverage_filter_modules']), 'code_coverage_files' => unserialize($variables['code_coverage_filter_files']), ); } // If a module filter is then then approve any paths within the module. if (!empty($variables['code_coverage_modules'])) { foreach ($variables['code_coverage_modules'] as $module) { if (strpos($path, $module) !== FALSE) { return TRUE; } } } // If a file filter is set then approve any paths found in the list. if (!empty($variables['code_coverage_files'])) { if (in_array($path, $variables['code_coverage_files'])) { return TRUE; } } // If neither filter is set the approve the path, otherwise the path did not // pass any of the set filters and should fail. return empty($variables['code_coverage_modules']) && empty($variables['code_coverage_files']); }