say_when 0.3.0 → 1.0.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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -4
  3. data/Gemfile +1 -1
  4. data/LICENSE +21 -0
  5. data/README.md +31 -0
  6. data/Rakefile +9 -1
  7. data/lib/generators/say_when/migration/migration_generator.rb +8 -5
  8. data/lib/generators/say_when/migration/templates/migration.rb +11 -8
  9. data/lib/say_when/base_job.rb +2 -0
  10. data/lib/say_when/cron_expression.rb +129 -191
  11. data/lib/say_when/processor/active_messaging.rb +7 -8
  12. data/lib/say_when/processor/base.rb +5 -3
  13. data/lib/say_when/processor/shoryuken.rb +14 -0
  14. data/lib/say_when/processor/simple.rb +2 -0
  15. data/lib/say_when/railtie.rb +9 -0
  16. data/lib/say_when/scheduler.rb +30 -56
  17. data/lib/say_when/storage/active_record/acts.rb +16 -16
  18. data/lib/say_when/storage/active_record/job.rb +17 -24
  19. data/lib/say_when/storage/active_record/job_execution.rb +5 -8
  20. data/lib/say_when/storage/memory/base.rb +3 -1
  21. data/lib/say_when/storage/memory/job.rb +14 -42
  22. data/lib/say_when/tasks.rb +4 -4
  23. data/lib/say_when/triggers/base.rb +4 -3
  24. data/lib/say_when/triggers/cron_strategy.rb +4 -3
  25. data/lib/say_when/triggers/instance_strategy.rb +4 -3
  26. data/lib/say_when/triggers/once_strategy.rb +3 -2
  27. data/lib/say_when/version.rb +3 -1
  28. data/lib/say_when.rb +8 -7
  29. data/lib/tasks/say_when.rake +3 -1
  30. data/say_when.gemspec +25 -19
  31. data/test/active_record_helper.rb +13 -0
  32. data/{spec → test}/db/schema.rb +4 -2
  33. data/{spec/spec_helper.rb → test/minitest_helper.rb} +9 -12
  34. data/test/say_when/cron_expression_spec.rb +74 -0
  35. data/{spec/say_when/processor/active_messaging_spec.rb → test/say_when/processor/active_messaging_test.rb} +16 -13
  36. data/test/say_when/scheduler_test.rb +75 -0
  37. data/test/say_when/storage/active_record/job_test.rb +90 -0
  38. data/test/say_when/storage/memory/job_test.rb +32 -0
  39. data/test/say_when/storage/memory/trigger_test.rb +54 -0
  40. data/test/say_when/triggers/once_strategy_test.rb +23 -0
  41. data/{spec → test}/support/models.rb +5 -3
  42. metadata +166 -153
  43. data/.travis.yml +0 -4
  44. data/generators/say_when_migration/say_when_migration_generator.rb +0 -11
  45. data/generators/say_when_migration/templates/migration.rb +0 -48
  46. data/spec/active_record_spec_helper.rb +0 -11
  47. data/spec/say_when/cron_expression_spec.rb +0 -72
  48. data/spec/say_when/scheduler_spec.rb +0 -76
  49. data/spec/say_when/storage/active_record/job_spec.rb +0 -98
  50. data/spec/say_when/storage/memory/job_spec.rb +0 -45
  51. data/spec/say_when/storage/memory/trigger_spec.rb +0 -54
  52. data/spec/say_when/triggers/once_strategy_spec.rb +0 -22
  53. data/spec/spec.opts +0 -4
@@ -1,2 +1,4 @@
1
+ # encoding: utf-8
2
+
1
3
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
2
- require 'say_when/tasks'
4
+ require 'say_when/tasks'
data/say_when.gemspec CHANGED
@@ -1,25 +1,31 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "say_when/version"
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'say_when/version'
4
5
 
5
- Gem::Specification.new do |s|
6
- s.name = "say_when"
7
- s.version = SayWhen::VERSION
8
- s.authors = ["Andrew Kuklewicz"]
9
- s.email = ["andrew@prx.org"]
10
- s.homepage = "http://labs.prx.org"
11
- s.summary = %q{Scheduling system for programmatically defined and stored jobs.}
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'say_when'
8
+ spec.version = SayWhen::VERSION
9
+ spec.authors = ['Andrew Kuklewicz']
10
+ spec.email = ['andrew@beginsinwonder.com']
11
+ spec.summary = %q{Scheduling system for programmatically defined and stored jobs.}
12
+ spec.description = %q{Scheduling system for programmatically defined and stored jobs.}
13
+ spec.homepage = 'https://github.com/kookster/say_when'
14
+ spec.license = 'MIT'
12
15
 
13
- s.files = `git ls-files`.split("\n")
14
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
- s.require_paths = ["lib"]
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']
17
20
 
18
- s.add_development_dependency "activemessaging", '~> 0.9.0'
19
- s.add_development_dependency "activesupport", '~> 2.3.14'
20
- s.add_development_dependency "activerecord", '~> 2.3.14'
21
- s.add_development_dependency 'rspec', "~> 1.3"
22
- s.add_development_dependency 'sqlite3'
23
- s.add_development_dependency 'rake', '~> 0.8.7'
21
+ spec.add_runtime_dependency('activesupport')
24
22
 
23
+ spec.add_development_dependency('activerecord')
24
+ spec.add_development_dependency('shoryuken')
25
+ spec.add_development_dependency('activemessaging')
26
+ spec.add_development_dependency('bundler', '~> 1.3')
27
+ spec.add_development_dependency('rake')
28
+ spec.add_development_dependency('minitest')
29
+ spec.add_development_dependency('simplecov')
30
+ spec.add_development_dependency('sqlite3')
25
31
  end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ require 'active_record'
4
+ require 'sqlite3'
5
+
6
+ ActiveRecord::Base.logger = Logger.new('/dev/null')
7
+
8
+ ActiveRecord::Base.establish_connection(
9
+ adapter: 'sqlite3',
10
+ database: (File.dirname(__FILE__) + '/db/test.db')
11
+ )
12
+
13
+ require (File.dirname(__FILE__) + '/db/schema.rb')
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  ActiveRecord::Schema.define(:version => 0) do
2
4
 
3
5
  create_table :say_when_jobs, :force => true do |t|
@@ -18,7 +20,7 @@ ActiveRecord::Schema.define(:version => 0) do
18
20
  t.string :job_method
19
21
  t.text :data
20
22
 
21
- t.timestamps
23
+ t.timestamps null: false
22
24
  end
23
25
 
24
26
  create_table :say_when_job_executions, :force => true do |t|
@@ -28,7 +30,7 @@ ActiveRecord::Schema.define(:version => 0) do
28
30
  t.datetime :start_at
29
31
  t.datetime :end_at
30
32
  end
31
-
33
+
32
34
  add_index :say_when_jobs, :status
33
35
  add_index :say_when_jobs, :next_fire_at
34
36
 
@@ -1,20 +1,17 @@
1
- ENV['RAILS_ENV']='test'
1
+ # encoding: utf-8
2
2
 
3
- require "rubygems"
4
- require 'bundler/setup'
5
- require 'active_support'
6
-
7
- require 'spec'
8
- require 'spec/autorun'
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+ require 'say_when'
9
5
 
10
- $: << (File.dirname(__FILE__) + "/../lib")
11
- require "say_when"
6
+ require 'minitest'
7
+ require 'minitest/autorun'
8
+ require 'minitest/spec'
9
+ require 'minitest/mock'
10
+ require 'fileutils'
12
11
 
13
12
  Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
14
13
 
15
- Spec::Runner.configure do |config|
16
- config.mock_with :rspec
17
- end
14
+ require 'active_support'
18
15
 
19
16
  module SayWhen
20
17
  module Test
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+
5
+ describe SayWhen::CronExpression do
6
+
7
+ it 'should set the time_zone' do
8
+ @ce = SayWhen::CronExpression.new("0 0 12 ? * 1#1 *", 'Pacific Time (US & Canada)')
9
+ @ce.time_zone.must_equal 'Pacific Time (US & Canada)'
10
+ end
11
+
12
+ describe 'get first sunday in the month with "1#1' do
13
+
14
+ before do
15
+ @ce = SayWhen::CronExpression.new("0 0 12 ? * 1#1 *", 'Pacific Time (US & Canada)')
16
+ end
17
+
18
+ it 'finds first sunday in the same month' do
19
+ @ce.next_fire_at(Time.utc(2008,1,1)).must_equal Time.parse('2008-01-06 12:00:00 -0800')
20
+ end
21
+
22
+
23
+ it 'finds first sunday in the next month' do
24
+ @ce.next_fire_at(Time.utc(2008,1,7)).must_equal Time.parse('2008-02-03 12:00:00 -0800')
25
+ end
26
+
27
+ it 'finds last sunday in the same month' do
28
+ @ce.last_fire_at(Time.utc(2008,1,10)).must_equal Time.parse('2008-01-06 12:00:00 -0800')
29
+ end
30
+
31
+ it 'finds sundays in the prior months and years' do
32
+ @ce.last_fire_at(Time.utc(2008,1,5)).must_equal Time.parse('2007-12-02 12:00:00 -0800')
33
+ @ce.last_fire_at(Time.parse('2007-12-02 12:00:00 -0800') - 1.second).must_equal Time.parse('2007-11-04 12:00:00 -0800')
34
+ @ce.last_fire_at(Time.parse('2007-11-04 12:00:00 -0800') - 1.second).must_equal Time.parse('2007-10-07 12:00:00 -0700')
35
+ @ce.next_fire_at(Time.parse('2007-10-07 12:00:00 -0700') + 1.second).must_equal Time.parse('2007-11-04 12:00:00 -0800')
36
+ end
37
+ end
38
+
39
+ describe 'get last sunday in the month with "1L"' do
40
+ before do
41
+ @ce = SayWhen::CronExpression.new("0 0 12 ? * 1L *", 'Pacific Time (US & Canada)')
42
+ end
43
+
44
+ it 'gets next final sunday for same month' do
45
+ @ce.next_fire_at(Time.utc(2008,1,1)).must_equal Time.parse('2008-01-27 12:00:00 -0800')
46
+ end
47
+
48
+
49
+ it 'gets next final sunday for next month' do
50
+ @ce.next_fire_at(Time.utc(2008,1,28)).must_equal Time.parse('2008-02-24 12:00:00 -0800')
51
+ end
52
+
53
+ it 'gets last final sunday for same month' do
54
+ @ce.last_fire_at(Time.utc(2008,1,28)).must_equal Time.parse('2008-01-27 12:00:00 -0800')
55
+ end
56
+
57
+ it 'gets last sunday for prior month and year' do
58
+ @ce.last_fire_at(Time.utc(2008,1,1)).must_equal Time.parse('2007-12-30 12:00:00 -0800')
59
+ end
60
+
61
+
62
+ it 'gets last sunday for prior month and year' do
63
+ nfa = @ce.last_fire_at(Time.utc(2007,12,1))
64
+ nfa.must_equal Time.parse('2007-11-25 12:00:00 -0800')
65
+
66
+ nfa = @ce.last_fire_at(nfa - 1.second)
67
+ nfa.must_equal Time.parse('2007-10-28 12:00:00 -0700')
68
+
69
+ nfa = @ce.next_fire_at(nfa + 1.second)
70
+ nfa.must_equal Time.parse('2007-11-25 12:00:00 -0800')
71
+ end
72
+
73
+ end
74
+ end
@@ -1,7 +1,13 @@
1
+ # encoding: utf-8
1
2
 
2
- require File.dirname(__FILE__) + '/../../spec_helper'
3
- require File.dirname(__FILE__) + '/../../../lib/say_when/processor/active_messaging'
4
- require File.dirname(__FILE__) + '/../../../lib/say_when/storage/active_record/job'
3
+ require 'minitest_helper'
4
+
5
+ require 'say_when/processor/active_messaging'
6
+ require 'say_when/storage/active_record/job'
7
+ require 'activemessaging'
8
+
9
+ ActiveMessaging.logger = Logger.new('/dev/null')
10
+ ActiveMessaging.load_extensions
5
11
 
6
12
  def destination(destination_name)
7
13
  d = ActiveMessaging::Gateway.find_destination(destination_name).value
@@ -12,11 +18,9 @@ describe SayWhen::Processor::ActiveMessaging do
12
18
 
13
19
  before do
14
20
 
15
- require 'activemessaging'
21
+ ActiveMessaging::Gateway.connections['default'] = ActiveMessaging::Gateway.adapters[:test].new({})
16
22
 
17
- ActiveMessaging::Gateway.stub!(:load_connection_configuration).and_return({:adapter=>:test})
18
-
19
- ActiveMessaging::Gateway.define do |s|
23
+ ActiveMessaging::Gateway.define do |s|
20
24
  s.destination :say_when, '/queue/SayWhen'
21
25
  end
22
26
 
@@ -27,12 +31,11 @@ describe SayWhen::Processor::ActiveMessaging do
27
31
  @processor = SayWhen::Processor::ActiveMessaging.new(SayWhen::Scheduler.scheduler)
28
32
  end
29
33
 
30
- it "process a job by sending a message" do
31
- @job = mock('SayWhen::Storage::ActiveRecord::Job')
32
- @job.should_receive(:id).and_return(100)
34
+ it 'process a job by sending a message' do
35
+ @job = Minitest::Mock.new
36
+ @job.expect(:id, 100)
33
37
  @processor.process(@job)
34
- destination(:say_when).messages.size.should == 1
35
- YAML::load(destination(:say_when).messages.first.body)[:job_id].should == 100
38
+ destination(:say_when).messages.size.must_equal 1
39
+ YAML::load(destination(:say_when).messages.first.body)[:job_id].must_equal 100
36
40
  end
37
-
38
41
  end
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+
3
+ require 'minitest_helper'
4
+
5
+ describe SayWhen::Scheduler do
6
+
7
+ before {
8
+ SayWhen::logger = Logger.new('/dev/null')
9
+ }
10
+
11
+ describe 'class methods' do
12
+
13
+ it 'can return singleton' do
14
+ s = SayWhen::Scheduler.scheduler
15
+ s.wont_be_nil
16
+ s.must_equal SayWhen::Scheduler.scheduler
17
+ end
18
+
19
+ it 'can be configured' do
20
+ SayWhen::Scheduler.configure do |scheduler|
21
+ scheduler.storage_strategy = :memory
22
+ scheduler.processor_class = SayWhen::Test::TestProcessor
23
+ end
24
+ SayWhen::Scheduler.scheduler.storage_strategy.must_equal :memory
25
+ SayWhen::Scheduler.scheduler.processor_class.must_equal SayWhen::Test::TestProcessor
26
+ end
27
+
28
+ it 'can schedule a new job' do
29
+ SayWhen::Scheduler.configure do |scheduler|
30
+ scheduler.storage_strategy = :memory
31
+ scheduler.processor_class = SayWhen::Test::TestProcessor
32
+ end
33
+
34
+ job = SayWhen::Scheduler.schedule(
35
+ trigger_strategy: 'once',
36
+ trigger_options: { at: 10.second.since },
37
+ job_class: 'SayWhen::Test::TestTask',
38
+ job_method: 'execute'
39
+ )
40
+ job.wont_be_nil
41
+ end
42
+
43
+ end
44
+
45
+ describe 'instance methods' do
46
+
47
+ before(:all) do
48
+ SayWhen::Scheduler.configure do |scheduler|
49
+ scheduler.storage_strategy = :memory
50
+ scheduler.processor_class = SayWhen::Test::TestProcessor
51
+ end
52
+ end
53
+
54
+ let (:scheduler) { SayWhen::Scheduler.scheduler }
55
+
56
+ it 'should instantiate the processor from its class' do
57
+ scheduler.processor.must_be_instance_of(SayWhen::Test::TestProcessor)
58
+ end
59
+
60
+ it 'should get the job class based on the strategy' do
61
+ scheduler.job_class.must_equal SayWhen::Storage::Memory::Job
62
+ end
63
+
64
+ it 'should start the scheduler running, and can stop it' do
65
+ scheduler.wont_be :running
66
+
67
+ scheduler_thread = Thread.start{ scheduler.start }
68
+ sleep(0.2)
69
+ scheduler.must_be :running
70
+
71
+ scheduler.stop
72
+ scheduler.wont_be :running
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+
3
+ require 'minitest_helper'
4
+ require 'active_record_helper'
5
+ require 'say_when/storage/active_record/job'
6
+
7
+ describe SayWhen::Storage::ActiveRecord::Job do
8
+
9
+ let(:valid_attributes) {
10
+ {
11
+ trigger_strategy: :cron,
12
+ trigger_options: { expression: '0 0 12 ? * * *', time_zone: 'Pacific Time (US & Canada)' },
13
+ data: { foo: 'bar', result: 1 },
14
+ job_class: 'SayWhen::Test::TestTask',
15
+ job_method: 'execute'
16
+ }
17
+ }
18
+
19
+ it 'can be instantiated' do
20
+ j = SayWhen::Storage::ActiveRecord::Job.create!(valid_attributes)
21
+ j.wont_be_nil
22
+ end
23
+
24
+ it 'can execute the task for the job' do
25
+ j = SayWhen::Storage::ActiveRecord::Job.create(valid_attributes)
26
+ j.execute_job( { result: 1 } ).must_equal 1
27
+ end
28
+
29
+ it 'can execute the job' do
30
+ j = SayWhen::Storage::ActiveRecord::Job.create(valid_attributes)
31
+ j.execute.must_equal 1
32
+ end
33
+
34
+ it 'derives a trigger from the attributes' do
35
+ t = SayWhen::Storage::ActiveRecord::Job.create(valid_attributes)
36
+ t.trigger.wont_be_nil
37
+ t.trigger.must_be_instance_of SayWhen::Triggers::CronStrategy
38
+ end
39
+
40
+ it 'has a waiting state on create' do
41
+ t = SayWhen::Storage::ActiveRecord::Job.create(valid_attributes)
42
+ t.status.must_equal SayWhen::BaseJob::STATE_WAITING
43
+ end
44
+
45
+ it 'has a next fire at set on create' do
46
+ opts = valid_attributes[:trigger_options]
47
+ ce = SayWhen::CronExpression.new(opts[:expression], opts[:time_zone])
48
+ j = SayWhen::Storage::ActiveRecord::Job.create(valid_attributes)
49
+ j.status.must_equal SayWhen::BaseJob::STATE_WAITING
50
+ j.next_fire_at.must_equal ce.next_fire_at
51
+ end
52
+
53
+ it 'can find the next job' do
54
+ SayWhen::Storage::ActiveRecord::Job.delete_all
55
+ j2_opts = {
56
+ trigger_strategy: :cron,
57
+ trigger_options: { expression: '0 0 10 ? * * *', time_zone: 'Pacific Time (US & Canada)' },
58
+ data: { foo: 'bar', result: 2 },
59
+ job_class: 'SayWhen::Test::TestTask',
60
+ job_method: 'execute'
61
+ }
62
+
63
+ now = Time.now.change(hour: 0)
64
+ Time.stub(:now, now) do
65
+ j1 = SayWhen::Storage::ActiveRecord::Job.create(valid_attributes)
66
+ j2 = SayWhen::Storage::ActiveRecord::Job.create(j2_opts)
67
+
68
+ next_job = SayWhen::Storage::ActiveRecord::Job.acquire_next(2.days.since)
69
+ next_job.must_equal j2
70
+ end
71
+ end
72
+
73
+ it 'can be fired' do
74
+ opts = valid_attributes[:trigger_options]
75
+ ce = SayWhen::CronExpression.new(opts[:expression], opts[:time_zone])
76
+ j = SayWhen::Storage::ActiveRecord::Job.create(valid_attributes)
77
+ nfa = ce.last_fire_at(j.created_at - 1.second)
78
+ lfa = ce.last_fire_at(nfa - 1.second)
79
+ j.next_fire_at = nfa
80
+ j.last_fire_at = lfa
81
+
82
+ now = Time.now
83
+ Time.stub(:now, now) do
84
+ j.fired
85
+ j.next_fire_at.must_equal ce.next_fire_at(now)
86
+ j.last_fire_at.must_equal now
87
+ j.status.must_equal SayWhen::BaseJob::STATE_WAITING
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require 'minitest_helper'
4
+ require 'say_when/storage/memory/job'
5
+
6
+ describe SayWhen::Storage::Memory::Job do
7
+
8
+ let(:valid_attributes) {
9
+ {
10
+ :name => 'Memory::Job::Test',
11
+ :group => 'Test',
12
+ :data => { foo: 'bar', result: 1 },
13
+ :job_class => 'SayWhen::Test::TestTask',
14
+ :job_method => 'execute'
15
+ }
16
+ }
17
+
18
+ it 'can be instantiated' do
19
+ j = SayWhen::Storage::Memory::Job.new(valid_attributes)
20
+ j.wont_be_nil
21
+ end
22
+
23
+ it 'can execute the task for the job' do
24
+ j = SayWhen::Storage::Memory::Job.new(valid_attributes)
25
+ j.execute_job( { result: 1 } ).must_equal 1
26
+ end
27
+
28
+ it 'can execute the job' do
29
+ j = SayWhen::Storage::Memory::Job.new(valid_attributes)
30
+ j.execute.must_equal 1
31
+ end
32
+ end
@@ -0,0 +1,54 @@
1
+ # require 'minitest_helper'
2
+ # require 'say_when/storage/memory/trigger'
3
+
4
+ # describe SayWhen::Storage::Memory::Trigger do
5
+
6
+ # let(:valid_attributes) {
7
+ # {
8
+ # expression: '0 0 12 ? * * *',
9
+ # time_zone: 'Pacific Time (US & Canada)'
10
+ # }
11
+ # }
12
+
13
+ # it 'can be instantiated' do
14
+ # t = SayWhen::Storage::Memory::Trigger.new(@valid_attributes)
15
+ # t.wont_be_nil
16
+ # end
17
+
18
+ # it 'sets a cron_expression' do
19
+ # t = SayWhen::Storage::Memory::Trigger.new(@valid_attributes)
20
+ # t.cron_expression.wont_be_nil
21
+ # t.cron_expression.expression.must_equal '0 0 12 ? * * *'
22
+ # t.cron_expression.time_zone.must_equal 'Pacific Time (US & Canada)'
23
+ # end
24
+
25
+ # it 'has a waiting state on instantiate' do
26
+ # t = SayWhen::Storage::Memory::Trigger.new(@valid_attributes)
27
+ # t.status.must_equal SayWhen::BaseTrigger::STATE_WAITING
28
+ # end
29
+
30
+ # it 'has a next fire at set on instantiate' do
31
+ # ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
32
+ # t = SayWhen::Storage::Memory::Trigger.new(@valid_attributes)
33
+ # t.status.must_equal SayWhen::BaseTrigger::STATE_WAITING
34
+ # t.next_fire_at.must_equal ce.next_fire_at
35
+ # end
36
+
37
+ # it 'can be fired' do
38
+ # ce = SayWhen::CronExpression.new(@valid_attributes[:expression], @valid_attributes[:time_zone])
39
+ # t = SayWhen::Storage::Memory::Trigger.new(@valid_attributes)
40
+ # nfa = ce.last_fire_at(1.second.ago)
41
+ # lfa = ce.last_fire_at(nfa - 1.second)
42
+ # t.next_fire_at = nfa
43
+ # t.last_fire_at = lfa
44
+
45
+ # now = Time.now
46
+ # Time.stub!(:now).and_return(now)
47
+
48
+ # t.fired
49
+ # t.next_fire_at.must_equal ce.next_fire_at(now)
50
+ # t.last_fire_at.must_equal now
51
+ # t.status.must_equal SayWhen::BaseTrigger::STATE_WAITING
52
+ # end
53
+
54
+ # end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ require 'minitest_helper'
4
+ require 'say_when/triggers/once_strategy'
5
+
6
+ describe SayWhen::Triggers::OnceStrategy do
7
+
8
+ it 'should be constucted with at option' do
9
+ time_at = 1.second.ago
10
+ o = SayWhen::Triggers::OnceStrategy.new({:at=>time_at})
11
+ o.wont_be_nil
12
+ o.once_at.must_equal time_at
13
+ end
14
+
15
+ it 'should return once at only once' do
16
+ time_at = 1.second.ago
17
+ o = SayWhen::Triggers::OnceStrategy.new({:at=>time_at})
18
+ o.wont_be_nil
19
+ o.next_fire_at.must_equal time_at
20
+ o.next_fire_at(time_at + 10.second).must_be_nil
21
+ o.next_fire_at(time_at - 10.second).must_equal time_at
22
+ end
23
+ end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'active_support'
2
4
 
3
5
  class TestModel < Object
@@ -6,13 +8,13 @@ class TestModel < Object
6
8
  def initialize(id=nil)
7
9
  @id = id
8
10
  end
9
-
11
+
10
12
  def ==(b)
11
13
  return false unless b
12
14
  # puts "compare: #{self.class.name}_#{@id} == #{b.class.name}_#{b.id}"
13
15
  @id == b.id
14
16
  end
15
-
17
+
16
18
  class << self
17
19
 
18
20
  def find(ids=nil)
@@ -28,4 +30,4 @@ end
28
30
 
29
31
  class Account < TestModel
30
32
  attr_accessor :owner
31
- end
33
+ end