metar-parser 1.1.4 → 1.1.5

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.
data/lib/metar/data.rb CHANGED
@@ -4,14 +4,13 @@ require 'm9t'
4
4
 
5
5
  module Metar
6
6
  locales_path = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'locales'))
7
- I18n.load_path += Dir.glob("#{ locales_path }/*.yml")
7
+ I18n.load_path += Dir.glob("#{locales_path}/*.yml")
8
8
 
9
9
  class Distance < M9t::Distance
10
-
11
10
  attr_accessor :units
12
11
 
13
12
  # nil is taken to mean 'data unavailable'
14
- def initialize( meters = nil )
13
+ def initialize(meters = nil)
15
14
  @units = :meters
16
15
  if meters
17
16
  super
@@ -21,19 +20,19 @@ module Metar
21
20
  end
22
21
 
23
22
  # Handles nil case differently to M9t::Distance
24
- def to_s( options = {} )
25
- options = { :units => @units,
26
- :precision => 0,
27
- :abbreviated => true }.merge( options )
23
+ def to_s(options = {})
24
+ options = {
25
+ :units => @units,
26
+ :precision => 0,
27
+ :abbreviated => true
28
+ }.merge(options)
28
29
  return I18n.t('metar.distance.unknown') if @value.nil?
29
- super( options )
30
+ super(options)
30
31
  end
31
-
32
32
  end
33
33
 
34
34
  # Adds a parse method to the M9t base class
35
35
  class Speed < M9t::Speed
36
-
37
36
  METAR_UNITS = {
38
37
  '' => :kilometers_per_hour,
39
38
  'KMH' => :kilometers_per_hour,
@@ -41,43 +40,39 @@ module Metar
41
40
  'KT' => :knots,
42
41
  }
43
42
 
44
- def Speed.parse(s)
43
+ def self.parse(s)
45
44
  case
46
45
  when s =~ /^(\d+)(|KT|MPS|KMH)$/
47
46
  # Call the appropriate factory method for the supplied units
48
- send( METAR_UNITS[$2], $1.to_i )
47
+ send(METAR_UNITS[$2], $1.to_i)
49
48
  else
50
49
  nil
51
50
  end
52
51
  end
53
-
54
52
  end
55
53
 
56
54
  # Adds a parse method to the M9t base class
57
55
  class Temperature < M9t::Temperature
58
-
59
- def Temperature.parse(s)
56
+ def self.parse(s)
60
57
  if s =~ /^(M?)(\d+)$/
61
58
  sign = $1
62
59
  value = $2.to_i
63
60
  value *= -1 if sign == 'M'
64
- new( value )
61
+ new(value)
65
62
  else
66
63
  nil
67
64
  end
68
65
  end
69
66
 
70
- def to_s( options = {} )
71
- options = { :abbreviated => true, :precision => 0 }.merge( options )
72
- super( options )
67
+ def to_s(options = {})
68
+ options = {:abbreviated => true, :precision => 0}.merge(options)
69
+ super(options)
73
70
  end
74
-
75
71
  end
76
72
 
77
73
  # Adds a parse method to the M9t base class
78
74
  class Pressure < M9t::Pressure
79
-
80
- def Pressure.parse(pressure)
75
+ def self.parse(pressure)
81
76
  case
82
77
  when pressure =~ /^Q(\d{4})$/
83
78
  hectopascals($1.to_f)
@@ -87,44 +82,34 @@ module Metar
87
82
  nil
88
83
  end
89
84
  end
90
-
91
85
  end
92
86
 
93
87
  class Direction < M9t::Direction
94
- def initialize( direction )
95
- direction = M9t::Direction::normalize( direction.to_f )
96
- super( direction )
88
+ def initialize(direction)
89
+ direction = M9t::Direction::normalize(direction.to_f)
90
+ super(direction)
97
91
  end
98
92
  end
99
93
 
100
94
  class Wind
101
-
102
- def Wind.parse(s)
95
+ def self.parse(s)
103
96
  case
104
97
  when s =~ /^(\d{3})(\d{2}(|MPS|KMH|KT))$/
105
98
  return nil if $1.to_i > 360
106
- new( Direction.new( $1 ),
107
- Speed.parse( $2 ) )
99
+ new(Direction.new($1), Speed.parse($2))
108
100
  when s =~ /^(\d{3})(\d{2})G(\d{2,3}(|MPS|KMH|KT))$/
109
101
  return nil if $1.to_i > 360
110
- new( Direction.new( $1 ),
111
- Speed.parse( $2 + $4 ),
112
- Speed.parse( $3 ) )
102
+ new(Direction.new($1), Speed.parse($2 + $4), Speed.parse($3))
113
103
  when s =~ /^VRB(\d{2})G(\d{2,3})(|MPS|KMH|KT)$/
114
104
  speed = $1 + $3
115
105
  gusts = $2 + $3
116
- new( :variable_direction,
117
- Speed.parse(speed),
118
- Speed.parse(gusts))
106
+ new(:variable_direction, Speed.parse(speed), Speed.parse(gusts))
119
107
  when s =~ /^VRB(\d{2}(|MPS|KMH|KT))$/
120
- new( :variable_direction,
121
- Speed.parse($1))
108
+ new(:variable_direction, Speed.parse($1))
122
109
  when s =~ /^\/{3}(\d{2}(|MPS|KMH|KT))$/
123
- new( :unknown_direction,
124
- Speed.parse($1))
110
+ new(:unknown_direction, Speed.parse($1))
125
111
  when s =~ %r(^/////(|MPS|KMH|KT)$)
126
- new( :unknown_direction,
127
- :unknown_speed)
112
+ new(:unknown_direction, :unknown_speed)
128
113
  else
129
114
  nil
130
115
  end
@@ -132,21 +117,25 @@ module Metar
132
117
 
133
118
  attr_reader :direction, :speed, :gusts
134
119
 
135
- def initialize( direction, speed, gusts = nil )
120
+ def initialize(direction, speed, gusts = nil)
136
121
  @direction, @speed, @gusts = direction, speed, gusts
137
122
  end
138
123
 
139
- def to_s( options = {} )
140
- options = { :direction_units => :compass,
141
- :speed_units => :kilometers_per_hour }.merge( options )
124
+ def to_s(options = {})
125
+ options = {
126
+ :direction_units => :compass,
127
+ :speed_units => :kilometers_per_hour
128
+ }.merge(options)
142
129
  speed =
143
130
  case @speed
144
131
  when :unknown_speed
145
132
  I18n.t('metar.wind.unknown_speed')
146
133
  else
147
- @speed.to_s( :abbreviated => true,
148
- :precision => 0,
149
- :units => options[ :speed_units ] )
134
+ @speed.to_s(
135
+ :abbreviated => true,
136
+ :precision => 0,
137
+ :units => options[:speed_units]
138
+ )
150
139
  end
151
140
  direction =
152
141
  case @direction
@@ -155,23 +144,23 @@ module Metar
155
144
  when :unknown_direction
156
145
  I18n.t('metar.wind.unknown_direction')
157
146
  else
158
- @direction.to_s( :units => options[ :direction_units ] )
147
+ @direction.to_s(:units => options[:direction_units])
159
148
  end
160
- s = "#{ speed } #{ direction }"
161
- if ! @gusts.nil?
162
- g = @gusts.to_s( :abbreviated => true,
163
- :precision => 0,
164
- :units => options[ :speed_units ] )
165
- s += " #{ I18n.t('metar.wind.gusts') } #{ g }"
149
+ s = "#{speed} #{direction}"
150
+ if not @gusts.nil?
151
+ g = @gusts.to_s(
152
+ :abbreviated => true,
153
+ :precision => 0,
154
+ :units => options[:speed_units]
155
+ )
156
+ s += " #{I18n.t('metar.wind.gusts')} #{g}"
166
157
  end
167
158
  s
168
159
  end
169
-
170
160
  end
171
161
 
172
162
  class VariableWind
173
-
174
- def VariableWind.parse(variable_wind)
163
+ def self.parse(variable_wind)
175
164
  if variable_wind =~ /^(\d+)V(\d+)$/
176
165
  new(Direction.new($1), Direction.new($2))
177
166
  else
@@ -186,38 +175,36 @@ module Metar
186
175
  end
187
176
 
188
177
  def to_s
189
- "#{ @direction1.to_s( :units => :compass ) } - #{ @direction2.to_s( :units => :compass ) }"
178
+ "#{@direction1.to_s(:units => :compass)} - #{@direction2.to_s(:units => :compass)}"
190
179
  end
191
-
192
180
  end
193
181
 
194
182
  class Visibility
195
-
196
- def Visibility.parse(s)
183
+ def self.parse(s)
197
184
  case
198
185
  when s == '9999'
199
- new( Distance.new( 10000 ), nil, :more_than )
186
+ new(Distance.new(10000), nil, :more_than)
200
187
  when s =~ /(\d{4})NDV/ # WMO
201
- new( Distance.new( $1.to_f ) ) # Assuming meters
188
+ new(Distance.new($1.to_f)) # Assuming meters
202
189
  when (s =~ /^((1|2)\s|)([1357])\/([248]|16)SM$/) # US
203
190
  miles = $1.to_f + $3.to_f / $4.to_f
204
- distance = Distance.miles( miles )
191
+ distance = Distance.miles(miles)
205
192
  distance.units = :miles
206
- new( distance )
193
+ new(distance)
207
194
  when s =~ /^(\d+)SM$/ # US
208
- distance = Distance.miles( $1.to_f )
195
+ distance = Distance.miles($1.to_f)
209
196
  distance.units = :miles
210
- new( distance )
197
+ new(distance)
211
198
  when s == 'M1/4SM' # US
212
- distance = Distance.miles( 0.25 )
199
+ distance = Distance.miles(0.25)
213
200
  distance.units = :miles
214
- new( distance, nil, :less_than )
201
+ new(distance, nil, :less_than)
215
202
  when s =~ /^(\d+)KM$/
216
- new( Distance.kilometers( $1 ) )
203
+ new(Distance.kilometers($1))
217
204
  when s =~ /^(\d+)$/ # We assume meters
218
- new( Distance.new( $1 ) )
205
+ new(Distance.new($1))
219
206
  when s =~ /^(\d+)(N|NE|E|SE|S|SW|W|NW)$/
220
- new( Distance.meters( $1 ), M9t::Direction.compass( $2 ) )
207
+ new(Distance.meters($1), M9t::Direction.compass($2))
221
208
  else
222
209
  nil
223
210
  end
@@ -229,36 +216,42 @@ module Metar
229
216
  @distance, @direction, @comparator = distance, direction, comparator
230
217
  end
231
218
 
232
- def to_s( options = {} )
233
- distance_options = { :abbreviated => true,
234
- :precision => 0,
235
- :units => :kilometers }.merge( options )
236
- direction_options = { :units => :compass }
219
+ def to_s(options = {})
220
+ distance_options = {
221
+ :abbreviated => true,
222
+ :precision => 0,
223
+ :units => :kilometers
224
+ }.merge(options)
225
+ direction_options = {:units => :compass}
237
226
  case
238
- when ( @direction.nil? and @comparator.nil? )
239
- @distance.to_s( distance_options )
227
+ when (@direction.nil? and @comparator.nil?)
228
+ @distance.to_s(distance_options)
240
229
  when @comparator.nil?
241
- "%s %s" % [ @distance.to_s( distance_options ),
242
- @direction.to_s( direction_options ) ]
230
+ [
231
+ @distance.to_s(distance_options),
232
+ @direction.to_s(direction_options)
233
+ ].join(' ')
243
234
  when @direction.nil?
244
- "%s %s" % [ I18n.t( 'comparison.' + @comparator.to_s ),
245
- @distance.to_s( distance_options ) ]
235
+ [
236
+ I18n.t('comparison.' + @comparator.to_s),
237
+ @distance.to_s(distance_options)
238
+ ].join(' ')
246
239
  else
247
- "%s %s %s" % [ I18n.t( 'comparison.' + @comparator.to_s ),
248
- @distance.to_s( distance_options ),
249
- @direction.to_s( direction_options ) ]
240
+ [
241
+ I18n.t('comparison.' + @comparator.to_s),
242
+ @distance.to_s(distance_options),
243
+ @direction.to_s(direction_options)
244
+ ].join(' ')
250
245
  end
251
246
  end
252
-
253
247
  end
254
248
 
255
249
  class RunwayVisibleRange
250
+ TENDENCY = {'' => nil, 'N' => :no_change, 'U' => :improving, 'D' => :worsening}
251
+ COMPARATOR = {'' => nil, 'P' => :more_than, 'M' => :less_than}
252
+ UNITS = {'' => :meters, 'FT' => :feet}
256
253
 
257
- TENDENCY = { '' => nil, 'N' => :no_change, 'U' => :improving, 'D' => :worsening }
258
- COMPARATOR = { '' => nil, 'P' => :more_than, 'M' => :less_than }
259
- UNITS = { '' => :meters, 'FT' => :feet }
260
-
261
- def RunwayVisibleRange.parse(runway_visible_range)
254
+ def self.parse(runway_visible_range)
262
255
  case
263
256
  when runway_visible_range =~ /^R(\d+[RLC]?)\/(P|M|)(\d{4})(N|U|D|)(FT|)$/
264
257
  designator = $1
@@ -266,7 +259,7 @@ module Metar
266
259
  count = $3.to_f
267
260
  tendency = TENDENCY[$4]
268
261
  units = UNITS[$5]
269
- distance = Distance.send( units, count )
262
+ distance = Distance.send(units, count)
270
263
  visibility = Visibility.new(distance, nil, comparator)
271
264
  new(designator, visibility, nil, tendency)
272
265
  when runway_visible_range =~ /^R(\d+[RLC]?)\/(P|M|)(\d{4})V(P|M|)(\d{4})(N|U|D)?(FT|)$/
@@ -277,50 +270,50 @@ module Metar
277
270
  count2 = $5.to_f
278
271
  tendency = TENDENCY[$6]
279
272
  units = UNITS[$7]
280
- distance1 = Distance.send( units, count1 )
281
- distance2 = Distance.send( units, count2 )
282
- visibility1 = Visibility.new( distance1, nil, comparator1 )
283
- visibility2 = Visibility.new( distance2, nil, comparator2 )
284
- new( designator, visibility1, visibility2, tendency, units )
273
+ distance1 = Distance.send(units, count1)
274
+ distance2 = Distance.send(units, count2)
275
+ visibility1 = Visibility.new(distance1, nil, comparator1)
276
+ visibility2 = Visibility.new(distance2, nil, comparator2)
277
+ new(designator, visibility1, visibility2, tendency, units)
285
278
  else
286
279
  nil
287
280
  end
288
281
  end
289
282
 
290
283
  attr_reader :designator, :visibility1, :visibility2, :tendency
291
- def initialize( designator, visibility1, visibility2 = nil, tendency = nil, units = :meters )
284
+ def initialize(designator, visibility1, visibility2 = nil, tendency = nil, units = :meters)
292
285
  @designator, @visibility1, @visibility2, @tendency, @units = designator, visibility1, visibility2, tendency, units
293
286
  end
294
287
 
295
288
  def to_s
296
- distance_options = { :abbreviated => true,
297
- :precision => 0,
298
- :units => @units }
289
+ distance_options = {
290
+ :abbreviated => true,
291
+ :precision => 0,
292
+ :units => @units
293
+ }
299
294
  s =
300
295
  if @visibility2.nil?
301
- I18n.t( 'metar.runway_visible_range.runway') +
302
- ' ' + @designator +
303
- ': ' + @visibility1.to_s( distance_options )
296
+ I18n.t('metar.runway_visible_range.runway') +
297
+ ' ' + @designator +
298
+ ': ' + @visibility1.to_s(distance_options)
304
299
  else
305
- I18n.t( 'metar.runway_visible_range.runway') +
306
- ' ' + @designator +
307
- ': ' + I18n.t('metar.runway_visible_range.from') +
308
- ' ' + @visibility1.to_s( distance_options ) +
309
- ' ' + I18n.t('metar.runway_visible_range.to') +
310
- ' ' + @visibility2.to_s( distance_options )
300
+ I18n.t('metar.runway_visible_range.runway') +
301
+ ' ' + @designator +
302
+ ': ' + I18n.t('metar.runway_visible_range.from') +
303
+ ' ' + @visibility1.to_s(distance_options) +
304
+ ' ' + I18n.t('metar.runway_visible_range.to') +
305
+ ' ' + @visibility2.to_s(distance_options)
311
306
  end
312
307
 
313
308
  if ! tendency.nil?
314
- s += ' ' + I18n.t( "tendency.#{ tendency }" )
309
+ s += ' ' + I18n.t("tendency.#{tendency}")
315
310
  end
316
311
 
317
312
  s
318
313
  end
319
-
320
314
  end
321
315
 
322
316
  class WeatherPhenomenon
323
-
324
317
  Modifiers = {
325
318
  '+' => 'heavy',
326
319
  '-' => 'light',
@@ -368,21 +361,21 @@ module Metar
368
361
  }
369
362
 
370
363
  # Accepts all standard (and some non-standard) present weather codes
371
- def WeatherPhenomenon.parse(s)
364
+ def self.parse(s)
372
365
  phenomena = Phenomena.keys.join('|')
373
366
  descriptors = Descriptors.keys.join('|')
374
367
  modifiers = Modifiers.keys.join('|')
375
368
  modifiers.gsub!(/([\+\-])/) { "\\#$1" }
376
- rxp = Regexp.new("^(#{ modifiers })?(#{ descriptors })?((?:#{ phenomena }){1,2})$")
369
+ rxp = Regexp.new("^(#{modifiers})?(#{descriptors})?((?:#{phenomena}){1,2})$")
377
370
  m = rxp.match(s)
378
371
  return nil if m.nil?
379
372
 
380
373
  modifier_code = m[1]
381
374
  descriptor_code = m[2]
382
375
  phenomena_codes = m[3].scan(/../)
383
- phenomena_phrase = phenomena_codes.map{ |c| Phenomena[c] }.join(' and ')
376
+ phenomena_phrase = phenomena_codes.map { |c| Phenomena[c] }.join(' and ')
384
377
 
385
- Metar::WeatherPhenomenon.new(phenomena_phrase, Modifiers[modifier_code], Descriptors[descriptor_code])
378
+ new(phenomena_phrase, Modifiers[modifier_code], Descriptors[descriptor_code])
386
379
  end
387
380
 
388
381
  attr_reader :phenomenon, :modifier, :descriptor
@@ -393,11 +386,9 @@ module Metar
393
386
  def to_s
394
387
  I18n.t("metar.present_weather.%s" % [@modifier, @descriptor, @phenomenon].compact.join(' '))
395
388
  end
396
-
397
389
  end
398
390
 
399
391
  class SkyCondition
400
-
401
392
  QUANTITY = {'BKN' => 'broken', 'FEW' => 'few', 'OVC' => 'overcast', 'SCT' => 'scattered'}
402
393
  CONDITION = {
403
394
  'CB' => 'cumulonimbus',
@@ -412,22 +403,22 @@ module Metar
412
403
  'SKC',
413
404
  ]
414
405
 
415
- def SkyCondition.parse(sky_condition)
406
+ def self.parse(sky_condition)
416
407
  case
417
- when CLEAR_SKIES.include?( sky_condition )
408
+ when CLEAR_SKIES.include?(sky_condition)
418
409
  new
419
410
  when sky_condition =~ /^(BKN|FEW|OVC|SCT)(\d+|\/{3})(CB|TCU|\/{3}|)?$/
420
- quantity = QUANTITY[ $1 ]
411
+ quantity = QUANTITY[$1]
421
412
  height =
422
413
  if $2 == '///'
423
414
  nil
424
415
  else
425
- Distance.new( $2.to_i * 30.48 )
416
+ Distance.new($2.to_i * 30.48)
426
417
  end
427
- type = CONDITION[ $3 ]
418
+ type = CONDITION[$3]
428
419
  new(quantity, height, type)
429
420
  when sky_condition =~ /^(CB|TCU)$/
430
- type = CONDITION[ $1 ]
421
+ type = CONDITION[$1]
431
422
  new(nil, nil, type)
432
423
  else
433
424
  nil
@@ -452,29 +443,25 @@ module Metar
452
443
  I18n.t('metar.sky_conditions.clear skies')
453
444
  else
454
445
  type = @type ? ' ' + @type : ''
455
- I18n.t("metar.sky_conditions.#{ @quantity }#{ type }")
446
+ I18n.t("metar.sky_conditions.#{@quantity}#{type}")
456
447
  end
457
448
  end
458
-
459
449
  end
460
450
 
461
451
  class VerticalVisibility
462
-
463
- def VerticalVisibility.parse( vertical_visibility )
452
+ def self.parse(vertical_visibility)
464
453
  case
465
454
  when vertical_visibility =~ /^VV(\d{3})$/
466
- Distance.new( $1.to_f * 30.48 )
455
+ Distance.new($1.to_f * 30.48)
467
456
  when vertical_visibility == '///'
468
457
  Distance.new
469
458
  else
470
459
  nil
471
460
  end
472
461
  end
473
-
474
462
  end
475
463
 
476
464
  class Remark
477
-
478
465
  PRESSURE_CHANGE_CHARACTER = [
479
466
  :increasing_then_decreasing, # 0
480
467
  :increasing_then_steady, # 1
@@ -488,7 +475,7 @@ module Metar
488
475
  ]
489
476
 
490
477
  INDICATOR_TYPE = {
491
- 'TS' => :thunderstorm_information,
478
+ 'TS' => :thunderstorm_information,
492
479
  'PWI' => :precipitation_identifier,
493
480
  'P' => :precipitation_amount,
494
481
  }
@@ -556,89 +543,20 @@ module Metar
556
543
  def self.inches_to_meters(digits)
557
544
  digits.to_f * 0.000254
558
545
  end
559
-
560
- end
561
-
562
- class TemperatureExtreme
563
-
564
- attr_accessor :value
565
- attr_accessor :extreme
566
-
567
- def initialize(extreme, value)
568
- @extreme, @value = extreme, value
569
- end
570
-
571
546
  end
572
547
 
573
- class PressureTendency
574
-
575
- attr_accessor :value
576
- attr_accessor :character
548
+ TemperatureExtreme = Struct.new(:extreme, :value)
549
+ PressureTendency = Struct.new(:character, :value)
550
+ Precipitation = Struct.new(:period, :amount)
551
+ AutomatedStationType = Struct.new(:type)
552
+ HourlyTemperaturAndDewPoint = Struct.new(:temperature, :dew_point)
553
+ SeaLevelPressure = Struct.new(:pressure)
554
+ SensorStatusIndicator = Struct.new(:type, :state)
555
+ ColorCode = Struct.new(:code)
577
556
 
578
- def initialize(character, value)
579
- @character, @value = character, value
580
- end
581
-
582
- end
583
-
584
- class Precipitation
585
-
586
- attr_accessor :period
587
- attr_accessor :amount
588
-
589
- def initialize(period, amount)
590
- @period, @amount = period, amount
591
- end
592
-
593
- end
594
-
595
- class AutomatedStationType
596
-
597
- attr_accessor :type
598
-
599
- def initialize(type)
600
- @type = type
601
- end
602
-
603
- end
604
-
605
- class HourlyTemperaturAndDewPoint
606
-
607
- attr_accessor :temperature
608
- attr_accessor :dew_point
609
-
610
- def initialize(temperature, dew_point)
611
- @temperature, @dew_point = temperature, dew_point
612
- end
613
-
614
- end
615
-
616
- class SeaLevelPressure
617
-
618
- attr_accessor :pressure
619
-
620
- def initialize(pressure)
621
- @pressure = pressure
622
- end
623
-
624
- end
625
-
626
- class SensorStatusIndicator
627
-
628
- attr_accessor :type
629
- attr_accessor :state
630
-
631
- def initialize(type, state)
632
- @type, @state = type, state
633
- end
634
-
635
- end
636
-
637
- class MaintenanceNeeded
638
- end
557
+ class MaintenanceNeeded; end
639
558
 
640
559
  class Lightning
641
-
642
560
  TYPE = {'' => :default}
643
561
 
644
562
  def self.parse_chunks(chunks)
@@ -695,18 +613,15 @@ module Metar
695
613
  end
696
614
 
697
615
  class VisibilityRemark < Visibility
698
-
699
616
  def self.parse(chunk)
700
617
  chunk =~ /^(\d{4})([NESW]?)$/
701
618
  distance = Distance.new($1)
702
619
 
703
620
  new(distance, $2, :more_than)
704
621
  end
705
-
706
622
  end
707
623
 
708
624
  class DensityAltitude
709
-
710
625
  def self.parse(chunk)
711
626
  chunk =~ /^(\d+)(FT)$/
712
627
  height = Distance.feet($1)
@@ -719,18 +634,6 @@ module Metar
719
634
  def initialize(height)
720
635
  @height = height
721
636
  end
722
-
723
- end
724
-
725
- class ColorCode
726
-
727
- attr_accessor :code
728
-
729
- def initialize(code)
730
- @code = code
731
- end
732
-
733
637
  end
734
-
735
638
  end
736
639
 
data/lib/metar/parser.rb CHANGED
@@ -301,7 +301,11 @@ module Metar
301
301
  break if @chunks.size == 0
302
302
  r = Metar::Remark.parse(@chunks[0])
303
303
  if r
304
- @remarks += [*r]
304
+ if r.is_a?(Array)
305
+ @remarks += r
306
+ else
307
+ @remarks << r
308
+ end
305
309
  @chunks.shift
306
310
  next
307
311
  end
data/lib/metar/report.rb CHANGED
@@ -40,7 +40,7 @@ module Metar
40
40
  end
41
41
 
42
42
  def time
43
- "%u:%u" % [@parser.time.hour, @parser.time.min]
43
+ "%u:%02u" % [@parser.time.hour, @parser.time.min]
44
44
  end
45
45
 
46
46
  def observer
data/lib/metar/version.rb CHANGED
@@ -2,7 +2,7 @@ module Metar
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
4
  MINOR = 1
5
- TINY = 4
5
+ TINY = 5
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -1,32 +1,28 @@
1
1
  # encoding: utf-8
2
- load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
2
+ require 'spec_helper'
3
3
 
4
4
  describe Metar::Parser do
5
-
6
- after :each do
5
+ after do
7
6
  Metar::Parser.compliance = :loose
8
7
  end
9
8
 
10
9
  context '.for_cccc' do
11
-
12
10
  it 'returns a loaded parser' do
13
- station = stub( 'station' )
14
- raw = stub( 'raw', :metar => "XXXX 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000",
15
- :time => '2010/02/06 16:10' )
16
- Metar::Station.stub!( :new => station )
17
- Metar::Raw::Noaa.stub!( :new => raw )
11
+ station = stub('station')
12
+ raw = stub('raw', :metar => "XXXX 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000",
13
+ :time => '2010/02/06 16:10')
14
+ Metar::Station.stub!(:new => station)
15
+ Metar::Raw::Noaa.stub!(:new => raw)
18
16
 
19
- parser = Metar::Parser.for_cccc( 'XXXX' )
17
+ parser = Metar::Parser.for_cccc('XXXX')
20
18
 
21
- parser. should be_a( Metar::Parser )
22
- parser.station_code. should == 'XXXX'
19
+ expect(parser).to be_a(Metar::Parser)
20
+ expect(parser.station_code).to eq('XXXX')
23
21
  end
24
-
25
22
  end
26
23
 
27
24
  context 'attributes' do
28
-
29
- before :each do
25
+ before do
30
26
  @call_time = Time.parse('2011-05-06 16:35')
31
27
  Time.stub!(:now).and_return(@call_time)
32
28
  end
@@ -34,315 +30,262 @@ describe Metar::Parser do
34
30
  it '.location missing' do
35
31
  expect do
36
32
  setup_parser("FUBAR 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
37
- end. to raise_error( Metar::ParseError, /Expecting location/ )
33
+ end.to raise_error(Metar::ParseError, /Expecting location/)
38
34
  end
39
35
 
40
36
  context 'datetime' do
41
-
42
37
  it 'is parsed' do
43
38
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
44
39
 
45
- parser.time. should == Time.gm(2011, 05, 06, 16, 10)
40
+ expect(parser.time).to eq(Time.gm(2011, 05, 06, 16, 10))
46
41
  end
47
42
 
48
43
  it 'throws an error is missing' do
49
44
  expect do
50
45
  setup_parser("PAIL 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
51
- end. to raise_error( Metar::ParseError, /Expecting datetime/ )
46
+ end.to raise_error(Metar::ParseError, /Expecting datetime/)
52
47
  end
53
48
 
54
49
  context 'in strict mode' do
55
-
56
- before :each do
50
+ before do
57
51
  Metar::Parser.compliance = :strict
58
52
  end
59
53
 
60
54
  it 'less than 6 numerals fails' do
61
55
  expect do
62
56
  parser = setup_parser('MMCE 21645Z 12010KT 8SM SKC 29/26 A2992 RMK')
63
- end. to raise_error(Metar::ParseError, /Expecting datetime/)
57
+ end.to raise_error(Metar::ParseError, /Expecting datetime/)
64
58
  end
65
-
66
59
  end
67
60
 
68
61
  context 'in loose mode' do
69
-
70
62
  it '5 numerals parses' do
71
63
  parser = setup_parser('MMCE 21645Z 12010KT 8SM SKC 29/26 A2992 RMK')
72
64
 
73
- parser.time. should == Time.gm(2011, 05, 02, 16, 45)
65
+ expect(parser.time).to eq(Time.gm(2011, 05, 02, 16, 45))
74
66
  end
75
67
 
76
68
  it "with 4 numerals parses, takes today's day" do
77
69
  parser = setup_parser('HKML 1600Z 19010KT 9999 FEW022 25/22 Q1015')
78
70
 
79
- parser.time. should == Time.gm(2011, 05, 06, 16, 00)
71
+ expect(parser.time).to eq(Time.gm(2011, 05, 06, 16, 00))
80
72
  end
81
-
82
73
  end
83
-
84
74
  end
85
75
 
86
76
  context '.observer' do
87
-
88
77
  it 'real' do
89
78
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
90
79
 
91
- parser.observer. should == :real
80
+ expect(parser.observer).to eq(:real)
92
81
  end
93
82
 
94
83
  it 'auto' do
95
84
  parser = setup_parser("CYXS 151034Z AUTO 09003KT 1/8SM FZFG VV001 M03/M03 A3019 RMK SLP263 ICG")
96
85
 
97
- parser.observer. should == :auto
86
+ expect(parser.observer).to eq(:auto)
98
87
  end
99
88
 
100
89
  it 'corrected' do
101
90
  parser = setup_parser("PAIL 061610Z COR 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
102
91
 
103
- parser.observer. should == :corrected
92
+ expect(parser.observer).to eq(:corrected)
104
93
  end
105
94
 
106
95
  it 'corrected (Canadian)' do
107
96
  parser = setup_parser('CYZU 310100Z CCA 26004KT 15SM FEW009 BKN040TCU BKN100 OVC210 15/12 A2996 RETS RMK SF1TCU4AC2CI1 SLP149')
108
97
 
109
- parser.observer. should == :corrected
98
+ expect(parser.observer).to eq(:corrected)
110
99
  end
111
-
112
100
  end
113
101
 
114
102
  it 'wind' do
115
103
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
116
104
 
117
- parser.wind.direction.value.should be_within( 0.0001 ).of( 240 )
118
- parser.wind.speed.to_knots. should be_within( 0.0001 ).of( 6 )
105
+ expect(parser.wind.direction.value).to be_within(0.0001).of(240)
106
+ expect(parser.wind.speed.to_knots).to be_within(0.0001).of(6)
119
107
  end
120
108
 
121
109
  it 'variable_wind' do
122
110
  parser = setup_parser("LIRQ 061520Z 01007KT 350V050 9999 SCT035 BKN080 08/02 Q1005")
123
111
 
124
- parser.variable_wind.direction1.value.
125
- should be_within( 0.0001 ).of( 350 )
126
- parser.variable_wind.direction2.value.
127
- should be_within( 0.0001 ).of( 50 )
112
+ expect(parser.variable_wind.direction1.value).to be_within(0.0001).of(350)
113
+ expect(parser.variable_wind.direction2.value).to be_within(0.0001).of(50)
128
114
  end
129
115
 
130
116
  context '.visibility' do
131
117
  it 'CAVOK' do
132
118
  parser = setup_parser("PAIL 061610Z 24006KT CAVOK M17/M20 A2910 RMK AO2 P0000")
133
119
 
134
- parser.visibility.distance.value.
135
- should be_within( 0.01 ).of( 10000.00 )
136
- parser.visibility.comparator.
137
- should == :more_than
138
- parser.present_weather.size.
139
- should == 1
140
- parser.present_weather[ 0 ].phenomenon.
141
- should == 'No significant weather'
142
- parser.sky_conditions.size.
143
- should == 1
144
- parser.sky_conditions[ 0 ].type.
145
- should == nil
120
+ expect(parser.visibility.distance.value).to be_within(0.01).of(10000.00)
121
+ expect(parser.visibility.comparator).to eq(:more_than)
122
+ expect(parser.present_weather.size).to eq(1)
123
+ expect(parser.present_weather[0].phenomenon).to eq('No significant weather')
124
+ expect(parser.sky_conditions.size).to eq(1)
125
+ expect(parser.sky_conditions[0].type).to eq(nil)
146
126
  end
147
127
 
148
128
  it 'visibility_miles_and_fractions' do
149
129
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
150
130
 
151
- parser.visibility.distance.to_miles.
152
- should be_within( 0.01 ).of( 1.75 )
131
+ expect(parser.visibility.distance.to_miles).to be_within(0.01).of(1.75)
153
132
  end
154
133
 
155
134
  it 'in meters' do
156
135
  parser = setup_parser('VABB 282210Z 22005KT 4000 HZ SCT018 FEW025TCU BKN100 28/25 Q1003 NOSIG')
157
136
 
158
- parser.visibility.distance.value.
159
- should be_within(0.01).of(4000)
137
+ expect(parser.visibility.distance.value).to be_within(0.01).of(4000)
160
138
  end
161
139
 
162
140
  it '//// with automatic observer' do
163
141
  parser = setup_parser("CYXS 151034Z AUTO 09003KT //// FZFG VV001 M03/M03 A3019 RMK SLP263 ICG")
164
142
 
165
- parser.visibility. should be_nil
143
+ expect(parser.visibility).to be_nil
166
144
  end
167
145
  end
168
146
 
169
147
  it 'runway_visible_range' do
170
148
  parser = setup_parser("ESSB 151020Z 26003KT 2000 R12/1000N R30/1500N VV002 M07/M07 Q1013 1271//55")
171
- parser.runway_visible_range.length.
172
- should == 2
173
- parser.runway_visible_range[0].designator.
174
- should == '12'
175
- parser.runway_visible_range[0].visibility1.distance.value.
176
- should == 1000
177
- parser.runway_visible_range[0].tendency.
178
- should == :no_change
149
+ expect(parser.runway_visible_range.size).to eq(2)
150
+ expect(parser.runway_visible_range[0].designator).to eq('12')
151
+ expect(parser.runway_visible_range[0].visibility1.distance.value).to eq(1000)
152
+ expect(parser.runway_visible_range[0].tendency).to eq(:no_change)
179
153
  end
180
154
 
181
155
  it 'runway_visible_range_defaults_to_empty_array' do
182
156
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
183
157
 
184
- parser.runway_visible_range.length.
185
- should == 0
158
+ expect(parser.runway_visible_range.size).to eq(0)
186
159
  end
187
160
 
188
161
  it 'runway_visible_range_variable' do
189
162
  parser = setup_parser("KPDX 151108Z 11006KT 1/4SM R10R/1600VP6000FT FG OVC002 05/05 A3022 RMK AO2")
190
163
 
191
- parser.runway_visible_range[0].visibility1.distance.to_feet.
192
- should == 1600.0
193
- parser.runway_visible_range[0].visibility2.distance.to_feet.
194
- should == 6000.0
164
+ expect(parser.runway_visible_range[0].visibility1.distance.to_feet).to eq(1600.0)
165
+ expect(parser.runway_visible_range[0].visibility2.distance.to_feet).to eq(6000.0)
195
166
  end
196
167
 
197
168
  context '.present_weather' do
198
-
199
169
  it 'normal' do
200
170
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
201
171
 
202
- parser.present_weather.size.
203
- should == 1
204
- parser.present_weather[0].modifier.
205
- should == 'light'
206
- parser.present_weather[0].phenomenon.
207
- should == 'snow'
172
+ expect(parser.present_weather.size).to eq(1)
173
+ expect(parser.present_weather[0].modifier).to eq('light')
174
+ expect(parser.present_weather[0].phenomenon).to eq('snow')
208
175
  end
209
176
 
210
177
  it 'auto + //' do
211
178
  parser = setup_parser("PAIL 061610Z AUTO 24006KT 1 3/4SM // BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
212
179
 
213
- parser.present_weather.size.
214
- should == 1
215
- parser.present_weather[0].phenomenon.
216
- should == 'not observed'
180
+ expect(parser.present_weather.size).to eq(1)
181
+ expect(parser.present_weather[0].phenomenon).to eq('not observed')
217
182
  end
218
-
219
183
  end
220
184
 
221
185
  it 'present_weather_defaults_to_empty_array' do
222
186
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
223
- parser.present_weather.length.
224
- should == 0
187
+ expect(parser.present_weather.size).to eq(0)
225
188
  end
226
189
 
227
190
  context '.sky_conditions' do
228
-
229
191
  it 'normal' do
230
192
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
231
193
 
232
- parser.sky_conditions.size.
233
- should == 2
234
- parser.sky_conditions[0].quantity.
235
- should == 'broken'
236
- parser.sky_conditions[0].height.value.
237
- should == 487.68
238
- parser.sky_conditions[1].quantity.
239
- should == 'overcast'
240
- parser.sky_conditions[1].height.value.
241
- should == 914.40
194
+ expect(parser.sky_conditions.size).to eq(2)
195
+ expect(parser.sky_conditions[0].quantity).to eq('broken')
196
+ expect(parser.sky_conditions[0].height.value).to eq(487.68)
197
+ expect(parser.sky_conditions[1].quantity).to eq('overcast')
198
+ expect(parser.sky_conditions[1].height.value).to eq(914.40)
242
199
  end
243
200
 
244
201
  it 'auto + ///' do
245
202
  parser = setup_parser("PAIL 061610Z AUTO 24006KT 1 3/4SM /// M17/M20 A2910 RMK AO2 P0000")
246
203
 
247
- parser.sky_conditions.size.
248
- should == 0
204
+ expect(parser.sky_conditions.size).to eq(0)
249
205
  end
250
-
251
206
  end
252
207
 
253
208
  it 'sky_conditions_defaults_to_empty_array' do
254
209
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN M17/M20 A2910 RMK AO2 P0000")
255
- parser.sky_conditions.length.
256
- should == 0
210
+ expect(parser.sky_conditions.size).to eq(0)
257
211
  end
258
212
 
259
213
  it 'vertical_visibility' do
260
214
  parser = setup_parser("CYXS 151034Z AUTO 09003KT 1/8SM FZFG VV001 M03/M03 A3019 RMK SLP263 ICG")
261
- parser.vertical_visibility.value.
262
- should == 30.48
215
+ expect(parser.vertical_visibility.value).to eq(30.48)
263
216
  end
264
217
 
265
218
  it 'temperature' do
266
219
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
267
- parser.temperature.value. should == -17
220
+ expect(parser.temperature.value).to eq(-17)
268
221
  end
269
222
 
270
223
  it 'dew_point' do
271
224
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
272
- parser.dew_point.value. should == -20
225
+ expect(parser.dew_point.value).to eq(-20)
273
226
  end
274
227
 
275
228
  it 'sea_level_pressure' do
276
229
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
277
- parser.sea_level_pressure.to_inches_of_mercury.
278
- should == 29.10
230
+ expect(parser.sea_level_pressure.to_inches_of_mercury).to eq(29.10)
279
231
  end
280
232
 
281
233
  it 'recent weather' do
282
234
  parser = setup_parser("CYQH 310110Z 00000KT 20SM SCT035CB BKN050 RETS RMK CB4SC1")
283
235
 
284
- parser.recent_weather. should be_a Array
285
- parser.recent_weather.size. should == 1
286
- parser.recent_weather[0].phenomenon.
287
- should == 'thunderstorm'
236
+ expect(parser.recent_weather).to be_a Array
237
+ expect(parser.recent_weather.size).to eq(1)
238
+ expect(parser.recent_weather[0].phenomenon).to eq('thunderstorm')
288
239
  end
289
240
 
290
241
  context 'remarks' do
291
-
292
242
  it 'are collected' do
293
243
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
294
244
 
295
- parser.remarks. should be_a Array
296
- parser.remarks.size. should == 2
245
+ expect(parser.remarks).to be_a Array
246
+ expect(parser.remarks.size).to eq(2)
297
247
  end
298
248
 
299
249
  it 'remarks defaults to empty array' do
300
250
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910")
301
251
 
302
- parser.remarks. should be_a Array
303
- parser.remarks.length. should == 0
252
+ expect(parser.remarks).to be_a Array
253
+ expect(parser.remarks.size).to eq(0)
304
254
  end
305
255
 
306
256
  it 'parses known remarks' do
307
257
  parser = setup_parser('CYZT 052200Z 31010KT 20SM SKC 17/12 A3005 RMK SLP174 20046')
308
258
 
309
- parser.remarks[0]. should be_a(Metar::SeaLevelPressure)
310
- parser.remarks[1]. should be_temperature_extreme(:minimum, 4.6)
259
+ expect(parser.remarks[0]).to be_a(Metar::SeaLevelPressure)
260
+ expect(parser.remarks[1]).to be_temperature_extreme(:minimum, 4.6)
311
261
  end
312
262
 
313
263
  context 'in strict mode' do
314
-
315
- before :each do
264
+ before do
316
265
  Metar::Parser.compliance = :strict
317
266
  end
318
267
 
319
268
  it 'unparsed data causes an error' do
320
269
  expect do
321
270
  setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 FOO RMK AO2 P0000")
322
- end. to raise_error(Metar::ParseError, /Unparsable text found/)
271
+ end.to raise_error(Metar::ParseError, /Unparsable text found/)
323
272
  end
324
-
325
273
  end
326
274
 
327
275
  context 'in loose mode' do
328
-
329
276
  it 'unparsed data is collected' do
330
277
  parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 FOO RMK AO2 P0000")
331
278
 
332
- parser.unparsed. should == ['FOO']
333
- parser.remarks.size. should == 2
279
+ expect(parser.unparsed).to eq(['FOO'])
280
+ expect(parser.remarks.size).to eq(2)
334
281
  end
335
-
336
282
  end
337
-
338
283
  end
339
284
 
340
285
  def setup_parser(metar)
341
286
  raw = Metar::Raw::Data.new(metar)
342
287
  Metar::Parser.new(raw)
343
288
  end
344
-
345
289
  end
346
-
347
290
  end
348
291
 
@@ -49,6 +49,12 @@ describe Metar::Report do
49
49
 
50
50
  context '#time' do
51
51
  specify { subject.time. should == @metar_time }
52
+
53
+ it 'zero-pads single figure minutes' do
54
+ @parser.stub(:time => Time.parse('10:02'))
55
+
56
+ expect(subject.time).to eq('10:02')
57
+ end
52
58
  end
53
59
 
54
60
  context '#observer' do
@@ -1,9 +1,9 @@
1
1
  # encoding: utf-8
2
- load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
2
+ load File.expand_path('../spec_helper.rb', File.dirname(__FILE__))
3
3
 
4
- RSpec::Matchers.define :be_wind do | direction, speed, gusts |
5
- match do | wind |
6
- if wind.nil? && [ direction, speed, gusts ].all?( &:nil? )
4
+ RSpec::Matchers.define :be_wind do |direction, speed, gusts|
5
+ match do |wind|
6
+ if wind.nil? && [direction, speed, gusts].all?(&:nil?)
7
7
  true
8
8
  elsif wind.nil?
9
9
  false
@@ -13,15 +13,15 @@ RSpec::Matchers.define :be_wind do | direction, speed, gusts |
13
13
  false
14
14
  elsif wind.gusts.nil? != gusts.nil?
15
15
  false
16
- elsif direction.is_a?( Symbol ) && wind.direction != direction
16
+ elsif direction.is_a?(Symbol) && wind.direction != direction
17
17
  false
18
- elsif direction.is_a?( M9t::Direction ) && (wind.direction.value - direction).abs > 0.01
18
+ elsif direction.is_a?(M9t::Direction) && (wind.direction.value - direction).abs > 0.01
19
19
  false
20
- elsif speed.is_a?( Symbol ) && wind.speed != speed
20
+ elsif speed.is_a?(Symbol) && wind.speed != speed
21
21
  false
22
- elsif speed.is_a?( Metar::Speed ) && (wind.speed.value - speed).abs > 0.01
22
+ elsif speed.is_a?(Metar::Speed) && (wind.speed.value - speed).abs > 0.01
23
23
  false
24
- elsif ! wind.gusts.nil? && (wind.gusts.value - gusts).abs > 0.01
24
+ elsif ! wind.gusts.nil? && (wind.gusts.value - gusts).abs > 0.01
25
25
  false
26
26
  else
27
27
  true
@@ -30,52 +30,48 @@ RSpec::Matchers.define :be_wind do | direction, speed, gusts |
30
30
  end
31
31
 
32
32
  describe Metar::Wind do
33
-
34
33
  context '.parse' do
35
-
36
34
  [
37
35
  # Direction and speed
38
- [ 'treats 5 digits as degrees and kilometers per hour', '12345', [ 123.0, 12.50, nil ] ],
39
- [ 'understands 5 digits + KMH', '12345KMH', [ 123.0, 12.50, nil ] ],
40
- [ 'understands 5 digits + MPS', '12345MPS', [ 123.0, 45.00, nil ] ],
41
- [ 'understands 5 digits + KT', '12345KT', [ 123.0, 23.15, nil ] ],
42
- [ 'rounds 360 down to 0', '36045KT', [ 0.0, 23.15, nil ] ],
43
- [ 'returns nil for directions outside 0 to 360', '88845KT', [ nil, nil, nil ] ],
36
+ ['treats 5 digits as degrees and kilometers per hour', '12345', [123.0, 12.50, nil]],
37
+ ['understands 5 digits + KMH', '12345KMH', [123.0, 12.50, nil]],
38
+ ['understands 5 digits + MPS', '12345MPS', [123.0, 45.00, nil]],
39
+ ['understands 5 digits + KT', '12345KT', [123.0, 23.15, nil]],
40
+ ['rounds 360 down to 0', '36045KT', [ 0.0, 23.15, nil]],
41
+ ['returns nil for directions outside 0 to 360', '88845KT', [nil, nil, nil]],
44
42
  # +gusts
45
- [ 'understands 5 digits + G + 2 digits', '12345G67', [ 123.0, 12.50, 18.61 ] ],
46
- [ 'understands 5 digits + G + 2 digits + KMH', '12345G67KMH', [ 123.0, 12.50, 18.61 ] ],
47
- [ 'understands 5 digits + G + 2 digits + MPS', '12345G67MPS', [ 123.0, 45.00, 67.00 ] ],
48
- [ 'understands 5 digits + G + 2 digits + KT', '12345G67KT', [ 123.0, 23.15, 34.47 ] ],
43
+ ['understands 5 digits + G + 2 digits', '12345G67', [123.0, 12.50, 18.61]],
44
+ ['understands 5 digits + G + 2 digits + KMH', '12345G67KMH', [123.0, 12.50, 18.61]],
45
+ ['understands 5 digits + G + 2 digits + MPS', '12345G67MPS', [123.0, 45.00, 67.00]],
46
+ ['understands 5 digits + G + 2 digits + KT', '12345G67KT', [123.0, 23.15, 34.47]],
49
47
  # Variable direction
50
- [ 'understands VRB + 2 digits' 'VRB12', [ :variable_direction, 3.33, nil ] ],
51
- [ 'understands VRB + 2 digits + KMH', 'VRB12KMH', [ :variable_direction, 3.33, nil ] ],
52
- [ 'understands VRB + 2 digits + MPS', 'VRB12MPS', [ :variable_direction, 12.00, nil ] ],
53
- [ 'understands VRB + 2 digits + KT', 'VRB12KT', [ :variable_direction, 6.17, nil ] ],
48
+ ['understands VRB + 2 digits', 'VRB12', [:variable_direction, 3.33, nil]],
49
+ ['understands VRB + 2 digits + KMH', 'VRB12KMH', [:variable_direction, 3.33, nil]],
50
+ ['understands VRB + 2 digits + MPS', 'VRB12MPS', [:variable_direction, 12.00, nil]],
51
+ ['understands VRB + 2 digits + KT', 'VRB12KT', [:variable_direction, 6.17, nil]],
54
52
  # + gusts
55
- [ 'understands VRB + 2 digits + G + 2 digits', 'VRB45G67', [ :variable_direction, 12.50, 18.61 ] ],
56
- [ 'understands VRB + 2 digits + G + 2 digits + KMH', 'VRB45G67KMH', [ :variable_direction, 12.50, 18.61 ] ],
57
- [ 'understands VRB + 2 digits + G + 2 digits + MPS', 'VRB45G67MPS', [ :variable_direction, 45.00, 67.00 ] ],
58
- [ 'understands VRB + 2 digits + G + 2 digits + KT', 'VRB45G67KT', [ :variable_direction, 23.15, 34.47 ] ],
53
+ ['understands VRB + 2 digits + G + 2 digits', 'VRB45G67', [:variable_direction, 12.50, 18.61]],
54
+ ['understands VRB + 2 digits + G + 2 digits + KMH', 'VRB45G67KMH', [:variable_direction, 12.50, 18.61]],
55
+ ['understands VRB + 2 digits + G + 2 digits + MPS', 'VRB45G67MPS', [:variable_direction, 45.00, 67.00]],
56
+ ['understands VRB + 2 digits + G + 2 digits + KT', 'VRB45G67KT', [:variable_direction, 23.15, 34.47]],
59
57
  # Unknown direction
60
- [ 'understands /// + 2 digits', '///12', [ :unknown_direction, 3.33, nil ] ],
61
- [ 'understands /// + 2 digits + KMH', '///12KMH', [ :unknown_direction, 3.33, nil ] ],
62
- [ 'understands /// + 2 digits + MPS', '///12MPS', [ :unknown_direction, 12.00, nil ] ],
63
- [ 'understands /// + 2 digits + KT', '///12KT', [ :unknown_direction, 6.17, nil ] ],
58
+ ['understands /// + 2 digits', '///12', [:unknown_direction, 3.33, nil]],
59
+ ['understands /// + 2 digits + KMH', '///12KMH', [:unknown_direction, 3.33, nil]],
60
+ ['understands /// + 2 digits + MPS', '///12MPS', [:unknown_direction, 12.00, nil]],
61
+ ['understands /// + 2 digits + KT', '///12KT', [:unknown_direction, 6.17, nil]],
64
62
  # Unknown direction and speed
65
- [ 'understands /////', '/////', [ :unknown_direction, :unknown_speed, nil ] ],
63
+ ['understands /////', '/////', [:unknown_direction, :unknown_speed, nil]],
66
64
  # Bad data
67
- [ 'returns nil for badly formatted values', 'XYZ12KT', [ nil, nil, nil ] ],
68
- [ 'returns nil for nil', nil, [ nil, nil, nil ] ],
69
- ].each do | docstring, raw, expected |
65
+ ['returns nil for badly formatted values', 'XYZ12KT', [nil, nil, nil]],
66
+ ['returns nil for nil', nil, [nil, nil, nil]],
67
+ ].each do |docstring, raw, expected|
70
68
  example docstring do
71
- Metar::Wind.parse( raw ).should be_wind( *expected )
69
+ Metar::Wind.parse(raw).should be_wind(*expected)
72
70
  end
73
71
  end
74
-
75
72
  end
76
73
 
77
74
  context '#to_s' do
78
-
79
75
  before :each do
80
76
  @locale = I18n.locale
81
77
  I18n.locale = :it
@@ -86,28 +82,26 @@ describe Metar::Wind do
86
82
  end
87
83
 
88
84
  [
89
- [ 'should format speed and direction', :en, [ nil, nil, nil ], '443km/h ESE' ],
90
- [ 'should handle variable_direction', :en, [ :variable_direction, nil, nil ], '443km/h variable direction' ],
91
- [ 'should handle unknown_direction', :en, [ :unknown_direction, nil, nil ], '443km/h unknown direction' ],
92
- [ 'should handle unknown_speed', :en, [ nil, :unknown_speed, nil ], 'unknown speed ESE' ],
93
- [ 'should include gusts', :en, [ nil, nil, Metar::Speed.new( 123 ) ], '443km/h ESE gusts 443km/h' ],
94
- [ 'should format speed and direction', :it, [ nil, nil, nil ], '443km/h ESE' ],
95
- [ 'should handle variable_direction', :it, [ :variable_direction, nil, nil ], '443km/h direzione variabile' ],
96
- [ 'should handle unknown_direction', :it, [ :unknown_direction, nil, nil ], '443km/h direzione sconosciuta' ],
97
- [ 'should handle unknown_speed', :it, [ nil, :unknown_speed, nil ], 'velocità sconosciuta ESE' ],
98
- [ 'should include gusts', :it, [ nil, nil, Metar::Speed.new( 123 ) ], '443km/h ESE folate di 443km/h' ],
99
- ].each do | docstring, locale, ( direction, speed, gusts ), expected |
100
- direction ||= M9t::Direction.new( 123 )
101
- speed ||= Metar::Speed.new( 123 )
85
+ ['should format speed and direction', :en, [nil, nil, nil ], '443km/h ESE' ],
86
+ ['should handle variable_direction', :en, [:variable_direction, nil, nil ], '443km/h variable direction' ],
87
+ ['should handle unknown_direction', :en, [:unknown_direction, nil, nil ], '443km/h unknown direction' ],
88
+ ['should handle unknown_speed', :en, [nil, :unknown_speed, nil ], 'unknown speed ESE' ],
89
+ ['should include gusts', :en, [nil, nil, Metar::Speed.new(123)], '443km/h ESE gusts 443km/h' ],
90
+ ['should format speed and direction', :it, [nil, nil, nil ], '443km/h ESE' ],
91
+ ['should handle variable_direction', :it, [:variable_direction, nil, nil ], '443km/h direzione variabile' ],
92
+ ['should handle unknown_direction', :it, [:unknown_direction, nil, nil ], '443km/h direzione sconosciuta'],
93
+ ['should handle unknown_speed', :it, [nil, :unknown_speed, nil ], 'velocità sconosciuta ESE' ],
94
+ ['should include gusts', :it, [nil, nil, Metar::Speed.new(123)], '443km/h ESE folate di 443km/h'],
95
+ ].each do |docstring, locale, (direction, speed, gusts), expected|
96
+ direction ||= M9t::Direction.new(123)
97
+ speed ||= Metar::Speed.new(123)
102
98
 
103
99
  example docstring + " (#{locale})" do
104
100
  I18n.locale = locale
105
- Metar::Wind.new( direction, speed, gusts ).to_s.
101
+ Metar::Wind.new(direction, speed, gusts).to_s.
106
102
  should == expected
107
103
  end
108
104
  end
109
-
110
105
  end
111
-
112
106
  end
113
107
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metar-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-24 00:00:00.000000000 Z
12
+ date: 2013-05-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -194,7 +194,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
194
194
  version: '0'
195
195
  segments:
196
196
  - 0
197
- hash: 256504047505018704
197
+ hash: 2864761200794302878
198
198
  required_rubygems_version: !ruby/object:Gem::Requirement
199
199
  none: false
200
200
  requirements:
@@ -203,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
203
  version: '0'
204
204
  segments:
205
205
  - 0
206
- hash: 256504047505018704
206
+ hash: 2864761200794302878
207
207
  requirements: []
208
208
  rubyforge_project: nowarning
209
209
  rubygems_version: 1.8.23