calendrier 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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