metar-parser 1.2.0 → 1.2.1

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -2
  3. data/lib/metar/data.rb +31 -32
  4. data/lib/metar/parser.rb +12 -11
  5. data/lib/metar/raw.rb +1 -1
  6. data/lib/metar/report.rb +3 -7
  7. data/lib/metar/station.rb +15 -21
  8. data/lib/metar/version.rb +1 -2
  9. data/spec/data_spec.rb +26 -0
  10. data/spec/{unit/distance_spec.rb → distance_spec.rb} +3 -3
  11. data/spec/{unit/i18n_spec.rb → i18n_spec.rb} +1 -1
  12. data/spec/{unit/parser_spec.rb → parser_spec.rb} +22 -8
  13. data/spec/pressure_spec.rb +22 -0
  14. data/spec/{unit/raw_spec.rb → raw_spec.rb} +33 -40
  15. data/spec/{unit/remark_spec.rb → remark_spec.rb} +4 -25
  16. data/spec/{unit/report_spec.rb → report_spec.rb} +18 -16
  17. data/spec/runway_visible_range_spec.rb +81 -0
  18. data/spec/{unit/sky_condition_spec.rb → sky_condition_spec.rb} +0 -1
  19. data/spec/spec_helper.rb +1 -1
  20. data/spec/speed_spec.rb +45 -0
  21. data/spec/{unit/station_spec.rb → station_spec.rb} +83 -52
  22. data/spec/{unit/temperature_spec.rb → temperature_spec.rb} +7 -7
  23. data/spec/{unit/variable_wind_spec.rb → variable_wind_spec.rb} +10 -11
  24. data/spec/{unit/vertical_visibility_spec.rb → vertical_visibility_spec.rb} +1 -1
  25. data/spec/{unit/visibility_spec.rb → visibility_spec.rb} +16 -20
  26. data/spec/weather_phenomenon_spec.rb +66 -0
  27. data/spec/{unit/wind_spec.rb → wind_spec.rb} +10 -11
  28. metadata +53 -38
  29. data/bin/parse_raw.rb +0 -27
  30. data/spec/unit/pressure_spec.rb +0 -22
  31. data/spec/unit/runway_visible_range_spec.rb +0 -88
  32. data/spec/unit/speed_spec.rb +0 -45
  33. data/spec/unit/weather_phenomenon_spec.rb +0 -66
@@ -76,8 +76,8 @@ describe Metar::Raw::Metar do
76
76
  let(:raw_metar) { "OPPS 3123Z 23006KT 4000 HZ SCT040 SCT100 17/12 Q1011" }
77
77
 
78
78
  it "throws an error" do
79
- expect { subject.time }.
80
- to raise_error(RuntimeError, /6 digit/)
79
+ expect { subject.time }
80
+ .to raise_error(RuntimeError, /6 digit/)
81
81
  end
82
82
  end
83
83
 
@@ -85,8 +85,8 @@ describe Metar::Raw::Metar do
85
85
  let(:raw_metar) { "OPPS 332359Z 23006KT 4000 HZ SCT040 SCT100 17/12 Q1011" }
86
86
 
87
87
  it "throws an error" do
88
- expect { subject.time }.
89
- to raise_error(RuntimeError, /at most 31/)
88
+ expect { subject.time }
89
+ .to raise_error(RuntimeError, /at most 31/)
90
90
  end
91
91
  end
92
92
 
@@ -94,8 +94,8 @@ describe Metar::Raw::Metar do
94
94
  let(:raw_metar) { "OPPS 002359Z 23006KT 4000 HZ SCT040 SCT100 17/12 Q1011" }
95
95
 
96
96
  it "throws an error" do
97
- expect { subject.time }.
98
- to raise_error(RuntimeError, /greater than 0/)
97
+ expect { subject.time }
98
+ .to raise_error(RuntimeError, /greater than 0/)
99
99
  end
100
100
  end
101
101
  end
@@ -157,6 +157,10 @@ describe Metar::Raw::Noaa do
157
157
  end
158
158
 
159
159
  context '.fetch' do
160
+ before do
161
+ allow(ftp).to receive(:retrbinary).and_yield("chunk 1\n").and_yield("chunk 2\n")
162
+ end
163
+
160
164
  it 'uses the connection' do
161
165
  Metar::Raw::Noaa.fetch('the_cccc')
162
166
 
@@ -170,51 +174,40 @@ describe Metar::Raw::Noaa do
170
174
  end
171
175
 
172
176
  it 'returns the data' do
173
- def ftp.retrbinary(*args, &block)
174
- block.call "chunk 1\n"
175
- block.call "chunk 2\n"
176
- end
177
177
  raw = Metar::Raw::Noaa.fetch('the_cccc')
178
178
 
179
179
  expect(raw).to eq("chunk 1\nchunk 2\n")
180
180
  end
181
181
 
182
- it 'retries retrieval once' do
183
- def ftp.attempt
184
- @attempt
185
- end
186
- def ftp.attempt=(a)
187
- @attempt = a
188
- end
189
- ftp.attempt = 0
190
- def ftp.retrbinary(*args, &block)
191
- self.attempt = self.attempt + 1
192
- raise Net::FTPTempError if self.attempt == 1
193
- block.call "chunk 1\n"
194
- block.call "chunk 2\n"
182
+ context 'if retrieval fails once' do
183
+ before do
184
+ @attempt = 0
185
+
186
+ allow(ftp).to receive(:retrbinary) do |_args, &block|
187
+ @attempt += 1
188
+ raise Net::FTPTempError if @attempt == 1
189
+ block.call "chunk 1\n"
190
+ block.call "chunk 2\n"
191
+ end
195
192
  end
196
-
197
- raw = Metar::Raw::Noaa.fetch('the_cccc')
198
193
 
199
- expect(raw).to eq("chunk 1\nchunk 2\n")
200
- end
194
+ it 'retries' do
195
+ raw = Metar::Raw::Noaa.fetch('the_cccc')
201
196
 
202
- it 'fails with an error, if retrieval fails twice' do
203
- def ftp.attempt
204
- @attempt
205
- end
206
- def ftp.attempt=(a)
207
- @attempt = a
197
+ expect(raw).to eq("chunk 1\nchunk 2\n")
208
198
  end
209
- ftp.attempt = 0
210
- def ftp.retrbinary(*args, &block)
211
- self.attempt = self.attempt + 1
212
- raise Net::FTPTempError
199
+ end
200
+
201
+ context 'if retrieval fails twice' do
202
+ before do
203
+ allow(ftp).to receive(:retrbinary).and_raise(Net::FTPTempError)
213
204
  end
214
205
 
215
- expect do
216
- Metar::Raw::Noaa.fetch('the_cccc')
217
- end.to raise_error(RuntimeError, /failed 2 times/)
206
+ it 'fails with an error' do
207
+ expect do
208
+ Metar::Raw::Noaa.fetch('the_cccc')
209
+ end.to raise_error(RuntimeError, /failed 2 times/)
210
+ end
218
211
  end
219
212
  end
220
213
 
@@ -1,5 +1,5 @@
1
1
  require "spec_helper"
2
-
2
+
3
3
  describe Metar::Remark do
4
4
  context '.parse' do
5
5
  it 'delegate to subclasses' do
@@ -21,22 +21,18 @@ describe Metar::Remark do
21
21
  expect(Metar::Remark.parse(raw)).to be_temperature_extreme(*expected)
22
22
  end
23
23
  end
24
-
25
24
  end
26
25
 
27
26
  context '24-hour maximum and minimum' do
28
-
29
27
  it 'returns minimum and maximum' do
30
28
  max, min = Metar::Remark.parse('400461006')
31
29
 
32
30
  expect(max).to be_temperature_extreme(:maximum, 4.6)
33
31
  expect(min).to be_temperature_extreme(:minimum, -0.6)
34
32
  end
35
-
36
33
  end
37
34
 
38
35
  context 'pressure tendency' do
39
-
40
36
  it 'steady_then_decreasing' do
41
37
  pt = Metar::Remark.parse('58033')
42
38
 
@@ -44,31 +40,26 @@ describe Metar::Remark do
44
40
  expect(pt.character).to eq(:steady_then_decreasing)
45
41
  expect(pt.value).to eq(3.3)
46
42
  end
47
-
48
43
  end
49
44
 
50
45
  context '3-hour and 6-hour precipitation' do
51
-
52
46
  it '60009' do
53
47
  pr = Metar::Remark.parse('60009')
54
-
48
+
55
49
  expect(pr).to be_a(Metar::Precipitation)
56
50
  expect(pr.period).to eq(3)
57
51
  expect(pr.amount.value).to eq(0.002286)
58
52
  end
59
-
60
53
  end
61
54
 
62
55
  context '24-hour precipitation' do
63
-
64
56
  it '70015' do
65
57
  pr = Metar::Remark.parse('70015')
66
-
58
+
67
59
  expect(pr).to be_a(Metar::Precipitation)
68
60
  expect(pr.period).to eq(24)
69
61
  expect(pr.amount.value).to eq(0.003810)
70
62
  end
71
-
72
63
  end
73
64
 
74
65
  context 'automated station' do
@@ -84,22 +75,18 @@ describe Metar::Remark do
84
75
  expect(aut.type).to eq(expected[1])
85
76
  end
86
77
  end
87
-
88
78
  end
89
79
 
90
80
  context 'sea-level pressure' do
91
-
92
81
  it 'SLP125' do
93
82
  slp = Metar::Remark.parse('SLP125')
94
83
 
95
84
  expect(slp).to be_a(Metar::SeaLevelPressure)
96
85
  expect(slp.pressure.value).to eq(0.0125)
97
86
  end
98
-
99
87
  end
100
88
 
101
89
  context 'hourly temperature and dew point' do
102
-
103
90
  it 'T00640036' do
104
91
  htm = Metar::Remark.parse('T00641036')
105
92
 
@@ -107,17 +94,12 @@ describe Metar::Remark do
107
94
  expect(htm.temperature.value).to eq(6.4)
108
95
  expect(htm.dew_point.value).to eq(-3.6)
109
96
  end
110
-
111
97
  end
112
-
113
98
  end
114
-
115
99
  end
116
100
 
117
101
  describe Metar::Lightning do
118
-
119
102
  context '.parse_chunks' do
120
-
121
103
  [
122
104
  ['direction', 'LTG SE', [:default, nil, ['SE']]],
123
105
  ['distance direction', 'LTG DSNT SE', [:default, 16093.44, ['SE']]],
@@ -151,7 +133,7 @@ describe Metar::Lightning do
151
133
  it 'fails if the first chunk is not LTGnnn' do
152
134
  expect do
153
135
  Metar::Lightning.parse_chunks(['FOO'])
154
- end. to raise_error(RuntimeError, /not lightning/)
136
+ end.to raise_error(RuntimeError, /not lightning/)
155
137
  end
156
138
 
157
139
  it "doesn't not fail if all chunks are parsed" do
@@ -161,8 +143,5 @@ describe Metar::Lightning do
161
143
 
162
144
  expect(chunks).to eq([])
163
145
  end
164
-
165
146
  end
166
-
167
147
  end
168
-
@@ -6,10 +6,10 @@ describe Metar::Report do
6
6
  let(:parser) do
7
7
  double(
8
8
  Metar::Parser,
9
- :station_code => station_code,
10
- :date => Date.parse(metar_date),
11
- :time => Time.parse(metar_datetime),
12
- :observer => :real
9
+ station_code: station_code,
10
+ date: Date.parse(metar_date),
11
+ time: Time.parse(metar_datetime),
12
+ observer: :real
13
13
  )
14
14
  end
15
15
  let(:station_code) { "SSSS" }
@@ -17,7 +17,9 @@ describe Metar::Report do
17
17
  let(:metar_date) { "2008/05/06" }
18
18
  let(:metar_time) { "10:56" }
19
19
  let(:metar_datetime) { "#{metar_date} #{metar_time}" }
20
- let(:station) { double(Metar::Station, :name => 'Airport 1', :country => 'Wwwwww') }
20
+ let(:station) do
21
+ double(Metar::Station, name: 'Airport 1', country: 'Wwwwww')
22
+ end
21
23
 
22
24
  before do
23
25
  allow(Metar::Station).to receive(:find_by_cccc).with(station_code) { station }
@@ -82,7 +84,7 @@ describe Metar::Report do
82
84
  :temperature,
83
85
  :dew_point,
84
86
  :sea_level_pressure,
85
- ].each do | attribute |
87
+ ].each do |attribute|
86
88
  example attribute do
87
89
  allow(parser).to receive(attribute) { attribute.to_s }
88
90
 
@@ -91,7 +93,7 @@ describe Metar::Report do
91
93
  end
92
94
 
93
95
  context "#sky_summary" do
94
- let(:conditions1) { double(:to_summary => "skies1") }
96
+ let(:conditions1) { double(to_summary: "skies1") }
95
97
 
96
98
  it "returns the summary" do
97
99
  allow(parser).to receive(:sky_conditions) { [conditions1] }
@@ -107,7 +109,7 @@ describe Metar::Report do
107
109
 
108
110
  it "uses the last, if there is more than 1" do
109
111
  @skies1 = double("sky_conditions1")
110
- @skies2 = double("sky_conditions2", :to_summary => "skies2")
112
+ @skies2 = double("sky_conditions2", to_summary: "skies2")
111
113
  allow(parser).to receive(:sky_conditions) { [@skies1, @skies2] }
112
114
 
113
115
  expect(subject.sky_summary).to eq("skies2")
@@ -117,28 +119,28 @@ describe Metar::Report do
117
119
 
118
120
  context "joined" do
119
121
  it "#runway_visible_range" do
120
- @rvr1 = double("rvr1", :to_s => "rvr1")
121
- @rvr2 = double("rvr2", :to_s => "rvr2")
122
+ @rvr1 = double("rvr1", to_s: "rvr1")
123
+ @rvr2 = double("rvr2", to_s: "rvr2")
122
124
  allow(parser).to receive(:runway_visible_range) { [@rvr1, @rvr2] }
123
125
 
124
126
  expect(subject.runway_visible_range).to eq("rvr1, rvr2")
125
127
  end
126
128
 
127
129
  it "#present_weather" do
128
- allow(parser).to receive(:present_weather) { ["pw1", "pw2"] }
130
+ allow(parser).to receive(:present_weather) { %w(pw1 pw2) }
129
131
 
130
132
  expect(subject.present_weather).to eq("pw1, pw2")
131
133
  end
132
134
 
133
135
  it "#remarks" do
134
- allow(parser).to receive(:remarks) { ["rem1", "rem2"] }
136
+ allow(parser).to receive(:remarks) { %w(rem1 rem2) }
135
137
 
136
138
  expect(subject.remarks).to eq("rem1, rem2")
137
139
  end
138
140
 
139
141
  it '#sky_conditions' do
140
- sky1 = double('sky1', :to_s => 'sky1')
141
- sky2 = double('sky2', :to_s => 'sky2')
142
+ sky1 = double('sky1', to_s: 'sky1')
143
+ sky2 = double('sky2', to_s: 'sky2')
142
144
  allow(parser).to receive(:sky_conditions) { [sky1, sky2] }
143
145
 
144
146
  expect(subject.sky_conditions).to eq("sky1, sky2")
@@ -147,8 +149,8 @@ describe Metar::Report do
147
149
  end
148
150
 
149
151
  context '#to_s' do
150
- let(:sky1) { double('sky1', :to_summary => 'sky1') }
151
- let(:sky2) { double('sky2', :to_summary => 'sky2') }
152
+ let(:sky1) { double('sky1', to_summary: 'sky1') }
153
+ let(:sky2) { double('sky2', to_summary: 'sky2') }
152
154
 
153
155
  before do
154
156
  allow(parser).to receive(:wind) { "wind" }
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ RSpec::Matchers.define :be_runway_visible_range do |designator, visibility1, visibility2, tendency|
5
+ match do |rvr|
6
+ if rvr.nil? && designator.nil?
7
+ true
8
+ elsif rvr.nil? != designator.nil?
9
+ false
10
+ elsif rvr.visibility1.nil? != visibility1.nil?
11
+ false
12
+ elsif rvr.visibility2.nil? != visibility2.nil?
13
+ false
14
+ elsif rvr.tendency.nil? != tendency.nil?
15
+ false
16
+ elsif ! visibility1.nil? &&
17
+ ((rvr.visibility1.distance.value - visibility1[0]).abs > 0.01 ||
18
+ rvr.visibility1.comparator != visibility1[ 2 ])
19
+ false
20
+ elsif ! visibility2.nil? &&
21
+ ((rvr.visibility2.distance.value - visibility2[0]).abs > 0.02 ||
22
+ rvr.visibility2.comparator != visibility2[2])
23
+ false
24
+ elsif tendency != rvr.tendency
25
+ false
26
+ else
27
+ true
28
+ end
29
+ end
30
+ end
31
+
32
+ describe Metar::RunwayVisibleRange do
33
+ context '.parse' do
34
+ [
35
+ ['understands R + nn + / + nnnn', 'R12/3400', ['12', [3400.00, nil, nil], nil, nil]],
36
+ ['understands runway positions: RLC', 'R12L/3400', ['12L', [3400.00, nil, nil], nil, nil]],
37
+ ['understands comparators: PM', 'R12/P3400', ['12', [3400.00, nil, :more_than], nil, nil]],
38
+ ['understands tendencies: NUD', 'R12/3400U', ['12', [3400.00, nil, nil], nil, :improving]],
39
+ ['understands feet', 'R12/3400FT', ['12', [1036.32, nil, nil], nil, nil]],
40
+ ['understands second visibilities (m)', 'R26/0750V1200U', ['12', [ 750.0, nil, nil], [1200.0, nil, nil], :improving]],
41
+ ['understands second visibilities (ft)', 'R12/3400V1800FT', ['12', [1036.32, nil, nil], [548.64, nil, nil], nil]],
42
+ ['returns nil for nil', nil, [nil, nil, nil, nil]],
43
+ ].each do |docstring, raw, expected|
44
+ example docstring do
45
+ expect(Metar::RunwayVisibleRange.parse(raw)).to be_runway_visible_range(*expected)
46
+ end
47
+ end
48
+ end
49
+
50
+ context '#to_s' do
51
+ before :all do
52
+ @locale = I18n.locale
53
+ I18n.locale = :it
54
+ end
55
+
56
+ after :all do
57
+ I18n.locale = @locale
58
+ end
59
+
60
+ [
61
+ ['v1', :en, [[3400.00, nil, nil], nil, nil], 'runway 14: 3400m'],
62
+ ['v1 and v2', :en, [[3400.00, nil, nil], [1900.00, nil, nil], nil ], 'runway 14: from 3400m to 1900m'],
63
+ ['v1 and tendency', :en, [[3400.00, nil, nil], nil, :improving ], 'runway 14: 3400m improving'],
64
+ ].each do |docstring, locale, (visibility1, visibility2, tendency), expected|
65
+ d1 = Metar::Distance.new(visibility1[0])
66
+ v1 = Metar::Visibility.new(d1, visibility1[1], visibility1[2])
67
+ v2 =
68
+ if ! visibility2.nil?
69
+ d2 = Metar::Distance.new(visibility2[0])
70
+ Metar::Visibility.new(d2, visibility2[1], visibility2[2])
71
+ else
72
+ nil
73
+ end
74
+
75
+ example docstring + " (#{locale})" do
76
+ I18n.locale = locale
77
+ expect(Metar::RunwayVisibleRange.new('14', v1, v2, tendency).to_s).to eq(expected)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -68,4 +68,3 @@ describe Metar::SkyCondition do
68
68
  end
69
69
  end
70
70
  end
71
-
data/spec/spec_helper.rb CHANGED
@@ -9,7 +9,7 @@ if RUBY_VERSION > '1.9'
9
9
  end
10
10
  end
11
11
 
12
- require File.expand_path( File.dirname(__FILE__) + '/../lib/metar' )
12
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/metar')
13
13
 
14
14
  RSpec::Matchers.define :be_temperature_extreme do |extreme, value|
15
15
  match do |remark|
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ describe Metar::Speed do
4
+ context '.parse' do
5
+ it 'returns nil for nil' do
6
+ speed = Metar::Speed.parse(nil)
7
+
8
+ expect(speed).to be_nil
9
+ end
10
+
11
+ it 'parses knots' do
12
+ speed = Metar::Speed.parse('5KT')
13
+
14
+ expect(speed).to be_a(Metar::Speed)
15
+ expect(speed.value).to be_within(0.01).of(2.57)
16
+ end
17
+
18
+ it 'parses meters per second' do
19
+ speed = Metar::Speed.parse('7MPS')
20
+
21
+ expect(speed).to be_a(Metar::Speed)
22
+ expect(speed.value).to be_within(0.01).of(7.00)
23
+ end
24
+
25
+ it 'parses kilometers per hour' do
26
+ speed = Metar::Speed.parse('14KMH')
27
+
28
+ expect(speed).to be_a(Metar::Speed)
29
+ expect(speed.value).to be_within(0.01).of(3.89)
30
+ end
31
+
32
+ it 'trates straight numbers as kilomters per hour' do
33
+ speed = Metar::Speed.parse('14')
34
+
35
+ expect(speed).to be_a(Metar::Speed)
36
+ expect(speed.value).to be_within(0.01).of(3.89)
37
+ end
38
+
39
+ it 'returns nil for other strings' do
40
+ speed = Metar::Speed.parse('')
41
+
42
+ expect(speed).to be_nil
43
+ end
44
+ end
45
+ end
@@ -4,10 +4,10 @@ require "spec_helper"
4
4
  require "stringio"
5
5
 
6
6
  RSpec::Matchers.define :have_attribute do |attribute|
7
- match do | object |
8
- if ! object.respond_to?( attribute )
7
+ match do |object|
8
+ if !object.respond_to?(attribute)
9
9
  false
10
- elsif object.method( attribute ).arity != 0
10
+ elsif object.method(attribute).arity != 0
11
11
  false
12
12
  else
13
13
  true
@@ -16,11 +16,10 @@ RSpec::Matchers.define :have_attribute do |attribute|
16
16
  end
17
17
 
18
18
  describe Metar::Station do
19
- let(:file) { double(File) }
20
-
21
19
  context "using structures" do
22
20
  before do
23
- allow(Metar::Station).to receive(:open).with(Metar::Station::NOAA_STATION_LIST_URL) { nsd_file }
21
+ allow(Metar::Station).to receive(:open)
22
+ .with(Metar::Station::NOAA_STATION_LIST_URL) { nsd_file }
24
23
  end
25
24
 
26
25
  context ".countries" do
@@ -69,18 +68,36 @@ describe Metar::Station do
69
68
  end
70
69
  end
71
70
 
71
+ ##
72
+ # NOAA Station list fields:
73
+ #
74
+ # 0 1 2 3 45 6 7 8 9 10 11 12 13
75
+ # PPPP;00;000;Airport P1;;Ppppp;1;11-03S;055-24E;11-03S;055-24E;000;000;P\r
76
+ #
77
+ # 0 - CCCC
78
+ # 1 - ?
79
+ # 2 - ?
80
+ # 3 - name of station
81
+ # 4 - state
82
+ # 5 - country
83
+ # 6 - ?
84
+ # 7 - latitude1
85
+ # 8 - longitude1
86
+ # 9 - latitude2
87
+ # 10 - longitude2
88
+ # 11 - ?
89
+ # 12 - ?
90
+ # 13 - ?
91
+ #
72
92
  def nsd_file
73
- #0 1 2 3 4 5 6 7 8 9 10 11 12 13
74
- #CCCC;??;???;name;state;country;?;latitude;longitude;latitude;longitude;???;???;?
75
- nsd_text =<<EOT
76
- PPPP;00;000;Airport P1;;Ppppp;1;11-03S;055-24E;11-03S;055-24E;000;000;P
77
- AAAA;00;000;Airport A1;;Aaaaa;1;11-03S;055-24E;11-03S;055-24E;000;000;P
78
- AAAB;00;000;Airport A2;;Aaaaa;1;11-03S;055-24E;11-03S;055-24E;000;000;P
79
- BBBA;00;000;Airport B1;;Bbbbb;1;11-03S;055-24E;11-03S;055-24E;000;000;P
80
- EOT
81
- StringIO.new( nsd_text )
93
+ nsd_text = <<-EOT.gsub(/^\s{8}/, "")
94
+ PPPP;00;000;Airport P1;;Ppppp;1;11-03S;055-24E;11-03S;055-24E;000;000;P\r
95
+ AAAA;00;000;Airport A1;;Aaaaa;1;11-03S;055-24E;11-03S;055-24E;000;000;P\r
96
+ AAAB;00;000;Airport A2;;Aaaaa;1;11-03S;055-24E;11-03S;055-24E;000;000;P\r
97
+ BBBA;00;000;Airport B1;;Bbbbb;1;11-03S;055-24E;11-03S;055-24E;000;000;P\r
98
+ EOT
99
+ StringIO.new(nsd_text)
82
100
  end
83
-
84
101
  end
85
102
 
86
103
  context ".to_longitude" do
@@ -103,58 +120,72 @@ EOT
103
120
  end
104
121
  end
105
122
 
106
- def noaa_data
123
+ let(:cccc) { "DDDD" }
124
+ let(:name) { "Station name" }
125
+ let(:state) { "State" }
126
+ let(:country) { "Country" }
127
+ let(:noaa_raw) do
128
+ cccc +
129
+ ";00;000;" +
130
+ name + ";" +
131
+ state + ";" +
132
+ country + ";1;11-03S;055-24E;11-03S;055-24E;000;000;P"
133
+ end
134
+ let(:noaa_data) do
107
135
  {
108
- :cccc => "DDDD",
109
- :name => "Station name",
110
- :state => "State",
111
- :country => "Country",
112
- :longitude => "055-24E",
113
- :latitude => "11-03S",
114
- :raw => "DDDD;00;000;Station name;State;Country;1;11-03S;055-24E;11-03S;055-24E;000;000;P",
136
+ cccc: cccc,
137
+ name: name,
138
+ state: state,
139
+ country: country,
140
+ longitude: "055-24E",
141
+ latitude: "11-03S",
142
+ raw: noaa_raw,
115
143
  }
116
144
  end
117
145
 
118
146
  context "attributes" do
119
- subject { Metar::Station.new("DDDD", noaa_data) }
120
- it { should have_attribute(:cccc) }
121
- it { should have_attribute(:code) }
122
- it { should have_attribute(:name) }
123
- it { should have_attribute(:state) }
124
- it { should have_attribute(:country) }
125
- it { should have_attribute(:longitude) }
126
- it { should have_attribute(:latitude) }
127
- it { should have_attribute(:raw) }
147
+ subject { Metar::Station.new("DDDD", noaa_data) }
148
+ it { should have_attribute(:cccc) }
149
+ it { should have_attribute(:code) }
150
+ it { should have_attribute(:name) }
151
+ it { should have_attribute(:state) }
152
+ it { should have_attribute(:country) }
153
+ it { should have_attribute(:longitude) }
154
+ it { should have_attribute(:latitude) }
155
+ it { should have_attribute(:raw) }
128
156
  end
129
-
157
+
130
158
  context "initialization" do
131
- it "should fail if cccc is missing" do
132
- expect do
133
- Metar::Station.new( nil, {} )
134
- end.to raise_error(RuntimeError, /must not be nil/)
135
- end
136
-
137
- it "should fail if cccc is empty" do
138
- expect do
139
- Metar::Station.new("", {})
140
- end.to raise_error( RuntimeError, /must not be empty/)
141
- end
142
-
159
+ it "should fail if cccc is missing" do
160
+ expect do
161
+ Metar::Station.new(nil, {})
162
+ end.to raise_error(RuntimeError, /must not be nil/)
163
+ end
164
+
165
+ it "should fail if cccc is empty" do
166
+ expect do
167
+ Metar::Station.new("", {})
168
+ end.to raise_error(RuntimeError, /must not be empty/)
169
+ end
170
+
143
171
  context "with noaa data" do
144
172
  subject { Metar::Station.new("DDDD", noaa_data) }
145
173
 
146
- specify { expect(subject.cccc).to eq("DDDD") }
147
- specify { expect(subject.name).to eq("Station name") }
148
- specify { expect(subject.state).to eq("State") }
149
- specify { expect(subject.country).to eq("Country") }
174
+ specify { expect(subject.cccc).to eq(cccc) }
175
+ specify { expect(subject.name).to eq(name) }
176
+ specify { expect(subject.state).to eq(state) }
177
+ specify { expect(subject.country).to eq(country) }
150
178
  specify { expect(subject.longitude).to eq(55.4) }
151
179
  specify { expect(subject.latitude).to eq(-11.05) }
152
- specify { expect(subject.raw).to eq("DDDD;00;000;Station name;State;Country;1;11-03S;055-24E;11-03S;055-24E;000;000;P") }
180
+ specify { expect(subject.raw).to eq(noaa_raw) }
153
181
  end
154
182
  end
155
183
 
156
184
  context "object navigation" do
157
- let(:raw) { double(Metar::Raw, :metar => "PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000", :time => "2010/02/06 16:10") }
185
+ let(:metar) do
186
+ "PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910"
187
+ end
188
+ let(:raw) { double(Metar::Raw, metar: metar, time: "2010/02/06 16:10") }
158
189
 
159
190
  before do
160
191
  # TODO: hack - once parser returns station this can be removed