Skip to content

Commit

Permalink
Merge pull request #30 from timrogers/find-all-by-city
Browse files Browse the repository at this point in the history
Support looking airports by city name with `Airports.find_all_by_city_name`
  • Loading branch information
Tim Rogers authored Dec 4, 2019
2 parents 9094130 + 4adaedc commit 847cdb4
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 21 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# v1.5.0 (5 December 2019)

* Support looking up airports by the name of the city they
are located in with `Airports.find_all_by_city_name` (@viral810, @timrogers)
* Refactor `Airports` so `Airport` objects are only generated once
and the code is cleaner (@timrogers)

# v1.4.1 (14 November 2019)

* Correct the time zone of Istanbul Airport (`IST`) (@aliismayilov)
Expand Down
33 changes: 17 additions & 16 deletions lib/airports.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,43 @@ module Airports
def self.find_by_iata_code(iata_code)
return unless iata_code.length == 3

airport_data = parsed_data.fetch(iata_code, nil)

return unless airport_data

Airport.
new(airport_data.each_with_object({}) { |(k, v), h| h[k.to_sym] = v })
all.find { |airport| airport.iata == iata_code }
end

def self.find_by_icao_code(icao_code)
return unless icao_code.length == 4

airport_data = parsed_data.values.find do |data|
data["icao"] == icao_code
end

return unless airport_data
all.find { |airport| airport.icao == icao_code }
end

Airport.
new(airport_data.each_with_object({}) { |(k, v), h| h[k.to_sym] = v })
def self.find_all_by_city_name(city_name)
all.select { |airport| airport.city.casecmp(city_name).zero? }
end

def self.iata_codes
parsed_data.keys
end

def self.all
@all ||= parsed_data.map do |_iata_code, airport_data|
Airport.
new(airport_data.each_with_object({}) { |(k, v), h| h[k.to_sym] = v })
@all ||= parsed_data.values.map do |airport_data|
airport_from_parsed_data_element(airport_data)
end
end

def self.parsed_data
@parsed_data ||= JSON.parse(data)
end

def self.airport_from_parsed_data_element(parsed_data_element)
# TODO: Once we're using Ruby 2.5+, use Hash#transform_keys here to symbolize the keys
transformed_hash = parsed_data_element.each_with_object({}) do |(k, v), hash|
hash[k.to_sym] = v
end

Airport.new(transformed_hash)
end
private_class_method :airport_from_parsed_data_element

def self.data
@data ||= File.read(data_path)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/airports/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Airports
VERSION = "1.4.1"
VERSION = "1.5.0"
end
29 changes: 25 additions & 4 deletions spec/airports_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,31 @@
context "with a code that is too long" do
let(:icao_code) { "ALICE" }

it "doesn't try to look it up" do
expect(described_class.parsed_data).to_not receive(:fetch).with(icao_code, nil)
find_by_icao_code
end
it { is_expected.to be_nil }
end
end

describe ".find_all_by_city_name" do
subject(:find_all_by_city_name) do
described_class.find_all_by_city_name(city_name)
end

context "with a city name that has matches" do
let(:city_name) { "London" }

its(:length) { is_expected.to eq(7) }
end

context "with a city name that has matches, apart from case" do
let(:city_name) { "lOnDoN" }

its(:length) { is_expected.to eq(7) }
end

context "with a non-matching city name" do
let(:city_name) { "Asgard" }

it { is_expected.to be_empty }
end
end
end

0 comments on commit 847cdb4

Please sign in to comment.