calendrier 0.9.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.
@@ -0,0 +1,63 @@
1
+ module Calendrier
2
+ module EventHelper
3
+
4
+ def count_sorted_events(events_by_date, cell_begin_time, cell_end_time)
5
+ counter = 0
6
+ sorted_events_do(events_by_date, cell_begin_time, cell_end_time) { |event| counter += 1 }
7
+ counter
8
+ end
9
+
10
+ def yield_sorted_events(events_by_date, cell_begin_time, cell_end_time, &block)
11
+ sorted_events_do(events_by_date, cell_begin_time, cell_end_time) { |event| yield event }
12
+ end
13
+
14
+ protected
15
+
16
+ def sorted_events_do(events_by_date, cell_begin_time, cell_end_time, &block)
17
+ begin
18
+ unless events_by_date[cell_begin_time.year.to_s][cell_begin_time.month.to_s][cell_begin_time.day.to_s].nil?
19
+ events_by_date[cell_begin_time.year.to_s][cell_begin_time.month.to_s][cell_begin_time.day.to_s].each do |event|
20
+ yield event if display_event?(event, cell_begin_time, cell_end_time) # && block_given?
21
+ end
22
+ end
23
+ rescue NoMethodError
24
+ end
25
+ end
26
+
27
+ def display_event?(event, cell_begin_time, cell_end_time)
28
+ event_begin_time = nil
29
+ event_end_time = nil
30
+
31
+ if event.respond_to?(:year) && event.respond_to?(:month) && event.respond_to?(:day)
32
+ event_begin_time = Time.utc(event.year, event.month, event.day)
33
+ event_end_time = Time.utc(event.year, event.month, event.day, 23, 59, 59)
34
+ end
35
+
36
+ if event.respond_to?(:begin_time) && event.respond_to?(:end_time)
37
+ event_begin_time = event.begin_time
38
+ event_end_time = event.end_time
39
+ end
40
+
41
+ if event_begin_time.to_i <= cell_begin_time.to_i
42
+ if event_end_time.to_i <= cell_end_time.to_i
43
+ if event_end_time.to_i > cell_begin_time.to_i
44
+ ok = true
45
+ end
46
+ else
47
+ ok = true
48
+ end
49
+ else
50
+ if event_end_time.to_i <= cell_end_time.to_i
51
+ ok = true
52
+ else
53
+ if event_begin_time.to_i < cell_end_time.to_i
54
+ ok = true
55
+ end
56
+ end
57
+ end
58
+
59
+ return ok
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,3 @@
1
+ module Calendrier
2
+ VERSION = "0.9.0"
3
+ end
@@ -0,0 +1,175 @@
1
+ require 'test_helper'
2
+
3
+ describe Calendrier::CalendrierBuilder do
4
+ before do
5
+
6
+ ActionView::Base.send(:include, Calendrier::CalendrierHelper)
7
+ ActionView::Base.send(:include, Calendrier::EventHelper)
8
+ @view = ActionView::Base.new
9
+ @cal_options = { :year => 2012, :month => 5, :day => 25, :start_on_monday => true, :title => 'This is the calendar title' }
10
+
11
+ # preparing array for the month of may 2012
12
+ @days_of_may = []
13
+ @days_of_may << ''
14
+ 31.times do |idx|
15
+ @days_of_may << (idx + 1).to_s
16
+ end
17
+ 3.times { @days_of_may << '' }
18
+
19
+ # preparing array for the week of the 25th of may 2012
20
+ @days_of_may_weekly = []
21
+ 24.times do |hour_idx|
22
+ @days_of_may_weekly << (hour_idx).to_s
23
+ 7.times do |day_idx|
24
+ @days_of_may_weekly << ''
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ # builder
31
+
32
+ it "should require context and elements" do
33
+ proc { Calendrier::CalendrierBuilder::Builder.new }.must_raise ArgumentError
34
+ end
35
+
36
+ it "should raise NotImplementedError for Builder instance" do
37
+ builder = Calendrier::CalendrierBuilder::Builder.new(@view)
38
+ proc { builder.render }.must_raise NotImplementedError
39
+ end
40
+
41
+ # simple builder #
42
+
43
+ it "should respond to render for SimpleBuilder instance" do
44
+ builder = Calendrier::CalendrierBuilder::SimpleBuilder.new(@view)
45
+ #proc { builder.render }.must_raise NotImplementedError
46
+ builder.render(nil, nil)
47
+ end
48
+
49
+ it "should return valid code for monthly calendar" do
50
+ options = { :display => :month }
51
+ header, content = generate_header_and_content(options)
52
+ builder = Calendrier::CalendrierBuilder::SimpleBuilder.new(@view, options)
53
+ html_doc = Nokogiri::XML::Document.parse(builder.render(header, content).html_safe)
54
+ html_doc.errors.must_equal []
55
+ end
56
+
57
+ it "should return valid code for weekly calendar" do
58
+ options = { :display => :week }
59
+ header, content = generate_header_and_content(options)
60
+ builder = Calendrier::CalendrierBuilder::SimpleBuilder.new(@view, options)
61
+ html_doc = Nokogiri::XML::Document.parse(builder.render(header, content).html_safe)
62
+ html_doc.errors.must_equal []
63
+ end
64
+
65
+ it "should have the right calendar title" do
66
+ cal = generate_calendar(:month)
67
+ html_doc = Nokogiri::HTML(cal.html_safe)
68
+ calendar_title = html_doc.css('div.calendar > span').map { |link| link.children.to_s }.first
69
+ calendar_title.must_match /#{@cal_options[:title]}/
70
+ end
71
+
72
+
73
+ # monthly
74
+ it "should return the default monthly calendar" do
75
+ cal = generate_calendar(:month)
76
+ cal.must_match %r{calendar month}
77
+ end
78
+
79
+ it "should have the right amount of lines for monthly calendar" do
80
+ cal = generate_calendar(:month)
81
+ html_doc = Nokogiri::HTML(cal.html_safe)
82
+ calendar_lines = html_doc.css('div.calendar tr')
83
+ calendar_lines_count = html_doc.css('div.calendar tr').count
84
+ calendar_lines_count.must_equal 5
85
+ end
86
+
87
+ it "should have the right amount of columns for monthly calendar" do
88
+ cal = generate_calendar(:month)
89
+ html_doc = Nokogiri::HTML(cal.html_safe)
90
+ calendar_columns_count = html_doc.css('div.calendar td').count
91
+ calendar_columns_count.must_equal 5 * 7
92
+ end
93
+
94
+ it "should have the rights columns for monthly calendar" do
95
+ cal = generate_calendar(:month)
96
+ html_doc = Nokogiri::HTML(cal.html_safe)
97
+ calendar_columns_arr = html_doc.css('div.calendar td')
98
+ content_arr = calendar_columns_arr.map { |col| col.children.text.to_s }
99
+ content_arr.must_equal @days_of_may
100
+ end
101
+
102
+ # weekly
103
+ it "should return the weekly calendar" do
104
+ cal = generate_calendar(:week)
105
+ cal.must_match %r{calendar week}
106
+ end
107
+
108
+ it "should have the right amount of lines for weekly calendar" do
109
+ cal = generate_calendar(:week)
110
+ html_doc = Nokogiri::HTML(cal.html_safe)
111
+ calendar_lines_count = html_doc.css('div.calendar tr').count
112
+ calendar_lines_count.must_equal 24
113
+ end
114
+
115
+ it "should have the right amount of columns for monthly calendar" do
116
+ cal = generate_calendar(:week)
117
+ html_doc = Nokogiri::HTML(cal.html_safe)
118
+ calendar_columns_count = html_doc.css('div.calendar td').count
119
+ calendar_columns_count.must_equal (1 + 7) * 24
120
+ end
121
+
122
+ it "should have the rights columns for monthly calendar" do
123
+ cal = generate_calendar(:week)
124
+ html_doc = Nokogiri::HTML(cal.html_safe)
125
+ calendar_columns_arr = html_doc.css('div.calendar td')
126
+ content_arr = calendar_columns_arr.map { |col| col.children.to_s }
127
+ content_arr.must_equal @days_of_may_weekly
128
+ end
129
+
130
+ def generate_calendar(display = :month)
131
+ options = @cal_options.merge :display => display
132
+ header, content = generate_header_and_content(options)
133
+ builder = Calendrier::CalendrierBuilder::SimpleBuilder.new(@view, options)
134
+ builder.render(header, content).html_safe
135
+ end
136
+
137
+ def generate_header_and_content(options = {})
138
+ display = options[:display] || :month
139
+ header = []
140
+ time_iterate(Time.utc(2012,5,21), Time.utc(2012,5,28)-1, 60*60*24) do |date|
141
+ header << date.to_date
142
+ end
143
+ content = []
144
+ content_intermediate = []
145
+ if display == :month
146
+ content_intermediate << content_hash(nil, nil)
147
+ time_iterate(Time.utc(2012,5,1), Time.utc(2012,5,31), 60*60*24) do |time|
148
+ content_intermediate << content_hash(time, nil)
149
+ end
150
+ 3.times { content_intermediate << content_hash(nil, nil) }
151
+ else
152
+ 24.times do |idx|
153
+ time_iterate(Time.utc(2012,5,21), Time.utc(2012,5,27), 60*60*24) do |time|
154
+ content_intermediate << content_hash(time + idx*60*60, nil)
155
+ end
156
+ end
157
+ end
158
+
159
+ (content_intermediate.count / 7).times do |idx|
160
+ content << content_intermediate.slice(idx * 7, 7)
161
+ end
162
+ [header, content]
163
+ end
164
+
165
+ def content_hash(time, content)
166
+ { time: time, content: content }
167
+ end
168
+
169
+ def time_iterate(start_time, end_time, step, &block)
170
+ begin
171
+ yield(start_time, start_time + step)
172
+ end while (start_time += step) <= end_time
173
+ end
174
+
175
+ end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ describe Calendrier::EventExtension do
4
+ before do
5
+
6
+ ActionController::Base.send(:include, Calendrier::EventExtension)
7
+ @ctrl = ActionController::Base.new
8
+
9
+ de = FakeDailyEvent.new(2012,5,21)
10
+ de2 = FakeDailyEvent.new(2012,5,24)
11
+ le = FakeLongEvent.new(Time.utc(2012,5,23).to_i, Time.utc(2012,5,25,12).to_i)
12
+
13
+ @events_sorted_manually = {"2012"=>{
14
+ "5"=>{
15
+ "21"=>[ de ],
16
+ "23"=>[ le ],
17
+ "24"=>[ le, de2 ],
18
+ "25"=>[ le ],
19
+ # "26"=>[ le ] # this one should not be display
20
+ }
21
+ }
22
+ }
23
+
24
+
25
+ @events_unordered = [ de, le, de2 ]
26
+
27
+ @events = @events_sorted_manually
28
+
29
+ end
30
+
31
+ it "should integrate with ActionController::Base" do
32
+ @ctrl.respond_to?(:sort_events).must_equal true
33
+ end
34
+
35
+ it "should return hash of events sorted by date" do
36
+ @ctrl.sort_events(@events_unordered).must_equal @events_sorted_manually
37
+ end
38
+
39
+ end
40
+
@@ -0,0 +1,60 @@
1
+ require 'test_helper'
2
+
3
+ describe Calendrier::CalendrierHelper do
4
+ before do
5
+
6
+ ActionView::Base.send(:include, Calendrier::CalendrierHelper)
7
+ ActionView::Base.send(:include, Calendrier::EventHelper)
8
+ @view = ActionView::Base.new
9
+ @cal_options = { :year => 2012, :month => 5, :day => 25, :start_on_monday => true }
10
+ de = FakeDailyEvent.new(2012,5,21)
11
+ de2 = FakeDailyEvent.new(2012,5,24)
12
+ le2 = FakeLongEvent.new(Time.utc(2012,5,23).to_i, Time.utc(2012,5,25).to_i)
13
+ @events_test = {"2012"=>{
14
+ "5"=>{
15
+ "21"=>[ de ],
16
+ "23"=>[ le2 ],
17
+ "24"=>[ de2, le2 ],
18
+ "25"=>[ le2 ],
19
+ "26"=>[ le2 ] # this one should not be display
20
+ }
21
+ }
22
+ }
23
+
24
+ # preparing events counter array for the week of the 25th of may 2012
25
+ @counter_of_may_weekly = []
26
+ 24.times { @counter_of_may_weekly = @counter_of_may_weekly + [1,0,1,2,0,0,0] }
27
+
28
+ # preparing events counter array for the week of the 25th of may 2012
29
+ @counter_of_may_monthly = []
30
+ 20.times { @counter_of_may_monthly << 0 }
31
+ @counter_of_may_monthly << 1
32
+ @counter_of_may_monthly << 0
33
+ @counter_of_may_monthly << 1
34
+ @counter_of_may_monthly << 2
35
+ 7.times { @counter_of_may_monthly << 0 }
36
+ end
37
+
38
+ it "should integrate with ActionView::Base" do
39
+ @view.respond_to?(:calendrier).must_equal true
40
+ end
41
+
42
+ it "should have the right amount of events for monthly calendar" do
43
+ counts = []
44
+ cal = @view.calendrier(@cal_options.merge :display => :month) do |cell_begin_time, cell_end_time|
45
+ counts << @view.count_sorted_events(@events_test, cell_begin_time, cell_end_time)
46
+ end
47
+ counts.must_equal @counter_of_may_monthly
48
+ end
49
+
50
+ it "should have the right amount of events for weekly calendar" do
51
+ counts = []
52
+ cal = @view.calendrier(@cal_options.merge :display => :week) do |cell_begin_time, cell_end_time|
53
+ counts << @view.count_sorted_events(@events_test, cell_begin_time, cell_end_time)
54
+ end
55
+ counts.must_equal @counter_of_may_weekly
56
+ end
57
+
58
+
59
+ end
60
+
@@ -0,0 +1,94 @@
1
+ require 'test_helper'
2
+
3
+ describe Calendrier::EventHelper do
4
+ before do
5
+
6
+ #ActionView::Base.send(:include, Calendrier::CalendrierHelper)
7
+ ActionView::Base.send(:include, Calendrier::EventHelper)
8
+ @view = ActionView::Base.new
9
+ @cal_options = { :year => 2012, :month => 5, :day => 25, :start_on_monday => true }
10
+
11
+ de = FakeDailyEvent.new(2012,5,21)
12
+ de2 = FakeDailyEvent.new(2012,5,24)
13
+ le = FakeLongEvent.new(Time.utc(2012,5,23).to_i, Time.utc(2012,5,25,12).to_i)
14
+
15
+ @events_sorted_manually = {"2012"=>{
16
+ "5"=>{
17
+ "21"=>[ de ],
18
+ "23"=>[ le ],
19
+ "24"=>[ le, de2 ],
20
+ "25"=>[ le ],
21
+ }
22
+ }
23
+ }
24
+
25
+ # "26"=>[ le ] # this one should not be displayed
26
+
27
+ @events = @events_sorted_manually
28
+
29
+ end
30
+
31
+ it "should integrate with ActionView::Base" do
32
+ @view.respond_to?(:count_sorted_events).must_equal true
33
+ @view.respond_to?(:yield_sorted_events).must_equal true
34
+ end
35
+
36
+ it "should count only one event" do
37
+ cell_begin_time = Time.utc(2012, 5, 23, 12)
38
+ cell_end_time = Time.utc(2012, 5, 23, 13)
39
+ @view.count_sorted_events(@events, cell_begin_time, cell_end_time).must_equal 1
40
+ end
41
+
42
+ it "should count the two events" do
43
+ cell_begin_time = Time.utc(2012, 5, 24, 12)
44
+ cell_end_time = Time.utc(2012, 5, 24, 13)
45
+ @view.count_sorted_events(@events, cell_begin_time, cell_end_time).must_equal 2
46
+ end
47
+
48
+ it "should count the right amount of events in the month" do
49
+ calendar_begin_time = Time.utc(2012, 5, 1)
50
+ calendar_end_time = Time.utc(2012, 5, 31)
51
+ events_count_of_may = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0]
52
+
53
+ step = 60 * 60 * 24 # 1.day
54
+
55
+ events_counts = []
56
+
57
+ time_iterate(calendar_begin_time, calendar_end_time, step) do |cell_begin_time, cell_end_time|
58
+ events_counts << @view.count_sorted_events(@events, cell_begin_time, cell_end_time)
59
+ end
60
+
61
+ events_counts.must_equal events_count_of_may
62
+ end
63
+
64
+ it "should count the right amount of events in the week" do
65
+ calendar_begin_time = Time.utc(2012, 5, 21, 0)
66
+ calendar_end_time = Time.utc(2012, 5, 27, 23, 59, 59)
67
+ events_count_of_one_week_in_may = []
68
+ 24.times { events_count_of_one_week_in_may << 1 }
69
+ 24.times { events_count_of_one_week_in_may << 0 }
70
+ 24.times { events_count_of_one_week_in_may << 1 }
71
+ 24.times { events_count_of_one_week_in_may << 2 }
72
+ 12.times { events_count_of_one_week_in_may << 1 }
73
+ (12+24+24).times { events_count_of_one_week_in_may << 0 }
74
+
75
+ step = 60 * 60 # 1.hour
76
+
77
+ events_counts = []
78
+
79
+ time_iterate(calendar_begin_time, calendar_end_time, step) do |cell_begin_time, cell_end_time|
80
+ events_counts << @view.count_sorted_events(@events, cell_begin_time, cell_end_time)
81
+ end
82
+
83
+ events_counts.must_equal events_count_of_one_week_in_may
84
+ end
85
+
86
+
87
+ def time_iterate(start_time, end_time, step, &block)
88
+ begin
89
+ yield(start_time, start_time + step)
90
+ end while (start_time += step) <= end_time
91
+ end
92
+
93
+ end
94
+
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ describe Calendrier do
4
+
5
+ it "must be defined" do
6
+ Calendrier::VERSION.wont_be_nil
7
+ end
8
+
9
+ end