spec/mongoid/mongoid_spec.rb in edge-state-machine-0.0.2 vs spec/mongoid/mongoid_spec.rb in edge-state-machine-0.0.3
- old
+ new
@@ -1,101 +1,7 @@
require 'mongoid/mongoid_helper'
-class MongoTrafficLight
- include Mongoid::Document
- include Mongoid::EdgeStateMachine
- field :state
-
- state_machine do
- state :off
-
- state :red
- state :green
- state :yellow
-
- event :red_on do
- transitions :to => :red, :from => [:yellow]
- end
-
- event :green_on do
- transitions :to => :green, :from => [:red]
- end
-
- event :yellow_on do
- transitions :to => :yellow, :from => [:green]
- end
-
- event :reset do
- transitions :to => :red, :from => [:off]
- end
- end
-end
-
-class MongoProtectedTrafficLight < MongoTrafficLight
- attr_protected :state
-end
-
-class MongoValidatingTrafficLight < MongoTrafficLight
- validate {|t| errors.add(:base, 'This TrafficLight will never validate after creation') unless t.new_record? }
-end
-
-class MongoConditionalValidatingTrafficLight < MongoTrafficLight
- validates :name, :presence => true, :length => { :within => 20..40 }, :confirmation => true, :if => :red?
-end
-
-class MongoOrder
- include Mongoid::Document
- include Mongoid::EdgeStateMachine
-
- field :state, :type => String
- field :order_number, :type => Integer
- field :paid_at, :type => DateTime
- field :prepared_on, :type => DateTime
- field :dispatched_at, :type => DateTime
- field :cancellation_date, :type => Date
-
- state_machine do
- state :opened
- state :placed
- state :paid
- state :prepared
- state :delivered
- state :cancelled
-
- # no timestamp col is being specified here - should be ignored
- event :place do
- transitions :from => :opened, :to => :placed
- end
-
- # should set paid_at timestamp
- event :pay, :timestamp => true do
- transitions :from => :placed, :to => :paid
- end
-
- # should set prepared_on
- event :prepare, :timestamp => true do
- transitions :from => :paid, :to => :prepared
- end
-
- # should set dispatched_at
- event :deliver, :timestamp => "dispatched_at" do
- transitions :from => :prepared, :to => :delivered
- end
-
- # should set cancellation_date
- event :cancel, :timestamp => :cancellation_date do
- transitions :from => [:placed, :paid, :prepared], :to => :cancelled
- end
-
- # should raise an exception as there is no timestamp col
- event :reopen, :timestamp => true do
- transitions :from => :cancelled, :to => :opened
- end
-
- end
-end
-
describe "mongoid state machine" do
context "existing mongo document" do
before do
Mongoid.master.collections.reject { |c| c.name =~ /^system\./ }.each(&:drop)
@@ -119,22 +25,28 @@
it "should not persist state on transition" do
@light.reset
@light.current_state.should == :red
@light.reload
- @light.state.should == "off"
+ @light.state.should == :off
end
it "should persists state on transition" do
@light.reset!
@light.current_state.should == :red
@light.reload
@light.state.should == "red"
end
+ it "should initialize the current state when loaded from database" do
+ @light.reset!
+ loaded_light = MongoTrafficLight.find(@light.id)
+ loaded_light.current_state.should == :red
+ end
+
it "should raise error on transition to an invalid state" do
- expect { @light.yellow_on }.should raise_error EdgeStateMachine::InvalidTransition
+ expect { @light.yellow_on }.should raise_error EdgeStateMachine::NoTransitionFound
@light.current_state.should == :off
end
it "should persist state when state is protected on transition" do
protected_light = MongoProtectedTrafficLight.create!
@@ -143,12 +55,12 @@
protected_light.reload
protected_light.state.should == "red"
end
it "should not validate when try transition with wrong state " do
- for s in @light.class.state_machine.states
- @light.state = s.name
+ for s in @light.class.state_machines[:default].states.keys
+ @light.state = s
@light.valid?.should == true
end
@light.state = "invalid_one"
@light.valid?.should_not == true
end
@@ -156,23 +68,42 @@
it "should raise exception when model validation fails on transition" do
validating_light = MongoValidatingTrafficLight.create!
expect {validating_light.reset!}.should raise_error Mongoid::Errors::Validations
end
- #it "should state query method used in a validation condition" do
- #validating_light = MongoConditionalValidatingTrafficLight.create!
+ it "should state query method used in a validation condition" do
+ validating_light = MongoConditionalValidatingTrafficLight.create!
#expect {validating_light.reset!}.should raise_error Mongoid::RecordInvalid
- #validating_light.off?.should == true
- #end
+ validating_light.off?.should == true
+ end
it "should reload the model when current state resets" do
@light.reset
@light.red?.should == true
@light.update_attribute(:state, 'green')
- @light.reload.green?.should == false # reloaded state should come from instance variable not from database
- # because the state can be changed without persist
+ @light.reload.green?.should == true # reloaded state should come from database
end
+
+ describe "scopes" do
+ it "should be added for each state" do
+ MongoTrafficLight.should respond_to(:off)
+ MongoTrafficLight.should respond_to(:red)
+ end
+
+ it "should not be added for each state" do
+ #MongoTrafficLightNoScope.should_not respond_to(:off)
+ #MongoTrafficLightNoScope.should_not respond_to(:red)
+ end
+
+ it "should behave like scopes" do
+ 3.times { MongoTrafficLight.create(:state => "off") }
+ 3.times { MongoTrafficLight.create(:state => "red") }
+ # one was created before
+ MongoTrafficLight.off.count.should == 4
+ MongoTrafficLight.red.count.should == 3
+ end
+ end
end
context "new active record" do
before do
@light = MongoTrafficLight.new
@@ -195,57 +126,8 @@
# control case, no timestamp has been set so we should expect default behaviour
it "should not raise any exceptions when moving to placed" do
@order = create_order
expect { @order.place! }.should_not raise_error
@order.state.should == "placed"
- end
-
- it "should set paid_at when moving to paid" do
- @order = create_order(:placed)
- @order.pay!
- @order.reload
- @order.paid_at.should_not be_nil
- end
-
- it "should set prepared_on when moving to prepared" do
- @order = create_order(:paid)
- @order.prepare!
- @order.reload
- @order.prepared_on.should_not be_nil
- end
-
- it "should set dispatched_at when moving to delivered" do
- @order = create_order(:prepared)
- @order.deliver!
- @order.reload
- @order.dispatched_at.should_not be_nil
- end
-
- it "should set cancellation_date when moving to cancelled" do
- @order = create_order(:placed)
- @order.cancel!
- @order.reload
- @order.cancellation_date.should_not be_nil
- end
-
- it "should raise an exception as there is no attribute when moving to reopened" do
- @order = create_order(:cancelled)
- expect { @order.re_open! }.should raise_error NoMethodError
- @order.reload
- end
-
- it "should raise an exception when passing an invalid value to timestamp options" do
- expect {
- class MongoOrder
- include Mongoid::Document
- include Mongoid::EdgeStateMachine
-
- state_machine do
- event :replace, timestamp: 1 do
- transitions :from => :prepared, :to => :placed
- end
- end
- end
- }.should raise_error ArgumentError
end
end
end
\ No newline at end of file