• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

RonasIT / laravel-entity-generator / 15315608533

29 May 2025 03:31AM UTC coverage: 100.0%. Remained the same
15315608533

Pull #155

github

web-flow
Merge 93320b33e into 2dbd60a67
Pull Request #155: refactor: remove useless faker import

896 of 896 relevant lines covered (100.0%)

5.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/Generators/AbstractTestsGenerator.php
1
<?php
2

3
namespace RonasIT\Support\Generators;
4

5
use DateTime;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Str;
8
use RonasIT\Support\Events\SuccessCreateMessage;
9
use RonasIT\Support\Exceptions\CircularRelationsFoundedException;
10

11
abstract class AbstractTestsGenerator extends EntityGenerator
12
{
13
    protected array $fakerProperties = [];
14
    protected array $getFields = [];
15
    protected bool $withAuth = false;
16

17
    const array FIXTURE_TYPES = [
18
        'create' => ['request', 'response'],
19
        'update' => ['request'],
20
    ];
21

22
    const string EMPTY_GUARDED_FIELD = '*';
23
    const string UPDATED_AT = 'updated_at';
24
    const string CREATED_AT = 'created_at';
25

26
    public function generate(): void
27
    {
28
        if ($this->canGenerateUserData()) {
11✔
29
            $this->withAuth = true;
5✔
30
        }
31

32
        $this->createDump();
11✔
33
        $this->generateFixtures();
8✔
34
        $this->generateTests();
8✔
35
    }
36

37
    protected function getFixturesPath($fileName = null): string
38
    {
39
        $path = base_path("{$this->paths['tests']}/fixtures/{$this->getTestClassName()}");
8✔
40

41
        if (empty($fileName)) {
8✔
42
            return $path;
8✔
43
        }
44

45
        return "{$path}/{$fileName}";
8✔
46
    }
47

48
    protected function createDump(): void
49
    {
50
        if (!$this->isStubExists('dump')) {
11✔
51
            return;
2✔
52
        }
53

54
        $content = $this->getStub('dump', [
9✔
55
            'inserts' => $this->getInserts()
9✔
56
        ]);
9✔
57

58
        $this->createFixtureFolder();
6✔
59

60
        $dumpName = $this->getDumpName();
6✔
61

62
        file_put_contents($this->getFixturesPath($dumpName), $content);
6✔
63

64
        event(new SuccessCreateMessage("Created a new Test dump on path: "
6✔
65
            . "{$this->paths['tests']}/fixtures/{$this->getTestClassName()}/{$dumpName}"));
6✔
66
    }
67

68
    protected function getDumpName(): string
69
    {
70
        return 'dump.sql';
4✔
71
    }
72

73
    protected function getInserts(): array
74
    {
75
        $arrayModels = [$this->model];
9✔
76

77
        if ($this->withAuth) {
9✔
78
            array_unshift($arrayModels, 'User');
4✔
79
        }
80

81
        return array_map(function ($model) {
9✔
82
            return [
6✔
83
                'name' => $this->getTableName($model),
6✔
84
                'items' => [
6✔
85
                    [
6✔
86
                        'fields' => $this->getModelFields($model),
6✔
87
                        'values' => $this->getDumpValuesList($model)
6✔
88
                    ]
6✔
89
                ]
6✔
90
            ];
6✔
91
        }, $this->buildRelationsTree($arrayModels));
9✔
92
    }
93

94
    protected function isFactoryExists(string $modelName): bool
95
    {
96
        return $this->classExists('factories', "{$modelName}Factory");
9✔
97
    }
98

99
    protected function isMethodExists($modelName, $method): bool
100
    {
101
        $modelClass = $this->getModelClass($modelName);
6✔
102

103
        return method_exists($modelClass, $method);
6✔
104
    }
105

106
    protected function getModelsWithFactories($models): array
107
    {
108
        return array_filter($models, function ($model) {
7✔
109
            return $this->isFactoryExists($model);
4✔
110
        });
7✔
111
    }
112

113
    protected function getDumpValuesList($model): array
114
    {
115
        $values = $this->buildEntityObject($model);
6✔
116

117
        array_walk($values, function (&$value) {
6✔
118
            if ($value instanceof DateTime) {
6✔
119
                $value = "{$value->format('Y-m-d h:i:s')}";
4✔
120
            } elseif (is_bool($value)) {
6✔
121
                $value = ($value) ? 'true' : 'false';
4✔
122
            } elseif (is_array($value)) {
6✔
123
                $value = json_encode($value);
4✔
124
            }
125

126
            $value = (is_string($value)) ? "'{$value}'" : $value;
6✔
127
        });
6✔
128

129
        return $values;
6✔
130
    }
131

132
    protected function getFixtureValuesList($model): array
133
    {
134
        $values = $this->buildEntityObject($model);
8✔
135

136
        array_walk($values, function (&$value) {
8✔
137
            if ($value instanceof DateTime) {
8✔
138
                $value = "{$value->format('Y-m-d h:i:s')}";
5✔
139
            }
140
        });
8✔
141

142
        return $values;
8✔
143
    }
144

145
    protected function buildEntityObject($model): array
146
    {
147
        $modelFields = $this->getModelFields($model);
8✔
148
        $mockEntity = $this->getMockModel($model);
8✔
149

150
        $result = [];
8✔
151

152
        foreach ($modelFields as $field) {
8✔
153
            $value = Arr::get($mockEntity, $field, 1);
8✔
154

155
            $result[$field] = $value;
8✔
156
        }
157

158
        return $result;
8✔
159
    }
160

161
    protected function getModelFields($model): array
162
    {
163
        $modelClass = $this->getModelClass($model);
8✔
164

165
        return $this->filterBadModelField($modelClass::getFields());
8✔
166
    }
167

168
    protected function getMockModel($model): array
169
    {
170
        $hasFactory = $this->isFactoryExists($model);
8✔
171

172
        if (!$hasFactory) {
8✔
173
            return [];
3✔
174
        }
175

176
        $factoryNamespace = "{$this->getOrCreateNamespace('factories')}\\{$model}Factory";
5✔
177
        $factory = $factoryNamespace::new();
5✔
178

179
        return $factory
5✔
180
            ->make()
5✔
181
            ->toArray();
5✔
182
    }
183

184
    protected function generateFixtures(): void
185
    {
186
        $object = $this->getFixtureValuesList($this->model);
8✔
187
        $entity = Str::snake($this->model);
8✔
188

189
        $this->createFixtureFolder();
8✔
190

191
        foreach (self::FIXTURE_TYPES as $type => $modifications) {
8✔
192
            if ($this->isFixtureNeeded($type)) {
8✔
193
                foreach ($modifications as $modification) {
7✔
194
                    $excepts = ($modification === 'request') ? ['id'] : [];
7✔
195

196
                    $this->generateFixture("{$type}_{$entity}_{$modification}.json", Arr::except($object, $excepts));
7✔
197
                }
198
            }
199
        }
200
    }
201

202
    protected function generateFixture($fixtureName, $data): void
203
    {
204
        $fixturePath = $this->getFixturesPath($fixtureName);
4✔
205
        $content = json_encode($data, JSON_PRETTY_PRINT);
4✔
206
        $fixtureRelativePath = "{$this->paths['tests']}/fixtures/{$this->getTestClassName()}/{$fixtureName}";
4✔
207

208
        file_put_contents($fixturePath, $content);
4✔
209

210
        event(new SuccessCreateMessage("Created a new Test fixture on path: {$fixtureRelativePath}"));
4✔
211
    }
212

213
    protected function buildRelationsTree($models): array
214
    {
215
        foreach ($models as $model) {
9✔
216
            $relations = $this->getRelatedModels($model, $this->getTestClassName());
9✔
217
            $relationsWithFactories = $this->getModelsWithFactories($relations);
7✔
218

219
            if (empty($relationsWithFactories)) {
7✔
220
                continue;
7✔
221
            }
222

223
            if (in_array($model, $relationsWithFactories)) {
4✔
224
                $this->throwFailureException(
1✔
225
                    CircularRelationsFoundedException::class,
1✔
226
                    'Circular relations founded.',
1✔
227
                    'Please resolve you relations in models, factories and database.'
1✔
228
                );
1✔
229
            }
230

231
            $relatedModels = $this->buildRelationsTree($relationsWithFactories);
4✔
232

233
            $models = array_merge($relatedModels, $models);
4✔
234
        }
235

236
        return array_unique($models);
7✔
237
    }
238

239
    protected function canGenerateUserData(): bool
240
    {
241
        return $this->classExists('models', 'User')
11✔
242
            && $this->isMethodExists('User', 'getFields');
11✔
243
    }
244

245
    protected function createFixtureFolder(): void
246
    {
247
        $fixturePath = $this->getFixturesPath();
8✔
248

249
        if (!file_exists($fixturePath)) {
8✔
250
            mkdir($fixturePath, 0777, true);
8✔
251
        }
252
    }
253

254
    abstract protected function getTestClassName(): string;
255

256
    abstract protected function isFixtureNeeded($type): bool;
257

258
    abstract protected function generateTests(): void;
259

260
    private function filterBadModelField($fields): array
261
    {
262
        return array_diff($fields, [
8✔
263
            self::EMPTY_GUARDED_FIELD,
8✔
264
            self::CREATED_AT,
8✔
265
            self::UPDATED_AT,
8✔
266
        ]);
8✔
267
    }
268
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc