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 #146

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions lecture_5/homework/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require spec_helper
3 changes: 3 additions & 0 deletions lecture_5/homework/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ gem 'active_model_serializers'

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

group :development do
Expand Down
10 changes: 10 additions & 0 deletions lecture_5/homework/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ GEM
tzinfo (~> 1.1)
arel (9.0.0)
ast (2.4.0)
awesome_print (1.8.0)
bootsnap (1.4.1)
msgpack (~> 1.0)
builder (3.2.3)
Expand All @@ -57,8 +58,14 @@ GEM
activesupport
concurrent-ruby (1.1.5)
crass (1.0.4)
database_cleaner (1.7.0)
diff-lcs (1.3)
erubi (1.8.0)
factory_bot (5.0.2)
activesupport (>= 4.2.0)
factory_bot_rails (5.0.2)
factory_bot (~> 5.0.2)
railties (>= 4.2.0)
ffi (1.10.0)
globalid (0.4.2)
activesupport (>= 4.2.0)
Expand Down Expand Up @@ -177,8 +184,11 @@ PLATFORMS

DEPENDENCIES
active_model_serializers
awesome_print
bootsnap (>= 1.1.0)
byebug
database_cleaner
factory_bot_rails
listen (>= 3.0.5, < 3.2)
pg
puma (~> 3.11)
Expand Down
22 changes: 20 additions & 2 deletions lecture_5/homework/app/controllers/buildings_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
# frozen_string_literal: true

class BuildingsController < ApplicationController
def index; end
def index
render json: buildings, status: 200
end

def show; end
def show
render json: building
end

private

def buildings
@buildings ||= fetch_buildings.present? ? fetch_buildings : NoBuildings.new.buildings
end

def fetch_buildings
BuildingsQueries.buildings(relation: Building)
end

def building
@building ||= BuildingsQueries.building(relation: Building, id: params[:id])
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def index
warriors = clan.warriors

if params.key?(:alive)
if params[:alive].to_i == 0
if params[:alive].to_i.zero?
render json: warriors.dead
else
render json: warriors.alive
Expand Down
7 changes: 7 additions & 0 deletions lecture_5/homework/app/nulls/no_buildings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class NoBuildings
def buildings
{ message: 'There are no buildings' }
end
end
19 changes: 19 additions & 0 deletions lecture_5/homework/app/queries/buildings_queries.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class BuildingsQueries
def self.buildings(relation:)
relation.includes(:warriors).all
end

def self.building(relation:, id:)
relation.find(id)
end

def self.count_warriors_of_specified_type(relation:, building:, type:)
relation.find(building.id).warriors.where(type: type).count
end

def self.update_siege_ability(relation:, building:, result:)
relation.find(building.id).update(siege_ability: result)
end
end
2 changes: 1 addition & 1 deletion lecture_5/homework/app/serializers/building_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

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

has_many :warriors
end
61 changes: 60 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,69 @@
module Reports
class SiegeReport
def initialize(building:)
@building = building
end

def call
raise NotImprementedYet
no_army? ? no_siege_ability : compute_siege_ability
end

private

def no_army?
@building.warriors.empty?
end

def no_siege_ability
save_siege_report_result(0)
@building.siege_ability = 0
end

def compute_siege_ability
daily_food_demand = compute_daily_food_demand
result = siege_ability(daily_food_demand)
save_siege_report_result(result)
end

def compute_daily_food_demand
stronghold_staff + hussars + samurais
end

def stronghold_staff
10
end

def hussars
BuildingsQueries.count_warriors_of_specified_type(
relation: Building,
building: @building,
type: 'Warriors::Hussar'
) * 2
end

def samurais
BuildingsQueries.count_warriors_of_specified_type(
relation: Building,
building: @building,
type: 'Warriors::Samurai'
)
end

def siege_ability(daily_food_demand)
granary / daily_food_demand
end

def granary
@building.granary
end

def save_siege_report_result(result)
BuildingsQueries.update_siege_ability(
relation: Building,
building: @building,
result: result
)
@building.siege_ability = result
end
end
end
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true

ActiveModelSerializers.config.adapter = :json_api
ActiveModel::Serializer.config.key_transform = :underscore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddSiegeAbilityToBuildings < ActiveRecord::Migration[5.2]
def change
add_column :buildings, :siege_ability, :integer
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class ComputeSiegeAbilitiesOfBuildings < ActiveRecord::Migration[5.2]
def change
Building.find_each do |building|
Reports::SiegeReport.new(building: building).call
end
end
end
4 changes: 3 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_28_121458) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand All @@ -20,6 +20,8 @@
t.string "type", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "granary", default: 0, null: false
t.integer "siege_ability"
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, class: Building do
sequence(:name) { |i| "Building_#{i}" }
sequence(:type) { |i| "Buildings::#{i.even? ? 'Walls' : 'Stronghold'}" }
granary { 100 }
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, class: Clan do
sequence(:name) { |i| "Clan number #{i}" }
end
end
23 changes: 23 additions & 0 deletions lecture_5/homework/spec/factories/warriors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

FactoryBot.define do
factory :warrior, class: Warrior do
association(:clan)
association(:building)
sequence(:type) { |i| i.even? ? 'Warriors::Hussar' : 'Warriors::Samurai' }
sequence(:name) { |i| "Warrior #{i}" }
preferred_weapon_kind { 'melee' }
armor_quality { 0 }
number_of_battles { 0 }
join_date { Time.now }
death_date { nil }

trait :hussar do
type { 'Warriors::Hussar' }
end

trait :samurai do
type { 'Warriors::Samurai' }
end
end
end
69 changes: 69 additions & 0 deletions lecture_5/homework/spec/rails_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 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"

config.include FactoryBot::Syntax::Methods

# 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")

config.before(:example) do
DatabaseCleaner.clean_with(:truncation)
end
end
Loading