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

Zad 5 #133

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open

Zad 5 #133

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lecture_5/homework/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@

# Ignore master key for decrypting credentials and more.
/config/master.key

.DS_Store
2 changes: 2 additions & 0 deletions lecture_5/homework/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--require spec_helper
--format documentation
2 changes: 2 additions & 0 deletions lecture_5/homework/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ Style/Documentation:

Metrics/LineLength:
Max: 100

require: rubocop-rspec
5 changes: 5 additions & 0 deletions lecture_5/homework/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ gem 'bootsnap', '>= 1.1.0', require: false
# ActiveModel::Serializer implementation and Rails hooks
gem 'active_model_serializers'

gem 'rspec-rails'

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: %i[mri mingw x64_mingw]
gem 'rubocop-performance'
gem 'rubocop-rspec'
gem 'factory_bot'
end

group :development do
Expand Down
9 changes: 9 additions & 0 deletions lecture_5/homework/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ GEM
crass (1.0.4)
diff-lcs (1.3)
erubi (1.8.0)
factory_bot (5.0.2)
activesupport (>= 4.2.0)
ffi (1.10.0)
globalid (0.4.2)
activesupport (>= 4.2.0)
Expand Down Expand Up @@ -149,6 +151,10 @@ GEM
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 1.6)
rubocop-performance (1.0.0)
rubocop (>= 0.58.0)
rubocop-rspec (1.32.0)
rubocop (>= 0.60.0)
ruby-progressbar (1.10.0)
ruby_dep (1.5.0)
spring (2.0.2)
Expand Down Expand Up @@ -179,12 +185,15 @@ DEPENDENCIES
active_model_serializers
bootsnap (>= 1.1.0)
byebug
factory_bot
listen (>= 3.0.5, < 3.2)
pg
puma (~> 3.11)
rails (~> 5.2.2)
rspec-rails
rubocop
rubocop-performance
rubocop-rspec
spring
spring-watcher-listen (~> 2.0.0)
tzinfo-data
Expand Down
14 changes: 12 additions & 2 deletions lecture_5/homework/app/controllers/buildings_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
# frozen_string_literal: true

class BuildingsController < ApplicationController
def index; end
def index
render json: Building.all
end

def show; end
def show
render json: building, include: [:warriors]
end

private

def building
@building ||= Building.find(params[:id])
end
end
6 changes: 5 additions & 1 deletion lecture_5/homework/app/serializers/building_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# frozen_string_literal: true

class BuildingSerializer < ActiveModel::Serializer
attributes :name
attributes :name, :type, :granary, :siege_ability

has_many :warriors

def siege_ability
Reports::SiegeReport.new(building: object).call
end
end
21 changes: 20 additions & 1 deletion lecture_5/homework/app/services/reports/siege_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,29 @@
module Reports
class SiegeReport
def initialize(building:)
@building = building
end

def call
raise NotImprementedYet
calc_siege_ability
end

private

attr_reader :building

def calc_siege_ability
return 0 if @building.warriors.count.zero?
Copy link
Collaborator

Choose a reason for hiding this comment

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

To sprawdzenie spokojnie by się mogło znaleźć gdzieś wyżej, żeby nie obciążać logiki serwisu :) Serwis najlepiej jeśli ma jedną odpowiedzialność, a Twój serwis poza liczeniem ile dni przetrwa dany budynek, stwierdza upadłość budynku jeśli nie ma w nim wojowników :)


day_req = 10
@building.warriors.each do |warrior|
day_req += if warrior.type == 'Warriors::Hussar'
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ładniej by to chyba wyglądało, jeśli Warrior miałby zaimplementowaną metodę/atrybut np. supply_burn_rate, który zwraca 1 jeśli warrior nie ma konia i 2 jeśli go ma, wtedy nie trzeba by myśleć nad takimi ifami w tym serwisie :)

2
else
1
end
end
@building.granary / day_req
end
end
end
3 changes: 2 additions & 1 deletion lecture_5/homework/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2019_04_05_090544) do
ActiveRecord::Schema.define(version: 2019_04_14_111449) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand All @@ -20,6 +20,7 @@
t.string "type", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "granary", default: 0, null: false
end

create_table "clans", force: :cascade do |t|
Expand Down
9 changes: 9 additions & 0 deletions lecture_5/homework/spec/factories/buildings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

FactoryBot.define do
factory :building do
name { 'Black Gate' }
type { 'Buildings::Walls' }
granary { 0 }
end
end
7 changes: 7 additions & 0 deletions lecture_5/homework/spec/factories/clans.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

FactoryBot.define do
factory :clan do
name { 'Stary Oboz' }
end
end
15 changes: 15 additions & 0 deletions lecture_5/homework/spec/factories/warriors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

FactoryBot.define do
factory :warrior, class: 'Warrior' do
association(:building)
association(:clan)
name { 'Lee' }

factory :hussar, parent: :warrior, class: 'Warriors::Hussar' do
end

factory :samurai, parent: :warrior, class: 'Warriors::Samurai' do
end
end
end
63 changes: 63 additions & 0 deletions lecture_5/homework/spec/rails_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
end
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true

# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, :type => :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!

# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
end
56 changes: 56 additions & 0 deletions lecture_5/homework/spec/requests/buildings_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'Buildings API', type: :request do
describe 'GET /buildings' do
before { create_list(:building, 2) }

it 'responds with 200' do
get '/buildings'
expect(response).to have_http_status(200)
end

it 'includes correct number of records' do
get '/buildings'
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ten get też mógłby się znaleźć w before

response_json = JSON.parse(response.body)
expect(response_json['data'].size).to eq(2)
end
end

describe 'GET /buildings/:id' do
let(:building) do
create(:building,
name: building_name,
granary: building_granary)
end
let(:building_name) { 'Black Gate' }
let(:building_granary) { 100 }

it 'includes correct name' do
get "/buildings/#{building.id}"
response_json = JSON.parse(response.body)
expect(response_json.dig('data', 'attributes', 'name')).to eq(building_name)
end

it 'includes correct granary amount' do
get "/buildings/#{building.id}"
response_json = JSON.parse(response.body)
expect(response_json.dig('data', 'attributes', 'granary')).to eq(building_granary)
end

it 'responds with 200' do
get "/buildings/#{building.id}"
expect(response).to have_http_status(200)
end

context 'when destroy building' do
before { building.destroy }

it 'responds with 404' do
get "/buildings/#{building.id}"
expect(response).to have_http_status(404)
end
end
end
end
68 changes: 68 additions & 0 deletions lecture_5/homework/spec/services/siege_report_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

require 'rails_helper'

describe Reports::SiegeReport do
subject(:siege_report) { described_class.new(building: building) }

let(:building) do
create(:building,
name: building_name,
granary: building_granary)
end
let(:building_name) { 'Black Gate' }

describe '#call' do
context 'without granary' do
let(:building_granary) { 0 }

it 'returns 0' do
expect(siege_report.call).to eq(0)
end
end

context 'without warriors' do
let(:building_granary) { 11 }

it 'returns 0' do
expect(siege_report.call).to eq(0)
end
end

context 'with one infantry' do
let(:warrior) { build(:samurai) }
let(:building_granary) { 11 }

it 'returns 1' do
warrior.building = building
warrior.save
expect(siege_report.call).to eq(1)
end
end

context 'with one cavalry' do
let(:warrior) { build(:hussar) }
let(:building_granary) { 12 }

it 'returns 1' do
warrior.building = building
warrior.save
expect(siege_report.call).to eq(1)
end
end

context 'with one infantry and one cavalry' do
let(:warrior1) { build(:samurai, name: 'Lee') }
let(:warrior2) { build(:hussar) }
let(:building_granary) { 12 }

it 'returns 1' do
warrior1.building = building
warrior1.save
warrior2.building = building
warrior2.save
expect(siege_report.call).to eq(1)
end
end
end
end
Loading