You are here

trait TestFileCreationTrait in Drupal 10

Same name and namespace in other branches
  1. 8 core/tests/Drupal/Tests/TestFileCreationTrait.php \Drupal\Tests\TestFileCreationTrait
  2. 9 core/tests/Drupal/Tests/TestFileCreationTrait.php \Drupal\Tests\TestFileCreationTrait

Provides methods to create test files from given values.

This trait is meant to be used only by test classes.

Hierarchy

59 files declare their use of TestFileCreationTrait
AjaxFileManagedMultipleTest.php in core/modules/file/tests/src/FunctionalJavascript/AjaxFileManagedMultipleTest.php
CKEditor5Test.php in core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5Test.php
CommentPreviewTest.php in core/modules/comment/tests/src/Functional/CommentPreviewTest.php
ConfigImportUploadTest.php in core/modules/config/tests/src/Functional/ConfigImportUploadTest.php
ContentEntityFormFieldValidationFilteringTest.php in core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormFieldValidationFilteringTest.php

... See full list

File

core/tests/Drupal/Tests/TestFileCreationTrait.php, line 12

Namespace

Drupal\Tests
View source
trait TestFileCreationTrait {

  /**
   * Whether the files were copied to the test files directory.
   *
   * @var bool
   */
  protected $generatedTestFiles = FALSE;

  /**
   * Gets a list of files that can be used in tests.
   *
   * The first time this method is called, it will call
   * $this->generateFile() to generate binary and ASCII text files in the
   * public:// directory. It will also copy all files in
   * core/tests/fixtures/files to public://. These contain image, SQL, PHP,
   * JavaScript, and HTML files.
   *
   * All filenames are prefixed with their type and have appropriate extensions:
   * - text-*.txt
   * - binary-*.txt
   * - html-*.html and html-*.txt
   * - image-*.png, image-*.jpg, and image-*.gif
   * - javascript-*.txt and javascript-*.script
   * - php-*.txt and php-*.php
   * - sql-*.txt and sql-*.sql
   *
   * Any subsequent calls will not generate any new files, or copy the files
   * over again. However, if a test class adds a new file to public:// that
   * is prefixed with one of the above types, it will get returned as well, even
   * on subsequent calls.
   *
   * @param $type
   *   File type, possible values: 'binary', 'html', 'image', 'javascript',
   *   'php', 'sql', 'text'.
   * @param $size
   *   (optional) File size in bytes to match. Defaults to NULL, which will not
   *   filter the returned list by size.
   *
   * @return array[]
   *   List of files in public:// that match the filter(s).
   */
  protected function getTestFiles($type, $size = NULL) {

    /** @var \Drupal\Core\File\FileSystemInterface $file_system */
    $file_system = \Drupal::service('file_system');
    if (empty($this->generatedTestFiles)) {

      // Generate binary test files.
      $lines = [
        64,
        1024,
      ];
      $count = 0;
      foreach ($lines as $line) {
        $this
          ->generateFile('binary-' . $count++, 64, $line, 'binary');
      }

      // Generate ASCII text test files.
      $lines = [
        16,
        256,
        1024,
        2048,
        20480,
      ];
      $count = 0;
      foreach ($lines as $line) {
        $this
          ->generateFile('text-' . $count++, 64, $line, 'text');
      }

      // Copy other test files from fixtures.
      $original = \Drupal::root() . '/core/tests/fixtures/files';
      $files = $file_system
        ->scanDirectory($original, '/(html|image|javascript|php|sql)-.*/');
      foreach ($files as $file) {
        $file_system
          ->copy($file->uri, PublicStream::basePath());
      }
      $this->generatedTestFiles = TRUE;
    }
    $files = [];

    // Make sure type is valid.
    if (in_array($type, [
      'binary',
      'html',
      'image',
      'javascript',
      'php',
      'sql',
      'text',
    ])) {
      $files = $file_system
        ->scanDirectory('public://', '/' . $type . '\\-.*/');

      // If size is set then remove any files that are not of that size.
      if ($size !== NULL) {
        foreach ($files as $file) {
          $stats = stat($file->uri);
          if ($stats['size'] != $size) {
            unset($files[$file->uri]);
          }
        }
      }
    }
    usort($files, [
      $this,
      'compareFiles',
    ]);
    return $files;
  }

  /**
   * Compares two files based on size and file name.
   *
   * Callback for uasort() within \TestFileCreationTrait::getTestFiles().
   *
   * @param object $file1
   *   The first file.
   * @param object $file2
   *   The second class.
   *
   * @return int
   */
  protected function compareFiles($file1, $file2) {
    $compare_size = filesize($file1->uri) - filesize($file2->uri);
    if ($compare_size) {

      // Sort by file size.
      return $compare_size;
    }
    else {

      // The files were the same size, so sort alphabetically.
      return strnatcmp($file1->name, $file2->name);
    }
  }

  /**
   * Generates a test file.
   *
   * @param string $filename
   *   The name of the file, including the path. The suffix '.txt' is appended
   *   to the supplied file name and the file is put into the public:// files
   *   directory.
   * @param int $width
   *   The number of characters on one line.
   * @param int $lines
   *   The number of lines in the file.
   * @param string $type
   *   (optional) The type, one of:
   *   - text: The generated file contains random ASCII characters.
   *   - binary: The generated file contains random characters whose codes are
   *     in the range of 0 to 31.
   *   - binary-text: The generated file contains random sequence of '0' and '1'
   *     values.
   *
   * @return string
   *   The name of the file, including the path.
   */
  public static function generateFile($filename, $width, $lines, $type = 'binary-text') {
    $text = '';
    for ($i = 0; $i < $lines; $i++) {

      // Generate $width - 1 characters to leave space for the "\n" character.
      for ($j = 0; $j < $width - 1; $j++) {
        switch ($type) {
          case 'text':
            $text .= chr(rand(32, 126));
            break;
          case 'binary':
            $text .= chr(rand(0, 31));
            break;
          case 'binary-text':
          default:
            $text .= rand(0, 1);
            break;
        }
      }
      $text .= "\n";
    }

    // Create filename.
    $filename = 'public://' . $filename . '.txt';
    file_put_contents($filename, $text);
    return $filename;
  }

}

Members