Extract default repository behavior into base class
This commit is contained in:
parent
66886e6ae6
commit
b6f2d46d91
@ -1,6 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'planet_express/version'
|
||||
|
||||
require 'planet_express/repository'
|
||||
|
||||
require 'planet_express/shipping_option'
|
||||
require 'planet_express/shipping_option_repository'
|
||||
|
||||
|
29
lib/planet_express/repository.rb
Normal file
29
lib/planet_express/repository.rb
Normal file
@ -0,0 +1,29 @@
|
||||
module PlanetExpress
|
||||
class Repository
|
||||
attr_reader :data
|
||||
|
||||
def initialize(data: )
|
||||
@data = data
|
||||
end
|
||||
|
||||
def all
|
||||
data
|
||||
end
|
||||
|
||||
def add(item)
|
||||
data.push(item)
|
||||
end
|
||||
|
||||
def remove(item)
|
||||
data.delete(item)
|
||||
end
|
||||
|
||||
def where(attribute_matchers = {})
|
||||
all.select do |entry|
|
||||
attribute_matchers.map do |attribute, value|
|
||||
entry.public_send(attribute.to_sym) == value
|
||||
end.all?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,24 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module PlanetExpress
|
||||
class ShippingOptionRepository
|
||||
class ShippingOptionRepository < Repository
|
||||
attr_reader :data
|
||||
def initialize(data: nil)
|
||||
@data = data || default_data
|
||||
end
|
||||
|
||||
def all
|
||||
data
|
||||
end
|
||||
|
||||
def where(attribute_matchers = {})
|
||||
all.select do |entry|
|
||||
attribute_matchers.map do |attribute, value|
|
||||
entry.public_send(attribute.to_sym) == value
|
||||
end.all?
|
||||
end
|
||||
end
|
||||
|
||||
def find_by_provider_and_package_size(provider, package_size)
|
||||
where(provider: provider, package_size: package_size).first
|
||||
end
|
||||
|
77
spec/repository_spec.rb
Normal file
77
spec/repository_spec.rb
Normal file
@ -0,0 +1,77 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe PlanetExpress::Repository do
|
||||
let!(:repository_item_class) { Struct.new(:test_attribute_a, :test_attribute_b) }
|
||||
|
||||
let(:repository_items) do
|
||||
5.times.map do |i|
|
||||
repository_item_class.new(i * 100, "Testing #{i}")
|
||||
end
|
||||
end
|
||||
|
||||
let!(:entries) { repository_items }
|
||||
|
||||
subject { described_class.new(data: entries) }
|
||||
|
||||
|
||||
describe '#where' do
|
||||
context 'no data' do
|
||||
let(:entries) { [] }
|
||||
|
||||
it 'returns an empty array' do
|
||||
expect(subject.where()).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
context 'no arguments' do
|
||||
before(:each) do
|
||||
expect(subject.all).to_not be_empty
|
||||
end
|
||||
|
||||
it 'returns all items' do
|
||||
expect(subject.where()).to eq(subject.all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with existing attribute' do
|
||||
let(:expected_item) do
|
||||
repository_item_class.new(150, 'Testing')
|
||||
end
|
||||
|
||||
let(:entries) { repository_items + [expected_item] }
|
||||
|
||||
it 'returns a list with the expected item' do
|
||||
expect(subject.where(test_attribute_a: 150, test_attribute_b: "Testing")).to eq([expected_item])
|
||||
end
|
||||
end
|
||||
|
||||
context 'with unknown attribute' do
|
||||
it 'throws an exception' do
|
||||
expect do
|
||||
subject.where(unknown_attribute: nil)
|
||||
end.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#add' do
|
||||
let(:item) { repository_item_class.new(152, 'Testing') }
|
||||
|
||||
it 'adds the item to the list' do
|
||||
subject.add(item)
|
||||
|
||||
expect(subject.where(test_attribute_a: 152, test_attribute_b: 'Testing')).to eq([item])
|
||||
end
|
||||
end
|
||||
|
||||
describe '#remove' do
|
||||
let(:item) { repository_item_class.new(153, 'Test') }
|
||||
|
||||
it 'removes the item from the list' do
|
||||
subject.add(item)
|
||||
|
||||
expect { subject.remove(item) }
|
||||
.to(change { subject.where(test_attribute_a: 153, test_attribute_b: 'Test') }.to([]))
|
||||
end
|
||||
end
|
||||
end
|
@ -3,52 +3,6 @@
|
||||
RSpec.describe PlanetExpress::ShippingOptionRepository do
|
||||
subject { PlanetExpress::ShippingOptionRepository.new }
|
||||
|
||||
describe '#where' do
|
||||
context 'no data' do
|
||||
subject { PlanetExpress::ShippingOptionRepository.new(data: []) }
|
||||
|
||||
it 'returns an empty array' do
|
||||
expect(subject.where()).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
context 'no arguments' do
|
||||
before(:each) do
|
||||
expect(subject.all).to_not be_empty
|
||||
end
|
||||
|
||||
it 'returns all items' do
|
||||
expect(subject.where()).to eq(subject.all)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with existing attribute' do
|
||||
let(:expected_item) do
|
||||
build(:shipping_option, package_size: 'L', price_in_cents: 410)
|
||||
end
|
||||
|
||||
let(:data) do
|
||||
build_list(:shipping_option, 4, price_in_cents: 500) + [expected_item]
|
||||
end
|
||||
|
||||
subject do
|
||||
PlanetExpress::ShippingOptionRepository.new(data: data)
|
||||
end
|
||||
|
||||
it 'returns a list with the expected item' do
|
||||
expect(subject.where(package_size: 'L', price_in_cents: 410)).to eq([expected_item])
|
||||
end
|
||||
end
|
||||
|
||||
context 'with unknown attribute' do
|
||||
it 'throws an exception' do
|
||||
expect do
|
||||
subject.where(unknown_attribute: nil)
|
||||
end.to raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#lowest_price_for_package_size' do
|
||||
it 'finds the lowest price for a package size' do
|
||||
expect(subject.lowest_price_for_package_size('L')).to eq(400)
|
||||
|
Loading…
Reference in New Issue
Block a user