chrono 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2654829b86a6c6e8ad37744e19fc96408a5ac9f
4
- data.tar.gz: a50cb68f2dcd05bafd92ce0c2f6ff6cc5df4e0f6
3
+ metadata.gz: e6fd43e8b0de253b8ac79fdc3185f2358cdc1791
4
+ data.tar.gz: b67b7851d8a25655d694e344f898de04056428fe
5
5
  SHA512:
6
- metadata.gz: 6d32b10ee846d5a185dcff6a05bb0dc11deee5cbb58ac9e68d32032fe26d04e80708be98da15b574abe7016d39059b19aba2685a73584ce3664859558a35a519
7
- data.tar.gz: 81d639646d8c41744af982fc1bb616df02fd3d3514be8e09897b2306253f489e83ed8da3bb0c90fc013225c53e5c5fee885f73ff859227a43ad9ee6ae25e7543
6
+ metadata.gz: b727c4e40b24389e70e6ec01830b77b93368d74231801b4d9e6bf3b8499577b340639e69c026013e947c89c52fa025fab1c6da010d5ef95550d1a859df3356e3
7
+ data.tar.gz: 5cbdd9900cff827c3d017fbdc5d2358253aa26bcc6c74c99f75bb9942e8f58ee9a6f4769859d59d71e0f7e3d9a28e3dcb22e88c62baa89a393309ca5f42d5680
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.2.0
2
+ - Add more strict validations
3
+ - Support some alias field names
4
+
1
5
  ## 0.1.0
2
6
  - Raise errors on invalid fields (thx @eagletmt)
3
7
 
data/chrono.gemspec CHANGED
@@ -20,6 +20,6 @@ Gem::Specification.new do |spec|
20
20
  spec.add_development_dependency "bundler"
21
21
  spec.add_development_dependency "codeclimate-test-reporter"
22
22
  spec.add_development_dependency "rake"
23
- spec.add_development_dependency "rspec", "2.14.1"
23
+ spec.add_development_dependency "rspec", "~> 3.4.0"
24
24
  spec.add_development_dependency "simplecov"
25
25
  end
@@ -1,8 +1,35 @@
1
1
  module Chrono
2
2
  module Fields
3
3
  class Month < Base
4
+ TABLE = {
5
+ 'jan' => '1',
6
+ 'feb' => '2',
7
+ 'mar' => '3',
8
+ 'apr' => '4',
9
+ 'may' => '5',
10
+ 'jun' => '6',
11
+ 'jul' => '7',
12
+ 'aug' => '8',
13
+ 'sep' => '9',
14
+ 'oct' => '10',
15
+ 'nov' => '11',
16
+ 'dec' => '12',
17
+ }
18
+ REGEXP = %r<\A(?<step>(?:\*|(?:(?<atom>\d+||jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)(?:-\g<atom>)?))(?:/\d+)?)(?:,\g<step>)*\z>ix
19
+
20
+ def initialize(source)
21
+ unless REGEXP =~ source
22
+ raise InvalidField.new('Unparsable field', source)
23
+ end
24
+ @source = source
25
+ end
26
+
4
27
  private
5
28
 
29
+ def interpolated
30
+ super.downcase.gsub(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/, TABLE)
31
+ end
32
+
6
33
  def range
7
34
  1..12
8
35
  end
@@ -1,8 +1,31 @@
1
1
  module Chrono
2
2
  module Fields
3
3
  class Wday < Base
4
+ TABLE = {
5
+ '7' => '0',
6
+ 'sun' => '0',
7
+ 'mon' => '1',
8
+ 'tue' => '2',
9
+ 'wed' => '3',
10
+ 'thu' => '4',
11
+ 'fri' => '5',
12
+ 'sat' => '6',
13
+ }
14
+ REGEXP = %r<\A(?:(?<step>(?:\*|(?:(?<atom>\d+|sun|mon|tue|wed|thu|fri|sat)(?:-\g<atom>)?))(?:/\d+)?)(?:,\g<step>)*)\z>ix
15
+
16
+ def initialize(source)
17
+ unless REGEXP =~ source
18
+ raise InvalidField.new('Unparsable field', source)
19
+ end
20
+ @source = source
21
+ end
22
+
4
23
  private
5
24
 
25
+ def interpolated
26
+ super.downcase.gsub(/7|sun|mon|tue|wed|thu|fri|sat/, TABLE)
27
+ end
28
+
6
29
  def range
7
30
  0..6
8
31
  end
@@ -1,8 +1,20 @@
1
1
  module Chrono
2
2
  class Schedule
3
3
  attr_reader :source
4
+ TABLE = {
5
+ '@yearly' => %w"0 0 1 1 *",
6
+ '@annually' => %w"0 0 1 1 *",
7
+ '@monthly' => %w"0 0 1 * *",
8
+ '@weekly' => %w"0 0 * * 0",
9
+ '@daily' => %w"0 0 * * *",
10
+ '@hourly' => %w"0 * * * *",
11
+ }
4
12
 
5
13
  def initialize(source)
14
+ if @fields = TABLE[source]
15
+ elsif %r<\A[ \t]*(?:(?<field>\S+)[ \t]+){4}\g<field>[ \t]*\z> !~ source
16
+ raise Chrono::Fields::Base::InvalidField.new('invalid source', source)
17
+ end
6
18
  @source = source
7
19
  end
8
20
 
@@ -1,3 +1,3 @@
1
1
  module Chrono
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -25,7 +25,7 @@ describe Chrono::Iterator do
25
25
  ].each_slice(3) do |from, to, source|
26
26
  it "ticks #{from} to #{to} by #{source}" do
27
27
  now = Time.parse(from)
28
- described_class.new(source, now: now).next.should == Time.parse(to)
28
+ expect(described_class.new(source, now: now).next).to eq(Time.parse(to))
29
29
  end
30
30
 
31
31
  it 'raises error when empty range is given' do
@@ -0,0 +1,268 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chrono::Schedule do
4
+ let (:schedule) { Chrono::Schedule.new(source) }
5
+
6
+ describe '.new' do
7
+ context 'valid source' do
8
+ subject { Chrono::Schedule.new("\t*\t*\t*\t*\t*\t") }
9
+ it { is_expected.to be_a(Chrono::Schedule) }
10
+ end
11
+ context 'six fields' do
12
+ subject { Chrono::Schedule.new('* * * * * *') }
13
+ it { expect{subject.minutes}.to raise_error(Chrono::Fields::Base::InvalidField) }
14
+ end
15
+ context '@yearly' do
16
+ subject { Chrono::Schedule.new('@yearly') }
17
+ it do
18
+ expect(subject.minutes).to eq([0])
19
+ expect(subject.hours).to eq([0])
20
+ expect(subject.days).to eq([1])
21
+ expect(subject.months).to eq([1])
22
+ expect(subject.wdays).to eq(7.times.to_a)
23
+ end
24
+ end
25
+ context '@annually' do
26
+ subject { Chrono::Schedule.new('@annually') }
27
+ it do
28
+ expect(subject.minutes).to eq([0])
29
+ expect(subject.hours).to eq([0])
30
+ expect(subject.days).to eq([1])
31
+ expect(subject.months).to eq([1])
32
+ expect(subject.wdays).to eq(7.times.to_a)
33
+ end
34
+ end
35
+ context '@monthly' do
36
+ subject { Chrono::Schedule.new('@monthly') }
37
+ it do
38
+ expect(subject.minutes).to eq([0])
39
+ expect(subject.hours).to eq([0])
40
+ expect(subject.days).to eq([1])
41
+ expect(subject.months).to eq((1..12).to_a)
42
+ expect(subject.wdays).to eq(7.times.to_a)
43
+ end
44
+ end
45
+ context '@weekly' do
46
+ subject { Chrono::Schedule.new('@weekly') }
47
+ it do
48
+ expect(subject.minutes).to eq([0])
49
+ expect(subject.hours).to eq([0])
50
+ expect(subject.days).to eq((1..31).to_a)
51
+ expect(subject.months).to eq((1..12).to_a)
52
+ expect(subject.wdays).to eq([0])
53
+ end
54
+ end
55
+ context '@daily' do
56
+ subject { Chrono::Schedule.new('@daily') }
57
+ it do
58
+ expect(subject.minutes).to eq([0])
59
+ expect(subject.hours).to eq([0])
60
+ expect(subject.days).to eq((1..31).to_a)
61
+ expect(subject.months).to eq((1..12).to_a)
62
+ expect(subject.wdays).to eq(7.times.to_a)
63
+ end
64
+ end
65
+ context '@hourly' do
66
+ subject { Chrono::Schedule.new('@hourly') }
67
+ it do
68
+ expect(subject.minutes).to eq([0])
69
+ expect(subject.hours).to eq(24.times.to_a)
70
+ expect(subject.days).to eq((1..31).to_a)
71
+ expect(subject.months).to eq((1..12).to_a)
72
+ expect(subject.wdays).to eq(7.times.to_a)
73
+ end
74
+ end
75
+ end
76
+
77
+ describe '#minutes' do
78
+ subject { schedule.minutes }
79
+ context "'0 0 * * *'" do
80
+ let (:source){ '0 0 * * *' }
81
+ it { is_expected.to eq [0] }
82
+ end
83
+ context "'59 0 * * *'" do
84
+ let (:source){ '59 0 * * *' }
85
+ it { is_expected.to eq [59] }
86
+ end
87
+ context "'60 0 * * *'" do
88
+ let (:source){ '60 0 * * *' }
89
+ it { expect{subject}.to raise_error(Chrono::Fields::Base::InvalidField) }
90
+ end
91
+ end
92
+
93
+ describe '#hours' do
94
+ subject { schedule.hours }
95
+ context "'0 0 * * *'" do
96
+ let (:source){ '0 0 * * *' }
97
+ it { is_expected.to eq [0] }
98
+ end
99
+ context "'0 23 * * *'" do
100
+ let (:source){ '0 23 * * *' }
101
+ it { is_expected.to eq [23] }
102
+ end
103
+ context "'0 24 * * *'" do
104
+ let (:source){ '0 24 * * *' }
105
+ it { expect{subject}.to raise_error(Chrono::Fields::Base::InvalidField) }
106
+ end
107
+ end
108
+
109
+ describe '#days' do
110
+ subject { schedule.days }
111
+ context 'day: 1' do
112
+ let (:source){ '0 0 1 * *' }
113
+ it { is_expected.to eq [1] }
114
+ end
115
+ context 'day: 31' do
116
+ let (:source){ '0 0 31 * *' }
117
+ it { is_expected.to eq [31] }
118
+ end
119
+ context 'day" 0' do
120
+ let (:source){ '0 0 0 * *' }
121
+ it { expect{subject}.to raise_error(Chrono::Fields::Base::InvalidField) }
122
+ end
123
+ context 'day: 32' do
124
+ let (:source){ '0 0 32 * *' }
125
+ it { expect{subject}.to raise_error(Chrono::Fields::Base::InvalidField) }
126
+ end
127
+ end
128
+
129
+ describe '#months' do
130
+ subject { schedule.months }
131
+ context 'month: 1' do
132
+ let (:source){ '0 0 1 1 *' }
133
+ it { is_expected.to eq [1] }
134
+ end
135
+ context 'month: 12' do
136
+ let (:source){ '0 0 1 12 0' }
137
+ it { is_expected.to eq [12] }
138
+ end
139
+ context 'month: 0' do
140
+ let (:source){ '0 0 1 0 *' }
141
+ it { expect{subject}.to raise_error(Chrono::Fields::Base::InvalidField) }
142
+ end
143
+ context 'month: 13' do
144
+ let (:source){ '0 0 13 0 *' }
145
+ it { expect{subject}.to raise_error(Chrono::Fields::Base::InvalidField) }
146
+ end
147
+ context 'month: Jan' do
148
+ let (:source){ '0 0 1 Jan 0' }
149
+ it { is_expected.to eq [1] }
150
+ end
151
+ context 'month: Feb' do
152
+ let (:source){ '0 0 1 Feb 0' }
153
+ it { is_expected.to eq [2] }
154
+ end
155
+ context 'month: Mar' do
156
+ let (:source){ '0 0 1 Mar 0' }
157
+ it { is_expected.to eq [3] }
158
+ end
159
+ context 'month: Apr' do
160
+ let (:source){ '0 0 1 Apr 0' }
161
+ it { is_expected.to eq [4] }
162
+ end
163
+ context 'month: May' do
164
+ let (:source){ '0 0 1 May 0' }
165
+ it { is_expected.to eq [5] }
166
+ end
167
+ context 'month: Jun' do
168
+ let (:source){ '0 0 1 Jun 0' }
169
+ it { is_expected.to eq [6] }
170
+ end
171
+ context 'month: Jul' do
172
+ let (:source){ '0 0 1 Jul 0' }
173
+ it { is_expected.to eq [7] }
174
+ end
175
+ context 'month: Aug' do
176
+ let (:source){ '0 0 1 Aug 0' }
177
+ it { is_expected.to eq [8] }
178
+ end
179
+ context 'month: Sep' do
180
+ let (:source){ '0 0 1 Sep 0' }
181
+ it { is_expected.to eq [9] }
182
+ end
183
+ context 'month: Oct' do
184
+ let (:source){ '0 0 1 Oct 0' }
185
+ it { is_expected.to eq [10] }
186
+ end
187
+ context 'month: Nov' do
188
+ let (:source){ '0 0 1 Nov 0' }
189
+ it { is_expected.to eq [11] }
190
+ end
191
+ context 'month: Dec' do
192
+ let (:source){ '0 0 1 Dec 0' }
193
+ it { is_expected.to eq [12] }
194
+ end
195
+ context 'month: Mar-Dec/3' do
196
+ let (:source){ '0 0 1 Mar-Dec/3 0' }
197
+ it { is_expected.to eq [3,6,9,12] }
198
+ end
199
+ context 'month: Mar,Jun,Sep,Dec' do
200
+ let (:source){ '0 0 1 Mar,Jun,Sep,Dec/3 0' }
201
+ it { is_expected.to eq [3,6,9,12] }
202
+ end
203
+ context 'month: January' do
204
+ let (:source){ '0 0 1 January 0' }
205
+ it { expect{subject}.to raise_error(Chrono::Fields::Base::InvalidField) }
206
+ end
207
+ context 'month: Abc' do
208
+ let (:source){ '0 0 1 Abc 0' }
209
+ it { expect{subject}.to raise_error(Chrono::Fields::Base::InvalidField) }
210
+ end
211
+ end
212
+
213
+ describe '#wdays' do
214
+ subject { schedule.wdays }
215
+ context 'wdays: 0' do
216
+ let (:source){ '0 0 * * 0' }
217
+ it { is_expected.to eq [0] }
218
+ end
219
+ context 'wdays: 6' do
220
+ let (:source){ '0 0 * * 6' }
221
+ it { is_expected.to eq [6] }
222
+ end
223
+ context 'wdays: 7' do
224
+ let (:source){ '0 0 * * 7' }
225
+ it { is_expected.to eq [0] }
226
+ end
227
+ context 'wdays: 8' do
228
+ let (:source){ '0 0 * * 8' }
229
+ it { expect{subject}.to raise_error(Chrono::Fields::Base::InvalidField) }
230
+ end
231
+ context 'wdays: sun' do
232
+ let (:source){ '0 0 * * sun' }
233
+ it { is_expected.to eq [0] }
234
+ end
235
+ context 'wdays: mon' do
236
+ let (:source){ '0 0 * * mon' }
237
+ it { is_expected.to eq [1] }
238
+ end
239
+ context 'wdays: tue' do
240
+ let (:source){ '0 0 * * tue' }
241
+ it { is_expected.to eq [2] }
242
+ end
243
+ context 'wdays: wed' do
244
+ let (:source){ '0 0 * * wed' }
245
+ it { is_expected.to eq [3] }
246
+ end
247
+ context 'wdays: Thu' do
248
+ let (:source){ '0 0 * * Thu' }
249
+ it { is_expected.to eq [4] }
250
+ end
251
+ context 'wdays: FRI' do
252
+ let (:source){ '0 0 * * FRI' }
253
+ it { is_expected.to eq [5] }
254
+ end
255
+ context 'wdays: Sat' do
256
+ let (:source){ '0 0 * * Sat' }
257
+ it { is_expected.to eq [6] }
258
+ end
259
+ context 'wdays: Sun-Sat' do
260
+ let (:source){ '0 0 * * Sun-Sat' }
261
+ it { is_expected.to eq [0,1,2,3,4,5,6] }
262
+ end
263
+ context 'wdays: Sun,Sat' do
264
+ let (:source){ '0 0 * * Sun,Sat' }
265
+ it { is_expected.to eq [0,6] }
266
+ end
267
+ end
268
+ end
@@ -15,8 +15,8 @@ describe Chrono::Trigger do
15
15
 
16
16
  describe "#once" do
17
17
  it "waits till scheduled time and then triggers a given job only once" do
18
- block.should_receive(:call)
19
- trigger.should_receive(:sleep)
18
+ expect(block).to receive(:call)
19
+ expect(trigger).to receive(:sleep)
20
20
  trigger.once
21
21
  end
22
22
  end
@@ -24,7 +24,7 @@ describe Chrono::Trigger do
24
24
  # Stub Trigger#loop behavior to avoid blocking main process.
25
25
  describe "#run" do
26
26
  before do
27
- trigger.stub(:loop) do |&block|
27
+ allow(trigger).to receive(:loop) do |&block|
28
28
  2.times do
29
29
  block.call
30
30
  end
@@ -32,8 +32,8 @@ describe Chrono::Trigger do
32
32
  end
33
33
 
34
34
  it "waits till scheduled time and then triggers a given job periodically" do
35
- block.should_receive(:call).twice
36
- trigger.should_receive(:sleep).twice
35
+ expect(block).to receive(:call).twice
36
+ expect(trigger).to receive(:sleep).twice
37
37
  trigger.run
38
38
  end
39
39
  end
data/spec/spec_helper.rb CHANGED
@@ -10,7 +10,6 @@ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
10
10
  require "chrono"
11
11
 
12
12
  RSpec.configure do |config|
13
- config.treat_symbols_as_metadata_keys_with_true_values = true
14
13
  config.run_all_when_everything_filtered = true
15
14
  config.filter_run :focus
16
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chrono
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-14 00:00:00.000000000 Z
11
+ date: 2015-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '='
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 2.14.1
75
+ version: 3.4.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '='
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 2.14.1
82
+ version: 3.4.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: simplecov
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,7 @@ files:
122
122
  - lib/chrono/trigger.rb
123
123
  - lib/chrono/version.rb
124
124
  - spec/chrono/iterator_spec.rb
125
+ - spec/chrono/schedule_spec.rb
125
126
  - spec/chrono/trigger_spec.rb
126
127
  - spec/spec_helper.rb
127
128
  homepage: https://github.com/r7kamura/chrono
@@ -150,6 +151,7 @@ specification_version: 4
150
151
  summary: Provides a chain of logics about chronology.
151
152
  test_files:
152
153
  - spec/chrono/iterator_spec.rb
154
+ - spec/chrono/schedule_spec.rb
153
155
  - spec/chrono/trigger_spec.rb
154
156
  - spec/spec_helper.rb
155
157
  has_rdoc: