Passed
Push — main ( 095ef5...91e9ab )
by Glynn
11:28 queued 09:54
created

TestManifestParser   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 264
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 118
c 2
b 0
f 0
dl 0
loc 264
rs 10
wmc 24

18 Methods

Rating   Name   Duplication   Size   Complexity  
A testFileAssetsEmpty() 0 13 2
A createTempFile() 0 5 1
A testGetAssetDetailsFromNonExistentFile() 0 6 1
A testGetCssUrisEmpty() 0 16 1
A testEmptyManifest() 0 13 2
A testGetCssUrisException() 0 4 1
A testGetAssetDetails() 0 23 1
A testGetEntryFilePathNull() 0 16 1
A testFileAssetsNotArray() 0 13 2
A testDecodeJsonError() 0 13 2
A testRemoveTrailingSlash() 0 4 1
A testGetEntryScriptsUri() 0 17 1
A testCreateParser() 0 4 1
A testGetCssUris() 0 18 1
A testGetAssetDetailsForNonExistentFile() 0 13 2
A removeTempFile() 0 4 1
A testManifestNotArray() 0 13 2
A testGetEntryFilePathException() 0 4 1
1
<?php
2
3
/**
4
 * Unit tests for the ManifestParser class.
5
 */
6
7
namespace Gin0115\ViteManifestParser\Tests;
8
9
use Exception;
10
use PHPUnit\Framework\TestCase;
11
use Gin0115\ViteManifestParser\ManifestParser;
12
13
class TestManifestParser extends TestCase
14
{
15
16
    /** 
17
     * Creates a temp file with the passed contents.
18
     * 
19
     * @param string $name The name to the temp file.
20
     * @param string $contents The contents of the temp file.
21
     * @return string The name to the temp file.
22
     */
23
    private function createTempFile(string $name, string $content): string
24
    {
25
        $tempFile = tempnam(sys_get_temp_dir(), $name);
26
        file_put_contents($tempFile, $content);
27
        return $tempFile;
28
    }
29
30
    /**
31
     * Removes a temp file based on its name.
32
     * 
33
     * @param string $name The name of the temp file.
34
     */
35
    private function removeTempFile(string $name): void
36
    {
37
        $tempFile = tempnam(sys_get_temp_dir(), $name);
38
        unlink($tempFile);
39
    }
40
41
    /** @testdox It should be possible to create a parser and get access to the build uri */
42
    public function testCreateParser()
43
    {
44
        $parser = new ManifestParser('http://example.com/assets', 'tests/fixtures/manifest.json');
45
        $this->assertEquals('http://example.com/assets', $parser->getAssetsUri());
46
    }
47
48
    /** @testdox When passing the assets path, any trailing slash should be removed. */
49
    public function testRemoveTrailingSlash()
50
    {
51
        $parser = new ManifestParser('http://example.com/assets/', 'tests/fixtures/manifest.json');
52
        $this->assertEquals('http://example.com/assets', $parser->getAssetsUri());
53
    }
54
55
    /** @testdox An exception should be thrown if attempting to get asset details from a file which doesn't exist. */
56
    public function testGetAssetDetailsFromNonExistentFile()
57
    {
58
        $this->expectException(\Exception::class);
59
        $this->expectExceptionMessage('Manifest file does not exist.');
60
        $parser = new ManifestParser('http://example.com/assets/', 'tests/fixtures/non-existent-manifest.json');
61
        $parser->getAssetsForVueFile('non-existent-file.js');
62
    }
63
64
    /** @testdox An exception should be thrown if any errors occurs decoding file contents from JSON. */
65
    public function testDecodeJsonError()
66
    {
67
        $file = $this->createTempFile('manifest-invalid.json', '{');
68
        $parser = new ManifestParser('http://example.com/assets/', $file);
69
70
        try {
71
            $parser->getAssetsForVueFile('main.js');
72
        } catch (\Throwable $th) {
73
            $this->assertInstanceOf(Exception::class, $th);
74
            $this->assertEquals('Manifest file is not valid JSON.', $th->getMessage());
75
        }
76
77
        $this->removeTempFile('manifest-invalid.json');
78
    }
79
80
    /** @testdox An exception should be thrown if the manifest file is empty or invalid. */
81
    public function testEmptyManifest()
82
    {
83
        $file = $this->createTempFile('manifest-empty.json', '{}');
84
        $parser = new ManifestParser('http://example.com/assets/', $file);
85
86
        try {
87
            $parser->getAssetsForVueFile('main.js');
88
        } catch (\Throwable $th) {
89
            $this->assertInstanceOf(Exception::class, $th);
90
            $this->assertEquals('Manifest file is empty or invalid.', $th->getMessage());
91
        }
92
93
        $this->removeTempFile('manifest-empty.json');
94
    }
95
96
    /** @testdox An exception should be thrown if the decoded manifest is not an array. */
97
    public function testManifestNotArray()
98
    {
99
        $file = $this->createTempFile('manifest-not-array.json', '"main.js"');
100
        $parser = new ManifestParser('http://example.com/assets/', $file);
101
102
        try {
103
            $parser->getAssetsForVueFile('main.js');
104
        } catch (\Throwable $th) {
105
            $this->assertInstanceOf(Exception::class, $th);
106
            $this->assertEquals('Manifest file is empty or invalid.', $th->getMessage());
107
        }
108
109
        $this->removeTempFile('manifest-not-array.json');
110
    }
111
112
    /** @testdox An exception be thrown attempting to get the assets for a file which doesn't exist on a valid manifest file. */
113
    public function testGetAssetDetailsForNonExistentFile()
114
    {
115
        $file = $this->createTempFile('manifest-valid.json', '{"main.js": "main.js"}');
116
        $parser = new ManifestParser('http://example.com/assets/', $file);
117
118
        try {
119
            $parser->getAssetsForVueFile('non-existent-file.js');
120
        } catch (\Throwable $th) {
121
            $this->assertInstanceOf(Exception::class, $th);
122
            $this->assertEquals('File does not exist in manifest.', $th->getMessage());
123
        }
124
125
        $this->removeTempFile('manifest-valid.json');
126
    }
127
128
    /** @testdox An exception be thrown if a files assets are not an array */
129
    public function testFileAssetsNotArray()
130
    {
131
        $file = $this->createTempFile('manifest-valid.json', '{"main.js": "main.js"}');
132
        $parser = new ManifestParser('http://example.com/assets/', $file);
133
134
        try {
135
            $parser->getAssetsForVueFile('main.js');
136
        } catch (\Throwable $th) {
137
            $this->assertInstanceOf(Exception::class, $th);
138
            $this->assertEquals('File assets are empty or invalid.', $th->getMessage());
139
        }
140
141
        $this->removeTempFile('manifest-valid.json');
142
    }
143
144
    /** @testdox An exception be thrown if a files assets are empty */
145
    public function testFileAssetsEmpty()
146
    {
147
        $file = $this->createTempFile('manifest-valid.json', '{"main.js": []}');
148
        $parser = new ManifestParser('http://example.com/assets/', $file);
149
150
        try {
151
            $parser->getAssetsForVueFile('main.js');
152
        } catch (\Throwable $th) {
153
            $this->assertInstanceOf(Exception::class, $th);
154
            $this->assertEquals('File assets are empty or invalid.', $th->getMessage());
155
        }
156
157
        $this->removeTempFile('manifest-valid.json');
158
    }
159
160
    /** @testdox It should be possible to access the file details for any file which is included in the manifest */
161
    public function testGetAssetDetails()
162
    {
163
        $manifest = [
164
            'file.js' => [
165
                'file' => 'some/path.file',
166
                'css' => [
167
                    'assets/file.css',
168
                    'assets/file2.css',
169
                ]
170
            ]
171
        ];
172
173
174
        $file = $this->createTempFile('testGetAssetDetails.json', \json_encode($manifest));
175
176
        $parser = new ManifestParser('http://example.com/', $file);
177
        $details = $parser->getAssetsForVueFile('file.js');
178
179
        $this->assertEquals('some/path.file', $details['file']);
180
        $this->assertContains('assets/file.css', $details['css']);
181
        $this->assertContains('assets/file2.css', $details['css']);
182
183
        $this->removeTempFile('testGetAssetDetails.json');
184
    }
185
186
    /** @testdox it should be possible to get the entry scripts URI which takes into account the asset uri passed. */
187
    public function testGetEntryScriptsUri()
188
    {
189
        $manifest = [
190
            'file.js' => [
191
                'file' => 'some/path.file',
192
                'css' => [
193
                    'assets/file.css',
194
                    'assets/file2.css',
195
                ]
196
            ]
197
        ];
198
199
        $file = $this->createTempFile('testGetEntryScriptsUri.json', \json_encode($manifest));
200
        $parser = new ManifestParser('http://example.com/assets/', $file);
201
        $this->assertEquals('http://example.com/assets/some/path.file', $parser->getEntryScriptUri('file.js'));
202
203
        $this->removeTempFile('testGetEntryScriptsUri.json');
204
    }
205
206
    /** @testdox When attempting to get the entry file uri, if the manifest doesn't contain a file property, null should be returned */
207
    public function testGetEntryFilePathNull()
208
    {
209
        $manifest = [
210
            'file.js' => [
211
                'css' => [
212
                    'assets/file.css',
213
                    'assets/file2.css',
214
                ]
215
            ]
216
        ];
217
218
        $file = $this->createTempFile('testGetEntryFilePathNull.json', \json_encode($manifest));
219
        $parser = new ManifestParser('http://example.com/assets/', $file);
220
        $this->assertNull($parser->getEntryScriptUri('file.js'));
221
222
        $this->removeTempFile('testGetEntryFilePathNull.json');
223
    }
224
225
    /** @testdox When attempting to get the entry file uri, if any exception is thrown, null should be returned */
226
    public function testGetEntryFilePathException()
227
    {
228
        $parser = new ManifestParser('http://example.com/assets/', 'i dont exist');
229
        $this->assertNull($parser->getEntryScriptUri('file.js'));
230
    }
231
232
    /** @testdox it should be possible to get the array of css URI's which takes into account the asset uri passed. */
233
    public function testGetCssUris()
234
    {
235
        $manifest = [
236
            'file.js' => [
237
                'file' => 'some/path.file',
238
                'css' => [
239
                    'assets/file.css',
240
                    'assets/file2.css',
241
                ]
242
            ]
243
        ];
244
245
        $file = $this->createTempFile('testGetCssUris.json', \json_encode($manifest));
246
        $parser = new ManifestParser('http://example.com', $file);
247
        $this->assertContains('http://example.com/assets/file.css', $parser->getEntryCssUris('file.js'));
248
        $this->assertContains('http://example.com/assets/file2.css', $parser->getEntryCssUris('file.js'));
249
250
        $this->removeTempFile('testGetCssUris.json');
251
    }
252
253
    /** @testdox When attempting to get the array of css URI's, if the manifest doesn't contain a file property, an empty should be returned */
254
    public function testGetCssUrisEmpty()
255
    {
256
        $manifest = [
257
            'file.js' => [
258
                'css' => [
259
                    'assets/file.css',
260
                    'assets/file2.css',
261
                ]
262
            ]
263
        ];
264
265
        $file = $this->createTempFile('testGetCssUrisEmpty.json', \json_encode($manifest));
266
        $parser = new ManifestParser('http://example.com', $file);
267
        $this->assertEmpty($parser->getEntryCssUris('not.js'));
268
269
        $this->removeTempFile('testGetCssUrisEmpty.json');
270
    }
271
272
    /** @testdox When attempting to get the array of css URI's, if any exception is thrown, empty array should be returned */
273
    public function testGetCssUrisException()
274
    {
275
        $parser = new ManifestParser('http://example.com', 'i dont exist');
276
        $this->assertEmpty($parser->getEntryCssUris('file.js'));
277
    }
278
279
280
}
281