Как создать класс или черту на пакете с автозагрузкой зарядки другим путем - PullRequest
0 голосов
/ 31 января 2019

Ну, я создаю провайдера пакетов для расширенных fzaninotto / faker

Для этого мне нужно использовать это в composer.json пакета, чтобы мой пакет мог стать поставщикомпакет Faker

"autoload": {
    "psr-4": {
      "Faker\\Provider\\": "src"
    }
},

Это не путь для моего пакета (реальный путь package\abkrim\fake-ads\src)

При создании нового класса фейкер легко (в пути package\abkrim\fake-ads\src):

<?php

namespace Faker\Provider;

use Faker\Generator;

class MyFakerClass extends Base
{
    public function __construct(Generator $generator)
    {
        parent::__construct($generator);
    }
    ...
    // My own functions
}

И создать файл класса для данных по тому же пути

<?php

namespace Faker\Provider;

class MyFakerDataClass
{
    // My own code
}

Использовать код и работать

$faker = (new \Faker\Factory())::create();
$faker->addProvider(new \Faker\Provider\Fakecar($faker));

echo $faker->someMethodOfMyFakerClass;

Но мне нравится создавать несколько классов (новые поставщики в одном и том жепакет).

Я не знаю, как создать базовый класс, потому что расширение Faker \ Generator и пространства имен не является моим собственным каталогом.

Итак, я создаю класс помощников вмой собственный каталог

<?php

namespace Faker\Provider;

class Helpers
{
    /**
     * @param array $values
     * @return string
     * @throws \Exception
     */
    public static function getWeighted(array $values) :string
    {
        $currentTotal = 0;
        $firstRand = random_int(1, 100);

        $total = array_sum($values);

        $rand = ($firstRand / 100) * $total;

        foreach ($values as $key => $weight) {
            $currentTotal += $weight;

            if ($rand <= $currentTotal) {
                return $key;
            }
        }

        return '';
    }
}

Для использования в моем провайдере используйте, например, и работает:

/**
 * @return string
 * @throws \Exception
 */
public static function flat() : string
{
    return Helpers::getWeighted(MyFakerDataClass::getStateTypeFlat());
}

Я думаю, что это не лучший и правильный метод.

Плюс,когда я пытаюсь создать тест, я не могу.

<?php

namespace Faker\Tests\Provider;

use Faker\Factory;
use Faker\Generator;
use Faker\Provider\FakerRealState;
use Faker\Provider\RealStateData;
use Faker\Provider\Helpers;
use PHPUnit\Framework\TestCase;

class FakeAdsRealStateTest extends TestCase
{
    /**
     * @var Generator
     */
    private $faker;

    private $helpers;

    public function setUp()
    {
        $faker = Factory::create();
        $faker->addProvider(new FakerRealState($faker));
        $this->faker = $faker;
    }

    /**
     * @param $property
     * @param null $class
     * @return mixed
     * @throws \ReflectionException
     */
    public function getProtectedProperty($property, $class = null)
    {
        if( is_null($class))
        {
            $class = new FakerRealState($this->faker);
        }
        $reflection = new \ReflectionClass($class);
        $reflection_property = $reflection->getProperty($property);
        $reflection_property->setAccessible(true);
        return $reflection_property->getValue($class, $property);
    }

    public function testGetWeighted()
    {
        $data = [
            'key1' => 80,
            'key2' => 19,
            'key3' => 1,
        ];

        $result = array_fill_keys(array_keys($data), 0);

        for($i = 0; $i<1000; $i++)
        {
            $result[$this->faker->getWeighted($data)]++;
        }

        $this->assertGreaterThan($result['key2'], $result['key1']);
        $this->assertGreaterThan($result['key3'], $result['key2']);
        $this->assertGreaterThan($result['key3'], $result['key1']);

        $this->assertEquals('', $this->faker->getWeighted([]));
    }
}

Ошибка

There was 1 error:

1) Faker\Tests\Provider\FakeAdsRealStateTest::testGetWeighted
InvalidArgumentException: Unknown formatter "getWeighted"

Я думаю, что проблема заключается в том, что яне знаю, как создать класс, чтобы распространить остальных поставщиков под призму fzaninotto / Faker, или даже создать черту.

...