spec/weather_spec.rb in barometer-0.8.0 vs spec/weather_spec.rb in barometer-0.9.0
- old
+ new
@@ -1,440 +1,260 @@
-require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+require 'spec_helper'
-describe Barometer::Weather do
+module Barometer
+ describe Weather do
+ def fake_response(args)
+ success = args.delete(:success?)
+ weight = args.delete(:weight) || 1
- describe "when initialized" do
-
- before(:each) do
- @weather = Barometer::Weather.new
+ double(:response,
+ success?: success.nil? ? true : success,
+ weight: weight,
+ current: double(:current, args)
+ )
end
- it "responds to measurements (and sets default value)" do
- @weather.measurements.should == []
- end
+ let(:weather) { Weather.new }
- it "responds to current" do
- @weather.respond_to?("current").should be_true
+ describe ".new" do
+ specify { expect( weather.responses ).to be_empty }
end
- it "responds to forecast" do
- @weather.respond_to?("forecast").should be_true
- end
+ describe "#source" do
+ let(:bar_response) { double(:response, source: :bar) }
+ let(:foo_response) { double(:response, source: :foo) }
- it "responds to today" do
- @weather.respond_to?("today").should be_true
- end
+ before { weather.responses = [foo_response, bar_response] }
- it "responds to tommorrow" do
- @weather.respond_to?("tomorrow").should be_true
- end
-
- it "responds to for" do
- @weather.respond_to?("for").should be_true
- end
-
- end
-
- describe "with measurements" do
-
- before(:each) do
- @weather = Barometer::Weather.new
- @wunderground = Barometer::Measurement.new(:wunderground)
- @wunderground.stub!(:success).and_return(true)
- @wunderground.stub!(:success?).and_return(true)
- @yahoo = Barometer::Measurement.new(:yahoo)
- @yahoo.stub!(:success).and_return(true)
- @yahoo.stub!(:success?).and_return(true)
- @google = Barometer::Measurement.new(:google)
- @weather.measurements << @wunderground
- @weather.measurements << @yahoo
- @weather.measurements << @google
- end
-
- it "retrieves a source measurement" do
- lambda { @weather.source(1) }.should raise_error(ArgumentError)
- lambda { @weather.source("valid") }.should_not raise_error(ArgumentError)
- lambda { @weather.source(:valid) }.should_not raise_error(ArgumentError)
- @weather.source(:does_not_exist).should be_nil
- @weather.source(:wunderground).should == @wunderground
- end
-
- it "lists the sources of measurements (that were successful)" do
- sources = @weather.sources
- sources.should_not be_nil
- @wunderground.success?.should be_true
- sources.include?(:wunderground).should be_true
- @yahoo.success?.should be_true
- sources.include?(:yahoo).should be_true
- @google.success?.should be_false
- sources.include?(:google).should be_false
- end
-
- it "returns the default source" do
- @weather.default.should == @wunderground
- end
-
- end
-
- describe "when calculating averages" do
-
- before(:each) do
- @weather = Barometer::Weather.new
- @wunderground = Barometer::Measurement.new(:wunderground)
- @wunderground.current = Barometer::Measurement::Result.new
- @wunderground.stub!(:success).and_return(true)
- @wunderground.stub!(:success?).and_return(true)
- @yahoo = Barometer::Measurement.new(:yahoo)
- @yahoo.current = Barometer::Measurement::Result.new
- @yahoo.stub!(:success).and_return(true)
- @yahoo.stub!(:success?).and_return(true)
- @google = Barometer::Measurement.new(:google)
- @weather.measurements << @wunderground
- @weather.measurements << @yahoo
- @weather.measurements << @google
- end
-
- it "doesn't include nil values" do
- @weather.source(:wunderground).current.temperature = Data::Temperature.new
- @weather.source(:wunderground).current.temperature.c = 10
-
- @weather.temperature.c.should == 10
-
- @weather.source(:yahoo).current.temperature = Data::Temperature.new
- @weather.source(:yahoo).current.temperature.c = nil
-
- @weather.temperature.c.should == 10
- end
-
- it "respects the measurement weight" do
- @weather.source(:wunderground).current.temperature = Data::Temperature.new
- @weather.source(:wunderground).current.temperature.c = 10
- @weather.source(:yahoo).current.temperature = Data::Temperature.new
- @weather.source(:yahoo).current.temperature.c = 4
-
- @weather.measurements.first.weight = 2
-
- @weather.temperature.c.should == 8
- end
-
- describe "for temperature" do
-
- before(:each) do
- @weather.source(:wunderground).current.temperature = Data::Temperature.new
- @weather.source(:wunderground).current.temperature.c = 10
- @weather.source(:yahoo).current.temperature = Data::Temperature.new
- @weather.source(:yahoo).current.temperature.c = 6
+ it "returns the response for the specified source" do
+ expect( weather.source(:foo) ).to eq foo_response
end
- it "returns averages" do
- @weather.temperature.c.should == 8
+ it "returns nil when nothing is found" do
+ expect( weather.source(:baz) ).to be_nil
end
-
- it "returns default when disabled" do
- @weather.temperature(false).c.should == 10
- end
-
end
- describe "for wind" do
-
- before(:each) do
- @weather.source(:wunderground).current.wind = Data::Speed.new
- @weather.source(:wunderground).current.wind.kph = 10
- @weather.source(:yahoo).current.wind = Data::Speed.new
- @weather.source(:yahoo).current.wind.kph = 6
+ describe "#success?" do
+ it "returns true when a response is successful" do
+ response_one = double(:response, success?: false)
+ response_two = double(:response, success?: true)
+ weather.responses = [response_one, response_two]
+ expect( weather ).to be_success
end
- it "returns averages" do
- @weather.wind.kph.should == 8
+ it "returns false when no responses are successful" do
+ response_one = double(:response, success?: false)
+ response_two = double(:response, success?: false)
+ weather.responses = [response_one, response_two]
+ expect( weather ).not_to be_success
end
-
- it "returns default when disabled" do
- @weather.wind(false).kph.should == 10
- end
-
end
- describe "for humidity" do
+ describe "#current" do
+ it "returns the current response for the first successful response" do
+ current_two = double(:current)
+ response_one = double(:response, success?: false)
+ response_two = double(:response, success?: true, current: current_two)
+ weather.responses = [response_one, response_two]
- before(:each) do
- @weather.source(:wunderground).current.humidity = 10
- @weather.source(:yahoo).current.humidity = 6
+ expect( weather.current ).to eq current_two
end
+ end
- it "returns averages" do
- @weather.humidity.should == 8
- end
+ describe "#forecast" do
+ it "returns the forecast response for the first successful response" do
+ forecast_two = double(:forecast)
+ response_one = double(:response, success?: false)
+ response_two = double(:response, success?: true, forecast: forecast_two)
+ weather.responses = [response_one, response_two]
- it "returns default when disabled" do
- @weather.humidity(false).should == 10
+ expect( weather.forecast ).to eq forecast_two
end
-
end
- describe "for pressure" do
+ describe "#today" do
+ it "returns the first forecast response for the first successful response" do
+ today = double(:forecast)
+ tommorrow = double(:forecast)
+ response_one = double(:response, success?: false)
+ response_two = double(:response, success?: true, forecast: [today, tommorrow])
+ weather.responses = [response_one, response_two]
- before(:each) do
- @weather.source(:wunderground).current.pressure = Data::Pressure.new
- @weather.source(:wunderground).current.pressure.mb = 10
- @weather.source(:yahoo).current.pressure = Data::Pressure.new
- @weather.source(:yahoo).current.pressure.mb = 6
+ expect( weather.today ).to eq today
end
+ end
- it "returns averages" do
- @weather.pressure.mb.should == 8
- end
+ describe "#tomorrow" do
+ it "returns the second forecast response for the first successful response" do
+ today = double(:forecast)
+ tommorrow = double(:forecast)
+ response_one = double(:response, success?: false)
+ response_two = double(:response, success?: true, forecast: [today, tommorrow])
+ weather.responses = [response_one, response_two]
- it "returns default when disabled" do
- @weather.pressure(false).mb.should == 10
+ expect( weather.tomorrow ).to eq tommorrow
end
-
end
- describe "for dew_point" do
+ describe "#for" do
+ it "delegates to the first successful response" do
+ response_one = double(:response, success?: false, for: nil)
+ response_two = double(:response, success?: true, for: nil)
+ weather.responses = [response_one, response_two]
- before(:each) do
- @weather.source(:wunderground).current.dew_point = Data::Temperature.new
- @weather.source(:wunderground).current.dew_point.c = 10
- @weather.source(:yahoo).current.dew_point = Data::Temperature.new
- @weather.source(:yahoo).current.dew_point.c = 6
- end
+ query = build_query
+ weather.for(query)
- it "returns averages" do
- @weather.dew_point.c.should == 8
+ expect( response_two ).to have_received(:for).with(query)
end
-
- it "returns default when disabled" do
- @weather.dew_point(false).c.should == 10
- end
-
end
- describe "for heat_index" do
+ describe "#temperature" do
+ let(:response_one) { fake_response(temperature: Data::Temperature.new(:metric, 20)) }
+ let(:response_two) { fake_response(temperature: Data::Temperature.new(:metric, 30)) }
- before(:each) do
- @weather.source(:wunderground).current.heat_index = Data::Temperature.new
- @weather.source(:wunderground).current.heat_index.c = 10
- @weather.source(:yahoo).current.heat_index = Data::Temperature.new
- @weather.source(:yahoo).current.heat_index.c = 6
- end
+ before { weather.responses = [response_one, response_two] }
- it "returns averages" do
- @weather.heat_index.c.should == 8
+ it "returns an average temeprature" do
+ expect( weather.temperature ).to eq Data::Temperature.new(:metric, 25.0)
end
- it "returns default when disabled" do
- @weather.heat_index(false).c.should == 10
+ it "returns nil when there is no valid data" do
+ response_one.stub(success?: false)
+ response_two.stub(success?: false)
+ expect( weather.temperature ).to be_nil
end
- end
-
- describe "for wind_chill" do
-
- before(:each) do
- @weather.source(:wunderground).current.wind_chill = Data::Temperature.new
- @weather.source(:wunderground).current.wind_chill.c = 10
- @weather.source(:yahoo).current.wind_chill = Data::Temperature.new
- @weather.source(:yahoo).current.wind_chill.c = 6
+ it "excludes unsuccessful responses" do
+ response_three = fake_response(success?: false, temperature: Data::Temperature.new(:metric, 10))
+ weather.responses << response_three
+ expect( weather.temperature ).to eq Data::Temperature.new(:metric, 25.0)
end
- it "returns averages" do
- @weather.wind_chill.c.should == 8
+ it "excludes nil values" do
+ response_three = fake_response(temperature: nil)
+ weather.responses << response_three
+ expect( weather.temperature ).to eq Data::Temperature.new(:metric, 25.0)
end
- it "returns default when disabled" do
- @weather.wind_chill(false).c.should == 10
+ it "returns a weighted average temeprature" do
+ response_one.stub(weight: 3)
+ response_two.stub(weight: 1)
+ expect( weather.temperature ).to eq Data::Temperature.new(:metric, 22.5)
end
- end
-
- describe "for visibility" do
-
- before(:each) do
- @weather.source(:wunderground).current.visibility = Data::Distance.new
- @weather.source(:wunderground).current.visibility.km = 10
- @weather.source(:yahoo).current.visibility = Data::Distance.new
- @weather.source(:yahoo).current.visibility.km = 6
+ it "respects response units" do
+ response_two.current.stub(temperature: Data::Temperature.new(:imperial, 68.0))
+ expect( weather.temperature.to_f ).to eq 20.0
end
- it "returns averages" do
- @weather.visibility.km.should == 8
- end
+ it "respects weather units" do
+ weather = Weather.new(:imperial)
+ weather.responses = [response_one, response_two]
- it "returns default when disabled" do
- @weather.visibility(false).km.should == 10
+ expect( weather.temperature.to_f ).to eq 77.0
end
-
end
- end
+ describe "#humidity" do
+ let(:response_one) { fake_response(humidity: 20.0) }
+ let(:response_two) { fake_response(humidity: 30.0) }
- describe "when answering the simple questions," do
+ before { weather.responses = [response_one, response_two] }
- before(:each) do
- @weather = Barometer::Weather.new
- @now = Data::LocalDateTime.parse("2:05 pm")
- end
-
- describe "windy?" do
-
- # it "requires time as a Data::LocalTime object" do
- # #lambda { @weather.windy?(1,"a") }.should raise_error(ArgumentError)
- # lambda { @weather.windy?(1,@now) }.should_not raise_error(ArgumentError)
- # end
-
- it "requires threshold as a number" do
- lambda { @weather.windy?(@now,"a") }.should raise_error(ArgumentError)
- lambda { @weather.windy?(@now,1) }.should_not raise_error(ArgumentError)
- lambda { @weather.windy?(@now,1.1) }.should_not raise_error(ArgumentError)
+ it "returns an average humidity" do
+ expect( weather.humidity ).to eq 25.0
end
- it "returns nil when no measurements" do
- @weather.measurements.should be_empty
- @weather.windy?.should be_nil
+ it "returns nil when there is no valid data" do
+ response_one.stub(success?: false)
+ response_two.stub(success?: false)
+ expect( weather.humidity ).to be_nil
end
- it "returns true if a measurement returns true" do
- wunderground = Barometer::Measurement.new(:wunderground)
- wunderground.stub!(:success).and_return(true)
- wunderground.stub!(:success?).and_return(true)
- @weather.measurements << wunderground
- @weather.measurements.each { |m| m.stub!(:windy?).and_return(true) }
- @weather.windy?.should be_true
+ it "excludes unsuccessful responses" do
+ response_three = fake_response(success?: false, humidity: 10.0)
+ weather.responses << response_three
+ expect( weather.humidity ).to eq 25.0
end
- it "returns false if a measurement returns false" do
- wunderground = Barometer::Measurement.new(:wunderground)
- wunderground.stub!(:success).and_return(true)
- wunderground.stub!(:success?).and_return(true)
- @weather.measurements << wunderground
- @weather.measurements.each { |m| m.stub!(:windy?).and_return(false) }
- @weather.windy?.should be_false
+ it "excludes nil values" do
+ response_three = fake_response(humidity: nil)
+ weather.responses << response_three
+ expect( weather.humidity ).to eq 25.0
end
+ it "returns a weighted average humidity" do
+ response_one.stub(weight: 3)
+ response_two.stub(weight: 1)
+ expect( weather.humidity ).to eq 22.5
+ end
end
- describe "wet?" do
+ describe "#dew_point" do
+ let(:response_one) { fake_response(dew_point: Data::Temperature.new(:metric, 20)) }
+ let(:response_two) { fake_response(dew_point: Data::Temperature.new(:metric, 30)) }
- it "requires threshold as a number" do
- lambda { @weather.wet?(@now,"a") }.should raise_error(ArgumentError)
- lambda { @weather.wet?(@now,1) }.should_not raise_error(ArgumentError)
- lambda { @weather.wet?(@now,1.1) }.should_not raise_error(ArgumentError)
- end
+ before { weather.responses = [response_one, response_two] }
- # it "requires time as a Data::LocalTime object" do
- # #lambda { @weather.wet?(1,"a") }.should raise_error(ArgumentError)
- # lambda { @weather.wet?(1,@now) }.should_not raise_error(ArgumentError)
- # end
-
- it "returns nil when no measurements" do
- @weather.measurements.should be_empty
- @weather.wet?.should be_nil
+ it "returns an average dew_point" do
+ expect( weather.dew_point ).to eq Data::Temperature.new(:metric, 25.0)
end
+ end
- it "returns true if a measurement returns true" do
- wunderground = Barometer::Measurement.new(:wunderground)
- wunderground.stub!(:success).and_return(true)
- wunderground.stub!(:success?).and_return(true)
- @weather.measurements << wunderground
- @weather.measurements.each { |m| m.stub!(:wet?).and_return(true) }
- @weather.wet?.should be_true
- end
+ describe "#heat_index" do
+ let(:response_one) { fake_response(heat_index: Data::Temperature.new(:metric, 20)) }
+ let(:response_two) { fake_response(heat_index: Data::Temperature.new(:metric, 30)) }
- it "returns false if a measurement returns false" do
- wunderground = Barometer::Measurement.new(:wunderground)
- wunderground.stub!(:success).and_return(true)
- wunderground.stub!(:success?).and_return(true)
- @weather.measurements << wunderground
- @weather.measurements.each { |m| m.stub!(:wet?).and_return(false) }
- @weather.wet?.should be_false
- end
+ before { weather.responses = [response_one, response_two] }
+ it "returns an average heat_index" do
+ expect( weather.heat_index ).to eq Data::Temperature.new(:metric, 25.0)
+ end
end
- describe "day? and night?" do
+ describe "#wind_chill" do
+ let(:response_one) { fake_response(wind_chill: Data::Temperature.new(:metric, 20)) }
+ let(:response_two) { fake_response(wind_chill: Data::Temperature.new(:metric, 30)) }
- it "requires time as a Data::LocalTime object" do
- #lambda { @weather.day?("a") }.should raise_error(ArgumentError)
- lambda { @weather.day?(@now) }.should_not raise_error(ArgumentError)
- end
+ before { weather.responses = [response_one, response_two] }
- it "requires time as a Data::LocalTime object" do
- #lambda { @weather.night?("a") }.should raise_error(ArgumentError)
- lambda { @weather.night?(@now) }.should_not raise_error(ArgumentError)
+ it "returns an average wind_chill" do
+ expect( weather.wind_chill ).to eq Data::Temperature.new(:metric, 25.0)
end
+ end
- it "returns nil when no measurements" do
- @weather.measurements.should be_empty
- @weather.day?.should be_nil
- @weather.night?.should be_nil
- end
+ describe "#pressure" do
+ let(:response_one) { fake_response(pressure: Data::Pressure.new(:metric, 20)) }
+ let(:response_two) { fake_response(pressure: Data::Pressure.new(:metric, 30)) }
- it "returns true if a measurement returns true (night is opposite)" do
- wunderground = Barometer::Measurement.new(:wunderground)
- wunderground.stub!(:success).and_return(true)
- wunderground.stub!(:success?).and_return(true)
- @weather.measurements << wunderground
- @weather.measurements.each { |m| m.stub!(:day?).and_return(true) }
- @weather.day?.should be_true
- @weather.night?.should be_false
- end
+ before { weather.responses = [response_one, response_two] }
- it "returns false if a measurement returns false (night is opposite)" do
- wunderground = Barometer::Measurement.new(:wunderground)
- wunderground.stub!(:success).and_return(true)
- wunderground.stub!(:success?).and_return(true)
- @weather.measurements << wunderground
- @weather.measurements.each { |m| m.stub!(:day?).and_return(false) }
- @weather.day?.should be_false
- @weather.night?.should be_true
+ it "returns an average pressure" do
+ expect( weather.pressure ).to eq Data::Pressure.new(:metric, 25.0)
end
-
end
- describe "sunny?" do
+ describe "#visibility" do
+ let(:response_one) { fake_response(visibility: Data::Distance.new(:metric, 20)) }
+ let(:response_two) { fake_response(visibility: Data::Distance.new(:metric, 30)) }
- it "requires time as a Data::LocalTime object" do
- #lambda { @weather.sunny?("a") }.should raise_error(ArgumentError)
- lambda { @weather.sunny?(@now) }.should_not raise_error(ArgumentError)
- end
+ before { weather.responses = [response_one, response_two] }
- it "returns nil when no measurements" do
- @weather.measurements.should be_empty
- @weather.sunny?.should be_nil
+ it "returns an average visibility" do
+ expect( weather.visibility ).to eq Data::Distance.new(:metric, 25.0)
end
+ end
- it "returns true if a measurement returns true" do
- wunderground = Barometer::Measurement.new(:wunderground)
- wunderground.stub!(:success).and_return(true)
- wunderground.stub!(:success?).and_return(true)
- @weather.measurements << wunderground
- @weather.measurements.each { |m| m.stub!(:day?).and_return(true) }
- @weather.measurements.each { |m| m.stub!(:sunny?).and_return(true) }
- @weather.sunny?.should be_true
- end
+ describe "#wind" do
+ let(:response_one) { fake_response(wind: Data::Vector.new(:metric, 20)) }
+ let(:response_two) { fake_response(wind: Data::Vector.new(:metric, 30)) }
- it "returns false if a measurement returns false" do
- wunderground = Barometer::Measurement.new(:wunderground)
- wunderground.stub!(:success).and_return(true)
- wunderground.stub!(:success?).and_return(true)
- @weather.measurements << wunderground
- @weather.measurements.each { |m| m.stub!(:day?).and_return(true) }
- @weather.measurements.each { |m| m.stub!(:sunny?).and_return(false) }
- @weather.sunny?.should be_false
- end
+ before { weather.responses = [response_one, response_two] }
- it "returns false if night time" do
- wunderground = Barometer::Measurement.new(:wunderground)
- wunderground.stub!(:success).and_return(true)
- wunderground.stub!(:success?).and_return(true)
- @weather.measurements << wunderground
- @weather.measurements.each { |m| m.stub!(:sunny?).and_return(true) }
- @weather.measurements.each { |m| m.stub!(:day?).and_return(false) }
- @weather.sunny?.should be_false
+ it "returns an average wind" do
+ expect( weather.wind ).to eq Data::Vector.new(:metric, 25.0)
end
-
end
-
end
-
end