7
7
8
8
namespace Magento \Framework \Css \Test \Unit \PreProcessor \Adapter \Less ;
9
9
10
+ use Magento \Framework \App \Filesystem \DirectoryList ;
10
11
use Magento \Framework \App \State ;
11
12
use Magento \Framework \Css \PreProcessor \Adapter \Less \Processor ;
12
13
use Magento \Framework \Css \PreProcessor \File \Temporary ;
@@ -23,8 +24,8 @@ class ProcessorTest extends TestCase
23
24
const ASSET_PATH = 'test-path ' ;
24
25
25
26
const TMP_PATH_LESS = '_file/test.less ' ;
26
-
27
- const TMP_PATH_CSS = '_file/test.css ' ;
27
+ const TMP_PATH_CSS_PRODUCTION = ' _file/test-production.css ' ;
28
+ const TMP_PATH_CSS_DEVELOPER = '_file/test-developer .css ' ;
28
29
29
30
const ERROR_MESSAGE = 'Test exception ' ;
30
31
@@ -52,6 +53,10 @@ class ProcessorTest extends TestCase
52
53
* @var Temporary|MockObject
53
54
*/
54
55
private $ temporaryFileMock ;
56
+ /**
57
+ * @var DirectoryList|MockObject
58
+ */
59
+ private $ directoryListMock ;
55
60
56
61
/**
57
62
* Set up
@@ -69,12 +74,16 @@ protected function setUp(): void
69
74
$ this ->temporaryFileMock = $ this ->getMockBuilder (Temporary::class)
70
75
->disableOriginalConstructor ()
71
76
->getMock ();
77
+ $ this ->directoryListMock = $ this ->getMockBuilder (DirectoryList::class)
78
+ ->disableOriginalConstructor ()
79
+ ->getMock ();
72
80
73
81
$ this ->processor = new Processor (
74
82
$ this ->loggerMock ,
75
83
$ this ->appStateMock ,
76
84
$ this ->assetSourceMock ,
77
- $ this ->temporaryFileMock
85
+ $ this ->temporaryFileMock ,
86
+ $ this ->directoryListMock ,
78
87
);
79
88
}
80
89
@@ -89,7 +98,7 @@ public function testProcessContentException()
89
98
90
99
$ this ->appStateMock ->expects (self ::once ())
91
100
->method ('getMode ' )
92
- ->willReturn (State::MODE_DEVELOPER );
101
+ ->willReturn (State::MODE_PRODUCTION );
93
102
94
103
$ this ->assetSourceMock ->expects (self ::once ())
95
104
->method ('getContent ' )
@@ -120,7 +129,7 @@ public function testProcessContentEmpty()
120
129
121
130
$ this ->appStateMock ->expects (self ::once ())
122
131
->method ('getMode ' )
123
- ->willReturn (State::MODE_DEVELOPER );
132
+ ->willReturn (State::MODE_PRODUCTION );
124
133
125
134
$ this ->assetSourceMock ->expects (self ::once ())
126
135
->method ('getContent ' )
@@ -141,15 +150,15 @@ public function testProcessContentEmpty()
141
150
}
142
151
143
152
/**
144
- * Test for processContent method (not empty content)
153
+ * Test for processContent method in production mode (not empty content)
145
154
*/
146
155
public function testProcessContentNotEmpty ()
147
156
{
148
157
$ assetMock = $ this ->getAssetMock ();
149
158
150
159
$ this ->appStateMock ->expects (self ::once ())
151
160
->method ('getMode ' )
152
- ->willReturn (State::MODE_DEVELOPER );
161
+ ->willReturn (State::MODE_PRODUCTION );
153
162
154
163
$ this ->assetSourceMock ->expects (self ::once ())
155
164
->method ('getContent ' )
@@ -170,11 +179,46 @@ public function testProcessContentNotEmpty()
170
179
171
180
$ clearSymbol = ["\n" , "\r" , "\t" , ' ' ];
172
181
self ::assertEquals (
173
- trim (str_replace ($ clearSymbol , '' , file_get_contents (__DIR__ . '/ ' . self ::TMP_PATH_CSS ))),
182
+ trim (str_replace ($ clearSymbol , '' , file_get_contents (__DIR__ . '/ ' . self ::TMP_PATH_CSS_PRODUCTION ))),
174
183
trim (str_replace ($ clearSymbol , '' , $ this ->processor ->processContent ($ assetMock )))
175
184
);
176
185
}
177
186
187
+ /**
188
+ * Test for processContent method in developer mode (not empty content)
189
+ */
190
+ public function testProcessContentNotEmptyInDeveloperMode ()
191
+ {
192
+ $ assetMock = $ this ->getAssetMock ();
193
+
194
+ $ this ->appStateMock ->expects (self ::once ())
195
+ ->method ('getMode ' )
196
+ ->willReturn (State::MODE_DEVELOPER );
197
+
198
+ $ this ->assetSourceMock ->expects (self ::once ())
199
+ ->method ('getContent ' )
200
+ ->with ($ assetMock )
201
+ ->willReturn (self ::TEST_CONTENT );
202
+
203
+ $ this ->temporaryFileMock ->expects (self ::once ())
204
+ ->method ('createFile ' )
205
+ ->with (self ::ASSET_PATH , self ::TEST_CONTENT )
206
+ ->willReturn (__DIR__ . '/ ' . self ::TMP_PATH_LESS );
207
+
208
+ $ assetMock ->expects (self ::once ())
209
+ ->method ('getPath ' )
210
+ ->willReturn (self ::ASSET_PATH );
211
+
212
+ $ this ->loggerMock ->expects (self ::never ())
213
+ ->method ('critical ' );
214
+
215
+ $ clearSymbol = ["\n" , "\r" , "\t" , ' ' ];
216
+ self ::assertEquals (
217
+ trim (str_replace ($ clearSymbol , '' , file_get_contents (__DIR__ . '/ ' . self ::TMP_PATH_CSS_DEVELOPER ))),
218
+ trim (str_replace ($ clearSymbol , '' , $ this ->normalizeInlineSourceMap ($ this ->processor ->processContent ($ assetMock ))))
219
+ );
220
+ }
221
+
178
222
/**
179
223
* @return File|MockObject
180
224
*/
@@ -186,4 +230,34 @@ private function getAssetMock()
186
230
187
231
return $ assetMock ;
188
232
}
233
+
234
+ /**
235
+ * - find json part of sourcemap
236
+ * - url decode it
237
+ * - replace \/ with / in source filenames
238
+ * - remove absolute path in filename, make it a relative path
239
+ */
240
+ private function normalizeInlineSourceMap (string $ css ): string
241
+ {
242
+ $ regexBegin = 'sourceMappingURL=data:application/json, ' ;
243
+ $ regexEnd = '*/ ' ;
244
+ $ regex = '@ ' . preg_quote ($ regexBegin , '@ ' ) . '([^\*]+) ' . preg_quote ($ regexEnd , '@ ' ) . '@ ' ;
245
+
246
+ if (preg_match ($ regex , $ css , $ matches ) === 1 ) {
247
+ $ inlineSourceMapJson = $ matches [1 ];
248
+ $ inlineSourceMapJson = urldecode ($ inlineSourceMapJson );
249
+ $ inlineSourceMapJson = json_decode ($ inlineSourceMapJson , true , 512 , JSON_UNESCAPED_SLASHES );
250
+
251
+ $ relativeFilenames = [];
252
+ foreach ($ inlineSourceMapJson ['sources ' ] as $ filename ) {
253
+ $ relativeFilenames [] = str_replace (sprintf ('%s/ ' , BP ), '' , $ filename );
254
+ }
255
+ $ inlineSourceMapJson ['sources ' ] = $ relativeFilenames ;
256
+ $ inlineSourceMapJson = json_encode ($ inlineSourceMapJson , JSON_UNESCAPED_SLASHES );
257
+
258
+ $ css = preg_replace ($ regex , sprintf ('%s%s%s ' , $ regexBegin , $ inlineSourceMapJson , $ regexEnd ), $ css );
259
+ }
260
+
261
+ return $ css ;
262
+ }
189
263
}
0 commit comments