diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..46ba22e --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,29 @@ +name: Tests + +on: + push: + branches: [ master ] + pull_request: + +jobs: + phpunit: + strategy: + matrix: + # 需要在以下 PHP 版本中测试 + php_version: [ 8.1 ] + runs-on: ubuntu-latest + steps: + # 检出代码 + - uses: actions/checkout@v2 + # 初始化 PHP 环境 + - name: Setup PHP environment + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php_version }} + coverage: xdebug + # 安装 composer 依赖 + - name: Install dependencies + run: composer install + # 执行 PHPUnit 测试 + - name: PHPUnit check + run: ./vendor/bin/phpunit --coverage-text \ No newline at end of file diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 0000000..3d4a3e1 --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +{"version":1,"defects":{"WeatherTest::testGetWeatherWithInvalidType":3,"WeatherTest::testGetWeather":3,"WeatherTest::testGetForecastsWeather":3,"WeatherTest::testGetWeatherInfo":3,"WeatherTest::testGetLiveWeather":3},"times":{"WeatherTest::testGetWeatherWithInvalidType":0.054,"WeatherTest::testGetWeather":0.495,"WeatherTest::testGetLiveWeather":0.001,"WeatherTest::testGetForecastsWeather":0,"WeatherTest::testGetWeatherInfo":0.388}} \ No newline at end of file diff --git a/README.md b/README.md index c063223..25475ba 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,93 @@ -

weather

- -

高德天气.

- +# 高德天气sdk +> 之前项目用过,但写的比较随意,刚好看到比较优质的教程,学习一下 ## Installing ```shell $ composer require madou1217/weather -vvv +``` + +### 使用方法: + +```php +weatherInfo($city_name)); + +// 获取实时天气 +$city_code = "654000"; +$weather->getLiveWeather($city_code); + +// 获取预报天气 +$weather->getForecastWeather($city_code); + +``` + +### 在Laravel中使用: + +.env 中添加: + +``` +AMAP_WEATHER_KEY=xxxxxxxxx +``` + +config/weathers.php 中: + +``` php + [ + 'key' => env('AMAP_WEATHER_KEY','U_DEFAULT_KEY'), + ], +] +``` + +#### 可以用两种方式来获取 Overtrue\Weather\Weather 实例: + +- 方法参数注入 + +```php +weatherInfo('乌鲁木齐市'); + //TODO ... +} ``` -## Usage +- 服务名访问 + +```php +weatherInfo('乌鲁木齐市'); + // TODO ... +} +``` -You can contribute in one of three ways: -1. File bug reports using the [issue tracker](https://github.com/madou1217/weather/issues). -2. Answer questions or fix bugs on the [issue tracker](https://github.com/madou1217/weather/issues). -3. Contribute new features or update the wiki. +## 参考 +- ### 学习地址: https://learnku.com/courses/creating-package +- ### [高德开放平台](https://lbs.amap.com/api/webservice/guide/api/weatherinfo) -_The code contribution process is not very formal. You just need to make sure that you follow the PSR-0, PSR-1, and PSR-2 coding guidelines. Any new code contributions must be accompanied by unit tests where applicable._ ## License diff --git a/src/Exceptions/Exception.php b/src/Exceptions/Exception.php new file mode 100644 index 0000000..8cd9f43 --- /dev/null +++ b/src/Exceptions/Exception.php @@ -0,0 +1,8 @@ +base_url); - - if (!\in_array(\strtolower($type), [1, 2])) { - throw new InvalidArgumentException('Invalid type value(1:base/ 2:all),you are : '.$type); + if (!\in_array(\strtolower($type), ['base', 'all'])) { + throw new InvalidArgumentException('Invalid type value(base / all),you are: '.$type); } + + $query = [ + 'key' => $this->key, + 'city' => $city, + 'output' => 'json', + 'extensions' => $type, + ]; try { $response = $this->client->get($url, [ - 'key' => $this->key, - 'city' => $city, - 'output' => 'json', - 'extensions' => $type == 1 ? 'base' : 'all', + 'query' => $query, ]); return json_decode($response->getBody()->getContents(), true) ?: []; } catch (\Exception $e) { @@ -52,5 +61,19 @@ public function weatherInfo(string $city, int $type = 1) } } + /** + * 获取实时天气 + */ + public function getLiveWeather(string $city): array + { + return $this->weatherInfo($city, 'base'); + } + /** + * 返回预报天气 + */ + public function getForecastWeather(string $city): array + { + return $this->weatherInfo($city, 'all'); + } } \ No newline at end of file diff --git a/tests/WeatherTest.php b/tests/WeatherTest.php new file mode 100644 index 0000000..b3b0e14 --- /dev/null +++ b/tests/WeatherTest.php @@ -0,0 +1,79 @@ +expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid type value(base / all),you are: foo'); + $w->weatherInfo('乌鲁木齐市', 'foo'); + $this->fail('Failed to assert getWeather throw exception with invalid argument.'); + } + + + /** + * @throws GuzzleException + * @throws InvalidArgumentException + * @throws HttpException + */ + public function testGetWeatherInfo() + { + // 创建模拟接口响应值。 + $response = new Response(200, [], '{"success": true}'); + + // 创建模拟 http client。 + $client = \Mockery::mock(Client::class); + + // 指定将会产生的行为(在后续的测试中将会按下面的参数来调用)。 + $client->allows()->get('https://restapi.amap.com/v3/weather/weatherInfo', [ + 'query' => [ + 'key' => 'mock-key', + 'city' => '乌鲁木齐市', + 'output' => 'json', + 'extensions' => 'base', + ], + ])->andReturn($response); + + // 将 `getHttpClient` 方法替换为上面创建的 http client 为返回值的模拟方法。 + $w = \Mockery::mock(Weather::class, ['mock-key'])->makePartial(); + $w->allows()->getHttpClient()->andReturn($client); // $client 为上面创建的模拟实例。 + + // 然后调用 `getWeather` 方法,并断言返回值为模拟的返回值。 + $this->assertSame(['success' => true], $w->weatherInfo('乌鲁木齐市')); + } + + + public function testGetLiveWeather() + { + // 将 getWeather 接口模拟为返回固定内容,以测试参数传递是否正确 + $w = \Mockery::mock(Weather::class, ['mock-key'])->makePartial(); + $w->expects()->weatherInfo('乌鲁木齐市', 'base')->andReturn(['success' => true]); + + // 断言正确传参并返回 + $this->assertSame(['success' => true], $w->getLiveWeather('乌鲁木齐市')); + } + + public function testGetForecastsWeather() + { + // 将 getWeather 接口模拟为返回固定内容,以测试参数传递是否正确 + $w = \Mockery::mock(Weather::class, ['mock-key'])->makePartial(); + $w->expects()->weatherInfo('乌鲁木齐市', 'all')->andReturn(['success' => true]); + + // 断言正确传参并返回 + $this->assertSame(['success' => true], $w->getForecastWeather('乌鲁木齐市')); + } +} \ No newline at end of file