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

valkyrjaio / valkyrja / 20156277091

12 Dec 2025 04:26AM UTC coverage: 73.416% (-0.6%) from 74.002%
20156277091

push

github

MelechMizrachi
CI: Trying to fix coveralls.

8125 of 11067 relevant lines covered (73.42%)

17.9 hits per line

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

23.08
/src/Valkyrja/Filesystem/InMemoryFilesystem.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <melechmizrachi@gmail.com>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13

14
namespace Valkyrja\Filesystem;
15

16
use Override;
17
use Valkyrja\Exception\RuntimeException;
18
use Valkyrja\Filesystem\Contract\Filesystem as Contract;
19
use Valkyrja\Filesystem\Data\InMemoryFile;
20
use Valkyrja\Filesystem\Data\InMemoryMetadata;
21
use Valkyrja\Filesystem\Enum\Visibility;
22
use Valkyrja\Filesystem\Exception\UnableToReadContentsException;
23

24
use function fread;
25
use function str_starts_with;
26
use function time;
27

28
/**
29
 * Class InMemoryFilesystem.
30
 *
31
 * @author Melech Mizrachi
32
 */
33
class InMemoryFilesystem implements Contract
34
{
35
    /**
36
     * @var array<string, InMemoryFile>
37
     */
38
    protected array $files = [];
39

40
    public function __construct(
8✔
41
        InMemoryFile ...$files
42
    ) {
43
        foreach ($files as $file) {
8✔
44
            $this->files[$file->name] = $file;
×
45
        }
46
    }
47

48
    /**
49
     * @inheritDoc
50
     */
51
    #[Override]
4✔
52
    public function exists(string $path): bool
53
    {
54
        return isset($this->files[$path]);
4✔
55
    }
56

57
    /**
58
     * @inheritDoc
59
     */
60
    #[Override]
4✔
61
    public function read(string $path): string
62
    {
63
        return $this->files[$path]->contents
4✔
64
            ?? throw new UnableToReadContentsException("Error reading file contents for $path");
4✔
65
    }
66

67
    /**
68
     * @inheritDoc
69
     */
70
    #[Override]
4✔
71
    public function write(string $path, string $contents): bool
72
    {
73
        $this->files[$path] = new InMemoryFile($path, $contents, timestamp: time());
4✔
74

75
        return true;
4✔
76
    }
77

78
    /**
79
     * @inheritDoc
80
     *
81
     * @param resource $resource The resource
82
     */
83
    #[Override]
×
84
    public function writeStream(string $path, $resource): bool
85
    {
86
        $pathContents = fread($resource, 4096);
×
87

88
        if ($pathContents === false) {
×
89
            throw new RuntimeException('Failed to read provided resource');
×
90
        }
91

92
        $this->files[$path] = new InMemoryFile($path, $pathContents, timestamp: time());
×
93

94
        return true;
×
95
    }
96

97
    /**
98
     * @inheritDoc
99
     */
100
    #[Override]
×
101
    public function update(string $path, string $contents): bool
102
    {
103
        return $this->write($path, $contents);
×
104
    }
105

106
    /**
107
     * @inheritDoc
108
     */
109
    #[Override]
×
110
    public function updateStream(string $path, $resource): bool
111
    {
112
        return $this->writeStream($path, $resource);
×
113
    }
114

115
    /**
116
     * @inheritDoc
117
     */
118
    #[Override]
×
119
    public function put(string $path, string $contents): bool
120
    {
121
        return $this->write($path, $contents);
×
122
    }
123

124
    /**
125
     * @inheritDoc
126
     */
127
    #[Override]
×
128
    public function putStream(string $path, $resource): bool
129
    {
130
        return $this->writeStream($path, $resource);
×
131
    }
132

133
    /**
134
     * @inheritDoc
135
     */
136
    #[Override]
×
137
    public function rename(string $path, string $newPath): bool
138
    {
139
        if ($this->exists($newPath) || ! $this->exists($path)) {
×
140
            return false;
×
141
        }
142

143
        $this->files[$newPath] = $this->files[$path];
×
144

145
        $this->delete($path);
×
146

147
        return true;
×
148
    }
149

150
    /**
151
     * @inheritDoc
152
     */
153
    #[Override]
×
154
    public function copy(string $path, string $newPath): bool
155
    {
156
        if ($this->exists($newPath) || ! $this->exists($path)) {
×
157
            return false;
×
158
        }
159

160
        $this->files[$newPath] = $this->files[$path];
×
161

162
        return true;
×
163
    }
164

165
    /**
166
     * @inheritDoc
167
     */
168
    #[Override]
4✔
169
    public function delete(string $path): bool
170
    {
171
        unset($this->files[$path]);
4✔
172

173
        return true;
4✔
174
    }
175

176
    /**
177
     * @inheritDoc
178
     */
179
    #[Override]
×
180
    public function metadata(string $path): array|null
181
    {
182
        return $this->getMetadataInternal($path)?->toArray();
×
183
    }
184

185
    /**
186
     * @inheritDoc
187
     */
188
    #[Override]
×
189
    public function mimetype(string $path): string|null
190
    {
191
        return $this->getMetadataInternal($path)->mimetype ?? null;
×
192
    }
193

194
    /**
195
     * @inheritDoc
196
     */
197
    #[Override]
×
198
    public function size(string $path): int|null
199
    {
200
        return $this->getMetadataInternal($path)->size ?? null;
×
201
    }
202

203
    /**
204
     * @inheritDoc
205
     */
206
    #[Override]
4✔
207
    public function timestamp(string $path): int|null
208
    {
209
        return $this->files[$path]->timestamp ?? null;
4✔
210
    }
211

212
    /**
213
     * @inheritDoc
214
     */
215
    #[Override]
×
216
    public function visibility(string $path): string|null
217
    {
218
        return $this->getMetadataInternal($path)->visibility ?? null;
×
219
    }
220

221
    /**
222
     * @inheritDoc
223
     */
224
    #[Override]
×
225
    public function setVisibility(string $path, Visibility $visibility): bool
226
    {
227
        if (! $this->exists($path)) {
×
228
            return false;
×
229
        }
230

231
        $this->files[$path]->metadata->visibility = $visibility->value;
×
232

233
        return true;
×
234
    }
235

236
    /**
237
     * @inheritDoc
238
     */
239
    #[Override]
×
240
    public function setVisibilityPublic(string $path): bool
241
    {
242
        return $this->setVisibility($path, Visibility::PUBLIC);
×
243
    }
244

245
    /**
246
     * @inheritDoc
247
     */
248
    #[Override]
×
249
    public function setVisibilityPrivate(string $path): bool
250
    {
251
        return $this->setVisibility($path, Visibility::PRIVATE);
×
252
    }
253

254
    /**
255
     * @inheritDoc
256
     */
257
    #[Override]
×
258
    public function createDir(string $path): bool
259
    {
260
        $this->files[$path] = new InMemoryFile($path, timestamp: time());
×
261

262
        return true;
×
263
    }
264

265
    /**
266
     * @inheritDoc
267
     */
268
    #[Override]
4✔
269
    public function deleteDir(string $path): bool
270
    {
271
        foreach ($this->files as $filePath => $file) {
4✔
272
            if (str_starts_with($filePath, $path)) {
×
273
                unset($this->files[$filePath]);
×
274
            }
275
        }
276

277
        return true;
4✔
278
    }
279

280
    /**
281
     * @inheritDoc
282
     */
283
    #[Override]
×
284
    public function listContents(string|null $directory = null, bool $recursive = false): array
285
    {
286
        $directory ??= '';
×
287

288
        $contents = [];
×
289

290
        foreach ($this->files as $filePath => $file) {
×
291
            if (str_starts_with($filePath, $directory)) {
×
292
                $contents[] = [
×
293
                    'path'     => $filePath,
×
294
                    'contents' => $file->contents,
×
295
                ];
×
296
            }
297
        }
298

299
        return $contents;
×
300
    }
301

302
    protected function getMetadataInternal(string $path): InMemoryMetadata|null
×
303
    {
304
        return $this->files[$path]->metadata ?? null;
×
305
    }
306
}
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