12
12
namespace Symfony \Flex \Tests ;
13
13
14
14
use Composer \Composer ;
15
+ use Composer \Config ;
15
16
use Composer \DependencyResolver \Operation \InstallOperation ;
16
17
use Composer \Factory ;
17
18
use Composer \Installer \PackageEvent ;
@@ -37,10 +38,6 @@ class FlexTest extends TestCase
37
38
{
38
39
public function testPostInstall ()
39
40
{
40
- $ package = new Package ('dummy/dummy ' , '1.0.0 ' , '1.0.0 ' );
41
- $ event = $ this ->getMockBuilder (PackageEvent::class)->disableOriginalConstructor ()->getMock ();
42
- $ event ->expects ($ this ->any ())->method ('getOperation ' )->willReturn (new InstallOperation ($ package ));
43
-
44
41
$ data = [
45
42
'manifests ' => [
46
43
'dummy/dummy ' => [
@@ -61,40 +58,14 @@ public function testPostInstall()
61
58
],
62
59
];
63
60
64
- $ configurator = $ this ->getMockBuilder (Configurator::class)->disableOriginalConstructor ()->getMock ();
65
- $ configurator ->expects ($ this ->once ())->method ('install ' )->with ($ this ->equalTo (new Recipe ($ package , 'dummy/dummy ' , 'install ' , $ data ['manifests ' ]['dummy/dummy ' ], $ data ['locks ' ]['dummy/dummy ' ])));
66
-
67
- $ downloader = $ this ->getMockBuilder (Downloader::class)->disableOriginalConstructor ()->getMock ();
68
- $ downloader ->expects ($ this ->once ())->method ('getRecipes ' )->willReturn ($ data );
69
- $ downloader ->expects ($ this ->once ())->method ('isEnabled ' )->willReturn (true );
70
-
71
61
$ io = new BufferIO ('' , OutputInterface::VERBOSITY_VERBOSE );
72
- $ locker = $ this ->getMockBuilder (Locker::class)->disableOriginalConstructor ()->getMock ();
73
- $ locker ->expects ($ this ->any ())->method ('getLockData ' )->willReturn (['content-hash ' => 'random ' ]);
74
-
75
- $ package = $ this ->getMockBuilder (RootPackageInterface::class)->disableOriginalConstructor ()->getMock ();
76
- $ package ->expects ($ this ->any ())->method ('getExtra ' )->willReturn (['symfony ' => ['allow-contrib ' => true ]]);
77
-
78
- $ lock = $ this ->getMockBuilder (Lock::class)->disableOriginalConstructor ()->getMock ();
79
- $ lock ->expects ($ this ->any ())->method ('has ' )->willReturn (false );
80
-
81
- $ flex = \Closure::bind (function () use ($ configurator , $ downloader , $ io , $ locker , $ package , $ lock ) {
82
- $ flex = new Flex ();
83
- $ flex ->composer = new Composer ();
84
- $ flex ->composer ->setLocker ($ locker );
85
- $ flex ->composer ->setPackage ($ package );
86
- $ flex ->io = $ io ;
87
- $ flex ->configurator = $ configurator ;
88
- $ flex ->downloader = $ downloader ;
89
- $ flex ->runningCommand = function () {
90
- };
91
- $ flex ->options = new Options (['config-dir ' => 'config ' , 'var-dir ' => 'var ' ]);
92
- $ flex ->lock = $ lock ;
62
+ $ package = new Package ('dummy/dummy ' , '1.0.0 ' , '1.0.0 ' );
63
+ $ recipe = new Recipe ($ package , 'dummy/dummy ' , 'install ' , $ data ['manifests ' ]['dummy/dummy ' ], $ data ['locks ' ]['dummy/dummy ' ]);
93
64
94
- return $ flex ;
95
- }, null , Flex::class)-> __invoke ( );
96
- $ flex ->record ($ event );
97
- $ flex ->install ($ this ->getMockBuilder (Event::class)-> disableOriginalConstructor ()-> getMock ());
65
+ $ rootPackage = $ this -> mockRootPackage ([ ' symfony ' => [ ' allow-contrib ' => true ]]) ;
66
+ $ flex = $ this -> mockFlex ( $ io , $ rootPackage , $ recipe , $ data );
67
+ $ flex ->record ($ this -> mockPackageEvent ( $ package ) );
68
+ $ flex ->install ($ this ->mockFlexEvent ());
98
69
99
70
$ expected = [
100
71
'' ,
@@ -124,22 +95,210 @@ public function testPostInstall()
124
95
public function testActivateLoadsClasses ()
125
96
{
126
97
$ io = new BufferIO ('' , OutputInterface::VERBOSITY_VERBOSE );
127
- $ composer = new Composer ();
128
- $ composer ->setConfig (Factory::createConfig ($ io ));
129
- $ package = $ this ->getMockBuilder (RootPackageInterface::class)->disableOriginalConstructor ()->getMock ();
130
- $ package ->method ('getExtra ' )->willReturn (['symfony ' => ['allow-contrib ' => true ]]);
98
+
99
+ $ package = $ this ->mockRootPackage (['symfony ' => ['allow-contrib ' => true ]]);
131
100
$ package ->method ('getRequires ' )->willReturn ([new Link ('dummy ' , 'symfony/flex ' )]);
132
- $ composer ->setPackage ($ package );
133
- $ localRepo = $ this ->getMockBuilder (WritableRepositoryInterface::class)->disableOriginalConstructor ()->getMock ();
134
- $ manager = $ this ->getMockBuilder (RepositoryManager::class)->disableOriginalConstructor ()->getMock ();
135
- $ manager ->expects ($ this ->once ())
136
- ->method ('getLocalRepository ' )
137
- ->willReturn ($ localRepo );
138
- $ composer ->setRepositoryManager ($ manager );
101
+
102
+ $ composer = $ this ->mockComposer ($ this ->mockLocker (), $ package , Factory::createConfig ($ io ));
103
+ $ composer ->setRepositoryManager ($ this ->mockManager ());
139
104
140
105
$ flex = new Flex ();
141
106
$ flex ->activate ($ composer , $ io );
142
107
143
108
$ this ->assertTrue (class_exists (Response::class, false ));
144
109
}
110
+
111
+ /**
112
+ * @dataProvider getPackagesWithExtraBundles
113
+ */
114
+ public function testExtraBundles (Package $ package , array $ expectedManifest , string $ expectedExceptionClass = null )
115
+ {
116
+ $ io = new BufferIO ('' , OutputInterface::VERBOSITY_VERBOSE );
117
+
118
+ $ recipe = null ;
119
+ if (\count ($ expectedManifest )) {
120
+ $ recipe = new Recipe ($ package , $ package ->getName (), 'install ' , $ expectedManifest );
121
+ }
122
+
123
+ if ($ expectedExceptionClass ) {
124
+ $ this ->expectException ($ expectedExceptionClass );
125
+ }
126
+
127
+ $ rootPackage = $ this ->mockRootPackage ($ package ->getExtra ());
128
+ $ flex = $ this ->mockFlex ($ io , $ rootPackage , $ recipe , []);
129
+ $ flex ->record ($ this ->mockPackageEvent ($ package ));
130
+ $ flex ->install ($ this ->mockFlexEvent ());
131
+ }
132
+
133
+ public function getPackagesWithExtraBundles (): array
134
+ {
135
+ $ extraBundle = new Package ('dummy/dummy ' , '1.0.0 ' , '1.0.0 ' );
136
+ $ extraBundle ->setExtra (['symfony ' => ['bundles ' => ['Dummy\Dummy ' => ['all ' ]]]]);
137
+
138
+ $ emptyExtraBundles = new Package ('dummy/dummy2 ' , '1.0.0 ' , '1.0.0 ' );
139
+ $ emptyExtraBundles ->setExtra (['symfony ' => ['bundles ' => []]]);
140
+
141
+ $ noExtraBundle = new Package ('symfony/debug-bundle ' , '1.0.0 ' , '1.0.0 ' );
142
+ $ noExtraBundle ->setAutoload (['psr-4 ' => ['Symfony \\Bundle \\DebugBundle \\' => '' ]]);
143
+
144
+ $ invalidExtraBundle = new Package ('dummy/dummy3 ' , '1.0.0 ' , '1.0.0 ' );
145
+ $ invalidExtraBundle ->setExtra (['symfony ' => ['bundles ' => 'BundleName ' ]]);
146
+
147
+ $ invalidExtraBundleEnvs = new Package ('dummy/dummy4 ' , '1.0.0 ' , '1.0.0 ' );
148
+ $ invalidExtraBundleEnvs ->setExtra (['symfony ' => ['bundles ' => ['Dummy\Dummy ' => 'all ' ]]]);
149
+
150
+ $ invalidExtraBundleNonStringEnv = new Package ('dummy/dummy5 ' , '1.0.0 ' , '1.0.0 ' );
151
+ $ invalidExtraBundleNonStringEnv ->setExtra (['symfony ' => ['bundles ' => ['Dummy\Dummy ' => [['all ' ]]]]]);
152
+
153
+ return [
154
+ [
155
+ $ extraBundle ,
156
+ [
157
+ 'origin ' => sprintf ('%s:%s@auto-generated recipe ' , $ extraBundle ->getName (), $ extraBundle ->getPrettyVersion ()),
158
+ 'manifest ' => [
159
+ 'bundles ' => [
160
+ 'Dummy\Dummy ' => ['all ' ],
161
+ ],
162
+ ],
163
+ ],
164
+ ],
165
+ [
166
+ $ emptyExtraBundles ,
167
+ [],
168
+ ],
169
+ [
170
+ $ noExtraBundle ,
171
+ [
172
+ 'origin ' => sprintf ('%s:%s@auto-generated recipe ' , $ noExtraBundle ->getName (), $ noExtraBundle ->getPrettyVersion ()),
173
+ 'manifest ' => [
174
+ 'bundles ' => [
175
+ 'Symfony\Bundle\DebugBundle\DebugBundle ' => ['all ' ],
176
+ ],
177
+ ],
178
+ ],
179
+ ],
180
+ [
181
+ $ invalidExtraBundle ,
182
+ [],
183
+ \InvalidArgumentException::class,
184
+ ],
185
+ [
186
+ $ invalidExtraBundleEnvs ,
187
+ [],
188
+ \InvalidArgumentException::class,
189
+ ],
190
+ [
191
+ $ invalidExtraBundleNonStringEnv ,
192
+ [],
193
+ \InvalidArgumentException::class,
194
+ ],
195
+ ];
196
+ }
197
+
198
+ private function mockPackageEvent (Package $ package ): PackageEvent
199
+ {
200
+ $ event = $ this ->getMockBuilder (PackageEvent::class, ['getOperation ' ])->disableOriginalConstructor ()->getMock ();
201
+ $ event ->expects ($ this ->any ())->method ('getOperation ' )->willReturn (new InstallOperation ($ package ));
202
+
203
+ return $ event ;
204
+ }
205
+
206
+ private function mockConfigurator (Recipe $ recipe = null ): Configurator
207
+ {
208
+ $ configurator = $ this ->getMockBuilder (Configurator::class)->disableOriginalConstructor ()->getMock ();
209
+
210
+ if ($ recipe ) {
211
+ $ configurator ->expects ($ this ->once ())->method ('install ' )->with ($ this ->equalTo ($ recipe ));
212
+ }
213
+
214
+ return $ configurator ;
215
+ }
216
+
217
+ private function mockDownloader (array $ recipes = []): Downloader
218
+ {
219
+ $ downloader = $ this ->getMockBuilder (Downloader::class)->disableOriginalConstructor ()->getMock ();
220
+
221
+ $ downloader ->expects ($ this ->once ())->method ('getRecipes ' )->willReturn ($ recipes );
222
+ $ downloader ->expects ($ this ->once ())->method ('isEnabled ' )->willReturn (true );
223
+
224
+ return $ downloader ;
225
+ }
226
+
227
+ private function mockLocker (array $ lockData = []): Locker
228
+ {
229
+ $ locker = $ this ->getMockBuilder (Locker::class)->disableOriginalConstructor ()->getMock ();
230
+
231
+ $ locker ->expects ($ this ->any ())->method ('getLockData ' )->willReturn (['content-hash ' => 'random ' , 'packages-dev ' => []] + $ lockData );
232
+
233
+ return $ locker ;
234
+ }
235
+
236
+ private function mockComposer (Locker $ locker , RootPackageInterface $ package , Config $ config = null ): Composer
237
+ {
238
+ if (null === $ config ) {
239
+ $ config = $ this ->getMockBuilder (Config::class)->getMock ();
240
+ $ config ->expects ($ this ->any ())->method ('get ' )->willReturn (__DIR__ .'/Fixtures/vendor ' );
241
+ }
242
+
243
+ $ composer = new Composer ();
244
+ $ composer ->setConfig ($ config );
245
+ $ composer ->setLocker ($ locker );
246
+ $ composer ->setPackage ($ package );
247
+
248
+ return $ composer ;
249
+ }
250
+
251
+ private function mockRootPackage (array $ extraData = []): RootPackageInterface
252
+ {
253
+ $ package = $ this ->getMockBuilder (RootPackageInterface::class)->disableOriginalConstructor ()->getMock ();
254
+
255
+ $ package ->expects ($ this ->any ())->method ('getExtra ' )->willReturn ($ extraData );
256
+
257
+ return $ package ;
258
+ }
259
+
260
+ private function mockLock (): Lock
261
+ {
262
+ $ lock = $ this ->getMockBuilder (Lock::class)->disableOriginalConstructor ()->getMock ();
263
+ $ lock ->expects ($ this ->any ())->method ('has ' )->willReturn (false );
264
+
265
+ return $ lock ;
266
+ }
267
+
268
+ private function mockFlexEvent (): Event
269
+ {
270
+ return $ this ->getMockBuilder (Event::class)->disableOriginalConstructor ()->getMock ();
271
+ }
272
+
273
+ private function mockManager (): RepositoryManager
274
+ {
275
+ $ manager = $ this ->getMockBuilder (RepositoryManager::class)->disableOriginalConstructor ()->getMock ();
276
+
277
+ $ localRepo = $ this ->getMockBuilder (WritableRepositoryInterface::class)->disableOriginalConstructor ()->getMock ();
278
+ $ manager ->expects ($ this ->once ())->method ('getLocalRepository ' )->willReturn ($ localRepo );
279
+
280
+ return $ manager ;
281
+ }
282
+
283
+ private function mockFlex (BufferIO $ io , RootPackageInterface $ package , Recipe $ recipe = null , array $ recipes = []): Flex
284
+ {
285
+ $ composer = $ this ->mockComposer ($ this ->mockLocker (), $ package );
286
+ $ configurator = $ this ->mockConfigurator ($ recipe );
287
+ $ downloader = $ this ->mockDownloader ($ recipes );
288
+ $ lock = $ this ->mockLock ();
289
+
290
+ return \Closure::bind (function () use ($ composer , $ io , $ configurator , $ downloader , $ lock ) {
291
+ $ flex = new Flex ();
292
+ $ flex ->composer = $ composer ;
293
+ $ flex ->io = $ io ;
294
+ $ flex ->configurator = $ configurator ;
295
+ $ flex ->downloader = $ downloader ;
296
+ $ flex ->runningCommand = function () {
297
+ };
298
+ $ flex ->options = new Options (['config-dir ' => 'config ' , 'var-dir ' => 'var ' ]);
299
+ $ flex ->lock = $ lock ;
300
+
301
+ return $ flex ;
302
+ }, null , Flex::class)->__invoke ();
303
+ }
145
304
}
0 commit comments