44
55use PhpParser \Node \Expr \Variable ;
66use PhpParser \Node \Name ;
7+ use PhpParser \Node \Scalar \LNumber ;
78use PhpParser \Node \Stmt \Catch_ ;
9+ use PhpParser \Node \Stmt \DeclareDeclare ;
810use PhpParser \Node \Stmt \TryCatch ;
911use PhpParser \ParserFactory ;
1012use PhpParser \PrettyPrinter \Standard ;
13+ use PhpParser \PrettyPrinterAbstract ;
1114use PhpSchool \PhpWorkshop \CodePatcher ;
1215use PhpSchool \PhpWorkshop \Exercise \ExerciseInterface ;
1316use PhpSchool \PhpWorkshop \Patch ;
@@ -92,7 +95,7 @@ public function codeProvider(): array
9295 (new Patch ())->withInsertion (new Insertion (Insertion::TYPE_BEFORE , ' <?php $before = "here"; ' )),
9396 "<?php \n\n\$before = \"here \"; \n\$original = true; "
9497 ],
95- 'transformer ' => [
98+ 'transformer-closure ' => [
9699 '<?php $original = true; ' ,
97100 (new Patch ())
98101 ->withTransformer (function (array $ statements ) {
@@ -119,6 +122,22 @@ public function codeProvider(): array
119122 }),
120123 "<?php \n\ntry { \n \$before = \"here \"; \n \$original = true; \n} catch (Exception \$e) { \n} "
121124 ],
125+ 'transformer-class ' => [
126+ '<?php $original = true; ' ,
127+ (new Patch ())
128+ ->withTransformer (new class implements Patch \Transformer {
129+ public function transform (array $ statements ): array
130+ {
131+ return [
132+ new TryCatch (
133+ $ statements ,
134+ [new Catch_ ([new Name (\Exception::class)], new Variable ('e ' ), [])]
135+ )
136+ ];
137+ }
138+ }),
139+ "<?php \n\ntry { \n \$original = true; \n} catch (Exception \$e) { \n} "
140+ ],
122141 ];
123142 }
124143
@@ -169,4 +188,61 @@ public function testTransformerWithStrictTypes(): void
169188 $ patcher ->patch ($ exercise , $ code )
170189 );
171190 }
191+
192+ public function testTransformerWhichAddsStrictTypesDoesNotResultInDoubleStrictTypesStatement (): void
193+ {
194+ $ code = '<?php declare(strict_types=1); $original = true; ' ;
195+ $ patch = (new Patch ())
196+ ->withTransformer (function (array $ statements ) {
197+ return [new \PhpParser \Node \Stmt \Declare_ ([
198+ new DeclareDeclare (
199+ new \PhpParser \Node \Identifier ('strict_types ' ),
200+ new LNumber (1 )
201+ )
202+ ])];
203+ });
204+
205+ $ patcher = new CodePatcher ((new ParserFactory ())->create (ParserFactory::PREFER_PHP7 ), new Standard ());
206+
207+ $ exercise = $ this ->createMock (PatchableExercise::class);
208+
209+ $ exercise
210+ ->expects ($ this ->once ())
211+ ->method ('getPatch ' )
212+ ->willReturn ($ patch );
213+
214+ $ this ->assertEquals (
215+ "<?php \n\ndeclare (strict_types=1); " ,
216+ $ patcher ->patch ($ exercise , $ code )
217+ );
218+ }
219+
220+ public function testAddingStrictTypesDeclareDoesNotBreakBeforeInsertion (): void
221+ {
222+ $ code = '<?php $original = true; ' ;
223+ $ patch = (new Patch ())
224+ ->withTransformer (function (array $ statements ) {
225+ return array_merge ([new \PhpParser \Node \Stmt \Declare_ ([
226+ new DeclareDeclare (
227+ new \PhpParser \Node \Identifier ('strict_types ' ),
228+ new LNumber (1 )
229+ )
230+ ])], $ statements );
231+ })
232+ ->withInsertion (new Insertion (Insertion::TYPE_BEFORE , '$before = "here"; ' ));
233+
234+ $ patcher = new CodePatcher ((new ParserFactory ())->create (ParserFactory::PREFER_PHP7 ), new Standard ());
235+
236+ $ exercise = $ this ->createMock (PatchableExercise::class);
237+
238+ $ exercise
239+ ->expects ($ this ->once ())
240+ ->method ('getPatch ' )
241+ ->willReturn ($ patch );
242+
243+ $ this ->assertEquals (
244+ "<?php \n\ndeclare (strict_types=1); \n\$before = \"here \"; \n\$original = true; " ,
245+ $ patcher ->patch ($ exercise , $ code )
246+ );
247+ }
172248}
0 commit comments