火星探査機、着陸座標


この一連の記事では、以下の仕様に従ってローバーソフトウェアを構築します 。 これにより、次のアプローチを実践できます。




前のパートでは、ナビゲーションパッケージを作成 、その中に初めて使用するための入力パラメーター検証するLandRoverクラスがあります。


ローバーは最初に所定の位置に着陸する必要があります。 位置は、座標( XおよびY 、整数)および方向(文字列値northeastwestまたはsouth )で構成されます。

今日はLandRoverをリファクタリングしLandRover


 cd packages/navigation git checkout 2-landing 

責任


LandRover見ると、変更の2つの理由がわかります。



これは、 LandRoverから抽出された2つの新しいクラス、 CoordinatesOrientation暗示しています。 この記事では、座標を管理します。


座標


まず、 phpspecを使用してテストクラスを作成しましょう


 vendor/bin/phpspec describe 'MarsRover\Navigation\Coordinates' 

新しいspec/MarsRover/Navigation/CoordinatesSpec.phpファイルが表示されます:


 namespace spec\MarsRover\Navigation; use MarsRover\Navigation\Coordinates; use PhpSpec\ObjectBehavior; use Prophecy\Argument; class CoordinatesSpec extends ObjectBehavior { function it_is_initializable() { $this->shouldHaveType(Coordinates::class); } } 

LandRoverテストクラスの基礎を使用して編集します。


 namespace spec\MarsRover\Navigation; use PhpSpec\ObjectBehavior; class CoordinatesSpec extends ObjectBehavior { const X = 23; const Y = 42; function it_has_x_coordinate() { $this->beConstructedWith( self::X, self::Y ); $this->getX()->shouldBe(self::X); } function it_cannot_have_non_integer_x_coordinate() { $this->beConstructedWith( 'Nobody expects the Spanish Inquisition!', self::Y ); $this->shouldThrow( \InvalidArgumentException::class )->duringInstantiation(); } function it_has_y_coordinate() { $this->beConstructedWith( self::X, self::Y ); $this->getY()->shouldBe(self::Y); } function it_cannot_have_non_integer_y_coordinate() { $this->beConstructedWith( self::X, 'No one expects the Spanish Inquisition!' ); $this->shouldThrow( \InvalidArgumentException::class )->duringInstantiation(); } } 

ここでテストを実行すると、 CoordinatesSpecクラスがロードされます。


 vendor/bin/phpspec run 

そして彼はsrc/MarsRover/Navigation/Coordinates.phpファイルを作成します:


 namespace MarsRover\Navigation; class Coordinates { private $argument1; private $argument2; public function __construct($argument1, $argument2) { $this->argument1 = $argument1; $this->argument2 = $argument2; } public function getX() { } public function getY() { } } 

今では、 LandRoverクラスに対して既に行ったことを完了するだけです。


 namespace MarsRover\Navigation; class Coordinates { private $x; private $y; public function __construct($x, $y) { if (false === is_int($x)) { throw new \InvalidArgumentException( 'X coordinate must be an integer' ); } $this->x = $x; if (false === is_int($y)) { throw new \InvalidArgumentException( 'Y coordinate must be an integer' ); } $this->y = $y; } public function getX() : int { return $this->x; } public function getY() : int { return $this->y; } } 

テストを実行します。


 vendor/bin/phpspec run 

すべて緑! LandRoverテストクラスを更新して、新しい座標クラスを使用します。


 namespace spec\MarsRover\Navigation; use PhpSpec\ObjectBehavior; class LandRoverSpec extends ObjectBehavior { const X = 23; const Y = 42; const ORIENTATION = 'north'; function it_has_coordinates() { $this->beConstructedWith( self::X, self::Y, self::ORIENTATION ); $coordinates = $this->getCoordinates(); $coordinates->getX()->shouldBe(self::X); $coordinates->getY()->shouldBe(self::Y); } function it_has_an_orientation() { $this->beConstructedWith( self::X, self::Y, self::ORIENTATION ); $this->getOrientation()->shouldBe(self::ORIENTATION); } function it_cannot_have_a_non_cardinal_orientation() { $this->beConstructedWith( self::X, self::Y, 'A hareng!' ); $this->shouldThrow( \InvalidArgumentException::class )->duringInstantiation(); } } 

xy値を検証する必要はなくなりました。これをすべてCoordinatesクラスに信頼し、これを処理してくれます。 これで、 LandRoverクラスを更新できます。


 namespace MarsRover\Navigation; class LandRover { const VALID_ORIENTATIONS = ['north', 'east', 'west', 'south']; private $coordinates; private $orientation; public function __construct($x, $y, $orientation) { $this->coordinates = new Coordinates($x, $y); if (false === in_array($orientation, self::VALID_ORIENTATIONS, true)) { throw new \InvalidArgumentException( 'Orientation must be one of: ' .implode(', ', self::VALID_ORIENTATIONS) ); } $this->orientation = $orientation; } public function getCoordinates() : Coordinates { return $this->coordinates; } public function getOrientation() : string { return $this->orientation; } } 

もう一度、テストを実行して、すべてが正常かどうかを確認します。


 vendor/bin/phpspec run 

素晴らしい、それはすべてなくなった! 変更を送信する:


 git add -A git commit -m '2: Created Coordinates' 

おわりに


テスト、コード、リファクタリングのTDDの全サイクルを実施しました。 phpspec使用は、テストクラスのプロトタイピングに非常に役立ち、コード自体にも役立ちました。


次は何ですか


次の記事では、 OrientationLandRoverを分離しLandRover


前: ローバー、着陸



Source: https://habr.com/ru/post/J315684/


All Articles