metar-parser 0.1.1 → 0.1.2
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.rb +1 -1
- data/lib/metar/data.rb +90 -78
- data/locales/en.yml +10 -0
- data/locales/it.yml +19 -9
- data/test/unit/data_test.rb +189 -13
- data/test/unit/report_test.rb +2 -2
- metadata +2 -2
data/lib/metar.rb
CHANGED
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
|
-
|
|
70
|
+
# Adds a parse method to the M9t base class
|
|
71
|
+
class Pressure < M9t::Pressure
|
|
50
72
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
99
|
+
nil
|
|
59
100
|
end
|
|
60
101
|
end
|
|
61
102
|
|
|
62
|
-
|
|
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
|
-
|
|
65
|
-
|
|
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
|
-
|
|
71
|
-
class Pressure < M9t::Pressure
|
|
131
|
+
class VariableWind
|
|
72
132
|
|
|
73
|
-
def
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
'
|
|
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
|
|
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
|
|
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
|
|
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
|
|
80
|
+
heavy snow: neve intensa
|
|
71
81
|
light snow: neve leggera
|
|
72
|
-
heavy shower of snow: nevicata
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
data/test/unit/data_test.rb
CHANGED
|
@@ -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
|
|
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
|
-
#
|
|
70
|
-
def
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
data/test/unit/report_test.rb
CHANGED
|
@@ -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
|
|
23
|
+
assert_equal('10°, 7 knots', report.wind)
|
|
24
24
|
I18n.locale = :it
|
|
25
|
-
assert_equal('10
|
|
25
|
+
assert_equal('10°, 7 nodi', report.wind)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def test_variable_wind
|