toyrobot 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +2 -2
  3. data/README.md +166 -10
  4. data/lib/toy_robot/application.rb +1 -13
  5. data/lib/toy_robot/board.rb +1 -1
  6. data/lib/toy_robot/command/parser.rb +6 -3
  7. data/lib/toy_robot/command/parser/base.rb +4 -25
  8. data/lib/toy_robot/command/parser/left.rb +12 -0
  9. data/lib/toy_robot/command/parser/move.rb +12 -0
  10. data/lib/toy_robot/command/parser/place.rb +3 -4
  11. data/lib/toy_robot/command/parser/report.rb +12 -0
  12. data/lib/toy_robot/command/parser/right.rb +12 -0
  13. data/lib/toy_robot/controller.rb +32 -0
  14. data/lib/toy_robot/factory.rb +6 -18
  15. data/lib/toy_robot/pose.rb +19 -5
  16. data/lib/toy_robot/robot.rb +11 -15
  17. data/lib/toy_robot/view.rb +10 -12
  18. data/test/board_double.rb +5 -0
  19. data/test/integration/test_factory.rb +2 -2
  20. data/test/integration/test_toy_robot.rb +1 -1
  21. data/test/pose_double.rb +23 -0
  22. data/test/test_board.rb +7 -14
  23. data/test/test_board_double.rb +13 -0
  24. data/test/test_board_interface.rb +15 -0
  25. data/test/{test_command_matcher.rb → test_command_parser.rb} +6 -6
  26. data/test/{test_command_matcher_interface.rb → test_command_parser_interface.rb} +5 -5
  27. data/test/test_command_parser_left.rb +20 -0
  28. data/test/{test_command_matcher_move.rb → test_command_parser_move.rb} +5 -5
  29. data/test/{test_command_matcher_place.rb → test_command_parser_place.rb} +10 -10
  30. data/test/{test_command_matcher_report.rb → test_command_parser_report.rb} +5 -5
  31. data/test/test_command_parser_right.rb +20 -0
  32. data/test/test_controller.rb +64 -0
  33. data/test/test_pose.rb +16 -20
  34. data/test/test_pose_double.rb +15 -0
  35. data/test/test_pose_interface.rb +26 -0
  36. data/test/test_reporter_interface.rb +13 -1
  37. data/test/test_robot.rb +70 -27
  38. data/toyrobot.gemspec +1 -1
  39. metadata +35 -26
  40. data/lib/toy_robot/command/base.rb +0 -5
  41. data/lib/toy_robot/command/token.rb +0 -11
  42. data/lib/toy_robot/placement.rb +0 -34
  43. data/lib/toy_robot/robot_controller.rb +0 -35
  44. data/test/test_command.rb +0 -22
  45. data/test/test_command_matcher_left.rb +0 -20
  46. data/test/test_command_matcher_right.rb +0 -20
  47. data/test/test_placement.rb +0 -94
  48. data/test/test_robot_controller.rb +0 -62
@@ -0,0 +1,32 @@
1
+ module ToyRobot
2
+ class Controller
3
+ def initialize(args)
4
+ @robot = args[:robot]
5
+ @view = args[:view]
6
+ end
7
+
8
+ def place(*args)
9
+ robot.place(*args)
10
+ end
11
+
12
+ def move(*_)
13
+ robot.move
14
+ end
15
+
16
+ def left(*_)
17
+ robot.left
18
+ end
19
+
20
+ def right(*_)
21
+ robot.right
22
+ end
23
+
24
+ def report(*_)
25
+ view.report
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :robot, :view
31
+ end
32
+ end
@@ -1,6 +1,5 @@
1
- require_relative 'robot_controller'
1
+ require_relative 'controller'
2
2
  require_relative 'robot'
3
- require_relative 'placement'
4
3
  require_relative 'board'
5
4
  require_relative 'pose'
6
5
  require_relative 'view'
@@ -12,18 +11,18 @@ module ToyRobot
12
11
  def create(identifier, opts = {})
13
12
  case identifier
14
13
  when :controller
15
- RobotControllerFactory.create(opts)
14
+ ControllerFactory.create(opts)
16
15
  end
17
16
  end
18
17
 
19
- module RobotControllerFactory
18
+ module ControllerFactory
20
19
  module_function
21
20
 
22
21
  def create(opts = {})
23
22
  robot = opts[:robot] || RobotFactory.create
24
23
  view = opts[:view] || ViewFactory.create(robot: robot)
25
24
 
26
- ToyRobot::RobotController.new(
25
+ ToyRobot::Controller.new(
27
26
  robot: robot,
28
27
  view: view
29
28
  )
@@ -47,22 +46,11 @@ module ToyRobot
47
46
  module RobotFactory
48
47
  module_function
49
48
 
50
- def create(opts = {})
51
- placement = opts[:placement] || PlacementFactory.create
52
-
53
- ToyRobot::Robot.new(
54
- placement: placement
55
- )
56
- end
57
- end
58
-
59
- module PlacementFactory
60
- module_function
61
-
62
49
  def create(opts = {})
63
50
  board = opts[:board] || BoardFactory.create
64
51
  pose = opts[:pose] || ToyRobot::Pose.new
65
- ToyRobot::Placement.new(
52
+
53
+ ToyRobot::Robot.new(
66
54
  board: board,
67
55
  pose: pose
68
56
  )
@@ -1,3 +1,5 @@
1
+ require 'ostruct'
2
+
1
3
  module ToyRobot
2
4
  class Pose
3
5
  module Orientation
@@ -7,14 +9,19 @@ module ToyRobot
7
9
  SOUTH = :south
8
10
  end
9
11
 
10
- attr_accessor :x, :y, :orientation
11
-
12
12
  def initialize(args = {})
13
13
  @x = args[:x]
14
14
  @y = args[:y]
15
15
  @orientation = args[:orientation]
16
16
  end
17
17
 
18
+ def mutate!(attrs = {})
19
+ self.x = attrs[:x] || x
20
+ self.y = attrs[:y] || y
21
+ self.orientation = attrs[:orientation] || orientation
22
+ self
23
+ end
24
+
18
25
  def adjacent
19
26
  dup.send(:adjacent!)
20
27
  end
@@ -22,6 +29,7 @@ module ToyRobot
22
29
  def rotate!(degrees)
23
30
  step = (degrees % 90) + (degrees/degrees.abs)
24
31
  self.orientation = step_orientation(step)
32
+ self
25
33
  end
26
34
 
27
35
  def report
@@ -32,8 +40,14 @@ module ToyRobot
32
40
  }
33
41
  end
34
42
 
43
+ def [](key)
44
+ report.send(:[], key)
45
+ end
46
+
35
47
  private
36
48
 
49
+ attr_accessor :x, :y, :orientation
50
+
37
51
  def step_orientation(by = 1)
38
52
  orientations = [
39
53
  Pose::Orientation::NORTH,
@@ -60,14 +74,14 @@ module ToyRobot
60
74
  end
61
75
 
62
76
  def increment!(coordinate, by = 1)
63
- update!(coordinate, by)
77
+ update_coordinate!(coordinate, by)
64
78
  end
65
79
 
66
80
  def decrement!(coordinate, by = -1)
67
- update!(coordinate, by)
81
+ update_coordinate!(coordinate, by)
68
82
  end
69
83
 
70
- def update!(coordinate, by)
84
+ def update_coordinate!(coordinate, by)
71
85
  case coordinate
72
86
  when :x
73
87
  self.x = x + by
@@ -1,41 +1,37 @@
1
- require 'forwardable'
2
-
3
1
  module ToyRobot
4
2
  class Robot
5
- extend Forwardable
6
-
7
3
  def initialize(args)
8
- @placement = args[:placement]
4
+ @board = args[:board]
5
+ @pose = args[:pose]
9
6
  end
10
7
 
11
- def place(*args)
12
- placement.update(*args)
8
+ def place(a_new_pose)
9
+ pose.mutate!(a_new_pose) if board.valid_pose?(a_new_pose)
10
+ nil
13
11
  end
14
12
 
15
13
  def move
16
- with_placement { placement.advance }
14
+ with_placement { place(pose.adjacent) and nil }
17
15
  end
18
16
 
19
17
  def right
20
- with_placement { placement.rotate(90) }
18
+ with_placement { pose.rotate!(90) and nil }
21
19
  end
22
20
 
23
21
  def left
24
- with_placement { placement.rotate(-90) }
22
+ with_placement { pose.rotate!(-90) and nil }
25
23
  end
26
24
 
27
25
  def report
28
- with_placement { placement.report }
26
+ with_placement { pose.report }
29
27
  end
30
28
 
31
29
  private
32
30
 
33
- attr_accessor :placement
31
+ attr_reader :board, :pose
34
32
 
35
33
  def with_placement
36
- if placement.on_board?
37
- yield
38
- end
34
+ yield if board && board.valid_pose?(pose)
39
35
  end
40
36
  end
41
37
  end
@@ -1,22 +1,20 @@
1
1
  module ToyRobot
2
- View = Struct.new(:args) do
2
+ class View
3
+ def initialize(args)
4
+ @robot = args[:robot]
5
+ @output = args[:output] || $stdout
6
+ end
7
+
3
8
  def report
4
- report = robot.report
5
- output.puts report_string(report) if report
9
+ output.puts format_report(robot.report)
6
10
  end
7
11
 
8
12
  private
9
13
 
10
- def report_string(report)
11
- "#{report[:x]},#{report[:y]},#{report[:orientation].upcase}"
12
- end
13
-
14
- def robot
15
- args[:robot]
16
- end
14
+ attr_reader :robot, :output
17
15
 
18
- def output
19
- args[:output] || $stdout
16
+ def format_report(report)
17
+ "#{report[:x]},#{report[:y]},#{report[:orientation].upcase}" if report
20
18
  end
21
19
  end
22
20
  end
@@ -0,0 +1,5 @@
1
+ class BoardDouble
2
+ def valid_pose?(pose)
3
+ pose && true
4
+ end
5
+ end
@@ -11,8 +11,8 @@ module ToyRobot
11
11
  assert_respond_to @object, :create
12
12
  end
13
13
 
14
- def test_that_create_returns_a_robot_controller
15
- assert_instance_of RobotController, @object.create(:controller)
14
+ def test_that_create_returns_a_controller
15
+ assert_instance_of Controller, @object.create(:controller)
16
16
  end
17
17
  end
18
18
  end
@@ -3,7 +3,7 @@ require 'minitest/autorun'
3
3
  module ToyRobot
4
4
  class ToyRobotTest < MiniTest::Unit::TestCase
5
5
  def test_that_it_is_executable
6
- assert system('[ -x bin/toyrobots ]')
6
+ assert system('[ -x bin/toyrobot ]')
7
7
  end
8
8
  end
9
9
  end
@@ -0,0 +1,23 @@
1
+ class PoseDouble
2
+ def mutate!(_ = nil)
3
+ self
4
+ end
5
+
6
+ def adjacent
7
+ self.class.new
8
+ end
9
+
10
+ def rotate!(_)
11
+ self
12
+ end
13
+
14
+ def report
15
+ {
16
+ x: 0,
17
+ y: 0,
18
+ orientation: :facing
19
+ }
20
+ end
21
+
22
+ def [](_); end;
23
+ end
data/test/test_board.rb CHANGED
@@ -1,31 +1,24 @@
1
1
  require_relative '../lib/toy_robot/board'
2
+ require_relative 'test_board_interface'
2
3
  require 'minitest/autorun'
3
4
 
4
5
  module ToyRobot
5
6
  class BoardTest < MiniTest::Unit::TestCase
6
-
7
- PoseDouble = Struct.new(:x, :y)
8
-
7
+ include BoardInterfaceTest
9
8
  def setup
10
- @board = Board.new(5,5)
9
+ @board = @object = Board.new(5,5)
11
10
  end
12
11
 
13
12
  def test_that_knows_a_valid_pose
14
- pose_double = PoseDouble.new(0,0)
15
-
16
- assert @board.valid_pose?(pose_double)
13
+ pose = {x: 0, y: 0}
14
+ assert @board.valid_pose?(pose)
17
15
  end
18
16
 
19
17
  def test_that_knows_an_invalid_pose
20
18
  [[-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"
19
+ pose = {x: out_of_range[0], y: out_of_range[1]}
20
+ refute @board.valid_pose?(pose), "Pose #{pose} should be invalid"
24
21
  end
25
22
  end
26
-
27
- def test_that_a_nil_pose_is_invalid
28
- refute @board.valid_pose?(nil)
29
- end
30
23
  end
31
24
  end
@@ -0,0 +1,13 @@
1
+ require_relative 'board_double'
2
+ require_relative 'test_board_interface'
3
+ require 'minitest/autorun'
4
+
5
+ module ToyRobot
6
+ class BoardDoubleTest < MiniTest::Unit::TestCase
7
+ include BoardInterfaceTest
8
+
9
+ def setup
10
+ @object = BoardDouble.new
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module ToyRobot
2
+ module BoardInterfaceTest
3
+ def test_board_public_interface
4
+ assert_respond_to @object, :valid_pose?
5
+ end
6
+
7
+ def test_that_valid_pose_returns_nil
8
+ assert_nil @object.valid_pose?(nil)
9
+ end
10
+
11
+ def test_that_valid_pose_returns_true_or_false
12
+ assert_includes [true, false], @object.valid_pose?({})
13
+ end
14
+ end
15
+ end
@@ -2,21 +2,21 @@ require_relative '../lib/toy_robot/command/parser'
2
2
  require 'minitest/autorun'
3
3
 
4
4
  module ToyRobot
5
- class CommandMatcherTest < MiniTest::Unit::TestCase
5
+ class CommandParserTest < MiniTest::Unit::TestCase
6
6
  def setup
7
- @matcher = Command::Parser
7
+ @parser = Command::Parser
8
8
  end
9
9
 
10
10
  def test_that_it_can_parse
11
- refute_equal nil, @matcher.parse('PLACE 0,0,NORTH')
11
+ refute_equal nil, @parser.parse('PLACE 0,0,NORTH')
12
12
  end
13
13
 
14
14
  def test_that_parsing_can_fail
15
- assert_equal nil, @matcher.parse('PLACE 0,0,NORTHISH')
15
+ assert_equal nil, @parser.parse('PLACE 0,0,NORTHISH')
16
16
  end
17
17
 
18
- def test_that_it_knows_all_matchers
19
- all = @matcher.all
18
+ def test_that_it_knows_all_parsers
19
+ all = @parser.all
20
20
 
21
21
  assert_includes all, Command::Parser::Place
22
22
 
@@ -1,6 +1,6 @@
1
1
  module ToyRobot
2
- module CommandMatcherInterfaceTest
3
- def test_it_implement_the_command_matcher_interface
2
+ module CommandParserInterfaceTest
3
+ def test_it_implement_the_command_parser_interface
4
4
  assert_respond_to @object, :build_with_match
5
5
  end
6
6
 
@@ -14,9 +14,9 @@ module ToyRobot
14
14
  end
15
15
  end
16
16
 
17
- def test_that_response_knows_token
18
- assert_equal @object_token,
19
- @object.build_with_match(@object_valid_str).token
17
+ def test_that_response_knows_msg
18
+ assert_equal @object_msg,
19
+ @object.build_with_match(@object_valid_str).msg
20
20
  end
21
21
 
22
22
  def test_that_response_knows_args
@@ -0,0 +1,20 @@
1
+ require_relative '../lib/toy_robot/command/parser/left'
2
+ require_relative 'test_command_parser_interface'
3
+ require 'minitest/autorun'
4
+
5
+ module ToyRobot
6
+ class CommandParserLeftTest < MiniTest::Unit::TestCase
7
+ include CommandParserInterfaceTest
8
+
9
+ def setup
10
+ @object = Command::Parser::Left
11
+ @object_msg = :left
12
+ @object_valid_str = 'LEFT'
13
+ @object_invalid_strs = [
14
+ 'LEFT ',
15
+ 'LEFTY',
16
+ 'LEFT 180'
17
+ ]
18
+ end
19
+ end
20
+ end
@@ -1,14 +1,14 @@
1
- require_relative '../lib/toy_robot/command/parser/base'
2
- require_relative 'test_command_matcher_interface'
1
+ require_relative '../lib/toy_robot/command/parser/move'
2
+ require_relative 'test_command_parser_interface'
3
3
  require 'minitest/autorun'
4
4
 
5
5
  module ToyRobot
6
- class CommandMatcherMoveTest < MiniTest::Unit::TestCase
7
- include CommandMatcherInterfaceTest
6
+ class CommandParserMoveTest < MiniTest::Unit::TestCase
7
+ include CommandParserInterfaceTest
8
8
 
9
9
  def setup
10
10
  @object = Command::Parser::Move
11
- @object_token = Command::Token::MOVE
11
+ @object_msg = :move
12
12
  @object_valid_str = 'MOVE'
13
13
  @object_invalid_strs = [
14
14
  'MOVE ',