weather-forecasts 1.1.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 (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