tickle 1.0.2 → 2.0.0rc3
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.
- checksums.yaml +5 -5
- data/.gitignore +3 -1
- data/.travis.yml +12 -0
- data/CHANGES.md +25 -3
- data/Gemfile +14 -1
- data/LICENCE +1 -1
- data/README.md +1 -1
- data/Rakefile +3 -8
- data/benchmarks/main.rb +71 -0
- data/lib/ext/array.rb +6 -0
- data/lib/ext/date_and_time.rb +64 -0
- data/lib/ext/string.rb +39 -0
- data/lib/tickle.rb +23 -113
- data/lib/tickle/filters.rb +58 -0
- data/lib/tickle/handler.rb +223 -80
- data/lib/tickle/helpers.rb +51 -0
- data/lib/tickle/patterns.rb +115 -0
- data/lib/tickle/repeater.rb +232 -116
- data/lib/tickle/tickle.rb +97 -201
- data/lib/tickle/tickled.rb +173 -0
- data/lib/tickle/token.rb +94 -0
- data/lib/tickle/version.rb +2 -2
- data/spec/helpers_spec.rb +36 -0
- data/spec/patterns_spec.rb +240 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/tickle_spec.rb +551 -0
- data/spec/token_spec.rb +82 -0
- data/tickle.gemspec +4 -9
- metadata +34 -74
- data/lib/numerizer/numerizer.rb +0 -103
data/lib/tickle/token.rb
ADDED
@@ -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
|
data/lib/tickle/version.rb
CHANGED
@@ -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
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
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 "/vendor.noindex/"
|
13
|
+
add_filter "/bin/"
|
14
|
+
add_filter "/spec/"
|
15
|
+
add_filter "/coverage/" # It used to do this for some reason, defensive of me.
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
Dir[ File.join( Spec_dir, "/support/**/*.rb")].each do |f|
|
20
|
+
require f
|
21
|
+
end
|
22
|
+
|
23
|
+
Time_now = Time.parse "2010-05-09 20:57:36 +0000"
|
24
|
+
|
25
|
+
require 'timecop'
|
26
|
+
|
27
|
+
RSpec.configure do |config|
|
28
|
+
config.expect_with :rspec do |c|
|
29
|
+
c.syntax = [:should, :expect]
|
30
|
+
end
|
31
|
+
|
32
|
+
tz = ENV["TZ"]
|
33
|
+
config.before(:all, :frozen => true) do
|
34
|
+
Timecop.freeze Time_now
|
35
|
+
ENV["TZ"] = "UTC"
|
36
|
+
end
|
37
|
+
config.after(:all, :frozen => true) do
|
38
|
+
Timecop.return
|
39
|
+
ENV["TZ"] = tz
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
warn "Actual Time now => #{Time.now}"
|
data/spec/tickle_spec.rb
ADDED
@@ -0,0 +1,551 @@
|
|
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 start is in the past, respect now option in parse" do
|
245
|
+
context "every other day" do
|
246
|
+
subject{ Tickle.parse('every other day', {:start=>Time.parse("2009-05-09 00:00:00 +0000"), :now=>Time.parse("2009-05-09 00:00:00 +0000"), :until=>Time.parse("2017-10-21 00:00:00 +0000") }) }
|
247
|
+
let(:expected) { {:next=>Time.parse("2009-05-11 00:00:00 +0000"), :expression=>"every other day", :starting=>Time.parse("2009-05-09 00:00:00 +0000"), :until=>nil} }
|
248
|
+
it { should == expected }
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context "Given that now is in the future, 2020-04-01 00:00:00 +0000" do
|
253
|
+
context "February" do
|
254
|
+
subject{ Tickle.parse('February', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
|
255
|
+
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} }
|
256
|
+
it { should == expected }
|
257
|
+
end
|
258
|
+
|
259
|
+
context "May" do
|
260
|
+
subject{ Tickle.parse('May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
|
261
|
+
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} }
|
262
|
+
it { should == expected }
|
263
|
+
end
|
264
|
+
|
265
|
+
context "june" do
|
266
|
+
subject{ Tickle.parse('june', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
|
267
|
+
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} }
|
268
|
+
it { should == expected }
|
269
|
+
end
|
270
|
+
|
271
|
+
context "beginning of the month" do
|
272
|
+
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")}) }
|
273
|
+
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} }
|
274
|
+
it { should == expected }
|
275
|
+
end
|
276
|
+
|
277
|
+
context "middle of the month" do
|
278
|
+
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")}) }
|
279
|
+
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} }
|
280
|
+
it { should == expected }
|
281
|
+
end
|
282
|
+
|
283
|
+
context "end of the month" do
|
284
|
+
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")}) }
|
285
|
+
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} }
|
286
|
+
it { should == expected }
|
287
|
+
end
|
288
|
+
|
289
|
+
context "beginning of the year" do
|
290
|
+
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")}) }
|
291
|
+
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} }
|
292
|
+
it { should == expected }
|
293
|
+
end
|
294
|
+
|
295
|
+
context "middle of the year" do
|
296
|
+
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")}) }
|
297
|
+
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} }
|
298
|
+
it { should == expected }
|
299
|
+
end
|
300
|
+
|
301
|
+
context "end of the year" do
|
302
|
+
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")}) }
|
303
|
+
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} }
|
304
|
+
it { should == expected }
|
305
|
+
end
|
306
|
+
|
307
|
+
context "the 3rd of May" do
|
308
|
+
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")}) }
|
309
|
+
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} }
|
310
|
+
it { should == expected }
|
311
|
+
end
|
312
|
+
|
313
|
+
context "the 3rd of February" do
|
314
|
+
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")}) }
|
315
|
+
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} }
|
316
|
+
it { should == expected }
|
317
|
+
end
|
318
|
+
|
319
|
+
context "the 3rd of February 2022" do
|
320
|
+
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")}) }
|
321
|
+
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} }
|
322
|
+
it { should == expected }
|
323
|
+
end
|
324
|
+
|
325
|
+
context "the 3rd of Feb 2022" do
|
326
|
+
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")}) }
|
327
|
+
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} }
|
328
|
+
it { should == expected }
|
329
|
+
end
|
330
|
+
|
331
|
+
context "the 4th of the month" do
|
332
|
+
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")}) }
|
333
|
+
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} }
|
334
|
+
it { should == expected }
|
335
|
+
end
|
336
|
+
|
337
|
+
context "the 10th of the month" do
|
338
|
+
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")}) }
|
339
|
+
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} }
|
340
|
+
it { should == expected }
|
341
|
+
end
|
342
|
+
|
343
|
+
context "the tenth of the month" do
|
344
|
+
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")}) }
|
345
|
+
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} }
|
346
|
+
it { should == expected }
|
347
|
+
end
|
348
|
+
|
349
|
+
context "first" do
|
350
|
+
subject{ Tickle.parse('first', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")}) }
|
351
|
+
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} }
|
352
|
+
it { should == expected }
|
353
|
+
end
|
354
|
+
|
355
|
+
context "the first of the month" do
|
356
|
+
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")}) }
|
357
|
+
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} }
|
358
|
+
it { should == expected }
|
359
|
+
end
|
360
|
+
|
361
|
+
context "the thirtieth" do
|
362
|
+
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")}) }
|
363
|
+
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} }
|
364
|
+
it { should == expected }
|
365
|
+
end
|
366
|
+
|
367
|
+
context "the fifth" do
|
368
|
+
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")}) }
|
369
|
+
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} }
|
370
|
+
it { should == expected }
|
371
|
+
end
|
372
|
+
|
373
|
+
context "the 1st Wednesday of the month" do
|
374
|
+
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")}) }
|
375
|
+
let(:expected) {
|
376
|
+
{: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}
|
377
|
+
}
|
378
|
+
it { should == expected }
|
379
|
+
end
|
380
|
+
|
381
|
+
context "the 3rd Sunday of May" do
|
382
|
+
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")}) }
|
383
|
+
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} }
|
384
|
+
it { should == expected }
|
385
|
+
end
|
386
|
+
|
387
|
+
context "the 3rd Sunday of the month" do
|
388
|
+
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")}) }
|
389
|
+
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} }
|
390
|
+
it { should == expected }
|
391
|
+
end
|
392
|
+
|
393
|
+
context "the 23rd of June" do
|
394
|
+
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")}) }
|
395
|
+
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} }
|
396
|
+
it { should == expected }
|
397
|
+
end
|
398
|
+
|
399
|
+
context "the twenty third of June" do
|
400
|
+
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")}) }
|
401
|
+
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} }
|
402
|
+
it { should == expected }
|
403
|
+
end
|
404
|
+
|
405
|
+
context "the thirty first of July" do
|
406
|
+
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")}) }
|
407
|
+
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} }
|
408
|
+
it { should == expected }
|
409
|
+
end
|
410
|
+
|
411
|
+
context "the twenty first" do
|
412
|
+
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")}) }
|
413
|
+
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} }
|
414
|
+
it { should == expected }
|
415
|
+
end
|
416
|
+
|
417
|
+
context "the twenty first of the month" do
|
418
|
+
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")}) }
|
419
|
+
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} }
|
420
|
+
it { should == expected }
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
context "beginning of the week" do
|
425
|
+
subject{ Tickle.parse('beginning of the week') }
|
426
|
+
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} }
|
427
|
+
it { should == expected }
|
428
|
+
end
|
429
|
+
|
430
|
+
context "middle of the week" do
|
431
|
+
subject{ Tickle.parse('middle of the week') }
|
432
|
+
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} }
|
433
|
+
it { should == expected }
|
434
|
+
end
|
435
|
+
|
436
|
+
context "end of the week" do
|
437
|
+
subject{ Tickle.parse('end of the week') }
|
438
|
+
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} }
|
439
|
+
it { should == expected }
|
440
|
+
end
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
context "Complex examples", :frozen => true do
|
445
|
+
|
446
|
+
context "starting today and ending one week from now" do
|
447
|
+
subject{ Tickle.parse('starting today and ending one week from now') }
|
448
|
+
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")} }
|
449
|
+
it { should == expected }
|
450
|
+
end
|
451
|
+
|
452
|
+
context "starting tomorrow and ending one week from now" do
|
453
|
+
subject{ Tickle.parse('starting tomorrow and ending one week from now') }
|
454
|
+
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")} }
|
455
|
+
it { should == expected }
|
456
|
+
end
|
457
|
+
|
458
|
+
context "starting Monday repeat every month" do
|
459
|
+
subject{ Tickle.parse('starting Monday repeat every month') }
|
460
|
+
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} }
|
461
|
+
it { should == expected }
|
462
|
+
end
|
463
|
+
|
464
|
+
context "starting May 13th repeat every week" do
|
465
|
+
subject{ Tickle.parse('starting May 13th repeat every week') }
|
466
|
+
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} }
|
467
|
+
it { should == expected }
|
468
|
+
end
|
469
|
+
|
470
|
+
context "starting May 13th repeat every other day" do
|
471
|
+
subject{ Tickle.parse('starting May 13th repeat every other day') }
|
472
|
+
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} }
|
473
|
+
it { should == expected }
|
474
|
+
end
|
475
|
+
|
476
|
+
context "every other day starts May 13th" do
|
477
|
+
subject{ Tickle.parse('every other day starts May 13th') }
|
478
|
+
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} }
|
479
|
+
it { should == expected }
|
480
|
+
end
|
481
|
+
|
482
|
+
context "every other day starts May 13" do
|
483
|
+
subject{ Tickle.parse('every other day starts May 13') }
|
484
|
+
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} }
|
485
|
+
it { should == expected }
|
486
|
+
end
|
487
|
+
|
488
|
+
context "every other day starting May 13th" do
|
489
|
+
subject{ Tickle.parse('every other day starting May 13th') }
|
490
|
+
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} }
|
491
|
+
it { should == expected }
|
492
|
+
end
|
493
|
+
|
494
|
+
context "every other day starting May 13" do
|
495
|
+
subject{ Tickle.parse('every other day starting May 13') }
|
496
|
+
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} }
|
497
|
+
it { should == expected }
|
498
|
+
end
|
499
|
+
|
500
|
+
context "every week starts this wednesday" do
|
501
|
+
subject{ Tickle.parse('every week starts this wednesday') }
|
502
|
+
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} }
|
503
|
+
it { should == expected }
|
504
|
+
end
|
505
|
+
|
506
|
+
context "every week starting this wednesday" do
|
507
|
+
subject{ Tickle.parse('every week starting this wednesday') }
|
508
|
+
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} }
|
509
|
+
it { should == expected }
|
510
|
+
end
|
511
|
+
|
512
|
+
context "every other day starting May 1st 2021" do
|
513
|
+
subject{ Tickle.parse('every other day starting May 1st 2021') }
|
514
|
+
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} }
|
515
|
+
it { should == expected }
|
516
|
+
end
|
517
|
+
|
518
|
+
context "every other day starting May 1 2021" do
|
519
|
+
subject{ Tickle.parse('every other day starting May 1 2021') }
|
520
|
+
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} }
|
521
|
+
it { should == expected }
|
522
|
+
end
|
523
|
+
|
524
|
+
context "every other week starting this Sunday" do
|
525
|
+
subject{ Tickle.parse('every other week starting this Sunday') }
|
526
|
+
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} }
|
527
|
+
it { should == expected }
|
528
|
+
end
|
529
|
+
|
530
|
+
context "every week starting this wednesday until May 13th" do
|
531
|
+
subject{ Tickle.parse('every week starting this wednesday until May 13th') }
|
532
|
+
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")} }
|
533
|
+
it { should == expected }
|
534
|
+
end
|
535
|
+
|
536
|
+
context "every week starting this wednesday ends May 13th" do
|
537
|
+
subject{ Tickle.parse('every week starting this wednesday ends May 13th') }
|
538
|
+
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")} }
|
539
|
+
it { should == expected }
|
540
|
+
end
|
541
|
+
|
542
|
+
context "every week starting this wednesday ending May 13th" do
|
543
|
+
subject{ Tickle.parse('every week starting this wednesday ending May 13th') }
|
544
|
+
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")} }
|
545
|
+
it { should == expected }
|
546
|
+
end
|
547
|
+
end
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
551
|
+
end # of module
|