metar-parser 1.5.0 → 1.7.0

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