metar-parser 0.9.11 → 0.9.12

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.
@@ -0,0 +1,73 @@
1
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
2
+ # encoding: utf-8
3
+
4
+ RSpec::Matchers.define :be_sky_condition do | quantity, height, type |
5
+ match do | sk |
6
+ if sk.nil? && quantity == :expect_nil
7
+ true
8
+ elsif sk.nil? && quantity != :expect_nil
9
+ false
10
+ elsif sk.quantity != quantity
11
+ false
12
+ elsif sk.height.is_a?(Metar::Distance) && sk.height.value != height
13
+ false
14
+ elsif sk.type != type
15
+ false
16
+ else
17
+ true
18
+ end
19
+ end
20
+ end
21
+
22
+ describe Metar::SkyCondition do
23
+
24
+ context '.parse' do
25
+
26
+ [
27
+ [ 'understands clear skies codes', 'NSC', [ nil, nil, nil ] ],
28
+ [ 'quantity + height', 'BKN12', [ 'broken', 360, nil ] ],
29
+ [ 'quantity + height + type', 'BKN12CB', [ 'broken', 360, 'cumulonimbus' ] ],
30
+ [ 'quantity + height + ///', 'BKN12///', [ 'broken', 360, nil ] ],
31
+ [ 'returns nil for unmatched', 'FUBAR', [ :expect_nil, nil, nil ] ],
32
+ ].each do | docstring, raw, expected |
33
+ example docstring do
34
+ Metar::SkyCondition.parse( raw ).should be_sky_condition( *expected )
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ context '.to_summary' do
41
+
42
+ [
43
+ [ 'all values nil', [ nil, nil, nil ], 'clear skies' ],
44
+ [ 'quantity', [ 'broken', nil, nil ], 'broken cloud' ],
45
+ [ 'quantity + type', [ 'broken', nil, 'cumulonimbus'], 'broken cumulonimbus' ],
46
+ ].each do | docstring, ( quantity, height, type ), expected |
47
+ example docstring do
48
+ sk = Metar::SkyCondition.new( quantity, height, type )
49
+
50
+ sk.to_summary. should == expected
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ context '.to_s' do
57
+
58
+ [
59
+ [ 'all values nil', [ nil, nil, nil ], 'clear skies' ],
60
+ [ 'quantity', [ 'broken', 360, nil ], 'broken cloud at 360' ],
61
+ [ 'quantity + type', [ 'broken', 360, 'cumulonimbus'], 'broken cumulonimbus at 360' ],
62
+ ].each do | docstring, ( quantity, height, type ), expected |
63
+ example docstring do
64
+ sk = Metar::SkyCondition.new( quantity, height, type )
65
+
66
+ sk.to_s. should == expected
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
@@ -0,0 +1,50 @@
1
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
2
+
3
+ describe Metar::Speed do
4
+
5
+ context '.parse' do
6
+
7
+ it 'returns nil for nil' do
8
+ speed = Metar::Speed.parse( nil )
9
+
10
+ speed. should be_nil
11
+ end
12
+
13
+ it 'parses knots' do
14
+ speed = Metar::Speed.parse( '5KT' )
15
+
16
+ speed. should be_a( Metar::Speed )
17
+ speed.value. should be_within( 0.01 ).of( 2.57 )
18
+ end
19
+
20
+ it 'parses meters per second' do
21
+ speed = Metar::Speed.parse( '7MPS' )
22
+
23
+ speed. should be_a( Metar::Speed )
24
+ speed.value. should be_within( 0.01 ).of( 7.00 )
25
+ end
26
+
27
+ it 'parses kilometers per hour' do
28
+ speed = Metar::Speed.parse( '14KMH' )
29
+
30
+ speed. should be_a( Metar::Speed )
31
+ speed.value. should be_within( 0.01 ).of( 3.89 )
32
+ end
33
+
34
+ it 'trates straight numbers as kilomters per hour' do
35
+ speed = Metar::Speed.parse( '14' )
36
+
37
+ speed. should be_a( Metar::Speed )
38
+ speed.value. should be_within( 0.01 ).of( 3.89 )
39
+ end
40
+
41
+ it 'returns nil for other strings' do
42
+ speed = Metar::Speed.parse( '' )
43
+
44
+ speed. should be_nil
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
@@ -0,0 +1,254 @@
1
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
2
+ # encoding: utf-8
3
+
4
+ require 'stringio'
5
+
6
+ RSpec::Matchers.define :have_attribute do | attribute |
7
+ match do | object |
8
+ if ! object.respond_to?( attribute )
9
+ false
10
+ elsif object.method( attribute ).arity != 0
11
+ false
12
+ else
13
+ true
14
+ end
15
+ end
16
+ end
17
+
18
+ describe Metar::Station do
19
+
20
+ before :each do
21
+ @file = stub( 'file' )
22
+ end
23
+
24
+ context '.download_local' do
25
+
26
+ it 'downloads the station list' do
27
+ File.stub!( :open => @file )
28
+
29
+ Metar::Station. should_receive( :open ).
30
+ with( /^http/ )
31
+
32
+ Metar::Station.download_local
33
+ end
34
+
35
+ it 'saves the list to disk' do
36
+ Metar::Station.stub!( :open ).and_return( 'aaa' )
37
+
38
+ File. should_receive( :open ) do | path, mode, &block |
39
+ path. should =~ %r(data/nsd_cccc.txt$)
40
+ mode. should == 'w'
41
+ block.call @file
42
+ end
43
+ @file. should_receive( :write ).
44
+ with( 'aaa' )
45
+
46
+ Metar::Station.download_local
47
+ end
48
+
49
+ end
50
+
51
+ context '.load_local' do
52
+
53
+ it 'downloads the station list, if missing, then loads it' do
54
+ File. should_receive( :exist? ).
55
+ and_return( false )
56
+ # open-uri call
57
+ Metar::Station. should_receive( :open ).
58
+ and_return( 'aaa' )
59
+
60
+ outfile = stub( 'outfile' )
61
+ File. should_receive( :open ).once.with( %r(nsd_cccc.txt), 'w' ) do | *args, &block |
62
+ block.call outfile
63
+ end
64
+ outfile. should_receive( :write ).
65
+ with( 'aaa' )
66
+
67
+ infile = stub( 'infile' )
68
+ File. should_receive( :open ).once.with( %r(nsd_cccc.txt) ) do | *args, &block |
69
+ block.call infile
70
+ end
71
+ infile. should_receive( :read ).
72
+ and_return( 'bbb' )
73
+
74
+ Metar::Station.load_local. should == 'bbb'
75
+ end
76
+
77
+ it 'loads the file, if already present' do
78
+ File. should_receive( :exist? ).
79
+ and_return( true )
80
+
81
+ File. should_receive( :open ).once.with( %r(nsd_cccc.txt) )
82
+
83
+ Metar::Station.load_local
84
+ end
85
+
86
+ end
87
+
88
+ context 'using structures' do
89
+
90
+ before :each do
91
+ preload_data
92
+ end
93
+
94
+ context '.countries' do
95
+ it 'lists unique countries in alphabetical order' do
96
+ Metar::Station.countries. should == [ 'Aaaaa', 'Bbbbb', 'Ppppp' ]
97
+ end
98
+ end
99
+
100
+ context '.all' do
101
+ it 'lists all stations' do
102
+ all = Metar::Station.all
103
+
104
+ all.map(&:cccc). should == ['PPPP', 'AAAA', 'AAAB', 'BBBA']
105
+ end
106
+ end
107
+
108
+ context '.find_by_cccc' do
109
+ it 'returns the matching station, if is exists' do
110
+ Metar::Station.find_by_cccc( 'AAAA' ).name.
111
+ should == 'Airport A1'
112
+ Metar::Station.find_by_cccc( 'ZZZZ' ).
113
+ should be_nil
114
+ end
115
+ end
116
+
117
+ context '.exist?' do
118
+ it 'check if the cccc code exists' do
119
+ Metar::Station.exist?( 'AAAA' ).
120
+ should be_true
121
+ Metar::Station.exist?( 'ZZZZ' ).
122
+ should be_false
123
+ end
124
+ end
125
+
126
+ context '.find_all_by_country' do
127
+ it 'lists all stations in a country' do
128
+ aaaaa = Metar::Station.find_all_by_country( 'Aaaaa' )
129
+
130
+ aaaaa.map(&:cccc). should == [ 'AAAA', 'AAAB' ]
131
+ end
132
+ end
133
+
134
+ def nsd_file
135
+ #0 1 2 3 4 5 6 7 8 9 10 11 12 13
136
+ #CCCC;??;???;name;state;country;?;latitude;longitude;latitude;longitude;???;???;?
137
+ nsd_text =<<EOT
138
+ PPPP;00;000;Airport P1;;Ppppp;1;11-03S;055-24E;11-03S;055-24E;000;000;P
139
+ AAAA;00;000;Airport A1;;Aaaaa;1;11-03S;055-24E;11-03S;055-24E;000;000;P
140
+ AAAB;00;000;Airport A2;;Aaaaa;1;11-03S;055-24E;11-03S;055-24E;000;000;P
141
+ BBBA;00;000;Airport B1;;Bbbbb;1;11-03S;055-24E;11-03S;055-24E;000;000;P
142
+ EOT
143
+ StringIO.new( nsd_text )
144
+ end
145
+
146
+ def preload_data
147
+ File.stub!( :exist? ).and_return( true )
148
+ File.stub!( :open ).with( %r(nsd_cccc.txt) ).and_return( nsd_file )
149
+ Metar::Station.load_local
150
+ end
151
+
152
+ end
153
+
154
+ context '.to_longitude' do
155
+ it 'converts strings to longitude' do
156
+ Metar::Station.to_longitude('055-24E').
157
+ should == 55.4
158
+ end
159
+ it 'returns nil for badly formed strings' do
160
+ Metar::Station.to_longitude('aaa').
161
+ should be_nil
162
+ end
163
+ end
164
+
165
+ context '.to_latitude' do
166
+ it 'converts strings to latitude' do
167
+ Metar::Station.to_latitude('11-03S').
168
+ should == -11.05
169
+ end
170
+ it 'returns nil for badly formed strings' do
171
+ Metar::Station.to_latitude('aaa').
172
+ should be_nil
173
+ end
174
+ end
175
+
176
+ def noaa_data
177
+ {
178
+ :cccc => 'DDDD',
179
+ :name => 'Station name',
180
+ :state => 'State',
181
+ :country => 'Country',
182
+ :longitude => '055-24E',
183
+ :latitude => '11-03S',
184
+ :raw => 'DDDD;00;000;Station name;State;Country;1;11-03S;055-24E;11-03S;055-24E;000;000;P',
185
+ }
186
+ end
187
+
188
+ context 'attributes' do
189
+
190
+ subject { Metar::Station.new( 'DDDD', noaa_data ) }
191
+ it { should have_attribute( :cccc ) }
192
+ it { should have_attribute( :code ) }
193
+ it { should have_attribute( :name ) }
194
+ it { should have_attribute( :state ) }
195
+ it { should have_attribute( :country ) }
196
+ it { should have_attribute( :longitude) }
197
+ it { should have_attribute( :latitude ) }
198
+ it { should have_attribute( :raw ) }
199
+
200
+ end
201
+
202
+ context 'initialization' do
203
+
204
+ it 'should fail if cccc is missing' do
205
+ expect do
206
+ Metar::Station.new( nil, {} )
207
+ end. to raise_error( RuntimeError, /must not be nil/ )
208
+ end
209
+
210
+ it 'should fail if cccc is empty' do
211
+ expect do
212
+ Metar::Station.new( '', {} )
213
+ end. to raise_error( RuntimeError, /must not be empty/ )
214
+ end
215
+
216
+ context 'with noaa data' do
217
+
218
+ subject { Metar::Station.new( 'DDDD', noaa_data ) }
219
+ specify { subject.cccc. should == 'DDDD' }
220
+ specify { subject.name. should == 'Station name' }
221
+ specify { subject.state. should == 'State' }
222
+ specify { subject.country. should == 'Country' }
223
+ specify { subject.longitude. should == 55.4 }
224
+ specify { subject.latitude. should == -11.05 }
225
+ specify { subject.raw. should == 'DDDD;00;000;Station name;State;Country;1;11-03S;055-24E;11-03S;055-24E;000;000;P' }
226
+
227
+ end
228
+
229
+ end
230
+
231
+ context 'object navigation' do
232
+ before :each do
233
+ @raw = stub('raw', :metar => 'PAIL 061610Z 24006KT 1 3/4SM -SN BKN016 OVC030 M17/M20 A2910 RMK AO2 P0000', :time => '2010/02/06 16:10' )
234
+ # TODO: hack - once parser returns station this can be removed
235
+ Metar::Raw. should_receive( :new ).
236
+ and_return( @raw )
237
+ end
238
+
239
+ subject { Metar::Station.new( 'DDDD', noaa_data ) }
240
+
241
+ it '.station should return the Parser' do
242
+ subject.parser. should be_a Metar::Parser
243
+ end
244
+
245
+ it '.report should return the Report' do
246
+ Metar::Station. should_receive( :find_by_cccc ).
247
+ and_return( subject )
248
+
249
+ subject.report. should be_a Metar::Report
250
+ end
251
+ end
252
+
253
+ end
254
+
@@ -0,0 +1,47 @@
1
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
2
+ # encoding: utf-8
3
+
4
+ describe Metar::Temperature do
5
+
6
+ context '.parse' do
7
+
8
+ it 'understands numbers' do
9
+ t = Metar::Temperature.parse( '5' )
10
+
11
+ t.value. should be_within( 0.01 ).of( 5.0 )
12
+ end
13
+
14
+ it 'treats an M-prefix as a negative indicator' do
15
+ t = Metar::Temperature.parse( 'M5' )
16
+
17
+ t.value. should be_within( 0.01 ).of( -5.0 )
18
+ end
19
+
20
+ it 'returns nil for other values' do
21
+ Metar::Temperature.parse('').
22
+ should be_nil
23
+ Metar::Temperature.parse('aaa').
24
+ should be_nil
25
+ end
26
+
27
+ end
28
+
29
+ context '#to_s' do
30
+
31
+ it 'abbreviates the units' do
32
+ t = Metar::Temperature.new( 5 )
33
+
34
+ t.to_s. should == '5°C'
35
+ end
36
+
37
+ it 'rounds to the nearest degree' do
38
+ Metar::Temperature.new( 5.1 ).to_s.
39
+ should == '5°C'
40
+ Metar::Temperature.new( 5.5 ).to_s.
41
+ should == '6°C'
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
@@ -0,0 +1,34 @@
1
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
2
+ # encoding: utf-8
3
+
4
+ describe Metar::VariableWind do
5
+
6
+ context '.parse' do
7
+
8
+ it 'understands nnn + V + nnn' do
9
+ vw = Metar::VariableWind.parse( '090V180' )
10
+
11
+ vw.direction1.value. should == 90.0
12
+ vw.direction2.value. should == 180.0
13
+ end
14
+
15
+ it 'returns nil for other' do
16
+ vw = Metar::VariableWind.parse( 'XXX' )
17
+
18
+ vw. should be_nil
19
+ end
20
+
21
+ end
22
+
23
+ context '#to_s' do
24
+
25
+ it 'renders the ' do
26
+ vw = Metar::VariableWind.parse( '090V180' )
27
+
28
+ vw.to_s. should == 'E - S'
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+