clockwork-test 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +190 -0
- data/Rakefile +7 -0
- data/clockwork-test.gemspec +29 -0
- data/lib/clockwork/test/event.rb +12 -0
- data/lib/clockwork/test/job_history.rb +40 -0
- data/lib/clockwork/test/manager.rb +89 -0
- data/lib/clockwork/test/rspec/matchers/have_run.rb +67 -0
- data/lib/clockwork/test/rspec/matchers.rb +13 -0
- data/lib/clockwork/test/version.rb +5 -0
- data/lib/clockwork/test.rb +74 -0
- data/spec/acceptance/clock_spec.rb +50 -0
- data/spec/clockwork/test/job_history_spec.rb +96 -0
- data/spec/clockwork/test/manager_spec.rb +176 -0
- data/spec/clockwork/test_spec.rb +28 -0
- data/spec/fixtures/clock.rb +13 -0
- data/spec/spec_helper.rb +9 -0
- metadata +169 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9e5400764eb671ac7bd63e5fbd30ffd6d173f65d
|
4
|
+
data.tar.gz: e73c3fa5290e7683b17f89b7e0f1b3c206a56bdb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 48a656be5270cfac4ea3821b8fa55f8db3c67fc2abca37147fd7eefe3105110c90849447d5cb688549dd6b38a38a6e1ad1ad2ae9e3b6611d157f82296263331a
|
7
|
+
data.tar.gz: 82fdef73b35c494bfc44a3239c94affca04e4ded03d0627576c6591e55a7e9e8d8b10e4a9e7fbbfeeadf800c5e53fed87dc6fc78a6af187599d79b8689c3efa4
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Kevin Murphy
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
# Clockwork::Test
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/kevin-j-m/clockwork-test.svg?branch=master)](https://travis-ci.org/kevin-j-m/clockwork-test)
|
4
|
+
|
5
|
+
[Clockwork](https://rubygems.org/gems/clockwork) is a scheduler process for running scheduled jobs. These scheduled jobs are likely of critical importance to your application. You need to ensure that the jobs run when they should, as often as they should, and with the proper behavior when run.
|
6
|
+
|
7
|
+
`Clockwork::Test` includes additional functionality that makes testing of your `clock.rb` file easy. This gem can help make sure that you have scheduled your events appropriately, including testing `if:` or `at:` conditions, as well as allowing you to run assertions against the code that is executed when a job is run.
|
8
|
+
|
9
|
+
`Clockwork::Test` has been verified against the latest release of clockwork at the time of its development, which is version 1.2.0. It does not require any specific test framework to be used with it, though all examples will use `rspec`.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
group :test do
|
17
|
+
gem 'clockwork-test'
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
$ gem install clockwork-test
|
28
|
+
|
29
|
+
## Example Tests
|
30
|
+
|
31
|
+
Given the following `clock.rb` file:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require "clockwork"
|
35
|
+
|
36
|
+
module Clockwork
|
37
|
+
configure do |config|
|
38
|
+
config[:tz] = "US/Eastern"
|
39
|
+
end
|
40
|
+
|
41
|
+
handler { |job| logger.info "Running #{job}" }
|
42
|
+
|
43
|
+
every(1.minute, "Run a job") do
|
44
|
+
"Here's a running job"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
The following tests may be run against it:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
describe Clockwork do
|
53
|
+
after(:each) { Clockwork::Test.clear! }
|
54
|
+
|
55
|
+
it "runs the job once" do
|
56
|
+
Clockwork::Test.run(max_ticks: 1)
|
57
|
+
|
58
|
+
expect(Clockwork::Test.ran_job?("Run a job")).to be_truthy
|
59
|
+
expect(Clockwork::Test.times_run("Run a job")).to eq 1
|
60
|
+
expect(Clockwork::Test.block_for("Run a job").call).to eq "Here's a running job"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "runs the job every minute over the course of an hour" do
|
64
|
+
start_time = Time.new(2015, 11, 2, 2, 0, 0)
|
65
|
+
end_time = Time.new(2015, 11, 2, 3, 0, 0)
|
66
|
+
|
67
|
+
Clockwork::Test.run(start_time: start_time, end_time: end_time, tick_speed:
|
68
|
+
1.minute)
|
69
|
+
|
70
|
+
expect(Clockwork::Test.times_run("Run a job").to eq 60
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "RSpec Custom Matcher" do
|
74
|
+
subject(:clockwork) { Clockwork::Test }
|
75
|
+
|
76
|
+
before { Clockwork::Test.run(max_ticks: 1) }
|
77
|
+
|
78
|
+
it { should have_run("Run a job") }
|
79
|
+
it { should have_run("Run a job").once }
|
80
|
+
|
81
|
+
it { should_not have_run("Run a job").exactly(2).times }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
## Usage
|
87
|
+
|
88
|
+
Replacing any calls to `Clockwork` with `Clockwork::Test` in your tests should perform as expected, with the one caveat that a job running in `Clockwork::Test` will not actually execute its event's handler code. That is suppressed, but made available via the `block_for` method.
|
89
|
+
|
90
|
+
### Running Clockwork in Tests
|
91
|
+
|
92
|
+
A call to `Clockwork.run` will run the clockwork process until it is signaled to stop, such as by receiving the `SIGINT` signal. `Clockwork::Test.run` provides two ways to easily stop the current execution:
|
93
|
+
|
94
|
+
1. After a particular number of clock ticks (See the `max_ticks` configuration setting).
|
95
|
+
3. After a moment in time has been reached (See the `end_time` configuration setting).
|
96
|
+
|
97
|
+
Either of these methods can be used by passing the proper configuration option into the `run` method of `Clockwork::Test`. If both are provided, whichever occurs first will be used to halt execution.
|
98
|
+
|
99
|
+
### Configuration Settings
|
100
|
+
|
101
|
+
#### max_ticks
|
102
|
+
|
103
|
+
Setting the `max_ticks` will determine the number of times that clockwork will run any events scheduled at that time. This is commonly used to let clockwork execute once, to then see if particular jobs are triggered right when clockwork starts up.
|
104
|
+
|
105
|
+
#### start_time
|
106
|
+
|
107
|
+
This is the time that you would like the clock file to start processing it. This may be used with either the `max_ticks` or `end_time` option to halt execution of the run loop.
|
108
|
+
|
109
|
+
If the `start_time` option is used, `Time.now` will be modified to the `start_time` at the beginning of execution of `Clockwork::Test.run`, and will be returned to the proper time at the conclusion of the run.
|
110
|
+
|
111
|
+
#### end_time
|
112
|
+
|
113
|
+
This specifies the time at which execution of clockwork should terminate. The run loop will continue until the `end_time` is reached, provided the `max_ticks` has not been exceeded, if that is provided.
|
114
|
+
|
115
|
+
This is commonly used along with `start_time` and `tick_speed` to quickly see if jobs run as often as expected over a certain period of time.
|
116
|
+
|
117
|
+
#### tick_speed
|
118
|
+
|
119
|
+
`tick_speed` should be provided as a unit of time, such as `1.minute` or `3.hours`. It is the amount of time that the test will progress time to on every subsequent clock tick.
|
120
|
+
|
121
|
+
If `tick_speed` is set to `1.minute` and the current time is `13:00`, the first tick will occur at `13:00`, and the second will appear occur at `13:01`.
|
122
|
+
|
123
|
+
This can be used in concert with `start_time` and `end_time` to quickly simulate moving across a large period of time, without having to wait for the full time period to occur in reality.
|
124
|
+
|
125
|
+
Note that `tick_speed` should not be set any higher than the minimum amount of granularity used in the clock file under test. Should the `tick_speed` be set to a higher amount, the number of times a job is run, or if the job is run at all, is subject to inconsistent and inaccurate results.
|
126
|
+
|
127
|
+
For example, with a `tick_speed` of `30.minutes` and a job that runs every `1.minute` over the course of an hour, the `times_ran` for that job will *not* be 60. It will be 2, assuming minimal passage of time in evaluating the actual clock tick.
|
128
|
+
|
129
|
+
#### file
|
130
|
+
|
131
|
+
The location of the clock file to test. This defaults to `"./config/clock.rb"` if a value is not provided.
|
132
|
+
|
133
|
+
### Assertions Against Test Runs
|
134
|
+
|
135
|
+
After running your clock file with `Clockwork::Test.run`, you can use the following methods to assert the clock file ran as expected:
|
136
|
+
|
137
|
+
#### ran_job?
|
138
|
+
|
139
|
+
`ran_job?` lets you know if a particular job ran during previous executions of `Clockwork::Test.run`.
|
140
|
+
|
141
|
+
If the job "test_job" has run, `ran_job?("test_job")` will be true; otherwise, the method will return false.
|
142
|
+
|
143
|
+
#### times_run
|
144
|
+
|
145
|
+
`times_run` provides the number of times a job has run during previous executions of `Clockwork::Test.run`.
|
146
|
+
|
147
|
+
If the job "test_job" never ran, `times_run("test_job")` will be 0; otherwise, it will be the number of times that the event was executed.
|
148
|
+
|
149
|
+
#### block_for
|
150
|
+
|
151
|
+
`block_for` returns the block that would be handled and run on each execution of a job. This can be useful for ensuring that the block you associated with an event does whatever it is that you expect it to do.
|
152
|
+
|
153
|
+
If the job "test_job" never ran, `block_for("test_job")` will return an empty proc; otherwise, the block of code that the event would run is returned, which can then be `call`ed to test.
|
154
|
+
|
155
|
+
### RSpec Matchers
|
156
|
+
|
157
|
+
`Clockwork::Test` includes a rspec test matcher to check if a job has been run.
|
158
|
+
|
159
|
+
To use, add the following to your `spec_helper.rb`:
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
RSpec.configure do |config|
|
163
|
+
config.include(Clockwork::Test::RSpec::Matchers)
|
164
|
+
end
|
165
|
+
```
|
166
|
+
|
167
|
+
The `have_run` matcher checks if a job by the name provided has been run, and allows for a specific number of times to be checked against.
|
168
|
+
|
169
|
+
`expect(Clockwork::Test).to have_run("Job Name").exactly(42).times`
|
170
|
+
|
171
|
+
You can alternatively pass the number of times in as an optional argument in the `have_run` method, as such:
|
172
|
+
|
173
|
+
`expect(Clockwork::Test).to have_run("Job Name", times: 42)`
|
174
|
+
|
175
|
+
Chaining `once` to `have_run` will check that the job was run one time only.
|
176
|
+
|
177
|
+
If you do not pass the number of times, either with a chained method call or as an optional argument to `have_run`, the matcher will just check if the job was run at all. It provides no assertion as to how often it was run, just that it's at least once.
|
178
|
+
|
179
|
+
### Resetting the clock
|
180
|
+
|
181
|
+
After each invocation of `Clockwork::Test.run` and assertions made against it, `Clockwork::Test.clear!` should be called. This will wipe all history away and load up the clock file fresh on the next `run`. Failure to do so across tests will carry over past history, which will cause the number of times a job has run to be incorrect and subject to a test ordering bug.
|
182
|
+
|
183
|
+
## Contributing
|
184
|
+
|
185
|
+
1. Fork it ( https://github.com/kevin-j-m/clockwork-test/fork )
|
186
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
187
|
+
3. Run the tests (`rspec`) and ensure they pass
|
188
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
189
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
190
|
+
6. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'clockwork/test/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "clockwork-test"
|
8
|
+
spec.version = Clockwork::Test::VERSION
|
9
|
+
spec.authors = ["Kevin Murphy"]
|
10
|
+
spec.email = ["murphy.kevin.mail@gmail.com"]
|
11
|
+
spec.summary = "Test clockwork scheduled jobs"
|
12
|
+
spec.description = "Run clockwork jobs in a test environment and assert jobs are run as expected"
|
13
|
+
spec.homepage = "https://github.com/kevin-j-m/clockwork-test"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "pry"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "rspec-its"
|
26
|
+
|
27
|
+
spec.add_runtime_dependency "clockwork"
|
28
|
+
spec.add_runtime_dependency "timecop"
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Clockwork
|
2
|
+
module Test
|
3
|
+
class JobHistory
|
4
|
+
def initialize(prior_history = {}, prior_work = {})
|
5
|
+
@history = prior_history
|
6
|
+
@work_done = prior_work
|
7
|
+
end
|
8
|
+
|
9
|
+
def jobs
|
10
|
+
history.keys
|
11
|
+
end
|
12
|
+
|
13
|
+
def ran_job?(job)
|
14
|
+
jobs.include?(job)
|
15
|
+
end
|
16
|
+
|
17
|
+
def times_run(job)
|
18
|
+
history[job] || 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def block_for(job)
|
22
|
+
work_done[job] || Proc.new {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def record(new_events)
|
26
|
+
new_events.each do |event|
|
27
|
+
job = event.job
|
28
|
+
|
29
|
+
prior_runs = times_run(job)
|
30
|
+
history[job] = prior_runs > 0 ? prior_runs + 1 : 1
|
31
|
+
work_done[job] = event.block
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :history, :work_done
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Clockwork
|
2
|
+
module Test
|
3
|
+
class Manager < Clockwork::Manager
|
4
|
+
attr_reader :total_ticks, :max_ticks, :end_time
|
5
|
+
|
6
|
+
def initialize(opts = {})
|
7
|
+
super()
|
8
|
+
@history = JobHistory.new
|
9
|
+
|
10
|
+
@total_ticks = 0
|
11
|
+
@max_ticks = opts[:max_ticks]
|
12
|
+
@end_time = opts[:end_time]
|
13
|
+
config[:logger].level = Logger::ERROR
|
14
|
+
end
|
15
|
+
|
16
|
+
def run(opts = {})
|
17
|
+
@max_ticks = opts[:max_ticks] if opts[:max_ticks]
|
18
|
+
@end_time = opts[:end_time] if opts[:end_time]
|
19
|
+
@tick_speed = opts[:tick_speed]
|
20
|
+
|
21
|
+
if opts[:start_time]
|
22
|
+
@time_altered = true
|
23
|
+
Timecop.travel(opts[:start_time])
|
24
|
+
end
|
25
|
+
|
26
|
+
super()
|
27
|
+
|
28
|
+
Timecop.return if @time_altered
|
29
|
+
end
|
30
|
+
|
31
|
+
def ran_job?(job)
|
32
|
+
history.ran_job?(job)
|
33
|
+
end
|
34
|
+
|
35
|
+
def times_run(job)
|
36
|
+
history.times_run(job)
|
37
|
+
end
|
38
|
+
|
39
|
+
def block_for(job)
|
40
|
+
history.block_for(job)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
attr_reader :history
|
46
|
+
|
47
|
+
def loop(&block)
|
48
|
+
while 1 == 1 do
|
49
|
+
update_job_history
|
50
|
+
|
51
|
+
block.call
|
52
|
+
|
53
|
+
@total_ticks += 1
|
54
|
+
break if ticks_exceeded? || time_exceeded?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def sleep(interval)
|
59
|
+
if @tick_speed
|
60
|
+
Timecop.travel(Time.now + @tick_speed)
|
61
|
+
else
|
62
|
+
super
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def register(period, job, block, options)
|
67
|
+
event = ::Clockwork::Test::Event.new(self, period, job, block || handler, options)
|
68
|
+
@events << event
|
69
|
+
event
|
70
|
+
end
|
71
|
+
|
72
|
+
def update_job_history
|
73
|
+
history.record(events_run_now)
|
74
|
+
end
|
75
|
+
|
76
|
+
def events_run_now
|
77
|
+
events_to_run(Time.now)
|
78
|
+
end
|
79
|
+
|
80
|
+
def ticks_exceeded?
|
81
|
+
max_ticks && total_ticks >= max_ticks
|
82
|
+
end
|
83
|
+
|
84
|
+
def time_exceeded?
|
85
|
+
end_time && Time.now >= end_time
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Clockwork
|
2
|
+
module Test
|
3
|
+
module RSpec
|
4
|
+
module Matchers
|
5
|
+
class HaveRun
|
6
|
+
def initialize(job_name = nil, opts = {})
|
7
|
+
@job_name = job_name
|
8
|
+
@times_run = opts[:times] || 1
|
9
|
+
@exactly = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(clock_test)
|
13
|
+
if @exactly
|
14
|
+
clock_test.manager.times_run(@job_name) == @times_run
|
15
|
+
else
|
16
|
+
clock_test.manager.ran_job?(@job_name)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def once
|
21
|
+
@times_run = 1
|
22
|
+
@exactly = true
|
23
|
+
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def exactly(times)
|
28
|
+
@times_run = times
|
29
|
+
@exactly = true
|
30
|
+
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def times(times = nil)
|
35
|
+
if times
|
36
|
+
@times_run = times
|
37
|
+
@exactly = true
|
38
|
+
end
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def time(times = nil)
|
44
|
+
if times
|
45
|
+
@times_run = times
|
46
|
+
@exactly = true
|
47
|
+
end
|
48
|
+
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def description
|
53
|
+
"run \"#{@job_name}\" #{@times_run} #{@times_run == 1 ? 'time' : 'times'}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def failure_message
|
57
|
+
"expected Clockwork::Test to have " + description
|
58
|
+
end
|
59
|
+
|
60
|
+
def failure_message_when_negated
|
61
|
+
"expected Clockwork::Test to not have run \"#{@job_name}\"."
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "clockwork"
|
2
|
+
require "timecop"
|
3
|
+
|
4
|
+
require "clockwork/test/event"
|
5
|
+
require "clockwork/test/job_history"
|
6
|
+
require "clockwork/test/manager"
|
7
|
+
require "clockwork/test/version"
|
8
|
+
require "clockwork/test/rspec/matchers"
|
9
|
+
|
10
|
+
module Clockwork
|
11
|
+
module Methods
|
12
|
+
def every(period, job, options={}, &block)
|
13
|
+
::Clockwork.manager.every(period, job, options, &block)
|
14
|
+
::Clockwork::Test.manager.every(period, job, options, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Test
|
19
|
+
class << self
|
20
|
+
def included(klass)
|
21
|
+
klass.send "include", Methods
|
22
|
+
klass.extend Methods
|
23
|
+
|
24
|
+
klass.send "include", ::Clockwork::Methods
|
25
|
+
klass.extend ::Clockwork::Methods
|
26
|
+
end
|
27
|
+
|
28
|
+
def manager
|
29
|
+
@manager ||= Clockwork::Test::Manager.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def manager=(manager)
|
33
|
+
@manager = manager
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Methods
|
38
|
+
def run(opts = {})
|
39
|
+
file = opts[:file] || "./config/clock.rb"
|
40
|
+
|
41
|
+
run_opts = {
|
42
|
+
max_ticks: opts[:max_ticks],
|
43
|
+
start_time: opts[:start_time],
|
44
|
+
end_time: opts[:end_time],
|
45
|
+
tick_speed: opts[:tick_speed]
|
46
|
+
}
|
47
|
+
|
48
|
+
# TODO parse file rather than loading it
|
49
|
+
# and overloading Clockwork::Methods::every
|
50
|
+
load file
|
51
|
+
|
52
|
+
manager.run(run_opts)
|
53
|
+
end
|
54
|
+
|
55
|
+
def clear!
|
56
|
+
Clockwork::Test.manager = Clockwork::Test::Manager.new
|
57
|
+
end
|
58
|
+
|
59
|
+
def ran_job?(job)
|
60
|
+
manager.ran_job?(job)
|
61
|
+
end
|
62
|
+
|
63
|
+
def times_run(job)
|
64
|
+
manager.times_run(job)
|
65
|
+
end
|
66
|
+
|
67
|
+
def block_for(job)
|
68
|
+
manager.block_for(job)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
extend Methods, ::Clockwork::Methods
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Clockwork" do
|
4
|
+
let(:clock_file) { "spec/fixtures/clock.rb" }
|
5
|
+
let(:test_job_name) { "Run a job" }
|
6
|
+
|
7
|
+
after(:each) { Clockwork::Test.clear! }
|
8
|
+
|
9
|
+
describe "Run a job" do
|
10
|
+
before { Clockwork::Test.run(file: clock_file, max_ticks: 1) }
|
11
|
+
|
12
|
+
it "runs the test job in the file" do
|
13
|
+
expect(Clockwork::Test.ran_job?(test_job_name)).to be_truthy
|
14
|
+
end
|
15
|
+
|
16
|
+
it "knows the job ran a single time" do
|
17
|
+
expect(Clockwork::Test.times_run(test_job_name)).to eq 1
|
18
|
+
end
|
19
|
+
|
20
|
+
it "retains a record of the work that the job would have done" do
|
21
|
+
expect(Clockwork::Test.block_for(test_job_name).call).to eq "Here's a running job"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "Custom matchers" do
|
26
|
+
subject(:clockwork) { Clockwork::Test }
|
27
|
+
|
28
|
+
before { Clockwork::Test.run(file: clock_file, max_ticks: 1) }
|
29
|
+
|
30
|
+
it { should have_run(test_job_name) }
|
31
|
+
it { should have_run(test_job_name).once }
|
32
|
+
|
33
|
+
it { should_not have_run(test_job_name).exactly(2).times }
|
34
|
+
|
35
|
+
it "works as an explicit expectation as well" do
|
36
|
+
expect(Clockwork::Test).to have_run(test_job_name)
|
37
|
+
expect(Clockwork::Test).to_not have_run(test_job_name).exactly(2).times
|
38
|
+
end
|
39
|
+
|
40
|
+
context "running multiple times" do
|
41
|
+
before { Clockwork::Test.run(file: clock_file, max_ticks: 2, tick_speed: 1.minute) }
|
42
|
+
|
43
|
+
it { should have_run(test_job_name).exactly(2).times }
|
44
|
+
it { should have_run(test_job_name) }
|
45
|
+
it { should have_run(test_job_name).times(2) }
|
46
|
+
it { should have_run(test_job_name).exactly(2) }
|
47
|
+
it { should have_run(test_job_name, times: 2) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "clockwork/test/job_history"
|
3
|
+
|
4
|
+
describe Clockwork::Test::JobHistory do
|
5
|
+
subject(:history) { Clockwork::Test::JobHistory.new(prior_history, prior_work) }
|
6
|
+
let(:prior_history) { {} }
|
7
|
+
let(:prior_work) { {} }
|
8
|
+
|
9
|
+
describe "#jobs" do
|
10
|
+
let(:prior_history) do
|
11
|
+
{
|
12
|
+
"#{first_job}" => 1,
|
13
|
+
"#{second_job}" => 1
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:first_job) { "job1" }
|
18
|
+
let(:second_job) { "job2" }
|
19
|
+
|
20
|
+
its(:jobs) { should include first_job, second_job }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#ran_job?" do
|
24
|
+
let(:prior_history) { { "#{first_job}" => 1 } }
|
25
|
+
let(:first_job) { "job1" }
|
26
|
+
let(:second_job) { "job2" }
|
27
|
+
|
28
|
+
it "finds history of a job that ran" do
|
29
|
+
expect(history.ran_job?(first_job)).to be_truthy
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not find history of a job never run" do
|
33
|
+
expect(history.ran_job?(second_job)).to be_falsey
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#times_run" do
|
38
|
+
let(:prior_history) { { "#{first_job}" => number_of_first_job_runs } }
|
39
|
+
let(:first_job) { "job1" }
|
40
|
+
let(:number_of_first_job_runs) { 42 }
|
41
|
+
let(:second_job) { "job2" }
|
42
|
+
|
43
|
+
it "finds the number of times a previously job has run" do
|
44
|
+
expect(history.times_run(first_job)).to eq number_of_first_job_runs
|
45
|
+
end
|
46
|
+
|
47
|
+
it "finds no runs for a job it has no history of" do
|
48
|
+
expect(history.times_run(second_job)).to eq 0
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#block_for" do
|
53
|
+
let(:prior_work) { { "#{job}" => block } }
|
54
|
+
let(:job) { "job" }
|
55
|
+
let(:block) { Proc.new { "Running #{job}" } }
|
56
|
+
|
57
|
+
it "recalls the block that was run for a previously run job" do
|
58
|
+
expect(history.block_for(job).call).to eq "Running #{job}"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "does nothing for a job that was not run" do
|
62
|
+
expect(history.block_for("not_run").call).to be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#record" do
|
67
|
+
let(:events) { [first_event, second_event] }
|
68
|
+
|
69
|
+
let(:first_event) { double(job: first_job, block: first_block) }
|
70
|
+
let(:first_job) { "job1" }
|
71
|
+
let(:first_block) { Proc.new { "Running #{first_job}" } }
|
72
|
+
|
73
|
+
let(:second_event) { double(job: second_job, block: second_block) }
|
74
|
+
let(:second_job) { "job2" }
|
75
|
+
let(:second_block) { Proc.new {} }
|
76
|
+
|
77
|
+
before { history.record(events) }
|
78
|
+
|
79
|
+
it "keeps a record of the job occurring" do
|
80
|
+
expect(history.jobs).to include first_job, second_job
|
81
|
+
end
|
82
|
+
|
83
|
+
it "knows the work the job would perform" do
|
84
|
+
expect(history.block_for(first_job).call).to eq "Running #{first_job}"
|
85
|
+
end
|
86
|
+
|
87
|
+
context "recording jobs that already ran" do
|
88
|
+
let(:prior_history) { { "#{first_job}" => 1 } }
|
89
|
+
|
90
|
+
it "increments the counter of the job already recording and adds a new entry for the job never recorded prior" do
|
91
|
+
expect(history.times_run(first_job)).to eq 2
|
92
|
+
expect(history.times_run(second_job)).to eq 1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "clockwork/test/manager"
|
3
|
+
|
4
|
+
describe Clockwork::Test::Manager do
|
5
|
+
subject(:manager) { Clockwork::Test::Manager.new(opts) }
|
6
|
+
let(:opts) { {} }
|
7
|
+
|
8
|
+
context "initial state" do
|
9
|
+
its(:total_ticks) { should eq 0 }
|
10
|
+
its(:max_ticks) { should be_nil }
|
11
|
+
its(:end_time) { should be_nil }
|
12
|
+
|
13
|
+
context "providing a maximum number of ticks" do
|
14
|
+
let(:opts) { { max_ticks: max_ticks } }
|
15
|
+
let(:max_ticks) { 42 }
|
16
|
+
|
17
|
+
its(:max_ticks) { should eq max_ticks }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "providing a time the clock should stop" do
|
21
|
+
let(:opts) { { end_time: end_time } }
|
22
|
+
let(:end_time) { Time.current }
|
23
|
+
|
24
|
+
its(:end_time) { should eq end_time }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#run" do
|
29
|
+
context "limiting the number of ticks" do
|
30
|
+
let(:opts) { { max_ticks: max_ticks } }
|
31
|
+
let(:max_ticks) { 1 }
|
32
|
+
|
33
|
+
it "only runs the number of times specified" do
|
34
|
+
manager.run
|
35
|
+
expect(manager.total_ticks).to eq 1
|
36
|
+
end
|
37
|
+
|
38
|
+
context "specifying number of ticks in the method invocation" do
|
39
|
+
let(:method_max_ticks) { 3 }
|
40
|
+
|
41
|
+
it "runs the number of times specified in the run call" do
|
42
|
+
manager.run(max_ticks: method_max_ticks)
|
43
|
+
expect(manager.total_ticks).to eq method_max_ticks
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "limiting the time the clock should run" do
|
49
|
+
let(:opts) { { end_time: end_time } }
|
50
|
+
let(:end_time) { Time.current + 2.seconds }
|
51
|
+
|
52
|
+
it "stops running after reaching the end time" do
|
53
|
+
manager.run
|
54
|
+
expect(Time.current).to be_within(1.second).of(end_time)
|
55
|
+
expect(manager.total_ticks).to be > 0
|
56
|
+
end
|
57
|
+
|
58
|
+
context "specifying the end time in the method invocation" do
|
59
|
+
let(:method_end_time) { Time.current + 4.seconds }
|
60
|
+
|
61
|
+
it "stops running after reaching the end time specified in the call" do
|
62
|
+
manager.run(end_time: method_end_time)
|
63
|
+
expect(Time.current).to be_within(1.second).of(method_end_time)
|
64
|
+
expect(manager.total_ticks).to be > 0
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "recording job history" do
|
70
|
+
let(:opts) { { max_ticks: max_ticks } }
|
71
|
+
let(:max_ticks) { 1 }
|
72
|
+
let(:job_name) { "Test job" }
|
73
|
+
|
74
|
+
before do
|
75
|
+
manager.handler { }
|
76
|
+
manager.every(1.minute, job_name)
|
77
|
+
manager.run
|
78
|
+
end
|
79
|
+
|
80
|
+
it "knows the job has run" do
|
81
|
+
expect(manager.ran_job?(job_name)).to be_truthy
|
82
|
+
end
|
83
|
+
|
84
|
+
it "finds a single run of the job" do
|
85
|
+
expect(manager.times_run(job_name)).to eq 1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "modifying when the test is run" do
|
90
|
+
let(:opts) { { max_ticks: max_ticks } }
|
91
|
+
let(:max_ticks) { 1 }
|
92
|
+
let(:job_name) { "Test job" }
|
93
|
+
let(:start_time) { Time.new(2000) }
|
94
|
+
|
95
|
+
before do
|
96
|
+
manager.handler { }
|
97
|
+
manager.every(1.minute, job_name, if: lambda { |t| t.year == 2000 })
|
98
|
+
manager.run(start_time: start_time)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "runs the jobs at the time specified" do
|
102
|
+
expect(manager.ran_job?(job_name)).to be_truthy
|
103
|
+
end
|
104
|
+
|
105
|
+
it "resets time at the conclusion of the run" do
|
106
|
+
expect(Time.now.year).to be > 2000
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "speeding up the test run" do
|
111
|
+
let(:start_time) { Time.new(2015, 11, 2, 2, 0, 0) }
|
112
|
+
let(:end_time) { Time.new(2015, 11, 2, 3, 0, 0) }
|
113
|
+
let(:tick_speed) { 1.minute }
|
114
|
+
let(:job_name) { "Test job" }
|
115
|
+
|
116
|
+
before do
|
117
|
+
manager.handler { }
|
118
|
+
manager.every(1.minute, job_name)
|
119
|
+
manager.run(start_time: start_time, end_time: end_time, tick_speed: tick_speed)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "runs the job as often as expected" do
|
123
|
+
expect(manager.times_run(job_name)).to eq 60
|
124
|
+
end
|
125
|
+
|
126
|
+
context "speeding up time" do
|
127
|
+
let(:tick_speed) { 30.minutes }
|
128
|
+
it "runs the job fewer times than it otherwise would" do
|
129
|
+
expect(manager.times_run(job_name)).to be < 60
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "#ran_job?" do
|
136
|
+
let(:history) { double("history") }
|
137
|
+
let(:job) { double("job") }
|
138
|
+
|
139
|
+
it "determines if the job has run from the job history" do
|
140
|
+
allow(manager).to receive(:history).and_return(history)
|
141
|
+
|
142
|
+
expect(history).to receive(:ran_job?).with(job)
|
143
|
+
manager.ran_job?(job)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "#times_run" do
|
148
|
+
let(:history) { double("history") }
|
149
|
+
let(:job) { double("job") }
|
150
|
+
|
151
|
+
it "determines the number of times the job has run from the history" do
|
152
|
+
allow(manager).to receive(:history).and_return(history)
|
153
|
+
|
154
|
+
expect(history).to receive(:times_run).with(job)
|
155
|
+
manager.times_run(job)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "#block_for" do
|
160
|
+
let(:opts) { { max_ticks: max_ticks } }
|
161
|
+
let(:max_ticks) { 1 }
|
162
|
+
let(:job_name) { "Test job" }
|
163
|
+
before do
|
164
|
+
manager.every(1.minute, job_name) { "Running #{job_name}" }
|
165
|
+
manager.run
|
166
|
+
end
|
167
|
+
|
168
|
+
it "recalls the block that was run for a previously run job" do
|
169
|
+
expect(manager.block_for(job_name).call).to eq "Running #{job_name}"
|
170
|
+
end
|
171
|
+
|
172
|
+
it "does nothing for a job that was not run" do
|
173
|
+
expect(manager.block_for("not_run").call).to be_nil
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Clockwork::Test do
|
4
|
+
let(:clock_file) { "spec/fixtures/clock.rb" }
|
5
|
+
let(:test_job_name) { "Run a job" }
|
6
|
+
let(:test_job_output) { "Here's a running job" }
|
7
|
+
|
8
|
+
it "has a version number" do
|
9
|
+
expect(Clockwork::Test::VERSION).not_to be nil
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ".run" do
|
13
|
+
before { Clockwork::Test.run(file: clock_file, max_ticks: 1) }
|
14
|
+
after { Clockwork::Test.clear! }
|
15
|
+
|
16
|
+
it "runs the test job in the file" do
|
17
|
+
expect(Clockwork::Test.ran_job?(test_job_name)).to be_truthy
|
18
|
+
end
|
19
|
+
|
20
|
+
it "knows the job ran a single time" do
|
21
|
+
expect(Clockwork::Test.times_run(test_job_name)).to eq 1
|
22
|
+
end
|
23
|
+
|
24
|
+
it "retains a record of the work that the job would have done" do
|
25
|
+
expect(Clockwork::Test.block_for(test_job_name).call).to eq test_job_output
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: clockwork-test
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Murphy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-11-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-its
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: clockwork
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: timecop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Run clockwork jobs in a test environment and assert jobs are run as expected
|
112
|
+
email:
|
113
|
+
- murphy.kevin.mail@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".rspec"
|
120
|
+
- ".travis.yml"
|
121
|
+
- Gemfile
|
122
|
+
- LICENSE.txt
|
123
|
+
- README.md
|
124
|
+
- Rakefile
|
125
|
+
- clockwork-test.gemspec
|
126
|
+
- lib/clockwork/test.rb
|
127
|
+
- lib/clockwork/test/event.rb
|
128
|
+
- lib/clockwork/test/job_history.rb
|
129
|
+
- lib/clockwork/test/manager.rb
|
130
|
+
- lib/clockwork/test/rspec/matchers.rb
|
131
|
+
- lib/clockwork/test/rspec/matchers/have_run.rb
|
132
|
+
- lib/clockwork/test/version.rb
|
133
|
+
- spec/acceptance/clock_spec.rb
|
134
|
+
- spec/clockwork/test/job_history_spec.rb
|
135
|
+
- spec/clockwork/test/manager_spec.rb
|
136
|
+
- spec/clockwork/test_spec.rb
|
137
|
+
- spec/fixtures/clock.rb
|
138
|
+
- spec/spec_helper.rb
|
139
|
+
homepage: https://github.com/kevin-j-m/clockwork-test
|
140
|
+
licenses:
|
141
|
+
- MIT
|
142
|
+
metadata: {}
|
143
|
+
post_install_message:
|
144
|
+
rdoc_options: []
|
145
|
+
require_paths:
|
146
|
+
- lib
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
requirements: []
|
158
|
+
rubyforge_project:
|
159
|
+
rubygems_version: 2.2.2
|
160
|
+
signing_key:
|
161
|
+
specification_version: 4
|
162
|
+
summary: Test clockwork scheduled jobs
|
163
|
+
test_files:
|
164
|
+
- spec/acceptance/clock_spec.rb
|
165
|
+
- spec/clockwork/test/job_history_spec.rb
|
166
|
+
- spec/clockwork/test/manager_spec.rb
|
167
|
+
- spec/clockwork/test_spec.rb
|
168
|
+
- spec/fixtures/clock.rb
|
169
|
+
- spec/spec_helper.rb
|