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.
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/README.md +69 -0
- data/Rakefile +1 -0
- data/calorie.gemspec +24 -0
- data/lib/calorie.rb +15 -0
- data/lib/calorie/calendar.rb +78 -0
- data/lib/calorie/day.rb +46 -0
- data/lib/calorie/version.rb +3 -0
- data/lib/calorie/week.rb +12 -0
- data/lib/calorie/weeks_in_month.rb +9 -0
- data/spec/calendar_spec.rb +42 -0
- data/spec/calorie_spec.rb +13 -0
- data/spec/day_spec.rb +53 -0
- data/spec/week_spec.rb +24 -0
- data/spec/weeks_in_month_spec.rb +95 -0
- metadata +84 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -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)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/calorie.gemspec
ADDED
@@ -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
|
data/lib/calorie.rb
ADDED
@@ -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
|
data/lib/calorie/day.rb
ADDED
@@ -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
|
data/lib/calorie/week.rb
ADDED
@@ -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
|
data/spec/day_spec.rb
ADDED
@@ -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
|
data/spec/week_spec.rb
ADDED
@@ -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: []
|