state_machine 0.10.3 → 0.10.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,9 @@
1
1
  == master
2
2
 
3
+ == 0.10.4 / 2011-04-14
4
+
5
+ * Fix translations not being available under certain environments in Rails applications
6
+
3
7
  == 0.10.3 / 2011-04-07
4
8
 
5
9
  * Fix state initialization failing in ActiveRecord 3.0.2+ when using with_state scopes for the default scope
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'rake/gempackagetask'
6
6
 
7
7
  spec = Gem::Specification.new do |s|
8
8
  s.name = 'state_machine'
9
- s.version = '0.10.3'
9
+ s.version = '0.10.4'
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.summary = 'Adds support for creating state machines for attributes on any Ruby class'
12
12
  s.description = s.summary
@@ -1,5 +1,21 @@
1
- class StateMachine::Railtie < Rails::Railtie
2
- rake_tasks do
3
- load 'tasks/state_machine.rb'
1
+ if defined?(Rails)
2
+ # Track all of the applicable locales to load
3
+ locale_paths = []
4
+ StateMachine::Integrations.all.each do |integration|
5
+ locale_paths << integration.locale_path if integration.available? && integration.locale_path
4
6
  end
5
- end if defined?(Rails::Railtie)
7
+
8
+ if defined?(Rails::Engine)
9
+ # Rails 3.x
10
+ class StateMachine::RailsEngine < Rails::Engine
11
+ rake_tasks do
12
+ load 'tasks/state_machine.rb'
13
+ end
14
+ end
15
+
16
+ StateMachine::RailsEngine.paths.config.locales = locale_paths
17
+ elsif defined?(I18n)
18
+ # Rails 2.x
19
+ I18n.load_path.unshift(*locale_paths)
20
+ end
21
+ end
@@ -267,13 +267,18 @@ module StateMachine
267
267
 
268
268
  @defaults = {}
269
269
 
270
+ # Whether this integration is available. Only true if ActiveModel is
271
+ # defined.
272
+ def self.available?
273
+ defined?(::ActiveModel)
274
+ end
275
+
270
276
  # Should this integration be used for state machines in the given class?
271
277
  # Classes that include ActiveModel::Dirty, ActiveModel::Observing, or
272
278
  # ActiveModel::Validations will automatically use the ActiveModel
273
279
  # integration.
274
280
  def self.matches?(klass)
275
- features = %w(Dirty Observing Validations)
276
- defined?(::ActiveModel) && features.any? {|feature| ::ActiveModel.const_defined?(feature) && klass <= ::ActiveModel.const_get(feature)}
281
+ %w(Dirty Observing Validations).any? {|feature| ::ActiveModel.const_defined?(feature) && klass <= ::ActiveModel.const_get(feature)}
277
282
  end
278
283
 
279
284
  # Forces the change in state to be recognized regardless of whether the
@@ -308,11 +313,6 @@ module StateMachine
308
313
  end
309
314
 
310
315
  protected
311
- # The name of this integration
312
- def integration
313
- :active_model
314
- end
315
-
316
316
  # Whether observers are supported in the integration. Only true if
317
317
  # ActiveModel::Observer is available.
318
318
  def supports_observers?
@@ -387,12 +387,7 @@ module StateMachine
387
387
 
388
388
  # Loads any locale files needed for translating validation errors
389
389
  def load_locale
390
- I18n.load_path.unshift(locale_path) unless I18n.load_path.include?(locale_path)
391
- end
392
-
393
- # The path to the locale file containing state_machine translations
394
- def locale_path
395
- "#{File.dirname(__FILE__)}/#{integration}/locale.rb"
390
+ I18n.load_path.unshift(@integration.locale_path) unless I18n.load_path.include?(@integration.locale_path)
396
391
  end
397
392
 
398
393
  # Loads extensions to ActiveModel's Observers
@@ -2,6 +2,13 @@ filename = "#{File.dirname(__FILE__)}/../active_model/locale.rb"
2
2
  translations = eval(IO.read(filename), binding, filename)
3
3
  translations[:en][:activerecord] = translations[:en].delete(:activemodel)
4
4
 
5
+ # Only ActiveRecord 2.3.5+ can pull i18n >= 0.1.3 from system-wide gems (and
6
+ # therefore possibly have I18n::VERSION available)
7
+ begin
8
+ require 'i18n/version'
9
+ rescue Exception => ex
10
+ end unless ::ActiveRecord::VERSION::MAJOR == 2 && (::ActiveRecord::VERSION::MINOR < 3 || ::ActiveRecord::VERSION::TINY < 5)
11
+
5
12
  # Only i18n 0.4.0+ has the new %{key} syntax
6
13
  if !defined?(I18n::VERSION) || I18n::VERSION < '0.4.0'
7
14
  translations[:en][:activerecord][:errors][:messages].each do |key, message|
@@ -97,15 +97,6 @@ module StateMachine
97
97
  end
98
98
  end
99
99
 
100
- version '2.0 - 2.3.4' do
101
- def self.active?
102
- ::ActiveRecord::VERSION::MAJOR == 2 && (::ActiveRecord::VERSION::MINOR < 3 || ::ActiveRecord::VERSION::TINY < 5)
103
- end
104
-
105
- def load_i18n_version
106
- end
107
- end
108
-
109
100
  version '2.0.x' do
110
101
  def self.active?
111
102
  ::ActiveRecord::VERSION::MAJOR == 2 && ::ActiveRecord::VERSION::MINOR == 0
@@ -323,11 +323,17 @@ module StateMachine
323
323
  # The default options to use for state machines using this integration
324
324
  @defaults = {:action => :save}
325
325
 
326
+ # Whether this integration is available. Only true if ActiveRecord::Base
327
+ # is defined.
328
+ def self.available?
329
+ defined?(::ActiveRecord::Base)
330
+ end
331
+
326
332
  # Should this integration be used for state machines in the given class?
327
333
  # Classes that inherit from ActiveRecord::Base will automatically use
328
334
  # the ActiveRecord integration.
329
335
  def self.matches?(klass)
330
- defined?(::ActiveRecord::Base) && klass <= ::ActiveRecord::Base
336
+ klass <= ::ActiveRecord::Base
331
337
  end
332
338
 
333
339
  def self.extended(base) #:nodoc:
@@ -336,26 +342,6 @@ module StateMachine
336
342
  end
337
343
 
338
344
  protected
339
- # The name of this integration
340
- def integration
341
- :active_record
342
- end
343
-
344
- # Loads locale files needed for translations
345
- def load_locale
346
- load_i18n_version
347
- super
348
- end
349
-
350
- # Loads the version of the i18n library so that that proper
351
- # interpolation syntax can be used
352
- def load_i18n_version
353
- begin
354
- require 'i18n/version'
355
- rescue Exception => ex
356
- end
357
- end
358
-
359
345
  # Only runs validations on the action if using <tt>:save</tt>
360
346
  def runs_validations_on_action?
361
347
  action == :save
@@ -2,21 +2,34 @@ module StateMachine
2
2
  module Integrations
3
3
  # Provides a set of base helpers for managing individual integrations
4
4
  module Base
5
- # Never matches
6
- def self.matches?(klass)
7
- false
8
- end
9
-
10
- def self.included(base) #:nodoc:
11
- base.class_eval do
12
- extend ClassMethods
13
- end
14
- end
15
-
16
5
  module ClassMethods
17
6
  # The default options to use for state machines using this integration
18
7
  attr_reader :defaults
19
8
 
9
+ # The name of the integration
10
+ def integration_name
11
+ @integration_name ||= begin
12
+ name = self.name.split('::').last
13
+ name.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
14
+ name.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
15
+ name.downcase!
16
+ name.to_sym
17
+ end
18
+ end
19
+
20
+ # Whether this integration is available for the current library. This
21
+ # is usually only true if the ORM that the integration is for is
22
+ # currently defined. Default is false.
23
+ def available?
24
+ false
25
+ end
26
+
27
+ # Whether the integration should be used for the given class. Default
28
+ # is false.
29
+ def matches?(klass)
30
+ false
31
+ end
32
+
20
33
  # Tracks the various version overrides for an integration
21
34
  def versions
22
35
  @versions ||= []
@@ -51,6 +64,14 @@ module StateMachine
51
64
  mod
52
65
  end
53
66
 
67
+ # The path to the locale file containing translations for this
68
+ # integration. This file will only exist for integrations that actually
69
+ # support i18n.
70
+ def locale_path
71
+ path = "#{File.dirname(__FILE__)}/#{integration_name}/locale.rb"
72
+ path if File.exists?(path)
73
+ end
74
+
54
75
  # Extends the given object with any version overrides that are currently
55
76
  # active
56
77
  def extended(base)
@@ -59,6 +80,12 @@ module StateMachine
59
80
  end
60
81
  end
61
82
  end
83
+
84
+ extend ClassMethods
85
+
86
+ def self.included(base) #:nodoc:
87
+ base.class_eval { extend ClassMethods }
88
+ end
62
89
  end
63
90
  end
64
91
  end
@@ -248,12 +248,18 @@ module StateMachine
248
248
  # The default options to use for state machines using this integration
249
249
  class << self; attr_reader :defaults; end
250
250
  @defaults = {:action => :save, :use_transactions => false}
251
-
251
+
252
+ # Whether this integration is available. Only true if DataMapper::Resource
253
+ # is defined.
254
+ def self.available?
255
+ defined?(::DataMapper::Resource)
256
+ end
257
+
252
258
  # Should this integration be used for state machines in the given class?
253
259
  # Classes that include DataMapper::Resource will automatically use the
254
260
  # DataMapper integration.
255
261
  def self.matches?(klass)
256
- defined?(::DataMapper::Resource) && klass <= ::DataMapper::Resource
262
+ klass <= ::DataMapper::Resource
257
263
  end
258
264
 
259
265
  # Loads additional files specific to DataMapper
@@ -194,19 +194,20 @@ module StateMachine
194
194
  # The default options to use for state machines using this integration
195
195
  @defaults = {:action => :save}
196
196
 
197
+ # Whether this integration is available. Only true if MongoMapper::Document
198
+ # is defined.
199
+ def self.available?
200
+ defined?(::MongoMapper::Document)
201
+ end
202
+
197
203
  # Should this integration be used for state machines in the given class?
198
204
  # Classes that include MongoMapper::Document will automatically use the
199
205
  # MongoMapper integration.
200
206
  def self.matches?(klass)
201
- defined?(::MongoMapper::Document) && klass <= ::MongoMapper::Document
207
+ klass <= ::MongoMapper::Document
202
208
  end
203
209
 
204
210
  protected
205
- # The name of this integration
206
- def integration
207
- :mongo_mapper
208
- end
209
-
210
211
  # Only runs validations on the action if using <tt>:save</tt>
211
212
  def runs_validations_on_action?
212
213
  action == :save
@@ -244,11 +244,17 @@ module StateMachine
244
244
  # The default options to use for state machines using this integration
245
245
  @defaults = {:action => :save}
246
246
 
247
+ # Whether this integration is available. Only true if Mongoid::Document
248
+ # is defined.
249
+ def self.available?
250
+ defined?(::Mongoid::Document)
251
+ end
252
+
247
253
  # Should this integration be used for state machines in the given class?
248
254
  # Classes that include Mongoid::Document will automatically use the
249
255
  # Mongoid integration.
250
256
  def self.matches?(klass)
251
- defined?(::Mongoid::Document) && klass <= ::Mongoid::Document
257
+ klass <= ::Mongoid::Document
252
258
  end
253
259
 
254
260
  def self.extended(base) #:nodoc:
@@ -270,11 +276,6 @@ module StateMachine
270
276
  end
271
277
 
272
278
  protected
273
- # The name of this integration
274
- def integration
275
- :mongoid
276
- end
277
-
278
279
  # Mongoid uses its own implementation of dirty tracking instead of
279
280
  # ActiveModel's and doesn't support the #{attribute}_will_change! APIs
280
281
  def supports_dirty_tracking?(object)
@@ -224,11 +224,17 @@ module StateMachine
224
224
  class << self; attr_reader :defaults; end
225
225
  @defaults = {:action => :save}
226
226
 
227
+ # Whether this integration is available. Only true if Sequel::Model is
228
+ # defined.
229
+ def self.available?
230
+ defined?(::Sequel::Model)
231
+ end
232
+
227
233
  # Should this integration be used for state machines in the given class?
228
234
  # Classes that include Sequel::Model will automatically use the Sequel
229
235
  # integration.
230
236
  def self.matches?(klass)
231
- defined?(::Sequel::Model) && klass <= ::Sequel::Model
237
+ klass <= ::Sequel::Model
232
238
  end
233
239
 
234
240
  # Forces the change in state to be recognized regardless of whether the
@@ -4,7 +4,16 @@ Dir["#{File.dirname(__FILE__)}/integrations/*.rb"].sort.each do |path|
4
4
  require "state_machine/integrations/#{File.basename(path)}"
5
5
  end
6
6
 
7
+ require 'state_machine/error'
8
+
7
9
  module StateMachine
10
+ # An invalid integration was specified
11
+ class IntegrationNotFound < Error
12
+ def initialize(name)
13
+ super(nil, "#{name.inspect} is an invalid integration")
14
+ end
15
+ end
16
+
8
17
  # Integrations allow state machines to take advantage of features within the
9
18
  # context of a particular library. This is currently most useful with
10
19
  # database libraries. For example, the various database integrations allow
@@ -65,10 +74,7 @@ module StateMachine
65
74
  # StateMachine::Integrations.match(MongoMapperVehicle) # => StateMachine::Integrations::MongoMapper
66
75
  # StateMachine::Integrations.match(SequelVehicle) # => StateMachine::Integrations::Sequel
67
76
  def self.match(klass)
68
- constants = self.constants.map {|c| c.to_s}.select {|c| c != 'ActiveModel'}.sort << 'ActiveModel'
69
- if integration = constants.find {|name| const_get(name).matches?(klass)}
70
- find(integration)
71
- end
77
+ all.detect {|integration| integration.available? && integration.matches?(klass)}
72
78
  end
73
79
 
74
80
  # Finds an integration with the given name. If the integration cannot be
@@ -76,15 +82,29 @@ module StateMachine
76
82
  #
77
83
  # == Examples
78
84
  #
79
- # StateMachine::Integrations.find(:active_record) # => StateMachine::Integrations::ActiveRecord
80
- # StateMachine::Integrations.find(:active_model) # => StateMachine::Integrations::ActiveModel
81
- # StateMachine::Integrations.find(:data_mapper) # => StateMachine::Integrations::DataMapper
82
- # StateMachine::Integrations.find(:mongoid) # => StateMachine::Integrations::Mongoid
83
- # StateMachine::Integrations.find(:mongo_mapper) # => StateMachine::Integrations::MongoMapper
84
- # StateMachine::Integrations.find(:sequel) # => StateMachine::Integrations::Sequel
85
- # StateMachine::Integrations.find(:invalid) # => NameError: wrong constant name Invalid
86
- def self.find(name)
87
- const_get(name.to_s.gsub(/(?:^|_)(.)/) {$1.upcase})
85
+ # StateMachine::Integrations.find_by_name(:active_record) # => StateMachine::Integrations::ActiveRecord
86
+ # StateMachine::Integrations.find_by_name(:active_model) # => StateMachine::Integrations::ActiveModel
87
+ # StateMachine::Integrations.find_by_name(:data_mapper) # => StateMachine::Integrations::DataMapper
88
+ # StateMachine::Integrations.find_by_name(:mongoid) # => StateMachine::Integrations::Mongoid
89
+ # StateMachine::Integrations.find_by_name(:mongo_mapper) # => StateMachine::Integrations::MongoMapper
90
+ # StateMachine::Integrations.find_by_name(:sequel) # => StateMachine::Integrations::Sequel
91
+ # StateMachine::Integrations.find_by_name(:invalid) # => StateMachine::IntegrationNotFound: :invalid is an invalid integration
92
+ def self.find_by_name(name)
93
+ all.detect {|integration| integration.integration_name == name} || raise(IntegrationNotFound.new(name))
94
+ end
95
+
96
+ # Gets a list of all of the available integrations for use. This will
97
+ # always list the ActiveModel integration last.
98
+ #
99
+ # == Example
100
+ #
101
+ # StateMachine::Integrations.all
102
+ # # => [StateMachine::Integrations::ActiveRecord, StateMachine::Integrations::DataMapper
103
+ # # StateMachine::Integrations::Mongoid, StateMachine::Integrations::MongoMapper,
104
+ # # StateMachine::Integrations::Sequel, StateMachine::Integrations::ActiveModel]
105
+ def self.all
106
+ constants = self.constants.map {|c| c.to_s}.select {|c| c != 'ActiveModel'}.sort << 'ActiveModel'
107
+ constants.map {|c| const_get(c)}
88
108
  end
89
109
  end
90
110
  end
@@ -421,14 +421,14 @@ module StateMachine
421
421
 
422
422
  # Find an integration that matches this machine's owner class
423
423
  if options.include?(:integration)
424
- integration = StateMachine::Integrations.find(options[:integration]) if options[:integration]
424
+ @integration = StateMachine::Integrations.find_by_name(options[:integration]) if options[:integration]
425
425
  else
426
- integration = StateMachine::Integrations.match(owner_class)
426
+ @integration = StateMachine::Integrations.match(owner_class)
427
427
  end
428
-
429
- if integration
430
- extend integration
431
- options = (integration.defaults || {}).merge(options)
428
+
429
+ if @integration
430
+ extend @integration
431
+ options = (@integration.defaults || {}).merge(options)
432
432
  end
433
433
 
434
434
  # Add machine-wide defaults
@@ -75,6 +75,14 @@ module ActiveModelTest
75
75
  end
76
76
 
77
77
  class IntegrationTest < BaseTestCase
78
+ def test_should_have_an_integration_name
79
+ assert_equal :active_model, StateMachine::Integrations::ActiveModel.integration_name
80
+ end
81
+
82
+ def test_should_be_available
83
+ assert StateMachine::Integrations::ActiveModel.available?
84
+ end
85
+
78
86
  def test_should_match_if_class_includes_dirty_feature
79
87
  assert StateMachine::Integrations::ActiveModel.matches?(new_model { include ActiveModel::Dirty })
80
88
  end
@@ -94,6 +102,10 @@ module ActiveModelTest
94
102
  def test_should_have_no_defaults
95
103
  assert_equal e = {}, StateMachine::Integrations::ActiveModel.defaults
96
104
  end
105
+
106
+ def test_should_have_a_locale_path
107
+ assert_not_nil StateMachine::Integrations::ActiveModel.locale_path
108
+ end
97
109
  end
98
110
 
99
111
  class MachineByDefaultTest < BaseTestCase
@@ -74,6 +74,14 @@ module ActiveRecordTest
74
74
  end
75
75
 
76
76
  class IntegrationTest < BaseTestCase
77
+ def test_should_have_an_integration_name
78
+ assert_equal :active_record, StateMachine::Integrations::ActiveRecord.integration_name
79
+ end
80
+
81
+ def test_should_be_available
82
+ assert StateMachine::Integrations::ActiveRecord.available?
83
+ end
84
+
77
85
  def test_should_match_if_class_inherits_from_active_record
78
86
  assert StateMachine::Integrations::ActiveRecord.matches?(new_model)
79
87
  end
@@ -85,6 +93,10 @@ module ActiveRecordTest
85
93
  def test_should_have_defaults
86
94
  assert_equal e = {:action => :save}, StateMachine::Integrations::ActiveRecord.defaults
87
95
  end
96
+
97
+ def test_should_have_a_locale_path
98
+ assert_not_nil StateMachine::Integrations::ActiveRecord.locale_path
99
+ end
88
100
  end
89
101
 
90
102
  class MachineWithoutDatabaseTest < BaseTestCase
@@ -5,9 +5,21 @@ require 'rubygems'
5
5
 
6
6
  module BaseTest
7
7
  class IntegrationTest < Test::Unit::TestCase
8
+ def test_should_have_an_integration_name
9
+ assert_equal :base, StateMachine::Integrations::Base.integration_name
10
+ end
11
+
12
+ def test_should_not_be_available
13
+ assert !StateMachine::Integrations::Base.available?
14
+ end
15
+
8
16
  def test_should_not_match_any_classes
9
17
  assert !StateMachine::Integrations::Base.matches?(Class.new)
10
18
  end
19
+
20
+ def test_should_not_have_a_locale_path
21
+ assert_nil StateMachine::Integrations::Base.locale_path
22
+ end
11
23
  end
12
24
 
13
25
  class IncludedTest < Test::Unit::TestCase
@@ -58,6 +58,14 @@ module DataMapperTest
58
58
  end
59
59
 
60
60
  class IntegrationTest < BaseTestCase
61
+ def test_should_have_an_integration_name
62
+ assert_equal :data_mapper, StateMachine::Integrations::DataMapper.integration_name
63
+ end
64
+
65
+ def test_should_be_available
66
+ assert StateMachine::Integrations::DataMapper.available?
67
+ end
68
+
61
69
  def test_should_match_if_class_includes_data_mapper
62
70
  assert StateMachine::Integrations::DataMapper.matches?(new_resource)
63
71
  end
@@ -69,6 +77,10 @@ module DataMapperTest
69
77
  def test_should_have_defaults
70
78
  assert_equal e = {:action => :save, :use_transactions => false}, StateMachine::Integrations::DataMapper.defaults
71
79
  end
80
+
81
+ def test_should_not_have_a_locale_path
82
+ assert_nil StateMachine::Integrations::DataMapper.locale_path
83
+ end
72
84
  end
73
85
 
74
86
  class MachineWithoutDatabaseTest < BaseTestCase
@@ -49,6 +49,14 @@ module MongoMapperTest
49
49
  end
50
50
 
51
51
  class IntegrationTest < BaseTestCase
52
+ def test_should_have_an_integration_name
53
+ assert_equal :mongo_mapper, StateMachine::Integrations::MongoMapper.integration_name
54
+ end
55
+
56
+ def test_should_be_available
57
+ assert StateMachine::Integrations::MongoMapper.available?
58
+ end
59
+
52
60
  def test_should_match_if_class_includes_mongo_mapper
53
61
  assert StateMachine::Integrations::MongoMapper.matches?(new_model)
54
62
  end
@@ -60,6 +68,10 @@ module MongoMapperTest
60
68
  def test_should_have_defaults
61
69
  assert_equal e = {:action => :save}, StateMachine::Integrations::MongoMapper.defaults
62
70
  end
71
+
72
+ def test_should_have_a_locale_path
73
+ assert_not_nil StateMachine::Integrations::MongoMapper.locale_path
74
+ end
63
75
  end
64
76
 
65
77
  class MachineWithoutDatabaseTest < BaseTestCase
@@ -40,6 +40,14 @@ module MongoidTest
40
40
  end
41
41
 
42
42
  class IntegrationTest < BaseTestCase
43
+ def test_should_have_an_integration_name
44
+ assert_equal :mongoid, StateMachine::Integrations::Mongoid.integration_name
45
+ end
46
+
47
+ def test_should_be_available
48
+ assert StateMachine::Integrations::Mongoid.available?
49
+ end
50
+
43
51
  def test_should_match_if_class_includes_mongoid
44
52
  assert StateMachine::Integrations::Mongoid.matches?(new_model)
45
53
  end
@@ -51,6 +59,10 @@ module MongoidTest
51
59
  def test_should_have_defaults
52
60
  assert_equal e = {:action => :save}, StateMachine::Integrations::Mongoid.defaults
53
61
  end
62
+
63
+ def test_should_have_a_locale_path
64
+ assert_not_nil StateMachine::Integrations::Mongoid.locale_path
65
+ end
54
66
  end
55
67
 
56
68
  class MachineByDefaultTest < BaseTestCase
@@ -38,6 +38,14 @@ module SequelTest
38
38
  end
39
39
 
40
40
  class IntegrationTest < BaseTestCase
41
+ def test_should_have_an_integration_name
42
+ assert_equal :sequel, StateMachine::Integrations::Sequel.integration_name
43
+ end
44
+
45
+ def test_should_be_available
46
+ assert StateMachine::Integrations::Sequel.available?
47
+ end
48
+
41
49
  def test_should_match_if_class_inherits_from_sequel
42
50
  assert StateMachine::Integrations::Sequel.matches?(new_model)
43
51
  end
@@ -49,6 +57,10 @@ module SequelTest
49
57
  def test_should_have_defaults
50
58
  assert_equal e = {:action => :save}, StateMachine::Integrations::Sequel.defaults
51
59
  end
60
+
61
+ def test_should_not_have_a_locale_path
62
+ assert_nil StateMachine::Integrations::Sequel.locale_path
63
+ end
52
64
  end
53
65
 
54
66
  class MachineWithoutDatabaseTest < BaseTestCase
@@ -11,6 +11,12 @@ class IntegrationMatcherTest < Test::Unit::TestCase
11
11
 
12
12
  def test_should_return_integration_class_if_match_found
13
13
  integration = Module.new do
14
+ include StateMachine::Integrations::Base
15
+
16
+ def self.available?
17
+ true
18
+ end
19
+
14
20
  def self.matches?(klass)
15
21
  true
16
22
  end
@@ -25,30 +31,31 @@ end
25
31
 
26
32
  class IntegrationFinderTest < Test::Unit::TestCase
27
33
  def test_should_find_base
28
- assert_equal StateMachine::Integrations::Base, StateMachine::Integrations.find(:base)
34
+ assert_equal StateMachine::Integrations::Base, StateMachine::Integrations.find_by_name(:base)
29
35
  end
30
36
 
31
37
  def test_should_find_active_model
32
- assert_equal StateMachine::Integrations::ActiveModel, StateMachine::Integrations.find(:active_model)
38
+ assert_equal StateMachine::Integrations::ActiveModel, StateMachine::Integrations.find_by_name(:active_model)
33
39
  end
34
40
 
35
41
  def test_should_find_active_record
36
- assert_equal StateMachine::Integrations::ActiveRecord, StateMachine::Integrations.find(:active_record)
42
+ assert_equal StateMachine::Integrations::ActiveRecord, StateMachine::Integrations.find_by_name(:active_record)
37
43
  end
38
44
 
39
45
  def test_should_find_data_mapper
40
- assert_equal StateMachine::Integrations::DataMapper, StateMachine::Integrations.find(:data_mapper)
46
+ assert_equal StateMachine::Integrations::DataMapper, StateMachine::Integrations.find_by_name(:data_mapper)
41
47
  end
42
48
 
43
49
  def test_should_find_mongo_mapper
44
- assert_equal StateMachine::Integrations::MongoMapper, StateMachine::Integrations.find(:mongo_mapper)
50
+ assert_equal StateMachine::Integrations::MongoMapper, StateMachine::Integrations.find_by_name(:mongo_mapper)
45
51
  end
46
52
 
47
53
  def test_should_find_sequel
48
- assert_equal StateMachine::Integrations::Sequel, StateMachine::Integrations.find(:sequel)
54
+ assert_equal StateMachine::Integrations::Sequel, StateMachine::Integrations.find_by_name(:sequel)
49
55
  end
50
56
 
51
57
  def test_should_raise_an_exception_if_invalid
52
- assert_raise(NameError) { StateMachine::Integrations.find(:invalid) }
58
+ exception = assert_raise(StateMachine::IntegrationNotFound) { StateMachine::Integrations.find_by_name(:invalid) }
59
+ assert_equal ':invalid is an invalid integration', exception.message
53
60
  end
54
61
  end
@@ -499,6 +499,10 @@ class MachineWithCustomIntegrationTest < Test::Unit::TestCase
499
499
  integration = Module.new do
500
500
  include StateMachine::Integrations::Base
501
501
 
502
+ def self.available?
503
+ true
504
+ end
505
+
502
506
  def self.matches?(klass)
503
507
  true
504
508
  end
@@ -511,8 +515,30 @@ class MachineWithCustomIntegrationTest < Test::Unit::TestCase
511
515
  machine = StateMachine::Machine.new(Class.new, :integration => :custom)
512
516
  assert (class << machine; ancestors; end).include?(StateMachine::Integrations::Custom)
513
517
  end
518
+
519
+ def test_should_not_be_extended_by_the_integration_if_implicit_but_not_available
520
+ StateMachine::Integrations::Custom.class_eval do
521
+ def self.available?
522
+ false
523
+ end
524
+ end
525
+
526
+ machine = StateMachine::Machine.new(Class.new)
527
+ assert !(class << machine; ancestors; end).include?(StateMachine::Integrations::Custom)
528
+ end
529
+
530
+ def test_should_not_be_extended_by_the_integration_if_implicit_but_not_matched
531
+ StateMachine::Integrations::Custom.class_eval do
532
+ def self.matches?(klass)
533
+ false
534
+ end
535
+ end
536
+
537
+ machine = StateMachine::Machine.new(Class.new)
538
+ assert !(class << machine; ancestors; end).include?(StateMachine::Integrations::Custom)
539
+ end
514
540
 
515
- def test_should_be_extended_by_the_integration_if_implicit
541
+ def test_should_be_extended_by_the_integration_if_implicit_and_available_and_matches
516
542
  machine = StateMachine::Machine.new(Class.new)
517
543
  assert (class << machine; ancestors; end).include?(StateMachine::Integrations::Custom)
518
544
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: state_machine
3
3
  version: !ruby/object:Gem::Version
4
- hash: 49
5
- prerelease:
4
+ hash: 63
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 10
9
- - 3
10
- version: 0.10.3
9
+ - 4
10
+ version: 0.10.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Aaron Pfeifer
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-07 00:00:00 -04:00
18
+ date: 2011-04-14 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -165,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
165
  requirements: []
166
166
 
167
167
  rubyforge_project: pluginaweek
168
- rubygems_version: 1.6.2
168
+ rubygems_version: 1.3.7
169
169
  signing_key:
170
170
  specification_version: 3
171
171
  summary: Adds support for creating state machines for attributes on any Ruby class