calorie 0.0.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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in calorie.gemspec
4
+ gemspec
@@ -0,0 +1,69 @@
1
+ # Calorie
2
+
3
+ A calendar is a calendar is a calendar.
4
+
5
+ Motivated by the frustration of solving the same problem in a dozen different ugly ways in a dozen different applications.
6
+
7
+ ## Requirements
8
+
9
+ This uses the ruby core `Date` library.
10
+
11
+ In other words, rails is *not* required.
12
+
13
+ ## Usage
14
+
15
+ Create a hash that uses the day of the month as the key.
16
+ The data can be anything, and only your code will be interacting with it.
17
+
18
+ data = {
19
+ 1 => thing,
20
+ 2 => different_thing,
21
+ 3 => nil,
22
+ 4 => medium_sized_thing,
23
+ 5 => complicated_thing,
24
+ 6 => nil,
25
+ # ... etc
26
+ }
27
+
28
+ Create a presenter for a month by sending in `year`, `month`, and the data:
29
+
30
+ cal = Calorie.new(2010, 6, data)
31
+
32
+ In your view, you can style it however you wish, e.g.:
33
+
34
+ cal.days_of_the_week do |label|
35
+ if day.weekend?
36
+ # label styled as a weekend
37
+ else
38
+ # label styled as a weekday
39
+ end
40
+ end
41
+
42
+ cal.each_week do |week|
43
+ week.each_day do |day|
44
+ unless day.blank?
45
+ # the day of the month is day.number
46
+ # do stuff with day.data
47
+ if day.today?
48
+ # omg, it's RIGHT NOW
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+
55
+ If you don't need to lay it out by week, you can also iterate straight through the days:
56
+
57
+ cal.each_day do |day|
58
+ # the day of the month is day.number
59
+ # do stuff with day.data
60
+ if day.today?
61
+ # omg, it's RIGHT NOW
62
+ end
63
+ end
64
+
65
+ ## TODO
66
+
67
+ * configurable week start
68
+ * i18n for days of the week
69
+ * add labels for current, previous, and next month (with i18n support)
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "calorie/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "calorie"
7
+ s.version = Calorie::VERSION
8
+ s.authors = ["Katrina Owen"]
9
+ s.email = ["katrina.owen@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{A calendar is a calendar is a calendar.}
12
+ s.description = %q{A simple, ruby calendar presenter.}
13
+
14
+ s.rubyforge_project = "calorie"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rspec"
22
+ s.add_development_dependency "timecop"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
@@ -0,0 +1,15 @@
1
+ require "calorie/version"
2
+
3
+ require 'date'
4
+
5
+ require 'calorie/weeks_in_month'
6
+ require 'calorie/calendar'
7
+ require 'calorie/week'
8
+ require 'calorie/day'
9
+
10
+ module Calorie
11
+
12
+ def self.new(year, month, data)
13
+ Calendar.new(year, month, data)
14
+ end
15
+ end
@@ -0,0 +1,78 @@
1
+ module Calorie
2
+
3
+ class Calendar
4
+ include WeeksInMonth
5
+
6
+ attr_reader :days, :weeks, :year, :month, :data
7
+ def initialize(year, month, data)
8
+ @data = data
9
+ @year = year
10
+ @month = month
11
+ initialize_days
12
+ initialize_weeks
13
+ end
14
+
15
+ def first_day
16
+ @first_day ||= Date.new(year, month, 1)
17
+ @first_day
18
+ end
19
+
20
+ def last_day
21
+ @last_day ||= first_day.next_month.prev_day
22
+ @last_day
23
+ end
24
+
25
+ def days_in_month
26
+ days.size
27
+ end
28
+
29
+ def first_day_falls_on
30
+ first_day.wday
31
+ end
32
+
33
+ def initialize_days
34
+ @days = []
35
+ (first_day.mday..last_day.mday).map do |i|
36
+ date = Date.new(year, month, i)
37
+ @days << Calorie::Day.new(date, data[i])
38
+ end
39
+ end
40
+
41
+ def initialize_weeks
42
+ @weeks = []
43
+ padded_days = days_for_slicing
44
+ number_of_weeks.times do
45
+ @weeks << Calorie::Week.new(padded_days.slice!(0..6))
46
+ end
47
+ end
48
+
49
+ def days_for_slicing
50
+ slices = days.clone
51
+
52
+ blank_days_at_start.times { slices.unshift(Calorie::Day.new) }
53
+ blank_days_at_end.times { slices.push(Calorie::Day.new) }
54
+
55
+ slices
56
+ end
57
+
58
+ def blank_days_at_start
59
+ first_day.wday
60
+ end
61
+
62
+ def blank_days_at_end
63
+ (blank_days_at_start + days_in_month) % 7
64
+ end
65
+
66
+ def days_in_month
67
+ last_day.mday
68
+ end
69
+
70
+ def each_day(&block)
71
+ days.each {|day| block.call(day) }
72
+ end
73
+
74
+ def days_of_the_week
75
+ %w(Su Mo Tu We Th Fr Sa)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,46 @@
1
+ module Calorie
2
+ class Day
3
+
4
+ def initialize(date = nil, data = nil)
5
+ if date
6
+ @date = date
7
+ else
8
+ @date = NullDate.new
9
+ end
10
+ @data = data
11
+ end
12
+
13
+ def weekend?
14
+ @date.sunday? || @date.saturday?
15
+ end
16
+
17
+ def number
18
+ @date.mday
19
+ end
20
+
21
+ def data
22
+ @data
23
+ end
24
+
25
+ def blank?
26
+ @date.is_a?(NullDate)
27
+ end
28
+
29
+ def today?
30
+ @date == Date.today
31
+ end
32
+ end
33
+
34
+ class NullDate
35
+ def sunday?
36
+ false
37
+ end
38
+
39
+ def saturday?
40
+ false
41
+ end
42
+
43
+ def mday
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Calorie
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,12 @@
1
+ module Calorie
2
+ class Week
3
+
4
+ def initialize(days)
5
+ @days = days
6
+ end
7
+
8
+ def each_day(&block)
9
+ @days.each {|day| block.call(day) }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ module Calorie
2
+ module WeeksInMonth
3
+
4
+ def number_of_weeks
5
+ ((days_in_month + first_day_falls_on) / 7.0).ceil
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,42 @@
1
+ require 'calorie'
2
+
3
+ describe Calorie::Calendar do
4
+ subject { Calorie::Calendar.new(2010, 12, {25 => 'Christmas'}) }
5
+
6
+ it "creates all the days" do
7
+ numbers = []
8
+ subject.each_day do |day|
9
+ numbers << day.number
10
+ end
11
+
12
+ numbers.should eq((1..31).to_a)
13
+ end
14
+
15
+ it "hands out the data" do
16
+ subject.each_day do |day|
17
+ if day.number == 25
18
+ day.data.should eq('Christmas')
19
+ end
20
+ end
21
+ end
22
+
23
+ it "gets the first week right" do
24
+ numbers = []
25
+ subject.weeks.first.each_day do |day|
26
+ numbers << day.number
27
+ end
28
+ numbers.should eq([nil, nil, nil] + (1..4).to_a)
29
+ end
30
+
31
+ it "gets the last week right" do
32
+ numbers = []
33
+ subject.weeks.last.each_day do |day|
34
+ numbers << day.number
35
+ end
36
+ numbers.should eq((26..31).to_a + [nil])
37
+ end
38
+
39
+ it "has labels for the days of the week" do
40
+ subject.days_of_the_week.should eq(%w(Su Mo Tu We Th Fr Sa))
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ require 'calorie'
2
+
3
+ describe Calorie do
4
+ it "provides a simple presenter for a monthly calendar" do
5
+ cal = Calorie.new(2010, 12, {25 => 'Christmas'})
6
+
7
+ cal.each_day do |day|
8
+ if day.number == 25
9
+ day.data.should eq('Christmas')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,53 @@
1
+ require 'calorie/day'
2
+ require 'timecop'
3
+
4
+ describe Calorie::Day do
5
+
6
+ context "during the weekend" do
7
+ subject { Calorie::Day.new(Date.new(2010, 6, 13), "hello, world") }
8
+
9
+ its(:number) { should eq(13) }
10
+ its(:data) { should eq("hello, world") }
11
+ its(:weekend?) { should be_true }
12
+ its(:blank?) { should be_false}
13
+
14
+ context "on that particular day" do
15
+ before :each do
16
+ Timecop.freeze(Time.new(2010, 6, 13, 11, 40, 17))
17
+ end
18
+
19
+ its(:today?) { should be_true }
20
+ end
21
+
22
+ context "on a different day" do
23
+ before :each do
24
+ Timecop.freeze(Time.new(2010, 6, 14, 20, 15, 47))
25
+ end
26
+
27
+ its(:today?) { should be_false }
28
+ end
29
+ end
30
+
31
+ context "midweek" do
32
+ subject { Calorie::Day.new(Date.new(2010, 6, 17), "so long, folks") }
33
+
34
+ its(:number) { should eq(17) }
35
+ its(:data) { should eq("so long, folks") }
36
+ its(:weekend?) { should be_false }
37
+ its(:blank?) { should be_false}
38
+ end
39
+
40
+ context "a null day" do
41
+ subject { Calorie::Day.new }
42
+ its(:blank?) { should be_true }
43
+ its(:number) { should be_nil }
44
+ its(:weekend?) { should be_false }
45
+ its(:data) { should be_nil }
46
+ end
47
+ end
48
+
49
+ describe Calorie::NullDate do
50
+ its(:mday) { should be_nil }
51
+ its(:sunday?) { should be_false }
52
+ its(:saturday?) { should be_false }
53
+ end
@@ -0,0 +1,24 @@
1
+ require 'calorie/day'
2
+ require 'calorie/week'
3
+
4
+ describe Calorie::Week do
5
+
6
+ it "loops through the days" do
7
+ days = [
8
+ Calorie::Day.new,
9
+ Calorie::Day.new,
10
+ Calorie::Day.new(Date.new(2010, 6, 1), "the first"),
11
+ Calorie::Day.new(Date.new(2010, 6, 2), "the second"),
12
+ Calorie::Day.new(Date.new(2010, 6, 3), "the third"),
13
+ Calorie::Day.new(Date.new(2010, 6, 4), "the fourth"),
14
+ Calorie::Day.new(Date.new(2010, 6, 5), "the fifth"),
15
+ ]
16
+
17
+ numbers = []
18
+ Calorie::Week.new(days).each_day do |day|
19
+ numbers << day.number
20
+ end
21
+
22
+ numbers.should eq([nil, nil, 1, 2, 3, 4, 5])
23
+ end
24
+ end
@@ -0,0 +1,95 @@
1
+ require 'calorie/weeks_in_month'
2
+
3
+ describe Calorie::WeeksInMonth do
4
+ let(:cal) { stub.extend(Calorie::WeeksInMonth) }
5
+
6
+ context "with a 28 day month" do
7
+ before :each do
8
+ cal.stub(:days_in_month => 28)
9
+ end
10
+
11
+ it "has 4 weeks when first day is Sunday" do
12
+ cal.stub(:first_day_falls_on => 0)
13
+ cal.number_of_weeks.should eq(4)
14
+ end
15
+
16
+ it "has 5 weeks when first day is Monday" do
17
+ cal.stub(:first_day_falls_on => 1)
18
+ cal.number_of_weeks.should eq(5)
19
+ end
20
+
21
+ it "has 5 weeks when first day is Saturday" do
22
+ cal.stub(:first_day_falls_on => 6)
23
+ cal.number_of_weeks.should eq(5)
24
+ end
25
+ end
26
+
27
+ context "with a 29 day month" do
28
+ before :each do
29
+ cal.stub(:days_in_month => 29)
30
+ end
31
+
32
+ it "has 5 weeks when first day is Sunday" do
33
+ cal.stub(:first_day_falls_on => 0)
34
+ cal.number_of_weeks.should eq(5)
35
+ end
36
+
37
+ it "has 5 weeks when first day is Monday" do
38
+ cal.stub(:first_day_falls_on => 1)
39
+ cal.number_of_weeks.should eq(5)
40
+ end
41
+
42
+ it "has 5 weeks when first day is Saturday" do
43
+ cal.stub(:first_day_falls_on => 6)
44
+ cal.number_of_weeks.should eq(5)
45
+ end
46
+
47
+ end
48
+
49
+ context "with a 30 day month" do
50
+ before :each do
51
+ cal.stub(:days_in_month => 30)
52
+ end
53
+
54
+ it "has 5 weeks when first day is Sunday" do
55
+ cal.stub(:first_day_falls_on => 0)
56
+ cal.number_of_weeks.should eq(5)
57
+ end
58
+
59
+ it "has 5 weeks when first day is Friday" do
60
+ cal.stub(:first_day_falls_on => 5)
61
+ cal.number_of_weeks.should eq(5)
62
+ end
63
+
64
+ it "has 6 weeks when first day is Saturday" do
65
+ cal.stub(:first_day_falls_on => 6)
66
+ cal.number_of_weeks.should eq(6)
67
+ end
68
+ end
69
+
70
+ context "with a 31 day month" do
71
+ before :each do
72
+ cal.stub(:days_in_month => 31)
73
+ end
74
+
75
+ it "has 5 weeks when first day is Sunday" do
76
+ cal.stub(:first_day_falls_on => 0)
77
+ cal.number_of_weeks.should eq(5)
78
+ end
79
+
80
+ it "has 5 weeks when first day is Thursday" do
81
+ cal.stub(:first_day_falls_on => 4)
82
+ cal.number_of_weeks.should eq(5)
83
+ end
84
+
85
+ it "has 6 weeks when first day is Friday" do
86
+ cal.stub(:first_day_falls_on => 5)
87
+ cal.number_of_weeks.should eq(6)
88
+ end
89
+
90
+ it "has 6 weeks when first day is Saturday" do
91
+ cal.stub(:first_day_falls_on => 6)
92
+ cal.number_of_weeks.should eq(6)
93
+ end
94
+ end
95
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: calorie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Katrina Owen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-27 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &2153896240 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2153896240
25
+ - !ruby/object:Gem::Dependency
26
+ name: timecop
27
+ requirement: &2153895820 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2153895820
36
+ description: A simple, ruby calendar presenter.
37
+ email:
38
+ - katrina.owen@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - .rspec
45
+ - Gemfile
46
+ - README.md
47
+ - Rakefile
48
+ - calorie.gemspec
49
+ - lib/calorie.rb
50
+ - lib/calorie/calendar.rb
51
+ - lib/calorie/day.rb
52
+ - lib/calorie/version.rb
53
+ - lib/calorie/week.rb
54
+ - lib/calorie/weeks_in_month.rb
55
+ - spec/calendar_spec.rb
56
+ - spec/calorie_spec.rb
57
+ - spec/day_spec.rb
58
+ - spec/week_spec.rb
59
+ - spec/weeks_in_month_spec.rb
60
+ homepage: ''
61
+ licenses: []
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project: calorie
80
+ rubygems_version: 1.8.10
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: A calendar is a calendar is a calendar.
84
+ test_files: []