aasm 4.0.8 → 4.2.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 +4 -4
- data/.travis.yml +5 -2
- data/CHANGELOG.md +18 -2
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +6 -3
- data/LICENSE +1 -1
- data/README.md +31 -5
- data/aasm.gemspec +1 -5
- data/gemfiles/rails_3.2.gemfile +3 -2
- data/gemfiles/rails_4.0.gemfile +2 -6
- data/gemfiles/rails_4.0_bson1.gemfile +14 -0
- data/gemfiles/rails_4.1.gemfile +2 -6
- data/gemfiles/rails_4.1_bson1.gemfile +14 -0
- data/gemfiles/rails_4.2.gemfile +1 -5
- data/gemfiles/rails_4.2_bson1.gemfile +14 -0
- data/lib/aasm/aasm.rb +13 -7
- data/lib/aasm/base.rb +12 -4
- data/lib/aasm/core/event.rb +1 -1
- data/lib/aasm/core/state.rb +8 -6
- data/lib/aasm/errors.rb +12 -1
- data/lib/aasm/persistence/active_record_persistence.rb +4 -4
- data/lib/aasm/persistence/base.rb +3 -0
- data/lib/aasm/persistence/mongo_mapper_persistence.rb +174 -0
- data/lib/aasm/persistence/mongoid_persistence.rb +1 -5
- data/lib/aasm/persistence/sequel_persistence.rb +1 -0
- data/lib/aasm/persistence.rb +2 -0
- data/lib/aasm/version.rb +1 -1
- data/spec/models/active_record/derivate_new_dsl.rb +3 -0
- data/spec/models/active_record/false_state.rb +17 -0
- data/spec/models/active_record/gate.rb +19 -0
- data/spec/models/active_record/localizer_test_model.rb +34 -0
- data/spec/models/active_record/no_direct_assignment.rb +10 -0
- data/spec/models/active_record/no_scope.rb +10 -0
- data/spec/models/active_record/persisted_state.rb +12 -0
- data/spec/models/active_record/provided_and_persisted_state.rb +24 -0
- data/spec/models/active_record/reader.rb +7 -0
- data/spec/models/active_record/simple_new_dsl.rb +8 -0
- data/spec/models/active_record/thief.rb +14 -0
- data/spec/models/active_record/transient.rb +6 -0
- data/spec/models/active_record/with_enum.rb +19 -0
- data/spec/models/active_record/with_false_enum.rb +15 -0
- data/spec/models/active_record/with_true_enum.rb +19 -0
- data/spec/models/active_record/writer.rb +6 -0
- data/spec/models/callbacks/with_args.rb +9 -9
- data/spec/models/{auth_machine.rb → complex_example.rb} +1 -1
- data/spec/models/default_state.rb +12 -0
- data/spec/models/initial_state_proc.rb +15 -0
- data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +10 -0
- data/spec/models/mongo_mapper/simple_mongo_mapper.rb +11 -0
- data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +12 -0
- data/spec/models/mongoid/simple_new_dsl_mongoid.rb +1 -1
- data/spec/models/{bar.rb → no_initial_state.rb} +1 -4
- data/spec/models/provided_state.rb +24 -0
- data/spec/models/simple_example.rb +15 -0
- data/spec/models/state_machine_with_failed_event.rb +12 -0
- data/spec/models/sub_class.rb +3 -0
- data/spec/models/sub_class_with_more_states.rb +7 -0
- data/spec/models/super_class.rb +18 -0
- data/spec/models/{argument.rb → valid_state_name.rb} +1 -1
- data/spec/models/validator.rb +8 -0
- data/spec/spec_helper.rb +3 -4
- data/spec/unit/api_spec.rb +6 -1
- data/spec/unit/callbacks_spec.rb +1 -1
- data/spec/unit/complex_example_spec.rb +2 -2
- data/spec/unit/event_naming_spec.rb +2 -15
- data/spec/unit/initial_state_spec.rb +3 -18
- data/spec/unit/inspection_spec.rb +7 -7
- data/spec/unit/localizer_spec.rb +0 -38
- data/spec/unit/persistence/active_record_persistence_spec.rb +26 -3
- data/spec/unit/persistence/mongo_mapper_persistance_spec.rb +135 -0
- data/spec/unit/persistence/mongoid_persistance_spec.rb +4 -10
- data/spec/unit/persistence/sequel_persistence_spec.rb +15 -1
- data/spec/unit/simple_example_spec.rb +26 -42
- data/spec/unit/subclassing_spec.rb +10 -10
- data/spec/unit/transition_spec.rb +6 -1
- metadata +72 -19
- data/spec/models/active_record/api.rb +0 -75
- data/spec/models/father.rb +0 -21
- data/spec/models/persistence.rb +0 -164
- data/spec/models/son.rb +0 -3
data/spec/models/validator.rb
CHANGED
|
@@ -12,6 +12,9 @@ class Validator < ActiveRecord::Base
|
|
|
12
12
|
transitions :to => :running, :from => :sleeping
|
|
13
13
|
end
|
|
14
14
|
event :sleep do
|
|
15
|
+
after_commit do |name|
|
|
16
|
+
change_name_on_sleep name
|
|
17
|
+
end
|
|
15
18
|
transitions :to => :sleeping, :from => :running
|
|
16
19
|
end
|
|
17
20
|
event :fail do
|
|
@@ -26,6 +29,11 @@ class Validator < ActiveRecord::Base
|
|
|
26
29
|
save!
|
|
27
30
|
end
|
|
28
31
|
|
|
32
|
+
def change_name_on_sleep name
|
|
33
|
+
self.name = name
|
|
34
|
+
save!
|
|
35
|
+
end
|
|
36
|
+
|
|
29
37
|
def fail
|
|
30
38
|
raise StandardError.new('failed on purpose')
|
|
31
39
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
|
2
2
|
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
|
3
3
|
require 'aasm'
|
|
4
|
-
|
|
5
4
|
require 'rspec'
|
|
6
5
|
|
|
7
|
-
require 'coveralls'
|
|
8
|
-
Coveralls.wear!
|
|
9
|
-
|
|
10
6
|
# require 'ruby-debug'; Debugger.settings[:autoeval] = true; debugger; rubys_debugger = 'annoying'
|
|
11
7
|
# require 'ruby-debug/completion'
|
|
12
8
|
# require 'pry'
|
|
13
9
|
|
|
10
|
+
SEQUEL_DB = defined?(JRUBY_VERSION) ? 'jdbc:sqlite::memory:' : 'sqlite:/'
|
|
11
|
+
|
|
14
12
|
def load_schema
|
|
13
|
+
require 'logger'
|
|
15
14
|
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
|
16
15
|
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
|
17
16
|
ActiveRecord::Base.establish_connection(config['sqlite3'])
|
data/spec/unit/api_spec.rb
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'models/
|
|
2
|
+
require 'models/default_state.rb'
|
|
3
|
+
require 'models/provided_state.rb'
|
|
4
|
+
require 'models/active_record/persisted_state.rb'
|
|
5
|
+
require 'models/active_record/provided_and_persisted_state.rb'
|
|
6
|
+
|
|
7
|
+
load_schema
|
|
3
8
|
|
|
4
9
|
describe "reading the current state" do
|
|
5
10
|
it "uses the AASM default" do
|
data/spec/unit/callbacks_spec.rb
CHANGED
|
@@ -145,7 +145,7 @@ describe 'callbacks for the new DSL' do
|
|
|
145
145
|
|
|
146
146
|
cb.reset_data
|
|
147
147
|
cb.close!(:arg1, :arg2)
|
|
148
|
-
expect(cb.data).to eql 'before(:arg1,:arg2) before_exit_open transition_proc(:arg1,:arg2) before_enter_closed aasm_write_state after_exit_open after_enter_closed after(:arg1,:arg2)'
|
|
148
|
+
expect(cb.data).to eql 'before(:arg1,:arg2) before_exit_open(:arg1,:arg2) transition_proc(:arg1,:arg2) before_enter_closed(:arg1,:arg2) aasm_write_state after_exit_open(:arg1,:arg2) after_enter_closed(:arg1,:arg2) after(:arg1,:arg2)'
|
|
149
149
|
end
|
|
150
150
|
|
|
151
151
|
it "should call the callbacks given the to-state as argument" do
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe 'on initialization' do
|
|
4
|
-
let(:auth) {
|
|
4
|
+
let(:auth) {ComplexExample.new}
|
|
5
5
|
|
|
6
6
|
it 'should be in the pending state' do
|
|
7
7
|
expect(auth.aasm.current_state).to eq(:pending)
|
|
@@ -14,7 +14,7 @@ describe 'on initialization' do
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
describe 'when being unsuspended' do
|
|
17
|
-
let(:auth) {
|
|
17
|
+
let(:auth) {ComplexExample.new}
|
|
18
18
|
|
|
19
19
|
it 'should be able to be unsuspended' do
|
|
20
20
|
auth.activate!
|
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
class SimpleStateMachine
|
|
4
|
-
include AASM
|
|
5
|
-
|
|
6
|
-
aasm do
|
|
7
|
-
state :init, :initial => true
|
|
8
|
-
state :failed
|
|
9
|
-
|
|
10
|
-
event :failed do
|
|
11
|
-
transitions :from => :init, :to => :failed
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
3
|
describe "event naming" do
|
|
17
|
-
let(:state_machine) {
|
|
4
|
+
let(:state_machine) { StateMachineWithFailedEvent.new }
|
|
18
5
|
|
|
19
|
-
it "allows an event of failed without blowing the stack" do
|
|
6
|
+
it "allows an event of failed without blowing the stack aka stack level too deep" do
|
|
20
7
|
state_machine.failed
|
|
21
8
|
|
|
22
9
|
expect { state_machine.failed }.to raise_error(AASM::InvalidTransition)
|
|
@@ -1,27 +1,12 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
class Banker
|
|
4
|
-
include AASM
|
|
5
|
-
aasm do
|
|
6
|
-
state :retired
|
|
7
|
-
state :selling_bad_mortgages
|
|
8
|
-
initial_state Proc.new { |banker| banker.rich? ? :retired : :selling_bad_mortgages }
|
|
9
|
-
end
|
|
10
|
-
RICH = 1_000_000
|
|
11
|
-
attr_accessor :balance
|
|
12
|
-
def initialize(balance = 0); self.balance = balance; end
|
|
13
|
-
def rich?; self.balance >= RICH; end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
3
|
describe 'initial states' do
|
|
17
|
-
let(:bar) {Bar.new}
|
|
18
|
-
|
|
19
4
|
it 'should use the first state defined if no initial state is given' do
|
|
20
|
-
expect(
|
|
5
|
+
expect(NoInitialState.new.aasm.current_state).to eq(:read)
|
|
21
6
|
end
|
|
22
7
|
|
|
23
8
|
it 'should determine initial state from the Proc results' do
|
|
24
|
-
expect(
|
|
25
|
-
expect(
|
|
9
|
+
expect(InitialStateProc.new(InitialStateProc::RICH - 1).aasm.current_state).to eq(:selling_bad_mortgages)
|
|
10
|
+
expect(InitialStateProc.new(InitialStateProc::RICH + 1).aasm.current_state).to eq(:retired)
|
|
26
11
|
end
|
|
27
12
|
end
|
|
@@ -62,11 +62,11 @@ describe 'inspection for common cases' do
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
describe "special cases" do
|
|
65
|
-
it "should support valid
|
|
66
|
-
expect(
|
|
67
|
-
expect(
|
|
65
|
+
it "should support valid as state name" do
|
|
66
|
+
expect(ValidStateName.aasm.states).to include(:invalid)
|
|
67
|
+
expect(ValidStateName.aasm.states).to include(:valid)
|
|
68
68
|
|
|
69
|
-
argument =
|
|
69
|
+
argument = ValidStateName.new
|
|
70
70
|
expect(argument.invalid?).to be_truthy
|
|
71
71
|
expect(argument.aasm.current_state).to eq(:invalid)
|
|
72
72
|
|
|
@@ -85,13 +85,13 @@ end
|
|
|
85
85
|
|
|
86
86
|
describe 'aasm.from_states_for_state' do
|
|
87
87
|
it "should return all from states for a state" do
|
|
88
|
-
expect(
|
|
89
|
-
froms =
|
|
88
|
+
expect(ComplexExample.aasm).to respond_to(:from_states_for_state)
|
|
89
|
+
froms = ComplexExample.aasm.from_states_for_state(:active)
|
|
90
90
|
[:pending, :passive, :suspended].each {|from| expect(froms).to include(from)}
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
it "should return from states for a state for a particular transition only" do
|
|
94
|
-
froms =
|
|
94
|
+
froms = ComplexExample.aasm.from_states_for_state(:active, :transition => :unsuspend)
|
|
95
95
|
[:suspended].each {|from| expect(froms).to include(from)}
|
|
96
96
|
end
|
|
97
97
|
end
|
data/spec/unit/localizer_spec.rb
CHANGED
|
@@ -1,48 +1,10 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'active_record'
|
|
3
|
-
require 'logger'
|
|
4
3
|
require 'i18n'
|
|
5
4
|
|
|
6
5
|
I18n.enforce_available_locales = false
|
|
7
6
|
load_schema
|
|
8
7
|
|
|
9
|
-
class LocalizerTestModel < ActiveRecord::Base
|
|
10
|
-
include AASM
|
|
11
|
-
|
|
12
|
-
attr_accessor :aasm_state
|
|
13
|
-
|
|
14
|
-
aasm do
|
|
15
|
-
state :opened, :initial => true
|
|
16
|
-
state :closed
|
|
17
|
-
event :close
|
|
18
|
-
event :open
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
describe 'localized state names' do
|
|
23
|
-
before(:all) do
|
|
24
|
-
I18n.load_path << 'spec/en.yml'
|
|
25
|
-
I18n.default_locale = :en
|
|
26
|
-
I18n.reload!
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
after(:all) do
|
|
30
|
-
I18n.load_path.clear
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it 'should localize' do
|
|
34
|
-
state = LocalizerTestModel.aasm.states.detect {|s| s == :opened}
|
|
35
|
-
expect(state.localized_name).to eq("It's open now!")
|
|
36
|
-
expect(state.human_name).to eq("It's open now!")
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it 'should use fallback' do
|
|
40
|
-
state = LocalizerTestModel.aasm.states.detect {|s| s == :closed}
|
|
41
|
-
expect(state.localized_name).to eq('Closed')
|
|
42
|
-
expect(state.human_name).to eq('Closed')
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
8
|
describe AASM::Localizer, "new style" do
|
|
47
9
|
before(:all) do
|
|
48
10
|
I18n.load_path << 'spec/en.yml'
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
require 'active_record'
|
|
2
|
-
require 'logger'
|
|
3
2
|
require 'spec_helper'
|
|
4
|
-
|
|
3
|
+
Dir[File.dirname(__FILE__) + "/../../models/active_record/*.rb"].sort.each { |f| require File.expand_path(f) }
|
|
5
4
|
load_schema
|
|
6
5
|
|
|
7
6
|
# if you want to see the statements while running the spec enable the following line
|
|
7
|
+
# require 'logger'
|
|
8
8
|
# ActiveRecord::Base.logger = Logger.new(STDERR)
|
|
9
9
|
|
|
10
10
|
shared_examples_for "aasm model" do
|
|
@@ -321,6 +321,24 @@ describe "direct assignment" do
|
|
|
321
321
|
expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
|
|
322
322
|
expect(obj.aasm_state.to_sym).to eql :pending
|
|
323
323
|
end
|
|
324
|
+
|
|
325
|
+
it 'can be turned off and on again' do
|
|
326
|
+
obj = NoDirectAssignment.create
|
|
327
|
+
expect(obj.aasm_state.to_sym).to eql :pending
|
|
328
|
+
|
|
329
|
+
expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
|
|
330
|
+
expect(obj.aasm_state.to_sym).to eql :pending
|
|
331
|
+
|
|
332
|
+
# allow it temporarily
|
|
333
|
+
NoDirectAssignment.aasm.state_machine.config.no_direct_assignment = false
|
|
334
|
+
obj.aasm_state = :pending
|
|
335
|
+
expect(obj.aasm_state.to_sym).to eql :pending
|
|
336
|
+
|
|
337
|
+
# and forbid it again
|
|
338
|
+
NoDirectAssignment.aasm.state_machine.config.no_direct_assignment = true
|
|
339
|
+
expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
|
|
340
|
+
expect(obj.aasm_state.to_sym).to eql :pending
|
|
341
|
+
end
|
|
324
342
|
end # direct assignment
|
|
325
343
|
|
|
326
344
|
describe 'initial states' do
|
|
@@ -431,9 +449,14 @@ describe 'transitions with persistence' do
|
|
|
431
449
|
it "should fire :after_commit if transaction was successful" do
|
|
432
450
|
validator = Validator.create(:name => 'name')
|
|
433
451
|
expect(validator).to be_sleeping
|
|
452
|
+
|
|
434
453
|
validator.run!
|
|
435
454
|
expect(validator).to be_running
|
|
436
|
-
expect(validator.name).
|
|
455
|
+
expect(validator.name).to eq("name changed")
|
|
456
|
+
|
|
457
|
+
validator.sleep!("sleeper")
|
|
458
|
+
expect(validator).to be_sleeping
|
|
459
|
+
expect(validator.name).to eq("sleeper")
|
|
437
460
|
end
|
|
438
461
|
|
|
439
462
|
it "should not fire :after_commit if transaction failed" 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'
|
|
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
|
|
139
|
-
expect(
|
|
140
|
-
|
|
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.
|
|
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
|
|
@@ -43,6 +44,11 @@ describe 'sequel' do
|
|
|
43
44
|
expect(model.aasm.current_state).to eq(:alpha)
|
|
44
45
|
end
|
|
45
46
|
|
|
47
|
+
it "should save the initial state" do
|
|
48
|
+
model.save
|
|
49
|
+
expect(model.status).to eq("alpha")
|
|
50
|
+
end
|
|
51
|
+
|
|
46
52
|
it "should return the aasm column when new and the aasm field is not nil" do
|
|
47
53
|
model.status = "beta"
|
|
48
54
|
expect(model.aasm.current_state).to eq(:beta)
|
|
@@ -60,6 +66,14 @@ describe 'sequel' do
|
|
|
60
66
|
expect(model.aasm.current_state).to be_nil
|
|
61
67
|
end
|
|
62
68
|
|
|
69
|
+
it "should not change the state if state is not loaded" do
|
|
70
|
+
model.release
|
|
71
|
+
model.save
|
|
72
|
+
model.class.select(:id).first.save
|
|
73
|
+
model.reload
|
|
74
|
+
expect(model.aasm.current_state).to eq(:beta)
|
|
75
|
+
end
|
|
76
|
+
|
|
63
77
|
it "should call aasm_ensure_initial_state on validation before create" do
|
|
64
78
|
expect(model).to receive(:aasm_ensure_initial_state).and_return(true)
|
|
65
79
|
model.valid?
|
|
@@ -1,58 +1,42 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
class Payment
|
|
4
|
-
include AASM
|
|
5
|
-
aasm do
|
|
6
|
-
state :initialised, :initial => true
|
|
7
|
-
state :filled_out
|
|
8
|
-
state :authorised
|
|
9
|
-
|
|
10
|
-
event :fill_out do
|
|
11
|
-
transitions :from => :initialised, :to => :filled_out
|
|
12
|
-
end
|
|
13
|
-
event :authorise do
|
|
14
|
-
transitions :from => :filled_out, :to => :authorised
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
3
|
describe 'state machine' do
|
|
20
|
-
let(:
|
|
4
|
+
let(:simple) { SimpleExample.new }
|
|
21
5
|
|
|
22
6
|
it 'starts with an initial state' do
|
|
23
|
-
expect(
|
|
24
|
-
expect(
|
|
25
|
-
expect(
|
|
7
|
+
expect(simple.aasm.current_state).to eq(:initialised)
|
|
8
|
+
expect(simple).to respond_to(:initialised?)
|
|
9
|
+
expect(simple).to be_initialised
|
|
26
10
|
end
|
|
27
11
|
|
|
28
12
|
it 'allows transitions to other states' do
|
|
29
|
-
expect(
|
|
30
|
-
expect(
|
|
31
|
-
|
|
32
|
-
expect(
|
|
33
|
-
expect(
|
|
34
|
-
|
|
35
|
-
expect(
|
|
36
|
-
expect(
|
|
37
|
-
|
|
38
|
-
expect(
|
|
39
|
-
expect(
|
|
13
|
+
expect(simple).to respond_to(:fill_out)
|
|
14
|
+
expect(simple).to respond_to(:fill_out!)
|
|
15
|
+
simple.fill_out!
|
|
16
|
+
expect(simple).to respond_to(:filled_out?)
|
|
17
|
+
expect(simple).to be_filled_out
|
|
18
|
+
|
|
19
|
+
expect(simple).to respond_to(:authorise)
|
|
20
|
+
expect(simple).to respond_to(:authorise!)
|
|
21
|
+
simple.authorise
|
|
22
|
+
expect(simple).to respond_to(:authorised?)
|
|
23
|
+
expect(simple).to be_authorised
|
|
40
24
|
end
|
|
41
25
|
|
|
42
26
|
it 'denies transitions to other states' do
|
|
43
|
-
expect {
|
|
44
|
-
expect {
|
|
45
|
-
|
|
46
|
-
expect {
|
|
47
|
-
expect {
|
|
48
|
-
|
|
49
|
-
expect {
|
|
50
|
-
expect {
|
|
27
|
+
expect {simple.authorise}.to raise_error(AASM::InvalidTransition)
|
|
28
|
+
expect {simple.authorise!}.to raise_error(AASM::InvalidTransition)
|
|
29
|
+
simple.fill_out
|
|
30
|
+
expect {simple.fill_out}.to raise_error(AASM::InvalidTransition)
|
|
31
|
+
expect {simple.fill_out!}.to raise_error(AASM::InvalidTransition)
|
|
32
|
+
simple.authorise
|
|
33
|
+
expect {simple.fill_out}.to raise_error(AASM::InvalidTransition)
|
|
34
|
+
expect {simple.fill_out!}.to raise_error(AASM::InvalidTransition)
|
|
51
35
|
end
|
|
52
36
|
|
|
53
37
|
it 'defines constants for each state name' do
|
|
54
|
-
expect(
|
|
55
|
-
expect(
|
|
56
|
-
expect(
|
|
38
|
+
expect(SimpleExample::STATE_INITIALISED).to eq(:initialised)
|
|
39
|
+
expect(SimpleExample::STATE_FILLED_OUT).to eq(:filled_out)
|
|
40
|
+
expect(SimpleExample::STATE_AUTHORISED).to eq(:authorised)
|
|
57
41
|
end
|
|
58
42
|
end
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe 'subclassing' do
|
|
4
|
-
let(:son) {Son.new}
|
|
5
4
|
|
|
6
5
|
it 'should have the parent states' do
|
|
7
|
-
|
|
8
|
-
expect(
|
|
6
|
+
SuperClass.aasm.states.each do |state|
|
|
7
|
+
expect(SubClassWithMoreStates.aasm.states).to include(state)
|
|
9
8
|
end
|
|
10
|
-
expect(
|
|
9
|
+
expect(SubClass.aasm.states).to eq(SuperClass.aasm.states)
|
|
11
10
|
end
|
|
12
11
|
|
|
13
12
|
it 'should not add the child states to the parent machine' do
|
|
14
|
-
expect(
|
|
13
|
+
expect(SuperClass.aasm.states).not_to include(:foo)
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
it "should have the same events as its parent" do
|
|
18
|
-
expect(
|
|
17
|
+
expect(SubClass.aasm.events).to eq(SuperClass.aasm.events)
|
|
19
18
|
end
|
|
20
19
|
|
|
21
|
-
it 'should know how to respond to
|
|
22
|
-
expect(
|
|
20
|
+
it 'should know how to respond to question methods' do
|
|
21
|
+
expect(SubClass.new.may_foo?).to be_truthy
|
|
23
22
|
end
|
|
24
23
|
|
|
25
|
-
it 'should not break if I call
|
|
24
|
+
it 'should not break if I call methods from super class' do
|
|
25
|
+
son = SubClass.new
|
|
26
26
|
son.update_state
|
|
27
|
-
expect(son.aasm.current_state).to eq(:
|
|
27
|
+
expect(son.aasm.current_state).to eq(:ended)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
end
|
|
@@ -4,7 +4,12 @@ describe 'transitions' do
|
|
|
4
4
|
|
|
5
5
|
it 'should raise an exception when whiny' do
|
|
6
6
|
process = ProcessWithNewDsl.new
|
|
7
|
-
expect { process.stop! }.to raise_error
|
|
7
|
+
expect { process.stop! }.to raise_error do |err|
|
|
8
|
+
expect(err.class).to eql(AASM::InvalidTransition)
|
|
9
|
+
expect(err.message).to eql("Event 'stop' cannot transition from 'sleeping'")
|
|
10
|
+
expect(err.object).to eql(process)
|
|
11
|
+
expect(err.event_name).to eql(:stop)
|
|
12
|
+
end
|
|
8
13
|
expect(process).to be_sleeping
|
|
9
14
|
end
|
|
10
15
|
|