bumbleworks 0.0.55 → 0.0.56

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -33,18 +33,23 @@ Bumbleworks.configure do |c|
33
33
  # c.storage = {}
34
34
  end
35
35
 
36
- # this next block is optional - it's only needed
37
- # if you want to load custom participants
38
- Bumbleworks.register_participants do
39
- # foo FooParticipant
40
- # bar BarParticipant
41
- # ...
42
- end
43
-
44
- # Load all process definitions in lib/process_definitions
45
- Bumbleworks.load_definitions!
46
-
47
- # Start a worker in the background
36
+ # Initialize Bumbleworks (autoloads necessary classes/modules)
37
+ Bumbleworks.initialize!
38
+
39
+ # Optionally, bootstrap in the initializer - don't do this in
40
+ # production, since every time this file is loaded, definitions and
41
+ # participant registrations will be overwritten, which will cause
42
+ # problems with any running workers. But if you've configured
43
+ # a Hash storage (see above) for dev/test, you have to bootstrap within
44
+ # the same process.
45
+ # In production, you'd separately run the `bumbleworks:bootstrap` rake
46
+ # task to load definitions and participant registration.
47
+ Bumbleworks.bootstrap!
48
+
49
+ # Start a worker in the background - this, too, should not be done
50
+ # in the initializer in a production environment - instead, the worker
51
+ # should be run in a separate process, using the `bumbleworks:start_worker`
52
+ # rake task.
48
53
  Bumbleworks.start_worker!
49
54
  ```
50
55
 
@@ -129,6 +134,27 @@ Bumbleworks.configure do |c|
129
134
  end
130
135
  ```
131
136
 
137
+ ### Participant Registration File
138
+
139
+ If your app has a `participants.rb` file at Bumbleworks.root (see Determining the Root Directory), Bumbleworks will load this file when you run `Bumbleworks.bootstrap!` (or run the `bumbleworks:bootstrap` rake task), which will create the registered participant list. The file should contain a block such as the following:
140
+
141
+ ```ruby
142
+ Bumbleworks.register_participants do
143
+ # foo FooParticipant
144
+ # bar BarParticipant
145
+ # ...
146
+ end
147
+ ```
148
+
149
+ You can customize the path to this file by setting Bumbleworks.participant_registration_file:
150
+
151
+ ```ruby
152
+ Bumbleworks.configure do |c|
153
+ c.participant_registration_file = '/absolute/path/to/participant/registration/file.rb'
154
+ # ...
155
+ end
156
+ ```
157
+
132
158
  ### Determining the Root Directory
133
159
 
134
160
  By default, Bumbleworks will attempt in several ways to find your root directory. In the most common cases (Rails, Sinatra, or Rory), it usually won't have trouble guessing the directory. The default `Bumbleworks.root` directory will be the framework's root with `lib/bumbleworks` appended.
@@ -150,7 +176,7 @@ Process definitions are just ruby files with blocks following Ruote's [Ruby DSL
150
176
  To actually load your process definitions from the directory:
151
177
 
152
178
  ```ruby
153
- Bumbleworks.load_definitions!
179
+ Bumbleworks.bootstrap!
154
180
  ```
155
181
 
156
182
  Keep in mind that any changed process definitions will overwrite previously loaded ones - in other words, after running this command successfully, all process definitions loaded into Bumbleworks will be in sync with the files in your definitions directory.
@@ -172,6 +198,8 @@ end
172
198
 
173
199
  Unless you add it yourself, Bumbleworks will register a "catchall" participant at the end of your participant list, which will catch any workitems not picked up by a participant higher in the list. Those workitems then fall into ruote's StorageParticipant, from where Bumbleworks will assemble its task queue.
174
200
 
201
+ This block should be placed in the Participant Registration File (see above), and then it will automatically be loaded when running `Bumbleworks.bootstrap!` (or the `bumbleworks:bootstrap` rake task).
202
+
175
203
  ### Starting Work
176
204
 
177
205
  Without running a "worker," Bumbleworks won't do anything behind the scenes - no workitems will proceed through their workflow, no schedules will be checked, etc. Running a worker is done using the following command:
@@ -182,7 +210,7 @@ Bumbleworks.start_worker!
182
210
 
183
211
  You can add this to the end of your initializer, but, while this is handy in development and testing, it's not a good practice to follow in production. In an actual production environment, you will likely have multiple workers running in their own threads, or even on separate servers. So the **preferred way** is to call the `Bumbleworks.start_worker!` method outside of the initializer, most likely in a Rake task that has your environment loaded.
184
212
 
185
- > Strictly speaking, the entire environment doesn't need to be loaded; only Bumbleworks.storage needs to be set before starting a worker. However, it's best practice to configure Bumbleworks in one place, to ensure you don't get your storage configurations out of sync.
213
+ > Strictly speaking, the entire environment doesn't need to be loaded; only Bumbleworks.storage and Bumbleworks.root need to be set (the latter will have a reasonable default if using a popular framework), and `Bumbleworks.initialize!` must be run, before starting a worker. However, it's best practice to configure Bumbleworks in one place, to ensure you don't get your storage configurations out of sync.
186
214
 
187
215
  You can run as many workers as you want in parallel, and as long as they're accessing the same storage, no concurrency issues should arise.
188
216
 
@@ -226,9 +254,9 @@ The tasks are:
226
254
 
227
255
  This task starts a Bumbleworks worker, and does not return. It will expect Bumbleworks to be required and for Bumbleworks' storage to be configured.
228
256
 
229
- 2. `rake bumbleworks:reload_definitions`
257
+ 2. `rake bumbleworks:bootstrap`
230
258
 
231
- All process definitions will be reloaded from the configured `definitions_directory`.
259
+ All process definitions will be loaded from the configured `definitions_directory`, and the participant registration file (at the configured `participant_registration_file` path) will be loaded. This operation will overwrite the current definitions and participant list, which is fine as long as no workers are currently running.
232
260
 
233
261
  ## Contributing
234
262
 
data/doc/QUICKSTART.md CHANGED
@@ -28,7 +28,7 @@
28
28
  c.storage = Redis.new
29
29
  end
30
30
 
31
- Bumbleworks.load_definitions!
31
+ Bumbleworks.initialize!
32
32
  ```
33
33
 
34
34
  1. Add your first process definition at `lib/bumbleworks/process_definitions/` (or `lib/bumbleworks/processes`):
@@ -43,25 +43,19 @@
43
43
 
44
44
  1. (*optional*) Put any [custom participants](http://ruote.rubyforge.org/implementing_participants.html) in `lib/bumbleworks/participants`.
45
45
 
46
- 1. Create an initializer file (e.g. `config/initializers/bumbleworks.rb` for Rails) with the following:
46
+ 1. (*optional*) Create a participant registration file at `lib/bumbleworks/participants.rb` with the following:
47
47
 
48
48
  ```ruby
49
- Bumbleworks.configure do |c|
50
- c.storage = Hash.new
51
- end
52
-
53
- # this next block is optional - it's only needed
54
- # if you want to load custom participants
55
49
  Bumbleworks.register_participants do
56
50
  # foo FooParticipant
57
51
  # bar BarParticipant
58
- # ...
52
+ # ... any other custom participants you created
59
53
  end
60
-
61
- Bumbleworks.load_definitions!
62
- Bumbleworks.start_worker!
63
54
  ```
64
55
 
56
+ 1. Run the `bumbleworks:bootstrap` rake task to load your process definitions and participant list
57
+ into your process storage (the Redis database).
58
+
65
59
  1. You can now launch processes using `Bumbleworks.launch!('process_definition_name')`. `#launch!` takes a hash as an optional second argument - anything set here will become workitem fields. A special key, `:entity`, can be used to specify a persistent business entity for the process, which will be retrievable from process tasks (using `Task#entity`).
66
60
 
67
61
  1. Any expressions of the form `[role] :task => [task_name]` will be turned into tasks retrievable at `Bumbleworks::Task.all`; you can get tasks specific to a role or roles using `Bumbleworks::Task.for_roles([role1, role2, ...])`.
data/lib/bumbleworks.rb CHANGED
@@ -102,14 +102,30 @@ module Bumbleworks
102
102
  # plumber PlumberClass
103
103
  # end
104
104
  def register_participants(&block)
105
- Bumbleworks::ParticipantRegistration.autoload_all
105
+ autoload_participants
106
106
  Bumbleworks::Ruote.register_participants(&block)
107
107
  end
108
108
 
109
+ # @public
110
+ # Syntactic sugar to register participants without supplying a
111
+ # block - ends up registering only default participants (such
112
+ # as the error handler and storage).
113
+ #
114
+ def register_default_participants
115
+ register_participants
116
+ end
117
+
118
+ # @public
119
+ # Autoloads all files in the configured participants_directory.
120
+ #
121
+ def autoload_participants
122
+ Bumbleworks::ParticipantRegistration.autoload_all
123
+ end
124
+
109
125
  # @public
110
126
  # Autoloads all files in the configured tasks_directory.
111
127
  #
112
- def register_tasks(&block)
128
+ def autoload_tasks
113
129
  Bumbleworks::Task.autoload_all
114
130
  end
115
131
 
@@ -118,7 +134,9 @@ module Bumbleworks
118
134
  # with the Ruote engine.
119
135
  #
120
136
  def load_definitions!(options = {})
121
- Bumbleworks::ProcessDefinition.create_all_from_directory!(definitions_directory, options)
137
+ if directory = definitions_directory
138
+ Bumbleworks::ProcessDefinition.create_all_from_directory!(directory, options)
139
+ end
122
140
  end
123
141
 
124
142
  # @public
@@ -130,6 +148,23 @@ module Bumbleworks
130
148
  Bumbleworks::Ruote.reset!
131
149
  end
132
150
 
151
+ # @public
152
+ # Autoloads all necessary files for the Bumbleworks environment
153
+ #
154
+ def initialize!
155
+ autoload_tasks
156
+ autoload_participants
157
+ end
158
+
159
+ # @public
160
+ # Loads process definitions, and loads participant registration file at
161
+ # configured participant_registration_file path.
162
+ #
163
+ def bootstrap!(options = {})
164
+ load_definitions!(options)
165
+ Bumbleworks::ParticipantRegistration.register!
166
+ end
167
+
133
168
  # @public
134
169
  # Launches the process definition with the given process name, as long as
135
170
  # that definition name is already registered with Bumbleworks. If options
@@ -49,7 +49,11 @@ module Bumbleworks
49
49
 
50
50
  # Path to the folder which holds the ruote definition files. Bumbleworks
51
51
  # will load all definition files by recursively traversing the directory
52
- # tree under this folder. No specific loading order is guaranteed
52
+ # tree under this folder. No specific loading order is guaranteed.
53
+ # These definition files will be loaded when Bumbleworks.bootstrap! is
54
+ # called, not Bootstrap.initialize! (since you don't want to re-register
55
+ # the participant list every time Bumbleworks is set up, but rather as an
56
+ # explicit task, for instance on deploy).
53
57
  #
54
58
  # default: ${Bumbleworks.root}/process_definitions then ${Bumbleworks.root}/processes
55
59
  define_setting :definitions_directory
@@ -69,6 +73,14 @@ module Bumbleworks
69
73
  # default: ${Bumbleworks.root}/tasks
70
74
  define_setting :tasks_directory
71
75
 
76
+ # Path to the file in which participant registration is defined. This file will
77
+ # be `load`ed when Bumbleworks.bootstrap! is called, not Bootstrap.initialize!
78
+ # (since you don't want to re-register the participant list every time Bumbleworks
79
+ # is set up, but rather as an explicit task, for instance on deploy).
80
+ #
81
+ # default: ${Bumbleworks.root}/participants.rb
82
+ define_setting :participant_registration_file
83
+
72
84
  # Bumbleworks requires a dedicated key-value storage for process information. Three
73
85
  # storage solutions are currently supported: Hash, Redis and Sequel. The latter
74
86
  # two require the bumbleworks-redis and bumbleworks-sequel gems, respectively.
@@ -160,6 +172,7 @@ module Bumbleworks
160
172
  def initialize
161
173
  @storage_adapters = []
162
174
  @storage_options = {}
175
+ @cached_paths = {}
163
176
  @timeout ||= 5
164
177
  end
165
178
 
@@ -168,7 +181,10 @@ module Bumbleworks
168
181
  # relative to Bumbleworks.root.
169
182
  #
170
183
  def definitions_directory
171
- @definitions_folder ||= default_definition_directory
184
+ @cached_paths[:definitions_directory] ||= look_up_configured_path(
185
+ :definitions_directory,
186
+ :defaults => ['process_definitions', 'processes']
187
+ )
172
188
  end
173
189
 
174
190
  # Path where Bumbleworks will look for ruote participants to load.
@@ -176,7 +192,10 @@ module Bumbleworks
176
192
  # relative to Bumbleworks.root.
177
193
  #
178
194
  def participants_directory
179
- @participants_folder ||= default_participant_directory
195
+ look_up_configured_path(
196
+ :participants_directory,
197
+ :defaults => ['participants']
198
+ )
180
199
  end
181
200
 
182
201
  # Path where Bumbleworks will look for task modules to load.
@@ -184,7 +203,22 @@ module Bumbleworks
184
203
  # relative to Bumbleworks.root.
185
204
  #
186
205
  def tasks_directory
187
- @tasks_folder ||= default_tasks_directory
206
+ @cached_paths[:tasks_directory] ||= look_up_configured_path(
207
+ :tasks_directory,
208
+ :defaults => ['tasks']
209
+ )
210
+ end
211
+
212
+ # Path where Bumbleworks will look for the participant registration
213
+ # file. The path can be relative or absolute. Relative paths are
214
+ # relative to Bumbleworks.root.
215
+ #
216
+ def participant_registration_file
217
+ @cached_paths[:participant_registration_file] ||= look_up_configured_path(
218
+ :participant_registration_file,
219
+ :defaults => ['participants.rb'],
220
+ :file => true
221
+ )
188
222
  end
189
223
 
190
224
  # Default history storage to true
@@ -250,14 +284,15 @@ module Bumbleworks
250
284
  def clear!
251
285
  defined_settings.each {|setting| instance_variable_set("@#{setting}", nil)}
252
286
  @storage_adapters = []
253
- @definitions_folder = @participants_folder = @tasks_folder = nil
287
+ @cached_paths = {}
254
288
  end
255
289
 
256
290
  def error_handlers
257
291
  @error_handlers ||= [Bumbleworks::ErrorLogger]
258
292
  end
259
293
 
260
- private
294
+ private
295
+
261
296
  def defined_settings
262
297
  self.class.defined_settings
263
298
  end
@@ -271,41 +306,46 @@ module Bumbleworks
271
306
  end
272
307
  end
273
308
 
274
- def default_definition_directory
275
- default_folders = ['process_definitions', 'processes']
276
- find_folder(default_folders, @definitions_directory, "Definitions folder not found")
309
+ def path_resolves?(path, options = {})
310
+ if options[:file]
311
+ File.file?(path.to_s)
312
+ else
313
+ File.directory?(path.to_s)
314
+ end
277
315
  end
278
316
 
279
- def default_participant_directory
280
- default_folders = ['participants']
281
- find_folder(default_folders, @participants_directory, "Participants folder not found")
317
+ def user_configured_path(path_type)
318
+ user_defined_path = instance_variable_get("@#{path_type}")
319
+ if user_defined_path
320
+ if user_defined_path[0] == '/'
321
+ user_defined_path
322
+ else
323
+ File.join(root, user_defined_path)
324
+ end
325
+ end
282
326
  end
283
327
 
284
- def default_tasks_directory
285
- default_folders = ['tasks']
286
- find_folder(default_folders, @tasks_directory, "Tasks folder not found")
328
+ def first_existing_default_path(possible_paths, options = {})
329
+ defaults = [possible_paths].flatten.compact.map { |d| File.join(root, d) }
330
+ defaults.detect do |default|
331
+ path_resolves?(default, :file => options[:file])
332
+ end
287
333
  end
288
334
 
289
- def find_folder(default_directories, user_defined_directory, message)
290
- if user_defined_directory
291
- # use user-defined directory if specified
292
- defined_directory = if user_defined_directory[0] == '/'
293
- user_defined_directory
335
+ # If the user explicitly declared a path, raises an exception if the
336
+ # path was not found. Missing default paths do not raise an exception
337
+ # since no paths are required.
338
+ def look_up_configured_path(path_type, options = {})
339
+ return @cached_paths[path_type] if @cached_paths.has_key?(path_type)
340
+ if user_defined_path = user_configured_path(path_type)
341
+ if path_resolves?(user_defined_path, :file => options[:file])
342
+ return user_defined_path
294
343
  else
295
- File.join(root, user_defined_directory)
296
- end
297
- else
298
- # next look in default directory structure
299
- defined_directory = default_directories.detect do |default_folder|
300
- folder = File.join(root, default_folder)
301
- next unless File.directory?(folder)
302
- break folder
344
+ raise Bumbleworks::InvalidSetting, "#{Bumbleworks::Support.humanize(path_type)} not found (looked for #{user_defined_path || defaults.join(', ')})"
303
345
  end
304
346
  end
305
347
 
306
- return defined_directory if File.directory?(defined_directory.to_s)
307
-
308
- raise Bumbleworks::InvalidSetting, "#{message} (looked in #{user_defined_directory || default_directories.join(', ')})"
348
+ first_existing_default_path(options[:defaults], :file => options[:file])
309
349
  end
310
350
  end
311
351
  end
@@ -9,9 +9,18 @@ module Bumbleworks
9
9
  # should define `GoatChallenge`.
10
10
  #
11
11
  def autoload_all(options = {})
12
- options[:directory] ||= Bumbleworks.participants_directory
13
- Bumbleworks::Support.all_files(options[:directory], :camelize => true).each do |path, name|
14
- Object.autoload name.to_sym, path
12
+ if directory = options[:directory] || Bumbleworks.participants_directory
13
+ Bumbleworks::Support.all_files(directory, :camelize => true).each do |path, name|
14
+ Object.autoload name.to_sym, path
15
+ end
16
+ end
17
+ end
18
+
19
+ def register!(options = {})
20
+ if file = options[:file] || Bumbleworks.participant_registration_file
21
+ Kernel.load file
22
+ else
23
+ Bumbleworks.register_default_participants
15
24
  end
16
25
  end
17
26
  end
@@ -34,7 +34,7 @@ module Bumbleworks
34
34
 
35
35
  def tokenize(string)
36
36
  return nil if string.nil?
37
- string = string.gsub(/&/, ' and ').
37
+ string = string.to_s.gsub(/&/, ' and ').
38
38
  gsub(/[ \/]+/, '_').
39
39
  gsub(/([a-z\d])([A-Z])/,'\1_\2').
40
40
  downcase
@@ -25,9 +25,10 @@ module Bumbleworks
25
25
  # should define `ChewCudTask`.
26
26
  #
27
27
  def autoload_all(options = {})
28
- options[:directory] ||= Bumbleworks.tasks_directory
29
- Bumbleworks::Support.all_files(options[:directory], :camelize => true).each do |path, name|
30
- Object.autoload name.to_sym, path
28
+ if directory = options[:directory] || Bumbleworks.tasks_directory
29
+ Bumbleworks::Support.all_files(directory, :camelize => true).each do |path, name|
30
+ Object.autoload name.to_sym, path
31
+ end
31
32
  end
32
33
  end
33
34
 
@@ -1,3 +1,3 @@
1
1
  module Bumbleworks
2
- VERSION = "0.0.55"
2
+ VERSION = "0.0.56"
3
3
  end
@@ -5,10 +5,10 @@ namespace :bumbleworks do
5
5
  Bumbleworks.start_worker!(:join => true, :verbose => verbose)
6
6
  end
7
7
 
8
- desc 'Reload all process definitions from directory'
9
- task :reload_definitions => :environment do
10
- puts "Reloading all Bumbleworks process definitions..." if verbose == true
11
- Bumbleworks.load_definitions!(:verbose => verbose)
8
+ desc 'Load process definitions and participant list'
9
+ task :bootstrap => :environment do
10
+ puts "Bootstrapping Bumbleworks definitions and participant list..." if verbose == true
11
+ Bumbleworks.bootstrap!(:verbose => verbose)
12
12
  end
13
13
 
14
14
  desc 'Launch a given Bumbleworks process'
@@ -3,11 +3,6 @@ Bumbleworks.configure! do |c|
3
3
  c.storage = {}
4
4
  end
5
5
 
6
- Bumbleworks.register_participants do
7
- honey_maker HoneyParticipant
8
- molasses_maker MolassesParticipant
9
- end
10
-
11
- Bumbleworks.register_tasks
12
- Bumbleworks.load_definitions!
6
+ Bumbleworks.bootstrap!
7
+ Bumbleworks.initialize!
13
8
  Bumbleworks.start_worker!
@@ -0,0 +1,4 @@
1
+ Bumbleworks.register_participants do
2
+ honey_maker HoneyParticipant
3
+ molasses_maker MolassesParticipant
4
+ end
@@ -92,23 +92,18 @@ describe Bumbleworks::Configuration do
92
92
  configuration.definitions_directory.should == '/Root/processes'
93
93
  end
94
94
 
95
- it 'raises an error if default folder not found' do
95
+ it 'returns nil if default folder not found' do
96
96
  configuration.root = '/Root'
97
- expect {
98
- configuration.definitions_directory
99
- }.to raise_error(
100
- Bumbleworks::InvalidSetting,
101
- "Definitions folder not found (looked in process_definitions, processes)"
102
- )
97
+ configuration.definitions_directory.should be_nil
103
98
  end
104
99
 
105
- it 'raises an error if specific folder not found' do
100
+ it 'raises error if specific folder not found' do
106
101
  configuration.definitions_directory = '/mumbo/jumbo'
107
102
  expect {
108
103
  configuration.definitions_directory
109
104
  }.to raise_error(
110
105
  Bumbleworks::InvalidSetting,
111
- "Definitions folder not found (looked in /mumbo/jumbo)"
106
+ "Definitions directory not found (looked for /mumbo/jumbo)"
112
107
  )
113
108
  end
114
109
  end
@@ -126,23 +121,18 @@ describe Bumbleworks::Configuration do
126
121
  configuration.participants_directory.should == '/Root/participants'
127
122
  end
128
123
 
129
- it 'raises an error if default folder not found' do
124
+ it 'returns nil if default folder not found' do
130
125
  configuration.root = '/Root'
131
- expect {
132
- configuration.participants_directory
133
- }.to raise_error(
134
- Bumbleworks::InvalidSetting,
135
- "Participants folder not found (looked in participants)"
136
- )
126
+ configuration.participants_directory.should be_nil
137
127
  end
138
128
 
139
- it 'raises an error if specific folder not found' do
129
+ it 'raises error if specific folder not found' do
140
130
  configuration.participants_directory = '/mumbo/jumbo'
141
131
  expect {
142
132
  configuration.participants_directory
143
133
  }.to raise_error(
144
134
  Bumbleworks::InvalidSetting,
145
- "Participants folder not found (looked in /mumbo/jumbo)"
135
+ "Participants directory not found (looked for /mumbo/jumbo)"
146
136
  )
147
137
  end
148
138
  end
@@ -160,23 +150,47 @@ describe Bumbleworks::Configuration do
160
150
  configuration.tasks_directory.should == '/Root/tasks'
161
151
  end
162
152
 
163
- it 'raises an error if default folder not found' do
153
+ it 'returns nil if default folder not found' do
164
154
  configuration.root = '/Root'
155
+ configuration.tasks_directory.should be_nil
156
+ end
157
+
158
+ it 'raises error if specific folder not found' do
159
+ configuration.tasks_directory = '/mumbo/jumbo'
165
160
  expect {
166
161
  configuration.tasks_directory
167
162
  }.to raise_error(
168
163
  Bumbleworks::InvalidSetting,
169
- "Tasks folder not found (looked in tasks)"
164
+ "Tasks directory not found (looked for /mumbo/jumbo)"
170
165
  )
171
166
  end
167
+ end
172
168
 
173
- it 'raises an error if specific folder not found' do
174
- configuration.tasks_directory = '/mumbo/jumbo'
169
+ describe "#participant_registration_file" do
170
+ it 'returns the path which was set by the client app' do
171
+ File.stub(:file?).with('/can/i/get/a/rooster.rb').and_return(true)
172
+ configuration.participant_registration_file = '/can/i/get/a/rooster.rb'
173
+ configuration.participant_registration_file.should == '/can/i/get/a/rooster.rb'
174
+ end
175
+
176
+ it 'returns the default folder if not set by client app' do
177
+ File.stub(:file?).with('/Root/participants.rb').and_return(true)
178
+ configuration.root = '/Root'
179
+ configuration.participant_registration_file.should == '/Root/participants.rb'
180
+ end
181
+
182
+ it 'returns nil if default path not found' do
183
+ configuration.root = '/Root'
184
+ configuration.participant_registration_file.should be_nil
185
+ end
186
+
187
+ it 'raises error if specific path not found' do
188
+ configuration.participant_registration_file = '/do/not/eat/friendly/people.rb'
175
189
  expect {
176
- configuration.tasks_directory
190
+ configuration.participant_registration_file
177
191
  }.to raise_error(
178
192
  Bumbleworks::InvalidSetting,
179
- "Tasks folder not found (looked in /mumbo/jumbo)"
193
+ "Participant registration file not found (looked for /do/not/eat/friendly/people.rb)"
180
194
  )
181
195
  end
182
196
  end
@@ -1,13 +1,48 @@
1
1
  describe Bumbleworks::ParticipantRegistration do
2
+ before(:each) do
3
+ Bumbleworks.reset!
4
+ Bumbleworks.root = File.join(fixtures_path, 'apps', 'with_default_directories')
5
+ end
6
+
2
7
  describe '.autoload_all' do
3
8
  it 'autoloads all participants in directory' do
4
- Bumbleworks.reset!
5
- Bumbleworks.root = File.join(fixtures_path, 'apps', 'with_default_directories')
6
9
  Object.should_receive(:autoload).with(:HoneyParticipant,
7
10
  File.join(Bumbleworks.root, 'participants', 'honey_participant.rb'))
8
11
  Object.should_receive(:autoload).with(:MolassesParticipant,
9
12
  File.join(Bumbleworks.root, 'participants', 'molasses_participant.rb'))
10
- Bumbleworks::ParticipantRegistration.autoload_all
13
+ described_class.autoload_all
14
+ end
15
+
16
+ it 'does nothing if using default path and directory does not exist' do
17
+ Bumbleworks.root = File.join(fixtures_path, 'apps', 'minimal')
18
+ described_class.autoload_all
19
+ end
20
+
21
+ it 'raises exception if using custom path and participants file does not exist' do
22
+ Bumbleworks.participants_directory = 'oysters'
23
+ expect {
24
+ described_class.autoload_all
25
+ }.to raise_error(Bumbleworks::InvalidSetting)
26
+ end
27
+ end
28
+
29
+ describe '.register!' do
30
+ it 'loads registration file' do
31
+ Kernel.should_receive(:load).with(File.join(Bumbleworks.root, 'participants.rb'))
32
+ described_class.register!
33
+ end
34
+
35
+ it 'registers default participants if using default path and file does not exist' do
36
+ Bumbleworks.root = File.join(fixtures_path, 'apps', 'minimal')
37
+ Bumbleworks.should_receive(:register_default_participants)
38
+ described_class.register!
39
+ end
40
+
41
+ it 'raises exception if using custom path and participants file does not exist' do
42
+ Bumbleworks.participant_registration_file = 'oysters'
43
+ expect {
44
+ described_class.register!
45
+ }.to raise_error(Bumbleworks::InvalidSetting)
11
46
  end
12
47
  end
13
48
  end
@@ -72,6 +72,10 @@ describe Bumbleworks::Support do
72
72
  it 'returns nil if given nil' do
73
73
  described_class.tokenize(nil).should be_nil
74
74
  end
75
+
76
+ it 'also handles symbols' do
77
+ described_class.tokenize(:yourFaceIsNice).should == 'your_face_is_nice'
78
+ end
75
79
  end
76
80
 
77
81
  describe '.humanize' do
@@ -34,7 +34,20 @@ describe Bumbleworks::Task do
34
34
  File.join(Bumbleworks.root, 'tasks', 'make_some_honey_task.rb'))
35
35
  Object.should_receive(:autoload).with(:TasteThatMolassesTask,
36
36
  File.join(Bumbleworks.root, 'tasks', 'taste_that_molasses_task.rb'))
37
- Bumbleworks::Task.autoload_all
37
+ described_class.autoload_all
38
+ end
39
+
40
+ it 'does nothing if using default path and directory does not exist' do
41
+ Bumbleworks.root = File.join(fixtures_path, 'apps', 'minimal')
42
+ described_class.autoload_all
43
+ end
44
+
45
+ it 'raises exception if using custom path and participants file does not exist' do
46
+ Bumbleworks.root = File.join(fixtures_path, 'apps', 'minimal')
47
+ Bumbleworks.tasks_directory = 'oysters'
48
+ expect {
49
+ described_class.autoload_all
50
+ }.to raise_error(Bumbleworks::InvalidSetting)
38
51
  end
39
52
  end
40
53
 
@@ -60,29 +60,76 @@ describe Bumbleworks do
60
60
  end
61
61
  end
62
62
 
63
- describe '.register_tasks' do
63
+ describe '.autoload_tasks' do
64
64
  it 'autoloads task modules' do
65
65
  Bumbleworks::Task.should_receive(:autoload_all)
66
- described_class.register_tasks
66
+ described_class.autoload_tasks
67
+ end
68
+ end
69
+
70
+ describe '.autoload_participants' do
71
+ it 'autoloads participant classes' do
72
+ Bumbleworks::ParticipantRegistration.should_receive(:autoload_all)
73
+ described_class.autoload_participants
74
+ end
75
+ end
76
+
77
+ describe '.initialize!' do
78
+ it 'autoloads task modules and participant classes' do
79
+ described_class.should_receive(:autoload_participants)
80
+ described_class.should_receive(:autoload_tasks)
81
+ described_class.initialize!
67
82
  end
68
83
  end
69
84
 
70
85
  describe '.register_participants' do
71
- it 'autoloads and registers participants' do
86
+ it 'autoloads participant classes and registers given participant list' do
72
87
  the_block = lambda { }
73
- Bumbleworks::ParticipantRegistration.should_receive(:autoload_all)
88
+ described_class.should_receive(:autoload_participants)
74
89
  Bumbleworks::Ruote.should_receive(:register_participants).with(&the_block)
75
90
  described_class.register_participants &the_block
76
91
  end
77
92
  end
78
93
 
94
+ describe '.register_default_participants' do
95
+ it 'registers default participants' do
96
+ described_class.should_receive(:autoload_participants).never
97
+ described_class.should_receive(:register_participants)
98
+ described_class.register_default_participants
99
+ end
100
+ end
101
+
79
102
  describe '.load_definitions!' do
80
103
  it 'creates all definitions from directory' do
81
104
  described_class.stub(:definitions_directory).and_return(:defs_dir)
82
- described_class.storage = {}
105
+ # described_class.storage = {}
83
106
  Bumbleworks::ProcessDefinition.should_receive(:create_all_from_directory!).with(:defs_dir, :fake_options)
84
107
  described_class.load_definitions!(:fake_options)
85
108
  end
109
+
110
+ it 'does nothing if using default path and directory does not exist' do
111
+ described_class.reset!
112
+ described_class.root = File.join(fixtures_path, 'apps', 'minimal')
113
+ Bumbleworks::ProcessDefinition.should_receive(:create_all_from_directory!).never
114
+ described_class.load_definitions!
115
+ end
116
+
117
+ it 'raises exception if using custom path and directory does not exist' do
118
+ described_class.reset!
119
+ described_class.root = File.join(fixtures_path, 'apps', 'minimal')
120
+ described_class.definitions_directory = 'oysters'
121
+ expect {
122
+ described_class.load_definitions!
123
+ }.to raise_error(Bumbleworks::InvalidSetting)
124
+ end
125
+ end
126
+
127
+ describe '.bootstrap!' do
128
+ it 'loads definitions and participant registration list' do
129
+ described_class.should_receive(:load_definitions!)
130
+ Bumbleworks::ParticipantRegistration.should_receive(:register!)
131
+ described_class.bootstrap!
132
+ end
86
133
  end
87
134
 
88
135
  describe '.configuration' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bumbleworks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.55
4
+ version: 0.0.56
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2014-01-14 00:00:00.000000000 Z
15
+ date: 2014-01-21 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: ruote
@@ -198,6 +198,7 @@ files:
198
198
  - lib/tasks/bumbleworks.rake
199
199
  - spec/fixtures/apps/with_default_directories/config_initializer.rb
200
200
  - spec/fixtures/apps/with_default_directories/full_initializer.rb
201
+ - spec/fixtures/apps/with_default_directories/participants.rb
201
202
  - spec/fixtures/apps/with_default_directories/participants/honey_participant.rb
202
203
  - spec/fixtures/apps/with_default_directories/participants/molasses_participant.rb
203
204
  - spec/fixtures/apps/with_default_directories/process_definitions/garbage_collector.rb
@@ -261,7 +262,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
261
262
  version: '0'
262
263
  segments:
263
264
  - 0
264
- hash: 2137363993883985375
265
+ hash: 1303608967349520599
265
266
  required_rubygems_version: !ruby/object:Gem::Requirement
266
267
  none: false
267
268
  requirements:
@@ -270,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
271
  version: '0'
271
272
  segments:
272
273
  - 0
273
- hash: 2137363993883985375
274
+ hash: 1303608967349520599
274
275
  requirements: []
275
276
  rubyforge_project:
276
277
  rubygems_version: 1.8.23
@@ -280,6 +281,7 @@ summary: Framework around ruote[http://github.com/jmettraux/ruote] workflow engi
280
281
  test_files:
281
282
  - spec/fixtures/apps/with_default_directories/config_initializer.rb
282
283
  - spec/fixtures/apps/with_default_directories/full_initializer.rb
284
+ - spec/fixtures/apps/with_default_directories/participants.rb
283
285
  - spec/fixtures/apps/with_default_directories/participants/honey_participant.rb
284
286
  - spec/fixtures/apps/with_default_directories/participants/molasses_participant.rb
285
287
  - spec/fixtures/apps/with_default_directories/process_definitions/garbage_collector.rb