seam-active_record 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 (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +45 -0
  6. data/Rakefile +1 -0
  7. data/lib/seam/active_record/version.rb +5 -0
  8. data/lib/seam/active_record.rb +75 -0
  9. data/lib/seam_effort.rb +3 -0
  10. data/migration_script.rb +13 -0
  11. data/seam-mongodb.gemspec +32 -0
  12. data/test_app/.gitignore +16 -0
  13. data/test_app/Gemfile +45 -0
  14. data/test_app/README.rdoc +28 -0
  15. data/test_app/Rakefile +6 -0
  16. data/test_app/app/assets/images/.keep +0 -0
  17. data/test_app/app/assets/javascripts/application.js +16 -0
  18. data/test_app/app/assets/stylesheets/application.css +15 -0
  19. data/test_app/app/controllers/application_controller.rb +5 -0
  20. data/test_app/app/controllers/concerns/.keep +0 -0
  21. data/test_app/app/helpers/application_helper.rb +2 -0
  22. data/test_app/app/mailers/.keep +0 -0
  23. data/test_app/app/models/.keep +0 -0
  24. data/test_app/app/models/concerns/.keep +0 -0
  25. data/test_app/app/views/layouts/application.html.erb +14 -0
  26. data/test_app/bin/bundle +3 -0
  27. data/test_app/bin/rails +8 -0
  28. data/test_app/bin/rake +8 -0
  29. data/test_app/bin/spring +18 -0
  30. data/test_app/config/application.rb +23 -0
  31. data/test_app/config/boot.rb +4 -0
  32. data/test_app/config/database.yml +25 -0
  33. data/test_app/config/environment.rb +5 -0
  34. data/test_app/config/environments/development.rb +37 -0
  35. data/test_app/config/environments/production.rb +82 -0
  36. data/test_app/config/environments/test.rb +39 -0
  37. data/test_app/config/initializers/assets.rb +8 -0
  38. data/test_app/config/initializers/backtrace_silencers.rb +7 -0
  39. data/test_app/config/initializers/cookies_serializer.rb +3 -0
  40. data/test_app/config/initializers/filter_parameter_logging.rb +4 -0
  41. data/test_app/config/initializers/inflections.rb +16 -0
  42. data/test_app/config/initializers/mime_types.rb +4 -0
  43. data/test_app/config/initializers/session_store.rb +3 -0
  44. data/test_app/config/initializers/wrap_parameters.rb +14 -0
  45. data/test_app/config/locales/en.yml +23 -0
  46. data/test_app/config/routes.rb +56 -0
  47. data/test_app/config/secrets.yml +22 -0
  48. data/test_app/config.ru +4 -0
  49. data/test_app/db/migrate/20140904165307_create_seam_efforts.rb +13 -0
  50. data/test_app/db/schema.rb +26 -0
  51. data/test_app/db/seeds.rb +7 -0
  52. data/test_app/lib/assets/.keep +0 -0
  53. data/test_app/lib/tasks/.keep +0 -0
  54. data/test_app/log/.keep +0 -0
  55. data/test_app/public/404.html +67 -0
  56. data/test_app/public/422.html +67 -0
  57. data/test_app/public/500.html +66 -0
  58. data/test_app/public/favicon.ico +0 -0
  59. data/test_app/public/robots.txt +5 -0
  60. data/test_app/spec/seam/effort_spec.rb +43 -0
  61. data/test_app/spec/seam/flow_spec.rb +173 -0
  62. data/test_app/spec/seam/persistence_spec.rb +0 -0
  63. data/test_app/spec/seam/step_spec.rb +34 -0
  64. data/test_app/spec/seam/wait_worker_spec.rb +179 -0
  65. data/test_app/spec/seam/worker_spec.rb +910 -0
  66. data/test_app/spec/seam_spec.rb +47 -0
  67. data/test_app/spec/spec_helper.rb +13 -0
  68. data/test_app/vendor/assets/javascripts/.keep +0 -0
  69. data/test_app/vendor/assets/stylesheets/.keep +0 -0
  70. metadata +252 -0
@@ -0,0 +1,173 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "flow" do
4
+ before do
5
+ Seam::Persistence.destroy
6
+ end
7
+
8
+ after do
9
+ Timecop.return
10
+ end
11
+
12
+ describe "a useful example" do
13
+ let(:flow) do
14
+ f = Seam::Flow.new
15
+ f.wait_for_attempting_contact_stage limit: 2.weeks
16
+ f.determine_if_postcard_should_be_sent
17
+ f.send_postcard_if_necessary
18
+ f
19
+ end
20
+
21
+ describe "steps that must be taken" do
22
+ before do
23
+ flow
24
+ end
25
+
26
+ it "should not throw an error" do
27
+ flow.steps.count.must_equal 3
28
+ end
29
+
30
+ it "should set the name of the three steps" do
31
+ flow.steps[0].name.must_equal "wait_for_attempting_contact_stage"
32
+ flow.steps[1].name.must_equal "determine_if_postcard_should_be_sent"
33
+ flow.steps[2].name.must_equal "send_postcard_if_necessary"
34
+ end
35
+
36
+ it "should set the step types of the three steps" do
37
+ flow.steps[0].type.must_equal "do"
38
+ flow.steps[1].type.must_equal "do"
39
+ flow.steps[2].type.must_equal "do"
40
+ end
41
+
42
+ it "should set the arguments as well" do
43
+ flow.steps[0].arguments.must_equal [{ limit: 14.days.to_i }]
44
+ flow.steps[1].arguments.must_equal []
45
+ flow.steps[2].arguments.must_equal []
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "a more useful example" do
51
+
52
+ describe "starting an effort" do
53
+ let(:flow) do
54
+ flow = Seam::Flow.new
55
+ flow.do_something
56
+ flow.do_something_else
57
+ flow
58
+ end
59
+
60
+ let(:now) { Time.parse('1/1/2011') }
61
+
62
+ before do
63
+ Timecop.freeze now
64
+
65
+ @expected_uuid = SecureRandom.uuid.to_s
66
+ SecureRandom.stubs(:uuid).returns(@expected_uuid)
67
+ .then.returns(1)
68
+ .then.returns(2)
69
+
70
+ @effort = flow.start( { first_name: 'John' } )
71
+ end
72
+
73
+ it "should mark no steps as completed" do
74
+ @effort.completed_steps.count.must_equal 0
75
+ end
76
+
77
+ it "should stamp the effort with a uuid" do
78
+ @effort.id.must_equal @expected_uuid
79
+ end
80
+
81
+ it "should stamp the create date" do
82
+ @effort.created_at.must_equal now
83
+ end
84
+
85
+ it "should stamp the next execute date" do
86
+ @effort.next_execute_at.must_equal now
87
+ end
88
+
89
+ it "should stamp the next step name" do
90
+ @effort.next_step.must_equal "do_something"
91
+ end
92
+
93
+ it "should save an effort in the db" do
94
+ effort = Seam::Effort.find @effort.id
95
+ effort.to_hash.contrast_with! @effort.to_hash, [:id, :created_at]
96
+ end
97
+
98
+ it "should set unique identifiers on the flow ids" do
99
+ effort = Seam::Effort.find @effort.id
100
+ effort.flow['steps'][0]['id'].must_equal '1'
101
+ effort.flow['steps'][1]['id'].must_equal '2'
102
+ end
103
+
104
+ end
105
+ end
106
+
107
+ describe "adding steps" do
108
+ describe "new steps" do
109
+ it "should return true" do
110
+ flow = Seam::Flow.new
111
+ flow.do_something.must_equal true
112
+ flow.do_something_else.must_equal true
113
+ end
114
+ end
115
+
116
+ describe "repeating steps" do
117
+ it "should only add the step once" do
118
+ flow = Seam::Flow.new
119
+ flow.do_something.must_equal true
120
+ flow.steps.count.must_equal 1
121
+ flow.do_something.must_equal true
122
+ flow.steps.count.must_equal 2
123
+ end
124
+ end
125
+
126
+ describe "repeating steps with different data" do
127
+ it "should only add the step once" do
128
+ flow = Seam::Flow.new
129
+ flow.do_something(special_id: 'one').must_equal true
130
+ flow.do_something( { special_id: 'two' }, 4).must_equal true
131
+ flow.steps.count.must_equal 2
132
+
133
+ flow.steps[0].arguments.count.must_equal 1
134
+ flow.steps[0].arguments[0].contrast_with!( { special_id: 'one' } )
135
+ flow.steps[1].arguments.count.must_equal 2
136
+ flow.steps[1].arguments[0].contrast_with!( { special_id: 'two' } )
137
+ flow.steps[1].arguments[1].must_equal 4
138
+ end
139
+ end
140
+ end
141
+
142
+ describe "stamping history" do
143
+ describe "default" do
144
+ it "should should be false" do
145
+ flow = Seam::Flow.new
146
+ flow.stamp_data_history.must_equal false
147
+ end
148
+ end
149
+
150
+ describe "setting it to true" do
151
+ it "allow to be set to true" do
152
+ flow = Seam::Flow.new
153
+ flow.stamp_data_history = true
154
+ flow.stamp_data_history.must_equal true
155
+ end
156
+ end
157
+
158
+ describe "carrying the value through the serialization" do
159
+
160
+ it "should be able to persist false" do
161
+ flow = Seam::Flow.new
162
+ flow.stamp_data_history = false
163
+ flow.to_hash[:stamp_data_history].must_equal false
164
+ end
165
+
166
+ it "should be able to persist true" do
167
+ flow = Seam::Flow.new
168
+ flow.stamp_data_history = true
169
+ flow.to_hash[:stamp_data_history].must_equal true
170
+ end
171
+ end
172
+ end
173
+ end
File without changes
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Seam::Step do
4
+ describe "initialize" do
5
+ it "should allow values to be set with the constructor" do
6
+ step = Seam::Step.new( { id: 'an id',
7
+ name: 'a name',
8
+ type: 'a type',
9
+ arguments: ['1234', 2] } )
10
+ step.id.must_equal 'an id'
11
+ step.name.must_equal 'a name'
12
+ step.type.must_equal 'a type'
13
+ step.arguments.count.must_equal 2
14
+ step.arguments[0].must_equal '1234'
15
+ step.arguments[1].must_equal 2
16
+ end
17
+ end
18
+
19
+ describe "to hash" do
20
+ it "should allow values to be set with the constructor" do
21
+ step = Seam::Step.new( { id: 'an id',
22
+ name: 'a name',
23
+ type: 'a type',
24
+ arguments: ['1234', 2] } )
25
+ step = Seam::Step.new step.to_hash
26
+ step.id.must_equal 'an id'
27
+ step.name.must_equal 'a name'
28
+ step.type.must_equal 'a type'
29
+ step.arguments.count.must_equal 2
30
+ step.arguments[0].must_equal '1234'
31
+ step.arguments[1].must_equal 2
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,179 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class DoSomething < Seam::Worker
4
+ def process
5
+ end
6
+ end
7
+
8
+ describe Seam::WaitWorker do
9
+
10
+ it "should be a worker" do
11
+ Seam::WaitWorker.new.is_a? Seam::Worker
12
+ end
13
+
14
+ it "should handle the wait step" do
15
+ Seam::WaitWorker.new.step.must_equal 'wait'
16
+ end
17
+
18
+ let(:today) do
19
+ Time.parse '1/1/2011'
20
+ end
21
+
22
+ let(:effort_id) do
23
+ effort = flow.start
24
+ effort.id
25
+ end
26
+
27
+ describe "using it in a flow" do
28
+
29
+ [:length_of_time].to_objects { [
30
+ [3.days],
31
+ [1.day],
32
+ [30.minutes]
33
+ ] }.each do |test|
34
+
35
+ describe "a simple situation" do
36
+
37
+ let(:flow) do
38
+ f = Seam::Flow.new
39
+ f.wait test.length_of_time
40
+ f.do_something
41
+ f
42
+ end
43
+
44
+ before do
45
+ Timecop.freeze today
46
+ effort_id
47
+ end
48
+
49
+ it "should move to the next step" do
50
+ Seam::WaitWorker.new.execute_all
51
+ Seam::Effort.find(effort_id).next_step.must_equal "do_something"
52
+ end
53
+ j
54
+ it "should set the next execute date" do
55
+ Seam::WaitWorker.new.execute_all
56
+ Seam::Effort.find(effort_id).next_execute_at.must_equal (today + test.length_of_time)
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+ describe "time has passed since the flow was started and the wait worker was called" do
64
+
65
+ let(:today) { Time.parse('1/1/2011') }
66
+ let(:time_to_wait) { 3.days }
67
+ let(:time_before_wait_worker_was_called) { 1.day }
68
+ let(:expected_start) { today + time_to_wait }
69
+
70
+ let(:flow) do
71
+ f = Seam::Flow.new
72
+ f.wait time_to_wait
73
+ f.do_something
74
+ f
75
+ end
76
+
77
+ before do
78
+ Timecop.freeze today
79
+ effort_id
80
+
81
+ Timecop.freeze today + time_before_wait_worker_was_called
82
+ end
83
+
84
+ it "should move to the next step" do
85
+ Seam::WaitWorker.new.execute_all
86
+ Seam::Effort.find(effort_id).next_step.must_equal "do_something"
87
+ end
88
+
89
+ it "should set the next execute date" do
90
+ Seam::WaitWorker.new.execute_all
91
+ Seam::Effort.find(effort_id).next_execute_at.must_equal expected_start
92
+ end
93
+
94
+ end
95
+
96
+ describe "time has passed since the last step was started and the wait worker was called" do
97
+
98
+ let(:today) { Time.parse('1/1/2011') }
99
+ let(:time_to_wait) { 8.days }
100
+ let(:time_it_took_for_previous_step) { 1.days }
101
+ let(:time_before_wait_worker_was_called) { 3.day }
102
+ let(:expected_start) { today + time_to_wait + time_it_took_for_previous_step }
103
+
104
+ let(:flow) do
105
+ f = Seam::Flow.new
106
+ f.do_something
107
+ f.wait time_to_wait
108
+ f.do_something
109
+ f
110
+ end
111
+
112
+ before do
113
+ Timecop.freeze today
114
+ effort_id
115
+
116
+ Timecop.freeze Time.now + time_it_took_for_previous_step
117
+ DoSomething.new.execute_all
118
+ Timecop.freeze Time.now + time_before_wait_worker_was_called
119
+ end
120
+
121
+ it "should move to the next step" do
122
+ Seam::WaitWorker.new.execute_all
123
+ Seam::Effort.find(effort_id).next_step.must_equal "do_something"
124
+ end
125
+
126
+ it "should set the next execute date" do
127
+ Seam::WaitWorker.new.execute_all
128
+ Seam::Effort.find(effort_id).next_execute_at.must_equal expected_start
129
+ end
130
+
131
+ end
132
+
133
+ describe "a more complex example of waiting" do
134
+
135
+ let(:today) { Time.parse('1/1/2011') }
136
+ let(:time_to_wait) { 8.days }
137
+ let(:time_it_took_for_first_step) { 1.days }
138
+ let(:time_it_took_for_second_step) { 4.days }
139
+ let(:time_before_wait_worker_was_called) { 3.day }
140
+ let(:expected_start) { today +
141
+ time_to_wait +
142
+ time_it_took_for_first_step +
143
+ time_it_took_for_second_step }
144
+
145
+ let(:flow) do
146
+ f = Seam::Flow.new
147
+ f.do_something
148
+ f.do_something
149
+ f.wait time_to_wait
150
+ f.do_something
151
+ f
152
+ end
153
+
154
+ before do
155
+ Timecop.freeze today
156
+ effort_id
157
+
158
+ Timecop.freeze Time.now + time_it_took_for_first_step
159
+ DoSomething.new.execute_all
160
+ Timecop.freeze Time.now + time_it_took_for_second_step
161
+ DoSomething.new.execute_all
162
+ Timecop.freeze Time.now + time_before_wait_worker_was_called
163
+ end
164
+
165
+ it "should move to the next step" do
166
+ Seam::WaitWorker.new.execute_all
167
+ Seam::Effort.find(effort_id).next_step.must_equal "do_something"
168
+ end
169
+
170
+ it "should set the next execute date" do
171
+ Seam::WaitWorker.new.execute_all
172
+ Seam::Effort.find(effort_id).next_execute_at.must_equal expected_start
173
+ end
174
+
175
+ end
176
+
177
+ end
178
+
179
+ end