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

RonasIT / laravel-helpers / 7204035570

14 Dec 2023 03:15AM UTC coverage: 64.058% (+2.0%) from 62.065%
7204035570

push

github

web-flow
Merge pull request #88 from RonasIT/add-nova-test-trait

Add nova test trait

56 of 57 new or added lines in 2 files covered. (98.25%)

663 of 1035 relevant lines covered (64.06%)

5.43 hits per line

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

98.04
/src/Tests/ModelTestState.php
1
<?php
2

3
namespace RonasIT\Support\Tests;
4

5
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Collection;
9
use Illuminate\Support\Facades\DB;
10
use PHPUnit\Framework\Assert;
11
use RonasIT\Support\Traits\FixturesTrait;
12

13
class ModelTestState extends Assert
14
{
15
    use FixturesTrait;
16

17
    protected Collection $state;
18
    protected Model $model;
19
    protected array $jsonFields;
20

21
    public function __construct(string $modelClassName)
22
    {
23
        $this->model = new $modelClassName();
3✔
24
        $this->state = $this->getDataSet($this->model->getTable());
3✔
25
        $this->jsonFields = $this->getModelJSONFields();
3✔
26
    }
27

28
    public function assertNotChanged(): void
29
    {
30
        $changes = $this->getChanges();
1✔
31

32
        $this->assertEquals([
1✔
33
            'updated' => [],
1✔
34
            'created' => [],
1✔
35
            'deleted' => []
1✔
36
        ], $changes);
1✔
37
    }
38

39
    public function assertChangesEqualsFixture(string $fixture, bool $exportMode = false): void
40
    {
41
        $changes = $this->getChanges();
1✔
42

43
        $this->assertEqualsFixture($fixture, $changes, $exportMode);
1✔
44
    }
45

46
    protected function getChanges(): array
47
    {
48
        $updatedData = $this->getDataSet($this->model->getTable());
2✔
49

50
        $updatedRecords = [];
2✔
51
        $deletedRecords = [];
2✔
52

53
        $this->state->each(function ($originItem) use (&$updatedData, &$updatedRecords, &$deletedRecords) {
2✔
54
            $updatedItemIndex = $updatedData->search(fn ($updatedItem) => $updatedItem['id'] === $originItem['id']);
2✔
55

56
            if ($updatedItemIndex === false) {
2✔
57
                $deletedRecords[] = $originItem;
1✔
58
            } else {
59
                $updatedItem = $updatedData->get($updatedItemIndex);
2✔
60
                $changes = array_diff_assoc($updatedItem, $originItem);
2✔
61

62
                if (!empty($changes)) {
2✔
63
                    $updatedRecords[] = array_merge(['id' => $originItem['id']], $changes);
1✔
64
                }
65

66
                $updatedData->forget($updatedItemIndex);
2✔
67
            }
68
        });
2✔
69

70
        return [
2✔
71
            'updated' => $this->prepareChanges($updatedRecords),
2✔
72
            'created' => $this->prepareChanges($updatedData->values()->toArray()),
2✔
73
            'deleted' => $this->prepareChanges($deletedRecords)
2✔
74
        ];
2✔
75
    }
76

77
    protected function prepareChanges(array $changes): array
78
    {
79
        $jsonFields = Arr::wrap($this->jsonFields);
2✔
80

81
        if (empty($jsonFields)) {
2✔
NEW
82
            return $changes;
×
83
        }
84

85
        return array_map(function ($item) use ($jsonFields) {
2✔
86
            foreach ($jsonFields as $jsonField) {
1✔
87
                if (Arr::has($item, $jsonField)) {
1✔
88
                    $item[$jsonField] = json_decode($item[$jsonField], true);
1✔
89
                }
90
            }
91

92
            return $item;
1✔
93
        }, $changes);
2✔
94
    }
95

96
    protected function getModelJSONFields(): array
97
    {
98
        $casts = $this->model->getCasts();
3✔
99

100
        $jsonCasts = array_filter($casts, fn ($cast) => $this->isJsonCast($cast));
3✔
101

102
        return array_keys($jsonCasts);
3✔
103
    }
104

105
    protected function isJsonCast(string $cast): bool
106
    {
107
        return ($cast === 'array') || (class_exists($cast) && is_subclass_of($cast, CastsAttributes::class));
3✔
108
    }
109

110
    protected function getFixturePath(string $fixtureName): string
111
    {
112
        $class = get_class($this);
1✔
113
        $explodedClass = explode('\\', $class);
1✔
114
        $className = Arr::last($explodedClass);
1✔
115
        $table = $this->model->getTable();
1✔
116

117
        return base_path("tests/fixtures/{$className}/changes/{$table}/{$fixtureName}");
1✔
118
    }
119

120
    protected function getDataSet(string $table, string $orderField = 'id'): Collection
121
    {
122
        return DB::table($table)
3✔
123
            ->orderBy($orderField)
3✔
124
            ->get()
3✔
125
            ->map(fn ($record) => (array) $record);
3✔
126
    }
127
}
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

© 2025 Coveralls, Inc