{"action":"created","comment":{"url":"https://api.github.com/repos/bforma/robo-racer/pulls/comments/32629316","id":32629316,"diff_hunk":"@@ -116,231 +137,335 @@\n               InstructionCard.u_turn(40),\n               InstructionCard.u_turn(50)\n             ]),\n-            AllRobotsProgrammedEvent.new(id)\n-          ]\n-        end\n-      end\n-\n-      context \"when trying to program an instruction that is not dealt to player\" do\n-        before do\n-          dispatch(create_game_command)\n-          dispatch(start_game_command)\n-\n-          command.instruction_cards[0] = InstructionCard.move_3(790)\n+          )\n         end\n \n-        specify do\n-          expect { dispatch(command) }.to raise_error(IllegalInstructionCardError)\n+        it 'denies re-programming the robot' do\n+          expect { dispatch(command) }.to raise_error(RobotAlreadyProgrammedError)\n         end\n       end\n \n-      context \"when robot is already programmed\" do\n-        before do\n-          dispatch(create_game_command)\n-          dispatch(start_game_command)\n-          dispatch(program_robot_command)\n-        end\n+      context 'given the player has not joined the game' do\n+        before { command.player_id = steven }\n \n-        specify do\n-          expect { dispatch(command.dup) }.to raise_error(RobotAlreadyProgrammedError)\n+        it 'denies programming the robot' do\n+          expect { dispatch(command) }.to raise_error(PlayerNotInGameError)\n         end\n       end\n+    end\n \n-      context \"when game not yet started\" do\n-        before { dispatch(create_game_command) }\n-\n-        specify do\n-          expect { dispatch(command) }.to raise_error(GameNotRunningError)\n-        end\n+    context 'given an unstarted game' do\n+      before do\n+        given_events(\n+          GameCreatedEvent.new(id, GameState::LOBBYING, bob),\n+          PlayerJoinedGameEvent.new(id, bob),\n+        )\n       end\n \n-      context \"when player not in game\" do\n-        before do\n-          dispatch(create_game_command)\n-          dispatch(start_game_command)\n-\n-          command.player_id = steven\n-        end\n-\n-        specify do\n-          expect { dispatch(command) }.to raise_error(PlayerNotInGameError)\n-        end\n+      it 'denies programming the robot' do\n+        expect { dispatch(command) }.to raise_error(GameNotRunningError)\n       end\n     end\n+  end\n \n-    describe PlayCurrentRoundCommand do\n-      let(:command) { play_current_round_command }\n-\n-      it_behaves_like \"an event publisher\" do\n-        before do\n-          dispatch(create_game_command)\n-          dispatch(start_game_command)\n-          dispatch(program_robot_command)\n-        end\n+  describe PlayCurrentRoundCommand do\n+    context 'given all robots where programmed' do\n+      before do\n+        given_events(\n+          GameCreatedEvent.new(id, GameState::LOBBYING, bob),\n+          PlayerJoinedGameEvent.new(id, bob),\n+          GameStartedEvent.new(id, GameState::RUNNING, deck, board),\n+          SpawnPlacedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n+          GoalPlacedEvent.new(id, Goal.new(2, 11, 1)),\n+          GoalPlacedEvent.new(id, Goal.new(10, 7, 2)),\n+          RobotSpawnedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n+          GameRoundStartedEvent.new(id, GameRound.new(1), {'bob' => []}, {'bob' => []}),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(10)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(20)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(30)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(40)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(50)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(60)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(70)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(90)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(110)),\n+          RobotProgrammedEvent.new(id, bob, [\n+            InstructionCard.u_turn(10),\n+            InstructionCard.u_turn(20),\n+            InstructionCard.u_turn(30),\n+            InstructionCard.u_turn(40),\n+            InstructionCard.u_turn(50)\n+          ]),\n+          AllRobotsProgrammedEvent.new(id)\n+        )\n+      end\n \n-        let(:expected_events) do\n-          [\n-            RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::UP)),\n-            RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n-            RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::UP)),\n-            RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n-            RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::UP)),\n-            InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(10)),\n-            InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(20)),\n-            InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(30)),\n-            InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(40)),\n-            InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(50)),\n-            InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(60)),\n-            InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(70)),\n-            InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(90)),\n-            InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(110)),\n-            GameRoundStartedEvent.new(\n-              id, GameRound.new(2), {'bob' => []}, {'bob' => []}\n-            ),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(130)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(150)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(170)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(190)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(210)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(230)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(250)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(270)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(290))\n-          ]\n-        end\n+      it 'plays the current round' do\n+        when_command PlayCurrentRoundCommand.new(id: id)\n+        then_events(\n+          GameRoundStartedPlayingEvent.new(id, GameRound.new(1)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(10)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::UP)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(20)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(30)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::UP)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(40)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(50)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::UP)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(10)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(20)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(30)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(40)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(50)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(60)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(70)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(90)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(110)),\n+          GameRoundFinishedPlayingEvent.new(id, GameRound.new(1)),\n+          GameRoundStartedEvent.new(id, GameRound.new(2), {'bob' => []}, {'bob' => []}),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(130)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(150)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(170)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(190)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(210)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(230)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(250)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(270)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(290))\n+        )\n       end\n+    end\n \n-      context \"given a winning player\" do\n-        let(:deck) do\n-          InstructionDeckComposer.compose\n-        end\n+    context 'given two players' do\n+      before do\n+        given_events(\n+          GameCreatedEvent.new(id, GameState::LOBBYING, bob),\n+          PlayerJoinedGameEvent.new(id, bob),\n+          PlayerJoinedGameEvent.new(id, steven),\n+          GameStartedEvent.new(id, GameState::RUNNING, deck, board),\n+          SpawnPlacedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n+          SpawnPlacedEvent.new(id, steven, GameUnit.new(3, 1, GameUnit::DOWN)),\n+          GoalPlacedEvent.new(id, Goal.new(2, 11, 1)),\n+          RobotSpawnedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n+          RobotSpawnedEvent.new(id, steven, GameUnit.new(3, 1, GameUnit::DOWN)),\n+          GameRoundStartedEvent.new(id, GameRound.new(1), {'bob' => [], 'steven' => []}, {'bob' => [], 'steven' => []}),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(10)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.u_turn(20)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(30)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.u_turn(40)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(50)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.u_turn(60)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(70)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_left(90)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(110)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_left(130)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(150)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_left(170)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(190)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_left(210)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(230)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_left(250)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(270)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_left(290)),\n+          RobotProgrammedEvent.new(id, bob, [\n+            InstructionCard.u_turn(10),\n+            InstructionCard.u_turn(30),\n+            InstructionCard.u_turn(50),\n+            InstructionCard.rotate_left(70),\n+            InstructionCard.rotate_left(110)\n+          ]),\n+          RobotProgrammedEvent.new(id, steven, [\n+            InstructionCard.u_turn(20),\n+            InstructionCard.u_turn(40),\n+            InstructionCard.u_turn(60),\n+            InstructionCard.rotate_left(90),\n+            InstructionCard.rotate_left(130)\n+          ]),\n+          AllRobotsProgrammedEvent.new(id)\n+        )\n+      end\n \n-        let(:tiles) do\n-          BoardComposer.compose\n-        end\n+      it 'plays the round' do\n+        when_command PlayCurrentRoundCommand.new(id: id)\n+        then_events(\n+          GameRoundStartedPlayingEvent.new(id, GameRound.new(1)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(10)),\n+          InstructionCardRevealedEvent.new(id, steven, InstructionCard.u_turn(20)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::UP)),\n+          RobotRotatedEvent.new(id, steven, GameUnit.new(3, 1, GameUnit::UP)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(30)),\n+          InstructionCardRevealedEvent.new(id, steven, InstructionCard.u_turn(40)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n+          RobotRotatedEvent.new(id, steven, GameUnit.new(3, 1, GameUnit::DOWN)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(50)),\n+          InstructionCardRevealedEvent.new(id, steven, InstructionCard.u_turn(60)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::UP)),\n+          RobotRotatedEvent.new(id, steven, GameUnit.new(3, 1, GameUnit::UP)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.rotate_left(70)),\n+          InstructionCardRevealedEvent.new(id, steven, InstructionCard.rotate_left(90)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::LEFT)),\n+          RobotRotatedEvent.new(id, steven, GameUnit.new(3, 1, GameUnit::LEFT)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.rotate_left(110)),\n+          InstructionCardRevealedEvent.new(id, steven, InstructionCard.rotate_left(130)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(2, 1, GameUnit::DOWN)),\n+          RobotRotatedEvent.new(id, steven, GameUnit.new(3, 1, GameUnit::DOWN)),\n+          GameRoundFinishedPlayingEvent.new(id, GameRound.new(1)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(10)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(20)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(30)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(40)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(50)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(60)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(70)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(90)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(110)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(130)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(150)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(170)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(190)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(210)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(230)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(250)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(270)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(290)),\n+          GameRoundStartedEvent.new(id, GameRound.new(2), {'bob' => [], 'steven' => []}, {'bob' => [], 'steven' => []}),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(310)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_left(330)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(350)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_left(370)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(390)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_left(410)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_right(80)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_right(100)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_right(120)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_right(140)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_right(160)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_right(180)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_right(200)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_right(220)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_right(240)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_right(260)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_right(280)),\n+          InstructionCardDealtEvent.new(id, steven, InstructionCard.rotate_right(300)),\n+        )\n+      end\n+    end\n \n-        before do\n-          given_events(\n-            GameCreatedEvent.new(id, GameState::LOBBYING, bob),\n-            PlayerJoinedGameEvent.new(id, bob),\n-            GameStartedEvent.new(id, GameState::RUNNING, deck, tiles),\n-            SpawnPlacedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::DOWN)),\n-            GoalPlacedEvent.new(id, Goal.new(0, 0, 1)),\n-            RobotSpawnedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::DOWN)),\n-            GameRoundStartedEvent.new(\n-              id, GameRound.new(1), {'bob' => []}, {'bob' => []}\n-            ),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(10)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(20)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(30)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(40)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(50)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(60)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(70)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(90)),\n-            InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(110)),\n-            RobotProgrammedEvent.new(id, bob, [\n-              InstructionCard.u_turn(10),\n-              InstructionCard.u_turn(20),\n-              InstructionCard.u_turn(30),\n-              InstructionCard.u_turn(40),\n-              InstructionCard.u_turn(50)\n-            ]),\n-            AllRobotsProgrammedEvent.new(id)\n-          )\n-        end\n+    context 'given a winning scenario' do\n+      before do\n+        given_events(\n+          GameCreatedEvent.new(id, GameState::LOBBYING, bob),\n+          PlayerJoinedGameEvent.new(id, bob),\n+          GameStartedEvent.new(id, GameState::RUNNING, deck, board),\n+          SpawnPlacedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::DOWN)),\n+          GoalPlacedEvent.new(id, Goal.new(0, 0, 1)),\n+          RobotSpawnedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::DOWN)),\n+          GameRoundStartedEvent.new(id, GameRound.new(1), {'bob' => []}, {'bob' => []}),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(10)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(20)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(30)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(40)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(50)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.u_turn(60)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(70)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(90)),\n+          InstructionCardDealtEvent.new(id, bob, InstructionCard.rotate_left(110)),\n+          RobotProgrammedEvent.new(id, bob, [\n+            InstructionCard.u_turn(10),\n+            InstructionCard.u_turn(20),\n+            InstructionCard.u_turn(30),\n+            InstructionCard.u_turn(40),\n+            InstructionCard.u_turn(50)\n+          ]),\n+          AllRobotsProgrammedEvent.new(id)\n+        )\n+      end\n \n-        it_behaves_like \"an event publisher\" do\n-          let(:expected_events) do\n-            [\n-              RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::UP)),\n-              RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::DOWN)),\n-              RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::UP)),\n-              RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::DOWN)),\n-              RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::UP)),\n-              GoalTouchedEvent.new(id, bob, Goal.new(0, 0, 1)),\n-              PlayerWonGameEvent.new(id, bob),\n-              SpawnReplacedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::UP)),\n-              InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(10)),\n-              InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(20)),\n-              InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(30)),\n-              InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(40)),\n-              InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(50)),\n-              InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(60)),\n-              InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(70)),\n-              InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(90)),\n-              InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(110)),\n-              GameEndedEvent.new(id, GameState::ENDED)\n-            ]\n-          end\n-        end\n+      it 'wins the game for a player' do\n+        when_command PlayCurrentRoundCommand.new(id: id)\n+        then_events(\n+          GameRoundStartedPlayingEvent.new(id, GameRound.new(1)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(10)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::UP)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(20)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::DOWN)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(30)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::UP)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(40)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::DOWN)),\n+          InstructionCardRevealedEvent.new(id, bob, InstructionCard.u_turn(50)),\n+          RobotRotatedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::UP)),\n+          GoalTouchedEvent.new(id, bob, Goal.new(0, 0, 1)),\n+          PlayerWonGameEvent.new(id, bob),\n+          SpawnReplacedEvent.new(id, bob, GameUnit.new(0, 0, GameUnit::UP)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(10)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(20)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(30)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(40)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(50)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.u_turn(60)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(70)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(90)),\n+          InstructionCardDiscardedEvent.new(id, InstructionCard.rotate_left(110)),\n+          GameRoundFinishedPlayingEvent.new(id, GameRound.new(1)),\n+          GameEndedEvent.new(id, GameState::ENDED)\n+        )\n       end\n     end\n   end\n \n   describe JoinGameCommand do\n-    let(:command) { join_game_command }\n-\n-    it_behaves_like \"an event publisher\" do\n-      before { dispatch(create_game_command) }\n+    subject(:command) { JoinGameCommand.new(id: id, player_id: steven) }\n+    before { given_events GameCreatedEvent.new(id, GameState::LOBBYING, bob) }\n \n-      let(:expected_events) { [PlayerJoinedGameEvent.new(id, steven)] }\n+    it 'joins a game' do\n+      when_command(command)\n+      then_events(PlayerJoinedGameEvent.new(id, steven))\n     end\n \n-    context \"when already in game\" do\n-      before do\n-        dispatch(create_game_command)\n-        dispatch(join_game_command)\n-      end\n+    context 'given the player already joined the game' do\n+      before { given_events PlayerJoinedGameEvent.new(id, steven) }\n \n-      specify do\n-        expect { dispatch(command.dup) }.to raise_error(PlayerAlreadyInGameError)\n+      it 'denies joining the game again' do\n+        expect { dispatch(command) }.to raise_error(PlayerAlreadyInGameError)\n       end\n     end\n \n-    context \"when game already started\" do\n-      before do\n-        dispatch(create_game_command)\n-        dispatch(start_game_command)\n-      end\n+    context 'given the game already started' do\n+      before { given_events GameStartedEvent.new(id, GameState::RUNNING, deck, board) }\n \n-      specify do\n+      it 'denies joining the game' do\n         expect { dispatch(command) }.to raise_error(GameAlreadyStartedError)\n       end\n     end\n   end\n \n   describe LeaveGameCommand do\n-    let(:command) { leave_game_command }\n-\n-    it_behaves_like \"an event publisher\" do\n-      before do\n-        dispatch(create_game_command)\n-        dispatch(join_game_command)\n-      end\n+    subject(:command) { LeaveGameCommand.new(id: id, player_id: steven) }\n+    before { given_events GameCreatedEvent.new(id, GameState::LOBBYING, bob) }\n \n-      let(:expected_events) { [PlayerLeftGameEvent.new(id, steven)] }\n-    end\n+    context 'given the player joined the game' do\n+      before { given_events PlayerJoinedGameEvent.new(id, steven) }\n \n-    context \"when not in game\" do\n-      before do\n-        dispatch(create_game_command)\n+      it 'leaves a game' do","path":"spec/domain/command_handlers/game_command_handler_spec.rb","position":710,"original_position":710,"commit_id":"41dbf5d27876a761964a23583ca441b3ca9ad8c5","original_commit_id":"41dbf5d27876a761964a23583ca441b3ca9ad8c5","user":{"login":"houndci","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci","html_url":"https://github.com/houndci","followers_url":"https://api.github.com/users/houndci/followers","following_url":"https://api.github.com/users/houndci/following{/other_user}","gists_url":"https://api.github.com/users/houndci/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci/subscriptions","organizations_url":"https://api.github.com/users/houndci/orgs","repos_url":"https://api.github.com/users/houndci/repos","events_url":"https://api.github.com/users/houndci/events{/privacy}","received_events_url":"https://api.github.com/users/houndci/received_events","type":"User","site_admin":false},"body":"Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.","created_at":"2015-06-17T14:04:09Z","updated_at":"2015-06-17T14:04:09Z","html_url":"https://github.com/bforma/robo-racer/pull/6#discussion_r32629316","pull_request_url":"https://api.github.com/repos/bforma/robo-racer/pulls/6","_links":{"self":{"href":"https://api.github.com/repos/bforma/robo-racer/pulls/comments/32629316"},"html":{"href":"https://github.com/bforma/robo-racer/pull/6#discussion_r32629316"},"pull_request":{"href":"https://api.github.com/repos/bforma/robo-racer/pulls/6"}}},"pull_request":{"url":"https://api.github.com/repos/bforma/robo-racer/pulls/6","id":37903878,"html_url":"https://github.com/bforma/robo-racer/pull/6","diff_url":"https://github.com/bforma/robo-racer/pull/6.diff","patch_url":"https://github.com/bforma/robo-racer/pull/6.patch","issue_url":"https://api.github.com/repos/bforma/robo-racer/issues/6","number":6,"state":"open","locked":false,"title":"Feature/humanly replay round","user":{"login":"bforma","id":1178544,"avatar_url":"https://avatars.githubusercontent.com/u/1178544?v=3","gravatar_id":"","url":"https://api.github.com/users/bforma","html_url":"https://github.com/bforma","followers_url":"https://api.github.com/users/bforma/followers","following_url":"https://api.github.com/users/bforma/following{/other_user}","gists_url":"https://api.github.com/users/bforma/gists{/gist_id}","starred_url":"https://api.github.com/users/bforma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bforma/subscriptions","organizations_url":"https://api.github.com/users/bforma/orgs","repos_url":"https://api.github.com/users/bforma/repos","events_url":"https://api.github.com/users/bforma/events{/privacy}","received_events_url":"https://api.github.com/users/bforma/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-06-17T14:03:28Z","updated_at":"2015-06-17T14:04:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"00035692ea4702f9a1329c0e601c9135f44935e7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/bforma/robo-racer/pulls/6/commits","review_comments_url":"https://api.github.com/repos/bforma/robo-racer/pulls/6/comments","review_comment_url":"https://api.github.com/repos/bforma/robo-racer/pulls/comments{/number}","comments_url":"https://api.github.com/repos/bforma/robo-racer/issues/6/comments","statuses_url":"https://api.github.com/repos/bforma/robo-racer/statuses/41dbf5d27876a761964a23583ca441b3ca9ad8c5","head":{"label":"bforma:feature/humanly-replay-round","ref":"feature/humanly-replay-round","sha":"41dbf5d27876a761964a23583ca441b3ca9ad8c5","user":{"login":"bforma","id":1178544,"avatar_url":"https://avatars.githubusercontent.com/u/1178544?v=3","gravatar_id":"","url":"https://api.github.com/users/bforma","html_url":"https://github.com/bforma","followers_url":"https://api.github.com/users/bforma/followers","following_url":"https://api.github.com/users/bforma/following{/other_user}","gists_url":"https://api.github.com/users/bforma/gists{/gist_id}","starred_url":"https://api.github.com/users/bforma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bforma/subscriptions","organizations_url":"https://api.github.com/users/bforma/orgs","repos_url":"https://api.github.com/users/bforma/repos","events_url":"https://api.github.com/users/bforma/events{/privacy}","received_events_url":"https://api.github.com/users/bforma/received_events","type":"User","site_admin":false},"repo":{"id":20587556,"name":"robo-racer","full_name":"bforma/robo-racer","owner":{"login":"bforma","id":1178544,"avatar_url":"https://avatars.githubusercontent.com/u/1178544?v=3","gravatar_id":"","url":"https://api.github.com/users/bforma","html_url":"https://github.com/bforma","followers_url":"https://api.github.com/users/bforma/followers","following_url":"https://api.github.com/users/bforma/following{/other_user}","gists_url":"https://api.github.com/users/bforma/gists{/gist_id}","starred_url":"https://api.github.com/users/bforma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bforma/subscriptions","organizations_url":"https://api.github.com/users/bforma/orgs","repos_url":"https://api.github.com/users/bforma/repos","events_url":"https://api.github.com/users/bforma/events{/privacy}","received_events_url":"https://api.github.com/users/bforma/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bforma/robo-racer","description":"","fork":false,"url":"https://api.github.com/repos/bforma/robo-racer","forks_url":"https://api.github.com/repos/bforma/robo-racer/forks","keys_url":"https://api.github.com/repos/bforma/robo-racer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bforma/robo-racer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bforma/robo-racer/teams","hooks_url":"https://api.github.com/repos/bforma/robo-racer/hooks","issue_events_url":"https://api.github.com/repos/bforma/robo-racer/issues/events{/number}","events_url":"https://api.github.com/repos/bforma/robo-racer/events","assignees_url":"https://api.github.com/repos/bforma/robo-racer/assignees{/user}","branches_url":"https://api.github.com/repos/bforma/robo-racer/branches{/branch}","tags_url":"https://api.github.com/repos/bforma/robo-racer/tags","blobs_url":"https://api.github.com/repos/bforma/robo-racer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bforma/robo-racer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bforma/robo-racer/git/refs{/sha}","trees_url":"https://api.github.com/repos/bforma/robo-racer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bforma/robo-racer/statuses/{sha}","languages_url":"https://api.github.com/repos/bforma/robo-racer/languages","stargazers_url":"https://api.github.com/repos/bforma/robo-racer/stargazers","contributors_url":"https://api.github.com/repos/bforma/robo-racer/contributors","subscribers_url":"https://api.github.com/repos/bforma/robo-racer/subscribers","subscription_url":"https://api.github.com/repos/bforma/robo-racer/subscription","commits_url":"https://api.github.com/repos/bforma/robo-racer/commits{/sha}","git_commits_url":"https://api.github.com/repos/bforma/robo-racer/git/commits{/sha}","comments_url":"https://api.github.com/repos/bforma/robo-racer/comments{/number}","issue_comment_url":"https://api.github.com/repos/bforma/robo-racer/issues/comments{/number}","contents_url":"https://api.github.com/repos/bforma/robo-racer/contents/{+path}","compare_url":"https://api.github.com/repos/bforma/robo-racer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bforma/robo-racer/merges","archive_url":"https://api.github.com/repos/bforma/robo-racer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bforma/robo-racer/downloads","issues_url":"https://api.github.com/repos/bforma/robo-racer/issues{/number}","pulls_url":"https://api.github.com/repos/bforma/robo-racer/pulls{/number}","milestones_url":"https://api.github.com/repos/bforma/robo-racer/milestones{/number}","notifications_url":"https://api.github.com/repos/bforma/robo-racer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bforma/robo-racer/labels{/name}","releases_url":"https://api.github.com/repos/bforma/robo-racer/releases{/id}","created_at":"2014-06-07T06:56:39Z","updated_at":"2015-04-18T09:07:51Z","pushed_at":"2015-06-17T14:03:29Z","git_url":"git://github.com/bforma/robo-racer.git","ssh_url":"git@github.com:bforma/robo-racer.git","clone_url":"https://github.com/bforma/robo-racer.git","svn_url":"https://github.com/bforma/robo-racer","homepage":null,"size":2168,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"bforma:master","ref":"master","sha":"969f0e099fc6262ec36b208c25aa2b930003c50a","user":{"login":"bforma","id":1178544,"avatar_url":"https://avatars.githubusercontent.com/u/1178544?v=3","gravatar_id":"","url":"https://api.github.com/users/bforma","html_url":"https://github.com/bforma","followers_url":"https://api.github.com/users/bforma/followers","following_url":"https://api.github.com/users/bforma/following{/other_user}","gists_url":"https://api.github.com/users/bforma/gists{/gist_id}","starred_url":"https://api.github.com/users/bforma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bforma/subscriptions","organizations_url":"https://api.github.com/users/bforma/orgs","repos_url":"https://api.github.com/users/bforma/repos","events_url":"https://api.github.com/users/bforma/events{/privacy}","received_events_url":"https://api.github.com/users/bforma/received_events","type":"User","site_admin":false},"repo":{"id":20587556,"name":"robo-racer","full_name":"bforma/robo-racer","owner":{"login":"bforma","id":1178544,"avatar_url":"https://avatars.githubusercontent.com/u/1178544?v=3","gravatar_id":"","url":"https://api.github.com/users/bforma","html_url":"https://github.com/bforma","followers_url":"https://api.github.com/users/bforma/followers","following_url":"https://api.github.com/users/bforma/following{/other_user}","gists_url":"https://api.github.com/users/bforma/gists{/gist_id}","starred_url":"https://api.github.com/users/bforma/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bforma/subscriptions","organizations_url":"https://api.github.com/users/bforma/orgs","repos_url":"https://api.github.com/users/bforma/repos","events_url":"https://api.github.com/users/bforma/events{/privacy}","received_events_url":"https://api.github.com/users/bforma/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bforma/robo-racer","description":"","fork":false,"url":"https://api.github.com/repos/bforma/robo-racer","forks_url":"https://api.github.com/repos/bforma/robo-racer/forks","keys_url":"https://api.github.com/repos/bforma/robo-racer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bforma/robo-racer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bforma/robo-racer/teams","hooks_url":"https://api.github.com/repos/bforma/robo-racer/hooks","issue_events_url":"https://api.github.com/repos/bforma/robo-racer/issues/events{/number}","events_url":"https://api.github.com/repos/bforma/robo-racer/events","assignees_url":"https://api.github.com/repos/bforma/robo-racer/assignees{/user}","branches_url":"https://api.github.com/repos/bforma/robo-racer/branches{/branch}","tags_url":"https://api.github.com/repos/bforma/robo-racer/tags","blobs_url":"https://api.github.com/repos/bforma/robo-racer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bforma/robo-racer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bforma/robo-racer/git/refs{/sha}","trees_url":"https://api.github.com/repos/bforma/robo-racer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bforma/robo-racer/statuses/{sha}","languages_url":"https://api.github.com/repos/bforma/robo-racer/languages","stargazers_url":"https://api.github.com/repos/bforma/robo-racer/stargazers","contributors_url":"https://api.github.com/repos/bforma/robo-racer/contributors","subscribers_url":"https://api.github.com/repos/bforma/robo-racer/subscribers","subscription_url":"https://api.github.com/repos/bforma/robo-racer/subscription","commits_url":"https://api.github.com/repos/bforma/robo-racer/commits{/sha}","git_commits_url":"https://api.github.com/repos/bforma/robo-racer/git/commits{/sha}","comments_url":"https://api.github.com/repos/bforma/robo-racer/comments{/number}","issue_comment_url":"https://api.github.com/repos/bforma/robo-racer/issues/comments{/number}","contents_url":"https://api.github.com/repos/bforma/robo-racer/contents/{+path}","compare_url":"https://api.github.com/repos/bforma/robo-racer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bforma/robo-racer/merges","archive_url":"https://api.github.com/repos/bforma/robo-racer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bforma/robo-racer/downloads","issues_url":"https://api.github.com/repos/bforma/robo-racer/issues{/number}","pulls_url":"https://api.github.com/repos/bforma/robo-racer/pulls{/number}","milestones_url":"https://api.github.com/repos/bforma/robo-racer/milestones{/number}","notifications_url":"https://api.github.com/repos/bforma/robo-racer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bforma/robo-racer/labels{/name}","releases_url":"https://api.github.com/repos/bforma/robo-racer/releases{/id}","created_at":"2014-06-07T06:56:39Z","updated_at":"2015-04-18T09:07:51Z","pushed_at":"2015-06-17T14:03:29Z","git_url":"git://github.com/bforma/robo-racer.git","ssh_url":"git@github.com:bforma/robo-racer.git","clone_url":"https://github.com/bforma/robo-racer.git","svn_url":"https://github.com/bforma/robo-racer","homepage":null,"size":2168,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/bforma/robo-racer/pulls/6"},"html":{"href":"https://github.com/bforma/robo-racer/pull/6"},"issue":{"href":"https://api.github.com/repos/bforma/robo-racer/issues/6"},"comments":{"href":"https://api.github.com/repos/bforma/robo-racer/issues/6/comments"},"review_comments":{"href":"https://api.github.com/repos/bforma/robo-racer/pulls/6/comments"},"review_comment":{"href":"https://api.github.com/repos/bforma/robo-racer/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/bforma/robo-racer/pulls/6/commits"},"statuses":{"href":"https://api.github.com/repos/bforma/robo-racer/statuses/41dbf5d27876a761964a23583ca441b3ca9ad8c5"}}}}