Skip to content

Commit 53a3976

Browse files
committed
HP-2247: refactor(tests): adopt PHP 8+ syntax with attributes and null-safe operators
1 parent a66b6bc commit 53a3976

22 files changed

Lines changed: 145 additions & 241 deletions

behat.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Behat\Config\Config;
6+
use Behat\Config\Profile;
7+
use Behat\Config\Suite;
8+
9+
return (new Config())
10+
->withProfile(
11+
(new Profile('default'))
12+
->withSuite(
13+
(new Suite('php-billing'))
14+
->withPaths('%paths.base%/tests/behat')
15+
->withContexts('hiqdev\php\billing\tests\behat\bootstrap\FeatureContext')
16+
)
17+
);

tests/behat/bootstrap/BaseContext.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ abstract class BaseContext implements Context
1818
/** @var BuilderInterface */
1919
protected $builder;
2020

21-
/**
22-
* @BeforeScenario
23-
*/
21+
#[\Behat\Hook\BeforeScenario]
2422
public function getBuilder(BeforeScenarioScope $scope)
2523
{
2624
$this->builder = $scope->getEnvironment()->getContext(BuilderContext::class)->getBuilder();

tests/behat/bootstrap/BillingContext.php

Lines changed: 54 additions & 128 deletions
Large diffs are not rendered by default.

tests/behat/bootstrap/BuilderContext.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ class BuilderContext implements Context
1717
{
1818
private $builder;
1919

20-
public function __construct(string $class = null)
20+
public function __construct(?string $class = null)
2121
{
22-
$class = $class ?? FactoryBasedBuilder::class;
22+
$class ??= FactoryBasedBuilder::class;
2323
$this->builder = new $class();
2424
}
2525

tests/behat/bootstrap/BuilderInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function setAction(string $type, int $amount, string $unit, string $targe
4040

4141
public function performCalculation(string $time): array;
4242

43-
public function targetChangePlan(string $target, string $planName, string $date, string $wallTime = null);
43+
public function targetChangePlan(string $target, string $planName, string $date, ?string $wallTime = null);
4444

4545
/**
4646
* @return SaleInterface[]

tests/behat/bootstrap/FactoryBasedBuilder.php

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public function recreatePlan(string $name)
121121
$plan->setPrices($this->prices);
122122
}
123123

124-
public function buildSale(string $target, $plan, string $time = null)
124+
public function buildSale(string $target, $plan, ?string $time = null)
125125
{
126126
$this->time = $time;
127127
$this->sale = $this->factory->get('sale', array_filter([
@@ -171,7 +171,7 @@ public function buildTarget(string $target)
171171
return $this->factory->get('target', $target);
172172
}
173173

174-
public function performCalculation(string $time = null): array
174+
public function performCalculation(?string $time = null): array
175175
{
176176
return $this->getBilling()->calculateCharges($this->actions);
177177
}
@@ -193,8 +193,8 @@ public function performAction(array $data)
193193

194194
public function buildAction(array $data)
195195
{
196-
$data['time'] = $data['time'] ?? $this->time;
197-
$data['customer'] = $data['customer'] ?? $this->customer;
196+
$data['time'] ??= $this->time;
197+
$data['customer'] ??= $this->customer;
198198
if (!empty($data['targets'])) {
199199
$data['target'] = $this->factory->get('targets', $data['targets']);
200200
}
@@ -204,8 +204,8 @@ public function buildAction(array $data)
204204

205205
public function findBills(array $data): array
206206
{
207-
$data['sum'] = $data['sum'] ?? '0 USD';
208-
$data['quantity'] = $data['quantity'] ?? '0 items';
207+
$data['sum'] ??= '0 USD';
208+
$data['quantity'] ??= '0 items';
209209
$bill = $this->buildBill($data);
210210
$repo = $this->getBilling()->getBillRepository();
211211

@@ -214,8 +214,8 @@ public function findBills(array $data): array
214214

215215
public function buildBill(array $data)
216216
{
217-
$data['time'] = $data['time'] ?? $this->time;
218-
$data['customer'] = $data['customer'] ?? $this->customer;
217+
$data['time'] ??= $this->time;
218+
$data['customer'] ??= $this->customer;
219219
if (!empty($data['targets'])) {
220220
$data['target'] = $this->factory->get('targets', $data['targets']);
221221
}
@@ -225,8 +225,8 @@ public function buildBill(array $data)
225225

226226
public function findCharges(array $data): array
227227
{
228-
$data['sum'] = $data['sum'] ?? '0 USD';
229-
$data['quantity'] = $data['quantity'] ?? '0 items';
228+
$data['sum'] ??= '0 USD';
229+
$data['quantity'] ??= '0 items';
230230
$bill = $this->buildCharge($data);
231231
$repo = $this->getBilling()->getChargeRepository();
232232

@@ -235,16 +235,16 @@ public function findCharges(array $data): array
235235

236236
public function buildCharge(array $data)
237237
{
238-
$data['time'] = $data['time'] ?? $this->time;
239-
$data['customer'] = $data['customer'] ?? $this->customer;
238+
$data['time'] ??= $this->time;
239+
$data['customer'] ??= $this->customer;
240240
if (!empty($data['targets'])) {
241241
$data['target'] = $this->factory->get('targets', $data['targets']);
242242
}
243243

244244
return $this->factory->get('bill', $data);
245245
}
246246

247-
public function targetChangePlan(string $target, string $planName, string $date, string $wallTime = null)
247+
public function targetChangePlan(string $target, string $planName, string $date, ?string $wallTime = null): never
248248
{
249249
throw new RuntimeException('Not implemented yet');
250250
}

tests/behat/bootstrap/FeatureContext.php

Lines changed: 28 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@ public function __construct()
9191
$this->billing = SimpleBilling::fromSale($this->sale);
9292
}
9393

94-
/**
95-
* @Given /(\S+) (\S+) price is ([0-9.]+) (\w+) per (\w+)(?: includes ([\d.]+))?/
96-
*/
94+
#[\Behat\Step\Given('/(\S+) (\S+) price is ([0-9.]+) (\w+) per (\w+)(?: includes ([\d.]+))?/')]
9795
public function priceIs($target, $type, $sum, $currency, $unit, $quantity = 0)
9896
{
9997
$type = Type::anyId($type);
@@ -104,9 +102,7 @@ public function priceIs($target, $type, $sum, $currency, $unit, $quantity = 0)
104102
}
105103

106104
protected array $progressivePrice = [];
107-
/**
108-
* @Given /(\S+) progressive price for (\S+) is +(\S+) (\S+) per (\S+) (\S+) (\S+) (\S+)$/
109-
*/
105+
#[\Behat\Step\Given('/(\S+) progressive price for (\S+) is +(\S+) (\S+) per (\S+) (\S+) (\S+) (\S+)$/')]
110106
public function progressivePrice($target, $type, $price, $currency, $unit, $sign, $quantity, $perUnit): void
111107
{
112108
if (empty($this->progressivePrice[$type])) {
@@ -128,9 +124,7 @@ public function progressivePrice($target, $type, $price, $currency, $unit, $sign
128124
}
129125
}
130126

131-
/**
132-
* @Given /^build progressive price/
133-
*/
127+
#[\Behat\Step\Given('/^build progressive price/')]
134128
public function buildProgressivePrices()
135129
{
136130
$i = 0;
@@ -148,9 +142,7 @@ public function buildProgressivePrices()
148142
}
149143
}
150144

151-
/**
152-
* @Given /sale close time is ([0-9.-]+)?/
153-
*/
145+
#[\Behat\Step\Given('/sale close time is ([0-9.-]+)?/')]
154146
public function setActionCloseTime($closeTime): void
155147
{
156148
if ($closeTime === null) {
@@ -160,30 +152,23 @@ public function setActionCloseTime($closeTime): void
160152
$this->sale->close(new DateTimeImmutable($closeTime));
161153
}
162154

163-
/**
164-
* @Given /sale time is (.+)$/
165-
*/
155+
#[\Behat\Step\Given('/sale time is (.+)$/')]
166156
public function setSaleTime($time): void
167157
{
168158
$ref = new ReflectionClass($this->sale);
169159
$prop = $ref->getProperty('time');
170-
$prop->setAccessible(true);
171160
$prop->setValue($this->sale, new DateTimeImmutable($time));
172-
$prop->setAccessible(false);
173161
}
174162

175163
private function setPrice($price)
176164
{
177165
$this->price = $price;
178166
$ref = new ReflectionClass($this->plan);
179167
$prop = $ref->getProperty('prices');
180-
$prop->setAccessible(true);
181168
$prop->setValue($this->plan, [$price]);
182169
}
183170

184-
/**
185-
* @Given /action is (\S+) ([\w_,]+)(?: ([0-9.]+) (\S+))?(?: in (.+))?/
186-
*/
171+
#[\Behat\Step\Given('/action is (\S+) ([\w_,]+)(?: ([0-9.]+) (\S+))?(?: in (.+))?/')]
187172
public function actionIs(string $target, string $type, float $amount, string $unit, ?string $date = null): void
188173
{
189174
$type = Type::anyId($type);
@@ -196,7 +181,7 @@ public function actionIs(string $target, string $type, float $amount, string $un
196181
);
197182
if ($type->getName() !== 'overuse') {
198183
// Overuses should be prepared in the test case
199-
$amount = $amount * $fractionOfMonth;
184+
$amount *= $fractionOfMonth;
200185
}
201186
}
202187
$quantity = Quantity::create($unit, $amount);
@@ -219,22 +204,18 @@ private function getFractionOfMonth(DateTimeImmutable $month, DateTimeImmutable
219204
{
220205
try {
221206
return UsageInterval::withinMonth($month, $startTime, $endTime)->ratioOfMonth();
222-
} catch (\InvalidArgumentException $e) {
207+
} catch (\InvalidArgumentException) {
223208
return 1;
224209
}
225210
}
226211

227-
/**
228-
* @Given /formula is (.+)/
229-
*/
212+
#[\Behat\Step\Given('/formula is (.+)/')]
230213
public function formulaIs(string $formula): void
231214
{
232215
$this->formula = $formula;
233216
}
234217

235-
/**
236-
* @Given /formula continues (.+)/
237-
*/
218+
#[\Behat\Step\Given('/formula continues (.+)/')]
238219
public function formulaContinues(string $formula): void
239220
{
240221
$this->formula .= "\n" . $formula;
@@ -250,64 +231,53 @@ protected function getFormulaEngine()
250231
}
251232

252233
/**
253-
* @When /action date is (.+)/
254234
* @throws Exception
255235
*/
236+
#[\Behat\Step\When('/action date is (.+)/')]
256237
public function actionDateIs(string $date): void
257238
{
258239
$this->action->setTime(new DateTimeImmutable($date));
259240
}
260241

261-
/**
262-
* @Given /^client rejected service at ?(.+?)$/
263-
*/
242+
#[\Behat\Step\Given('/^client rejected service at ?(.+?)$/')]
264243
public function actionCloseDateIs(?string $close_date): void
265244
{
266-
$close_date = trim($close_date);
245+
$close_date = trim((string) $close_date);
267246
if (empty($close_date)) {
268247
return;
269248
}
270249

271250
$this->sale->close(new DateTimeImmutable($close_date));
272251
}
273252

274-
/**
275-
* @Then /^error is$/m
276-
*/
253+
#[\Behat\Step\Then('/^error is$/m')]
277254
public function multilineErrorIs(\Behat\Gherkin\Node\PyStringNode $value)
278255
{
279256
$this->expectedError = $value->getRaw();
280257
}
281258

282259
/**
283-
* @Then /^error is (.+)$/
284-
*
285260
* @param string $error
286261
*/
262+
#[\Behat\Step\Then('/^error is (.+)$/')]
287263
public function errorIs($error): void
288264
{
289265
$this->expectedError = $error;
290266
}
291267

292-
/**
293-
* @Then /^(\w+) charge is ?(?: with ?)?$/
294-
*/
268+
#[\Behat\Step\Then('/^(\w+) charge is ?(?: with ?)?$/')]
295269
public function emptyCharge(string $numeral): void
296270
{
297271
$this->chargeIs($numeral);
298272
}
299273

300-
/**
301-
* @Then /^(\w+) charge is (\S+) +(-?[0-9.]+) ([A-Z]{3})(?: for ([\d.]+)? (\w+)?)?(?: with (.+)?)?$/
302-
*/
274+
#[\Behat\Step\Then('/^(\w+) charge is (\S+) +(-?[0-9.]+) ([A-Z]{3})(?: for ([\d.]+)? (\w+)?)?(?: with (.+)?)?$/')]
303275
public function chargeWithSum($numeral, $type = null, $sum = null, $currency = null, $qty = null, $unit = null, $events = null): void
304276
{
305277
$this->chargeIs($numeral, $type, $sum, $currency, null, $qty, $unit, $events);
306278
}
307279

308-
/**
309-
* @Then /^(\w+) charge is (\S+) +(-?[0-9.]+) ([A-Z]{3}) reason ([\w]+)(?: with (.+)?)?$/
310-
*/
280+
#[\Behat\Step\Then('/^(\w+) charge is (\S+) +(-?[0-9.]+) ([A-Z]{3}) reason ([\w]+)(?: with (.+)?)?$/')]
311281
public function chargeWithReason($numeral, $type = null, $sum = null, $currency = null, $reason = null, $events = null): void
312282
{
313283
$this->chargeIs($numeral, $type, $sum, $currency, $reason, null, null, $events);
@@ -322,12 +292,10 @@ public function chargeIs($numeral, $type = null, $sum = null, $currency = null,
322292
$this->assertCharge($this->charges[$no] ?? null, $type, $sum, $currency, $reason, $qty, $unit, $events);
323293
}
324294

325-
/**
326-
* @When /^calculating charges$/
327-
*/
295+
#[\Behat\Step\When('/^calculating charges$/')]
328296
public function calculatePrice(): void
329297
{
330-
$this->expectError(function () {
298+
$this->expectError(function (): void {
331299
if ($this->formula !== null) {
332300
$this->price->setModifier($this->getFormulaEngine()->build($this->formula));
333301
}
@@ -395,7 +363,7 @@ public function assertCharge($charge, $type, $sum, $currency, $reason, $qty, $un
395363
}
396364
if ($events !== null) {
397365
$storedEvents = $charge->releaseEvents();
398-
foreach (array_map('trim', explode(',', $events)) as $eventClass) {
366+
foreach (array_map(trim(...), explode(',', $events)) as $eventClass) {
399367
foreach ($storedEvents as $storedEvent) {
400368
$eventReflection = new \ReflectionObject($storedEvent);
401369
if ($eventReflection->getShortName() === $eventClass) {
@@ -412,16 +380,12 @@ public function assertCharge($charge, $type, $sum, $currency, $reason, $qty, $un
412380

413381
private function normalizeType($string): string
414382
{
415-
switch ($string) {
416-
case 'discount,discount':
417-
return 'discount';
418-
case 'monthly,leasing':
419-
return 'leasing';
420-
case 'monthly,installment':
421-
return 'installment';
422-
default:
423-
return $string;
424-
}
383+
return match ($string) {
384+
'discount,discount' => 'discount',
385+
'monthly,leasing' => 'leasing',
386+
'monthly,installment' => 'installment',
387+
default => $string,
388+
};
425389
}
426390

427391
private function ensureNo(string $numeral): int
@@ -435,9 +399,7 @@ private function ensureNo(string $numeral): int
435399
return --$result;
436400
}
437401

438-
/**
439-
* @Given /^progressive price calculation steps are (.*)$/
440-
*/
402+
#[\Behat\Step\Given('/^progressive price calculation steps are (.*)$/')]
441403
public function progressivePriceCalculationStepsAre($explanation)
442404
{
443405
if (!$this->price instanceof ProgressivePrice) {

tests/support/order/SimpleBilling.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
class SimpleBilling extends Billing
2828
{
2929
public function __construct(
30-
CalculatorInterface $calculator = null,
31-
AggregatorInterface $aggregator = null,
32-
MergerInterface $merger = null,
30+
?CalculatorInterface $calculator = null,
31+
?AggregatorInterface $aggregator = null,
32+
?MergerInterface $merger = null,
3333
$repository = null
3434
) {
3535
$calculator = $calculator ?: new SimpleCalculator();
@@ -45,9 +45,9 @@ public function getBillRepository(): BillRepositoryInterface
4545
return $this->repository;
4646
}
4747

48-
public static function fromPlan(PlanInterface $plan, CustomerInterface $customer = null)
48+
public static function fromPlan(PlanInterface $plan, ?CustomerInterface $customer = null)
4949
{
50-
$customer = $customer ?? $plan->getSeller();
50+
$customer ??= $plan->getSeller();
5151
$sale = new Sale(null, Target::any(), $customer, $plan);
5252

5353
return self::fromSale($sale);

0 commit comments

Comments
 (0)