Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stevie Spiegl RPS #2115

Open
wants to merge 62 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
4359d10
first commit
S-Spiegl May 7, 2022
1a24ee3
added app.rb and testing_infrastructure_spec
S-Spiegl May 7, 2022
cea74c9
commit check
S-Spiegl May 7, 2022
43edfb8
added play.erb
S-Spiegl May 7, 2022
e071a99
added Player model, '/play' route, and redirected '/name'
S-Spiegl May 7, 2022
392b36c
added play_game_spec and tests
S-Spiegl May 7, 2022
b136975
the model and controller are on speaking terms
S-Spiegl May 7, 2022
3be0405
game works. needs more tests
S-Spiegl May 7, 2022
0736433
some refactoring, several tests still need writing
S-Spiegl May 7, 2022
8bfb302
replaced buttons with images and updated tests accordingly
S-Spiegl May 7, 2022
23d4805
added capybara tests for various outcomes
S-Spiegl May 8, 2022
c1a4456
added background image for results screen
S-Spiegl May 8, 2022
0a48d3e
getting new errors
S-Spiegl May 8, 2022
af14b6c
come back here for comments/questions
S-Spiegl May 8, 2022
7fc16b4
refactored controller, took out comments
S-Spiegl May 8, 2022
f0c7b17
committing before changing computers
Jun 5, 2022
6ced6bc
Update README.md
S-Spiegl Jul 20, 2022
598460d
Update README.md
S-Spiegl Jul 20, 2022
d7f237f
Update README.md
S-Spiegl Jul 20, 2022
b331630
moved styling to stylesheet
S-Spiegl Aug 4, 2022
0162508
Merge branch 'main' of https://github.com/S-Spiegl/rps-challenge
S-Spiegl Aug 4, 2022
737ec52
set images as row, moved more logic to css
S-Spiegl Aug 4, 2022
e8cacd9
tidied up css for all views
S-Spiegl Aug 4, 2022
82d354a
finished tidying up css
S-Spiegl Aug 4, 2022
06a966c
Update README.md
S-Spiegl Aug 4, 2022
633c77b
added movies
S-Spiegl Aug 4, 2022
ddb2463
Merge branch 'main' of https://github.com/S-Spiegl/rps-challenge
S-Spiegl Aug 4, 2022
5dcf235
set up databases
S-Spiegl Aug 4, 2022
c5a6c4f
database accepting booleans for each go to represent wins, draws and …
S-Spiegl Aug 4, 2022
bb949f7
incrementing won, drew, lost columns in postgres
S-Spiegl Aug 4, 2022
9d44f07
renamed game to round;
S-Spiegl Aug 4, 2022
88bf62a
keeps track of score and prints to screen
S-Spiegl Aug 5, 2022
1353f7a
about to branch off for deployment
S-Spiegl Aug 5, 2022
dae923e
still undeployed
S-Spiegl Aug 5, 2022
6f8e164
Update README.md
S-Spiegl Aug 6, 2022
177486c
switched to improving tests branch
S-Spiegl Aug 6, 2022
1c2215f
mocking for round_spec passing
S-Spiegl Aug 6, 2022
06e98e2
tidied up round_spec
S-Spiegl Aug 6, 2022
f3b1de1
tests working
S-Spiegl Aug 6, 2022
1cb42bb
Merge pull request #1 from S-Spiegl/improving-tests
S-Spiegl Aug 6, 2022
d143894
merged
S-Spiegl Aug 6, 2022
da77118
set up test database
S-Spiegl Aug 6, 2022
db0dba3
added procfile
S-Spiegl Aug 7, 2022
2eab430
updated gemfile
S-Spiegl Aug 7, 2022
63b1b62
updated gemfile again
S-Spiegl Aug 7, 2022
2d23f71
testing if PG is the issue
S-Spiegl Aug 7, 2022
508234a
testing if PG is the issue
S-Spiegl Aug 7, 2022
a74ace6
fixing PG
S-Spiegl Aug 7, 2022
66baab1
fixing PG still
S-Spiegl Aug 7, 2022
64d1602
fixing PG still
S-Spiegl Aug 7, 2022
a34292f
fixing PG still
S-Spiegl Aug 7, 2022
10ba08e
fixing PG still
S-Spiegl Aug 7, 2022
b7773b9
fixing PG still
S-Spiegl Aug 7, 2022
1a95f63
fixing PG still
S-Spiegl Aug 7, 2022
72c4d4f
fixing PG still
S-Spiegl Aug 7, 2022
63bb33e
fixing PG still
S-Spiegl Aug 7, 2022
cebb680
still trying to establish connection
S-Spiegl Aug 7, 2022
852c43f
still trying to establish connection
S-Spiegl Aug 8, 2022
c252626
got PG working by transferring some of the logic into the round.rb, b…
S-Spiegl Aug 8, 2022
0401afd
successfully deployed. Now need to edit table functionality
S-Spiegl Aug 8, 2022
e0db0da
Update README.md
S-Spiegl Aug 8, 2022
2d98a80
Update README.md
S-Spiegl Aug 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Expand Up @@ -3,6 +3,8 @@ source 'https://rubygems.org'
ruby '3.0.2'

gem 'sinatra'
gem 'sinatra-contrib'
gem 'webrick'

group :test do
gem 'capybara'
Expand Down
10 changes: 10 additions & 0 deletions Gemfile.lock
Expand Up @@ -17,6 +17,7 @@ GEM
docile (1.4.0)
mini_mime (1.1.1)
mini_portile2 (2.6.1)
multi_json (1.15.0)
mustermann (1.1.1)
ruby2_keywords (~> 0.0.1)
nokogiri (1.12.3)
Expand Down Expand Up @@ -76,10 +77,17 @@ GEM
rack (~> 2.2)
rack-protection (= 2.1.0)
tilt (~> 2.0)
sinatra-contrib (2.1.0)
multi_json
mustermann (~> 1.0)
rack-protection (= 2.1.0)
sinatra (= 2.1.0)
tilt (~> 2.0)
terminal-table (3.0.1)
unicode-display_width (>= 1.1.1, < 3)
tilt (2.0.10)
unicode-display_width (2.0.0)
webrick (1.7.0)
xpath (3.2.0)
nokogiri (~> 1.8)

Expand All @@ -93,6 +101,8 @@ DEPENDENCIES
simplecov
simplecov-console
sinatra
sinatra-contrib
webrick

RUBY VERSION
ruby 3.0.2p107
Expand Down
42 changes: 42 additions & 0 deletions app.rb
@@ -0,0 +1,42 @@
require 'sinatra/base'
require 'sinatra/reloader'
require './lib/player'
require './lib/game'

class RockPaperScissors < Sinatra::Base
configure :development do
register Sinatra::Reloader
end

enable :sessions

get '/' do
erb :form
end

post '/play' do
session[:player] = params[:player]
$player = Player.new(params[:player])
@player_name = $player.name
erb :play
end

post '/play_again' do
session[:player] = params[:player]
$player = Player.new(params[:player])
@player_name = $player.name
erb :play_again
end

post '/battle' do
@player = $player
@player_weapon = @player.select_weapon(params[:player_choice])
game = Game.new(@player_weapon)
@message = game.engine
@computer_weapon = game.computer_weapon
erb :battle
end

# Start the server if this file is executed directly (don't change the line below)
run! if app_file == $0
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great file, concise, good use of class names and instance and global variables

2 changes: 2 additions & 0 deletions config.ru
@@ -0,0 +1,2 @@
require_relative 'app'
run RockPaperScissors
8 changes: 8 additions & 0 deletions lib/computer.rb
@@ -0,0 +1,8 @@
require_relative 'game'

class Computer
def weapon
Game::WEAPONS.sample
# syntax for referring to a constant in another class
end
end
31 changes: 31 additions & 0 deletions lib/game.rb
@@ -0,0 +1,31 @@
require_relative 'computer'

class Game

WEAPONS = [:rock, :paper, :scissors]
attr_reader :player, :engine, :computer_weapon, :computer, :player_weapon

def initialize(player_weapon, computer = Computer.new)
@player_weapon = player_weapon.to_sym
@computer = computer
@computer_weapon = computer.weapon
end

def engine
if @player_weapon == @computer_weapon
"draw"
elsif @player_weapon == :rock && @computer_weapon == :scissors
"You chose wisely."
elsif @player_weapon == :rock && @computer_weapon == :paper
"You did not choose wisely."
elsif @player_weapon == :scissors && @computer_weapon == :paper
"You chose wisely."
elsif @player_weapon == :scissors && @computer_weapon == :rock
"You did not choose wisely."
elsif @player_weapon == :paper && @computer_weapon == :rock
"You chose wisely."
elsif @player_weapon == :paper && @computer_weapon == :scissors
"You did not choose wisely."
end
end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to see the creation of a WEAPONS constant in this file. Could the engine method be refactored to reduce repetition - perhaps the use of a hash?

end
13 changes: 13 additions & 0 deletions lib/player.rb
@@ -0,0 +1,13 @@
class Player

attr_reader :name, :weapon

def initialize(name)
@name = name
end

def select_weapon(weapon)
@weapon = weapon
end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the WEAPONS constant be used in this file too?

end
23 changes: 23 additions & 0 deletions spec/computer_spec.rb
@@ -0,0 +1,23 @@
require 'computer'

describe Computer do
it 'can choose rock' do
dbl_cpu = double("rock")
allow(dbl_cpu).to receive(:weapon).and_return(:rock)
srand(2)
expect(subject.weapon).to eq(:rock)
end

it 'can choose paper' do
dbl_cpu = double("paper")
allow(dbl_cpu).to receive(:weapon).and_return(:paper)
srand(1)
expect(subject.weapon).to eq(:paper)
end
it 'can choose scissors' do
dbl_cpu = double("scissors")
allow(dbl_cpu).to receive(:weapon).and_return(:scissors)
srand(3)
expect(subject.weapon).to eq(:scissors)
end
end
24 changes: 24 additions & 0 deletions spec/features/enter_names_spec.rb
@@ -0,0 +1,24 @@
require 'capybara/rspec'
require_relative '../../app'

Capybara.app = RockPaperScissors

feature 'allows player to enter their name' do
scenario 'player is able to enter their name' do
visit('/')
expect(page).to have_field('player')
expect(page).to have_button('Submit name')
end

scenario 'player is taken to a new page to start the game' do
sign_in
expect(current_path).to eq('/play')
end

scenario 'player can see their name on the play page' do
sign_in
expect(current_path).to eq('/play')
expect(page).to have_content('Alien')
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clear, concise, good indentation


end
47 changes: 47 additions & 0 deletions spec/features/play_game_spec.rb
@@ -0,0 +1,47 @@
require 'capybara/rspec'
require_relative '../../app'

Capybara.app = RockPaperScissors

feature 'allows player to play a game of RockPaperScissors' do
scenario 'the player can choose from three buttons' do
sign_in
expect(page).to have_xpath('/html/body/form[1]/input[1]')
expect(page).to have_xpath('/html/body/form[2]/input[1]')
expect(page).to have_xpath('/html/body/div/form/input[1]')
end

scenario 'a player can return to the play screen to have another go' do
sign_in
click_on(id='rock')
expect(page).to have_button('Have another go?')
end


scenario 'clicking a button takes the player to the winner page' do
sign_in
click_on(id='rock')
expect(current_path).to eq '/battle'
end

scenario 'rock beats scissors' do
allow_any_instance_of(Computer).to receive(:weapon).and_return(:scissors)
sign_in
click_on(id='rock')
expect(page).to have_content "You chose wisely."
end

scenario 'paper beats rock' do
allow_any_instance_of(Computer).to receive(:weapon).and_return(:paper)
sign_in
click_on(id='rock')
expect(page).to have_content "You did not choose wisely."
end

scenario 'scissors beats paper' do
allow_any_instance_of(Computer).to receive(:weapon).and_return(:paper)
sign_in
click_on(id='scissors')
expect(page).to have_content "You chose wisely."
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really clear test scenarios, really enjoyed reading these if I'm honest. Good takeaway for my tests in the future, thank you!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, good testing, well done for using stubs effectively here

end
12 changes: 12 additions & 0 deletions spec/features/testing_infrastructure_spec.rb
@@ -0,0 +1,12 @@
require 'capybara/rspec'
require_relative '../../app'

Capybara.app = RockPaperScissors

feature 'confirms that the testing infrastructure is working' do
scenario 'the home page returns a successful status code' do
visit('/')
expect(page.status_code).to eq(200)
end

end
5 changes: 5 additions & 0 deletions spec/features/web_helpers.rb
@@ -0,0 +1,5 @@
def sign_in
visit('/')
fill_in 'player', with: 'Alien'
click_on('Submit name!')
end
4 changes: 4 additions & 0 deletions spec/game_spec.rb
@@ -0,0 +1,4 @@
require 'game'

describe Game do
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty file? I think you left the spec for this somewhere else? Then maybe you could delete this file

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it would be good to consider what you might have tested in here if you had the time - you could even comment some ideas and come back to it at a later stage when you want to make improvements, especially the logic in Game is an important one.

8 changes: 8 additions & 0 deletions spec/player_spec.rb
@@ -0,0 +1,8 @@
require 'player'

describe Player do
let(:player) { described_class.new('Clodius') }
it "should return player's name" do
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

much better indentation here. Clear class names and tests. Nice one man!

expect(player.name).to eq('Clodius')
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
@@ -1,6 +1,7 @@
require 'capybara/rspec'
require 'simplecov'
require 'simplecov-console'
require './spec/features/web_helpers'

SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::Console,
Expand Down
22 changes: 22 additions & 0 deletions views/battle.erb
@@ -0,0 +1,22 @@
<style>
body {
<!-- margin: 0 auto; -->
text-align: center;
width: 100vw;
background-image: url("https://source.unsplash.com/h4elZPxUXLU");
background-attachment: fixed;
background-repeat: no-repeat;
background-size: 100vw;
}
h1 {font-family: arial;
text-align: center;}
</style>
<body>

<h1>You chose <%= @player_weapon %>...<br></h1>
<h1>Computer chose <%= @computer_weapon %>...<br><h1>
<h1><%= @message %><h1>
<form action='/play_again' method='post'>
<button type="submit" style="padding: 5px 10px">Have another go?</button>
</form>
</body>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same again. Takes maybe a day or two to write the code, but people would have to read it an unspecified amount of time

15 changes: 15 additions & 0 deletions views/form.erb
@@ -0,0 +1,15 @@
<style> form {
text-align: center;
font-family: arial;
padding-bottom: 10px;
}
input {border-radius: 7px;}
button {border-radius: 7px;}
h1 {text-align: center; font-family: arial; padding-top: 20px}
</style>

<h1>Enter Name</h1>
<form action='/play' method='post'>
<input type="text" name="player" style="padding: 5px 15px"><br><br>
<button type="submit" style="padding: 5px 10px">Submit name!</button>
</form>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation.. naughty naughty!

Empty file added views/name.erb
Empty file.
31 changes: 31 additions & 0 deletions views/play.erb
@@ -0,0 +1,31 @@
<html>
<head>
<style>
h1 {text-align: center; font-family: arial; margin: 0}
h2 {text-align: center; font-family: arial;}
div {text-align: center;}
form {text-align: center;}
form:hover {opacity: 0.7;}
</style>
</head>
<body>

<h1>Welcome, <%= @player_name %></h1><br>
<h2>Choose wisely.</h2>
<form action='/battle' method='post'>
<input type='image' src='https://source.unsplash.com/QxjEi8Fs9Hg' width='400'
border='2' name='player_choice' type='submit' id='rock'></>
<input type="hidden" name="player_choice" value="rock" />
</form>
<form action='/battle' method='post'>
<input type='image' src='https://source.unsplash.com/RyrFRsVoe2Q' width='400'
border='2' name='player_choice' type='submit' id='paper'></>
<input type="hidden" name="player_choice" value="paper" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to indent everything! Makes it easier to read for others ;) Maybe even have blank lines between the parts that don't relate i.e. After each form to show where one stops and the other starts (this is only when you know a code review will be done)

</form>
<div style="margin: 0px auto; width: 400; height: 267; overflow: hidden; border: 2px solid black">
<form action='/battle' method='post'>
<input type='image' src='https://source.unsplash.com/c18q3myyHLU' width='400'
name='player_choice' type='submit' id='scissors'></>
<input type="hidden" name="player_choice" value="scissors" />
</form>
</div>
34 changes: 34 additions & 0 deletions views/play_again.erb
@@ -0,0 +1,34 @@
<html>
<head>
<style>
h1 {text-align: center; font-family: arial}
h2 {text-align: center; font-family: arial}
h3 {text-align: center; font-family: arial}
div {text-align: center;}
form {text-align: center;}
form:hover {opacity: 0.7;}
</style>
</head>
<body>

<h3>Insanity is doing the same thing over and over again and expecting a different result.</h3>
<h3>Except when it comes to rock, paper, scissors.</h3>
<h3>Choose wisely.</h3>
<form action='/battle' method='post'>
<input type='image' src='https://source.unsplash.com/QxjEi8Fs9Hg' width='400'
border='2' name='player_choice' type='submit' id='rock'></>
<input type="hidden" name="player_choice" value="rock" />
</form>
<form action='/battle' method='post'>
<input type='image' src='https://source.unsplash.com/RyrFRsVoe2Q' width='400'
border='2' name='player_choice' type='submit' id='paper'></>
<input type="hidden" name="player_choice" value="paper" />
</form>
<div style="margin: 0px auto; width: 400; height: 267; overflow: hidden; border: 2px solid black">
<!-- margin: 0px auto saved me here, nothing else would center the div -->
<form action='/battle' method='post'>
<input type='image' src='https://source.unsplash.com/c18q3myyHLU' width='400'
name='player_choice' type='submit' id='scissors'></>
<input type="hidden" name="player_choice" value="scissors" />
</form>
</div>