metar-parser 1.4.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -49
- data/Rakefile +2 -1
- data/lib/metar/data/base.rb +16 -10
- data/lib/metar/data/density_altitude.rb +16 -10
- data/lib/metar/data/direction.rb +10 -4
- data/lib/metar/data/distance.rb +27 -20
- data/lib/metar/data/lightning.rb +69 -60
- data/lib/metar/data/observer.rb +26 -20
- data/lib/metar/data/pressure.rb +28 -22
- data/lib/metar/data/remark.rb +146 -130
- data/lib/metar/data/runway_visible_range.rb +98 -78
- data/lib/metar/data/sky_condition.rb +68 -57
- data/lib/metar/data/speed.rb +21 -14
- data/lib/metar/data/station_code.rb +8 -4
- data/lib/metar/data/temperature.rb +21 -13
- data/lib/metar/data/temperature_and_dew_point.rb +22 -16
- data/lib/metar/data/time.rb +57 -47
- data/lib/metar/data/variable_wind.rb +30 -19
- data/lib/metar/data/vertical_visibility.rb +27 -21
- data/lib/metar/data/visibility.rb +91 -79
- data/lib/metar/data/visibility_remark.rb +16 -5
- data/lib/metar/data/weather_phenomenon.rb +92 -74
- data/lib/metar/data/wind.rb +106 -87
- data/lib/metar/data.rb +25 -23
- data/lib/metar/i18n.rb +5 -2
- data/lib/metar/parser.rb +47 -22
- data/lib/metar/raw.rb +32 -44
- data/lib/metar/report.rb +31 -20
- data/lib/metar/station.rb +28 -19
- data/lib/metar/version.rb +4 -2
- data/lib/metar.rb +2 -1
- data/locales/de.yml +1 -0
- data/locales/en.yml +1 -0
- data/locales/it.yml +1 -0
- data/locales/pt-BR.yml +1 -0
- data/spec/data/density_altitude_spec.rb +2 -1
- data/spec/data/distance_spec.rb +2 -1
- data/spec/data/lightning_spec.rb +26 -9
- data/spec/data/pressure_spec.rb +2 -0
- data/spec/data/remark_spec.rb +26 -9
- data/spec/data/runway_visible_range_spec.rb +71 -35
- data/spec/data/sky_condition_spec.rb +63 -19
- data/spec/data/speed_spec.rb +2 -0
- data/spec/data/temperature_spec.rb +2 -1
- data/spec/data/variable_wind_spec.rb +2 -0
- data/spec/data/vertical_visibility_spec.rb +4 -4
- data/spec/data/visibility_remark_spec.rb +2 -1
- data/spec/data/visibility_spec.rb +46 -25
- data/spec/data/weather_phenomenon_spec.rb +79 -24
- data/spec/data/wind_spec.rb +156 -38
- data/spec/i18n_spec.rb +2 -0
- data/spec/parser_spec.rb +224 -64
- data/spec/raw_spec.rb +40 -68
- data/spec/report_spec.rb +27 -25
- data/spec/spec_helper.rb +5 -6
- data/spec/station_spec.rb +43 -44
- metadata +56 -43
data/spec/parser_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'spec_helper'
|
3
4
|
|
4
5
|
require 'timecop'
|
@@ -11,8 +12,11 @@ describe Metar::Parser do
|
|
11
12
|
context '.for_cccc' do
|
12
13
|
let(:station) { double(Metar::Station) }
|
13
14
|
let(:raw) { double(Metar::Raw::Noaa, metar: metar, time: time) }
|
14
|
-
let(:metar)
|
15
|
-
|
15
|
+
let(:metar) do
|
16
|
+
"XXXX 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
17
|
+
"RMK AO2 P0000"
|
18
|
+
end
|
19
|
+
let(:time) { Time.gm(2010, 2, 6) }
|
16
20
|
|
17
21
|
before do
|
18
22
|
allow(Metar::Station).to receive(:new) { station }
|
@@ -33,22 +37,33 @@ describe Metar::Parser do
|
|
33
37
|
before { Timecop.freeze(call_time) }
|
34
38
|
after { Timecop.return }
|
35
39
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
+
context 'with location missing' do
|
41
|
+
let(:missing_location) do
|
42
|
+
"FUBAR 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000"
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'fails' do
|
46
|
+
expect do
|
47
|
+
setup_parser(missing_location)
|
48
|
+
end.to raise_error(Metar::ParseError, /Expecting location/)
|
49
|
+
end
|
40
50
|
end
|
41
51
|
|
42
52
|
context 'datetime' do
|
43
53
|
it 'is parsed' do
|
44
|
-
parser = setup_parser(
|
54
|
+
parser = setup_parser(
|
55
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
56
|
+
"RMK AO2 P0000"
|
57
|
+
)
|
45
58
|
|
46
|
-
expect(parser.time).to eq(Time.gm(2011,
|
59
|
+
expect(parser.time).to eq(Time.gm(2011, 5, 6, 16, 10))
|
47
60
|
end
|
48
61
|
|
49
62
|
it 'throws an error is missing' do
|
50
63
|
expect do
|
51
|
-
setup_parser(
|
64
|
+
setup_parser(
|
65
|
+
"PAIL 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000"
|
66
|
+
)
|
52
67
|
end.to raise_error(Metar::ParseError, /Expecting datetime/)
|
53
68
|
end
|
54
69
|
|
@@ -74,7 +89,7 @@ describe Metar::Parser do
|
|
74
89
|
|
75
90
|
it 'less than 6 numerals fails' do
|
76
91
|
expect do
|
77
|
-
|
92
|
+
setup_parser('MMCE 21645Z 12010KT 8SM SKC 29/26 A2992 RMK')
|
78
93
|
end.to raise_error(Metar::ParseError, /Expecting datetime/)
|
79
94
|
end
|
80
95
|
end
|
@@ -83,64 +98,110 @@ describe Metar::Parser do
|
|
83
98
|
it '5 numerals parses' do
|
84
99
|
parser = setup_parser('MMCE 21645Z 12010KT 8SM SKC 29/26 A2992 RMK')
|
85
100
|
|
86
|
-
expect(parser.time).to eq(Time.gm(2011,
|
101
|
+
expect(parser.time).to eq(Time.gm(2011, 5, 2, 16, 45))
|
87
102
|
end
|
88
103
|
|
89
104
|
it "with 4 numerals parses, takes today's day" do
|
90
105
|
parser = setup_parser('HKML 1600Z 19010KT 9999 FEW022 25/22 Q1015')
|
91
106
|
|
92
|
-
expect(parser.time).to eq(Time.gm(2011,
|
107
|
+
expect(parser.time).to eq(Time.gm(2011, 5, 6, 16, 0))
|
93
108
|
end
|
94
109
|
end
|
95
110
|
end
|
96
111
|
|
97
112
|
context '.observer' do
|
98
113
|
it 'real' do
|
99
|
-
parser = setup_parser(
|
114
|
+
parser = setup_parser(
|
115
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
116
|
+
"RMK AO2 P0000"
|
117
|
+
)
|
100
118
|
|
101
119
|
expect(parser.observer.value).to eq(:real)
|
102
120
|
end
|
103
121
|
|
104
122
|
it 'auto' do
|
105
|
-
parser = setup_parser(
|
123
|
+
parser = setup_parser(
|
124
|
+
"CYXS 151034Z AUTO 09003KT 1/8SM FZFG VV001 M03/M03 A3019 " \
|
125
|
+
"RMK SLP263 ICG"
|
126
|
+
)
|
106
127
|
|
107
128
|
expect(parser.observer.value).to eq(:auto)
|
108
129
|
end
|
109
130
|
|
110
131
|
it 'corrected' do
|
111
|
-
parser = setup_parser(
|
132
|
+
parser = setup_parser(
|
133
|
+
"PAIL 061610Z COR 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
134
|
+
"RMK AO2 P0000"
|
135
|
+
)
|
112
136
|
|
113
137
|
expect(parser.observer.value).to eq(:corrected)
|
114
138
|
end
|
115
139
|
|
116
140
|
it 'corrected (Canadian, first correction)' do
|
117
|
-
parser = setup_parser(
|
141
|
+
parser = setup_parser(
|
142
|
+
"CYZU 310100Z CCA 26004KT 15SM " \
|
143
|
+
"FEW009 BKN040TCU BKN100 OVC210 15/12 A2996 RETS " \
|
144
|
+
"RMK SF1TCU4AC2CI1 SLP149"
|
145
|
+
)
|
118
146
|
|
119
147
|
expect(parser.observer.value).to eq(:corrected)
|
120
148
|
end
|
121
149
|
|
122
150
|
it 'corrected (Canadian, second correction)' do
|
123
|
-
parser = setup_parser(
|
151
|
+
parser = setup_parser(
|
152
|
+
"CYCX 052000Z CCB 30014G27KT 15SM DRSN SCT035 M02/M09 A2992 " \
|
153
|
+
"RMK SC4 SLP133"
|
154
|
+
)
|
124
155
|
|
125
156
|
expect(parser.observer.value).to eq(:corrected)
|
126
157
|
end
|
127
158
|
|
128
159
|
it 'corrected (Canadian, rare third correction)' do
|
129
|
-
parser = setup_parser(
|
160
|
+
parser = setup_parser(
|
161
|
+
"CYEG 120000Z CCC 12005KT 15SM FEW110 BKN190 03/M01 A2980 " \
|
162
|
+
"RMK AC2AC3 SLP122"
|
163
|
+
)
|
130
164
|
|
131
165
|
expect(parser.observer.value).to eq(:corrected)
|
132
166
|
end
|
133
167
|
end
|
134
168
|
|
135
|
-
|
136
|
-
|
169
|
+
context 'wind' do
|
170
|
+
it 'is parsed' do
|
171
|
+
parser = setup_parser(
|
172
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
173
|
+
"RMK AO2 P0000"
|
174
|
+
)
|
175
|
+
|
176
|
+
expect(parser.wind.direction.value).to be_within(0.0001).of(240)
|
177
|
+
expect(parser.wind.speed.to_knots).to be_within(0.0001).of(6)
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'in strict mode' do
|
181
|
+
before do
|
182
|
+
Metar::Parser.compliance = :strict
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'more than 5 digits fails' do
|
186
|
+
expect do
|
187
|
+
setup_parser('KSEE 181947Z 000000KT 10SM SKC 22/10 A2999')
|
188
|
+
end.to raise_error(Metar::ParseError, /Unparsable/)
|
189
|
+
end
|
190
|
+
end
|
137
191
|
|
138
|
-
|
139
|
-
|
192
|
+
context 'in loose mode' do
|
193
|
+
it 'more than 5 digits is parsed' do
|
194
|
+
parser = setup_parser('KSEE 181947Z 000000KT 10SM SKC 22/10 A2999')
|
195
|
+
expect(parser.wind.direction.value).to eq(0.0)
|
196
|
+
expect(parser.visibility.distance.value).to be_within(1).of(16_093)
|
197
|
+
end
|
198
|
+
end
|
140
199
|
end
|
141
200
|
|
142
201
|
it 'variable_wind' do
|
143
|
-
parser = setup_parser(
|
202
|
+
parser = setup_parser(
|
203
|
+
"LIRQ 061520Z 01007KT 350V050 9999 SCT035 BKN080 08/02 Q1005"
|
204
|
+
)
|
144
205
|
|
145
206
|
expect(parser.variable_wind.direction1.value).to be_within(0.0001).of(350)
|
146
207
|
expect(parser.variable_wind.direction2.value).to be_within(0.0001).of(50)
|
@@ -148,59 +209,87 @@ describe Metar::Parser do
|
|
148
209
|
|
149
210
|
context '.visibility' do
|
150
211
|
it 'CAVOK' do
|
151
|
-
parser = setup_parser(
|
212
|
+
parser = setup_parser(
|
213
|
+
"PAIL 061610Z 24006KT CAVOK M17/M20 A2910 RMK AO2 P0000"
|
214
|
+
)
|
152
215
|
|
153
|
-
expect(parser.visibility.distance.value).
|
216
|
+
expect(parser.visibility.distance.value).
|
217
|
+
to be_within(0.01).of(10_000.00)
|
154
218
|
expect(parser.visibility.comparator).to eq(:more_than)
|
155
219
|
expect(parser.present_weather.size).to eq(1)
|
156
|
-
expect(parser.present_weather[0].phenomenon).
|
220
|
+
expect(parser.present_weather[0].phenomenon).
|
221
|
+
to eq('No significant weather')
|
157
222
|
expect(parser.sky_conditions.size).to eq(1)
|
158
223
|
expect(parser.sky_conditions[0].type).to eq(nil)
|
159
224
|
end
|
160
225
|
|
161
226
|
it 'visibility_miles_and_fractions' do
|
162
|
-
parser = setup_parser(
|
227
|
+
parser = setup_parser(
|
228
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
229
|
+
"RMK AO2 P0000"
|
230
|
+
)
|
163
231
|
|
164
232
|
expect(parser.visibility.distance.to_miles).to be_within(0.01).of(1.75)
|
165
233
|
end
|
166
234
|
|
167
235
|
it 'in meters' do
|
168
|
-
parser = setup_parser(
|
236
|
+
parser = setup_parser(
|
237
|
+
"VABB 282210Z 22005KT 4000 HZ SCT018 " \
|
238
|
+
"FEW025TCU BKN100 28/25 Q1003 NOSIG"
|
239
|
+
)
|
169
240
|
|
170
241
|
expect(parser.visibility.distance.value).to be_within(0.01).of(4000)
|
171
242
|
end
|
172
243
|
|
173
244
|
it '//// with automatic observer' do
|
174
|
-
parser = setup_parser(
|
245
|
+
parser = setup_parser(
|
246
|
+
"CYXS 151034Z AUTO 09003KT //// FZFG VV001 M03/M03 A3019 " \
|
247
|
+
"RMK SLP263 ICG"
|
248
|
+
)
|
175
249
|
|
176
250
|
expect(parser.visibility).to be_nil
|
177
251
|
end
|
178
252
|
end
|
179
253
|
|
180
254
|
it 'runway_visible_range' do
|
181
|
-
parser = setup_parser(
|
255
|
+
parser = setup_parser(
|
256
|
+
"ESSB 151020Z 26003KT 2000 R12/1000N R30/1500N VV002 M07/M07 " \
|
257
|
+
"Q1013 1271//55"
|
258
|
+
)
|
182
259
|
expect(parser.runway_visible_range.size).to eq(2)
|
183
260
|
expect(parser.runway_visible_range[0].designator).to eq('12')
|
184
|
-
expect(parser.runway_visible_range[0].visibility1.distance.value).
|
261
|
+
expect(parser.runway_visible_range[0].visibility1.distance.value).
|
262
|
+
to eq(1000)
|
185
263
|
expect(parser.runway_visible_range[0].tendency).to eq(:no_change)
|
186
264
|
end
|
187
265
|
|
188
266
|
it 'runway_visible_range_defaults_to_empty_array' do
|
189
|
-
parser = setup_parser(
|
267
|
+
parser = setup_parser(
|
268
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
269
|
+
"RMK AO2 P0000"
|
270
|
+
)
|
190
271
|
|
191
272
|
expect(parser.runway_visible_range.size).to eq(0)
|
192
273
|
end
|
193
274
|
|
194
275
|
it 'runway_visible_range_variable' do
|
195
|
-
parser = setup_parser(
|
196
|
-
|
197
|
-
|
198
|
-
|
276
|
+
parser = setup_parser(
|
277
|
+
"KPDX 151108Z 11006KT 1/4SM R10R/1600VP6000FT FG OVC002 05/05 A3022 " \
|
278
|
+
"RMK AO2"
|
279
|
+
)
|
280
|
+
|
281
|
+
expect(parser.runway_visible_range[0].visibility1.distance.to_feet).
|
282
|
+
to eq(1600.0)
|
283
|
+
expect(parser.runway_visible_range[0].visibility2.distance.to_feet).
|
284
|
+
to eq(6000.0)
|
199
285
|
end
|
200
286
|
|
201
287
|
context '.present_weather' do
|
202
288
|
it 'normal' do
|
203
|
-
parser = setup_parser(
|
289
|
+
parser = setup_parser(
|
290
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
291
|
+
"RMK AO2 P0000"
|
292
|
+
)
|
204
293
|
|
205
294
|
expect(parser.present_weather.size).to eq(1)
|
206
295
|
expect(parser.present_weather[0].modifier).to eq('light')
|
@@ -208,21 +297,38 @@ describe Metar::Parser do
|
|
208
297
|
end
|
209
298
|
|
210
299
|
it 'auto + //' do
|
211
|
-
parser = setup_parser(
|
300
|
+
parser = setup_parser(
|
301
|
+
"PAIL 061610Z AUTO 24006KT 1 3/4SM // BKN016 OVC030 M17/M20 A2910 " \
|
302
|
+
"RMK AO2 P0000"
|
303
|
+
)
|
212
304
|
|
213
305
|
expect(parser.present_weather.size).to eq(1)
|
214
306
|
expect(parser.present_weather[0].phenomenon).to eq('not observed')
|
215
307
|
end
|
308
|
+
|
309
|
+
it 'reports no significant weather' do
|
310
|
+
parser = setup_parser(
|
311
|
+
"LFSL 260630Z 31007KT 6000 NSW SCT018 BKN100 29/23 Q1010 NOSIG"
|
312
|
+
)
|
313
|
+
|
314
|
+
expect(parser.present_weather.size).to eq(1)
|
315
|
+
expect(parser.present_weather[0].phenomenon).to eq('no significant weather')
|
316
|
+
end
|
216
317
|
end
|
217
318
|
|
218
319
|
it 'present_weather_defaults_to_empty_array' do
|
219
|
-
parser = setup_parser(
|
320
|
+
parser = setup_parser(
|
321
|
+
"PAIL 061610Z 24006KT 1 3/4SM BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000"
|
322
|
+
)
|
220
323
|
expect(parser.present_weather.size).to eq(0)
|
221
324
|
end
|
222
325
|
|
223
326
|
context '.sky_conditions' do
|
224
327
|
it 'normal' do
|
225
|
-
parser = setup_parser(
|
328
|
+
parser = setup_parser(
|
329
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
330
|
+
"RMK AO2 P0000"
|
331
|
+
)
|
226
332
|
|
227
333
|
expect(parser.sky_conditions.size).to eq(2)
|
228
334
|
expect(parser.sky_conditions[0].quantity).to eq('broken')
|
@@ -232,39 +338,72 @@ describe Metar::Parser do
|
|
232
338
|
end
|
233
339
|
|
234
340
|
it 'auto + ///' do
|
235
|
-
parser = setup_parser(
|
341
|
+
parser = setup_parser(
|
342
|
+
"PAIL 061610Z AUTO 24006KT 1 3/4SM /// M17/M20 A2910 RMK AO2 P0000"
|
343
|
+
)
|
236
344
|
|
237
345
|
expect(parser.sky_conditions.size).to eq(0)
|
238
346
|
end
|
239
347
|
end
|
240
348
|
|
241
349
|
it 'sky_conditions_defaults_to_empty_array' do
|
242
|
-
parser = setup_parser(
|
350
|
+
parser = setup_parser(
|
351
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN M17/M20 A2910 RMK AO2 P0000"
|
352
|
+
)
|
243
353
|
expect(parser.sky_conditions.size).to eq(0)
|
244
354
|
end
|
245
355
|
|
246
356
|
it 'vertical_visibility' do
|
247
|
-
parser = setup_parser(
|
357
|
+
parser = setup_parser(
|
358
|
+
"CYXS 151034Z AUTO 09003KT 1/8SM FZFG VV001 M03/M03 A3019 " \
|
359
|
+
"RMK SLP263 ICG"
|
360
|
+
)
|
248
361
|
expect(parser.vertical_visibility.value).to eq(30.48)
|
249
362
|
end
|
250
363
|
|
251
364
|
it 'temperature' do
|
252
|
-
parser = setup_parser(
|
365
|
+
parser = setup_parser(
|
366
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
367
|
+
"RMK AO2 P0000"
|
368
|
+
)
|
253
369
|
expect(parser.temperature.value).to eq(-17)
|
254
370
|
end
|
255
371
|
|
372
|
+
it "accepts a blank temperature" do
|
373
|
+
parser = setup_parser(
|
374
|
+
"KSMO 281655Z 18003KT 9SM SCT020 /20 A3002 RMK A02 T0200 $"
|
375
|
+
)
|
376
|
+
expect(parser.temperature).to eq(nil)
|
377
|
+
end
|
378
|
+
|
256
379
|
it 'dew_point' do
|
257
|
-
parser = setup_parser(
|
380
|
+
parser = setup_parser(
|
381
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
382
|
+
"RMK AO2 P0000"
|
383
|
+
)
|
258
384
|
expect(parser.dew_point.value).to eq(-20)
|
259
385
|
end
|
260
386
|
|
387
|
+
it "accepts a blank dew_point" do
|
388
|
+
parser = setup_parser(
|
389
|
+
"KSMO 281655Z 18003KT 9SM SCT020 20/ A3002 RMK A02 T0200 $"
|
390
|
+
)
|
391
|
+
expect(parser.dew_point).to eq(nil)
|
392
|
+
end
|
393
|
+
|
261
394
|
it 'sea_level_pressure' do
|
262
|
-
parser = setup_parser(
|
263
|
-
|
395
|
+
parser = setup_parser(
|
396
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
397
|
+
"RMK AO2 P0000"
|
398
|
+
)
|
399
|
+
expect(parser.sea_level_pressure.pressure.to_inches_of_mercury).
|
400
|
+
to eq(29.10)
|
264
401
|
end
|
265
402
|
|
266
403
|
it 'recent weather' do
|
267
|
-
parser = setup_parser(
|
404
|
+
parser = setup_parser(
|
405
|
+
"CYQH 310110Z 00000KT 20SM SCT035CB BKN050 RETS RMK CB4SC1"
|
406
|
+
)
|
268
407
|
|
269
408
|
expect(parser.recent_weather).to be_a Array
|
270
409
|
expect(parser.recent_weather.size).to eq(1)
|
@@ -273,14 +412,19 @@ describe Metar::Parser do
|
|
273
412
|
|
274
413
|
context 'remarks' do
|
275
414
|
it 'are collected' do
|
276
|
-
parser = setup_parser(
|
415
|
+
parser = setup_parser(
|
416
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
417
|
+
"RMK AO2 P0000"
|
418
|
+
)
|
277
419
|
|
278
420
|
expect(parser.remarks).to be_a Array
|
279
421
|
expect(parser.remarks.size).to eq(2)
|
280
422
|
end
|
281
423
|
|
282
424
|
it 'remarks defaults to empty array' do
|
283
|
-
parser = setup_parser(
|
425
|
+
parser = setup_parser(
|
426
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910"
|
427
|
+
)
|
284
428
|
|
285
429
|
expect(parser.remarks).to be_a Array
|
286
430
|
expect(parser.remarks.size).to eq(0)
|
@@ -288,19 +432,26 @@ describe Metar::Parser do
|
|
288
432
|
|
289
433
|
context 'known remarks' do
|
290
434
|
it 'parses sea level pressure' do
|
291
|
-
parser = setup_parser(
|
435
|
+
parser = setup_parser(
|
436
|
+
'CYZT 052200Z 31010KT 20SM SKC 17/12 A3005 RMK SLP174 20046'
|
437
|
+
)
|
292
438
|
|
293
439
|
expect(parser.remarks[0]).to be_a(Metar::Data::SeaLevelPressure)
|
294
440
|
end
|
295
441
|
|
296
442
|
it 'parses extreme temperature' do
|
297
|
-
parser = setup_parser(
|
443
|
+
parser = setup_parser(
|
444
|
+
'CYZT 052200Z 31010KT 20SM SKC 17/12 A3005 RMK SLP174 20046'
|
445
|
+
)
|
298
446
|
|
299
447
|
expect(parser.remarks[1]).to be_temperature_extreme(:minimum, 4.6)
|
300
448
|
end
|
301
449
|
|
302
450
|
it 'parses density altitude' do
|
303
|
-
parser = setup_parser(
|
451
|
+
parser = setup_parser(
|
452
|
+
"CYBW 010000Z AUTO VRB04KT 9SM SCT070 13/M01 A3028 " \
|
453
|
+
"RMK DENSITY ALT 4100FT="
|
454
|
+
)
|
304
455
|
|
305
456
|
expect(parser.remarks[0]).to be_a(Metar::Data::DensityAltitude)
|
306
457
|
expect(parser.remarks[0].height.value).to be_within(0.001).of(1249.68)
|
@@ -314,14 +465,20 @@ describe Metar::Parser do
|
|
314
465
|
|
315
466
|
it 'unparsed data causes an error' do
|
316
467
|
expect do
|
317
|
-
setup_parser(
|
468
|
+
setup_parser(
|
469
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
470
|
+
"FOO RMK AO2 P0000"
|
471
|
+
)
|
318
472
|
end.to raise_error(Metar::ParseError, /Unparsable text found/)
|
319
473
|
end
|
320
474
|
end
|
321
475
|
|
322
476
|
context 'in loose mode' do
|
323
477
|
it 'unparsed data is collected' do
|
324
|
-
parser = setup_parser(
|
478
|
+
parser = setup_parser(
|
479
|
+
"PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 " \
|
480
|
+
"FOO RMK AO2 P0000"
|
481
|
+
)
|
325
482
|
|
326
483
|
expect(parser.unparsed).to eq(['FOO'])
|
327
484
|
expect(parser.remarks.size).to eq(2)
|
@@ -330,7 +487,9 @@ describe Metar::Parser do
|
|
330
487
|
end
|
331
488
|
|
332
489
|
context "final '='" do
|
333
|
-
let(:parser)
|
490
|
+
let(:parser) do
|
491
|
+
setup_parser('LPPT 070530Z 34003KT 310V010 CAVOK 14/12 Q1013=')
|
492
|
+
end
|
334
493
|
|
335
494
|
it 'parses the final chunk' do
|
336
495
|
expect(parser.sea_level_pressure.value).to eq(1.013)
|
@@ -350,7 +509,9 @@ describe Metar::Parser do
|
|
350
509
|
end
|
351
510
|
|
352
511
|
context "final ' ='" do
|
353
|
-
let(:parser)
|
512
|
+
let(:parser) do
|
513
|
+
setup_parser('LPPT 070530Z 34003KT 310V010 CAVOK 14/12 Q1013 =')
|
514
|
+
end
|
354
515
|
|
355
516
|
it 'parses the final chunk' do
|
356
517
|
expect(parser.sea_level_pressure.value).to eq(1.013)
|
@@ -399,12 +560,12 @@ describe Metar::Parser do
|
|
399
560
|
[
|
400
561
|
[:metar, "is the raw METAR string"],
|
401
562
|
[:station_code, "the station code"],
|
402
|
-
[:datetime, "the date/time string"]
|
563
|
+
[:datetime, "the date/time string"]
|
403
564
|
].each do |attr, description|
|
404
|
-
context
|
565
|
+
context attr.to_s do
|
405
566
|
specify ":#{attr} is #{description}" do
|
406
567
|
expect(result).to include(attr)
|
407
|
-
expect(result[attr]).to eq(
|
568
|
+
expect(result[attr]).to eq(send(attr))
|
408
569
|
end
|
409
570
|
end
|
410
571
|
end
|
@@ -416,11 +577,11 @@ describe Metar::Parser do
|
|
416
577
|
[:visibility, "visibility"],
|
417
578
|
[:runway_visible_range, "runway visible range"],
|
418
579
|
[:present_weather, "present weather"],
|
419
|
-
[:sky_conditions, "sky conditions"]
|
580
|
+
[:sky_conditions, "sky conditions"],
|
420
581
|
[:vertical_visibility, "vertical visibility"],
|
421
582
|
[:temperature_and_dew_point, "temperature and dew point"],
|
422
583
|
[:sea_level_pressure, "sea-level pressure"],
|
423
|
-
[:recent_weather, "recent weather"]
|
584
|
+
[:recent_weather, "recent weather"]
|
424
585
|
].each do |attr, name|
|
425
586
|
context "with #{name}" do
|
426
587
|
let(:parts) { super() + [send(attr)] }
|
@@ -468,4 +629,3 @@ describe Metar::Parser do
|
|
468
629
|
Metar::Parser.new(raw)
|
469
630
|
end
|
470
631
|
end
|
471
|
-
|