Created
October 1, 2018 19:16
-
-
Save mingca/e18c5953a5228bc5f594ab1fa58dd58b to your computer and use it in GitHub Desktop.
People parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# File: app.rb | |
require 'date' | |
require 'test/unit' | |
CITY_ABBREVS = { | |
'LA' => 'Los Angeles', | |
'NYC' => 'New York City' | |
}.freeze | |
class ParserUndefined < StandardError; end | |
class AbbreviationMissing < StandardError; end | |
# General parser | |
class Parser | |
def initialize(row) | |
@row = row | |
end | |
def parse | |
@slices = @row.split(self.class::Delimiter).map(&:strip) | |
[first_name, city_name, birth_date].join(' ') | |
end | |
protected | |
def first_name | |
@slices[self.class::Order[:first_name]] | |
end | |
def city_name | |
slice = @slices[self.class::Order[:city_name]] | |
if city_name_abbrev? | |
raise AbbreviationMissing unless CITY_ABBREVS.key? slice | |
CITY_ABBREVS[slice] | |
else | |
slice | |
end | |
end | |
def birth_date | |
slice = @slices[self.class::Order[:birth_date]] | |
Date.strptime(slice, self.class::DateFormat) | |
.strftime('%m/%d/%Y') | |
end | |
def city_name_abbrev? | |
false | |
end | |
end | |
# Comma parser | |
class CommaParser < Parser | |
Delimiter = ','.freeze | |
Order = { | |
first_name: 0, | |
city_name: 1, | |
birth_date: 2 | |
}.freeze | |
DateFormat = '%m/%d/%Y'.freeze | |
end | |
# Dollar parser | |
class DollarParser < Parser | |
Delimiter = '$'.freeze | |
Order = { | |
first_name: 3, | |
city_name: 0, | |
birth_date: 1 | |
}.freeze | |
DateFormat = '%m-%d-%Y'.freeze | |
protected | |
def city_name_abbrev? | |
true | |
end | |
end | |
# People controller | |
class PeopleController | |
def self.normalize(request_params) | |
results = [] | |
request_params.each do |k, v| | |
class_name = "#{k.capitalize}Parser" | |
raise ParserUndefined unless Object.const_defined?(class_name) | |
results << v.map { |e| Object.const_get(class_name).new(e).parse } | |
end | |
results | |
end | |
end | |
begin | |
result = PeopleController.normalize( | |
# Fields: first name, city name, birth date | |
comma: [ | |
'Mckayla, Atlanta, 5/29/1986', | |
'Elliot, New York City, 4/3/1947' | |
], | |
# Fields: city abbreviation, birth date, last name, first name | |
dollar: [ | |
'LA $ 10-4-1974 $ Nolan $ Rhiannon', | |
'NYC $ 12-1-1962 $ Bruen $ Rigoberto' | |
] | |
) | |
puts result | |
rescue AbbreviationMissing, ParserUndefined | |
puts 'There was an error while parsing' | |
end | |
# Expected return (order of entries doesn't matter): | |
# [ | |
# 'Mckayla Atlanta 5/29/1986', | |
# 'Elliot New York City 4/3/1947', | |
# 'Rhiannon Los Angeles 10/4/1974', | |
# 'Rigoberto New York City 12/1/1962', | |
# ] | |
# Test PeopleController | |
class TestPeopleController < Test::Unit::TestCase | |
def setup | |
@parser = PeopleController.normalize( | |
dollar: ['LA $ 10-4-1974 $ Nolan $ Rhiannon'] | |
) | |
end | |
def test_parser | |
assert_not_nil @parser | |
assert_raise ParserUndefined do | |
PeopleController.normalize(sharp: ['LA # 10-4-1974 # Nolan # Rhiannon']) | |
end | |
end | |
end | |
# Test DollarParser | |
class TestDollarParser < Test::Unit::TestCase | |
def setup | |
@parser = DollarParser.new('NONE $ 10-4-1974 $ Nolan $ Rhiannon') | |
end | |
def test_city_name | |
assert_raise AbbreviationMissing do | |
@parser.parse | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment