metar-parser 1.4.2 → 1.6.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 +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
-