tickle 1.2.0 → 2.0.0.rc1
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 +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +6 -4
- data/CHANGES.md +6 -24
- data/Gemfile +13 -4
- data/LICENCE +1 -1
- data/README.md +2 -2
- data/Rakefile +4 -7
- 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 +24 -117
- 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 +98 -220
- data/lib/tickle/tickled.rb +174 -0
- data/lib/tickle/token.rb +94 -0
- data/lib/tickle/version.rb +1 -1
- data/spec/helpers_spec.rb +36 -0
- data/spec/patterns_spec.rb +240 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/tickle_spec.rb +543 -0
- data/spec/token_spec.rb +82 -0
- data/test/helper.rb +0 -2
- data/test/test_parsing.rb +14 -23
- data/tickle.gemspec +2 -9
- metadata +32 -113
data/spec/token_spec.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative "../lib/tickle/token.rb"
|
3
|
+
require 'rspec/its'
|
4
|
+
|
5
|
+
module Tickle # for convenience
|
6
|
+
|
7
|
+
describe "Token" do
|
8
|
+
|
9
|
+
describe "The basics" do
|
10
|
+
subject { Token.new( "" ) }
|
11
|
+
it { should be_a_kind_of ::String }
|
12
|
+
it { should respond_to :original }
|
13
|
+
it { should respond_to :word }
|
14
|
+
it { should respond_to :type }
|
15
|
+
it { should respond_to :interval }
|
16
|
+
it { should respond_to :start }
|
17
|
+
it { should respond_to :update! }
|
18
|
+
it { should respond_to :normalize! }
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
describe "Instantation" do
|
23
|
+
context "Given a token" do
|
24
|
+
context "and no options" do
|
25
|
+
subject { Token.new( "Today" ) }
|
26
|
+
its(:original) { should == "Today" }
|
27
|
+
its(:word) { should be_nil }
|
28
|
+
its(:type) { should be_nil }
|
29
|
+
its(:interval) { should be_nil }
|
30
|
+
its(:start) { should be_nil }
|
31
|
+
it { should == "Today" }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "After normalization" do
|
37
|
+
context "Given a token" do
|
38
|
+
context "That is not a number" do
|
39
|
+
context "and no options" do
|
40
|
+
subject { Token.new( "Today" ).normalize! }
|
41
|
+
it { should == "Today" }
|
42
|
+
its(:word) { should == "today" }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
context "That is a number" do
|
46
|
+
context "and no options" do
|
47
|
+
subject { Token.new( "Twenty" ).normalize! }
|
48
|
+
it { should == "Twenty" }
|
49
|
+
its(:word) { should == "20" }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
describe "update!" do
|
57
|
+
pending
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
describe "tokenize" do
|
62
|
+
subject { Token.tokenize "Next Monday" }
|
63
|
+
it { should == ["Next", "Monday"] }
|
64
|
+
its(:first) { should be_a_kind_of Token }
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
describe "scan" do
|
69
|
+
context "Given an invalid argument" do
|
70
|
+
it {
|
71
|
+
expect {Token.scan Token.tokenize 9999}.to raise_error ArgumentError
|
72
|
+
}
|
73
|
+
end
|
74
|
+
context "Given a valid argument (tokens)" do
|
75
|
+
subject { Token.scan! Token.tokenize "Next Monday" }
|
76
|
+
it { should == ["Next", "Monday"] }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
data/test/helper.rb
CHANGED
data/test/test_parsing.rb
CHANGED
@@ -4,22 +4,16 @@ require 'test/unit'
|
|
4
4
|
|
5
5
|
class TestParsing < Test::Unit::TestCase
|
6
6
|
|
7
|
-
Time_now = Time.parse "2010-05-09 20:57:36 +0000"
|
8
7
|
def setup
|
9
8
|
Tickle.debug = (ARGV.detect {|a| a == '--d'})
|
10
9
|
@verbose = (ARGV.detect {|a| a == '--v'})
|
11
|
-
|
12
|
-
|
10
|
+
|
11
|
+
puts "Time.now"
|
12
|
+
p Time.now
|
13
13
|
|
14
14
|
@date = Date.today
|
15
|
-
@tz = ENV["TZ"]
|
16
15
|
end
|
17
16
|
|
18
|
-
def teardown
|
19
|
-
Timecop.return
|
20
|
-
ENV["TZ"] = @tz
|
21
|
-
end
|
22
|
-
|
23
17
|
def test_parse_best_guess_simple
|
24
18
|
start = Date.new(2020, 04, 01)
|
25
19
|
|
@@ -91,15 +85,12 @@ class TestParsing < Test::Unit::TestCase
|
|
91
85
|
assert_date_match(Date.new(2020, 04, 21), 'the twenty first of the month', {:start => start, :now => start})
|
92
86
|
end
|
93
87
|
|
94
|
-
def test_parse_best_guess_complex_and
|
95
|
-
assert_tickle_match(@date.bump(:day, 1), @date, @date.bump(:week, 1), 'day', 'starting today and ending one week from now') if Time.now.hour < 21 # => demonstrates leaving out the actual time period and implying it as daily
|
96
|
-
assert_tickle_match(@date.bump(:day, 1), @date.bump(:day, 1), @date.bump(:week, 1), 'day','starting tomorrow and ending one week from now') # => demonstrates leaving out the actual time period and implying it as daily.
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
88
|
def test_parse_best_guess_complex
|
101
89
|
start = Date.new(2020, 04, 01)
|
102
90
|
|
91
|
+
assert_tickle_match(@date.bump(:day, 1), @date, @date.bump(:week, 1), 'day', 'starting today and ending one week from now') if Time.now.hour < 21 # => demonstrates leaving out the actual time period and implying it as daily
|
92
|
+
assert_tickle_match(@date.bump(:day, 1), @date.bump(:day, 1), @date.bump(:week, 1), 'day','starting tomorrow and ending one week from now') # => demonstrates leaving out the actual time period and implying it as daily.
|
93
|
+
|
103
94
|
assert_tickle_match(@date.bump(:wday, 'Mon'), @date.bump(:wday, 'Mon'), nil, 'month', 'starting Monday repeat every month')
|
104
95
|
|
105
96
|
year = @date >= Date.new(@date.year, 5, 13) ? @date.bump(:year,1) : @date.year
|
@@ -174,30 +165,30 @@ class TestParsing < Test::Unit::TestCase
|
|
174
165
|
|
175
166
|
def test_argument_validation
|
176
167
|
assert_raise(Tickle::InvalidArgumentException) do
|
177
|
-
Tickle.parse("may 27", :today => 'something odd')
|
168
|
+
time = Tickle.parse("may 27", :today => 'something odd')
|
178
169
|
end
|
179
170
|
|
180
171
|
assert_raise(Tickle::InvalidArgumentException) do
|
181
|
-
Tickle.parse("may 27", :foo => :bar)
|
172
|
+
time = Tickle.parse("may 27", :foo => :bar)
|
182
173
|
end
|
183
174
|
|
184
175
|
assert_raise(Tickle::InvalidArgumentException) do
|
185
|
-
Tickle.parse(nil)
|
176
|
+
time = Tickle.parse(nil)
|
186
177
|
end
|
187
178
|
|
188
179
|
assert_raise(Tickle::InvalidDateExpression) do
|
189
180
|
past_date = Date.civil(Date.today.year, Date.today.month, Date.today.day - 1)
|
190
|
-
Tickle.parse("every other day", {:start => past_date})
|
181
|
+
time = Tickle.parse("every other day", {:start => past_date})
|
191
182
|
end
|
192
183
|
|
193
184
|
assert_raise(Tickle::InvalidDateExpression) do
|
194
|
-
start_date = Date.civil(Date.today.year, Date.today.month
|
195
|
-
end_date = Date.civil(Date.today.year, Date.today.month
|
196
|
-
Tickle.parse("every other day", :start => start_date, :until => end_date)
|
185
|
+
start_date = Date.civil(Date.today.year, Date.today.month, Date.today.day + 10)
|
186
|
+
end_date = Date.civil(Date.today.year, Date.today.month, Date.today.day + 5)
|
187
|
+
time = Tickle.parse("every other day", :start => start_date, :until => end_date)
|
197
188
|
end
|
198
189
|
|
199
190
|
assert_raise(Tickle::InvalidDateExpression) do
|
200
|
-
end_date = Date.civil(Date.today.year, Date.today.month, Date.today.day)
|
191
|
+
end_date = Date.civil(Date.today.year, Date.today.month+2, Date.today.day)
|
201
192
|
parse_now('every 3 months', {:until => end_date})
|
202
193
|
end
|
203
194
|
end
|
data/tickle.gemspec
CHANGED
@@ -20,15 +20,8 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.require_paths = ["lib"]
|
22
22
|
|
23
|
-
s.add_dependency "gitlab-chronic", "~> 0.10.6"
|
24
23
|
s.add_dependency "numerizer", "~> 0.2.0"
|
25
|
-
s.
|
26
|
-
s.
|
27
|
-
s.add_development_dependency "test-unit"
|
28
|
-
s.add_development_dependency "bundler"
|
29
|
-
s.add_development_dependency "rake"
|
30
|
-
s.add_development_dependency "yard"
|
31
|
-
s.add_development_dependency "maruku"
|
32
|
-
s.add_development_dependency "timecop"
|
24
|
+
s.add_dependency "chronic", "~> 0.10.2"
|
25
|
+
s.add_dependency "texttube", "~> 6.0.0"
|
33
26
|
end
|
34
27
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tickle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Lippiner
|
@@ -9,22 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-11-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: gitlab-chronic
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - "~>"
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: 0.10.6
|
21
|
-
type: :runtime
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - "~>"
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: 0.10.6
|
28
14
|
- !ruby/object:Gem::Dependency
|
29
15
|
name: numerizer
|
30
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -40,117 +26,33 @@ dependencies:
|
|
40
26
|
- !ruby/object:Gem::Version
|
41
27
|
version: 0.2.0
|
42
28
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
29
|
+
name: chronic
|
44
30
|
requirement: !ruby/object:Gem::Requirement
|
45
31
|
requirements:
|
46
32
|
- - "~>"
|
47
33
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
49
|
-
type: :
|
34
|
+
version: 0.10.2
|
35
|
+
type: :runtime
|
50
36
|
prerelease: false
|
51
37
|
version_requirements: !ruby/object:Gem::Requirement
|
52
38
|
requirements:
|
53
39
|
- - "~>"
|
54
40
|
- !ruby/object:Gem::Version
|
55
|
-
version:
|
41
|
+
version: 0.10.2
|
56
42
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
43
|
+
name: texttube
|
58
44
|
requirement: !ruby/object:Gem::Requirement
|
59
45
|
requirements:
|
60
|
-
- - "
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: '0'
|
63
|
-
type: :development
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '0'
|
70
|
-
- !ruby/object:Gem::Dependency
|
71
|
-
name: test-unit
|
72
|
-
requirement: !ruby/object:Gem::Requirement
|
73
|
-
requirements:
|
74
|
-
- - ">="
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: '0'
|
77
|
-
type: :development
|
78
|
-
prerelease: false
|
79
|
-
version_requirements: !ruby/object:Gem::Requirement
|
80
|
-
requirements:
|
81
|
-
- - ">="
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: '0'
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
|
-
name: bundler
|
86
|
-
requirement: !ruby/object:Gem::Requirement
|
87
|
-
requirements:
|
88
|
-
- - ">="
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: '0'
|
91
|
-
type: :development
|
92
|
-
prerelease: false
|
93
|
-
version_requirements: !ruby/object:Gem::Requirement
|
94
|
-
requirements:
|
95
|
-
- - ">="
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: '0'
|
98
|
-
- !ruby/object:Gem::Dependency
|
99
|
-
name: rake
|
100
|
-
requirement: !ruby/object:Gem::Requirement
|
101
|
-
requirements:
|
102
|
-
- - ">="
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
version: '0'
|
105
|
-
type: :development
|
106
|
-
prerelease: false
|
107
|
-
version_requirements: !ruby/object:Gem::Requirement
|
108
|
-
requirements:
|
109
|
-
- - ">="
|
110
|
-
- !ruby/object:Gem::Version
|
111
|
-
version: '0'
|
112
|
-
- !ruby/object:Gem::Dependency
|
113
|
-
name: yard
|
114
|
-
requirement: !ruby/object:Gem::Requirement
|
115
|
-
requirements:
|
116
|
-
- - ">="
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: '0'
|
119
|
-
type: :development
|
120
|
-
prerelease: false
|
121
|
-
version_requirements: !ruby/object:Gem::Requirement
|
122
|
-
requirements:
|
123
|
-
- - ">="
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: '0'
|
126
|
-
- !ruby/object:Gem::Dependency
|
127
|
-
name: maruku
|
128
|
-
requirement: !ruby/object:Gem::Requirement
|
129
|
-
requirements:
|
130
|
-
- - ">="
|
131
|
-
- !ruby/object:Gem::Version
|
132
|
-
version: '0'
|
133
|
-
type: :development
|
134
|
-
prerelease: false
|
135
|
-
version_requirements: !ruby/object:Gem::Requirement
|
136
|
-
requirements:
|
137
|
-
- - ">="
|
138
|
-
- !ruby/object:Gem::Version
|
139
|
-
version: '0'
|
140
|
-
- !ruby/object:Gem::Dependency
|
141
|
-
name: timecop
|
142
|
-
requirement: !ruby/object:Gem::Requirement
|
143
|
-
requirements:
|
144
|
-
- - ">="
|
46
|
+
- - "~>"
|
145
47
|
- !ruby/object:Gem::Version
|
146
|
-
version:
|
147
|
-
type: :
|
48
|
+
version: 6.0.0
|
49
|
+
type: :runtime
|
148
50
|
prerelease: false
|
149
51
|
version_requirements: !ruby/object:Gem::Requirement
|
150
52
|
requirements:
|
151
|
-
- - "
|
53
|
+
- - "~>"
|
152
54
|
- !ruby/object:Gem::Version
|
153
|
-
version:
|
55
|
+
version: 6.0.0
|
154
56
|
description: Tickle is a date/time helper gem to help parse natural language into
|
155
57
|
a recurring pattern. Tickle is designed to be a compliment of Chronic and can interpret
|
156
58
|
things such as "every 2 days, every Sunday, Sundays, Weekly, etc.
|
@@ -168,14 +70,27 @@ files:
|
|
168
70
|
- README.md
|
169
71
|
- Rakefile
|
170
72
|
- SCENARIOS.rdoc
|
73
|
+
- benchmarks/main.rb
|
171
74
|
- examples.rb
|
172
75
|
- git-flow-version
|
76
|
+
- lib/ext/array.rb
|
77
|
+
- lib/ext/date_and_time.rb
|
78
|
+
- lib/ext/string.rb
|
173
79
|
- lib/tickle.rb
|
80
|
+
- lib/tickle/filters.rb
|
174
81
|
- lib/tickle/handler.rb
|
82
|
+
- lib/tickle/helpers.rb
|
83
|
+
- lib/tickle/patterns.rb
|
175
84
|
- lib/tickle/repeater.rb
|
176
85
|
- lib/tickle/tickle.rb
|
86
|
+
- lib/tickle/tickled.rb
|
87
|
+
- lib/tickle/token.rb
|
177
88
|
- lib/tickle/version.rb
|
89
|
+
- spec/helpers_spec.rb
|
90
|
+
- spec/patterns_spec.rb
|
178
91
|
- spec/spec_helper.rb
|
92
|
+
- spec/tickle_spec.rb
|
93
|
+
- spec/token_spec.rb
|
179
94
|
- test/git-flow-version
|
180
95
|
- test/helper.rb
|
181
96
|
- test/test_parsing.rb
|
@@ -195,17 +110,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
195
110
|
version: '0'
|
196
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
197
112
|
requirements:
|
198
|
-
- - "
|
113
|
+
- - ">"
|
199
114
|
- !ruby/object:Gem::Version
|
200
|
-
version:
|
115
|
+
version: 1.3.1
|
201
116
|
requirements: []
|
202
117
|
rubyforge_project:
|
203
|
-
rubygems_version: 2.5
|
118
|
+
rubygems_version: 2.4.5
|
204
119
|
signing_key:
|
205
120
|
specification_version: 4
|
206
121
|
summary: natural language parser for recurring events
|
207
122
|
test_files:
|
123
|
+
- spec/helpers_spec.rb
|
124
|
+
- spec/patterns_spec.rb
|
208
125
|
- spec/spec_helper.rb
|
126
|
+
- spec/tickle_spec.rb
|
127
|
+
- spec/token_spec.rb
|
209
128
|
- test/git-flow-version
|
210
129
|
- test/helper.rb
|
211
130
|
- test/test_parsing.rb
|