toyrobot 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/CONTRIBUTING.md +28 -0
- data/LICENSE +24 -0
- data/README.md +148 -0
- data/Rakefile +21 -0
- data/bin/toyrobot +5 -0
- data/data/example_input_a.txt +3 -0
- data/data/example_input_b.txt +3 -0
- data/data/example_input_c.txt +6 -0
- data/lib/toy_robot/application.rb +38 -0
- data/lib/toy_robot/board.rb +16 -0
- data/lib/toy_robot/command/base.rb +5 -0
- data/lib/toy_robot/command/parser/base.rb +58 -0
- data/lib/toy_robot/command/parser/place.rb +37 -0
- data/lib/toy_robot/command/parser.rb +20 -0
- data/lib/toy_robot/command/token.rb +11 -0
- data/lib/toy_robot/factory.rb +83 -0
- data/lib/toy_robot/placement.rb +34 -0
- data/lib/toy_robot/pose.rb +79 -0
- data/lib/toy_robot/robot.rb +41 -0
- data/lib/toy_robot/robot_controller.rb +35 -0
- data/lib/toy_robot/view.rb +22 -0
- data/lib/toy_robot.rb +1 -0
- data/test/integration/test_application.rb +24 -0
- data/test/integration/test_factory.rb +18 -0
- data/test/integration/test_toy_robot.rb +9 -0
- data/test/test_board.rb +31 -0
- data/test/test_command.rb +22 -0
- data/test/test_command_matcher.rb +32 -0
- data/test/test_command_matcher_interface.rb +31 -0
- data/test/test_command_matcher_left.rb +20 -0
- data/test/test_command_matcher_move.rb +21 -0
- data/test/test_command_matcher_place.rb +56 -0
- data/test/test_command_matcher_report.rb +21 -0
- data/test/test_command_matcher_right.rb +20 -0
- data/test/test_placement.rb +94 -0
- data/test/test_pose.rb +146 -0
- data/test/test_reporter_interface.rb +7 -0
- data/test/test_robot.rb +70 -0
- data/test/test_robot_controller.rb +62 -0
- data/test/test_view.rb +32 -0
- data/toyrobot.gemspec +20 -0
- metadata +139 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module ToyRobot
|
4
|
+
class Robot
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@placement = args[:placement]
|
9
|
+
end
|
10
|
+
|
11
|
+
def place(*args)
|
12
|
+
placement.update(*args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def move
|
16
|
+
with_placement { placement.advance }
|
17
|
+
end
|
18
|
+
|
19
|
+
def right
|
20
|
+
with_placement { placement.rotate(90) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def left
|
24
|
+
with_placement { placement.rotate(-90) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def report
|
28
|
+
with_placement { placement.report }
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_accessor :placement
|
34
|
+
|
35
|
+
def with_placement
|
36
|
+
if placement.on_board?
|
37
|
+
yield
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'command/token'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module ToyRobot
|
5
|
+
class RobotController
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :robot, :place, :move, :left, :right
|
9
|
+
def_delegator :view, :report
|
10
|
+
|
11
|
+
def initialize(args)
|
12
|
+
@robot = args[:robot]
|
13
|
+
@view = args[:view]
|
14
|
+
end
|
15
|
+
|
16
|
+
def input(command)
|
17
|
+
case command.token
|
18
|
+
when Command::Token::PLACE
|
19
|
+
place(command.args)
|
20
|
+
when Command::Token::MOVE
|
21
|
+
move
|
22
|
+
when Command::Token::RIGHT
|
23
|
+
right
|
24
|
+
when Command::Token::LEFT
|
25
|
+
left
|
26
|
+
when Command::Token::REPORT
|
27
|
+
report
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :robot, :view
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ToyRobot
|
2
|
+
View = Struct.new(:args) do
|
3
|
+
def report
|
4
|
+
report = robot.report
|
5
|
+
output.puts report_string(report) if report
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def report_string(report)
|
11
|
+
"#{report[:x]},#{report[:y]},#{report[:orientation].upcase}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def robot
|
15
|
+
args[:robot]
|
16
|
+
end
|
17
|
+
|
18
|
+
def output
|
19
|
+
args[:output] || $stdout
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/toy_robot.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'toy_robot/application'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative '../../lib/toy_robot'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
module ToyRobot
|
5
|
+
class ToyRobotTest < MiniTest::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@app = lambda { |f| ToyRobot::Application.new(nil, input: f).run }
|
8
|
+
end
|
9
|
+
def test_example_input_a
|
10
|
+
file = File.open('data/example_input_a.txt', 'r')
|
11
|
+
assert_output(/\A0,1,NORTH\n\z/) { @app.call(file) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_example_input_b
|
15
|
+
file = File.open('data/example_input_b.txt', 'r')
|
16
|
+
assert_output(/\A0,0,WEST\n\z/) { @app.call(file) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_example_input_c
|
20
|
+
file = File.open('data/example_input_c.txt', 'r')
|
21
|
+
assert_output(/\A3,3,NORTH\n\z/) { @app.call(file) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '../../lib/toy_robot/factory'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
module ToyRobot
|
5
|
+
class FactoryTest < MiniTest::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@object = Factory
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_public_interface
|
11
|
+
assert_respond_to @object, :create
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_that_create_returns_a_robot_controller
|
15
|
+
assert_instance_of RobotController, @object.create(:controller)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/test/test_board.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative '../lib/toy_robot/board'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
module ToyRobot
|
5
|
+
class BoardTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
PoseDouble = Struct.new(:x, :y)
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@board = Board.new(5,5)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_that_knows_a_valid_pose
|
14
|
+
pose_double = PoseDouble.new(0,0)
|
15
|
+
|
16
|
+
assert @board.valid_pose?(pose_double)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_that_knows_an_invalid_pose
|
20
|
+
[[-1,0], [0,-1], [6,0], [0,6]].each do |out_of_range|
|
21
|
+
pose_double = PoseDouble.new(*out_of_range)
|
22
|
+
|
23
|
+
refute @board.valid_pose?(pose_double), "Pose #{pose_double} should be invalid"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_that_a_nil_pose_is_invalid
|
28
|
+
refute @board.valid_pose?(nil)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative '../lib/toy_robot/command/token'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
module ToyRobot
|
5
|
+
class CommandTest < MiniTest::Unit::TestCase
|
6
|
+
def test_tokens_are_defined
|
7
|
+
assert defined?(Command::Token::PLACE)
|
8
|
+
|
9
|
+
assert defined?(Command::Token::MOVE)
|
10
|
+
|
11
|
+
assert defined?(Command::Token::RIGHT)
|
12
|
+
|
13
|
+
assert defined?(Command::Token::LEFT)
|
14
|
+
|
15
|
+
assert defined?(Command::Token::REPORT)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_base_is_defined
|
19
|
+
assert defined?(Command::Base)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../lib/toy_robot/command/parser'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
module ToyRobot
|
5
|
+
class CommandMatcherTest < MiniTest::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@matcher = Command::Parser
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_that_it_can_parse
|
11
|
+
refute_equal nil, @matcher.parse('PLACE 0,0,NORTH')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_that_parsing_can_fail
|
15
|
+
assert_equal nil, @matcher.parse('PLACE 0,0,NORTHISH')
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_that_it_knows_all_matchers
|
19
|
+
all = @matcher.all
|
20
|
+
|
21
|
+
assert_includes all, Command::Parser::Place
|
22
|
+
|
23
|
+
assert_includes all, Command::Parser::Move
|
24
|
+
|
25
|
+
assert_includes all, Command::Parser::Left
|
26
|
+
|
27
|
+
assert_includes all, Command::Parser::Right
|
28
|
+
|
29
|
+
assert_includes all, Command::Parser::Report
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ToyRobot
|
2
|
+
module CommandMatcherInterfaceTest
|
3
|
+
def test_it_implement_the_command_matcher_interface
|
4
|
+
assert_respond_to @object, :build_with_match
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_that_it_matches_a_valid_string
|
8
|
+
assert @object.build_with_match(@object_valid_str)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_that_it_ignores_invalid_strings
|
12
|
+
@object_invalid_strs.each do |invalid|
|
13
|
+
refute @object.build_with_match(invalid), "It should ignore '#{invalid}'"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_that_response_knows_token
|
18
|
+
assert_equal @object_token,
|
19
|
+
@object.build_with_match(@object_valid_str).token
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_that_response_knows_args
|
23
|
+
assert_respond_to @object.build_with_match(@object_valid_str),
|
24
|
+
:args
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_that_response_is_nil
|
28
|
+
assert_equal nil, @object.build_with_match(@object_invalid_strs.sample)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../lib/toy_robot/command/parser/base'
|
2
|
+
require_relative 'test_command_matcher_interface'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
module ToyRobot
|
6
|
+
class CommandMatcherLeftTest < MiniTest::Unit::TestCase
|
7
|
+
include CommandMatcherInterfaceTest
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@object = Command::Parser::Left
|
11
|
+
@object_token = Command::Token::LEFT
|
12
|
+
@object_valid_str = 'LEFT'
|
13
|
+
@object_invalid_strs = [
|
14
|
+
'LEFT ',
|
15
|
+
'LEFTY',
|
16
|
+
'LEFT 180'
|
17
|
+
]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../lib/toy_robot/command/parser/base'
|
2
|
+
require_relative 'test_command_matcher_interface'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
module ToyRobot
|
6
|
+
class CommandMatcherMoveTest < MiniTest::Unit::TestCase
|
7
|
+
include CommandMatcherInterfaceTest
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@object = Command::Parser::Move
|
11
|
+
@object_token = Command::Token::MOVE
|
12
|
+
@object_valid_str = 'MOVE'
|
13
|
+
@object_invalid_strs = [
|
14
|
+
'MOVE ',
|
15
|
+
'MOVER',
|
16
|
+
'MOVE 180',
|
17
|
+
'move'
|
18
|
+
]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative '../lib/toy_robot/command/parser/place'
|
2
|
+
require_relative 'test_command_matcher_interface'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
module ToyRobot
|
6
|
+
class CommandMatcherPlaceTest < MiniTest::Unit::TestCase
|
7
|
+
include CommandMatcherInterfaceTest
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@object = Command::Parser::Place
|
11
|
+
@object_token = Command::Token::PLACE
|
12
|
+
@object_valid_str = 'PLACE 0,0,NORTH'
|
13
|
+
@object_invalid_strs = [
|
14
|
+
'PLACE',
|
15
|
+
'PLACE ',
|
16
|
+
'PLACE X,Y,Z,F',
|
17
|
+
'PLACE 0,0,OTHER',
|
18
|
+
'PLACE 0,0',
|
19
|
+
'PLACE 0,a,NORTH',
|
20
|
+
'PLACE a,99,NORTH',
|
21
|
+
'PLACE a,NORHT',
|
22
|
+
'PLACE 0,NORTH'
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_that_response_args_know_x
|
27
|
+
assert_equal 123,
|
28
|
+
@object.build_with_match('PLACE 123,0,NORTH').args.x
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_that_response_args_know_y
|
32
|
+
assert_equal 123,
|
33
|
+
@object.build_with_match('PLACE 0,123,NORTH').args.y
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_that_response_args_knows_north_orientation
|
37
|
+
assert_equal Pose::Orientation::NORTH,
|
38
|
+
@object.build_with_match('PLACE 0,123,NORTH').args.orientation
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_that_response_args_knows_south_orientation
|
42
|
+
assert_equal Pose::Orientation::SOUTH,
|
43
|
+
@object.build_with_match('PLACE 0,123,SOUTH').args.orientation
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_that_response_args_knows_east_orientation
|
47
|
+
assert_equal Pose::Orientation::EAST,
|
48
|
+
@object.build_with_match('PLACE 0,123,EAST').args.orientation
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_that_response_args_knows_west_orientation
|
52
|
+
assert_equal Pose::Orientation::WEST,
|
53
|
+
@object.build_with_match('PLACE 0,123,WEST').args.orientation
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../lib/toy_robot/command/parser/base'
|
2
|
+
require_relative 'test_command_matcher_interface'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
module ToyRobot
|
6
|
+
class CommandMatcherReportTest < MiniTest::Unit::TestCase
|
7
|
+
include CommandMatcherInterfaceTest
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@object = Command::Parser::Report
|
11
|
+
@object_token = Command::Token::REPORT
|
12
|
+
@object_valid_str = 'REPORT'
|
13
|
+
@object_invalid_strs = [
|
14
|
+
'REPORT ',
|
15
|
+
'REPORTNOW',
|
16
|
+
'REP',
|
17
|
+
'R'
|
18
|
+
]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../lib/toy_robot/command/parser/base'
|
2
|
+
require_relative 'test_command_matcher_interface'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
module ToyRobot
|
6
|
+
class CommandMatcherRightTest < MiniTest::Unit::TestCase
|
7
|
+
include CommandMatcherInterfaceTest
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@object = Command::Parser::Right
|
11
|
+
@object_token = Command::Token::RIGHT
|
12
|
+
@object_valid_str = 'RIGHT'
|
13
|
+
@object_invalid_strs = [
|
14
|
+
'RIGHT ',
|
15
|
+
'RIGHTY',
|
16
|
+
'RIGHT 180'
|
17
|
+
]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative '../lib/toy_robot/placement'
|
2
|
+
require_relative 'test_reporter_interface'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
module ToyRobot
|
6
|
+
class PlacementTest < MiniTest::Unit::TestCase
|
7
|
+
include ReporterInterfaceTest
|
8
|
+
|
9
|
+
SimpleDouble = Struct.new(:stub) do
|
10
|
+
def valid_pose?(_)
|
11
|
+
stub.fetch(:valid_pose?)
|
12
|
+
end
|
13
|
+
|
14
|
+
def adjacent
|
15
|
+
stub.fetch(:adjacent)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup
|
20
|
+
@board = SimpleDouble.new(valid_pose?: true)
|
21
|
+
@pose = SimpleDouble.new
|
22
|
+
@placement = @object = Placement.new(board: @board, pose: @pose)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_respond_to_public_interface
|
26
|
+
assert_respond_to @placement, :update
|
27
|
+
assert_respond_to @placement, :advance
|
28
|
+
assert_respond_to @placement, :rotate
|
29
|
+
assert_respond_to @placement, :on_board?
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_that_it_might_be_on_board
|
33
|
+
assert @placement.on_board?
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_that_it_might_not_be_on_board
|
37
|
+
@board[:stub] = { valid_pose?: false }
|
38
|
+
|
39
|
+
refute @placement.on_board?
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_that_it_might_update
|
43
|
+
new_pose = Object.new
|
44
|
+
|
45
|
+
@placement.update(new_pose)
|
46
|
+
|
47
|
+
assert_equal new_pose, @placement.instance_variable_get(:@pose)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_that_update_might_fail
|
51
|
+
@board[:stub] = { valid_pose?: false }
|
52
|
+
|
53
|
+
@placement.update('invalid_pose')
|
54
|
+
|
55
|
+
assert_equal @pose, @placement.instance_variable_get(:@pose)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_that_it_might_advance
|
59
|
+
adjacent_pose = Object.new
|
60
|
+
@pose[:stub] = { adjacent: adjacent_pose }
|
61
|
+
|
62
|
+
@placement.advance
|
63
|
+
|
64
|
+
assert_equal adjacent_pose, @placement.instance_variable_get(:@pose)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_that_it_might_not_advance
|
68
|
+
@board[:stub] = { valid_pose?: false }
|
69
|
+
@pose[:stub] = { adjacent: 'anything' }
|
70
|
+
|
71
|
+
@placement.advance
|
72
|
+
|
73
|
+
assert_equal @pose, @placement.instance_variable_get(:@pose)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_that_it_rotates
|
77
|
+
pose = MiniTest::Mock.new
|
78
|
+
placement = Placement.new(pose: pose)
|
79
|
+
|
80
|
+
pose.expect(:rotate!, nil, [123])
|
81
|
+
placement.rotate(123)
|
82
|
+
pose.verify
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_that_it_reports
|
86
|
+
pose = MiniTest::Mock.new
|
87
|
+
placement = Placement.new(pose: pose)
|
88
|
+
|
89
|
+
pose.expect(:report, nil)
|
90
|
+
placement.report
|
91
|
+
pose.verify
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/test/test_pose.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
require_relative '../lib/toy_robot/pose'
|
2
|
+
require_relative 'test_reporter_interface'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
module ToyRobot
|
6
|
+
class PoseTest < MiniTest::Unit::TestCase
|
7
|
+
include ReporterInterfaceTest
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@x, @y = 0, 1
|
11
|
+
@orientation = Pose::Orientation::EAST
|
12
|
+
@pose = @object = Pose.new(
|
13
|
+
x: @x,
|
14
|
+
y: @y,
|
15
|
+
orientation: @orientation
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_public_interface
|
20
|
+
assert_respond_to @pose, :adjacent
|
21
|
+
assert_respond_to @pose, :rotate!
|
22
|
+
assert_respond_to @pose, :report
|
23
|
+
assert_respond_to @pose, :x
|
24
|
+
assert_respond_to @pose, :y
|
25
|
+
assert_respond_to @pose, :orientation
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_it_can_be_initialized_without_arguments
|
29
|
+
assert Pose.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_that_adjacent_returns_a_pose
|
33
|
+
assert_instance_of Pose, @pose.adjacent
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_that_adjacent_pose_is_not_the_reciever
|
37
|
+
refute_equal @pose, @pose.adjacent
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_that_knows_adjacent_when_facing_east
|
41
|
+
adjacent_pose_hash = {
|
42
|
+
x: @x + 1,
|
43
|
+
y: @y,
|
44
|
+
orientation: @orientation
|
45
|
+
}
|
46
|
+
|
47
|
+
assert_pose adjacent_pose_hash, @pose.adjacent
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_that_knows_adjacent_when_facing_north
|
51
|
+
orientation = Pose::Orientation::NORTH
|
52
|
+
@pose.instance_variable_set(:@orientation, orientation)
|
53
|
+
adjacent_pose_hash = {
|
54
|
+
x: @x,
|
55
|
+
y: @y + 1,
|
56
|
+
orientation: orientation
|
57
|
+
}
|
58
|
+
|
59
|
+
assert_pose adjacent_pose_hash, @pose.adjacent
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_that_knows_adjacent_when_facing_west
|
63
|
+
orientation = Pose::Orientation::WEST
|
64
|
+
@pose.instance_variable_set(:@orientation, orientation)
|
65
|
+
adjacent_pose_hash = {
|
66
|
+
x: @x - 1,
|
67
|
+
y: @y,
|
68
|
+
orientation: orientation
|
69
|
+
}
|
70
|
+
|
71
|
+
assert_pose adjacent_pose_hash, @pose.adjacent
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_that_knows_adjacent_when_facing_south
|
75
|
+
orientation = Pose::Orientation::SOUTH
|
76
|
+
@pose.instance_variable_set(:@orientation, orientation)
|
77
|
+
adjacent_pose_hash = {
|
78
|
+
x: @x,
|
79
|
+
y: @y - 1,
|
80
|
+
orientation: orientation
|
81
|
+
}
|
82
|
+
|
83
|
+
assert_pose adjacent_pose_hash, @pose.adjacent
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_that_can_rotate_90
|
87
|
+
clockwise_orientations = [
|
88
|
+
Pose::Orientation::NORTH,
|
89
|
+
Pose::Orientation::EAST,
|
90
|
+
Pose::Orientation::SOUTH,
|
91
|
+
Pose::Orientation::WEST,
|
92
|
+
Pose::Orientation::NORTH
|
93
|
+
]
|
94
|
+
|
95
|
+
clockwise_orientations.each_cons(2) do |initial_orientation, rotated_orientation|
|
96
|
+
@pose.instance_variable_set(:@orientation, initial_orientation)
|
97
|
+
rotated_pose_hash = {x: @x, y: @y, orientation: rotated_orientation}
|
98
|
+
|
99
|
+
@pose.rotate!(90)
|
100
|
+
|
101
|
+
assert_pose rotated_pose_hash, @pose
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_that_can_rotate_90_counterclockwise
|
106
|
+
counter_clockwise_orientations = [
|
107
|
+
Pose::Orientation::NORTH,
|
108
|
+
Pose::Orientation::WEST,
|
109
|
+
Pose::Orientation::SOUTH,
|
110
|
+
Pose::Orientation::EAST,
|
111
|
+
Pose::Orientation::NORTH
|
112
|
+
]
|
113
|
+
|
114
|
+
counter_clockwise_orientations.each_cons(2) do |initial_orientation, rotated_orientation|
|
115
|
+
@pose.instance_variable_set(:@orientation, initial_orientation)
|
116
|
+
rotated_pose_hash = {
|
117
|
+
x: @x,
|
118
|
+
y: @y,
|
119
|
+
orientation: rotated_orientation
|
120
|
+
}
|
121
|
+
|
122
|
+
@pose.rotate!(-90)
|
123
|
+
|
124
|
+
assert_pose rotated_pose_hash, @pose
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_that_it_reports_x
|
129
|
+
assert_includes @pose.report, :x
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_that_it_reports_y
|
133
|
+
assert_includes @pose.report, :y
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_that_it_reports_orientation
|
137
|
+
assert_includes @pose.report, :orientation
|
138
|
+
end
|
139
|
+
|
140
|
+
def assert_pose(expected_pose_hash, actual)
|
141
|
+
assert_equal expected_pose_hash[:x], actual.send(:x), ':x coordinate is different'
|
142
|
+
assert_equal expected_pose_hash[:y], actual.send(:y), ':y coordinate is different'
|
143
|
+
assert_equal expected_pose_hash[:orientation], actual.send(:orientation), ':orientation is different'
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|