mirror of
https://git.yoomoney.ru/scm/sdk/yookassa-sdk-php.git
synced 2026-08-17 09:33:34 +00:00
2db9951ff6
Информация про чеки самозанятых в платежах и возвратах удалена - больше не поддерживаем сервисы для самозанятых Добавлена возможность выставления счета по смс и email Добавлена поддержка работы со списками выплат Обновлен Copyright
625 lines
24 KiB
PHP
625 lines
24 KiB
PHP
<?php
|
||
|
||
/*
|
||
* The MIT License
|
||
*
|
||
* Copyright (c) 2026 "YooMoney", NBСO LLC
|
||
*
|
||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
* of this software and associated documentation files (the "Software"), to deal
|
||
* in the Software without restriction, including without limitation the rights
|
||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
* copies of the Software, and to permit persons to whom the Software is
|
||
* furnished to do so, subject to the following conditions:
|
||
*
|
||
* The above copyright notice and this permission notice shall be included in
|
||
* all copies or substantial portions of the Software.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
* THE SOFTWARE.
|
||
*/
|
||
|
||
namespace Tests\YooKassa;
|
||
|
||
use Exception;
|
||
use Faker\Factory;
|
||
use Faker\Generator;
|
||
use InvalidArgumentException;
|
||
use PHPUnit\Framework\TestCase;
|
||
use ReflectionClass;
|
||
use ReflectionMethod;
|
||
use ReflectionNamedType;
|
||
use stdClass;
|
||
use TypeError;
|
||
use YooKassa\Common\AbstractEnum;
|
||
use YooKassa\Common\AbstractObject;
|
||
use YooKassa\Common\ListObject;
|
||
use YooKassa\Helpers\Random;
|
||
use YooKassa\Model\Metadata;
|
||
use YooKassa\Validator\Constraints\AllType;
|
||
use YooKassa\Validator\Constraints\Choice;
|
||
use YooKassa\Validator\Constraints\Count;
|
||
use YooKassa\Validator\Constraints\Date;
|
||
use YooKassa\Validator\Constraints\DateTime as DateTimeValidation;
|
||
use YooKassa\Validator\Constraints\Email;
|
||
use YooKassa\Validator\Constraints\GreaterThan;
|
||
use YooKassa\Validator\Constraints\GreaterThanOrEqual;
|
||
use YooKassa\Validator\Constraints\Ip;
|
||
use YooKassa\Validator\Constraints\Length;
|
||
use YooKassa\Validator\Constraints\LessThan;
|
||
use YooKassa\Validator\Constraints\LessThanOrEqual;
|
||
use YooKassa\Validator\Constraints\NotBlank;
|
||
use YooKassa\Validator\Constraints\NotNull;
|
||
use YooKassa\Validator\Constraints\Regex;
|
||
use YooKassa\Validator\Constraints\Type;
|
||
use YooKassa\Validator\Constraints\Url;
|
||
use YooKassa\Validator\Exceptions\EmptyPropertyValueException;
|
||
use YooKassa\Validator\Exceptions\InvalidPropertyValueException;
|
||
use YooKassa\Validator\Exceptions\InvalidPropertyValueTypeException;
|
||
use YooKassa\Validator\Exceptions\ValidatorParameterException;
|
||
use YooKassa\Validator\Validator;
|
||
use DateTime;
|
||
|
||
/**
|
||
* AbstractTestCase
|
||
*
|
||
* PHP version 8.0
|
||
*
|
||
* @category ClassTest
|
||
* @description Абстрактный класс по генерации валидных и невалидных данных для тестов.
|
||
* @author cms@yoomoney.ru
|
||
* @link https://yookassa.ru/developers/api
|
||
*/
|
||
class AbstractTestCase extends TestCase
|
||
{
|
||
/**
|
||
* Возвращает валидный заполненный экземпляр класса на основе класса
|
||
*
|
||
* @param AbstractObject $class
|
||
* @param bool $isArray
|
||
*
|
||
* @return array
|
||
* @throws \ReflectionException
|
||
*/
|
||
public function getValidDataProviderByClass(AbstractObject $class, bool $isArray = false): array
|
||
{
|
||
return [$this->prepareArrayForObject($class, $isArray)];
|
||
}
|
||
|
||
/**
|
||
* Возвращает валидные данные на основе правил свойства
|
||
*
|
||
* @param array|null $propRules
|
||
*
|
||
* @return array
|
||
* @throws \ReflectionException
|
||
*/
|
||
public function getValidDataProviderByType(?array $propRules): array
|
||
{
|
||
if (empty($propRules)) {
|
||
return [];
|
||
}
|
||
|
||
$arrayProps = $this->parsePropRules($propRules);
|
||
if (empty($arrayProps) || !isset($arrayProps['type'])) {
|
||
return [];
|
||
}
|
||
|
||
$result = [];
|
||
if (!$arrayProps['isRequired']) {
|
||
$result = [
|
||
[null]
|
||
];
|
||
|
||
if ($arrayProps['type'] !== 'float' && $arrayProps['type'] !== 'int') {
|
||
$result[] = [''];
|
||
}
|
||
}
|
||
|
||
if (isset($arrayProps['regex'])) {
|
||
$max = Random::int(1, 10);
|
||
for ($i = 0; $i < $max; $i++) {
|
||
$result[] = [$this->prepareDataByRegex($arrayProps['regex'], $arrayProps['max'] ?? null, isset($arrayProps['min']) ?? null)];
|
||
}
|
||
return $result;
|
||
}
|
||
return array_merge($result, $this->prepareDataByType($arrayProps));
|
||
}
|
||
|
||
/**
|
||
* Возвращает невалидные данные на основе правил свойства
|
||
*
|
||
* @param array|null $propRules
|
||
*
|
||
* @return array
|
||
*/
|
||
public function getInvalidDataProviderByType(?array $propRules): array
|
||
{
|
||
if (empty($propRules)) {
|
||
return [];
|
||
}
|
||
|
||
$arrayProps = $this->parsePropRules($propRules);
|
||
if (empty($arrayProps)) {
|
||
return [];
|
||
}
|
||
$result = [];
|
||
|
||
if (isset($arrayProps['isRequired']) && $arrayProps['isRequired']) {
|
||
$result = [
|
||
[null, EmptyPropertyValueException::class]
|
||
];
|
||
|
||
if ($arrayProps['type'] === 'float'
|
||
|| $arrayProps['type'] === 'int'
|
||
|| $arrayProps['type'] === 'numeric'
|
||
) {
|
||
$result[] = ['', TypeError::class];
|
||
} else {
|
||
$result[] = ['', EmptyPropertyValueException::class];
|
||
}
|
||
}
|
||
|
||
if (!isset($arrayProps['type'])) {
|
||
return $result;
|
||
}
|
||
|
||
if ($arrayProps['type'] === Metadata::class) {
|
||
if (isset($arrayProps['all_type']) && $arrayProps['all_type'] === 'string') {
|
||
$arrayMetadata = [
|
||
[[Random::int()], InvalidPropertyValueTypeException::class],
|
||
[[new stdClass()], InvalidPropertyValueTypeException::class],
|
||
[true, ValidatorParameterException::class],
|
||
];
|
||
return array_merge($result, $arrayMetadata);
|
||
}
|
||
$arrayMetadata = [
|
||
[Random::int(), InvalidPropertyValueTypeException::class],
|
||
[new stdClass(), InvalidPropertyValueTypeException::class],
|
||
[true, InvalidPropertyValueTypeException::class],
|
||
];
|
||
return array_merge($result, $arrayMetadata);
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'DateTime') {
|
||
$arrayDateTime = [
|
||
[Random::str(100), InvalidPropertyValueException::class],
|
||
[Random::int(), InvalidPropertyValueException::class],
|
||
];
|
||
return array_merge($result, $arrayDateTime);
|
||
}
|
||
|
||
/**
|
||
* object
|
||
*/
|
||
if (class_exists($arrayProps['type']) && $arrayProps['type'] !== ListObject::class) {
|
||
$arrayObject = [
|
||
[new stdClass(), InvalidPropertyValueTypeException::class],
|
||
[new DateTime(), InvalidPropertyValueTypeException::class],
|
||
];
|
||
return array_merge($result, $arrayObject);
|
||
}
|
||
|
||
/**
|
||
* ListObject
|
||
*/
|
||
if (($arrayProps['type'] === ListObject::class) && isset($arrayProps['all_type'])) {
|
||
return [
|
||
[new stdClass(), ValidatorParameterException::class],
|
||
[[new stdClass()], InvalidArgumentException::class],
|
||
];
|
||
}
|
||
|
||
/**
|
||
* choices
|
||
*/
|
||
if ($arrayProps['type'] === 'string' && isset($arrayProps['choices'])) {
|
||
return [
|
||
[[], TypeError::class],
|
||
[fopen(__FILE__, 'rb'), TypeError::class],
|
||
[true, InvalidPropertyValueException::class],
|
||
[Random::str(10), InvalidPropertyValueException::class],
|
||
];
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'bool') {
|
||
return [
|
||
[['string'], TypeError::class],
|
||
];
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'string') {
|
||
$arrayString = [
|
||
[[], TypeError::class],
|
||
[new stdClass(), TypeError::class],
|
||
];
|
||
if (isset($arrayProps['max'])) {
|
||
$result[] = [Random::str($arrayProps['max'] + 1), InvalidPropertyValueException::class];
|
||
}
|
||
if (isset($arrayProps['min']) && $arrayProps['min'] > 1) {
|
||
$result[] = [Random::str($arrayProps['min'] - 1), InvalidPropertyValueException::class];
|
||
}
|
||
return array_merge($result, $arrayString);
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'float' || $arrayProps['type'] === 'int' || $arrayProps['type'] === 'numeric') {
|
||
$arrayFloat = [
|
||
[[], TypeError::class],
|
||
[new stdClass(), TypeError::class],
|
||
];
|
||
if (isset($arrayProps['max'])) {
|
||
$result[] = [Random::int($arrayProps['max'], $arrayProps['max'] + 1), InvalidPropertyValueException::class];
|
||
}
|
||
if (isset($arrayProps['min']) && $arrayProps['min'] > 1) {
|
||
$result[] = [Random::int($arrayProps['min'] - 1, $arrayProps['min']), InvalidPropertyValueException::class];
|
||
}
|
||
if (isset($arrayProps['greaterThan'])) {
|
||
$result[] = [$arrayProps['greaterThan'] - 1, InvalidPropertyValueException::class];
|
||
}
|
||
if (isset($arrayProps['lessThan'])) {
|
||
$result[] = [$arrayProps['lessThan'] + 1, InvalidPropertyValueException::class];
|
||
}
|
||
return array_merge($result, $arrayFloat);
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'array') {
|
||
$array = [
|
||
[[new stdClass()], InvalidPropertyValueTypeException::class],
|
||
];
|
||
return array_merge($result, $array);
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Парсит массив правил свойства
|
||
*
|
||
* @param array $propRules
|
||
*
|
||
* @return array
|
||
*/
|
||
private function parsePropRules(array $propRules): array
|
||
{
|
||
$arrayProps = [
|
||
'isRequired' => false
|
||
];
|
||
foreach ($propRules as $rule) {
|
||
switch (true) {
|
||
case $rule instanceof Length:
|
||
$arrayProps['max'] = (int)$rule->getMax() ?: $arrayProps['max'] ?? null;
|
||
$arrayProps['min'] = (int)$rule->getMin() ?: $arrayProps['min'] ?? null;
|
||
break;
|
||
case $rule instanceof NotBlank:
|
||
case $rule instanceof NotNull:
|
||
$arrayProps['isRequired'] = true;
|
||
break;
|
||
case $rule instanceof Choice:
|
||
$arrayProps['choices'] = $rule->getCallback() ?: $rule->getChoices();
|
||
break;
|
||
case $rule instanceof GreaterThanOrEqual:
|
||
$arrayProps['greaterThanOrEqual'] = $rule->getValue();
|
||
break;
|
||
case $rule instanceof GreaterThan:
|
||
$arrayProps['greaterThan'] = $rule->getValue();
|
||
break;
|
||
case $rule instanceof LessThanOrEqual:
|
||
$arrayProps['lessThanOrEqual'] = $rule->getValue();
|
||
break;
|
||
case $rule instanceof LessThan:
|
||
$arrayProps['lessThan'] = $rule->getValue();
|
||
break;
|
||
case $rule instanceof Regex:
|
||
$arrayProps['regex'] = str_replace('/', '', $rule->getPattern());
|
||
break;
|
||
case $rule instanceof Type:
|
||
$arrayProps['type'] = $rule->getType();
|
||
break;
|
||
case $rule instanceof AllType:
|
||
$arrayProps['all_type'] = $rule->getType();
|
||
break;
|
||
case $rule instanceof DateTimeValidation:
|
||
$arrayProps['datetime_format'] = $rule->getFormat();
|
||
break;
|
||
case $rule instanceof Count:
|
||
$arrayProps['count_max'] = (int)$rule->getMax() ?: $arrayProps['count_max'] ?? null;
|
||
$arrayProps['count_min'] = (int)$rule->getMin() ?: $arrayProps['count_min'] ?? null;
|
||
break;
|
||
case $rule instanceof Url:
|
||
$arrayProps['url'] = $rule->getProtocols();
|
||
break;
|
||
case $rule instanceof Date:
|
||
$arrayProps['data'] = true;
|
||
break;
|
||
case $rule instanceof Email:
|
||
$arrayProps['email'] = $rule->getMode();
|
||
break;
|
||
case $rule instanceof Ip:
|
||
$arrayProps['ip'] = $rule->getVersion();
|
||
break;
|
||
}
|
||
}
|
||
|
||
return $arrayProps;
|
||
}
|
||
|
||
/**
|
||
* Подготавливает валидные данные на основе правил свойства
|
||
*
|
||
* @param array $arrayProps
|
||
*
|
||
* @return array
|
||
* @throws \ReflectionException
|
||
*/
|
||
private function prepareDataByType(array $arrayProps): array
|
||
{
|
||
if (!isset($arrayProps['type'])) {
|
||
return [];
|
||
}
|
||
|
||
$result = [];
|
||
|
||
/** Генерирует массив объектов */
|
||
if (isset($arrayProps['all_type']) && class_exists($arrayProps['all_type'])) {
|
||
return $this->generateArrayOfObject($arrayProps);
|
||
}
|
||
|
||
/** Генерирует массив массивов */
|
||
if (class_exists($arrayProps['type']) && $arrayProps['type'] !== 'DateTime' && $arrayProps['type'] !== Metadata::class) {
|
||
return $this->generateArrayOfArray($arrayProps);
|
||
}
|
||
|
||
$max = Random::int(1, 10);
|
||
for ($i = 0; $i < $max; $i++) {
|
||
$result[] = [$this->generateRandom($arrayProps)];
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Подготавливает валидные данные на основе регулярного выражения
|
||
*
|
||
* @param string $regex
|
||
* @param int|null $max
|
||
* @param int|null $min
|
||
* @return string|null
|
||
*/
|
||
private function prepareDataByRegex(string $regex, ?int $max = null, ?int $min = null): ?string
|
||
{
|
||
$regex = preg_replace('/^\/?\^?/', '', $regex);
|
||
$regex = preg_replace('/([\^\$])|[^ \]\{\}\)]+$/', '', $regex);
|
||
if (($min || $max) && !preg_match('/{((.*?))}/', $regex)) {
|
||
$length = '{' . ($min !== null ? $min : '') . ',' . ($max !== null ? $max : '') . '}';
|
||
$regex .= $length;
|
||
}
|
||
|
||
return Factory::create()->regexify($regex);
|
||
}
|
||
|
||
/**
|
||
* Подготавливает массив данных для объекта на основе рефлексии класса
|
||
*
|
||
* @param string|object $class Класс, данные для которых необходимо подготовить
|
||
* @param bool $isArray Флаг создания данных в виде объекта или массива
|
||
*
|
||
* @return array
|
||
* @throws Exception
|
||
* @throws \ReflectionException
|
||
*/
|
||
private function prepareArrayForObject(mixed $class, bool $isArray = true): array
|
||
{
|
||
$value = [];
|
||
$object = new $class;
|
||
$validator = new Validator($object);
|
||
$properties = (new ReflectionClass($object))->getProperties();
|
||
foreach ($properties as $property) {
|
||
$arrayProps = $this->parsePropRules($validator->getRulesByPropName($property->getName()));
|
||
if (!isset($arrayProps['type'])) {
|
||
return [];
|
||
}
|
||
$propertyName = substr($property->getName(), 1);
|
||
|
||
/** Проверяем, является ли параметр массивом объектов */
|
||
$class = $arrayProps['all_type'] ?? $arrayProps['type'];
|
||
|
||
/** Проверяем, установлено ли дефолтное значение в свойстве, если да, то устанавливаем и выходим */
|
||
if (!empty($object->{$property->getName()}) && !class_exists($class) && ($class === 'string' || (int)$object->{$property->getName()} !== 0 )) {
|
||
$value[$propertyName] = $object->{$property->getName()};
|
||
continue;
|
||
}
|
||
|
||
/** Проверяем, является ли значение $class абстрактным классом, если да, то генерируем модель через фабрику, заполняем её данными и выходим */
|
||
if (class_exists($class)) {
|
||
$reflectionProperty = new ReflectionClass($class);
|
||
if ($reflectionProperty->isAbstract()) {
|
||
$class = $this->generateClassByFactory($reflectionProperty);
|
||
$value[$propertyName] = $this->prepareArrayForObject($class);
|
||
continue;
|
||
}
|
||
}
|
||
|
||
/** Проверяем, является ли параметр массивом объектов, если да, то генерируем массив массивов\объектов и выходим */
|
||
if (isset($arrayProps['all_type']) && $arrayProps['all_type'] !== 'string') {
|
||
$value[$propertyName] = $isArray ? [$this->prepareArrayForObject($class, $isArray)] : [new $class($this->prepareArrayForObject($class, $isArray))];
|
||
continue;
|
||
}
|
||
|
||
/** Проверяем, является ли значение $class классом\DateTime\Metadata, если нет\да, то устанавливаем рандомные значения для свойства и выходим */
|
||
if ($class === 'DateTime' || $class === Metadata::class || !class_exists($class)) {
|
||
$value[$propertyName] = isset($arrayProps['regex']) ? $this->prepareDataByRegex($arrayProps['regex'], $arrayProps['max'] ?? null, isset($arrayProps['min']) ?? null) : $this->generateRandom($arrayProps);
|
||
continue;
|
||
}
|
||
|
||
/** Проверяем, является ли значение $class enum, если да, то выбираем рандомно значение и выходим */
|
||
if (new $class instanceof AbstractEnum) {
|
||
/** @var AbstractEnum $class */
|
||
$value[$propertyName] = Random::value($class::getValidValues());
|
||
continue;
|
||
}
|
||
|
||
/** Проверяем, является ли значение $class классом, если да, то генерируем значения в виде массивов или объектов и выходим */
|
||
if (new $class instanceof AbstractObject) {
|
||
$value[$propertyName] = $this->prepareArrayForObject($class);
|
||
}
|
||
}
|
||
|
||
return $value;
|
||
}
|
||
|
||
/**
|
||
* Генерирует рандомные данные на основе типа свойства
|
||
*
|
||
* @param array $arrayProps
|
||
*
|
||
* @return mixed
|
||
*/
|
||
private function generateRandom(array $arrayProps): mixed
|
||
{
|
||
if (!isset($arrayProps['type'])) {
|
||
return null;
|
||
}
|
||
|
||
$faker = Factory::create();
|
||
|
||
if ($arrayProps['type'] === 'string' && isset($arrayProps['choices'])) {
|
||
if (class_exists($arrayProps['choices'][0])) {
|
||
/** @var AbstractEnum $enumClass */
|
||
$enumClass = new $arrayProps['choices'][0]();
|
||
return $faker->randomElement($enumClass::getValidValues());
|
||
}
|
||
|
||
if (is_array($arrayProps['choices'])) {
|
||
return $faker->randomElement($arrayProps['choices']);
|
||
}
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'string') {
|
||
if (isset($arrayProps['url'])) {
|
||
$max = isset($arrayProps['max']) ? $arrayProps['max'] - 11 : 10;
|
||
$min = $arrayProps['min'] ?? 5;
|
||
|
||
return 'https://' . Random::str($min, $max, 'abcdefghilkmnopqrstuvwxyz') . '.ru';
|
||
}
|
||
|
||
if (isset($arrayProps['email'])) {
|
||
return $faker->email();
|
||
}
|
||
|
||
if (isset($arrayProps['ip'])) {
|
||
return $arrayProps['ip'] === Ip::V6 ? $faker->ipv6() : $faker->ipv4();
|
||
}
|
||
|
||
return Random::str($arrayProps['min'] ?? 1, $arrayProps['max'] ?? 100);
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'float' || $arrayProps['type'] === 'numeric') {
|
||
$floatResult = $faker->randomFloat(null, $arrayProps['min'] ?? $arrayProps['greaterThanOrEqual'] ?? 1, $arrayProps['max'] ?? $arrayProps['lessThanOrEqual'] ?? 1000);
|
||
return (int) round($floatResult * 100.0);
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'int') {
|
||
return $faker->numberBetween($arrayProps['min'] ?? $arrayProps['greaterThanOrEqual'] ?? 1, $arrayProps['max'] ?? $arrayProps['lessThanOrEqual'] ?? 1000);
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'bool') {
|
||
return $faker->boolean();
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'DateTime') {
|
||
$format = (isset($arrayProps['data']) && $arrayProps['data'])
|
||
? 'Y-m-d'
|
||
: $arrayProps['datetime_format'] ?? YOOKASSA_DATE;
|
||
return $faker->boolean() ? $faker->time($format) : $faker->date($format);
|
||
}
|
||
|
||
if ($arrayProps['type'] === 'array' || $arrayProps['type'] === Metadata::class) {
|
||
$arrayData = [];
|
||
$max = $faker->numberBetween(1, 10);
|
||
for ($i = 0; $i < $max; $i++) {
|
||
$arrayData[Random::str(1, 10)] = Random::str(5, 10);
|
||
}
|
||
return $arrayData;
|
||
}
|
||
|
||
if (class_exists($arrayProps['type'])) {
|
||
return new $arrayProps['type'];
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* Генерирует экземпляр класса на основе фабрики, беря рандомные данные из фабрики
|
||
*
|
||
* @param ReflectionClass $reflection
|
||
*
|
||
* @return mixed
|
||
* @throws \ReflectionException
|
||
*/
|
||
private function generateClassByFactory(ReflectionClass $reflection): mixed
|
||
{
|
||
$fileName = substr($reflection->getShortName(), 8);
|
||
$factoryName = $reflection->getNamespaceName() . '\\' . $fileName . 'Factory';
|
||
$factoryClass = new $factoryName();
|
||
$reflectionFactoryClass = new ReflectionClass($factoryClass);
|
||
$typeClassMap = $reflectionFactoryClass->getProperty('typeClassMap')->getDefaultValue();
|
||
|
||
$typeValue = Random::value(array_keys($typeClassMap));
|
||
return (new $factoryName)->factory($typeValue);
|
||
}
|
||
|
||
/**
|
||
* Генерирует массив объектов
|
||
*
|
||
* @param array $arrayProps
|
||
*
|
||
* @return array
|
||
* @throws \ReflectionException
|
||
*/
|
||
private function generateArrayOfObject(array $arrayProps): array
|
||
{
|
||
$result = [];
|
||
$value = [];
|
||
$max = Random::int(1, 10);
|
||
$reflection = new ReflectionClass($arrayProps['all_type']);
|
||
for ($y = 0; $y < $max; $y++) {
|
||
/** Проверяем, есть ли требование по минимальному и максимальному количеству объектов в коллекции, если да, берем эти значения, если нет, берем рандомно */
|
||
$countMax = Random::int($arrayProps['count_min'] ?? 1, $arrayProps['count_max'] ?? 10);
|
||
for ($i = 0; $i < $countMax; $i++) {
|
||
$isArray = Random::bool();
|
||
$type = !$reflection->isAbstract() ? $reflection->getName() : $this->generateClassByFactory($reflection);
|
||
$value[] = $i % 2 ? new $type($this->prepareArrayForObject($type, $isArray)) : $this->prepareArrayForObject($type);
|
||
}
|
||
$result[] = [$value];
|
||
unset($value);
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Генерирует массив массивов
|
||
*
|
||
* @param array $arrayProps
|
||
*
|
||
* @return array
|
||
* @throws \ReflectionException
|
||
*/
|
||
private function generateArrayOfArray(array $arrayProps): array
|
||
{
|
||
$result = [];
|
||
$reflection = new ReflectionClass($arrayProps['type']);
|
||
$max = Random::int(1, 10);
|
||
for ($i = 0; $i < $max; $i++) {
|
||
$isArray = Random::bool();
|
||
$arrayProps['type'] = !$reflection->isAbstract() ? $reflection->getName() : $this->generateClassByFactory($reflection);
|
||
$result[] = [$i % 2 ? new $arrayProps['type']($this->prepareArrayForObject($arrayProps['type'], $isArray)) : $this->prepareArrayForObject($arrayProps['type'])];
|
||
}
|
||
return $result;
|
||
}
|
||
}
|