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)

[((475, 545), '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', ([], {}), '()\n', (543, 545), True, 'from tests.test_environment import mocks as m\n'), ((560, 615), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ([], {}), '()\n', (613, 615), True, 'from tests.test_environment import mocks as m\n'), ((630, 671), 'services.RoverRunnerService', 'RoverRunnerService', (['grid', 'rover', 'mss', 'tss'], {}), '(grid, rover, mss, tss)\n', (648, 671), False, 'from services import RoverRunnerService\n'), ((966, 1036), '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', ([], {}), '()\n', (1034, 1036), True, 'from tests.test_environment import mocks as m\n'), ((1051, 1106), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ([], {}), '()\n', (1104, 1106), True, 'from tests.test_environment import mocks as m\n'), ((1121, 1162), 'services.RoverRunnerService', 'RoverRunnerService', (['grid', 'rover', 'mss', 'tss'], {}), '(grid, rover, mss, tss)\n', (1139, 1162), False, 'from services import RoverRunnerService\n'), ((1458, 1529), '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', ([], {}), '()\n', (1527, 1529), True, 'from tests.test_environment import mocks as m\n'), ((1544, 1599), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ([], {}), '()\n', (1597, 1599), True, 'from tests.test_environment import mocks as m\n'), ((1614, 1655), 'services.RoverRunnerService', 'RoverRunnerService', (['grid', 'rover', 'mss', 'tss'], {}), '(grid, rover, mss, tss)\n', (1632, 1655), False, 'from services import RoverRunnerService\n'), ((1875, 1891), 'data_objects.Rover', 'Rover', (['(1)', '(1)', '"""E"""'], {}), "(1, 1, 'E')\n", (1880, 1891), False, 'from data_objects import Rover\n'), ((1906, 1977), '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', ([], {}), '()\n', (1975, 1977), True, 'from tests.test_environment import mocks as m\n'), ((1992, 2046), 'tests.test_environment.mocks.get_mocked_move_command_selector_east_command_only', 'm.get_mocked_move_command_selector_east_command_only', ([], {}), '()\n', (2044, 2046), True, 'from tests.test_environment import mocks as m\n'), ((2061, 2102), 'services.RoverRunnerService', 'RoverRunnerService', (['grid', 'rover', 'mss', 'tss'], {}), '(grid, rover, mss, tss)\n', (2079, 2102), False, 'from services import RoverRunnerService\n'), ((2288, 2304), 'data_objects.Rover', 'Rover', (['(1)', '(1)', '"""N"""'], {}), "(1, 1, 'N')\n", (2293, 2304), False, 'from data_objects import Rover\n'), ((2319, 2390), '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', ([], {}), '()\n', (2388, 2390), True, 'from tests.test_environment import mocks as m\n'), ((2405, 2460), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ([], {}), '()\n', (2458, 2460), True, 'from tests.test_environment import mocks as m\n'), ((2475, 2516), 'services.RoverRunnerService', 'RoverRunnerService', (['grid', 'rover', 'mss', 'tss'], {}), '(grid, rover, mss, tss)\n', (2493, 2516), False, 'from services import RoverRunnerService\n'), ((2701, 2717), 'data_objects.Rover', 'Rover', (['(0)', '(1)', '"""W"""'], {}), "(0, 1, 'W')\n", (2706, 2717), False, 'from data_objects import Rover\n'), ((2732, 2803), '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', ([], {}), '()\n', (2801, 2803), True, 'from tests.test_environment import mocks as m\n'), ((2818, 2872), 'tests.test_environment.mocks.get_mocked_move_command_selector_west_command_only', 'm.get_mocked_move_command_selector_west_command_only', ([], {}), '()\n', (2870, 2872), True, 'from tests.test_environment import mocks as m\n'), ((2887, 2928), 'services.RoverRunnerService', 'RoverRunnerService', (['grid', 'rover', 'mss', 'tss'], {}), '(grid, rover, mss, tss)\n', (2905, 2928), False, 'from services import RoverRunnerService\n'), ((3114, 3130), 'data_objects.Rover', 'Rover', (['(0)', '(0)', '"""S"""'], {}), "(0, 0, 'S')\n", (3119, 3130), False, 'from data_objects import Rover\n'), ((3145, 3216), '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', ([], {}), '()\n', (3214, 3216), True, 'from tests.test_environment import mocks as m\n'), ((3231, 3286), 'tests.test_environment.mocks.get_mocked_move_command_selector_south_command_only', 'm.get_mocked_move_command_selector_south_command_only', ([], {}), '()\n', (3284, 3286), True, 'from tests.test_environment import mocks as m\n'), ((3301, 3342), 'services.RoverRunnerService', 'RoverRunnerService', (['grid', 'rover', 'mss', 'tss'], {}), '(grid, rover, mss, tss)\n', (3319, 3342), False, 'from services import RoverRunnerService\n'), ((3612, 3682), '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', ([], {}), '()\n', (3680, 3682), True, 'from tests.test_environment import mocks as m\n'), ((3697, 3752), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ([], {}), '()\n', (3750, 3752), True, 'from tests.test_environment import mocks as m\n'), ((3767, 3808), 'services.RoverRunnerService', 'RoverRunnerService', (['grid', 'rover', 'mss', 'tss'], {}), '(grid, rover, mss, tss)\n', (3785, 3808), False, 'from services import RoverRunnerService\n'), ((4102, 4172), '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', ([], {}), '()\n', (4170, 4172), True, 'from tests.test_environment import mocks as m\n'), ((4187, 4242), 'tests.test_environment.mocks.get_mocked_move_command_selector_north_command_only', 'm.get_mocked_move_command_selector_north_command_only', ([], {}), '()\n', (4240, 4242), True, 'from tests.test_environment import mocks as m\n'), ((4257, 4298), 'services.RoverRunnerService', 'RoverRunnerService', (['grid', 'rover', 'mss', 'tss'], {}), '(grid, rover, mss, tss)\n', (4275, 4298), False, 'from services import RoverRunnerService\n'), ((732, 748), 'data_objects.Rover', 'Rover', (['(0)', '(1)', '"""N"""'], {}), "(0, 1, 'N')\n", (737, 748), False, 'from data_objects import Rover\n'), ((1223, 1239), 'data_objects.Rover', 'Rover', (['(0)', '(0)', '"""W"""'], {}), "(0, 0, 'W')\n", (1228, 1239), False, 'from data_objects import Rover\n'), ((1716, 1732), 'data_objects.Rover', 'Rover', (['(0)', '(0)', '"""E"""'], {}), "(0, 0, 'E')\n", (1721, 1732), False, 'from data_objects import Rover\n')]