Skip to content

Commit 85b6bb1

Browse files
Merge pull request #127 from magento-commerce/MCLOUD-13149
MCLOUD-13149: Add support of php 8.4 to cloud-patches
2 parents 9e2696a + dbb1f1a commit 85b6bb1

31 files changed

+640
-299
lines changed

composer.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
"require": {
1414
"php": "^8.0",
1515
"ext-json": "*",
16-
"composer/composer": "^1.9 || ^2.0",
16+
"composer/composer": "^1.9 || ^2.8 || !=2.2.16",
1717
"composer/semver": "@stable",
18-
"monolog/monolog": "^1.25||^2.3||^2.7|| ^3.6",
19-
"symfony/config": "^3.3||^4.4||^5.0||^6.0",
20-
"symfony/console": "^2.8 || ^4.0 || ^5.1 || ^5.4 || ^6.4",
21-
"symfony/dependency-injection": "^3.3||^4.3||^5.0||^6.0",
22-
"symfony/process": "^2.1 || ^4.1 || ^5.1 || ^5.4 || ^6.4",
18+
"monolog/monolog": "^2.3 || ^2.7 || ^3.6",
19+
"symfony/config": "^4.4 || ^5.1 || ^5.4 || ^6.4",
20+
"symfony/console": "^4.4 || ^5.1 || ^5.4 || ^6.4",
21+
"symfony/dependency-injection": "^4.4 || ^5.1 || ^5.4 || ^6.4",
22+
"symfony/process": "^4.4 || ^5.1 || ^5.4 || ^6.4",
2323
"symfony/proxy-manager-bridge": "^3.3||^4.3||^5.0||^6.0",
24-
"symfony/yaml": "^3.3||^4.0||^5.0||^6.0||^7.0",
24+
"symfony/yaml": "^4.4 || ^5.1 || ^5.4 || ^6.4",
2525
"magento/quality-patches": "^1.1.0"
2626
},
2727
"require-dev": {
@@ -32,7 +32,7 @@
3232
"codeception/module-rest": "^1.2 || ^3.0",
3333
"consolidation/robo": "^1.2 || ^3.0 || ^5.0",
3434
"phpmd/phpmd": "@stable",
35-
"phpunit/phpunit": "^8.5 || ^9.5",
35+
"phpunit/phpunit": "^10.0",
3636
"squizlabs/php_codesniffer": "^3.0"
3737
},
3838
"bin": [

src/App/GenericException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class GenericException extends \Exception
1919
* @param int $code
2020
* @param Throwable|null $previous
2121
*/
22-
public function __construct(string $message, int $code = 0, Throwable $previous = null)
22+
public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null)
2323
{
2424
parent::__construct($message, $code, $previous);
2525
}

src/Console/QuestionFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class QuestionFactory
2222
*
2323
* @return Question
2424
*/
25-
public function create(string $question, string $default = null): Question
25+
public function create(string $question, ?string $default = null): Question
2626
{
2727
return new Question($question, $default);
2828
}

src/Shell/ProcessFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function __construct(DirectoryList $directoryList, Composer $composer)
4949
* @return Process
5050
* @throws PackageNotFoundException
5151
*/
52-
public function create(array $cmd, string $input = null): Process
52+
public function create(array $cmd, ?string $input = null): Process
5353
{
5454
return new Process(
5555
$this->processSupportsArrayParam() ? $cmd : implode(' ', $cmd),

src/Test/Unit/Command/Process/Action/ApplyOptionalActionTest.php

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,12 @@ public function testExecuteSuccessful()
108108
$outputMock = $this->getMockForAbstractClass(OutputInterface::class);
109109
$this->optionalPool->expects($this->once())
110110
->method('getList')
111-
->withConsecutive([$patchFilter])
111+
->willReturnCallback(function ($filter) use ($patchFilter, $patch1) {
112+
if ($filter === $patchFilter) {
113+
return [$patch1];
114+
}
115+
return [];
116+
})
112117
->willReturn([$patch1, $patch2, $patch3]);
113118

114119
$this->applier->method('apply')
@@ -117,18 +122,27 @@ public function testExecuteSuccessful()
117122
[$patch2->getPath(), $patch2->getId(), 'Patch ' . $patch2->getId() .' has been applied'],
118123
[$patch3->getPath(), $patch3->getId(), 'Patch ' . $patch3->getId() .' has been applied'],
119124
]);
120-
121125
$this->renderer->expects($this->exactly(3))
122-
->method('printPatchInfo')
123-
->withConsecutive(
124-
[$outputMock, $patch1, 'Patch ' . $patch1->getId() .' has been applied'],
125-
[$outputMock, $patch2, 'Patch ' . $patch2->getId() .' has been applied'],
126-
[$outputMock, $patch3, 'Patch ' . $patch3->getId() .' has been applied']
127-
);
128-
126+
->method('printPatchInfo')
127+
->willReturnCallback(function ($patch, $message) use ($patch1, $patch2, $patch3) {
128+
static $callCount = 0;
129+
$expectedPatches = [$patch1, $patch2, $patch3];
130+
$expectedMessages = [
131+
'Patch ' . $patch1->getId() . ' has been applied',
132+
'Patch ' . $patch2->getId() . ' has been applied',
133+
'Patch ' . $patch3->getId() . ' has been applied'
134+
];
135+
136+
if ($patch === $expectedPatches[$callCount] && $message === $expectedMessages[$callCount]) {
137+
$callCount++;
138+
return true;
139+
}
140+
141+
return false;
142+
});
129143
$this->action->execute($inputMock, $outputMock, $patchFilter);
130144
}
131-
145+
132146
/**
133147
* Tests successful optional patches applying.
134148
*
@@ -149,22 +163,24 @@ public function testApplyAlreadyAppliedPatch()
149163
$outputMock = $this->getMockForAbstractClass(OutputInterface::class);
150164
$this->optionalPool->expects($this->once())
151165
->method('getList')
152-
->withConsecutive([$patchFilter])
166+
->willReturnCallback(function ($filter) use ($patchFilter, $patch1) {
167+
if ($filter === $patchFilter) {
168+
return [$patch1];
169+
}
170+
return [];
171+
})
153172
->willReturn([$patch1]);
154-
155173
$this->applier->expects($this->never())
156174
->method('apply');
157175
$this->renderer->expects($this->never())
158176
->method('printPatchInfo');
159177

160178
$outputMock->expects($this->once())
161179
->method('writeln')
162-
->withConsecutive(
163-
[
164-
$this->stringContains(
165-
'Patch ' . $patch1->getId() .' (' . $patch1->getFilename() . ') was already applied'
166-
)
167-
]
180+
->with(
181+
$this->stringContains(
182+
'Patch ' . $patch1->getId() .' (' . $patch1->getFilename() . ') was already applied'
183+
)
168184
);
169185

170186
$this->action->execute($inputMock, $outputMock, $patchFilter);
@@ -203,8 +219,10 @@ public function testApplyingAllPatchesAndSkipDeprecated()
203219

204220
$this->renderer->expects($this->once())
205221
->method('printPatchInfo')
206-
->withConsecutive(
207-
[$outputMock, $patch1, 'Patch ' . $patch1->getId() .' has been applied']
222+
->with(
223+
$outputMock,
224+
$patch1,
225+
'Patch ' . $patch1->getId() .' has been applied'
208226
);
209227

210228
$this->action->execute($inputMock, $outputMock, $patchFilter);
@@ -232,27 +250,35 @@ public function testApplyWithException()
232250
->willReturn([$patch1, $patch2]);
233251

234252
$this->applier->method('apply')
235-
->willReturnMap([
236-
[$patch1->getPath(), $patch1->getId()],
237-
[$patch2->getPath(), $patch2->getId()]
238-
])->willReturnCallback(
239-
function ($path, $id) {
240-
if ($id === 'MC-22222') {
241-
throw new ApplierException('Applier error message');
242-
}
243-
244-
return "Patch {$path} {$id} has been applied";
253+
->willReturnCallback(function ($path, $id) use ($patch1, $patch2) {
254+
if ($id === 'MC-22222') {
255+
throw new ApplierException('Applier error message');
245256
}
246-
);
247-
257+
// Return success message for the first patch
258+
return "Patch {$path} {$id} has been applied";
259+
});
248260
$this->conflictProcessor->expects($this->once())
249261
->method('process')
250-
->withConsecutive([$outputMock, $patch2, [$patch1], 'Applier error message'])
262+
->willReturnCallback(function ($patch, $message) use ($patch1, $patch2, $patch3) {
263+
static $callCount = 0;
264+
$expectedPatches = [$patch1, $patch2, $patch3];
265+
$expectedMessages = [
266+
'Patch ' . $patch1->getId() . ' has been applied',
267+
'Patch ' . $patch2->getId() . ' has been applied',
268+
'Patch ' . $patch3->getId() . ' has been applied'
269+
];
270+
271+
if ($patch === $expectedPatches[$callCount] && $message === $expectedMessages[$callCount]) {
272+
$callCount++;
273+
return true;
274+
}
275+
276+
return false;
277+
})
251278
->willThrowException(new RuntimeException('Error message'));
252279

253280
$this->expectException(RuntimeException::class);
254281
$this->expectExceptionMessage('Error message');
255-
256282
$this->action->execute($inputMock, $outputMock, $patchFilter);
257283
}
258284

src/Test/Unit/Command/Process/Action/ConfirmRequiredActionTest.php

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,24 +86,34 @@ public function testAskConfirmationForNotAppliedPatches()
8686
]);
8787

8888
/** @var InputInterface|MockObject $inputMock */
89-
$inputMock = $this->getMockForAbstractClass(InputInterface::class);
89+
$inputMock = $this->createMock(InputInterface::class);
9090
/** @var OutputInterface|MockObject $outputMock */
91-
$outputMock = $this->getMockForAbstractClass(OutputInterface::class);
91+
$outputMock = $this->createMock(OutputInterface::class);
9292
$this->optionalPool->expects($this->once())
9393
->method('getAdditionalRequiredPatches')
94-
->withConsecutive([$patchFilter])
94+
->willReturnCallback(function ($filter) use ($patchFilter, $patch1) {
95+
if ($filter === $patchFilter) {
96+
return [$patch1];
97+
}
98+
return [];
99+
})
95100
->willReturn([$patch1, $patch2, $patch3]);
96101

97-
$aggregatedPatch = $this->getMockForAbstractClass(AggregatedPatchInterface::class);
102+
$aggregatedPatch = $this->createMock(AggregatedPatchInterface::class);
98103
$this->aggregator->expects($this->once())
99104
->method('aggregate')
100105
->with([$patch1, $patch2])
101106
->willReturn([$aggregatedPatch]);
102107

103108
$this->renderer->expects($this->once())
104109
->method('printTable')
105-
->withConsecutive([$outputMock, [$aggregatedPatch]]);
106-
110+
->with($outputMock, [$aggregatedPatch])
111+
->willReturnCallback(function ($output) use ($outputMock, $aggregatedPatch) {
112+
if ($output === $outputMock && $aggregatedPatch === [$aggregatedPatch]) {
113+
throw new RuntimeException('Error message');
114+
}
115+
return null;
116+
});
107117
$this->renderer->expects($this->once())
108118
->method('printQuestion')
109119
->willReturn(true);
@@ -119,12 +129,12 @@ public function testPatchNotFoundException()
119129
$patchFilter = ['unknown id'];
120130

121131
/** @var InputInterface|MockObject $inputMock */
122-
$inputMock = $this->getMockForAbstractClass(InputInterface::class);
132+
$inputMock = $this->createMock(InputInterface::class);
123133
/** @var OutputInterface|MockObject $outputMock */
124-
$outputMock = $this->getMockForAbstractClass(OutputInterface::class);
125-
$this->optionalPool->expects($this->once())
134+
$outputMock = $this->createMock(OutputInterface::class);
135+
$this->optionalPool->expects($this->once())
126136
->method('getAdditionalRequiredPatches')
127-
->withConsecutive([$patchFilter])
137+
->with($patchFilter)
128138
->willThrowException(new PatchNotFoundException(''));
129139

130140
$this->expectException(RuntimeException::class);
@@ -144,23 +154,29 @@ public function testConfirmationRejected()
144154
]);
145155

146156
/** @var InputInterface|MockObject $inputMock */
147-
$inputMock = $this->getMockForAbstractClass(InputInterface::class);
157+
$inputMock = $this->createMock(InputInterface::class);
148158
/** @var OutputInterface|MockObject $outputMock */
149-
$outputMock = $this->getMockForAbstractClass(OutputInterface::class);
159+
$outputMock = $this->createMock(OutputInterface::class);
150160
$this->optionalPool->expects($this->once())
151161
->method('getAdditionalRequiredPatches')
152-
->withConsecutive([$patchFilter])
162+
->willReturnCallback(function ($filter) use ($patchFilter, $patch1) {
163+
if ($filter === $patchFilter) {
164+
return [$patch1];
165+
}
166+
return [];
167+
})
153168
->willReturn([$patch1]);
154169

155-
$aggregatedPatch = $this->getMockForAbstractClass(AggregatedPatchInterface::class);
170+
$aggregatedPatch = $this->createMock(AggregatedPatchInterface::class);
156171
$this->aggregator->expects($this->once())
157172
->method('aggregate')
158173
->with([$patch1])
159174
->willReturn([$aggregatedPatch]);
160175

161-
$this->renderer->expects($this->once())
162-
->method('printTable')
163-
->withConsecutive([$outputMock, [$aggregatedPatch]]);
176+
$this->optionalPool->expects($this->once())
177+
->method('getAdditionalRequiredPatches')
178+
->with($patchFilter)
179+
->willReturn([$patch1]);
164180

165181
$this->renderer->expects($this->once())
166182
->method('printQuestion')
@@ -181,7 +197,7 @@ public function testConfirmationRejected()
181197
*/
182198
private function createPatch(string $path, string $id, bool $isDeprecated = false)
183199
{
184-
$patch = $this->getMockForAbstractClass(PatchInterface::class);
200+
$patch = $this->createMock(PatchInterface::class);
185201
$patch->method('getPath')->willReturn($path);
186202
$patch->method('getFilename')->willReturn('filename.patch');
187203
$patch->method('getId')->willReturn($id);

0 commit comments

Comments
 (0)