pluginaweek-state_machine 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG.rdoc +273 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +466 -0
  4. data/Rakefile +98 -0
  5. data/examples/AutoShop_state.png +0 -0
  6. data/examples/Car_state.png +0 -0
  7. data/examples/TrafficLight_state.png +0 -0
  8. data/examples/Vehicle_state.png +0 -0
  9. data/examples/auto_shop.rb +11 -0
  10. data/examples/car.rb +19 -0
  11. data/examples/merb-rest/controller.rb +51 -0
  12. data/examples/merb-rest/model.rb +28 -0
  13. data/examples/merb-rest/view_edit.html.erb +24 -0
  14. data/examples/merb-rest/view_index.html.erb +23 -0
  15. data/examples/merb-rest/view_new.html.erb +13 -0
  16. data/examples/merb-rest/view_show.html.erb +17 -0
  17. data/examples/rails-rest/controller.rb +43 -0
  18. data/examples/rails-rest/migration.rb +11 -0
  19. data/examples/rails-rest/model.rb +23 -0
  20. data/examples/rails-rest/view_edit.html.erb +25 -0
  21. data/examples/rails-rest/view_index.html.erb +23 -0
  22. data/examples/rails-rest/view_new.html.erb +14 -0
  23. data/examples/rails-rest/view_show.html.erb +17 -0
  24. data/examples/traffic_light.rb +7 -0
  25. data/examples/vehicle.rb +31 -0
  26. data/init.rb +1 -0
  27. data/lib/state_machine.rb +429 -0
  28. data/lib/state_machine/assertions.rb +36 -0
  29. data/lib/state_machine/callback.rb +189 -0
  30. data/lib/state_machine/condition_proxy.rb +94 -0
  31. data/lib/state_machine/eval_helpers.rb +67 -0
  32. data/lib/state_machine/event.rb +251 -0
  33. data/lib/state_machine/event_collection.rb +113 -0
  34. data/lib/state_machine/extensions.rb +158 -0
  35. data/lib/state_machine/guard.rb +219 -0
  36. data/lib/state_machine/integrations.rb +68 -0
  37. data/lib/state_machine/integrations/active_record.rb +444 -0
  38. data/lib/state_machine/integrations/active_record/locale.rb +10 -0
  39. data/lib/state_machine/integrations/active_record/observer.rb +41 -0
  40. data/lib/state_machine/integrations/data_mapper.rb +325 -0
  41. data/lib/state_machine/integrations/data_mapper/observer.rb +139 -0
  42. data/lib/state_machine/integrations/sequel.rb +292 -0
  43. data/lib/state_machine/machine.rb +1431 -0
  44. data/lib/state_machine/machine_collection.rb +146 -0
  45. data/lib/state_machine/matcher.rb +123 -0
  46. data/lib/state_machine/matcher_helpers.rb +54 -0
  47. data/lib/state_machine/node_collection.rb +152 -0
  48. data/lib/state_machine/state.rb +249 -0
  49. data/lib/state_machine/state_collection.rb +112 -0
  50. data/lib/state_machine/transition.rb +367 -0
  51. data/tasks/state_machine.rake +1 -0
  52. data/tasks/state_machine.rb +30 -0
  53. data/test/classes/switch.rb +11 -0
  54. data/test/functional/state_machine_test.rb +941 -0
  55. data/test/test_helper.rb +4 -0
  56. data/test/unit/assertions_test.rb +40 -0
  57. data/test/unit/callback_test.rb +455 -0
  58. data/test/unit/condition_proxy_test.rb +328 -0
  59. data/test/unit/eval_helpers_test.rb +129 -0
  60. data/test/unit/event_collection_test.rb +293 -0
  61. data/test/unit/event_test.rb +605 -0
  62. data/test/unit/guard_test.rb +862 -0
  63. data/test/unit/integrations/active_record_test.rb +1001 -0
  64. data/test/unit/integrations/data_mapper_test.rb +694 -0
  65. data/test/unit/integrations/sequel_test.rb +486 -0
  66. data/test/unit/integrations_test.rb +42 -0
  67. data/test/unit/invalid_event_test.rb +7 -0
  68. data/test/unit/invalid_transition_test.rb +7 -0
  69. data/test/unit/machine_collection_test.rb +710 -0
  70. data/test/unit/machine_test.rb +1910 -0
  71. data/test/unit/matcher_helpers_test.rb +37 -0
  72. data/test/unit/matcher_test.rb +155 -0
  73. data/test/unit/node_collection_test.rb +207 -0
  74. data/test/unit/state_collection_test.rb +280 -0
  75. data/test/unit/state_machine_test.rb +31 -0
  76. data/test/unit/state_test.rb +795 -0
  77. data/test/unit/transition_test.rb +1113 -0
  78. metadata +161 -0
@@ -0,0 +1,98 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/contrib/sshpublisher'
5
+
6
+ spec = Gem::Specification.new do |s|
7
+ s.name = 'state_machine'
8
+ s.version = '0.7.5'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'Adds support for creating state machines for attributes on any Ruby class'
11
+ s.description = s.summary
12
+
13
+ s.files = FileList['{examples,lib,tasks,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/*.log']
14
+ s.require_path = 'lib'
15
+ s.has_rdoc = true
16
+ s.test_files = Dir['test/**/*_test.rb']
17
+
18
+ s.author = 'Aaron Pfeifer'
19
+ s.email = 'aaron@pluginaweek.org'
20
+ s.homepage = 'http://www.pluginaweek.org'
21
+ s.rubyforge_project = 'pluginaweek'
22
+ end
23
+
24
+ desc 'Default: run all tests.'
25
+ task :default => :test
26
+
27
+ desc "Test the #{spec.name} plugin."
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.libs << 'lib'
30
+ t.test_files = spec.test_files
31
+ t.verbose = true
32
+ end
33
+
34
+ begin
35
+ require 'rcov/rcovtask'
36
+ namespace :test do
37
+ desc "Test the #{spec.name} plugin with Rcov."
38
+ Rcov::RcovTask.new(:rcov) do |t|
39
+ t.libs << 'lib'
40
+ t.test_files = spec.test_files
41
+ t.rcov_opts << '--exclude="^(?!lib/)"'
42
+ t.verbose = true
43
+ end
44
+ end
45
+ rescue LoadError
46
+ end
47
+
48
+ desc "Generate documentation for the #{spec.name} plugin."
49
+ Rake::RDocTask.new(:rdoc) do |rdoc|
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = spec.name
52
+ rdoc.template = '../rdoc_template.rb'
53
+ rdoc.options << '--line-numbers' << '--inline-source'
54
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
55
+ end
56
+
57
+ desc 'Generate a gemspec file.'
58
+ task :gemspec do
59
+ File.open("#{spec.name}.gemspec", 'w') do |f|
60
+ f.write spec.to_ruby
61
+ end
62
+ end
63
+
64
+ Rake::GemPackageTask.new(spec) do |p|
65
+ p.gem_spec = spec
66
+ p.need_tar = true
67
+ p.need_zip = true
68
+ end
69
+
70
+ desc 'Publish the beta gem.'
71
+ task :pgem => [:package] do
72
+ Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload
73
+ end
74
+
75
+ desc 'Publish the API documentation.'
76
+ task :pdoc => [:rdoc] do
77
+ Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload
78
+ end
79
+
80
+ desc 'Publish the API docs and gem'
81
+ task :publish => [:pgem, :pdoc, :release]
82
+
83
+ desc 'Publish the release files to RubyForge.'
84
+ task :release => [:gem, :package] do
85
+ require 'rubyforge'
86
+
87
+ ruby_forge = RubyForge.new.configure
88
+ ruby_forge.login
89
+
90
+ %w(gem tgz zip).each do |ext|
91
+ file = "pkg/#{spec.name}-#{spec.version}.#{ext}"
92
+ puts "Releasing #{File.basename(file)}..."
93
+
94
+ ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
95
+ end
96
+ end
97
+
98
+ Dir['tasks/**/*.rake'].each {|rake| load rake}
Binary file
@@ -0,0 +1,11 @@
1
+ class AutoShop
2
+ state_machine :initial => :available do
3
+ event :tow_vehicle do
4
+ transition :available => :busy
5
+ end
6
+
7
+ event :fix_vehicle do
8
+ transition :busy => :available
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ class Car < Vehicle
2
+ state_machine do
3
+ event :reverse do
4
+ transition [:parked, :idling, :first_gear] => :backing_up
5
+ end
6
+
7
+ event :park do
8
+ transition :backing_up => :parked
9
+ end
10
+
11
+ event :idle do
12
+ transition :backing_up => :idling
13
+ end
14
+
15
+ event :shift_up do
16
+ transition :backing_up => :first_gear
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,51 @@
1
+ class Users < Application
2
+ # GET /users
3
+ def index
4
+ @users = User.all
5
+ display @users
6
+ end
7
+
8
+ # GET /users/1
9
+ def show(id)
10
+ @user = User.get(id)
11
+ raise NotFound unless @user
12
+ display @user
13
+ end
14
+
15
+ # GET /users/new
16
+ def new
17
+ only_provides :html
18
+ @user = User.new
19
+ display @user
20
+ end
21
+
22
+ # GET /users/1/edit
23
+ def edit(id)
24
+ only_provides :html
25
+ @user = User.get(id)
26
+ raise NotFound unless @user
27
+ display @user
28
+ end
29
+
30
+ # POST /users
31
+ def create(user)
32
+ @user = User.new(user)
33
+ if @user.save
34
+ redirect resource(@user), :message => {:notice => "User was successfully created"}
35
+ else
36
+ message[:error] = "User failed to be created"
37
+ render :new
38
+ end
39
+ end
40
+
41
+ # PUT /users/1
42
+ def update(id, user)
43
+ @user = User.get(id)
44
+ raise NotFound unless @user
45
+ if @user.update_attributes(user)
46
+ redirect resource(@user)
47
+ else
48
+ display @user, :edit
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,28 @@
1
+ class User
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :name, String
6
+
7
+ validates_present :name, :state, :access_state
8
+
9
+ state_machine :initial => :unregistered do
10
+ event :register do
11
+ transition :unregistered => :registered
12
+ end
13
+
14
+ event :unregister do
15
+ transition :registered => :unregistered
16
+ end
17
+ end
18
+
19
+ state_machine :access_state, :initial => :enabled do
20
+ event :enable do
21
+ transition all => :enabled
22
+ end
23
+
24
+ event :disable do
25
+ transition all => :disabled
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ <h1>Editing User</h1>
2
+
3
+ <%= form_for @user, :action => resource(@user) do %>
4
+ <%= error_messages %>
5
+
6
+ <p>
7
+ <%= text_field :name, :label => 'Name' %>
8
+ </p>
9
+
10
+ <p>
11
+ <%= label :state %><br />
12
+ <%= select :state_event, :selected => @user.state_event.to_s, :collection => @user.state_transitions, :value_method => :event, :text_method => :to_name, :prompt => @user.state_name.to_s %>
13
+ </p>
14
+
15
+ <p>
16
+ <%= label :access_state %><br />
17
+ <%= select :access_state_event, :selected => @user.access_state_event.to_s, :collection => @user.access_state_transitions, :value_method => :event, :text_method => :event, :prompt => "don't change" %>
18
+ </p>
19
+
20
+ <p><%= submit 'Update' %></p>
21
+ <% end =%>
22
+
23
+ <%= link_to 'Show', resource(@user) %> |
24
+ <%= link_to 'Back', resource(:users) %>
@@ -0,0 +1,23 @@
1
+ <h1>Listing Users</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ <th>State</th>
7
+ <th>Access State</th>
8
+ </tr>
9
+
10
+ <% @users.each do |user| %>
11
+ <tr>
12
+ <td><%=h user.name %></td>
13
+ <td><%=h user.state %></td>
14
+ <td><%=h user.access_state %></td>
15
+ <td><%= link_to 'Show', resource(user) %></td>
16
+ <td><%= link_to 'Edit', resource(user, :edit) %></td>
17
+ </tr>
18
+ <% end %>
19
+ </table>
20
+
21
+ <br />
22
+
23
+ <%= link_to 'New User', resource(:users, :new) %>
@@ -0,0 +1,13 @@
1
+ <h1>New User</h1>
2
+
3
+ <%= form_for @user, :action => resource(:users) do %>
4
+ <%= error_messages %>
5
+
6
+ <p>
7
+ <%= text_field :name, :label => 'Name' %>
8
+ </p>
9
+
10
+ <p><%= submit 'Create' %></p>
11
+ <% end =%>
12
+
13
+ <%= link_to 'Back', resource(:users) %>
@@ -0,0 +1,17 @@
1
+ <p>
2
+ <b>Name:</b>
3
+ <%=h @user.name %>
4
+ </p>
5
+
6
+ <p>
7
+ <b>State:</b>
8
+ <%=h @user.state %>
9
+ </p>
10
+
11
+ <p>
12
+ <b>Access State:</b>
13
+ <%=h @user.access_state %>
14
+ </p>
15
+
16
+ <%= link_to 'Edit', resource(@user, :edit) %> |
17
+ <%= link_to 'Back', resource(:users) %>
@@ -0,0 +1,43 @@
1
+ class UsersController < ApplicationController
2
+ # GET /users
3
+ def index
4
+ @users = User.all
5
+ end
6
+
7
+ # GET /users/1
8
+ def show
9
+ @user = User.find(params[:id])
10
+ end
11
+
12
+ # GET /users/new
13
+ def new
14
+ @user = User.new
15
+ end
16
+
17
+ # GET /users/1/edit
18
+ def edit
19
+ @user = User.find(params[:id])
20
+ end
21
+
22
+ # POST /users
23
+ def create
24
+ @user = User.new(params[:user])
25
+
26
+ if @user.save
27
+ redirect_to(@user)
28
+ else
29
+ render :action => 'new'
30
+ end
31
+ end
32
+
33
+ # PUT /users/1
34
+ def update
35
+ @user = User.find(params[:id])
36
+
37
+ if @user.update_attributes(params[:user])
38
+ redirect_to(@user)
39
+ else
40
+ render :action => 'edit'
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :name, :state, :access_state
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :users
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ class User < ActiveRecord::Base
2
+ validates_presence_of :name, :state, :access_state
3
+
4
+ state_machine :initial => :unregistered do
5
+ event :register do
6
+ transition :unregistered => :registered
7
+ end
8
+
9
+ event :unregister do
10
+ transition :registered => :unregistered
11
+ end
12
+ end
13
+
14
+ state_machine :access_state, :initial => :enabled do
15
+ event :enable do
16
+ transition all => :enabled
17
+ end
18
+
19
+ event :disable do
20
+ transition all => :disabled
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ <h1>Editing User</h1>
2
+
3
+ <% form_for(@user) do |f| %>
4
+ <%= f.error_messages %>
5
+
6
+ <p>
7
+ <%= f.label :name %><br />
8
+ <%= f.text_field :name %>
9
+ </p>
10
+
11
+ <p>
12
+ <%= f.label :state %><br />
13
+ <%= f.collection_select :state_event, @user.state_transitions, :event, :to_name, :include_blank => @user.state_name.to_s %>
14
+ </p>
15
+
16
+ <p>
17
+ <%= f.label :access_state %><br />
18
+ <%= f.collection_select :access_state_event, @user.access_state_transitions, :event, :event, :include_blank => "don't change" %>
19
+ </p>
20
+
21
+ <p><%= f.submit 'Update' %></p>
22
+ <% end %>
23
+
24
+ <%= link_to 'Show', @user %> |
25
+ <%= link_to 'Back', users_path %>
@@ -0,0 +1,23 @@
1
+ <h1>Listing Users</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ <th>State</th>
7
+ <th>Access State</th>
8
+ </tr>
9
+
10
+ <% @users.each do |user| %>
11
+ <tr>
12
+ <td><%=h user.name %></td>
13
+ <td><%=h user.state %></td>
14
+ <td><%=h user.access_state %></td>
15
+ <td><%= link_to 'Show', user %></td>
16
+ <td><%= link_to 'Edit', edit_user_path(user) %></td>
17
+ </tr>
18
+ <% end %>
19
+ </table>
20
+
21
+ <br />
22
+
23
+ <%= link_to 'New User', new_user_path %>
@@ -0,0 +1,14 @@
1
+ <h1>New User</h1>
2
+
3
+ <% form_for @user do |f| %>
4
+ <%= f.error_messages %>
5
+
6
+ <p>
7
+ <%= f.label :name %><br />
8
+ <%= f.text_field :name %>
9
+ </p>
10
+
11
+ <p><%= f.submit 'Create' %></p>
12
+ <% end %>
13
+
14
+ <%= link_to 'Back', users_path %>