Passed
Push — master ( 6f905d...2edd34 )
by Oleg
02:55
created

AbstractTest::getHaveInRepoPhrase()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 54
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 7.0529

Importance

Changes 0
Metric Value
cc 7
eloc 41
nc 6
nop 1
dl 0
loc 54
rs 7.8331
c 0
b 0
f 0
ccs 35
cts 39
cp 0.8974
crap 7.0529

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
4
namespace SlayerBirden\DFCodeGeneration\Generator\Tests;
5
6
use SlayerBirden\DFCodeGeneration\Generator\GeneratorInterface;
7
8
abstract class AbstractTest implements GeneratorInterface
9
{
10
    /**
11
     * @var EntityProviderFactoryInterface
12
     */
13
    protected $entityProviderFactory;
14
    /**
15
     * @var string
16
     */
17
    protected $entityClassName;
18
    /**
19
     * @var EntityProviderInterface[]
20
     */
21
    protected $providers = [];
22
    private $innerProviders = [];
23
    private $appended = [];
24
    /**
25
     * The default probability of Nulled values being filled with data
26
     * @var float
27
     */
28
    private $probabilityOfFilledNullable;
29
30 10
    public function __construct(
31
        string $entityClassName,
32
        EntityProviderFactoryInterface $entityProviderFactory,
33
        float $probabilityOfFilledNullable = .5
34
    ) {
35 10
        $this->entityProviderFactory = $entityProviderFactory;
36 10
        $this->entityClassName = $entityClassName;
37 10
        $this->probabilityOfFilledNullable = $probabilityOfFilledNullable;
38 10
    }
39
40 5
    protected function getLatestProvider()
41
    {
42 5
        if (count($this->providers)) {
43 5
            return end($this->providers);
44
        } else {
45 5
            return $this->entityProviderFactory->create($this->entityClassName);
46
        }
47
    }
48
49 10
    protected function generateHaveInRepo(int $count = 1): string
50
    {
51 10
        $generated = 0;
52 10
        $body = '';
53 10
        while ($generated < $count) {
54 10
            $provider = $this->entityProviderFactory->create($this->entityClassName);
55 10
            $body .= $this->getHaveInRepoPhrase($provider);
56 10
            $this->providers[] = $provider;
57 10
            $generated++;
58
        }
59 10
        return $body;
60
    }
61
62 3
    private function getInnerProvider(string $entity): EntityProviderInterface
63
    {
64 3
        if (!isset($this->innerProviders[$entity])) {
65 3
            $this->innerProviders[$entity] = $this->entityProviderFactory->create($entity);
66
        }
67
68 3
        return $this->innerProviders[$entity];
69
    }
70
71 3
    private function appendOnce(string $content, string $to)
72
    {
73 3
        if (in_array($content, $this->appended, true)) {
74 2
            return $to;
75
        }
76 3
        $this->appended[] = $content;
77 3
        return $to . $content;
78
    }
79
80 10
    private function getHaveInRepoPhrase(EntityProviderInterface $provider): string
81
    {
82 10
        $body = '';
83
84 10
        $params = [];
85 10
        foreach ($provider->getEntitySpec() as $item) {
86 10
            $key = $item['name'];
87 10
            $type = $item['type'];
88 10
            $entity = $item['entity'] ?? '';
89 10
            $nullable = $item['nullable'] ?? false;
90 10
            $referenceColumn = $item['ref_column_key'] ?? 'id';
91
            // Skip 50% of nullable values (by default)
92 10
            if ($nullable && rand(0,100)/100 > $this->probabilityOfFilledNullable) {
93 7
                continue;
94
            }
95
            switch ($type) {
96 10
                case 'manytoone':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
97 2
                    $innerProvider = $this->getInnerProvider($entity);
98 2
                    $body = $this->appendOnce(
99 2
                        $this->getHaveInRepoPhrase($innerProvider) . $this->getUsagePhrase($innerProvider, $referenceColumn),
100 2
                        $body
101
                    );
102 2
                    $params[$key] = '$' . $innerProvider->getShortName();
103 2
                    break;
104 10
                case 'manytomany':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
105 1
                    $innerProvider = $this->getInnerProvider($entity);
106 1
                    $body = $this->appendOnce(
107 1
                        $this->getHaveInRepoPhrase($innerProvider) . $this->getUsagePhrase($innerProvider, $referenceColumn),
108 1
                        $body
109
                    );
110 1
                    $params[$key] = '[$' . $innerProvider->getShortName() . ']';
111 1
                    break;
112 10
                case 'onetoone':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
113
                    $innerProvider = $this->entityProviderFactory->create($entity);
114
                    $body .= $this->getHaveInRepoPhrase($innerProvider) . $this->getUsagePhrase($innerProvider, $referenceColumn);
115
                    $params[$key] = '$' . $innerProvider->getShortName();
116
                    break;
117
                default:
0 ignored issues
show
Coding Style introduced by
DEFAULT statements must be defined using a colon

As per the PSR-2 coding standard, default statements should not be wrapped in curly braces.

switch ($expr) {
    default: { //wrong
        doSomething();
        break;
    }
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
118 10
                    $params[$key] = new ProviderValuePromise($provider, $key);
119 10
                    break;
120
            }
121
        }
122
123 10
        $params = $this->resolvePromises($params);
124
125 10
        $body .= '$I->haveInRepository(%1$s, %2$s);';
126
        $args = [
127 10
            '\'' . $provider->getEntityClassName() . '\'',
128 10
            var_export($params, true),
129
        ];
130 10
        $body = sprintf($body, ...$args);
131 10
        $body = preg_replace("/'(\\[?\\$\w*\\]?)'/", '$1', $body);
132
133 10
        return $body . PHP_EOL;
134
    }
135
136
    private function resolvePromises(array $params): array
137
    {
138 10
        return array_map(function ($item) {
139 10
            if ($item instanceof ProviderValuePromise) {
140 10
                return $item->resolve();
141
            }
142 3
            return $item;
143 10
        }, $params);
144
    }
145
146 3
    protected function getHaveInRepoParams(int $idx = 0): array
147
    {
148 3
        if (isset($this->providers[$idx])) {
149 3
            return $this->providers[$idx]->getPostParams();
150
        }
151
152
        throw new \InvalidArgumentException('Wrong id provided.');
153
    }
154
155 3
    protected function getUsagePhrase(EntityProviderInterface $provider, string $referenceColumn): string
156
    {
157 3
        $body = '$%s = $I->grabEntityFromRepository(%s, [\'' . $referenceColumn . '\' => %d]);';
158
159
        $args = [
160 3
            $provider->getShortName(),
161 3
            '\'' . $provider->getEntityClassName() . '\'',
162 3
            $provider->getId(),
163
        ];
164 3
        $body = sprintf($body, ...$args);
165
166 3
        return $body . PHP_EOL;
167
    }
168
}
169