tickle 1.2.0 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,94 @@
1
+ module Tickle
2
+
3
+ require 'numerizer'
4
+ require_relative "repeater.rb"
5
+
6
+ # An extended String
7
+ class Token < ::String
8
+ attr_accessor :original
9
+
10
+
11
+ # !@attribute [rw] word Normalized original
12
+ # @return [String]
13
+ attr_accessor:word
14
+
15
+ attr_accessor :type, :interval, :start
16
+
17
+
18
+ # @param [#downcase] original
19
+ # @param [Hash] options
20
+ # @option options [String] :word Normalized original, the implied word
21
+ def initialize(original, options={})
22
+ @original = original
23
+ @word = options[:word]
24
+ @type = options[:type]
25
+ @interval = options[:interval]
26
+ @start = options[:start]
27
+ super @original
28
+ end
29
+
30
+
31
+ def update!(options={})
32
+ options = {
33
+ :start => nil,
34
+ :interval => nil,
35
+ }.merge( options )
36
+ fail ArgumentError, "Token#update! must be passed a 'type'" if options.nil? or options.empty? or not options.has_key?(:type) or options[:type].nil?
37
+
38
+ @type = options[:type]
39
+ @start = options[:start]
40
+ @interval = options[:interval]
41
+ self
42
+ end
43
+
44
+
45
+ COMMON_SYMBOLS = %r{
46
+ (
47
+ [ / \- , @ ]
48
+ )
49
+ }x
50
+
51
+
52
+ # Clean up the specified input text by stripping unwanted characters,
53
+ # converting idioms to their canonical form, converting number words
54
+ # to numbers (three => 3), and converting ordinal words to numeric
55
+ # ordinals (third => 3rd)
56
+ def normalize!
57
+ @word = Numerizer.numerize(@original.downcase)
58
+ .gsub(/['"\.]/, '')
59
+ .gsub(COMMON_SYMBOLS) {" #{$1} "}
60
+ self
61
+ end
62
+
63
+
64
+ # Split the text on spaces and convert each word into
65
+ # a Token
66
+ # @param [#split] text The text to be tokenized.
67
+ # @return [Array<Token>] The tokens.
68
+ def self.tokenize(text)
69
+ fail ArgumentError unless text.respond_to? :split
70
+ text.split(/\s+/).map { |word| Token.new(word) }
71
+ end
72
+
73
+
74
+ # Returns an array of types for all tokens
75
+ def self.types(tokens)
76
+ tokens.map(&:type)
77
+ end
78
+
79
+
80
+ def self.token_of_type(type, tokens)
81
+ tokens.detect {|token| token.type == type}
82
+ end
83
+
84
+
85
+ # @return [Array<Tickle::Token>]
86
+ def self.scan!( tokens )
87
+ fail ArgumentError, "Token#scan must be provided with and Array of Tokens to work with." unless tokens.respond_to? :each
88
+ repeater = Repeater.new tokens
89
+ repeater.scan!
90
+ repeater.tokens
91
+ end
92
+
93
+ end
94
+ end
@@ -1,5 +1,5 @@
1
1
  module Tickle
2
2
 
3
3
  # This library's current version.
4
- VERSION = "1.2.0"
4
+ VERSION = "2.0.0.rc1"
5
5
  end
@@ -0,0 +1,36 @@
1
+ require "spec_helper"
2
+ require_relative "../lib/tickle/helpers.rb"
3
+
4
+
5
+ module Tickle # for convenience
6
+
7
+
8
+ describe "Helpers module" do
9
+
10
+ describe "combine_multiple_numbers" do
11
+ subject(:out) { Helpers.combine_multiple_numbers tokens}
12
+ context "When given an empty set" do
13
+ let(:tokens) { [] }
14
+ it { should == [] }
15
+ end
16
+ context "When given compound numbers" do
17
+ context "like 'twenty first'" do
18
+ let(:tokens) { [
19
+ Token.new("twenty", word: "20", type: :number, start: 20, interval: 20),
20
+ Token.new("first", word: "1st", type: :ordinal, start: 1, interval: 1),
21
+ ] }
22
+ subject{ out.first }
23
+ its(:original) { should == "twenty first" }
24
+ its(:word) { should == "21st" }
25
+ its(:type) { should == :ordinal }
26
+ its(:start) { should == "21"}
27
+ its(:interval) {should == 365 }
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+
36
+ end # of convenience
@@ -0,0 +1,240 @@
1
+ require 'spec_helper'
2
+ require_relative "../lib/tickle/patterns.rb"
3
+
4
+ module Tickle # for convenience
5
+
6
+ # TODO move these to patterns_spec
7
+ describe "Patterns" do
8
+ let(:example1) { "every thursday starting tomorrow until May 15th" }
9
+ let(:example2) { "starting thursday every Tuesday until May 15th" }
10
+ let(:example3) { "every thursday starting tomorrow until May 15th" }
11
+ let(:example4) { "starting thursday on the 5th day of each month until May 15th" }
12
+ describe "START_EVERY_REGEX" do
13
+ context "Given example1" do
14
+ subject { Patterns::START_EVERY_REGEX.match example1 }
15
+ it { should be_nil }
16
+ end
17
+ context "Given example2" do
18
+ subject { Patterns::START_EVERY_REGEX.match example2 }
19
+ it { should_not be_nil }
20
+ end
21
+ context "Given example3" do
22
+ subject { Patterns::START_EVERY_REGEX.match example3 }
23
+ it { should be_nil }
24
+ end
25
+ context "Given example4" do
26
+ subject { Patterns::START_EVERY_REGEX.match example4 }
27
+ it { should_not be_nil }
28
+ end
29
+ end
30
+ describe "EVERY_START_REGEX" do
31
+ context "Given example1" do
32
+ subject { Patterns::EVERY_START_REGEX.match example1 }
33
+ it { should_not be_nil }
34
+ end
35
+ context "Given example2" do
36
+ subject { Patterns::EVERY_START_REGEX.match example2 }
37
+ it { should be_nil }
38
+ end
39
+ context "Given example3" do
40
+ subject { Patterns::EVERY_START_REGEX.match example3 }
41
+ it { should_not be_nil }
42
+ end
43
+ context "Given example4" do
44
+ subject { Patterns::EVERY_START_REGEX.match example4 }
45
+ it { should be_nil }
46
+ end
47
+ end
48
+ describe "START_ENDING_REGEX" do
49
+ context "Given example1" do
50
+ subject { Patterns::START_ENDING_REGEX.match example1 }
51
+ it { should be_nil }
52
+ end
53
+ context "Given example2" do
54
+ subject { Patterns::START_ENDING_REGEX.match example2 }
55
+ it { should_not be_nil }
56
+ end
57
+ context "Given example3" do
58
+ subject { Patterns::START_ENDING_REGEX.match example3 }
59
+ it { should be_nil }
60
+ end
61
+ context "Given example4" do
62
+ subject { Patterns::START_ENDING_REGEX.match example4 }
63
+ it { should_not be_nil }
64
+ end
65
+ end
66
+
67
+
68
+ describe "SET_IDENTIFIER" do
69
+ subject { Patterns::SET_IDENTIFIER }
70
+ context "Given 'every'" do
71
+ it { should match "every" }
72
+ end
73
+ context "Given 'each'" do
74
+ it { should match "each" }
75
+ end
76
+ context "Given 'on'" do
77
+ it { should match "on" }
78
+ end
79
+ context "Given 'on the'" do
80
+ it { should match "on the" }
81
+ end
82
+ end
83
+
84
+ describe "REPETITION" do
85
+ subject { Patterns::REPETITION }
86
+ context "Given 'repeat'" do
87
+ it { should match "repeat" }
88
+ end
89
+ end
90
+
91
+ describe "ON_THE" do
92
+ subject { Patterns::ON_THE }
93
+ context "Given 'on'" do
94
+ it { should match "on" }
95
+ end
96
+ context "Given 'on the'" do
97
+ it { should match "on the" }
98
+ end
99
+ end
100
+
101
+ describe "END_OR_UNTIL" do
102
+ subject { Patterns::END_OR_UNTIL }
103
+ context "Given 'end'" do
104
+ it { should match "end" }
105
+ end
106
+ context "Given 'ends'" do
107
+ it { should match "ends" }
108
+ end
109
+ context "Given 'ends on'" do
110
+ it { should match "ends on" }
111
+ end
112
+ context "Given 'ends on the'" do
113
+ it { should match "ends on the" }
114
+ end
115
+ context "Given 'ending'" do
116
+ it { should match "ending" }
117
+ end
118
+ context "Given 'ending on'" do
119
+ it { should match "ending on" }
120
+ end
121
+ context "Given 'ending on the'" do
122
+ it { should match "ending on the" }
123
+ end
124
+ context "Given 'until'" do
125
+ it { should match "until" }
126
+ end
127
+ context "Given 'until the'" do
128
+ it { should match "until the" }
129
+ end
130
+ context "Given 'send'" do
131
+ it { should_not match "send" }
132
+ end
133
+ end
134
+
135
+ describe "PLURAL_OR_PRESENT_PARTICIPLE" do
136
+ subject { Patterns::PLURAL_OR_PRESENT_PARTICIPLE }
137
+ context "Given 's'" do
138
+ it { should match "s" }
139
+ end
140
+ context "Given 'ing'" do
141
+ it { should match "ing" }
142
+ end
143
+ end
144
+
145
+ describe "START" do
146
+ subject { Patterns::START }
147
+ context "Given 'starting'" do
148
+ it { should match "starting" }
149
+ end
150
+ context "Given 'starts'" do
151
+ it { should match "starts" }
152
+ end
153
+ context "Given 'start'" do
154
+ it { should match "start" }
155
+ end
156
+ end
157
+
158
+ describe "START_EVERY_REGEX" do
159
+ subject { Patterns::START_EVERY_REGEX }
160
+ context "Given 'starting today on the 12th'" do
161
+ let(:phrase) { "starting today on the 12th" }
162
+ it { should match phrase }
163
+ its(:names) { should =~ %w{start event repeat} }
164
+ describe "Captures" do
165
+ subject { Patterns::START_EVERY_REGEX.match phrase }
166
+ its([:start]) { should == "today" }
167
+ its([:event]) { should == "12th" }
168
+ end
169
+ end
170
+ context "Given 'starting Monday repeat every month'" do
171
+ let(:phrase) { "starting Monday repeat every month" }
172
+ it { should match phrase }
173
+ describe "Captures" do
174
+ subject { Patterns::START_EVERY_REGEX.match phrase }
175
+ its([:start]) { should == "Monday" }
176
+ its([:event]) { should == "month" }
177
+ end
178
+ end
179
+ end
180
+
181
+ describe "START_ENDING_REGEX" do
182
+ subject { Patterns::START_ENDING_REGEX }
183
+ context "Given 'starting today until the 12th'" do
184
+ let(:phrase) { "starting today until the 12th" }
185
+ it { should match phrase }
186
+ describe "Captures" do
187
+ subject { Patterns::START_ENDING_REGEX.match phrase }
188
+ its([:start]) { should == "today" }
189
+ its([:finish]) { should == "12th" }
190
+ end
191
+ end
192
+ context "Given 'starting today and ending one week from now'" do
193
+ let(:phrase) { "starting today and ending one week from now"}
194
+ it { should match phrase }
195
+ describe "Captures" do
196
+ subject { Patterns::START_ENDING_REGEX.match phrase }
197
+ its([:start]) { should == "today" }
198
+ its([:finish]) { should == "one week from now" }
199
+ end
200
+ end
201
+ end
202
+
203
+ describe "EVERY_START_REGEX" do
204
+ subject { Patterns::EVERY_START_REGEX }
205
+ context "Given 'every Monday starting the 12th'" do
206
+ let(:phrase) { "every Monday starting on the 12th" }
207
+ it { should match phrase }
208
+ describe "Captures" do
209
+ subject { Patterns::EVERY_START_REGEX.match phrase }
210
+ its([:start]) { should == "12th" }
211
+ its([:event]) { should == "Monday" }
212
+ end
213
+ end
214
+ end
215
+
216
+ describe "PROCESS_FOR_ENDING" do
217
+ subject { Patterns::PROCESS_FOR_ENDING }
218
+ context "Given 'Monday until the 12th'" do
219
+ let(:phrase) { "Monday until the 12th" }
220
+ it { should match phrase }
221
+ describe "Captures" do
222
+ subject { Patterns::PROCESS_FOR_ENDING.match phrase }
223
+ its([:target]) { should == "Monday" }
224
+ its([:ending]) { should == "12th" }
225
+ end
226
+ end
227
+ context "Given 'Tuesday ending on the 12th'" do
228
+ let(:phrase) { "Tuesday ending on the 12th" }
229
+ it { should match phrase }
230
+ describe "Captures" do
231
+ subject { Patterns::PROCESS_FOR_ENDING.match phrase }
232
+ its([:target]) { should == "Tuesday" }
233
+ its([:ending]) { should == "12th" }
234
+ end
235
+ end
236
+ end
237
+
238
+
239
+ end
240
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rspec'
4
+ require 'rspec/its'
5
+ Spec_dir = File.expand_path( File.dirname __FILE__ )
6
+
7
+
8
+ # code coverage
9
+ require 'simplecov'
10
+ SimpleCov.start do
11
+ add_filter "/vendor/"
12
+ add_filter "/bin/"
13
+ add_filter "/spec/"
14
+ end
15
+
16
+
17
+ Dir[ File.join( Spec_dir, "/support/**/*.rb")].each do |f|
18
+ require f
19
+ end
20
+
21
+ Time_now = Time.parse "2010-05-09 20:57:36 +0000"
22
+
23
+ require 'timecop'
24
+
25
+ RSpec.configure do |config|
26
+ config.expect_with :rspec do |c|
27
+ c.syntax = [:should, :expect]
28
+ end
29
+
30
+ tz = ENV["TZ"]
31
+ config.before(:all, :frozen => true) do
32
+ Timecop.freeze Time_now
33
+ ENV["TZ"] = "UTC"
34
+ end
35
+ config.after(:all, :frozen => true) do
36
+ Timecop.return
37
+ ENV["TZ"] = tz
38
+ end
39
+ end
40
+
41
+ warn "Actual Time now => #{Time.now}"
@@ -0,0 +1,543 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+ require_relative "../lib/tickle.rb"
5
+ require 'timecop'
6
+
7
+ module Tickle # for convenience
8
+
9
+ day = 86400
10
+
11
+ describe "Parsing" do
12
+
13
+ describe "parse", :integration => true do
14
+
15
+ context "Asked with an object that responds to :to_time" do
16
+ describe "Returning it immediately" do
17
+ let(:expected) { Date.parse("7th October 2015") }
18
+ subject{ Tickle.parse(expected) }
19
+ it { should == expected }
20
+ end
21
+ end
22
+
23
+ context "Simple examples", :frozen => true do
24
+
25
+ # Can't use second as it clashes with date ordinal names
26
+ context "seconds" do
27
+ subject{ Tickle.parse('seconds') }
28
+ let(:expected) { {:next=>Time.parse("2010-05-09 20:57:37 +0000"), :expression=>"seconds", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
29
+ it { should == expected }
30
+ end
31
+
32
+ # Other variant for seconds
33
+ context "sec" do
34
+ subject{ Tickle.parse('sec') }
35
+ let(:expected) { {:next=>Time.parse("2010-05-09 20:57:37 +0000"), :expression=>"sec", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
36
+ it { should == expected }
37
+ end
38
+
39
+ context "minute" do
40
+ subject{ Tickle.parse('minute') }
41
+ let(:expected) { {:next=>Time.parse("2010-05-09 20:58:36 +0000"), :expression=>"minute", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
42
+ xit { should == expected }
43
+ end
44
+
45
+ context "hour" do
46
+ subject{ Tickle.parse('hour') }
47
+ let(:expected) { {:next=>Time.parse("2010-05-09 21:57:36 +0000"), :expression=>"hour", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
48
+ xit { should == expected }
49
+ end
50
+
51
+ context "day" do
52
+ subject{ Tickle.parse('day') }
53
+ let(:expected) { {:next=>Time.parse("2010-05-10 20:57:36 +0000"), :expression=>"day", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
54
+ it { should == expected }
55
+ end
56
+
57
+ context "week" do
58
+ subject{ Tickle.parse('week') }
59
+ let(:expected) { {:next=>Time.parse("2010-05-16 20:57:36 +0000"), :expression=>"week", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
60
+ it { should == expected }
61
+ end
62
+
63
+ context "month" do
64
+ subject{ Tickle.parse('month') }
65
+ let(:expected) { {:next=>Time.parse("2010-06-09 20:57:36 +0000"), :expression=>"month", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
66
+ it { should == expected }
67
+ end
68
+
69
+ context "year" do
70
+ subject{ Tickle.parse('year') }
71
+ let(:expected) { {:next=>Time.parse("2011-05-09 20:57:36 +0000"), :expression=>"year", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
72
+ it { should == expected }
73
+ end
74
+
75
+ context "hourly" do
76
+ subject{ Tickle.parse('hourly') }
77
+ let(:expected) { {:next=>Time.parse("2010-05-09 21:57:36 +0000"), :expression=>"hourly", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
78
+ xit { should == expected }
79
+ end
80
+
81
+ context "daily" do
82
+ subject{ Tickle.parse('daily') }
83
+ let(:expected) { {:next=>Time.parse("2010-05-10 20:57:36 +0000"), :expression=>"daily", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
84
+ it { should == expected }
85
+ end
86
+
87
+ context "weekly" do
88
+ subject{ Tickle.parse('weekly') }
89
+ let(:expected) { {:next=>Time.parse("2010-05-16 20:57:36 +0000"), :expression=>"weekly", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
90
+ it { should == expected }
91
+ end
92
+
93
+ context "monthly" do
94
+ subject{ Tickle.parse('monthly') }
95
+ let(:expected) { {:next=>Time.parse("2010-06-09 20:57:36 +0000"), :expression=>"monthly", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
96
+ it { should == expected }
97
+ end
98
+
99
+ context "yearly" do
100
+ subject{ Tickle.parse('yearly') }
101
+ let(:expected) { {:next=>Time.parse("2011-05-09 20:57:36 +0000"), :expression=>"yearly", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
102
+ it { should == expected }
103
+ end
104
+
105
+ context "3 seconds" do
106
+ subject{ Tickle.parse('3 seconds') }
107
+ let(:expected) { {:next=>Time.parse("2010-05-09 20:57:39 +0000"), :expression=>"3 seconds", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
108
+ it { should == expected }
109
+ end
110
+
111
+ context "3 sec" do
112
+ subject{ Tickle.parse('3 sec') }
113
+ let(:expected) { {:next=>Time.parse("2010-05-09 20:57:39 +0000"), :expression=>"3 sec", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
114
+ it { should == expected }
115
+ end
116
+
117
+ context "3 minutes" do
118
+ subject{ Tickle.parse('3 minutes') }
119
+ let(:expected) { {:next=>Time.parse("2010-05-09 21:00:36 +0000"), :expression=>"3 minutes", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
120
+ xit { should == expected }
121
+ end
122
+
123
+ context "3 hours" do
124
+ subject{ Tickle.parse('3 hours') }
125
+ let(:expected) { {:next=>Time.parse("2010-05-09 23:57:36 +0000"), :expression=>"3 hours", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
126
+ xit { should == expected }
127
+ end
128
+
129
+ context "3 days" do
130
+ subject{ Tickle.parse('3 days') }
131
+ let(:expected) { {:next=>Time.parse("2010-05-12 20:57:36 +0000"), :expression=>"3 days", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
132
+ it { should == expected }
133
+ end
134
+
135
+ context "3 weeks" do
136
+ subject{ Tickle.parse('3 weeks') }
137
+ let(:expected) { {:next=>Time.parse("2010-05-30 20:57:36 +0000"), :expression=>"3 weeks", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
138
+ it { should == expected }
139
+ end
140
+
141
+ context "3 months" do
142
+ subject{ Tickle.parse('3 months') }
143
+ let(:expected) { {:next=>Time.parse("2010-08-09 20:57:36 +0000"), :expression=>"3 months", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
144
+ it { should == expected }
145
+ end
146
+
147
+ context "3 years" do
148
+ subject{ Tickle.parse('3 years') }
149
+ let(:expected) { {:next=>Time.parse("2013-05-09 20:57:36 +0000"), :expression=>"3 years", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
150
+ it { should == expected }
151
+ end
152
+
153
+ context "other seconds" do
154
+ subject{ Tickle.parse('other second') }
155
+ let(:expected) { {:next=>Time.parse("2010-05-09 20:57:38 +0000"), :expression=>"other second", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
156
+ xit { should == expected }
157
+ end
158
+
159
+ context "other sec" do
160
+ subject{ Tickle.parse('other second') }
161
+ let(:expected) { {:next=>Time.parse("2010-05-09 20:57:38 +0000"), :expression=>"other second", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
162
+ xit { should == expected }
163
+ end
164
+
165
+ context "other minute" do
166
+ subject{ Tickle.parse('other minute') }
167
+ let(:expected) { {:next=>Time.parse("2010-05-09 20:59:36 +0000"), :expression=>"other minute", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
168
+ xit { should == expected }
169
+ end
170
+
171
+ context "other hour" do
172
+ subject{ Tickle.parse('other hour') }
173
+ let(:expected) { {:next=>Time.parse("2010-05-09 22:57:36 +0000"), :expression=>"other hour", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
174
+ xit { should == expected }
175
+ end
176
+
177
+ context "other day" do
178
+ subject{ Tickle.parse('other day') }
179
+ let(:expected) { {:next=>Time.parse("2010-05-11 20:57:36 +0000"), :expression=>"other day", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
180
+ it { should == expected }
181
+ end
182
+
183
+ context "other week" do
184
+ subject{ Tickle.parse('other week') }
185
+ let(:expected) { {:next=>Time.parse("2010-05-23 20:57:36 +0000"), :expression=>"other week", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
186
+ it { should == expected }
187
+ end
188
+
189
+ context "other month" do
190
+ subject{ Tickle.parse('other month') }
191
+ let(:expected) { {:next=>Time.parse("2010-07-09 20:57:36 +0000"), :expression=>"other month", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
192
+ it { should == expected }
193
+ end
194
+
195
+ context "other year" do
196
+ subject{ Tickle.parse('other year') }
197
+ let(:expected) { {:next=>Time.parse("2012-05-09 20:57:36 +0000"), :expression=>"other year", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
198
+ it { should == expected }
199
+ end
200
+
201
+ context "noon" do
202
+ subject{ Tickle.parse('noon') }
203
+ let(:expected) { {:next=>Time.parse("2010-05-10 12:00:00 +0000"), :expression=>"12:00", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
204
+ xit { should == expected }
205
+ end
206
+
207
+ context "midnight" do
208
+ subject{ Tickle.parse('noon') }
209
+ let(:expected) { {:next=>Time.parse("2010-05-10 00:00:00 +0000"), :expression=>"00:00", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
210
+ xit { should == expected }
211
+ end
212
+
213
+ context "Monday" do
214
+ subject{ Tickle.parse('Monday') }
215
+ let(:expected) { {:next=>Time.parse("2010-05-10 12:00:00 +0000"), :expression=>"monday", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
216
+ it { should == expected }
217
+ end
218
+
219
+ context "Wednesday" do
220
+ subject{ Tickle.parse('Wednesday') }
221
+ let(:expected) { {:next=>Time.parse("2010-05-12 12:00:00 +0000"), :expression=>"wednesday", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
222
+ it { should == expected }
223
+ end
224
+
225
+ context "Friday" do
226
+ subject{ Tickle.parse('Friday') }
227
+ let(:expected) { {:next=>Time.parse("2010-05-14 12:00:00 +0000"), :expression=>"friday", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
228
+ it { should == expected }
229
+ end
230
+
231
+ context "With time specified", :frozen => true do
232
+ context "Monday at 3am" do
233
+ subject{ Tickle.parse('Monday at 3am') }
234
+ let(:expected) { {:next=>Time.parse("2010-05-10 15:00:00 +0000"), :expression=>"monday 15:00", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
235
+ xit { should == expected }
236
+ end
237
+ context "daily 16:23" do
238
+ subject{ Tickle.parse('daily') }
239
+ let(:expected) { {:next=>Time.parse("2010-05-10 16:23:00 +0000"), :expression=>"daily 16:23", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
240
+ xit { should == expected }
241
+ end
242
+ end
243
+
244
+ context "Given that now is in the future, 2020-04-01 00:00:00 +0000" do
245
+ context "February" do
246
+ subject{ Tickle.parse('February', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
247
+ let(:expected) { {:next=>Time.parse("2021-02-01 12:00:00 +0000"), :expression=>"february", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
248
+ it { should == expected }
249
+ end
250
+
251
+ context "May" do
252
+ subject{ Tickle.parse('May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
253
+ let(:expected) { {:next=>Time.parse("2020-05-01 12:00:00 +0000"), :expression=>"may", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
254
+ it { should == expected }
255
+ end
256
+
257
+ context "june" do
258
+ subject{ Tickle.parse('june', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
259
+ let(:expected) { {:next=>Time.parse("2020-06-01 12:00:00 +0000"), :expression=>"june", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
260
+ it { should == expected }
261
+ end
262
+
263
+ context "beginning of the month" do
264
+ subject{ Tickle.parse('beginning of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
265
+ let(:expected) { {:next=>Time.parse("2020-05-01 00:00:00 +0000"), :expression=>"beginning of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
266
+ it { should == expected }
267
+ end
268
+
269
+ context "middle of the month" do
270
+ subject{ Tickle.parse('middle of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
271
+ let(:expected) { {:next=>Time.parse("2020-04-15 00:00:00 +0000"), :expression=>"middle of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
272
+ it { should == expected }
273
+ end
274
+
275
+ context "end of the month" do
276
+ subject{ Tickle.parse('end of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
277
+ let(:expected) { {:next=>Time.parse("2020-04-30 00:00:00 +0000"), :expression=>"end of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
278
+ it { should == expected }
279
+ end
280
+
281
+ context "beginning of the year" do
282
+ subject{ Tickle.parse('beginning of the year', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
283
+ let(:expected) { {:next=>Time.parse("2021-01-01 00:00:00 +0000"), :expression=>"beginning of the year", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
284
+ it { should == expected }
285
+ end
286
+
287
+ context "middle of the year" do
288
+ subject{ Tickle.parse('middle of the year', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
289
+ let(:expected) { {:next=>Time.parse("2020-06-15 00:00:00 +0000"), :expression=>"middle of the year", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
290
+ it { should == expected }
291
+ end
292
+
293
+ context "end of the year" do
294
+ subject{ Tickle.parse('end of the year', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
295
+ let(:expected) { {:next=>Time.parse("2020-12-31 00:00:00 +0000"), :expression=>"end of the year", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
296
+ it { should == expected }
297
+ end
298
+
299
+ context "the 3rd of May" do
300
+ subject{ Tickle.parse('the 3rd of May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
301
+ let(:expected) { {:next=>Time.parse("2020-05-03 00:00:00 +0000"), :expression=>"the 3rd of may", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
302
+ it { should == expected }
303
+ end
304
+
305
+ context "the 3rd of February" do
306
+ subject{ Tickle.parse('the 3rd of February', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
307
+ let(:expected) { {:next=>Time.parse("2021-02-03 00:00:00 +0000"), :expression=>"the 3rd of february", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
308
+ it { should == expected }
309
+ end
310
+
311
+ context "the 3rd of February 2022" do
312
+ subject{ Tickle.parse('the 3rd of February 2022', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
313
+ let(:expected) { {:next=>Time.parse("2022-02-03 00:00:00 +0000"), :expression=>"the 3rd of february 2022", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
314
+ it { should == expected }
315
+ end
316
+
317
+ context "the 3rd of Feb 2022" do
318
+ subject{ Tickle.parse('the 3rd of Feb 2022', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
319
+ let(:expected) { {:next=>Time.parse("2022-02-03 00:00:00 +0000"), :expression=>"the 3rd of feb 2022", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
320
+ it { should == expected }
321
+ end
322
+
323
+ context "the 4th of the month" do
324
+ subject{ Tickle.parse('the 4th of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
325
+ let(:expected) { {:next=>Time.parse("2020-04-04 00:00:00 +0000"), :expression=>"the 4th of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
326
+ it { should == expected }
327
+ end
328
+
329
+ context "the 10th of the month" do
330
+ subject{ Tickle.parse('the 10th of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
331
+ let(:expected) { {:next=>Time.parse("2020-04-10 00:00:00 +0000"), :expression=>"the 10th of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
332
+ it { should == expected }
333
+ end
334
+
335
+ context "the tenth of the month" do
336
+ subject{ Tickle.parse('the tenth of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
337
+ let(:expected) { {:next=>Time.parse("2020-04-10 00:00:00 +0000"), :expression=>"the tenth of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
338
+ it { should == expected }
339
+ end
340
+
341
+ context "first" do
342
+ subject{ Tickle.parse('first', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
343
+ let(:expected) { {:next=>Time.parse("2020-05-01 00:00:00 +0000"), :expression=>"first", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
344
+ it { should == expected }
345
+ end
346
+
347
+ context "the first of the month" do
348
+ subject{ Tickle.parse('the first of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
349
+ let(:expected) { {:next=>Time.parse("2020-05-01 00:00:00 +0000"), :expression=>"the first of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
350
+ it { should == expected }
351
+ end
352
+
353
+ context "the thirtieth" do
354
+ subject{ Tickle.parse('the thirtieth', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
355
+ let(:expected) { {:next=>Time.parse("2020-04-30 00:00:00 +0000"), :expression=>"the thirtieth", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
356
+ it { should == expected }
357
+ end
358
+
359
+ context "the fifth" do
360
+ subject{ Tickle.parse('the fifth', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
361
+ let(:expected) { {:next=>Time.parse("2020-04-05 00:00:00 +0000"), :expression=>"the fifth", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
362
+ it { should == expected }
363
+ end
364
+
365
+ context "the 1st Wednesday of the month" do
366
+ subject{ Tickle.parse('the 1st wednesday of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
367
+ let(:expected) {
368
+ {:next=>Time.parse("2020-05-01 00:00:00 +0000"), :expression=>"the 1st wednesday of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil}
369
+ }
370
+ it { should == expected }
371
+ end
372
+
373
+ context "the 3rd Sunday of May" do
374
+ subject{ Tickle.parse('the 3rd Sunday of May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
375
+ let(:expected) { {:next=>Time.parse("2020-05-17 12:00:00 +0000"), :expression=>"the 3rd sunday of may", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
376
+ it { should == expected }
377
+ end
378
+
379
+ context "the 3rd Sunday of the month" do
380
+ subject{ Tickle.parse('the 3rd Sunday of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
381
+ let(:expected) { {:next=>Time.parse("2020-04-19 12:00:00 +0000"), :expression=>"the 3rd sunday of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
382
+ it { should == expected }
383
+ end
384
+
385
+ context "the 23rd of June" do
386
+ subject{ Tickle.parse('the 23rd of June', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
387
+ let(:expected) { {:next=>Time.parse("2020-06-23 00:00:00 +0000"), :expression=>"the 23rd of june", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
388
+ it { should == expected }
389
+ end
390
+
391
+ context "the twenty third of June" do
392
+ subject{ Tickle.parse('the twenty third of June', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
393
+ let(:expected) { {:next=>Time.parse("2020-06-23 00:00:00 +0000"), :expression=>"the twenty third of june", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
394
+ it { should == expected }
395
+ end
396
+
397
+ context "the thirty first of July" do
398
+ subject{ Tickle.parse('the thirty first of July', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
399
+ let(:expected) { {:next=>Time.parse("2020-07-31 00:00:00 +0000"), :expression=>"the thirty first of july", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
400
+ it { should == expected }
401
+ end
402
+
403
+ context "the twenty first" do
404
+ subject{ Tickle.parse('the twenty first', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
405
+ let(:expected) { {:next=>Time.parse("2020-04-21 00:00:00 +0000"), :expression=>"the twenty first", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
406
+ it { should == expected }
407
+ end
408
+
409
+ context "the twenty first of the month" do
410
+ subject{ Tickle.parse('the twenty first of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
411
+ let(:expected) { {:next=>Time.parse("2020-04-21 00:00:00 +0000"), :expression=>"the twenty first of the month", :starting=>Time.parse("2020-04-01 00:00:00 +0000"), :until=>nil} }
412
+ it { should == expected }
413
+ end
414
+ end
415
+
416
+ context "beginning of the week" do
417
+ subject{ Tickle.parse('beginning of the week') }
418
+ let(:expected) { {:next=>Time.parse("2010-05-16 12:00:00 +0000"), :expression=>"beginning of the week", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
419
+ it { should == expected }
420
+ end
421
+
422
+ context "middle of the week" do
423
+ subject{ Tickle.parse('middle of the week') }
424
+ let(:expected) { {:next=>Time.parse("2010-05-12 12:00:00 +0000"), :expression=>"middle of the week", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
425
+ it { should == expected }
426
+ end
427
+
428
+ context "end of the week" do
429
+ subject{ Tickle.parse('end of the week') }
430
+ let(:expected) { {:next=>Time.parse("2010-05-15 12:00:00 +0000"), :expression=>"end of the week", :starting=>Time.parse("2010-05-09 20:57:36 +0000"), :until=>nil} }
431
+ it { should == expected }
432
+ end
433
+
434
+ end
435
+
436
+ context "Complex examples", :frozen => true do
437
+
438
+ context "starting today and ending one week from now" do
439
+ subject{ Tickle.parse('starting today and ending one week from now') }
440
+ let(:expected) { {:next=>Time.parse("2010-05-10 22:00:00 +0000"), :expression=>"day", :starting=>Time.parse("2010-05-09 22:00:00 +0000"), :until=>Time.parse("2010-05-16 20:57:36 +0000")} }
441
+ it { should == expected }
442
+ end
443
+
444
+ context "starting tomorrow and ending one week from now" do
445
+ subject{ Tickle.parse('starting tomorrow and ending one week from now') }
446
+ let(:expected) { {:next=>Time.parse("2010-05-10 12:00:00 +0000"), :expression=>"day", :starting=>Time.parse("2010-05-10 12:00:00 +0000"), :until=>Time.parse("2010-05-16 20:57:36 +0000")} }
447
+ it { should == expected }
448
+ end
449
+
450
+ context "starting Monday repeat every month" do
451
+ subject{ Tickle.parse('starting Monday repeat every month') }
452
+ let(:expected) { {:next=>Time.parse("2010-05-10 12:00:00 +0000"), :expression=>"month", :starting=>Time.parse("2010-05-10 12:00:00 +0000"), :until=>nil} }
453
+ it { should == expected }
454
+ end
455
+
456
+ context "starting May 13th repeat every week" do
457
+ subject{ Tickle.parse('starting May 13th repeat every week') }
458
+ let(:expected) { {:next=>Time.parse("2010-05-13 12:00:00 +0000"), :expression=>"week", :starting=>Time.parse("2010-05-13 12:00:00 +0000"), :until=>nil} }
459
+ it { should == expected }
460
+ end
461
+
462
+ context "starting May 13th repeat every other day" do
463
+ subject{ Tickle.parse('starting May 13th repeat every other day') }
464
+ let(:expected) { {:next=>Time.parse("2010-05-13 12:00:00 +0000"), :expression=>"other day", :starting=>Time.parse("2010-05-13 12:00:00 +0000"), :until=>nil} }
465
+ it { should == expected }
466
+ end
467
+
468
+ context "every other day starts May 13th" do
469
+ subject{ Tickle.parse('every other day starts May 13th') }
470
+ let(:expected) { {:next=>Time.parse("2010-05-13 12:00:00 +0000"), :expression=>"other day", :starting=>Time.parse("2010-05-13 12:00:00 +0000"), :until=>nil} }
471
+ it { should == expected }
472
+ end
473
+
474
+ context "every other day starts May 13" do
475
+ subject{ Tickle.parse('every other day starts May 13') }
476
+ let(:expected) { {:next=>Time.parse("2010-05-13 12:00:00 +0000"), :expression=>"other day", :starting=>Time.parse("2010-05-13 12:00:00 +0000"), :until=>nil} }
477
+ it { should == expected }
478
+ end
479
+
480
+ context "every other day starting May 13th" do
481
+ subject{ Tickle.parse('every other day starting May 13th') }
482
+ let(:expected) { {:next=>Time.parse("2010-05-13 12:00:00 +0000"), :expression=>"other day", :starting=>Time.parse("2010-05-13 12:00:00 +0000"), :until=>nil} }
483
+ it { should == expected }
484
+ end
485
+
486
+ context "every other day starting May 13" do
487
+ subject{ Tickle.parse('every other day starting May 13') }
488
+ let(:expected) { {:next=>Time.parse("2010-05-13 12:00:00 +0000"), :expression=>"other day", :starting=>Time.parse("2010-05-13 12:00:00 +0000"), :until=>nil} }
489
+ it { should == expected }
490
+ end
491
+
492
+ context "every week starts this wednesday" do
493
+ subject{ Tickle.parse('every week starts this wednesday') }
494
+ let(:expected) { {:next=>Time.parse("2010-05-12 12:00:00 +0000"), :expression=>"week", :starting=>Time.parse("2010-05-12 12:00:00 +0000"), :until=>nil} }
495
+ it { should == expected }
496
+ end
497
+
498
+ context "every week starting this wednesday" do
499
+ subject{ Tickle.parse('every week starting this wednesday') }
500
+ let(:expected) { {:next=>Time.parse("2010-05-12 12:00:00 +0000"), :expression=>"week", :starting=>Time.parse("2010-05-12 12:00:00 +0000"), :until=>nil} }
501
+ it { should == expected }
502
+ end
503
+
504
+ context "every other day starting May 1st 2021" do
505
+ subject{ Tickle.parse('every other day starting May 1st 2021') }
506
+ let(:expected) { {:next=>Time.parse("2021-05-01 12:00:00 +0000"), :expression=>"other day", :starting=>Time.parse("2021-05-01 12:00:00 +0000"), :until=>nil} }
507
+ it { should == expected }
508
+ end
509
+
510
+ context "every other day starting May 1 2021" do
511
+ subject{ Tickle.parse('every other day starting May 1 2021') }
512
+ let(:expected) { {:next=>Time.parse("2021-05-01 12:00:00 +0000"), :expression=>"other day", :starting=>Time.parse("2021-05-01 12:00:00 +0000"), :until=>nil} }
513
+ it { should == expected }
514
+ end
515
+
516
+ context "every other week starting this Sunday" do
517
+ subject{ Tickle.parse('every other week starting this Sunday') }
518
+ let(:expected) { {:next=>Time.parse("2010-05-16 12:00:00 +0000"), :expression=>"other week", :starting=>Time.parse("2010-05-16 12:00:00 +0000"), :until=>nil} }
519
+ it { should == expected }
520
+ end
521
+
522
+ context "every week starting this wednesday until May 13th" do
523
+ subject{ Tickle.parse('every week starting this wednesday until May 13th') }
524
+ let(:expected) { {:next=>Time.parse("2010-05-12 12:00:00 +0000"), :expression=>"week", :starting=>Time.parse("2010-05-12 12:00:00 +0000"), :until=>Time.parse("2010-05-13 12:00:00 +0000")} }
525
+ it { should == expected }
526
+ end
527
+
528
+ context "every week starting this wednesday ends May 13th" do
529
+ subject{ Tickle.parse('every week starting this wednesday ends May 13th') }
530
+ let(:expected) { {:next=>Time.parse("2010-05-12 12:00:00 +0000"), :expression=>"week", :starting=>Time.parse("2010-05-12 12:00:00 +0000"), :until=>Time.parse("2010-05-13 12:00:00 +0000")} }
531
+ it { should == expected }
532
+ end
533
+
534
+ context "every week starting this wednesday ending May 13th" do
535
+ subject{ Tickle.parse('every week starting this wednesday ending May 13th') }
536
+ let(:expected) { {:next=>Time.parse("2010-05-12 12:00:00 +0000"), :expression=>"week", :starting=>Time.parse("2010-05-12 12:00:00 +0000"), :until=>Time.parse("2010-05-13 12:00:00 +0000")} }
537
+ it { should == expected }
538
+ end
539
+ end
540
+ end
541
+ end
542
+
543
+ end # of module