110 lines
4.1 KiB
PHP
110 lines
4.1 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright (c) 2025, Антон Аксенов
|
|
* This file is part of m3u.su project
|
|
* MIT License: https://git.axenov.dev/IPTV/web/src/branch/master/LICENSE
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests;
|
|
|
|
use InvalidArgumentException;
|
|
|
|
trait FixtureHandler
|
|
{
|
|
/**
|
|
* Вычитывает содержимое файла строкой
|
|
*
|
|
* @param string $filepath
|
|
* @return string
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function loadFixtureContent(string $filepath): string
|
|
{
|
|
$filepath = static::buildFixtureFilePath($filepath);
|
|
is_file($filepath) || throw new InvalidArgumentException('File not found: ' . $filepath);
|
|
|
|
return (string) file_get_contents($filepath);
|
|
}
|
|
|
|
/**
|
|
* Вычитывает .json файл в php-массив
|
|
*
|
|
* @param string $filepath
|
|
* @param string|null $key
|
|
* @return array
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
protected function loadJsonFixture(string $filepath, ?string $key = null): array
|
|
{
|
|
$contents = $this->loadFixtureContent($filepath);
|
|
$contents = json_decode($contents, true);
|
|
|
|
return $key ? $contents[$key] : $contents;
|
|
}
|
|
|
|
/**
|
|
* Подгружает фиксутуру для тестов
|
|
*
|
|
* @param string $filepath Имя файла или путь до него внутри tests/Fixtures/...
|
|
* @return mixed
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
protected function loadPhpFixture(string $filepath): mixed
|
|
{
|
|
$filepath = static::buildFixtureFilePath($filepath);
|
|
is_file($filepath) || throw new InvalidArgumentException('File not found: ' . $filepath);
|
|
|
|
return require $filepath;
|
|
}
|
|
|
|
/**
|
|
* Сохраняет указанные сырые данные в виде файла с данными
|
|
* для использования в качестве фикстуры в тестах.
|
|
*
|
|
* Использование:
|
|
* 0. предполагается при подготовке к написанию теста
|
|
* 1. вызвать `makeFixture()`, передав нужные данные
|
|
* 2. найти файл в `tests/Fixtures/...`, проверить корректность
|
|
* 3. подгрузить фикстуру и замокать вызов курсорной БД-функции
|
|
* ```
|
|
* $fixture = this->loadFixture(...);
|
|
* $this->mockDbCursor(...)->andReturn($fixture);
|
|
* ```
|
|
*
|
|
* @param array|Collection $data Данные для сохранения в фикстуре
|
|
* @param string $name Имя файла или путь до него внутри tests/Fixtures/...
|
|
* @param bool $is_json Сохранить в json-формате
|
|
*/
|
|
public static function saveFixture(mixed $data, string $name, bool $is_json = false): void
|
|
{
|
|
$data = match (true) {
|
|
$data instanceof Traversable => iterator_to_array($data),
|
|
default => $data,
|
|
};
|
|
if ($is_json) {
|
|
$string = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
|
$ext = 'json';
|
|
} else {
|
|
$string = var_export($data, true);
|
|
$string = preg_replace("/(\n\\s+)?array\\s\\(/", '[', $string); // конвертим в короткий синтаксис
|
|
$string = str_replace([')', 'NULL'], [']', 'null'], $string); // остатки
|
|
$string = "<?php\n\ndeclare(strict_types=1);\n\nreturn {$string};\n"; // добавляем заголовок для файла
|
|
$ext = 'php';
|
|
}
|
|
$filepath = __DIR__ . "/Fixtures/{$name}.{$ext}";
|
|
!file_exists($filepath) && @mkdir(dirname($filepath), recursive: true);
|
|
$filepath = str_replace('/', DIRECTORY_SEPARATOR, $filepath);
|
|
file_put_contents($filepath, $string);
|
|
}
|
|
|
|
protected static function buildFixtureFilePath(string $filepath): string
|
|
{
|
|
$filepath = trim(ltrim($filepath, DIRECTORY_SEPARATOR));
|
|
|
|
return __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . $filepath;
|
|
}
|
|
}
|