greyhawkweather 0.0.6 → 0.0.7

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 (53) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +28 -0
  5. data/History.txt +5 -0
  6. data/Manifest.txt +16 -14
  7. data/Rakefile +10 -22
  8. data/bin/greyweathergen +6 -2
  9. data/greyhawkweather.gemspec +33 -0
  10. data/lib/baselinedata.rb +1 -3
  11. data/lib/greyhawkweather.rb +2 -3
  12. data/lib/greyhawkweather/version.rb +4 -0
  13. data/lib/greyhawkweathergenerator.rb +4 -6
  14. data/lib/options.rb +15 -0
  15. data/lib/precipitationoccurance.rb +8 -4
  16. data/lib/singledayweather.rb +11 -3
  17. data/lib/skyconditions.rb +1 -1
  18. data/lib/temperaturerange.rb +10 -2
  19. data/lib/util/dieroller.rb +3 -3
  20. data/lib/weathergenerator.rb +15 -9
  21. data/lib/wind.rb +3 -1
  22. data/spec/acceptance_spec.rb +52 -0
  23. data/spec/dieroller_spec.rb +22 -0
  24. data/spec/latitude_spec.rb +25 -0
  25. data/spec/month_spec.rb +34 -0
  26. data/spec/options_spec.rb +25 -0
  27. data/spec/precipation_spec.rb +23 -0
  28. data/spec/precipitation_occurance_spec.rb +114 -0
  29. data/spec/singledayweather_spec.rb +44 -0
  30. data/spec/sky_conditions_spec.rb +20 -0
  31. data/spec/spec_helper.rb +22 -0
  32. data/spec/temperature_range_spec.rb +27 -0
  33. data/spec/weathergenerator_spec.rb +63 -0
  34. data/spec/wind_spec.rb +8 -0
  35. data/todo.org +3 -2
  36. metadata +67 -80
  37. data.tar.gz.sig +0 -1
  38. data/.gemtest +0 -0
  39. data/test/rollers/avgroller.rb +0 -7
  40. data/test/rollers/riggedroller.rb +0 -11
  41. data/test/test_acceptance.rb +0 -36
  42. data/test/test_dieroller.rb +0 -30
  43. data/test/test_greyhawkweather.rb +0 -11
  44. data/test/test_helper.rb +0 -3
  45. data/test/test_month.rb +0 -36
  46. data/test/test_precipitation.rb +0 -26
  47. data/test/test_precipitation_occurance.rb +0 -93
  48. data/test/test_singledayweather.rb +0 -61
  49. data/test/test_sky_conditions.rb +0 -23
  50. data/test/test_temperature_range.rb +0 -30
  51. data/test/test_weather_generator.rb +0 -59
  52. data/test/test_wind.rb +0 -11
  53. metadata.gz.sig +0 -1
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ require 'util/dieroller'
3
+
4
+ describe DieRoller do
5
+ it "should use Kernel::rand" do
6
+ subject.stub(:rand).and_return 0
7
+ subject.should_receive(:rand).with(6)
8
+ subject.roll(6)
9
+ end
10
+
11
+ it "should return random number +1" do
12
+ subject.stub(:rand).and_return 0
13
+ subject.should_receive :rand
14
+ subject.roll(6).should == 1
15
+ end
16
+
17
+ it "should apply modifier if given" do
18
+ subject.stub(:rand).and_return 1
19
+ subject.roll(6, 2).should equal 4
20
+ subject.roll(6, -3).should == -1
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require 'singledayweather'
3
+ require 'util/dieroller'
4
+
5
+ describe "Base temperature modified by latitude" do
6
+ let(:month) {
7
+ month = mock(:Month).as_null_object
8
+ month.stub(:temp_range).and_return((10..20))
9
+ month
10
+ }
11
+
12
+ let(:roller) {
13
+ rigged_roller_mock 10
14
+ }
15
+
16
+ it "should increase base temp by 2 degrees Farenheit for each degree latitude below 40" do
17
+ weather = SingleDayWeather.new(month, roller, PrecipitationOccurance.new, nil, :plains, 30)
18
+ weather.temperature_range.should == (-10..0)
19
+ end
20
+
21
+ it "should decrease base temp by 2 degrees Farenheit for each degree latitude above 40" do
22
+ weather = SingleDayWeather.new(month, roller, PrecipitationOccurance.new, nil, :plains, 50)
23
+ weather.temperature_range.should == (30..40)
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'month'
3
+
4
+ describe Month do
5
+ it "uses sky condition data to determine current conditions" do
6
+ month = Month.new(nil, SkyConditions.new((0..34), (35..65), (66..100)))
7
+ month.sky_conditions(make_roller(25)).should eq(:clear)
8
+ month.sky_conditions(make_roller(50)).should eq(:partly_cloudy)
9
+ month.sky_conditions(make_roller(75)).should eq(:cloudy)
10
+ end
11
+
12
+ it "uses temp range data to determine current conditions" do
13
+ month = Month.new(TemperatureRange.new(10, [8, 2], [20, 5]), nil)
14
+ month.temp_range(make_roller(5)).should == (0..17)
15
+ end
16
+
17
+ it "handles record high" do
18
+ month = Month.new(TemperatureRange.new(10, [8, 2], [20, 5]), nil)
19
+ month.temp_range(make_roller(1), :high).should == (14..23)
20
+ end
21
+
22
+ it "determines precipitation" do
23
+ month = Month.new(nil, nil, 50)
24
+ month.has_precipitation(make_roller(10)).should be_true
25
+ month.has_precipitation(make_roller(70)).should be_false
26
+ end
27
+
28
+ private
29
+ def make_roller(roll)
30
+ roller = mock(:DieRoller)
31
+ roller.stub(:roll) { |n, m| roll + (m || 0)}
32
+ roller
33
+ end
34
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require 'options'
3
+
4
+ describe 'WeatherGeneratorOptions' do
5
+ describe 'defaults' do
6
+ subject { WeatherGeneratorOptions.new }
7
+ its(:month) { should == 1 }
8
+ its(:num_days) { should == 28 }
9
+ its(:terrain) { should == :plains }
10
+ its(:dieroller) { should be_instance_of(DieRoller) }
11
+ end
12
+
13
+ describe 'overriding defaults' do
14
+ class SpecialDieRoller < DieRoller
15
+ end
16
+ subject { WeatherGeneratorOptions.new({:month => 4,
17
+ :num_days => 10,
18
+ :terrain => :hills,
19
+ :dieroller => SpecialDieRoller.new})}
20
+ its(:month) { should == 4 }
21
+ its(:num_days) { should == 10 }
22
+ its(:terrain) { should == :hills }
23
+ its(:dieroller) { should be_instance_of(SpecialDieRoller) }
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ require 'precipitation'
3
+ require 'precipitationinfo'
4
+
5
+ describe Precipitation do
6
+ it "has rainbow" do
7
+ precip = Precipitation.new(PrecipitationInfo.create_from_data({:name => "foo", :chance_of_rainbow => 30}),
8
+ rigged_roller_mock(10))
9
+ precip.rainbow?.should be_true
10
+ end
11
+
12
+ it "has no rainbow" do
13
+ precip = Precipitation.new(PrecipitationInfo.create_from_data({:name => "foo", :chance_of_rainbow => 30}),
14
+ rigged_roller_mock(40))
15
+ precip.rainbow?.should be_false
16
+ end
17
+
18
+ it "has no rainbow if there is no chance of rainbow" do
19
+ precip = Precipitation.new(PrecipitationInfo.create_from_data({ :name => "foo", :chance_of_rainbow => 0}),
20
+ rigged_roller_mock(0))
21
+ precip.rainbow?.should be_false
22
+ end
23
+ end
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+ require 'precipitationoccurance'
3
+
4
+ describe PrecipitationOccurance do
5
+ it "returns array of precipitation" do
6
+ roller = make_roller(13)
7
+ precip_occur = PrecipitationOccurance.new({(0..20) => mock(:PrecipitationInfo).as_null_object,
8
+ (21..100) => mock(:PrecipitationInfo).as_null_object})
9
+ precip_occur.type(roller).should be_instance_of Array
10
+ precip_occur.type(roller)[0].should be_instance_of Precipitation
11
+ end
12
+
13
+ it "determines precipitation" do
14
+ snowstorm = create_test_precipitation(:light_snowstorm)
15
+ rainstorm = create_test_precipitation(:light_rainstorm)
16
+
17
+ precip_occur = PrecipitationOccurance.new({(0..20) => snowstorm,
18
+ (21..100) => rainstorm})
19
+ { 13 => :light_snowstorm,
20
+ 57 => :light_rainstorm
21
+ }.each_pair { |roll, precip|
22
+ precip_occur.type(make_roller(roll))[0].name.should == precip
23
+ }
24
+ end
25
+
26
+ it "loads from file" do
27
+ precip_occur = PrecipitationOccurance.load("data/precipitationoccurance.yml")
28
+ precip_occur.type(make_roller(22))[0].name.should == "Sleetstorm"
29
+ end
30
+
31
+ it "defaults to null precipitation" do
32
+ PrecipitationOccurance.new.type(make_roller(13))[0].name.should == NullPrecipitationInfo.new.name
33
+ end
34
+
35
+ it "checks for and computes continuing precipitation" do
36
+ snowstorm = create_test_precipitation(:light_snowstorm)
37
+ rainstorm = create_test_precipitation(:light_rainstorm)
38
+ precip_occur = PrecipitationOccurance.new({(0..20) => snowstorm,
39
+ (21..100) => rainstorm})
40
+ precip_occur.type(make_roller(35, 5, 1, 5, 10, 5, 5, 100)).map{ |p| p.name }.should ==
41
+ [:light_rainstorm, :light_snowstorm, :light_rainstorm, :light_rainstorm]
42
+ end
43
+
44
+ it "checks terrain for precipitation" do
45
+ precip = mock(:PrecipitationInfo)
46
+ precip.stub(:not_allowed_in).and_return([:desert])
47
+
48
+ precip_occur = PrecipitationOccurance.new({ (0..20) => precip})
49
+ precip_occur.type(make_roller(10), nil, :desert).first.name.should == NullPrecipitationInfo.new.name
50
+ end
51
+
52
+ it "does no reroll if temp_range is ok" do
53
+ precip = create_test_precipitation(:foo, 0, [10,50])
54
+ precip_occur = PrecipitationOccurance.new({(0..20) => precip})
55
+
56
+ roller = make_roller(10)
57
+ roller.should_receive(:roll).exactly(1)
58
+
59
+ precip_occur.type(roller, (20..40))
60
+ end
61
+
62
+ it "rerolls if temp is too low" do
63
+ precip = create_test_precipitation(:foo, 0, [20,20])
64
+ precip_occur = PrecipitationOccurance.new({(0..20) => precip})
65
+
66
+ roller = make_roller(10)
67
+ roller.should_receive(:roll).exactly(2)
68
+
69
+ precip_occur.type(roller, (0..10))
70
+ end
71
+
72
+ it "rerolls if temp is too high" do
73
+ precip = create_test_precipitation(:foo, 0, [20,20])
74
+ precip_occur = PrecipitationOccurance.new({(0..20) => precip})
75
+
76
+ roller = make_roller(10)
77
+ roller.should_receive(:roll).exactly(2)
78
+
79
+ precip_occur.type(roller, (50..60))
80
+
81
+ end
82
+
83
+ it "checks temp ranges for continuing weather" do
84
+ precipcold = create_test_precipitation(:cold, 0, [20,20])
85
+ precipwarm = create_test_precipitation(:warm, 10, [30,30])
86
+
87
+ precip_occur = PrecipitationOccurance.new({(0..20) => precipcold, (30..50) => precipwarm})
88
+
89
+ roller = make_roller(40, 10, 10)
90
+ roller.should_receive(:roll).exactly(3)
91
+
92
+ precipitations = precip_occur.type(roller, (30..30))
93
+ precipitations.collect { |p| p.name }.should == [:warm, "No Precipitation"]
94
+ end
95
+
96
+
97
+ private
98
+ def make_roller(*rolls)
99
+ roller = mock(:DieRoller)
100
+ roller.stub(:roll).and_return(*rolls)
101
+ roller
102
+ end
103
+
104
+ def create_test_precipitation (name, chance_to_continue = 10, min_max = [0, 100])
105
+ precip = mock(:Precipitation)
106
+ precip.stub(:not_allowed_in).and_return([])
107
+ precip.stub(:min_temp).and_return(min_max[0])
108
+ precip.stub(:max_temp).and_return(min_max[1])
109
+ precip.stub(:name).and_return(name)
110
+ precip.stub(:chance_of_rainbow).and_return(0)
111
+ precip.stub(:chance_to_continue).and_return(chance_to_continue)
112
+ precip
113
+ end
114
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+ require 'singledayweather'
3
+
4
+ describe SingleDayWeather do
5
+ it "temp range is calculated by appropriate die rolls" do
6
+ roller = rigged_roller_mock 0
7
+ month = mock(:Month).as_null_object
8
+ month.should_recieve(:temp_range).with(roller, nil)
9
+ month.stub(:temp_range).and_return((5..24))
10
+ SingleDayWeather.new(month, roller).temperature_range.should == (5..24)
11
+ end
12
+
13
+ it "determines sky conditions" do
14
+ roller = rigged_roller_mock 50
15
+ month = mock(:Month).as_null_object
16
+ month.stub(:sky_conditions).and_return(:partly_cloudy)
17
+ SingleDayWeather.new(month, roller).sky_conditions.should == :partly_cloudy
18
+ end
19
+
20
+ it "determines precipitation" do
21
+ roller = rigged_roller_mock 0
22
+
23
+ month = mock(:Month).as_null_object
24
+
25
+ precip = mock(:PrecipitationInfo)
26
+
27
+ precipitation = mock(:PrecipitationOccurance).as_null_object
28
+ precipitation.should_receive(:type).with(roller, anything(), anything()).and_return([precip])
29
+ SingleDayWeather.new(month, roller, precipitation).precipitation.should == [precip]
30
+ end
31
+
32
+ it "deals with record highs" do
33
+ roller = rigged_roller_mock 0
34
+ month = mock(:Month).as_null_object
35
+ month.should_recieve(:temp_range).with(anything(), anything(), :high)
36
+ precip_occur = mock(:PrecipitationOccurance).as_null_object
37
+ precip_occur.stub(:type)
38
+ SingleDayWeather.new(month, roller, precip_occur, :high)
39
+ end
40
+
41
+ it "determines wind" do
42
+ SingleDayWeather.new(mock(:Month).as_null_object, avg_roller_mock).wind.to_s.should == "9SE"
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'skyconditions'
3
+
4
+ describe 'SkyConditions' do
5
+ let(:conditions) { SkyConditions.new((01..23), (24..50), (51..100)) }
6
+
7
+ it 'picks from ranges' do
8
+ conditions.condition(rigged_roller_mock(1)).should eq(:clear)
9
+ conditions.condition(rigged_roller_mock(23)).should eq(:clear)
10
+ conditions.condition(rigged_roller_mock(24)).should eq(:partly_cloudy)
11
+ conditions.condition(rigged_roller_mock(50)).should eq(:partly_cloudy)
12
+ conditions.condition(rigged_roller_mock(51)).should eq(:cloudy)
13
+ conditions.condition(rigged_roller_mock(99)).should eq(:cloudy)
14
+ conditions.condition(rigged_roller_mock(100)).should eq(:cloudy)
15
+ end
16
+
17
+ it 'should treat 0 as 100' do
18
+ conditions.condition(rigged_roller_mock(0)).should eq(:cloudy)
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'rspec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ gem 'rspec'
6
+ require 'rspec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'greyhawkweather'
11
+
12
+ def avg_roller_mock
13
+ roller = mock(:DieRoller)
14
+ roller.stub(:roll) {|n, m| n/2 + (m||0)}
15
+ roller
16
+ end
17
+
18
+ def rigged_roller_mock(n)
19
+ roller = mock(:DieRoller)
20
+ roller.stub(:roll).and_return n
21
+ roller
22
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ require 'temperaturerange'
3
+
4
+ describe "TemperatureRange" do
5
+ let(:roller) do
6
+ avg_roller_mock()
7
+ end
8
+
9
+ subject {TemperatureRange.new(10, [8, 2], [8, 2])}
10
+
11
+ it "uses die roller for range construction" do
12
+ subject.range(roller).should == (4..16)
13
+ end
14
+
15
+ it "handles record highs and lows (including mixtures" do
16
+ HIGHS_AND_LOWS = {
17
+ :high => (14..26),
18
+ [:high, :high] => (24..36),
19
+ :low => (-6..6),
20
+ [:low, :low] => (-16..-4),
21
+ [:high, :low] => (4..16),
22
+ [:high, :low, :high] => (14..26) }
23
+
24
+ HIGHS_AND_LOWS.each { |record, temp_range|
25
+ subject.range(roller, record) == temp_range }
26
+ end
27
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'weathergenerator'
3
+ require 'options'
4
+
5
+ describe 'WeatherGenerator' do
6
+ let(:roller) do
7
+ avg_roller_mock
8
+ end
9
+ let(:baseline) do
10
+ baseline = mock(:BaselineData)
11
+ baseline.stub(:month) do |m|
12
+ month = mock(:month)
13
+ month.stub(:temp_range) { m..m+1 }
14
+ month
15
+ end
16
+ baseline
17
+ end
18
+
19
+ before(:each) do
20
+ SingleDayWeather.stub(:new) do |m, roller, precip, hilo, terrain|
21
+ day = mock(:SingleDayWeather)
22
+ day.stub(:temperature_range) { m.temp_range }
23
+ day.stub(:record){ hilo }
24
+ day.stub(:terrain) { terrain }
25
+ day
26
+ end
27
+ end
28
+
29
+ it 'creates num_days of weather' do
30
+ options = WeatherGeneratorOptions.new({:month => 1, :num_days => 13, :dieroller => roller })
31
+ generator = WeatherGenerator.new baseline, nil, options
32
+ generator.days.length.should == 13
33
+ end
34
+
35
+ it 'generates weather across month boundaries' do
36
+ baseline.stub(:num_months) { 2 }
37
+
38
+ options = WeatherGeneratorOptions.new({:month => 1, :num_days => 31, :dieroller => roller })
39
+ generator = WeatherGenerator.new baseline, nil, options
40
+ generator.days.select {|d| d.temperature_range.begin == 1 }.should have(28).items
41
+ generator.days.select {|d| d.temperature_range.begin == 2 }.length.should == 3
42
+ end
43
+
44
+ it 'generates days across year boundaries' do
45
+ baseline.stub(:num_months) { 2 }
46
+ options = WeatherGeneratorOptions.new({:month => 2, :num_days => 29, :dieroller => roller })
47
+ generator = WeatherGenerator.new baseline, nil, options
48
+ generator.days.last.temperature_range.begin.should == 1
49
+ end
50
+
51
+ it 'checks for record high and low' do
52
+ roller.stub(:roll) { 1 }
53
+ options = WeatherGeneratorOptions.new({:month => 1, :num_days => 1, :dieroller => roller })
54
+ generator = WeatherGenerator.new baseline, nil, options
55
+ generator.days.first.record.should == [:low, :low, :low]
56
+ end
57
+
58
+ it 'uses terrain for precipitation check' do
59
+ options = WeatherGeneratorOptions.new({:month => 1, :num_days => 1, :dieroller => roller, :terrain => :desert })
60
+ generator = WeatherGenerator.new baseline, nil, options
61
+ generator.days.first.terrain.should == :desert
62
+ end
63
+ end
data/spec/wind_spec.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'wind'
3
+
4
+ describe Wind do
5
+ it "does default calculation" do
6
+ Wind.new(avg_roller_mock).to_s.should == "9SE"
7
+ end
8
+ end