google_distance_matrix 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +16 -0
  3. data/.rubocop.yml +6 -0
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +1 -0
  6. data/CHANGELOG.md +20 -0
  7. data/Gemfile +2 -0
  8. data/Rakefile +9 -4
  9. data/google_distance_matrix.gemspec +20 -18
  10. data/lib/google_distance_matrix/client.rb +32 -18
  11. data/lib/google_distance_matrix/client_cache.rb +9 -3
  12. data/lib/google_distance_matrix/configuration.rb +37 -19
  13. data/lib/google_distance_matrix/errors.rb +6 -3
  14. data/lib/google_distance_matrix/log_subscriber.rb +14 -14
  15. data/lib/google_distance_matrix/logger.rb +6 -4
  16. data/lib/google_distance_matrix/matrix.rb +45 -22
  17. data/lib/google_distance_matrix/place.rb +32 -25
  18. data/lib/google_distance_matrix/places.rb +5 -4
  19. data/lib/google_distance_matrix/polyline_encoder/delta.rb +4 -2
  20. data/lib/google_distance_matrix/polyline_encoder/value_encoder.rb +11 -4
  21. data/lib/google_distance_matrix/polyline_encoder.rb +2 -2
  22. data/lib/google_distance_matrix/railtie.rb +4 -1
  23. data/lib/google_distance_matrix/route.rb +22 -15
  24. data/lib/google_distance_matrix/routes_finder.rb +25 -29
  25. data/lib/google_distance_matrix/url_builder/polyline_encoder_buffer.rb +3 -0
  26. data/lib/google_distance_matrix/url_builder.rb +44 -16
  27. data/lib/google_distance_matrix/version.rb +3 -1
  28. data/lib/google_distance_matrix.rb +25 -23
  29. data/spec/lib/google_distance_matrix/client_cache_spec.rb +26 -11
  30. data/spec/lib/google_distance_matrix/client_spec.rb +40 -30
  31. data/spec/lib/google_distance_matrix/configuration_spec.rb +36 -24
  32. data/spec/lib/google_distance_matrix/log_subscriber_spec.rb +13 -44
  33. data/spec/lib/google_distance_matrix/logger_spec.rb +16 -13
  34. data/spec/lib/google_distance_matrix/matrix_spec.rb +90 -57
  35. data/spec/lib/google_distance_matrix/place_spec.rb +30 -25
  36. data/spec/lib/google_distance_matrix/places_spec.rb +29 -28
  37. data/spec/lib/google_distance_matrix/polyline_encoder/delta_spec.rb +5 -3
  38. data/spec/lib/google_distance_matrix/polyline_encoder_spec.rb +7 -2
  39. data/spec/lib/google_distance_matrix/route_spec.rb +11 -9
  40. data/spec/lib/google_distance_matrix/routes_finder_spec.rb +95 -81
  41. data/spec/lib/google_distance_matrix/url_builder_spec.rb +97 -48
  42. data/spec/spec_helper.rb +3 -1
  43. metadata +35 -7
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GoogleDistanceMatrix
2
4
  # Public: Represents a distance matrix.
3
5
  #
@@ -25,23 +27,25 @@ module GoogleDistanceMatrix
25
27
  # config.mode = "walking"
26
28
  # end
27
29
  #
28
- # You can set default configuration by doing: GoogleDistanceMatrix.configure_defaults { |c| c.sensor = true }
30
+ # You can set default configuration by doing:
31
+ # GoogleDistanceMatrix.configure_defaults { |c| c.sensor = true }
29
32
  #
30
33
  #
31
34
  # Query API and get the matrix back
32
35
  #
33
36
  # matrix.data # Returns a two dimensional array.
34
37
  # # Rows are ordered according to the values in the origins.
35
- # # Each row corresponds to an origin, and each element within that row corresponds to
38
+ # # Each row corresponds to an origin, and each element
39
+ # # within that row corresponds to
36
40
  # # a pairing of the origin with a destination.
37
41
  #
38
42
  #
39
43
  class Matrix
40
44
  include ActiveModel::Validations
41
45
 
42
- validates :origins, length: {minimum: 1, too_short: "must have at least one origin"}
43
- validates :destinations, length: {minimum: 1, too_short: "must have at least one destination"}
44
- validate { errors.add(:configuration, "is invalid") if configuration.invalid? }
46
+ validates :origins, length: { minimum: 1, too_short: 'must have at least one origin' }
47
+ validates :destinations, length: { minimum: 1, too_short: 'must have at least one destination' }
48
+ validate { errors.add(:configuration, 'is invalid') if configuration.invalid? }
45
49
 
46
50
  attr_reader :origins, :destinations, :configuration
47
51
 
@@ -53,6 +57,7 @@ module GoogleDistanceMatrix
53
57
  @configuration = attributes[:configuration] || GoogleDistanceMatrix.default_configuration.dup
54
58
  end
55
59
 
60
+ delegate :sensitive_url, :filtered_url, to: :url_builder
56
61
 
57
62
  delegate :route_for, :routes_for, to: :routes_finder
58
63
  delegate :route_for!, :routes_for!, to: :routes_finder
@@ -61,7 +66,6 @@ module GoogleDistanceMatrix
61
66
  delegate :shortest_route_by_duration_in_traffic_to, to: :routes_finder
62
67
  delegate :shortest_route_by_duration_in_traffic_to!, to: :routes_finder
63
68
 
64
-
65
69
  # Public: The data for this matrix.
66
70
  #
67
71
  # Returns a two dimensional array, the matrix's data
@@ -83,40 +87,59 @@ module GoogleDistanceMatrix
83
87
  @data.present?
84
88
  end
85
89
 
86
-
87
-
88
90
  def configure
89
91
  yield configuration
90
92
  end
91
93
 
92
- def url
93
- UrlBuilder.new(self).url
94
- end
95
-
96
-
97
94
  def inspect
98
95
  attributes = %w[origins destinations]
99
- attributes << "data" if loaded?
96
+ attributes << 'data' if loaded?
100
97
  inspection = attributes.map { |a| "#{a}: #{public_send(a).inspect}" }.join ', '
101
98
 
102
99
  "#<#{self.class} #{inspection}>"
103
100
  end
104
101
 
105
-
106
102
  private
107
103
 
104
+ def url_builder
105
+ # We do not keep url builder as an instance variable as origins and destinations
106
+ # may be added after URL is being built for the first time. We should either
107
+ # make our matrix immutable or reset if origins/destinations are added after data (and
108
+ # the url) first being built and data fetched.
109
+ UrlBuilder.new self
110
+ end
111
+
108
112
  def routes_finder
109
113
  @routes_finder ||= RoutesFinder.new self
110
114
  end
111
115
 
112
116
  def load_matrix
113
- parsed = JSON.parse client.get(url, instrumentation: {elements: origins.length * destinations.length}).body
117
+ body = client.get(
118
+ sensitive_url,
119
+ instrumentation: instrumentation_for_api_request,
120
+ configuration: configuration
121
+ ).body
122
+
123
+ parsed = JSON.parse(body)
124
+ create_route_objects_for_parsed_data parsed
125
+ end
126
+
127
+ def instrumentation_for_api_request
128
+ {
129
+ elements: origins.length * destinations.length,
130
+ sensitive_url: sensitive_url,
131
+ filtered_url: filtered_url
132
+ }
133
+ end
114
134
 
115
- parsed["rows"].each_with_index.map do |row, origin_index|
135
+ def create_route_objects_for_parsed_data(parsed)
136
+ parsed['rows'].each_with_index.map do |row, origin_index|
116
137
  origin = origins[origin_index]
117
138
 
118
- row["elements"].each_with_index.map do |element, destination_index|
119
- route_attributes = element.merge(origin: origin, destination: destinations[destination_index])
139
+ row['elements'].each_with_index.map do |element, destination_index|
140
+ route_attributes = element.merge(
141
+ origin: origin, destination: destinations[destination_index]
142
+ )
120
143
  Route.new route_attributes
121
144
  end
122
145
  end
@@ -133,9 +156,9 @@ module GoogleDistanceMatrix
133
156
  end
134
157
 
135
158
  def clear_from_cache!
136
- if configuration.cache
137
- configuration.cache.delete ClientCache.key(url)
138
- end
159
+ return if configuration.cache.nil?
160
+
161
+ configuration.cache.delete ClientCache.key(sensitive_url, configuration)
139
162
  end
140
163
  end
141
164
  end
@@ -1,20 +1,22 @@
1
- # Public: Represents a place and knows how to convert it to param.
2
- #
3
- # Examples
4
- #
5
- # GoogleDistanceMatrix::Place.new address: "My address"
6
- # GoogleDistanceMatrix::Place.new lat: 1, lng: 3
7
- #
8
- # You may also build places by other objects responding to lat and lng or address.
9
- # If your object responds to all of the attributes we'll use lat and lng as data
10
- # for the Place.
11
- #
12
- # GoogleDistanceMatrix::Place.new object
1
+ # frozen_string_literal: true
2
+
13
3
  module GoogleDistanceMatrix
4
+ # Public: Represents a place and knows how to convert it to param.
5
+ #
6
+ # Examples
7
+ #
8
+ # GoogleDistanceMatrix::Place.new address: "My address"
9
+ # GoogleDistanceMatrix::Place.new lat: 1, lng: 3
10
+ #
11
+ # You may also build places by other objects responding to lat and lng or address.
12
+ # If your object responds to all of the attributes we'll use lat and lng as data
13
+ # for the Place.
14
+ #
15
+ # GoogleDistanceMatrix::Place.new object
14
16
  class Place
15
- ATTRIBUTES = %w[address lat lng]
17
+ ATTRIBUTES = %w[address lat lng].freeze
16
18
 
17
- attr_reader *ATTRIBUTES, :extracted_attributes_from
19
+ attr_reader(*ATTRIBUTES, :extracted_attributes_from)
18
20
 
19
21
  def initialize(attributes_or_object)
20
22
  if respond_to_needed_attributes? attributes_or_object
@@ -22,7 +24,7 @@ module GoogleDistanceMatrix
22
24
  elsif attributes_or_object.is_a? Hash
23
25
  assign_attributes attributes_or_object
24
26
  else
25
- fail ArgumentError, "Must be either hash or object responding to lat, lng or address. "
27
+ raise ArgumentError, 'Must be either hash or object responding to lat, lng or address. '
26
28
  end
27
29
 
28
30
  validate_attributes
@@ -33,7 +35,6 @@ module GoogleDistanceMatrix
33
35
  address.present? ? address : lat_lng(options[:lat_lng_scale]).join(',')
34
36
  end
35
37
 
36
-
37
38
  def eql?(other)
38
39
  if address.present?
39
40
  address == other.address
@@ -58,7 +59,9 @@ module GoogleDistanceMatrix
58
59
  end
59
60
 
60
61
  def inspect
61
- inspection = (ATTRIBUTES | [:extracted_attributes_from]).reject { |a| public_send(a).blank? }.map { |a| "#{a}: #{public_send(a).inspect}" }.join ', '
62
+ inspection = (ATTRIBUTES | [:extracted_attributes_from])
63
+ .reject { |a| public_send(a).blank? }
64
+ .map { |a| "#{a}: #{public_send(a).inspect}" }.join ', '
62
65
 
63
66
  "#<#{self.class} #{inspection}>"
64
67
  end
@@ -66,19 +69,17 @@ module GoogleDistanceMatrix
66
69
  private
67
70
 
68
71
  def respond_to_needed_attributes?(object)
69
- (object.respond_to?(:lat) && object.respond_to?(:lng)) || object.respond_to?(:address)
72
+ (object.respond_to?(:lat) && object.respond_to?(:lng)) || object.respond_to?(:address)
70
73
  end
71
74
 
72
75
  def extract_and_assign_attributes_from_object(object)
73
- attrs = Hash[ATTRIBUTES.map do |attr_name|
76
+ attrs = Hash[ATTRIBUTES.map do |attr_name|
74
77
  if object.respond_to? attr_name
75
78
  [attr_name, object.public_send(attr_name)]
76
79
  end
77
80
  end.compact]
78
81
 
79
- if attrs.has_key?('lat') || attrs.has_key?('lng')
80
- attrs.delete 'address'
81
- end
82
+ attrs.delete 'address' if attrs.key?('lat') || attrs.key?('lng')
82
83
 
83
84
  @extracted_attributes_from = object
84
85
  assign_attributes attrs
@@ -92,14 +93,20 @@ module GoogleDistanceMatrix
92
93
  @lng = attributes[:lng]
93
94
  end
94
95
 
96
+ # rubocop:disable Metrics/AbcSize
97
+ # rubocop:disable Metrics/CyclomaticComplexity
98
+ # rubocop:disable Style/GuardClause
95
99
  def validate_attributes
96
- unless address.present? || (lat.present? && lng.present?)
97
- fail ArgumentError, "Must provide an address, or lat and lng."
100
+ unless address.present? || (lat.present? && lng.present?)
101
+ raise ArgumentError, 'Must provide an address, or lat and lng.'
98
102
  end
99
103
 
100
104
  if address.present? && lat.present? && lng.present?
101
- fail ArgumentError, "Cannot provide address, lat and lng."
105
+ raise ArgumentError, 'Cannot provide address, lat and lng.'
102
106
  end
103
107
  end
108
+ # rubocop:enable Metrics/AbcSize
109
+ # rubocop:enable Metrics/CyclomaticComplexity
110
+ # rubocop:enable Style/GuardClause
104
111
  end
105
112
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GoogleDistanceMatrix
4
+ # Represents a collection of places
2
5
  class Places
3
6
  include Enumerable
4
7
 
@@ -7,10 +10,9 @@ module GoogleDistanceMatrix
7
10
  concat Array.wrap(places)
8
11
  end
9
12
 
10
-
11
13
  delegate :each, :[], :length, :index, :pop, :shift, :delete_at, :compact, :inspect, to: :places
12
14
 
13
- [:<<, :push, :unshift].each do |method|
15
+ %i[<< push unshift].each do |method|
14
16
  define_method method do |*args|
15
17
  args = ensure_args_are_places args
16
18
 
@@ -22,10 +24,9 @@ module GoogleDistanceMatrix
22
24
  end
23
25
 
24
26
  def concat(other)
25
- push *other
27
+ push(*other)
26
28
  end
27
29
 
28
-
29
30
  private
30
31
 
31
32
  attr_reader :places
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GoogleDistanceMatrix
2
4
  class PolylineEncoder
3
5
  # Calculates deltas between lat_lng values, internal helper class for PolylineEncoder.
@@ -20,7 +22,6 @@ module GoogleDistanceMatrix
20
22
  calculate_deltas rounded
21
23
  end
22
24
 
23
-
24
25
  private
25
26
 
26
27
  def round_to_precision(array_of_lat_lng_pairs)
@@ -42,7 +43,8 @@ module GoogleDistanceMatrix
42
43
  deltas << lat - delta_lat
43
44
  deltas << lng - delta_lng
44
45
 
45
- delta_lat, delta_lng = lat, lng
46
+ delta_lat = lat
47
+ delta_lng = lng
46
48
  end
47
49
 
48
50
  deltas
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Style/NumericPredicate
1
4
  module GoogleDistanceMatrix
2
5
  class PolylineEncoder
3
6
  # Encodes a single value, like 17998321, in to encoded polyline value,
@@ -9,6 +12,8 @@ module GoogleDistanceMatrix
9
12
  #
10
13
  # @see GoogleDistanceMatrix::PolylineEncoder
11
14
  class ValueEncoder
15
+ # rubocop:disable Metrics/MethodLength
16
+ # rubocop:disable Metrics/AbcSize
12
17
  def encode(value)
13
18
  negative = value < 0
14
19
  value = value.abs
@@ -27,7 +32,7 @@ module GoogleDistanceMatrix
27
32
  # Right shift bits to get rid of the ones we just put on the array.
28
33
  # Bits will end up in reverse order.
29
34
  chunks_of_5_bits = []
30
- while value > 0 do
35
+ while value > 0
31
36
  chunks_of_5_bits.push(value & 0x1f)
32
37
  value >>= 5
33
38
  end
@@ -44,6 +49,8 @@ module GoogleDistanceMatrix
44
49
  # step 11: Convert to ASCII
45
50
  chunks_of_5_bits.map(&:chr)
46
51
  end
52
+ # rubocop:enable Metrics/MethodLength
53
+ # rubocop:enable Metrics/AbcSize
47
54
 
48
55
  private
49
56
 
@@ -52,9 +59,9 @@ module GoogleDistanceMatrix
52
59
  # Example of usage
53
60
  # p d 17998321 # => "00000001 00010010 10100001 11110001"
54
61
  def d(v, bits = 32, chunk_size = 8)
55
- (bits - 1).downto(0).
56
- map { |n| v[n] }.
57
- each_slice(chunk_size).map { |chunk| chunk.join }.join ' '
62
+ (bits - 1).downto(0)
63
+ .map { |n| v[n] }
64
+ .each_slice(chunk_size).map(&:join).join ' '
58
65
  end
59
66
  end
60
67
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'polyline_encoder/delta'
2
4
  require_relative 'polyline_encoder/value_encoder'
3
5
 
@@ -7,7 +9,6 @@ module GoogleDistanceMatrix
7
9
  #
8
10
  # See https://developers.google.com/maps/documentation/utilities/polylinealgorithm
9
11
  class PolylineEncoder
10
-
11
12
  # Encodes a set of lat/lng pairs
12
13
  #
13
14
  # Example
@@ -16,7 +17,6 @@ module GoogleDistanceMatrix
16
17
  new(array_of_lat_lng_pairs).encode
17
18
  end
18
19
 
19
-
20
20
  # Initialize a new encoder
21
21
  #
22
22
  # Arguments
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GoogleDistanceMatrix
4
+ # Class integrating with rails
2
5
  class Railtie < Rails::Railtie
3
- initializer "google_distance_matrix.logger_setup" do
6
+ initializer 'google_distance_matrix.logger_setup' do
4
7
  GoogleDistanceMatrix.configure_defaults do |config|
5
8
  config.logger = Rails.logger
6
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GoogleDistanceMatrix
2
4
  # Public: Thin wrapper class for an element in the matrix.
3
5
  #
@@ -15,10 +17,9 @@ module GoogleDistanceMatrix
15
17
  duration_in_traffic_text duration_in_traffic_in_seconds
16
18
  ].freeze
17
19
 
18
- attr_reader *ATTRIBUTES
19
-
20
- delegate *(STATUSES.map { |s| s + '?' }), to: :status, allow_nil: true
20
+ attr_reader(*ATTRIBUTES)
21
21
 
22
+ delegate(*(STATUSES.map { |s| s + '?' }), to: :status, allow_nil: true)
22
23
 
23
24
  def initialize(attributes = {})
24
25
  attributes = attributes.with_indifferent_access
@@ -28,25 +29,31 @@ module GoogleDistanceMatrix
28
29
 
29
30
  @status = ActiveSupport::StringInquirer.new attributes[:status].downcase
30
31
 
31
- if ok?
32
- @distance_text = attributes[:distance][:text]
33
- @distance_in_meters = attributes[:distance][:value]
34
- @duration_text = attributes[:duration][:text]
35
- @duration_in_seconds = attributes[:duration][:value]
32
+ assign attributes if ok?
33
+ end
36
34
 
37
- if attributes.key? :duration_in_traffic
38
- @duration_in_traffic_text = attributes[:duration_in_traffic][:text]
39
- @duration_in_traffic_in_seconds = attributes[:duration_in_traffic][:value]
40
- end
35
+ def inspect
36
+ attrs = ATTRIBUTES.reject do |a|
37
+ public_send(a).blank?
41
38
  end
39
+
40
+ inspection = attrs.map { |a| "#{a}: #{public_send(a).inspect}" }.join ', '
41
+
42
+ "#<#{self.class} #{inspection}>"
42
43
  end
43
44
 
45
+ private
44
46
 
47
+ def assign(attributes)
48
+ @distance_text = attributes[:distance][:text]
49
+ @distance_in_meters = attributes[:distance][:value]
50
+ @duration_text = attributes[:duration][:text]
51
+ @duration_in_seconds = attributes[:duration][:value]
45
52
 
46
- def inspect
47
- inspection = ATTRIBUTES.reject { |a| public_send(a).blank? }.map { |a| "#{a}: #{public_send(a).inspect}" }.join ', '
53
+ return unless attributes.key? :duration_in_traffic
48
54
 
49
- "#<#{self.class} #{inspection}>"
55
+ @duration_in_traffic_text = attributes[:duration_in_traffic][:text]
56
+ @duration_in_traffic_in_seconds = attributes[:duration_in_traffic][:value]
50
57
  end
51
58
  end
52
59
  end
@@ -1,18 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GoogleDistanceMatrix
2
4
  # Public: Has logic for doing finder operations on a matrix.
5
+ #
6
+ # rubocop:disable Metrics/ClassLength
3
7
  class RoutesFinder
4
-
5
8
  attr_reader :matrix
6
9
  delegate :data, :origins, :destinations, :configuration, to: :matrix
7
10
 
8
-
9
11
  def initialize(matrix)
10
12
  @matrix = matrix
11
- end
13
+ end # Public: Finds routes for given place.
12
14
 
13
-
14
-
15
- # Public: Finds routes for given place.
16
15
  #
17
16
  # place - Either an origin or destination, or an object which you built the place from
18
17
  #
@@ -25,7 +24,7 @@ module GoogleDistanceMatrix
25
24
  elsif destinations.include? place
26
25
  routes_for_destination place
27
26
  else
28
- fail ArgumentError, "Given place not an origin nor destination."
27
+ raise ArgumentError, 'Given place not an origin nor destination.'
29
28
  end
30
29
  end
31
30
 
@@ -41,11 +40,11 @@ module GoogleDistanceMatrix
41
40
  end
42
41
  end
43
42
 
44
-
45
43
  # Public: Finds a route for you based on one origin and destination
46
44
  #
47
45
  # origin - A place representing the origin, or an object which you built the origin from
48
- # destination - A place representing the destination, or an object which you built the destination from
46
+ # destination - A place representing the destination, or an object which you built the
47
+ # destination from
49
48
  #
50
49
  # A Route for given origin and destination
51
50
  def route_for(options = {})
@@ -55,7 +54,7 @@ module GoogleDistanceMatrix
55
54
  destination = ensure_place options[:destination]
56
55
 
57
56
  if origin.nil? || destination.nil?
58
- fail ArgumentError, "Must provide origin and destination"
57
+ raise ArgumentError, 'Must provide origin and destination'
59
58
  end
60
59
 
61
60
  routes_for(origin).detect { |route| route.destination == destination }
@@ -71,7 +70,6 @@ module GoogleDistanceMatrix
71
70
  end
72
71
  end
73
72
 
74
-
75
73
  # Public: Finds shortes route by distance to a place.
76
74
  #
77
75
  # place - The place, or object place was built from, you want the shortest route to
@@ -79,7 +77,7 @@ module GoogleDistanceMatrix
79
77
  # Returns shortest route, or nil if no routes had status ok
80
78
  def shortest_route_by_distance_to(place_or_object_place_was_built_from)
81
79
  routes = routes_for place_or_object_place_was_built_from
82
- select_ok_routes(routes).min_by &:distance_in_meters
80
+ select_ok_routes(routes).min_by(&:distance_in_meters)
83
81
  end
84
82
 
85
83
  # Public: Finds shortes route by distance to a place.
@@ -88,7 +86,7 @@ module GoogleDistanceMatrix
88
86
  #
89
87
  # Returns shortest route, fails if any of the routes are not ok
90
88
  def shortest_route_by_distance_to!(place_or_object_place_was_built_from)
91
- routes_for!(place_or_object_place_was_built_from).min_by &:distance_in_meters
89
+ routes_for!(place_or_object_place_was_built_from).min_by(&:distance_in_meters)
92
90
  end
93
91
 
94
92
  # Public: Finds shortes route by duration to a place.
@@ -98,7 +96,7 @@ module GoogleDistanceMatrix
98
96
  # Returns shortest route, or nil if no routes had status ok
99
97
  def shortest_route_by_duration_to(place_or_object_place_was_built_from)
100
98
  routes = routes_for place_or_object_place_was_built_from
101
- select_ok_routes(routes).min_by &:duration_in_seconds
99
+ select_ok_routes(routes).min_by(&:duration_in_seconds)
102
100
  end
103
101
 
104
102
  # Public: Finds shortes route by duration to a place.
@@ -107,7 +105,7 @@ module GoogleDistanceMatrix
107
105
  #
108
106
  # Returns shortest route, fails if any of the routes are not ok
109
107
  def shortest_route_by_duration_to!(place_or_object_place_was_built_from)
110
- routes_for!(place_or_object_place_was_built_from).min_by &:duration_in_seconds
108
+ routes_for!(place_or_object_place_was_built_from).min_by(&:duration_in_seconds)
111
109
  end
112
110
 
113
111
  # Public: Finds shortes route by duration in traffic to a place.
@@ -122,7 +120,7 @@ module GoogleDistanceMatrix
122
120
  ensure_driving_and_departure_time_or_fail!
123
121
 
124
122
  routes = routes_for place_or_object_place_was_built_from
125
- select_ok_routes(routes).min_by &:duration_in_traffic_in_seconds
123
+ select_ok_routes(routes).min_by(&:duration_in_traffic_in_seconds)
126
124
  end
127
125
 
128
126
  # Public: Finds shortes route by duration in traffic to a place.
@@ -136,11 +134,9 @@ module GoogleDistanceMatrix
136
134
  def shortest_route_by_duration_in_traffic_to!(place_or_object_place_was_built_from)
137
135
  ensure_driving_and_departure_time_or_fail!
138
136
 
139
- routes_for!(place_or_object_place_was_built_from).min_by &:duration_in_traffic_in_seconds
137
+ routes_for!(place_or_object_place_was_built_from).min_by(&:duration_in_traffic_in_seconds)
140
138
  end
141
139
 
142
-
143
-
144
140
  private
145
141
 
146
142
  def ensure_place(object)
@@ -148,27 +144,27 @@ module GoogleDistanceMatrix
148
144
  object
149
145
  else
150
146
  find_place_for_object(origins, object) ||
151
- find_place_for_object(destinations, object)
147
+ find_place_for_object(destinations, object)
152
148
  end
153
149
  end
154
150
 
155
151
  def find_place_for_object(collection, object)
156
152
  collection.detect do |place|
157
153
  place.extracted_attributes_from.present? &&
158
- place.extracted_attributes_from == object
154
+ place.extracted_attributes_from == object
159
155
  end
160
156
  end
161
157
 
162
158
  def routes_for_origin(origin)
163
159
  index = origins.index origin
164
- fail ArgumentError, "Given origin is not i matrix."if index.nil?
160
+ raise ArgumentError, 'Given origin is not i matrix.' if index.nil?
165
161
 
166
162
  data[index]
167
163
  end
168
164
 
169
165
  def routes_for_destination(destination)
170
166
  index = destinations.index destination
171
- fail ArgumentError, "Given destination is not i matrix." if index.nil?
167
+ raise ArgumentError, 'Given destination is not i matrix.' if index.nil?
172
168
 
173
169
  [].tap do |routes|
174
170
  data.each { |row| routes << row[index] }
@@ -180,24 +176,24 @@ module GoogleDistanceMatrix
180
176
  destination_index = destinations.index destination
181
177
 
182
178
  if origin_index.nil? || destination_index.nil?
183
- fail ArgumentError, "Given origin or destination is not i matrix."
179
+ raise ArgumentError, 'Given origin or destination is not i matrix.'
184
180
  end
185
181
 
186
182
  [data[origin_index][destination_index]]
187
183
  end
188
184
 
189
185
  def fail_unless_route_is_ok(route)
190
- fail InvalidRoute.new route unless route.ok?
186
+ raise InvalidRoute, route unless route.ok?
191
187
  end
192
188
 
193
189
  def select_ok_routes(routes)
194
- routes.select &:ok?
190
+ routes.select(&:ok?)
195
191
  end
196
192
 
197
193
  def ensure_driving_and_departure_time_or_fail!
198
- if configuration.mode != 'driving' || configuration.departure_time.nil?
199
- fail InvalidQuery, "Matrix must be in mode driving and a departure_time must be set"
200
- end
194
+ return if configuration.mode == 'driving' && configuration.departure_time.present?
195
+
196
+ raise InvalidQuery, 'Matrix must be in mode driving and a departure_time must be set'
201
197
  end
202
198
  end
203
199
  end