annotate core/tests/Drupal/Tests/TestFileCreationTrait.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests;
Chris@0 4
Chris@0 5 use Drupal\Core\StreamWrapper\PublicStream;
Chris@0 6
Chris@0 7 /**
Chris@0 8 * Provides methods to create test files from given values.
Chris@0 9 *
Chris@0 10 * This trait is meant to be used only by test classes.
Chris@0 11 */
Chris@0 12 trait TestFileCreationTrait {
Chris@0 13
Chris@0 14 /**
Chris@0 15 * Whether the files were copied to the test files directory.
Chris@0 16 *
Chris@0 17 * @var bool
Chris@0 18 */
Chris@0 19 protected $generatedTestFiles = FALSE;
Chris@0 20
Chris@0 21 /**
Chris@0 22 * Gets a list of files that can be used in tests.
Chris@0 23 *
Chris@0 24 * The first time this method is called, it will call
Chris@0 25 * $this->generateFile() to generate binary and ASCII text files in the
Chris@0 26 * public:// directory. It will also copy all files in
Chris@0 27 * core/modules/simpletest/files to public://. These contain image, SQL, PHP,
Chris@0 28 * JavaScript, and HTML files.
Chris@0 29 *
Chris@0 30 * All filenames are prefixed with their type and have appropriate extensions:
Chris@0 31 * - text-*.txt
Chris@0 32 * - binary-*.txt
Chris@0 33 * - html-*.html and html-*.txt
Chris@0 34 * - image-*.png, image-*.jpg, and image-*.gif
Chris@0 35 * - javascript-*.txt and javascript-*.script
Chris@0 36 * - php-*.txt and php-*.php
Chris@0 37 * - sql-*.txt and sql-*.sql
Chris@0 38 *
Chris@0 39 * Any subsequent calls will not generate any new files, or copy the files
Chris@0 40 * over again. However, if a test class adds a new file to public:// that
Chris@0 41 * is prefixed with one of the above types, it will get returned as well, even
Chris@0 42 * on subsequent calls.
Chris@0 43 *
Chris@0 44 * @param $type
Chris@0 45 * File type, possible values: 'binary', 'html', 'image', 'javascript',
Chris@0 46 * 'php', 'sql', 'text'.
Chris@0 47 * @param $size
Chris@0 48 * (optional) File size in bytes to match. Defaults to NULL, which will not
Chris@0 49 * filter the returned list by size.
Chris@0 50 *
Chris@0 51 * @return array[]
Chris@0 52 * List of files in public:// that match the filter(s).
Chris@0 53 */
Chris@0 54 protected function getTestFiles($type, $size = NULL) {
Chris@0 55 if (empty($this->generatedTestFiles)) {
Chris@0 56 // Generate binary test files.
Chris@0 57 $lines = [64, 1024];
Chris@0 58 $count = 0;
Chris@0 59 foreach ($lines as $line) {
Chris@0 60 $this->generateFile('binary-' . $count++, 64, $line, 'binary');
Chris@0 61 }
Chris@0 62
Chris@0 63 // Generate ASCII text test files.
Chris@0 64 $lines = [16, 256, 1024, 2048, 20480];
Chris@0 65 $count = 0;
Chris@0 66 foreach ($lines as $line) {
Chris@0 67 $this->generateFile('text-' . $count++, 64, $line, 'text');
Chris@0 68 }
Chris@0 69
Chris@0 70 // Copy other test files from simpletest.
Chris@0 71 $original = drupal_get_path('module', 'simpletest') . '/files';
Chris@0 72 $files = file_scan_directory($original, '/(html|image|javascript|php|sql)-.*/');
Chris@0 73 foreach ($files as $file) {
Chris@18 74 \Drupal::service('file_system')->copy($file->uri, PublicStream::basePath());
Chris@0 75 }
Chris@0 76
Chris@0 77 $this->generatedTestFiles = TRUE;
Chris@0 78 }
Chris@0 79
Chris@0 80 $files = [];
Chris@0 81 // Make sure type is valid.
Chris@0 82 if (in_array($type, ['binary', 'html', 'image', 'javascript', 'php', 'sql', 'text'])) {
Chris@0 83 $files = file_scan_directory('public://', '/' . $type . '\-.*/');
Chris@0 84
Chris@0 85 // If size is set then remove any files that are not of that size.
Chris@0 86 if ($size !== NULL) {
Chris@0 87 foreach ($files as $file) {
Chris@0 88 $stats = stat($file->uri);
Chris@0 89 if ($stats['size'] != $size) {
Chris@0 90 unset($files[$file->uri]);
Chris@0 91 }
Chris@0 92 }
Chris@0 93 }
Chris@0 94 }
Chris@0 95 usort($files, [$this, 'compareFiles']);
Chris@0 96 return $files;
Chris@0 97 }
Chris@0 98
Chris@0 99 /**
Chris@0 100 * Compares two files based on size and file name.
Chris@0 101 *
Chris@0 102 * Callback for uasort() within \TestFileCreationTrait::getTestFiles().
Chris@0 103 *
Chris@0 104 * @param \stdClass $file1
Chris@0 105 * The first file.
Chris@0 106 * @param \stdClass $file2
Chris@0 107 * The second class.
Chris@0 108 *
Chris@0 109 * @return int
Chris@0 110 */
Chris@0 111 protected function compareFiles($file1, $file2) {
Chris@0 112 $compare_size = filesize($file1->uri) - filesize($file2->uri);
Chris@0 113 if ($compare_size) {
Chris@0 114 // Sort by file size.
Chris@0 115 return $compare_size;
Chris@0 116 }
Chris@0 117 else {
Chris@0 118 // The files were the same size, so sort alphabetically.
Chris@0 119 return strnatcmp($file1->name, $file2->name);
Chris@0 120 }
Chris@0 121 }
Chris@0 122
Chris@0 123 /**
Chris@0 124 * Generates a test file.
Chris@0 125 *
Chris@0 126 * @param string $filename
Chris@0 127 * The name of the file, including the path. The suffix '.txt' is appended
Chris@0 128 * to the supplied file name and the file is put into the public:// files
Chris@0 129 * directory.
Chris@0 130 * @param int $width
Chris@0 131 * The number of characters on one line.
Chris@0 132 * @param int $lines
Chris@0 133 * The number of lines in the file.
Chris@0 134 * @param string $type
Chris@0 135 * (optional) The type, one of:
Chris@0 136 * - text: The generated file contains random ASCII characters.
Chris@0 137 * - binary: The generated file contains random characters whose codes are
Chris@0 138 * in the range of 0 to 31.
Chris@0 139 * - binary-text: The generated file contains random sequence of '0' and '1'
Chris@0 140 * values.
Chris@0 141 *
Chris@0 142 * @return string
Chris@0 143 * The name of the file, including the path.
Chris@0 144 */
Chris@0 145 public static function generateFile($filename, $width, $lines, $type = 'binary-text') {
Chris@0 146 $text = '';
Chris@0 147 for ($i = 0; $i < $lines; $i++) {
Chris@0 148 // Generate $width - 1 characters to leave space for the "\n" character.
Chris@0 149 for ($j = 0; $j < $width - 1; $j++) {
Chris@0 150 switch ($type) {
Chris@0 151 case 'text':
Chris@0 152 $text .= chr(rand(32, 126));
Chris@0 153 break;
Chris@0 154 case 'binary':
Chris@0 155 $text .= chr(rand(0, 31));
Chris@0 156 break;
Chris@0 157 case 'binary-text':
Chris@0 158 default:
Chris@0 159 $text .= rand(0, 1);
Chris@0 160 break;
Chris@0 161 }
Chris@0 162 }
Chris@0 163 $text .= "\n";
Chris@0 164 }
Chris@0 165
Chris@0 166 // Create filename.
Chris@12 167 $filename = 'public://' . $filename . '.txt';
Chris@12 168 file_put_contents($filename, $text);
Chris@0 169 return $filename;
Chris@0 170 }
Chris@0 171
Chris@0 172 }