aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2010-01-31 14:32:26 +0000
committerPratik Naik <pratiknaik@gmail.com>2010-01-31 14:32:26 +0000
commited60021f39f7913537dcad181e4061e423dc6c3d (patch)
tree86532c43aabe9125422f84b48a899f2672900bf5 /activemodel
parentc6af337d2d6c86792cdc8132224ebe9294d35774 (diff)
parentb3a028259f373fd58fea2171a1e9e8b2fe3e253a (diff)
downloadrails-ed60021f39f7913537dcad181e4061e423dc6c3d.tar.gz
rails-ed60021f39f7913537dcad181e4061e423dc6c3d.tar.bz2
rails-ed60021f39f7913537dcad181e4061e423dc6c3d.zip
Merge remote branch 'mainstream/master'
Conflicts: activemodel/lib/active_model/state_machine.rb
Diffstat (limited to 'activemodel')
-rw-r--r--activemodel/lib/active_model.rb1
-rw-r--r--activemodel/lib/active_model/errors.rb21
-rw-r--r--activemodel/lib/active_model/state_machine.rb219
-rw-r--r--activemodel/lib/active_model/state_machine/event.rb62
-rw-r--r--activemodel/lib/active_model/state_machine/machine.rb75
-rw-r--r--activemodel/lib/active_model/state_machine/state.rb47
-rw-r--r--activemodel/lib/active_model/state_machine/state_transition.rb40
-rw-r--r--activemodel/test/cases/state_machine/event_test.rb49
-rw-r--r--activemodel/test/cases/state_machine/machine_test.rb43
-rw-r--r--activemodel/test/cases/state_machine/state_test.rb72
-rw-r--r--activemodel/test/cases/state_machine/state_transition_test.rb84
-rw-r--r--activemodel/test/cases/state_machine_test.rb312
-rw-r--r--activemodel/test/cases/validations/i18n_validation_test.rb28
13 files changed, 28 insertions, 1025 deletions
diff --git a/activemodel/lib/active_model.rb b/activemodel/lib/active_model.rb
index 6eab00c177..1609075f7e 100644
--- a/activemodel/lib/active_model.rb
+++ b/activemodel/lib/active_model.rb
@@ -43,7 +43,6 @@ module ActiveModel
autoload :Observer, 'active_model/observing'
autoload :Observing
autoload :Serialization
- autoload :StateMachine
autoload :TestCase
autoload :Translation
autoload :VERSION
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index 76e6ad93a7..f1d74db5f3 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -242,28 +242,35 @@ module ActiveModel
# <li><tt>activemodel.errors.models.admin.blank</tt></li>
# <li><tt>activemodel.errors.models.user.attributes.title.blank</tt></li>
# <li><tt>activemodel.errors.models.user.blank</tt></li>
- # <li><tt>activemodel.errors.messages.blank</tt></li>
# <li>any default you provided through the +options+ hash (in the activemodel.errors scope)</li>
+ # <li><tt>activemodel.errors.messages.blank</tt></li>
+ # <li><tt>errors.attributes.title.blank</tt></li>
+ # <li><tt>errors.messages.blank</tt></li>
# </ol>
def generate_message(attribute, message = :invalid, options = {})
message, options[:default] = options[:default], message if options[:default].is_a?(Symbol)
defaults = @base.class.lookup_ancestors.map do |klass|
- [ :"models.#{klass.name.underscore}.attributes.#{attribute}.#{message}",
- :"models.#{klass.name.underscore}.#{message}" ]
+ [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.attributes.#{attribute}.#{message}",
+ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.#{message}" ]
end
defaults << options.delete(:default)
- defaults = defaults.compact.flatten << :"messages.#{message}"
+ defaults << :"#{@base.class.i18n_scope}.errors.messages.#{message}"
+ defaults << :"errors.attributes.#{attribute}.#{message}"
+ defaults << :"errors.messages.#{message}"
+
+ defaults.compact!
+ defaults.flatten!
key = defaults.shift
value = @base.send(:read_attribute_for_validation, attribute)
- options = { :default => defaults,
+ options = {
+ :default => defaults,
:model => @base.class.model_name.human,
:attribute => @base.class.human_attribute_name(attribute),
- :value => value,
- :scope => [:errors]
+ :value => value
}.merge(options)
I18n.translate(key, options)
diff --git a/activemodel/lib/active_model/state_machine.rb b/activemodel/lib/active_model/state_machine.rb
deleted file mode 100644
index 64b91c1659..0000000000
--- a/activemodel/lib/active_model/state_machine.rb
+++ /dev/null
@@ -1,219 +0,0 @@
-module ActiveModel
-
- # ActiveModel::StateMachine provides methods that turn your object into a
- # finite state machine, able to move from one state to another.
- #
- # A minimal implementation could be:
- #
- # class EmailMessage
- # include ActiveModel::StateMachine
- #
- # state_machine do
- # state :unread
- # state :read
- # end
- #
- # event :open_email do
- # transitions :to => :read, :from => :unread
- # end
- # end
- #
- # === Examples
- #
- # class TrafficLight
- # include ActiveModel::StateMachine
- #
- # attr_reader :runners_caught
- #
- # def initialize
- # @runners_caught = 0
- # end
- #
- # state_machine do
- # state :red
- # state :green
- # state :yellow
- # state :blink
- #
- # event :change_color do
- # transitions :to => :red, :from => [:yellow],
- # :on_transition => :catch_runners
- # transitions :to => :green, :from => [:red]
- # transitions :to => :yellow, :from => [:green]
- # end
- #
- # event :defect do
- # transitions :to => :blink, :from => [:yellow, :red, :green]
- # end
- #
- # event :repair do
- # transitions :to => :red, :from => [:blink]
- # end
- # end
- #
- # def catch_runners
- # @runners_caught += 1
- # end
- # end
- #
- # light = TrafficLight.new
- # light.current_state # => :red
- # light.change_color! # => true
- # light.current_state # => :green
- # light.green? # => true
- # light.change_color! # => true
- # light.current_state # => :yellow
- # light.red? # => false
- # light.change_color! # => true
- # light.runners_caught # => 1
- #
- # * The initial state for TrafficLight is red which is the first state defined.
- #
- # TrafficLight.state_machine.initial_state # => :red
- #
- # * Call an event to transition a state machine, e.g. <tt>change_color!</tt>.
- # You can call the event with or without the exclamation mark, however, the common Ruby
- # idiom is to name methods that directly change the state of the receivier with
- # an exclamation mark, so <tt>change_color!</tt> is preferred over <tt>change_color</tt>.
- #
- # light.current_state #=> :green
- # light.change_color! #=> true
- # light.current_state #=> :yellow
- #
- # * On a succesful transition to red (from yellow), the local +catch_runners+
- # method is executed
- #
- # light.current_state #=> :red
- # light.change_color! #=> true
- # light.runners_caught #=> 1
- #
- # * The object acts differently depending on its current state, for instance,
- # the change_color! method has a different action depending on the current
- # color of the light
- #
- # light.change_color! #=> true
- # light.current_state #=> :red
- # light.change_color! #=> true
- # light.current_state #=> :green
- #
- # * Get the possible events for a state
- #
- # TrafficLight.state_machine.events_for(:red) # => [:change_color, :defect]
- # TrafficLight.state_machine.events_for(:blink) # => [:repair]
- #
- # The StateMachine also supports the following features :
- #
- # * Success callbacks on event transition
- #
- # event :sample, :success => :we_win do
- # ...
- # end
- #
- # * Enter and exit callbacks par state
- #
- # state :open, :enter => [:alert_twitter, :send_emails], :exit => :alert_twitter
- #
- # * Guards on transition
- #
- # event :close do
- # # You may only close the store if the safe is locked!!
- # transitions :to => :closed, :from => :open, :guard => :safe_locked?
- # end
- #
- # * Setting the initial state
- #
- # state_machine :initial => :yellow do
- # ...
- # end
- #
- # * Named the state machine, to have more than one
- #
- # class Stated
- # include ActiveModel::StateMachine
- #
- # strate_machine :name => :ontest do
- # end
- #
- # state_machine do
- # end
- # end
- #
- # # Get the state of the <tt>:ontest</tt> state machine
- # stat.current_state(:ontest)
- # # Get the initial state
- # Stated.state_machine(:ontest).initial_state
- #
- # * Changing the state
- #
- # stat.current_state(:default, :astate) # => :astate
- # # But you must give the name of the state machine, here <tt>:default</tt>
- #
- module StateMachine
- autoload :Event, 'active_model/state_machine/event'
- autoload :Machine, 'active_model/state_machine/machine'
- autoload :State, 'active_model/state_machine/state'
- autoload :StateTransition, 'active_model/state_machine/state_transition'
-
- extend ActiveSupport::Concern
-
- class InvalidTransition < Exception
- end
-
- module ClassMethods
- def inherited(klass)
- super
- klass.state_machines = state_machines
- end
-
- def state_machines
- @state_machines ||= {}
- end
-
- def state_machines=(value)
- @state_machines = value ? value.dup : nil
- end
-
- def state_machine(name = nil, options = {}, &block)
- if name.is_a?(Hash)
- options = name
- name = nil
- end
- name ||= :default
- state_machines[name] ||= Machine.new(self, name)
- block ? state_machines[name].update(options, &block) : state_machines[name]
- end
-
- def define_state_query_method(state_name)
- name = "#{state_name}?"
- undef_method(name) if method_defined?(name)
- class_eval "def #{name}; current_state.to_s == %(#{state_name}) end"
- end
- end
-
- def current_state(name = nil, new_state = nil, persist = false)
- sm = self.class.state_machine(name)
- ivar = sm.current_state_variable
- if name && new_state
- if persist && respond_to?(:write_state)
- write_state(sm, new_state)
- end
-
- if respond_to?(:write_state_without_persistence)
- write_state_without_persistence(sm, new_state)
- end
-
- instance_variable_set(ivar, new_state)
- else
- instance_variable_set(ivar, nil) unless instance_variable_defined?(ivar)
- value = instance_variable_get(ivar)
- return value if value
-
- if respond_to?(:read_state)
- value = instance_variable_set(ivar, read_state(sm))
- end
-
- value || sm.initial_state
- end
- end
- end
-end
diff --git a/activemodel/lib/active_model/state_machine/event.rb b/activemodel/lib/active_model/state_machine/event.rb
deleted file mode 100644
index 30e9601dc2..0000000000
--- a/activemodel/lib/active_model/state_machine/event.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-module ActiveModel
- module StateMachine
- class Event
- attr_reader :name, :success
-
- def initialize(machine, name, options = {}, &block)
- @machine, @name, @transitions = machine, name, []
- if machine
- machine.klass.send(:define_method, "#{name}!") do |*args|
- machine.fire_event(name, self, true, *args)
- end
-
- machine.klass.send(:define_method, name.to_s) do |*args|
- machine.fire_event(name, self, false, *args)
- end
- end
- update(options, &block)
- end
-
- def fire(obj, to_state = nil, *args)
- transitions = @transitions.select { |t| t.from == obj.current_state(@machine ? @machine.name : nil) }
- raise InvalidTransition if transitions.size == 0
-
- next_state = nil
- transitions.each do |transition|
- next if to_state && !Array(transition.to).include?(to_state)
- if transition.perform(obj)
- next_state = to_state || Array(transition.to).first
- transition.execute(obj, *args)
- break
- end
- end
- next_state
- end
-
- def transitions_from_state?(state)
- @transitions.any? { |t| t.from? state }
- end
-
- def ==(event)
- if event.is_a? Symbol
- name == event
- else
- name == event.name
- end
- end
-
- def update(options = {}, &block)
- if options.key?(:success) then @success = options[:success] end
- if block then instance_eval(&block) end
- self
- end
-
- private
- def transitions(trans_opts)
- Array(trans_opts[:from]).each do |s|
- @transitions << StateTransition.new(trans_opts.merge({:from => s.to_sym}))
- end
- end
- end
- end
-end
diff --git a/activemodel/lib/active_model/state_machine/machine.rb b/activemodel/lib/active_model/state_machine/machine.rb
deleted file mode 100644
index 777531213e..0000000000
--- a/activemodel/lib/active_model/state_machine/machine.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-module ActiveModel
- module StateMachine
- class Machine
- attr_writer :initial_state
- attr_accessor :states, :events, :state_index
- attr_reader :klass, :name
-
- def initialize(klass, name, options = {}, &block)
- @klass, @name, @states, @state_index, @events = klass, name, [], {}, {}
- update(options, &block)
- end
-
- def initial_state
- @initial_state ||= (states.first ? states.first.name : nil)
- end
-
- def update(options = {}, &block)
- if options.key?(:initial) then @initial_state = options[:initial] end
- if block then instance_eval(&block) end
- self
- end
-
- def fire_event(event, record, persist, *args)
- state_index[record.current_state(@name)].call_action(:exit, record)
- if new_state = @events[event].fire(record, *args)
- state_index[new_state].call_action(:enter, record)
-
- if record.respond_to?(event_fired_callback)
- record.send(event_fired_callback, record.current_state, new_state)
- end
-
- record.current_state(@name, new_state, persist)
- record.send(@events[event].success) if @events[event].success
- true
- else
- if record.respond_to?(event_failed_callback)
- record.send(event_failed_callback, event)
- end
-
- false
- end
- end
-
- def states_for_select
- states.map { |st| [st.display_name, st.name.to_s] }
- end
-
- def events_for(state)
- events = @events.values.select { |event| event.transitions_from_state?(state) }
- events.map! { |event| event.name }
- end
-
- def current_state_variable
- "@#{@name}_current_state"
- end
-
- private
- def state(name, options = {})
- @states << (state_index[name] ||= State.new(name, :machine => self)).update(options)
- end
-
- def event(name, options = {}, &block)
- (@events[name] ||= Event.new(self, name)).update(options, &block)
- end
-
- def event_fired_callback
- @event_fired_callback ||= (@name == :default ? '' : "#{@name}_") + 'event_fired'
- end
-
- def event_failed_callback
- @event_failed_callback ||= (@name == :default ? '' : "#{@name}_") + 'event_failed'
- end
- end
- end
-end
diff --git a/activemodel/lib/active_model/state_machine/state.rb b/activemodel/lib/active_model/state_machine/state.rb
deleted file mode 100644
index 76916b1d86..0000000000
--- a/activemodel/lib/active_model/state_machine/state.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-module ActiveModel
- module StateMachine
- class State
- attr_reader :name, :options
-
- def initialize(name, options = {})
- @name = name
- if machine = options.delete(:machine)
- machine.klass.define_state_query_method(name)
- end
- update(options)
- end
-
- def ==(state)
- if state.is_a? Symbol
- name == state
- else
- name == state.name
- end
- end
-
- def call_action(action, record)
- action = @options[action]
- case action
- when Symbol, String
- record.send(action)
- when Proc
- action.call(record)
- end
- end
-
- def display_name
- @display_name ||= name.to_s.gsub(/_/, ' ').capitalize
- end
-
- def for_select
- [display_name, name.to_s]
- end
-
- def update(options = {})
- if options.key?(:display) then @display_name = options.delete(:display) end
- @options = options
- self
- end
- end
- end
-end
diff --git a/activemodel/lib/active_model/state_machine/state_transition.rb b/activemodel/lib/active_model/state_machine/state_transition.rb
deleted file mode 100644
index b0c5504de7..0000000000
--- a/activemodel/lib/active_model/state_machine/state_transition.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-module ActiveModel
- module StateMachine
- class StateTransition
- attr_reader :from, :to, :options
-
- def initialize(opts)
- @from, @to, @guard, @on_transition = opts[:from], opts[:to], opts[:guard], opts[:on_transition]
- @options = opts
- end
-
- def perform(obj)
- case @guard
- when Symbol, String
- obj.send(@guard)
- when Proc
- @guard.call(obj)
- else
- true
- end
- end
-
- def execute(obj, *args)
- case @on_transition
- when Symbol, String
- obj.send(@on_transition, *args)
- when Proc
- @on_transition.call(obj, *args)
- end
- end
-
- def ==(obj)
- @from == obj.from && @to == obj.to
- end
-
- def from?(value)
- @from == value
- end
- end
- end
-end
diff --git a/activemodel/test/cases/state_machine/event_test.rb b/activemodel/test/cases/state_machine/event_test.rb
deleted file mode 100644
index 2a0ef53a3f..0000000000
--- a/activemodel/test/cases/state_machine/event_test.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'cases/helper'
-
-class EventTest < ActiveModel::TestCase
- def setup
- @state_name = :close_order
- @success = :success_callback
- end
-
- def new_event
- @event = ActiveModel::StateMachine::Event.new(nil, @state_name, {:success => @success}) do
- transitions :to => :closed, :from => [:open, :received]
- end
- end
-
- test 'should set the name' do
- assert_equal @state_name, new_event.name
- end
-
- test 'should set the success option' do
- assert_equal @success, new_event.success
- end
-
- test 'should create StateTransitions' do
- ActiveModel::StateMachine::StateTransition.expects(:new).with(:to => :closed, :from => :open)
- ActiveModel::StateMachine::StateTransition.expects(:new).with(:to => :closed, :from => :received)
- new_event
- end
-end
-
-class EventBeingFiredTest < ActiveModel::TestCase
- test 'should raise an AASM::InvalidTransition error if the transitions are empty' do
- event = ActiveModel::StateMachine::Event.new(nil, :event)
-
- assert_raise ActiveModel::StateMachine::InvalidTransition do
- event.fire(nil)
- end
- end
-
- test 'should return the state of the first matching transition it finds' do
- event = ActiveModel::StateMachine::Event.new(nil, :event) do
- transitions :to => :closed, :from => [:open, :received]
- end
-
- obj = stub
- obj.stubs(:current_state).returns(:open)
-
- assert_equal :closed, event.fire(obj)
- end
-end
diff --git a/activemodel/test/cases/state_machine/machine_test.rb b/activemodel/test/cases/state_machine/machine_test.rb
deleted file mode 100644
index 2aa954d80c..0000000000
--- a/activemodel/test/cases/state_machine/machine_test.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-require 'cases/helper'
-
-class MachineTestSubject
- include ActiveModel::StateMachine
-
- state_machine do
- state :open
- state :closed
- end
-
- state_machine :initial => :foo do
- event :shutdown do
- transitions :from => :open, :to => :closed
- end
-
- event :timeout do
- transitions :from => :open, :to => :closed
- end
- end
-
- state_machine :extra, :initial => :bar do
- end
-end
-
-class StateMachineMachineTest < ActiveModel::TestCase
- test "allows reuse of existing machines" do
- assert_equal 2, MachineTestSubject.state_machines.size
- end
-
- test "sets #initial_state from :initial option" do
- assert_equal :bar, MachineTestSubject.state_machine(:extra).initial_state
- end
-
- test "accesses non-default state machine" do
- assert_kind_of ActiveModel::StateMachine::Machine, MachineTestSubject.state_machine(:extra)
- end
-
- test "finds events for given state" do
- events = MachineTestSubject.state_machine.events_for(:open)
- assert events.include?(:shutdown)
- assert events.include?(:timeout)
- end
-end
diff --git a/activemodel/test/cases/state_machine/state_test.rb b/activemodel/test/cases/state_machine/state_test.rb
deleted file mode 100644
index 527bfd4c04..0000000000
--- a/activemodel/test/cases/state_machine/state_test.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-require 'cases/helper'
-
-class StateTestSubject
- include ActiveModel::StateMachine
-
- state_machine do
- end
-end
-
-class StateTest < ActiveModel::TestCase
- def setup
- @state_name = :astate
- @machine = StateTestSubject.state_machine
- @options = { :crazy_custom_key => 'key', :machine => @machine }
- end
-
- def new_state(options={})
- ActiveModel::StateMachine::State.new(@state_name, @options.merge(options))
- end
-
- test 'sets the name' do
- assert_equal :astate, new_state.name
- end
-
- test 'sets the display_name from name' do
- assert_equal "Astate", new_state.display_name
- end
-
- test 'sets the display_name from options' do
- assert_equal "A State", new_state(:display => "A State").display_name
- end
-
- test 'sets the options and expose them as options' do
- @options.delete(:machine)
- assert_equal @options, new_state.options
- end
-
- test 'equals a symbol of the same name' do
- assert_equal new_state, :astate
- end
-
- test 'equals a State of the same name' do
- assert_equal new_state, new_state
- end
-
- test 'should send a message to the record for an action if the action is present as a symbol' do
- state = new_state(:entering => :foo)
-
- record = stub
- record.expects(:foo)
-
- state.call_action(:entering, record)
- end
-
- test 'should send a message to the record for an action if the action is present as a string' do
- state = new_state(:entering => 'foo')
-
- record = stub
- record.expects(:foo)
-
- state.call_action(:entering, record)
- end
-
- test 'should call a proc, passing in the record for an action if the action is present' do
- state = new_state(:entering => Proc.new {|r| r.foobar})
-
- record = stub
- record.expects(:foobar)
-
- state.call_action(:entering, record)
- end
-end
diff --git a/activemodel/test/cases/state_machine/state_transition_test.rb b/activemodel/test/cases/state_machine/state_transition_test.rb
deleted file mode 100644
index 17f9d88be7..0000000000
--- a/activemodel/test/cases/state_machine/state_transition_test.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-require 'cases/helper'
-
-class StateTransitionTest < ActiveModel::TestCase
- test 'should set from, to, and opts attr readers' do
- opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
- st = ActiveModel::StateMachine::StateTransition.new(opts)
-
- assert_equal opts[:from], st.from
- assert_equal opts[:to], st.to
- assert_equal opts, st.options
- end
-
- test 'should pass equality check if from and to are the same' do
- opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
- st = ActiveModel::StateMachine::StateTransition.new(opts)
-
- obj = stub
- obj.stubs(:from).returns(opts[:from])
- obj.stubs(:to).returns(opts[:to])
-
- assert_equal st, obj
- end
-
- test 'should fail equality check if from are not the same' do
- opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
- st = ActiveModel::StateMachine::StateTransition.new(opts)
-
- obj = stub
- obj.stubs(:from).returns('blah')
- obj.stubs(:to).returns(opts[:to])
-
- assert_not_equal st, obj
- end
-
- test 'should fail equality check if to are not the same' do
- opts = {:from => 'foo', :to => 'bar', :guard => 'g'}
- st = ActiveModel::StateMachine::StateTransition.new(opts)
-
- obj = stub
- obj.stubs(:from).returns(opts[:from])
- obj.stubs(:to).returns('blah')
-
- assert_not_equal st, obj
- end
-end
-
-class StateTransitionGuardCheckTest < ActiveModel::TestCase
- test 'should return true of there is no guard' do
- opts = {:from => 'foo', :to => 'bar'}
- st = ActiveModel::StateMachine::StateTransition.new(opts)
-
- assert st.perform(nil)
- end
-
- test 'should call the method on the object if guard is a symbol' do
- opts = {:from => 'foo', :to => 'bar', :guard => :test_guard}
- st = ActiveModel::StateMachine::StateTransition.new(opts)
-
- obj = stub
- obj.expects(:test_guard)
-
- st.perform(obj)
- end
-
- test 'should call the method on the object if guard is a string' do
- opts = {:from => 'foo', :to => 'bar', :guard => 'test_guard'}
- st = ActiveModel::StateMachine::StateTransition.new(opts)
-
- obj = stub
- obj.expects(:test_guard)
-
- st.perform(obj)
- end
-
- test 'should call the proc passing the object if the guard is a proc' do
- opts = {:from => 'foo', :to => 'bar', :guard => Proc.new {|o| o.test_guard}}
- st = ActiveModel::StateMachine::StateTransition.new(opts)
-
- obj = stub
- obj.expects(:test_guard)
-
- st.perform(obj)
- end
-end
diff --git a/activemodel/test/cases/state_machine_test.rb b/activemodel/test/cases/state_machine_test.rb
deleted file mode 100644
index f66299741e..0000000000
--- a/activemodel/test/cases/state_machine_test.rb
+++ /dev/null
@@ -1,312 +0,0 @@
-require 'cases/helper'
-
-class StateMachineSubject
- include ActiveModel::StateMachine
-
- state_machine do
- state :open, :exit => :exit
- state :closed, :enter => :enter
-
- event :close, :success => :success_callback do
- transitions :to => :closed, :from => [:open]
- end
-
- event :null do
- transitions :to => :closed, :from => [:open], :guard => :always_false
- end
- end
-
- state_machine :bar do
- state :read
- state :ended
-
- event :foo do
- transitions :to => :ended, :from => [:read]
- end
- end
-
- def always_false
- false
- end
-
- def success_callback
- end
-
- def enter
- end
- def exit
- end
-end
-
-class StateMachineSubjectSubclass < StateMachineSubject
-end
-
-class StateMachineClassLevelTest < ActiveModel::TestCase
- test 'defines a class level #state_machine method on its including class' do
- assert StateMachineSubject.respond_to?(:state_machine)
- end
-
- test 'defines a class level #state_machines method on its including class' do
- assert StateMachineSubject.respond_to?(:state_machines)
- end
-
- test 'class level #state_machine returns machine instance' do
- assert_kind_of ActiveModel::StateMachine::Machine, StateMachineSubject.state_machine
- end
-
- test 'class level #state_machine returns machine instance with given name' do
- assert_kind_of ActiveModel::StateMachine::Machine, StateMachineSubject.state_machine(:default)
- end
-
- test 'class level #state_machines returns hash of machine instances' do
- assert_kind_of ActiveModel::StateMachine::Machine, StateMachineSubject.state_machines[:default]
- end
-
- test "should return a select friendly array of states in the form of [['Friendly name', 'state_name']]" do
- assert_equal [['Open', 'open'], ['Closed', 'closed']], StateMachineSubject.state_machine.states_for_select
- end
-end
-
-class StateMachineInstanceLevelTest < ActiveModel::TestCase
- def setup
- @foo = StateMachineSubject.new
- end
-
- test 'defines an accessor for the current state' do
- assert @foo.respond_to?(:current_state)
- end
-
- test 'defines a state querying instance method on including class' do
- assert @foo.respond_to?(:open?)
- end
-
- test 'defines an event! instance method' do
- assert @foo.respond_to?(:close!)
- end
-
- test 'defines an event instance method' do
- assert @foo.respond_to?(:close)
- end
-end
-
-class StateMachineInitialStatesTest < ActiveModel::TestCase
- def setup
- @foo = StateMachineSubject.new
- end
-
- test 'sets the initial state' do
- assert_equal :open, @foo.current_state
- end
-
- test '#open? should be initially true' do
- assert @foo.open?
- end
-
- test '#closed? should be initially false' do
- assert !@foo.closed?
- end
-
- test 'uses the first state defined if no initial state is given' do
- assert_equal :read, @foo.current_state(:bar)
- end
-end
-
-class StateMachineEventFiringWithPersistenceTest < ActiveModel::TestCase
- def setup
- @subj = StateMachineSubject.new
- end
-
- test 'updates the current state' do
- @subj.close!
-
- assert_equal :closed, @subj.current_state
- end
-
- test 'fires the Event' do
- @subj.class.state_machine.events[:close].expects(:fire).with(@subj)
- @subj.close!
- end
-
- test 'calls the success callback if one was provided' do
- @subj.expects(:success_callback)
- @subj.close!
- end
-
- test 'attempts to persist if write_state is defined' do
- def @subj.write_state
- end
-
- @subj.expects(:write_state)
- @subj.close!
- end
-end
-
-class StateMachineEventFiringWithoutPersistence < ActiveModel::TestCase
- test 'updates the current state' do
- subj = StateMachineSubject.new
- assert_equal :open, subj.current_state
- subj.close
- assert_equal :closed, subj.current_state
- end
-
- test 'fires the Event' do
- subj = StateMachineSubject.new
-
- StateMachineSubject.state_machine.events[:close].expects(:fire).with(subj)
- subj.close
- end
-
- test 'attempts to persist if write_state is defined' do
- subj = StateMachineSubject.new
-
- def subj.write_state
- end
-
- subj.expects(:write_state_without_persistence)
-
- subj.close
- end
-end
-
-class StateMachinePersistenceTest < ActiveModel::TestCase
- test 'reads the state if it has not been set and read_state is defined' do
- subj = StateMachineSubject.new
- def subj.read_state
- end
-
- subj.expects(:read_state).with(StateMachineSubject.state_machine)
-
- subj.current_state
- end
-end
-
-class StateMachineEventCallbacksTest < ActiveModel::TestCase
- test 'should call aasm_event_fired if defined and successful for bang fire' do
- subj = StateMachineSubject.new
- def subj.aasm_event_fired(from, to)
- end
-
- subj.expects(:event_fired)
-
- subj.close!
- end
-
- test 'should call aasm_event_fired if defined and successful for non-bang fire' do
- subj = StateMachineSubject.new
- def subj.aasm_event_fired(from, to)
- end
-
- subj.expects(:event_fired)
-
- subj.close
- end
-
- test 'should call aasm_event_failed if defined and transition failed for bang fire' do
- subj = StateMachineSubject.new
- def subj.event_failed(event)
- end
-
- subj.expects(:event_failed)
-
- subj.null!
- end
-
- test 'should call aasm_event_failed if defined and transition failed for non-bang fire' do
- subj = StateMachineSubject.new
- def subj.aasm_event_failed(event)
- end
-
- subj.expects(:event_failed)
-
- subj.null
- end
-end
-
-class StateMachineStateActionsTest < ActiveModel::TestCase
- test "calls enter when entering state" do
- subj = StateMachineSubject.new
- subj.expects(:enter)
- subj.close
- end
-
- test "calls exit when exiting state" do
- subj = StateMachineSubject.new
- subj.expects(:exit)
- subj.close
- end
-end
-
-class StateMachineInheritanceTest < ActiveModel::TestCase
- test "has the same states as its parent" do
- assert_equal StateMachineSubject.state_machine.states, StateMachineSubjectSubclass.state_machine.states
- end
-
- test "has the same events as its parent" do
- assert_equal StateMachineSubject.state_machine.events, StateMachineSubjectSubclass.state_machine.events
- end
-end
-
-class StateMachineSubject
- state_machine :chetan_patil, :initial => :sleeping do
- state :sleeping
- state :showering
- state :working
- state :dating
-
- event :wakeup do
- transitions :from => :sleeping, :to => [:showering, :working]
- end
-
- event :dress do
- transitions :from => :sleeping, :to => :working, :on_transition => :wear_clothes
- transitions :from => :showering, :to => [:working, :dating], :on_transition => Proc.new { |obj, *args| obj.wear_clothes(*args) }
- end
- end
-
- def wear_clothes(shirt_color, trouser_type)
- end
-end
-
-class StateMachineWithComplexTransitionsTest < ActiveModel::TestCase
- def setup
- @subj = StateMachineSubject.new
- end
-
- test 'transitions to specified next state (sleeping to showering)' do
- @subj.wakeup! :showering
-
- assert_equal :showering, @subj.current_state(:chetan_patil)
- end
-
- test 'transitions to specified next state (sleeping to working)' do
- @subj.wakeup! :working
-
- assert_equal :working, @subj.current_state(:chetan_patil)
- end
-
- test 'transitions to default (first or showering) state' do
- @subj.wakeup!
-
- assert_equal :showering, @subj.current_state(:chetan_patil)
- end
-
- test 'transitions to default state when on_transition invoked' do
- @subj.dress!(nil, 'purple', 'dressy')
-
- assert_equal :working, @subj.current_state(:chetan_patil)
- end
-
- test 'calls on_transition method with args' do
- @subj.wakeup! :showering
-
- @subj.expects(:wear_clothes).with('blue', 'jeans')
- @subj.dress! :working, 'blue', 'jeans'
- end
-
- test 'calls on_transition proc' do
- @subj.wakeup! :showering
-
- @subj.expects(:wear_clothes).with('purple', 'slacks')
- @subj.dress!(:dating, 'purple', 'slacks')
- end
-end
diff --git a/activemodel/test/cases/validations/i18n_validation_test.rb b/activemodel/test/cases/validations/i18n_validation_test.rb
index 7d33fcea98..38844bb1fa 100644
--- a/activemodel/test/cases/validations/i18n_validation_test.rb
+++ b/activemodel/test/cases/validations/i18n_validation_test.rb
@@ -254,7 +254,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_confirmation_of w/o mocha
def test_validates_confirmation_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:confirmation => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:confirmation => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:confirmation => 'global message'}}
Person.validates_confirmation_of :title
@@ -275,7 +275,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_acceptance_of w/o mocha
def test_validates_acceptance_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:accepted => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:accepted => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:accepted => 'global message'}}
Person.validates_acceptance_of :title, :allow_nil => false
@@ -294,7 +294,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_presence_of w/o mocha
def test_validates_presence_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:blank => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:blank => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:blank => 'global message'}}
Person.validates_presence_of :title
@@ -313,7 +313,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_length_of :within w/o mocha
def test_validates_length_of_within_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:too_short => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:too_short => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:too_short => 'global message'}}
Person.validates_length_of :title, :within => 3..5
@@ -332,7 +332,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_length_of :is w/o mocha
def test_validates_length_of_is_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:wrong_length => 'global message'}}
Person.validates_length_of :title, :is => 5
@@ -351,7 +351,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_format_of w/o mocha
def test_validates_format_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:invalid => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:invalid => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:invalid => 'global message'}}
Person.validates_format_of :title, :with => /^[1-9][0-9]*$/
@@ -370,7 +370,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_inclusion_of w/o mocha
def test_validates_inclusion_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:inclusion => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:inclusion => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:inclusion => 'global message'}}
Person.validates_inclusion_of :title, :in => %w(a b c)
@@ -389,7 +389,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_exclusion_of w/o mocha
def test_validates_exclusion_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:exclusion => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:exclusion => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:exclusion => 'global message'}}
Person.validates_exclusion_of :title, :in => %w(a b c)
@@ -410,7 +410,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_numericality_of without :only_integer w/o mocha
def test_validates_numericality_of_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:not_a_number => 'global message'}}
Person.validates_numericality_of :title
@@ -431,7 +431,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_numericality_of with :only_integer w/o mocha
def test_validates_numericality_of_only_integer_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:not_a_number => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:not_a_number => 'global message'}}
Person.validates_numericality_of :title, :only_integer => true
@@ -452,7 +452,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_numericality_of :odd w/o mocha
def test_validates_numericality_of_odd_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:odd => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:odd => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:odd => 'global message'}}
Person.validates_numericality_of :title, :only_integer => true, :odd => true
@@ -473,7 +473,7 @@ class I18nValidationTest < ActiveModel::TestCase
# validates_numericality_of :less_than w/o mocha
def test_validates_numericality_of_less_than_finds_custom_model_key_translation
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:less_than => 'custom message'}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:less_than => 'custom message'}}}}}}
I18n.backend.store_translations 'en', :errors => {:messages => {:less_than => 'global message'}}
Person.validates_numericality_of :title, :only_integer => true, :less_than => 0
@@ -502,7 +502,7 @@ class I18nValidationTest < ActiveModel::TestCase
end
def test_validates_with_message_symbol_must_translate_per_attribute
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:attributes => {:title => {:custom_error => "I am a custom error"}}}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:attributes => {:title => {:custom_error => "I am a custom error"}}}}}}
Person.validates_presence_of :title, :message => :custom_error
@person.title = nil
@person.valid?
@@ -510,7 +510,7 @@ class I18nValidationTest < ActiveModel::TestCase
end
def test_validates_with_message_symbol_must_translate_per_model
- I18n.backend.store_translations 'en', :errors => {:models => {:person => {:custom_error => "I am a custom error"}}}
+ I18n.backend.store_translations 'en', :activemodel => {:errors => {:models => {:person => {:custom_error => "I am a custom error"}}}}
Person.validates_presence_of :title, :message => :custom_error
@person.title = nil
@person.valid?