metar-parser 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/metar.rb CHANGED
@@ -8,7 +8,7 @@ module Metar
8
8
  module VERSION #:nodoc:
9
9
  MAJOR = 0
10
10
  MINOR = 1
11
- TINY = 1
11
+ TINY = 2
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY].join('.')
14
14
  end
data/lib/metar/data.rb CHANGED
@@ -7,6 +7,27 @@ module Metar
7
7
  locales_path = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'locales'))
8
8
  I18n.load_path += Dir.glob("#{ locales_path }/*.yml")
9
9
 
10
+ # Subclasses M9t::Distance
11
+ # Uses kilometers as desired default output unit
12
+ class Distance < M9t::Distance
13
+
14
+ # nil is taken to mean 'data unavailable'
15
+ def initialize(meters = nil, options = {})
16
+ if meters
17
+ super(meters, { :units => :kilometers, :precision => 0, :abbreviated => true }.merge(options))
18
+ else
19
+ @value = nil
20
+ end
21
+ end
22
+
23
+ # Handles nil case differently to M9t::Distance
24
+ def to_s
25
+ return I18n.t('metar.distance.unknown') if @value.nil?
26
+ super
27
+ end
28
+
29
+ end
30
+
10
31
  # Adds a parse method to the M9t base class
11
32
  class Speed < M9t::Speed
12
33
 
@@ -46,39 +67,87 @@ module Metar
46
67
 
47
68
  end
48
69
 
49
- class Distance < M9t::Distance
70
+ # Adds a parse method to the M9t base class
71
+ class Pressure < M9t::Pressure
50
72
 
51
- # Subclasses M9t::Distance
52
- # Uses kilometers as desired default output unit
53
- # nil is taken to mean 'data unavailable'
54
- def initialize(meters = nil, options = {})
55
- if meters
56
- super(meters, { :units => :kilometers, :precision => 0, :abbreviated => true }.merge(options))
73
+ def Pressure.parse(pressure)
74
+ case
75
+ when pressure =~ /^Q(\d{4})$/
76
+ hectopascals($1.to_f)
77
+ when pressure =~ /^A(\d{4})$/
78
+ inches_of_mercury($1.to_f / 100.0)
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ class Wind
85
+
86
+ def Wind.parse(s)
87
+ case
88
+ when s =~ /^(\d{3})(\d{2}(|MPS|KMH|KT))$/
89
+ new(M9t::Direction.new($1, { :abbreviated => true }), Speed.parse($2))
90
+ when s =~ /^(\d{3})(\d{2})G(\d{2,3}(|MPS|KMH|KT))$/
91
+ new(M9t::Direction.new($1, { :abbreviated => true }), Speed.parse($2))
92
+ when s =~ /^VRB(\d{2}(|MPS|KMH|KT))$/
93
+ new(:variable_direction, Speed.parse($1))
94
+ when s =~ /^\/{3}(\d{2}(|MPS|KMH|KT))$/
95
+ new(:unknown_direction, Speed.parse($1))
96
+ when s =~ /^\/{3}(\/{2}(|MPS|KMH|KT))$/
97
+ new(:unknown_direction, :unknown)
57
98
  else
58
- @value = nil
99
+ nil
59
100
  end
60
101
  end
61
102
 
62
- # Handles nil case differently to M9t::Distance
103
+ attr_reader :direction, :speed, :units
104
+
105
+ def initialize(direction, speed, units = :kilometers_per_hour)
106
+ @direction, @speed = direction, speed
107
+ end
108
+
63
109
  def to_s
64
- return I18n.t('metar.distance.unknown') if @value.nil?
65
- super
110
+ direction =
111
+ case @direction
112
+ when :variable_direction
113
+ I18n.t('metar.wind.variable_direction')
114
+ when :unknown_direction
115
+ I18n.t('metar.wind.unknown_direction')
116
+ else
117
+ @direction.to_s
118
+ end
119
+ speed =
120
+ case @speed
121
+ when :unknown
122
+ I18n.t('metar.wind.unknown_speed')
123
+ else
124
+ @speed.to_s
125
+ end
126
+ "#{ direction }, #{ speed }"
66
127
  end
67
128
 
68
129
  end
69
130
 
70
- # Adds a parse method to the M9t base class
71
- class Pressure < M9t::Pressure
131
+ class VariableWind
72
132
 
73
- def Pressure.parse(pressure)
74
- case
75
- when pressure =~ /^Q(\d{4})$/
76
- hectopascals($1.to_f)
77
- when pressure =~ /^A(\d{4})$/
78
- inches_of_mercury($1.to_f / 100.0)
133
+ def VariableWind.parse(variable_wind)
134
+ if variable_wind =~ /^(\d+)V(\d+)$/
135
+ new(M9t::Direction.new($1), M9t::Direction.new($2))
136
+ else
137
+ nil
79
138
  end
80
139
  end
81
140
 
141
+ attr_reader :direction1, :direction2
142
+
143
+ def initialize(direction1, direction2)
144
+ @direction1, @direction2 = direction1, direction2
145
+ end
146
+
147
+ def to_s
148
+ "#{ @direction1 } - #{ @direction2 }"
149
+ end
150
+
82
151
  end
83
152
 
84
153
  class Visibility
@@ -127,59 +196,6 @@ module Metar
127
196
  end
128
197
  end
129
198
 
130
- class Wind
131
-
132
- def Wind.parse(s)
133
- case
134
- when s =~ /^(\d{3})(\d{2}(KT|MPS|KMH|))$/
135
- new(M9t::Direction.new($1, { :abbreviated => true }), Speed.parse($2))
136
- when s =~ /^(\d{3})(\d{2})G(\d{2,3}(KT|MPS|KMH|))$/
137
- new(M9t::Direction.new($1, { :abbreviated => true }), Speed.parse($2))
138
- when s =~ /^VRB(\d{2}(KT|MPS|KMH|))$/
139
- new('variable direction', Speed.parse($1))
140
- when s =~ /^\/{3}(\d{2}(KT|MPS|KMH|))$/
141
- new('unknown direction', Speed.parse($1))
142
- when s =~ /^\/{3}(\/{2}(KT|MPS|KMH|))$/
143
- new('unknown direction', 'unknown')
144
- else
145
- nil
146
- end
147
- end
148
-
149
- attr_reader :direction, :speed, :units
150
-
151
- def initialize(direction, speed, units = :kilometers_per_hour)
152
- @direction, @speed = direction, speed
153
- end
154
-
155
- def to_s
156
- "#{ @direction } #{ @speed }"
157
- end
158
-
159
- end
160
-
161
- class VariableWind
162
-
163
- def VariableWind.parse(variable_wind)
164
- if variable_wind =~ /^(\d+)V(\d+)$/
165
- new(M9t::Direction.new($1), M9t::Direction.new($2))
166
- else
167
- nil
168
- end
169
- end
170
-
171
- attr_reader :direction1, :direction2
172
-
173
- def initialize(direction1, direction2)
174
- @direction1, @direction2 = direction1, direction2
175
- end
176
-
177
- def to_s
178
- "#{ @direction1 } - #{ @direction2 }"
179
- end
180
-
181
- end
182
-
183
199
  class RunwayVisibleRange
184
200
 
185
201
  TENDENCY = { '' => nil, 'N' => :no_change, 'U' => :improving, 'D' => :worsening }
@@ -226,17 +242,12 @@ module Metar
226
242
  end
227
243
  end
228
244
 
229
- private
230
-
231
- def RunwayVisibleRange.parse_visibility(distance)
232
- end
233
-
234
245
  end
235
246
 
236
247
  class WeatherPhenomenon
237
248
 
238
249
  Modifiers = {
239
- '\+' => 'heavy',
250
+ '+' => 'heavy',
240
251
  '-' => 'light',
241
252
  'VC' => 'nearby'
242
253
  }
@@ -290,6 +301,7 @@ module Metar
290
301
  codes = Phenomena.keys.join('|')
291
302
  descriptors = Descriptors.keys.join('|')
292
303
  modifiers = Modifiers.keys.join('|')
304
+ modifiers.gsub!(/([\+\-])/) { "\\#$1" }
293
305
  rxp = Regexp.new("^(#{ modifiers })?(#{ descriptors })?(#{ codes })$")
294
306
  if rxp.match(s)
295
307
  modifier_code = $1
data/locales/en.yml CHANGED
@@ -15,11 +15,21 @@ en:
15
15
  at: at
16
16
  distance:
17
17
  unknown: unknown
18
+ wind:
19
+ variable_direction: variable direction
20
+ unknown_direction: unknown direction
21
+ unknown_speed: unknown speed
18
22
  sky_conditions:
19
23
  clear skies: clear skies
20
24
  broken: broken cloud
25
+ broken cumulonimbus: broken cumulonimbus
26
+ broken towering cumulus: broken towering cumulus clouds
21
27
  few: few clouds
28
+ few cumulonimbus: few cumulonimbus
29
+ few towering cumulus: few towering cumulus clouds
22
30
  scattered: scattered cloud
31
+ scattered cumulonimbus: scattered cumulonimbus
32
+ scattered towering cumulus: scattered towering cumulus clouds
23
33
  overcast: overcast
24
34
  runway_visible_range:
25
35
  runway: runway
data/locales/it.yml CHANGED
@@ -15,11 +15,21 @@ it:
15
15
  at: a
16
16
  distance:
17
17
  unknown: sconosciuto
18
+ wind:
19
+ variable_direction: direzione variabile
20
+ unknown_direction: direzione sconosciuta
21
+ unknown_speed: velocità sconosciuta
18
22
  sky_conditions:
19
23
  clear skies: cielo sereno
20
24
  broken: nuvolosità parziale
25
+ broken cumulonimbus: copertura parziale di cumulonembi
26
+ broken towering cumulus: copertura parziale di cumulonembi
21
27
  few: poche nuvole
28
+ broken cumulonimbus: pochi cumulonembi
29
+ broken towering cumulus: pochi cumulonembi
22
30
  scattered: nuvole sparse
31
+ scattered cumulonimbus: cumulonembi sparsi
32
+ scattered towering cumulus: cumulonembi sparsi
23
33
  overcast: chiuso
24
34
  runway_visible_range:
25
35
  runway: pista
@@ -33,7 +43,7 @@ it:
33
43
  nearby blowing dust: deriva vicina di polviscolo # ?
34
44
  heavy drizzle: pioggerellina fitta
35
45
  light drizzle: pioggerellina rada
36
- heavy freezing drizzle: pioggerellina ghiacciata pesante
46
+ heavy freezing drizzle: pioggerellina ghiacciata intensa
37
47
  light freezing drizzle: pioggerellina ghiacciata leggera
38
48
  fog: nebbia
39
49
  patches of fog: nebbia a banchi
@@ -55,11 +65,11 @@ it:
55
65
  nearby dust whirls: vortici di polvere vicini
56
66
  spray: "spruzzi d'aqua"
57
67
  rain: pioggia
58
- heavy rain: pioggia pesante
68
+ heavy rain: pioggia intensa
59
69
  light rain: pioggia leggera
60
70
  heavy shower of rain: acquazzone intenso
61
71
  light shower of rain: acquazzone leggero
62
- heavy freezing rain: pioggia ghiacciata pesante
72
+ heavy freezing rain: pioggia ghiacciata intensa
63
73
  light freezing rain: pioggia ghiacciata leggera
64
74
  sand: sabbia
65
75
  blowing sand: sabbia e vento
@@ -67,9 +77,9 @@ it:
67
77
  nearby blowing sand: deriva di sabbia vicina
68
78
  nearby shower: acquazzone vicino
69
79
  snow: neve
70
- heavy snow: neve pesante
80
+ heavy snow: neve intensa
71
81
  light snow: neve leggera
72
- heavy shower of snow: nevicata pesante
82
+ heavy shower of snow: nevicata intensa
73
83
  light shower of snow: nevicata leggera
74
84
  blowing snow: neve portata dal vento
75
85
  low drifting snow: deriva di neve
@@ -79,20 +89,20 @@ it:
79
89
  snow and rain: neve mista a pioggia
80
90
  squall: bufera
81
91
  unknown phenomenon: fenomeno sconosciuto
82
- heavy freezing unknown phenomenon: fenomeno ghiacciato sconosciuto pesante
92
+ heavy freezing unknown phenomenon: fenomeno ghiacciato sconosciuto intenso
83
93
  light freezing unknown phenomenon: fenomeno ghiacciato sconosciuto leggero
84
- heavy shower of freezing unknown phenomenon: scroscio pesante ghiacciata di fenomeno sconosciuto
94
+ heavy shower of freezing unknown phenomenon: scroscio intenso ghiacciata di fenomeno sconosciuto
85
95
  light shower of freezing unknown phenomenon: scroscio leggero ghiacciata di fenomeno sconosciuto
86
96
  volcanic ash: cenere volcanica
87
97
  nearby volcanic ash: cenere volcanica vicina
88
98
  funnel cloud: nube a imbuto
89
99
  nearby funnel cloud: nube a imbuto vicina
90
100
  sand storm: tempesta di sabbia
91
- heavy sand storm: tempesta di sabbia pesante
101
+ heavy sand storm: tempesta di sabbia intensa
92
102
  light sand storm: tempesta di sabbia leggera
93
103
  nearby sand storm: tempesta di sabbia vicina
94
104
  dust storm: tempesta di polvere
95
- heavy dust storm: tempesta di polvere pesante
105
+ heavy dust storm: tempesta di polvere intensa
96
106
  light dust storm: tempesta di polvere leggera
97
107
  nearby dust storm: tempesta di polvere vicina
98
108
  thunderstorm: temporale
@@ -13,13 +13,33 @@ class TestMetarData < Test::Unit::TestCase
13
13
  assert_equal('10 kilometers', M9t::Distance.new(10000, {:units => :kilometers, :precision => 0}).to_s)
14
14
  end
15
15
 
16
+ # Distance
17
+ def test_distance_nil
18
+ distance = Metar::Distance.new
19
+ I18n.locale = :en
20
+ assert_equal('unknown', distance.to_s)
21
+ I18n.locale = :it
22
+ assert_equal('sconosciuto', distance.to_s)
23
+ end
24
+
25
+ def test_distance_with_default_options
26
+ distance = Metar::Distance.new(123)
27
+ assert_equal(123, distance.value)
28
+ assert_equal(:kilometers, distance.options[:units])
29
+ end
30
+
31
+ def test_distance_setting_options
32
+ distance = Metar::Distance.new(123, { :units => :feet })
33
+ assert_equal('404ft', distance.to_s)
34
+ end
35
+
16
36
  # Speed
17
37
  def test_speed_parse_blank_gives_nil
18
38
  speed = Metar::Speed.parse('')
19
39
  assert_nil(speed)
20
40
  end
21
41
 
22
- def test_class_options_set
42
+ def test_speed_class_options_set
23
43
  assert_not_nil(Metar::Speed.options)
24
44
  end
25
45
 
@@ -44,7 +64,7 @@ class TestMetarData < Test::Unit::TestCase
44
64
  speed = Metar::Speed.parse('12MPS')
45
65
  assert_equal(:meters_per_second, speed.options[:units])
46
66
  end
47
-
67
+
48
68
  # Temperature
49
69
  def test_temperature_parse_blank_gives_nil
50
70
  temperature = Metar::Temperature.parse('')
@@ -59,6 +79,7 @@ class TestMetarData < Test::Unit::TestCase
59
79
  def test_temperature_parse_positive
60
80
  temperature = Metar::Temperature.parse('12')
61
81
  assert_equal(12, temperature.value)
82
+ assert_equal(:degrees, temperature.options[:units])
62
83
  end
63
84
 
64
85
  def test_temperature_parse_negative
@@ -66,23 +87,74 @@ class TestMetarData < Test::Unit::TestCase
66
87
  assert_equal(-12, temperature.value)
67
88
  end
68
89
 
69
- # Distance
70
- def test_distance_nil
71
- distance = Metar::Distance.new
72
- I18n.locale = :en
73
- assert_equal('unknown', distance.to_s)
74
- I18n.locale = :it
75
- assert_equal('sconosciuto', distance.to_s)
90
+ # Pressure
91
+ def test_pressure_parse_hectopascals
92
+ pressure = Metar::Pressure.parse('Q1002')
93
+ assert_equal(1.002, pressure.value)
94
+ end
95
+
96
+ def test_pressure_parse_hectopascals_leading_zero
97
+ pressure = Metar::Pressure.parse('Q0992')
98
+ assert_equal(0.992, pressure.value)
99
+ end
100
+
101
+ def test_pressure_parse_inches_of_mercury
102
+ pressure = Metar::Pressure.parse('A3019')
103
+ assert_in_delta(1.02235, pressure.value, 0.00001)
76
104
  end
77
105
 
78
106
  # Wind
79
- def test_wind
107
+ def test_wind_parse_default_units
108
+ wind = Metar::Wind.parse('18012')
109
+ assert_equal(180, wind.direction.value)
110
+ assert_equal(12.0, wind.speed.to_kilometers_per_hour)
111
+ assert_equal(:kilometers_per_hour, wind.speed.options[:units])
112
+ end
113
+
114
+ def test_wind_parse_mps
115
+ wind = Metar::Wind.parse('18012MPS')
116
+ assert_equal(180, wind.direction.value)
117
+ assert_equal(12.0, wind.speed.value)
118
+ assert_equal(:meters_per_second, wind.speed.options[:units])
119
+ end
120
+
121
+ def test_wind_parse_kmh
122
+ wind = Metar::Wind.parse('27012KMH')
123
+ assert_equal(270, wind.direction.value)
124
+ assert_equal(12.0, wind.speed.to_kilometers_per_hour)
125
+ assert_equal(:kilometers_per_hour, wind.speed.options[:units])
126
+ end
127
+
128
+ def test_wind_parse_knots
80
129
  wind = Metar::Wind.parse('24006KT')
81
130
  assert_equal(240, wind.direction.value)
82
131
  assert_equal(6, wind.speed.to_knots)
83
132
  assert_equal(:knots, wind.speed.options[:units])
84
133
  end
85
134
 
135
+ def test_wind_parse_variable_direction
136
+ wind = Metar::Wind.parse('VRB20KT')
137
+ assert_equal(:variable_direction, wind.direction)
138
+ assert_equal(20, wind.speed.to_knots)
139
+ assert_equal(:knots, wind.speed.options[:units])
140
+ assert_equal('variable direction, 20 knots', wind.to_s)
141
+ end
142
+
143
+ def test_wind_parse_unknown_direction
144
+ wind = Metar::Wind.parse('///20KT')
145
+ assert_equal(:unknown_direction, wind.direction)
146
+ assert_equal(20, wind.speed.to_knots)
147
+ assert_equal(:knots, wind.speed.options[:units])
148
+ assert_equal('unknown direction, 20 knots', wind.to_s)
149
+ end
150
+
151
+ def test_wind_parse_unknown_direction_and_speed
152
+ wind = Metar::Wind.parse('/////')
153
+ assert_equal(:unknown_direction, wind.direction)
154
+ assert_equal(:unknown, wind.speed)
155
+ assert_equal('unknown direction, unknown speed', wind.to_s)
156
+ end
157
+
86
158
  # VariableWind
87
159
  def test_variable_wind
88
160
  variable_wind = Metar::VariableWind.parse('350V050')
@@ -143,13 +215,19 @@ class TestMetarData < Test::Unit::TestCase
143
215
  visibility.direction.options[:units] = :compass
144
216
  assert_equal('5km NE', visibility.to_s)
145
217
  end
146
-
218
+
147
219
  # RunwayVisibleRange
148
220
  def test_runway_visible_range
149
221
  runway_visible_range = Metar::RunwayVisibleRange.parse('R12/1000N')
150
222
  assert_equal('12', runway_visible_range.designator)
151
223
  assert_equal(1000, runway_visible_range.visibility1.distance.value)
152
224
  assert_equal(:no_change, runway_visible_range.tendency)
225
+ assert_equal('runway 12: 1000m', runway_visible_range.to_s)
226
+ end
227
+
228
+ def test_runway_visible_range_descriptor_with_letter
229
+ runway_visible_range = Metar::RunwayVisibleRange.parse('R12R/1000N')
230
+ assert_equal('12R', runway_visible_range.designator)
153
231
  end
154
232
 
155
233
  def test_runway_visible_range_variable
@@ -160,24 +238,122 @@ class TestMetarData < Test::Unit::TestCase
160
238
  end
161
239
 
162
240
  # WeatherPhenomenon
163
- def test_weather_phenomenon_i18n
241
+ def test_weather_phenomenon_snra
242
+ phenomenon = Metar::WeatherPhenomenon.parse('SNRA')
243
+ assert_equal('snow and rain', phenomenon.to_s)
244
+ I18n.locale = :it
245
+ assert_equal('neve mista a pioggia', phenomenon.to_s)
246
+ end
247
+
248
+ def test_weather_phenomenon_fzfg
164
249
  freezing_rain = Metar::WeatherPhenomenon.parse('FZFG')
165
250
  assert_equal('freezing fog', freezing_rain.to_s)
166
251
  I18n.locale = :it
167
252
  assert_equal('nebbia ghiacciata', freezing_rain.to_s)
168
253
  end
169
254
 
255
+ def test_weather_phenomenon_with_modifier_plus
256
+ phenomenon = Metar::WeatherPhenomenon.parse('+RA')
257
+ assert_equal('heavy', phenomenon.modifier)
258
+ assert_equal('heavy rain', phenomenon.to_s)
259
+ I18n.locale = :it
260
+ assert_equal('pioggia intensa', phenomenon.to_s)
261
+ end
262
+
263
+ def test_weather_phenomenon_with_modifier_minus
264
+ phenomenon = Metar::WeatherPhenomenon.parse('-RA')
265
+ assert_equal('light', phenomenon.modifier)
266
+ assert_equal('light rain', phenomenon.to_s)
267
+ I18n.locale = :it
268
+ assert_equal('pioggia leggera', phenomenon.to_s)
269
+ end
270
+
170
271
  # SkyCondition
171
- def test_sky_condition
272
+ def test_sky_condition_nsc
273
+ sky_condition = Metar::SkyCondition.parse('NSC')
274
+ assert_nil(sky_condition.quantity)
275
+ assert_nil(sky_condition.height)
276
+ assert_equal('clear skies', sky_condition.to_s)
277
+ I18n.locale = :it
278
+ assert_equal('cielo sereno', sky_condition.to_s)
279
+ end
280
+
281
+ def test_sky_condition_clr
282
+ sky_condition = Metar::SkyCondition.parse('CLR')
283
+ assert_equal('clear skies', sky_condition.to_s)
284
+ I18n.locale = :it
285
+ assert_equal('cielo sereno', sky_condition.to_s)
286
+ end
287
+
288
+ def test_sky_condition_broken
172
289
  sky_condition = Metar::SkyCondition.parse('BKN016')
173
290
  assert_equal('broken', sky_condition.quantity)
174
291
  assert_equal(480, sky_condition.height.value)
292
+ assert_equal('broken cloud at 480m', sky_condition.to_s)
293
+ I18n.locale = :it
294
+ assert_equal('nuvolosità parziale a 480m', sky_condition.to_s)
295
+ end
296
+
297
+ def test_sky_condition_few
298
+ sky_condition = Metar::SkyCondition.parse('FEW016')
299
+ assert_equal('few', sky_condition.quantity)
300
+ assert_equal(480, sky_condition.height.value)
301
+ assert_equal('few clouds at 480m', sky_condition.to_s)
302
+ I18n.locale = :it
303
+ assert_equal('poche nuvole a 480m', sky_condition.to_s)
304
+ end
305
+
306
+ def test_sky_condition_ovc
307
+ sky_condition = Metar::SkyCondition.parse('OVC016')
308
+ assert_equal('overcast', sky_condition.quantity)
309
+ assert_equal(480, sky_condition.height.value)
310
+ assert_equal('overcast at 480m', sky_condition.to_s)
311
+ I18n.locale = :it
312
+ assert_equal('chiuso a 480m', sky_condition.to_s)
313
+ end
314
+
315
+ def test_sky_condition_sct
316
+ sky_condition = Metar::SkyCondition.parse('SCT016')
317
+ assert_equal('scattered', sky_condition.quantity)
318
+ assert_equal(480, sky_condition.height.value)
319
+ assert_equal('scattered cloud at 480m', sky_condition.to_s)
320
+ I18n.locale = :it
321
+ assert_equal('nuvole sparse a 480m', sky_condition.to_s)
322
+ end
323
+
324
+ def test_sky_condition_cloud_types_cb
325
+ sky_condition = Metar::SkyCondition.parse('SCT016CB')
326
+ assert_equal('scattered', sky_condition.quantity)
327
+ assert_equal('cumulonimbus', sky_condition.type)
328
+ assert_equal(480, sky_condition.height.value)
329
+ assert_equal('scattered cumulonimbus at 480m', sky_condition.to_s)
330
+ I18n.locale = :it
331
+ assert_equal('cumulonembi sparsi a 480m', sky_condition.to_s)
332
+ end
333
+
334
+ def test_sky_condition_cloud_types_tcu
335
+ sky_condition = Metar::SkyCondition.parse('SCT016TCU')
336
+ assert_equal('scattered', sky_condition.quantity)
337
+ assert_equal('towering cumulus', sky_condition.type)
338
+ assert_equal(480, sky_condition.height.value)
339
+ assert_equal('scattered towering cumulus clouds at 480m', sky_condition.to_s)
340
+ I18n.locale = :it
341
+ assert_equal('cumulonembi sparsi a 480m', sky_condition.to_s)
175
342
  end
176
343
 
177
344
  # VerticalVisibility
178
345
  def test_vertical_visibility
179
346
  vertical_visibility = Metar::VerticalVisibility.parse('VV001')
180
347
  assert_equal(30, vertical_visibility.value)
348
+ assert_equal('30m', vertical_visibility.to_s)
349
+ end
350
+
351
+ def test_vertical_visibility_unknown
352
+ vertical_visibility = Metar::VerticalVisibility.parse('///')
353
+ assert_nil(vertical_visibility.value)
354
+ assert_equal('unknown', vertical_visibility.to_s)
355
+ I18n.locale = :it
356
+ assert_equal('sconosciuto', vertical_visibility.to_s)
181
357
  end
182
358
 
183
359
  end
@@ -20,9 +20,9 @@ class TestMetarReport < Test::Unit::TestCase
20
20
 
21
21
  def test_wind_knots
22
22
  report = setup_report('LIRQ', "2010/02/06 15:20\nLIRQ 061520Z 01007KT 350V050 9999 SCT035 BKN080 08/02 Q1005")
23
- assert_equal('10° 7 knots', report.wind)
23
+ assert_equal('10°, 7 knots', report.wind)
24
24
  I18n.locale = :it
25
- assert_equal('10° 7 nodi', report.wind)
25
+ assert_equal('10°, 7 nodi', report.wind)
26
26
  end
27
27
 
28
28
  def test_variable_wind
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 1
9
- version: 0.1.1
8
+ - 2
9
+ version: 0.1.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Joe Yates