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,230 @@ 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 getPackagesForAutoDiscovery
113
+ */
114
+ public function testBundlesAutoDiscovery (Package $ package , array $ expectedManifest )
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
+ $ devPackages = $ package ->isDev () ? [['name ' => $ package ->getName ()]] : [];
124
+
125
+ $ rootPackage = $ this ->mockRootPackage ($ package ->getExtra ());
126
+ $ flex = $ this ->mockFlex ($ io , $ rootPackage , $ recipe , [], ['packages-dev ' => $ devPackages ]);
127
+ $ flex ->record ($ this ->mockPackageEvent ($ package ));
128
+ $ flex ->install ($ this ->mockFlexEvent ());
129
+ }
130
+
131
+ public function getPackagesForAutoDiscovery (): array
132
+ {
133
+ $ return = [];
134
+
135
+ $ versions = ['1.0 ' , '2.0-dev ' ];
136
+ $ packages = self ::getTestPackages ();
137
+
138
+ foreach ($ packages as $ name => $ info ) {
139
+ foreach ($ versions as $ version ) {
140
+ $ package = new Package ($ name , $ version , $ version );
141
+ $ package ->setAutoload ($ info ['autoload ' ]);
142
+ if (isset ($ info ['type ' ])) {
143
+ $ package ->setType ($ info ['type ' ]);
144
+ }
145
+
146
+ $ expectedManifest = [
147
+ 'origin ' => sprintf ('%s:%s@auto-generated recipe ' , $ package ->getName (),
148
+ $ package ->getPrettyVersion ()),
149
+ 'manifest ' => ['bundles ' => []],
150
+ ];
151
+
152
+ $ envs = $ package ->isDev () ? ['dev ' , 'test ' ] : ['all ' ];
153
+ foreach ($ info ['bundles ' ] as $ bundle ) {
154
+ $ expectedManifest ['manifest ' ]['bundles ' ][$ bundle ] = $ envs ;
155
+ }
156
+
157
+ $ return [] = [$ package , $ expectedManifest ];
158
+ }
159
+ }
160
+
161
+ return $ return ;
162
+ }
163
+
164
+ public static function getTestPackages (): array
165
+ {
166
+ return [
167
+ 'symfony/debug-bundle ' => [
168
+ 'autoload ' => ['psr-4 ' => ['Symfony \\Bundle \\DebugBundle \\' => '' ]],
169
+ 'bundles ' => ['Symfony \\Bundle \\DebugBundle \\DebugBundle ' ],
170
+ ],
171
+ 'symfony/dummy ' => [
172
+ 'autoload ' => ['psr-4 ' => ['Symfony \\Bundle \\FirstDummyBundle \\' => 'FirstDummyBundle/ ' , 'Symfony \\Bundle \\SecondDummyBundle \\' => 'SecondDummyBundle/ ' ]],
173
+ 'bundles ' => ['Symfony \\Bundle \\FirstDummyBundle \\FirstDummyBundle ' , 'Symfony \\Bundle \\SecondDummyBundle \\SecondDummyBundle ' ],
174
+ ],
175
+ 'doctrine/doctrine-cache-bundle ' => [
176
+ 'autoload ' => ['psr-4 ' => ['Doctrine \\Bundle \\DoctrineCacheBundle \\' => '' ]],
177
+ 'bundles ' => ['Doctrine \\Bundle \\DoctrineCacheBundle \\DoctrineCacheBundle ' ],
178
+ ],
179
+ 'eightpoints/guzzle-bundle ' => [
180
+ 'autoload ' => ['psr-0 ' => ['EightPoints \\Bundle \\GuzzleBundle ' => '' ]],
181
+ 'bundles ' => ['EightPoints \\Bundle \\GuzzleBundle \\GuzzleBundle ' ],
182
+ ],
183
+ 'easycorp/easy-security-bundle ' => [
184
+ 'autoload ' => ['psr-4 ' => ['EasyCorp \\Bundle \\EasySecurityBundle \\' => '' ]],
185
+ 'bundles ' => ['EasyCorp \\Bundle \\EasySecurityBundle \\EasySecurityBundle ' ],
186
+ ],
187
+ 'symfony-cmf/routing-bundle ' => [
188
+ 'autoload ' => ['psr-4 ' => ['Symfony \\Cmf \\Bundle \\RoutingBundle \\' => '' ]],
189
+ 'bundles ' => ['Symfony \\Cmf \\Bundle \\RoutingBundle \\CmfRoutingBundle ' ],
190
+ ],
191
+ 'easycorp/easy-deploy-bundle ' => [
192
+ 'autoload ' => ['psr-4 ' => ['EasyCorp \\Bundle \\EasyDeployBundle \\' => 'src/ ' ]],
193
+ 'bundles ' => ['EasyCorp \\Bundle \\EasyDeployBundle \\EasyDeployBundle ' ],
194
+ ],
195
+ 'easycorp/easy-deploy-bundle ' => [
196
+ 'autoload ' => ['psr-4 ' => ['EasyCorp \\Bundle \\EasyDeployBundle \\' => ['src ' , 'tests ' ]]],
197
+ 'bundles ' => ['EasyCorp \\Bundle \\EasyDeployBundle \\EasyDeployBundle ' ],
198
+ ],
199
+ 'web-token/jwt-bundle ' => [
200
+ 'autoload ' => ['psr-4 ' => ['Jose \\Bundle \\JoseFramework \\' => ['' ]]],
201
+ 'bundles ' => ['Jose \\Bundle \\JoseFramework \\JoseFrameworkBundle ' ],
202
+ ],
203
+ 'sylius/shop-api-plugin ' => [
204
+ 'autoload ' => ['psr-4 ' => ['Sylius \\ShopApiPlugin \\' => 'src/ ' ]],
205
+ 'bundles ' => ['Sylius \\ShopApiPlugin \\ShopApiPlugin ' ],
206
+ 'type ' => 'sylius-plugin ' ,
207
+ ],
208
+ 'dunglas/sylius-acme-plugin ' => [
209
+ 'autoload ' => ['psr-4 ' => ['Dunglas \\SyliusAcmePlugin \\' => 'src/ ' ]],
210
+ 'bundles ' => ['Dunglas \\SyliusAcmePlugin \\DunglasSyliusAcmePlugin ' ],
211
+ 'type ' => 'sylius-plugin ' ,
212
+ ],
213
+ ];
214
+ }
215
+
216
+ private function mockPackageEvent (Package $ package ): PackageEvent
217
+ {
218
+ $ event = $ this ->getMockBuilder (PackageEvent::class, ['getOperation ' ])->disableOriginalConstructor ()->getMock ();
219
+ $ event ->expects ($ this ->any ())->method ('getOperation ' )->willReturn (new InstallOperation ($ package ));
220
+
221
+ return $ event ;
222
+ }
223
+
224
+ private function mockConfigurator (Recipe $ recipe = null ): Configurator
225
+ {
226
+ $ configurator = $ this ->getMockBuilder (Configurator::class)->disableOriginalConstructor ()->getMock ();
227
+
228
+ if ($ recipe ) {
229
+ $ configurator ->expects ($ this ->once ())->method ('install ' )->with ($ this ->equalTo ($ recipe ));
230
+ }
231
+
232
+ return $ configurator ;
233
+ }
234
+
235
+ private function mockDownloader (array $ recipes = []): Downloader
236
+ {
237
+ $ downloader = $ this ->getMockBuilder (Downloader::class)->disableOriginalConstructor ()->getMock ();
238
+
239
+ $ downloader ->expects ($ this ->once ())->method ('getRecipes ' )->willReturn ($ recipes );
240
+ $ downloader ->expects ($ this ->once ())->method ('isEnabled ' )->willReturn (true );
241
+
242
+ return $ downloader ;
243
+ }
244
+
245
+ private function mockLocker (array $ lockData = []): Locker
246
+ {
247
+ $ locker = $ this ->getMockBuilder (Locker::class)->disableOriginalConstructor ()->getMock ();
248
+
249
+ $ lockData = array_merge (['content-hash ' => 'random ' , 'packages-dev ' => []], $ lockData );
250
+ $ locker ->expects ($ this ->any ())->method ('getLockData ' )->willReturn ($ lockData );
251
+
252
+ return $ locker ;
253
+ }
254
+
255
+ private function mockComposer (Locker $ locker , RootPackageInterface $ package , Config $ config = null ): Composer
256
+ {
257
+ if (null === $ config ) {
258
+ $ config = $ this ->getMockBuilder (Config::class)->getMock ();
259
+ $ config ->expects ($ this ->any ())->method ('get ' )->willReturn (__DIR__ .'/Fixtures/vendor ' );
260
+ }
261
+
262
+ $ composer = new Composer ();
263
+ $ composer ->setConfig ($ config );
264
+ $ composer ->setLocker ($ locker );
265
+ $ composer ->setPackage ($ package );
266
+
267
+ return $ composer ;
268
+ }
269
+
270
+ private function mockRootPackage (array $ extraData = []): RootPackageInterface
271
+ {
272
+ $ package = $ this ->getMockBuilder (RootPackageInterface::class)->disableOriginalConstructor ()->getMock ();
273
+
274
+ $ package ->expects ($ this ->any ())->method ('getExtra ' )->willReturn ($ extraData );
275
+
276
+ return $ package ;
277
+ }
278
+
279
+ private function mockLock (): Lock
280
+ {
281
+ $ lock = $ this ->getMockBuilder (Lock::class)->disableOriginalConstructor ()->getMock ();
282
+ $ lock ->expects ($ this ->any ())->method ('has ' )->willReturn (false );
283
+
284
+ return $ lock ;
285
+ }
286
+
287
+ private function mockFlexEvent (): Event
288
+ {
289
+ return $ this ->getMockBuilder (Event::class)->disableOriginalConstructor ()->getMock ();
290
+ }
291
+
292
+ private function mockManager (): RepositoryManager
293
+ {
294
+ $ manager = $ this ->getMockBuilder (RepositoryManager::class)->disableOriginalConstructor ()->getMock ();
295
+
296
+ $ localRepo = $ this ->getMockBuilder (WritableRepositoryInterface::class)->disableOriginalConstructor ()->getMock ();
297
+ $ manager ->expects ($ this ->once ())->method ('getLocalRepository ' )->willReturn ($ localRepo );
298
+
299
+ return $ manager ;
300
+ }
301
+
302
+ private function mockFlex (BufferIO $ io , RootPackageInterface $ package , Recipe $ recipe = null , array $ recipes = [], array $ lockerData = []): Flex
303
+ {
304
+ $ composer = $ this ->mockComposer ($ this ->mockLocker ($ lockerData ), $ package );
305
+
306
+ $ configurator = $ this ->mockConfigurator ($ recipe );
307
+ $ downloader = $ this ->mockDownloader ($ recipes );
308
+ $ lock = $ this ->mockLock ();
309
+
310
+ return \Closure::bind (function () use ($ composer , $ io , $ configurator , $ downloader , $ lock ) {
311
+ $ flex = new Flex ();
312
+ $ flex ->composer = $ composer ;
313
+ $ flex ->io = $ io ;
314
+ $ flex ->configurator = $ configurator ;
315
+ $ flex ->downloader = $ downloader ;
316
+ $ flex ->runningCommand = function () {
317
+ };
318
+ $ flex ->options = new Options (['config-dir ' => 'config ' , 'var-dir ' => 'var ' ]);
319
+ $ flex ->lock = $ lock ;
320
+
321
+ return $ flex ;
322
+ }, null , Flex::class)->__invoke ();
323
+ }
145
324
}
0 commit comments