metar-parser 1.1.8 → 1.2.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.
- checksums.yaml +7 -0
- data/README.md +39 -24
- data/Rakefile +0 -11
- data/bin/parse_raw.rb +0 -1
- data/lib/metar/raw.rb +57 -18
- data/lib/metar/version.rb +2 -2
- data/spec/spec_helper.rb +0 -1
- data/spec/unit/distance_spec.rb +36 -46
- data/spec/unit/parser_spec.rb +32 -11
- data/spec/unit/pressure_spec.rb +6 -17
- data/spec/unit/raw_spec.rb +117 -38
- data/spec/unit/remark_spec.rb +34 -39
- data/spec/unit/report_spec.rb +92 -102
- data/spec/unit/runway_visible_range_spec.rb +3 -4
- data/spec/unit/sky_condition_spec.rb +2 -2
- data/spec/unit/speed_spec.rb +11 -17
- data/spec/unit/station_spec.rb +92 -101
- data/spec/unit/temperature_spec.rb +8 -19
- data/spec/unit/variable_wind_spec.rb +9 -17
- data/spec/unit/vertical_visibility_spec.rb +8 -14
- data/spec/unit/visibility_spec.rb +16 -19
- data/spec/unit/weather_phenomenon_spec.rb +3 -4
- data/spec/unit/wind_spec.rb +13 -14
- metadata +147 -163
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
2
|
+
require "spec_helper"
|
3
3
|
|
4
4
|
RSpec::Matchers.define :be_runway_visible_range do | designator, visibility1, visibility2, tendency |
|
5
5
|
match do | rvr |
|
@@ -44,7 +44,7 @@ describe Metar::RunwayVisibleRange do
|
|
44
44
|
[ 'returns nil for nil', nil, [ nil, nil, nil, nil ] ],
|
45
45
|
].each do | docstring, raw, expected |
|
46
46
|
example docstring do
|
47
|
-
Metar::RunwayVisibleRange.parse(
|
47
|
+
expect(Metar::RunwayVisibleRange.parse(raw)).to be_runway_visible_range( *expected )
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -78,8 +78,7 @@ describe Metar::RunwayVisibleRange do
|
|
78
78
|
|
79
79
|
example docstring + " (#{locale})" do
|
80
80
|
I18n.locale = locale
|
81
|
-
Metar::RunwayVisibleRange.new(
|
82
|
-
should == expected
|
81
|
+
expect(Metar::RunwayVisibleRange.new('14', v1, v2, tendency).to_s).to eq(expected)
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
2
|
+
require "spec_helper"
|
3
3
|
|
4
4
|
RSpec::Matchers.define :be_sky_condition do |quantity, height, type|
|
5
5
|
match do |sk|
|
@@ -31,7 +31,7 @@ describe Metar::SkyCondition do
|
|
31
31
|
['returns nil for unmatched', 'FUBAR', [:expect_nil, nil, nil]],
|
32
32
|
].each do |docstring, raw, expected|
|
33
33
|
example docstring do
|
34
|
-
Metar::SkyCondition.parse(raw).
|
34
|
+
expect(Metar::SkyCondition.parse(raw)).to be_sky_condition(*expected)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/spec/unit/speed_spec.rb
CHANGED
@@ -1,51 +1,45 @@
|
|
1
|
-
|
2
|
-
load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
|
1
|
+
require "spec_helper"
|
3
2
|
|
4
3
|
describe Metar::Speed do
|
5
|
-
|
6
4
|
context '.parse' do
|
7
|
-
|
8
5
|
it 'returns nil for nil' do
|
9
6
|
speed = Metar::Speed.parse( nil )
|
10
7
|
|
11
|
-
speed.
|
8
|
+
expect(speed).to be_nil
|
12
9
|
end
|
13
10
|
|
14
11
|
it 'parses knots' do
|
15
12
|
speed = Metar::Speed.parse( '5KT' )
|
16
13
|
|
17
|
-
speed.
|
18
|
-
speed.value.
|
14
|
+
expect(speed).to be_a( Metar::Speed )
|
15
|
+
expect(speed.value).to be_within( 0.01 ).of( 2.57 )
|
19
16
|
end
|
20
17
|
|
21
18
|
it 'parses meters per second' do
|
22
19
|
speed = Metar::Speed.parse( '7MPS' )
|
23
20
|
|
24
|
-
speed.
|
25
|
-
speed.value.
|
21
|
+
expect(speed).to be_a( Metar::Speed )
|
22
|
+
expect(speed.value).to be_within( 0.01 ).of( 7.00 )
|
26
23
|
end
|
27
24
|
|
28
25
|
it 'parses kilometers per hour' do
|
29
26
|
speed = Metar::Speed.parse( '14KMH' )
|
30
27
|
|
31
|
-
speed.
|
32
|
-
speed.value.
|
28
|
+
expect(speed).to be_a( Metar::Speed )
|
29
|
+
expect(speed.value).to be_within( 0.01 ).of( 3.89 )
|
33
30
|
end
|
34
31
|
|
35
32
|
it 'trates straight numbers as kilomters per hour' do
|
36
33
|
speed = Metar::Speed.parse( '14' )
|
37
34
|
|
38
|
-
speed.
|
39
|
-
speed.value.
|
35
|
+
expect(speed).to be_a( Metar::Speed )
|
36
|
+
expect(speed.value).to be_within( 0.01 ).of( 3.89 )
|
40
37
|
end
|
41
38
|
|
42
39
|
it 'returns nil for other strings' do
|
43
40
|
speed = Metar::Speed.parse( '' )
|
44
41
|
|
45
|
-
speed.
|
42
|
+
expect(speed).to be_nil
|
46
43
|
end
|
47
|
-
|
48
44
|
end
|
49
|
-
|
50
45
|
end
|
51
|
-
|
data/spec/unit/station_spec.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
2
|
+
require "spec_helper"
|
3
3
|
|
4
|
-
require
|
4
|
+
require "stringio"
|
5
5
|
|
6
|
-
RSpec::Matchers.define :have_attribute do |
|
6
|
+
RSpec::Matchers.define :have_attribute do |attribute|
|
7
7
|
match do | object |
|
8
8
|
if ! object.respond_to?( attribute )
|
9
9
|
false
|
@@ -16,54 +16,56 @@ RSpec::Matchers.define :have_attribute do | attribute |
|
|
16
16
|
end
|
17
17
|
|
18
18
|
describe Metar::Station do
|
19
|
+
let(:file) { double(File) }
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
context 'using structures' do
|
25
|
-
|
26
|
-
before :each do
|
27
|
-
Metar::Station.stub!(:open).with(Metar::Station::NOAA_STATION_LIST_URL).and_return(nsd_file)
|
21
|
+
context "using structures" do
|
22
|
+
before do
|
23
|
+
allow(Metar::Station).to receive(:open).with(Metar::Station::NOAA_STATION_LIST_URL) { nsd_file }
|
28
24
|
end
|
29
25
|
|
30
|
-
context
|
31
|
-
it
|
32
|
-
Metar::Station.countries.
|
26
|
+
context ".countries" do
|
27
|
+
it "lists unique countries in alphabetical order" do
|
28
|
+
expect(Metar::Station.countries).to eq(%w(Aaaaa Bbbbb Ppppp))
|
33
29
|
end
|
34
30
|
end
|
35
31
|
|
36
|
-
context
|
37
|
-
it
|
38
|
-
|
32
|
+
context ".all" do
|
33
|
+
it "lists all stations" do
|
34
|
+
all_ccccs = Metar::Station.all.map(&:cccc)
|
39
35
|
|
40
|
-
|
36
|
+
expect(all_ccccs).to eq(%w(PPPP AAAA AAAB BBBA))
|
41
37
|
end
|
42
38
|
end
|
43
39
|
|
44
|
-
context
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
context ".find_by_cccc" do
|
41
|
+
context "when the station exists" do
|
42
|
+
it "returns the matching station" do
|
43
|
+
expect(Metar::Station.find_by_cccc("AAAA").name).to eq("Airport A1")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when the station doesn't exist" do
|
48
|
+
it "is nil" do
|
49
|
+
expect(Metar::Station.find_by_cccc("ZZZZ")).to be_nil
|
50
|
+
end
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
context
|
54
|
-
it
|
55
|
-
Metar::Station.exist?(
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
context ".exist?" do
|
55
|
+
it "is true if the cccc exists" do
|
56
|
+
expect(Metar::Station.exist?("AAAA")).to be_truthy
|
57
|
+
end
|
58
|
+
|
59
|
+
it "is false if the cccc doesn't exist" do
|
60
|
+
expect(Metar::Station.exist?("ZZZZ")).to be_falsey
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
62
|
-
context
|
63
|
-
it
|
64
|
-
aaaaa = Metar::Station.find_all_by_country(
|
64
|
+
context ".find_all_by_country" do
|
65
|
+
it "lists all stations in a country" do
|
66
|
+
aaaaa = Metar::Station.find_all_by_country("Aaaaa")
|
65
67
|
|
66
|
-
aaaaa.map(&:cccc).
|
68
|
+
expect(aaaaa.map(&:cccc)).to eq(%w(AAAA AAAB))
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
@@ -81,104 +83,93 @@ EOT
|
|
81
83
|
|
82
84
|
end
|
83
85
|
|
84
|
-
context
|
85
|
-
it
|
86
|
-
Metar::Station.to_longitude(
|
87
|
-
should == 55.4
|
86
|
+
context ".to_longitude" do
|
87
|
+
it "converts strings to longitude" do
|
88
|
+
expect(Metar::Station.to_longitude("055-24E")).to eq(55.4)
|
88
89
|
end
|
89
|
-
|
90
|
-
|
91
|
-
|
90
|
+
|
91
|
+
it "returns nil for badly formed strings" do
|
92
|
+
expect(Metar::Station.to_longitude("aaa")).to be_nil
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
95
|
-
context
|
96
|
-
it
|
97
|
-
Metar::Station.to_latitude(
|
98
|
-
should == -11.05
|
96
|
+
context ".to_latitude" do
|
97
|
+
it "converts strings to latitude" do
|
98
|
+
expect(Metar::Station.to_latitude("11-03S")).to eq(-11.05)
|
99
99
|
end
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
|
101
|
+
it "returns nil for badly formed strings" do
|
102
|
+
expect(Metar::Station.to_latitude("aaa")).to be_nil
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
106
|
def noaa_data
|
107
107
|
{
|
108
|
-
:cccc =>
|
109
|
-
:name =>
|
110
|
-
:state =>
|
111
|
-
:country =>
|
112
|
-
:longitude =>
|
113
|
-
:latitude =>
|
114
|
-
:raw =>
|
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",
|
115
115
|
}
|
116
116
|
end
|
117
117
|
|
118
|
-
context
|
119
|
-
|
120
|
-
|
121
|
-
it { should have_attribute(
|
122
|
-
it { should have_attribute(
|
123
|
-
it { should have_attribute(
|
124
|
-
it { should have_attribute(
|
125
|
-
it { should have_attribute(
|
126
|
-
it { should have_attribute(
|
127
|
-
it { should have_attribute(
|
128
|
-
it { should have_attribute( :raw ) }
|
129
|
-
|
118
|
+
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) }
|
130
128
|
end
|
131
129
|
|
132
|
-
context
|
133
|
-
|
134
|
-
it 'should fail if cccc is missing' do
|
130
|
+
context "initialization" do
|
131
|
+
it "should fail if cccc is missing" do
|
135
132
|
expect do
|
136
133
|
Metar::Station.new( nil, {} )
|
137
|
-
end.
|
134
|
+
end.to raise_error(RuntimeError, /must not be nil/)
|
138
135
|
end
|
139
136
|
|
140
|
-
it
|
137
|
+
it "should fail if cccc is empty" do
|
141
138
|
expect do
|
142
|
-
Metar::Station.new(
|
143
|
-
end.
|
139
|
+
Metar::Station.new("", {})
|
140
|
+
end.to raise_error( RuntimeError, /must not be empty/)
|
144
141
|
end
|
145
142
|
|
146
|
-
context
|
147
|
-
|
148
|
-
subject { Metar::Station.new( 'DDDD', noaa_data ) }
|
149
|
-
specify { subject.cccc. should == 'DDDD' }
|
150
|
-
specify { subject.name. should == 'Station name' }
|
151
|
-
specify { subject.state. should == 'State' }
|
152
|
-
specify { subject.country. should == 'Country' }
|
153
|
-
specify { subject.longitude. should == 55.4 }
|
154
|
-
specify { subject.latitude. should == -11.05 }
|
155
|
-
specify { subject.raw. should == 'DDDD;00;000;Station name;State;Country;1;11-03S;055-24E;11-03S;055-24E;000;000;P' }
|
156
|
-
|
157
|
-
end
|
143
|
+
context "with noaa data" do
|
144
|
+
subject { Metar::Station.new("DDDD", noaa_data) }
|
158
145
|
|
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") }
|
150
|
+
specify { expect(subject.longitude).to eq(55.4) }
|
151
|
+
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") }
|
153
|
+
end
|
159
154
|
end
|
160
155
|
|
161
|
-
context
|
162
|
-
|
163
|
-
|
156
|
+
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") }
|
158
|
+
|
159
|
+
before do
|
164
160
|
# TODO: hack - once parser returns station this can be removed
|
165
|
-
Metar::Raw::Noaa.
|
166
|
-
|
161
|
+
allow(Metar::Raw::Noaa).to receive(:new) { raw }
|
162
|
+
allow(Metar::Station).to receive(:find_by_cccc) { subject }
|
167
163
|
end
|
168
164
|
|
169
|
-
subject {
|
165
|
+
subject { described_class.new("DDDD", noaa_data) }
|
170
166
|
|
171
|
-
it
|
172
|
-
subject.parser.
|
167
|
+
it ".station should return the Parser" do
|
168
|
+
expect(subject.parser).to be_a(Metar::Parser)
|
173
169
|
end
|
174
170
|
|
175
|
-
it
|
176
|
-
Metar::
|
177
|
-
and_return( subject )
|
178
|
-
|
179
|
-
subject.report. should be_a Metar::Report
|
171
|
+
it ".report should return the Report" do
|
172
|
+
expect(subject.report).to be_a(Metar::Report)
|
180
173
|
end
|
181
174
|
end
|
182
|
-
|
183
175
|
end
|
184
|
-
|
@@ -1,47 +1,36 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
2
|
+
require "spec_helper"
|
3
3
|
|
4
4
|
describe Metar::Temperature do
|
5
|
-
|
6
5
|
context '.parse' do
|
7
|
-
|
8
6
|
it 'understands numbers' do
|
9
7
|
t = Metar::Temperature.parse( '5' )
|
10
8
|
|
11
|
-
t.value.
|
9
|
+
expect(t.value).to be_within( 0.01 ).of( 5.0 )
|
12
10
|
end
|
13
11
|
|
14
12
|
it 'treats an M-prefix as a negative indicator' do
|
15
13
|
t = Metar::Temperature.parse( 'M5' )
|
16
14
|
|
17
|
-
t.value.
|
15
|
+
expect(t.value).to be_within( 0.01 ).of( -5.0 )
|
18
16
|
end
|
19
17
|
|
20
18
|
it 'returns nil for other values' do
|
21
|
-
Metar::Temperature.parse('').
|
22
|
-
|
23
|
-
Metar::Temperature.parse('aaa').
|
24
|
-
should be_nil
|
19
|
+
expect(Metar::Temperature.parse('')).to be_nil
|
20
|
+
expect(Metar::Temperature.parse('aaa')).to be_nil
|
25
21
|
end
|
26
|
-
|
27
22
|
end
|
28
23
|
|
29
24
|
context '#to_s' do
|
30
|
-
|
31
25
|
it 'abbreviates the units' do
|
32
26
|
t = Metar::Temperature.new( 5 )
|
33
27
|
|
34
|
-
t.to_s.
|
28
|
+
expect(t.to_s).to eq('5°C')
|
35
29
|
end
|
36
30
|
|
37
31
|
it 'rounds to the nearest degree' do
|
38
|
-
Metar::Temperature.new( 5.1 ).to_s.
|
39
|
-
|
40
|
-
Metar::Temperature.new( 5.5 ).to_s.
|
41
|
-
should == '6°C'
|
32
|
+
expect(Metar::Temperature.new( 5.1 ).to_s).to eq('5°C')
|
33
|
+
expect(Metar::Temperature.new( 5.5 ).to_s).to eq('6°C')
|
42
34
|
end
|
43
|
-
|
44
35
|
end
|
45
|
-
|
46
36
|
end
|
47
|
-
|
@@ -1,49 +1,41 @@
|
|
1
|
-
|
2
|
-
load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
|
1
|
+
require "spec_helper"
|
3
2
|
|
4
3
|
describe Metar::VariableWind do
|
5
|
-
|
6
4
|
context '.parse' do
|
7
|
-
|
8
5
|
it 'understands nnn + V + nnn' do
|
9
6
|
vw = Metar::VariableWind.parse( '090V180' )
|
10
7
|
|
11
|
-
vw.direction1.value.
|
12
|
-
vw.direction2.value.
|
8
|
+
expect(vw.direction1.value).to eq( 90.0)
|
9
|
+
expect(vw.direction2.value).to eq(180.0)
|
13
10
|
end
|
14
11
|
|
15
12
|
it 'accepts 360, rounding to 0 - 1' do
|
16
13
|
vw = Metar::VariableWind.parse( '360V090' )
|
17
14
|
|
18
|
-
vw.direction1.value.
|
19
|
-
vw.direction2.value.
|
15
|
+
expect(vw.direction1.value).to eq( 0.0)
|
16
|
+
expect(vw.direction2.value).to eq( 90.0)
|
20
17
|
end
|
21
18
|
|
22
19
|
|
23
20
|
it 'accepts 360, rounding to 0 - 2' do
|
24
21
|
vw = Metar::VariableWind.parse( '090V360' )
|
25
22
|
|
26
|
-
vw.direction1.value.
|
27
|
-
vw.direction2.value.
|
23
|
+
expect(vw.direction1.value).to eq( 90.0)
|
24
|
+
expect(vw.direction2.value).to eq( 0.0)
|
28
25
|
end
|
29
26
|
|
30
27
|
it 'returns nil for other' do
|
31
28
|
vw = Metar::VariableWind.parse( 'XXX' )
|
32
29
|
|
33
|
-
vw.
|
30
|
+
expect(vw).to be_nil
|
34
31
|
end
|
35
|
-
|
36
32
|
end
|
37
33
|
|
38
34
|
context '#to_s' do
|
39
|
-
|
40
35
|
it 'renders compatible values as compass directions' do
|
41
36
|
vw = Metar::VariableWind.parse( '090V180' )
|
42
37
|
|
43
|
-
vw.to_s.
|
38
|
+
expect(vw.to_s).to eq('E - S')
|
44
39
|
end
|
45
|
-
|
46
40
|
end
|
47
|
-
|
48
41
|
end
|
49
|
-
|