Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI: separate psalm and phpstan workflows #113

Merged
merged 3 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 55 additions & 3 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ on: # yamllint disable-line rule:truthy
pull_request:
paths:
- 'src/**'
- 'tests/**'
- 'bin/trap'
- '.php-cs-fixer.dist.php'
- 'psalm*'
- 'phpstan*'
- 'composer.*'
push:
paths:
- 'src/**'
- 'tests/**'
- 'bin/trap'
- '.php-cs-fixer.dist.php'
- 'psalm*'
- 'phpstan*'
- 'composer.*'

name: 🔍 Static analysis

jobs:
static-analysis:
psalm:
timeout-minutes: 4
runs-on: ${{ matrix.os }}
concurrency:
Expand Down Expand Up @@ -68,5 +72,53 @@ jobs:
- name: 🔍 Run static analysis using vimeo/psalm
run: composer psalm:ci

phpstan:
timeout-minutes: 4
runs-on: ${{ matrix.os }}
concurrency:
cancel-in-progress: true
group: static-analysis-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
strategy:
fail-fast: true
matrix:
os:
- ubuntu-latest
php-version:
- '8.2'
dependencies:
- locked
steps:
- name: 📦 Check out the codebase
uses: actions/checkout@v4.1.5

- name: 🛠️ Setup PHP
uses: shivammathur/setup-php@2.30.4
with:
php-version: ${{ matrix.php-version }}
extensions: none, ctype, curl, dom, json, mbstring, phar, simplexml, tokenizer, xml, xmlwriter, sockets, opcache, pcntl, posix
ini-values: error_reporting=E_ALL
coverage: none

- name: 🛠️ Setup problem matchers
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"

- name: 🤖 Validate composer.json and composer.lock
run: composer validate --ansi --strict

- name: 🔍 Get composer cache directory
uses: wayofdev/gh-actions/actions/composer/get-cache-directory@v3.1.0

- name: ♻️ Restore cached dependencies installed with composer
uses: actions/cache@v4.0.2
with:
path: ${{ env.COMPOSER_CACHE_DIR }}
key: php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}
restore-keys: php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-

- name: 📥 Install "${{ matrix.dependencies }}" dependencies
uses: wayofdev/gh-actions/actions/composer/install@v3.1.0
with:
dependencies: ${{ matrix.dependencies }}

- name: 🔍 Run static analysis using phpstan/phpstan
run: composer stan:ci
4 changes: 3 additions & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ parameters:
paths:
- bin/
- src/
- tests/
- .php-cs-fixer.dist.php
excludePaths:
analyse:
- src/Test/Proto/
tmpDir: .build/phpstan/
2 changes: 1 addition & 1 deletion tests/Unit/Client/FunctionTrapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ public function testLeak(): void
trap($object, $object);
unset($object);

$this->assertNull($ref->get());
self::assertNull($ref->get());
}
}
16 changes: 8 additions & 8 deletions tests/Unit/Client/TrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,27 +51,27 @@ public function testLeak(): void
tr($object, $object);
unset($object);

$this->assertNull($ref->get());
self::assertNull($ref->get());
}

public function testReturn(): void
{
$this->assertSame(42, tr(42));
$this->assertSame(42, tr(named: 42));
$this->assertSame(42, tr(42, 43));
$this->assertSame('foo', tr(...['0' => 'foo', 42 => 90]));
$this->assertNull(tr(null));
self::assertSame(42, tr(42));
self::assertSame(42, tr(named: 42));
self::assertSame(42, tr(42, 43));
self::assertSame('foo', tr(...['0' => 'foo', 42 => 90]));
self::assertNull(tr(null));
}

public function testReturnSendsDumpOnce(): void
{
$dumper = $this->getMockBuilder(DataDumperInterface::class)
->getMock();
$dumper->expects($this->once())
$dumper->expects(self::once())
->method('dump')
->willReturnArgument(1);
Dumper::setDumper($dumper);

$this->assertSame(42, tr(42));
self::assertSame(42, tr(42));
}
}
34 changes: 17 additions & 17 deletions tests/Unit/Client/TrapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static function provideTrapTimes(): iterable
public function testLabel(): void
{
trap(FooName: 'foo-value');
$this->assertSame('FooName', self::$lastData->getContext()['label']);
self::assertSame('FooName', self::$lastData->getContext()['label']);
}

public function testSimpleContext(): void
Expand Down Expand Up @@ -61,11 +61,11 @@ public function testStackTrace(): void
{
$line = __FILE__ . ':' . __LINE__ and trap()->stackTrace();

$this->assertArrayHasKey('trace', self::$lastData->getValue());
self::assertArrayHasKey('trace', self::$lastData->getValue());

$neededLine = \array_key_first(self::$lastData->getValue()['trace']->getValue());

$this->assertStringContainsString($line, $neededLine);
self::assertStringContainsString($line, $neededLine);
}

/**
Expand All @@ -89,7 +89,7 @@ public function testLeak(): void
trap($object, $object);
unset($object);

$this->assertNull($ref->get());
self::assertNull($ref->get());
}

public function testTrapOnce(): void
Expand All @@ -103,29 +103,29 @@ public function testTrapOnce(): void

public function testReturn(): void
{
$this->assertSame(42, trap(42)->return());
$this->assertSame(42, trap(named: 42)->return());
$this->assertSame(42, trap(named: 42)->return('bad-name'));
$this->assertSame(42, trap(42, 43)->return());
$this->assertSame(42, trap(int: 42, foo: 'bar')->return('int'));
$this->assertSame(42, trap(int: 42, foo: 'bar')->return(0));
$this->assertSame('foo', trap(...['0' => 'foo', 42 => 90])->return());
$this->assertNull(trap(null)->return());

$this->expectException(\InvalidArgumentException::class);
$this->assertSame(42, trap(42, 43)->return(10));
self::assertSame(42, trap(42)->return());
self::assertSame(42, trap(named: 42)->return());
self::assertSame(42, trap(named: 42)->return('bad-name'));
self::assertSame(42, trap(42, 43)->return());
self::assertSame(42, trap(int: 42, foo: 'bar')->return('int'));
self::assertSame(42, trap(int: 42, foo: 'bar')->return(0));
self::assertSame('foo', trap(...['0' => 'foo', 42 => 90])->return());
self::assertNull(trap(null)->return());

self::expectException(\InvalidArgumentException::class);
self::assertSame(42, trap(42, 43)->return(10));
}

public function testReturnSendsDumpOnce(): void
{
$dumper = $this->getMockBuilder(DataDumperInterface::class)
->getMock();
$dumper->expects($this->once())
$dumper->expects(self::once())
->method('dump')
->willReturnArgument(1);
Dumper::setDumper($dumper);

$this->assertSame(42, trap(42)->return());
self::assertSame(42, trap(42)->return());
}

/**
Expand Down
24 changes: 12 additions & 12 deletions tests/Unit/Handler/Router/RouterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,55 +62,55 @@ public function testRouteAssertions(string $class): void
);

Router::assert($routes, $asserts);
$this->assertTrue(true, (string) $method . ' passed');
self::assertTrue(true, (string) $method . ' passed');
}
}

public function testTryPrivate(): void
{
$router = Router::new(self::class);

$this->assertNotNull($router->match(Method::Get, '/private-route'));
self::assertNotNull($router->match(Method::Get, '/private-route'));
}

public function testMatchPublicStaticRoute(): void
{
$router = Router::new($this);

$this->assertNotNull($route = $router->match(Method::Get, '/public-static-route'));
$this->assertSame('public-static-route-result', $route());
self::assertNotNull($route = $router->match(Method::Get, '/public-static-route'));
self::assertSame('public-static-route-result', $route());
}

public function testMatchPublicStaticStaticRoute(): void
{
$router = Router::new(self::class);

$this->assertNotNull($route = $router->match(Method::Get, '/public-static-static-route'));
$this->assertSame('public-static-static-route-result', $route());
self::assertNotNull($route = $router->match(Method::Get, '/public-static-static-route'));
self::assertSame('public-static-static-route-result', $route());
}

public function testMatchPublicStaticRegexpRoute(): void
{
$router = Router::new(self::class);

$this->assertNotNull($route = $router->match(Method::Delete, '/item/123e4567-e89b-12d3-a456-426614174000'));
$this->assertSame('123e4567-e89b-12d3-a456-426614174000', $route());
self::assertNotNull($route = $router->match(Method::Delete, '/item/123e4567-e89b-12d3-a456-426614174000'));
self::assertSame('123e4567-e89b-12d3-a456-426614174000', $route());
}

public function testMatchPublicStaticRegexpRouteWithAdditionalArgs(): void
{
$router = Router::new(self::class);

$this->assertNotNull($route = $router->match(Method::Delete, '/item/123e4567-e89b-12d3-a456-426614174000'));
$this->assertSame('123e4567-e89b-12d3-a456-426614174000', $route(id: 'test'));
self::assertNotNull($route = $router->match(Method::Delete, '/item/123e4567-e89b-12d3-a456-426614174000'));
self::assertSame('123e4567-e89b-12d3-a456-426614174000', $route(id: 'test'));
}

public function testArgumentsCollision(): void
{
$router = Router::new(self::class);

$this->assertNotNull($route = $router->match(Method::Delete, '/item/123e4567-e89b-12d3-a456-426614174000'));
$this->assertSame('123e4567-e89b-12d3-a456-426614174000', $route(uuid: 'no-pasaran'));
self::assertNotNull($route = $router->match(Method::Delete, '/item/123e4567-e89b-12d3-a456-426614174000'));
self::assertSame('123e4567-e89b-12d3-a456-426614174000', $route(uuid: 'no-pasaran'));
}

#[StaticRoute(Method::Get, '/public-static-route')]
Expand Down
20 changes: 10 additions & 10 deletions tests/Unit/Sender/Frontend/EventsStorageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ public function testMaxEventsLimit(): void
$storage->add($e2 = $this->createEvent());
$storage->add($e3 = $this->createEvent());

$this->assertCount(2, $storage);
self::assertCount(2, $storage);
// In an ordered event sequence of adding events, the first event should be removed
$this->assertNull($storage->get($e1->uuid));
$this->assertNotNull($storage->get($e2->uuid));
$this->assertNotNull($storage->get($e3->uuid));
self::assertNull($storage->get($e1->uuid));
self::assertNotNull($storage->get($e2->uuid));
self::assertNotNull($storage->get($e3->uuid));
}

public function testMaxEventsLimitWithSort(): void
Expand All @@ -39,15 +39,15 @@ public function testMaxEventsLimitWithSort(): void
$storage->add($e2 = $this->createEvent());
$storage->add($e3 = $this->createEvent(timestamp: \microtime(true) - 1));

$this->assertCount(2, $storage);
self::assertCount(2, $storage);
// new event should be added in order of timestamp, and then the first event should be removed
$this->assertNull($storage->get($e3->uuid));
$this->assertNotNull($storage->get($e1->uuid));
$this->assertNotNull($storage->get($e2->uuid));
self::assertNull($storage->get($e3->uuid));
self::assertNotNull($storage->get($e1->uuid));
self::assertNotNull($storage->get($e2->uuid));
// Check order of events
$events = \iterator_to_array($storage->getIterator(), false);
$this->assertSame($e2->uuid, $events[0]->uuid);
$this->assertSame($e1->uuid, $events[1]->uuid);
self::assertSame($e2->uuid, $events[0]->uuid);
self::assertSame($e1->uuid, $events[1]->uuid);
}

private function createEvent(
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/Traffic/Dispatcher/HttpTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ public static function detectProvider()
public function testDetect(string $data, ?bool $expected): void
{
$dispatcher = new Http();
$this->assertSame($expected, $dispatcher->detect($data, new \DateTimeImmutable()));
self::assertSame($expected, $dispatcher->detect($data, new \DateTimeImmutable()));
}
}
2 changes: 1 addition & 1 deletion tests/Unit/Traffic/Dispatcher/VarDumperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static function detectProvider(): iterable
public function testDetect(string $data, ?bool $expected): void
{
$dispatcher = new VarDumper();
$this->assertSame($expected, $dispatcher->detect($data, new \DateTimeImmutable()));
self::assertSame($expected, $dispatcher->detect($data, new \DateTimeImmutable()));
}

public function testDispatchFramesTime(): void
Expand Down
6 changes: 3 additions & 3 deletions tests/Unit/Traffic/Emitter/HttpTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ static function () use ($response, $stream2): void {
}

// Check that the data is the same
$this->assertSame($data1, $data2);
$this->assertSame($content, $data1);
$this->assertSame($content, $data2);
self::assertSame($data1, $data2);
self::assertSame($content, $data1);
self::assertSame($content, $data2);
}
}
20 changes: 10 additions & 10 deletions tests/Unit/Traffic/Message/Multipart/FieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,35 @@ public function testGetters(): void
{
$field = new Field(['Foo' => 'Bar'], 'name', 'value');

$this->assertSame('name', $field->getName());
$this->assertSame('value', $field->getValue());
$this->assertSame('Bar', $field->getHeaderLine('foo'));
self::assertSame('name', $field->getName());
self::assertSame('value', $field->getValue());
self::assertSame('Bar', $field->getHeaderLine('foo'));
}

public function testWithHeader(): void
{
$field = new Field(['Foo' => 'Bar'], 'name', 'value');
$new = $field->withHeader('foo', 'baz');

$this->assertNotSame($field, $new);
$this->assertSame('Bar', $field->getHeaderLine('foo'));
$this->assertSame('baz', $new->getHeaderLine('foo'));
self::assertNotSame($field, $new);
self::assertSame('Bar', $field->getHeaderLine('foo'));
self::assertSame('baz', $new->getHeaderLine('foo'));
}

public function testFromArray(): void
{
$field = Field::fromArray(['headers' => ['Foo' => ['Bar', 'Baz']], 'value' => 'bar']);

$this->assertNull($field->getName());
$this->assertSame('bar', $field->getValue());
$this->assertSame(['Bar', 'Baz'], $field->getHeader('foo'));
self::assertNull($field->getName());
self::assertSame('bar', $field->getValue());
self::assertSame(['Bar', 'Baz'], $field->getHeader('foo'));
}

public function testSerializeAndUnserialize(): void
{
$from = new Field(['Foo' => ['Bar', 'Baz']], 'message', 'foo bar baz');
$to = Field::fromArray($from->jsonSerialize());

$this->assertEquals($from, $to);
self::assertEquals($from, $to);
}
}
Loading
Loading