1
0

Apply linting rules

This commit is contained in:
Tim Kächele 2024-08-25 09:23:52 +02:00
parent 056a9d1a11
commit bf84952f56
28 changed files with 249 additions and 251 deletions

12
Gemfile
View File

@ -1,12 +1,12 @@
# frozen_string_literal: true # frozen_string_literal: true
source 'https://rubygems.org' source "https://rubygems.org"
# Specify your gem's dependencies in planet_express.gemspec # Specify your gem's dependencies in planet_express.gemspec
gemspec gemspec
gem 'rake' gem "rake"
gem 'rspec' gem "rspec"
gem 'factory_bot' gem "factory_bot"
gem 'standard' gem "standard"
gem 'simplecov' gem "simplecov"

View File

@ -1,15 +1,15 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'bundler/gem_tasks' require "bundler/gem_tasks"
require 'rspec/core/rake_task' require "rspec/core/rake_task"
require 'planet_express' require "planet_express"
RSpec::Core::RakeTask.new(:spec) RSpec::Core::RakeTask.new(:spec)
task default: :spec task default: :spec
task :process, [:input_file] do |_t, args| task :process, [:input_file] do |_t, args|
file = File.open(args.input_file, 'r') file = File.open(args.input_file, "r")
shipping_option_repository = PlanetExpress::ShippingOptionRepository.new shipping_option_repository = PlanetExpress::ShippingOptionRepository.new
shipment_repository = PlanetExpress::ShipmentRepository.new(data: []) shipment_repository = PlanetExpress::ShipmentRepository.new(data: [])

View File

@ -1,28 +1,28 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'planet_express/date' require "planet_express/date"
require 'planet_express/version' require "planet_express/version"
require 'planet_express/repository' require "planet_express/repository"
require 'planet_express/discounts/discount' require "planet_express/discounts/discount"
require 'planet_express/discounts/discount_budget' require "planet_express/discounts/discount_budget"
require 'planet_express/discounts/discount_budget_for_month_repository' require "planet_express/discounts/discount_budget_for_month_repository"
require 'planet_express/shipments/invalid_shipment' require "planet_express/shipments/invalid_shipment"
require 'planet_express/shipments/shipment' require "planet_express/shipments/shipment"
require 'planet_express/shipments/shipment_repository' require "planet_express/shipments/shipment_repository"
require 'planet_express/shipments/shipment_reader' require "planet_express/shipments/shipment_reader"
require 'planet_express/shipments/shipment_formatter' require "planet_express/shipments/shipment_formatter"
require 'planet_express/shipping_options/shipping_option' require "planet_express/shipping_options/shipping_option"
require 'planet_express/shipping_options/shipping_option_repository' require "planet_express/shipping_options/shipping_option_repository"
require 'planet_express/rules/rule' require "planet_express/rules/rule"
require 'planet_express/rules/s_shipment_discount_rule' require "planet_express/rules/s_shipment_discount_rule"
require 'planet_express/rules/l_shipment_discount_rule' require "planet_express/rules/l_shipment_discount_rule"
require 'planet_express/shipment_discount_calculator' require "planet_express/shipment_discount_calculator"
module PlanetExpress module PlanetExpress
end end

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'date' require "date"
# Nasty monkey patching to make date objects know about the beginning of a month # Nasty monkey patching to make date objects know about the beginning of a month
class Date class Date

View File

@ -14,8 +14,8 @@ module PlanetExpress
data data
end end
def each(&block) def each(&)
data.each(&block) data.each(&)
end end
def add(item) def add(item)

View File

@ -30,7 +30,7 @@ module PlanetExpress
month = shipment.month month = shipment.month
count = shipment_repository.l_shipment_count_for_provider_and_month(provider, count = shipment_repository.l_shipment_count_for_provider_and_month(provider,
month) month)
count == 2 count == 2
end end

View File

@ -3,12 +3,12 @@
module PlanetExpress module PlanetExpress
class Rule class Rule
attr_reader :discount_budget_for_month_repository, attr_reader :discount_budget_for_month_repository,
:shipping_option_repository, :shipping_option_repository,
:shipment_repository :shipment_repository
def initialize(discount_budget_for_month_repository:, def initialize(discount_budget_for_month_repository:,
shipping_option_repository:, shipping_option_repository:,
shipment_repository:) shipment_repository:)
@discount_budget_for_month_repository = discount_budget_for_month_repository @discount_budget_for_month_repository = discount_budget_for_month_repository
@shipping_option_repository = shipping_option_repository @shipping_option_repository = shipping_option_repository
@shipment_repository = shipment_repository @shipment_repository = shipment_repository

View File

@ -5,7 +5,7 @@ module PlanetExpress
attr_reader :shipment_repository, :rules attr_reader :shipment_repository, :rules
def initialize(shipment_repository:, def initialize(shipment_repository:,
rules:) rules:)
@shipment_repository = shipment_repository @shipment_repository = shipment_repository
@rules = rules @rules = rules
end end

View File

@ -21,11 +21,11 @@ module PlanetExpress
price = shipment.price_with_discounts price = shipment.price_with_discounts
discount = shipment.total_discount_amount discount = shipment.total_discount_amount
"#{date} #{package_size} #{provider} #{format_money(price)} #{discount.zero? ? '-' : format_money(discount)}" "#{date} #{package_size} #{provider} #{format_money(price)} #{discount.zero? ? "-" : format_money(discount)}"
end end
def format_money(amount) def format_money(amount)
amount.to_s.rjust(3, '0').insert(-3, '.') amount.to_s.rjust(3, "0").insert(-3, ".")
end end
end end
end end

View File

@ -18,7 +18,7 @@ module PlanetExpress
shipping_option = find_shipping_option(row) shipping_option = find_shipping_option(row)
if date.nil? || shipping_option.nil? if date.nil? || shipping_option.nil?
yield InvalidShipment.new(row.join(' ')) yield InvalidShipment.new(row.join(" "))
else else
yield Shipment.new(date, shipping_option) yield Shipment.new(date, shipping_option)
end end

View File

@ -3,15 +3,15 @@
module PlanetExpress module PlanetExpress
ShippingOption = Struct.new(:provider, :package_size, :price_in_cents) do ShippingOption = Struct.new(:provider, :package_size, :price_in_cents) do
def s_shipment? def s_shipment?
package_size == 'S' package_size == "S"
end end
def l_shipment? def l_shipment?
package_size == 'L' package_size == "L"
end end
def lp_provider? def lp_provider?
provider == 'LP' provider == "LP"
end end
def inspect def inspect

View File

@ -24,12 +24,12 @@ module PlanetExpress
def default_data def default_data
[ [
ShippingOption.new('LP', 'S', 150), ShippingOption.new("LP", "S", 150),
ShippingOption.new('LP', 'M', 490), ShippingOption.new("LP", "M", 490),
ShippingOption.new('LP', 'L', 690), ShippingOption.new("LP", "L", 690),
ShippingOption.new('MR', 'S', 200), ShippingOption.new("MR", "S", 200),
ShippingOption.new('MR', 'M', 300), ShippingOption.new("MR", "M", 300),
ShippingOption.new('MR', 'L', 400) ShippingOption.new("MR", "L", 400)
] ]
end end
@ -43,12 +43,12 @@ module PlanetExpress
available_package_sizes = data.map { |option| option.package_size }.uniq available_package_sizes = data.map { |option| option.package_size }.uniq
lowest_price_per_option_tuples = available_package_sizes.map do |package_size| lowest_price_per_option_tuples = available_package_sizes.map do |package_size|
option = data.select { |option| option.package_size == package_size } option = data.select { |option| option.package_size == package_size }
.min_by { |option| option.price_in_cents } .min_by { |option| option.price_in_cents }
[option.package_size, option.price_in_cents] [option.package_size, option.price_in_cents]
end end
@lowest_price_lookup_table = Hash[lowest_price_per_option_tuples] @lowest_price_lookup_table = lowest_price_per_option_tuples.to_h
end end
end end
end end

View File

@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
module PlanetExpress module PlanetExpress
VERSION = '0.1.0' VERSION = "0.1.0"
end end

View File

@ -1,22 +1,22 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'lib/planet_express/version' require_relative "lib/planet_express/version"
Gem::Specification.new do |spec| Gem::Specification.new do |spec|
spec.name = 'planet_express' spec.name = "planet_express"
spec.version = PlanetExpress::VERSION spec.version = PlanetExpress::VERSION
spec.authors = ['Tim Kächele'] spec.authors = ["Tim Kächele"]
spec.email = ['mail@timkaechele.me'] spec.email = ["mail@timkaechele.me"]
spec.summary = 'Calculate your shipment discounts easily' spec.summary = "Calculate your shipment discounts easily"
spec.description = 'A library to calculate the applicable shipment discounts for a list of shipments.' spec.description = "A library to calculate the applicable shipment discounts for a list of shipments."
spec.homepage = 'https://git.timkaechele.me/timkaechele/planet_express' spec.homepage = "https://git.timkaechele.me/timkaechele/planet_express"
spec.license = 'MIT' spec.license = "MIT"
spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0') spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
spec.metadata["allowed_push_host"] = "https://git.timkaechele.me/api/packages/timkaechele/rubygems" spec.metadata["allowed_push_host"] = "https://git.timkaechele.me/api/packages/timkaechele/rubygems"
spec.metadata['homepage_uri'] = spec.homepage spec.metadata["homepage_uri"] = spec.homepage
# spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here." # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
@ -25,9 +25,7 @@ Gem::Specification.new do |spec|
spec.files = Dir.chdir(File.expand_path(__dir__)) do spec.files = Dir.chdir(File.expand_path(__dir__)) do
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end end
spec.bindir = 'exe' spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib'] spec.require_paths = ["lib"]
end end

View File

@ -5,15 +5,15 @@ RSpec.describe PlanetExpress::DiscountBudgetForMonthRepository do
let(:march_date_a) { Date.new(2021, 3, 6) } let(:march_date_a) { Date.new(2021, 3, 6) }
let(:march_date_b) { Date.new(2021, 3, 6) } let(:march_date_b) { Date.new(2021, 3, 6) }
describe '#for_month' do describe "#for_month" do
it 'returns the same discount budget for the same month' do it "returns the same discount budget for the same month" do
expect(subject.for_month(march_date_a).object_id).to( expect(subject.for_month(march_date_a).object_id).to(
eq(subject.for_month(march_date_b).object_id) eq(subject.for_month(march_date_b).object_id)
) )
end end
context 'not yet initialized month' do context "not yet initialized month" do
it 'returns a discount budget' do it "returns a discount budget" do
result = subject.for_month(march_date_a) result = subject.for_month(march_date_a)
expect(result).to be_an_instance_of(PlanetExpress::DiscountBudget) expect(result).to be_an_instance_of(PlanetExpress::DiscountBudget)
@ -21,12 +21,12 @@ RSpec.describe PlanetExpress::DiscountBudgetForMonthRepository do
end end
end end
context 'other month' do context "other month" do
let(:april_date) { Date.new(2021, 4, 12) } let(:april_date) { Date.new(2021, 4, 12) }
it 'returns a different discount budget' do it "returns a different discount budget" do
expect(subject.for_month(march_date_a).object_id).to_not(eq( expect(subject.for_month(march_date_a).object_id).to_not(eq(
subject.for_month(april_date).object_id subject.for_month(april_date).object_id
)) ))
end end
end end
end end

View File

@ -4,17 +4,17 @@ RSpec.describe PlanetExpress::DiscountBudget do
let(:budget) { 500 } let(:budget) { 500 }
subject { described_class.new(budget: budget) } subject { described_class.new(budget: budget) }
describe '#register_applied_discount' do describe "#register_applied_discount" do
context 'with sufficient remaining budget' do context "with sufficient remaining budget" do
it 'returns the full discount' do it "returns the full discount" do
expect(subject.register_applied_discount(120)).to eq(120) expect(subject.register_applied_discount(120)).to eq(120)
expect(subject.available_budget).to eq(380) expect(subject.available_budget).to eq(380)
expect(subject.remaining_budget?).to eq(true) expect(subject.remaining_budget?).to eq(true)
end end
end end
context 'with insufficient remaining budget' do context "with insufficient remaining budget" do
it 'returns only the remaining budget' do it "returns only the remaining budget" do
expect(subject.register_applied_discount(650)).to eq(500) expect(subject.register_applied_discount(650)).to eq(500)
expect(subject.available_budget).to eq(0) expect(subject.available_budget).to eq(0)
expect(subject.remaining_budget?).to eq(false) expect(subject.remaining_budget?).to eq(false)
@ -22,15 +22,15 @@ RSpec.describe PlanetExpress::DiscountBudget do
end end
end end
describe '#maximum_possible_discount' do describe "#maximum_possible_discount" do
context 'with sufficient budget' do context "with sufficient budget" do
it 'returns the full discount amount' do it "returns the full discount amount" do
expect(subject.maximum_possible_discount(300)).to eq(300) expect(subject.maximum_possible_discount(300)).to eq(300)
end end
end end
context 'with insufficient budget' do context "with insufficient budget" do
it 'returns the maximum possible amount' do it "returns the maximum possible amount" do
expect(subject.maximum_possible_discount(600)).to eq(500) expect(subject.maximum_possible_discount(600)).to eq(500)
end end
end end

View File

@ -2,7 +2,7 @@
FactoryBot.define do FactoryBot.define do
factory :shipping_option, class: PlanetExpress::ShippingOption do factory :shipping_option, class: PlanetExpress::ShippingOption do
sequence(:provider) { 'LP' } sequence(:provider) { "LP" }
sequence(:package_size) { %w[S M L].sample } sequence(:package_size) { %w[S M L].sample }
sequence(:price_in_cents) { |i| i * 100 } sequence(:price_in_cents) { |i| i * 100 }
end end

View File

@ -14,30 +14,30 @@ RSpec.describe PlanetExpress::LShipmentDiscountRule do
end end
let(:correct_shipping_option) do let(:correct_shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('LP', 'L') shipping_option_repo.find_by_provider_and_package_size("LP", "L")
end end
let(:applicable_shipment) do let(:applicable_shipment) do
PlanetExpress::Shipment.new(Date.today, correct_shipping_option) PlanetExpress::Shipment.new(Date.today, correct_shipping_option)
end end
context 'l_shipment' do context "l_shipment" do
context 'not the third shipment' do context "not the third shipment" do
it 'does not apply the discount' do it "does not apply the discount" do
expect do expect do
subject.apply_to(applicable_shipment) subject.apply_to(applicable_shipment)
end.to_not(change { applicable_shipment.discounts }) end.to_not(change { applicable_shipment.discounts })
end end
end end
context 'third shipment for LP' do context "third shipment for LP" do
context 'LP provider' do context "LP provider" do
before(:each) do before(:each) do
shipment_repo.add(applicable_shipment) shipment_repo.add(applicable_shipment)
shipment_repo.add(applicable_shipment) shipment_repo.add(applicable_shipment)
end end
it 'does apply the discount' do it "does apply the discount" do
expect do expect do
subject.apply_to(applicable_shipment) subject.apply_to(applicable_shipment)
end.to(change { applicable_shipment.discounts.length }.by(1)) end.to(change { applicable_shipment.discounts.length }.by(1))
@ -46,7 +46,7 @@ RSpec.describe PlanetExpress::LShipmentDiscountRule do
expect(discount.amount).to eq(applicable_shipment.shipping_option.price_in_cents) expect(discount.amount).to eq(applicable_shipment.shipping_option.price_in_cents)
end end
it 'updates the discount budget' do it "updates the discount budget" do
expected_difference = -applicable_shipment.shipping_option.price_in_cents expected_difference = -applicable_shipment.shipping_option.price_in_cents
expect do expect do
@ -55,38 +55,38 @@ RSpec.describe PlanetExpress::LShipmentDiscountRule do
end end
end end
context 'non LP provider' do context "non LP provider" do
before(:each) do before(:each) do
shipment_repo.add(applicable_shipment) shipment_repo.add(applicable_shipment)
shipment_repo.add(applicable_shipment) shipment_repo.add(applicable_shipment)
end end
let(:shipping_option) do let(:shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('MR', 'L') shipping_option_repo.find_by_provider_and_package_size("MR", "L")
end end
let(:shipment) do let(:shipment) do
PlanetExpress::Shipment.new(Date.today, shipping_option) PlanetExpress::Shipment.new(Date.today, shipping_option)
end end
it 'does not update the discounts' do it "does not update the discounts" do
expect do expect do
subject.apply_to(shipment) subject.apply_to(shipment)
end.to_not(change { shipment.discounts }) end.to_not(change { shipment.discounts })
end end
end end
context 'non L shipment' do context "non L shipment" do
before(:each) do before(:each) do
shipment_repo.add(applicable_shipment) shipment_repo.add(applicable_shipment)
shipment_repo.add(applicable_shipment) shipment_repo.add(applicable_shipment)
end end
let(:shipping_option) do let(:shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('LP', 'M') shipping_option_repo.find_by_provider_and_package_size("LP", "M")
end end
let(:shipment) do let(:shipment) do
PlanetExpress::Shipment.new(Date.today, shipping_option) PlanetExpress::Shipment.new(Date.today, shipping_option)
end end
it 'does not update the discounts' do it "does not update the discounts" do
expect do expect do
subject.apply_to(shipment) subject.apply_to(shipment)
end.to_not(change { shipment.discounts }) end.to_not(change { shipment.discounts })

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
RSpec.describe PlanetExpress do RSpec.describe PlanetExpress do
it 'has a version number' do it "has a version number" do
expect(PlanetExpress::VERSION).not_to be nil expect(PlanetExpress::VERSION).not_to be nil
end end
end end

View File

@ -13,39 +13,39 @@ RSpec.describe PlanetExpress::Repository do
subject { described_class.new(data: entries) } subject { described_class.new(data: entries) }
describe '#where' do describe "#where" do
context 'no data' do context "no data" do
let(:entries) { [] } let(:entries) { [] }
it 'returns an empty array' do it "returns an empty array" do
expect(subject.where).to eq([]) expect(subject.where).to eq([])
end end
end end
context 'no arguments' do context "no arguments" do
before(:each) do before(:each) do
expect(subject.all).to_not be_empty expect(subject.all).to_not be_empty
end end
it 'returns all items' do it "returns all items" do
expect(subject.where).to eq(subject.all) expect(subject.where).to eq(subject.all)
end end
end end
context 'with existing attribute' do context "with existing attribute" do
let(:expected_item) do let(:expected_item) do
repository_item_class.new(150, 'Testing') repository_item_class.new(150, "Testing")
end end
let(:entries) { repository_items + [expected_item] } let(:entries) { repository_items + [expected_item] }
it 'returns a list with the expected item' do it "returns a list with the expected item" do
expect(subject.where(test_attribute_a: 150, test_attribute_b: 'Testing')).to eq([expected_item]) expect(subject.where(test_attribute_a: 150, test_attribute_b: "Testing")).to eq([expected_item])
end end
end end
context 'with unknown attribute' do context "with unknown attribute" do
it 'throws an exception' do it "throws an exception" do
expect do expect do
subject.where(unknown_attribute: nil) subject.where(unknown_attribute: nil)
end.to raise_error(NoMethodError) end.to raise_error(NoMethodError)
@ -53,24 +53,24 @@ RSpec.describe PlanetExpress::Repository do
end end
end end
describe '#add' do describe "#add" do
let(:item) { repository_item_class.new(152, 'Testing') } let(:item) { repository_item_class.new(152, "Testing") }
it 'adds the item to the list' do it "adds the item to the list" do
subject.add(item) subject.add(item)
expect(subject.where(test_attribute_a: 152, test_attribute_b: 'Testing')).to eq([item]) expect(subject.where(test_attribute_a: 152, test_attribute_b: "Testing")).to eq([item])
end end
end end
describe '#remove' do describe "#remove" do
let(:item) { repository_item_class.new(153, 'Test') } let(:item) { repository_item_class.new(153, "Test") }
it 'removes the item from the list' do it "removes the item from the list" do
subject.add(item) subject.add(item)
expect { subject.remove(item) } expect { subject.remove(item) }
.to(change { subject.where(test_attribute_a: 153, test_attribute_b: 'Test') }.to([])) .to(change { subject.where(test_attribute_a: 153, test_attribute_b: "Test") }.to([]))
end end
end end
end end

View File

@ -13,18 +13,18 @@ RSpec.describe PlanetExpress::SShipmentDiscountRule do
) )
end end
context 's_shipment' do context "s_shipment" do
context 'more expensive than cheapest option' do context "more expensive than cheapest option" do
let(:shipping_option) do let(:shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('MR', 'S') shipping_option_repo.find_by_provider_and_package_size("MR", "S")
end end
let(:shipment) do let(:shipment) do
PlanetExpress::Shipment.new(Date.today, PlanetExpress::Shipment.new(Date.today,
shipping_option) shipping_option)
end end
it 'does applies the discount' do it "does applies the discount" do
expect do expect do
subject.apply_to(shipment) subject.apply_to(shipment)
end.to(change { shipment.discounts.length }.by(1)) end.to(change { shipment.discounts.length }.by(1))
@ -32,24 +32,24 @@ RSpec.describe PlanetExpress::SShipmentDiscountRule do
expect(shipment.discounts.last.amount).to eq(50) expect(shipment.discounts.last.amount).to eq(50)
end end
it 'changes the discount budget' do it "changes the discount budget" do
expect do expect do
subject.apply_to(shipment) subject.apply_to(shipment)
end.to(change { budget_repo.for_month(shipment.month).available_budget }.by(-50)) end.to(change { budget_repo.for_month(shipment.month).available_budget }.by(-50))
end end
end end
context 'equals cheapest options' do context "equals cheapest options" do
let(:shipping_option) do let(:shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('LP', 'S') shipping_option_repo.find_by_provider_and_package_size("LP", "S")
end end
let(:shipment) do let(:shipment) do
PlanetExpress::Shipment.new(Date.today, PlanetExpress::Shipment.new(Date.today,
shipping_option) shipping_option)
end end
it 'does not apply the discount' do it "does not apply the discount" do
expect do expect do
subject.apply_to(shipment) subject.apply_to(shipment)
end.to_not(change { shipment.discounts }) end.to_not(change { shipment.discounts })
@ -57,17 +57,17 @@ RSpec.describe PlanetExpress::SShipmentDiscountRule do
end end
end end
context 'non s_shipment' do context "non s_shipment" do
let(:shipping_option) do let(:shipping_option) do
shipping_option_repo.find_by_provider_and_package_size('LP', 'M') shipping_option_repo.find_by_provider_and_package_size("LP", "M")
end end
let(:shipment) do let(:shipment) do
PlanetExpress::Shipment.new(Date.today, PlanetExpress::Shipment.new(Date.today,
shipping_option) shipping_option)
end end
it 'does not apply the discount' do it "does not apply the discount" do
expect do expect do
subject.apply_to(shipment) subject.apply_to(shipment)
end.to_not(change { shipment.discounts }) end.to_not(change { shipment.discounts })

View File

@ -5,7 +5,7 @@ RSpec.describe PlanetExpress::ShipmentDiscountCalculator do
PlanetExpress::ShippingOptionRepository.new(data: []) PlanetExpress::ShippingOptionRepository.new(data: [])
end end
let(:rule) do let(:rule) do
double('Rule') double("Rule")
end end
let(:rules) do let(:rules) do
[rule] [rule]
@ -13,22 +13,22 @@ RSpec.describe PlanetExpress::ShipmentDiscountCalculator do
subject do subject do
described_class.new(shipment_repository: shipment_repository, described_class.new(shipment_repository: shipment_repository,
rules: rules) rules: rules)
end end
describe '#run' do describe "#run" do
context 'with valid shipment' do context "with valid shipment" do
let(:shipment_reader) do let(:shipment_reader) do
[PlanetExpress::Shipment.new(Date.today, build(:shipping_option))] [PlanetExpress::Shipment.new(Date.today, build(:shipping_option))]
end end
it 'does call the rule on the invalid shipment' do it "does call the rule on the invalid shipment" do
expect(rule).to receive(:apply_to) expect(rule).to receive(:apply_to)
subject.run(shipment_reader) subject.run(shipment_reader)
end end
it 'adds the shipment to the shipment_repository' do it "adds the shipment to the shipment_repository" do
expect(rule).to receive(:apply_to) expect(rule).to receive(:apply_to)
expect do expect do
@ -37,18 +37,18 @@ RSpec.describe PlanetExpress::ShipmentDiscountCalculator do
end end
end end
context 'with invalid shipment' do context "with invalid shipment" do
let(:shipment_reader) do let(:shipment_reader) do
[PlanetExpress::InvalidShipment.new('Invalid')] [PlanetExpress::InvalidShipment.new("Invalid")]
end end
it 'does not call the rule with the invalid shipment' do it "does not call the rule with the invalid shipment" do
expect(rule).to_not receive(:apply_to) expect(rule).to_not receive(:apply_to)
subject.run(shipment_reader) subject.run(shipment_reader)
end end
it 'adds the shipment to the shipment_repository' do it "adds the shipment to the shipment_repository" do
expect do expect do
subject.run(shipment_reader) subject.run(shipment_reader)
end.to(change { shipment_repository.all.length }.by(1)) end.to(change { shipment_repository.all.length }.by(1))

View File

@ -5,56 +5,56 @@ RSpec.describe PlanetExpress::ShipmentFormatter do
described_class.new described_class.new
end end
describe '#format' do describe "#format" do
context 'invalid shipment' do context "invalid shipment" do
let(:shipment) do let(:shipment) do
PlanetExpress::InvalidShipment.new('Invalid Shipment') PlanetExpress::InvalidShipment.new("Invalid Shipment")
end end
it 'returns a well formatted string' do it "returns a well formatted string" do
expect(subject.format(shipment)).to eq('Invalid Shipment IGNORED') expect(subject.format(shipment)).to eq("Invalid Shipment IGNORED")
end end
end end
context 'valid shipment' do context "valid shipment" do
let(:date) { Date.today } let(:date) { Date.today }
let(:shipping_option) do let(:shipping_option) do
build(:shipping_option, build(:shipping_option,
provider: 'T', provider: "T",
package_size: 'S', package_size: "S",
price_in_cents: 120) price_in_cents: 120)
end end
let(:shipment) do let(:shipment) do
PlanetExpress::Shipment.new(date, shipping_option) PlanetExpress::Shipment.new(date, shipping_option)
end end
it 'returns a well formatted string' do it "returns a well formatted string" do
result = subject.format(shipment) result = subject.format(shipment)
parts = result.split(' ') parts = result.split(" ")
expect(parts[0]).to eq(date.iso8601) expect(parts[0]).to eq(date.iso8601)
expect(parts[1]).to eq(shipping_option.package_size) expect(parts[1]).to eq(shipping_option.package_size)
expect(parts[2]).to eq(shipping_option.provider) expect(parts[2]).to eq(shipping_option.provider)
expect(parts[3]).to eq('1.20') expect(parts[3]).to eq("1.20")
expect(parts[4]).to eq('-') expect(parts[4]).to eq("-")
end end
context 'with discounts' do context "with discounts" do
before(:each) do before(:each) do
shipment.add_discount(PlanetExpress::Discount.new(50, nil)) shipment.add_discount(PlanetExpress::Discount.new(50, nil))
shipment.add_discount(PlanetExpress::Discount.new(25, nil)) shipment.add_discount(PlanetExpress::Discount.new(25, nil))
end end
it 'includes the discounts' do it "includes the discounts" do
result = subject.format(shipment) result = subject.format(shipment)
parts = result.split(' ') parts = result.split(" ")
expect(parts[0]).to eq(date.iso8601) expect(parts[0]).to eq(date.iso8601)
expect(parts[1]).to eq(shipping_option.package_size) expect(parts[1]).to eq(shipping_option.package_size)
expect(parts[2]).to eq(shipping_option.provider) expect(parts[2]).to eq(shipping_option.provider)
expect(parts[3]).to eq('0.45') expect(parts[3]).to eq("0.45")
expect(parts[4]).to eq('0.75') expect(parts[4]).to eq("0.75")
end end
end end
end end

View File

@ -3,41 +3,41 @@
RSpec.describe PlanetExpress::ShipmentReader do RSpec.describe PlanetExpress::ShipmentReader do
let(:shipping_option_repsitory) { PlanetExpress::ShippingOptionRepository.new } let(:shipping_option_repsitory) { PlanetExpress::ShippingOptionRepository.new }
let(:input) { '' } let(:input) { "" }
subject { PlanetExpress::ShipmentReader.new(input, shipping_option_repsitory) } subject { PlanetExpress::ShipmentReader.new(input, shipping_option_repsitory) }
describe '#each' do describe "#each" do
context 'with a file' do context "with a file" do
let(:input) { File.read(File.expand_path('fixtures/shipment_input_file.txt', __dir__)) } let(:input) { File.read(File.expand_path("fixtures/shipment_input_file.txt", __dir__)) }
let(:result) { subject.to_a } let(:result) { subject.to_a }
it 'parses the file' do it "parses the file" do
expect(result.length).to eq(21) expect(result.length).to eq(21)
expect(result.select { |item| item.instance_of?(PlanetExpress::Shipment) }.length).to eq(20) expect(result.select { |item| item.instance_of?(PlanetExpress::Shipment) }.length).to eq(20)
expect(result.select { |item| item.instance_of?(PlanetExpress::InvalidShipment) }.length).to eq(1) expect(result.select { |item| item.instance_of?(PlanetExpress::InvalidShipment) }.length).to eq(1)
end end
end end
context 'with valid shipment' do context "with valid shipment" do
let(:input) { '2015-02-01 S MR' } let(:input) { "2015-02-01 S MR" }
let(:result) { subject.to_a } let(:result) { subject.to_a }
let(:shipment) { result.first } let(:shipment) { result.first }
it 'returns a parsed shipment' do it "returns a parsed shipment" do
expect(shipment.date).to eq(Date.new(2015, 2, 1)) expect(shipment.date).to eq(Date.new(2015, 2, 1))
expect(shipment.shipping_option).to eq(PlanetExpress::ShippingOption.new('MR', 'S', 200)) expect(shipment.shipping_option).to eq(PlanetExpress::ShippingOption.new("MR", "S", 200))
end end
end end
context 'with an invalid shipment' do context "with an invalid shipment" do
let(:input) { '2015-02-29 CUSPS' } let(:input) { "2015-02-29 CUSPS" }
let(:result) { subject.to_a } let(:result) { subject.to_a }
let(:shipment) { result.first } let(:shipment) { result.first }
it 'returns an invalid shipment' do it "returns an invalid shipment" do
expect(shipment).to be_an_instance_of(PlanetExpress::InvalidShipment) expect(shipment).to be_an_instance_of(PlanetExpress::InvalidShipment)
end end
end end

View File

@ -4,29 +4,29 @@ RSpec.describe PlanetExpress::ShipmentRepository do
let(:items) { [] } let(:items) { [] }
subject { described_class.new(data: items) } subject { described_class.new(data: items) }
describe 'rule_applied_in_month?' do describe "rule_applied_in_month?" do
context 'empty repository' do context "empty repository" do
let(:items) { [] } let(:items) { [] }
it 'returns false' do it "returns false" do
result = subject.rule_applied_in_month?(Date.today.begin_of_month, result = subject.rule_applied_in_month?(Date.today.begin_of_month,
PlanetExpress::Rule) PlanetExpress::Rule)
expect(result).to eq(false) expect(result).to eq(false)
end end
end end
context 'with invalid shipments' do context "with invalid shipments" do
let(:items) { [PlanetExpress::InvalidShipment.new('')] } let(:items) { [PlanetExpress::InvalidShipment.new("")] }
it 'returns false' do it "returns false" do
result = subject.rule_applied_in_month?(Date.today.begin_of_month, result = subject.rule_applied_in_month?(Date.today.begin_of_month,
PlanetExpress::Rule) PlanetExpress::Rule)
expect(result).to eq(false) expect(result).to eq(false)
end end
end end
context 'with valid shipment matching' do context "with valid shipment matching" do
let(:rule) do let(:rule) do
Object.new Object.new
end end
@ -39,15 +39,15 @@ RSpec.describe PlanetExpress::ShipmentRepository do
let(:items) { [shipment] } let(:items) { [shipment] }
it 'returns true' do it "returns true" do
result = subject.rule_applied_in_month?(Date.today.begin_of_month, result = subject.rule_applied_in_month?(Date.today.begin_of_month,
rule.class) rule.class)
expect(result).to eq(true) expect(result).to eq(true)
end end
end end
context 'with valid shipment not matching' do context "with valid shipment not matching" do
let(:rule) do let(:rule) do
Object.new Object.new
end end
@ -64,22 +64,22 @@ RSpec.describe PlanetExpress::ShipmentRepository do
let(:items) { [shipment] } let(:items) { [shipment] }
it 'returns false' do it "returns false" do
result = subject.rule_applied_in_month?(Date.today.begin_of_month, result = subject.rule_applied_in_month?(Date.today.begin_of_month,
other_rule.class) other_rule.class)
expect(result).to eq(false) expect(result).to eq(false)
end end
end end
end end
describe '#l_shipment_count_for_provider_and_month' do describe "#l_shipment_count_for_provider_and_month" do
context 'empty repository' do context "empty repository" do
let(:items) { [] } let(:items) { [] }
it 'returns 0' do it "returns 0" do
result = subject.l_shipment_count_for_provider_and_month( result = subject.l_shipment_count_for_provider_and_month(
'LP', "LP",
Date.today.begin_of_month Date.today.begin_of_month
) )
@ -87,11 +87,11 @@ RSpec.describe PlanetExpress::ShipmentRepository do
end end
end end
context 'with invalid shipments' do context "with invalid shipments" do
let(:items) { [PlanetExpress::InvalidShipment.new('')] } let(:items) { [PlanetExpress::InvalidShipment.new("")] }
it 'returns 0' do it "returns 0" do
result = subject.l_shipment_count_for_provider_and_month( result = subject.l_shipment_count_for_provider_and_month(
'LP', "LP",
Date.today.begin_of_month Date.today.begin_of_month
) )
@ -99,47 +99,47 @@ RSpec.describe PlanetExpress::ShipmentRepository do
end end
end end
context 'with valid shipment matching' do context "with valid shipment matching" do
let(:shipment) do let(:shipment) do
PlanetExpress::Shipment.new(Date.today, PlanetExpress::Shipment.new(Date.today,
build(:shipping_option, build(:shipping_option,
package_size: 'L')) package_size: "L"))
end end
let(:provider) { shipment.provider } let(:provider) { shipment.provider }
let(:items) { [shipment] } let(:items) { [shipment] }
it 'returns 1' do it "returns 1" do
result = subject.l_shipment_count_for_provider_and_month(provider, result = subject.l_shipment_count_for_provider_and_month(provider,
Date.today.begin_of_month) Date.today.begin_of_month)
expect(result).to eq(1) expect(result).to eq(1)
end end
end end
context 'with valid shipment not matching' do context "with valid shipment not matching" do
let(:shipment) do let(:shipment) do
PlanetExpress::Shipment.new(Date.today, PlanetExpress::Shipment.new(Date.today,
build(:shipping_option, build(:shipping_option,
package_size: 'L')) package_size: "L"))
end end
let(:provider) { shipment.provider } let(:provider) { shipment.provider }
let(:items) { [shipment] } let(:items) { [shipment] }
context 'different provider' do context "different provider" do
it 'returns 0' do it "returns 0" do
result = subject.l_shipment_count_for_provider_and_month('MP_XXX_TEST', result = subject.l_shipment_count_for_provider_and_month("MP_XXX_TEST",
Date.today.begin_of_month) Date.today.begin_of_month)
expect(result).to eq(0) expect(result).to eq(0)
end end
end end
context 'different month' do context "different month" do
it 'returns 0' do it "returns 0" do
result = subject.l_shipment_count_for_provider_and_month(provider, result = subject.l_shipment_count_for_provider_and_month(provider,
Date.today.next_month.begin_of_month) Date.today.next_month.begin_of_month)
expect(result).to eq(0) expect(result).to eq(0)
end end

View File

@ -3,26 +3,26 @@
RSpec.describe PlanetExpress::ShippingOptionRepository do RSpec.describe PlanetExpress::ShippingOptionRepository do
subject { PlanetExpress::ShippingOptionRepository.new } subject { PlanetExpress::ShippingOptionRepository.new }
describe '#lowest_price_for_package_size' do describe "#lowest_price_for_package_size" do
it 'finds the lowest price for a package size' do it "finds the lowest price for a package size" do
expect(subject.lowest_price_for_package_size('L')).to eq(400) expect(subject.lowest_price_for_package_size("L")).to eq(400)
end end
end end
describe '#lowest_price_for_package_size' do describe "#lowest_price_for_package_size" do
context 'existing option' do context "existing option" do
it 'finds the correct shipping option' do it "finds the correct shipping option" do
result = subject.find_by_provider_and_package_size('LP', 'S') result = subject.find_by_provider_and_package_size("LP", "S")
expect(result.provider).to eq('LP') expect(result.provider).to eq("LP")
expect(result.package_size).to eq('S') expect(result.package_size).to eq("S")
expect(result.price_in_cents).to eq(150) expect(result.price_in_cents).to eq(150)
end end
end end
context 'unknown option' do context "unknown option" do
it 'returns nil' do it "returns nil" do
result = subject.find_by_provider_and_package_size('UNKNOWN', 'S') result = subject.find_by_provider_and_package_size("UNKNOWN", "S")
expect(result).to eq(nil) expect(result).to eq(nil)
end end

View File

@ -1,51 +1,51 @@
# frozen_string_literal: true # frozen_string_literal: true
RSpec.describe PlanetExpress::ShippingOption do RSpec.describe PlanetExpress::ShippingOption do
describe '#s_shipment?' do describe "#s_shipment?" do
context 'with S package size' do context "with S package size" do
subject { build(:shipping_option, package_size: 'S') } subject { build(:shipping_option, package_size: "S") }
it 'returns true' do it "returns true" do
expect(subject.s_shipment?).to eq(true) expect(subject.s_shipment?).to eq(true)
end end
end end
context 'with non S package size' do context "with non S package size" do
subject { build(:shipping_option, package_size: 'M') } subject { build(:shipping_option, package_size: "M") }
it 'returns false' do it "returns false" do
expect(subject.s_shipment?).to eq(false) expect(subject.s_shipment?).to eq(false)
end end
end end
end end
describe '#l_shipment?' do describe "#l_shipment?" do
context 'with L package size' do context "with L package size" do
subject { build(:shipping_option, package_size: 'L') } subject { build(:shipping_option, package_size: "L") }
it 'returns true' do it "returns true" do
expect(subject.l_shipment?).to eq(true) expect(subject.l_shipment?).to eq(true)
end end
end end
context 'with non L package size' do context "with non L package size" do
subject { build(:shipping_option, package_size: 'M') } subject { build(:shipping_option, package_size: "M") }
it 'returns false' do it "returns false" do
expect(subject.l_shipment?).to eq(false) expect(subject.l_shipment?).to eq(false)
end end
end end
end end
describe '#lp_provider?' do describe "#lp_provider?" do
context 'with LP provider' do context "with LP provider" do
subject { build(:shipping_option, provider: 'LP') } subject { build(:shipping_option, provider: "LP") }
it 'returns true' do it "returns true" do
expect(subject.lp_provider?).to eq(true) expect(subject.lp_provider?).to eq(true)
end end
end end
context 'with non L package size' do context "with non L package size" do
subject { build(:shipping_option, provider: 'MP') } subject { build(:shipping_option, provider: "MP") }
it 'returns false' do it "returns false" do
expect(subject.lp_provider?).to eq(false) expect(subject.lp_provider?).to eq(false)
end end
end end

View File

@ -1,16 +1,16 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'bundler/setup' require "bundler/setup"
require 'active_support/inflector' require "active_support/inflector"
require 'factory_bot' require "factory_bot"
require 'simplecov' require "simplecov"
SimpleCov.start SimpleCov.start
require 'planet_express' require "planet_express"
require 'rspec/mocks' require "rspec/mocks"
RSpec.configure do |config| RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure # Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = '.rspec_status' config.example_status_persistence_file_path = ".rspec_status"
# Disable RSpec exposing methods globally on `Module` and `main` # Disable RSpec exposing methods globally on `Module` and `main`
config.disable_monkey_patching! config.disable_monkey_patching!