trait TestFileCreationTrait

Same name in other branches
  1. 9 core/tests/Drupal/Tests/TestFileCreationTrait.php \Drupal\Tests\TestFileCreationTrait
  2. 8.9.x core/tests/Drupal/Tests/TestFileCreationTrait.php \Drupal\Tests\TestFileCreationTrait
  3. 10 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

63 files declare their use of TestFileCreationTrait
AccessTest.php in core/modules/file/tests/src/Kernel/AccessTest.php
AjaxFileManagedMultipleTest.php in core/modules/file/tests/src/FunctionalJavascript/AjaxFileManagedMultipleTest.php
AjaxMaintenanceModeTest.php in core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxMaintenanceModeTest.php
ArchiverTestBase.php in core/tests/Drupal/KernelTests/Core/Archiver/ArchiverTestBase.php
CKEditor5FragmentLinkTest.php in core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5FragmentLinkTest.php

... See full list

File

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

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 object[]
     *   List of files in public:// that match the filter(s). Each file is an
     *   object with 'uri', 'filename', and 'name' properties.
     */
    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.
     */
    protected 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

Title Sort descending Modifiers Object type Summary
TestFileCreationTrait::$generatedTestFiles protected property Whether the files were copied to the test files directory.
TestFileCreationTrait::compareFiles protected function Compares two files based on size and file name.
TestFileCreationTrait::generateFile protected static function Generates a test file.
TestFileCreationTrait::getTestFiles protected function Gets a list of files that can be used in tests.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.