weather-forecasts 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +10 -0
  6. data/LICENSE +20 -0
  7. data/README.md +135 -0
  8. data/bin/wf-console +21 -0
  9. data/lib/weather-forecasts.rb +1 -0
  10. data/lib/weather_forecasts.rb +23 -0
  11. data/lib/weather_forecasts/client.rb +65 -0
  12. data/lib/weather_forecasts/client/error.rb +18 -0
  13. data/lib/weather_forecasts/client/help_console.rb +9 -0
  14. data/lib/weather_forecasts/client/query.rb +155 -0
  15. data/lib/weather_forecasts/client/query/query_property.rb +68 -0
  16. data/lib/weather_forecasts/client/query/query_utilities.rb +16 -0
  17. data/lib/weather_forecasts/client/query/select_by_days_query.rb +35 -0
  18. data/lib/weather_forecasts/client/query/select_coordinates_by_cities_query.rb +47 -0
  19. data/lib/weather_forecasts/client/query/select_coordinates_by_zip_query.rb +34 -0
  20. data/lib/weather_forecasts/client/query/select_corner_coordinates_query.rb +38 -0
  21. data/lib/weather_forecasts/client/query/select_gridpoint_coordinates_query.rb +35 -0
  22. data/lib/weather_forecasts/client/query/select_linepoint_coordinates_query.rb +33 -0
  23. data/lib/weather_forecasts/client/query/select_query.rb +48 -0
  24. data/lib/weather_forecasts/client/query/select_square_coordinates_query.rb +35 -0
  25. data/lib/weather_forecasts/client/query/selection_attributes.rb +19 -0
  26. data/lib/weather_forecasts/client/version.rb +5 -0
  27. data/lib/weather_forecasts/dwml.rb +38 -0
  28. data/lib/weather_forecasts/dwml/data_extractor.rb +55 -0
  29. data/lib/weather_forecasts/dwml/head_extractor.rb +49 -0
  30. data/lib/weather_forecasts/dwml/location.rb +33 -0
  31. data/lib/weather_forecasts/dwml/parameter_extractor.rb +281 -0
  32. data/lib/weather_forecasts/dwml/time_layout.rb +55 -0
  33. data/spec/fixtures/vcr_cassettes/select_by_days_query.yml +557 -0
  34. data/spec/fixtures/vcr_cassettes/select_coordinates_by_cities_query.yml +437 -0
  35. data/spec/fixtures/vcr_cassettes/select_coordinates_by_zip_query.yml +437 -0
  36. data/spec/fixtures/vcr_cassettes/select_corner_coordinates_query.yml +438 -0
  37. data/spec/fixtures/vcr_cassettes/select_gridpoint_coordinates_query.yml +467 -0
  38. data/spec/fixtures/vcr_cassettes/select_linepoint_coordinates_query.yml +440 -0
  39. data/spec/fixtures/vcr_cassettes/select_query.yml +1647 -0
  40. data/spec/fixtures/vcr_cassettes/select_square_coordinates_query.yml +443 -0
  41. data/spec/lib/ndfd/client/query/query_property_spec.rb +41 -0
  42. data/spec/lib/ndfd/client/query/select_by_days_query_spec.rb +35 -0
  43. data/spec/lib/ndfd/client/query/select_coordinates_by_cities_query_spec.rb +33 -0
  44. data/spec/lib/ndfd/client/query/select_coordinates_by_zip_query_spec.rb +34 -0
  45. data/spec/lib/ndfd/client/query/select_corner_coordinates_query_spec.rb +35 -0
  46. data/spec/lib/ndfd/client/query/select_gridpoint_coordinates_query_spec.rb +37 -0
  47. data/spec/lib/ndfd/client/query/select_linepoint_coordinates_query_spec.rb +36 -0
  48. data/spec/lib/ndfd/client/query/select_query_spec.rb +46 -0
  49. data/spec/lib/ndfd/client/query/select_square_coordinates_query_spec.rb +37 -0
  50. data/spec/lib/ndfd/client/query/selection_attributes_spec.rb +13 -0
  51. data/spec/lib/ndfd/client/query_spec.rb +91 -0
  52. data/spec/lib/ndfd/client_spec.rb +61 -0
  53. data/spec/spec_helper.rb +33 -0
  54. data/spec/support/resources/sample_document.xml +61 -0
  55. data/weather-forecasts.gemspec +39 -0
  56. metadata +224 -0
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client::SelectByDaysQuery do
4
+ let(:conditions) {
5
+ {
6
+ :coordinates => [ {:latitude => 38.99, :longitude => -77.01 }],
7
+ :days => 5,
8
+ :start_date => Time.zone.now,
9
+ :unit => "e",
10
+ :format => "24 hourly"
11
+ }
12
+ }
13
+
14
+ let(:null_logger) { Logger.new(File.open("/dev/null", "w")) }
15
+
16
+ subject { WeatherForecasts.client(:logger => null_logger).select_by_days }
17
+
18
+ before(:each) do
19
+ # Silence HTTPI logger (used by Savon)
20
+ HTTPI.logger = null_logger
21
+ end
22
+
23
+ describe "#execute" do
24
+ before(:each) do
25
+ VCR.use_cassette('select_by_days_query') do
26
+ @response = subject.where(conditions).execute
27
+ end
28
+ end
29
+
30
+ it "returns a valid response" do
31
+ @response.should be_a(Hash)
32
+ @response[:parameters]["point1"][:temperature][:maximum][:name].should == "Daily Maximum Temperature"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client::SelectCoordinatesByCitiesQuery do
4
+ let(:conditions) {
5
+ {
6
+ :display => :all
7
+ }
8
+ }
9
+
10
+ let(:null_logger) { Logger.new(File.open("/dev/null", "w")) }
11
+
12
+ subject { WeatherForecasts.client(:logger => null_logger).select_coordinates_by_cities }
13
+
14
+ # Silence savon's HTTP request logger
15
+ before(:each) do
16
+ HTTPI.logger = null_logger
17
+ end
18
+
19
+ describe "#execute" do
20
+ before(:each) do
21
+ VCR.use_cassette('select_coordinates_by_cities_query') do
22
+ @response = subject.where(conditions).execute
23
+ end
24
+ end
25
+
26
+ it "returns a valid response" do
27
+ @response.should be_a(Hash)
28
+ @response["Denver,CO"].values.each do |value|
29
+ value.should be_a(Numeric)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client::SelectCoordinatesByZipQuery do
4
+ let(:conditions) {
5
+ {
6
+ :zip => ["80129", "80128"]
7
+ }
8
+ }
9
+
10
+ let(:null_logger) { Logger.new(File.open("/dev/null", "w")) }
11
+
12
+ subject { WeatherForecasts.client(:logger => null_logger).select_coordinates_by_zip }
13
+
14
+ # Silence savon's HTTP request logger
15
+ before(:each) do
16
+ HTTPI.logger = null_logger
17
+ end
18
+
19
+ describe "#execute" do
20
+ before(:each) do
21
+ VCR.use_cassette('select_coordinates_by_zip_query') do
22
+ @response = subject.where(conditions).execute
23
+ end
24
+ end
25
+
26
+ it "returns a valid response" do
27
+ @response.should be_a(Hash)
28
+ @response.keys.should include(*conditions[:zip])
29
+ @response.each do |_, value|
30
+ value.values.each {|v| v.should be_a(Numeric) }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client::SelectCornerCoordinatesQuery do
4
+ let(:conditions) {
5
+ {
6
+ :sector => :conus
7
+ }
8
+ }
9
+
10
+ let(:null_logger) { Logger.new(File.open("/dev/null", "w")) }
11
+
12
+ subject { WeatherForecasts.client(:logger => null_logger).select_corner_coordinates }
13
+
14
+ # Silence savon's HTTP request logger
15
+ before(:each) do
16
+ HTTPI.logger = null_logger
17
+ end
18
+
19
+ describe "#execute" do
20
+ before(:each) do
21
+ VCR.use_cassette('select_corner_coordinates_query') do
22
+ @response = subject.where(conditions).execute
23
+ end
24
+ end
25
+
26
+ it "returns a valid response" do
27
+ @response.should be_a(Array)
28
+
29
+ @response.first.keys.should include(:latitude, :longitude)
30
+ @response.first.values.each do |value|
31
+ value.should be_a(Numeric)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client::SelectGridpointCoordinatesQuery do
4
+ let(:conditions) {
5
+ {
6
+ :lower_left_coordinate => { :latitude => 39.547101, :longitude => -105.215759 },
7
+ :upper_right_coordinate => { :latitude => 39.991484, :longitude => -104.704895 },
8
+ :resolution => 2
9
+ }
10
+ }
11
+
12
+ let(:null_logger) { Logger.new(File.open("/dev/null", "w")) }
13
+
14
+ subject { WeatherForecasts.client(:logger => null_logger).select_gridpoint_coordinates }
15
+
16
+ # Silence savon's HTTP request logger
17
+ before(:each) do
18
+ HTTPI.logger = null_logger
19
+ end
20
+
21
+ describe "#execute" do
22
+ before(:each) do
23
+ VCR.use_cassette('select_gridpoint_coordinates_query') do
24
+ @response = subject.where(conditions).execute
25
+ end
26
+ end
27
+
28
+ it "returns a valid response" do
29
+ @response.should be_a(Array)
30
+
31
+ @response.first.keys.should include(:latitude, :longitude)
32
+ @response.first.values.each do |value|
33
+ value.should be_a(Numeric)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client::SelectLinepointCoordinatesQuery do
4
+ let(:conditions) {
5
+ {
6
+ :start_coordinate => { :latitude => 39.547101, :longitude => -105.215759 },
7
+ :stop_coordinate => { :latitude => 39.991484, :longitude => -104.704895 }
8
+ }
9
+ }
10
+
11
+ let(:null_logger) { Logger.new(File.open("/dev/null", "w")) }
12
+
13
+ subject { WeatherForecasts.client(:logger => null_logger).select_linepoint_coordinates }
14
+
15
+ # Silence savon's HTTP request logger
16
+ before(:each) do
17
+ HTTPI.logger = null_logger
18
+ end
19
+
20
+ describe "#execute" do
21
+ before(:each) do
22
+ VCR.use_cassette('select_linepoint_coordinates_query') do
23
+ @response = subject.where(conditions).execute
24
+ end
25
+ end
26
+
27
+ it "returns a valid response" do
28
+ @response.should be_a(Array)
29
+
30
+ @response.first.keys.should include(:latitude, :longitude)
31
+ @response.first.values.each do |value|
32
+ value.should be_a(Numeric)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client::SelectQuery do
4
+ let(:dimensions) {
5
+ # NOTE: Adding all dimensions to ensure it doesn't blow up when parsing
6
+ [ :maxt,:mint,:temp,:dew,:appt,:pop12,:qpf,:snow,:sky,:rh,:wspd,:wdir,:wx,:icons,
7
+ :waveh,:incw34,:incw50,:incw64,:cumw34,:cumw50,:cumw64,:wgust,:critfireo,:dryfireo,
8
+ :conhazo,:ptornado,:phail,:ptstmwinds,:pxtornado,:pxhail,:pxtstmwinds,:ptotsvrtstm,
9
+ :pxtotsvrtstm,:tmpabv14d,:tmpblw14d,:tmpabv30d,:tmpblw30d,:tmpabv90d,:tmpblw90d,
10
+ :prcpabv14d,:prcpblw14d,:prcpabv30d,:prcpblw30d,:prcpabv90d,:prcpblw90d,:precipa_r,
11
+ :sky_r,:td_r,:temp_r,:wdir_r,:wspd_r,:wwa,:iceaccum,:maxrh,:minrh ]
12
+ }
13
+
14
+ let(:conditions) {
15
+ {
16
+ :coordinates => [ {:latitude => 38.99, :longitude => -77.01 }],
17
+ :product => "time-series",
18
+ :start_time => Time.zone.now,
19
+ :end_time => Time.zone.now + 6.days,
20
+ :unit => "e"
21
+ }
22
+ }
23
+
24
+ let(:null_logger) { Logger.new(File.open("/dev/null", "w")) }
25
+
26
+ subject { WeatherForecasts.client(:logger => null_logger).select(*dimensions) }
27
+
28
+ before(:each) do
29
+ # Silence HTTPI logger (used by Savon)
30
+ HTTPI.logger = null_logger
31
+ end
32
+
33
+ describe "#execute" do
34
+ before(:each) do
35
+ VCR.use_cassette('select_query') do
36
+ @response = subject.where(conditions).execute
37
+ end
38
+ end
39
+
40
+ # TODO: Add verification for each metric
41
+ it "returns a valid response" do
42
+ @response.should be_a(Hash)
43
+ @response[:parameters]["point1"][:temperature][:maximum][:name].should == "Daily Maximum Temperature"
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client::SelectSquareCoordinatesQuery do
4
+ let(:conditions) {
5
+ {
6
+ :center_point => { :latitude => 39.547101, :longitude => -105.215759 },
7
+ :distance => { :latitude => 0.547101, :longitude => 0.215759 },
8
+ :resolution => 10
9
+ }
10
+ }
11
+
12
+ let(:null_logger) { Logger.new(File.open("/dev/null", "w")) }
13
+
14
+ subject { WeatherForecasts.client(:logger => null_logger).select_square_coordinates }
15
+
16
+ # Silence savon's HTTP request logger
17
+ before(:each) do
18
+ HTTPI.logger = null_logger
19
+ end
20
+
21
+ describe "#execute" do
22
+ before(:each) do
23
+ VCR.use_cassette('select_square_coordinates_query') do
24
+ @response = subject.where(conditions).execute
25
+ end
26
+ end
27
+
28
+ it "returns a valid response" do
29
+ @response.should be_a(Array)
30
+
31
+ @response.first.keys.should include(:latitude, :longitude)
32
+ @response.first.values.each do |value|
33
+ value.should be_a(Numeric)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client::SelectionAttributes do
4
+ let(:attr) { :blah }
5
+
6
+ subject { WeatherForecasts::Client::SelectionAttributes.new(attr) }
7
+
8
+ describe "#valid?" do
9
+ it "raises an error if an invalid selection attribute is used" do
10
+ expect { subject.valid?(:wrong) }.to raise_error(WeatherForecasts::Client::InvalidSelectionAttributeError)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ class WeatherForecasts::Client::TestQuery < WeatherForecasts::Client::Query
4
+ set_selection_attributes :thing1, :thing2
5
+
6
+ property :property1, :type => Array, :required => true, :required_keys => [:lat, :long]
7
+ property :property2, :type => String, :required => true, :options => ["one", "two"], :default => "one"
8
+ end
9
+
10
+ describe WeatherForecasts::Client::Query do
11
+ let(:soap_client) { double }
12
+ let(:attrs) { {} }
13
+ let(:subclass) { WeatherForecasts::Client::TestQuery }
14
+
15
+ let(:conditions_with_defaults) { {
16
+ :property1 => [{ :lat => 67.87, :long => -107.37 }]
17
+ }
18
+ }
19
+
20
+ let(:conditions_overriding_defaults) { {
21
+ :property1 => [{ :lat => 67.87, :long => -107.37 }],
22
+ :property2 => "two"
23
+ }
24
+ }
25
+
26
+ subject { subclass.new(soap_client, attrs) }
27
+
28
+ describe "#where" do
29
+ it "updates the #conditions attributes and sets any defaults that aren't set" do
30
+ subject.where(conditions_with_defaults)
31
+ subject.conditions.should == conditions_with_defaults.merge(:property2 => "one")
32
+ end
33
+
34
+ it "does not set a conditions to a default value if it is already set" do
35
+ subject.where(conditions_overriding_defaults)
36
+ subject.conditions.should == conditions_overriding_defaults
37
+ end
38
+
39
+ it "returns self" do
40
+ subject.where(conditions_overriding_defaults).should be_a(subclass)
41
+ end
42
+ end
43
+
44
+ describe "#execute" do
45
+ it "raises a not implemented error (intended for subclasses)" do
46
+ expect { subject.execute }.to raise_error(NotImplementedError)
47
+ end
48
+ end
49
+
50
+ describe "#validate" do
51
+ context "for selection attributes" do
52
+ context "with valid selection attributes" do
53
+ it "validates that the selection attributes are appropriately set" do
54
+ instance = subclass.new(soap_client, [:thing1, :thing2])
55
+ instance.where(conditions_with_defaults)
56
+
57
+ expect { instance.validate }.not_to raise_error
58
+ end
59
+ end
60
+
61
+ context "with invalid selection attributes" do
62
+ it "raises an error" do
63
+ instance = subclass.new(soap_client, [:thing1, :thing2, :thing3])
64
+ instance.where(conditions_with_defaults)
65
+
66
+ expect { instance.validate }.to raise_error(WeatherForecasts::Client::InvalidSelectionAttributeError)
67
+ end
68
+ end
69
+ end
70
+
71
+ context "for conditions" do
72
+ context "with valid conditions" do
73
+ it "validates that the conditions are appropriately set" do
74
+ instance = subclass.new(soap_client)
75
+ instance.where(conditions_with_defaults)
76
+
77
+ expect { instance.validate }.not_to raise_error
78
+ end
79
+ end
80
+
81
+ context "with invalid conditions" do
82
+ it "raises an error" do
83
+ instance = subclass.new(soap_client)
84
+ instance.where(conditions_with_defaults.merge(:property2 => "blah"))
85
+
86
+ expect { instance.validate }.to raise_error(WeatherForecasts::Client::InvalidOptionSpecifiedError)
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherForecasts::Client do
4
+ subject { WeatherForecasts.client }
5
+
6
+ let(:options) { double }
7
+
8
+ describe "#soap_client" do
9
+ it "returns a soap client" do
10
+ subject.soap_client.should be_a(Savon::Client)
11
+ end
12
+ end
13
+
14
+ describe "#select" do
15
+ it "returns as WeatherForecasts::Client::SelectQuery object" do
16
+ subject.select(options).should be_a(WeatherForecasts::Client::SelectQuery)
17
+ end
18
+ end
19
+
20
+ describe "#select_by_days" do
21
+ it "returns as WeatherForecasts::Client::SelectByDaysQuery object" do
22
+ subject.select_by_days.should be_a(WeatherForecasts::Client::SelectByDaysQuery)
23
+ end
24
+ end
25
+
26
+ describe "#select_coordinates_by_zip" do
27
+ it "returns as WeatherForecasts::Client::SelectCoordinatesByZipQuery object" do
28
+ subject.select_coordinates_by_zip.should be_a(WeatherForecasts::Client::SelectCoordinatesByZipQuery)
29
+ end
30
+ end
31
+
32
+ describe "#select_gridpoint_coordinates" do
33
+ it "returns as WeatherForecasts::Client::SelectGridpointCoordinatesQuery object" do
34
+ subject.select_gridpoint_coordinates.should be_a(WeatherForecasts::Client::SelectGridpointCoordinatesQuery)
35
+ end
36
+ end
37
+
38
+ describe "#select_linepoint_coordinates" do
39
+ it "returns as WeatherForecasts::Client::SelectLinepointCoordinatesQuery object" do
40
+ subject.select_linepoint_coordinates.should be_a(WeatherForecasts::Client::SelectLinepointCoordinatesQuery)
41
+ end
42
+ end
43
+
44
+ describe "#select_cities_coordinates" do
45
+ it "returns as WeatherForecasts::Client::SelectCitiesCoordinatesQuery object" do
46
+ subject.select_coordinates_by_cities.should be_a(WeatherForecasts::Client::SelectCoordinatesByCitiesQuery)
47
+ end
48
+ end
49
+
50
+ describe "#select_corner_coordinates" do
51
+ it "returns as WeatherForecasts::Client::SelectCornerCoordinatesQuery object" do
52
+ subject.select_corner_coordinates.should be_a(WeatherForecasts::Client::SelectCornerCoordinatesQuery)
53
+ end
54
+ end
55
+
56
+ describe "#select_square_coordinates" do
57
+ it "returns as WeatherForecasts::Client::SelectSquareCoordinatesQuery object" do
58
+ subject.select_square_coordinates.should be_a(WeatherForecasts::Client::SelectSquareCoordinatesQuery)
59
+ end
60
+ end
61
+ end