1+ <?php
2+ declare (strict_types=1 );
3+
4+ namespace App \Tests \Unit \Application \Service ;
5+
6+ use App \Application \Enum \Direction ;
7+ use App \Application \Factory \RoverFactory ;
8+ use App \Application \Repository \RoverRepositoryInterface ;
9+ use App \Application \Service \NasaRoverService ;
10+ use App \Application \Service \RoverPositionDto ;
11+ use App \Command \NasaRovers \Dto \RoverInformationDto ;
12+ use App \Domain \Entity \Rover ;
13+ use Exception ;
14+ use PHPUnit \Framework \MockObject \MockObject ;
15+ use PHPUnit \Framework \TestCase ;
16+
17+ class NasaRoverServiceTest extends TestCase
18+ {
19+ private RoverFactory |MockObject $ roverFactory ;
20+ private RoverRepositoryInterface |MockObject $ roverRepository ;
21+ private NasaRoverService $ nasaRoverService ;
22+
23+ protected function setUp (): void
24+ {
25+ $ this ->roverFactory = $ this ->createMock (RoverFactory::class);
26+ $ this ->roverRepository = $ this ->createMock (RoverRepositoryInterface::class);
27+
28+ $ this ->nasaRoverService = new NasaRoverService (
29+ $ this ->roverFactory ,
30+ $ this ->roverRepository
31+ );
32+
33+ parent ::setUp ();
34+ }
35+
36+ /**
37+ * @throws Exception
38+ *
39+ * @dataProvider roverCoordinatesDataProvider
40+ */
41+ public function testSuccessRoverMoving (
42+ int $ xCoordinate ,
43+ int $ yCoordinate ,
44+ Direction $ direction
45+ ): void {
46+ $ rover = new Rover ($ xCoordinate , $ yCoordinate , $ direction );
47+ $ rover2 = new Rover ($ xCoordinate , $ yCoordinate +1 , $ direction );
48+ $ finalRoverObject = new Rover ($ xCoordinate , $ yCoordinate +2 , $ direction );
49+
50+ $ this ->roverFactory ->expects (self ::once ())
51+ ->method ('create ' )
52+ ->with ($ xCoordinate , $ yCoordinate , $ direction )
53+ ->willReturn ($ rover );
54+
55+ $ this ->roverRepository ->expects (self ::exactly (2 ))
56+ ->method ('move ' )
57+ ->withConsecutive (
58+ [$ rover ],
59+ [$ rover2 ]
60+ )
61+ ->willReturnOnConsecutiveCalls (
62+ $ rover2 ,
63+ $ finalRoverObject
64+ );
65+
66+ $ this ->roverRepository ->expects (self ::never ())
67+ ->method ('turnLeft ' );
68+
69+ $ this ->roverRepository ->expects (self ::never ())
70+ ->method ('turnRight ' );
71+
72+ $ expectedResult = new RoverPositionDto ($ xCoordinate , $ yCoordinate +2 , Direction::North);
73+
74+ $ roverInformationDto = new RoverInformationDto ($ xCoordinate , $ yCoordinate , $ direction );
75+ $ roverInformationDto ->setActions ('MM ' );
76+ $ actualResult = $ this ->nasaRoverService ->process ($ roverInformationDto );
77+
78+ $ this ->assertEquals ($ expectedResult , $ actualResult );
79+ }
80+
81+ /**
82+ * @throws Exception
83+ *
84+ * @dataProvider roverCoordinatesDataProvider
85+ */
86+ public function testSuccessTurnLeft (
87+ int $ xCoordinate ,
88+ int $ yCoordinate
89+ ): void {
90+ $ direction = Direction::North;
91+
92+ $ rover = new Rover ($ xCoordinate , $ yCoordinate , $ direction );
93+ $ rover2 = new Rover ($ xCoordinate , $ yCoordinate +1 , Direction::West);
94+ $ finalRoverObject = new Rover ($ xCoordinate , $ yCoordinate +2 , Direction::South);
95+
96+ $ this ->roverFactory ->expects (self ::once ())
97+ ->method ('create ' )
98+ ->with ($ xCoordinate , $ yCoordinate , $ direction )
99+ ->willReturn ($ rover );
100+
101+ $ this ->roverRepository ->expects (self ::exactly (2 ))
102+ ->method ('turnLeft ' )
103+ ->withConsecutive (
104+ [$ rover ],
105+ [$ rover2 ]
106+ )
107+ ->willReturnOnConsecutiveCalls (
108+ $ rover2 ,
109+ $ finalRoverObject
110+ );
111+
112+ $ this ->roverRepository ->expects (self ::never ())
113+ ->method ('move ' );
114+
115+ $ this ->roverRepository ->expects (self ::never ())
116+ ->method ('turnRight ' );
117+
118+ $ expectedResult = new RoverPositionDto ($ xCoordinate , $ yCoordinate +2 , Direction::South);
119+
120+ $ roverInformationDto = new RoverInformationDto ($ xCoordinate , $ yCoordinate , $ direction );
121+ $ roverInformationDto ->setActions ('LL ' );
122+ $ actualResult = $ this ->nasaRoverService ->process ($ roverInformationDto );
123+
124+ $ this ->assertEquals ($ expectedResult , $ actualResult );
125+ }
126+
127+ /**
128+ * @throws Exception
129+ *
130+ * @dataProvider roverCoordinatesDataProvider
131+ */
132+ public function testSuccessTurnRight (
133+ int $ xCoordinate ,
134+ int $ yCoordinate
135+ ): void {
136+ $ direction = Direction::North;
137+
138+ $ rover = new Rover ($ xCoordinate , $ yCoordinate , $ direction );
139+ $ rover2 = new Rover ($ xCoordinate , $ yCoordinate +1 , Direction::East);
140+ $ finalRoverObject = new Rover ($ xCoordinate , $ yCoordinate +2 , Direction::South);
141+
142+ $ this ->roverFactory ->expects (self ::once ())
143+ ->method ('create ' )
144+ ->with ($ xCoordinate , $ yCoordinate , $ direction )
145+ ->willReturn ($ rover );
146+
147+ $ this ->roverRepository ->expects (self ::exactly (2 ))
148+ ->method ('turnRight ' )
149+ ->withConsecutive (
150+ [$ rover ],
151+ [$ rover2 ]
152+ )
153+ ->willReturnOnConsecutiveCalls (
154+ $ rover2 ,
155+ $ finalRoverObject
156+ );
157+
158+ $ this ->roverRepository ->expects (self ::never ())
159+ ->method ('move ' );
160+
161+ $ this ->roverRepository ->expects (self ::never ())
162+ ->method ('turnLeft ' );
163+
164+ $ expectedResult = new RoverPositionDto ($ xCoordinate , $ yCoordinate +2 , Direction::South);
165+
166+ $ roverInformationDto = new RoverInformationDto ($ xCoordinate , $ yCoordinate , $ direction );
167+ $ roverInformationDto ->setActions ('RR ' );
168+ $ actualResult = $ this ->nasaRoverService ->process ($ roverInformationDto );
169+
170+ $ this ->assertEquals ($ expectedResult , $ actualResult );
171+ }
172+
173+ /**
174+ * @throws Exception
175+ *
176+ * @dataProvider roverCoordinatesDataProvider
177+ */
178+ public function testInvalidAction (
179+ int $ xCoordinate ,
180+ int $ yCoordinate ,
181+ Direction $ direction
182+ ): void {
183+ $ rover = new Rover ($ xCoordinate , $ yCoordinate , $ direction );
184+
185+ $ this ->roverFactory ->expects (self ::once ())
186+ ->method ('create ' )
187+ ->with ($ xCoordinate , $ yCoordinate , $ direction )
188+ ->willReturn ($ rover );
189+
190+ $ this ->roverRepository ->expects (self ::never ())
191+ ->method ('turnRight ' );
192+
193+ $ this ->roverRepository ->expects (self ::never ())
194+ ->method ('move ' );
195+
196+ $ this ->roverRepository ->expects (self ::never ())
197+ ->method ('turnLeft ' );
198+
199+ $ roverInformationDto = new RoverInformationDto ($ xCoordinate , $ yCoordinate , $ direction );
200+ $ roverInformationDto ->setActions ('DD ' );
201+
202+ $ this ->expectException (Exception::class);
203+
204+ $ this ->nasaRoverService ->process ($ roverInformationDto );
205+ }
206+
207+ public function roverCoordinatesDataProvider (): array
208+ {
209+ return [
210+ [1 , 2 , Direction::North]
211+ ];
212+ }
213+ }
0 commit comments