chrono 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: