Implement shipment reader
- Add shipment object - Add object to represent invalid shipments - Implement reader for the csv input format
This commit is contained in:
parent
e169921c14
commit
66886e6ae6
@ -4,6 +4,10 @@ require 'planet_express/version'
|
||||
require 'planet_express/shipping_option'
|
||||
require 'planet_express/shipping_option_repository'
|
||||
|
||||
require 'planet_express/shipment'
|
||||
require 'planet_express/invalid_shipment'
|
||||
require 'planet_express/shipment_reader'
|
||||
|
||||
module PlanetExpress
|
||||
class Error < StandardError; end
|
||||
# Your code goes here...
|
||||
|
11
lib/planet_express/invalid_shipment.rb
Normal file
11
lib/planet_express/invalid_shipment.rb
Normal file
@ -0,0 +1,11 @@
|
||||
module PlanetExpress
|
||||
class InvalidShipment
|
||||
def initialize(raw_string)
|
||||
@raw_string = raw_string
|
||||
end
|
||||
|
||||
def if_valid(&block)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
25
lib/planet_express/shipment.rb
Normal file
25
lib/planet_express/shipment.rb
Normal file
@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module PlanetExpress
|
||||
class Shipment
|
||||
attr_reader :date, :shipping_option, :discounts
|
||||
|
||||
def initialize(date, shipping_option)
|
||||
@date = date
|
||||
@shipping_option = shipping_option
|
||||
@discounts = []
|
||||
end
|
||||
|
||||
def if_valid(&block)
|
||||
yield self
|
||||
end
|
||||
|
||||
def add_discount(discount)
|
||||
discounts.push(discount)
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#{self.class.name} [#{date} #{shipping_option}]"
|
||||
end
|
||||
end
|
||||
end
|
40
lib/planet_express/shipment_reader.rb
Normal file
40
lib/planet_express/shipment_reader.rb
Normal file
@ -0,0 +1,40 @@
|
||||
require 'csv'
|
||||
|
||||
module PlanetExpress
|
||||
class ShipmentReader
|
||||
include Enumerable
|
||||
attr_reader :input, :shipping_option_repository
|
||||
|
||||
def initialize(input, shipping_option_repository)
|
||||
@input = input
|
||||
@shipping_option_repository = shipping_option_repository
|
||||
end
|
||||
|
||||
def each
|
||||
CSV.new(input, headers: false, col_sep: ' ').each do |row|
|
||||
date = parse_date(row)
|
||||
shipping_option = find_shipping_option(row)
|
||||
|
||||
if date.nil? || shipping_option.nil?
|
||||
yield InvalidShipment.new(row.join(" "))
|
||||
else
|
||||
yield Shipment.new(date, shipping_option)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_shipping_option(row)
|
||||
shipping_option_repository.find_by_provider_and_package_size(row[2], row[1])
|
||||
end
|
||||
|
||||
def parse_date(row)
|
||||
begin
|
||||
return Date.iso8601(row[0])
|
||||
rescue ArgumentError => _e
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
spec/fixtures/shipment_input_file.txt
vendored
Normal file
21
spec/fixtures/shipment_input_file.txt
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
2015-02-01 S MR
|
||||
2015-02-02 S MR
|
||||
2015-02-03 L LP
|
||||
2015-02-05 S LP
|
||||
2015-02-06 S MR
|
||||
2015-02-06 L LP
|
||||
2015-02-07 L MR
|
||||
2015-02-08 M MR
|
||||
2015-02-09 L LP
|
||||
2015-02-10 L LP
|
||||
2015-02-10 S MR
|
||||
2015-02-10 S MR
|
||||
2015-02-11 L LP
|
||||
2015-02-12 M MR
|
||||
2015-02-13 M LP
|
||||
2015-02-15 S MR
|
||||
2015-02-17 L LP
|
||||
2015-02-17 S MR
|
||||
2015-02-24 L LP
|
||||
2015-02-29 CUSPS
|
||||
2015-03-01 S MR
|
45
spec/shipment_reader_spec.rb
Normal file
45
spec/shipment_reader_spec.rb
Normal file
@ -0,0 +1,45 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe PlanetExpress::ShipmentReader do
|
||||
let(:shipping_option_repsitory) { PlanetExpress::ShippingOptionRepository.new }
|
||||
|
||||
let(:input) { '' }
|
||||
|
||||
subject { PlanetExpress::ShipmentReader.new(input, shipping_option_repsitory) }
|
||||
|
||||
describe '#each' do
|
||||
context 'with a file' do
|
||||
let(:input) { File.read(File.expand_path('../fixtures/shipment_input_file.txt', __FILE__)) }
|
||||
let(:result) { subject.to_a }
|
||||
|
||||
it 'parses the file' do
|
||||
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::InvalidShipment) }.length).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid shipment' do
|
||||
let(:input) { '2015-02-01 S MR' }
|
||||
|
||||
let(:result) { subject.to_a }
|
||||
let(:shipment) { result.first }
|
||||
|
||||
it 'returns a parsed shipment' do
|
||||
expect(shipment.date).to eq(Date.new(2015, 2, 1))
|
||||
expect(shipment.shipping_option).to eq(PlanetExpress::ShippingOption.new('MR', 'S', 200))
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an invalid shipment' do
|
||||
let(:input) { '2015-02-29 CUSPS' }
|
||||
|
||||
let(:result) { subject.to_a }
|
||||
let(:shipment) { result.first }
|
||||
|
||||
it 'returns an invalid shipment' do
|
||||
expect(shipment).to be_an_instance_of(PlanetExpress::InvalidShipment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user