1+ <?php
2+
3+ use PlinCode \LaravelCleanArchitecture \Commands \GeneratePackageCommand ;
4+ use Illuminate \Filesystem \Filesystem ;
5+ use Illuminate \Support \Facades \File ;
6+
7+ describe ('GeneratePackageCommand ' , function () {
8+ beforeEach (function () {
9+ $ this ->filesystem = new Filesystem ();
10+ $ this ->command = new GeneratePackageCommand ($ this ->filesystem );
11+ $ this ->tempPath = sys_get_temp_dir () . '/test-package- ' . uniqid ();
12+
13+ // Mock the output to avoid writeln errors
14+ $ mockOutput = mock ('Symfony\Component\Console\Output\OutputInterface ' );
15+ $ mockOutput ->shouldReceive ('writeln ' )->andReturn ();
16+ $ mockOutput ->shouldReceive ('write ' )->andReturn ();
17+
18+ $ reflection = new ReflectionClass ($ this ->command );
19+ $ outputProperty = $ reflection ->getProperty ('output ' );
20+ $ outputProperty ->setAccessible (true );
21+ $ outputProperty ->setValue ($ this ->command , $ mockOutput );
22+ });
23+
24+ afterEach (function () {
25+ if (is_dir ($ this ->tempPath )) {
26+ $ this ->filesystem ->deleteDirectory ($ this ->tempPath );
27+ }
28+ });
29+
30+ it ('has correct command signature and description ' , function () {
31+ expect ($ this ->command ->getName ())->toBe ('clean-arch:generate-package ' );
32+ expect ($ this ->command ->getDescription ())->toBe ('Generate a new Laravel package with Clean Architecture structure ' );
33+ });
34+
35+ it ('has required arguments ' , function () {
36+ $ definition = $ this ->command ->getDefinition ();
37+
38+ expect ($ definition ->hasArgument ('name ' ))->toBeTrue ();
39+ expect ($ definition ->hasArgument ('vendor ' ))->toBeTrue ();
40+ expect ($ definition ->getArgument ('name ' )->getDescription ())->toBe ('The name of the package ' );
41+ expect ($ definition ->getArgument ('vendor ' )->getDescription ())->toBe ('The vendor name ' );
42+ });
43+
44+ it ('has correct options ' , function () {
45+ $ definition = $ this ->command ->getDefinition ();
46+
47+ expect ($ definition ->hasOption ('path ' ))->toBeTrue ();
48+ expect ($ definition ->hasOption ('force ' ))->toBeTrue ();
49+ expect ($ definition ->getOption ('path ' )->getDescription ())->toBe ('Custom path for the package ' );
50+ expect ($ definition ->getOption ('force ' )->getDescription ())->toBe ('Overwrite existing files ' );
51+ });
52+
53+ it ('can create package structure ' , function () {
54+ $ reflection = new ReflectionClass ($ this ->command );
55+ $ method = $ reflection ->getMethod ('createPackageStructure ' );
56+ $ method ->setAccessible (true );
57+
58+ $ packageName = 'test-package ' ;
59+ $ studlyName = 'TestPackage ' ;
60+ $ namespace = 'TestVendor \\TestPackage ' ;
61+ $ vendor = 'test-vendor ' ;
62+
63+ // Mock the filesystem to avoid actual file creation
64+ $ mockFilesystem = mock (Filesystem::class);
65+ $ mockFilesystem ->shouldReceive ('isDirectory ' )->andReturn (false );
66+ $ mockFilesystem ->shouldReceive ('makeDirectory ' )->andReturn (true );
67+ $ mockFilesystem ->shouldReceive ('put ' )->andReturn (true );
68+ $ mockFilesystem ->shouldReceive ('exists ' )->andReturn (true );
69+ $ mockFilesystem ->shouldReceive ('get ' )->andReturn ('stub content ' );
70+
71+ $ reflection ->getProperty ('files ' )->setValue ($ this ->command , $ mockFilesystem );
72+
73+ $ result = $ method ->invoke ($ this ->command , $ this ->tempPath , $ packageName , $ studlyName , $ namespace , $ vendor );
74+ expect ($ result )->toBeNull (); // Void method returns null
75+ });
76+
77+ it ('can create package composer.json ' , function () {
78+ $ reflection = new ReflectionClass ($ this ->command );
79+ $ method = $ reflection ->getMethod ('createPackageComposer ' );
80+ $ method ->setAccessible (true );
81+
82+ $ packageName = 'test-package ' ;
83+ $ studlyName = 'TestPackage ' ;
84+ $ namespace = 'TestVendor \\TestPackage ' ;
85+ $ vendor = 'test-vendor ' ;
86+
87+ // Create temp directory
88+ $ this ->filesystem ->makeDirectory ($ this ->tempPath , 0755 , true );
89+
90+ $ method ->invoke ($ this ->command , $ this ->tempPath , $ packageName , $ studlyName , $ namespace , $ vendor );
91+
92+ expect (file_exists ($ this ->tempPath . '/composer.json ' ))->toBeTrue ();
93+
94+ $ composerContent = json_decode (file_get_contents ($ this ->tempPath . '/composer.json ' ), true );
95+ expect ($ composerContent ['name ' ])->toBe ('test-vendor/test-package ' );
96+ expect ($ composerContent ['description ' ])->toBe ('Laravel package for TestPackage ' );
97+ expect ($ composerContent ['type ' ])->toBe ('library ' );
98+ });
99+
100+ it ('can create service provider ' , function () {
101+ $ reflection = new ReflectionClass ($ this ->command );
102+ $ method = $ reflection ->getMethod ('createPackageServiceProvider ' );
103+ $ method ->setAccessible (true );
104+
105+ $ studlyName = 'TestPackage ' ;
106+ $ namespace = 'TestVendor \\TestPackage ' ;
107+
108+ // Create a mock stub content
109+ $ stubContent = '<?php namespace {{Namespace}}; class {{StudlyName}}ServiceProvider {} ' ;
110+
111+ // Mock filesystem to return stub content
112+ $ mockFilesystem = mock (Filesystem::class);
113+ $ mockFilesystem ->shouldReceive ('exists ' )->andReturn (true );
114+ $ mockFilesystem ->shouldReceive ('get ' )->andReturn ($ stubContent );
115+ $ mockFilesystem ->shouldReceive ('put ' )->andReturn (true );
116+
117+ $ reflection ->getProperty ('files ' )->setValue ($ this ->command , $ mockFilesystem );
118+
119+ $ result = $ method ->invoke ($ this ->command , $ this ->tempPath , $ studlyName , $ namespace );
120+ expect ($ result )->toBeNull (); // Void method returns null
121+ });
122+
123+ it ('can create package model ' , function () {
124+ $ reflection = new ReflectionClass ($ this ->command );
125+ $ method = $ reflection ->getMethod ('createPackageModel ' );
126+ $ method ->setAccessible (true );
127+
128+ $ studlyName = 'TestPackage ' ;
129+ $ namespace = 'TestVendor \\TestPackage ' ;
130+
131+ // Mock filesystem and stub
132+ $ mockFilesystem = mock (Filesystem::class);
133+ $ mockFilesystem ->shouldReceive ('exists ' )->andReturn (true );
134+ $ mockFilesystem ->shouldReceive ('get ' )->andReturn ('<?php namespace {{Namespace}}; class {{StudlyName}} {} ' );
135+ $ mockFilesystem ->shouldReceive ('put ' )->andReturn (true );
136+
137+ $ reflection ->getProperty ('files ' )->setValue ($ this ->command , $ mockFilesystem );
138+
139+ $ result = $ method ->invoke ($ this ->command , $ this ->tempPath , $ studlyName , $ namespace );
140+ expect ($ result )->toBeNull (); // Void method returns null
141+ });
142+
143+ it ('can create package service ' , function () {
144+ $ reflection = new ReflectionClass ($ this ->command );
145+ $ method = $ reflection ->getMethod ('createPackageService ' );
146+ $ method ->setAccessible (true );
147+
148+ $ studlyName = 'TestPackage ' ;
149+ $ namespace = 'TestVendor \\TestPackage ' ;
150+
151+ // Mock filesystem and stub
152+ $ mockFilesystem = mock (Filesystem::class);
153+ $ mockFilesystem ->shouldReceive ('exists ' )->andReturn (true );
154+ $ mockFilesystem ->shouldReceive ('get ' )->andReturn ('<?php namespace {{Namespace}}; class {{StudlyName}}Service {} ' );
155+ $ mockFilesystem ->shouldReceive ('put ' )->andReturn (true );
156+
157+ $ reflection ->getProperty ('files ' )->setValue ($ this ->command , $ mockFilesystem );
158+
159+ $ result = $ method ->invoke ($ this ->command , $ this ->tempPath , $ studlyName , $ namespace );
160+ expect ($ result )->toBeNull (); // Void method returns null
161+ });
162+
163+ it ('can create package readme ' , function () {
164+ $ reflection = new ReflectionClass ($ this ->command );
165+ $ method = $ reflection ->getMethod ('createPackageReadme ' );
166+ $ method ->setAccessible (true );
167+
168+ $ packageName = 'test-package ' ;
169+ $ studlyName = 'TestPackage ' ;
170+ $ vendor = 'test-vendor ' ;
171+
172+ // Mock filesystem and stub
173+ $ mockFilesystem = mock (Filesystem::class);
174+ $ mockFilesystem ->shouldReceive ('exists ' )->andReturn (true );
175+ $ mockFilesystem ->shouldReceive ('get ' )->andReturn ('# {{PackageName}} by {{VendorName}} ' );
176+ $ mockFilesystem ->shouldReceive ('put ' )->andReturn (true );
177+
178+ $ reflection ->getProperty ('files ' )->setValue ($ this ->command , $ mockFilesystem );
179+
180+ $ result = $ method ->invoke ($ this ->command , $ this ->tempPath , $ packageName , $ studlyName , $ vendor );
181+ expect ($ result )->toBeNull (); // Void method returns null
182+ });
183+
184+ it ('throws exception when stub file not found ' , function () {
185+ $ reflection = new ReflectionClass ($ this ->command );
186+ $ method = $ reflection ->getMethod ('getStub ' );
187+ $ method ->setAccessible (true );
188+
189+ // Mock filesystem to return false for exists
190+ $ mockFilesystem = mock (Filesystem::class);
191+ $ mockFilesystem ->shouldReceive ('exists ' )->andReturn (false );
192+
193+ $ reflection ->getProperty ('files ' )->setValue ($ this ->command , $ mockFilesystem );
194+
195+ expect (function () use ($ method ) {
196+ $ method ->invoke ($ this ->command , 'non-existent-stub ' );
197+ })->toThrow (Exception::class, 'Stub file not found ' );
198+ });
199+
200+ it ('can get stub content when file exists ' , function () {
201+ $ reflection = new ReflectionClass ($ this ->command );
202+ $ method = $ reflection ->getMethod ('getStub ' );
203+ $ method ->setAccessible (true );
204+
205+ $ stubContent = '<?php // Test stub content ' ;
206+
207+ // Mock filesystem to return stub content
208+ $ mockFilesystem = mock (Filesystem::class);
209+ $ mockFilesystem ->shouldReceive ('exists ' )->andReturn (true );
210+ $ mockFilesystem ->shouldReceive ('get ' )->andReturn ($ stubContent );
211+
212+ $ reflection ->getProperty ('files ' )->setValue ($ this ->command , $ mockFilesystem );
213+
214+ $ result = $ method ->invoke ($ this ->command , 'test-stub ' );
215+ expect ($ result )->toBe ($ stubContent );
216+ });
217+ });
0 commit comments