crono 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,13 @@
1
- require "spec_helper"
1
+ require 'spec_helper'
2
2
 
3
3
  class TestJob
4
- def perform;end
4
+ def perform
5
+ end
5
6
  end
6
7
 
7
8
  describe Crono::PerformerProxy do
8
- it "should add job to schedule" do
9
+ it 'should add job to schedule' do
9
10
  expect(Crono.scheduler).to receive(:add_job).with(kind_of(Crono::Job))
10
- Crono.perform(TestJob).every(2.days, at: "15:30")
11
+ Crono.perform(TestJob).every(2.days, at: '15:30')
11
12
  end
12
13
  end
@@ -1,4 +1,4 @@
1
- require "spec_helper"
1
+ require 'spec_helper'
2
2
 
3
3
  describe Crono::Period do
4
4
  around(:each) do |example|
@@ -7,49 +7,93 @@ describe Crono::Period do
7
7
  end
8
8
  end
9
9
 
10
- describe "#description" do
11
- it "should return period description" do
12
- @period = Crono::Period.new(2.day, at: "15:20")
13
- expect(@period.description).to be_eql("every 2 days at 15:20")
10
+ describe '#description' do
11
+ it 'should return period description' do
12
+ @period = Crono::Period.new(1.week, on: :monday, at: '15:20')
13
+ expect(@period.description).to be_eql('every 7 days at 15:20 on Monday')
14
14
  end
15
15
  end
16
16
 
17
- describe "#next" do
18
- context "in daily basis" do
19
- it "should return the time 2 days from now" do
17
+ describe '#next' do
18
+ context 'in weakly basis' do
19
+ it "should raise error if 'on' is wrong" do
20
+ expect { @period = Crono::Period.new(7.days, on: :bad_day) }
21
+ .to raise_error("Wrong 'on' day")
22
+ end
23
+
24
+ it 'should raise error when period is less than 1 week' do
25
+ expect { @period = Crono::Period.new(6.days, on: :monday) }
26
+ .to raise_error("period should be at least 1 week to use 'on'")
27
+ end
28
+
29
+ it "should return a 'on' day" do
30
+ @period = Crono::Period.new(1.week, on: :thursday, at: '15:30')
31
+ current_week = Time.now.beginning_of_week
32
+ last_run_time = current_week.advance(days: 1) # last run on the tuesday
33
+ next_run_at = Time.now.next_week.advance(days: 3)
34
+ .change(hour: 15, min: 30)
35
+ expect(@period.next(since: last_run_time)).to be_eql(next_run_at)
36
+ end
37
+
38
+ it "should return a next week day 'on'" do
39
+ @period = Crono::Period.new(1.week, on: :thursday)
40
+ Timecop.freeze(Time.now.beginning_of_week.advance(days: 4)) do
41
+ expect(@period.next).to be_eql(Time.now.next_week.advance(days: 3))
42
+ end
43
+ end
44
+
45
+ it 'should return a current week day on the first run if not too late' do
46
+ @period = Crono::Period.new(7.days, on: :tuesday)
47
+ beginning_of_the_week = Time.now.beginning_of_week
48
+ tuesday = beginning_of_the_week.advance(days: 1)
49
+ Timecop.freeze(beginning_of_the_week) do
50
+ expect(@period.next).to be_eql(tuesday)
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'in daily basis' do
56
+ it 'should return the time 2 days from now' do
20
57
  @period = Crono::Period.new(2.day)
21
58
  expect(@period.next).to be_eql(2.day.from_now)
22
59
  end
23
60
 
24
61
  it "should set time to 'at' time as a string" do
25
62
  time = 10.minutes.ago
26
- @period = Crono::Period.new(2.day, at: [time.hour, time.min].join(':'))
63
+ at = [time.hour, time.min].join(':')
64
+ @period = Crono::Period.new(2.day, at: at)
27
65
  expect(@period.next).to be_eql(2.day.from_now.change(hour: time.hour, min: time.min))
28
66
  end
29
67
 
30
68
  it "should set time to 'at' time as a hash" do
31
69
  time = 10.minutes.ago
32
- at = {hour: time.hour, min: time.min}
70
+ at = { hour: time.hour, min: time.min }
33
71
  @period = Crono::Period.new(2.day, at: at)
34
72
  expect(@period.next).to be_eql(2.day.from_now.change(at))
35
73
  end
36
74
 
37
75
  it "should raise error when 'at' is wrong" do
38
76
  expect {
39
- @period = Crono::Period.new(2.day, at: 1)
77
+ Crono::Period.new(2.day, at: 1)
40
78
  }.to raise_error("Unknown 'at' format")
41
79
  end
42
80
 
43
- it "should return time in relation to last time" do
81
+ it 'should raise error when period is less than 1 day' do
82
+ expect {
83
+ Crono::Period.new(5.hours, at: '15:30')
84
+ }.to raise_error("period should be at least 1 day to use 'at'")
85
+ end
86
+
87
+ it 'should return time in relation to last time' do
44
88
  @period = Crono::Period.new(2.day)
45
89
  expect(@period.next(since: 1.day.ago)).to be_eql(1.day.from_now)
46
90
  end
47
91
 
48
- it "should return today time if it is first run and not too late" do
92
+ it 'should return today time if it is first run and not too late' do
49
93
  time = 10.minutes.from_now
50
- at = {hour: time.hour, min: time.min}
94
+ at = { hour: time.hour, min: time.min }
51
95
  @period = Crono::Period.new(2.day, at: at)
52
- expect(@period.next).to be_eql(Time.now.change(at))
96
+ expect(@period.next.utc.to_s).to be_eql(Time.now.change(at).utc.to_s)
53
97
  end
54
98
  end
55
99
  end
@@ -1,30 +1,31 @@
1
- require "spec_helper"
1
+ require 'spec_helper'
2
2
 
3
3
  class TestJob
4
- def perform;end
4
+ def perform
5
+ end
5
6
  end
6
7
 
7
8
  describe Crono::Scheduler do
8
9
  before(:each) do
9
10
  @scheduler = Crono::Scheduler.new
10
11
  @jobs = [
11
- Crono::Period.new(3.day, at: 10.minutes.from_now.strftime("%H:%M")),
12
- Crono::Period.new(1.day, at: 20.minutes.from_now.strftime("%H:%M")),
13
- Crono::Period.new(7.day, at: 40.minutes.from_now.strftime("%H:%M"))
12
+ Crono::Period.new(3.day, at: 10.minutes.from_now.strftime('%H:%M')),
13
+ Crono::Period.new(1.day, at: 20.minutes.from_now.strftime('%H:%M')),
14
+ Crono::Period.new(7.day, at: 40.minutes.from_now.strftime('%H:%M'))
14
15
  ].map { |period| Crono::Job.new(TestJob, period) }
15
16
  @scheduler.jobs = @jobs
16
17
  end
17
18
 
18
- describe "#add_job" do
19
- it "should call Job#load on Job" do
20
- @job = Crono::Job.new(TestJob, Crono::Period.new(10.day, at: "04:05"))
19
+ describe '#add_job' do
20
+ it 'should call Job#load on Job' do
21
+ @job = Crono::Job.new(TestJob, Crono::Period.new(10.day, at: '04:05'))
21
22
  expect(@job).to receive(:load)
22
23
  @scheduler.add_job(@job)
23
24
  end
24
25
  end
25
26
 
26
- describe "#next" do
27
- it "should return next job in schedule" do
27
+ describe '#next' do
28
+ it 'should return next job in schedule' do
28
29
  expect(@scheduler.next).to be @jobs[0]
29
30
  end
30
31
  end
@@ -6,9 +6,10 @@ require 'byebug'
6
6
  require 'crono'
7
7
  require 'generators/crono/install/templates/migrations/create_crono_jobs.rb'
8
8
 
9
- ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: "file::memory:?cache=shared")
9
+ ActiveRecord::Base.establish_connection(
10
+ adapter: 'sqlite3',
11
+ database: 'file::memory:?cache=shared'
12
+ )
13
+
10
14
  ActiveRecord::Base.logger = Logger.new(STDOUT)
11
15
  CreateCronoJobs.up
12
-
13
- RSpec.configure do |config|
14
- end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'rack/test'
3
+ include Rack::Test::Methods
4
+
5
+ describe Crono::Web do
6
+ let(:app) { Crono::Web }
7
+
8
+ before do
9
+ @test_job_id = 'Perform TestJob every 5 seconds'
10
+ @test_job_log = 'All runs ok'
11
+ @test_job = Crono::CronoJob.create!(
12
+ job_id: @test_job_id,
13
+ log: @test_job_log
14
+ )
15
+ end
16
+
17
+ after { @test_job.destroy }
18
+
19
+ describe '/' do
20
+ it 'should show all jobs' do
21
+ get '/'
22
+ expect(last_response).to be_ok
23
+ expect(last_response.body).to include @test_job_id
24
+ end
25
+
26
+ it 'should show a error mark when a job is unhealthy' do
27
+ @test_job.update(healthy: false)
28
+ get '/'
29
+ expect(last_response.body).to include 'Error'
30
+ end
31
+ end
32
+
33
+ describe '/job/:id' do
34
+ it 'should show job log' do
35
+ get "/job/#{@test_job.id}"
36
+ expect(last_response).to be_ok
37
+ expect(last_response.body).to include @test_job_id
38
+ expect(last_response.body).to include @test_job_log
39
+ end
40
+
41
+ it 'should show a message about the unhealthy job' do
42
+ message = 'An error occurs during the last execution of this job'
43
+ @test_job.update(healthy: false)
44
+ get "/job/#{@test_job.id}"
45
+ expect(last_response.body).to include message
46
+ end
47
+ end
48
+ end
@@ -7,11 +7,16 @@
7
7
  %th Job
8
8
  %th Last performed at
9
9
  %th
10
- - for job in @jobs
10
+ %th
11
+ - @jobs.each do |job|
11
12
  %tr
12
13
  %td= job.job_id
13
- %td= job.last_performed_at || "—"
14
+ %td= job.last_performed_at || '-'
15
+ %td
16
+ - if job.healthy == false
17
+ %a{ href: url("/job/#{job.id}") }
18
+ %span.label.label-danger Error
14
19
  %td
15
- %a{href: url("/jobs/#{job.id}")}
20
+ %a{ href: url("/job/#{job.id}") }
16
21
  Log
17
22
  %span.glyphicon.glyphicon-menu-right
@@ -1,8 +1,14 @@
1
1
  %ol.breadcrumb
2
2
  %li
3
- %a{href: url("/")} Home
3
+ %a{ href: url('/') } Home
4
4
  %li.active= @job.job_id
5
5
 
6
6
  %h2
7
7
  "#{@job.job_id}" Log:
8
+
9
+ - if @job.healthy == false
10
+ .alert.alert-danger{ role: 'alert' }
11
+ An error occurs during the last execution of this job.
12
+ Check the log below for details.
13
+
8
14
  %pre= @job.log
@@ -1,15 +1,15 @@
1
1
  !!! 5
2
- %html{lang: "en"}
2
+ %html{ lang: 'en' }
3
3
  %head
4
- %meta{charset: "utf-8"}
5
- %meta{"http-equiv" => "X-UA-Compatible", content: "IE=edge"}
6
- %meta{name: "viewport", content: "width=device-width, initial-scale=1"}
4
+ %meta{ charset: 'utf-8' }
5
+ %meta{ 'http-equiv' => 'X-UA-Compatible', content: 'IE=edge' }
6
+ %meta{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
7
7
 
8
8
  %title Crono Dashboard
9
9
 
10
- %link{href: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css", rel: "stylesheet"}
11
- %link{href: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css", rel: "stylesheet"}
12
- %link{href: "#{env['SCRIPT_NAME']}/custom.css", rel: "stylesheet"}
10
+ %link{ href: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css', rel: 'stylesheet' }
11
+ %link{ href: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css', rel: 'stylesheet' }
12
+ %link{ href: "#{env['SCRIPT_NAME']}/custom.css", rel: 'stylesheet' }
13
13
 
14
14
  %body
15
15
  %br
@@ -21,5 +21,5 @@
21
21
  %small Dashboard
22
22
  = yield
23
23
 
24
- %script{src: "https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"}
25
- %script{src: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"}
24
+ %script{ src: 'https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js' }
25
+ %script{ src: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js' }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crono
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dzmitry Plashchynski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-08 00:00:00.000000000 Z
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rack-test
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  description: Job scheduler for Rails
168
182
  email:
169
183
  - plashchynski@gmail.com
@@ -209,6 +223,7 @@ files:
209
223
  - spec/period_spec.rb
210
224
  - spec/scheduler_spec.rb
211
225
  - spec/spec_helper.rb
226
+ - spec/web_spec.rb
212
227
  - tmp/.gitkeep
213
228
  - web/assets/custom.css
214
229
  - web/views/dashboard.haml
@@ -234,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
234
249
  version: 1.3.6
235
250
  requirements: []
236
251
  rubyforge_project: crono
237
- rubygems_version: 2.4.5
252
+ rubygems_version: 2.4.6
238
253
  signing_key:
239
254
  specification_version: 4
240
255
  summary: Job scheduler for Rails