aasm 4.0.7 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b5ff962a4061c7b5c90ef8615cc68a91201001c
4
- data.tar.gz: 5f05fb22ab55b5e2101ed50ecd270182ffa16d7d
3
+ metadata.gz: a07996d6cd3f0270a6ec9d010a904cebd462b6a7
4
+ data.tar.gz: 57e8efc5d284371e23c50d41771beb3172787bdd
5
5
  SHA512:
6
- metadata.gz: 9cd75c3602fc6d7f0a432f8a776434f8db864998533f59227de2a617bc1f346bbaa7ef28884b3ecf242e215506d9c1f77f3fbd88c223f8b0631c2d2ea439dfc4
7
- data.tar.gz: 61d2d2b38f233d7241b21a122e748cc6ded58f15475bca1a557febb4523cb288d050f0f5208d1bc3820411dbe6b7959105dfe123c5e441beb49d2379003e452d
6
+ metadata.gz: 0e1f53507bcbcf9deecce7193a5fed9f37ae5fbc91b6325f127820ead35113e19bea7dba6f87af9482affac31462b05e1b6c89a87ef61a47ad93d95c07f19179
7
+ data.tar.gz: 9da9eea4b58047190c441dc42c120fed864c318828340cc61505601f70179736d9cc70a0f60166bae13c6fc6aa3f3c8c4569047915a0af72ab152f30ce5422fd
data/.travis.yml CHANGED
@@ -8,8 +8,9 @@ rvm:
8
8
  - 1.9.3
9
9
  - 2.0.0
10
10
  - 2.1
11
+ - 2.2
11
12
  # - jruby-18mode # JRuby in 1.8 mode
12
- - jruby-19mode # JRuby in 1.9 mode
13
+ - jruby-1.7 # JRuby in 1.9 mode
13
14
  - rbx-2.2.1
14
15
 
15
16
  services: mongodb
@@ -17,12 +18,16 @@ services: mongodb
17
18
  gemfile:
18
19
  - gemfiles/rails_3.2.gemfile
19
20
  - gemfiles/rails_4.0.gemfile
21
+ - gemfiles/rails_4.0_bson1.gemfile
20
22
  - gemfiles/rails_4.1.gemfile
23
+ - gemfiles/rails_4.1_bson1.gemfile
24
+ - gemfiles/rails_4.2.gemfile
25
+ - gemfiles/rails_4.2_bson1.gemfile
21
26
 
22
27
  matrix:
23
28
  allow_failures:
24
29
  - rvm: rbx-2.2.1
25
- - rvm: jruby-19mode
30
+ - rvm: jruby-1.7
26
31
  exclude:
27
32
  - rvm: 1.9.3
28
33
  gemfile: gemfiles/rails_4.1.gemfile
data/CHANGELOG.md CHANGED
@@ -1,10 +1,18 @@
1
1
  # CHANGELOG
2
2
 
3
- ## 4.1.0 (not yet released)
3
+ ## 4.2.0 (not yet released)
4
4
 
5
+ ## 4.1.0
6
+
7
+ * bugfix: initialize the aasm state column after initialization of the _Mongoid_ instance (see [issue #206](https://github.com/aasm/aasm/issues/206), thanks to [@Shwetakale ](https://github.com/Shwetakale ))
8
+ * added support for mongomapper ORM (see [issue #203](https://github.com/aasm/aasm/issues/203), thanks to [@reidmorrison ](https://github.com/reidmorrison ))
5
9
  * `aasm_column` has been removed. Use `aasm.attribute_name` instead
6
10
  * `aasm_human_event_name` has been removed. Use `aasm.human_event_name` instead
7
11
 
12
+ ## 4.0.8
13
+
14
+ * bugfix: may_event_name? should return true or false only (see [issue #200](https://github.com/aasm/aasm/issues/200) for details)
15
+
8
16
  ## 4.0.7
9
17
 
10
18
  * bugfix: take private methods into account when checking for callbacks (see [issue #197](https://github.com/aasm/aasm/issues/197) for details)
data/Gemfile CHANGED
@@ -1,12 +1,16 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gem "sqlite3", :platforms => :ruby
4
- gem "coveralls", :platforms => :ruby
4
+ gem "coveralls"
5
5
  gem 'rubysl', :platforms => :rbx
6
6
  gem "jruby-openssl", :platforms => :jruby
7
7
  gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
8
8
  gem "rails", "~>4.1"
9
- gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
9
+ gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
10
10
  gem 'sequel'
11
+ # Since mongoid V4 requires incompatible bson V2, cannot have mongoid (V4 or greater)
12
+ # and mongo_mapper ( or mongo ) in the same application
13
+ #gem 'mongo_mapper', '~> 0.13'
14
+ #gem 'bson_ext', :platforms => :ruby
11
15
 
12
16
  gemspec
data/README.md CHANGED
@@ -9,8 +9,8 @@ This package contains AASM, a library for adding finite state machines to Ruby c
9
9
 
10
10
  AASM started as the *acts_as_state_machine* plugin but has evolved into a more generic library
11
11
  that no longer targets only ActiveRecord models. It currently provides adapters for
12
- [ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html) and
13
- [Mongoid](http://mongoid.org/), but it can be used for any Ruby class, no matter what
12
+ [ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html),
13
+ [Mongoid](http://mongoid.org/), and [Mongomapper](http://mongomapper.com/) but it can be used for any Ruby class, no matter what
14
14
  parent class it has (if any).
15
15
 
16
16
  ## Upgrade from version 3 to 4
@@ -435,7 +435,7 @@ to ```false```.
435
435
 
436
436
  ### Sequel
437
437
 
438
- AASM also supports [Sequel](http://sequel.jeremyevans.net/) besides _ActiveRecord_ and _Mongoid_.
438
+ AASM also supports [Sequel](http://sequel.jeremyevans.net/) besides _ActiveRecord_, _Mongoid_, and _MongoMapper_.
439
439
 
440
440
  ```ruby
441
441
  class Job < Sequel::Model
@@ -466,6 +466,23 @@ class Job
466
466
  end
467
467
  ```
468
468
 
469
+ ### MongoMapper
470
+
471
+ AASM also supports persistence to Mongodb if you're using MongoMapper. Make sure
472
+ to include MongoMapper::Document before you include AASM.
473
+
474
+ ```ruby
475
+ class Job
476
+ include MongoMapper::Document
477
+ include AASM
478
+
479
+ key :aasm_state, Symbol
480
+ aasm do
481
+ ...
482
+ end
483
+ end
484
+ ```
485
+
469
486
  ### Automatic Scopes
470
487
 
471
488
  AASM will automatically create scope methods for each state in the model.
@@ -671,7 +688,7 @@ purpose.
671
688
 
672
689
  ## License ##
673
690
 
674
- Copyright (c) 2006-2014 Scott Barron
691
+ Copyright (c) 2006-2015 Scott Barron
675
692
 
676
693
  Permission is hereby granted, free of charge, to any person obtaining
677
694
  a copy of this software and associated documentation files (the
data/aasm.gemspec CHANGED
@@ -9,10 +9,13 @@ Gem::Specification.new do |s|
9
9
  s.email = %q{scott@elitists.net, ttilley@gmail.com, aasm@mt7.de}
10
10
  s.homepage = %q{https://github.com/aasm/aasm}
11
11
  s.summary = %q{State machine mixin for Ruby objects}
12
- s.description = %q{AASM is a continuation of the acts as state machine rails plugin, built for plain Ruby objects.}
12
+ s.description = %q{AASM is a continuation of the acts-as-state-machine rails plugin, built for plain Ruby objects.}
13
13
  s.date = Time.now
14
14
  s.licenses = ["MIT"]
15
15
 
16
+ s.platform = Gem::Platform::RUBY
17
+ s.required_ruby_version = '>= 1.9.3'
18
+
16
19
  s.add_development_dependency 'rake'
17
20
  s.add_development_dependency 'sdoc'
18
21
  s.add_development_dependency 'rspec'
@@ -25,8 +28,6 @@ Gem::Specification.new do |s|
25
28
  # s.add_development_dependency 'mime-types', '~> 1.25' # needed by coveralls (>= 2.0 needs Ruby >=1.9.2)
26
29
  # s.add_development_dependency 'coveralls'
27
30
 
28
- s.platform = Gem::Platform::RUBY
29
- # s.required_ruby_version = '>= 1.9.3'
30
31
  s.files = `git ls-files`.split("\n")
31
32
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
32
33
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -7,7 +7,9 @@ gem 'rubinius-developer_tools', :platforms => :rbx
7
7
  gem "jruby-openssl", :platforms => :jruby
8
8
  gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
9
  gem "rails", "3.2.21"
10
- gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
10
+ gem 'mongoid', '~>3.1' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
11
11
  gem 'sequel'
12
+ gem 'mongo_mapper', '~>0.13'
13
+ gem 'bson_ext', :platforms => :ruby
12
14
 
13
15
  gemspec :path => "../"
@@ -6,11 +6,8 @@ gem 'rubysl', :platforms => :rbx
6
6
  gem 'rubinius-developer_tools', :platforms => :rbx
7
7
  gem "jruby-openssl", :platforms => :jruby
8
8
  gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
- gem "rails", "4.0.12"
10
-
11
- # mongoid is not yet compatible with Rails >= 4
12
- # gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
13
-
9
+ gem "rails", "4.0.13"
10
+ gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
14
11
  gem 'sequel'
15
12
 
16
13
  gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "sqlite3", :platforms => :ruby
4
+ gem "coveralls"
5
+ gem 'rubysl', :platforms => :rbx
6
+ gem 'rubinius-developer_tools', :platforms => :rbx
7
+ gem "jruby-openssl", :platforms => :jruby
8
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
+ gem "rails", "4.0.13"
10
+ gem 'sequel'
11
+ gem 'mongo_mapper', '~>0.13'
12
+ gem 'bson_ext', :platforms => :ruby
13
+
14
+ gemspec :path => "../"
@@ -6,11 +6,8 @@ gem 'rubysl', :platforms => :rbx
6
6
  gem 'rubinius-developer_tools', :platforms => :rbx
7
7
  gem "jruby-openssl", :platforms => :jruby
8
8
  gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
- gem "rails", "4.1.8"
10
-
11
- # mongoid is not yet compatible with Rails >= 4
12
- # gem 'mongoid' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
13
-
9
+ gem "rails", "4.1.9"
10
+ gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
14
11
  gem 'sequel'
15
12
 
16
13
  gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "sqlite3", :platforms => :ruby
4
+ gem "coveralls"
5
+ gem 'rubysl', :platforms => :rbx
6
+ gem 'rubinius-developer_tools', :platforms => :rbx
7
+ gem "jruby-openssl", :platforms => :jruby
8
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
+ gem "rails", "4.1.9"
10
+ gem 'sequel'
11
+ gem 'mongo_mapper', '~> 0.13'
12
+ gem 'bson_ext', :platforms => :ruby
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,13 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "sqlite3", :platforms => :ruby
4
+ gem "coveralls"
5
+ gem 'rubysl', :platforms => :rbx
6
+ gem 'rubinius-developer_tools', :platforms => :rbx
7
+ gem "jruby-openssl", :platforms => :jruby
8
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
+ gem "rails", "4.2.0"
10
+ gem 'mongoid', '~>4.0' if Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3')
11
+ gem 'sequel'
12
+
13
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "sqlite3", :platforms => :ruby
4
+ gem "coveralls"
5
+ gem 'rubysl', :platforms => :rbx
6
+ gem 'rubinius-developer_tools', :platforms => :rbx
7
+ gem "jruby-openssl", :platforms => :jruby
8
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
9
+ gem "rails", "4.2.0"
10
+ gem 'sequel'
11
+ gem 'mongo_mapper'
12
+ gem 'bson_ext', :platforms => :ruby
13
+
14
+ gemspec :path => "../"
data/lib/aasm/base.rb CHANGED
@@ -56,12 +56,12 @@ module AASM
56
56
  def state(name, options={})
57
57
  @state_machine.add_state(name, @klass, options)
58
58
 
59
- @klass.send(:define_method, "#{name.to_s}?") do
59
+ @klass.send(:define_method, "#{name}?") do
60
60
  aasm.current_state == name
61
61
  end
62
62
 
63
- unless @klass.const_defined?("STATE_#{name.to_s.upcase}")
64
- @klass.const_set("STATE_#{name.to_s.upcase}", name)
63
+ unless @klass.const_defined?("STATE_#{name.upcase}")
64
+ @klass.const_set("STATE_#{name.upcase}", name)
65
65
  end
66
66
  end
67
67
 
@@ -72,16 +72,16 @@ module AASM
72
72
  # an addition over standard aasm so that, before firing an event, you can ask
73
73
  # may_event? and get back a boolean that tells you whether the guard method
74
74
  # on the transition will let this happen.
75
- @klass.send(:define_method, "may_#{name.to_s}?") do |*args|
75
+ @klass.send(:define_method, "may_#{name}?") do |*args|
76
76
  aasm.may_fire_event?(name, *args)
77
77
  end
78
78
 
79
- @klass.send(:define_method, "#{name.to_s}!") do |*args, &block|
80
- aasm.current_event = "#{name.to_s}!".to_sym
79
+ @klass.send(:define_method, "#{name}!") do |*args, &block|
80
+ aasm.current_event = "#{name}!".to_sym
81
81
  aasm_fire_event(name, {:persist => true}, *args, &block)
82
82
  end
83
83
 
84
- @klass.send(:define_method, "#{name.to_s}") do |*args, &block|
84
+ @klass.send(:define_method, "#{name}") do |*args, &block|
85
85
  aasm.current_event = name.to_sym
86
86
  aasm_fire_event(name, {:persist => false}, *args, &block)
87
87
  end
@@ -76,7 +76,7 @@ module AASM
76
76
 
77
77
  def may_fire_event?(name, *args)
78
78
  if event = @instance.class.aasm.state_machine.events[name]
79
- event.may_fire?(@instance, *args)
79
+ !!event.may_fire?(@instance, *args)
80
80
  else
81
81
  false # unknown event
82
82
  end
@@ -10,7 +10,7 @@ module AASM
10
10
  #
11
11
  # Adds
12
12
  #
13
- # before_validation :aasm_ensure_initial_state, :on => :create
13
+ # after_initialize :aasm_ensure_initial_state
14
14
  #
15
15
  # As a result, it doesn't matter when you define your methods - the following 2 are equivalent
16
16
  #
@@ -142,9 +142,9 @@ module AASM
142
142
 
143
143
  def aasm_raw_attribute_value(state)
144
144
  if aasm_enum
145
- value = self.class.send(aasm_enum)[state]
145
+ self.class.send(aasm_enum)[state]
146
146
  else
147
- value = state.to_s
147
+ state.to_s
148
148
  end
149
149
  end
150
150
 
@@ -166,7 +166,7 @@ module AASM
166
166
  def aasm_ensure_initial_state
167
167
  # checking via respond_to? does not work in Rails <= 3
168
168
  # if respond_to?(self.class.aasm.attribute_name) && send(self.class.aasm.attribute_name).blank? # Rails 4
169
- if attributes.key?(self.class.aasm.attribute_name.to_s) && send(self.class.aasm.attribute_name).blank?
169
+ if attribute_names.include?(self.class.aasm.attribute_name.to_s) && send(self.class.aasm.attribute_name).blank?
170
170
  aasm.enter_initial_state
171
171
  end
172
172
  end
@@ -71,6 +71,9 @@ module AASM
71
71
  elsif @klass.ancestors.map {|klass| klass.to_s}.include?("Mongoid::Document")
72
72
  scope_options = lambda { @klass.send(:where, {@klass.aasm.attribute_name.to_sym => name.to_s}) }
73
73
  @klass.send(:scope, name, scope_options)
74
+ elsif @klass.ancestors.map {|klass| klass.to_s}.include?("MongoMapper::Document")
75
+ conditions = { @klass.aasm.attribute_name.to_sym => name.to_s }
76
+ @klass.scope(name, lambda { @klass.where(conditions) })
74
77
  end
75
78
  end
76
79
  end
@@ -0,0 +1,174 @@
1
+ require_relative 'base'
2
+
3
+ module AASM
4
+ module Persistence
5
+ module MongoMapperPersistence
6
+ # This method:
7
+ #
8
+ # * extends the model with ClassMethods
9
+ # * includes InstanceMethods
10
+ #
11
+ # Adds
12
+ #
13
+ # before_validation :aasm_ensure_initial_state, :on => :create
14
+ #
15
+ # As a result, it doesn't matter when you define your methods - the following 2 are equivalent
16
+ #
17
+ # class Foo
18
+ # include MongoMapper::Document
19
+ # def aasm_write_state(state)
20
+ # "bar"
21
+ # end
22
+ # include AASM
23
+ # end
24
+ #
25
+ # class Foo < ActiveRecord::Base
26
+ # include MongoMapper::Document
27
+ # include AASM
28
+ # def aasm_write_state(state)
29
+ # "bar"
30
+ # end
31
+ # end
32
+ #
33
+ def self.included(base)
34
+ base.send(:include, AASM::Persistence::Base)
35
+ base.extend AASM::Persistence::MongoMapperPersistence::ClassMethods
36
+ base.send(:include, AASM::Persistence::MongoMapperPersistence::InstanceMethods)
37
+
38
+ base.before_create :aasm_ensure_initial_state
39
+
40
+ # ensure state is in the list of states
41
+ base.validate :aasm_validate_states
42
+ end
43
+
44
+ module ClassMethods
45
+
46
+ def find_in_state(number, state, *args)
47
+ with_state_scope(state).find!(number, *args)
48
+ end
49
+
50
+ def count_in_state(state, *args)
51
+ with_state_scope(state).count(*args)
52
+ end
53
+
54
+ def calculate_in_state(state, *args)
55
+ with_state_scope(state).calculate(*args)
56
+ end
57
+
58
+ protected
59
+ def with_state_scope(state)
60
+ where(aasm.attribute_name.to_sym => state.to_s)
61
+ end
62
+ end
63
+
64
+ module InstanceMethods
65
+
66
+ # Writes <tt>state</tt> to the state column and persists it to the database
67
+ #
68
+ # foo = Foo.find(1)
69
+ # foo.aasm.current_state # => :opened
70
+ # foo.close!
71
+ # foo.aasm.current_state # => :closed
72
+ # Foo.find(1).aasm.current_state # => :closed
73
+ #
74
+ # NOTE: intended to be called from an event
75
+ def aasm_write_state(state)
76
+ old_value = read_attribute(self.class.aasm.attribute_name)
77
+ aasm_write_attribute state
78
+
79
+ success = if aasm_skipping_validations
80
+ value = aasm_raw_attribute_value state
81
+ self.class.where(self.class.primary_key => self.id).update_all(self.class.aasm.attribute_name => value) == 1
82
+ else
83
+ self.save
84
+ end
85
+ unless success
86
+ write_attribute(self.class.aasm.attribute_name, old_value)
87
+ return false
88
+ end
89
+
90
+ true
91
+ end
92
+
93
+ # Writes <tt>state</tt> to the state column, but does not persist it to the database
94
+ #
95
+ # foo = Foo.find(1)
96
+ # foo.aasm.current_state # => :opened
97
+ # foo.close
98
+ # foo.aasm.current_state # => :closed
99
+ # Foo.find(1).aasm.current_state # => :opened
100
+ # foo.save
101
+ # foo.aasm.current_state # => :closed
102
+ # Foo.find(1).aasm.current_state # => :closed
103
+ #
104
+ # NOTE: intended to be called from an event
105
+ def aasm_write_state_without_persistence(state)
106
+ aasm_write_attribute state
107
+ end
108
+
109
+ private
110
+ def aasm_enum
111
+ case AASM::StateMachine[self.class].config.enum
112
+ when false then nil
113
+ when true then aasm_guess_enum_method
114
+ when nil then aasm_guess_enum_method if aasm_column_looks_like_enum
115
+ else AASM::StateMachine[self.class].config.enum
116
+ end
117
+ end
118
+
119
+ def aasm_column_looks_like_enum
120
+ self.class.keys[self.class.aasm.attribute_name.to_s].type == Integer
121
+ end
122
+
123
+ def aasm_guess_enum_method
124
+ self.class.aasm.attribute_name.to_s.pluralize.to_sym
125
+ end
126
+
127
+ def aasm_skipping_validations
128
+ AASM::StateMachine[self.class].config.skip_validation_on_save
129
+ end
130
+
131
+ def aasm_write_attribute(state)
132
+ write_attribute self.class.aasm.attribute_name, aasm_raw_attribute_value(state)
133
+ end
134
+
135
+ def aasm_raw_attribute_value(state)
136
+ if aasm_enum
137
+ self.class.send(aasm_enum)[state]
138
+ else
139
+ state.to_s
140
+ end
141
+ end
142
+
143
+ # Ensures that if the aasm_state column is nil and the record is new
144
+ # that the initial state gets populated before validation on create
145
+ #
146
+ # foo = Foo.new
147
+ # foo.aasm_state # => nil
148
+ # foo.valid?
149
+ # foo.aasm_state # => "open" (where :open is the initial state)
150
+ #
151
+ #
152
+ # foo = Foo.find(:first)
153
+ # foo.aasm_state # => 1
154
+ # foo.aasm_state = nil
155
+ # foo.valid?
156
+ # foo.aasm_state # => nil
157
+ #
158
+ def aasm_ensure_initial_state
159
+ return send("#{self.class.aasm.attribute_name}=", aasm.enter_initial_state.to_s) if send(self.class.aasm.attribute_name).blank?
160
+ end
161
+
162
+ def aasm_validate_states
163
+ send("#{self.class.aasm.attribute_name}=", aasm.enter_initial_state.to_s) if send(self.class.aasm.attribute_name).blank?
164
+ unless AASM::StateMachine[self.class].config.skip_validation_on_save
165
+ if aasm.current_state && !aasm.states.include?(aasm.current_state)
166
+ self.errors.add(AASM::StateMachine[self.class].config.column , "is invalid")
167
+ end
168
+ end
169
+ end
170
+ end # InstanceMethods
171
+
172
+ end
173
+ end # Persistence
174
+ end # AASM
@@ -35,11 +35,7 @@ module AASM
35
35
  base.extend AASM::Persistence::MongoidPersistence::ClassMethods
36
36
  base.send(:include, AASM::Persistence::MongoidPersistence::InstanceMethods)
37
37
 
38
- # Mongoid's Validatable gem dependency goes not have a before_validation_on_xxx hook yet.
39
- # base.before_validation_on_create :aasm_ensure_initial_state
40
- base.before_validation :aasm_ensure_initial_state
41
- # ensure initial aasm state even when validations are skipped
42
- base.before_create :aasm_ensure_initial_state
38
+ base.after_initialize :aasm_ensure_initial_state
43
39
  end
44
40
 
45
41
  module ClassMethods
@@ -10,6 +10,8 @@ module AASM
10
10
  include_persistence base, :active_record
11
11
  elsif hierarchy.include?("Mongoid::Document")
12
12
  include_persistence base, :mongoid
13
+ elsif hierarchy.include?("MongoMapper::Document")
14
+ include_persistence base, :mongo_mapper
13
15
  elsif hierarchy.include?("Sequel::Model")
14
16
  include_persistence base, :sequel
15
17
  else
data/lib/aasm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module AASM
2
- VERSION = "4.0.7"
2
+ VERSION = "4.1.0"
3
3
  end
@@ -0,0 +1,10 @@
1
+ class NoScopeMongoMapper
2
+ include MongoMapper::Document
3
+ include AASM
4
+
5
+ key :status, String
6
+
7
+ aasm :create_scopes => false, :column => :status do
8
+ state :ignored_scope
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ class SimpleMongoMapper
2
+ include MongoMapper::Document
3
+ include AASM
4
+
5
+ key :status, String
6
+
7
+ aasm column: :status do
8
+ state :unknown_scope
9
+ state :next
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class SimpleNewDslMongoMapper
2
+ include MongoMapper::Document
3
+ include AASM
4
+
5
+ key :status, String
6
+
7
+ aasm :column => :status
8
+ aasm do
9
+ state :unknown_scope
10
+ state :next
11
+ end
12
+ end
@@ -6,7 +6,7 @@ class SimpleNewDslMongoid
6
6
 
7
7
  aasm :column => :status
8
8
  aasm do
9
- state :unknown_scope
9
+ state :unknown_scope, :initial => true
10
10
  state :new
11
11
  end
12
12
  end
data/spec/spec_helper.rb CHANGED
@@ -11,6 +11,8 @@ Coveralls.wear!
11
11
  # require 'ruby-debug/completion'
12
12
  # require 'pry'
13
13
 
14
+ SEQUEL_DB = defined?(JRUBY_VERSION) ? 'jdbc:sqlite::memory:' : 'sqlite:/'
15
+
14
16
  def load_schema
15
17
  config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
16
18
  ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
@@ -19,24 +19,24 @@ describe 'when being unsuspended' do
19
19
  it 'should be able to be unsuspended' do
20
20
  auth.activate!
21
21
  auth.suspend!
22
- expect(auth.may_unsuspend?).to be_truthy
22
+ expect(auth.may_unsuspend?).to be true
23
23
  end
24
24
 
25
25
  it 'should not be able to be unsuspended into active' do
26
26
  auth.suspend!
27
- expect(auth.may_unsuspend?(:active)).not_to be_truthy
27
+ expect(auth.may_unsuspend?(:active)).not_to be true
28
28
  end
29
29
 
30
30
  it 'should be able to be unsuspended into active if polite' do
31
31
  auth.suspend!
32
- expect(auth.may_wait?(:waiting, :please)).to be_truthy
32
+ expect(auth.may_wait?(:waiting, :please)).to be true
33
33
  auth.wait!(nil, :please)
34
34
  end
35
35
 
36
36
  it 'should not be able to be unsuspended into active if not polite' do
37
37
  auth.suspend!
38
- expect(auth.may_wait?(:waiting)).not_to be_truthy
39
- expect(auth.may_wait?(:waiting, :rude)).not_to be_truthy
38
+ expect(auth.may_wait?(:waiting)).not_to be true
39
+ expect(auth.may_wait?(:waiting, :rude)).not_to be true
40
40
  expect {auth.wait!(nil, :rude)}.to raise_error(AASM::InvalidTransition)
41
41
  expect {auth.wait!}.to raise_error(AASM::InvalidTransition)
42
42
  end
@@ -46,7 +46,7 @@ describe 'when being unsuspended' do
46
46
  auth.suspend!
47
47
  auth.unsuspend!
48
48
 
49
- expect(auth.may_unpassify?).not_to be_truthy
49
+ expect(auth.may_unpassify?).not_to be true
50
50
  expect {auth.unpassify!}.to raise_error(AASM::InvalidTransition)
51
51
  end
52
52
 
@@ -74,11 +74,11 @@ describe 'when being unsuspended' do
74
74
  end
75
75
 
76
76
  it "should be able to fire known events" do
77
- expect(auth.aasm.may_fire_event?(:activate)).to be_truthy
77
+ expect(auth.aasm.may_fire_event?(:activate)).to be true
78
78
  end
79
79
 
80
80
  it "should not be able to fire unknown events" do
81
- expect(auth.aasm.may_fire_event?(:unknown)).to be_falsey
81
+ expect(auth.aasm.may_fire_event?(:unknown)).to be false
82
82
  end
83
83
 
84
84
  end
@@ -257,6 +257,7 @@ describe "instance methods" do
257
257
 
258
258
  end
259
259
 
260
+ if ActiveRecord::VERSION::MAJOR < 4 && ActiveRecord::VERSION::MINOR < 2 # won't work with Rails >= 4.2
260
261
  describe "direct state column access" do
261
262
  it "accepts false states" do
262
263
  f = FalseState.create!
@@ -266,6 +267,7 @@ describe "direct state column access" do
266
267
  }.to_not raise_error
267
268
  end
268
269
  end
270
+ end
269
271
 
270
272
  describe 'subclasses' do
271
273
  it "should have the same states as its parent class" do
@@ -0,0 +1,135 @@
1
+ describe 'mongo_mapper' do
2
+ begin
3
+ require 'mongo_mapper'
4
+ require 'logger'
5
+ require 'spec_helper'
6
+
7
+ before(:all) do
8
+ Dir[File.dirname(__FILE__) + "/../../models/mongo_mapper/*.rb"].sort.each { |f| require File.expand_path(f) }
9
+
10
+ config = {
11
+ 'test' => {
12
+ 'database' => "mongo_mapper_#{Process.pid}"
13
+ }
14
+ }
15
+
16
+ MongoMapper.setup(config, 'test') #, :logger => Logger.new(STDERR))
17
+ end
18
+
19
+ after do
20
+ # Clear Out all non-system Mongo collections between tests
21
+ MongoMapper.database.collections.each do |collection|
22
+ collection.drop unless collection.capped? || (collection.name =~ /\Asystem/)
23
+ end
24
+ end
25
+
26
+ describe "named scopes with the old DSL" do
27
+
28
+ context "Does not already respond_to? the scope name" do
29
+ it "should add a scope" do
30
+ expect(SimpleMongoMapper).to respond_to(:unknown_scope)
31
+ expect(SimpleMongoMapper.unknown_scope.class).to eq(MongoMapper::Plugins::Querying::DecoratedPluckyQuery)
32
+ #expect(SimpleMongoMapper.unknown_scope.is_a?(ActiveRecord::Relation)).to be_truthy
33
+ end
34
+ end
35
+
36
+ context "Already respond_to? the scope name" do
37
+ it "should not add a scope" do
38
+ expect(SimpleMongoMapper).to respond_to(:next)
39
+ expect(SimpleMongoMapper.new.class).to eq(SimpleMongoMapper)
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ describe "named scopes with the new DSL" do
46
+
47
+ context "Does not already respond_to? the scope name" do
48
+ it "should add a scope" do
49
+ expect(SimpleNewDslMongoMapper).to respond_to(:unknown_scope)
50
+ expect(SimpleNewDslMongoMapper.unknown_scope.class).to eq(MongoMapper::Plugins::Querying::DecoratedPluckyQuery)
51
+ end
52
+ end
53
+
54
+ context "Already respond_to? the scope name" do
55
+ it "should not add a scope" do
56
+ expect(SimpleNewDslMongoMapper).to respond_to(:next)
57
+ expect(SimpleNewDslMongoMapper.new.class).to eq(SimpleNewDslMongoMapper)
58
+ end
59
+ end
60
+
61
+ it "does not create scopes if requested" do
62
+ expect(NoScopeMongoMapper).not_to respond_to(:ignored_scope)
63
+ end
64
+
65
+ end
66
+
67
+ describe "#find_in_state" do
68
+
69
+ let!(:model) { SimpleNewDslMongoMapper.create!(:status => :unknown_scope) }
70
+ let!(:model_id) { model._id }
71
+
72
+ it "should respond to method" do
73
+ expect(SimpleNewDslMongoMapper).to respond_to(:find_in_state)
74
+ end
75
+
76
+ it "should find the model when given the correct scope and model id" do
77
+ expect(SimpleNewDslMongoMapper.find_in_state(model_id, 'unknown_scope').class).to eq(SimpleNewDslMongoMapper)
78
+ expect(SimpleNewDslMongoMapper.find_in_state(model_id, 'unknown_scope')).to eq(model)
79
+ end
80
+
81
+ it "should raise DocumentNotFound error when given incorrect scope" do
82
+ expect {SimpleNewDslMongoMapper.find_in_state(model_id, 'next')}.to raise_error MongoMapper::DocumentNotFound
83
+ end
84
+
85
+ it "should raise DocumentNotFound error when given incorrect model id" do
86
+ expect {SimpleNewDslMongoMapper.find_in_state('bad_id', 'unknown_scope')}.to raise_error MongoMapper::DocumentNotFound
87
+ end
88
+
89
+ end
90
+
91
+ describe "#count_in_state" do
92
+
93
+ before do
94
+ 3.times { SimpleNewDslMongoMapper.create!(:status => :unknown_scope) }
95
+ end
96
+
97
+ it "should respond to method" do
98
+ expect(SimpleNewDslMongoMapper).to respond_to(:count_in_state)
99
+ end
100
+
101
+ it "should return n for a scope with n records persisted" do
102
+ expect(SimpleNewDslMongoMapper.count_in_state('unknown_scope').class).to eq(Fixnum)
103
+ expect(SimpleNewDslMongoMapper.count_in_state('unknown_scope')).to eq(3)
104
+ end
105
+
106
+ it "should return zero for a scope without records persisted" do
107
+ expect(SimpleNewDslMongoMapper.count_in_state('next').class).to eq(Fixnum)
108
+ expect(SimpleNewDslMongoMapper.count_in_state('next')).to eq(0)
109
+ end
110
+
111
+ end
112
+
113
+ describe "instance methods" do
114
+
115
+ let(:simple) {SimpleNewDslMongoMapper.new}
116
+
117
+ it "should call aasm_ensure_initial_state on validation before create" do
118
+ expect(SimpleNewDslMongoMapper.aasm.initial_state).to eq(:unknown_scope)
119
+ expect(SimpleNewDslMongoMapper.aasm.attribute_name).to eq(:status)
120
+ expect(simple.status).to eq(nil)
121
+ simple.valid?
122
+ expect(simple.status).to eq('unknown_scope')
123
+ end
124
+
125
+ it "should call aasm_ensure_initial_state before create, even if skipping validations" do
126
+ expect(simple.status).to eq(nil)
127
+ simple.save(:validate => false)
128
+ expect(simple.status).to eq('unknown_scope')
129
+ end
130
+ end
131
+
132
+ rescue LoadError
133
+ puts "Not running MongoMapper specs because mongo_mapper gem is not installed!!!"
134
+ end
135
+ end
@@ -1,6 +1,4 @@
1
- describe 'mongoid', :if => Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version.create('1.9.3') do
2
- # describe 'mongoid' do
3
-
1
+ describe 'mongoid' do
4
2
  begin
5
3
  require 'mongoid'
6
4
  require 'logger'
@@ -135,15 +133,11 @@ describe 'mongoid', :if => Gem::Version.create(RUBY_VERSION.dup) >= Gem::Version
135
133
  describe "instance methods" do
136
134
  let(:simple) {SimpleNewDslMongoid.new}
137
135
 
138
- it "should call aasm_ensure_initial_state on validation before create" do
139
- expect(simple).to receive(:aasm_ensure_initial_state).and_return(true)
140
- simple.valid?
136
+ it "should initialize the aasm state on instantiation" do
137
+ expect(SimpleNewDslMongoid.new.status).to eql 'unknown_scope'
138
+ expect(SimpleNewDslMongoid.new.aasm.current_state).to eql :unknown_scope
141
139
  end
142
140
 
143
- it "should call aasm_ensure_initial_state before create, even if skipping validations" do
144
- expect(simple).to receive(:aasm_ensure_initial_state).and_return(true)
145
- simple.save(:validate => false)
146
- end
147
141
  end
148
142
 
149
143
  rescue LoadError
@@ -6,7 +6,8 @@ describe 'sequel' do
6
6
  require 'spec_helper'
7
7
 
8
8
  before(:all) do
9
- db = Sequel.sqlite
9
+ db = Sequel.connect(SEQUEL_DB)
10
+
10
11
  # if you want to see the statements while running the spec enable the following line
11
12
  # db.loggers << Logger.new($stderr)
12
13
  db.create_table(:models) do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aasm
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.7
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Barron
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-12-20 00:00:00.000000000 Z
13
+ date: 2015-02-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -68,7 +68,7 @@ dependencies:
68
68
  - - ">="
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0'
71
- description: AASM is a continuation of the acts as state machine rails plugin, built
71
+ description: AASM is a continuation of the acts-as-state-machine rails plugin, built
72
72
  for plain Ruby objects.
73
73
  email: scott@elitists.net, ttilley@gmail.com, aasm@mt7.de
74
74
  executables: []
@@ -91,7 +91,11 @@ files:
91
91
  - callbacks.txt
92
92
  - gemfiles/rails_3.2.gemfile
93
93
  - gemfiles/rails_4.0.gemfile
94
+ - gemfiles/rails_4.0_bson1.gemfile
94
95
  - gemfiles/rails_4.1.gemfile
96
+ - gemfiles/rails_4.1_bson1.gemfile
97
+ - gemfiles/rails_4.2.gemfile
98
+ - gemfiles/rails_4.2_bson1.gemfile
95
99
  - lib/aasm.rb
96
100
  - lib/aasm/aasm.rb
97
101
  - lib/aasm/base.rb
@@ -106,6 +110,7 @@ files:
106
110
  - lib/aasm/persistence.rb
107
111
  - lib/aasm/persistence/active_record_persistence.rb
108
112
  - lib/aasm/persistence/base.rb
113
+ - lib/aasm/persistence/mongo_mapper_persistence.rb
109
114
  - lib/aasm/persistence/mongoid_persistence.rb
110
115
  - lib/aasm/persistence/plain_persistence.rb
111
116
  - lib/aasm/persistence/sequel_persistence.rb
@@ -131,6 +136,9 @@ files:
131
136
  - spec/models/foo.rb
132
137
  - spec/models/guardian.rb
133
138
  - spec/models/invalid_persistor.rb
139
+ - spec/models/mongo_mapper/no_scope_mongo_mapper.rb
140
+ - spec/models/mongo_mapper/simple_mongo_mapper.rb
141
+ - spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb
134
142
  - spec/models/mongoid/no_scope_mongoid.rb
135
143
  - spec/models/mongoid/simple_mongoid.rb
136
144
  - spec/models/mongoid/simple_new_dsl_mongoid.rb
@@ -158,6 +166,7 @@ files:
158
166
  - spec/unit/memory_leak_spec.rb
159
167
  - spec/unit/new_dsl_spec.rb
160
168
  - spec/unit/persistence/active_record_persistence_spec.rb
169
+ - spec/unit/persistence/mongo_mapper_persistance_spec.rb
161
170
  - spec/unit/persistence/mongoid_persistance_spec.rb
162
171
  - spec/unit/persistence/sequel_persistence_spec.rb
163
172
  - spec/unit/reloading_spec.rb
@@ -177,7 +186,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
177
186
  requirements:
178
187
  - - ">="
179
188
  - !ruby/object:Gem::Version
180
- version: '0'
189
+ version: 1.9.3
181
190
  required_rubygems_version: !ruby/object:Gem::Requirement
182
191
  requirements:
183
192
  - - ">="
@@ -210,6 +219,9 @@ test_files:
210
219
  - spec/models/foo.rb
211
220
  - spec/models/guardian.rb
212
221
  - spec/models/invalid_persistor.rb
222
+ - spec/models/mongo_mapper/no_scope_mongo_mapper.rb
223
+ - spec/models/mongo_mapper/simple_mongo_mapper.rb
224
+ - spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb
213
225
  - spec/models/mongoid/no_scope_mongoid.rb
214
226
  - spec/models/mongoid/simple_mongoid.rb
215
227
  - spec/models/mongoid/simple_new_dsl_mongoid.rb
@@ -237,6 +249,7 @@ test_files:
237
249
  - spec/unit/memory_leak_spec.rb
238
250
  - spec/unit/new_dsl_spec.rb
239
251
  - spec/unit/persistence/active_record_persistence_spec.rb
252
+ - spec/unit/persistence/mongo_mapper_persistance_spec.rb
240
253
  - spec/unit/persistence/mongoid_persistance_spec.rb
241
254
  - spec/unit/persistence/sequel_persistence_spec.rb
242
255
  - spec/unit/reloading_spec.rb