This commit is contained in:
2025-10-20 10:02:41 +08:00
parent a4858d47fc
commit dc0a271adf
2805 changed files with 451240 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
vendor/
composer.lock
.php_cs.cache

View File

@@ -0,0 +1,65 @@
<?php
/*
* This document has been generated with
* https://mlocati.github.io/php-cs-fixer-configurator/#version:2.15|configurator
* you can change this configuration by importing this file.
*/
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setIndent(' ')
->setRules([
'@PSR2' => true,
'@PhpCsFixer' => true,
'@Symfony:risky' => true,
'concat_space' => ['spacing' => 'one'],
'array_syntax' => ['syntax' => 'short'],
'array_indentation' => true,
'combine_consecutive_unsets' => true,
'method_separation' => true,
'single_quote' => true,
'declare_equal_normalize' => true,
'function_typehint_space' => true,
'hash_to_slash_comment' => true,
'include' => true,
'lowercase_cast' => true,
'no_multiline_whitespace_before_semicolons' => true,
'no_leading_import_slash' => true,
'no_multiline_whitespace_around_double_arrow' => true,
'no_spaces_around_offset' => true,
'no_unneeded_control_parentheses' => true,
'no_unused_imports' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'object_operator_without_whitespace' => true,
'single_blank_line_before_namespace' => true,
'single_class_element_per_statement' => true,
'space_after_semicolon' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'trailing_comma_in_multiline_array' => true,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'whitespace_after_comma_in_array' => true,
'no_extra_consecutive_blank_lines' => [
'curly_brace_block',
'extra',
'parenthesis_brace_block',
'square_brace_block',
'throw',
'use',
],
'binary_operator_spaces' => [
'align_double_arrow' => true,
'align_equals' => true,
],
'braces' => [
'allow_single_line_closure' => true,
],
])
->setFinder(
PhpCsFixer\Finder::create()
->exclude('vendor')
->exclude('tests')
->in(__DIR__)
);

View File

@@ -0,0 +1,31 @@
English | [简体中文](README-CN.md)
![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
## Alibaba Cloud Tea Util for PHP
## Installation
### Composer
```bash
composer require alibabacloud/tea-utils
```
## Issues
[Opening an Issue](https://github.com/aliyun/tea-util/issues/new), Issues not conforming to the guidelines may be closed immediately.
## Changelog
Detailed changes for each release are documented in the [release notes](./ChangeLog.txt).
## References
* [Latest Release](https://github.com/aliyun/tea-util)
## License
[Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)
Copyright (c) 2009-present, Alibaba Cloud All rights reserved.

31
vendor/alibabacloud/tea-utils/README.md vendored Normal file
View File

@@ -0,0 +1,31 @@
[English](README.md) | 简体中文
![](https://aliyunsdk-pages.alicdn.com/icons/AlibabaCloud.svg)
## Alibaba Cloud Tea Util for PHP
## 安装
### Composer
```bash
composer require alibabacloud/tea-utils
```
## 问题
[提交 Issue](https://github.com/aliyun/tea-util/issues/new),不符合指南的问题可能会立即关闭。
## 发行说明
每个版本的详细更改记录在[发行说明](./ChangeLog.txt)中。
## 相关
* [最新源码](https://github.com/aliyun/tea-util)
## 许可证
[Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)
Copyright (c) 2009-present, Alibaba Cloud All rights reserved.

View File

@@ -0,0 +1,38 @@
{
"name": "alibabacloud/tea-utils",
"description": "Alibaba Cloud Tea Utils for PHP",
"type": "library",
"license": "Apache-2.0",
"authors": [
{
"name": "Alibaba Cloud SDK",
"email": "sdk-team@alibabacloud.com"
}
],
"support": {
"source": "https://github.com/aliyun/tea-util",
"issues": "https://github.com/aliyun/tea-util/issues"
},
"require": {
"php": ">5.5",
"alibabacloud/tea": "^3.1"
},
"autoload": {
"psr-4": {
"AlibabaCloud\\Tea\\Utils\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"AlibabaCloud\\Tea\\Utils\\Tests\\": "tests"
}
},
"scripts": {
"fixer": "php-cs-fixer fix ./",
"test": [
"@clearCache",
"./vendor/bin/phpunit --colors=always"
],
"clearCache": "rm -rf cache/*"
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="tests/bootstrap.php" colors="true" executionOrder="depends,defects" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
<report>
<clover outputFile="cache/coverage.clover"/>
<html outputDirectory="cache/coverage" lowUpperBound="35" highLowerBound="70"/>
</report>
</coverage>
<logging/>
<testsuites>
<testsuite name="default">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@@ -0,0 +1,600 @@
<?php
namespace AlibabaCloud\Tea\Utils;
use AlibabaCloud\Tea\Model;
use GuzzleHttp\Psr7\Stream;
use Psr\Http\Message\StreamInterface;
class Utils
{
private static $defaultUserAgent = '';
/**
* Convert a string(utf8) to bytes.
*
* @param string $string
*
* @return array the return bytes
*/
public static function toBytes($string)
{
if (self::is_bytes($string)) {
return $string;
}
$bytes = [];
for ($i = 0; $i < \strlen($string); ++$i) {
$bytes[] = \ord($string[$i]);
}
return $bytes;
}
/**
* Convert a bytes to string(utf8).
*
* @param array $bytes
*
* @return string the return string
*/
public static function toString($bytes)
{
if (\is_string($bytes)) {
return $bytes;
}
$str = '';
foreach ($bytes as $ch) {
$str .= \chr($ch);
}
return $str;
}
/**
* Parse it by JSON format.
*
* @param string $jsonString
*
* @return array the parsed result
*/
public static function parseJSON($jsonString)
{
return json_decode($jsonString, true);
}
/**
* Read data from a readable stream, and compose it to a bytes.
*
* @param StreamInterface $stream the readable stream
*
* @return array the bytes result
*/
public static function readAsBytes($stream)
{
$str = self::readAsString($stream);
return self::toBytes($str);
}
/**
* Read data from a readable stream, and compose it to a string.
*
* @param StreamInterface $stream the readable stream
*
* @return string the string result
*/
public static function readAsString($stream)
{
if ($stream->isSeekable()) {
$stream->rewind();
}
return $stream->getContents();
}
/**
* Read data from a readable stream, and parse it by JSON format.
*
* @param StreamInterface $stream the readable stream
*
* @return array the parsed result
*/
public static function readAsJSON($stream)
{
return self::parseJSON(self::readAsString($stream));
}
/**
* Generate a nonce string.
*
* @return string the nonce string
*/
public static function getNonce()
{
return md5(uniqid() . uniqid(md5(microtime(true)), true));
}
/**
* Get an UTC format string by current date, e.g. 'Thu, 06 Feb 2020 07:32:54 GMT'.
*
* @return string the UTC format string
*/
public static function getDateUTCString()
{
return gmdate('D, d M Y H:i:s T');
}
/**
* If not set the real, use default value.
*
* @param string $real
* @param string $default
*
* @return string
*/
public static function defaultString($real, $default = '')
{
return null === $real ? $default : $real;
}
/**
* If not set the real, use default value.
*
* @param int $real
* @param int $default
*
* @return int the return number
*/
public static function defaultNumber($real, $default = 0)
{
if (null === $real) {
return $default;
}
return (int) $real;
}
/**
* Format a map to form string, like a=a%20b%20c.
*
* @param array|object $query
*
* @return string the form string
*/
public static function toFormString($query)
{
if (null === $query) {
return '';
}
if (\is_object($query)) {
$query = json_decode(self::toJSONString($query), true);
}
return str_replace('+', '%20', http_build_query($query));
}
/**
* If not set the real, use default value.
*
* @param array|Model $object
*
* @return string the return string
*/
public static function toJSONString($object)
{
if (is_string($object)) {
return $object;
}
if ($object instanceof Model) {
$object = $object->toMap();
}
return json_encode($object, JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES);
}
/**
* Check the string is empty?
*
* @param string $val
*
* @return bool if string is null or zero length, return true
*
* @deprecated
*/
public static function _empty($val)
{
return empty($val);
}
/**
* Check the string is empty?
*
* @param string $val
*
* @return bool if string is null or zero length, return true
*
* @deprecated
*/
public static function emptyWithSuffix($val)
{
return empty($val);
}
/**
* Check the string is empty?
*
* @param string $val
*
* @return bool if string is null or zero length, return true
*/
public static function empty_($val)
{
return empty($val);
}
/**
* Check one string equals another one?
*
* @param int $left
* @param int $right
*
* @return bool if equals, return true
*/
public static function equalString($left, $right)
{
return $left === $right;
}
/**
* Check one number equals another one?
*
* @param int $left
* @param int $right
*
* @return bool if equals, return true
*/
public static function equalNumber($left, $right)
{
return $left === $right;
}
/**
* Check one value is unset.
*
* @param mixed $value
*
* @return bool if unset, return true
*/
public static function isUnset(&$value = null)
{
return !isset($value) || null === $value;
}
/**
* Stringify the value of map.
*
* @param array $map
*
* @return array the new stringified map
*/
public static function stringifyMapValue($map)
{
if (null === $map) {
return [];
}
foreach ($map as &$node) {
if (is_numeric($node)) {
$node = (string) $node;
} elseif (null === $node) {
$node = '';
} elseif (\is_bool($node)) {
$node = true === $node ? 'true' : 'false';
} elseif (\is_object($node)) {
$node = json_decode(json_encode($node), true);
}
}
return $map;
}
/**
* Anyify the value of map.
*
* @param array $m
*
* @return array the new anyfied map
*/
public static function anyifyMapValue($m)
{
return $m;
}
/**
* Assert a value, if it is a boolean, return it, otherwise throws.
*
* @param mixed $value
*
* @return bool the boolean value
*/
public static function assertAsBoolean($value)
{
if (\is_bool($value)) {
return $value;
}
throw new \InvalidArgumentException('It is not a boolean value.');
}
/**
* Assert a value, if it is a string, return it, otherwise throws.
*
* @param mixed $value
*
* @return string the string value
*/
public static function assertAsString($value)
{
if (\is_string($value)) {
return $value;
}
throw new \InvalidArgumentException('It is not a string value.');
}
private static function is_bytes($value)
{
if (!\is_array($value)) {
return false;
}
$i = 0;
foreach ($value as $k => $ord) {
if ($k !== $i) {
return false;
}
if (!\is_int($ord)) {
return false;
}
if ($ord < 0 || $ord > 255) {
return false;
}
++$i;
}
return true;
}
/**
* Assert a value, if it is a bytes, return it, otherwise throws.
*
* @param mixed $value
*
* @return bytes the bytes value
*/
public static function assertAsBytes($value)
{
if (self::is_bytes($value)) {
return $value;
}
throw new \InvalidArgumentException('It is not a bytes value.');
}
/**
* Assert a value, if it is a number, return it, otherwise throws.
*
* @param mixed $value
*
* @return int the number value
*/
public static function assertAsNumber($value)
{
if (\is_numeric($value)) {
return $value;
}
throw new \InvalidArgumentException('It is not a number value.');
}
/**
* Assert a value, if it is a integer, return it, otherwise throws
* @param mixed $value
* @return int the integer value
*/
public static function assertAsInteger($value){
if (\is_int($value)) {
return $value;
}
throw new \InvalidArgumentException('It is not a int value.');
}
/**
* Assert a value, if it is a map, return it, otherwise throws.
*
* @param $any
*
* @return array the map value
*/
public static function assertAsMap($any)
{
if (\is_array($any)) {
return $any;
}
throw new \InvalidArgumentException('It is not a map value.');
}
public static function assertAsArray($any){
if (\is_array($any)) {
return $any;
}
throw new \InvalidArgumentException('It is not a array value.');
}
/**
* Get user agent, if it userAgent is not null, splice it with defaultUserAgent and return, otherwise return
* defaultUserAgent.
*
* @param string $userAgent
*
* @return string the string value
*/
public static function getUserAgent($userAgent = '')
{
if (empty(self::$defaultUserAgent)) {
self::$defaultUserAgent = sprintf('AlibabaCloud (%s; %s) PHP/%s Core/3.1 TeaDSL/1', PHP_OS, \PHP_SAPI, PHP_VERSION);
}
if (!empty($userAgent)) {
return self::$defaultUserAgent . ' ' . $userAgent;
}
return self::$defaultUserAgent;
}
/**
* If the code between 200 and 300, return true, or return false.
*
* @param int $code
*
* @return bool
*/
public static function is2xx($code)
{
return $code >= 200 && $code < 300;
}
/**
* If the code between 300 and 400, return true, or return false.
*
* @param int $code
*
* @return bool
*/
public static function is3xx($code)
{
return $code >= 300 && $code < 400;
}
/**
* If the code between 400 and 500, return true, or return false.
*
* @param int $code
*
* @return bool
*/
public static function is4xx($code)
{
return $code >= 400 && $code < 500;
}
/**
* If the code between 500 and 600, return true, or return false.
*
* @param int $code
*
* @return bool
*/
public static function is5xx($code)
{
return $code >= 500 && $code < 600;
}
/**
* Validate model.
*
* @param Model $model
*/
public static function validateModel($model)
{
if (null !== $model) {
$model->validate();
}
}
/**
* Model transforms to map[string]any.
*
* @param Model $model
*
* @return array
*/
public static function toMap($model)
{
if (null === $model) {
return [];
}
$map = $model->toMap();
$names = $model->getName();
$vars = get_object_vars($model);
foreach ($vars as $k => $v) {
if (false !== strpos($k, 'Shrink') && !isset($names[$k])) {
// A field that has the suffix `Shrink` and is not a Model class property.
$targetKey = ucfirst(substr($k, 0, \strlen($k) - 6));
if (isset($map[$targetKey])) {
// $targetKey exists in $map.
$map[$targetKey] = $v;
}
}
}
return $map;
}
/**
* Suspends the current thread for the specified number of milliseconds.
*
* @param int $millisecond
*/
public static function sleep($millisecond)
{
usleep($millisecond * 1000);
}
/**
* Transform input as array.
*
* @param mixed $input
*
* @return array
*/
public static function toArray($input)
{
if (\is_array($input)) {
foreach ($input as $k => &$v) {
$v = self::toArray($v);
}
} elseif ($input instanceof Model) {
$input = $input->toMap();
foreach ($input as $k => &$v) {
$v = self::toArray($v);
}
}
return $input;
}
/**
* Assert a value, if it is a readable, return it, otherwise throws.
*
* @param mixed $value
*
* @return Stream the readable value
*/
public static function assertAsReadable($value)
{
if (\is_string($value)) {
return new Stream(
fopen('data://text/plain;base64,' .
base64_encode($value), 'r')
);
}
if ($value instanceof Stream) {
return $value;
}
throw new \InvalidArgumentException('It is not a stream value.');
}
}

View File

@@ -0,0 +1,38 @@
<?php
// This file is auto-generated, don't edit it. Thanks.
namespace AlibabaCloud\Tea\Utils\Utils;
use AlibabaCloud\Tea\Model;
class ExtendsParameters extends Model {
public function validate() {}
public function toMap() {
$res = [];
if (null !== $this->headers) {
$res['headers'] = $this->headers;
}
if (null !== $this->queries) {
$res['queries'] = $this->queries;
}
return $res;
}
/**
* @param array $map
* @return ExtendsParameters
*/
public static function fromMap($map = []) {
$model = new self();
if(isset($map['headers'])){
$model->headers = $map['headers'];
}
if(isset($map['queries'])){
$model->queries = $map['queries'];
}
return $model;
}
public $headers;
public $queries;
}

View File

@@ -0,0 +1,273 @@
<?php
// This file is auto-generated, don't edit it. Thanks.
namespace AlibabaCloud\Tea\Utils\Utils;
use AlibabaCloud\Tea\Model;
/**
* The common runtime options model
*/
class RuntimeOptions extends Model {
protected $_name = [
'autoretry' => 'autoretry',
'ignoreSSL' => 'ignoreSSL',
'key' => 'key',
'cert' => 'cert',
'ca' => 'ca',
'maxAttempts' => 'max_attempts',
'backoffPolicy' => 'backoff_policy',
'backoffPeriod' => 'backoff_period',
'readTimeout' => 'readTimeout',
'connectTimeout' => 'connectTimeout',
'httpProxy' => 'httpProxy',
'httpsProxy' => 'httpsProxy',
'noProxy' => 'noProxy',
'maxIdleConns' => 'maxIdleConns',
'localAddr' => 'localAddr',
'socks5Proxy' => 'socks5Proxy',
'socks5NetWork' => 'socks5NetWork',
'keepAlive' => 'keepAlive',
];
public function validate() {}
public function toMap() {
$res = [];
if (null !== $this->autoretry) {
$res['autoretry'] = $this->autoretry;
}
if (null !== $this->ignoreSSL) {
$res['ignoreSSL'] = $this->ignoreSSL;
}
if (null !== $this->key) {
$res['key'] = $this->key;
}
if (null !== $this->cert) {
$res['cert'] = $this->cert;
}
if (null !== $this->ca) {
$res['ca'] = $this->ca;
}
if (null !== $this->maxAttempts) {
$res['max_attempts'] = $this->maxAttempts;
}
if (null !== $this->backoffPolicy) {
$res['backoff_policy'] = $this->backoffPolicy;
}
if (null !== $this->backoffPeriod) {
$res['backoff_period'] = $this->backoffPeriod;
}
if (null !== $this->readTimeout) {
$res['readTimeout'] = $this->readTimeout;
}
if (null !== $this->connectTimeout) {
$res['connectTimeout'] = $this->connectTimeout;
}
if (null !== $this->httpProxy) {
$res['httpProxy'] = $this->httpProxy;
}
if (null !== $this->httpsProxy) {
$res['httpsProxy'] = $this->httpsProxy;
}
if (null !== $this->noProxy) {
$res['noProxy'] = $this->noProxy;
}
if (null !== $this->maxIdleConns) {
$res['maxIdleConns'] = $this->maxIdleConns;
}
if (null !== $this->localAddr) {
$res['localAddr'] = $this->localAddr;
}
if (null !== $this->socks5Proxy) {
$res['socks5Proxy'] = $this->socks5Proxy;
}
if (null !== $this->socks5NetWork) {
$res['socks5NetWork'] = $this->socks5NetWork;
}
if (null !== $this->keepAlive) {
$res['keepAlive'] = $this->keepAlive;
}
if (null !== $this->extendsParameters) {
$res['extendsParameters'] = null !== $this->extendsParameters ? $this->extendsParameters->toMap() : null;
}
return $res;
}
/**
* @param array $map
* @return RuntimeOptions
*/
public static function fromMap($map = []) {
$model = new self();
if(isset($map['autoretry'])){
$model->autoretry = $map['autoretry'];
}
if(isset($map['ignoreSSL'])){
$model->ignoreSSL = $map['ignoreSSL'];
}
if(isset($map['key'])){
$model->key = $map['key'];
}
if(isset($map['cert'])){
$model->cert = $map['cert'];
}
if(isset($map['ca'])){
$model->ca = $map['ca'];
}
if(isset($map['max_attempts'])){
$model->maxAttempts = $map['max_attempts'];
}
if(isset($map['backoff_policy'])){
$model->backoffPolicy = $map['backoff_policy'];
}
if(isset($map['backoff_period'])){
$model->backoffPeriod = $map['backoff_period'];
}
if(isset($map['readTimeout'])){
$model->readTimeout = $map['readTimeout'];
}
if(isset($map['connectTimeout'])){
$model->connectTimeout = $map['connectTimeout'];
}
if(isset($map['httpProxy'])){
$model->httpProxy = $map['httpProxy'];
}
if(isset($map['httpsProxy'])){
$model->httpsProxy = $map['httpsProxy'];
}
if(isset($map['noProxy'])){
$model->noProxy = $map['noProxy'];
}
if(isset($map['maxIdleConns'])){
$model->maxIdleConns = $map['maxIdleConns'];
}
if(isset($map['localAddr'])){
$model->localAddr = $map['localAddr'];
}
if(isset($map['socks5Proxy'])){
$model->socks5Proxy = $map['socks5Proxy'];
}
if(isset($map['socks5NetWork'])){
$model->socks5NetWork = $map['socks5NetWork'];
}
if(isset($map['keepAlive'])){
$model->keepAlive = $map['keepAlive'];
}
if(isset($map['extendsParameters'])){
$model->extendsParameters = ExtendsParameters::fromMap($map['extendsParameters']);
}
return $model;
}
/**
* @description whether to try again
* @var bool
*/
public $autoretry;
/**
* @description ignore SSL validation
* @var bool
*/
public $ignoreSSL;
/**
* @description privite key for client certificate
* @var string
*/
public $key;
/**
* @description client certificate
* @var string
*/
public $cert;
/**
* @description server certificate
* @var string
*/
public $ca;
/**
* @description maximum number of retries
* @var int
*/
public $maxAttempts;
/**
* @description backoff policy
* @var string
*/
public $backoffPolicy;
/**
* @description backoff period
* @var int
*/
public $backoffPeriod;
/**
* @description read timeout
* @var int
*/
public $readTimeout;
/**
* @description connect timeout
* @var int
*/
public $connectTimeout;
/**
* @description http proxy url
* @var string
*/
public $httpProxy;
/**
* @description https Proxy url
* @var string
*/
public $httpsProxy;
/**
* @description agent blacklist
* @var string
*/
public $noProxy;
/**
* @description maximum number of connections
* @var int
*/
public $maxIdleConns;
/**
* @description local addr
* @var string
*/
public $localAddr;
/**
* @description SOCKS5 proxy
* @var string
*/
public $socks5Proxy;
/**
* @description SOCKS5 netWork
* @var string
*/
public $socks5NetWork;
/**
* @description whether to enable keep-alive
* @var bool
*/
public $keepAlive;
/**
* @description Extends Parameters
* @var ExtendsParameters
*/
public $extendsParameters;
}

View File

@@ -0,0 +1,550 @@
<?php
namespace AlibabaCloud\Tea\Utils\Tests;
use AlibabaCloud\Tea\Model;
use AlibabaCloud\Tea\Utils\Utils;
use AlibabaCloud\Tea\Utils\Utils\ExtendsParameters;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
use GuzzleHttp\Psr7\Stream;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
/**
* @internal
* @coversNothing
*/
final class UtilsTest extends TestCase
{
public function getStream()
{
return new Stream(fopen('http://httpbin.org/get', 'r'));
}
public function testToBytes()
{
$this->assertEquals([
115, 116, 114, 105, 110, 103,
], Utils::toBytes('string'));
$this->assertEquals([
115, 116, 114, 105, 110, 103,
], Utils::toBytes([
115, 116, 114, 105, 110, 103,
]));
}
public function testToString()
{
$this->assertEquals('string', Utils::toString([
115, 116, 114, 105, 110, 103,
]));
$this->assertEquals('string', Utils::toString('string'));
}
public function testParseJSON()
{
$this->assertEquals([
'a' => 'b',
], Utils::parseJSON('{"a":"b"}'));
}
public function testReadAsBytes()
{
$bytes = Utils::readAsBytes($this->getStream());
$this->assertEquals(123, $bytes[0]);
}
public function testReadAsString()
{
$string = Utils::readAsString($this->getStream());
$this->assertEquals($string[0], '{');
}
public function testReadAsJSON()
{
$result = Utils::readAsJSON($this->getStream());
$this->assertEquals('http://httpbin.org/get', $result['url']);
}
public function testGetNonce()
{
$nonce1 = Utils::getNonce();
$nonce2 = Utils::getNonce();
$this->assertNotEquals($nonce1, $nonce2);
}
public function testGetDateUTCString()
{
$gmdate = Utils::getDateUTCString();
$now = time();
$this->assertTrue(abs($now - strtotime($gmdate)) <= 1);
}
public function testDefaultString()
{
$this->assertEquals('', Utils::defaultString(null));
$this->assertEquals('default', Utils::defaultString(null, 'default'));
$this->assertEquals('real', Utils::defaultString('real', 'default'));
}
public function testDefaultNumber()
{
$this->assertEquals(0, Utils::defaultNumber(null));
$this->assertEquals(0, Utils::defaultNumber(0, 3));
$this->assertEquals(404, Utils::defaultNumber(null, 404));
$this->assertEquals(200, Utils::defaultNumber(200, 404));
}
public function testToFormString()
{
$query = [
'foo' => 'bar',
'empty' => '',
'a' => null,
'withWhiteSpace' => 'a b',
];
$this->assertEquals('foo=bar&empty=&withWhiteSpace=a%20b', Utils::toFormString($query));
$object = json_decode(json_encode($query));
$this->assertEquals('foo=bar&empty=&withWhiteSpace=a%20b', Utils::toFormString($object));
}
public function testToJSONString()
{
$object = new \stdClass();
$this->assertJson(Utils::toJSONString($object));
$this->assertEquals('[]', Utils::toJSONString([]));
$this->assertEquals('["foo"]', Utils::toJSONString(['foo']));
$this->assertEquals(
'{"str":"test","number":1,"bool":false,"null":null,"chinese":"中文","http":"https://aliyun.com:8080/zh/中文.html"}',
Utils::toJSONString([
'str' => 'test',
'number' => 1,
'bool' => FALSE,
'null' => null,
'chinese' => '中文',
'http' => 'https://aliyun.com:8080/zh/中文.html',
])
);
$this->assertEquals('1', Utils::toJSONString(1));
$this->assertEquals('true', Utils::toJSONString(TRUE));
$this->assertEquals('null', Utils::toJSONString(null));
}
public function testEmpty()
{
$this->assertTrue(Utils::_empty(''));
$this->assertFalse(Utils::_empty('not empty'));
}
public function testEqualString()
{
$this->assertTrue(Utils::equalString('a', 'a'));
$this->assertFalse(Utils::equalString('a', 'b'));
}
public function testEqualNumber()
{
$this->assertTrue(Utils::equalNumber(1, 1));
$this->assertFalse(Utils::equalNumber(1, 2));
}
public function testIsUnset()
{
$this->assertTrue(Utils::isUnset($a));
$b = 1;
$this->assertFalse(Utils::isUnset($b));
}
public function testStringifyMapValue()
{
$this->assertEquals([], Utils::stringifyMapValue(null));
$this->assertEquals([
'foo' => 'bar',
'null' => '',
'true' => 'true',
'false' => 'false',
'number' => '1000',
], Utils::stringifyMapValue([
'foo' => 'bar',
'null' => null,
'true' => true,
'false' => false,
'number' => 1000,
]));
}
public function testAnyifyMapValue()
{
$this->assertEquals([
'foo' => 'bar',
'null' => null,
'true' => true,
'false' => false,
'number' => 1000,
], Utils::anyifyMapValue([
'foo' => 'bar',
'null' => null,
'true' => true,
'false' => false,
'number' => 1000,
]));
}
public function testAssertAsBoolean()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a boolean value.');
Utils::assertAsBoolean('true');
try {
$map = true;
$this->assertEquals($map, Utils::assertAsBoolean($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsString()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a string value.');
Utils::assertAsString(123);
try {
$map = '123';
$this->assertEquals($map, Utils::assertAsString($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsBytes()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a bytes value.');
// failed because $var is not array
Utils::assertAsBytes('test');
// failed because $var is map not array
Utils::assertAsBytes(['foo' => 1]);
// failed because item value is not int
Utils::assertAsBytes(['1']);
// failed because item value is out off range
Utils::assertAsBytes([256]);
try {
// success
$map = [1, 2, 3];
$this->assertEquals($map, Utils::assertAsBytes($map));
$this->assertEquals([
115, 116, 114, 105, 110, 103,
], Utils::assertAsBytes(Utils::toBytes('string')));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsNumber()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a number value.');
Utils::assertAsNumber('is not number');
try {
$map = 123;
$this->assertEquals($map, Utils::assertAsNumber($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsInteger()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a int value.');
Utils::assertAsInteger('is not int');
try {
$map = 123;
$this->assertEquals($map, Utils::assertAsInteger($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsMap()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a map value.');
Utils::assertAsMap('is not array');
try {
$map = ['foo' => 'bar'];
$this->assertEquals($map, Utils::assertAsMap($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testAssertAsArray()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a array value.');
Utils::assertAsArray('is not array');
try {
$map = ['foo'];
$this->assertEquals($map, Utils::assertAsArray($map));
} catch (\Exception $e) {
// should not be here
$this->assertTrue(false);
}
}
public function testGetUserAgent()
{
$this->assertTrue(false !== strpos(Utils::getUserAgent('CustomUserAgent'), 'CustomUserAgent'));
}
public function testIs2xx()
{
$this->assertTrue(Utils::is2xx(200));
$this->assertFalse(Utils::is2xx(300));
}
public function testIs3xx()
{
$this->assertTrue(Utils::is3xx(300));
$this->assertFalse(Utils::is3xx(400));
}
public function testIs4xx()
{
$this->assertTrue(Utils::is4xx(400));
$this->assertFalse(Utils::is4xx(500));
}
public function testIs5xx()
{
$this->assertTrue(Utils::is5xx(500));
$this->assertFalse(Utils::is5xx(600));
}
public function testToMap()
{
$from = new RequestTest();
$from->query = new RequestTestQuery([
'booleanParamInQuery' => true,
'mapParamInQuery' => [1, 2, 3],
]);
$this->assertTrue($from->query->booleanParamInQuery);
$this->assertEquals([1, 2, 3], $from->query->mapParamInQuery);
$target = new RequestShrinkTest([]);
$this->convert($from, $target);
$this->assertEquals([
'BooleanParamInQuery' => true,
'MapParamInQuery' => [1, 2, 3],
], $target->query->toMap());
$target->query->mapParamInQueryShrink = json_encode($from->query->mapParamInQuery);
$this->assertEquals([
'BooleanParamInQuery' => true,
'MapParamInQuery' => '[1,2,3]',
], Utils::toMap($target->query));
}
public function testSleep()
{
$before = microtime(true) * 1000;
Utils::sleep(1000);
$after = microtime(true) * 1000;
$sub = $after - $before;
$this->assertTrue(990 <= $sub && $sub <= 1100);
}
public function testToArray()
{
$model = new RequestTest();
$model->query = 'foo';
$this->assertEquals([
['query' => 'foo'],
], Utils::toArray([$model]));
$subModel = new RequestTest();
$subModel->query = 'bar';
$model->query = $subModel;
$this->assertEquals([
['query' => ['query' => 'bar']],
], Utils::toArray([$model]));
}
public function testAssertAsReadable()
{
$s0 = Utils::assertAsReadable('string content');
$this->assertTrue($s0 instanceof Stream);
$s1 = Utils::assertAsReadable($s0);
$this->assertEquals($s1, $s0);
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('It is not a stream value.');
Utils::assertAsReadable(0);
}
public function testRuntimeOptions()
{
$opts = new RuntimeOptions([
"autoretry" => false,
"ignoreSSL" => false,
"key" => "key",
"cert" => "cert",
"ca" => "ca",
"maxAttempts" => 3,
"backoffPolicy" => "backoffPolicy",
"backoffPeriod" => 10,
"readTimeout" => 3000,
"connectTimeout" => 3000,
"httpProxy" => "httpProxy",
"httpsProxy" => "httpsProxy",
"noProxy" => "noProxy",
"maxIdleConns" => 300,
"keepAlive" => true,
"extendsParameters" => new ExtendsParameters([
"headers" => ['key' => 'value'],
"queries" => ['key' => 'value'],
]),
]);
$this->assertEquals(false, $opts->autoretry);
$this->assertEquals(false, $opts->ignoreSSL);
$this->assertEquals("key", $opts->key);
$this->assertEquals("cert", $opts->cert);
$this->assertEquals("ca", $opts->ca);
$this->assertEquals(3, $opts->maxAttempts);
$this->assertEquals("backoffPolicy", $opts->backoffPolicy);
$this->assertEquals(10, $opts->backoffPeriod);
$this->assertEquals(3000, $opts->readTimeout);
$this->assertEquals(3000, $opts->connectTimeout);
$this->assertEquals("httpProxy", $opts->httpProxy);
$this->assertEquals("httpsProxy", $opts->httpsProxy);
$this->assertEquals("noProxy", $opts->noProxy);
$this->assertEquals(300, $opts->maxIdleConns);
$this->assertEquals(true, $opts->keepAlive);
$this->assertEquals('value', $opts->extendsParameters->headers['key']);
$this->assertEquals('value', $opts->extendsParameters->queries['key']);
}
private function convert($body, &$content)
{
$class = new \ReflectionClass($body);
foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
$name = $property->getName();
if (!$property->isStatic()) {
$value = $property->getValue($body);
if ($value instanceof StreamInterface) {
continue;
}
$content->{$name} = $value;
}
}
}
}
/**
* @internal
* @coversNothing
*/
class RequestTest extends Model
{
/**
* @var RequestTestQuery
*/
public $query;
}
/**
* @internal
* @coversNothing
*/
class RequestShrinkTest extends Model
{
/**
* @var RequestTestShrinkQuery
*/
public $query;
}
class RequestTestQuery extends Model
{
/**
* @description test
*
* @var bool
*/
public $booleanParamInQuery;
/**
* @description test
*
* @var array
*/
public $mapParamInQuery;
protected $_name = [
'booleanParamInQuery' => 'BooleanParamInQuery',
'mapParamInQuery' => 'MapParamInQuery',
];
public function toMap()
{
$res = [];
if (null !== $this->booleanParamInQuery) {
$res['BooleanParamInQuery'] = $this->booleanParamInQuery;
}
if (null !== $this->mapParamInQuery) {
$res['MapParamInQuery'] = $this->mapParamInQuery;
}
return $res;
}
}
class RequestTestShrinkQuery extends Model
{
/**
* @description test
*
* @var float
*/
public $booleanParamInQuery;
/**
* @description test
*
* @var string
*/
public $mapParamInQueryShrink;
protected $_name = [
'booleanParamInQuery' => 'BooleanParamInQuery',
'mapParamInQueryShrink' => 'MapParamInQuery',
];
public function toMap()
{
$res = [];
if (null !== $this->booleanParamInQuery) {
$res['BooleanParamInQuery'] = $this->booleanParamInQuery;
}
if (null !== $this->mapParamInQueryShrink) {
$res['MapParamInQuery'] = $this->mapParamInQueryShrink;
}
return $res;
}
}

View File

@@ -0,0 +1,3 @@
<?php
require dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';