import unittest
from services import RoverRunnerService
from tests.test_environment.marses import small_mars_with_one_rover_empty_commands
from tests.test_environment import mocks as m
from data_objects import Rover


class TestRoverRunnerService(unittest.TestCase):

    def test_rover_runner_moves_rover_forward(self):
        grid = small_mars_with_one_rover_empty_commands.grid
        rover = small_mars_with_one_rover_empty_commands.rover_setups[0].rover
        tss = m.get_mocked_turn_command_selector_turn_left_from_north_command_only()
        mss = m.get_mocked_move_command_selector_north_command_only()
        rrs = RoverRunnerService(grid, rover, mss, tss)
        final_pos = rrs.run(['M'])
        self.assertEqual(Rover(0, 1, 'N'), final_pos)

    def test_rover_runner_turns_rover_left(self):
        grid = small_mars_with_one_rover_empty_commands.grid
        rover = small_mars_with_one_rover_empty_commands.rover_setups[0].rover
        tss = m.get_mocked_turn_command_selector_turn_left_from_north_command_only()
        mss = m.get_mocked_move_command_selector_north_command_only()
        rrs = RoverRunnerService(grid, rover, mss, tss)
        final_pos = rrs.run(['L'])
        self.assertEqual(Rover(0, 0, 'W'), final_pos)

    def test_rover_runner_turns_rover_right(self):
        grid = small_mars_with_one_rover_empty_commands.grid
        rover = small_mars_with_one_rover_empty_commands.rover_setups[0].rover
        tss = m.get_mocked_turn_command_selector_turn_right_from_north_command_only()
        mss = m.get_mocked_move_command_selector_north_command_only()
        rrs = RoverRunnerService(grid, rover, mss, tss)
        final_pos = rrs.run(['R'])
        self.assertEqual(Rover(0, 0, 'E'), final_pos)

    def test_rover_runner_goes_off_gird_east(self):
        grid = small_mars_with_one_rover_empty_commands.grid
        rover = Rover(1, 1, "E")
        tss = m.get_mocked_turn_command_selector_turn_right_from_north_command_only()
        mss = m.get_mocked_move_command_selector_east_command_only()
        rrs = RoverRunnerService(grid, rover, mss, tss)
        self.assertRaises(ValueError, rrs.run, ['M'])

    def test_rover_runner_goes_off_gird_north(self):
        grid = small_mars_with_one_rover_empty_commands.grid
        rover = Rover(1, 1, "N")
        tss = m.get_mocked_turn_command_selector_turn_right_from_north_command_only()
        mss = m.get_mocked_move_command_selector_north_command_only()
        rrs = RoverRunnerService(grid, rover, mss, tss)
        self.assertRaises(ValueError, rrs.run, ['M'])

    def test_rover_runner_goes_off_gird_west(self):
        grid = small_mars_with_one_rover_empty_commands.grid
        rover = Rover(0, 1, "W")
        tss = m.get_mocked_turn_command_selector_turn_right_from_north_command_only()
        mss = m.get_mocked_move_command_selector_west_command_only()
        rrs = RoverRunnerService(grid, rover, mss, tss)
        self.assertRaises(ValueError, rrs.run, ['M'])

    def test_rover_runner_goes_off_gird_south(self):
        grid = small_mars_with_one_rover_empty_commands.grid
        rover = Rover(0, 0, "S")
        tss = m.get_mocked_turn_command_selector_turn_right_from_north_command_only()
        mss = m.get_mocked_move_command_selector_south_command_only()
        rrs = RoverRunnerService(grid, rover, mss, tss)
        self.assertRaises(ValueError, rrs.run, ['M'])

    def test_rover_runner_does_nothing_empty_command(self):
        grid = small_mars_with_one_rover_empty_commands.grid
        rover = small_mars_with_one_rover_empty_commands.rover_setups[0].rover
        tss = m.get_mocked_turn_command_selector_turn_left_from_north_command_only()
        mss = m.get_mocked_move_command_selector_north_command_only()
        rrs = RoverRunnerService(grid, rover, mss, tss)
        final_pos = rrs.run([])
        self.assertEqual(rover, final_pos)

    def test_rover_runner_raises_error_for_None_command(self):
        grid = small_mars_with_one_rover_empty_commands.grid
        rover = small_mars_with_one_rover_empty_commands.rover_setups[0].rover
        tss = m.get_mocked_turn_command_selector_turn_left_from_north_command_only()
        mss = m.get_mocked_move_command_selector_north_command_only()
        rrs = RoverRunnerService(grid, rover, mss, tss)
        self.assertRaises(TypeError, rrs.run, None)

[((13, 14, 13, 84), 'tests.test_environment.mocks.get_mocked_turn_command_selector_turn_left_from_north_command_only', 'm.get_mocked_turn_command_selector_turn_left_from_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((14, 14, 14, 69), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((15, 14, 15, 55), 'services.RoverRunnerService', 'RoverRunnerService', ({(15, 33, 15, 37): 'grid', (15, 39, 15, 44): 'rover', (15, 46, 15, 49): 'mss', (15, 51, 15, 54): 'tss'}, {}), '(grid, rover, mss, tss)', False, 'from services import RoverRunnerService\n'), ((22, 14, 22, 84), 'tests.test_environment.mocks.get_mocked_turn_command_selector_turn_left_from_north_command_only', 'm.get_mocked_turn_command_selector_turn_left_from_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((23, 14, 23, 69), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((24, 14, 24, 55), 'services.RoverRunnerService', 'RoverRunnerService', ({(24, 33, 24, 37): 'grid', (24, 39, 24, 44): 'rover', (24, 46, 24, 49): 'mss', (24, 51, 24, 54): 'tss'}, {}), '(grid, rover, mss, tss)', False, 'from services import RoverRunnerService\n'), ((31, 14, 31, 85), 'tests.test_environment.mocks.get_mocked_turn_command_selector_turn_right_from_north_command_only', 'm.get_mocked_turn_command_selector_turn_right_from_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((32, 14, 32, 69), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((33, 14, 33, 55), 'services.RoverRunnerService', 'RoverRunnerService', ({(33, 33, 33, 37): 'grid', (33, 39, 33, 44): 'rover', (33, 46, 33, 49): 'mss', (33, 51, 33, 54): 'tss'}, {}), '(grid, rover, mss, tss)', False, 'from services import RoverRunnerService\n'), ((39, 16, 39, 32), 'data_objects.Rover', 'Rover', ({(39, 22, 39, 23): '1', (39, 25, 39, 26): '1', (39, 28, 39, 31): '"""E"""'}, {}), "(1, 1, 'E')", False, 'from data_objects import Rover\n'), ((40, 14, 40, 85), 'tests.test_environment.mocks.get_mocked_turn_command_selector_turn_right_from_north_command_only', 'm.get_mocked_turn_command_selector_turn_right_from_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((41, 14, 41, 68), 'tests.test_environment.mocks.get_mocked_move_command_selector_east_command_only', 'm.get_mocked_move_command_selector_east_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((42, 14, 42, 55), 'services.RoverRunnerService', 'RoverRunnerService', ({(42, 33, 42, 37): 'grid', (42, 39, 42, 44): 'rover', (42, 46, 42, 49): 'mss', (42, 51, 42, 54): 'tss'}, {}), '(grid, rover, mss, tss)', False, 'from services import RoverRunnerService\n'), ((47, 16, 47, 32), 'data_objects.Rover', 'Rover', ({(47, 22, 47, 23): '1', (47, 25, 47, 26): '1', (47, 28, 47, 31): '"""N"""'}, {}), "(1, 1, 'N')", False, 'from data_objects import Rover\n'), ((48, 14, 48, 85), 'tests.test_environment.mocks.get_mocked_turn_command_selector_turn_right_from_north_command_only', 'm.get_mocked_turn_command_selector_turn_right_from_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((49, 14, 49, 69), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((50, 14, 50, 55), 'services.RoverRunnerService', 'RoverRunnerService', ({(50, 33, 50, 37): 'grid', (50, 39, 50, 44): 'rover', (50, 46, 50, 49): 'mss', (50, 51, 50, 54): 'tss'}, {}), '(grid, rover, mss, tss)', False, 'from services import RoverRunnerService\n'), ((55, 16, 55, 32), 'data_objects.Rover', 'Rover', ({(55, 22, 55, 23): '0', (55, 25, 55, 26): '1', (55, 28, 55, 31): '"""W"""'}, {}), "(0, 1, 'W')", False, 'from data_objects import Rover\n'), ((56, 14, 56, 85), 'tests.test_environment.mocks.get_mocked_turn_command_selector_turn_right_from_north_command_only', 'm.get_mocked_turn_command_selector_turn_right_from_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((57, 14, 57, 68), 'tests.test_environment.mocks.get_mocked_move_command_selector_west_command_only', 'm.get_mocked_move_command_selector_west_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((58, 14, 58, 55), 'services.RoverRunnerService', 'RoverRunnerService', ({(58, 33, 58, 37): 'grid', (58, 39, 58, 44): 'rover', (58, 46, 58, 49): 'mss', (58, 51, 58, 54): 'tss'}, {}), '(grid, rover, mss, tss)', False, 'from services import RoverRunnerService\n'), ((63, 16, 63, 32), 'data_objects.Rover', 'Rover', ({(63, 22, 63, 23): '0', (63, 25, 63, 26): '0', (63, 28, 63, 31): '"""S"""'}, {}), "(0, 0, 'S')", False, 'from data_objects import Rover\n'), ((64, 14, 64, 85), 'tests.test_environment.mocks.get_mocked_turn_command_selector_turn_right_from_north_command_only', 'm.get_mocked_turn_command_selector_turn_right_from_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((65, 14, 65, 69), 'tests.test_environment.mocks.get_mocked_move_command_selector_south_command_only', 'm.get_mocked_move_command_selector_south_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((66, 14, 66, 55), 'services.RoverRunnerService', 'RoverRunnerService', ({(66, 33, 66, 37): 'grid', (66, 39, 66, 44): 'rover', (66, 46, 66, 49): 'mss', (66, 51, 66, 54): 'tss'}, {}), '(grid, rover, mss, tss)', False, 'from services import RoverRunnerService\n'), ((72, 14, 72, 84), 'tests.test_environment.mocks.get_mocked_turn_command_selector_turn_left_from_north_command_only', 'm.get_mocked_turn_command_selector_turn_left_from_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((73, 14, 73, 69), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((74, 14, 74, 55), 'services.RoverRunnerService', 'RoverRunnerService', ({(74, 33, 74, 37): 'grid', (74, 39, 74, 44): 'rover', (74, 46, 74, 49): 'mss', (74, 51, 74, 54): 'tss'}, {}), '(grid, rover, mss, tss)', False, 'from services import RoverRunnerService\n'), ((81, 14, 81, 84), 'tests.test_environment.mocks.get_mocked_turn_command_selector_turn_left_from_north_command_only', 'm.get_mocked_turn_command_selector_turn_left_from_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((82, 14, 82, 69), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ({}, {}), '()', True, 'from tests.test_environment import mocks as m\n'), ((83, 14, 83, 55), 'services.RoverRunnerService', 'RoverRunnerService', ({(83, 33, 83, 37): 'grid', (83, 39, 83, 44): 'rover', (83, 46, 83, 49): 'mss', (83, 51, 83, 54): 'tss'}, {}), '(grid, rover, mss, tss)', False, 'from services import RoverRunnerService\n'), ((17, 25, 17, 41), 'data_objects.Rover', 'Rover', ({(17, 31, 17, 32): '(0)', (17, 34, 17, 35): '(1)', (17, 37, 17, 40): '"""N"""'}, {}), "(0, 1, 'N')", False, 'from data_objects import Rover\n'), ((26, 25, 26, 41), 'data_objects.Rover', 'Rover', ({(26, 31, 26, 32): '(0)', (26, 34, 26, 35): '(0)', (26, 37, 26, 40): '"""W"""'}, {}), "(0, 0, 'W')", False, 'from data_objects import Rover\n'), ((35, 25, 35, 41), 'data_objects.Rover', 'Rover', ({(35, 31, 35, 32): '(0)', (35, 34, 35, 35): '(0)', (35, 37, 35, 40): '"""E"""'}, {}), "(0, 0, 'E')", False, 'from data_objects import Rover\n')]