Skip to content

Commit 222d191

Browse files
authored
Automatic static analysis with phpstan (#11)
1 parent 2ee7256 commit 222d191

File tree

20 files changed

+187
-23
lines changed

20 files changed

+187
-23
lines changed

.github/workflows/tests.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,40 @@ jobs:
4343
- name: "Run tests with phpunit/phpunit"
4444
run: vendor/bin/phpunit
4545

46+
phpstan:
47+
name: "PhpStan"
48+
runs-on: ubuntu-latest
49+
50+
strategy:
51+
matrix:
52+
include:
53+
- php-version: 7.4
54+
symfony-version: 5.1.*
55+
56+
steps:
57+
- name: "Checkout"
58+
uses: actions/checkout@v2
59+
60+
- name: "Setup PHP"
61+
uses: shivammathur/setup-php@v2
62+
with:
63+
coverage: none
64+
php-version: ${{ matrix.php-version }}
65+
66+
- name: "Install dependencies with composer"
67+
run: |
68+
composer require --no-update "symfony/console:${{ matrix.symfony-version }}"
69+
composer require --no-update "symfony/filesystem:${{ matrix.symfony-version }}"
70+
composer require --no-update "symfony/framework-bundle:${{ matrix.symfony-version }}"
71+
composer require --no-update "symfony/messenger:${{ matrix.symfony-version }}"
72+
composer require --no-update "symfony/process:${{ matrix.symfony-version }}"
73+
composer require --no-update "symfony/serializer:${{ matrix.symfony-version }}"
74+
composer require --no-update "symfony/validator:${{ matrix.symfony-version }}"
75+
composer update --no-interaction --no-progress --no-suggest
76+
77+
- name: "Run static analyzis with phpstan/phpstan"
78+
run: vendor/bin/phpstan analyze
79+
4680
checkstyke:
4781
name: "Checkstyle"
4882
runs-on: ubuntu-latest

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/.idea/
12
/.phpcs-cache
23
/.phpunit.result.cache
34
/tests/.artifacts/

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"symfony/validator": "^4.4|^5.0"
2626
},
2727
"require-dev": {
28+
"phpstan/phpstan": "^0.12",
2829
"phpspec/prophecy-phpunit": "^2.0",
2930
"phpunit/phpunit": "^9.4",
3031
"squizlabs/php_codesniffer": "^3.5",

phpstan.neon

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
parameters:
2+
level: max
3+
checkMissingIterableValueType: false
4+
checkGenericClassInNonGenericObjectType: false
5+
paths:
6+
- src/batch/src/
7+
- src/batch-box-spout/src/
8+
- src/batch-doctrine-dbal/src/
9+
- src/batch-doctrine-orm/src/
10+
- src/batch-doctrine-persistence/src/
11+
- src/batch-symfony-console/src/
12+
- src/batch-symfony-framework/src/
13+
- src/batch-symfony-messenger/src/
14+
- src/batch-symfony-serializer/src/
15+
- src/batch-symfony-validator/src/
16+
17+
ignoreErrors:
18+
# The DependencyInjection returns are complex to deal with
19+
- message: '#.*NodeParentInterface\|null.*#'
20+
path: ./src/batch-symfony-framework/src/DependencyInjection

src/batch-box-spout/src/FlatFileWriter.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Box\Spout\Writer\Common\Creator\WriterFactory;
99
use Box\Spout\Writer\CSV\Writer as CsvWriter;
1010
use Box\Spout\Writer\WriterInterface;
11+
use Yokai\Batch\Exception\BadMethodCallException;
1112
use Yokai\Batch\Exception\RuntimeException;
1213
use Yokai\Batch\Exception\UnexpectedValueException;
1314
use Yokai\Batch\Job\Item\FlushableInterface;
@@ -90,6 +91,10 @@ public function initialize(): void
9091
*/
9192
public function write(iterable $items): void
9293
{
94+
if ($this->writer === null) {
95+
throw BadMethodCallException::itemComponentNotInitialized($this);
96+
}
97+
9398
if (!$this->headersAdded) {
9499
$this->headersAdded = true;
95100
if ($this->headers !== null) {
@@ -110,6 +115,10 @@ public function write(iterable $items): void
110115
*/
111116
public function flush(): void
112117
{
118+
if ($this->writer === null) {
119+
throw BadMethodCallException::itemComponentNotInitialized($this);
120+
}
121+
113122
$this->writer->close();
114123
$this->writer = null;
115124
$this->headersAdded = false;

src/batch-box-spout/tests/FlatFileWriterTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Box\Spout\Reader\Wrapper\XMLReader;
99
use PHPUnit\Framework\TestCase;
1010
use Yokai\Batch\Bridge\Box\Spout\FlatFileWriter;
11+
use Yokai\Batch\Exception\BadMethodCallException;
1112
use Yokai\Batch\Exception\UnexpectedValueException;
1213
use Yokai\Batch\JobExecution;
1314
use Yokai\Batch\JobParameters;
@@ -76,6 +77,28 @@ public function testWrite(
7677
$this->assertFileContents($type, $file, $expectedContent);
7778
}
7879

80+
/**
81+
* @dataProvider types
82+
*/
83+
public function testShouldInitializeBeforeWrite(string $type): void
84+
{
85+
$this->expectException(BadMethodCallException::class);
86+
87+
$writer = new FlatFileWriter($type);
88+
$writer->write([true]);
89+
}
90+
91+
/**
92+
* @dataProvider types
93+
*/
94+
public function testShouldInitializeBeforeFlush(string $type): void
95+
{
96+
$this->expectException(BadMethodCallException::class);
97+
98+
$writer = new FlatFileWriter($type);
99+
$writer->flush();
100+
}
101+
79102
public function types(): \Generator
80103
{
81104
foreach ([Type::CSV, Type::XLSX, Type::ODS] as $type) {

src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Yokai\Batch\Bridge\Doctrine\DBAL;
66

77
use Doctrine\DBAL\Connection;
8+
use Doctrine\DBAL\Driver\Result;
89
use Doctrine\DBAL\Exception as DBALException;
910
use Doctrine\DBAL\Schema\AbstractAsset;
1011
use Doctrine\DBAL\Schema\Schema;
@@ -359,6 +360,7 @@ private function identity(JobExecution $execution): array
359360

360361
private function fetchRow(string $jobName, string $id): array
361362
{
363+
/** @var Result $statement */
362364
$statement = $this->connection->executeQuery(
363365
"SELECT * FROM {$this->table} WHERE {$this->jobNameCol} = :jobName AND {$this->idCol} = :id",
364366
['jobName' => $jobName, 'id' => $id],
@@ -367,7 +369,12 @@ private function fetchRow(string $jobName, string $id): array
367369
$rows = $statement->fetchAllAssociative();
368370
switch (count($rows)) {
369371
case 1:
370-
return array_shift($rows);
372+
$row = array_shift($rows);
373+
if (!\is_array($row)) {
374+
throw UnexpectedValueException::type('array', $row);
375+
}
376+
377+
return $row;
371378
case 0:
372379
throw new RuntimeException(
373380
\sprintf('No row found for job %s#%s.', $jobName, $id)
@@ -381,6 +388,7 @@ private function fetchRow(string $jobName, string $id): array
381388

382389
private function queryList(string $query, array $parameters, array $types): iterable
383390
{
391+
/** @var Result $statement */
384392
$statement = $this->connection->executeQuery($query, $parameters, $types);
385393

386394
while ($row = $statement->fetchAssociative()) {

src/batch-doctrine-dbal/src/JobExecutionRowNormalizer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ public function toChildRow(JobExecution $jobExecution): array
185185
];
186186
}
187187

188+
/**
189+
* @param array|string $value
190+
*
191+
* @return array
192+
*/
188193
private function jsonFromString($value): array
189194
{
190195
if (is_string($value)) {

src/batch-doctrine-persistence/src/ObjectWriter.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ public function __construct(ManagerRegistry $doctrine)
4242
public function write(iterable $items): void
4343
{
4444
foreach ($items as $item) {
45+
if (!is_object($item)) {
46+
throw $this->createInvalidItemException($item);
47+
}
48+
4549
$this->getManagerForClass($item)->persist($item);
4650
}
4751

@@ -57,12 +61,8 @@ public function write(iterable $items): void
5761
$this->encounteredClasses = [];
5862
}
5963

60-
private function getManagerForClass($item): ObjectManager
64+
private function getManagerForClass(object $item): ObjectManager
6165
{
62-
if (!is_object($item)) {
63-
throw $this->createInvalidItemException($item);
64-
}
65-
6666
$class = get_class($item);
6767

6868
$manager = $this->managerForClass[$class] ?? null;
@@ -81,6 +81,11 @@ private function getManagerForClass($item): ObjectManager
8181
return $manager;
8282
}
8383

84+
/**
85+
* @param mixed $item
86+
*
87+
* @return InvalidArgumentException
88+
*/
8489
private function createInvalidItemException($item): InvalidArgumentException
8590
{
8691
return new InvalidArgumentException(

src/batch-doctrine-persistence/tests/ObjectWriterTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use PHPUnit\Framework\TestCase;
1010
use Prophecy\Argument;
1111
use Prophecy\PhpUnit\ProphecyTrait;
12-
use Prophecy\Prophecy\ObjectProphecny;
12+
use Prophecy\Prophecy\ObjectProphecy;
1313
use Yokai\Batch\Bridge\Doctrine\Persistence\ObjectWriter;
1414
use Yokai\Batch\Exception\InvalidArgumentException;
1515

0 commit comments

Comments
 (0)