ullr 0.1.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.
- data/.bnsignore +18 -0
- data/History.txt +3 -0
- data/README.md +68 -0
- data/Rakefile +24 -0
- data/bin/ullr +7 -0
- data/lib/ullr.rb +60 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/ullr_spec.rb +476 -0
- data/version.txt +1 -0
- metadata +84 -0
data/.bnsignore
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# The list of files that should be ignored by Mr Bones.
|
|
2
|
+
# Lines that start with '#' are comments.
|
|
3
|
+
#
|
|
4
|
+
# A .gitignore file can be used instead by setting it as the ignore
|
|
5
|
+
# file in your Rakefile:
|
|
6
|
+
#
|
|
7
|
+
# Bones {
|
|
8
|
+
# ignore_file '.gitignore'
|
|
9
|
+
# }
|
|
10
|
+
#
|
|
11
|
+
# For a project with a C extension, the following would be a good set of
|
|
12
|
+
# exclude patterns (uncomment them if you want to use them):
|
|
13
|
+
# *.[oa]
|
|
14
|
+
# *~
|
|
15
|
+
announcement.txt
|
|
16
|
+
coverage
|
|
17
|
+
doc
|
|
18
|
+
pkg
|
data/History.txt
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
ullr
|
|
2
|
+
===========
|
|
3
|
+
|
|
4
|
+
ullr is a little gem that consumes NOAA weather xml for a given lat/long, and returns a ruby object with 12 hour forecasts along with some sugar to let you know if any sugar will be falling from the sky.
|
|
5
|
+
|
|
6
|
+
Features
|
|
7
|
+
--------
|
|
8
|
+
|
|
9
|
+
* Grabs data that powers point forecast pages (http://forecast.weather.gov/MapClick.php?lat=43.98886243884903&lon=-121.68182373046875&site=pdt&smap=1&unit=0&lg=en&FcstType=text)
|
|
10
|
+
* Returns object with access to forecasted start_time, name (i.e. This Evening), text (i.e. Mostly sunny, high near 19), snow boolean, high_temperature, low_temperature, wind_direction, wind_speeds (array of low,high), snow_estimate (array of low,high)
|
|
11
|
+
|
|
12
|
+
Examples
|
|
13
|
+
--------
|
|
14
|
+
|
|
15
|
+
iheartsnow = Ullr::Forecast.new(:lat => 43.98, :lon => -121.68)
|
|
16
|
+
iheartsnow.get_nooa_forecast
|
|
17
|
+
|
|
18
|
+
Run Tests
|
|
19
|
+
---------
|
|
20
|
+
|
|
21
|
+
rake test
|
|
22
|
+
|
|
23
|
+
Stuff To Do
|
|
24
|
+
-----------
|
|
25
|
+
|
|
26
|
+
* Add support for other data sources (weatherbug, wunderground etc)
|
|
27
|
+
* Some more integration tests
|
|
28
|
+
|
|
29
|
+
Requirements
|
|
30
|
+
------------
|
|
31
|
+
|
|
32
|
+
* happymapper
|
|
33
|
+
|
|
34
|
+
Install
|
|
35
|
+
-------
|
|
36
|
+
|
|
37
|
+
* gem 'ullr'
|
|
38
|
+
|
|
39
|
+
Author
|
|
40
|
+
------
|
|
41
|
+
|
|
42
|
+
Original author: Timmy Crawford
|
|
43
|
+
|
|
44
|
+
License
|
|
45
|
+
-------
|
|
46
|
+
|
|
47
|
+
The MIT License
|
|
48
|
+
|
|
49
|
+
Copyright (c) 2011 Timmy Crawford
|
|
50
|
+
|
|
51
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
52
|
+
a copy of this software and associated documentation files (the
|
|
53
|
+
'Software'), to deal in the Software without restriction, including
|
|
54
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
55
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
56
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
57
|
+
the following conditions:
|
|
58
|
+
|
|
59
|
+
The above copyright notice and this permission notice shall be
|
|
60
|
+
included in all copies or substantial portions of the Software.
|
|
61
|
+
|
|
62
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
63
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
64
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
65
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
66
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
67
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
68
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
begin
|
|
3
|
+
require 'bones'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
abort '### Please install the "bones" gem ###'
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
require 'rspec/core/rake_task'
|
|
9
|
+
|
|
10
|
+
desc "Run all examples"
|
|
11
|
+
RSpec::Core::RakeTask.new('test') do |t|
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
task :default => 'test'
|
|
16
|
+
task 'gem:release' => 'test'
|
|
17
|
+
|
|
18
|
+
Bones {
|
|
19
|
+
name 'ullr'
|
|
20
|
+
authors 'Timmy Crawford'
|
|
21
|
+
email 'timmydcrawford@gmail.com'
|
|
22
|
+
url 'https://github.com/timmyc/ullr'
|
|
23
|
+
}
|
|
24
|
+
|
data/bin/ullr
ADDED
data/lib/ullr.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
|
|
2
|
+
module Ullr
|
|
3
|
+
|
|
4
|
+
# :stopdoc:
|
|
5
|
+
LIBPATH = ::File.expand_path('..', __FILE__) + ::File::SEPARATOR
|
|
6
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
|
7
|
+
VERSION = ::File.read(PATH + 'version.txt').strip
|
|
8
|
+
# :startdoc:
|
|
9
|
+
|
|
10
|
+
# Returns the library path for the module. If any arguments are given,
|
|
11
|
+
# they will be joined to the end of the libray path using
|
|
12
|
+
# <tt>File.join</tt>.
|
|
13
|
+
#
|
|
14
|
+
def self.libpath( *args )
|
|
15
|
+
rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
|
16
|
+
if block_given?
|
|
17
|
+
begin
|
|
18
|
+
$LOAD_PATH.unshift LIBPATH
|
|
19
|
+
rv = yield
|
|
20
|
+
ensure
|
|
21
|
+
$LOAD_PATH.shift
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
return rv
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Returns the lpath for the module. If any arguments are given,
|
|
28
|
+
# they will be joined to the end of the path using
|
|
29
|
+
# <tt>File.join</tt>.
|
|
30
|
+
#
|
|
31
|
+
def self.path( *args )
|
|
32
|
+
rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
|
33
|
+
if block_given?
|
|
34
|
+
begin
|
|
35
|
+
$LOAD_PATH.unshift PATH
|
|
36
|
+
rv = yield
|
|
37
|
+
ensure
|
|
38
|
+
$LOAD_PATH.shift
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
return rv
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Utility method used to require all files ending in .rb that lie in the
|
|
45
|
+
# directory below this file that has the same name as the filename passed
|
|
46
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
|
47
|
+
# the _filename_ does not have to be equivalent to the directory.
|
|
48
|
+
#
|
|
49
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
|
50
|
+
dir ||= ::File.basename(fname, '.*')
|
|
51
|
+
search_me = ::File.expand_path(
|
|
52
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
|
53
|
+
|
|
54
|
+
Dir.glob(search_me).sort.each {|rb| require rb}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end # module Ullr
|
|
58
|
+
|
|
59
|
+
Ullr.require_all_libs_relative_to(__FILE__)
|
|
60
|
+
|
data/spec/spec_helper.rb
ADDED
data/spec/ullr_spec.rb
ADDED
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
|
|
2
|
+
require File.join(File.dirname(__FILE__), %w[spec_helper])
|
|
3
|
+
|
|
4
|
+
describe Ullr do
|
|
5
|
+
context Ullr::NOAA do
|
|
6
|
+
before do
|
|
7
|
+
@noaa_fixture = File.new( File.join(File.dirname(__FILE__),'fixtures','noaa.xml'))
|
|
8
|
+
@noaa_data = @noaa_fixture.read
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
context Ullr::NOAA::Data do
|
|
12
|
+
before do
|
|
13
|
+
@results = Ullr::NOAA::Data.parse(@noaa_data)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should find two data elements" do
|
|
17
|
+
@results.size.should eql(2)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'Forecast Data' do
|
|
21
|
+
before do
|
|
22
|
+
@data = @results.find{|o| o.type == 'forecast'}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should respond to type" do
|
|
26
|
+
@data.respond_to?(:type).should be_true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should have a type of forecast" do
|
|
30
|
+
@data.type.should eql('forecast')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'Paremeters' do
|
|
34
|
+
before do
|
|
35
|
+
@parameters = @data.parameters
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should have one parameters" do
|
|
39
|
+
@parameters.instance_of?(Ullr::NOAA::Parameters).should be_true
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'Worded Forecast' do
|
|
43
|
+
before do
|
|
44
|
+
@worded_forecast = @parameters.worded_forecast
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should have one worded_forecast" do
|
|
48
|
+
@worded_forecast.instance_of?(Ullr::NOAA::WordedForecast).should be_true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should have a time-layout" do
|
|
52
|
+
@worded_forecast.time_layout.should eql('k-p12h-n13-1')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should have a data_source" do
|
|
56
|
+
@worded_forecast.dataSource.should eql('pdtNetcdf')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should have a wordGenerator" do
|
|
60
|
+
@worded_forecast.wordGenerator.should eql('markMitchell')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context 'Text' do
|
|
64
|
+
before do
|
|
65
|
+
@text = @worded_forecast.texts.first
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should have many icon_links" do
|
|
69
|
+
@worded_forecast.texts.instance_of?(Array).should be_true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should have a value" do
|
|
73
|
+
@text.value.should eql('A 20 percent chance of snow. Partly sunny, with a high near 39. West wind around 9 mph. ')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should respond to has_snow?" do
|
|
77
|
+
@text.respond_to?(:has_snow?).should be_true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should return true to has_snow? if snow exists" do
|
|
81
|
+
@text.has_snow?.should be_true
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should return false to has_snow? if no snow exists" do
|
|
85
|
+
@text.value = "foo"
|
|
86
|
+
@text.has_snow?.should be_false
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "should respond to snow_estimate" do
|
|
90
|
+
@text.respond_to?(:snow_estimate).should be_true
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "should return [0,1] as the estimate when snow exists but no estimate given" do
|
|
94
|
+
@text.snow_estimate.should eql(['0','1'])
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should return zeros when no snow exists" do
|
|
98
|
+
@text.value = "foo"
|
|
99
|
+
@text.snow_estimate.should eql(['0','0'])
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should return the proper snow estimate when range is given" do
|
|
103
|
+
@text.value = "blah blah blah. New snow accumulation of 6 to 8"
|
|
104
|
+
@text.snow_estimate.should eql(['6','8'])
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should support sickter double digit days" do
|
|
108
|
+
@text.value = "blah blah blah. New snow accumulation of 16 to 18"
|
|
109
|
+
@text.snow_estimate.should eql(['16','18'])
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "should support less than an inch" do
|
|
113
|
+
@text.value = "blah blah blah around an inch possible"
|
|
114
|
+
@text.snow_estimate.should eql(['0','1'])
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context 'Temperatures' do
|
|
118
|
+
it "should set a low temperature if present" do
|
|
119
|
+
@text.value = "Mostly cloudy, with a low around 27. North wind between 5 and 8 mph."
|
|
120
|
+
@text.low_temperature.should eql('27')
|
|
121
|
+
end
|
|
122
|
+
it "should not set a low temperature if none present" do
|
|
123
|
+
@text.value = "Mostly cloudy, with a high near 39. Northwest wind around 9 mph."
|
|
124
|
+
@text.low_temperature.should eql('')
|
|
125
|
+
end
|
|
126
|
+
it "should set a high temperature if present" do
|
|
127
|
+
@text.value = "Mostly cloudy, with a high near 39. Northwest wind around 9 mph."
|
|
128
|
+
@text.high_temperature.should eql('39')
|
|
129
|
+
end
|
|
130
|
+
it "should not set a high temperature if none present" do
|
|
131
|
+
@text.value = "Mostly cloudy, with a low around 27. North wind between 5 and 8 mph."
|
|
132
|
+
@text.high_temperature.should eql('')
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context 'Winds' do
|
|
137
|
+
it "should set a wind direction if present" do
|
|
138
|
+
@text.value = "Mostly sunny, with a high near 38. East wind around 5 mph."
|
|
139
|
+
@text.wind_direction.should eql('east')
|
|
140
|
+
end
|
|
141
|
+
it "should not set a wind direction if none present" do
|
|
142
|
+
@text.value = "Mostly sunny, with a high near 38."
|
|
143
|
+
@text.wind_direction.should eql('')
|
|
144
|
+
end
|
|
145
|
+
it "should return an array of wind speeds with the same value" do
|
|
146
|
+
@text.value = "Mostly sunny, with a high near 38. East wind around 5 mph."
|
|
147
|
+
@text.wind_speeds.should eql(['5','5'])
|
|
148
|
+
end
|
|
149
|
+
it "should return an array of wind speeds with the min and max values" do
|
|
150
|
+
@text.value = "Mostly sunny, with a high near 38. North wind between 5 and 8 mph."
|
|
151
|
+
@text.wind_speeds.should eql(['5','8'])
|
|
152
|
+
end
|
|
153
|
+
it "should return an empty array if not wind data present" do
|
|
154
|
+
@text.value = "Mostly sunny, with a high near 38."
|
|
155
|
+
@text.wind_speeds.should eql(['',''])
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
context 'Icons' do
|
|
163
|
+
before do
|
|
164
|
+
@icons = @parameters.conditions_icon
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "should have one weather" do
|
|
168
|
+
@icons.instance_of?(Ullr::NOAA::ConditionsIcon).should be_true
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "should have a time-layout" do
|
|
172
|
+
@icons.time_layout.should eql('k-p12h-n13-1')
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "should have a name" do
|
|
176
|
+
@icons.name.should eql('Conditions Icon')
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
context 'Icon Links' do
|
|
180
|
+
before do
|
|
181
|
+
@icon_link = @icons.icon_links.first
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should have many icon_links" do
|
|
185
|
+
@icons.icon_links.instance_of?(Array).should be_true
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it "should have a url" do
|
|
189
|
+
@icon_link.url.should eql("http://forecast.weather.gov/images/wtf/sn20.jpg")
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
context 'Weather' do
|
|
196
|
+
before do
|
|
197
|
+
@weather = @parameters.weather
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "should have one weather" do
|
|
201
|
+
@weather.instance_of?(Ullr::NOAA::Weather).should be_true
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "should have a time-layout" do
|
|
205
|
+
@weather.time_layout.should eql('k-p12h-n13-1')
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "should have a name" do
|
|
209
|
+
@weather.name.should eql('Weather Type, Coverage, Intensity')
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
context 'Weather Conditions' do
|
|
213
|
+
before do
|
|
214
|
+
@weather_conditions = @weather.weather_conditions.first
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "should have many weather_conditions" do
|
|
218
|
+
@weather.weather_conditions.instance_of?(Array).should be_true
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it "should have a weather_summary" do
|
|
222
|
+
@weather_conditions.weather_summary.should eql("Slight Chc Snow")
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
context 'Probability of Precipitation' do
|
|
229
|
+
it "should have one pops" do
|
|
230
|
+
@parameters.pops.instance_of?(Ullr::NOAA::POP).should be_true
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
context 'instance of' do
|
|
234
|
+
before do
|
|
235
|
+
@pop = @parameters.pops
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "should have a type" do
|
|
239
|
+
@pop.type.should eql('12 hour')
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "should have a units" do
|
|
243
|
+
@pop.units.should eql('percent')
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it "should have a time_layout" do
|
|
247
|
+
@pop.time_layout.should eql('k-p12h-n13-1')
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "should have many values" do
|
|
251
|
+
@pop.values.instance_of?(Array).should be_true
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it "should have the correct number of values" do
|
|
255
|
+
@pop.values.size.should eql(13)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
context 'Temperatures' do
|
|
261
|
+
it "should have many temperatures" do
|
|
262
|
+
@parameters.temperatures.instance_of?(Array).should be_true
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
context 'instance of' do
|
|
266
|
+
before do
|
|
267
|
+
@temperature = @parameters.temperatures.first
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "should have a type" do
|
|
271
|
+
@temperature.type.should eql('maximum')
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it "should have a units" do
|
|
275
|
+
@temperature.units.should eql('Fahrenheit')
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it "should have a time_layout" do
|
|
279
|
+
@temperature.time_layout.should eql('k-p24h-n7-1')
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
context 'TimeLayouts' do
|
|
286
|
+
it "should have many time_layouts" do
|
|
287
|
+
@data.time_layouts.instance_of?(Array).should be_true
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
it "should have four time_layouts" do
|
|
291
|
+
@data.time_layouts.size.should eql(4)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
context 'Instance of TimeLayout' do
|
|
295
|
+
before do
|
|
296
|
+
@time_layout = @data.time_layouts[1]
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
it "should have a time_coordinate" do
|
|
300
|
+
@time_layout.time_coordinate.should eql('local')
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it "should have a summarization" do
|
|
304
|
+
@time_layout.summarization.should eql('12hourly')
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
it "should have a layout_key" do
|
|
308
|
+
@time_layout.layout_key.should eql('k-p12h-n13-1')
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
context 'Start Valid Times' do
|
|
312
|
+
it "should have many start_valid_times" do
|
|
313
|
+
@time_layout.start_valid_times.instance_of?(Array).should be_true
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
it "should have two start_valid_times" do
|
|
317
|
+
@time_layout.start_valid_times.size.should eql(13)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
context 'Instance of' do
|
|
321
|
+
before do
|
|
322
|
+
@start_valid_time = @time_layout.start_valid_times.first
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
it "should have a period_name" do
|
|
326
|
+
@start_valid_time.period_name.should eql('This Afternoon')
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it "should have a DateTime period_start" do
|
|
330
|
+
@start_valid_time.period_start.should eql(DateTime.parse('2011-12-18T12:00:00-08:00'))
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
context 'Location' do
|
|
338
|
+
before do
|
|
339
|
+
@location = @data.location
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
it "should have one location" do
|
|
343
|
+
@location.instance_of?(Ullr::NOAA::Location).should be_true
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it "should have a key" do
|
|
347
|
+
@location.location_key.should eql('point1')
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it "should have a description" do
|
|
351
|
+
@location.description.should eql('Mount Bachelor, OR')
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
context 'Point' do
|
|
355
|
+
before do
|
|
356
|
+
@point = @location.point
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it "should have one point" do
|
|
360
|
+
@point.instance_of?(Ullr::NOAA::Point).should be_true
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
it "should have a latitude" do
|
|
364
|
+
@point.latitude.should eql('43.99')
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
it "should have a longitude" do
|
|
368
|
+
@point.longitude.should eql('-121.68')
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
context 'City' do
|
|
373
|
+
before do
|
|
374
|
+
@city = @location.city
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
it "should have one city" do
|
|
378
|
+
@city.instance_of?(Ullr::NOAA::City).should be_true
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
it "should have a name" do
|
|
382
|
+
@city.name.should eql('Mount Bachelor')
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
it "should have a state" do
|
|
386
|
+
@city.state.should eql('OR')
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
context 'Height' do
|
|
391
|
+
before do
|
|
392
|
+
@height = @location.height
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
it "should have one height" do
|
|
396
|
+
@height.instance_of?(Ullr::NOAA::Height).should be_true
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
it "should have an elevation" do
|
|
400
|
+
@height.elevation.should eql('7636')
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
it "should have a datum" do
|
|
404
|
+
@height.datum.should eql('mean sea level')
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
it "should have many time layouts" do
|
|
410
|
+
@data.time_layouts.instance_of?(Array).should be_true
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
context Ullr::Forecast do
|
|
417
|
+
before do
|
|
418
|
+
@noaa_fixture = File.new( File.join(File.dirname(__FILE__),'fixtures','noaa.xml'))
|
|
419
|
+
end
|
|
420
|
+
describe "required options" do
|
|
421
|
+
it "should require a lon to be passed in" do
|
|
422
|
+
expect{ Ullr::Forecast.new(:lat => 'blah') }.to raise_error(ArgumentError)
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
it "should require a lat to be passed in" do
|
|
426
|
+
expect{ Ullr::Forecast.new(:lon => 'blah') }.to raise_error(ArgumentError)
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
it "should require lat,lon to be floating points" do
|
|
430
|
+
expect{ Ullr::Forecast.new(:lat => 'blah', :lon => 'meh') }.to raise_error(ArgumentError)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
it "should not rais an error if lat lon are passed and are both floats" do
|
|
434
|
+
expect{ Ullr::Forecast.new(:lat => 43.98, :lon => -121.68) }.to_not raise_error(ArgumentError)
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
describe "instance varialbes" do
|
|
439
|
+
before do
|
|
440
|
+
@lat = 43.98
|
|
441
|
+
@lon = -121.68
|
|
442
|
+
@forecast = Ullr::Forecast.new(:lat => @lat, :lon => @lon)
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
it "should set the lat lng instance variables" do
|
|
446
|
+
@forecast.lat.should eql(@lat)
|
|
447
|
+
@forecast.lon.should eql(@lon)
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
it "should set the endpoint instance variable" do
|
|
451
|
+
@forecast.noaa_endpoint.should eql("http://forecast.weather.gov/MapClick.php?lat=#{@lat}&lon=#{@lon}&FcstType=dwml")
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
describe "get noaa data" do
|
|
456
|
+
before do
|
|
457
|
+
@lat = 43.98
|
|
458
|
+
@lon = -121.68
|
|
459
|
+
@forecast = Ullr::Forecast.new(:lat => @lat, :lon => @lon)
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
it "should call open to endpoint url" do
|
|
463
|
+
@forecast.should_receive(:open).with(@forecast.noaa_endpoint).and_return(@noaa_fixture)
|
|
464
|
+
@forecast.get_noaa_forecast
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
it "should handle socket errors to noaa endpoint" do
|
|
468
|
+
@forecast.should_receive(:open).with(@forecast.noaa_endpoint).and_raise(SocketError)
|
|
469
|
+
@forecast.get_noaa_forecast
|
|
470
|
+
@forecast.socket_error.should be_true
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
|
data/version.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
metadata
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ullr
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Timmy Crawford
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2011-12-17 00:00:00.000000000Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: happymapper
|
|
16
|
+
requirement: &70111612913000 !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 0.4.0
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: *70111612913000
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: bones
|
|
27
|
+
requirement: &70111612911660 !ruby/object:Gem::Requirement
|
|
28
|
+
none: false
|
|
29
|
+
requirements:
|
|
30
|
+
- - ! '>='
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 3.7.3
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: *70111612911660
|
|
36
|
+
description: ullr is a little gem that consumes NOAA weather xml for a given lat/long,
|
|
37
|
+
and returns an array of data with 12 hour forecasts along with some sugar to let
|
|
38
|
+
you know if any sugar will be falling from the sky.
|
|
39
|
+
email: timmydcrawford@gmail.com
|
|
40
|
+
executables:
|
|
41
|
+
- ullr
|
|
42
|
+
extensions: []
|
|
43
|
+
extra_rdoc_files:
|
|
44
|
+
- History.txt
|
|
45
|
+
- bin/ullr
|
|
46
|
+
files:
|
|
47
|
+
- .bnsignore
|
|
48
|
+
- History.txt
|
|
49
|
+
- README.md
|
|
50
|
+
- Rakefile
|
|
51
|
+
- bin/ullr
|
|
52
|
+
- lib/ullr.rb
|
|
53
|
+
- spec/spec_helper.rb
|
|
54
|
+
- spec/ullr_spec.rb
|
|
55
|
+
- version.txt
|
|
56
|
+
homepage: https://github.com/timmyc/ullr
|
|
57
|
+
licenses: []
|
|
58
|
+
post_install_message:
|
|
59
|
+
rdoc_options:
|
|
60
|
+
- --main
|
|
61
|
+
- README.md
|
|
62
|
+
require_paths:
|
|
63
|
+
- lib
|
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
|
+
none: false
|
|
66
|
+
requirements:
|
|
67
|
+
- - ! '>='
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
|
+
none: false
|
|
72
|
+
requirements:
|
|
73
|
+
- - ! '>='
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
requirements: []
|
|
77
|
+
rubyforge_project: ullr
|
|
78
|
+
rubygems_version: 1.8.6
|
|
79
|
+
signing_key:
|
|
80
|
+
specification_version: 3
|
|
81
|
+
summary: ullr consumes NOAA weather xml for a given lat/long, and returns an array
|
|
82
|
+
of forecast data.
|
|
83
|
+
test_files:
|
|
84
|
+
- spec/ullr_spec.rb
|