spree-state_machine 2.0.0.beta1

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 (140) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +12 -0
  4. data/.yardopts +5 -0
  5. data/CHANGELOG.md +502 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +20 -0
  8. data/README.md +1246 -0
  9. data/Rakefile +20 -0
  10. data/examples/AutoShop_state.png +0 -0
  11. data/examples/Car_state.png +0 -0
  12. data/examples/Gemfile +5 -0
  13. data/examples/Gemfile.lock +14 -0
  14. data/examples/TrafficLight_state.png +0 -0
  15. data/examples/Vehicle_state.png +0 -0
  16. data/examples/auto_shop.rb +13 -0
  17. data/examples/car.rb +21 -0
  18. data/examples/doc/AutoShop.html +2856 -0
  19. data/examples/doc/AutoShop_state.png +0 -0
  20. data/examples/doc/Car.html +919 -0
  21. data/examples/doc/Car_state.png +0 -0
  22. data/examples/doc/TrafficLight.html +2230 -0
  23. data/examples/doc/TrafficLight_state.png +0 -0
  24. data/examples/doc/Vehicle.html +7921 -0
  25. data/examples/doc/Vehicle_state.png +0 -0
  26. data/examples/doc/_index.html +136 -0
  27. data/examples/doc/class_list.html +47 -0
  28. data/examples/doc/css/common.css +1 -0
  29. data/examples/doc/css/full_list.css +55 -0
  30. data/examples/doc/css/style.css +322 -0
  31. data/examples/doc/file_list.html +46 -0
  32. data/examples/doc/frames.html +13 -0
  33. data/examples/doc/index.html +136 -0
  34. data/examples/doc/js/app.js +205 -0
  35. data/examples/doc/js/full_list.js +173 -0
  36. data/examples/doc/js/jquery.js +16 -0
  37. data/examples/doc/method_list.html +734 -0
  38. data/examples/doc/top-level-namespace.html +105 -0
  39. data/examples/merb-rest/controller.rb +51 -0
  40. data/examples/merb-rest/model.rb +28 -0
  41. data/examples/merb-rest/view_edit.html.erb +24 -0
  42. data/examples/merb-rest/view_index.html.erb +23 -0
  43. data/examples/merb-rest/view_new.html.erb +13 -0
  44. data/examples/merb-rest/view_show.html.erb +17 -0
  45. data/examples/rails-rest/controller.rb +43 -0
  46. data/examples/rails-rest/migration.rb +7 -0
  47. data/examples/rails-rest/model.rb +23 -0
  48. data/examples/rails-rest/view__form.html.erb +34 -0
  49. data/examples/rails-rest/view_edit.html.erb +6 -0
  50. data/examples/rails-rest/view_index.html.erb +25 -0
  51. data/examples/rails-rest/view_new.html.erb +5 -0
  52. data/examples/rails-rest/view_show.html.erb +19 -0
  53. data/examples/traffic_light.rb +9 -0
  54. data/examples/vehicle.rb +33 -0
  55. data/lib/state_machine/assertions.rb +36 -0
  56. data/lib/state_machine/branch.rb +225 -0
  57. data/lib/state_machine/callback.rb +236 -0
  58. data/lib/state_machine/core.rb +7 -0
  59. data/lib/state_machine/core_ext/class/state_machine.rb +5 -0
  60. data/lib/state_machine/core_ext.rb +2 -0
  61. data/lib/state_machine/error.rb +13 -0
  62. data/lib/state_machine/eval_helpers.rb +87 -0
  63. data/lib/state_machine/event.rb +257 -0
  64. data/lib/state_machine/event_collection.rb +141 -0
  65. data/lib/state_machine/extensions.rb +149 -0
  66. data/lib/state_machine/graph.rb +92 -0
  67. data/lib/state_machine/helper_module.rb +17 -0
  68. data/lib/state_machine/initializers/rails.rb +25 -0
  69. data/lib/state_machine/initializers.rb +4 -0
  70. data/lib/state_machine/integrations/active_model/locale.rb +11 -0
  71. data/lib/state_machine/integrations/active_model/observer.rb +33 -0
  72. data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
  73. data/lib/state_machine/integrations/active_model/versions.rb +31 -0
  74. data/lib/state_machine/integrations/active_model.rb +585 -0
  75. data/lib/state_machine/integrations/active_record/locale.rb +20 -0
  76. data/lib/state_machine/integrations/active_record/versions.rb +123 -0
  77. data/lib/state_machine/integrations/active_record.rb +525 -0
  78. data/lib/state_machine/integrations/base.rb +100 -0
  79. data/lib/state_machine/integrations.rb +121 -0
  80. data/lib/state_machine/machine.rb +2287 -0
  81. data/lib/state_machine/machine_collection.rb +74 -0
  82. data/lib/state_machine/macro_methods.rb +522 -0
  83. data/lib/state_machine/matcher.rb +123 -0
  84. data/lib/state_machine/matcher_helpers.rb +54 -0
  85. data/lib/state_machine/node_collection.rb +222 -0
  86. data/lib/state_machine/path.rb +120 -0
  87. data/lib/state_machine/path_collection.rb +90 -0
  88. data/lib/state_machine/state.rb +297 -0
  89. data/lib/state_machine/state_collection.rb +112 -0
  90. data/lib/state_machine/state_context.rb +138 -0
  91. data/lib/state_machine/transition.rb +470 -0
  92. data/lib/state_machine/transition_collection.rb +245 -0
  93. data/lib/state_machine/version.rb +3 -0
  94. data/lib/state_machine/yard/handlers/base.rb +32 -0
  95. data/lib/state_machine/yard/handlers/event.rb +25 -0
  96. data/lib/state_machine/yard/handlers/machine.rb +344 -0
  97. data/lib/state_machine/yard/handlers/state.rb +25 -0
  98. data/lib/state_machine/yard/handlers/transition.rb +47 -0
  99. data/lib/state_machine/yard/handlers.rb +12 -0
  100. data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
  101. data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
  102. data/lib/state_machine/yard/templates.rb +3 -0
  103. data/lib/state_machine/yard.rb +8 -0
  104. data/lib/state_machine.rb +8 -0
  105. data/lib/yard-state_machine.rb +2 -0
  106. data/state_machine.gemspec +22 -0
  107. data/test/files/en.yml +17 -0
  108. data/test/files/switch.rb +15 -0
  109. data/test/functional/state_machine_test.rb +1066 -0
  110. data/test/test_helper.rb +7 -0
  111. data/test/unit/assertions_test.rb +40 -0
  112. data/test/unit/branch_test.rb +969 -0
  113. data/test/unit/callback_test.rb +704 -0
  114. data/test/unit/error_test.rb +43 -0
  115. data/test/unit/eval_helpers_test.rb +270 -0
  116. data/test/unit/event_collection_test.rb +398 -0
  117. data/test/unit/event_test.rb +1196 -0
  118. data/test/unit/graph_test.rb +98 -0
  119. data/test/unit/helper_module_test.rb +17 -0
  120. data/test/unit/integrations/active_model_test.rb +1245 -0
  121. data/test/unit/integrations/active_record_test.rb +2551 -0
  122. data/test/unit/integrations/base_test.rb +104 -0
  123. data/test/unit/integrations_test.rb +71 -0
  124. data/test/unit/invalid_event_test.rb +20 -0
  125. data/test/unit/invalid_parallel_transition_test.rb +18 -0
  126. data/test/unit/invalid_transition_test.rb +115 -0
  127. data/test/unit/machine_collection_test.rb +603 -0
  128. data/test/unit/machine_test.rb +3395 -0
  129. data/test/unit/matcher_helpers_test.rb +37 -0
  130. data/test/unit/matcher_test.rb +155 -0
  131. data/test/unit/node_collection_test.rb +362 -0
  132. data/test/unit/path_collection_test.rb +266 -0
  133. data/test/unit/path_test.rb +485 -0
  134. data/test/unit/state_collection_test.rb +352 -0
  135. data/test/unit/state_context_test.rb +441 -0
  136. data/test/unit/state_machine_test.rb +31 -0
  137. data/test/unit/state_test.rb +1101 -0
  138. data/test/unit/transition_collection_test.rb +2168 -0
  139. data/test/unit/transition_test.rb +1558 -0
  140. metadata +264 -0
@@ -0,0 +1,104 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+
3
+ # Load library
4
+ require 'rubygems'
5
+
6
+ module BaseTest
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
+
16
+ def test_should_not_have_any_matching_ancestors
17
+ assert_equal [], StateMachine::Integrations::Base.matching_ancestors
18
+ end
19
+
20
+ def test_should_not_match_any_classes
21
+ assert !StateMachine::Integrations::Base.matches?(Class.new)
22
+ end
23
+
24
+ def test_should_not_have_a_locale_path
25
+ assert_nil StateMachine::Integrations::Base.locale_path
26
+ end
27
+ end
28
+
29
+ class IncludedTest < Test::Unit::TestCase
30
+ def setup
31
+ @integration = Module.new
32
+ StateMachine::Integrations.const_set('Custom', @integration)
33
+
34
+ @integration.class_eval do
35
+ include StateMachine::Integrations::Base
36
+ end
37
+ end
38
+
39
+ def test_should_not_have_any_defaults
40
+ assert_nil @integration.defaults
41
+ end
42
+
43
+ def test_should_not_have_any_versions
44
+ assert_equal [], @integration.versions
45
+ end
46
+
47
+ def test_should_track_version
48
+ version1 = @integration.version '1.0' do
49
+ def self.active?
50
+ true
51
+ end
52
+ end
53
+
54
+ version2 = @integration.version '2.0' do
55
+ def self.active?
56
+ false
57
+ end
58
+ end
59
+
60
+ assert_equal [version1, version2], @integration.versions
61
+ end
62
+
63
+ def test_should_allow_active_versions_to_override_default_behavior
64
+ @integration.class_eval do
65
+ def version1_included?
66
+ false
67
+ end
68
+
69
+ def version2_included?
70
+ false
71
+ end
72
+ end
73
+
74
+ @integration.version '1.0' do
75
+ def self.active?
76
+ true
77
+ end
78
+
79
+ def version1_included?
80
+ true
81
+ end
82
+ end
83
+
84
+ @integration.version '2.0' do
85
+ def self.active?
86
+ false
87
+ end
88
+
89
+ def version2_included?
90
+ true
91
+ end
92
+ end
93
+
94
+ @machine = StateMachine::Machine.new(Class.new, :integration => :custom)
95
+ assert @machine.version1_included?
96
+ assert !@machine.version2_included?
97
+ end
98
+
99
+ def teardown
100
+ StateMachine::Integrations.send(:remove_const, 'Custom')
101
+ super
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class IntegrationMatcherTest < Test::Unit::TestCase
4
+ def setup
5
+ superclass = Class.new
6
+ self.class.const_set('Vehicle', superclass)
7
+
8
+ @klass = Class.new(superclass)
9
+ end
10
+
11
+ def test_should_return_nil_if_no_match_found
12
+ assert_nil StateMachine::Integrations.match(@klass)
13
+ end
14
+
15
+ def test_should_return_integration_class_if_match_found
16
+ integration = Module.new do
17
+ include StateMachine::Integrations::Base
18
+
19
+ def self.matching_ancestors
20
+ ['IntegrationMatcherTest::Vehicle']
21
+ end
22
+ end
23
+ StateMachine::Integrations.const_set('Custom', integration)
24
+
25
+ assert_equal integration, StateMachine::Integrations.match(@klass)
26
+ ensure
27
+ StateMachine::Integrations.send(:remove_const, 'Custom')
28
+ end
29
+
30
+ def test_should_return_nil_if_no_match_found_with_ancestors
31
+ assert_nil StateMachine::Integrations.match_ancestors(['IntegrationMatcherTest::Fake'])
32
+ end
33
+
34
+ def test_should_return_integration_class_if_match_found_with_ancestors
35
+ integration = Module.new do
36
+ include StateMachine::Integrations::Base
37
+
38
+ def self.matching_ancestors
39
+ ['IntegrationMatcherTest::Vehicle']
40
+ end
41
+ end
42
+ StateMachine::Integrations.const_set('Custom', integration)
43
+
44
+ assert_equal integration, StateMachine::Integrations.match_ancestors(['IntegrationMatcherTest::Fake', 'IntegrationMatcherTest::Vehicle'])
45
+ ensure
46
+ StateMachine::Integrations.send(:remove_const, 'Custom')
47
+ end
48
+
49
+ def teardown
50
+ self.class.send(:remove_const, 'Vehicle')
51
+ end
52
+ end
53
+
54
+ class IntegrationFinderTest < Test::Unit::TestCase
55
+ def test_should_find_base
56
+ assert_equal StateMachine::Integrations::Base, StateMachine::Integrations.find_by_name(:base)
57
+ end
58
+
59
+ def test_should_find_active_model
60
+ assert_equal StateMachine::Integrations::ActiveModel, StateMachine::Integrations.find_by_name(:active_model)
61
+ end
62
+
63
+ def test_should_find_active_record
64
+ assert_equal StateMachine::Integrations::ActiveRecord, StateMachine::Integrations.find_by_name(:active_record)
65
+ end
66
+
67
+ def test_should_raise_an_exception_if_invalid
68
+ exception = assert_raise(StateMachine::IntegrationNotFound) { StateMachine::Integrations.find_by_name(:invalid) }
69
+ assert_equal ':invalid is an invalid integration', exception.message
70
+ end
71
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class InvalidEventTest < Test::Unit::TestCase
4
+ def setup
5
+ @object = Object.new
6
+ @invalid_event = StateMachine::InvalidEvent.new(@object, :invalid)
7
+ end
8
+
9
+ def test_should_have_an_object
10
+ assert_equal @object, @invalid_event.object
11
+ end
12
+
13
+ def test_should_have_an_event
14
+ assert_equal :invalid, @invalid_event.event
15
+ end
16
+
17
+ def test_should_generate_a_message
18
+ assert_equal ':invalid is an unknown state machine event', @invalid_event.message
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class InvalidParallelTransitionTest < Test::Unit::TestCase
4
+ def setup
5
+ @object = Object.new
6
+ @events = [:ignite, :disable_alarm]
7
+
8
+ @invalid_transition = StateMachine::InvalidParallelTransition.new(@object, @events)
9
+ end
10
+
11
+ def test_should_have_an_object
12
+ assert_equal @object, @invalid_transition.object
13
+ end
14
+
15
+ def test_should_have_events
16
+ assert_equal @events, @invalid_transition.events
17
+ end
18
+ end
@@ -0,0 +1,115 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class InvalidTransitionTest < Test::Unit::TestCase
4
+ def setup
5
+ @klass = Class.new
6
+ @machine = StateMachine::Machine.new(@klass)
7
+ @state = @machine.state :parked
8
+ @machine.event :ignite
9
+
10
+ @object = @klass.new
11
+ @object.state = 'parked'
12
+
13
+ @invalid_transition = StateMachine::InvalidTransition.new(@object, @machine, :ignite)
14
+ end
15
+
16
+ def test_should_have_an_object
17
+ assert_equal @object, @invalid_transition.object
18
+ end
19
+
20
+ def test_should_have_a_machine
21
+ assert_equal @machine, @invalid_transition.machine
22
+ end
23
+
24
+ def test_should_have_an_event
25
+ assert_equal :ignite, @invalid_transition.event
26
+ end
27
+
28
+ def test_should_have_a_qualified_event
29
+ assert_equal :ignite, @invalid_transition.qualified_event
30
+ end
31
+
32
+ def test_should_have_a_from_value
33
+ assert_equal 'parked', @invalid_transition.from
34
+ end
35
+
36
+ def test_should_have_a_from_name
37
+ assert_equal :parked, @invalid_transition.from_name
38
+ end
39
+
40
+ def test_should_have_a_qualified_from_name
41
+ assert_equal :parked, @invalid_transition.qualified_from_name
42
+ end
43
+
44
+ def test_should_generate_a_message
45
+ assert_equal 'Cannot transition state via :ignite from :parked', @invalid_transition.message
46
+ end
47
+ end
48
+
49
+ class InvalidTransitionWithNamespaceTest < Test::Unit::TestCase
50
+ def setup
51
+ @klass = Class.new
52
+ @machine = StateMachine::Machine.new(@klass, :namespace => 'alarm')
53
+ @state = @machine.state :active
54
+ @machine.event :disable
55
+
56
+ @object = @klass.new
57
+ @object.state = 'active'
58
+
59
+ @invalid_transition = StateMachine::InvalidTransition.new(@object, @machine, :disable)
60
+ end
61
+
62
+ def test_should_have_an_event
63
+ assert_equal :disable, @invalid_transition.event
64
+ end
65
+
66
+ def test_should_have_a_qualified_event
67
+ assert_equal :disable_alarm, @invalid_transition.qualified_event
68
+ end
69
+
70
+ def test_should_have_a_from_name
71
+ assert_equal :active, @invalid_transition.from_name
72
+ end
73
+
74
+ def test_should_have_a_qualified_from_name
75
+ assert_equal :alarm_active, @invalid_transition.qualified_from_name
76
+ end
77
+ end
78
+
79
+ class InvalidTransitionWithIntegrationTest < Test::Unit::TestCase
80
+ def setup
81
+ StateMachine::Integrations.const_set('Custom', Module.new do
82
+ include StateMachine::Integrations::Base
83
+
84
+ def errors_for(object)
85
+ object.errors
86
+ end
87
+ end)
88
+
89
+ @klass = Class.new do
90
+ attr_accessor :errors
91
+ end
92
+ @machine = StateMachine::Machine.new(@klass, :integration => :custom)
93
+ @machine.state :parked
94
+ @machine.event :ignite
95
+
96
+ @object = @klass.new
97
+ @object.state = 'parked'
98
+ end
99
+
100
+ def test_should_generate_a_message_without_reasons_if_empty
101
+ @object.errors = ''
102
+ invalid_transition = StateMachine::InvalidTransition.new(@object, @machine, :ignite)
103
+ assert_equal 'Cannot transition state via :ignite from :parked', invalid_transition.message
104
+ end
105
+
106
+ def test_should_generate_a_message_with_error_reasons_if_errors_found
107
+ @object.errors = 'Id is invalid, Name is invalid'
108
+ invalid_transition = StateMachine::InvalidTransition.new(@object, @machine, :ignite)
109
+ assert_equal 'Cannot transition state via :ignite from :parked (Reason(s): Id is invalid, Name is invalid)', invalid_transition.message
110
+ end
111
+
112
+ def teardown
113
+ StateMachine::Integrations.send(:remove_const, 'Custom')
114
+ end
115
+ end