ess 0.9.3 → 1.0.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.
- data/README.md +78 -5
- data/lib/ess/dtd.rb +11 -1
- data/lib/ess/element.rb +86 -7
- data/lib/ess/ess.rb +298 -0
- data/lib/ess/examples.rb +6 -3
- data/lib/ess/helpers.rb +3 -0
- data/lib/ess/maker.rb +40 -6
- data/lib/ess/parser.rb +31 -0
- data/lib/ess/postprocessing.rb +4 -0
- data/lib/ess/pusher.rb +38 -0
- data/lib/ess/validation.rb +36 -1
- data/lib/ess/version.rb +1 -1
- data/spec/ess/ess_spec.rb +350 -0
- data/spec/ess/full_spec.rb +184 -5
- data/spec/ess/parser_spec.rb +58 -0
- data/spec/spec_helper.rb +1 -0
- metadata +7 -2
data/lib/ess/examples.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
module ESS
|
2
2
|
module Examples
|
3
|
+
##
|
4
|
+
# Example feeds for documentation and testing.
|
5
|
+
#
|
3
6
|
|
4
7
|
def self.from_essfeeds_org_home
|
5
8
|
ess = Maker.make do |ess|
|
@@ -45,7 +48,7 @@ module ESS
|
|
45
48
|
item.selected_day_attr "saturday,sunday"
|
46
49
|
|
47
50
|
item.name "Match Date"
|
48
|
-
item.start "2011-12-
|
51
|
+
item.start "2011-12-17T18:30:02Z"
|
49
52
|
item.duration "10800"
|
50
53
|
end
|
51
54
|
|
@@ -129,7 +132,7 @@ module ESS
|
|
129
132
|
item.country_code "US"
|
130
133
|
item.logo "http://sample.com/logo_120x60.png"
|
131
134
|
item.icon "http://sample.com/icon_64x64.png"
|
132
|
-
item.email "contact@
|
135
|
+
item.email "contact@example.com"
|
133
136
|
item.phone "+001 (646) 234-5566"
|
134
137
|
end
|
135
138
|
|
@@ -261,7 +264,7 @@ module ESS
|
|
261
264
|
|
262
265
|
feed.dates.add_item :type => "recurrent", :unit => "month", :limit => 6, :selected_day => "saturday", :selected_week => "first,last" do |item|
|
263
266
|
item.name "Course the first and last Saturdays of every month"
|
264
|
-
item.start "2013-10-
|
267
|
+
item.start "2013-10-05T15:30:00Z"
|
265
268
|
item.duration "21600"
|
266
269
|
end
|
267
270
|
|
data/lib/ess/helpers.rb
CHANGED
data/lib/ess/maker.rb
CHANGED
@@ -1,12 +1,37 @@
|
|
1
1
|
module ESS
|
2
2
|
class Maker
|
3
|
-
DEFAULT_OPTIONS = {
|
4
|
-
:version => "0.9",
|
5
|
-
:lang => "en",
|
6
|
-
:validate => true,
|
7
|
-
:push => false
|
8
|
-
}
|
9
3
|
|
4
|
+
##
|
5
|
+
# Create a new ESS document. See README for examples on how it should
|
6
|
+
# be used.
|
7
|
+
#
|
8
|
+
# === Yields
|
9
|
+
#
|
10
|
+
# [ESS::ESS] object representing the "ess" root tag of an ESS document
|
11
|
+
#
|
12
|
+
# === Options
|
13
|
+
#
|
14
|
+
# Currently, the following options are defined:
|
15
|
+
#
|
16
|
+
# ==== :push
|
17
|
+
#
|
18
|
+
# Whether to push the resulting document to aggregators before returning
|
19
|
+
# from the method. Default is false.
|
20
|
+
#
|
21
|
+
# ==== :validate
|
22
|
+
#
|
23
|
+
# Validate resulting document before returning from the method. Default
|
24
|
+
# is true.
|
25
|
+
#
|
26
|
+
# ==== :version
|
27
|
+
#
|
28
|
+
# Set a different value for the "version" attribute of the "ess" tag.
|
29
|
+
# Default is "0.9".
|
30
|
+
#
|
31
|
+
# ==== :lang
|
32
|
+
#
|
33
|
+
# Set a value for the "lang" attribute of the "ess" tag. Default is "en".
|
34
|
+
#
|
10
35
|
def self.make options={}, &block
|
11
36
|
options = DEFAULT_OPTIONS.merge options
|
12
37
|
ess = ESS.new
|
@@ -19,6 +44,15 @@ module ESS
|
|
19
44
|
ess.push_to_aggregators(options) if options[:push] || options[:aggregators]
|
20
45
|
return ess
|
21
46
|
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
DEFAULT_OPTIONS = {
|
51
|
+
:version => "0.9",
|
52
|
+
:lang => "en",
|
53
|
+
:validate => true,
|
54
|
+
:push => false
|
55
|
+
}
|
22
56
|
end
|
23
57
|
end
|
24
58
|
|
data/lib/ess/parser.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "ess"
|
2
|
+
require "rexml/document"
|
3
|
+
|
4
|
+
module ESS
|
5
|
+
class Parser
|
6
|
+
def self.parse data
|
7
|
+
doc = REXML::Document.new data
|
8
|
+
ess = doc.root
|
9
|
+
if ess.nil?
|
10
|
+
raise ArgumentError, "the argument has to contain a valid xml document"
|
11
|
+
end
|
12
|
+
new_ess = ESS.new
|
13
|
+
new_ess.disable_postprocessing
|
14
|
+
parse_element(ess, new_ess)
|
15
|
+
new_ess.enable_postprocessing
|
16
|
+
new_ess
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.parse_element element, new_element=nil
|
20
|
+
element.attributes.each_pair do |attr, value|
|
21
|
+
new_element.send(attr + "_attr", value)
|
22
|
+
end
|
23
|
+
element.elements.each do |element|
|
24
|
+
new_element.send("add_" + element.name, element.text) do |new_element|
|
25
|
+
parse_element element, new_element
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
data/lib/ess/postprocessing.rb
CHANGED
@@ -4,6 +4,10 @@ require 'date'
|
|
4
4
|
|
5
5
|
module ESS
|
6
6
|
module Postprocessing
|
7
|
+
##
|
8
|
+
# Varous classes for postprocessing tag values. Should not be used directly,
|
9
|
+
# instances of it's classes are part of the DTD.
|
10
|
+
#
|
7
11
|
class FeedTitle
|
8
12
|
def process feed_tag, title_tag
|
9
13
|
feed_tag.id(title_tag.text!) if feed_tag.id.text! == ""
|
data/lib/ess/pusher.rb
CHANGED
@@ -5,15 +5,53 @@ require 'uri'
|
|
5
5
|
|
6
6
|
module ESS
|
7
7
|
module Pusher
|
8
|
+
##
|
9
|
+
# Sets the default aggregator services. Accepts a list of links in strings.
|
10
|
+
#
|
8
11
|
def self.aggregators= aggs
|
9
12
|
raise ArgumentError, "this method requires a list of links" if aggs.class != Array
|
10
13
|
@@aggregators = aggs
|
11
14
|
end
|
12
15
|
|
16
|
+
##
|
17
|
+
# Returns the aggregator services currently set as default.
|
18
|
+
#
|
13
19
|
def self.aggregators
|
14
20
|
@@aggregators ||= ["http://api.hypecal.com/v1/ess/aggregator.json"]
|
15
21
|
end
|
16
22
|
|
23
|
+
##
|
24
|
+
# Pushes the feed to aggregators.
|
25
|
+
#
|
26
|
+
# === Options
|
27
|
+
#
|
28
|
+
# ==== :data
|
29
|
+
#
|
30
|
+
# A string, with an XML document representing the feed that needs to be
|
31
|
+
# pushed.
|
32
|
+
#
|
33
|
+
# ==== :feed
|
34
|
+
#
|
35
|
+
# This is an alternative to the :data option. This method accepts the feed
|
36
|
+
# link instead of the whole document. The aggregator service will pull the
|
37
|
+
# feed using this link.
|
38
|
+
#
|
39
|
+
# ==== :request
|
40
|
+
#
|
41
|
+
# This should be the request object that generated this feed. It can be
|
42
|
+
# useful for the aggregator service to receive some of th information
|
43
|
+
# from this object for crawling purposes.
|
44
|
+
#
|
45
|
+
# ==== :aggregators
|
46
|
+
#
|
47
|
+
# Intead of using the default aggregator services, this options can be used
|
48
|
+
# to specify what aggregators should the document be pushed to.
|
49
|
+
#
|
50
|
+
# ==== :ignore_errors
|
51
|
+
#
|
52
|
+
# The method will ignore any response from the aggregator services if this
|
53
|
+
# option is true. Default is false.
|
54
|
+
#
|
17
55
|
def self.push_to_aggregators options={}
|
18
56
|
options = { :aggregators => Pusher::aggregators,
|
19
57
|
:feed => nil,
|
data/lib/ess/validation.rb
CHANGED
@@ -1,10 +1,20 @@
|
|
1
1
|
require 'ess/helpers'
|
2
2
|
require 'time'
|
3
|
+
require 'resolv'
|
3
4
|
|
4
5
|
module ESS
|
5
6
|
module Validation
|
7
|
+
##
|
8
|
+
# Varous classes for validation of tag values. Should not be used directly,
|
9
|
+
# instances of it's classes are part of the DTD.
|
10
|
+
#
|
6
11
|
|
7
12
|
class ValidationError < StandardError
|
13
|
+
##
|
14
|
+
# This exception is generated when the validator find an error
|
15
|
+
# in the document. It should contain a message describing what
|
16
|
+
# was the value which caused it to be raised.
|
17
|
+
#
|
8
18
|
end
|
9
19
|
|
10
20
|
class TextIsNotNull
|
@@ -17,7 +27,32 @@ module ESS
|
|
17
27
|
|
18
28
|
class TextIsValidEmail
|
19
29
|
def validate tag
|
20
|
-
|
30
|
+
return if valid_domain?(tag.text!)
|
31
|
+
raise InvalidValueError, "the email \"#{tag.text!}\" could not be validated"
|
32
|
+
end
|
33
|
+
|
34
|
+
EMAIL_PATTERN = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
35
|
+
SERVER_TIMEOUT = 10
|
36
|
+
|
37
|
+
def valid_domain?(email)
|
38
|
+
domain = email.match(EMAIL_PATTERN)[2]
|
39
|
+
dns = Resolv::DNS.new
|
40
|
+
Timeout::timeout(SERVER_TIMEOUT) do
|
41
|
+
|
42
|
+
# Check the MX record
|
43
|
+
mx_records = dns.getresources(domain, Resolv::DNS::Resource::IN::MX)
|
44
|
+
|
45
|
+
mx_records.sort_by {|mx| mx.preference}.each do |mx|
|
46
|
+
a_records = dns.getresources(mx.exchange.to_s, Resolv::DNS::Resource::IN::A)
|
47
|
+
return true if a_records.any?
|
48
|
+
end
|
49
|
+
|
50
|
+
#Try a straight A record
|
51
|
+
a_records = dns.getresources(domain, Resolv::DNS::Resource::IN::A)
|
52
|
+
a_records.any?
|
53
|
+
end
|
54
|
+
rescue Timeout::Error, Errno::ECONNREFUSED
|
55
|
+
false
|
21
56
|
end
|
22
57
|
end
|
23
58
|
|
data/lib/ess/version.rb
CHANGED
@@ -0,0 +1,350 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ESS
|
4
|
+
describe "ESS" do
|
5
|
+
let(:future_year) { Time.now.year + 2 }
|
6
|
+
|
7
|
+
context 'feed with one item with standalone date' do
|
8
|
+
let(:ess) do
|
9
|
+
ess = ESS.new
|
10
|
+
ess.channel.add_feed do |feed|
|
11
|
+
feed.title "Feed 1"
|
12
|
+
feed.dates.add_item do |item|
|
13
|
+
item.type_attr "standalone"
|
14
|
+
item.name "Date 1"
|
15
|
+
item.start Time.parse("#{future_year}-01-01T00:00:00Z")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
ess
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#find_coming' do
|
22
|
+
it 'should return that one item in an array' do
|
23
|
+
feeds = ess.find_coming
|
24
|
+
feeds.length.should == 1
|
25
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#find_between' do
|
30
|
+
it 'should return that one item in an array if it\'s between the two moments in time' do
|
31
|
+
feeds = ess.find_between(Time.parse("#{future_year-1}-12-31T23:59:00Z"), Time.parse("#{future_year}-01-01T00:01:00Z"))
|
32
|
+
feeds.length.should == 1
|
33
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should return an empty array if the item event is not between the two moments in time' do
|
37
|
+
feeds = ess.find_between(Time.parse("#{future_year}-01-01T00:01:00Z"), Time.parse("#{future_year}-01-01T00:03:00Z"))
|
38
|
+
feeds.length.should == 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'ESS channel with two feeds with future standalone dates' do
|
44
|
+
let(:ess) do
|
45
|
+
ess = ESS.new
|
46
|
+
ess.channel.add_feed do |feed|
|
47
|
+
feed.title "Feed 1"
|
48
|
+
feed.dates.add_item do |item|
|
49
|
+
item.type_attr "standalone"
|
50
|
+
item.name "Date 1"
|
51
|
+
item.start Time.parse("#{future_year}-01-01T00:00:00Z")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
ess.channel.add_feed do |feed|
|
55
|
+
feed.title "Feed 2"
|
56
|
+
feed.dates.add_item do |item|
|
57
|
+
item.type_attr "standalone"
|
58
|
+
item.name "Date 1"
|
59
|
+
item.start Time.parse("#{future_year}-01-08T00:00:00Z")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
ess
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#find_coming' do
|
66
|
+
it 'should return both items in an array if no parameters were specified' do
|
67
|
+
feeds = ess.find_coming
|
68
|
+
feeds.length.should == 2
|
69
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
70
|
+
feeds[1][:feed].title.text!.should == "Feed 2"
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should return the first feed in an array if passed the number 1' do
|
74
|
+
feeds = ess.find_coming(1)
|
75
|
+
feeds.length.should == 1
|
76
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should return both items in an array if passed the number 2' do
|
80
|
+
feeds = ess.find_coming(2)
|
81
|
+
feeds.length.should == 2
|
82
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
83
|
+
feeds[1][:feed].title.text!.should == "Feed 2"
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should return both items in an array if passed the number 2, sorted by asc. date/time' do
|
87
|
+
feeds = ess.channel.feed_list
|
88
|
+
tmp1 = feeds[0]
|
89
|
+
tmp2 = feeds[1]
|
90
|
+
ess.channel.feed_list.clear
|
91
|
+
ess.channel.feed_list << tmp2
|
92
|
+
ess.channel.feed_list << tmp1
|
93
|
+
feeds = ess.find_coming(2)
|
94
|
+
feeds.length.should == 2
|
95
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
96
|
+
feeds[1][:feed].title.text!.should == "Feed 2"
|
97
|
+
end
|
98
|
+
it 'should return both items in an array if passed the number 3' do
|
99
|
+
feeds = ess.find_coming(3)
|
100
|
+
feeds.length.should == 2
|
101
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
102
|
+
feeds[1][:feed].title.text!.should == "Feed 2"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#find_between' do
|
107
|
+
it 'should return an empty list if none of the events is between two moments in time' do
|
108
|
+
feeds = ess.find_between(Time.parse("#{future_year-1}-12-21T23:59:00Z"), Time.parse("#{future_year-1}-12-31T00:01:00Z"))
|
109
|
+
feeds.length.should == 0
|
110
|
+
feeds = ess.find_between(Time.parse("#{future_year}-01-10T23:59:00Z"), Time.parse("#{future_year}-01-13T00:01:00Z"))
|
111
|
+
feeds.length.should == 0
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should return the first feed if it is happening between the two dates' do
|
115
|
+
feeds = ess.find_between(Time.parse("#{future_year-1}-12-21T23:59:00Z"), Time.parse("#{future_year}-01-05T00:01:00Z"))
|
116
|
+
feeds.length.should == 1
|
117
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should return the second feed if it is happening between the two dates' do
|
121
|
+
feeds = ess.find_between(Time.parse("#{future_year}-01-01T00:02:00Z"), Time.parse("#{future_year}-01-09T00:01:00Z"))
|
122
|
+
feeds.length.should == 1
|
123
|
+
feeds[0][:feed].title.text!.should == "Feed 2"
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should return both items if they both happen in the interval' do
|
127
|
+
feeds = ess.find_between(Time.parse("#{future_year}-01-01T00:00:00Z"), Time.parse("#{future_year}-01-09T00:01:00Z"))
|
128
|
+
feeds.length.should == 2
|
129
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
130
|
+
feeds[1][:feed].title.text!.should == "Feed 2"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'one feed with two date items with standalone values' do
|
136
|
+
let(:ess) do
|
137
|
+
ess = ESS.new
|
138
|
+
ess.channel.add_feed do |feed|
|
139
|
+
feed.title "Feed 1"
|
140
|
+
feed.dates.add_item do |item|
|
141
|
+
item.type_attr "standalone"
|
142
|
+
item.name "Date 2"
|
143
|
+
item.start Time.parse("#{future_year}-01-01T00:15:00Z")
|
144
|
+
end
|
145
|
+
feed.dates.add_item do |item|
|
146
|
+
item.type_attr "standalone"
|
147
|
+
item.name "Date 1"
|
148
|
+
item.start Time.parse("#{future_year}-01-01T00:00:00Z")
|
149
|
+
end
|
150
|
+
end
|
151
|
+
ess
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "#find_coming" do
|
155
|
+
it 'should return two items in a list, if no arguments are passed' do
|
156
|
+
ess.find_coming.length.should == 2
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should return one item in a list, if the only argument is a 1' do
|
160
|
+
ess.find_coming(1).length.should == 1
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should return a list of dicts, with keys :time and :feed' do
|
164
|
+
feeds = ess.find_coming
|
165
|
+
feeds.each do |feed|
|
166
|
+
feed[:time].should_not be_nil
|
167
|
+
feed[:feed].should_not be_nil
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should return a list of discts sorted by ascending order of time' do
|
172
|
+
feeds = ess.find_coming
|
173
|
+
feeds[0][:time].should == Time.parse("#{future_year}-01-01T00:00:00Z")
|
174
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
175
|
+
feeds[1][:time].should == Time.parse("#{future_year}-01-01T00:15:00Z")
|
176
|
+
feeds[1][:feed].title.text!.should == "Feed 1"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "#find_between" do
|
181
|
+
it 'should return two items in a list, if both date items are within the time period' do
|
182
|
+
feeds = ess.find_between(Time.parse("#{future_year}-01-01T00:00:00Z"), Time.parse("#{future_year}-01-09T00:01:00Z"))
|
183
|
+
feeds.length == 2
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should return two hashes in a list, with :time and :feed values defined' do
|
187
|
+
feeds = ess.find_between(Time.parse("#{future_year}-01-01T00:00:00Z"), Time.parse("#{future_year}-01-09T00:01:00Z"))
|
188
|
+
feeds.each do |feed|
|
189
|
+
feed[:time].should_not be_nil
|
190
|
+
feed[:feed].should_not be_nil
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'should return a list of dicts sorted by ascending order of time' do
|
195
|
+
feeds = ess.find_coming
|
196
|
+
feeds[0][:time].should == Time.parse("#{future_year}-01-01T00:00:00Z")
|
197
|
+
feeds[0][:feed].title.text!.should == "Feed 1"
|
198
|
+
feeds[1][:time].should == Time.parse("#{future_year}-01-01T00:15:00Z")
|
199
|
+
feeds[1][:feed].title.text!.should == "Feed 1"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'feed with one item with recurring date with a limit attribute' do
|
205
|
+
let(:ess) do
|
206
|
+
ess = ESS.new
|
207
|
+
ess.channel.add_feed do |feed|
|
208
|
+
feed.title "Feed 1"
|
209
|
+
feed.dates.add_item do |item|
|
210
|
+
item.type_attr "recurrent"
|
211
|
+
item.unit_attr "month"
|
212
|
+
item.limit_attr "5"
|
213
|
+
item.name "Date 1"
|
214
|
+
item.start Time.parse("#{future_year}-01-01T00:00:00Z")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
ess
|
218
|
+
end
|
219
|
+
|
220
|
+
describe "#find_coming" do
|
221
|
+
it 'should return the array with as much elements, as there will be separate events' do
|
222
|
+
ess.find_coming.length.should == 5
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'should return a list of feeds, sorted by starting date/time' do
|
226
|
+
feeds = ess.find_coming
|
227
|
+
feeds[0][:time].should == Time.parse("#{future_year}-01-01T00:00:00Z")
|
228
|
+
feeds[1][:time].should == Time.parse("#{future_year}-02-01T00:00:00Z")
|
229
|
+
feeds[2][:time].should == Time.parse("#{future_year}-03-01T00:00:00Z")
|
230
|
+
feeds[3][:time].should == Time.parse("#{future_year}-04-01T00:00:00Z")
|
231
|
+
feeds[4][:time].should == Time.parse("#{future_year}-05-01T00:00:00Z")
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "#find_coming" do
|
236
|
+
it 'should return a list of event instances within time boundaries' do
|
237
|
+
feeds = ess.find_between(Time.parse("#{future_year}-02-11T00:00:00Z"), Time.parse("#{future_year}-07-11T12:00:00Z"))
|
238
|
+
feeds.length.should == 3
|
239
|
+
feeds[0][:time].should == Time.parse("#{future_year}-03-01T00:00:00Z")
|
240
|
+
feeds[1][:time].should == Time.parse("#{future_year}-04-01T00:00:00Z")
|
241
|
+
feeds[2][:time].should == Time.parse("#{future_year}-05-01T00:00:00Z")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context 'feed with one item with recurring date with a limit attribute and an interval attribute' do
|
247
|
+
let(:ess) do
|
248
|
+
ess = ESS.new
|
249
|
+
ess.channel.add_feed do |feed|
|
250
|
+
feed.title "Feed 1"
|
251
|
+
feed.dates.add_item do |item|
|
252
|
+
item.type_attr "recurrent"
|
253
|
+
item.unit_attr "month"
|
254
|
+
item.interval_attr "2"
|
255
|
+
item.limit_attr "5"
|
256
|
+
item.name "Date 1"
|
257
|
+
item.start Time.parse("#{future_year}-01-01T00:00:00Z")
|
258
|
+
end
|
259
|
+
end
|
260
|
+
ess
|
261
|
+
end
|
262
|
+
|
263
|
+
describe "#find_coming" do
|
264
|
+
it 'should return the array with as much elements, as there will be separate events' do
|
265
|
+
ess.find_coming.length.should == 5
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should return a list of feeds, sorted by starting date/time' do
|
269
|
+
feeds = ess.find_coming
|
270
|
+
feeds[0][:time].should == Time.parse("#{future_year}-01-01T00:00:00Z")
|
271
|
+
feeds[1][:time].should == Time.parse("#{future_year}-03-01T00:00:00Z")
|
272
|
+
feeds[2][:time].should == Time.parse("#{future_year}-05-01T00:00:00Z")
|
273
|
+
feeds[3][:time].should == Time.parse("#{future_year}-07-01T00:00:00Z")
|
274
|
+
feeds[4][:time].should == Time.parse("#{future_year}-09-01T00:00:00Z")
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe "#find_between" do
|
279
|
+
it 'should return a list of feeds between the two dates it received as parameters' do
|
280
|
+
feeds = ess.find_between(Time.parse("#{future_year}-03-11T00:00:00Z"), Time.parse("#{future_year}-10-11T00:00:00Z"))
|
281
|
+
feeds.length.should == 3
|
282
|
+
feeds[0][:time].should == Time.parse("#{future_year}-05-01T00:00:00Z")
|
283
|
+
feeds[1][:time].should == Time.parse("#{future_year}-07-01T00:00:00Z")
|
284
|
+
feeds[2][:time].should == Time.parse("#{future_year}-09-01T00:00:00Z")
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context 'feed with one item with recurring date with a limit attribute and a selected_day attribute' do
|
290
|
+
let(:ess) do
|
291
|
+
ess = ESS.new
|
292
|
+
ess.channel.add_feed do |feed|
|
293
|
+
feed.title "Feed 1"
|
294
|
+
feed.dates.add_item do |item|
|
295
|
+
item.type_attr "recurrent"
|
296
|
+
item.unit_attr "month"
|
297
|
+
item.limit_attr "5"
|
298
|
+
item.selected_day_attr "2"
|
299
|
+
item.name "Date 1"
|
300
|
+
item.start Time.parse("#{future_year}-01-02T00:00:00Z")
|
301
|
+
end
|
302
|
+
end
|
303
|
+
ess
|
304
|
+
end
|
305
|
+
|
306
|
+
describe "#find_coming" do
|
307
|
+
it 'should return events only on those days specified in the selected_day attribute' do
|
308
|
+
feeds = ess.find_coming
|
309
|
+
feeds.length.should == 5
|
310
|
+
feeds[0][:time].should == Time.parse("#{future_year}-01-02T00:00:00Z")
|
311
|
+
feeds[1][:time].should == Time.parse("#{future_year}-02-02T00:00:00Z")
|
312
|
+
feeds[2][:time].should == Time.parse("#{future_year}-03-02T00:00:00Z")
|
313
|
+
feeds[3][:time].should == Time.parse("#{future_year}-04-02T00:00:00Z")
|
314
|
+
feeds[4][:time].should == Time.parse("#{future_year}-05-02T00:00:00Z")
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'should support using day names' do
|
318
|
+
ess.channel.feed.dates.item.selected_day_attr "monday"
|
319
|
+
feeds = ess.find_coming(30)
|
320
|
+
feeds.length.should be > 19
|
321
|
+
feeds.length.should be < 26
|
322
|
+
feeds.each do |event|
|
323
|
+
event[:time].wday.should == 1
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
describe "#find_between" do
|
329
|
+
it 'should return events only on those days specified in the selected_day attribute' do
|
330
|
+
feeds = ess.find_between(Time.parse("#{future_year}-01-05 00:00"), Time.parse("#{future_year}-04-06T00:00:00Z"))
|
331
|
+
feeds.length.should == 3
|
332
|
+
feeds[0][:time].should == Time.parse("#{future_year}-02-02T00:00:00Z")
|
333
|
+
feeds[1][:time].should == Time.parse("#{future_year}-03-02T00:00:00Z")
|
334
|
+
feeds[2][:time].should == Time.parse("#{future_year}-04-02T00:00:00Z")
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'should support using day names' do
|
338
|
+
ess.channel.feed.dates.item.selected_day_attr "monday"
|
339
|
+
feeds = ess.find_between(Time.parse("#{future_year}-02-01T00:00:00Z"), Time.parse("#{future_year}-04-30T00:00:00Z"))
|
340
|
+
feeds.length.should be > 11
|
341
|
+
feeds.length.should be < 16
|
342
|
+
feeds.each do |event|
|
343
|
+
event[:time].wday.should == 1
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|