diff --git a/.github/workflows/php.yml b/.github/workflows/codecov.yml
similarity index 91%
rename from .github/workflows/php.yml
rename to .github/workflows/codecov.yml
index 147cf17..4d1d440 100644
--- a/.github/workflows/php.yml
+++ b/.github/workflows/codecov.yml
@@ -1,10 +1,8 @@
-name: Build
+name: Codecov
on:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
+ push: ~
+ pull_request: ~
jobs:
build:
diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml
new file mode 100644
index 0000000..d59a5d3
--- /dev/null
+++ b/.github/workflows/psalm.yml
@@ -0,0 +1,36 @@
+name: Psalm
+
+on:
+ push: ~
+ pull_request: ~
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Install PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 7.4
+
+ - name: Validate composer.json and composer.lock
+ run: composer validate --strict
+
+ - name: Cache Composer packages
+ id: composer-cache
+ uses: actions/cache@v2
+ with:
+ path: vendor
+ key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-php-
+
+ - name: Install dependencies
+ run: composer install --prefer-dist --no-progress
+
+ - name: Psalm
+ run: |
+ ./vendor/bin/psalm --no-progress || ./vendor/bin/psalm --output-format=github --no-progress
diff --git a/README.md b/README.md
index 651c7c8..03d9701 100755
--- a/README.md
+++ b/README.md
@@ -137,7 +137,7 @@ use Dzhdmitry\TinkoffInvestApi\Streaming\WebsocketConnectionFactory;
while ($message = yield $connection->receive()) {
/** @var \Amp\Websocket\Message $message полученное из WebSocket сообщение */
- /** @var AbstractResponse $response десериализованное тело сообщения */
+ /** @var AbstractResponse $response десериализованное тело сообщения */
$response = $deserializer->deserialize(yield $message->buffer());
echo $response->getEvent() . ' at ' . $response->getTime()->format(DATE_RFC3339) . "\n";
diff --git a/composer.json b/composer.json
index e5622ae..1dd955a 100755
--- a/composer.json
+++ b/composer.json
@@ -30,6 +30,7 @@
}
},
"require-dev": {
- "phpunit/phpunit": "^9.3"
+ "phpunit/phpunit": "^9.3",
+ "vimeo/psalm": "^4.9"
}
}
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 0000000..c23e3ca
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Rest/Schema/Payload/MoneyAmount.php b/src/Rest/Schema/Payload/MoneyAmount.php
index bafd647..e6a4083 100644
--- a/src/Rest/Schema/Payload/MoneyAmount.php
+++ b/src/Rest/Schema/Payload/MoneyAmount.php
@@ -16,12 +16,12 @@ class MoneyAmount
/**
* @param string $currency
- * @param float $value
+ * @param $value
*/
public function __construct(string $currency, $value)
{
$this->currency = $currency;
- $this->value = $value;
+ $this->value = (float) $value;
}
/**
@@ -45,10 +45,6 @@ public function getValue(): float
*/
public function __toString(): string
{
- return sprintf(
- is_float($this->value) ? '%.2f %s' : '%d %s',
- $this->value,
- $this->currency
- );
+ return sprintf('%.2f %s', $this->value, $this->currency);
}
}
diff --git a/src/Streaming/Connection.php b/src/Streaming/Connection.php
index 937b198..c630578 100644
--- a/src/Streaming/Connection.php
+++ b/src/Streaming/Connection.php
@@ -11,6 +11,7 @@
use Amp\Websocket\ClientMetadata;
use Amp\Websocket\ClosedException;
use Amp\Websocket\Code;
+use Amp\Websocket\Message;
use Amp\Websocket\Options;
use Dzhdmitry\TinkoffInvestApi\Streaming\Schema\Request\RequestInterface;
@@ -54,7 +55,7 @@ public function unsubscribe(RequestInterface $request): Promise
}
/**
- * @return Promise
+ * @return Promise
*
* @throws ClosedException
*/
@@ -67,7 +68,7 @@ public function receive(): Promise
* @param int $code
* @param string $reason
*
- * @return Promise
+ * @return Promise
*/
public function close(int $code = Code::NORMAL_CLOSE, string $reason = ''): Promise
{
diff --git a/src/Streaming/Denormalizer/ResponseDenormalizer.php b/src/Streaming/Denormalizer/ResponseDenormalizer.php
index 4e68fb3..b19ab7e 100644
--- a/src/Streaming/Denormalizer/ResponseDenormalizer.php
+++ b/src/Streaming/Denormalizer/ResponseDenormalizer.php
@@ -6,11 +6,12 @@
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
+use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerAwareTrait;
/**
- * Десериализует ассоциативныймассив в один из объектов, унаследованных от AbstractResponse.
+ * Десериализует ассоциативный массив в один из объектов, унаследованных от AbstractResponse.
* Класс обекта определяет по полю "event" массива
*/
class ResponseDenormalizer implements ContextAwareDenormalizerInterface, SerializerAwareInterface
@@ -25,7 +26,7 @@ class ResponseDenormalizer implements ContextAwareDenormalizerInterface, Seriali
/**
* @param string[] $responseTypes
*/
- public function __construct($responseTypes)
+ public function __construct(array $responseTypes)
{
$this->responseTypes = $responseTypes;
}
@@ -53,6 +54,10 @@ public function denormalize($data, string $type, string $format = null, array $c
throw new UnexpectedValueException('Data has unknown event type ' . $data['event']);
}
+ if (!($this->serializer instanceof Serializer)) {
+ throw new \LogicException('Serializer must be instance of ' . Serializer::class);
+ }
+
return $this->serializer->denormalize($data, $this->responseTypes[$data['event']], $format, $context);
}
}