Skip to content

Commit

Permalink
Add new PHP versions to build workflow (#15)
Browse files Browse the repository at this point in the history
* Add new PHP versions to build workflow

* Fix normalizing leading slashes for getPath() and __toString() methods to Uri class
  • Loading branch information
devanych authored Apr 2, 2023
1 parent bb3f88f commit 0ee1b1c
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
/infection.json.dist export-ignore
/phpcs.xml export-ignore
/phpunit.xml.dist export-ignore
/psalm.xml export-ignore
/psalm.xml.dist export-ignore
41 changes: 29 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
on:
- pull_request
- push
pull_request:
paths-ignore:
- 'docs/**'
- 'README.md'
- 'CHANGELOG.md'
- '.gitignore'
- '.gitattributes'
- 'psalm.xml.dist'

push:
paths-ignore:
- 'docs/**'
- 'README.md'
- 'CHANGELOG.md'
- '.gitignore'
- '.gitattributes'
- 'psalm.xml.dist'

name: build

Expand All @@ -22,40 +37,42 @@ jobs:
php:
- "7.4"
- "8.0"
- "8.1"
- "8.2"

steps:
- name: Checkout
uses: actions/checkout@v2
- name: Checkout.
uses: actions/checkout@v3

- name: Install PHP
- name: Install PHP with extensions.
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
ini-values: date.timezone='UTC'
tools: composer:v2
coverage: pcov

- name: Determine composer cache directory on Linux
- name: Determine composer cache directory on Linux.
if: matrix.os == 'ubuntu-latest'
run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV

- name: Determine composer cache directory on Windows
- name: Determine composer cache directory on Windows.
if: matrix.os == 'windows-latest'
run: echo "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append

- name: Cache dependencies installed with composer
uses: actions/cache@v2
- name: Cache dependencies installed with composer.
uses: actions/cache@v3
with:
path: ${{ env.COMPOSER_CACHE_DIR }}
key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: |
php${{ matrix.php }}-composer-
- name: Update composer
- name: Update composer.
run: composer self-update

- name: Install dependencies with composer
- name: Install dependencies with composer.
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: Run tests with phpunit
- name: Run tests with phpunit.
run: vendor/bin/phpunit --colors=always
41 changes: 29 additions & 12 deletions .github/workflows/static.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
on:
- pull_request
- push
pull_request:
paths-ignore:
- 'docs/**'
- 'README.md'
- 'CHANGELOG.md'
- '.gitignore'
- '.gitattributes'
- 'phpunit.xml.dist'

push:
paths-ignore:
- 'docs/**'
- 'README.md'
- 'CHANGELOG.md'
- '.gitignore'
- '.gitattributes'
- 'phpunit.xml.dist'

name: static

Expand All @@ -18,37 +33,39 @@ jobs:
php:
- "7.4"
- "8.0"
- "8.1"
- "8.2"

steps:
- name: Checkout
uses: actions/checkout@v2
- name: Checkout.
uses: actions/checkout@v3

- name: Install PHP
- name: Install PHP with extensions.
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
ini-values: memory_limit=-1
tools: composer:v2

- name: Determine composer cache directory
- name: Determine composer cache directory.
run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV

- name: Cache dependencies installed with composer
uses: actions/cache@v2
- name: Cache dependencies installed with composer.
uses: actions/cache@v3
with:
path: ${{ env.COMPOSER_CACHE_DIR }}
key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: |
php${{ matrix.php }}-composer-
- name: Update composer
- name: Update composer.
run: composer self-update

- name: Install dependencies with composer
- name: Install dependencies with composer.
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi

- name: PHPCS check
- name: PHPCS check.
run: vendor/bin/phpcs

- name: Psalm static analysis
- name: Psalm static analysis.
run: vendor/bin/psalm --no-progress
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.phpunit.result.cache
composer.lock
phpunit.xml
psalm.xml
vendor
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"php-http/psr7-integration-tests": "1.1.1",
"squizlabs/php_codesniffer": "^3.6",
"vimeo/psalm": "^4.8"
"php-http/psr7-integration-tests": "1.2",
"squizlabs/php_codesniffer": "^3.7",
"vimeo/psalm": "^4.9|^5.2"
},
"provide": {
"psr/http-message-implementation": "1.0",
Expand Down
16 changes: 0 additions & 16 deletions infection.json.dist

This file was deleted.

37 changes: 19 additions & 18 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd"
bootstrap="./vendor/autoload.php"
executionOrder="depends,defects"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
convertWarningsToExceptions="true"
convertNoticesToExceptions="true"
convertErrorsToExceptions="true"
stopOnFailure="false"
verbose="true"
colors="true"
bootstrap="vendor/autoload.php"
executionOrder="random"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
convertWarningsToExceptions="true"
convertNoticesToExceptions="true"
convertErrorsToExceptions="true"
resolveDependencies="true"
stopOnFailure="false"
failOnWarning="true"
failOnRisky="true"
verbose="true"
colors="true"
>
<php>
<ini name="error_reporting" value="-1" />
Expand All @@ -30,9 +31,9 @@
</testsuite>
</testsuites>

<filter>
<whitelist>
<directory suffix=".php">./src/</directory>
</whitelist>
</filter>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
</coverage>
</phpunit>
6 changes: 5 additions & 1 deletion psalm.xml → psalm.xml.dist
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<?xml version="1.0"?>
<psalm
errorLevel="1"
findUnusedPsalmSuppress="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<directory name="src"/>
<ignoreFiles>
<directory name="vendor"/>
</ignoreFiles>
</projectFiles>

<issueHandlers>
Expand Down
3 changes: 1 addition & 2 deletions src/ResponseTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ public function getStatusCode(): int
* @psalm-suppress DocblockTypeContradiction
* @psalm-suppress TypeDoesNotContainType
* @psalm-suppress RedundantCondition
* @psalm-suppress NoValue
*/
public function withStatus($code, $reasonPhrase = ''): ResponseInterface
{
Expand Down Expand Up @@ -184,7 +185,6 @@ public function withStatus($code, $reasonPhrase = ''): ResponseInterface
* @link http://tools.ietf.org/html/rfc7231#section-6
* @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
* @return string Reason phrase; must return an empty string if none present.
* @psalm-suppress RedundantCondition
*/
public function getReasonPhrase(): string
{
Expand All @@ -197,7 +197,6 @@ public function getReasonPhrase(): string
* @param StreamInterface|string|resource|null $body
* @param array $headers
* @param string $protocol
* @psalm-suppress MixedArgumentTypeCoercion
*/
private function init(
int $statusCode = 200,
Expand Down
24 changes: 19 additions & 5 deletions src/Uri.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,14 @@ public function __toString(): string
}

if ($this->path !== '') {
$this->cache .= $authority ? '/' . ltrim($this->path, '/') : $this->path;
if ($authority === '') {
// If the path is starting with more than one "/" and no authority is present,
// the starting slashes MUST be reduced to one.
$this->cache .= $this->path[0] === '/' ? '/' . ltrim($this->path, '/') : $this->path;
} else {
// If the path is rootless and an authority is present, the path MUST be prefixed by "/".
$this->cache .= $this->path[0] === '/' ? $this->path : '/' . $this->path;
}
}

if ($this->query !== '') {
Expand Down Expand Up @@ -193,7 +200,16 @@ public function getPort(): ?int
*/
public function getPath(): string
{
return $this->path;
if ($this->path === '' || $this->path === '/') {
return $this->path;
}

if ($this->path[0] !== '/') {
// If the path is rootless and an authority is present, the path MUST be prefixed by "/".
return $this->host === '' ? $this->path : '/' . $this->path;
}

return '/' . ltrim($this->path, '/');
}

/**
Expand Down Expand Up @@ -438,8 +454,7 @@ private function normalizePath(string $path): string
return $path;
}

$path = $this->encode($path, '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/');
return $path === '' ? '' : (($path[0] === '/') ? '/' . ltrim($path, '/') : $path);
return $this->encode($path, '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/');
}

/**
Expand Down Expand Up @@ -490,7 +505,6 @@ private function normalizeFragment(string $fragment): string
* @param string $string
* @param string $pattern
* @return string
* @psalm-suppress MixedArgument
*/
private function encode(string $string, string $pattern): string
{
Expand Down
23 changes: 21 additions & 2 deletions tests/UriTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ public function invalidConstructorProvider(): array
public function testConstructorThrowExceptionForInvalidSourceUri($uri): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectDeprecationMessage('The source URI string appears to be malformed');
new Uri($uri);
}

Expand Down Expand Up @@ -301,7 +300,7 @@ public function testWithPortThrowExceptionForInvalidPort($port): void

public function testWithPath(): void
{
$uri = $this->uri->withPath($path = 'path/to/tar<>get');
$uri = $this->uri->withPath('path/to/tar<>get');
$this->assertNotSame($this->uri, $uri);
$this->assertSame('path/to/tar%3C%3Eget', $uri->getPath());
}
Expand All @@ -327,6 +326,26 @@ public function testWithPathHasNotBeenChangedNotClone(): void
$this->assertSame($this->uri->getPath(), $uri->getPath());
}

public function testAddsSlashForRelativeUriStringWithHost(): void
{
// If the path is rootless and an authority is present, the path MUST be prefixed by "/".
$uri = $this->uri->withPath('path')->withHost('example.com');
$this->assertNotSame($this->uri, $uri);
$this->assertSame('/path', $uri->getPath());
$this->assertSame('//example.com/path', (string) $uri);
}

public function testRemoveExtraSlashesWithoutHost(): void
{
// If the path is starting with more than one "/" and no authority is
// present, the starting slashes MUST be reduced to one.
$uri = $this->uri->withPath('//path');
$this->assertNotSame($this->uri, $uri);
$this->assertSame('/path', $uri->getPath());
// URI "//path" would be interpreted as network reference and thus change the original path to the host.
$this->assertSame('/path', (string) $uri);
}

/**
* @return array
*/
Expand Down

0 comments on commit 0ee1b1c

Please sign in to comment.