zhong 0.1.3 → 0.1.4

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: 5945fa0ab193d6a729fdf393166c8d380a06558e
4
- data.tar.gz: 8956f5b216934a2ebc5b9014c53b655c46ff462a
3
+ metadata.gz: 56d5bb0e028b58158fb6078391782b96a4dab9d3
4
+ data.tar.gz: 1b9dcabc60857d70547c091ddb526d706f258a1d
5
5
  SHA512:
6
- metadata.gz: 62629516856da87db6bdf7a54dc616efe247b7ce29e039d989ee0b69a7fa9015fb2d43a15b651aea30c604942ce2b2fd0aeecd1961fe63bb9d201bfdbfc0e428
7
- data.tar.gz: 7afeb0d7ee86d65eed6964c03f161730bd4050ce5d70c1ce86d137d9ae0f22a95e5ff91a0f10a87080d6e192d399afc0664427ac8bfa231bcc4313c3cc437134
6
+ metadata.gz: b1e9ecee03c7c42c66440daff973f0273558c5ba3b2925479062a07d35bd340f94315608035ef2e44401efb82b0807a3dab72c91e277bda47d81d83818938c67
7
+ data.tar.gz: e03cb2a4b7f285021ac254bdd019c2017b0a085a2b3ae51d88a19bbd2af6e9b5330b4ee75e894511c236fed27908c7a96013bed47d1210d7e21b4a304a1658ee
@@ -1,3 +1,8 @@
1
+ ## 0.1.4
2
+
3
+ - Fix several bugs related to time parsing.
4
+ - In a totally unrelated change, add some tests around time parsing.
5
+
1
6
  ## 0.1.3
2
7
 
3
8
  - Fix several memory leaks.
data/bin/zhong CHANGED
@@ -4,7 +4,6 @@ STDERR.sync = STDOUT.sync = true
4
4
 
5
5
  require "bundler/setup"
6
6
  require "zhong"
7
- require "memory_profiler"
8
7
 
9
8
  usage = "zhong <zhong.rb>"
10
9
  file = ARGV.shift || abort(usage)
@@ -17,22 +17,35 @@ module Zhong
17
17
 
18
18
  attr_accessor :minute, :hour, :wday
19
19
 
20
- def initialize(minute: nil, hour: nil, wday: nil, grace: 0.minutes)
20
+ def initialize(minute: nil, hour: nil, wday: nil, grace: 0.seconds)
21
21
  @minute = minute
22
22
  @hour = hour
23
23
  @wday = wday
24
24
  @grace = grace
25
+
26
+ fail ArgumentError unless valid?
25
27
  end
26
28
 
27
29
  def next_at(time = Time.now)
28
30
  at_time = @wday.nil? ? time.dup : (time + (@wday - time.wday).days)
29
31
 
30
- at_time = at_time.change(min: @minute)
31
- at_time = at_time.change(hour: @hour) if @hour
32
+ at_time = if !@minute.nil? && !@hour.nil?
33
+ at_time.change(hour: @hour, min: @minute)
34
+ elsif !@minute.nil?
35
+ at_time.change(min: @minute)
36
+ elsif !@hour.nil? && @hour != time.hour
37
+ at_time.change(hour: @hour)
38
+ else
39
+ at_time.change(sec: 0)
40
+ end
32
41
 
33
- if at_time < @grace.ago
42
+ if at_time < (time.change(sec: 0) - @grace)
34
43
  if @wday.nil?
35
- at_time += 1.day
44
+ if @hour.nil?
45
+ at_time += 1.hour
46
+ else
47
+ at_time += 1.day
48
+ end
36
49
  else
37
50
  at_time += 1.week
38
51
  end
@@ -41,7 +54,13 @@ module Zhong
41
54
  end
42
55
  end
43
56
 
44
- def self.parse(at, grace: 0)
57
+ private def valid?
58
+ (@minute.nil? || (0..59).cover?(@minute)) &&
59
+ (@hour.nil? || (0..23).cover?(@hour)) &&
60
+ (@wday.nil? || (0..6).cover?(@wday))
61
+ end
62
+
63
+ def self.parse(at, grace: 0.seconds)
45
64
  return unless at
46
65
 
47
66
  # TODO: refactor this mess
@@ -51,7 +70,7 @@ module Zhong
51
70
 
52
71
  case at
53
72
  when /\A([[:alpha:]]+)\s+(.*)\z/
54
- wday = WDAYS[$1]
73
+ wday = WDAYS[$1.downcase]
55
74
 
56
75
  if wday
57
76
  parsed_time = parse($2, grace: grace)
@@ -65,12 +84,12 @@ module Zhong
65
84
  when /\A\*{1,2}:(\d\d)\z/
66
85
  new(minute: $1.to_i, grace: grace)
67
86
  when /\A(\d{1,2}):\*{1,2}\z/
68
- new(hour: $1, grace: grace)
87
+ new(hour: $1.to_i, grace: grace)
69
88
  else
70
89
  fail FailedToParse, at
71
90
  end
72
91
  rescue ArgumentError
73
- throw FailedToParse, at
92
+ fail FailedToParse, at
74
93
  end
75
94
  end
76
95
 
@@ -8,7 +8,7 @@ module Zhong
8
8
  month: 1.month,
9
9
  semiannual: 6.months, # enterprise!
10
10
  year: 1.year,
11
- decade: 10.year
11
+ decade: 10.years
12
12
  }.freeze
13
13
 
14
14
  def initialize(period)
@@ -13,7 +13,7 @@ module Zhong
13
13
  @logger.error "warning: #{self} has `at` but no `every`; could run far more often than expected!"
14
14
  end
15
15
 
16
- fail "must specific either `at` or `every` for a job" unless @at || @every
16
+ fail "must specific either `at` or `every` for job: #{self}" unless @at || @every
17
17
 
18
18
  @block = block
19
19
 
@@ -19,7 +19,7 @@ module Zhong
19
19
  end
20
20
 
21
21
  def category(name)
22
- fail "cannot nest categories: #{name} would be nested in #{@category}" if @category
22
+ fail "cannot nest categories: #{name} would be nested in #{@category} (#{caller.first})" if @category
23
23
 
24
24
  @category = name.to_s
25
25
 
@@ -29,6 +29,7 @@ module Zhong
29
29
  end
30
30
 
31
31
  def every(period, name, opts = {}, &block)
32
+ fail "must specify a period for #{name} (#{caller.first})" unless period
32
33
  job = Job.new(name, opts.merge(@config).merge(every: period, category: @category), &block)
33
34
  add(job)
34
35
  end
@@ -1,3 +1,3 @@
1
1
  module Zhong
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+
3
+ if ENV["CODECLIMATE_REPO_TOKEN"]
4
+ require "codeclimate-test-reporter"
5
+ CodeClimate::TestReporter.start
6
+ end
7
+
8
+ require "zhong"
9
+ require "minitest/autorun"
10
+
11
+ ENV["ZHONG_TEST"] = "true"
@@ -1,6 +1,146 @@
1
- require 'minitest_helper'
1
+ require "test_helper"
2
2
 
3
- class TestZhong < Minitest::Test
3
+ # Many At tests lifted from Clockwork (thanks Clockwork!)
4
+ class TestAt < Minitest::Test
5
+ def time_in_day(hour, minute, day = 0, sec = 0)
6
+ Time.new.beginning_of_week(:monday).change(hour: hour, min: minute, sec: sec) + day.days
7
+ end
8
+
9
+ def test_16_20
10
+ at = Zhong::At.parse("16:20", grace: 0)
11
+
12
+ assert_equal time_in_day(16, 20), at.next_at(time_in_day(16, 15))
13
+ assert_equal time_in_day(16, 20), at.next_at(time_in_day(16, 20))
14
+ assert_equal time_in_day(16, 20), at.next_at(time_in_day(16, 20, 0, 10))
15
+ assert_equal time_in_day(16, 20), at.next_at(time_in_day(16, 20, 0, 59))
16
+ assert_equal time_in_day(16, 20, 1), at.next_at(time_in_day(16, 21))
17
+ assert_equal time_in_day(16, 20, 1), at.next_at(time_in_day(16, 21, 0, 01))
18
+ assert_equal time_in_day(16, 20, 2), at.next_at(time_in_day(16, 21, 1, 30))
19
+ end
20
+
21
+ def test_16_20_with_grace
22
+ at = Zhong::At.parse("16:20", grace: 5.minutes)
23
+
24
+ assert_equal time_in_day(16, 20), at.next_at(time_in_day(16, 21))
25
+ assert_equal time_in_day(16, 20), at.next_at(time_in_day(16, 25))
26
+ assert_equal time_in_day(16, 20, 1), at.next_at(time_in_day(16, 26))
27
+ end
28
+
29
+ def test_8_20_before
30
+ at = Zhong::At.parse("8:20")
31
+
32
+ assert_equal time_in_day(8, 20), at.next_at(time_in_day(8, 15))
33
+ assert_equal time_in_day(8, 20, 1), at.next_at(time_in_day(8, 21))
34
+ end
35
+
36
+ def test_two_star_20
37
+ at = Zhong::At.parse("**:20")
38
+
39
+ assert_equal time_in_day(8, 20), at.next_at(time_in_day(8, 15))
40
+ assert_equal time_in_day(9, 20), at.next_at(time_in_day(9, 15))
41
+ assert_equal time_in_day(10, 20), at.next_at(time_in_day(9, 45))
42
+ end
43
+
44
+ def test_one_star_20
45
+ at = Zhong::At.parse("*:45")
46
+
47
+ assert_equal time_in_day(8, 45), at.next_at(time_in_day(8, 35))
48
+ assert_equal time_in_day(9, 45), at.next_at(time_in_day(9, 35))
49
+ assert_equal time_in_day(10, 45), at.next_at(time_in_day(9, 50))
50
+ end
51
+
52
+ def test_one_star_20_with_grace
53
+ at = Zhong::At.parse("*:45", grace: 5.minutes)
54
+
55
+ assert_equal time_in_day(8, 45), at.next_at(time_in_day(8, 35))
56
+ assert_equal time_in_day(8, 45), at.next_at(time_in_day(8, 50))
57
+ assert_equal time_in_day(9, 45), at.next_at(time_in_day(8, 51))
58
+ assert_equal time_in_day(9, 45), at.next_at(time_in_day(9, 35))
59
+ assert_equal time_in_day(10, 45), at.next_at(time_in_day(9, 55))
60
+ end
61
+
62
+ def test_16_two_stars
63
+ at = Zhong::At.parse("16:**")
64
+
65
+ assert_equal time_in_day(16, 00), at.next_at(time_in_day(8, 45))
66
+ assert_equal time_in_day(16, 00), at.next_at(time_in_day(10, 00))
67
+ assert_equal time_in_day(16, 00), at.next_at(time_in_day(16, 00))
68
+ assert_equal time_in_day(16, 01), at.next_at(time_in_day(16, 01))
69
+ assert_equal time_in_day(16, 30), at.next_at(time_in_day(16, 30))
70
+ assert_equal time_in_day(16, 59), at.next_at(time_in_day(16, 59))
71
+ assert_equal time_in_day(16, 00, 1), at.next_at(time_in_day(17, 00))
72
+ assert_equal time_in_day(16, 00, 1), at.next_at(time_in_day(23, 59))
73
+ end
74
+
75
+ def test_8_two_stars
76
+ at = Zhong::At.parse("8:**")
77
+
78
+ assert_equal time_in_day(8, 00), at.next_at(time_in_day(3, 45))
79
+ assert_equal time_in_day(8, 00), at.next_at(time_in_day(5, 00))
80
+ assert_equal time_in_day(8, 00), at.next_at(time_in_day(8, 00))
81
+ assert_equal time_in_day(8, 01), at.next_at(time_in_day(8, 01))
82
+ assert_equal time_in_day(8, 30), at.next_at(time_in_day(8, 30))
83
+ assert_equal time_in_day(8, 59), at.next_at(time_in_day(8, 59))
84
+ assert_equal time_in_day(8, 00, 1), at.next_at(time_in_day(9, 00))
85
+ assert_equal time_in_day(8, 00, 1), at.next_at(time_in_day(12, 59))
86
+ end
87
+
88
+ def test_saturday_12
89
+ at = Zhong::At.parse("Saturday 12:00")
90
+
91
+ assert_equal time_in_day(12, 00, 5), at.next_at(time_in_day(12, 00))
92
+ assert_equal time_in_day(12, 00, 5), at.next_at(time_in_day(13, 00, 1))
93
+ assert_equal time_in_day(12, 00, 5), at.next_at(time_in_day(23, 59, 3))
94
+ assert_equal time_in_day(12, 00, 5), at.next_at(time_in_day(12, 00, 5))
95
+ assert_equal time_in_day(12, 00, 12), at.next_at(time_in_day(12, 01, 5))
96
+ assert_equal time_in_day(12, 00, 12), at.next_at(time_in_day(13, 01, 6, 01))
97
+ end
98
+
99
+ def test_sat_12
100
+ at = Zhong::At.parse("sat 12:00")
101
+
102
+ assert_equal time_in_day(12, 00, 5), at.next_at(time_in_day(12, 00))
103
+ assert_equal time_in_day(12, 00, 5), at.next_at(time_in_day(13, 00, 1))
104
+ assert_equal time_in_day(12, 00, 5), at.next_at(time_in_day(23, 59, 3))
105
+ assert_equal time_in_day(12, 00, 5), at.next_at(time_in_day(12, 00, 5))
106
+ assert_equal time_in_day(12, 00, 12), at.next_at(time_in_day(12, 01, 5))
107
+ assert_equal time_in_day(12, 00, 12), at.next_at(time_in_day(13, 01, 6, 01))
108
+ end
109
+
110
+ def test_tue_12_59
111
+ at = Zhong::At.parse("tue 12:59")
112
+
113
+ assert_equal time_in_day(12, 59, 1), at.next_at(time_in_day(7, 00))
114
+ assert_equal time_in_day(12, 59, 1), at.next_at(time_in_day(12, 00, 1))
115
+ assert_equal time_in_day(12, 59, 1), at.next_at(time_in_day(12, 59, 1))
116
+ assert_equal time_in_day(12, 59, 8), at.next_at(time_in_day(13, 00, 1))
117
+ assert_equal time_in_day(12, 59, 8), at.next_at(time_in_day(13, 01, 6, 01))
118
+ end
119
+
120
+ def test_thr_12_59
121
+ at = Zhong::At.parse("thr 12:59")
122
+
123
+ assert_equal time_in_day(12, 59, 3), at.next_at(time_in_day(7, 00))
124
+ assert_equal time_in_day(12, 59, 3), at.next_at(time_in_day(12, 00, 3))
125
+ assert_equal time_in_day(12, 59, 3), at.next_at(time_in_day(12, 59, 3))
126
+ assert_equal time_in_day(12, 59, 10), at.next_at(time_in_day(13, 00, 3))
127
+ assert_equal time_in_day(12, 59, 10), at.next_at(time_in_day(13, 01, 6, 01))
128
+ end
129
+
130
+ def test_invalid_time_32
131
+ assert_raises Zhong::At::FailedToParse do
132
+ Zhong::At.parse("32:00")
133
+ end
134
+ end
135
+
136
+ def test_invalid_multi_line_time_sat_12
137
+ assert_raises Zhong::At::FailedToParse do
138
+ Zhong::At.parse("sat 12:00\nreally invalid time")
139
+ end
140
+ end
141
+ end
142
+
143
+ class TestLibrary < Minitest::Test
4
144
  def test_that_it_has_a_version_number
5
145
  refute_nil ::Zhong::VERSION
6
146
  end
@@ -26,11 +26,10 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency "redis"
27
27
  spec.add_dependency "tzinfo"
28
28
  spec.add_dependency "activesupport"
29
- spec.add_dependency "memory_profiler"
30
29
 
31
30
  spec.add_development_dependency "bundler", "~> 1.5"
32
31
  spec.add_development_dependency "rake", "~> 10.0"
33
32
  spec.add_development_dependency "rubocop", "~> 0.30.0"
34
33
  spec.add_development_dependency "minitest", "~> 5.5.0"
35
- # spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4.7"
34
+ spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4.7"
36
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zhong
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Elser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-07 00:00:00.000000000 Z
11
+ date: 2015-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: suo
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: memory_profiler
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: bundler
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +122,20 @@ dependencies:
136
122
  - - "~>"
137
123
  - !ruby/object:Gem::Version
138
124
  version: 5.5.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: codeclimate-test-reporter
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.4.7
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.4.7
139
139
  description: Reliable, distributed cron.
140
140
  email:
141
141
  - nick.elser@gmail.com
@@ -164,7 +164,7 @@ files:
164
164
  - lib/zhong/scheduler.rb
165
165
  - lib/zhong/util.rb
166
166
  - lib/zhong/version.rb
167
- - test/minitest_helper.rb
167
+ - test/test_helper.rb
168
168
  - test/zhong_test.rb
169
169
  - zhong.gemspec
170
170
  homepage: https://www.github.com/nickelser/zhong
@@ -192,5 +192,5 @@ signing_key:
192
192
  specification_version: 4
193
193
  summary: Reliable, distributed cron.
194
194
  test_files:
195
- - test/minitest_helper.rb
195
+ - test/test_helper.rb
196
196
  - test/zhong_test.rb
@@ -1,4 +0,0 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
- require 'zhong'
3
-
4
- require 'minitest/autorun'