From 8c5e952146c2a806de9b7a6d2fbd16194af14a0f Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Wed, 21 Feb 2018 16:02:52 +0100 Subject: [PATCH 1/3] Rename Bearing ->Direction (to make it more consistent) --- exercises/robot-simulator/RobotSimulator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/robot-simulator/RobotSimulator.cs b/exercises/robot-simulator/RobotSimulator.cs index 5fa8c719b7..ea43330b75 100644 --- a/exercises/robot-simulator/RobotSimulator.cs +++ b/exercises/robot-simulator/RobotSimulator.cs @@ -1,6 +1,6 @@ using System; -public enum Bearing +public enum Direction { North, East, @@ -22,11 +22,11 @@ public Coordinate(int x, int y) public class RobotSimulator { - public RobotSimulator(Bearing bearing, Coordinate coordinate) + public RobotSimulator(Direction direction, Coordinate coordinate) { } - public Bearing Bearing + public Direction Direction { get { From 8b96a55a99661b256958864ea244e368aa268575 Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Wed, 21 Feb 2018 16:04:38 +0100 Subject: [PATCH 2/3] Add robot-simulator test generator --- .../robot-simulator/RobotSimulatorTest.cs | 183 +++++++++++++++--- generators/Exercises/RobotSimulator.cs | 116 +++++++++++ 2 files changed, 268 insertions(+), 31 deletions(-) create mode 100644 generators/Exercises/RobotSimulator.cs diff --git a/exercises/robot-simulator/RobotSimulatorTest.cs b/exercises/robot-simulator/RobotSimulatorTest.cs index db5be514b7..7e193df89c 100644 --- a/exercises/robot-simulator/RobotSimulatorTest.cs +++ b/exercises/robot-simulator/RobotSimulatorTest.cs @@ -1,59 +1,180 @@ -using Xunit; +// This file was auto-generated based on version 2.2.0 of the canonical data. + +using Xunit; public class RobotSimulatorTest { [Fact] - public void Turn_right_edge_case() + public void A_robot_is_created_with_a_position_and_a_direction_robots_are_created_with_a_position_and_direction() + { + var sut = new RobotSimulator(Direction.North, new Coordinate(0, 0)); + Assert.Equal(Direction.North, sut.Direction); + Assert.Equal(0, sut.Coordinate.X); + Assert.Equal(0, sut.Coordinate.Y); + } + + [Fact(Skip = "Remove to run test")] + public void A_robot_is_created_with_a_position_and_a_direction_negative_positions_are_allowed() + { + var sut = new RobotSimulator(Direction.South, new Coordinate(-1, -1)); + Assert.Equal(Direction.South, sut.Direction); + Assert.Equal(-1, sut.Coordinate.X); + Assert.Equal(-1, sut.Coordinate.Y); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_clockwise_does_not_change_the_position() + { + var sut = new RobotSimulator(Direction.North, new Coordinate(0, 0)); + sut.TurnRight(); + Assert.Equal(0, sut.Coordinate.X); + Assert.Equal(0, sut.Coordinate.Y); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_clockwise_changes_the_direction_from_north_to_east() + { + var sut = new RobotSimulator(Direction.North, new Coordinate(0, 0)); + sut.TurnRight(); + Assert.Equal(Direction.East, sut.Direction); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_clockwise_changes_the_direction_from_east_to_south() + { + var sut = new RobotSimulator(Direction.East, new Coordinate(0, 0)); + sut.TurnRight(); + Assert.Equal(Direction.South, sut.Direction); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_clockwise_changes_the_direction_from_south_to_west() + { + var sut = new RobotSimulator(Direction.South, new Coordinate(0, 0)); + sut.TurnRight(); + Assert.Equal(Direction.West, sut.Direction); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_clockwise_changes_the_direction_from_west_to_north() + { + var sut = new RobotSimulator(Direction.West, new Coordinate(0, 0)); + sut.TurnRight(); + Assert.Equal(Direction.North, sut.Direction); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_counter_clockwise_does_not_change_the_position() + { + var sut = new RobotSimulator(Direction.North, new Coordinate(0, 0)); + sut.TurnLeft(); + Assert.Equal(0, sut.Coordinate.X); + Assert.Equal(0, sut.Coordinate.Y); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_counter_clockwise_changes_the_direction_from_north_to_west() + { + var sut = new RobotSimulator(Direction.North, new Coordinate(0, 0)); + sut.TurnLeft(); + Assert.Equal(Direction.West, sut.Direction); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_counter_clockwise_changes_the_direction_from_west_to_south() + { + var sut = new RobotSimulator(Direction.West, new Coordinate(0, 0)); + sut.TurnLeft(); + Assert.Equal(Direction.South, sut.Direction); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_counter_clockwise_changes_the_direction_from_south_to_east() + { + var sut = new RobotSimulator(Direction.South, new Coordinate(0, 0)); + sut.TurnLeft(); + Assert.Equal(Direction.East, sut.Direction); + } + + [Fact(Skip = "Remove to run test")] + public void Rotates_the_robots_direction_90_degrees_counter_clockwise_changes_the_direction_from_east_to_north() + { + var sut = new RobotSimulator(Direction.East, new Coordinate(0, 0)); + sut.TurnLeft(); + Assert.Equal(Direction.North, sut.Direction); + } + + [Fact(Skip = "Remove to run test")] + public void Moves_the_robot_forward_1_space_in_the_direction_it_is_pointing_does_not_change_the_direction() { - var robot = new RobotSimulator(Bearing.West, new Coordinate(0, 0)); - robot.TurnRight(); - Assert.Equal(Bearing.North, robot.Bearing); + var sut = new RobotSimulator(Direction.North, new Coordinate(0, 0)); + sut.Advance(); + Assert.Equal(Direction.North, sut.Direction); } [Fact(Skip = "Remove to run test")] - public void Turn_left_edge_case() + public void Moves_the_robot_forward_1_space_in_the_direction_it_is_pointing_increases_the_y_coordinate_one_when_facing_north() { - var robot = new RobotSimulator(Bearing.North, new Coordinate(0, 0)); - robot.TurnLeft(); - Assert.Equal(Bearing.West, robot.Bearing); + var sut = new RobotSimulator(Direction.North, new Coordinate(0, 0)); + sut.Advance(); + Assert.Equal(0, sut.Coordinate.X); + Assert.Equal(1, sut.Coordinate.Y); } [Fact(Skip = "Remove to run test")] - public void Robbie() + public void Moves_the_robot_forward_1_space_in_the_direction_it_is_pointing_decreases_the_y_coordinate_by_one_when_facing_south() { - var robbie = new RobotSimulator(Bearing.East, new Coordinate(-2, 1)); - Assert.Equal(Bearing.East, robbie.Bearing); - Assert.Equal(new Coordinate(-2, 1), robbie.Coordinate); + var sut = new RobotSimulator(Direction.South, new Coordinate(0, 0)); + sut.Advance(); + Assert.Equal(0, sut.Coordinate.X); + Assert.Equal(-1, sut.Coordinate.Y); + } - robbie.Simulate("RLAALAL"); - Assert.Equal(Bearing.West, robbie.Bearing); - Assert.Equal(new Coordinate(0, 2), robbie.Coordinate); + [Fact(Skip = "Remove to run test")] + public void Moves_the_robot_forward_1_space_in_the_direction_it_is_pointing_increases_the_x_coordinate_by_one_when_facing_east() + { + var sut = new RobotSimulator(Direction.East, new Coordinate(0, 0)); + sut.Advance(); + Assert.Equal(1, sut.Coordinate.X); + Assert.Equal(0, sut.Coordinate.Y); + } + + [Fact(Skip = "Remove to run test")] + public void Moves_the_robot_forward_1_space_in_the_direction_it_is_pointing_decreases_the_x_coordinate_by_one_when_facing_west() + { + var sut = new RobotSimulator(Direction.West, new Coordinate(0, 0)); + sut.Advance(); + Assert.Equal(-1, sut.Coordinate.X); + Assert.Equal(0, sut.Coordinate.Y); } [Fact(Skip = "Remove to run test")] - public void Clutz() + public void Where_r_turn_right_l_turn_left_and_a_advance_the_robot_can_follow_a_series_of_instructions_and_end_up_with_the_correct_position_and_direction_instructions_to_move_west_and_north() { - var clutz = new RobotSimulator(Bearing.North, new Coordinate(0, 0)); - clutz.Simulate("LAAARALA"); - Assert.Equal(Bearing.West, clutz.Bearing); - Assert.Equal(new Coordinate(-4, 1), clutz.Coordinate); + var sut = new RobotSimulator(Direction.North, new Coordinate(0, 0)); + sut.Simulate("LAAARALA"); + Assert.Equal(Direction.West, sut.Direction); + Assert.Equal(-4, sut.Coordinate.X); + Assert.Equal(1, sut.Coordinate.Y); } [Fact(Skip = "Remove to run test")] - public void Sphero() + public void Where_r_turn_right_l_turn_left_and_a_advance_the_robot_can_follow_a_series_of_instructions_and_end_up_with_the_correct_position_and_direction_instructions_to_move_west_and_south() { - var sphero = new RobotSimulator(Bearing.East, new Coordinate(2, -7)); - sphero.Simulate("RRAAAAALA"); - Assert.Equal(Bearing.South, sphero.Bearing); - Assert.Equal(new Coordinate(-3, -8), sphero.Coordinate); + var sut = new RobotSimulator(Direction.East, new Coordinate(2, -7)); + sut.Simulate("RRAAAAALA"); + Assert.Equal(Direction.South, sut.Direction); + Assert.Equal(-3, sut.Coordinate.X); + Assert.Equal(-8, sut.Coordinate.Y); } [Fact(Skip = "Remove to run test")] - public void Roomba() + public void Where_r_turn_right_l_turn_left_and_a_advance_the_robot_can_follow_a_series_of_instructions_and_end_up_with_the_correct_position_and_direction_instructions_to_move_east_and_north() { - var roomba = new RobotSimulator(Bearing.South, new Coordinate(8, 4)); - roomba.Simulate("LAAARRRALLLL"); - Assert.Equal(Bearing.North, roomba.Bearing); - Assert.Equal(new Coordinate(11, 5), roomba.Coordinate); + var sut = new RobotSimulator(Direction.South, new Coordinate(8, 4)); + sut.Simulate("LAAARRRALLLL"); + Assert.Equal(Direction.North, sut.Direction); + Assert.Equal(11, sut.Coordinate.X); + Assert.Equal(5, sut.Coordinate.Y); } } \ No newline at end of file diff --git a/generators/Exercises/RobotSimulator.cs b/generators/Exercises/RobotSimulator.cs new file mode 100644 index 0000000000..fc9407316a --- /dev/null +++ b/generators/Exercises/RobotSimulator.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Generators.Input; +using Generators.Output; + +namespace Generators.Exercises +{ + public class RobotSimulator : GeneratorExercise + { + protected override void UpdateCanonicalData(CanonicalData canonicalData) + { + const string direction = "direction"; + const string position = "position"; + const string coordinate = "coordinate"; + + foreach (var canonicalDataCase in canonicalData.Cases) + { + var positionVal = new UnescapedValue(GetCoordinateInstance(canonicalDataCase.Input["input"][position])); + var directionVal = new UnescapedValue(GetDirectionEnum(canonicalDataCase.Input["input"][direction])); + + canonicalDataCase.Properties[direction] = directionVal; + canonicalDataCase.Properties[coordinate] = positionVal; + + canonicalDataCase.SetConstructorInputParameters(direction, coordinate); + + canonicalDataCase.UseFullDescriptionPath = true; + canonicalDataCase.UseVariableForTested = true; + } + } + + protected override string RenderTestMethodBodyArrange(TestMethodBody testMethodBody) + { + ((testMethodBody.ArrangeTemplateParameters as dynamic).Variables as List).RemoveAt(1); + + return base.RenderTestMethodBodyArrange(testMethodBody); + } + + protected override string RenderTestMethodBodyAct(TestMethodBody testMethodBody) + { + switch (testMethodBody.CanonicalDataCase.Property) + { + case "create": return string.Empty; + case "instructions": return RenderInstructionsMethodBodyAct(testMethodBody); + default: return RenderDefaultMethodBodyAct(testMethodBody); + } + } + + private string RenderDefaultMethodBodyAct(TestMethodBody testMethodBody) + { + string template = @"sut.{{MethodInvocation}}();"; + + var templateParameters = new + { + MethodInvocation = testMethodBody.CanonicalDataCase.Property.ToTestedMethodName() + }; + + return TemplateRenderer.RenderInline(template, templateParameters); + } + + private string RenderInstructionsMethodBodyAct(TestMethodBody testMethodBody) + { + string template = @"sut.{{MethodInvocation}}(""{{Instructions}}"");"; + + var templateParameters = new + { + MethodInvocation = "Simulate", + Instructions = testMethodBody.CanonicalDataCase.Properties["input"]["instructions"] + }; + + return TemplateRenderer.RenderInline(template, templateParameters); + } + + protected override string RenderTestMethodBodyAssert(TestMethodBody testMethodBody) + { + var expected = testMethodBody.CanonicalDataCase.Expected as Dictionary; + expected.TryGetValue("position", out dynamic position); + expected.TryGetValue("direction", out dynamic direction); + + StringBuilder template = new StringBuilder(); + + if (direction != null) + template.AppendLine("Assert.Equal({{Direction}}, sut.Direction);"); + + if (position != null) + { + template.AppendLine("Assert.Equal({{X}}, sut.Coordinate.X);"); + template.AppendLine("Assert.Equal({{Y}}, sut.Coordinate.Y);"); + } + + var templateParameters = new + { + Direction = !string.IsNullOrEmpty(direction) ? GetDirectionEnum(direction) : null, + X = position?["x"], + Y = position?["y"] + }; + + return TemplateRenderer.RenderInline(template.ToString(), templateParameters); + } + + private string GetDirectionEnum(string direction) + { + switch (direction) + { + case "north": return "Direction.North"; + case "east": return "Direction.East"; + case "south": return "Direction.South"; + case "west": return "Direction.West"; + + default: throw new ArgumentException("Unrecognized 'Direction' enum value"); + } + } + + private string GetCoordinateInstance(dynamic coordinates) => $"new Coordinate({coordinates["x"]}, {coordinates["y"]})"; + } +} From f5594f2a6fe67bec9b4686514427fe9312776374 Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Thu, 22 Feb 2018 10:35:13 +0100 Subject: [PATCH 3/3] Rename Bearing -> Direction in Example --- exercises/robot-simulator/Example.cs | 54 ++++++++++++++-------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/exercises/robot-simulator/Example.cs b/exercises/robot-simulator/Example.cs index 66c4e5e6d7..139df644bc 100644 --- a/exercises/robot-simulator/Example.cs +++ b/exercises/robot-simulator/Example.cs @@ -1,6 +1,6 @@ using System; -public enum Bearing +public enum Direction { North, East, @@ -22,30 +22,30 @@ public Coordinate(int x, int y) public class RobotSimulator { - public RobotSimulator(Bearing bearing, Coordinate coordinate) + public RobotSimulator(Direction bearing, Coordinate coordinate) { - Bearing = bearing; + Direction = bearing; Coordinate = coordinate; } - public Bearing Bearing { get; private set; } + public Direction Direction { get; private set; } public Coordinate Coordinate { get; private set; } public void TurnRight() { - switch (Bearing) + switch (Direction) { - case Bearing.North: - Bearing = Bearing.East; + case Direction.North: + Direction = Direction.East; break; - case Bearing.East: - Bearing = Bearing.South; + case Direction.East: + Direction = Direction.South; break; - case Bearing.South: - Bearing = Bearing.West; + case Direction.South: + Direction = Direction.West; break; - case Bearing.West: - Bearing = Bearing.North; + case Direction.West: + Direction = Direction.North; break; default: throw new ArgumentOutOfRangeException(); @@ -54,19 +54,19 @@ public void TurnRight() public void TurnLeft() { - switch (Bearing) + switch (Direction) { - case Bearing.North: - Bearing = Bearing.West; + case Direction.North: + Direction = Direction.West; break; - case Bearing.East: - Bearing = Bearing.North; + case Direction.East: + Direction = Direction.North; break; - case Bearing.South: - Bearing = Bearing.East; + case Direction.South: + Direction = Direction.East; break; - case Bearing.West: - Bearing = Bearing.South; + case Direction.West: + Direction = Direction.South; break; default: throw new ArgumentOutOfRangeException(); @@ -75,18 +75,18 @@ public void TurnLeft() public void Advance() { - switch (Bearing) + switch (Direction) { - case Bearing.North: + case Direction.North: Coordinate = new Coordinate(Coordinate.X, Coordinate.Y + 1); break; - case Bearing.East: + case Direction.East: Coordinate = new Coordinate(Coordinate.X + 1, Coordinate.Y); break; - case Bearing.South: + case Direction.South: Coordinate = new Coordinate(Coordinate.X, Coordinate.Y - 1); break; - case Bearing.West: + case Direction.West: Coordinate = new Coordinate(Coordinate.X - 1, Coordinate.Y); break; default: