regentanz 0.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.
Files changed (39) hide show
  1. data/.gitignore +5 -0
  2. data/CHANGELOG.rdoc +22 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +24 -0
  5. data/README.rdoc +46 -0
  6. data/Rakefile +23 -0
  7. data/lib/regentanz/astronomy.rb +69 -0
  8. data/lib/regentanz/cache/base.rb +51 -0
  9. data/lib/regentanz/cache/file.rb +86 -0
  10. data/lib/regentanz/cache.rb +2 -0
  11. data/lib/regentanz/callbacks.rb +18 -0
  12. data/lib/regentanz/conditions/base.rb +16 -0
  13. data/lib/regentanz/conditions/current.rb +14 -0
  14. data/lib/regentanz/conditions/forecast.rb +14 -0
  15. data/lib/regentanz/conditions.rb +3 -0
  16. data/lib/regentanz/configuration.rb +55 -0
  17. data/lib/regentanz/configurator.rb +22 -0
  18. data/lib/regentanz/google_weather.rb +151 -0
  19. data/lib/regentanz/parser/google_weather.rb +100 -0
  20. data/lib/regentanz/parser.rb +1 -0
  21. data/lib/regentanz/test_helper.rb +52 -0
  22. data/lib/regentanz/version.rb +4 -0
  23. data/lib/regentanz.rb +12 -0
  24. data/regentanz.gemspec +31 -0
  25. data/test/factories.rb +8 -0
  26. data/test/support/support_mailer.rb +7 -0
  27. data/test/support/tmp/.gitignore +1 -0
  28. data/test/support/valid_response.xml.erb +26 -0
  29. data/test/test_helper.rb +18 -0
  30. data/test/unit/astronomy_test.rb +26 -0
  31. data/test/unit/cache/base_test.rb +53 -0
  32. data/test/unit/cache/file_test.rb +141 -0
  33. data/test/unit/callbacks_test.rb +27 -0
  34. data/test/unit/configuration_test.rb +57 -0
  35. data/test/unit/current_condition_test.rb +33 -0
  36. data/test/unit/forecast_condition_test.rb +35 -0
  37. data/test/unit/google_weather_test.rb +131 -0
  38. data/test/unit/parser/google_weather_parser_test.rb +71 -0
  39. metadata +219 -0
@@ -0,0 +1,100 @@
1
+ module Regentanz
2
+ module Parser
3
+ class GoogleWeather
4
+ require 'iconv'
5
+
6
+ XML_ENCODING = 'LATIN1' # source encoding of the XML data
7
+
8
+ # Converts a string from XML_ENCODING to UTF-8 using the Iconv library.
9
+ #
10
+ # === Note
11
+ # FIXME The XML source document seems to be delivered LATIN1 or UTF-8, completely
12
+ # random and unpredictable.
13
+ #
14
+ # === Parameters
15
+ # * +data+: string to convert
16
+ def convert_encoding data
17
+ return if data.blank?
18
+ self.class::XML_ENCODING != "UTF-8" ? Iconv.iconv("UTF-8", self.class::XML_ENCODING, data).flatten.join(" ") : data
19
+ end
20
+
21
+ def parse_current!(xml)
22
+ return if xml.blank?
23
+ begin
24
+ doc = REXML::Document.new(xml)
25
+ if doc.elements['xml_api_reply/weather/current_conditions']
26
+ attributes = {}
27
+ doc.elements['xml_api_reply/weather/current_conditions'].each_element do |ele|
28
+ attributes.merge! parse_node(ele)
29
+ end
30
+ Regentanz::Conditions::Current.new(attributes)
31
+ end
32
+ rescue
33
+ # FIXME should report error
34
+ end
35
+ end
36
+
37
+ def parse_forecast!(xml)
38
+ return if xml.blank?
39
+ forecasts = []
40
+ begin
41
+ doc = REXML::Document.new(xml)
42
+ if doc.elements['xml_api_reply/weather/forecast_conditions']
43
+ doc.elements.each('xml_api_reply/weather/forecast_conditions') do |forecast_element|
44
+ attributes = {}
45
+ forecast_element.each_element { |ele| attributes.merge! parse_node(ele) }
46
+ forecasts << Regentanz::Conditions::Forecast.new(attributes)
47
+ end
48
+ end
49
+ forecasts
50
+ rescue
51
+ # FIXME should report error
52
+ end
53
+ end
54
+
55
+ #private # FIXME private methods should start here after parse! has been implemented
56
+
57
+ # Handles some special treatment for certain sub-elements, transforms _element_
58
+ # into a hash and returns it.
59
+ #
60
+ # === Parameters
61
+ # * +element+ childnode of type REXML::Element
62
+ def parse_node(element)
63
+ hash = {}
64
+ hash.merge! parse_style(element.attribute("data").to_s) if element.name == "icon"
65
+ if element.name == "humidity"
66
+ # Handle the small whitespace just before the '%'
67
+ hash.merge! element.name => element.attribute("data").to_s.gsub(/(\d+).+%$/, '\1 %')
68
+ elsif element.name == "icon"
69
+ # We want the full URL
70
+ hash.merge! element.name => "http://www.google.com" + element.attribute("data").to_s
71
+ elsif (element.name == "high" or element.name == "low") and @lang == "en"
72
+ # Forecast-temperatures in EN are listed in °F; we fix that here
73
+ temp_f = element.attribute("data").to_s.to_i
74
+ hash.merge! element.name => ( temp_f - 32 ) * 5 / 9
75
+ else
76
+ hash.merge! element.name => element.attribute("data").to_s
77
+ end
78
+ hash
79
+ end
80
+
81
+ private
82
+
83
+ # Extracts a name for the weather condition from the icon name. Intended to
84
+ # be used as CSS style class name.
85
+ #
86
+ # === Parameters
87
+ # * +path+ an URI-string to Google's weather icon
88
+ def parse_style(path)
89
+ hash = {}
90
+ unless path.blank?
91
+ style = File.basename(path) # FIXME is this what we want for everyone?
92
+ style = style.slice(0, style.rindex(".")).gsub(/_/, '-')
93
+ hash = { "style" => style }
94
+ end
95
+ hash
96
+ end
97
+
98
+ end
99
+ end
100
+ end
@@ -0,0 +1 @@
1
+ require 'regentanz/parser/google_weather'
@@ -0,0 +1,52 @@
1
+ module Regentanz
2
+ module TestHelper
3
+
4
+ # Default values used for testing. Use this in your setup methods.
5
+ # Configuration values can be overriden by supplying a block. See
6
+ # Regentanz::Configuration for supported values.
7
+ def setup_regentanz_test_configuration!
8
+ Regentanz.configure do |config|
9
+ config.retry_ttl = Regentanz::Configuration.default_cache_ttl
10
+ config.do_not_get_weather = true
11
+ config.retry_ttl = Regentanz::Configuration.default_retry_ttl
12
+ config.suppress_stderr_output = true
13
+ yield config if block_given? # add settings or override above from client
14
+ end
15
+ end
16
+
17
+ # Returns an invalid API response that will cause REXML to hickup
18
+ def invalid_xml_response
19
+ '<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">' \
20
+ "<TITLE>302 Moved</TITLE></HEAD><BODY>\n" \
21
+ "<H1>302 Moved</H1>\n" \
22
+ "The document has moved\n" \
23
+ '<A HREF="http://sorry.google.com/sorry/?continue=http://www.google.com/ig/api%3Fweather%3D86747%252CGermany%26hl%3Dde">here</A>' \
24
+ "</BODY></HTML>\n"
25
+ end
26
+
27
+ # Returns a valid xml api reply based upon ./test/support/valid_response.xml.erb
28
+ def valid_xml_response
29
+ filename = File.join(Regentanz.configuration.cache_dir, '..', 'valid_response.xml.erb')
30
+ xmlerb = ERB.new(File.open(filename, 'r') { |file| file.read })
31
+ xmlerb.result
32
+ end
33
+
34
+ # Creates a cache file +filename+ with contents of #invalid_xml_response
35
+ # FIXME this is deprecated with the introduction of Regentanz::Cache::File
36
+ def create_invalid_xml_response(filename)
37
+ File.open(filename, "w+") { |f| f.puts invalid_xml_response }
38
+ end
39
+
40
+ # Stub Net::HTTP.get_response to return a semi-dynamic (ie. current date) xml
41
+ # response-
42
+ def stub_valid_xml_api_response!
43
+ mock_response = mock()
44
+ mock_response.stubs(:body).returns(valid_xml_response)
45
+ Net::HTTP.stubs(:get_response).returns(mock_response)
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
52
+ include Regentanz::TestHelper
@@ -0,0 +1,4 @@
1
+ module Regentanz
2
+ VERSION = "0.2.0"
3
+ end
4
+
data/lib/regentanz.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+ require 'action_mailer'
4
+ require 'regentanz/version'
5
+ require 'regentanz/cache'
6
+ require 'regentanz/configuration'
7
+ require 'regentanz/configurator'
8
+ require 'regentanz/callbacks'
9
+ require 'regentanz/astronomy'
10
+ require 'regentanz/conditions'
11
+ require 'regentanz/parser'
12
+ require 'regentanz/google_weather'
data/regentanz.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "regentanz/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "regentanz"
7
+ s.version = Regentanz::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Carsten Zimmermann"]
10
+ s.email = ["cz@aegisnet.de"]
11
+ s.homepage = ""
12
+ s.summary = %q{Library to access the Google Weather API}
13
+ s.description = %q{Library to access the Google Weather API}
14
+
15
+ s.rubyforge_project = "regentanz"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'actionmailer', '~> 3.0.10'
23
+ s.add_dependency 'activesupport', '~> 3.0.10'
24
+
25
+ s.add_development_dependency 'rake'
26
+ s.add_development_dependency 'mocha'
27
+ s.add_development_dependency 'bundler'
28
+ s.add_development_dependency 'redgreen'
29
+ s.add_development_dependency 'factory_girl'
30
+
31
+ end
data/test/factories.rb ADDED
@@ -0,0 +1,8 @@
1
+ module Regentanz
2
+ module Test
3
+ Factory.define :google_weather, :class => Regentanz::GoogleWeather, :default_strategy => :build do |f|
4
+ f.location "Testhausen"
5
+ f.cache_id "test"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ class SupportMailer
2
+
3
+ def self.deliver_weather_retry_marker_notification!(weather_obj, mode)
4
+ ActionMailer::Base.deliveries << "fake mail"
5
+ end
6
+
7
+ end
@@ -0,0 +1 @@
1
+ *.xml
@@ -0,0 +1,26 @@
1
+ <?xml version="1.0"?>
2
+ <xml_api_reply version="1">
3
+ <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" >
4
+ <forecast_information>
5
+ <city data="Berlin, Berlin"/><postal_code data="Berlin,Germany"/>
6
+ <latitude_e6 data=""/>
7
+ <longitude_e6 data=""/>
8
+ <forecast_date data="<%= Date.today.strftime("%Y-%m-%d") %>"/>
9
+ <current_date_time data="<%= 5.minutes.ago.utc.strftime("%Y-%m-%d %H:%M:00") %> +0000"/>
10
+ <unit_system data="SI"/>
11
+ </forecast_information>
12
+ <current_conditions>
13
+ <condition data="Klar"/><temp_f data="77"/>
14
+ <temp_c data="25"/>
15
+ <humidity data="Feuchtigkeit: 57 %"/>
16
+ <icon data="/ig/images/weather/sunny.gif"/>
17
+ <wind_condition data="Wind: W mit 24 km/h"/>
18
+ </current_conditions>
19
+ <forecast_conditions>
20
+ <day_of_week data="Do."/><low data="16"/>
21
+ <high data="31"/>
22
+ <icon data="/ig/images/weather/chance_of_rain.gif"/>
23
+ <condition data="Vereinzelt Regen"/>
24
+ </forecast_conditions>
25
+ </weather>
26
+ </xml_api_reply>
@@ -0,0 +1,18 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ require "test/unit"
5
+ require "active_support/test_case"
6
+ require 'action_mailer/test_helper'
7
+ Bundler.require(:default, :development)
8
+ require 'test/factories'
9
+
10
+ # FIXME move SupportMailer into callbacks
11
+ require File.join(File.dirname(__FILE__), 'support', 'support_mailer')
12
+
13
+ # Configure for test mode
14
+ require 'regentanz/test_helper'
15
+ setup_regentanz_test_configuration! do |config|
16
+ config.cache_dir = File.expand_path(File.join(File.dirname(__FILE__), '', 'support', 'tmp'))
17
+ config.retry_marker = File.expand_path(File.join(File.dirname(__FILE__), 'support', 'tmp', 'test_api_retry.txt'))
18
+ end
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class AstronomyTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @object = Object.new
7
+ @object.extend Regentanz::Astronomy
8
+ end
9
+
10
+ def test_google_weather_should_include_astronomy
11
+ assert Regentanz::GoogleWeather.included_modules.include?(Regentanz::Astronomy)
12
+ end
13
+
14
+ def test_deg_to_rad
15
+ assert Regentanz::Astronomy.private_instance_methods.include?("deg_to_rad")
16
+ degrees = 42
17
+ assert_equal degrees*Math::PI/180, @object.send(:deg_to_rad, degrees)
18
+ end
19
+
20
+ def test_rad_to_deg
21
+ assert Regentanz::Astronomy.private_instance_methods.include?("rad_to_deg")
22
+ radians = 42
23
+ assert_equal radians*180/Math::PI, @object.send(:rad_to_deg, radians)
24
+ end
25
+
26
+ end
@@ -0,0 +1,53 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+ require 'digest/sha1'
3
+
4
+ class Regentanz::Cache::BaseTest < ActiveSupport::TestCase
5
+
6
+ LINT_METHODS = [:available?, :expire!, :get, :set, :valid?]
7
+
8
+ test "should define public interface for all cache backend" do
9
+ obj = Regentanz::Cache::Base.new
10
+ LINT_METHODS.each do |method|
11
+ assert_respond_to obj, method
12
+ end
13
+ end
14
+
15
+ test "should have check cache backend compatability via lint class method" do
16
+ assert_respond_to Regentanz::Cache::Base, :lint
17
+
18
+ obj = Object.new
19
+ assert !Regentanz::Cache::Base.lint(obj)
20
+ assert !Regentanz::Cache::Base.lint(Object)
21
+
22
+ LINT_METHODS.each do |method|
23
+ Object.any_instance.stubs(method)
24
+ end
25
+ assert Regentanz::Cache::Base.lint(obj)
26
+ assert Regentanz::Cache::Base.lint(Object)
27
+ end
28
+
29
+ test "should have key sanitizer class method" do
30
+ assert_respond_to Regentanz::Cache::Base, :sanitize_key
31
+ key = Digest::SHA1.hexdigest("a test string")
32
+ assert_equal key, Regentanz::Cache::Base.sanitize_key("a test string")
33
+
34
+ assert_not_equal Regentanz::Cache::Base.sanitize_key("a test string"),
35
+ Regentanz::Cache::Base.sanitize_key("another test string")
36
+ end
37
+
38
+ test "should inform about retry state" do
39
+ obj = Regentanz::Cache::Base.new
40
+ assert_respond_to obj, :waiting_for_retry?
41
+ end
42
+
43
+ test "should check if retry wait time is over" do
44
+ obj = Regentanz::Cache::Base.new
45
+ assert_respond_to obj, :unset_retry_state!
46
+ end
47
+
48
+ test "should enter retry state" do
49
+ obj = Regentanz::Cache::Base.new
50
+ assert_respond_to obj, :set_retry_state!
51
+ end
52
+
53
+ end
@@ -0,0 +1,141 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class Regentanz::Cache::FileTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ setup_regentanz_test_configuration!
7
+ end
8
+
9
+ def teardown
10
+ Dir.glob(File.join(Regentanz.configuration.cache_dir, "**", "*")).each { |file| File.unlink(file) }
11
+ end
12
+
13
+ test "should not fail lint" do
14
+ assert Regentanz::Cache::Base.lint(Regentanz::Cache::File)
15
+ assert Regentanz::Cache::Base.lint(Regentanz::Cache::File.new)
16
+ end
17
+
18
+ test "should return filename for key" do
19
+ obj = Regentanz::Cache::File.new
20
+ assert_respond_to obj, :filename
21
+ filename = File.join(Regentanz.configuration.cache_dir, "regentanz_test.xml")
22
+ assert_equal filename, obj.filename("test")
23
+ end
24
+
25
+ test "should create cache file" do
26
+ obj = Regentanz::Cache::File.new
27
+ assert !File.exists?(obj.filename("test"))
28
+ assert obj.set("test", "some cache values")
29
+ assert File.exists?(obj.filename("test"))
30
+ end
31
+
32
+ test "should rescue set from saving errors" do
33
+ File.expects(:open).raises(SystemCallError, "pretend something went wrong")
34
+ obj = Regentanz::Cache::File.new
35
+ assert_nothing_raised do
36
+ assert !obj.set("test", "some cache values")
37
+ end
38
+ end
39
+
40
+ test "available?" do
41
+ obj = Regentanz::Cache::File.new
42
+ assert !obj.available?("test")
43
+
44
+ File.new(obj.filename("test"), "w+").close
45
+ assert obj.available?("test")
46
+ end
47
+
48
+ test "should delete file after expire" do
49
+ obj = Regentanz::Cache::File.new
50
+ assert !obj.expire!("test") # nothing to expire, return false
51
+
52
+ File.new(obj.filename("test"), "w+").close
53
+ assert obj.expire!("test")
54
+ assert !File.exists?(obj.filename("test"))
55
+ end
56
+
57
+ test "should rescue expire from saving errors" do
58
+ File.expects(:delete).raises(SystemCallError, "pretend something went wrong").once
59
+ obj = Regentanz::Cache::File.new
60
+ assert_nothing_raised do
61
+ File.new(obj.filename("test"), "w+").close
62
+ assert !obj.expire!("test")
63
+ end
64
+ end
65
+
66
+ test "should get contents from file" do
67
+ obj = Regentanz::Cache::File.new
68
+
69
+ File.open(obj.filename('test_get'), 'w+') {|file| file.print "cached data" }
70
+ assert obj.available?('test_get')
71
+ assert_equal "cached data", obj.get('test_get')
72
+ # cache not available, return false
73
+ assert_nil obj.get("does not exist")
74
+ end
75
+
76
+ test "should rescue get from reading errors" do
77
+ obj = Regentanz::Cache::File.new
78
+ File.open(obj.filename('test'), 'w+') {|file| file.print "cached data" }
79
+ File.expects(:open).raises(SystemCallError, "pretend something went wrong").once
80
+
81
+ assert_nothing_raised do
82
+ assert !obj.get("test")
83
+ end
84
+ end
85
+
86
+ test "should check validity" do
87
+ obj = Regentanz::Cache::File.new
88
+ assert !obj.valid?('test')
89
+ File.open(obj.filename('test'), 'w+') { |file| file.puts valid_xml_response }
90
+
91
+ # valid_xml_response contains current datestamp,
92
+ # so should be valid on all fronts
93
+ assert obj.valid?('test')
94
+
95
+ # Pretend the file is too old
96
+ Regentanz.configuration.cache_ttl = 0
97
+ assert !obj.valid?('test')
98
+ end
99
+
100
+ test "should rescue valid from REXML errors" do
101
+ obj = Regentanz::Cache::File.new
102
+ File.open(obj.filename('test'), 'w+') { |file| file.puts invalid_xml_response }
103
+ REXML::Document.expects(:new).raises(REXML::ParseException, "pretend something went wrong")
104
+
105
+ assert_nothing_raised do
106
+ assert !obj.valid?('test')
107
+ end
108
+ end
109
+
110
+ # ##############################
111
+ # Retry-state tests
112
+ # ##############################
113
+
114
+ test "should inform about retry state" do
115
+ obj = Regentanz::Cache::File.new
116
+ assert !obj.waiting_for_retry?
117
+
118
+ File.expects(:exists?).with(Regentanz.configuration.retry_marker).returns(true)
119
+ assert obj.waiting_for_retry?
120
+ end
121
+
122
+ test "should check if retry wait time is over" do
123
+ obj = Regentanz::Cache::File.new
124
+ File.new(Regentanz.configuration.retry_marker, "w+").close
125
+ Regentanz.configuration.retry_ttl = 1000.hours.to_i # something incredibly high to warrant retry state
126
+ assert !obj.unset_retry_state! # not waited long enough
127
+
128
+ Regentanz.configuration.retry_ttl = 0
129
+ assert obj.unset_retry_state!
130
+ assert !File.exists?(Regentanz.configuration.retry_marker)
131
+ end
132
+
133
+ test "should enter retry state" do
134
+ obj = Regentanz::Cache::File.new
135
+ assert !File.exists?(Regentanz.configuration.retry_marker)
136
+ assert obj.set_retry_state!
137
+ assert obj.set_retry_state! # subsequent calls return the same
138
+ assert File.exists?(Regentanz.configuration.retry_marker)
139
+ end
140
+
141
+ end
@@ -0,0 +1,27 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class CallbacksTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @object = Object.new
7
+ @object.extend Regentanz::Callbacks
8
+ end
9
+
10
+ def test_should_define_constant
11
+ assert Regentanz::Callbacks::CALLBACKS
12
+ expected_callbacks = [:api_failure_detected, :api_failure_resumed]
13
+ assert_equal expected_callbacks, Regentanz::Callbacks::CALLBACKS
14
+ end
15
+
16
+ def test_google_weather_should_include_callbacks
17
+ assert Regentanz::GoogleWeather.included_modules.include?(Regentanz::Callbacks)
18
+ assert Regentanz::GoogleWeather.included_modules.include?(ActiveSupport::Callbacks)
19
+ end
20
+
21
+ def test_should_define_each_callback_method
22
+ Regentanz::Callbacks::CALLBACKS.each do |callback_method|
23
+ assert @object.private_methods.include?(callback_method.to_s), "#{callback_method} not defined"
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,57 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+ require "tmpdir"
3
+
4
+ class ConfigurationTest < ActiveSupport::TestCase
5
+
6
+ test "should configure Regentanz" do
7
+ assert_respond_to Regentanz, :configure
8
+ assert_respond_to Regentanz, :configuration
9
+ assert_not_nil Regentanz.configuration
10
+
11
+ Regentanz.configure do |config|
12
+ config.do_not_get_weather = true
13
+ end
14
+ assert_not_nil Regentanz.configuration
15
+ assert Regentanz.configuration.do_not_get_weather
16
+ end
17
+
18
+ test "should have configuration" do
19
+ configuration_options = [
20
+ :base_url,
21
+ :cache_backend,
22
+ :cache_dir,
23
+ :cache_prefix,
24
+ :cache_ttl,
25
+ :retry_marker,
26
+ :retry_ttl,
27
+ :do_not_get_weather,
28
+ :suppress_stderr_output
29
+ ]
30
+ assert_equal configuration_options, Regentanz::Configuration::OPTIONS, "Diff: #{configuration_options - Regentanz::Configuration::OPTIONS}"
31
+ obj = Regentanz::Configuration.new
32
+ configuration_options.each do |config_option|
33
+ assert_respond_to obj, config_option
34
+ end
35
+ end
36
+
37
+ test "every DEFAULT_OPTION should have a cattr_accessor" do
38
+ assert_not_nil Regentanz::Configuration::DEFAULT_OPTIONS
39
+ Regentanz::Configuration::DEFAULT_OPTIONS.each do |config_option|
40
+ assert_respond_to Regentanz::Configuration, :"default_#{config_option}"
41
+ assert_not_nil Regentanz::Configuration.send(:"default_#{config_option}")
42
+ end
43
+
44
+ end
45
+
46
+ test "instance should have sane defaults" do
47
+ obj = Regentanz::Configuration.new
48
+ tmpdir = Dir.tmpdir
49
+ assert_equal "http://www.google.com/ig/api", obj.base_url
50
+ assert_equal "#{tmpdir}", obj.cache_dir
51
+ assert_equal "regentanz", obj.cache_prefix
52
+ assert_equal 14400, obj.cache_ttl
53
+ assert_equal 3600, obj.retry_ttl
54
+ assert_equal "#{tmpdir}/regentanz_api_retry.txt", obj.retry_marker
55
+ end
56
+
57
+ end
@@ -0,0 +1,33 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class CurrentConditionTest < ActiveSupport::TestCase
4
+
5
+ test "should define setters and getters" do
6
+ obj = Regentanz::Conditions::Current.new
7
+ [:condition, :style, :icon, :humidity, :wind_condition, :temp_c, :temp_f].each do |attr|
8
+ assert_respond_to obj, attr
9
+ assert_respond_to obj, :"#{attr}="
10
+ end
11
+ end
12
+
13
+ test "should initialize with attributes hash" do
14
+ attributes = {
15
+ "condition" => "Klar",
16
+ "temp_f" => "77",
17
+ "temp_c" => "25",
18
+ "humidity" => "Feuchtigkeit: 57 %",
19
+ "icon" => "http://www.google.com/ig/images/weather/sunny.gif",
20
+ "style" => "sunny",
21
+ "wind_condition" => "Wind: W mit 24 km/h"
22
+ }
23
+ obj = Regentanz::Conditions::Current.new(attributes)
24
+ assert_equal "Klar", obj.condition
25
+ assert_equal 77, obj.temp_f
26
+ assert_equal 25, obj.temp_c
27
+ assert_equal "Feuchtigkeit: 57 %", obj.humidity
28
+ assert_equal "http://www.google.com/ig/images/weather/sunny.gif", obj.icon
29
+ assert_equal "sunny", obj.style
30
+ assert_equal "Wind: W mit 24 km/h", obj.wind_condition
31
+ end
32
+
33
+ end
@@ -0,0 +1,35 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class ForecastConditionTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @object = Regentanz::Conditions::Forecast.new
7
+ end
8
+
9
+ test "should define setters and getters" do
10
+ [:condition, :style, :icon, :day_of_week, :high, :low].each do |attr|
11
+ assert_respond_to @object, attr
12
+ assert_respond_to @object, :"#{attr}="
13
+ end
14
+ end
15
+
16
+ test "should initialize with attributes hash" do
17
+ attributes = {
18
+ "high" => "31",
19
+ "condition" => "Vereinzelt Regen",
20
+ "icon" => "http://www.google.com/ig/images/weather/chance_of_rain.gif",
21
+ "day_of_week" =>"Do.",
22
+ "low" => "16",
23
+ "style" => "chance-of-rain"
24
+ }
25
+
26
+ obj = Regentanz::Conditions::Forecast.new(attributes)
27
+ assert_equal 31, obj.high
28
+ assert_equal "Vereinzelt Regen", obj.condition
29
+ assert_equal "http://www.google.com/ig/images/weather/chance_of_rain.gif", obj.icon
30
+ assert_equal "Do.", obj.day_of_week
31
+ assert_equal 16, obj.low
32
+ assert_equal "chance-of-rain", obj.style
33
+ end
34
+
35
+ end