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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -49
  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 -13
  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 +106 -87
  25. data/lib/metar/data.rb +25 -23
  26. data/lib/metar/i18n.rb +5 -2
  27. data/lib/metar/parser.rb +47 -22
  28. data/lib/metar/raw.rb +32 -44
  29. data/lib/metar/report.rb +31 -20
  30. data/lib/metar/station.rb +28 -19
  31. data/lib/metar/version.rb +4 -2
  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 +224 -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 +43 -44
  58. metadata +56 -43
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,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, 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
133
167
  end
134
168
 
135
- it 'wind' do
136
- parser = setup_parser("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
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
- expect(parser.wind.direction.value).to be_within(0.0001).of(240)
139
- expect(parser.wind.speed.to_knots).to be_within(0.0001).of(6)
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("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
+ )
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("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
+ )
152
215
 
153
- 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)
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).to eq('No significant weather')
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("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
+ )
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('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
+ )
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("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
+ )
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("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
+ )
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).to eq(1000)
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("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
+ )
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("KPDX 151108Z 11006KT 1/4SM R10R/1600VP6000FT FG OVC002 05/05 A3022 RMK AO2")
196
-
197
- expect(parser.runway_visible_range[0].visibility1.distance.to_feet).to eq(1600.0)
198
- 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)
199
285
  end
200
286
 
201
287
  context '.present_weather' do
202
288
  it 'normal' do
203
- 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
+ )
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("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
+ )
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("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
+ )
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("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
+ )
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("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
+ )
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("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
+ )
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("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
+ )
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("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
+ )
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("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
+ )
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("PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000")
263
- 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)
264
401
  end
265
402
 
266
403
  it 'recent weather' do
267
- 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
+ )
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("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
+ )
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("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
+ )
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('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
+ )
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('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
+ )
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('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
+ )
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("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
+ )
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("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
+ )
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) {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
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) {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
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 "#{attr}" do
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(self.send(attr))
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
-